29use Psr\Log\LoggerInterface;
44 private LoggerInterface $logger;
52 LoggerInterface $logger
54 $this->dbProvider = $dbProvider;
55 $this->pageLookup = $pageLookup;
56 $this->titleParser = $titleParser;
57 $this->repoGroup = $repoGroup;
58 $this->logger = $logger;
63 $cacheKey = self::makeCacheKey( $page );
64 $cachedValue = $this->procCache->get( $cacheKey );
65 if ( $cachedValue !==
null ) {
66 return $cachedValue ?:
null;
71 $file = $this->repoGroup->findFile( $page );
72 if ( $file && !$file->isLocal() ) {
73 $from = $file->getRedirected();
74 $to = $file->getName();
75 if ( $from ===
null || $from === $to ) {
76 $this->procCache->set( $cacheKey,
false );
80 $target =
new TitleValue(
NS_FILE, $to );
81 $this->procCache->set( $cacheKey, $target );
86 $page = $this->pageLookup->getPageByReference( $page );
87 if ( $page ===
null || !$page->isRedirect() ) {
88 $this->procCache->set( $cacheKey,
false );
92 $dbr = $this->dbProvider->getReplicaDatabase();
93 $row = $dbr->newSelectQueryBuilder()
94 ->select( [
'rd_namespace',
'rd_title',
'rd_fragment',
'rd_interwiki' ] )
96 ->where( [
'rd_from' => $page->
getId() ] )
97 ->caller( __METHOD__ )
102 'Found inconsistent redirect status; probably the page was deleted after it was loaded'
104 $this->procCache->set( $cacheKey,
false );
108 $target = $this->createRedirectTarget(
115 $this->procCache->set( $cacheKey, $target );
132 ?
bool $lastRevWasRedirect =
null
137 $isRedirect = $target !==
null;
138 $cacheKey = self::makeCacheKey( $page );
140 if ( !$isRedirect && $lastRevWasRedirect ===
false ) {
141 $this->procCache->set( $cacheKey,
false );
146 $rt = Title::newFromLinkTarget( $target );
147 if ( !$rt->isValidRedirectTarget() ) {
149 $this->procCache->set( $cacheKey,
false );
153 $dbw = $this->dbProvider->getPrimaryDatabase();
154 $dbw->startAtomic( __METHOD__ );
156 $truncatedFragment = self::truncateFragment( $rt->getFragment() );
157 $dbw->newInsertQueryBuilder()
158 ->insertInto(
'redirect' )
160 'rd_from' => $page->
getId(),
161 'rd_namespace' => $rt->getNamespace(),
162 'rd_title' => $rt->getDBkey(),
163 'rd_fragment' => $truncatedFragment,
164 'rd_interwiki' => $rt->getInterwiki(),
166 ->onDuplicateKeyUpdate()
167 ->uniqueIndexFields( [
'rd_from' ] )
169 'rd_namespace' => $rt->getNamespace(),
170 'rd_title' => $rt->getDBkey(),
171 'rd_fragment' => $truncatedFragment,
172 'rd_interwiki' => $rt->getInterwiki(),
174 ->caller( __METHOD__ )
177 $dbw->endAtomic( __METHOD__ );
179 $this->procCache->set(
181 $this->createRedirectTarget(
189 $dbw = $this->dbProvider->getPrimaryDatabase();
191 $dbw->newDeleteQueryBuilder()
192 ->deleteFrom(
'redirect' )
193 ->where( [
'rd_from' => $page->
getId() ] )
194 ->caller( __METHOD__ )
197 $this->procCache->set( $cacheKey,
false );
201 $this->repoGroup->getLocalRepo()->invalidateImageRedirect( $page );
214 $this->procCache->clear( self::makeCacheKey( $page ) );
222 private static function makeCacheKey( $page ) {
223 return "{$page->getNamespace()}:{$page->getDBkey()}";
236 private function createRedirectTarget( $namespace, $title, $fragment, $interwiki ): ?LinkTarget {
246 $fragment = self::truncateFragment( $fragment );
252 $target = $this->titleParser->makeTitleValueSafe( $namespace, $title, $fragment, $interwiki );
253 if ( $target !==
null && Title::newFromLinkTarget( $target )->isValidRedirectTarget() ) {
266 private static function truncateFragment( $fragment ) {
267 return mb_strcut( $fragment, 0, 255 );
if(!defined('MW_SETUP_CALLBACK'))
Store key-value entries in a size-limited in-memory LRU cache.
Service for storing and retrieving page redirect information.
clearCache( $page)
Clear process-cached redirect information for a page.
updateRedirectTarget(PageIdentity $page, ?LinkTarget $target, ?bool $lastRevWasRedirect=null)
Update the redirect target for a page.
getRedirectTarget(PageIdentity $page)
Get the redirect destination.
__construct(IConnectionProvider $dbProvider, PageLookup $pageLookup, TitleParser $titleParser, RepoGroup $repoGroup, LoggerInterface $logger)
Prioritized list of file repositories.
Interface for objects (potentially) representing an editable wiki page.
getId( $wikiId=self::LOCAL)
Returns the page ID.
Service for looking up information about wiki pages.
Service for resolving a wiki page redirect.