r106405 MediaWiki - Code Review archive

Repository:MediaWiki
Revision:r106404‎ | r106405 | r106406 >
Date:03:12, 16 December 2011
Author:jeroendedauw
Status:ok
Tags:
Comment:
follow up to r106404 - created base class for form pages taking away most of the work utilizing the epdbobject class
Modified paths:
  • /trunk/extensions/EducationProgram/specials/SpecialEPFormPage.php (modified) (history)
  • /trunk/extensions/EducationProgram/specials/SpecialEditInstitution.php (modified) (history)

Diff [purge]

Index: trunk/extensions/EducationProgram/specials/SpecialEditInstitution.php
@@ -23,283 +23,36 @@
2424 }
2525
2626 /**
27 - * Attempt to get the contest to be edited or create the one to be added.
28 - * If this works, show the form, if not, redirect to special:contests.
29 - *
30 - * @since 0.1
31 - */
32 - protected function showContent() {
33 - if ( $this->isNew() ) {
34 - $conditions = array( 'name' => $this->getRequest()->getVal( 'neworg' ) );
35 -
36 - $contest = Contest::s()->selectRow( null, $conditions );
37 -
38 - if ( $contest === false ) {
39 - $contest = new Contest( $conditions, true );
40 - }
41 - else {
42 - $this->showWarning( 'contest-edit-exists-already' );
43 - }
44 - }
45 - else {
46 - $contest = Contest::s()->selectRow( null, array( 'name' => $this->subPage ) );
47 - }
48 -
49 - if ( $contest === false ) {
50 - $this->getOutput()->redirect( SpecialPage::getTitleFor( 'Contests' )->getLocalURL() );
51 - }
52 - else {
53 - if ( !$this->isNew() ) {
54 - $this->getOutput()->addHTML(
55 - SpecialContestPage::getNavigation( $contest->getField( 'name' ), $this->getUser(), $this->getLanguage(), $this->getName() )
56 - );
57 - }
58 -
59 - $this->contest = $contest;
60 - $this->showForm();
61 - $this->getOutput()->addModules( 'contest.special.editcontest' );
62 - }
63 - }
64 -
65 - /**
6627 * (non-PHPdoc)
67 - * @see FormSpecialPage::getFormFields()
 28+ * @see SpecialEPFormPage::getFormFields()
6829 * @return array
6930 */
7031 protected function getFormFields() {
 32+ $fields = parent::getFormFields();
7133
72 - /**
73 - * @var $contest Contest
74 - */
75 - $contest = $this->contest;
76 -
77 - $fields = array();
78 -
79 - $fields['id'] = array ( 'type' => 'hidden' );
80 -
8134 $fields['name'] = array (
8235 'type' => 'text',
83 - 'label-message' => 'contest-edit-name',
84 - 'id' => 'contest-name-field',
 36+ 'label-message' => 'educationprogram-org-edit-name',
 37+ 'id' => 'org-name-field',
8538 );
8639
87 - $fields['status'] = array (
88 - 'type' => 'radio',
89 - 'label-message' => 'contest-edit-status',
90 - 'options' => Contest::getStatusMessages( true )
91 - );
92 -
93 - $fields['intro'] = array (
94 - 'type' => 'text',
95 - 'label-message' => 'contest-edit-intro',
96 - );
97 -
98 - $fields['opportunities'] = array (
99 - 'type' => 'text',
100 - 'label-message' => 'contest-edit-opportunities',
101 - );
102 -
103 - $fields['rules_page'] = array (
104 - 'type' => 'text',
105 - 'label-message' => 'contest-edit-rulespage',
106 - );
107 -
108 - $fields['help'] = array (
109 - 'type' => 'text',
110 - 'label-message' => 'contest-edit-help',
111 - );
112 -
113 - $fields['signup_email'] = array (
114 - 'type' => 'text',
115 - 'label-message' => 'contest-edit-signup',
116 - );
117 -
118 - $fields['reminder_email'] = array (
119 - 'type' => 'text',
120 - 'label-message' => 'contest-edit-reminder',
121 - );
122 -
123 - $fields['end'] = array (
124 - 'type' => 'text',
125 - 'label-message' => 'contest-edit-end',
126 - 'id' => 'contest-edit-end',
127 - 'size' => 15
128 - );
129 -
130 - if ( $contest !== false ) {
131 - foreach ( $fields as $name => $data ) {
132 - $default = $contest->getField( $name );
133 -
134 - if ( $name == 'end' ) {
135 - $default = wfTimestamp( TS_DB, $default );
136 - }
137 -
138 - $fields[$name]['default'] = $default;
139 - }
140 - }
141 -
142 - $mappedFields = array();
143 -
144 - foreach ( $fields as $name => $field ) {
145 - $mappedFields['contest-' . $name] = $field;
146 - }
147 -
148 - if ( $contest !== false ) {
149 - foreach ( $contest->getChallenges() as /* ContestChallenge */ $challenge ) {
150 - $mappedFields[] = array(
151 - 'class' => 'ContestChallengeField',
152 - 'options' => $challenge->toArray()
153 - );
154 - }
155 - }
156 -
157 - $mappedFields['delete-challenges'] = array ( 'type' => 'hidden', 'id' => 'delete-challenges' );
158 -
159 - return $mappedFields;
 40+ return $this->processFormFields( $fields );
16041 }
161 -
 42+
16243 /**
163 - * Process the form. At this point we know that the user passes all the criteria in
164 - * userCanExecute(), and if the data array contains 'Username', etc, then Username
165 - * resets are allowed.
166 - *
167 - * @param array $data
168 - *
169 - * @return Bool|Array
 44+ * (non-PHPdoc)
 45+ * @see SpecialEPFormPage::getListPage()
17046 */
171 - public function onSubmit( array $data ) {
172 - $fields = array();
173 -
174 - foreach ( $data as $name => $value ) {
175 - $matches = array();
176 -
177 - if ( preg_match( '/contest-(.+)/', $name, $matches ) ) {
178 - if ( $matches[1] == 'end' ) {
179 - $value = wfTimestamp( TS_MW, strtotime( $value ) );
180 - }
181 -
182 - $fields[$matches[1]] = $value;
183 - }
184 - }
185 -
186 - // If no ID is set, this means it's a new contest, so set the ID to null for an insert.
187 - // However, the user can have hot the back button after creation of a new contest,
188 - // re-submitting the form. In this case, get the ID of the already existing item for an update.
189 - if ( !array_key_exists( 'id', $fields ) || $fields['id'] === '' ) {
190 - $contest = Contest::s()->selectRow( 'id', array( 'name' => $fields['name'] ) );
191 - $fields['id'] = $contest === false ? null : $contest->getField( 'id' );
192 - }
193 -
194 - $contest = new Contest( $fields, is_null( $fields['id'] ) );
195 -
196 - $contest->setChallenges( $this->getSubmittedChallenges() );
197 - $success = $contest->writeAllToDB();
198 -
199 - $success = $this->removeDeletedChallenges( $data['delete-challenges'] ) && $success;
200 -
201 - if ( $success ) {
202 - return true;
203 - }
204 - else {
205 - return array(); // TODO
206 - }
 47+ protected function getListPage() {
 48+ return 'Institutions';
20749 }
208 -
 50+
20951 /**
210 - * The UI keeps track of 'removed' challenges by storing them into a
211 - * hidden HTML input, pipe-separated. On submission, this method
212 - * takes this string and actually deletes them.
213 - *
214 - * @since 0.1
215 - *
216 - * @param string $idString
217 - *
218 - * @return boolean Success indicator
 52+ * (non-PHPdoc)
 53+ * @see SpecialEPFormPage::getListPage()
21954 */
220 - protected function removeDeletedChallenges( $idString ) {
221 - if ( $idString == '' ) {
222 - return true;
223 - }
224 -
225 - if ( !ContestSettings::get( 'contestDeletionEnabled' ) ) {
226 - // Shouldn't get here (UI should prevent it)
227 - throw new MWException( 'Contest deletion is disabled', 'contestdeletiondisabled' );
228 - }
229 -
230 - return ContestChallenge::s()->delete( array( 'id' => explode( '|', $idString ) ) );
 55+ protected function getObjectClassName() {
 56+ return 'EPOrg';
23157 }
23258
233 - /**
234 - * Finds the submitted challanges and returns them as a list of
235 - * ContestChallenge objects.
236 - *
237 - * @since 0.1
238 - *
239 - * @return array of ContestChallenge
240 - */
241 - protected function getSubmittedChallenges() {
242 - $challenges = array();
243 -
244 - foreach ( $this->getrequest()->getValues() as $name => $value ) {
245 - $matches = array();
246 -
247 - if ( preg_match( '/contest-challenge-(\d+)/', $name, $matches ) ) {
248 - $challenges[] = $this->getSubmittedChallenge( $matches[1] );
249 - } elseif ( preg_match( '/contest-challenge-new-(\d+)/', $name, $matches ) ) {
250 - $challenges[] = $this->getSubmittedChallenge( $matches[1], true );
251 - }
252 - }
253 -
254 - return $challenges;
255 - }
256 -
257 - /**
258 - * Create and return a contest challenge object from the submitted data.
259 - *
260 - * @since 0.1
261 - *
262 - * @param integer|null $challengeId
263 - *
264 - * @return ContestChallenge
265 - */
266 - protected function getSubmittedChallenge( $challengeId, $isNewChallenge = false ) {
267 - if ( $isNewChallenge ) {
268 - $challengeDbId = null;
269 - $challengeId = "new-$challengeId";
270 - } else {
271 - $challengeDbId = $challengeId;
272 - }
273 -
274 - $request = $this->getRequest();
275 -
276 - return new ContestChallenge( array(
277 - 'id' => $challengeDbId,
278 - 'text' => $request->getText( "challenge-text-$challengeId" ),
279 - 'title' => $request->getText( "contest-challenge-$challengeId" ),
280 - 'oneline' => $request->getText( "challenge-oneline-$challengeId" ),
281 - ) );
282 - }
283 -
284 - /**
285 - * Gets called after the form is saved.
286 - * Enter description here ...
287 - */
288 - public function onSuccess() {
289 - $this->getOutput()->redirect( SpecialPage::getTitleFor( 'Institutions' )->getLocalURL() );
290 - }
291 -
292 - /**
293 - * Show a message in a warning box.
294 - *
295 - * @since 0.1
296 - *
297 - * @param string $message
298 - */
299 - protected function showWarning( $message ) {
300 - $this->getOutput()->addHTML(
301 - '<p class="visualClear warningbox">' . wfMsgExt( $message, 'parseinline' ) . '</p>'
302 - . '<hr style="display: block; clear: both; visibility: hidden;" />'
303 - );
304 - }
305 -
30659 }
Index: trunk/extensions/EducationProgram/specials/SpecialEPFormPage.php
@@ -20,9 +20,35 @@
2121 * @since 0.1
2222 * @var string
2323 */
24 - public $subPage;
 24+ protected $subPage;
2525
2626 /**
 27+ * Instance of the object being edited or created.
 28+ *
 29+ * @since 0.1
 30+ * @var EPDBObject|false
 31+ */
 32+ protected $item;
 33+
 34+ /**
 35+ * Returns the name of the EPDBObject deriving class this page edits or creates.
 36+ *
 37+ * @since 0.1
 38+ *
 39+ * @return string
 40+ */
 41+ protected abstract function getObjectClassName();
 42+
 43+ /**
 44+ * Gets the name of the list page corresponding to this edit page.
 45+ *
 46+ * @since 0.1
 47+ *
 48+ * @return string
 49+ */
 50+ protected abstract function getListPage();
 51+
 52+ /**
2753 * @see SpecialPage::getDescription
2854 *
2955 * @since 0.1
@@ -70,8 +96,11 @@
7197 }
7298
7399 /**
 100+ * Returns if the page should work in insertion mode rather then modification mode.
74101 *
75 - * Enter description here ...
 102+ * @since 0.1
 103+ *
 104+ * @return boolean
76105 */
77106 protected function isNew() {
78107 return $this->getRequest()->wasPosted() && $this->getUser()->matchEditToken( $this->getRequest()->getVal( 'wpEditToken' ) );
@@ -89,7 +118,60 @@
90119 $this->onSuccess();
91120 }
92121 }
 122+
 123+ /**
 124+ * Returns the data to use as condition for selecting the object,
 125+ * or in case nothing matches the selection, the data to initialize
 126+ * it with. This is typically an identifier such as name or id.
 127+ *
 128+ * @since 0.1
 129+ *
 130+ * @return array
 131+ */
 132+ protected function getNewData() {
 133+ return array( 'name' => $this->getRequest()->getVal( 'newname' ) );
 134+ }
 135+
 136+ /**
 137+ * Attempt to get the contest to be edited or create the one to be added.
 138+ * If this works, show the form, if not, redirect to special:contests.
 139+ *
 140+ * @since 0.1
 141+ */
 142+ protected function showContent() {
 143+ $c = $this->getObjectClassName();
 144+
 145+ if ( $this->isNew() ) {
 146+ $data = $this->getNewData();
93147
 148+ $object = $c::selectRow( null, $data );
 149+
 150+ if ( $object === false ) {
 151+ $object = new Contest( $data, true );
 152+ }
 153+ else {
 154+ $this->showWarning( 'educationprogram-' . strtolower( $this->getName() ) . '-exists-already' );
 155+ }
 156+ }
 157+ else {
 158+ $object = $c::selectRow( null, array( 'name' => $this->subPage ) );
 159+ }
 160+
 161+ if ( $object === false ) {
 162+ $this->getOutput()->redirect( SpecialPage::getTitleFor( $this->getListPage() )->getLocalURL() );
 163+ }
 164+ else {
 165+// if ( !$this->isNew() ) {
 166+// $this->getOutput()->addHTML(
 167+// SpecialContestPage::getNavigation( $contest->getField( 'name' ), $this->getUser(), $this->getLanguage(), $this->getName() )
 168+// );
 169+// }
 170+
 171+ $this->item = $object;
 172+ $this->showForm();
 173+ }
 174+ }
 175+
94176 /**
95177 * (non-PHPdoc)
96178 * @see FormSpecialPage::getForm()
@@ -103,7 +185,7 @@
104186 wfMsg( 'cancel' ),
105187 'cancelEdit',
106188 array(
107 - 'target-url' => SpecialPage::getTitleFor( 'Contests' )->getFullURL()
 189+ 'target-url' => SpecialPage::getTitleFor( $this->getListPage() )->getFullURL()
108190 )
109191 );
110192
@@ -115,8 +197,46 @@
116198
117199 return $form;
118200 }
 201+
 202+ /**
 203+ * (non-PHPdoc)
 204+ * @see FormSpecialPage::getFormFields()
 205+ * @return array
 206+ */
 207+ protected function getFormFields() {
 208+ $fields = array();
119209
 210+ $fields['id'] = array ( 'type' => 'hidden' );
 211+
 212+ return $fields;
 213+ }
 214+
120215 /**
 216+ * Populates the form fields with the data of the item
 217+ * and prefixes their names.
 218+ *
 219+ * @since 0.1
 220+ *
 221+ * @param array $fields
 222+ */
 223+ protected function processFormFields( array $fields ) {
 224+ if ( $this->item !== false ) {
 225+ foreach ( $fields as $name => $data ) {
 226+ $default = $this->item->getField( $name );
 227+ $fields[$name]['default'] = $default;
 228+ }
 229+ }
 230+
 231+ $mappedFields = array();
 232+
 233+ foreach ( $fields as $name => $field ) {
 234+ $mappedFields['item-' . $name] = $field;
 235+ }
 236+
 237+ return $mappedFields;
 238+ }
 239+
 240+ /**
121241 * Show a message in a warning box.
122242 *
123243 * @since 0.1
@@ -131,5 +251,47 @@
132252 . '<hr style="display: block; clear: both; visibility: hidden;" />'
133253 );
134254 }
 255+
 256+ /**
 257+ * Gets called after the form is saved.
 258+ *
 259+ * @since 0.1
 260+ */
 261+ public function onSuccess() {
 262+ $this->getOutput()->redirect( SpecialPage::getTitleFor( $this->getListPage() )->getLocalURL() );
 263+ }
 264+
 265+ /**
 266+ * Process the form. At this point we know that the user passes all the criteria in
 267+ * userCanExecute(), and if the data array contains 'Username', etc, then Username
 268+ * resets are allowed.
 269+ *
 270+ * @param array $data
 271+ *
 272+ * @return Bool|Array
 273+ */
 274+ public function onSubmit( array $data ) {
 275+ $fields = array();
135276
 277+ foreach ( $data as $name => $value ) {
 278+ $matches = array();
 279+
 280+ if ( preg_match( '/item-(.+)/', $name, $matches ) ) {
 281+ $fields[$matches[1]] = $value;
 282+ }
 283+ }
 284+
 285+ $c = $this->getObjectClassName();
 286+ $item = new $c( $fields, is_null( $fields['id'] ) );
 287+
 288+ $success = $item->writeAllToDB();
 289+
 290+ if ( $success ) {
 291+ return true;
 292+ }
 293+ else {
 294+ return array(); // TODO
 295+ }
 296+ }
 297+
136298 }

Follow-up revisions

RevisionCommit summaryAuthorDate
r106407follow up to r106404 r106405 - cleanup and fixesjeroendedauw03:34, 16 December 2011

Past revisions this follows-up on

RevisionCommit summaryAuthorDate
r106404unfinished code, will follow up soonish, from other devicejeroendedauw02:24, 16 December 2011

Status & tagging log