r45231 MediaWiki - Code Review archive

Repository:MediaWiki
Revision:r45230‎ | r45231 | r45232 >
Date:17:25, 31 December 2008
Author:vasilievvv
Status:reverted (Comments)
Tags:
Comment:
* (bug 674) Allow users to be blocked from editing a specific article
** Also supports blocking user from editing whole namespace
** Fixed most issues which were found before
Modified paths:
  • /trunk/phase3/includes/Article.php (modified) (history)
  • /trunk/phase3/includes/AutoLoader.php (modified) (history)
  • /trunk/phase3/includes/DefaultSettings.php (modified) (history)
  • /trunk/phase3/includes/LogPage.php (modified) (history)
  • /trunk/phase3/includes/SpecialPage.php (modified) (history)
  • /trunk/phase3/includes/Title.php (modified) (history)
  • /trunk/phase3/includes/User.php (modified) (history)
  • /trunk/phase3/includes/UserRestriction.php (added) (history)
  • /trunk/phase3/includes/specials/SpecialListUserRestrictions.php (modified) (history)
  • /trunk/phase3/includes/specials/SpecialRemoveRestrictions.php (modified) (history)
  • /trunk/phase3/includes/specials/SpecialRestrictUser.php (modified) (history)
  • /trunk/phase3/languages/messages/MessagesEn.php (modified) (history)
  • /trunk/phase3/maintenance/archives/patch-user_restrictions.sql (added) (history)
  • /trunk/phase3/maintenance/language/messages.inc (modified) (history)
  • /trunk/phase3/maintenance/parserTests.inc (modified) (history)
  • /trunk/phase3/maintenance/tables.sql (modified) (history)
  • /trunk/phase3/maintenance/updaters.inc (modified) (history)

Diff [purge]

Index: trunk/phase3/maintenance/archives/patch-user_restrictions.sql
@@ -0,0 +1,42 @@
 2+-- Allows admins to block user from editing certain namespaces or pages
 3+
 4+CREATE TABLE /*$wgDBprefix*/user_restrictions (
 5+ -- ID of the restriction
 6+ ur_id int NOT NULL auto_increment,
 7+
 8+ -- Restriction type. Block from either editing namespace or page
 9+ ur_type varbinary(255) NOT NULL,
 10+ -- Namespace to restrict if ur_type = namespace
 11+ ur_namespace int default NULL,
 12+ -- Page to restrict if ur_type = page
 13+ ur_page_namespace int default NULL,
 14+ ur_page_title varchar(255) binary default '',
 15+
 16+ -- User that is restricted
 17+ ur_user int unsigned NOT NULL,
 18+ ur_user_text tinyblob NOT NULL,
 19+
 20+ -- User who has done this restriction
 21+ ur_by int unsigned NOT NULL,
 22+ ur_by_text varchar(255) binary NOT NULL default '',
 23+ -- Reason for this restriction
 24+ ur_reason tinyblob NOT NULL,
 25+
 26+ -- Time when this restriction was made
 27+ ur_timestamp varbinary(14) NOT NULL default '',
 28+ -- Expiry or "infinity"
 29+ ur_expiry varbinary(14) NOT NULL default '',
 30+
 31+ PRIMARY KEY ur_id (ur_id),
 32+ -- For looking up restrictions for user and title
 33+ INDEX ur_user (ur_user,ur_user_text(255)),
 34+ INDEX ur_user_page(ur_user,ur_page_namespace,ur_page_title(255)),
 35+ INDEX ur_user_namespace(ur_user,ur_namespace),
 36+ -- For Special:ListUserRestrictions
 37+ INDEX ur_type (ur_type(255),ur_timestamp),
 38+ INDEX ur_namespace (ur_namespace,ur_timestamp),
 39+ INDEX ur_page (ur_page_namespace,ur_page_title,ur_timestamp),
 40+ INDEX ur_timestamp (ur_timestamp),
 41+ -- For quick removal of expired restrictions
 42+ INDEX ur_expiry (ur_expiry)
 43+) /*$wgDBTableOptions*/;
Property changes on: trunk/phase3/maintenance/archives/patch-user_restrictions.sql
___________________________________________________________________
Added: svn:eol-style
144 + native
Index: trunk/phase3/maintenance/parserTests.inc
@@ -593,7 +593,7 @@
594594 'site_stats', 'hitcounter', 'ipblocks', 'image', 'oldimage',
595595 'recentchanges', 'watchlist', 'math', 'interwiki',
596596 'querycache', 'objectcache', 'job', 'redirect', 'querycachetwo',
597 - 'archive', 'user_groups', 'page_props', 'category'
 597+ 'archive', 'user_groups', 'page_props', 'category', 'user_restrictions',
598598 );
599599
600600 if ($wgDBtype === 'mysql')
Index: trunk/phase3/maintenance/updaters.inc
@@ -145,9 +145,10 @@
146146 array( 'update_password_format' ),
147147
148148 // 1.14
149 - array( 'add_field', 'site_stats', 'ss_active_users', 'patch-ss_active_users.sql' ),
 149+ array( 'add_field', 'site_stats', 'ss_active_users', 'patch-ss_active_users.sql' ),
150150 array( 'do_active_users_init' ),
151 - array( 'add_field', 'ipblocks', 'ipb_allow_usertalk', 'patch-ipb_allow_usertalk.sql' )
 151+ array( 'add_field', 'ipblocks', 'ipb_allow_usertalk', 'patch-ipb_allow_usertalk.sql' ),
 152+ array( 'add_table', 'user_restrictions', 'patch-user_restrictions.sql' ),
152153 );
153154
154155
Index: trunk/phase3/maintenance/language/messages.inc
@@ -569,6 +569,10 @@
570570 'edit-conflict',
571571 'edit-no-change',
572572 'edit-already-exists',
 573+ 'userrestricted-page',
 574+ 'userrestricted-namespace',
 575+ 'userrestricted-page-indef',
 576+ 'userrestricted-namespace-indef',
573577 ),
574578 'parserwarnings' => array(
575579 'expensive-parserfunction-warning',
@@ -1804,6 +1808,7 @@
18051809 'ipbsubmit',
18061810 'ipbother',
18071811 'ipboptions',
 1812+ 'ipbinfinite',
18081813 'ipbotheroption',
18091814 'ipbotherreason',
18101815 'ipbhidename',
@@ -1877,6 +1882,69 @@
18781883 'sorbs_create_account_reason',
18791884 'cant-block-while-blocked',
18801885 ),
 1886+ 'listuserrestrictions' => array(
 1887+ 'listuserrestrictions',
 1888+ 'listuserrestrictions-intro',
 1889+ 'listuserrestrictions-row-ns',
 1890+ 'listuserrestrictions-row-page',
 1891+ 'listuserrestrictions-row-expiry',
 1892+ 'listuserrestrictions-legend',
 1893+ 'listuserrestrictions-type',
 1894+ 'listuserrestrictions-user',
 1895+ 'listuserrestrictions-namespace',
 1896+ 'listuserrestrictions-page',
 1897+ 'listuserrestrictions-submit',
 1898+ 'listuserrestrictions-notfound',
 1899+ 'listuserrestrictions-empty',
 1900+ 'listuserrestrictions-remove',
 1901+ 'userrestrictiontype-none',
 1902+ 'userrestrictiontype-namespace',
 1903+ 'userrestrictiontype-page',
 1904+ ),
 1905+ 'removerestrictions' => array(
 1906+ 'removerestrictions',
 1907+ 'removerestrictions-intro',
 1908+ 'removerestrictions-noid',
 1909+ 'removerestrictions-wrongid',
 1910+ 'removerestrictions-legend',
 1911+ 'removerestrictions-user',
 1912+ 'removerestrictions-type',
 1913+ 'removerestrictions-page',
 1914+ 'removerestrictions-namespace',
 1915+ 'removerestrictions-reason',
 1916+ 'removerestrictions-submit',
 1917+ 'removerestrictions-success',
 1918+ ),
 1919+ 'restrictuser' => array(
 1920+ 'restrictuser',
 1921+ 'restrictuser-userselect',
 1922+ 'restrictuser-user',
 1923+ 'restrictuser-go',
 1924+ 'restrictuser-notfound',
 1925+ 'restrictuser-existing',
 1926+ 'restrictuser-legend-page',
 1927+ 'restrictuser-legend-namespace',
 1928+ 'restrictuser-title',
 1929+ 'restrictuser-namespace',
 1930+ 'restrictuser-expiry',
 1931+ 'restrictuser-reason',
 1932+ 'restrictuser-submit',
 1933+ 'restrictuser-badtitle',
 1934+ 'restrictuser-badnamespace',
 1935+ 'restrictuser-badexpiry',
 1936+ 'restrictuser-duptitle',
 1937+ 'restrictuser-dupnamespace',
 1938+ 'restrictuser-success',
 1939+ 'restrictuser-description',
 1940+ ),
 1941+ 'restrictlog' => array(
 1942+ 'restrictionlog',
 1943+ 'restrictionlogtext',
 1944+ 'restrictentry',
 1945+ 'restrictremoveentry',
 1946+ 'restrictlognamespace',
 1947+ 'restrictlogpage',
 1948+ ),
18811949 'developertools' => array(
18821950 'lockdb',
18831951 'unlockdb',
@@ -3005,6 +3073,10 @@
30063074 'sp-contributions' => '',
30073075 'whatlinkshere' => 'What links here',
30083076 'block' => 'Block/unblock',
 3077+ 'listuserrestrictions' => 'Special:ListUserRestrictions',
 3078+ 'removerestrictions' => 'Special:RemoveRestrictions',
 3079+ 'restrictuser' => 'Restrict user',
 3080+ 'restrictlog' => 'Special:Log/restrict',
30093081 'developertools' => 'Developer tools',
30103082 'movepage' => 'Move page',
30113083 'export' => 'Export',
Index: trunk/phase3/maintenance/tables.sql
@@ -1243,4 +1243,47 @@
12441244 PRIMARY KEY (ul_key)
12451245 ) /*$wgDBTableOptions*/;
12461246
 1247+-- Allows admins to block user from editing certain namespaces or pages
 1248+CREATE TABLE /*$wgDBprefix*/user_restrictions (
 1249+ -- ID of the restriction
 1250+ ur_id int NOT NULL auto_increment,
 1251+
 1252+ -- Restriction type. Block from either editing namespace or page
 1253+ ur_type varbinary(255) NOT NULL,
 1254+ -- Namespace to restrict if ur_type = namespace
 1255+ ur_namespace int default NULL,
 1256+ -- Page to restrict if ur_type = page
 1257+ ur_page_namespace int default NULL,
 1258+ ur_page_title varchar(255) binary default '',
 1259+
 1260+ -- User that is restricted
 1261+ ur_user int unsigned NOT NULL,
 1262+ ur_user_text tinyblob NOT NULL,
 1263+
 1264+ -- User who has done this restriction
 1265+ ur_by int unsigned NOT NULL,
 1266+ ur_by_text varchar(255) binary NOT NULL default '',
 1267+ -- Reason for this restriction
 1268+ ur_reason tinyblob NOT NULL,
 1269+
 1270+ -- Time when this restriction was made
 1271+ ur_timestamp varbinary(14) NOT NULL default '',
 1272+ -- Expiry or "infinity"
 1273+ ur_expiry varbinary(14) NOT NULL default '',
 1274+
 1275+ PRIMARY KEY ur_id (ur_id),
 1276+ -- For looking up restrictions for user and title
 1277+ INDEX ur_user (ur_user,ur_user_text(255)),
 1278+ INDEX ur_user_page(ur_user,ur_page_namespace,ur_page_title(255)),
 1279+ INDEX ur_user_namespace(ur_user,ur_namespace),
 1280+ -- For Special:ListUserRestrictions
 1281+ INDEX ur_type (ur_type(255),ur_timestamp),
 1282+ INDEX ur_namespace (ur_namespace,ur_timestamp),
 1283+ INDEX ur_page (ur_page_namespace,ur_page_title,ur_timestamp),
 1284+ INDEX ur_timestamp (ur_timestamp),
 1285+ -- For quick removal of expired restrictions
 1286+ INDEX ur_expiry (ur_expiry)
 1287+) /*$wgDBTableOptions*/;
 1288+
 1289+
12471290 -- vim: sw=2 sts=2 et
Index: trunk/phase3/includes/User.php
@@ -151,7 +151,7 @@
152152 'markbotedits',
153153 'minoredit',
154154 'move',
155 - 'movepage',
 155+ 'movefile',
156156 'move-rootuserpages',
157157 'move-subpages',
158158 'nominornewtalk',
@@ -161,6 +161,7 @@
162162 'proxyunbannable',
163163 'purge',
164164 'read',
 165+ 'restrict',
165166 'reupload',
166167 'reupload-shared',
167168 'rollback',
Index: trunk/phase3/includes/Article.php
@@ -2435,7 +2435,12 @@
24362436 );
24372437
24382438 # Delete restrictions for it
2439 - $dbw->delete( 'page_restrictions', array ( 'pr_page' => $id ), __METHOD__ );
 2439+ $dbw->delete( 'page_restrictions', array( 'pr_page' => $id ), __METHOD__ );
 2440+ $dbw->delete( 'user_restrictions',
 2441+ array(
 2442+ 'ur_page_namespace' => $this->mTitle->getNamespace(),
 2443+ 'ur_page_title' => $this->mTitle->getDBKey()
 2444+ ), __METHOD__ );
24402445
24412446 # Now that it's safely backed up, delete it
24422447 $dbw->delete( 'page', array( 'page_id' => $id ), __METHOD__);
Index: trunk/phase3/includes/UserRestriction.php
@@ -0,0 +1,189 @@
 2+<?php
 3+
 4+/**
 5+ * Object that represents a user restriction
 6+ */
 7+class UserRestriction {
 8+ const PAGE = 'page';
 9+ const NAMESPACE = 'namespace';
 10+
 11+ private $mId, $mType, $mNamespace, $mPage, $mSubjectText, $mSubjectId,
 12+ $mBlockerId, $mBlockerText, $mReason, $mTimestamp, $mExpiry;
 13+
 14+ public static function newFromRow( $row ) {
 15+ if( !$row )
 16+ return null;
 17+
 18+ $obj = new UserRestriction();
 19+ $obj->mId = $row->ur_id;
 20+ $obj->mType = $row->ur_type;
 21+ if( $obj->mType == self::PAGE ) {
 22+ $obj->mPage = Title::makeTitle( $row->ur_page_namespace, $row->ur_page_title );
 23+ } elseif( $obj->mType == self::NAMESPACE ) {
 24+ $obj->mNamespace = $row->ur_namespace;
 25+ } else {
 26+ throw new MWException( "Unknown user restriction type: {$row->ur_type}" );
 27+ }
 28+
 29+ $obj->mSubjectId = $row->ur_user;
 30+ $obj->mSubjectText = $row->ur_user_text;
 31+ $obj->mBlockerId = $row->ur_by;
 32+ $obj->mBlockerText = $row->ur_by_text;
 33+ $obj->mReason = $row->ur_reason;
 34+ $obj->mTimestamp = wfTimestamp( TS_MW, $row->ur_timestamp );
 35+ $obj->mExpiry = $row->ur_expiry;
 36+ return $obj;
 37+ }
 38+
 39+ public static function fetchForUser( $user, $forWrite = false ) {
 40+ $dbr = wfGetDB( $forWrite ? DB_MASTER : DB_SLAVE );
 41+ if( is_int( $user ) )
 42+ $query = array( 'ur_user' => $user );
 43+ else
 44+ $query = array( 'ur_user_text' => $user );
 45+ $res = $dbr->select( 'user_restrictions', '*', $query, __METHOD__ );
 46+ $result = array();
 47+ foreach( $res as $row ) {
 48+ $result[] = self::newFromRow( $row );
 49+ }
 50+ return $result;
 51+ }
 52+
 53+ public static function fetchForTitle( $user, $title ) {
 54+ $dbr = wfGetDB( DB_SLAVE );
 55+ if( $user->isLoggedIn() )
 56+ $query = array( 'ur_user' => $user->getId() );
 57+ else
 58+ $query = array( 'ur_user_text' => $user->getName() );
 59+ $query['ur_page_namespace'] = $title->getNamespace();
 60+ $query['ur_page_title'] = $title->getDBKey();
 61+ $res = $dbr->select( 'user_restrictions', '*', $query, __METHOD__ );
 62+ $result = array();
 63+ foreach( $res as $row ) {
 64+ $result[] = self::newFromRow( $row );
 65+ }
 66+ return $result;
 67+ }
 68+
 69+ public static function fetchForNamespace( $user, $ns ) {
 70+ $dbr = wfGetDB( DB_SLAVE );
 71+ if( $user->isLoggedIn() )
 72+ $query = array( 'ur_user' => $user->getId() );
 73+ else
 74+ $query = array( 'ur_user_text' => $user->getName() );
 75+ $query['ur_namespace'] = $ns;
 76+ $res = $dbr->select( 'user_restrictions', '*', $query, __METHOD__ );
 77+ $result = array();
 78+ foreach( $res as $row ) {
 79+ $result[] = self::newFromRow( $row );
 80+ }
 81+ return $result;
 82+ }
 83+
 84+ public static function newFromId( $id, $forWrite = false ) {
 85+ $dbr = wfGetDB( $forWrite ? DB_MASTER : DB_SLAVE );
 86+ if( !$id || !is_numeric( $id ) )
 87+ return null;
 88+ $res = $dbr->selectRow( 'user_restrictions', '*', array( 'ur_id' => $id ), __METHOD__ );
 89+ return self::newFromRow( $res );
 90+ }
 91+
 92+ public function getId() { return $this->mId; }
 93+ public function setId( $v ) { $this->mId = $v; }
 94+ public function getType() { return $this->mType; }
 95+ public function setType( $v ) { $this->mType = $v; }
 96+ public function getNamespace() { return $this->mNamespace; }
 97+ public function setNamespace( $v ) { $this->mNamespace = $v; }
 98+ public function getPage() { return $this->mPage; }
 99+ public function setPage( $v ) { $this->mPage = $v; }
 100+ public function getSubjectId() { return $this->mSubjectId; }
 101+ public function setSubjectId( $v ) { $this->mSubjectId = $v; }
 102+ public function getSubjectText() { return $this->mSubjectText; }
 103+ public function setSubjectText( $v ) { $this->mSubjectText = $v; }
 104+ public function getBlockerId() { return $this->mBlockerId; }
 105+ public function setBlockerId( $v ) { $this->mBlockerId = $v; }
 106+ public function getBlockerText() { return $this->mBlockerText; }
 107+ public function setBlockerText( $v ) { $this->mBlockerText = $v; }
 108+ public function getReason() { return $this->mReason; }
 109+ public function setReason( $v ) { $this->mReason = $v; }
 110+ public function getTimestamp() { return $this->mTimestamp; }
 111+ public function setTimestamp( $v ) { $this->mTimestamp = $v; }
 112+ public function getExpiry() { return $this->mExpiry; }
 113+ public function setExpiry( $v ) { $this->mExpiry = $v; }
 114+
 115+ public function isPage() {
 116+ return $this->mType == self::PAGE;
 117+ }
 118+ public function isNamespace() {
 119+ return $this->mType == self::NAMESPACE;
 120+ }
 121+
 122+ public function isExpired() {
 123+ return is_numeric( $this->mExpiry ) && $this->mExpiry < wfTimestampNow( TS_MW );
 124+ }
 125+
 126+ public function deleteIfExpired() {
 127+ if( $this->isExpired() ) {
 128+ $this->delete();
 129+ return true;
 130+ } else {
 131+ return false;
 132+ }
 133+ }
 134+
 135+ public function delete() {
 136+ $dbw = wfGetDB( DB_MASTER );
 137+ $dbw->delete( 'user_restrictions', array( 'ur_id' => $this->mId ), __METHOD__ );
 138+ return $dbw->affectedRows();
 139+ }
 140+
 141+ public static function purgeExpired() {
 142+ $dbw = wfGetDB( DB_MASTER );
 143+ $dbw->delete( 'user_restrictions', array( 'ur_expiry < ' . $dbw->addQuotes( $dbw->timestamp() ) ), __METHOD__ );
 144+ }
 145+
 146+ public function commit() {
 147+ $dbw = wfGetDB( DB_MASTER );
 148+ $this->setId( $dbw->nextSequenceValue('user_restrictions_ur_id_val') );
 149+ $row = array(
 150+ 'ur_id' => $this->mId,
 151+ 'ur_type' => $this->mType,
 152+ 'ur_user' => $this->mSubjectId,
 153+ 'ur_user_text' => $this->mSubjectText,
 154+ 'ur_by' => $this->mBlockerId,
 155+ 'ur_by_text' => $this->mBlockerText,
 156+ 'ur_reason' => $this->mReason,
 157+ 'ur_timestamp' => $dbw->timestamp( $this->mTimestamp ),
 158+ 'ur_expiry' => $this->mExpiry,
 159+ );
 160+ if( $this->isPage() ) {
 161+ $row['ur_page_namespace'] = $this->mPage->getNamespace();
 162+ $row['ur_page_title'] = $this->mPage->getDbKey();
 163+ }
 164+ if( $this->isNamespace() ) {
 165+ $row['ur_namespace'] = $this->mNamespace;
 166+ }
 167+ $dbw->insert( 'user_restrictions', $row, __METHOD__ );
 168+ }
 169+
 170+ public static function formatType( $type ) {
 171+ return wfMsg( 'userrestrictiontype-' . $type );
 172+ }
 173+
 174+ /**
 175+ * Converts expiry which user input to the internal representation.
 176+ * Returns false if invalid expiry is set, Block::infinity() on empty value,
 177+ * Block::infinity() on infinity or 14-symbol timestamp
 178+ */
 179+ public static function convertExpiry( $expiry ) {
 180+ if( !$expiry )
 181+ return Block::infinity();
 182+ if( in_array( $expiry, array( 'infinite', 'infinity', 'indefinite' ) ) )
 183+ return Block::infinity();
 184+ $unix = @strtotime( $expiry );
 185+ if( !$unix || $unix === -1 )
 186+ return false;
 187+ else
 188+ return wfTimestamp( TS_MW, $unix );
 189+ }
 190+}
Property changes on: trunk/phase3/includes/UserRestriction.php
___________________________________________________________________
Added: svn:eol-style
1191 + native
Index: trunk/phase3/includes/AutoLoader.php
@@ -201,6 +201,8 @@
202202 'UserArray' => 'includes/UserArray.php',
203203 'UserArrayFromResult' => 'includes/UserArray.php',
204204 'UserMailer' => 'includes/UserMailer.php',
 205+ 'UserRestriction' => 'includes/UserRestriction.php',
 206+ 'UserRestrictionsPager' => 'includes/specials/SpecialListUserRestrictions.php',
205207 'UserRightsProxy' => 'includes/UserRightsProxy.php',
206208 'WatchedItem' => 'includes/WatchedItem.php',
207209 'WatchlistEditor' => 'includes/WatchlistEditor.php',
Index: trunk/phase3/includes/Title.php
@@ -1009,9 +1009,7 @@
10101010 }
10111011 $errors = $this->getUserPermissionsErrorsInternal( $action, $user, $doExpensiveQueries );
10121012
1013 - global $wgContLang;
1014 - global $wgLang;
1015 - global $wgEmailConfirmToEdit;
 1013+ global $wgContLang, $wgLang, $wgEmailConfirmToEdit;
10161014
10171015 if ( $wgEmailConfirmToEdit && !$user->isEmailConfirmed() && $action != 'createaccount' ) {
10181016 $errors[] = array( 'confirmedittext' );
@@ -1043,20 +1041,7 @@
10441042 $blockTimestamp = $wgLang->timeanddate( wfTimestamp( TS_MW, $user->mBlock->mTimestamp ), true );
10451043
10461044 if ( $blockExpiry == 'infinity' ) {
1047 - // Entry in database (table ipblocks) is 'infinity' but 'ipboptions' uses 'infinite' or 'indefinite'
1048 - $scBlockExpiryOptions = wfMsg( 'ipboptions' );
1049 -
1050 - foreach ( explode( ',', $scBlockExpiryOptions ) as $option ) {
1051 - if ( strpos( $option, ':' ) == false )
1052 - continue;
1053 -
1054 - list ($show, $value) = explode( ":", $option );
1055 -
1056 - if ( $value == 'infinite' || $value == 'indefinite' ) {
1057 - $blockExpiry = $show;
1058 - break;
1059 - }
1060 - }
 1045+ $blockExpiry = wfMsg( 'ipbinfinite' );
10611046 } else {
10621047 $blockExpiry = $wgLang->timeanddate( wfTimestamp( TS_MW, $blockExpiry ), true );
10631048 }
@@ -1066,9 +1051,9 @@
10671052 $errors[] = array( ($block->mAuto ? 'autoblockedtext' : 'blockedtext'), $link, $reason, $ip, $name,
10681053 $blockid, $blockExpiry, $intended, $blockTimestamp );
10691054 }
1070 -
 1055+
10711056 // Remove the errors being ignored.
1072 -
 1057+
10731058 foreach( $errors as $index => $error ) {
10741059 $error_key = is_array($error) ? $error[0] : $error;
10751060
@@ -1091,6 +1076,8 @@
10921077 * @return \type{\array} Array of arrays of the arguments to wfMsg to explain permissions problems.
10931078 */
10941079 private function getUserPermissionsErrorsInternal( $action, $user, $doExpensiveQueries = true ) {
 1080+ global $wgLang;
 1081+
10951082 wfProfileIn( __METHOD__ );
10961083
10971084 $errors = array();
@@ -1262,6 +1249,34 @@
12631250 $errors[] = $return;
12641251 }
12651252
 1253+ // Check per-user restrictions
 1254+ if( $doExpensiveQueries && $action != 'read' ) {
 1255+ $rs = UserRestriction::fetchForTitle( $user, $this );
 1256+ if( !$rs )
 1257+ $rs = UserRestriction::fetchForNamespace( $user, $this->getNamespace() );
 1258+ if( $rs ) {
 1259+ $r = $rs[0];
 1260+ if( !$r->deleteIfExpired() ) {
 1261+ $error = array();
 1262+ $start = array( $wgLang->date( $r->getTimestamp() ), $wgLang->time( $r->getTimestamp() ) );
 1263+ if( $r->isPage() )
 1264+ $error = array( 'userrestricted-page', $this->getFullText(),
 1265+ $r->getBlockerText(), $r->getReason(), $start[0], $start[1] );
 1266+ elseif( $r->isNamespace() )
 1267+ $error = array( 'userrestricted-namespace', $wgLang->getDisplayNsText( $this->getNamespace() ),
 1268+ $r->getBlockerText(), $r->getReason(), $start[0], $start[1] );
 1269+
 1270+ if( $r->getExpiry() == 'infinity' ) {
 1271+ $error[0] .= '-indef';
 1272+ } else {
 1273+ $error[] = $wgLang->date( $r->getExpiry() );
 1274+ $error[] = $wgLang->time( $r->getExpiry() );
 1275+ }
 1276+ $errors[] = $error;
 1277+ }
 1278+ }
 1279+ }
 1280+
12661281 wfProfileOut( __METHOD__ );
12671282 return $errors;
12681283 }
@@ -2558,6 +2573,12 @@
25592574 $log->addEntry( 'move_prot', $nt, $comment, array($this->getPrefixedText()) ); // FIXME: $params?
25602575 }
25612576
 2577+ # Update user restrictions
 2578+ $dbw->update( 'user_restrictions',
 2579+ array( 'ur_page_namespace' => $nt->getNamespace(), 'ur_page_title' => $nt->getDBKey() ),
 2580+ array( 'ur_page_namespace' => $this->getNamespace(), 'ur_page_title' => $this->getDBKey() ),
 2581+ __METHOD__ );
 2582+
25622583 # Update watchlists
25632584 $oldnamespace = $this->getNamespace() & ~1;
25642585 $newnamespace = $nt->getNamespace() & ~1;
Index: trunk/phase3/includes/DefaultSettings.php
@@ -1232,6 +1232,7 @@
12331233 $wgGroupPermissions['sysop']['apihighlimits'] = true;
12341234 $wgGroupPermissions['sysop']['browsearchive'] = true;
12351235 $wgGroupPermissions['sysop']['noratelimit'] = true;
 1236+$wgGroupPermissions['sysop']['restrict'] = true;
12361237 $wgGroupPermissions['sysop']['movefile'] = true;
12371238 #$wgGroupPermissions['sysop']['mergehistory'] = true;
12381239
@@ -2798,6 +2799,7 @@
27992800 'patrol',
28002801 'merge',
28012802 'suppress',
 2803+ 'restrict',
28022804 );
28032805
28042806 /**
@@ -2853,6 +2855,7 @@
28542856 'patrol' => 'patrol-log-page',
28552857 'merge' => 'mergelog',
28562858 'suppress' => 'suppressionlog',
 2859+ 'restrict' => 'restrictionlog',
28572860 );
28582861
28592862 /**
@@ -2874,6 +2877,7 @@
28752878 'patrol' => 'patrol-log-header',
28762879 'merge' => 'mergelogpagetext',
28772880 'suppress' => 'suppressionlogtext',
 2881+ 'restrict' => 'restrictionlogtext',
28782882 );
28792883
28802884 /**
@@ -2913,6 +2917,8 @@
29142918 'suppress/delete' => 'suppressedarticle',
29152919 'suppress/block' => 'blocklogentry',
29162920 'suppress/reblock' => 'reblock-logentry',
 2921+ 'restrict/restrict' => 'restrictentry',
 2922+ 'restrict/remove' => 'restrictremoveentry',
29172923 );
29182924
29192925 /**
@@ -2984,6 +2990,8 @@
29852991 'Preferences' => 'users',
29862992 'Resetpass' => 'users',
29872993 'DeletedContributions' => 'users',
 2994+ 'ListUserRestrictions' => 'users',
 2995+ 'RestrictUser' => 'users',
29882996
29892997 'Mostlinked' => 'highuse',
29902998 'Mostlinkedcategories' => 'highuse',
Index: trunk/phase3/includes/specials/SpecialRestrictUser.php
@@ -2,6 +2,8 @@
33
44 function wfSpecialRestrictUser( $par = null ) {
55 global $wgOut, $wgRequest;
 6+ $wgOut->addHTML( wfMsgExt( 'restrictuser-description', 'parse' ) );
 7+
68 $user = $userOrig = null;
79 if( $par ) {
810 $userOrig = $par;
@@ -48,8 +50,6 @@
4951 }
5052
5153 public static function existingRestrictions( $restrictions ) {
52 - //TODO: autoload?
53 - require_once( dirname( __FILE__ ) . '/SpecialListUserRestrictions.php' );
5454 $s = Xml::fieldset( wfMsg( 'restrictuser-existing' ) ) . '<ul>';
5555 foreach( $restrictions as $r )
5656 $s .= UserRestrictionsPager::formatRestriction( $r );
@@ -126,6 +126,7 @@
127127 $l = new LogPage( 'restrict' );
128128 $l->addEntry( 'restrict', Title::makeTitle( NS_USER, $user ), $r->getReason(),
129129 array( $r->getType(), $r->getPage()->getFullText(), $logExpiry) );
 130+ self::invalidateCache( $user );
130131 }
131132
132133 public static function namespaceRestrictionForm( $uid, $user, $oldRestrictions ) {
@@ -136,13 +137,13 @@
137138 $wgUser->matchEditToken( $wgRequest->getVal( 'edittoken' ) ) ) {
138139 $ns = $wgRequest->getVal( 'namespace' );
139140 if( $wgContLang->getNsText( $ns ) === false )
140 - $error = wfMsgExt( 'restrictuser-badnamespace', 'parseinline' );
 141+ $error = array( 'restrictuser-badnamespace' );
141142 elseif( UserRestriction::convertExpiry( $wgRequest->getVal( 'expiry' ) ) === false )
142 - $error = wfMsgExt( 'restrictuser-badexpiry', 'parseinline', $wgRequest->getVal( 'expiry' ) );
 143+ $error = array( 'restrictuser-badexpiry', $wgRequest->getVal( 'expiry' ) );
143144 else
144145 foreach( $oldRestrictions as $r )
145146 if( $r->isNamespace() && $r->getNamespace() == $ns )
146 - $error = wfMsgExt( 'restrictuser-dupnamespace', 'parse' );
 147+ $error = array( 'restrictuser-dupnamespace' );
147148 if( !$error ) {
148149 self::doNamespaceRestriction( $uid, $user );
149150 $success = array('restrictuser-success', $user);
@@ -185,5 +186,11 @@
186187 $l = new LogPage( 'restrict' );
187188 $l->addEntry( 'restrict', Title::makeTitle( NS_USER, $user ), $r->getReason(),
188189 array( $r->getType(), $r->getNamespace(), $logExpiry ) );
 190+ self::invalidateCache( $user );
189191 }
 192+
 193+ private static function invalidateCache( $user ) {
 194+ $userObj = User::newFromName( $user, false );
 195+ $userObj->invalidateCache();
 196+ }
190197 }
Index: trunk/phase3/includes/specials/SpecialRemoveRestrictions.php
@@ -56,5 +56,7 @@
5757 if( $r->isNamespace() )
5858 $params[] = $r->getNamespace();
5959 $log->addEntry( 'remove', Title::makeTitle( NS_USER, $r->getSubjectText() ), $reason, $params );
 60+ $userObj = User::newFromName( $r->getSubjectText(), false );
 61+ $userObj->invalidateCache();
6062 return $result;
6163 }
Index: trunk/phase3/includes/specials/SpecialListUserRestrictions.php
@@ -134,7 +134,7 @@
135135 $subjlink = $sk->userLink( $r->getSubjectId(), $r->getSubjectText() ) .
136136 $sk->userToolLinks( $r->getSubjectId(), $r->getSubjectText() );
137137 $expiry = is_numeric( $r->getExpiry() ) ?
138 - wfMsg( 'listuserrestrictions-row-expiry', $wgLang->timeanddate( $r->getExpiry() ) ) :
 138+ wfMsg( 'listuserrestrictions-row-expiry', $wgLang->date( $r->getExpiry() ), $wgLang->time( $r->getExpiry() ) ) :
139139 wfMsg( 'ipbinfinite' );
140140 $msg = '';
141141 if( $r->isNamespace() ) {
Index: trunk/phase3/includes/SpecialPage.php
@@ -129,6 +129,9 @@
130130 'Allpages' => 'SpecialAllpages',
131131 'Prefixindex' => 'SpecialPrefixindex',
132132 'Ipblocklist' => array( 'SpecialPage', 'Ipblocklist' ),
 133+ 'ListUserRestrictions' => array( 'SpecialPage', 'ListUserRestrictions' ),
 134+ 'RemoveRestrictions' => array( 'UnlistedSpecialPage', 'RemoveRestrictions', 'restrict' ),
 135+ 'RestrictUser' => array( 'SpecialPage', 'RestrictUser', 'restrict' ),
133136 'Specialpages' => array( 'UnlistedSpecialPage', 'Specialpages' ),
134137 'Contributions' => 'SpecialContributions',
135138 'Emailuser' => array( 'UnlistedSpecialPage', 'Emailuser' ),
Index: trunk/phase3/includes/LogPage.php
@@ -193,6 +193,19 @@
194194 } else {
195195 $rv = wfMsgForContent( $wgLogActions[$key], $titleLink );
196196 }
 197+ } elseif( $type == 'restrict' ) {
 198+ if( $params[0] == UserRestriction::PAGE )
 199+ $subj = wfMsgExt( 'restrictlogpage', 'parseinline', $params[1] );
 200+ if( $params[0] == UserRestriction::NAMESPACE )
 201+ $subj = wfMsgExt( 'restrictlognamespace', 'parseinline', $wgLang->getDisplayNsText( $params[1] ) );
 202+ $expiry = '';
 203+ if( $key == 'restrict/restrict' )
 204+ $expiry = $wgLang->translateBlockExpiry( $params[2] );
 205+ if ( $skin ) {
 206+ $rv = wfMsg( $wgLogActions[$key], $titleLink, $subj, $expiry );
 207+ } else {
 208+ $rv = wfMsgForContent( $wgLogActions[$key], $titleLink, $subj, $expiry );
 209+ }
197210 } else {
198211 $details = '';
199212 array_unshift( $params, $titleLink );
@@ -264,6 +277,7 @@
265278 }
266279 break;
267280 case 'rights':
 281+ case 'restrict':
268282 $text = $wgContLang->ucfirst( $title->getText() );
269283 $titleLink = $skin->makeLinkObj( Title::makeTitle( NS_USER, $text ) );
270284 break;
Index: trunk/phase3/languages/messages/MessagesEn.php
@@ -431,6 +431,9 @@
432432 'LinkSearch' => array( 'LinkSearch' ),
433433 'DeletedContributions' => array( 'DeletedContributions' ),
434434 'Interwiki' => array( 'Interwiki' ),
 435+ 'ListUserRestrictions' => array( 'ListUserRestrictions' ),
 436+ 'RemoveRestrictions' => array( 'RemoveRestrictions' ),
 437+ 'RestrictUser' => array( 'RestrictUser' ),
435438 );
436439
437440 /**
@@ -1196,7 +1199,39 @@
11971200 'edit-no-change' => 'Your edit was ignored, because no change was made to the text.',
11981201 'edit-already-exists' => 'Could not create a new page.
11991202 It already exists.',
 1203+'userrestricted-page' => '<big>\'\'\'Your user name or IP address has been restricted from editing page "$1".\'\'\'</big>
12001204
 1205+The restriction was put by [[User:$2|$2]].
 1206+The reason given is \'\'$3\'\'.
 1207+
 1208+Restriction was put on $4 at $5 and expires on $6 at $7.
 1209+
 1210+You can contact [[User:$2|$2]] or another [[{{MediaWiki:Grouppage-sysop}}|administrator]] to discuss the restriction.',
 1211+'userrestricted-namespace' => "<big>'''Your user name or IP address has been restricted from editing $1 namespace.'''</big>
 1212+
 1213+The restriction was put by [[User:$2|$2]].
 1214+The reason given is ''$3''.
 1215+
 1216+Restriction was put on $4 at $5 and expires on $6 at $7.
 1217+
 1218+You can contact [[User:$2|$2]] or another [[{{MediaWiki:Grouppage-sysop}}|administrator]] to discuss the restriction.",
 1219+'userrestricted-page-indef' => '<big>\'\'\'Your user name or IP address has been restricted from editing page "$1".\'\'\'</big>
 1220+
 1221+The restriction was put by [[User:$2|$2]].
 1222+The reason given is \'\'$3\'\'.
 1223+
 1224+Restriction was put on $4 at $5 and will not expire.
 1225+
 1226+You can contact [[User:$2|$2]] or another [[{{MediaWiki:Grouppage-sysop}}|administrator]] to discuss the restriction.',
 1227+'userrestricted-namespace-indef' => "<big>'''Your user name or IP address has been restricted from editing $1 namespace.'''</big>
 1228+
 1229+The restriction was put by [[User:$2|$2]].
 1230+The reason given is ''$3''.
 1231+
 1232+Restriction was put on $4 at $5 and will not expire.
 1233+
 1234+You can contact [[User:$2|$2]] or another [[{{MediaWiki:Grouppage-sysop}}|administrator]] to discuss the restriction.",
 1235+
12011236 # Parser/template warnings
12021237 'expensive-parserfunction-warning' => 'Warning: This page contains too many expensive parser function calls.
12031238
@@ -2604,6 +2639,7 @@
26052640 'ipbsubmit' => 'Block this user',
26062641 'ipbother' => 'Other time:',
26072642 'ipboptions' => '2 hours:2 hours,1 day:1 day,3 days:3 days,1 week:1 week,2 weeks:2 weeks,1 month:1 month,3 months:3 months,6 months:6 months,1 year:1 year,infinite:infinite', # display1:time1,display2:time2,...
 2643+'ipbinfinite' => 'infinite',
26082644 'ipbotheroption' => 'other',
26092645 'ipbotherreason' => 'Other/additional reason:',
26102646 'ipbhidename' => 'Hide username from the block log, active block list and user list',
@@ -2686,6 +2722,72 @@
26872723 You cannot create an account',
26882724 'cant-block-while-blocked' => 'You cannot block other users while you are blocked.',
26892725
 2726+# Special:ListUserRestrictions
 2727+'listuserrestrictions' => 'List of user restrictions',
 2728+'listuserrestrictions-intro' => 'This list contains all restrictions from editing certain pages and namespaces put on users.
 2729+[[Special:Ipblocklist|Blocks]] are not listed here.',
 2730+'listuserrestrictions-row-ns' => 'restricted $1 from editing $2 namespace ($3)',
 2731+'listuserrestrictions-row-page' => 'restricted $1 from editing $2 ($3)',
 2732+'listuserrestrictions-row-expiry' => 'expires on $1 at $2',
 2733+'listuserrestrictions-legend' => 'Find a restriction',
 2734+'listuserrestrictions-type' => 'Type:',
 2735+'listuserrestrictions-user' => 'User:',
 2736+'listuserrestrictions-namespace' => 'Namespace:',
 2737+'listuserrestrictions-page' => 'Page:',
 2738+'listuserrestrictions-submit' => 'Go',
 2739+'listuserrestrictions-notfound' => 'There is no restriction that matches specified criteria.',
 2740+'listuserrestrictions-empty' => 'This list is empty.',
 2741+'listuserrestrictions-remove' => 'remove',
 2742+'userrestrictiontype-none' => '(none)',
 2743+'userrestrictiontype-namespace' => 'Namespace',
 2744+'userrestrictiontype-page' => 'Page',
 2745+
 2746+# Special:RemoveRestrictions
 2747+'removerestrictions' => 'Remove restriction from a user',
 2748+'removerestrictions-intro' => 'Use the form below to remove a restriction from a certain user.',
 2749+'removerestrictions-noid' => 'No restriction ID was specified.',
 2750+'removerestrictions-wrongid' => 'Restriction with that ID not found.
 2751+Most probably someone has removed it or it expired.',
 2752+'removerestrictions-legend' => 'Remove a restriction',
 2753+'removerestrictions-user' => 'Restricted user:',
 2754+'removerestrictions-type' => 'Restriction type:',
 2755+'removerestrictions-page' => 'Page:',
 2756+'removerestrictions-namespace' => 'Namespace:',
 2757+'removerestrictions-reason' => 'Reason:',
 2758+'removerestrictions-submit' => 'Remove the restriction',
 2759+'removerestrictions-success' => 'Successfully removed the restriction from [[User:$1|$1]].',
 2760+
 2761+# Restrict user
 2762+'restrictuser' => 'Restrict user',
 2763+'restrictuser-userselect' => 'Select a user',
 2764+'restrictuser-user' => 'User:',
 2765+'restrictuser-go' => 'Restrict user',
 2766+'restrictuser-notfound' => 'User not found',
 2767+'restrictuser-existing' => 'Existing restrictions',
 2768+'restrictuser-legend-page' => 'Restrict from editing certain page',
 2769+'restrictuser-legend-namespace' => 'Restrict from editing certain namespace',
 2770+'restrictuser-title' => 'Page to restrict:',
 2771+'restrictuser-namespace' => 'Namespace:',
 2772+'restrictuser-expiry' => 'Expires:',
 2773+'restrictuser-reason' => 'Reason:',
 2774+'restrictuser-submit' => 'Restrict user',
 2775+'restrictuser-badtitle' => 'Invalid title specified: $1.',
 2776+'restrictuser-badnamespace' => 'Invalid namespace specified.',
 2777+'restrictuser-badexpiry' => 'Invalid expiry specified: $1.',
 2778+'restrictuser-duptitle' => 'User is already restricted from editing this title.',
 2779+'restrictuser-dupnamespace' => 'User is already restricted from editing this namespace.',
 2780+'restrictuser-success' => 'Successfully restricted user $1.',
 2781+'restrictuser-description' => 'Use the form below to block write access to a specific page or namespace from a specific IP address or username.
 2782+This should be done only in accordance with policy. Fill in a specific reason below.',
 2783+
 2784+# Special:Log/restrict
 2785+'restrictionlog' => 'User restriction log',
 2786+'restrictionlogtext' => 'This log contains all restrictions put on users by administrators.',
 2787+'restrictentry' => 'restricted $1 from editing $2 (expiry set to $3)',
 2788+'restrictremoveentry' => 'removed restriction from $1 for editing $2',
 2789+'restrictlognamespace' => '$1 namespace',
 2790+'restrictlogpage' => '[[$1]]', # do not translate or duplicate this message to other languages
 2791+
26902792 # Developer tools
26912793 'lockdb' => 'Lock database',
26922794 'unlockdb' => 'Unlock database',

Follow-up revisions

RevisionCommit summaryAuthorDate
r45241Revert r45231, r45235 "* (bug 674) Allow users to be blocked from editing a s...brion18:56, 31 December 2008

Past revisions this follows-up on

RevisionCommit summaryAuthorDate
r41352* (bug 674) Allow users to be blocked from editing a specific article...vasilievvv16:08, 28 September 2008

Comments

#Comment by Brion VIBBER (talk | contribs)   18:56, 31 December 2008

Reverted for now in r45241

Unexpected schema changes in the middle of code review and run-up to 1.14 freeze

Status & tagging log