Code Coverage |
||||||||||
Lines |
Functions and Methods |
Classes and Traits |
||||||||
Total | |
28.07% |
16 / 57 |
|
33.33% |
2 / 6 |
CRAP | |
0.00% |
0 / 1 |
LinksMigration | |
28.07% |
16 / 57 |
|
33.33% |
2 / 6 |
124.55 | |
0.00% |
0 / 1 |
__construct | |
100.00% |
2 / 2 |
|
100.00% |
1 / 1 |
1 | |||
getLinksConditions | |
58.33% |
7 / 12 |
|
0.00% |
0 / 1 |
3.65 | |||
getQueryInfo | |
0.00% |
0 / 26 |
|
0.00% |
0 / 1 |
12 | |||
getTitleFields | |
0.00% |
0 / 4 |
|
0.00% |
0 / 1 |
6 | |||
isMigrationReadNew | |
100.00% |
2 / 2 |
|
100.00% |
1 / 1 |
2 | |||
assertMapping | |
45.45% |
5 / 11 |
|
0.00% |
0 / 1 |
11.84 |
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 | |
21 | namespace MediaWiki\Linker; |
22 | |
23 | use InvalidArgumentException; |
24 | use MediaWiki\Config\Config; |
25 | use MediaWiki\MainConfigNames; |
26 | |
27 | /** |
28 | * Service for compat reading of links tables |
29 | * |
30 | * @since 1.39 |
31 | */ |
32 | class LinksMigration { |
33 | |
34 | /** @var Config */ |
35 | private $config; |
36 | |
37 | /** @var LinkTargetLookup */ |
38 | private $linkTargetLookup; |
39 | |
40 | /** @var array[] */ |
41 | public static $mapping = [ |
42 | 'templatelinks' => [ |
43 | 'config' => -1, |
44 | 'page_id' => 'tl_from', |
45 | // Used by the updater only |
46 | 'ns' => 'tl_namespace', |
47 | // Used by the updater only |
48 | 'title' => 'tl_title', |
49 | 'target_id' => 'tl_target_id', |
50 | 'deprecated_configs' => [], |
51 | ], |
52 | 'pagelinks' => [ |
53 | 'config' => MainConfigNames::PageLinksSchemaMigrationStage, |
54 | 'page_id' => 'pl_from', |
55 | 'ns' => 'pl_namespace', |
56 | 'title' => 'pl_title', |
57 | 'target_id' => 'pl_target_id', |
58 | 'deprecated_configs' => [ |
59 | SCHEMA_COMPAT_WRITE_OLD, |
60 | SCHEMA_COMPAT_READ_OLD |
61 | ], |
62 | ], |
63 | 'categorylinks' => [ |
64 | 'config' => MainConfigNames::CategoryLinksSchemaMigrationStage, |
65 | 'page_id' => 'cl_from', |
66 | 'ns' => 14, |
67 | 'title' => 'cl_to', |
68 | 'target_id' => 'cl_target_id', |
69 | 'deprecated_configs' => [], |
70 | ], |
71 | ]; |
72 | |
73 | /** @var string[] */ |
74 | public static $prefixToTableMapping = [ |
75 | 'tl' => 'templatelinks', |
76 | 'pl' => 'pagelinks', |
77 | 'cl' => 'categorylinks', |
78 | ]; |
79 | |
80 | public function __construct( Config $config, LinkTargetLookup $linktargetLookup ) { |
81 | $this->config = $config; |
82 | $this->linkTargetLookup = $linktargetLookup; |
83 | } |
84 | |
85 | /** |
86 | * Return the conditions to be used in querying backlinks to a page |
87 | * |
88 | * @param string $table |
89 | * @param LinkTarget $linkTarget |
90 | * @return array |
91 | */ |
92 | public function getLinksConditions( string $table, LinkTarget $linkTarget ): array { |
93 | $this->assertMapping( $table ); |
94 | if ( $this->isMigrationReadNew( $table ) ) { |
95 | $targetId = $this->linkTargetLookup->getLinkTargetId( $linkTarget ); |
96 | // Not found, it shouldn't pick anything |
97 | if ( !$targetId ) { |
98 | return [ '1=0' ]; |
99 | } |
100 | return [ |
101 | self::$mapping[$table]['target_id'] => $targetId, |
102 | ]; |
103 | } else { |
104 | return [ |
105 | self::$mapping[$table]['ns'] => $linkTarget->getNamespace(), |
106 | self::$mapping[$table]['title'] => $linkTarget->getDBkey(), |
107 | ]; |
108 | } |
109 | } |
110 | |
111 | /** |
112 | * Return the query to be used when you want to or from a group of pages |
113 | * |
114 | * @param string $table |
115 | * @param string $joinTable table to end the join chain. Most of the time it's linktarget |
116 | * @param string $joinType |
117 | * @return array |
118 | */ |
119 | public function getQueryInfo( string $table, string $joinTable = 'linktarget', string $joinType = 'JOIN' ) { |
120 | $this->assertMapping( $table ); |
121 | if ( $this->isMigrationReadNew( $table ) ) { |
122 | $targetId = self::$mapping[$table]['target_id']; |
123 | if ( $joinTable === 'linktarget' ) { |
124 | $tables = [ $table, 'linktarget' ]; |
125 | } else { |
126 | $tables = [ 'linktarget', $table ]; |
127 | } |
128 | return [ |
129 | 'tables' => $tables, |
130 | 'fields' => [ |
131 | $targetId, |
132 | 'lt_namespace', |
133 | 'lt_title' |
134 | ], |
135 | 'joins' => [ $joinTable => [ |
136 | $joinType, |
137 | [ "$targetId=lt_id" ] |
138 | ] ], |
139 | ]; |
140 | } else { |
141 | return [ |
142 | 'fields' => [ |
143 | self::$mapping[$table]['ns'], |
144 | self::$mapping[$table]['title'] |
145 | ], |
146 | 'tables' => [ $table ], |
147 | 'joins' => [], |
148 | ]; |
149 | } |
150 | } |
151 | |
152 | public function getTitleFields( $table ) { |
153 | $this->assertMapping( $table ); |
154 | |
155 | if ( $this->isMigrationReadNew( $table ) ) { |
156 | return [ 'lt_namespace', 'lt_title' ]; |
157 | } else { |
158 | return [ self::$mapping[$table]['ns'], self::$mapping[$table]['title'] ]; |
159 | } |
160 | } |
161 | |
162 | private function isMigrationReadNew( string $table ): bool { |
163 | return self::$mapping[$table]['config'] === -1 || |
164 | $this->config->get( self::$mapping[$table]['config'] ) & SCHEMA_COMPAT_READ_NEW; |
165 | } |
166 | |
167 | private function assertMapping( string $table ) { |
168 | if ( !isset( self::$mapping[$table] ) ) { |
169 | throw new InvalidArgumentException( |
170 | "LinksMigration doesn't support the $table table yet" |
171 | ); |
172 | } |
173 | |
174 | if ( self::$mapping[$table]['config'] !== -1 && self::$mapping[$table]['deprecated_configs'] ) { |
175 | $config = $this->config->get( self::$mapping[$table]['config'] ); |
176 | foreach ( self::$mapping[$table]['deprecated_configs'] as $deprecatedConfig ) { |
177 | if ( $config & $deprecatedConfig ) { |
178 | throw new InvalidArgumentException( |
179 | "LinksMigration config $config on $table table is not supported anymore" |
180 | ); |
181 | } |
182 | } |
183 | |
184 | } |
185 | } |
186 | } |