MediaWiki REL1_37
SpecialBrokenRedirects.php
Go to the documentation of this file.
1<?php
29
37
40
46 public function __construct(
50 ) {
51 parent::__construct( 'BrokenRedirects' );
52 $this->contentHandlerFactory = $contentHandlerFactory;
53 $this->setDBLoadBalancer( $loadBalancer );
54 $this->setLinkBatchFactory( $linkBatchFactory );
55 }
56
57 public function isExpensive() {
58 return true;
59 }
60
61 public function isSyndicated() {
62 return false;
63 }
64
65 protected function sortDescending() {
66 return false;
67 }
68
69 protected function getPageHeader() {
70 return $this->msg( 'brokenredirectstext' )->parseAsBlock();
71 }
72
73 public function getQueryInfo() {
74 $dbr = $this->getDBLoadBalancer()->getConnectionRef( ILoadBalancer::DB_REPLICA );
75
76 return [
77 'tables' => [
78 'redirect',
79 'p1' => 'page',
80 'p2' => 'page',
81 ],
82 'fields' => [
83 'namespace' => 'p1.page_namespace',
84 'title' => 'p1.page_title',
85 'rd_namespace',
86 'rd_title',
87 'rd_fragment',
88 ],
89 'conds' => [
90 // Exclude pages that don't exist locally as wiki pages,
91 // but aren't "broken" either.
92 // Special pages and interwiki links
93 'rd_namespace >= 0',
94 'rd_interwiki IS NULL OR rd_interwiki = ' . $dbr->addQuotes( '' ),
95 'p2.page_namespace IS NULL',
96 ],
97 'join_conds' => [
98 'p1' => [ 'JOIN', [
99 'rd_from=p1.page_id',
100 ] ],
101 'p2' => [ 'LEFT JOIN', [
102 'rd_namespace=p2.page_namespace',
103 'rd_title=p2.page_title'
104 ] ],
105 ],
106 ];
107 }
108
112 protected function getOrderFields() {
113 return [ 'rd_namespace', 'rd_title', 'rd_from' ];
114 }
115
121 public function formatResult( $skin, $result ) {
122 $fromObj = Title::makeTitle( $result->namespace, $result->title );
123 if ( isset( $result->rd_title ) ) {
124 $toObj = Title::makeTitle( $result->rd_namespace, $result->rd_title, $result->rd_fragment );
125 } else {
126 $blinks = $fromObj->getBrokenLinksFrom(); # TODO: check for redirect, not for links
127 if ( $blinks ) {
128 $toObj = $blinks[0];
129 } else {
130 $toObj = false;
131 }
132 }
133
135
136 // $toObj may very easily be false if the $result list is cached
137 if ( !is_object( $toObj ) ) {
138 return '<del>' . $linkRenderer->makeLink( $fromObj ) . '</del>';
139 }
140
142 $fromObj,
143 null,
144 [],
145 [ 'redirect' => 'no' ]
146 );
147 $links = [];
148 // if the page is editable, add an edit link
149 if (
150 // check user permissions
151 $this->getAuthority()->isAllowed( 'edit' ) &&
152 // check, if the content model is editable through action=edit
153 $this->contentHandlerFactory->getContentHandler( $fromObj->getContentModel() )
154 ->supportsDirectEditing()
155 ) {
156 $links[] = $linkRenderer->makeKnownLink(
157 $fromObj,
158 $this->msg( 'brokenredirects-edit' )->text(),
159 [],
160 [ 'action' => 'edit' ]
161 );
162 }
163 $to = $linkRenderer->makeBrokenLink( $toObj, $toObj->getFullText() );
164 $arr = $this->getLanguage()->getArrow();
165
166 $out = $from . $this->msg( 'word-separator' )->escaped();
167
168 if ( $this->getAuthority()->isAllowed( 'delete' ) ) {
169 $links[] = $linkRenderer->makeKnownLink(
170 $fromObj,
171 $this->msg( 'brokenredirects-delete' )->text(),
172 [],
173 [
174 'action' => 'delete',
175 'wpReason' => $this->msg( 'brokenredirects-delete-reason' )
176 ->inContentLanguage()
177 ->text()
178 ]
179 );
180 }
181
182 if ( $links ) {
183 $out .= $this->msg( 'parentheses' )->rawParams( $this->getLanguage()
184 ->pipeList( $links ) )->escaped();
185 }
186 $out .= " {$arr} {$to}";
187
188 return $out;
189 }
190
191 public function execute( $par ) {
192 $this->addHelpLink( 'Help:Redirects' );
193 parent::execute( $par );
194 }
195
202 public function preprocessResults( $db, $res ) {
204 }
205
206 protected function getGroupName() {
207 return 'maintenance';
208 }
209}
makeKnownLink( $target, $text=null, array $extraAttribs=[], array $query=[])
makeBrokenLink( $target, $text=null, array $extraAttribs=[], array $query=[])
makeLink( $target, $text=null, array $extraAttribs=[], array $query=[])
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:41
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)
LinkBatchFactory null $linkBatchFactory
Definition QueryPage.php:74
setLinkBatchFactory(LinkBatchFactory $linkBatchFactory)
getDBLoadBalancer()
ILoadBalancer null $loadBalancer
Definition QueryPage.php:71
A special page listing redirects to non existent page.
preprocessResults( $db, $res)
Cache page content model for performance.
isSyndicated()
Sometime 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()
Is this query expensive (for some definition of expensive)? Then we don't let it run in miser mode.
IContentHandlerFactory $contentHandlerFactory
__construct(IContentHandlerFactory $contentHandlerFactory, ILoadBalancer $loadBalancer, LinkBatchFactory $linkBatchFactory)
getPageHeader()
The content returned by this function will be output before any result.
LinkRenderer null $linkRenderer
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:38
Database cluster connection, tracking, load balancing, and transaction manager interface.
Result wrapper for grabbing data queried from an IDatabase object.