Code Coverage |
||||||||||
Lines |
Functions and Methods |
Classes and Traits |
||||||||
Total | |
0.00% |
0 / 75 |
|
0.00% |
0 / 3 |
CRAP | |
0.00% |
0 / 1 |
UpdateRestrictions | |
0.00% |
0 / 72 |
|
0.00% |
0 / 3 |
132 | |
0.00% |
0 / 1 |
__construct | |
0.00% |
0 / 3 |
|
0.00% |
0 / 1 |
2 | |||
execute | |
0.00% |
0 / 58 |
|
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 | require_once __DIR__ . '/Maintenance.php'; |
28 | |
29 | /** |
30 | * Maintenance script that updates page_restrictions table from |
31 | * old page_restriction column. |
32 | * |
33 | * @ingroup Maintenance |
34 | */ |
35 | class UpdateRestrictions extends Maintenance { |
36 | public function __construct() { |
37 | parent::__construct(); |
38 | $this->addDescription( 'Updates page_restrictions table from old page_restriction column' ); |
39 | $this->setBatchSize( 1000 ); |
40 | } |
41 | |
42 | public function execute() { |
43 | $dbw = $this->getDB( DB_PRIMARY ); |
44 | $batchSize = $this->getBatchSize(); |
45 | |
46 | if ( !$dbw->tableExists( 'page_restrictions', __METHOD__ ) ) { |
47 | $this->fatalError( "page_restrictions table does not exist" ); |
48 | } |
49 | |
50 | if ( !$dbw->fieldExists( 'page', 'page_restrictions' ) ) { |
51 | $this->output( "Migration is not needed.\n" ); |
52 | return true; |
53 | } |
54 | |
55 | $encodedExpiry = $dbw->getInfinity(); |
56 | |
57 | $maxPageId = $dbw->newSelectQueryBuilder() |
58 | ->select( 'MAX(page_id)' ) |
59 | ->from( 'page' ) |
60 | ->caller( __METHOD__ )->fetchField(); |
61 | $escapedEmptyBlobValue = $dbw->addQuotes( '' ); |
62 | |
63 | $batchMinPageId = 0; |
64 | |
65 | do { |
66 | $batchMaxPageId = $batchMinPageId + $batchSize; |
67 | |
68 | $this->output( "...processing page IDs from $batchMinPageId to $batchMaxPageId.\n" ); |
69 | |
70 | $res = $dbw->newSelectQueryBuilder() |
71 | ->select( [ 'page_id', 'page_restrictions' ] ) |
72 | ->from( 'page' ) |
73 | ->where( [ |
74 | "page_restrictions != $escapedEmptyBlobValue", |
75 | $dbw->expr( 'page_id', '>', $batchMinPageId ), |
76 | $dbw->expr( 'page_id', '<=', $batchMaxPageId ), |
77 | ] ) |
78 | ->caller( __METHOD__ )->fetchResultSet(); |
79 | |
80 | // No pages have legacy protection settings in the current batch |
81 | if ( !$res->numRows() ) { |
82 | $batchMinPageId = $batchMaxPageId; |
83 | continue; |
84 | } |
85 | |
86 | $batch = []; |
87 | $pageIds = []; |
88 | |
89 | foreach ( $res as $row ) { |
90 | $pageIds[] = $row->page_id; |
91 | |
92 | $restrictionsByAction = $this->mapLegacyRestrictionBlob( $row->page_restrictions ); |
93 | |
94 | # Update restrictions table |
95 | foreach ( $restrictionsByAction as $action => $restrictions ) { |
96 | $batch[] = [ |
97 | 'pr_page' => $row->page_id, |
98 | 'pr_type' => $action, |
99 | 'pr_level' => $restrictions, |
100 | 'pr_cascade' => 0, |
101 | 'pr_expiry' => $encodedExpiry |
102 | ]; |
103 | } |
104 | } |
105 | |
106 | $this->beginTransaction( $dbw, __METHOD__ ); |
107 | |
108 | // Insert new format protection settings for the pages in the current batch. |
109 | // Use INSERT IGNORE to ignore conflicts with new format settings that might exist for the page |
110 | $dbw->newInsertQueryBuilder() |
111 | ->insertInto( 'page_restrictions' ) |
112 | ->ignore() |
113 | ->rows( $batch ) |
114 | ->caller( __METHOD__ )->execute(); |
115 | |
116 | // Clear out the legacy page.page_restrictions blob for this batch |
117 | $dbw->newUpdateQueryBuilder() |
118 | ->update( 'page' ) |
119 | ->set( [ 'page_restrictions' => '' ] ) |
120 | ->where( [ 'page_id' => $pageIds ] ) |
121 | ->caller( __METHOD__ ) |
122 | ->execute(); |
123 | |
124 | $this->commitTransaction( $dbw, __METHOD__ ); |
125 | |
126 | $batchMinPageId = $batchMaxPageId; |
127 | } while ( $batchMaxPageId < $maxPageId ); |
128 | |
129 | $this->output( "...Done!\n" ); |
130 | return true; |
131 | } |
132 | |
133 | /** |
134 | * Convert a legacy restriction specification from the page.page_restrictions blob to |
135 | * a map of action names to restriction levels. |
136 | * |
137 | * @param string $legacyBlob Legacy page.page_restrictions blob, |
138 | * e.g. "sysop" or "edit=sysop:move=autoconfirmed" |
139 | * @return string[] array of restriction levels keyed by action names |
140 | */ |
141 | private function mapLegacyRestrictionBlob( $legacyBlob ) { |
142 | $oldRestrictions = []; |
143 | |
144 | foreach ( explode( ':', trim( $legacyBlob ) ) as $restrict ) { |
145 | $temp = explode( '=', trim( $restrict ) ); |
146 | |
147 | // Treat old old format without action name as edit/move restriction |
148 | if ( count( $temp ) == 1 ) { |
149 | $level = trim( $temp[0] ); |
150 | |
151 | $oldRestrictions['edit'] = $level; |
152 | $oldRestrictions['move'] = $level; |
153 | } else { |
154 | $restriction = trim( $temp[1] ); |
155 | // Some old entries are empty |
156 | if ( $restriction != '' ) { |
157 | $oldRestrictions[$temp[0]] = $restriction; |
158 | } |
159 | } |
160 | } |
161 | |
162 | return $oldRestrictions; |
163 | } |
164 | } |
165 | |
166 | $maintClass = UpdateRestrictions::class; |
167 | require_once RUN_MAINTENANCE_IF_MAIN; |