diff options
author | Brian Evans <grknight@gentoo.org> | 2018-11-20 10:51:06 -0500 |
---|---|---|
committer | Brian Evans <grknight@gentoo.org> | 2018-11-20 10:51:06 -0500 |
commit | 1ea74fa59d8d1c6c12d20be6c8e7d5ac7f370fdb (patch) | |
tree | ad113bd05db878a61b503938c05fe046eca25ee0 /MLEB/Translate/TranslateUtils.php | |
parent | LinkAttributes: Update to v0.2 (diff) | |
download | extensions-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.php | 286 |
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 + ); + } + } } |