Localisation updates from https://translatewiki.net.
[mediawiki.git] / maintenance / updateRestrictions.php
blob6fc0b90c5d4402dd8c687491f334e66ef9d1199f
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.
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.
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.
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
23 * @file
24 * @ingroup Maintenance
27 use MediaWiki\Maintenance\Maintenance;
29 // @codeCoverageIgnoreStart
30 require_once __DIR__ . '/Maintenance.php';
31 // @codeCoverageIgnoreEnd
33 /**
34 * Maintenance script that updates page_restrictions table from
35 * old page_restriction column.
37 * @ingroup Maintenance
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 );
46 public function execute() {
47 $dbw = $this->getDB( DB_PRIMARY );
48 $batchSize = $this->getBatchSize();
50 if ( !$dbw->tableExists( 'page_restrictions', __METHOD__ ) ) {
51 $this->fatalError( "page_restrictions table does not exist" );
54 if ( !$dbw->fieldExists( 'page', 'page_restrictions', __METHOD__ ) ) {
55 $this->output( "Migration is not needed.\n" );
56 return true;
59 $encodedExpiry = $dbw->getInfinity();
61 $maxPageId = $dbw->newSelectQueryBuilder()
62 ->select( 'MAX(page_id)' )
63 ->from( 'page' )
64 ->caller( __METHOD__ )->fetchField();
66 $batchMinPageId = 0;
68 do {
69 $batchMaxPageId = $batchMinPageId + $batchSize;
71 $this->output( "...processing page IDs from $batchMinPageId to $batchMaxPageId.\n" );
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();
83 // No pages have legacy protection settings in the current batch
84 if ( !$res->numRows() ) {
85 $batchMinPageId = $batchMaxPageId;
86 continue;
89 $batch = [];
90 $pageIds = [];
92 foreach ( $res as $row ) {
93 $pageIds[] = $row->page_id;
95 $restrictionsByAction = $this->mapLegacyRestrictionBlob( $row->page_restrictions );
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
109 $this->beginTransaction( $dbw, __METHOD__ );
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();
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();
127 $this->commitTransaction( $dbw, __METHOD__ );
129 $batchMinPageId = $batchMaxPageId;
130 } while ( $batchMaxPageId < $maxPageId );
132 $this->output( "...Done!\n" );
133 return true;
137 * Convert a legacy restriction specification from the page.page_restrictions blob to
138 * a map of action names to restriction levels.
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
144 private function mapLegacyRestrictionBlob( $legacyBlob ) {
145 $oldRestrictions = [];
147 foreach ( explode( ':', trim( $legacyBlob ) ) as $restrict ) {
148 $temp = explode( '=', trim( $restrict ) );
150 // Treat old old format without action name as edit/move restriction
151 if ( count( $temp ) == 1 ) {
152 $level = trim( $temp[0] );
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;
165 return $oldRestrictions;
169 // @codeCoverageIgnoreStart
170 $maintClass = UpdateRestrictions::class;
171 require_once RUN_MAINTENANCE_IF_MAIN;
172 // @codeCoverageIgnoreEnd