PageRenderTime 45ms CodeModel.GetById 19ms RepoModel.GetById 0ms app.codeStats 0ms

/includes/cache/GenderCache.php

https://github.com/spenser-roark/OOUG-Wiki
PHP | 135 lines | 82 code | 19 blank | 34 comment | 15 complexity | f078212757264700c780c3be3a0dcd5d MD5 | raw file
Possible License(s): GPL-2.0, Apache-2.0, LGPL-3.0
  1. <?php
  2. /**
  3. * Caches user genders when needed to use correct namespace aliases.
  4. * @author Niklas Laxstrรถm
  5. * @since 1.18
  6. */
  7. class GenderCache {
  8. protected $cache = array();
  9. protected $default;
  10. protected $misses = 0;
  11. protected $missLimit = 1000;
  12. /**
  13. * @return GenderCache
  14. */
  15. public static function singleton() {
  16. static $that = null;
  17. if ( $that === null ) {
  18. $that = new self();
  19. }
  20. return $that;
  21. }
  22. protected function __construct() {}
  23. /**
  24. * Returns the default gender option in this wiki.
  25. * @return String
  26. */
  27. protected function getDefault() {
  28. if ( $this->default === null ) {
  29. $this->default = User::getDefaultOption( 'gender' );
  30. }
  31. return $this->default;
  32. }
  33. /**
  34. * Returns the gender for given username.
  35. * @param $username String: username
  36. * @param $caller String: the calling method
  37. * @return String
  38. */
  39. public function getGenderOf( $username, $caller = '' ) {
  40. global $wgUser;
  41. $username = strtr( $username, '_', ' ' );
  42. if ( !isset( $this->cache[$username] ) ) {
  43. if ( $this->misses >= $this->missLimit && $wgUser->getName() !== $username ) {
  44. if( $this->misses === $this->missLimit ) {
  45. $this->misses++;
  46. wfDebug( __METHOD__ . ": too many misses, returning default onwards\n" );
  47. }
  48. return $this->getDefault();
  49. } else {
  50. $this->misses++;
  51. if ( !User::isValidUserName( $username ) ) {
  52. $this->cache[$username] = $this->getDefault();
  53. } else {
  54. $this->doQuery( $username, $caller );
  55. }
  56. }
  57. }
  58. /* Undefined if there is a valid username which for some reason doesn't
  59. * exist in the database.
  60. */
  61. return isset( $this->cache[$username] ) ? $this->cache[$username] : $this->getDefault();
  62. }
  63. /**
  64. * Wrapper for doQuery that processes raw LinkBatch data.
  65. *
  66. * @param $data
  67. * @param $caller
  68. */
  69. public function doLinkBatch( $data, $caller = '' ) {
  70. $users = array();
  71. foreach ( $data as $ns => $pagenames ) {
  72. if ( !MWNamespace::hasGenderDistinction( $ns ) ) continue;
  73. foreach ( array_keys( $pagenames ) as $username ) {
  74. if ( isset( $this->cache[$username] ) ) continue;
  75. $users[$username] = true;
  76. }
  77. }
  78. $this->doQuery( array_keys( $users ), $caller );
  79. }
  80. /**
  81. * Preloads genders for given list of users.
  82. * @param $users List|String: usernames
  83. * @param $caller String: the calling method
  84. */
  85. public function doQuery( $users, $caller = '' ) {
  86. $default = $this->getDefault();
  87. foreach ( (array) $users as $index => $value ) {
  88. $name = strtr( $value, '_', ' ' );
  89. if ( isset( $this->cache[$name] ) ) {
  90. // Skip users whose gender setting we already know
  91. unset( $users[$index] );
  92. } else {
  93. $users[$index] = $name;
  94. // For existing users, this value will be overwritten by the correct value
  95. $this->cache[$name] = $default;
  96. }
  97. }
  98. if ( count( $users ) === 0 ) {
  99. return;
  100. }
  101. $dbr = wfGetDB( DB_SLAVE );
  102. $table = array( 'user', 'user_properties' );
  103. $fields = array( 'user_name', 'up_value' );
  104. $conds = array( 'user_name' => $users );
  105. $joins = array( 'user_properties' =>
  106. array( 'LEFT JOIN', array( 'user_id = up_user', 'up_property' => 'gender' ) ) );
  107. $comment = __METHOD__;
  108. if ( strval( $caller ) !== '' ) {
  109. $comment .= "/$caller";
  110. }
  111. $res = $dbr->select( $table, $fields, $conds, $comment, $joins, $joins );
  112. foreach ( $res as $row ) {
  113. $this->cache[$row->user_name] = $row->up_value ? $row->up_value : $default;
  114. }
  115. }
  116. }