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