Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
30.19% covered (danger)
30.19%
16 / 53
20.00% covered (danger)
20.00%
1 / 5
CRAP
0.00% covered (danger)
0.00%
0 / 1
LinksMigration
30.19% covered (danger)
30.19%
16 / 53
20.00% covered (danger)
20.00%
1 / 5
60.99
0.00% covered (danger)
0.00%
0 / 1
 __construct
100.00% covered (success)
100.00%
2 / 2
100.00% covered (success)
100.00%
1 / 1
1
 getLinksConditions
91.67% covered (success)
91.67%
11 / 12
0.00% covered (danger)
0.00%
0 / 1
3.01
 getQueryInfo
0.00% covered (danger)
0.00%
0 / 26
0.00% covered (danger)
0.00%
0 / 1
12
 getTitleFields
0.00% covered (danger)
0.00%
0 / 4
0.00% covered (danger)
0.00%
0 / 1
6
 assertMapping
33.33% covered (danger)
33.33%
3 / 9
0.00% covered (danger)
0.00%
0 / 1
5.67
1<?php
2/**
3 * This program is free software; you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License as published by
5 * the Free Software Foundation; either version 2 of the License, or
6 * (at your option) any later version.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License along
14 * with this program; if not, write to the Free Software Foundation, Inc.,
15 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
16 * http://www.gnu.org/copyleft/gpl.html
17 *
18 * @file
19 */
20
21namespace MediaWiki\Linker;
22
23use InvalidArgumentException;
24use MediaWiki\Config\Config;
25use MediaWiki\MainConfigNames;
26
27/**
28 * Service for compat reading of links tables
29 *
30 * @since 1.39
31 */
32class LinksMigration {
33
34    /** @var Config */
35    private $config;
36
37    /** @var LinkTargetLookup */
38    private $linkTargetLookup;
39
40    public static $mapping = [
41        'templatelinks' => [
42            'config' => MainConfigNames::TemplateLinksSchemaMigrationStage,
43            'page_id' => 'tl_from',
44            'ns' => 'tl_namespace',
45            'title' => 'tl_title',
46            'target_id' => 'tl_target_id',
47            'deprecated_configs' => [ SCHEMA_COMPAT_OLD ],
48        ],
49        'pagelinks' => [
50            'config' => MainConfigNames::PageLinksSchemaMigrationStage,
51            'page_id' => 'pl_from',
52            'ns' => 'pl_namespace',
53            'title' => 'pl_title',
54            'target_id' => 'pl_target_id',
55            'deprecated_configs' => [],
56        ],
57    ];
58
59    public static $prefixToTableMapping = [
60        'tl' => 'templatelinks',
61        'pl' => 'pagelinks',
62    ];
63
64    /**
65     * @param Config $config
66     * @param LinkTargetLookup $linktargetLookup
67     */
68    public function __construct( Config $config, LinkTargetLookup $linktargetLookup ) {
69        $this->config = $config;
70        $this->linkTargetLookup = $linktargetLookup;
71    }
72
73    /**
74     * Return the conditions to be used in querying backlinks to a page
75     *
76     * @param string $table
77     * @param LinkTarget $linkTarget
78     * @return array
79     */
80    public function getLinksConditions( string $table, LinkTarget $linkTarget ): array {
81        $this->assertMapping( $table );
82        if ( $this->config->get( self::$mapping[$table]['config'] ) & SCHEMA_COMPAT_READ_NEW ) {
83            $targetId = $this->linkTargetLookup->getLinkTargetId( $linkTarget );
84            // Not found, it shouldn't pick anything
85            if ( !$targetId ) {
86                return [ '1=0' ];
87            }
88            return [
89                self::$mapping[$table]['target_id'] => $targetId,
90            ];
91        } else {
92            return [
93                self::$mapping[$table]['ns'] => $linkTarget->getNamespace(),
94                self::$mapping[$table]['title'] => $linkTarget->getDBkey(),
95            ];
96        }
97    }
98
99    /**
100     * Return the query to be used when you want to or from a group of pages
101     *
102     * @param string $table
103     * @param string $joinTable table to end the join chain. Most of the time it's linktarget
104     * @param string $joinType
105     * @return array
106     */
107    public function getQueryInfo( string $table, string $joinTable = 'linktarget', string $joinType = 'JOIN' ) {
108        $this->assertMapping( $table );
109        if ( $this->config->get( self::$mapping[$table]['config'] ) & SCHEMA_COMPAT_READ_NEW ) {
110            $targetId = self::$mapping[$table]['target_id'];
111            if ( $joinTable === 'linktarget' ) {
112                $tables = [ $table, 'linktarget' ];
113            } else {
114                $tables = [ 'linktarget', $table ];
115            }
116            return [
117                'tables' => $tables,
118                'fields' => [
119                    $targetId,
120                    'lt_namespace',
121                    'lt_title'
122                ],
123                'joins' => [ $joinTable => [
124                    $joinType,
125                    [ "$targetId=lt_id" ]
126                ] ],
127            ];
128        } else {
129            return [
130                'fields' => [
131                    self::$mapping[$table]['ns'],
132                    self::$mapping[$table]['title']
133                ],
134                'tables' => [ $table ],
135                'joins' => [],
136            ];
137        }
138    }
139
140    public function getTitleFields( $table ) {
141        $this->assertMapping( $table );
142
143        if ( $this->config->get( self::$mapping[$table]['config'] ) & SCHEMA_COMPAT_READ_NEW ) {
144            return [ 'lt_namespace', 'lt_title' ];
145        } else {
146            return [ self::$mapping[$table]['ns'], self::$mapping[$table]['title'] ];
147        }
148    }
149
150    private function assertMapping( string $table ) {
151        if ( !isset( self::$mapping[$table] ) ) {
152            throw new InvalidArgumentException(
153                "LinksMigration doesn't support the $table table yet"
154            );
155        }
156
157        $config = $this->config->get( self::$mapping[$table]['config'] );
158        if ( in_array( $config, self::$mapping[$table]['deprecated_configs'] ) ) {
159            throw new InvalidArgumentException(
160                "LinksMigration config $config on $table table is not supported anymore"
161            );
162        }
163    }
164}