Index: trunk/phase3/includes/Article.php |
— | — | @@ -37,6 +37,18 @@ |
38 | 38 | /**@}}*/ |
39 | 39 | |
40 | 40 | /** |
| 41 | + * Constants used by internal components to get rollback results |
| 42 | + */ |
| 43 | + const SUCCESS = 0; // Operation successful |
| 44 | + const PERM_DENIED = 1; // Permission denied |
| 45 | + const BLOCKED = 2; // User has been blocked |
| 46 | + const READONLY = 3; // Wiki is in read-only mode |
| 47 | + const BAD_TOKEN = 4; // Invalid token specified |
| 48 | + const BAD_TITLE = 5; // $this is not a valid Article |
| 49 | + const ALREADY_ROLLED = 6; // Someone else already rolled this back. $from and $summary will be set |
| 50 | + const ONLY_AUTHOR = 7; // User is the only author of the page |
| 51 | + |
| 52 | + /** |
41 | 53 | * Constructor and clear the article |
42 | 54 | * @param $title Reference to a Title object. |
43 | 55 | * @param $oldId Integer revision ID, null to fetch from request, zero for current |
— | — | @@ -2155,61 +2167,53 @@ |
2156 | 2168 | return true; |
2157 | 2169 | } |
2158 | 2170 | |
2159 | | - /** |
2160 | | - * Revert a modification |
| 2171 | + /** Backend rollback implementation. UI logic is in rollback() |
| 2172 | + * @param string $fromP - Name of the user whose edits to rollback. |
| 2173 | + * @param string $summary - Custom summary. Set to default summary if empty. |
| 2174 | + * @param string $token - Rollback token. |
| 2175 | + * @param bool $bot - If true, mark all reverted edits as bot. |
| 2176 | + * |
| 2177 | + * @param array $resultDetails contains result-specific dict of additional values |
| 2178 | + * ALREADY_ROLLED : 'current' (rev) |
| 2179 | + * SUCCESS : 'summary' (str), 'current' (rev), 'target' (rev) |
| 2180 | + * |
| 2181 | + * @return self::SUCCESS on succes, self::* on failure |
2161 | 2182 | */ |
2162 | | - function rollback() { |
2163 | | - global $wgUser, $wgOut, $wgRequest, $wgUseRCPatrol; |
2164 | | - |
| 2183 | + public function doRollback($fromP, $summary, $token, $bot, &$resultDetails) { |
| 2184 | + global $wgUser, $wgUseRCPatrol; |
| 2185 | + |
| 2186 | + $resultDetails = null; |
| 2187 | + |
2165 | 2188 | if( $wgUser->isAllowed( 'rollback' ) ) { |
2166 | 2189 | if( $wgUser->isBlocked() ) { |
2167 | | - $wgOut->blockedPage(); |
2168 | | - return; |
| 2190 | + return self::BLOCKED; |
2169 | 2191 | } |
2170 | 2192 | } else { |
2171 | | - $wgOut->permissionRequired( 'rollback' ); |
2172 | | - return; |
| 2193 | + return self::PERM_DENIED; |
2173 | 2194 | } |
2174 | | - |
| 2195 | + |
2175 | 2196 | if ( wfReadOnly() ) { |
2176 | | - $wgOut->readOnlyPage( $this->getContent() ); |
2177 | | - return; |
| 2197 | + return self::READONLY; |
2178 | 2198 | } |
2179 | | - if( !$wgUser->matchEditToken( $wgRequest->getVal( 'token' ), |
2180 | | - array( $this->mTitle->getPrefixedText(), |
2181 | | - $wgRequest->getVal( 'from' ) ) ) ) { |
2182 | | - $wgOut->setPageTitle( wfMsg( 'rollbackfailed' ) ); |
2183 | | - $wgOut->addWikiText( wfMsg( 'sessionfailure' ) ); |
2184 | | - return; |
| 2199 | + if( !$wgUser->matchEditToken( $token, |
| 2200 | + array( $this->mTitle->getPrefixedText(), $fromP ))) { |
| 2201 | + return self::BAD_TOKEN; |
2185 | 2202 | } |
2186 | 2203 | $dbw = wfGetDB( DB_MASTER ); |
2187 | 2204 | |
2188 | | - # Enhanced rollback, marks edits rc_bot=1 |
2189 | | - $bot = $wgRequest->getBool( 'bot' ); |
2190 | | - |
2191 | 2205 | # Replace all this user's current edits with the next one down |
2192 | 2206 | |
2193 | 2207 | # Get the last editor |
2194 | 2208 | $current = Revision::newFromTitle( $this->mTitle ); |
2195 | 2209 | if( is_null( $current ) ) { |
2196 | 2210 | # Something wrong... no page? |
2197 | | - $wgOut->addHTML( wfMsg( 'notanarticle' ) ); |
2198 | | - return; |
| 2211 | + return self::BAD_TITLE; |
2199 | 2212 | } |
2200 | 2213 | |
2201 | | - $from = str_replace( '_', ' ', $wgRequest->getVal( 'from' ) ); |
| 2214 | + $from = str_replace( '_', ' ', $fromP ); |
2202 | 2215 | if( $from != $current->getUserText() ) { |
2203 | | - $wgOut->setPageTitle( wfMsg('rollbackfailed') ); |
2204 | | - $wgOut->addWikiText( wfMsg( 'alreadyrolled', |
2205 | | - htmlspecialchars( $this->mTitle->getPrefixedText()), |
2206 | | - htmlspecialchars( $from ), |
2207 | | - htmlspecialchars( $current->getUserText() ) ) ); |
2208 | | - if( $current->getComment() != '') { |
2209 | | - $wgOut->addHTML( |
2210 | | - wfMsg( 'editcomment', |
2211 | | - $wgUser->getSkin()->formatComment( $current->getComment() ) ) ); |
2212 | | - } |
2213 | | - return; |
| 2216 | + $resultDetails = array('current' => $current); |
| 2217 | + return self::ALREADY_ROLLED; |
2214 | 2218 | } |
2215 | 2219 | |
2216 | 2220 | # Get the last edit not by this guy |
— | — | @@ -2227,11 +2231,9 @@ |
2228 | 2232 | ); |
2229 | 2233 | if( $s === false ) { |
2230 | 2234 | # Something wrong |
2231 | | - $wgOut->setPageTitle(wfMsg('rollbackfailed')); |
2232 | | - $wgOut->addHTML( wfMsg( 'cantrollback' ) ); |
2233 | | - return; |
| 2235 | + return self::ONLY_AUTHOR; |
2234 | 2236 | } |
2235 | | - |
| 2237 | + |
2236 | 2238 | $set = array(); |
2237 | 2239 | if ( $bot ) { |
2238 | 2240 | # Mark all reverted edits as bot |
— | — | @@ -2244,35 +2246,99 @@ |
2245 | 2247 | |
2246 | 2248 | if ( $set ) { |
2247 | 2249 | $dbw->update( 'recentchanges', $set, |
2248 | | - array( /* WHERE */ |
2249 | | - 'rc_cur_id' => $current->getPage(), |
2250 | | - 'rc_user_text' => $current->getUserText(), |
2251 | | - "rc_timestamp > '{$s->rev_timestamp}'", |
2252 | | - ), __METHOD__ |
2253 | | - ); |
| 2250 | + array( /* WHERE */ |
| 2251 | + 'rc_cur_id' => $current->getPage(), |
| 2252 | + 'rc_user_text' => $current->getUserText(), |
| 2253 | + "rc_timestamp > '{$s->rev_timestamp}'", |
| 2254 | + ), __METHOD__ |
| 2255 | + ); |
2254 | 2256 | } |
2255 | 2257 | |
2256 | 2258 | # Get the edit summary |
2257 | 2259 | $target = Revision::newFromId( $s->rev_id ); |
2258 | | - $newComment = wfMsgForContent( 'revertpage', $target->getUserText(), $from ); |
2259 | | - $newComment = $wgRequest->getText( 'summary', $newComment ); |
| 2260 | + if (empty($summary)) |
| 2261 | + $summary = wfMsgForContent( 'revertpage', $target->getUserText(), $from ); |
2260 | 2262 | |
2261 | 2263 | # Save |
2262 | 2264 | $flags = EDIT_UPDATE | EDIT_MINOR; |
2263 | 2265 | if( $bot ) |
2264 | 2266 | $flags |= EDIT_FORCE_BOT; |
2265 | | - $this->doEdit( $target->getText(), $newComment, $flags ); |
| 2267 | + $this->doEdit( $target->getText(), $summary, $flags ); |
2266 | 2268 | |
2267 | | - # User feedback |
2268 | | - $wgOut->setPageTitle( wfMsg( 'actioncomplete' ) ); |
2269 | | - $wgOut->setRobotPolicy( 'noindex,nofollow' ); |
2270 | | - $old = $wgUser->getSkin()->userLink( $current->getUser(), $current->getUserText() ) |
2271 | | - . $wgUser->getSkin()->userToolLinks( $current->getUser(), $current->getUserText() ); |
2272 | | - $new = $wgUser->getSkin()->userLink( $target->getUser(), $target->getUserText() ) |
2273 | | - . $wgUser->getSkin()->userToolLinks( $target->getUser(), $target->getUserText() ); |
2274 | | - $wgOut->addHtml( wfMsgExt( 'rollback-success', array( 'parse', 'replaceafter' ), $old, $new ) ); |
| 2269 | + $resultDetails = array( |
| 2270 | + 'summary' => $summary, |
| 2271 | + 'current' => $current, |
| 2272 | + 'target' => $target); |
| 2273 | + return self::SUCCESS; |
| 2274 | + } |
2275 | 2275 | |
2276 | | - $wgOut->returnToMain( false ); |
| 2276 | + /** UI entry point for rollbacks. Relies on doRollback() to do the hard work */ |
| 2277 | + function rollback() { |
| 2278 | + global $wgUser, $wgOut, $wgRequest, $wgUseRCPatrol; |
| 2279 | + |
| 2280 | + // Call doRollback() and interpret its return value |
| 2281 | + $resultDetails = null; |
| 2282 | + $retval = $this->doRollback( |
| 2283 | + $wgRequest->getVal('from'), |
| 2284 | + $wgRequest->getText('summary'), |
| 2285 | + $wgRequest->getVal('token'), |
| 2286 | + $wgRequest->getBool('bot'), |
| 2287 | + &$resultDetails); |
| 2288 | + |
| 2289 | + switch($retval) |
| 2290 | + { |
| 2291 | + default: |
| 2292 | + throw new MWException( "Unknown retval $retval" ); |
| 2293 | + break; |
| 2294 | + case self::BLOCKED: |
| 2295 | + $wgOut->blockedPage(); |
| 2296 | + break; |
| 2297 | + case self::PERM_DENIED: |
| 2298 | + $wgOut->permissionRequired( 'rollback' ); |
| 2299 | + break; |
| 2300 | + case self::READONLY: |
| 2301 | + $wgOut->readOnlyPage( $this->getContent() ); |
| 2302 | + break; |
| 2303 | + case self::BAD_TOKEN: |
| 2304 | + $wgOut->setPageTitle( wfMsg( 'rollbackfailed' ) ); |
| 2305 | + $wgOut->addWikiText( wfMsg( 'sessionfailure' ) ); |
| 2306 | + break; |
| 2307 | + case self::BAD_TITLE: |
| 2308 | + $wgOut->addHTML( wfMsg( 'notanarticle' ) ); |
| 2309 | + break; |
| 2310 | + case self::ALREADY_ROLLED: |
| 2311 | + $current = $resultDetails['current']; |
| 2312 | + $wgOut->setPageTitle( wfMsg('rollbackfailed') ); |
| 2313 | + $wgOut->addWikiText( wfMsg( 'alreadyrolled', |
| 2314 | + htmlspecialchars( $this->mTitle->getPrefixedText()), |
| 2315 | + htmlspecialchars( $wgRequest->getVal('from') ), |
| 2316 | + htmlspecialchars( $current->getUserText() ) ) ); |
| 2317 | + if( $current->getComment() != '') { |
| 2318 | + $wgOut->addHTML( |
| 2319 | + wfMsg( 'editcomment', |
| 2320 | + $wgUser->getSkin()->formatComment( $current->getComment() ) ) ); |
| 2321 | + } |
| 2322 | + break; |
| 2323 | + case self::ONLY_AUTHOR: |
| 2324 | + $wgOut->setPageTitle(wfMsg('rollbackfailed')); |
| 2325 | + $wgOut->addHTML( wfMsg( 'cantrollback' ) ); |
| 2326 | + break; |
| 2327 | + case self::SUCCESS: |
| 2328 | + # User feedback |
| 2329 | + $current = $resultDetails['current']; |
| 2330 | + $target = $resultDetails['target']; |
| 2331 | + |
| 2332 | + $wgOut->setPageTitle( wfMsg( 'actioncomplete' ) ); |
| 2333 | + $wgOut->setRobotPolicy( 'noindex,nofollow' ); |
| 2334 | + $old = $wgUser->getSkin()->userLink( $current->getUser(), $current->getUserText() ) |
| 2335 | + . $wgUser->getSkin()->userToolLinks( $current->getUser(), $current->getUserText() ); |
| 2336 | + $new = $wgUser->getSkin()->userLink( $target->getUser(), $target->getUserText() ) |
| 2337 | + . $wgUser->getSkin()->userToolLinks( $target->getUser(), $target->getUserText() ); |
| 2338 | + $wgOut->addHtml( wfMsgExt( 'rollback-success', array( 'parse', 'replaceafter' ), $old, $new ) ); |
| 2339 | + |
| 2340 | + $wgOut->returnToMain( false ); |
| 2341 | + break; |
| 2342 | + } |
2277 | 2343 | } |
2278 | 2344 | |
2279 | 2345 | |