summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBrian Evans <grknight@gentoo.org>2018-11-20 10:51:06 -0500
committerBrian Evans <grknight@gentoo.org>2018-11-20 10:51:06 -0500
commit1ea74fa59d8d1c6c12d20be6c8e7d5ac7f370fdb (patch)
treead113bd05db878a61b503938c05fe046eca25ee0 /MLEB/Translate/TranslateUtils.php
parentLinkAttributes: Update to v0.2 (diff)
downloadextensions-1ea74fa59d8d1c6c12d20be6c8e7d5ac7f370fdb.tar.gz
extensions-1ea74fa59d8d1c6c12d20be6c8e7d5ac7f370fdb.tar.bz2
extensions-1ea74fa59d8d1c6c12d20be6c8e7d5ac7f370fdb.zip
Update to MediaWikiLanguageExtensionBundle-2018.10
Signed-off-by: Brian Evans <grknight@gentoo.org>
Diffstat (limited to 'MLEB/Translate/TranslateUtils.php')
-rw-r--r--MLEB/Translate/TranslateUtils.php286
1 files changed, 196 insertions, 90 deletions
diff --git a/MLEB/Translate/TranslateUtils.php b/MLEB/Translate/TranslateUtils.php
index 09243a36..f9aa5a56 100644
--- a/MLEB/Translate/TranslateUtils.php
+++ b/MLEB/Translate/TranslateUtils.php
@@ -4,10 +4,11 @@
*
* @file
* @author Niklas Laxström
- * @copyright Copyright © 2007-2013 Niklas Laxström
- * @license GPL-2.0+
+ * @license GPL-2.0-or-later
*/
+use MediaWiki\MediaWikiServices;
+
/**
* Essentially random collection of helper functions, similar to GlobalFunctions.php.
*/
@@ -22,7 +23,7 @@ class TranslateUtils {
*/
public static function title( $message, $code, $ns = NS_MEDIAWIKI ) {
// Cache some amount of titles for speed.
- static $cache = array();
+ static $cache = [];
$key = $ns . ':' . $message;
if ( !isset( $cache[$key] ) ) {
@@ -47,7 +48,7 @@ class TranslateUtils {
$code = substr( $text, $pos + 1 );
$key = substr( $text, 0, $pos );
- return array( $key, $code );
+ return [ $key, $code ];
}
/**
@@ -59,7 +60,7 @@ class TranslateUtils {
*/
public static function getMessageContent( $key, $language, $namespace = NS_MEDIAWIKI ) {
$title = self::title( $key, $language, $namespace );
- $data = self::getContents( array( $title ), $namespace );
+ $data = self::getContents( [ $title ], $namespace );
return isset( $data[$title][0] ) ? $data[$title][0] : null;
}
@@ -73,24 +74,41 @@ class TranslateUtils {
* text and last author indexed by page name.
*/
public static function getContents( $titles, $namespace ) {
- $dbr = wfGetDB( DB_SLAVE );
- $rows = $dbr->select( array( 'page', 'revision', 'text' ),
- array( 'page_title', 'old_text', 'old_flags', 'rev_user_text' ),
- array(
+ $dbr = wfGetDB( DB_REPLICA );
+
+ if ( class_exists( ActorMigration::class ) ) {
+ $actorQuery = ActorMigration::newMigration()->getJoin( 'rev_user' );
+ } else {
+ $actorQuery = [
+ 'tables' => [],
+ 'fields' => [ 'rev_user_text' => 'rev_user_text' ],
+ 'joins' => [],
+ ];
+ }
+
+ $rows = $dbr->select( [ 'page', 'revision', 'text' ] + $actorQuery['tables'],
+ [
+ 'page_title', 'old_text', 'old_flags',
+ 'rev_user_text' => $actorQuery['fields']['rev_user_text']
+ ],
+ [
'page_namespace' => $namespace,
- 'page_latest=rev_id',
- 'rev_text_id=old_id',
'page_title' => $titles
- ),
- __METHOD__
+ ],
+ __METHOD__,
+ [],
+ [
+ 'revision' => [ 'JOIN', 'page_latest=rev_id' ],
+ 'text' => [ 'JOIN', 'rev_text_id=old_id' ],
+ ] + $actorQuery['joins']
);
- $titles = array();
+ $titles = [];
foreach ( $rows as $row ) {
- $titles[$row->page_title] = array(
+ $titles[$row->page_title] = [
Revision::getRevisionText( $row ),
$row->rev_user_text
- );
+ ];
}
$rows->free();
@@ -107,36 +125,66 @@ class TranslateUtils {
* @return array List of recent changes.
*/
public static function translationChanges(
- $hours = 24, $bots = false, $ns = null, $extraFields = array()
+ $hours = 24, $bots = false, $ns = null, array $extraFields = []
) {
global $wgTranslateMessageNamespaces;
- $dbr = wfGetDB( DB_SLAVE );
- $recentchanges = $dbr->tableName( 'recentchanges' );
- $hours = intval( $hours );
+ $dbr = wfGetDB( DB_REPLICA );
+
+ if ( class_exists( ActorMigration::class ) ) {
+ $actorQuery = ActorMigration::newMigration()->getJoin( 'rc_user' );
+ } else {
+ $actorQuery = [
+ 'tables' => [],
+ 'fields' => [ 'rc_user_text' => 'rc_user_text' ],
+ 'joins' => [],
+ ];
+ }
+
+ $hours = (int)$hours;
$cutoff_unixtime = time() - ( $hours * 3600 );
$cutoff = $dbr->timestamp( $cutoff_unixtime );
- $namespaces = $dbr->makeList( $wgTranslateMessageNamespaces );
- if ( $ns ) {
- $namespaces = $dbr->makeList( $ns );
+ $conds = [
+ 'rc_timestamp >= ' . $dbr->addQuotes( $cutoff ),
+ 'rc_namespace' => $ns ?: $wgTranslateMessageNamespaces,
+ ];
+ if ( $bots ) {
+ $conds['rc_bot'] = 0;
}
- $fields = array_merge(
- array( 'rc_title', 'rc_timestamp', 'rc_user_text', 'rc_namespace' ),
- $extraFields
+ $res = $dbr->select(
+ [ 'recentchanges' ] + $actorQuery['tables'],
+ array_merge( [
+ 'rc_namespace', 'rc_title', 'rc_timestamp',
+ 'rc_user_text' => $actorQuery['fields']['rc_user_text'],
+ ], $extraFields ),
+ $conds,
+ __METHOD__,
+ [],
+ $actorQuery['joins']
);
- $fields = implode( ',', $fields );
- // @todo Raw SQL
- $sql = "SELECT $fields, substring_index(rc_title, '/', -1) as lang FROM $recentchanges " .
- "WHERE rc_timestamp >= '{$cutoff}' " .
- ( $bots ? '' : 'AND rc_bot = 0 ' ) .
- "AND rc_namespace in ($namespaces) " .
- "ORDER BY lang ASC, rc_timestamp DESC";
-
- $res = $dbr->query( $sql, __METHOD__ );
$rows = iterator_to_array( $res );
+ // Calculate 'lang', then sort by it and rc_timestamp
+ foreach ( $rows as &$row ) {
+ $pos = strrpos( $row->rc_title, '/' );
+ $row->lang = $pos === false ? $row->rc_title : substr( $row->rc_title, $pos + 1 );
+ }
+ unset( $row );
+
+ usort( $rows, function ( $a, $b ) {
+ $x = strcmp( $a->lang, $b->lang );
+ if ( !$x ) {
+ // descending order
+ $x = strcmp(
+ wfTimestamp( TS_MW, $b->rc_timestamp ),
+ wfTimestamp( TS_MW, $a->rc_timestamp )
+ );
+ }
+ return $x;
+ } );
+
return $rows;
}
@@ -145,11 +193,11 @@ class TranslateUtils {
/**
* Returns a localised language name.
* @param string $code Language code.
- * @param string $language Language code of language the the name should be in.
+ * @param null|string $language Language code of the language that the name should be in.
* @return string Best-effort localisation of wanted language name.
*/
public static function getLanguageName( $code, $language = 'en' ) {
- $languages = TranslateUtils::getLanguageNames( $language );
+ $languages = self::getLanguageNames( $language );
if ( isset( $languages[$code] ) ) {
return $languages[$code];
@@ -170,7 +218,7 @@ class TranslateUtils {
$selector->setAttribute( 'id', 'language' );
$selector->setAttribute( 'name', 'language' );
- return $selector->getHtml();
+ return $selector->getHTML();
}
/**
@@ -199,10 +247,10 @@ class TranslateUtils {
* Get translated language names for the languages generally supported for
* translation in the current wiki. Message groups can have further
* exclusions.
- * @param string $code
+ * @param null|string $code
* @return array ( language code => language name )
*/
- public static function getLanguageNames( /*string */$code ) {
+ public static function getLanguageNames( $code ) {
$languageNames = Language::fetchLanguageNames( $code );
// Remove languages with deprecated codes (bug T37475)
@@ -212,12 +260,25 @@ class TranslateUtils {
unset( $languageNames[$dummyLanguageCode] );
}
- wfRunHooks( 'TranslateSupportedLanguages', array( &$languageNames, $code ) );
+ Hooks::run( 'TranslateSupportedLanguages', [ &$languageNames, $code ] );
return $languageNames;
}
/**
+ * Get the normalised IETF language tag.
+ * @param string $code The language code.
+ * @deprecated This provides backward compatibility; replace with
+ * \LanguageCode::bcp47() once MW 1.30 is no longer supported.
+ */
+ public static function bcp47( $code ) {
+ if ( !is_callable( [ 'LanguageCode', 'bcp47' ] ) ) {
+ return wfBCP47( $code );
+ }
+ return LanguageCode::bcp47( $code );
+ }
+
+ /**
* Returns the primary group message belongs to.
* @param int $namespace
* @param string $key
@@ -242,7 +303,7 @@ class TranslateUtils {
if ( isset( $mi[$normkey] ) ) {
return (array)$mi[$normkey];
} else {
- return array();
+ return [];
}
}
@@ -255,7 +316,7 @@ class TranslateUtils {
public static function normaliseKey( $namespace, $key ) {
$key = lcfirst( $key );
- return strtr( "$namespace:$key", " ", "_" );
+ return strtr( "$namespace:$key", ' ', '_' );
}
/**
@@ -265,7 +326,7 @@ class TranslateUtils {
* @param array $attributes Html attributes for the fieldset.
* @return string Html.
*/
- public static function fieldset( $legend, $contents, $attributes = array() ) {
+ public static function fieldset( $legend, $contents, array $attributes = [] ) {
return Xml::openElement( 'fieldset', $attributes ) .
Xml::tags( 'legend', null, $legend ) . $contents .
Xml::closeElement( 'fieldset' );
@@ -324,51 +385,6 @@ class TranslateUtils {
}
/**
- * Adds help link with an icon to upper right corner.
- * @param OutputPage $out
- * @param string $to
- * @param bool $overrideBaseUrl
- * @since 2012-01-12
- */
- public static function addSpecialHelpLink( OutputPage $out, $to, $overrideBaseUrl = false ) {
- $out->addModuleStyles( 'ext.translate.helplink' );
- $text = wfMessage( 'translate-gethelp' )->escaped();
-
- if ( $overrideBaseUrl ) {
- $helpUrl = $to;
- } else {
- $helpUrl = "//www.mediawiki.org/wiki/Special:MyLanguage/$to";
- }
-
- $link = Html::rawElement(
- 'a',
- array(
- 'href' => $helpUrl,
- 'target' => '_blank',
- 'class' => 'mw-translate-helplink',
- ),
- $text
- );
-
- if ( method_exists( $out, 'addIndicators' ) ) {
- $out->addIndicators( array( 'translate-help' => $link ) );
- } else {
- $wrapper = Html::rawElement( 'div', array( 'class' => 'mw-translate-helplink-wrapper' ), $link );
- $out->addHtml( $wrapper );
- }
- }
-
- /**
- * Convenience function to get API query string for retrieving a token.
- * @param string $token
- * @return string
- * @since 2012-05-03
- */
- public static function getTokenAction( $token ) {
- return "action=tokens&type=$token";
- }
-
- /**
* Returns a random string that can be used as placeholder in strings.
* @return string
* @since 2012-07-31
@@ -393,7 +409,7 @@ class TranslateUtils {
return null;
}
- $formats = array();
+ $formats = [];
$filename = substr( $icon, 7 );
$file = wfFindFile( $filename );
@@ -427,4 +443,94 @@ class TranslateUtils {
return $langs;
}
+
+ /**
+ * Get a DB handle suitable for read and read-for-write cases
+ *
+ * @return \Wikimedia\Rdbms\IDatabase Master for HTTP POST, CLI, DB already changed;
+ * slave otherwise
+ */
+ public static function getSafeReadDB() {
+ $lb = MediaWikiServices::getInstance()->getDBLoadBalancer();
+ // Parsing APIs need POST for payloads but are read-only, so avoid spamming
+ // the master then. No good way to check this at the moment...
+ if ( PageTranslationHooks::$renderingContext ) {
+ $index = DB_REPLICA;
+ } else {
+ $index = (
+ PHP_SAPI === 'cli' ||
+ RequestContext::getMain()->getRequest()->wasPosted() ||
+ $lb->hasOrMadeRecentMasterChanges()
+ ) ? DB_MASTER : DB_REPLICA;
+ }
+
+ return $lb->getConnection( $index );
+ }
+
+ /**
+ * Get an URL that points to an editor for this message handle.
+ * @param MessageHandle $handle
+ * @return string Domain relative URL
+ * @since 2017.10
+ */
+ public static function getEditorUrl( MessageHandle $handle ) {
+ if ( !$handle->isValid() ) {
+ return $handle->getTitle()->getLocalURL( [ 'action' => 'edit' ] );
+ }
+
+ $title = self::getSpecialPage( 'Translate' )->getPageTitle();
+ return $title->getLocalURL( [
+ 'showMessage' => $handle->getInternalKey(),
+ 'group' => $handle->getGroup()->getId(),
+ 'language' => $handle->getCode(),
+ ] );
+ }
+
+ /**
+ * Compatibility for pre-1.32, when SpecialPageFactory methods were static.
+ *
+ * @see SpecialPageFactory::resolveAlias
+ * @param string $text
+ * @return array
+ */
+ public static function resolveSpecialPageAlias( $text ) : array {
+ if ( method_exists( MediaWikiServices::class, 'getSpecialPageFactory' ) ) {
+ return MediaWikiServices::getInstance()->getSpecialPageFactory()->resolveAlias( $text );
+ }
+ return SpecialPageFactory::resolveAlias( $text );
+ }
+
+ /**
+ * Compatibility for pre-1.32, when SpecialPageFactory methods were static.
+ *
+ * @see SpecialPageFactory::getPage
+ * @param string $name
+ * @return SpecialPage|null
+ */
+ public static function getSpecialPage( $name ) {
+ if ( method_exists( MediaWikiServices::class, 'getSpecialPageFactory' ) ) {
+ return MediaWikiServices::getInstance()->getSpecialPageFactory()->getPage( $name );
+ }
+ return SpecialPageFactory::getPage( $name );
+ }
+
+ /**
+ * Compatibility for pre-1.32, before OutputPage::addWikiTextAsInterface()
+ *
+ * @see OutputPage::addWikiTextAsInterface
+ * @param OutputPage $out
+ * @param string $text The wikitext to add to the output.
+ */
+ public static function addWikiTextAsInterface( OutputPage $out, $text ) {
+ if ( is_callable( [ $out, 'addWikiTextAsInterface' ] ) ) {
+ $out->addWikiTextAsInterface( $text );
+ } else {
+ // $out->addWikiTextTitle is deprecated in 1.32, but has existed
+ // since (at least) MW 1.21, so use that as a fallback.
+ $out->addWikiTextTitle(
+ $text, $out->getTitle(),
+ /*linestart*/true, /*tidy*/true, /*interface*/true
+ );
+ }
+ }
}