[ Index ]

PHP Cross Reference of MediaWiki-1.24.0

title

Body

[close]

/includes/ -> Autopromote.php (source)

   1  <?php
   2  /**
   3   * Automatic user rights promotion based on conditions specified
   4   * in $wgAutopromote.
   5   *
   6   * This program is free software; you can redistribute it and/or modify
   7   * it under the terms of the GNU General Public License as published by
   8   * the Free Software Foundation; either version 2 of the License, or
   9   * (at your option) any later version.
  10   *
  11   * This program is distributed in the hope that it will be useful,
  12   * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  14   * GNU General Public License for more details.
  15   *
  16   * You should have received a copy of the GNU General Public License along
  17   * with this program; if not, write to the Free Software Foundation, Inc.,
  18   * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
  19   * http://www.gnu.org/copyleft/gpl.html
  20   *
  21   * @file
  22   */
  23  
  24  /**
  25   * This class checks if user can get extra rights
  26   * because of conditions specified in $wgAutopromote
  27   */
  28  class Autopromote {
  29      /**
  30       * Get the groups for the given user based on $wgAutopromote.
  31       *
  32       * @param User $user The user to get the groups for
  33       * @return array Array of groups to promote to.
  34       */
  35  	public static function getAutopromoteGroups( User $user ) {
  36          global $wgAutopromote;
  37  
  38          $promote = array();
  39  
  40          foreach ( $wgAutopromote as $group => $cond ) {
  41              if ( self::recCheckCondition( $cond, $user ) ) {
  42                  $promote[] = $group;
  43              }
  44          }
  45  
  46          wfRunHooks( 'GetAutoPromoteGroups', array( $user, &$promote ) );
  47  
  48          return $promote;
  49      }
  50  
  51      /**
  52       * Get the groups for the given user based on the given criteria.
  53       *
  54       * Does not return groups the user already belongs to or has once belonged.
  55       *
  56       * @param User $user The user to get the groups for
  57       * @param string $event Key in $wgAutopromoteOnce (each one has groups/criteria)
  58       *
  59       * @return array Groups the user should be promoted to.
  60       *
  61       * @see $wgAutopromoteOnce
  62       */
  63  	public static function getAutopromoteOnceGroups( User $user, $event ) {
  64          global $wgAutopromoteOnce;
  65  
  66          $promote = array();
  67  
  68          if ( isset( $wgAutopromoteOnce[$event] ) && count( $wgAutopromoteOnce[$event] ) ) {
  69              $currentGroups = $user->getGroups();
  70              $formerGroups = $user->getFormerGroups();
  71              foreach ( $wgAutopromoteOnce[$event] as $group => $cond ) {
  72                  // Do not check if the user's already a member
  73                  if ( in_array( $group, $currentGroups ) ) {
  74                      continue;
  75                  }
  76                  // Do not autopromote if the user has belonged to the group
  77                  if ( in_array( $group, $formerGroups ) ) {
  78                      continue;
  79                  }
  80                  // Finally - check the conditions
  81                  if ( self::recCheckCondition( $cond, $user ) ) {
  82                      $promote[] = $group;
  83                  }
  84              }
  85          }
  86  
  87          return $promote;
  88      }
  89  
  90      /**
  91       * Recursively check a condition.  Conditions are in the form
  92       *   array( '&' or '|' or '^' or '!', cond1, cond2, ... )
  93       * where cond1, cond2, ... are themselves conditions; *OR*
  94       *   APCOND_EMAILCONFIRMED, *OR*
  95       *   array( APCOND_EMAILCONFIRMED ), *OR*
  96       *   array( APCOND_EDITCOUNT, number of edits ), *OR*
  97       *   array( APCOND_AGE, seconds since registration ), *OR*
  98       *   similar constructs defined by extensions.
  99       * This function evaluates the former type recursively, and passes off to
 100       * self::checkCondition for evaluation of the latter type.
 101       *
 102       * @param mixed $cond A condition, possibly containing other conditions
 103       * @param User $user The user to check the conditions against
 104       * @return bool Whether the condition is true
 105       */
 106  	private static function recCheckCondition( $cond, User $user ) {
 107          $validOps = array( '&', '|', '^', '!' );
 108  
 109          if ( is_array( $cond ) && count( $cond ) >= 2 && in_array( $cond[0], $validOps ) ) {
 110              # Recursive condition
 111              if ( $cond[0] == '&' ) { // AND (all conds pass)
 112                  foreach ( array_slice( $cond, 1 ) as $subcond ) {
 113                      if ( !self::recCheckCondition( $subcond, $user ) ) {
 114                          return false;
 115                      }
 116                  }
 117  
 118                  return true;
 119              } elseif ( $cond[0] == '|' ) { // OR (at least one cond passes)
 120                  foreach ( array_slice( $cond, 1 ) as $subcond ) {
 121                      if ( self::recCheckCondition( $subcond, $user ) ) {
 122                          return true;
 123                      }
 124                  }
 125  
 126                  return false;
 127              } elseif ( $cond[0] == '^' ) { // XOR (exactly one cond passes)
 128                  if ( count( $cond ) > 3 ) {
 129                      wfWarn( 'recCheckCondition() given XOR ("^") condition on three or more conditions.' .
 130                          ' Check your $wgAutopromote and $wgAutopromoteOnce settings.' );
 131                  }
 132                  return self::recCheckCondition( $cond[1], $user )
 133                      xor self::recCheckCondition( $cond[2], $user );
 134              } elseif ( $cond[0] == '!' ) { // NOT (no conds pass)
 135                  foreach ( array_slice( $cond, 1 ) as $subcond ) {
 136                      if ( self::recCheckCondition( $subcond, $user ) ) {
 137                          return false;
 138                      }
 139                  }
 140  
 141                  return true;
 142              }
 143          }
 144          // If we got here, the array presumably does not contain other conditions;
 145          // it's not recursive.  Pass it off to self::checkCondition.
 146          if ( !is_array( $cond ) ) {
 147              $cond = array( $cond );
 148          }
 149  
 150          return self::checkCondition( $cond, $user );
 151      }
 152  
 153      /**
 154       * As recCheckCondition, but *not* recursive.  The only valid conditions
 155       * are those whose first element is APCOND_EMAILCONFIRMED/APCOND_EDITCOUNT/
 156       * APCOND_AGE.  Other types will throw an exception if no extension evaluates them.
 157       *
 158       * @param array $cond A condition, which must not contain other conditions
 159       * @param User $user The user to check the condition against
 160       * @throws MWException
 161       * @return bool Whether the condition is true for the user
 162       */
 163  	private static function checkCondition( $cond, User $user ) {
 164          global $wgEmailAuthentication;
 165          if ( count( $cond ) < 1 ) {
 166              return false;
 167          }
 168  
 169          switch ( $cond[0] ) {
 170              case APCOND_EMAILCONFIRMED:
 171                  if ( Sanitizer::validateEmail( $user->getEmail() ) ) {
 172                      if ( $wgEmailAuthentication ) {
 173                          return (bool)$user->getEmailAuthenticationTimestamp();
 174                      } else {
 175                          return true;
 176                      }
 177                  }
 178                  return false;
 179              case APCOND_EDITCOUNT:
 180                  return $user->getEditCount() >= $cond[1];
 181              case APCOND_AGE:
 182                  $age = time() - wfTimestampOrNull( TS_UNIX, $user->getRegistration() );
 183                  return $age >= $cond[1];
 184              case APCOND_AGE_FROM_EDIT:
 185                  $age = time() - wfTimestampOrNull( TS_UNIX, $user->getFirstEditTimestamp() );
 186                  return $age >= $cond[1];
 187              case APCOND_INGROUPS:
 188                  $groups = array_slice( $cond, 1 );
 189                  return count( array_intersect( $groups, $user->getGroups() ) ) == count( $groups );
 190              case APCOND_ISIP:
 191                  return $cond[1] == $user->getRequest()->getIP();
 192              case APCOND_IPINRANGE:
 193                  return IP::isInRange( $user->getRequest()->getIP(), $cond[1] );
 194              case APCOND_BLOCKED:
 195                  return $user->isBlocked();
 196              case APCOND_ISBOT:
 197                  return in_array( 'bot', User::getGroupPermissions( $user->getGroups() ) );
 198              default:
 199                  $result = null;
 200                  wfRunHooks( 'AutopromoteCondition', array( $cond[0],
 201                      array_slice( $cond, 1 ), $user, &$result ) );
 202                  if ( $result === null ) {
 203                      throw new MWException( "Unrecognized condition {$cond[0]} for autopromotion!" );
 204                  }
 205  
 206                  return (bool)$result;
 207          }
 208      }
 209  }


Generated: Fri Nov 28 14:03:12 2014 Cross-referenced by PHPXref 0.7.1