Second attempt for this thing..
regularly. Below only new and removed languages are listed, as well as
changes to languages because of Bugzilla reports.
+* (bug 17160) Gender specific display text for User namespace
+
== Compatibility ==
MediaWiki 1.18 requires PHP 5.1 (5.2 recommended). PHP 4 is no longer
'ForkController' => 'includes/ForkController.php',
'FormatExif' => 'includes/Exif.php',
'FormOptions' => 'includes/FormOptions.php',
+ 'GenderCache' => 'includes/GenderCache.php',
'GlobalDependency' => 'includes/CacheDependency.php',
'HashBagOStuff' => 'includes/BagOStuff.php',
'HashtableReplacer' => 'includes/StringUtils.php',
--- /dev/null
+<?php
+
+/**
+ * Caches user genders when needed to use correct namespace alises.
+ * @author Niklas Laxström
+ * @since 1.18
+ */
+class GenderCache {
+ protected $cache = array();
+ protected $default;
+ protected $misses = 0;
+ protected $missLimit = 1000;
+
+ public static function singleton() {
+ static $that = null;
+ if ( $that === null ) {
+ $that = new self();
+ }
+ return $that;
+ }
+
+ protected function __construct() {}
+
+ /**
+ * Returns the default gender option in this wiki.
+ * @return String
+ */
+ protected function getDefault() {
+ if ( $this->default === null ) {
+ $this->default = User::getDefaultOption( 'gender' );
+ }
+ return $this->default;
+ }
+
+ /**
+ * Returns the gender for given username.
+ * @param $users String: username
+ * @param $caller String: the calling method
+ * @return String
+ */
+ public function getGenderOf( $username, $caller = '' ) {
+ global $wgUser;
+
+ $username = strtr( $username, '_', ' ' );
+ if ( !isset( $this->cache[$username] ) ) {
+
+ if ( $this->misses >= $this->missLimit && $wgUser->getName() !== $username ) {
+ if( $this->misses === $this->missLimit ) {
+ $this->misses++;
+ wfDebug( __METHOD__ . ": too many misses, returning default onwards\n" );
+ }
+ return $this->getDefault();
+
+ } else {
+ $this->misses++;
+ if ( !User::isValidUserName( $username ) ) {
+ $this->cache[$username] = $this->getDefault();
+ } else {
+ $this->doQuery( $username, $caller );
+ }
+ }
+
+ }
+
+ /* Undefined if there is a valid username which for some reason doesn't
+ * exist in the database.
+ */
+ return isset( $this->cache[$username] ) ? $this->cache[$username] : $this->getDefault();
+ }
+
+ /**
+ * Wrapper for doQuery that processes raw LinkBatch data.
+ */
+ public function doLinkBatch( $data, $caller = '' ) {
+ $users = array();
+ foreach ( $data as $ns => $pagenames ) {
+ if ( !MWNamespace::hasGenderDistinction( $ns ) ) continue;
+ foreach ( array_keys( $pagenames ) as $username ) {
+ if ( isset( $this->cache[$username] ) ) continue;
+ $users[$username] = true;
+ }
+ }
+
+ $this->doQuery( array_keys( $users ), $caller );
+
+ }
+
+ /**
+ * Preloads genders for given list of users.
+ * @param $users List|String: usernames
+ * @param $caller String: the calling method
+ */
+ public function doQuery( $users, $caller = '' ) {
+ if ( count( $users ) === 0 ) return false;
+
+ foreach ( (array) $users as $index => $value ) {
+ $users[$index] = strtr( $value, '_', ' ' );
+ }
+
+ $dbr = wfGetDB( DB_SLAVE );
+ $table = array( 'user', 'user_properties' );
+ $fields = array( 'user_name', 'up_value' );
+ $conds = array( 'user_name' => $users );
+ $joins = array( 'user_properties' =>
+ array( 'LEFT JOIN', array( 'user_id = up_user', 'up_property' => 'gender' ) ) );
+
+ $comment = __METHOD__;
+ if ( strval( $caller ) !== '' ) {
+ $comment .= "/$caller";
+ }
+ $res = $dbr->select( $table, $fields, $conds, $comment, $joins, $joins );
+
+ $default = $this->getDefault();
+ foreach ( $res as $row ) {
+ $this->cache[$row->user_name] = $row->up_value ? $row->up_value : $default;
+ }
+ }
+
+}
wfProfileIn( __METHOD__ );
$res = $this->doQuery();
$ids = $this->addResultToCache( $cache, $res );
+ $this->doGenderQuery();
wfProfileOut( __METHOD__ );
return $ids;
}
return $res;
}
+ public function doGenderQuery() {
+ if ( $this->isEmpty() ) {
+ return false;
+ }
+
+ global $wgContLang;
+ if ( !$wgContLang->needsGenderDistinction() ) {
+ return false;
+ }
+
+ $genderCache = GenderCache::singleton();
+ $genderCache->dolinkBatch( $this->data, $this->caller );
+ }
+
/**
* Construct a WHERE clause which will match all the given titles.
*
'defaultUserOptionOverrides', 'linkTrail', 'namespaceAliases',
'dateFormats', 'datePreferences', 'datePreferenceMigrationMap',
'defaultDateFormat', 'extraUserToggles', 'specialPageAliases',
- 'imageFiles', 'preloadedMessages',
+ 'imageFiles', 'preloadedMessages', 'namespaceGenderAliases',
);
/**
// Default to the global setting
return $wgCapitalLinks;
}
+
+ /**
+ * Does the namespace (potentially) have different aliases for different
+ * genders. Not all languages make a distinction here.
+ *
+ * @since 1.18
+ * @param $index int Index to check
+ * @return bool
+ */
+ public static function hasGenderDistinction( $index ) {
+ return $index == NS_USER || $index == NS_USER_TALK;
+ }
+
}
return MWNamespace::getCanonicalName( $this->mNamespace );
}
}
+
+ if ( $wgContLang->needsGenderDistinction() &&
+ MWNamespace::hasGenderDistinction( $this->mNamespace ) ) {
+ $gender = GenderCache::singleton()->getGenderOf( $this->getText(), __METHOD__ );
+ return $wgContLang->getGenderNsText( $this->mNamespace, $gender );
+ }
+
return $wgContLang->getNsText( $this->mNamespace );
}
return strtr( $ns, '_', ' ' );
}
+ /**
+ * Returns gender-dependent namespace alias if available.
+ * @param $index Int: namespace index
+ * @param $gender String: gender key (male, female... )
+ * @return String
+ * @since 1.18
+ */
+ function getGenderNsText( $index, $gender ) {
+ $ns = self::$dataCache->getItem( $this->mCode, 'namespaceGenderAliases' );
+ return isset( $ns[$index][$gender] ) ? $ns[$index][$gender] : $this->getNsText( $index );
+ }
+
+ /**
+ * Whether this language makes distinguishes genders for example in
+ * namespaces.
+ * @return bool
+ * @since 1.18
+ */
+ function needsGenderDistinction() {
+ $aliases = self::$dataCache->getItem( $this->mCode, 'namespaceGenderAliases' );
+ return count( $aliases ) > 0;
+ }
+
/**
* Get a namespace key by value, case insensitive.
* Only matches namespace names for the current language, not the
}
}
}
+
+ $genders = self::$dataCache->getItem( $this->mCode, 'namespaceGenderAliases' );
+ foreach ( $genders as $index => $forms ) {
+ foreach ( $forms as $alias ) {
+ $aliases[$alias] = $index;
+ }
+ }
+
$this->namespaceAliases = $aliases;
}
return $this->namespaceAliases;
*/
$namespaceAliases = array();
+/**
+ * Array of gender specific. namespace aliases.
+ * Mapping NS_xxx to array of GENDERKEY to alias.
+ * Example:
+$namespaceGenderAliases = array(
+ NS_USER => array( 'male' => 'Male_user', 'female' => 'Female_user' ),
+);
+ */
+$namespaceGenderAliases = array();
+
/**
* Deprecated, use the message array
*/