MediaWiki master
SpecialWantedCategories.php
Go to the documentation of this file.
1<?php
9namespace MediaWiki\Specials;
10
11use MediaWiki\Cache\LinkBatchFactory;
14use MediaWiki\Languages\LanguageConverterFactory;
19use stdClass;
22
30 private $currentCategoryCounts;
31
32 private ILanguageConverter $languageConverter;
33 private LinksMigration $linksMigration;
34
35 public function __construct(
36 IConnectionProvider $dbProvider,
37 LinkBatchFactory $linkBatchFactory,
38 LanguageConverterFactory $languageConverterFactory,
39 LinksMigration $linksMigration
40 ) {
41 parent::__construct( 'Wantedcategories' );
42 $this->setDatabaseProvider( $dbProvider );
43 $this->setLinkBatchFactory( $linkBatchFactory );
44 $this->languageConverter = $languageConverterFactory->getLanguageConverter( $this->getContentLanguage() );
45 $this->linksMigration = $linksMigration;
46 }
47
49 public function getQueryInfo() {
50 $queryInfo = $this->linksMigration->getQueryInfo( 'categorylinks' );
51 $titleField = $this->linksMigration->getTitleFields( 'categorylinks' )[1];
52
53 return [
54 'tables' => array_merge( $queryInfo['tables'], [ 'page' ] ),
55 'fields' => [
56 'namespace' => NS_CATEGORY,
57 'title' => $titleField,
58 'value' => 'COUNT(*)'
59 ],
60 'conds' => [ 'page_title' => null ],
61 'options' => [ 'GROUP BY' => $titleField ],
62 'join_conds' => array_merge( $queryInfo['joins'],
63 [ 'page' => [ 'LEFT JOIN',
64 [ 'page_title = ' . $titleField,
65 'page_namespace' => NS_CATEGORY ] ] ] )
66 ];
67 }
68
70 protected function getRecacheDB() {
71 return $this->getDatabaseProvider()->getReplicaDatabase(
72 CategoryLinksTable::VIRTUAL_DOMAIN,
73 'vslow'
74 );
75 }
76
78 public function preprocessResults( $db, $res ) {
79 parent::preprocessResults( $db, $res );
80
81 $this->currentCategoryCounts = [];
82
83 if ( !$res->numRows() || !$this->isCached() ) {
84 return;
85 }
86
87 // Fetch (hopefully) up-to-date numbers of pages in each category.
88 // This should be fast enough as we limit the list to a reasonable length.
89
90 $allCategories = [];
91 foreach ( $res as $row ) {
92 $allCategories[] = $row->title;
93 }
94
95 $categoryRes = $db->newSelectQueryBuilder()
96 ->select( [ 'cat_title', 'cat_pages' ] )
97 ->from( 'category' )
98 ->where( [ 'cat_title' => $allCategories ] )
99 ->caller( __METHOD__ )->fetchResultSet();
100 foreach ( $categoryRes as $row ) {
101 $this->currentCategoryCounts[$row->cat_title] = intval( $row->cat_pages );
102 }
103
104 // Back to start for display
105 $res->seek( 0 );
106 }
107
113 public function formatResult( $skin, $result ) {
114 $nt = Title::makeTitle( $result->namespace, $result->title );
115
116 $text = new HtmlArmor( $this->languageConverter->convertHtml( $nt->getText() ) );
117
118 if ( !$this->isCached() ) {
119 // We can assume the freshest data
120 $plink = $this->getLinkRenderer()->makeBrokenLink(
121 $nt,
122 $text
123 );
124 $nlinks = $this->msg( 'nmembers' )->numParams( $result->value )->escaped();
125 } else {
126 $plink = $this->getLinkRenderer()->makeLink( $nt, $text );
127
128 $currentValue = $this->currentCategoryCounts[$result->title] ?? 0;
129 $cachedValue = intval( $result->value ); // T76910
130
131 // If the category has been created or emptied since the list was refreshed, strike it
132 if ( $nt->isKnown() || $currentValue === 0 ) {
133 $plink = "<del>$plink</del>";
134 }
135
136 // Show the current number of category entries if it changed
137 if ( $currentValue !== $cachedValue ) {
138 $nlinks = $this->msg( 'nmemberschanged' )
139 ->numParams( $cachedValue, $currentValue )->escaped();
140 } else {
141 $nlinks = $this->msg( 'nmembers' )->numParams( $cachedValue )->escaped();
142 }
143 }
144
145 return $this->getLanguage()->specialList( $plink, $nlinks );
146 }
147
149 protected function getGroupName() {
150 return 'maintenance';
151 }
152}
153
158class_alias( SpecialWantedCategories::class, 'SpecialWantedCategories' );
const NS_CATEGORY
Definition Defines.php:65
makeTitle( $linkId)
Convert a link ID to a Title.to override Title
Service for compat reading of links tables.
The base class for all skins.
Definition Skin.php:52
setDatabaseProvider(IConnectionProvider $databaseProvider)
isCached()
Whether or not the output of the page in question is retrieved from the database cache.
setLinkBatchFactory(LinkBatchFactory $linkBatchFactory)
msg( $key,... $params)
Wrapper around wfMessage that sets the current context.
getContentLanguage()
Shortcut to get content language.
getLanguage()
Shortcut to get user's language.
Base class for a "wanted" query page like WantedPages, WantedTemplates, etc.
preprocessResults( $db, $res)
Cache page existence for performance.to override
__construct(IConnectionProvider $dbProvider, LinkBatchFactory $linkBatchFactory, LanguageConverterFactory $languageConverterFactory, LinksMigration $linksMigration)
getGroupName()
Under which header this special page is listed in Special:SpecialPages See messages 'specialpages-gro...
getQueryInfo()
Subclasses return an SQL query here, formatted as an array with the following keys: tables => Table(s...
getRecacheDB()
Get a DB connection to be used for slow recache queries.to override IReadableDatabase
Represents a title within MediaWiki.
Definition Title.php:70
Marks HTML that shouldn't be escaped.
Definition HtmlArmor.php:18
The shared interface for all language converters.
Provide primary and replica IDatabase connections.