Файловый менеджер - Редактировать - /var/www/html/mediawiki-1.43.1/includes/jobqueue/jobs/DoubleRedirectJob.php
Ðазад
<?php /** * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * http://www.gnu.org/copyleft/gpl.html * * @file */ use MediaWiki\Cache\CacheKeyHelper; use MediaWiki\Linker\LinkTarget; use MediaWiki\MediaWikiServices; use MediaWiki\Page\PageReference; use MediaWiki\Page\WikiPageFactory; use MediaWiki\Parser\MagicWordFactory; use MediaWiki\Revision\RevisionLookup; use MediaWiki\Revision\SlotRecord; use MediaWiki\Title\Title; use MediaWiki\User\User; use Wikimedia\Rdbms\IDBAccessObject; /** * Fix any double redirects after moving a page. * * @ingroup JobQueue */ class DoubleRedirectJob extends Job { /** * @var int Max number of double redirect jobs counter. * This is meant to avoid excessive memory usage. This is * also used in fixDoubleRedirects.php script. */ public const MAX_DR_JOBS_COUNTER = 10000; /** @var Title The title which has changed, redirects pointing to this * title are fixed */ private $redirTitle; /** @var User */ private static $user; /** @var RevisionLookup */ private $revisionLookup; /** @var MagicWordFactory */ private $magicWordFactory; /** @var WikiPageFactory */ private $wikiPageFactory; /** * @param PageReference $page * @param array $params Expected to contain these elements: * - 'redirTitle' => string The title that changed and should be fixed. * - 'reason' => string Reason for the change, can be "move" or "maintenance". Used as a suffix * for the message keys "double-redirect-fixed-move" and * "double-redirect-fixed-maintenance". * ] * @param RevisionLookup $revisionLookup * @param MagicWordFactory $magicWordFactory * @param WikiPageFactory $wikiPageFactory */ public function __construct( PageReference $page, array $params, RevisionLookup $revisionLookup, MagicWordFactory $magicWordFactory, WikiPageFactory $wikiPageFactory ) { parent::__construct( 'fixDoubleRedirect', $page, $params ); $this->redirTitle = Title::newFromText( $params['redirTitle'] ); $this->revisionLookup = $revisionLookup; $this->magicWordFactory = $magicWordFactory; $this->wikiPageFactory = $wikiPageFactory; } /** * Insert jobs into the job queue to fix redirects to the given title * @param string $reason The reason for the fix, see message * "double-redirect-fixed-<reason>" * @param LinkTarget $redirTitle The title which has changed, redirects * pointing to this title are fixed */ public static function fixRedirects( $reason, $redirTitle ) { # Need to use the primary DB to get the redirect table updated in the same transaction $services = MediaWikiServices::getInstance(); $dbw = $services->getConnectionProvider()->getPrimaryDatabase(); $res = $dbw->newSelectQueryBuilder() ->select( [ 'page_namespace', 'page_title' ] ) ->from( 'redirect' ) ->join( 'page', null, 'page_id = rd_from' ) ->where( [ 'rd_namespace' => $redirTitle->getNamespace(), 'rd_title' => $redirTitle->getDBkey() ] ) ->andWhere( [ 'rd_interwiki' => '' ] ) ->caller( __METHOD__ )->fetchResultSet(); if ( !$res->numRows() ) { return; } $jobs = []; $jobQueueGroup = $services->getJobQueueGroup(); foreach ( $res as $row ) { $title = Title::makeTitleSafe( $row->page_namespace, $row->page_title ); if ( !$title || !$title->canExist() ) { continue; } $jobs[] = new self( $title, [ 'reason' => $reason, 'redirTitle' => $services->getTitleFormatter() ->getPrefixedDBkey( $redirTitle ) ], $services->getRevisionLookup(), $services->getMagicWordFactory(), $services->getWikiPageFactory() ); # Avoid excessive memory usage if ( count( $jobs ) > self::MAX_DR_JOBS_COUNTER ) { $jobQueueGroup->push( $jobs ); $jobs = []; } } $jobQueueGroup->push( $jobs ); } /** * @return bool */ public function run() { if ( !$this->redirTitle ) { $this->setLastError( 'Invalid title' ); return false; } if ( !$this->title->canExist() ) { // Needs a proper title for WikiPageFactory::newFromTitle and RevisionStore::getRevisionByTitle $this->setLastError( 'Cannot edit title' ); return false; } $targetRev = $this->revisionLookup ->getRevisionByTitle( $this->title, 0, IDBAccessObject::READ_LATEST ); if ( !$targetRev ) { wfDebug( __METHOD__ . ": target redirect already deleted, ignoring" ); return true; } $content = $targetRev->getContent( SlotRecord::MAIN ); $currentDest = $content ? $content->getRedirectTarget() : null; if ( !$currentDest || !$currentDest->equals( $this->redirTitle ) ) { wfDebug( __METHOD__ . ": Redirect has changed since the job was queued" ); return true; } // Check for a suppression tag (used e.g. in periodically archived discussions) $mw = $this->magicWordFactory->get( 'staticredirect' ); if ( $content->matchMagicWord( $mw ) ) { wfDebug( __METHOD__ . ": skipping: suppressed with __STATICREDIRECT__" ); return true; } // Find the current final destination $newTitle = self::getFinalDestination( $this->redirTitle ); if ( !$newTitle ) { wfDebug( __METHOD__ . ": skipping: single redirect, circular redirect or invalid redirect destination" ); return true; } if ( $newTitle->equals( $this->redirTitle ) ) { // The redirect is already right, no need to change it // This can happen if the page was moved back (say after vandalism) wfDebug( __METHOD__ . " : skipping, already good" ); } // Preserve fragment (T16904) $newTitle = Title::makeTitle( $newTitle->getNamespace(), $newTitle->getDBkey(), $currentDest->getFragment(), $newTitle->getInterwiki() ); // Fix the text $newContent = $content->updateRedirect( $newTitle ); if ( $newContent->equals( $content ) ) { $this->setLastError( 'Content unchanged???' ); return false; } $user = $this->getUser(); if ( !$user ) { $this->setLastError( 'Invalid user' ); return false; } // Save it // phpcs:ignore MediaWiki.Usage.DeprecatedGlobalVariables.Deprecated$wgUser global $wgUser; $oldUser = $wgUser; $wgUser = $user; $article = $this->wikiPageFactory->newFromTitle( $this->title ); // Messages: double-redirect-fixed-move, double-redirect-fixed-maintenance $reason = wfMessage( 'double-redirect-fixed-' . $this->params['reason'], $this->redirTitle->getPrefixedText(), $newTitle->getPrefixedText() )->inContentLanguage()->text(); // Avoid RC flood, and use minor to avoid email notifs $flags = EDIT_UPDATE | EDIT_SUPPRESS_RC | EDIT_INTERNAL | EDIT_MINOR; $article->doUserEditContent( $newContent, $user, $reason, $flags ); $wgUser = $oldUser; return true; } /** * Get the final destination of a redirect * * @param LinkTarget $title * * @return Title|false The final Title after following all redirects, or false if * the page is not a redirect or the redirect loops. */ public static function getFinalDestination( $title ) { $dbw = MediaWikiServices::getInstance()->getConnectionProvider()->getPrimaryDatabase(); // Circular redirect check $seenTitles = []; $dest = false; while ( true ) { $titleText = CacheKeyHelper::getKeyForPage( $title ); if ( isset( $seenTitles[$titleText] ) ) { wfDebug( __METHOD__, "Circular redirect detected, aborting" ); return false; } $seenTitles[$titleText] = true; if ( $title->isExternal() ) { // If the target is interwiki, we have to break early (T42352). // Otherwise it will look up a row in the local page table // with the namespace/page of the interwiki target which can cause // unexpected results (e.g. X -> foo:Bar -> Bar -> .. ) break; } $row = $dbw->newSelectQueryBuilder() ->select( [ 'rd_namespace', 'rd_title', 'rd_interwiki' ] ) ->from( 'redirect' ) ->join( 'page', null, 'page_id = rd_from' ) ->where( [ 'page_namespace' => $title->getNamespace() ] ) ->andWhere( [ 'page_title' => $title->getDBkey() ] ) ->caller( __METHOD__ )->fetchRow(); if ( !$row ) { # No redirect from here, chain terminates break; } else { $dest = $title = Title::makeTitle( $row->rd_namespace, $row->rd_title, '', $row->rd_interwiki ); } } return $dest; } /** * Get a user object for doing edits, from a request-lifetime cache * False will be returned if the user name specified in the * 'double-redirect-fixer' message is invalid. * * @return User|false */ private function getUser() { if ( !self::$user ) { $username = wfMessage( 'double-redirect-fixer' )->inContentLanguage()->text(); self::$user = User::newFromName( $username ); # User::newFromName() can return false on a badly configured wiki. if ( self::$user && !self::$user->isRegistered() ) { self::$user->addToDatabase(); } } return self::$user; } }
| ver. 1.1 | |
.
| PHP 8.4.18 | Ð“ÐµÐ½ÐµÑ€Ð°Ñ†Ð¸Ñ Ñтраницы: 0 |
proxy
|
phpinfo
|
ÐаÑтройка