Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
0.00% covered (danger)
0.00%
0 / 65
0.00% covered (danger)
0.00%
0 / 11
CRAP
0.00% covered (danger)
0.00%
0 / 1
SpecialListRedirects
0.00% covered (danger)
0.00%
0 / 64
0.00% covered (danger)
0.00%
0 / 11
306
0.00% covered (danger)
0.00%
0 / 1
 __construct
0.00% covered (danger)
0.00%
0 / 5
0.00% covered (danger)
0.00%
0 / 1
2
 isExpensive
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 isSyndicated
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 sortDescending
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 getQueryInfo
0.00% covered (danger)
0.00%
0 / 14
0.00% covered (danger)
0.00%
0 / 1
2
 getOrderFields
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 preprocessResults
0.00% covered (danger)
0.00%
0 / 10
0.00% covered (danger)
0.00%
0 / 1
20
 getRedirectTarget
0.00% covered (danger)
0.00%
0 / 13
0.00% covered (danger)
0.00%
0 / 1
12
 formatResult
0.00% covered (danger)
0.00%
0 / 15
0.00% covered (danger)
0.00%
0 / 1
6
 execute
0.00% covered (danger)
0.00%
0 / 2
0.00% covered (danger)
0.00%
0 / 1
2
 getGroupName
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
1<?php
2/**
3 * Implements Special:Listredirects
4 *
5 * Copyright © 2006 Rob Church
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License along
18 * with this program; if not, write to the Free Software Foundation, Inc.,
19 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
20 * http://www.gnu.org/copyleft/gpl.html
21 *
22 * @file
23 * @ingroup SpecialPage
24 * @author Rob Church <robchur@gmail.com>
25 */
26
27namespace MediaWiki\Specials;
28
29use MediaWiki\Cache\LinkBatchFactory;
30use MediaWiki\Page\RedirectLookup;
31use MediaWiki\Page\WikiPageFactory;
32use MediaWiki\SpecialPage\QueryPage;
33use MediaWiki\Title\Title;
34use Skin;
35use stdClass;
36use Wikimedia\Rdbms\IConnectionProvider;
37use Wikimedia\Rdbms\IDatabase;
38use Wikimedia\Rdbms\IResultWrapper;
39
40/**
41 * Special:Listredirects - Lists all the redirects on the wiki.
42 * @ingroup SpecialPage
43 */
44class SpecialListRedirects extends QueryPage {
45
46    private LinkBatchFactory $linkBatchFactory;
47    private WikiPageFactory $wikiPageFactory;
48    private RedirectLookup $redirectLookup;
49
50    /**
51     * @param LinkBatchFactory $linkBatchFactory
52     * @param IConnectionProvider $dbProvider
53     * @param WikiPageFactory $wikiPageFactory
54     * @param RedirectLookup $redirectLookup
55     */
56    public function __construct(
57        LinkBatchFactory $linkBatchFactory,
58        IConnectionProvider $dbProvider,
59        WikiPageFactory $wikiPageFactory,
60        RedirectLookup $redirectLookup
61    ) {
62        parent::__construct( 'Listredirects' );
63        $this->linkBatchFactory = $linkBatchFactory;
64        $this->setDatabaseProvider( $dbProvider );
65        $this->wikiPageFactory = $wikiPageFactory;
66        $this->redirectLookup = $redirectLookup;
67    }
68
69    public function isExpensive() {
70        return true;
71    }
72
73    public function isSyndicated() {
74        return false;
75    }
76
77    protected function sortDescending() {
78        return false;
79    }
80
81    public function getQueryInfo() {
82        return [
83            'tables' => [ 'page', 'redirect' ],
84            'fields' => [ 'namespace' => 'page_namespace',
85                'title' => 'page_title',
86                'rd_namespace',
87                'rd_title',
88                'rd_fragment',
89                'rd_interwiki',
90            ],
91            'conds' => [ 'page_is_redirect' => 1 ],
92            'join_conds' => [ 'redirect' => [
93                'LEFT JOIN', 'rd_from=page_id' ],
94            ]
95        ];
96    }
97
98    protected function getOrderFields() {
99        return [ 'page_namespace', 'page_title' ];
100    }
101
102    /**
103     * Cache page existence for performance
104     *
105     * @param IDatabase $db
106     * @param IResultWrapper $res
107     */
108    public function preprocessResults( $db, $res ) {
109        if ( !$res->numRows() ) {
110            return;
111        }
112
113        $batch = $this->linkBatchFactory->newLinkBatch();
114        foreach ( $res as $row ) {
115            $batch->add( $row->namespace, $row->title );
116            $redirTarget = $this->getRedirectTarget( $row );
117            if ( $redirTarget ) {
118                $batch->addObj( $redirTarget );
119            }
120        }
121        $batch->execute();
122
123        // Back to start for display
124        $res->seek( 0 );
125    }
126
127    /**
128     * @param stdClass $row
129     * @return Title|null
130     */
131    protected function getRedirectTarget( $row ) {
132        if ( isset( $row->rd_title ) ) {
133            return Title::makeTitle(
134                $row->rd_namespace,
135                $row->rd_title,
136                $row->rd_fragment,
137                $row->rd_interwiki
138            );
139        } else {
140            $title = Title::makeTitle( $row->namespace, $row->title );
141            if ( !$title->canExist() ) {
142                return null;
143            }
144
145            return Title::castFromLinkTarget(
146                $this->redirectLookup->getRedirectTarget( $title )
147            );
148        }
149    }
150
151    /**
152     * @param Skin $skin
153     * @param stdClass $result Result row
154     * @return string
155     */
156    public function formatResult( $skin, $result ) {
157        $linkRenderer = $this->getLinkRenderer();
158        # Make a link to the redirect itself
159        $rd_title = Title::makeTitle( $result->namespace, $result->title );
160        $rd_link = $linkRenderer->makeLink(
161            $rd_title,
162            null,
163            [],
164            [ 'redirect' => 'no' ]
165        );
166
167        # Find out where the redirect leads
168        $target = $this->getRedirectTarget( $result );
169        if ( $target ) {
170            # Make a link to the destination page
171            $lang = $this->getLanguage();
172            $arr = $lang->getArrow() . $lang->getDirMark();
173            $targetLink = $linkRenderer->makeLink( $target, $target->getFullText() );
174
175            return "$rd_link $arr $targetLink";
176        } else {
177            return "<del>$rd_link</del>";
178        }
179    }
180
181    public function execute( $par ) {
182        $this->addHelpLink( 'Help:Redirects' );
183        parent::execute( $par );
184    }
185
186    protected function getGroupName() {
187        return 'pages';
188    }
189}
190
191/** @deprecated class alias since 1.41 */
192class_alias( SpecialListRedirects::class, 'SpecialListRedirects' );