Index: trunk/extensions/Survey/Survey.php |
— | — | @@ -54,6 +54,7 @@ |
55 | 55 | $wgAutoloadClasses['ApiSubmitSurvey'] = dirname( __FILE__ ) . '/api/ApiSubmitSurvey.php'; |
56 | 56 | |
57 | 57 | $wgAutoloadClasses['Survey'] = dirname( __FILE__ ) . '/includes/Survey.class.php'; |
| 58 | +$wgAutoloadClasses['SurveyQuestion'] = dirname( __FILE__ ) . '/includes/SurveyQuestion.php'; |
58 | 59 | |
59 | 60 | $wgAutoloadClasses['SpecialSurveys'] = dirname( __FILE__ ) . '/specials/SpecialSurveys.php'; |
60 | 61 | $wgAutoloadClasses['SpecialSurveyStats'] = dirname( __FILE__ ) . '/specials/SpecialSurveyStats.php'; |
Index: trunk/extensions/Survey/includes/Survey.class.php |
— | — | @@ -102,18 +102,19 @@ |
103 | 103 | return false; |
104 | 104 | } |
105 | 105 | |
106 | | - $questions = $loadQuestions ? self::getQuestionsFromDB( $dbr, $survey->survey_id ) : array(); |
107 | | - |
108 | | - return new self( |
| 106 | + $survey = new self( |
109 | 107 | $survey->survey_id, |
110 | 108 | $survey->survey_name, |
111 | | - $survey->survey_enabled, |
112 | | - $questions |
| 109 | + $survey->survey_enabled |
113 | 110 | ); |
| 111 | + |
| 112 | + if ( $loadQuestions ) { |
| 113 | + $survey->loadQuestionsFromDB(); |
| 114 | + } |
| 115 | + |
| 116 | + return $survey; |
114 | 117 | } |
115 | 118 | |
116 | | - |
117 | | - |
118 | 119 | /** |
119 | 120 | * Constructor. |
120 | 121 | * |
— | — | @@ -124,7 +125,7 @@ |
125 | 126 | * @param boolean $enabled |
126 | 127 | * @param array $questions |
127 | 128 | */ |
128 | | - public function __construct( $id, $name, $enabled, array $questions ) { |
| 129 | + public function __construct( $id, $name, $enabled, array $questions = array() ) { |
129 | 130 | $this->id = $id; |
130 | 131 | $this->name = $name; |
131 | 132 | $this->enabled = $enabled; |
— | — | @@ -133,6 +134,15 @@ |
134 | 135 | } |
135 | 136 | |
136 | 137 | /** |
| 138 | + * Load the surveys questions from the database. |
| 139 | + * |
| 140 | + * @since 0.1 |
| 141 | + */ |
| 142 | + public function loadQuestionsFromDB() { |
| 143 | + $this->questions = SurveyQuestion::getQuestionsForSurvey( $this->id ); |
| 144 | + } |
| 145 | + |
| 146 | + /** |
137 | 147 | * Writes the survey to the database, either updating it |
138 | 148 | * when it already exists, or inserting it when it doesn't. |
139 | 149 | * |
— | — | @@ -142,11 +152,23 @@ |
143 | 153 | */ |
144 | 154 | public function writeToDB() { |
145 | 155 | if ( is_null( $this->id ) ) { |
146 | | - return $this->insertIntoDB(); |
| 156 | + $success = $this->insertIntoDB(); |
147 | 157 | } |
148 | 158 | else { |
149 | | - return $this->updateInDB(); |
| 159 | + $success = $this->updateInDB(); |
150 | 160 | } |
| 161 | + |
| 162 | + $dbw = wfGetDB( DB_MASTER ); |
| 163 | + |
| 164 | + $dbw->begin(); |
| 165 | + |
| 166 | + foreach ( $this->questions as /* SurveyQuestion */ $question ) { |
| 167 | + $success = $question->writeToDB( $this->id ) && $success; |
| 168 | + } |
| 169 | + |
| 170 | + $dbw->commit(); |
| 171 | + |
| 172 | + return $success; |
151 | 173 | } |
152 | 174 | |
153 | 175 | /** |
— | — | @@ -157,13 +179,15 @@ |
158 | 180 | * @return boolean Success indicator |
159 | 181 | */ |
160 | 182 | protected function updateInDB() { |
161 | | - $dbr = wfGetDB( DB_MASTER ); |
| 183 | + $dbw = wfGetDB( DB_MASTER ); |
162 | 184 | |
163 | | - return $dbr->update( |
| 185 | + $success = $dbw->update( |
164 | 186 | 'surveys', |
165 | 187 | $this->getWriteValues(), |
166 | 188 | array( 'survey_id' => $this->id ) |
167 | 189 | ); |
| 190 | + |
| 191 | + return $success; |
168 | 192 | } |
169 | 193 | |
170 | 194 | /** |
— | — | @@ -174,16 +198,16 @@ |
175 | 199 | * @return boolean Success indicator |
176 | 200 | */ |
177 | 201 | protected function insertIntoDB() { |
178 | | - $dbr = wfGetDB( DB_MASTER ); |
| 202 | + $dbw = wfGetDB( DB_MASTER ); |
179 | 203 | |
180 | | - $result = $dbr->insert( |
| 204 | + $success = $dbw->insert( |
181 | 205 | 'surveys', |
182 | 206 | $this->getWriteValues() |
183 | 207 | ); |
184 | 208 | |
185 | | - $this->id = $dbr->insertId(); |
| 209 | + $this->id = $dbw->insertId(); |
186 | 210 | |
187 | | - return $result; |
| 211 | + return $success; |
188 | 212 | } |
189 | 213 | |
190 | 214 | /** |
Index: trunk/extensions/Survey/includes/SurveyQuestion.php |
— | — | @@ -56,6 +56,16 @@ |
57 | 57 | protected $answers; |
58 | 58 | |
59 | 59 | /** |
| 60 | + * Indicated if the question was removed. |
| 61 | + * Removed questions are kept in the db so their answers can |
| 62 | + * still be used untill the survey itself gets removed. |
| 63 | + * |
| 64 | + * @since 0.1 |
| 65 | + * @var boolean |
| 66 | + */ |
| 67 | + protected $removed; |
| 68 | + |
| 69 | + /** |
60 | 70 | * Constructor. |
61 | 71 | * |
62 | 72 | * @since 0.1 |
— | — | @@ -65,16 +75,65 @@ |
66 | 76 | * @param integer $type |
67 | 77 | * @param boolean $required |
68 | 78 | * @param array $answers |
| 79 | + * @param boolean $removed |
69 | 80 | */ |
70 | | - public function __construct( $id, $text, $type, $required, array $answers = array() ) { |
| 81 | + public function __construct( $id, $text, $type, $required, array $answers = array(), $removed = false ) { |
71 | 82 | $this->id = $id; |
72 | 83 | $this->text = $text; |
73 | 84 | $this->type = $type; |
74 | 85 | $this->required = $required; |
75 | 86 | $this->answers = $answers; |
| 87 | + $this->removed = $removed; |
76 | 88 | } |
77 | 89 | |
78 | 90 | /** |
| 91 | + * Unserialization method for survey question data passed as a multi-value API parameter. |
| 92 | + * Uses base64 and replaces padding = by !, so the values does not contain any = or |. |
| 93 | + * |
| 94 | + * @since 0.1 |
| 95 | + * |
| 96 | + * @param string $args |
| 97 | + * |
| 98 | + * @return SurveyQuestion |
| 99 | + */ |
| 100 | + public static function newFromUrlData( $args ) { |
| 101 | + $args = (array)FormatJson::decode( base64_decode( str_replace( '!', '=', $args ) ) ); |
| 102 | + |
| 103 | + return new self( |
| 104 | + array_key_exists( 'id', $args ) ? $args['id'] : null, |
| 105 | + $args['text'], |
| 106 | + $args['type'], |
| 107 | + $args['required'], |
| 108 | + $args['answers'], |
| 109 | + $args['removed'] |
| 110 | + ); |
| 111 | + } |
| 112 | + |
| 113 | + /** |
| 114 | + * Serialization method for survey questions that need to be passed via multi-value API parameter. |
| 115 | + * Uses base64 and replaces padding = by !, so the values does not contain any = or |. |
| 116 | + * |
| 117 | + * @since 0.1 |
| 118 | + * |
| 119 | + * @return string |
| 120 | + */ |
| 121 | + public function toUrlData() { |
| 122 | + $args = array( |
| 123 | + 'text' => $this->text, |
| 124 | + 'type' => $this->type, |
| 125 | + 'required' => $this->required, |
| 126 | + 'answers' => $this->answers, |
| 127 | + 'removed' => $this->removed, |
| 128 | + ); |
| 129 | + |
| 130 | + if ( !is_null( $this->id ) ) { |
| 131 | + $args['id'] = $this->id; |
| 132 | + } |
| 133 | + |
| 134 | + return str_replace( '=', '!', base64_encode( FormatJson::encode( $args ) ) ); |
| 135 | + } |
| 136 | + |
| 137 | + /** |
79 | 138 | * Returns the questions for the specified survey. |
80 | 139 | * |
81 | 140 | * @since 0.1 |
— | — | @@ -134,14 +193,16 @@ |
135 | 194 | * |
136 | 195 | * @since 0.1 |
137 | 196 | * |
| 197 | + * @param integer $surveyId |
| 198 | + * |
138 | 199 | * @return boolean Success indicator |
139 | 200 | */ |
140 | | - public function writeToDB() { |
| 201 | + public function writeToDB( $surveyId ) { |
141 | 202 | if ( is_null( $this->id ) ) { |
142 | | - return $this->insertIntoDB(); |
| 203 | + return $this->insertIntoDB( $surveyId ); |
143 | 204 | } |
144 | 205 | else { |
145 | | - return $this->updateInDB(); |
| 206 | + return $this->updateInDB( $surveyId ); |
146 | 207 | } |
147 | 208 | } |
148 | 209 | |
— | — | @@ -150,14 +211,16 @@ |
151 | 212 | * |
152 | 213 | * @since 0.1 |
153 | 214 | * |
| 215 | + * @param integer $surveyId |
| 216 | + * |
154 | 217 | * @return boolean Success indicator |
155 | 218 | */ |
156 | | - protected function updateInDB() { |
| 219 | + protected function updateInDB( $surveyId ) { |
157 | 220 | $dbr = wfGetDB( DB_MASTER ); |
158 | 221 | |
159 | 222 | return $dbr->update( |
160 | 223 | 'survey_questions', |
161 | | - $this->getWriteValues(), |
| 224 | + $this->getWriteValues( $surveyId ), |
162 | 225 | array( 'question_id' => $this->id ) |
163 | 226 | ); |
164 | 227 | } |
— | — | @@ -167,14 +230,16 @@ |
168 | 231 | * |
169 | 232 | * @since 0.1 |
170 | 233 | * |
| 234 | + * @param integer $surveyId |
| 235 | + * |
171 | 236 | * @return boolean Success indicator |
172 | 237 | */ |
173 | | - protected function insertIntoDB() { |
| 238 | + protected function insertIntoDB( $surveyId ) { |
174 | 239 | $dbr = wfGetDB( DB_MASTER ); |
175 | 240 | |
176 | 241 | $result = $dbr->insert( |
177 | 242 | 'survey_questions', |
178 | | - $this->getWriteValues() |
| 243 | + $this->getWriteValues( $surveyId ) |
179 | 244 | ); |
180 | 245 | |
181 | 246 | $this->id = $dbr->insertId(); |
— | — | @@ -187,10 +252,13 @@ |
188 | 253 | * |
189 | 254 | * @since 0.1 |
190 | 255 | * |
| 256 | + * @param integer $surveyId |
| 257 | + * |
191 | 258 | * @return array |
192 | 259 | */ |
193 | | - protected function getWriteValues() { |
| 260 | + protected function getWriteValues( $surveyId ) { |
194 | 261 | return array( |
| 262 | + 'question_survey_id' => $surveyId, |
195 | 263 | 'question_text' => $this->text, |
196 | 264 | 'question_type' => $this->type, |
197 | 265 | 'question_required' => $this->required, |
Index: trunk/extensions/Survey/api/ApiEditSurvey.php |
— | — | @@ -27,26 +27,83 @@ |
28 | 28 | |
29 | 29 | $params = $this->extractRequestParams(); |
30 | 30 | |
| 31 | +// $q = new SurveyQuestion(null, 'new q', 1, false); |
| 32 | +// var_dump($q->toUrlData());exit; |
| 33 | + // eyJ0ZXh0IjoibmV3IHEiLCJ0eXBlIjoxLCJyZXF1aXJlZCI6ZmFsc2UsImFuc3dlcnMiOltdfQ!! |
| 34 | + |
| 35 | + foreach ( $params['questions'] as &$question ) { |
| 36 | + $question = SurveyQuestion::newFromUrlData( $question ); |
| 37 | + } |
| 38 | + |
| 39 | + $survey = new Survey( |
| 40 | + $params['id'], |
| 41 | + $params['name'], |
| 42 | + $params['enabled'] == 1, |
| 43 | + $params['questions'] |
| 44 | + ); |
| 45 | + |
| 46 | + $this->getResult()->addValue( |
| 47 | + null, |
| 48 | + 'success', |
| 49 | + $survey->writeToDB() |
| 50 | + ); |
| 51 | + |
| 52 | + $this->getResult()->addValue( |
| 53 | + 'survey', |
| 54 | + 'id', |
| 55 | + $survey->getId() |
| 56 | + ); |
| 57 | + |
| 58 | + $this->getResult()->addValue( |
| 59 | + 'survey', |
| 60 | + 'name', |
| 61 | + $survey->getName() |
| 62 | + ); |
31 | 63 | } |
32 | 64 | |
33 | 65 | public function getAllowedParams() { |
34 | 66 | return array( |
| 67 | + 'id' => array( |
| 68 | + ApiBase::PARAM_TYPE => 'integer', |
| 69 | + ApiBase::PARAM_REQUIRED => true, |
| 70 | + ), |
| 71 | + 'name' => array( |
| 72 | + ApiBase::PARAM_TYPE => 'string', |
| 73 | + ApiBase::PARAM_REQUIRED => true, |
| 74 | + ), |
| 75 | + 'enabled' => array( |
| 76 | + ApiBase::PARAM_TYPE => 'integer', |
| 77 | + ApiBase::PARAM_REQUIRED => true, |
| 78 | + ), |
| 79 | + 'questions' => array( |
| 80 | + ApiBase::PARAM_TYPE => 'string', |
| 81 | + ApiBase::PARAM_ISMULTI => true, |
| 82 | + ApiBase::PARAM_REQUIRED => true, |
| 83 | + ), |
35 | 84 | ); |
36 | 85 | } |
37 | 86 | |
38 | 87 | public function getParamDescription() { |
39 | 88 | return array( |
| 89 | + 'id' => 'The ID of the survey to modify', |
| 90 | + 'name' => 'The name of the survey', |
| 91 | + 'enabled' => 'Enable the survey or not', |
| 92 | + 'questions' => 'The questions that make up the survey', |
40 | 93 | ); |
41 | 94 | } |
42 | 95 | |
43 | 96 | public function getDescription() { |
44 | 97 | return array( |
45 | | - '' |
| 98 | + 'API module for editing a survey.' |
46 | 99 | ); |
47 | 100 | } |
48 | 101 | |
49 | 102 | public function getPossibleErrors() { |
50 | 103 | return array_merge( parent::getPossibleErrors(), array( |
| 104 | + array( 'missingparam', 'id' ), |
| 105 | + array( 'missingparam', 'name' ), |
| 106 | + array( 'missingparam', 'enabled' ), |
| 107 | + array( 'missingparam', 'questions' ), |
51 | 108 | ) ); |
52 | 109 | } |
53 | 110 | |
Index: trunk/extensions/Survey/api/ApiAddSurvey.php |
— | — | @@ -27,11 +27,15 @@ |
28 | 28 | |
29 | 29 | $params = $this->extractRequestParams(); |
30 | 30 | |
| 31 | + foreach ( $params['questions'] as &$question ) { |
| 32 | + $question = SurveyQuestion::newFromUrlData( $question ); |
| 33 | + } |
| 34 | + |
31 | 35 | $survey = new Survey( |
32 | 36 | null, |
33 | 37 | $params['name'], |
34 | 38 | $params['enabled'] == 1, |
35 | | - $params['questions'] // TODO |
| 39 | + $params['questions'] |
36 | 40 | ); |
37 | 41 | |
38 | 42 | $this->getResult()->addValue( |
Index: trunk/extensions/Survey/Survey.sql |
— | — | @@ -16,7 +16,8 @@ |
17 | 17 | question_text TEXT NOT NULL, |
18 | 18 | question_type INT(2) unsigned NOT NULL, |
19 | 19 | question_required INT(2) unsigned NOT NULL, |
20 | | - question_answers BLOB NOT NULL |
| 20 | + question_answers BLOB NOT NULL, |
| 21 | + question_removed TINYINT NOT NULL default '0' |
21 | 22 | ) /*$wgDBTableOptions*/; |
22 | 23 | |
23 | 24 | -- Submissions |