MediaWiki  REL1_24
ApiMove.php
Go to the documentation of this file.
00001 <?php
00031 class ApiMove extends ApiBase {
00032 
00033     public function execute() {
00034         $user = $this->getUser();
00035         $params = $this->extractRequestParams();
00036 
00037         $this->requireOnlyOneParameter( $params, 'from', 'fromid' );
00038 
00039         if ( isset( $params['from'] ) ) {
00040             $fromTitle = Title::newFromText( $params['from'] );
00041             if ( !$fromTitle || $fromTitle->isExternal() ) {
00042                 $this->dieUsageMsg( array( 'invalidtitle', $params['from'] ) );
00043             }
00044         } elseif ( isset( $params['fromid'] ) ) {
00045             $fromTitle = Title::newFromID( $params['fromid'] );
00046             if ( !$fromTitle ) {
00047                 $this->dieUsageMsg( array( 'nosuchpageid', $params['fromid'] ) );
00048             }
00049         }
00050 
00051         if ( !$fromTitle->exists() ) {
00052             $this->dieUsageMsg( 'notanarticle' );
00053         }
00054         $fromTalk = $fromTitle->getTalkPage();
00055 
00056         $toTitle = Title::newFromText( $params['to'] );
00057         if ( !$toTitle || $toTitle->isExternal() ) {
00058             $this->dieUsageMsg( array( 'invalidtitle', $params['to'] ) );
00059         }
00060         $toTalk = $toTitle->getTalkPage();
00061 
00062         if ( $toTitle->getNamespace() == NS_FILE
00063             && !RepoGroup::singleton()->getLocalRepo()->findFile( $toTitle )
00064             && wfFindFile( $toTitle )
00065         ) {
00066             if ( !$params['ignorewarnings'] && $user->isAllowed( 'reupload-shared' ) ) {
00067                 $this->dieUsageMsg( 'sharedfile-exists' );
00068             } elseif ( !$user->isAllowed( 'reupload-shared' ) ) {
00069                 $this->dieUsageMsg( 'cantoverwrite-sharedfile' );
00070             }
00071         }
00072 
00073         // Move the page
00074         $toTitleExists = $toTitle->exists();
00075         $retval = $fromTitle->moveTo( $toTitle, true, $params['reason'], !$params['noredirect'] );
00076         if ( $retval !== true ) {
00077             $this->dieUsageMsg( reset( $retval ) );
00078         }
00079 
00080         $r = array(
00081             'from' => $fromTitle->getPrefixedText(),
00082             'to' => $toTitle->getPrefixedText(),
00083             'reason' => $params['reason']
00084         );
00085 
00086         if ( $fromTitle->exists() ) {
00087             //NOTE: we assume that if the old title exists, it's because it was re-created as
00088             // a redirect to the new title. This is not safe, but what we did before was
00089             // even worse: we just determined whether a redirect should have been created,
00090             // and reported that it was created if it should have, without any checks.
00091             // Also note that isRedirect() is unreliable because of bug 37209.
00092             $r['redirectcreated'] = '';
00093         }
00094 
00095         if ( $toTitleExists ) {
00096             $r['moveoverredirect'] = '';
00097         }
00098 
00099         // Move the talk page
00100         if ( $params['movetalk'] && $fromTalk->exists() && !$fromTitle->isTalkPage() ) {
00101             $toTalkExists = $toTalk->exists();
00102             $retval = $fromTalk->moveTo( $toTalk, true, $params['reason'], !$params['noredirect'] );
00103             if ( $retval === true ) {
00104                 $r['talkfrom'] = $fromTalk->getPrefixedText();
00105                 $r['talkto'] = $toTalk->getPrefixedText();
00106                 if ( $toTalkExists ) {
00107                     $r['talkmoveoverredirect'] = '';
00108                 }
00109             } else {
00110                 // We're not gonna dieUsage() on failure, since we already changed something
00111                 $parsed = $this->parseMsg( reset( $retval ) );
00112                 $r['talkmove-error-code'] = $parsed['code'];
00113                 $r['talkmove-error-info'] = $parsed['info'];
00114             }
00115         }
00116 
00117         $result = $this->getResult();
00118 
00119         // Move subpages
00120         if ( $params['movesubpages'] ) {
00121             $r['subpages'] = $this->moveSubpages( $fromTitle, $toTitle,
00122                 $params['reason'], $params['noredirect'] );
00123             $result->setIndexedTagName( $r['subpages'], 'subpage' );
00124 
00125             if ( $params['movetalk'] ) {
00126                 $r['subpages-talk'] = $this->moveSubpages( $fromTalk, $toTalk,
00127                     $params['reason'], $params['noredirect'] );
00128                 $result->setIndexedTagName( $r['subpages-talk'], 'subpage' );
00129             }
00130         }
00131 
00132         $watch = 'preferences';
00133         if ( isset( $params['watchlist'] ) ) {
00134             $watch = $params['watchlist'];
00135         } elseif ( $params['watch'] ) {
00136             $watch = 'watch';
00137             $this->logFeatureUsage( 'action=move&watch' );
00138         } elseif ( $params['unwatch'] ) {
00139             $watch = 'unwatch';
00140             $this->logFeatureUsage( 'action=move&unwatch' );
00141         }
00142 
00143         // Watch pages
00144         $this->setWatch( $watch, $fromTitle, 'watchmoves' );
00145         $this->setWatch( $watch, $toTitle, 'watchmoves' );
00146 
00147         $result->addValue( null, $this->getModuleName(), $r );
00148     }
00149 
00157     public function moveSubpages( $fromTitle, $toTitle, $reason, $noredirect ) {
00158         $retval = array();
00159         $success = $fromTitle->moveSubpages( $toTitle, true, $reason, !$noredirect );
00160         if ( isset( $success[0] ) ) {
00161             return array( 'error' => $this->parseMsg( $success ) );
00162         }
00163 
00164         // At least some pages could be moved
00165         // Report each of them separately
00166         foreach ( $success as $oldTitle => $newTitle ) {
00167             $r = array( 'from' => $oldTitle );
00168             if ( is_array( $newTitle ) ) {
00169                 $r['error'] = $this->parseMsg( reset( $newTitle ) );
00170             } else {
00171                 // Success
00172                 $r['to'] = $newTitle;
00173             }
00174             $retval[] = $r;
00175         }
00176 
00177         return $retval;
00178     }
00179 
00180     public function mustBePosted() {
00181         return true;
00182     }
00183 
00184     public function isWriteMode() {
00185         return true;
00186     }
00187 
00188     public function getAllowedParams() {
00189         return array(
00190             'from' => null,
00191             'fromid' => array(
00192                 ApiBase::PARAM_TYPE => 'integer'
00193             ),
00194             'to' => array(
00195                 ApiBase::PARAM_TYPE => 'string',
00196                 ApiBase::PARAM_REQUIRED => true
00197             ),
00198             'reason' => '',
00199             'movetalk' => false,
00200             'movesubpages' => false,
00201             'noredirect' => false,
00202             'watch' => array(
00203                 ApiBase::PARAM_DFLT => false,
00204                 ApiBase::PARAM_DEPRECATED => true,
00205             ),
00206             'unwatch' => array(
00207                 ApiBase::PARAM_DFLT => false,
00208                 ApiBase::PARAM_DEPRECATED => true,
00209             ),
00210             'watchlist' => array(
00211                 ApiBase::PARAM_DFLT => 'preferences',
00212                 ApiBase::PARAM_TYPE => array(
00213                     'watch',
00214                     'unwatch',
00215                     'preferences',
00216                     'nochange'
00217                 ),
00218             ),
00219             'ignorewarnings' => false
00220         );
00221     }
00222 
00223     public function getParamDescription() {
00224         $p = $this->getModulePrefix();
00225 
00226         return array(
00227             'from' => "Title of the page you want to move. Cannot be used together with {$p}fromid",
00228             'fromid' => "Page ID of the page you want to move. Cannot be used together with {$p}from",
00229             'to' => 'Title you want to rename the page to',
00230             'reason' => 'Reason for the move',
00231             'movetalk' => 'Move the talk page, if it exists',
00232             'movesubpages' => 'Move subpages, if applicable',
00233             'noredirect' => 'Don\'t create a redirect',
00234             'watch' => 'Add the page and the redirect to your watchlist',
00235             'unwatch' => 'Remove the page and the redirect from your watchlist',
00236             'watchlist' => 'Unconditionally add or remove the page from your ' .
00237                 'watchlist, use preferences or do not change watch',
00238             'ignorewarnings' => 'Ignore any warnings'
00239         );
00240     }
00241 
00242     public function getDescription() {
00243         return 'Move a page.';
00244     }
00245 
00246     public function needsToken() {
00247         return 'csrf';
00248     }
00249 
00250     public function getExamples() {
00251         return array(
00252             'api.php?action=move&from=Badtitle&to=Goodtitle&token=123ABC&' .
00253                 'reason=Misspelled%20title&movetalk=&noredirect='
00254         );
00255     }
00256 
00257     public function getHelpUrls() {
00258         return 'https://www.mediawiki.org/wiki/API:Move';
00259     }
00260 }