Index: trunk/extensions/FlaggedRevs/forms/FlaggedRevsConfigForm.php |
— | — | @@ -6,7 +6,9 @@ |
7 | 7 | /** |
8 | 8 | * Class containing stability settings form business logic |
9 | 9 | * |
10 | | - * Note: handleParams() must be called after the user parameters are set |
| 10 | + * Usage: (a) set ALL form params before doing anything else |
| 11 | + * (b) call ready() when all params are set |
| 12 | + * (c) check isAllowed() before calling submit() as needed |
11 | 13 | */ |
12 | 14 | abstract class FlaggedRevsConfigForm |
13 | 15 | { |
— | — | @@ -20,14 +22,12 @@ |
21 | 23 | protected $expirySelection = ''; # Expiry dropdown key |
22 | 24 | protected $override = -1; # Default version |
23 | 25 | protected $autoreview = ''; # Autoreview restrictions... |
24 | | - protected $wasPosted = false; # POST request? |
25 | 26 | |
26 | 27 | protected $page = false; # Target page obj (of $target) |
27 | 28 | protected $oldConfig = array(); # Old page config |
28 | 29 | protected $oldExpiry = ''; # Old page config expiry (GMT) |
29 | | - protected $isAllowed = null; # $wgUser can submit? |
30 | 30 | |
31 | | - protected $submitLock = 1; # Disallow bad submissions |
| 31 | + protected $inputLock = 0; # Disallow bad submissions |
32 | 32 | |
33 | 33 | public function getTarget() { |
34 | 34 | return $this->target; |
— | — | @@ -35,6 +35,7 @@ |
36 | 36 | |
37 | 37 | public function setTarget( $value ) { |
38 | 38 | $this->trySet( $this->target, $value ); |
| 39 | + $this->page = Title::newFromURL( $this->target ); |
39 | 40 | } |
40 | 41 | |
41 | 42 | public function getWatchThis() { |
— | — | @@ -85,90 +86,122 @@ |
86 | 87 | $this->trySet( $this->autoreview, $value ); |
87 | 88 | } |
88 | 89 | |
89 | | - public function setWasPosted( $value ) { |
90 | | - $this->trySet( $this->wasPosted, $value ); |
91 | | - } |
92 | | - |
93 | 90 | /** |
94 | 91 | * Set a member field to a value if the fields are unlocked |
95 | 92 | */ |
96 | 93 | protected function trySet( &$field, $value ) { |
97 | | - if ( $this->submitLock ) { |
| 94 | + if ( $this->inputLock ) { |
| 95 | + throw new MWException( "FlaggedRevsConfigForm fields cannot be set anymore.\n"); |
| 96 | + } else { |
98 | 97 | $field = $value; // submission locked => still allowing input |
99 | | - } else { |
100 | | - throw new MWException( "FlaggedRevsConfigForm fields cannot be set after validation.\n"); |
| 98 | + } |
| 99 | + } |
| 100 | + |
| 101 | + /** |
| 102 | + * Signal that inputs are starting |
| 103 | + */ |
| 104 | + public function start() { |
| 105 | + $this->inputLock = 0; |
| 106 | + } |
| 107 | + |
| 108 | + /** |
| 109 | + * Signal that inputs are done and load old config |
| 110 | + * @return mixed (true on success, error string on target failure) |
| 111 | + */ |
| 112 | + public function ready() { |
| 113 | + $this->inputLock = 1; |
| 114 | + $status = $this->checkTarget(); |
| 115 | + if ( $status !== true ) { |
| 116 | + return $status; // bad target |
101 | 117 | } |
| 118 | + $this->loadOldConfig(); // current settings from DB |
| 119 | + return $status; |
102 | 120 | } |
103 | 121 | |
104 | | - /** |
105 | | - * Verify and clean up parameters and preload data from DB. |
106 | | - * Locks the member fields from being set. |
107 | | - * |
108 | | - * Note: some items may not all be set on failure. |
| 122 | + /* |
| 123 | + * Preload existing page settings (e.g. from GET request). |
109 | 124 | * @return mixed (true on success, error string on failure) |
110 | 125 | */ |
111 | | - public function handleParams() { |
112 | | - $this->page = Title::newFromURL( $this->target ); |
113 | | - if ( is_null( $this->page ) ) { |
114 | | - return 'stabilize_page_invalid'; // page title is invalid |
115 | | - } elseif ( !$this->page->exists() ) { |
116 | | - return 'stabilize_page_notexists'; // page must exist |
117 | | - } elseif ( !FlaggedRevs::inReviewNamespace( $this->page ) ) { |
118 | | - return 'stabilize_page_unreviewable'; |
| 126 | + public function preloadSettings() { |
| 127 | + if ( !$this->inputLock ) { |
| 128 | + throw new MWException( "FlaggedRevsConfigForm input fields not set yet.\n"); |
119 | 129 | } |
120 | | - # Get the current page config and GMT expiry |
121 | | - $this->oldConfig = FlaggedRevs::getPageVisibilitySettings( $this->page, FR_MASTER ); |
122 | | - $this->oldExpiry = $this->oldConfig['expiry'] === 'infinity' |
123 | | - ? 'infinite' |
124 | | - : wfTimestamp( TS_RFC2822, $this->oldConfig['expiry'] ); |
125 | | - # Handle views (GET) |
126 | | - if ( !$this->wasPosted ) { |
127 | | - # Fill in existing settings |
128 | | - $ok = $this->preloadSettings(); |
129 | | - # Handle submission data (POST) |
130 | | - } else { |
131 | | - $ok = $this->handlePostedParams(); |
| 130 | + $status = $this->checkTarget(); |
| 131 | + if ( $status !== true ) { |
| 132 | + return $status; // bad target |
132 | 133 | } |
133 | | - if ( $ok === true && $this->wasPosted ) { |
134 | | - $this->submitLock = 0; // allow calling of submit() |
| 134 | + return $this->reallyPreloadSettings(); // load the params... |
| 135 | + } |
| 136 | + |
| 137 | + /* |
| 138 | + * @return mixed (true on success, error string on failure) |
| 139 | + */ |
| 140 | + protected function reallyPreloadSettings() { |
| 141 | + return true; |
| 142 | + } |
| 143 | + |
| 144 | + /* |
| 145 | + * Verify and clean up parameters (e.g. from POST request). |
| 146 | + * @return mixed (true on success, error string on failure) |
| 147 | + */ |
| 148 | + protected function checkSettings() { |
| 149 | + $status = $this->checkTarget(); |
| 150 | + if ( $status !== true ) { |
| 151 | + return $status; // bad target |
135 | 152 | } |
136 | | - return $ok; |
| 153 | + $status = $this->reallyCheckSettings(); // check other params... |
| 154 | + return $status; |
137 | 155 | } |
138 | 156 | |
139 | 157 | /* |
140 | | - * Preload existing page settings |
141 | 158 | * @return mixed (true on success, error string on failure) |
142 | 159 | */ |
143 | | - protected function preloadSettings() { |
| 160 | + protected function reallyCheckSettings() { |
144 | 161 | return true; |
145 | 162 | } |
146 | 163 | |
147 | 164 | /* |
148 | | - * Verify and clean up parameters from POST request. |
| 165 | + * Check that the target page is valid |
149 | 166 | * @return mixed (true on success, error string on failure) |
150 | 167 | */ |
151 | | - protected function handlePostedParams() { |
| 168 | + protected function checkTarget() { |
| 169 | + $this->page = Title::newFromURL( $this->target ); |
| 170 | + if ( is_null( $this->page ) ) { |
| 171 | + return 'stabilize_page_invalid'; |
| 172 | + } elseif ( !$this->page->exists() ) { |
| 173 | + return 'stabilize_page_notexists'; |
| 174 | + } elseif ( !FlaggedRevs::inReviewNamespace( $this->page ) ) { |
| 175 | + return 'stabilize_page_unreviewable'; |
| 176 | + } |
152 | 177 | return true; |
153 | 178 | } |
154 | 179 | |
| 180 | + protected function loadOldConfig() { |
| 181 | + # Get the current page config and GMT expiry |
| 182 | + $this->oldConfig = FlaggedRevs::getPageVisibilitySettings( $this->page, FR_MASTER ); |
| 183 | + $this->oldExpiry = $this->oldConfig['expiry'] === 'infinity' |
| 184 | + ? 'infinite' |
| 185 | + : wfTimestamp( TS_RFC2822, $this->oldConfig['expiry'] ); |
| 186 | + } |
| 187 | + |
155 | 188 | /* |
156 | 189 | * Gets the target page Obj |
157 | 190 | * @return mixed (Title or null) |
158 | 191 | */ |
159 | 192 | public function getPage() { |
160 | | - if ( $this->page === false ) { |
161 | | - $this->handleParams(); // handleParams() not called first |
| 193 | + if ( !$this->inputLock ) { |
| 194 | + throw new MWException( "FlaggedRevsConfigForm input fields not set yet.\n"); |
162 | 195 | } |
163 | 196 | return $this->page; |
164 | | - } |
| 197 | + } |
165 | 198 | |
166 | 199 | /* |
167 | 200 | * Gets the current config expiry in GMT (or 'infinite') |
168 | 201 | * @return string |
169 | 202 | */ |
170 | 203 | public function getOldExpiryGMT() { |
171 | | - if ( $this->page === false ) { |
172 | | - $this->handleParams(); // handleParams() not called first |
| 204 | + if ( !$this->inputLock ) { |
| 205 | + throw new MWException( "FlaggedRevsConfigForm input fields not set yet.\n"); |
173 | 206 | } |
174 | 207 | return $this->oldExpiry; |
175 | 208 | } |
— | — | @@ -176,35 +209,33 @@ |
177 | 210 | /* |
178 | 211 | * Can the user change the settings for this page? |
179 | 212 | * Note: if the current autoreview restriction is too high for this user |
180 | | - * then this will return false. Use for form selectors. |
| 213 | + * then this will return false. Useful for form selectors. |
181 | 214 | * @return bool |
182 | 215 | */ |
183 | 216 | public function isAllowed() { |
184 | | - if ( $this->page === false ) { |
185 | | - $this->handleParams(); // handleParams() not called first |
186 | | - } |
187 | | - if ( $this->isAllowed === null ) { |
188 | | - # Users who cannot edit or review the page cannot set this |
189 | | - $this->isAllowed = ( $this->page |
190 | | - && $this->page->userCan( 'stablesettings' ) |
191 | | - && $this->page->userCan( 'edit' ) |
192 | | - && $this->page->userCan( 'review' ) |
193 | | - ); |
194 | | - } |
195 | | - return $this->isAllowed; |
| 217 | + # Users who cannot edit or review the page cannot set this |
| 218 | + return ( $this->page |
| 219 | + && $this->page->userCan( 'stablesettings' ) |
| 220 | + && $this->page->userCan( 'edit' ) |
| 221 | + && $this->page->userCan( 'review' ) |
| 222 | + ); |
196 | 223 | } |
197 | 224 | |
198 | 225 | /** |
199 | | - * Verify and clean up parameters and preload data from DB. |
200 | | - * Note: some items may not all be set on failure. |
| 226 | + * Submit the form parameters for the page config to the DB. |
| 227 | + * Note: caller is responsible for permission checks. |
| 228 | + * |
201 | 229 | * @return mixed (true on success, error string on failure) |
202 | 230 | */ |
203 | 231 | public function submit() { |
204 | 232 | global $wgUser; |
205 | | - if ( $this->submitLock ) { |
206 | | - throw new MWException( "FlaggedRevsConfigForm::submit() called either " . |
207 | | - "without calling handleParams() or called in spite of its failure.\n" ); |
| 233 | + if ( !$this->inputLock ) { |
| 234 | + throw new MWException( "FlaggedRevsConfigForm input fields not set yet.\n"); |
208 | 235 | } |
| 236 | + $status = $this->checkSettings(); |
| 237 | + if ( $status !== true ) { |
| 238 | + return $status; // cannot submit - broken params |
| 239 | + } |
209 | 240 | # Are we are going back to site defaults? |
210 | 241 | $reset = $this->newConfigIsReset(); |
211 | 242 | # Parse and cleanup the expiry time given... |
— | — | @@ -408,7 +439,17 @@ |
409 | 440 | $this->trySet( $this->override, $value ); |
410 | 441 | } |
411 | 442 | |
412 | | - public function handlePostedParams() { |
| 443 | + protected function reallyPreloadSettings() { |
| 444 | + $this->select = $this->oldConfig['select']; |
| 445 | + $this->override = $this->oldConfig['override']; |
| 446 | + $this->autoreview = $this->oldConfig['autoreview']; |
| 447 | + $this->expiry = $this->oldExpiry; |
| 448 | + $this->expirySelection = 'existing'; |
| 449 | + $this->watchThis = $this->page->userIsWatching(); |
| 450 | + return true; |
| 451 | + } |
| 452 | + |
| 453 | + protected function reallyCheckSettings() { |
413 | 454 | $this->loadReason(); |
414 | 455 | $this->loadExpiry(); |
415 | 456 | $this->override = $this->override ? 1 : 0; // default version settings is 0 or 1 |
— | — | @@ -433,21 +474,12 @@ |
434 | 475 | |
435 | 476 | // Return current config array |
436 | 477 | public function getOldConfig() { |
437 | | - if ( $this->page === false ) { |
438 | | - $this->handleParams(); // handleParams() not called first |
| 478 | + if ( !$this->inputLock ) { |
| 479 | + throw new MWException( "FlaggedRevsConfigForm input fields not set yet.\n"); |
439 | 480 | } |
440 | 481 | return $this->oldConfig; |
441 | 482 | } |
442 | 483 | |
443 | | - protected function preloadSettings() { |
444 | | - # Get visiblity settings... |
445 | | - $this->select = $this->oldConfig['select']; |
446 | | - $this->override = $this->oldConfig['override']; |
447 | | - # Get autoreview restrictions... |
448 | | - $this->autoreview = $this->oldConfig['autoreview']; |
449 | | - return true; |
450 | | - } |
451 | | - |
452 | 484 | // returns whether row changed |
453 | 485 | protected function updateConfigRow( $reset ) { |
454 | 486 | $changed = false; |
— | — | @@ -511,7 +543,15 @@ |
512 | 544 | |
513 | 545 | // Assumes $wgFlaggedRevsProtection is on |
514 | 546 | class PageStabilityProtectForm extends FlaggedRevsConfigForm { |
515 | | - public function handlePostedParams() { |
| 547 | + protected function reallyPreloadSettings() { |
| 548 | + $this->autoreview = $this->oldConfig['autoreview']; // protect level |
| 549 | + $this->expiry = $this->oldExpiry; |
| 550 | + $this->expirySelection = 'existing'; |
| 551 | + $this->watchThis = $this->page->userIsWatching(); |
| 552 | + return true; |
| 553 | + } |
| 554 | + |
| 555 | + protected function reallyCheckSettings() { |
516 | 556 | $this->loadReason(); |
517 | 557 | $this->loadExpiry(); |
518 | 558 | # Autoreview only when protecting currently unprotected pages |
— | — | @@ -545,11 +585,6 @@ |
546 | 586 | ); |
547 | 587 | } |
548 | 588 | |
549 | | - protected function preloadSettings() { |
550 | | - # Get autoreview restrictions... |
551 | | - $this->autoreview = $this->oldConfig['autoreview']; |
552 | | - } |
553 | | - |
554 | 589 | protected function updateConfigRow( $reset ) { |
555 | 590 | $changed = false; |
556 | 591 | $dbw = wfGetDB( DB_MASTER ); |
Index: trunk/extensions/FlaggedRevs/specialpages/Stabilization_body.php |
— | — | @@ -38,10 +38,12 @@ |
39 | 39 | |
40 | 40 | $this->form = new PageStabilityForm(); |
41 | 41 | $form = $this->form; // convenience |
42 | | - # Our target page |
| 42 | + # Target page |
43 | 43 | $form->setTarget( $wgRequest->getVal( 'page', $par ) ); |
44 | 44 | # Watch checkbox |
45 | 45 | $form->setWatchThis( (bool)$wgRequest->getCheck( 'wpWatchthis' ) ); |
| 46 | + # Get auto-review option... |
| 47 | + $form->setReviewThis( $wgRequest->getBool( 'wpReviewthis', true ) ); |
46 | 48 | # Reason |
47 | 49 | $form->setReason( $wgRequest->getText( 'wpReason' ) ); |
48 | 50 | $form->setReasonSelection( $wgRequest->getVal( 'wpReasonSelection' ) ); |
— | — | @@ -53,19 +55,14 @@ |
54 | 56 | $form->setOverride( (int)$wgRequest->getBool( 'wpStableconfig-override' ) ); |
55 | 57 | # Get autoreview restrictions... |
56 | 58 | $form->setAutoreview( $wgRequest->getVal( 'mwProtect-level-autoreview' ) ); |
57 | | - # Get auto-review option... |
58 | | - $form->setReviewThis( $wgRequest->getBool( 'wpReviewthis', true ) ); |
59 | | - $form->setWasPosted( $wgRequest->wasPosted() ); |
60 | 59 | |
61 | | - # Fill in & validate some parameters |
62 | | - $status = $form->handleParams(); |
63 | | - $title = $form->getPage(); // convenience |
64 | | - |
65 | | - # We need a valid, existing, page... |
| 60 | + $status = $form->ready(); // params all set |
66 | 61 | if ( $status === 'stabilize_page_invalid' ) { |
67 | 62 | $wgOut->showErrorPage( 'notargettitle', 'notargettext' ); |
68 | 63 | return; |
69 | | - } elseif ( $status === 'stabilize_page_notexists' ) { |
| 64 | + } |
| 65 | + $title = $form->getPage(); // convenience |
| 66 | + if ( $status === 'stabilize_page_notexists' ) { |
70 | 67 | $wgOut->addWikiText( |
71 | 68 | wfMsg( 'stabilization-notexists', $title->getPrefixedText() ) ); |
72 | 69 | return; |
— | — | @@ -74,16 +71,17 @@ |
75 | 72 | wfMsg( 'stabilization-notcontent', $title->getPrefixedText() ) ); |
76 | 73 | return; |
77 | 74 | } |
78 | | - |
79 | | - # Show form or submit... |
80 | | - if ( $form->isAllowed() && $status === true && $confirmed ) { |
| 75 | + # Form POST request... |
| 76 | + if ( $confirmed && $form->isAllowed() ) { |
81 | 77 | $status = $form->submit(); |
82 | 78 | if ( $status === true ) { |
83 | 79 | $wgOut->redirect( $title->getFullUrl() ); |
84 | 80 | } else { |
85 | 81 | $this->showForm( wfMsg( $status ) ); |
86 | 82 | } |
| 83 | + # Form GET request... |
87 | 84 | } else { |
| 85 | + $form->preloadSettings(); |
88 | 86 | $this->showForm(); |
89 | 87 | } |
90 | 88 | } |
Index: trunk/extensions/FlaggedRevs/FlaggedRevs.hooks.php |
— | — | @@ -2236,15 +2236,12 @@ |
2237 | 2237 | $form->setReasonSelection( $wgRequest->getVal( 'wpProtectReasonSelection' ) ); // dropdown |
2238 | 2238 | $form->setExpiry( $wgRequest->getVal( 'mwStabilizeExpiryOther' ) ); // manual |
2239 | 2239 | $form->setExpirySelection( $wgRequest->getVal( 'mwStabilizeExpirySelection' ) ); // dropdown |
2240 | | - $form->setWasPosted( $wgRequest->wasPosted() ); // double-check |
2241 | | - $status = $form->handleParams(); |
2242 | | - if ( $status === true ) { |
| 2240 | + $form->ready(); // params all set |
| 2241 | + if ( $wgRequest->wasPosted() && $form->isAllowed() ) { |
2243 | 2242 | $status = $form->submit(); |
2244 | 2243 | if ( $status !== true ) { |
2245 | 2244 | $errorMsg = wfMsg( $status ); // some error message |
2246 | 2245 | } |
2247 | | - } else { |
2248 | | - $errorMsg = wfMsg( $status ); // some error message |
2249 | 2246 | } |
2250 | 2247 | return true; |
2251 | 2248 | } |
Index: trunk/extensions/FlaggedRevs/api/ApiStabilize.php |
— | — | @@ -76,16 +76,13 @@ |
77 | 77 | } |
78 | 78 | $form->setAutoreview( $restriction ); # Autoreview restriction |
79 | 79 | $form->setWasPosted( true ); // already validated |
80 | | - |
81 | | - $status = $form->handleParams(); |
82 | | - if ( $status === true ) { |
83 | | - $status = $form->submit(); // true/error message key |
84 | | - if ( $status !== true ) { |
85 | | - $this->dieUsage( wfMsg( $status ) ); |
86 | | - } |
87 | | - } else { |
88 | | - $this->dieUsage( wfMsg( $status ), $status ); |
| 80 | + $form->ready(); |
| 81 | + |
| 82 | + $status = $form->submit(); // true/error message key |
| 83 | + if ( $status !== true ) { |
| 84 | + $this->dieUsage( wfMsg( $status ) ); |
89 | 85 | } |
| 86 | + |
90 | 87 | # Output success line with the title and config parameters |
91 | 88 | $res = array(); |
92 | 89 | $res['title'] = $title->getPrefixedText(); |