* (bug 674) Allow users to be blocked from editing a specific article
[lhc/web/wiklou.git] / includes / User.php
index bc4b131..2efe9f1 100644 (file)
@@ -118,6 +118,8 @@ class User {
                'mEditCount',
                // user_group table
                'mGroups',
+               // user_restrictions table
+               'mRestrictions',
        );
 
        /**
@@ -156,6 +158,7 @@ class User {
                'proxyunbannable',
                'purge',
                'read',
+               'restrict',
                'reupload',
                'reupload-shared',
                'rollback',
@@ -177,7 +180,8 @@ class User {
        //@{
        var $mId, $mName, $mRealName, $mPassword, $mNewpassword, $mNewpassTime,
                $mEmail, $mOptions, $mTouched, $mToken, $mEmailAuthenticated,
-               $mEmailToken, $mEmailTokenExpires, $mRegistration, $mGroups;
+               $mEmailToken, $mEmailTokenExpires, $mRegistration, $mGroups,
+               $mRestrictions;
        //@}
 
        /**
@@ -297,6 +301,7 @@ class User {
        function saveToCache() {
                $this->load();
                $this->loadGroups();
+               $this->loadRestrictions();
                if ( $this->isAnon() ) {
                        // Anonymous users are uncached
                        return;
@@ -646,7 +651,9 @@ class User {
                        return false;
 
                # Clean up name according to title rules
-               $t = Title::newFromText( $name );
+               $t = ($validate === 'valid') ? 
+                       Title::newFromText( $name ) : Title::makeTitle( NS_USER, $name );
+               # Check for invalid titles
                if( is_null( $t ) ) {
                        return false;
                }
@@ -876,6 +883,7 @@ class User {
                        # Initialise user table data
                        $this->loadFromRow( $s );
                        $this->mGroups = null; // deferred
+                       $this->mRestrictions = null;
                        $this->getEditCount(); // revalidation for nulls
                        return true;
                } else {
@@ -1034,6 +1042,7 @@ class User {
                
                $this->mBlockedby = 0;
                $this->mHideName = 0;
+               $this->mAllowUsertalk = 0;
                $ip = wfGetIP();
 
                if ($this->isAllowed( 'ipblock-exempt' ) ) {
@@ -1049,12 +1058,14 @@ class User {
                        $this->mBlockedby = $this->mBlock->mBy;
                        $this->mBlockreason = $this->mBlock->mReason;
                        $this->mHideName = $this->mBlock->mHideName;
+                       $this->mAllowUsertalk = $this->mBlock->mAllowUsertalk;
                        if ( $this->isLoggedIn() ) {
                                $this->spreadBlock();
                        }
                } else {
-                       $this->mBlock = null;
-                       wfDebug( __METHOD__.": No block.\n" );
+                       // Bug 13611: don't remove mBlock here, to allow account creation blocks to 
+                       // apply to users. Note that the existence of $this->mBlock is not used to 
+                       // check for edit blocks, $this->mBlockedby is instead.
                }
 
                # Proxy blocking
@@ -1105,19 +1116,15 @@ class User {
 
                $found = false;
                $host = '';
-               // FIXME: IPv6 ???
-               $m = array();
-               if ( preg_match( '/^(\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})$/', $ip, $m ) ) {
+               // FIXME: IPv6 ???  (http://bugs.php.net/bug.php?id=33170)
+               if( IP::isIPv4($ip) ) {
                        # Make hostname
-                       for ( $i=4; $i>=1; $i-- ) {
-                               $host .= $m[$i] . '.';
-                       }
-                       $host .= $base;
+                       $host = "$ip.$base";
 
                        # Send query
                        $ipList = gethostbynamel( $host );
 
-                       if ( $ipList ) {
+                       if( $ipList ) {
                                wfDebug( "Hostname $host is {$ipList[0]}, it's a proxy says $base!\n" );
                                $found = true;
                        } else {
@@ -1267,7 +1274,7 @@ class User {
                wfDebug( __METHOD__.": asking isBlocked()\n" );
                $blocked = $this->isBlocked( $bFromSlave );
                # If a user's name is suppressed, they cannot make edits anywhere
-               if ( !$this->mHideName && $wgBlockAllowsUTEdit && $title->getText() === $this->getName() &&
+               if ( !$this->mHideName && $this->mAllowUsertalk && $title->getText() === $this->getName() &&
                  $title->getNamespace() == NS_USER_TALK ) {
                        $blocked = false;
                        wfDebug( __METHOD__.": self-talk page, ignoring any blocks\n" );
@@ -2007,7 +2014,9 @@ class User {
                        // In the spirit of DWIM
                        return true;
 
-               return in_array( $action, $this->getRights() );
+               # Use strict parameter to avoid matching numeric 0 accidentally inserted 
+               # by misconfiguration: 0 == 'foo'
+               return in_array( $action, $this->getRights(), true );
        }
 
        /**
@@ -2438,7 +2447,7 @@ class User {
         * @return \type{\string} Page rendering hash
         */
        function getPageRenderingHash() {
-               global $wgContLang, $wgUseDynamicDates, $wgLang;
+               global $wgUseDynamicDates, $wgRenderHashAppend, $wgLang, $wgContLang;
                if( $this->mHash ){
                        return $this->mHash;
                }
@@ -2458,6 +2467,8 @@ class User {
                $extra = $wgContLang->getExtraHashOptions();
                $confstr .= $extra;
 
+               $confstr .= $wgRenderHashAppend;
+
                // Give a chance for extensions to modify the hash, if they have
                // extra options or other effects on the parser cache.
                wfRunHooks( 'PageRenderingHash', array( &$confstr ) );
@@ -3221,7 +3232,7 @@ class User {
         * Add an autocreate newuser log entry for this user
         * Used by things like CentralAuth and perhaps other authplugins.
         */
-       public static function addNewUserLogEntryAutoCreate() {
+       public function addNewUserLogEntryAutoCreate() {
                global $wgNewUserLog;
                if( empty($wgNewUserLog) ) {
                        return true; // disabled
@@ -3231,4 +3242,50 @@ class User {
                return true;
        }
 
+       // Restrictions-related block
+
+       public function loadRestrictions() {
+               if( !$this->mRestrictions )
+                       $this->mRestrictions = UserRestriction::fetchForUser( $this->isLoggedIn() ? 
+                               intval( $this->getId() ) : $this->getName()  );
+       }
+
+       public function getRestrictions() {
+               $this->loadRestrictions();
+
+               // Check for expired restrictions. Recache if found expired ones
+               static $checked = false;
+               if( !$checked ) {
+                       $expired = false;
+                       $old = $this->mRestrictions;
+                       $this->mRestrictions = array();
+                       foreach( $old as $restriction ) {
+                               if( $restriction->deleteIfExpired() )
+                                       $expired = true;
+                               else
+                                       $this->mRestrictions[] = $restriction;
+                       }
+                       if( $expired )
+                               $this->saveToCache();
+                       $checked = true;
+               }
+
+               return $this->mRestrictions;
+       }
+
+       public function getRestrictionForPage( Title $page ) {
+               foreach( $this->getRestrictions() as $r ) {
+                       if( $r->isPage() && $page->equals( $r->getPage() ) )
+                               return $r;
+               }
+               return null;
+       }
+
+       public function getRestrictionForNamespace( $nsid ) {
+               foreach( $this->getRestrictions() as $r ) {
+                       if( $r->isNamespace() && $r->getNamespace() == $nsid )
+                               return $r;
+               }
+               return null;
+       }
 }