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