MediaWiki 1.40.4
SpecialBrokenRedirects.php
Go to the documentation of this file.
1<?php
30
38
40 private $contentHandlerFactory;
41
47 public function __construct(
48 IContentHandlerFactory $contentHandlerFactory,
49 ILoadBalancer $loadBalancer,
50 LinkBatchFactory $linkBatchFactory
51 ) {
52 parent::__construct( 'BrokenRedirects' );
53 $this->contentHandlerFactory = $contentHandlerFactory;
54 $this->setDBLoadBalancer( $loadBalancer );
55 $this->setLinkBatchFactory( $linkBatchFactory );
56 }
57
58 public function isExpensive() {
59 return true;
60 }
61
62 public function isSyndicated() {
63 return false;
64 }
65
66 protected function sortDescending() {
67 return false;
68 }
69
70 protected function getPageHeader() {
71 return $this->msg( 'brokenredirectstext' )->parseAsBlock();
72 }
73
74 public function getQueryInfo() {
75 $dbr = $this->getDBLoadBalancer()->getConnectionRef( ILoadBalancer::DB_REPLICA );
76
77 return [
78 'tables' => [
79 'redirect',
80 'p1' => 'page',
81 'p2' => 'page',
82 ],
83 'fields' => [
84 'namespace' => 'p1.page_namespace',
85 'title' => 'p1.page_title',
86 'rd_namespace',
87 'rd_title',
88 'rd_fragment',
89 ],
90 'conds' => [
91 // Exclude pages that don't exist locally as wiki pages,
92 // but aren't "broken" either.
93 // Special pages and interwiki links
94 'rd_namespace >= 0',
95 'rd_interwiki IS NULL OR rd_interwiki = ' . $dbr->addQuotes( '' ),
96 'p2.page_namespace IS NULL',
97 ],
98 'join_conds' => [
99 'p1' => [ 'JOIN', [
100 'rd_from=p1.page_id',
101 ] ],
102 'p2' => [ 'LEFT JOIN', [
103 'rd_namespace=p2.page_namespace',
104 'rd_title=p2.page_title'
105 ] ],
106 ],
107 ];
108 }
109
113 protected function getOrderFields() {
114 return [ 'rd_namespace', 'rd_title', 'rd_from' ];
115 }
116
122 public function formatResult( $skin, $result ) {
123 $fromObj = Title::makeTitle( $result->namespace, $result->title );
124 if ( isset( $result->rd_title ) ) {
125 $toObj = Title::makeTitle(
126 $result->rd_namespace,
127 $result->rd_title,
128 $result->rd_fragment ?? ''
129 );
130 } else {
131 $blinks = $fromObj->getBrokenLinksFrom(); # TODO: check for redirect, not for links
132 if ( $blinks ) {
133 $toObj = $blinks[0];
134 } else {
135 $toObj = false;
136 }
137 }
138
139 $linkRenderer = $this->getLinkRenderer();
140
141 // $toObj may very easily be false if the $result list is cached
142 if ( !is_object( $toObj ) ) {
143 return '<del>' . $linkRenderer->makeLink( $fromObj ) . '</del>';
144 }
145
146 $from = $linkRenderer->makeKnownLink(
147 $fromObj,
148 null,
149 [],
150 [ 'redirect' => 'no' ]
151 );
152 $links = [];
153 // if the page is editable, add an edit link
154 if (
155 // check user permissions
156 $this->getAuthority()->isAllowed( 'edit' ) &&
157 // check, if the content model is editable through action=edit
158 $this->contentHandlerFactory->getContentHandler( $fromObj->getContentModel() )
159 ->supportsDirectEditing()
160 ) {
161 $links[] = $linkRenderer->makeKnownLink(
162 $fromObj,
163 $this->msg( 'brokenredirects-edit' )->text(),
164 [],
165 [ 'action' => 'edit' ]
166 );
167 }
168 $to = $linkRenderer->makeBrokenLink( $toObj, $toObj->getFullText() );
169 $arr = $this->getLanguage()->getArrow();
170
171 $out = $from . $this->msg( 'word-separator' )->escaped();
172
173 if ( $this->getAuthority()->isAllowed( 'delete' ) ) {
174 $links[] = $linkRenderer->makeKnownLink(
175 $fromObj,
176 $this->msg( 'brokenredirects-delete' )->text(),
177 [],
178 [
179 'action' => 'delete',
180 'wpReason' => $this->msg( 'brokenredirects-delete-reason' )
181 ->inContentLanguage()
182 ->text()
183 ]
184 );
185 }
186
187 if ( $links ) {
188 $out .= $this->msg( 'parentheses' )->rawParams( $this->getLanguage()
189 ->pipeList( $links ) )->escaped();
190 }
191 $out .= " {$arr} {$to}";
192
193 return $out;
194 }
195
196 public function execute( $par ) {
197 $this->addHelpLink( 'Help:Redirects' );
198 parent::execute( $par );
199 }
200
207 public function preprocessResults( $db, $res ) {
209 }
210
211 protected function getGroupName() {
212 return 'maintenance';
213 }
214}
Represents a title within MediaWiki.
Definition Title.php:82
This is a class for doing query pages; since they're almost all the same, we factor out some of the f...
Definition QueryPage.php:45
executeLBFromResultWrapper(IResultWrapper $res, $ns=null)
Creates a new LinkBatch object, adds all pages from the passed result wrapper (MUST include title and...
setDBLoadBalancer(ILoadBalancer $loadBalancer)
setLinkBatchFactory(LinkBatchFactory $linkBatchFactory)
getDBLoadBalancer()
A special page listing redirects to non existent page.
preprocessResults( $db, $res)
Cache page content model for performance.
isSyndicated()
Sometimes we don't want to build rss / atom feeds.
getQueryInfo()
Subclasses return an SQL query here, formatted as an array with the following keys: tables => Table(s...
execute( $par)
This is the actual workhorse.
getGroupName()
Under which header this special page is listed in Special:SpecialPages See messages 'specialpages-gro...
sortDescending()
Override to sort by increasing values.
isExpensive()
Should this query page only be updated offline on large wikis?
__construct(IContentHandlerFactory $contentHandlerFactory, ILoadBalancer $loadBalancer, LinkBatchFactory $linkBatchFactory)
getPageHeader()
The content returned by this function will be output before any result.
msg( $key,... $params)
Wrapper around wfMessage that sets the current context.
getAuthority()
Shortcut to get the Authority executing this instance.
getLanguage()
Shortcut to get user's language.
addHelpLink( $to, $overrideBaseUrl=false)
Adds help link with an icon via page indicators.
Basic database interface for live and lazy-loaded relation database handles.
Definition IDatabase.php:36
This class is a delegate to ILBFactory for a given database cluster.
Result wrapper for grabbing data queried from an IDatabase object.