[ Index ]

PHP Cross Reference of MediaWiki-1.24.0

title

Body

[close]

/includes/cache/ -> GenderCache.php (source)

   1  <?php
   2  /**
   3   * Caches user genders when needed to use correct namespace aliases.
   4   *
   5   * This program is free software; you can redistribute it and/or modify
   6   * it under the terms of the GNU General Public License as published by
   7   * the Free Software Foundation; either version 2 of the License, or
   8   * (at your option) any later version.
   9   *
  10   * This program is distributed in the hope that it will be useful,
  11   * but WITHOUT ANY WARRANTY; without even the implied warranty of
  12   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13   * GNU General Public License for more details.
  14   *
  15   * You should have received a copy of the GNU General Public License along
  16   * with this program; if not, write to the Free Software Foundation, Inc.,
  17   * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
  18   * http://www.gnu.org/copyleft/gpl.html
  19   *
  20   * @file
  21   * @author Niklas Laxström
  22   * @ingroup Cache
  23   */
  24  
  25  /**
  26   * Caches user genders when needed to use correct namespace aliases.
  27   *
  28   * @since 1.18
  29   */
  30  class GenderCache {
  31      protected $cache = array();
  32      protected $default;
  33      protected $misses = 0;
  34      protected $missLimit = 1000;
  35  
  36      /**
  37       * @return GenderCache
  38       */
  39  	public static function singleton() {
  40          static $that = null;
  41          if ( $that === null ) {
  42              $that = new self();
  43          }
  44  
  45          return $that;
  46      }
  47  
  48  	protected function __construct() {
  49      }
  50  
  51      /**
  52       * Returns the default gender option in this wiki.
  53       * @return string
  54       */
  55  	protected function getDefault() {
  56          if ( $this->default === null ) {
  57              $this->default = User::getDefaultOption( 'gender' );
  58          }
  59  
  60          return $this->default;
  61      }
  62  
  63      /**
  64       * Returns the gender for given username.
  65       * @param string|User $username Username
  66       * @param string $caller The calling method
  67       * @return string
  68       */
  69  	public function getGenderOf( $username, $caller = '' ) {
  70          global $wgUser;
  71  
  72          if ( $username instanceof User ) {
  73              $username = $username->getName();
  74          }
  75  
  76          $username = self::normalizeUsername( $username );
  77          if ( !isset( $this->cache[$username] ) ) {
  78              if ( $this->misses >= $this->missLimit && $wgUser->getName() !== $username ) {
  79                  if ( $this->misses === $this->missLimit ) {
  80                      $this->misses++;
  81                      wfDebug( __METHOD__ . ": too many misses, returning default onwards\n" );
  82                  }
  83  
  84                  return $this->getDefault();
  85              } else {
  86                  $this->misses++;
  87                  $this->doQuery( $username, $caller );
  88              }
  89          }
  90  
  91          /* Undefined if there is a valid username which for some reason doesn't
  92           * exist in the database.
  93           */
  94          return isset( $this->cache[$username] ) ? $this->cache[$username] : $this->getDefault();
  95      }
  96  
  97      /**
  98       * Wrapper for doQuery that processes raw LinkBatch data.
  99       *
 100       * @param array $data
 101       * @param string $caller
 102       */
 103  	public function doLinkBatch( $data, $caller = '' ) {
 104          $users = array();
 105          foreach ( $data as $ns => $pagenames ) {
 106              if ( !MWNamespace::hasGenderDistinction( $ns ) ) {
 107                  continue;
 108              }
 109              foreach ( array_keys( $pagenames ) as $username ) {
 110                  $users[$username] = true;
 111              }
 112          }
 113  
 114          $this->doQuery( array_keys( $users ), $caller );
 115      }
 116  
 117      /**
 118       * Wrapper for doQuery that processes a title or string array.
 119       *
 120       * @since 1.20
 121       * @param array $titles Array of Title objects or strings
 122       * @param string $caller The calling method
 123       */
 124  	public function doTitlesArray( $titles, $caller = '' ) {
 125          $users = array();
 126          foreach ( $titles as $title ) {
 127              $titleObj = is_string( $title ) ? Title::newFromText( $title ) : $title;
 128              if ( !$titleObj ) {
 129                  continue;
 130              }
 131              if ( !MWNamespace::hasGenderDistinction( $titleObj->getNamespace() ) ) {
 132                  continue;
 133              }
 134              $users[] = $titleObj->getText();
 135          }
 136  
 137          $this->doQuery( $users, $caller );
 138      }
 139  
 140      /**
 141       * Preloads genders for given list of users.
 142       * @param array|string $users Usernames
 143       * @param string $caller The calling method
 144       */
 145  	public function doQuery( $users, $caller = '' ) {
 146          $default = $this->getDefault();
 147  
 148          $usersToCheck = array();
 149          foreach ( (array)$users as $value ) {
 150              $name = self::normalizeUsername( $value );
 151              // Skip users whose gender setting we already know
 152              if ( !isset( $this->cache[$name] ) ) {
 153                  // For existing users, this value will be overwritten by the correct value
 154                  $this->cache[$name] = $default;
 155                  // query only for valid names, which can be in the database
 156                  if ( User::isValidUserName( $name ) ) {
 157                      $usersToCheck[] = $name;
 158                  }
 159              }
 160          }
 161  
 162          if ( count( $usersToCheck ) === 0 ) {
 163              return;
 164          }
 165  
 166          $dbr = wfGetDB( DB_SLAVE );
 167          $table = array( 'user', 'user_properties' );
 168          $fields = array( 'user_name', 'up_value' );
 169          $conds = array( 'user_name' => $usersToCheck );
 170          $joins = array( 'user_properties' =>
 171              array( 'LEFT JOIN', array( 'user_id = up_user', 'up_property' => 'gender' ) ) );
 172  
 173          $comment = __METHOD__;
 174          if ( strval( $caller ) !== '' ) {
 175              $comment .= "/$caller";
 176          }
 177          $res = $dbr->select( $table, $fields, $conds, $comment, array(), $joins );
 178  
 179          foreach ( $res as $row ) {
 180              $this->cache[$row->user_name] = $row->up_value ? $row->up_value : $default;
 181          }
 182      }
 183  
 184  	private static function normalizeUsername( $username ) {
 185          // Strip off subpages
 186          $indexSlash = strpos( $username, '/' );
 187          if ( $indexSlash !== false ) {
 188              $username = substr( $username, 0, $indexSlash );
 189          }
 190  
 191          // normalize underscore/spaces
 192          return strtr( $username, '_', ' ' );
 193      }
 194  }


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