Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
0.00% covered (danger)
0.00%
0 / 115
0.00% covered (danger)
0.00%
0 / 6
CRAP
0.00% covered (danger)
0.00%
0 / 1
ApiQueryIWLinks
0.00% covered (danger)
0.00%
0 / 114
0.00% covered (danger)
0.00%
0 / 6
462
0.00% covered (danger)
0.00%
0 / 1
 __construct
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 execute
0.00% covered (danger)
0.00%
0 / 73
0.00% covered (danger)
0.00%
0 / 1
272
 getCacheMode
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 getAllowedParams
0.00% covered (danger)
0.00%
0 / 32
0.00% covered (danger)
0.00%
0 / 1
2
 getExamplesMessages
0.00% covered (danger)
0.00%
0 / 6
0.00% covered (danger)
0.00%
0 / 1
2
 getHelpUrls
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
1<?php
2/**
3 * API for MediaWiki 1.17+
4 *
5 * Copyright © 2010 Sam Reed
6 * Copyright © 2006 Yuri Astrakhan "<Firstname><Lastname>@gmail.com"
7 *
8 * @license GPL-2.0-or-later
9 * @file
10 */
11
12namespace MediaWiki\Api;
13
14use MediaWiki\Deferred\LinksUpdate\InterwikiLinksTable;
15use MediaWiki\Title\Title;
16use MediaWiki\Utils\UrlUtils;
17use Wikimedia\ParamValidator\ParamValidator;
18use Wikimedia\ParamValidator\TypeDef\IntegerDef;
19
20/**
21 * A query module to list all interwiki links on a page
22 *
23 * @ingroup API
24 */
25class ApiQueryIWLinks extends ApiQueryBase {
26
27    public function __construct(
28        ApiQuery $query,
29        string $moduleName,
30        private readonly UrlUtils $urlUtils,
31    ) {
32        parent::__construct( $query, $moduleName, 'iw' );
33    }
34
35    public function execute() {
36        $pages = $this->getPageSet()->getGoodPages();
37        if ( $pages === [] ) {
38            return;
39        }
40
41        $params = $this->extractRequestParams();
42        $prop = array_fill_keys( (array)$params['prop'], true );
43
44        if ( isset( $params['title'] ) && !isset( $params['prefix'] ) ) {
45            $this->dieWithError(
46                [
47                    'apierror-invalidparammix-mustusewith',
48                    $this->encodeParamName( 'title' ),
49                    $this->encodeParamName( 'prefix' ),
50                ],
51                'invalidparammix'
52            );
53        }
54
55        // Handle deprecated param
56        $this->requireMaxOneParameter( $params, 'url', 'prop' );
57        if ( $params['url'] ) {
58            $prop = [ 'url' => 1 ];
59        }
60
61        $this->setVirtualDomain( InterwikiLinksTable::VIRTUAL_DOMAIN );
62
63        $this->addFields( [
64            'iwl_from',
65            'iwl_prefix',
66            'iwl_title'
67        ] );
68        $this->addTables( 'iwlinks' );
69        $this->addWhereFld( 'iwl_from', array_keys( $pages ) );
70
71        if ( $params['continue'] !== null ) {
72            $cont = $this->parseContinueParamOrDie( $params['continue'], [ 'int', 'string', 'string' ] );
73            $op = $params['dir'] == 'descending' ? '<=' : '>=';
74            $this->addWhere( $this->getDB()->buildComparison( $op, [
75                'iwl_from' => $cont[0],
76                'iwl_prefix' => $cont[1],
77                'iwl_title' => $cont[2],
78            ] ) );
79        }
80
81        $sort = ( $params['dir'] == 'descending' ? ' DESC' : '' );
82        if ( isset( $params['prefix'] ) ) {
83            $this->addWhereFld( 'iwl_prefix', $params['prefix'] );
84            if ( isset( $params['title'] ) ) {
85                $this->addWhereFld( 'iwl_title', $params['title'] );
86                $this->addOption( 'ORDER BY', 'iwl_from' . $sort );
87            } else {
88                $this->addOption( 'ORDER BY', [
89                    'iwl_from' . $sort,
90                    'iwl_title' . $sort
91                ] );
92            }
93        } else {
94            // Don't order by iwl_from if it's constant in the WHERE clause
95            if ( count( $pages ) === 1 ) {
96                $this->addOption( 'ORDER BY', 'iwl_prefix' . $sort );
97            } else {
98                $this->addOption( 'ORDER BY', [
99                    'iwl_from' . $sort,
100                    'iwl_prefix' . $sort,
101                    'iwl_title' . $sort
102                ] );
103            }
104        }
105
106        $this->addOption( 'LIMIT', $params['limit'] + 1 );
107        $res = $this->select( __METHOD__ );
108
109        $count = 0;
110        foreach ( $res as $row ) {
111            if ( ++$count > $params['limit'] ) {
112                // We've reached the one extra which shows that
113                // there are additional pages to be had. Stop here...
114                $this->setContinueEnumParameter(
115                    'continue',
116                    "{$row->iwl_from}|{$row->iwl_prefix}|{$row->iwl_title}"
117                );
118                break;
119            }
120            $entry = [ 'prefix' => $row->iwl_prefix ];
121
122            if ( isset( $prop['url'] ) ) {
123                $title = Title::newFromText( "{$row->iwl_prefix}:{$row->iwl_title}" );
124                if ( $title ) {
125                    $entry['url'] = (string)$this->urlUtils->expand( $title->getFullURL(), PROTO_CURRENT );
126                }
127            }
128
129            ApiResult::setContentValue( $entry, 'title', $row->iwl_title );
130            $fit = $this->addPageSubItem( $row->iwl_from, $entry );
131            if ( !$fit ) {
132                $this->setContinueEnumParameter(
133                    'continue',
134                    "{$row->iwl_from}|{$row->iwl_prefix}|{$row->iwl_title}"
135                );
136                break;
137            }
138        }
139    }
140
141    /** @inheritDoc */
142    public function getCacheMode( $params ) {
143        return 'public';
144    }
145
146    /** @inheritDoc */
147    public function getAllowedParams() {
148        return [
149            'prop' => [
150                ParamValidator::PARAM_ISMULTI => true,
151                ParamValidator::PARAM_TYPE => [
152                    'url',
153                ],
154                ApiBase::PARAM_HELP_MSG_PER_VALUE => [],
155            ],
156            'prefix' => null,
157            'title' => null,
158            'dir' => [
159                ParamValidator::PARAM_DEFAULT => 'ascending',
160                ParamValidator::PARAM_TYPE => [
161                    'ascending',
162                    'descending'
163                ]
164            ],
165            'limit' => [
166                ParamValidator::PARAM_DEFAULT => 10,
167                ParamValidator::PARAM_TYPE => 'limit',
168                IntegerDef::PARAM_MIN => 1,
169                IntegerDef::PARAM_MAX => ApiBase::LIMIT_BIG1,
170                IntegerDef::PARAM_MAX2 => ApiBase::LIMIT_BIG2
171            ],
172            'continue' => [
173                ApiBase::PARAM_HELP_MSG => 'api-help-param-continue',
174            ],
175            'url' => [
176                ParamValidator::PARAM_DEFAULT => false,
177                ParamValidator::PARAM_DEPRECATED => true,
178            ],
179        ];
180    }
181
182    /** @inheritDoc */
183    protected function getExamplesMessages() {
184        $title = Title::newMainPage()->getPrefixedText();
185        $mp = rawurlencode( $title );
186
187        return [
188            "action=query&prop=iwlinks&titles={$mp}"
189                => 'apihelp-query+iwlinks-example-simple',
190        ];
191    }
192
193    /** @inheritDoc */
194    public function getHelpUrls() {
195        return 'https://www.mediawiki.org/wiki/Special:MyLanguage/API:Iwlinks';
196    }
197}
198
199/** @deprecated class alias since 1.43 */
200class_alias( ApiQueryIWLinks::class, 'ApiQueryIWLinks' );