http://www.mediawiki.org/wiki/Special:Code/MediaWiki/90749

Revision: 90749
Author:   aaron
Date:     2011-06-25 02:52:30 +0000 (Sat, 25 Jun 2011)
Log Message:
-----------
Added one-time promote support via Autopromote::autopromoteOnceHook function. 
This is still a bit rough on the edges. This uses a hook since extension may 
want to control when it's called for performance reasons. Patch by lampak. (for 
bug 24948)

Modified Paths:
--------------
    trunk/phase3/includes/Autopromote.php
    trunk/phase3/includes/DefaultSettings.php
    trunk/phase3/includes/User.php
    trunk/phase3/includes/installer/MysqlUpdater.php
    trunk/phase3/includes/installer/SqliteUpdater.php
    trunk/phase3/maintenance/postgres/tables.sql
    trunk/phase3/maintenance/tables.sql

Added Paths:
-----------
    trunk/phase3/maintenance/archives/patch-user_former_groups.sql
    trunk/phase3/maintenance/postgres/archives/patch-user_former_groups.sql

Modified: trunk/phase3/includes/Autopromote.php
===================================================================
--- trunk/phase3/includes/Autopromote.php       2011-06-25 01:46:43 UTC (rev 
90748)
+++ trunk/phase3/includes/Autopromote.php       2011-06-25 02:52:30 UTC (rev 
90749)
@@ -6,6 +6,41 @@
 
 class Autopromote {
        /**
+        * A function which may be assigned to a hook in order to check 
+        *   autopromotion of the current user (\ref $wgUser) to the specified 
+        *   group.
+        *    
+        * Contrary to autopromotion by \ref $wgAutopromote, the group will be 
+        *   possible to remove manually via Special:UserRights. In such case it
+        *   will not be re-added autmoatically. The user will also not lose the
+        *   group if they no longer meet the criteria.
+        *   
+        * Example configuration: 
+        * \code $wgHooks['ArticleSaveComplete'][] = array (
+        *     'Autopromote::autopromoteOnceHook', 
+        *     array( 'somegroup' => array(APCOND_EDITCOUNT, 200) )
+        * ); \endcode
+        * 
+        * The second array should be of the same format as \ref $wgAutopromote.
+        * 
+        * This funciton simply runs User::autopromoteOnce() on $wgUser. You may
+        *   run this method from your custom function if you wish.  
+        * 
+        * @param $criteria array Groups and conditions which must be met in 
order to
+        *   aquire these groups. Array of the same format as \ref 
$wgAutopromote.
+        *               
+        * @return Always true.
+        * 
+        * @see User::autopromoteOnce()
+        * @see $wgAutopromote
+        */
+       public static function autopromoteOnceHook($criteria) {
+               global $wgUser; 
+               $wgUser->autopromoteOnce($criteria); 
+               return true; 
+       }
+       
+       /**
         * Get the groups for the given user based on $wgAutopromote.
         *
         * @param $user User The user to get the groups for
@@ -26,6 +61,41 @@
 
                return $promote;
        }
+       
+       /**
+        * Get the groups for the given user based on the given criteria.
+        * 
+        * Does not return groups the user already belongs to or has once 
belonged.
+        * 
+        * @param $user The user to get the groups for
+        * @param $criteria array Groups and conditions the user must meet in 
order
+        *   to be promoted to these groups. Array of the same format as 
+        *   \ref $wgAutopromote. 
+        *               
+        * @return array Groups the user should be promoted to.
+        */
+       public static function getAutopromoteOnceGroups( User $user, $criteria 
) {
+               $promote = array();
+               
+               //get the current groups 
+               $currentGroups = $user->getGroups();
+               
+               foreach( $criteria as $group => $cond ) {
+                       //do not check if the user's already a member
+                       if ( in_array($group, $currentGroups))
+                               continue;
+               
+                       //do not autopromote if the user has belonged to the 
group
+                       $formerGroups = $user->getFormerGroups();
+                       if ( in_array($group, $formerGroups) )
+                               continue;
+                               
+                       //finally - check the conditions 
+                       if ( self::recCheckCondition($cond, $user) )
+                               $promote[] = $group; 
+               }
+               return $promote;
+       }
 
        /**
         * Recursively check a condition.  Conditions are in the form

Modified: trunk/phase3/includes/DefaultSettings.php
===================================================================
--- trunk/phase3/includes/DefaultSettings.php   2011-06-25 01:46:43 UTC (rev 
90748)
+++ trunk/phase3/includes/DefaultSettings.php   2011-06-25 02:52:30 UTC (rev 
90749)
@@ -3513,6 +3513,12 @@
  *
  * If $wgEmailAuthentication is off, APCOND_EMAILCONFIRMED will be true for any
  * user who has provided an e-mail address.
+ * 
+ * If the groups should be removable, consider using 
+ *   Autopromote::autopromoteOnceHook() instead.
+ * 
+ * @see Autopromote::autopromoteOnceHook()
+ * @see User::autopromoteOnce()
  */
 $wgAutopromote = array(
        'autoconfirmed' => array( '&',

Modified: trunk/phase3/includes/User.php
===================================================================
--- trunk/phase3/includes/User.php      2011-06-25 01:46:43 UTC (rev 90748)
+++ trunk/phase3/includes/User.php      2011-06-25 02:52:30 UTC (rev 90749)
@@ -71,7 +71,7 @@
                'mEmailTokenExpires',
                'mRegistration',
                'mEditCount',
-               // user_group table
+               // user_groups table
                'mGroups',
                // user_properties table
                'mOptionOverrides',
@@ -182,7 +182,7 @@
         * Lazy-initialized variables, invalidated with clearInstanceCache
         */
        var $mNewtalk, $mDatePreference, $mBlockedby, $mHash, $mRights,
-               $mBlockreason, $mEffectiveGroups, $mBlockedGlobally,
+               $mBlockreason, $mEffectiveGroups, $mFormerGroups, 
$mBlockedGlobally,
                $mLocked, $mHideName, $mOptions;
 
        /**
@@ -1103,6 +1103,33 @@
        }
 
        /**
+        * Add the user to the group if he/she meets given criteria.
+        * 
+        * Contrary to autopromotion by \ref $wgAutopromote, the group will be 
+        *   possible to remove manually via Special:UserRights. In such case it
+        *   will not be re-added autmoatically. The user will also not lose the
+        *   group if they no longer meet the criteria.
+        *   
+        * @param $criteria array Groups and conditions the user must meet in 
order
+        *   to be promoted to these groups. Array of the same format as 
+        *   \ref $wgAutopromote. 
+        *   
+        * @return array Array of groups the user has been promoted to.  
+        * 
+        * @see $wgAutopromote
+        * @see Autopromote::autopromoteOnceHook()
+        */
+       public function autopromoteOnce( $criteria ) {          
+               if ($this->getId())     {
+                       $toPromote = 
Autopromote::getAutopromoteOnceGroups($this, $criteria);
+                       foreach($toPromote as $group)
+                               $this->addGroup($group);
+                       return $toPromote;
+               }
+               return array(); 
+       }
+       
+       /**
         * Clear various cached data stored in this object.
         * @param $reloadFrom String Reload user and user_groups table data 
from a
         *   given source. May be "name", "id", "defaults", "session", or false 
for
@@ -1116,7 +1143,7 @@
                $this->mSkin = null;
                $this->mRights = null;
                $this->mEffectiveGroups = null;
-               $this->mOptions = null;
+               $this->mOptions = null; 
 
                if ( $reloadFrom ) {
                        $this->mLoadedItems = array();
@@ -2240,8 +2267,32 @@
                }
                return $this->mEffectiveGroups;
        }
-
+       
        /**
+        * Returns the groups the user has belonged to. 
+        * 
+        * The user may still belong to the returned groups. Compare with 
getGroups().
+        * 
+        * The function will not return groups the user had belonged to before 
MW 1.17
+        *  
+        * @return array Names of the groups the user has belonged to. 
+        */
+       function getFormerGroups() {
+               if(is_null($this->mFormerGroups)) {
+                       $dbr = wfGetDB( DB_MASTER );
+                       $res = $dbr->select( 'user_former_groups',
+                               array( 'ufg_group' ),
+                               array( 'ufg_user' => $this->mId ),
+                               __METHOD__ );
+                       $this->mFormerGroups = array();
+                       while( $row = $dbr->fetchObject( $res ) ) {
+                               $this->mFormerGroups[] = $row->ufg_group;
+                       }
+               }       
+               return $this->mFormerGroups;
+       }
+       
+       /**
         * Get the user's edit count.
         * @return Int
         */
@@ -2297,6 +2348,14 @@
                                        'ug_user'  => $this->getID(),
                                        'ug_group' => $group,
                                ), __METHOD__ );
+                       //remember that the user has had this group
+                       $dbw->insert( 'user_former_groups',
+                               array(
+                                       'ufg_user'  => $this->getID(),
+                                       'ufg_group' => $group,
+                               ),
+                               __METHOD__,
+                               array( 'IGNORE' ) );
                }
                $this->loadGroups();
                $this->mGroups = array_diff( $this->mGroups, array( $group ) );

Modified: trunk/phase3/includes/installer/MysqlUpdater.php
===================================================================
--- trunk/phase3/includes/installer/MysqlUpdater.php    2011-06-25 01:46:43 UTC 
(rev 90748)
+++ trunk/phase3/includes/installer/MysqlUpdater.php    2011-06-25 02:52:30 UTC 
(rev 90749)
@@ -162,6 +162,7 @@
 
                        // 1.17
                        array( 'addTable', 'iwlinks',                           
'patch-iwlinks.sql' ),
+                       array( 'addTable', 'user_former_groups',             
'patch-user_former_groups.sql'),
                        array( 'addIndex', 'iwlinks', 'iwl_prefix_title_from',  
'patch-rename-iwl_prefix.sql' ),
                        array( 'addField', 'updatelog',     'ul_value',         
'patch-ul_value.sql' ),
                        array( 'addField', 'interwiki',     'iw_api',           
'patch-iw_api_and_wikiid.sql' ),

Modified: trunk/phase3/includes/installer/SqliteUpdater.php
===================================================================
--- trunk/phase3/includes/installer/SqliteUpdater.php   2011-06-25 01:46:43 UTC 
(rev 90748)
+++ trunk/phase3/includes/installer/SqliteUpdater.php   2011-06-25 02:52:30 UTC 
(rev 90749)
@@ -43,6 +43,7 @@
 
                        // 1.17
                        array( 'addTable', 'iwlinks',                           
 'patch-iwlinks.sql' ),
+                       array( 'addTable', 'user_former_groups',             
'patch-user_former_groups.sql'),
                        array( 'addIndex', 'iwlinks',   
'iwl_prefix_title_from', 'patch-rename-iwl_prefix.sql' ),
                        array( 'addField', 'updatelog', 'ul_value',             
 'patch-ul_value.sql' ),
                        array( 'addField', 'interwiki',     'iw_api',           
'patch-iw_api_and_wikiid.sql' ),

Added: trunk/phase3/maintenance/archives/patch-user_former_groups.sql
===================================================================
--- trunk/phase3/maintenance/archives/patch-user_former_groups.sql              
                (rev 0)
+++ trunk/phase3/maintenance/archives/patch-user_former_groups.sql      
2011-06-25 02:52:30 UTC (rev 90749)
@@ -0,0 +1,10 @@
+-- Stores the groups the user has once belonged to. 
+-- The user may still belong these groups. Check user_groups.
+CREATE TABLE /*_*/user_former_groups (
+  -- Key to user_id
+  ufg_user int unsigned NOT NULL default 0,
+  ufg_group varbinary(16) NOT NULL default '',
+  
+  PRIMARY KEY (ufg_user,ufg_group),
+  KEY (ufg_group)
+) /*$wgDBTableOptions*/;


Property changes on: 
trunk/phase3/maintenance/archives/patch-user_former_groups.sql
___________________________________________________________________
Added: svn:eol-style
   + native

Added: trunk/phase3/maintenance/postgres/archives/patch-user_former_groups.sql
===================================================================
--- trunk/phase3/maintenance/postgres/archives/patch-user_former_groups.sql     
                        (rev 0)
+++ trunk/phase3/maintenance/postgres/archives/patch-user_former_groups.sql     
2011-06-25 02:52:30 UTC (rev 90749)
@@ -0,0 +1,5 @@
+CREATE TABLE user_former_groups (
+  ufg_user   INTEGER      NULL  REFERENCES mwuser(user_id) ON DELETE CASCADE 
DEFERRABLE INITIALLY DEFERRED,
+  ufg_group  TEXT     NOT NULL
+);
+CREATE UNIQUE INDEX user_former_groups_unique ON user_former_groups (ufg_user, 
ufg_group);


Property changes on: 
trunk/phase3/maintenance/postgres/archives/patch-user_former_groups.sql
___________________________________________________________________
Added: svn:eol-style
   + native

Modified: trunk/phase3/maintenance/postgres/tables.sql
===================================================================
--- trunk/phase3/maintenance/postgres/tables.sql        2011-06-25 01:46:43 UTC 
(rev 90748)
+++ trunk/phase3/maintenance/postgres/tables.sql        2011-06-25 02:52:30 UTC 
(rev 90749)
@@ -54,6 +54,12 @@
 );
 CREATE UNIQUE INDEX user_groups_unique ON user_groups (ug_user, ug_group);
 
+CREATE TABLE user_former_groups (
+  ufg_user   INTEGER      NULL  REFERENCES mwuser(user_id) ON DELETE CASCADE 
DEFERRABLE INITIALLY DEFERRED,
+  ufg_group  TEXT     NOT NULL
+);
+CREATE UNIQUE INDEX user_former_groups_unique ON user_former_groups (ufg_user, 
ufg_group);
+
 CREATE TABLE user_newtalk (
   user_id              INTEGER      NOT NULL  REFERENCES mwuser(user_id) ON 
DELETE CASCADE DEFERRABLE INITIALLY DEFERRED,
   user_ip              TEXT             NULL,

Modified: trunk/phase3/maintenance/tables.sql
===================================================================
--- trunk/phase3/maintenance/tables.sql 2011-06-25 01:46:43 UTC (rev 90748)
+++ trunk/phase3/maintenance/tables.sql 2011-06-25 02:52:30 UTC (rev 90749)
@@ -164,7 +164,17 @@
 CREATE UNIQUE INDEX /*i*/ug_user_group ON /*_*/user_groups (ug_user,ug_group);
 CREATE INDEX /*i*/ug_group ON /*_*/user_groups (ug_group);
 
+-- Stores the groups the user has once belonged to. 
+-- The user may still belong these groups. Check user_groups.
+CREATE TABLE /*_*/user_former_groups (
+  -- Key to user_id
+  ufg_user int unsigned NOT NULL default 0,
+  ufg_group varbinary(16) NOT NULL default ''
+) /*$wgDBTableOptions*/;
 
+CREATE UNIQUE INDEX /*i*/ufg_user_group ON /*_*/user_former_groups 
(ufg_user,ufg_group);
+CREATE INDEX /*i*/ufg_group ON /*_*/user_former_groups (ufg_group);
+
 --
 -- Stores notifications of user talk page changes, for the display
 -- of the "you have new messages" box


_______________________________________________
MediaWiki-CVS mailing list
[email protected]
https://lists.wikimedia.org/mailman/listinfo/mediawiki-cvs

Reply via email to