66 private array $redirectTargets = [];
73 parent::__construct(
'BrokenRedirects' );
74 $this->contentHandlerFactory = $contentHandlerFactory;
92 return $this->
msg(
'brokenredirectstext' )->parseAsBlock();
105 'namespace' =>
'p1.page_namespace',
106 'title' =>
'p1.page_title',
114 $dbr->expr(
'rd_namespace',
'>=', 0 ),
115 'rd_interwiki' =>
'',
116 'p2.page_namespace' =>
null,
120 'rd_from=p1.page_id',
122 'p2' => [
'LEFT JOIN', [
123 'rd_namespace=p2.page_namespace',
124 'rd_title=p2.page_title'
134 return [
'rd_namespace',
'rd_title',
'rd_from' ];
144 if ( !$res->numRows() ) {
150 foreach ( $res as $row ) {
152 $batch->add( $row->namespace, $row->title );
155 $batch->add( $row->rd_namespace, $row->rd_title );
160 $rdRes = $db->newSelectQueryBuilder()
161 ->select( [
'page_namespace',
'page_title',
'rd_namespace',
'rd_title',
'rd_fragment' ] )
163 ->join(
'redirect',
null,
'page_id = rd_from' )
164 ->where( $batch->constructSet(
'page', $db ) )
165 ->caller( __METHOD__ )
168 foreach ( $rdRes as $rdRow ) {
169 $batch->add( $rdRow->rd_namespace, $rdRow->rd_title );
170 $this->redirectTargets[$rdRow->page_namespace][$rdRow->page_title] =
171 Title::makeTitle( $rdRow->rd_namespace, $rdRow->rd_title, $rdRow->rd_fragment );
180 if ( isset( $result->rd_title ) ) {
181 return Title::makeTitle(
182 $result->rd_namespace,
187 return $this->redirectTargets[$result->namespace][$result->title] ??
null;
197 $fromObj = Title::makeTitle( $result->namespace, $result->title );
198 $toObj = $this->getRedirectTarget( $result );
200 $linkRenderer = $this->getLinkRenderer();
202 if ( $toObj ===
null || $toObj->isKnown() ) {
203 return '<del>' . $linkRenderer->makeLink( $fromObj ) .
'</del>';
206 $from = $linkRenderer->makeKnownLink(
210 [
'redirect' =>
'no' ]
216 $this->getAuthority()->isAllowed(
'edit' ) &&
218 $this->contentHandlerFactory->getContentHandler( $fromObj->getContentModel() )
219 ->supportsDirectEditing()
221 $links[] = $linkRenderer->makeKnownLink(
223 $this->msg(
'brokenredirects-edit' )->text(),
225 [
'action' =>
'edit' ]
228 $to = $linkRenderer->makeBrokenLink( $toObj, $toObj->getFullText() );
229 $arr = $this->getLanguage()->getArrow();
231 $out = $from . $this->msg(
'word-separator' )->escaped();
233 if ( $this->getAuthority()->isAllowed(
'delete' ) ) {
234 $links[] = $linkRenderer->makeKnownLink(
236 $this->msg(
'brokenredirects-delete' )->text(),
239 'action' =>
'delete',
240 'wpReason' => $this->msg(
'brokenredirects-delete-reason' )
241 ->inContentLanguage()
248 $out .= $this->msg(
'parentheses' )->rawParams( $this->getLanguage()
249 ->pipeList( $links ) )->escaped();
251 $out .=
" {$arr} {$to}";
257 $this->addHelpLink(
'Help:Redirects' );
258 parent::execute( $par );
262 return 'maintenance';
267class_alias( SpecialBrokenRedirects::class,
'SpecialBrokenRedirects' );
if(!defined('MW_SETUP_CALLBACK'))
This is a class for doing query pages; since they're almost all the same, we factor out some of the f...
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.