Code Coverage |
||||||||||
Lines |
Functions and Methods |
Classes and Traits |
||||||||
Total | |
0.00% |
0 / 71 |
|
0.00% |
0 / 3 |
CRAP | |
0.00% |
0 / 1 |
UpdateRestrictions | |
0.00% |
0 / 71 |
|
0.00% |
0 / 3 |
132 | |
0.00% |
0 / 1 |
__construct | |
0.00% |
0 / 3 |
|
0.00% |
0 / 1 |
2 | |||
execute | |
0.00% |
0 / 57 |
|
0.00% |
0 / 1 |
42 | |||
mapLegacyRestrictionBlob | |
0.00% |
0 / 11 |
|
0.00% |
0 / 1 |
20 |
1 | <?php |
2 | /** |
3 | * Makes the required database updates for Special:ProtectedPages |
4 | * to show all protected pages, even ones before the page restrictions |
5 | * schema change. All remaining page_restriction column values are moved |
6 | * to the new table. |
7 | * |
8 | * This program is free software; you can redistribute it and/or modify |
9 | * it under the terms of the GNU General Public License as published by |
10 | * the Free Software Foundation; either version 2 of the License, or |
11 | * (at your option) any later version. |
12 | * |
13 | * This program is distributed in the hope that it will be useful, |
14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
16 | * GNU General Public License for more details. |
17 | * |
18 | * You should have received a copy of the GNU General Public License along |
19 | * with this program; if not, write to the Free Software Foundation, Inc., |
20 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. |
21 | * http://www.gnu.org/copyleft/gpl.html |
22 | * |
23 | * @file |
24 | * @ingroup Maintenance |
25 | */ |
26 | |
27 | use MediaWiki\Maintenance\Maintenance; |
28 | |
29 | // @codeCoverageIgnoreStart |
30 | require_once __DIR__ . '/Maintenance.php'; |
31 | // @codeCoverageIgnoreEnd |
32 | |
33 | /** |
34 | * Maintenance script that updates page_restrictions table from |
35 | * old page_restriction column. |
36 | * |
37 | * @ingroup Maintenance |
38 | */ |
39 | class UpdateRestrictions extends Maintenance { |
40 | public function __construct() { |
41 | parent::__construct(); |
42 | $this->addDescription( 'Updates page_restrictions table from old page_restriction column' ); |
43 | $this->setBatchSize( 1000 ); |
44 | } |
45 | |
46 | public function execute() { |
47 | $dbw = $this->getDB( DB_PRIMARY ); |
48 | $batchSize = $this->getBatchSize(); |
49 | |
50 | if ( !$dbw->tableExists( 'page_restrictions', __METHOD__ ) ) { |
51 | $this->fatalError( "page_restrictions table does not exist" ); |
52 | } |
53 | |
54 | if ( !$dbw->fieldExists( 'page', 'page_restrictions', __METHOD__ ) ) { |
55 | $this->output( "Migration is not needed.\n" ); |
56 | return true; |
57 | } |
58 | |
59 | $encodedExpiry = $dbw->getInfinity(); |
60 | |
61 | $maxPageId = $dbw->newSelectQueryBuilder() |
62 | ->select( 'MAX(page_id)' ) |
63 | ->from( 'page' ) |
64 | ->caller( __METHOD__ )->fetchField(); |
65 | |
66 | $batchMinPageId = 0; |
67 | |
68 | do { |
69 | $batchMaxPageId = $batchMinPageId + $batchSize; |
70 | |
71 | $this->output( "...processing page IDs from $batchMinPageId to $batchMaxPageId.\n" ); |
72 | |
73 | $res = $dbw->newSelectQueryBuilder() |
74 | ->select( [ 'page_id', 'page_restrictions' ] ) |
75 | ->from( 'page' ) |
76 | ->where( [ |
77 | $dbw->expr( 'page_restrictions', '!=', '' ), |
78 | $dbw->expr( 'page_id', '>', $batchMinPageId ), |
79 | $dbw->expr( 'page_id', '<=', $batchMaxPageId ), |
80 | ] ) |
81 | ->caller( __METHOD__ )->fetchResultSet(); |
82 | |
83 | // No pages have legacy protection settings in the current batch |
84 | if ( !$res->numRows() ) { |
85 | $batchMinPageId = $batchMaxPageId; |
86 | continue; |
87 | } |
88 | |
89 | $batch = []; |
90 | $pageIds = []; |
91 | |
92 | foreach ( $res as $row ) { |
93 | $pageIds[] = $row->page_id; |
94 | |
95 | $restrictionsByAction = $this->mapLegacyRestrictionBlob( $row->page_restrictions ); |
96 | |
97 | # Update restrictions table |
98 | foreach ( $restrictionsByAction as $action => $restrictions ) { |
99 | $batch[] = [ |
100 | 'pr_page' => $row->page_id, |
101 | 'pr_type' => $action, |
102 | 'pr_level' => $restrictions, |
103 | 'pr_cascade' => 0, |
104 | 'pr_expiry' => $encodedExpiry |
105 | ]; |
106 | } |
107 | } |
108 | |
109 | $this->beginTransaction( $dbw, __METHOD__ ); |
110 | |
111 | // Insert new format protection settings for the pages in the current batch. |
112 | // Use INSERT IGNORE to ignore conflicts with new format settings that might exist for the page |
113 | $dbw->newInsertQueryBuilder() |
114 | ->insertInto( 'page_restrictions' ) |
115 | ->ignore() |
116 | ->rows( $batch ) |
117 | ->caller( __METHOD__ )->execute(); |
118 | |
119 | // Clear out the legacy page.page_restrictions blob for this batch |
120 | $dbw->newUpdateQueryBuilder() |
121 | ->update( 'page' ) |
122 | ->set( [ 'page_restrictions' => '' ] ) |
123 | ->where( [ 'page_id' => $pageIds ] ) |
124 | ->caller( __METHOD__ ) |
125 | ->execute(); |
126 | |
127 | $this->commitTransaction( $dbw, __METHOD__ ); |
128 | |
129 | $batchMinPageId = $batchMaxPageId; |
130 | } while ( $batchMaxPageId < $maxPageId ); |
131 | |
132 | $this->output( "...Done!\n" ); |
133 | return true; |
134 | } |
135 | |
136 | /** |
137 | * Convert a legacy restriction specification from the page.page_restrictions blob to |
138 | * a map of action names to restriction levels. |
139 | * |
140 | * @param string $legacyBlob Legacy page.page_restrictions blob, |
141 | * e.g. "sysop" or "edit=sysop:move=autoconfirmed" |
142 | * @return string[] array of restriction levels keyed by action names |
143 | */ |
144 | private function mapLegacyRestrictionBlob( $legacyBlob ) { |
145 | $oldRestrictions = []; |
146 | |
147 | foreach ( explode( ':', trim( $legacyBlob ) ) as $restrict ) { |
148 | $temp = explode( '=', trim( $restrict ) ); |
149 | |
150 | // Treat old old format without action name as edit/move restriction |
151 | if ( count( $temp ) == 1 ) { |
152 | $level = trim( $temp[0] ); |
153 | |
154 | $oldRestrictions['edit'] = $level; |
155 | $oldRestrictions['move'] = $level; |
156 | } else { |
157 | $restriction = trim( $temp[1] ); |
158 | // Some old entries are empty |
159 | if ( $restriction != '' ) { |
160 | $oldRestrictions[$temp[0]] = $restriction; |
161 | } |
162 | } |
163 | } |
164 | |
165 | return $oldRestrictions; |
166 | } |
167 | } |
168 | |
169 | // @codeCoverageIgnoreStart |
170 | $maintClass = UpdateRestrictions::class; |
171 | require_once RUN_MAINTENANCE_IF_MAIN; |
172 | // @codeCoverageIgnoreEnd |