MediaWiki  REL1_21
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( 'from' => $fromTitle->getPrefixedText(), 'to' => $toTitle->getPrefixedText(), 'reason' => $params['reason'] );
00081 
00082                 if ( $fromTitle->exists() ) {
00083                         //NOTE: we assume that if the old title exists, it's because it was re-created as
00084                         // a redirect to the new title. This is not safe, but what we did before was
00085                         // even worse: we just determined whether a redirect should have been created,
00086                         // and reported that it was created if it should have, without any checks.
00087                         // Also note that isRedirect() is unreliable because of bug 37209.
00088                         $r['redirectcreated'] = '';
00089                 }
00090 
00091                 if( $toTitleExists ) {
00092                         $r['moveoverredirect'] = '';
00093                 }
00094 
00095                 // Move the talk page
00096                 if ( $params['movetalk'] && $fromTalk->exists() && !$fromTitle->isTalkPage() ) {
00097                         $toTalkExists = $toTalk->exists();
00098                         $retval = $fromTalk->moveTo( $toTalk, true, $params['reason'], !$params['noredirect'] );
00099                         if ( $retval === true ) {
00100                                 $r['talkfrom'] = $fromTalk->getPrefixedText();
00101                                 $r['talkto'] = $toTalk->getPrefixedText();
00102                                 if( $toTalkExists ) {
00103                                         $r['talkmoveoverredirect'] = '';
00104                                 }
00105                         } else {
00106                                 // We're not gonna dieUsage() on failure, since we already changed something
00107                                 $parsed = $this->parseMsg( reset( $retval ) );
00108                                 $r['talkmove-error-code'] = $parsed['code'];
00109                                 $r['talkmove-error-info'] = $parsed['info'];
00110                         }
00111                 }
00112 
00113                 $result = $this->getResult();
00114 
00115                 // Move subpages
00116                 if ( $params['movesubpages'] ) {
00117                         $r['subpages'] = $this->moveSubpages( $fromTitle, $toTitle,
00118                                         $params['reason'], $params['noredirect'] );
00119                         $result->setIndexedTagName( $r['subpages'], 'subpage' );
00120 
00121                         if ( $params['movetalk'] ) {
00122                                 $r['subpages-talk'] = $this->moveSubpages( $fromTalk, $toTalk,
00123                                         $params['reason'], $params['noredirect'] );
00124                                 $result->setIndexedTagName( $r['subpages-talk'], 'subpage' );
00125                         }
00126                 }
00127 
00128                 $watch = 'preferences';
00129                 if ( isset( $params['watchlist'] ) ) {
00130                         $watch = $params['watchlist'];
00131                 } elseif ( $params['watch'] ) {
00132                         $watch = 'watch';
00133                 } elseif ( $params['unwatch'] ) {
00134                         $watch = 'unwatch';
00135                 }
00136 
00137                 // Watch pages
00138                 $this->setWatch( $watch, $fromTitle, 'watchmoves' );
00139                 $this->setWatch( $watch, $toTitle, 'watchmoves' );
00140 
00141                 $result->addValue( null, $this->getModuleName(), $r );
00142         }
00143 
00151         public function moveSubpages( $fromTitle, $toTitle, $reason, $noredirect ) {
00152                 $retval = array();
00153                 $success = $fromTitle->moveSubpages( $toTitle, true, $reason, !$noredirect );
00154                 if ( isset( $success[0] ) ) {
00155                         return array( 'error' => $this->parseMsg( $success ) );
00156                 } else {
00157                         // At least some pages could be moved
00158                         // Report each of them separately
00159                         foreach ( $success as $oldTitle => $newTitle ) {
00160                                 $r = array( 'from' => $oldTitle );
00161                                 if ( is_array( $newTitle ) ) {
00162                                         $r['error'] = $this->parseMsg( reset( $newTitle ) );
00163                                 } else {
00164                                         // Success
00165                                         $r['to'] = $newTitle;
00166                                 }
00167                                 $retval[] = $r;
00168                         }
00169                 }
00170                 return $retval;
00171         }
00172 
00173         public function mustBePosted() {
00174                 return true;
00175         }
00176 
00177         public function isWriteMode() {
00178                 return true;
00179         }
00180 
00181         public function getAllowedParams() {
00182                 return array(
00183                         'from' => null,
00184                         'fromid' => array(
00185                                 ApiBase::PARAM_TYPE => 'integer'
00186                         ),
00187                         'to' => array(
00188                                 ApiBase::PARAM_TYPE => 'string',
00189                                 ApiBase::PARAM_REQUIRED => true
00190                         ),
00191                         'token' => array(
00192                                 ApiBase::PARAM_TYPE => 'string',
00193                                 ApiBase::PARAM_REQUIRED => true
00194                         ),
00195                         'reason' => '',
00196                         'movetalk' => false,
00197                         'movesubpages' => false,
00198                         'noredirect' => false,
00199                         'watch' => array(
00200                                 ApiBase::PARAM_DFLT => false,
00201                                 ApiBase::PARAM_DEPRECATED => true,
00202                         ),
00203                         'unwatch' => array(
00204                                 ApiBase::PARAM_DFLT => false,
00205                                 ApiBase::PARAM_DEPRECATED => true,
00206                         ),
00207                         'watchlist' => array(
00208                                 ApiBase::PARAM_DFLT => 'preferences',
00209                                 ApiBase::PARAM_TYPE => array(
00210                                         'watch',
00211                                         'unwatch',
00212                                         'preferences',
00213                                         'nochange'
00214                                 ),
00215                         ),
00216                         'ignorewarnings' => false
00217                 );
00218         }
00219 
00220         public function getParamDescription() {
00221                 $p = $this->getModulePrefix();
00222                 return array(
00223                         'from' => "Title of the page you want to move. Cannot be used together with {$p}fromid",
00224                         'fromid' => "Page ID of the page you want to move. Cannot be used together with {$p}from",
00225                         'to' => 'Title you want to rename the page to',
00226                         'token' => 'A move token previously retrieved through prop=info',
00227                         'reason' => 'Reason for the move',
00228                         'movetalk' => 'Move the talk page, if it exists',
00229                         'movesubpages' => 'Move subpages, if applicable',
00230                         'noredirect' => 'Don\'t create a redirect',
00231                         'watch' => 'Add the page and the redirect to your watchlist',
00232                         'unwatch' => 'Remove the page and the redirect from your watchlist',
00233                         'watchlist' => 'Unconditionally add or remove the page from your watchlist, use preferences or do not change watch',
00234                         'ignorewarnings' => 'Ignore any warnings'
00235                 );
00236         }
00237 
00238         public function getResultProperties() {
00239                 return array(
00240                         '' => array(
00241                                 'from' => 'string',
00242                                 'to' => 'string',
00243                                 'reason' => 'string',
00244                                 'redirectcreated' => 'boolean',
00245                                 'moveoverredirect' => 'boolean',
00246                                 'talkfrom' => array(
00247                                         ApiBase::PROP_TYPE => 'string',
00248                                         ApiBase::PROP_NULLABLE => true
00249                                 ),
00250                                 'talkto' => array(
00251                                         ApiBase::PROP_TYPE => 'string',
00252                                         ApiBase::PROP_NULLABLE => true
00253                                 ),
00254                                 'talkmoveoverredirect' => 'boolean',
00255                                 'talkmove-error-code' => array(
00256                                         ApiBase::PROP_TYPE => 'string',
00257                                         ApiBase::PROP_NULLABLE => true
00258                                 ),
00259                                 'talkmove-error-info' => array(
00260                                         ApiBase::PROP_TYPE => 'string',
00261                                         ApiBase::PROP_NULLABLE => true
00262                                 )
00263                         )
00264                 );
00265         }
00266 
00267         public function getDescription() {
00268                 return 'Move a page';
00269         }
00270 
00271         public function getPossibleErrors() {
00272                 return array_merge( parent::getPossibleErrors(),
00273                         $this->getRequireOnlyOneParameterErrorMessages( array( 'from', 'fromid' ) ),
00274                         array(
00275                                 array( 'invalidtitle', 'from' ),
00276                                 array( 'nosuchpageid', 'fromid' ),
00277                                 array( 'notanarticle' ),
00278                                 array( 'invalidtitle', 'to' ),
00279                                 array( 'sharedfile-exists' ),
00280                         )
00281                 );
00282         }
00283 
00284         public function needsToken() {
00285                 return true;
00286         }
00287 
00288         public function getTokenSalt() {
00289                 return '';
00290         }
00291 
00292         public function getExamples() {
00293                 return array(
00294                         'api.php?action=move&from=Badtitle&to=Goodtitle&token=123ABC&reason=Misspelled%20title&movetalk=&noredirect='
00295                 );
00296         }
00297 
00298         public function getHelpUrls() {
00299                 return 'https://www.mediawiki.org/wiki/API:Move';
00300         }
00301 }