X-Git-Url: https://git.heureux-cyclage.org/?a=blobdiff_plain;f=includes%2FMovePage.php;h=564c8f4d6ca591522cf9fe262ad63e15a2ef0a16;hb=5a451fd01be397db3209c1881a335423706da5c2;hp=832e24af81225ff4bd52d3ef617cb5a0e9561ca0;hpb=22ac82f4cd7960735339d23865fce21665ea9c17;p=lhc%2Fweb%2Fwiklou.git diff --git a/includes/MovePage.php b/includes/MovePage.php index 832e24af81..564c8f4d6c 100644 --- a/includes/MovePage.php +++ b/includes/MovePage.php @@ -19,9 +19,13 @@ * @file */ +use MediaWiki\Config\ServiceOptions; use MediaWiki\MediaWikiServices; +use MediaWiki\Page\MovePageFactory; +use MediaWiki\Permissions\PermissionManager; use MediaWiki\Revision\SlotRecord; use Wikimedia\Rdbms\IDatabase; +use Wikimedia\Rdbms\ILoadBalancer; /** * Handles the backend logic of moving a page from one title @@ -41,9 +45,69 @@ class MovePage { */ protected $newTitle; - public function __construct( Title $oldTitle, Title $newTitle ) { + /** + * @var ServiceOptions + */ + protected $options; + + /** + * @var ILoadBalancer + */ + protected $loadBalancer; + + /** + * @var NamespaceInfo + */ + protected $nsInfo; + + /** + * @var WatchedItemStoreInterface + */ + protected $watchedItems; + + /** + * @var PermissionManager + */ + protected $permMgr; + + /** + * @var RepoGroup + */ + protected $repoGroup; + + /** + * Calling this directly is deprecated in 1.34. Use MovePageFactory instead. + * + * @param Title $oldTitle + * @param Title $newTitle + * @param ServiceOptions|null $options + * @param ILoadBalancer|null $loadBalancer + * @param NamespaceInfo|null $nsInfo + * @param WatchedItemStore|null $watchedItems + * @param PermissionManager|null $permMgr + */ + public function __construct( + Title $oldTitle, + Title $newTitle, + ServiceOptions $options = null, + ILoadBalancer $loadBalancer = null, + NamespaceInfo $nsInfo = null, + WatchedItemStoreInterface $watchedItems = null, + PermissionManager $permMgr = null, + RepoGroup $repoGroup = null + ) { $this->oldTitle = $oldTitle; $this->newTitle = $newTitle; + $this->options = $options ?? + new ServiceOptions( MovePageFactory::$constructorOptions, + MediaWikiServices::getInstance()->getMainConfig() ); + $this->loadBalancer = + $loadBalancer ?? MediaWikiServices::getInstance()->getDBLoadBalancer(); + $this->nsInfo = $nsInfo ?? MediaWikiServices::getInstance()->getNamespaceInfo(); + $this->watchedItems = + $watchedItems ?? MediaWikiServices::getInstance()->getWatchedItemStore(); + $this->permMgr = $permMgr ?? MediaWikiServices::getInstance()->getPermissionManager(); + $this->repoGroup = $repoGroup ?? MediaWikiServices::getInstance()->getRepoGroup(); } /** @@ -58,10 +122,10 @@ class MovePage { $status = new Status(); $errors = wfMergeErrorArrays( - $this->oldTitle->getUserPermissionsErrors( 'move', $user ), - $this->oldTitle->getUserPermissionsErrors( 'edit', $user ), - $this->newTitle->getUserPermissionsErrors( 'move-target', $user ), - $this->newTitle->getUserPermissionsErrors( 'edit', $user ) + $this->permMgr->getPermissionErrors( 'move', $user, $this->oldTitle ), + $this->permMgr->getPermissionErrors( 'edit', $user, $this->oldTitle ), + $this->permMgr->getPermissionErrors( 'move-target', $user, $this->newTitle ), + $this->permMgr->getPermissionErrors( 'edit', $user, $this->newTitle ) ); // Convert into a Status object @@ -77,8 +141,9 @@ class MovePage { } $tp = $this->newTitle->getTitleProtection(); - if ( $tp !== false && !$user->isAllowed( $tp['permission'] ) ) { - $status->fatal( 'cantmove-titleprotected' ); + $permissionManager = MediaWikiServices::getInstance()->getPermissionManager(); + if ( $tp !== false && !$permissionManager->userHasRight( $user, $tp['permission'] ) ) { + $status->fatal( 'cantmove-titleprotected' ); } Hooks::run( 'MovePageCheckPermissions', @@ -96,44 +161,41 @@ class MovePage { * @return Status */ public function isValidMove() { - global $wgContentHandlerUseDB; $status = new Status(); if ( $this->oldTitle->equals( $this->newTitle ) ) { $status->fatal( 'selfmove' ); + } elseif ( $this->newTitle->getArticleID() && !$this->isValidMoveTarget() ) { + // The move is allowed only if (1) the target doesn't exist, or (2) the target is a + // redirect to the source, and has no history (so we can undo bad moves right after + // they're done). + $status->fatal( 'articleexists' ); } - if ( !$this->oldTitle->isMovable() ) { + + // @todo If the old title is invalid, maybe we should check if it somehow exists in the + // database and allow moving it to a valid name? Why prohibit the move from an empty name + // without checking in the database? + if ( $this->oldTitle->getDBkey() == '' ) { + $status->fatal( 'badarticleerror' ); + } elseif ( $this->oldTitle->isExternal() ) { + $status->fatal( 'immobile-source-namespace-iw' ); + } elseif ( !$this->oldTitle->isMovable() ) { $status->fatal( 'immobile-source-namespace', $this->oldTitle->getNsText() ); + } elseif ( !$this->oldTitle->exists() ) { + $status->fatal( 'movepage-source-doesnt-exist' ); } + if ( $this->newTitle->isExternal() ) { $status->fatal( 'immobile-target-namespace-iw' ); - } - if ( !$this->newTitle->isMovable() ) { + } elseif ( !$this->newTitle->isMovable() ) { $status->fatal( 'immobile-target-namespace', $this->newTitle->getNsText() ); } - - $oldid = $this->oldTitle->getArticleID(); - - if ( $this->newTitle->getDBkey() === '' ) { - $status->fatal( 'articleexists' ); - } - if ( - ( $this->oldTitle->getDBkey() == '' ) || - ( !$oldid ) || - ( $this->newTitle->getDBkey() == '' ) - ) { - $status->fatal( 'badarticleerror' ); - } - - # The move is allowed only if (1) the target doesn't exist, or - # (2) the target is a redirect to the source, and has no history - # (so we can undo bad moves right after they're done). - if ( $this->newTitle->getArticleID() && !$this->isValidMoveTarget() ) { - $status->fatal( 'articleexists' ); + if ( !$this->newTitle->isValid() ) { + $status->fatal( 'movepage-invalid-target-title' ); } // Content model checks - if ( !$wgContentHandlerUseDB && + if ( !$this->options->get( 'ContentHandlerUseDB' ) && $this->oldTitle->getContentModel() !== $this->newTitle->getContentModel() ) { // can't move a page if that would change the page's content model $status->fatal( @@ -174,7 +236,14 @@ class MovePage { */ protected function isValidFileMove() { $status = new Status(); - $file = wfLocalFile( $this->oldTitle ); + + if ( !$this->newTitle->inNamespace( NS_FILE ) ) { + $status->fatal( 'imagenocrossnamespace' ); + // No need for further errors about the target filename being wrong + return $status; + } + + $file = $this->repoGroup->getLocalRepo()->newFile( $this->oldTitle ); $file->load( File::READ_LATEST ); if ( $file->exists() ) { if ( $this->newTitle->getText() != wfStripIllegalFilenameChars( $this->newTitle->getText() ) ) { @@ -185,10 +254,6 @@ class MovePage { } } - if ( !$this->newTitle->inNamespace( NS_FILE ) ) { - $status->fatal( 'imagenocrossnamespace' ); - } - return $status; } @@ -202,7 +267,7 @@ class MovePage { protected function isValidMoveTarget() { # Is it an existing file? if ( $this->newTitle->inNamespace( NS_FILE ) ) { - $file = wfLocalFile( $this->newTitle ); + $file = $this->repoGroup->getLocalRepo()->newFile( $this->newTitle ); $file->load( File::READ_LATEST ); if ( $file->exists() ) { wfDebug( __METHOD__ . ": file exists\n" ); @@ -287,7 +352,8 @@ class MovePage { } // Check suppressredirect permission - if ( !$user->isAllowed( 'suppressredirect' ) ) { + $permissionManager = MediaWikiServices::getInstance()->getPermissionManager(); + if ( !$permissionManager->userHasRight( $user, 'suppressredirect' ) ) { $createRedirect = true; } @@ -380,7 +446,7 @@ class MovePage { $status = Status::newFatal( 'movepage-max-pages', $wgMaximumMovedPages ); $perTitleStatus[$oldSubpage->getPrefixedText()] = $status; $topStatus->merge( $status ); - $topStatus->setOk( true ); + $topStatus->setOK( true ); break; } @@ -413,7 +479,7 @@ class MovePage { } $perTitleStatus[$oldSubpage->getPrefixedText()] = $status; $topStatus->merge( $status ); - $topStatus->setOk( true ); + $topStatus->setOK( true ); } $topStatus->value = $perTitleStatus; @@ -430,8 +496,6 @@ class MovePage { * @return Status */ private function moveUnsafe( User $user, $reason, $createRedirect, array $changeTags ) { - global $wgCategoryCollation; - $status = Status::newGood(); Hooks::run( 'TitleMove', [ $this->oldTitle, $this->newTitle, $user, $reason, &$status ] ); if ( !$status->isOK() ) { @@ -439,7 +503,7 @@ class MovePage { return $status; } - $dbw = wfGetDB( DB_MASTER ); + $dbw = $this->loadBalancer->getConnection( DB_MASTER ); $dbw->startAtomic( __METHOD__, IDatabase::ATOMIC_CANCELABLE ); Hooks::run( 'TitleMoveStarting', [ $this->oldTitle, $this->newTitle, $user ] ); @@ -461,9 +525,7 @@ class MovePage { [ 'cl_from' => $pageid ], __METHOD__ ); - $services = MediaWikiServices::getInstance(); - $type = $services->getNamespaceInfo()-> - getCategoryLinkType( $this->newTitle->getNamespace() ); + $type = $this->nsInfo->getCategoryLinkType( $this->newTitle->getNamespace() ); foreach ( $prefixes as $prefixRow ) { $prefix = $prefixRow->cl_sortkey_prefix; $catTo = $prefixRow->cl_to; @@ -471,7 +533,7 @@ class MovePage { [ 'cl_sortkey' => Collation::singleton()->getSortKey( $this->newTitle->getCategorySortkey( $prefix ) ), - 'cl_collation' => $wgCategoryCollation, + 'cl_collation' => $this->options->get( 'CategoryCollation' ), 'cl_type' => $type, 'cl_timestamp=cl_timestamp' ], [ @@ -536,7 +598,7 @@ class MovePage { '4::oldtitle' => $this->oldTitle->getPrefixedText(), ] ); $logEntry->setRelations( [ 'pr_id' => $logRelationsValues ] ); - $logEntry->setTags( $changeTags ); + $logEntry->addTags( $changeTags ); $logId = $logEntry->insert(); $logEntry->publish( $logId ); } @@ -563,13 +625,10 @@ class MovePage { # Update watchlists $oldtitle = $this->oldTitle->getDBkey(); $newtitle = $this->newTitle->getDBkey(); - $oldsnamespace = $services->getNamespaceInfo()-> - getSubject( $this->oldTitle->getNamespace() ); - $newsnamespace = $services->getNamespaceInfo()-> - getSubject( $this->newTitle->getNamespace() ); + $oldsnamespace = $this->nsInfo->getSubject( $this->oldTitle->getNamespace() ); + $newsnamespace = $this->nsInfo->getSubject( $this->newTitle->getNamespace() ); if ( $oldsnamespace != $newsnamespace || $oldtitle != $newtitle ) { - $services->getWatchedItemStore()->duplicateAllAssociatedEntries( - $this->oldTitle, $this->newTitle ); + $this->watchedItems->duplicateAllAssociatedEntries( $this->oldTitle, $this->newTitle ); } // If it is a file then move it last. @@ -630,15 +689,15 @@ class MovePage { $oldTitle->getPrefixedText() ); - $file = wfLocalFile( $oldTitle ); + $file = $this->repoGroup->getLocalRepo()->newFile( $oldTitle ); $file->load( File::READ_LATEST ); if ( $file->exists() ) { $status = $file->move( $newTitle ); } // Clear RepoGroup process cache - RepoGroup::singleton()->clearCache( $oldTitle ); - RepoGroup::singleton()->clearCache( $newTitle ); # clear false negative cache + $this->repoGroup->clearCache( $oldTitle ); + $this->repoGroup->clearCache( $newTitle ); # clear false negative cache return $status; } @@ -739,7 +798,7 @@ class MovePage { $comment .= wfMessage( 'colon-separator' )->inContentLanguage()->text() . $reason; } - $dbw = wfGetDB( DB_MASTER ); + $dbw = $this->loadBalancer->getConnection( DB_MASTER ); $oldpage = WikiPage::factory( $this->oldTitle ); $oldcountable = $oldpage->isCountable(); @@ -836,7 +895,7 @@ class MovePage { # Log the move $logid = $logEntry->insert(); - $logEntry->setTags( $changeTags ); + $logEntry->addTags( $changeTags ); $logEntry->publish( $logid ); return $nullRevision;