diff options
author | Alex Legler <alex@a3li.li> | 2014-12-23 17:49:26 +0100 |
---|---|---|
committer | Alex Legler <alex@a3li.li> | 2014-12-23 17:49:26 +0100 |
commit | e352fff59842ca14fbfd81ee1c4a64297bb598c5 (patch) | |
tree | 153f268484aa5cc41cacf912bdce8c4847df222d /MLEB/Translate/TranslateUtils.php | |
download | extensions-e352fff59842ca14fbfd81ee1c4a64297bb598c5.tar.gz extensions-e352fff59842ca14fbfd81ee1c4a64297bb598c5.tar.bz2 extensions-e352fff59842ca14fbfd81ee1c4a64297bb598c5.zip |
Add initial set of additional extensions
Diffstat (limited to 'MLEB/Translate/TranslateUtils.php')
-rw-r--r-- | MLEB/Translate/TranslateUtils.php | 430 |
1 files changed, 430 insertions, 0 deletions
diff --git a/MLEB/Translate/TranslateUtils.php b/MLEB/Translate/TranslateUtils.php new file mode 100644 index 00000000..f2e10c9d --- /dev/null +++ b/MLEB/Translate/TranslateUtils.php @@ -0,0 +1,430 @@ +<?php +/** + * This file contains classes with static helper functions for other classes. + * + * @file + * @author Niklas Laxström + * @copyright Copyright © 2007-2013 Niklas Laxström + * @license GPL-2.0+ + */ + +/** + * Essentially random collection of helper functions, similar to GlobalFunctions.php. + */ +class TranslateUtils { + /** + * Does quick normalisation of message name so that in can be looked from the + * database. + * @param string $message Name of the message + * @param string $code Language code in lower case and with dash as delimiter + * @param int $ns Namespace constant + * @return string The normalised title as a string. + */ + public static function title( $message, $code, $ns = NS_MEDIAWIKI ) { + // Cache some amount of titles for speed. + static $cache = array(); + $key = $ns . ':' . $message; + + if ( !isset( $cache[$key] ) ) { + $cache[$key] = Title::capitalize( $message, $ns ); + } + + if ( $code ) { + return $cache[$key] . '/' . $code; + } else { + return $cache[$key]; + } + } + + /** + * Splits page name into message key and language code. + * @param string $text + * @return array ( string, string ) Key and language code. + * @todo Handle names without slash. + */ + public static function figureMessage( $text ) { + $pos = strrpos( $text, '/' ); + $code = substr( $text, $pos + 1 ); + $key = substr( $text, 0, $pos ); + + return array( $key, $code ); + } + + /** + * Loads page content *without* side effects. + * @param string $key Message key. + * @param string $language Language code. + * @param int $namespace Namespace number. + * @return string|null The contents or null. + */ + public static function getMessageContent( $key, $language, $namespace = NS_MEDIAWIKI ) { + $title = self::title( $key, $language, $namespace ); + $data = self::getContents( array( $title ), $namespace ); + + return isset( $data[$title][0] ) ? $data[$title][0] : null; + } + + /** + * Fetches contents for pagenames in given namespace without side effects. + * + * @param string|string[] $titles Database page names. + * @param int $namespace The number of the namespace. + * @return array ( string => array ( string, string ) ) Tuples of page + * 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( + 'page_namespace' => $namespace, + 'page_latest=rev_id', + 'rev_text_id=old_id', + 'page_title' => $titles + ), + __METHOD__ + ); + + $titles = array(); + foreach ( $rows as $row ) { + $titles[$row->page_title] = array( + Revision::getRevisionText( $row ), + $row->rev_user_text + ); + } + $rows->free(); + + return $titles; + } + + /** + * Fetches recent changes for titles in given namespaces + * + * @param int $hours Number of hours. + * @param bool $bots Should bot edits be included. + * @param null|int[] $ns List of namespace IDs. + * @param string[] $extraFields List of extra columns to fetch. + * @return array List of recent changes. + */ + public static function translationChanges( + $hours = 24, $bots = false, $ns = null, $extraFields = array() + ) { + global $wgTranslateMessageNamespaces; + + $dbr = wfGetDB( DB_SLAVE ); + $recentchanges = $dbr->tableName( 'recentchanges' ); + $hours = intval( $hours ); + $cutoff_unixtime = time() - ( $hours * 3600 ); + $cutoff = $dbr->timestamp( $cutoff_unixtime ); + + $namespaces = $dbr->makeList( $wgTranslateMessageNamespaces ); + if ( $ns ) { + $namespaces = $dbr->makeList( $ns ); + } + + $fields = array_merge( + array( 'rc_title', 'rc_timestamp', 'rc_user_text', 'rc_namespace' ), + $extraFields + ); + $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 ); + + return $rows; + } + + /* Some other helpers for output */ + + /** + * Returns a localised language name. + * @param string $code Language code. + * @param string $language Language code of language the 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 ); + + if ( isset( $languages[$code] ) ) { + return $languages[$code]; + } else { + return $code; + } + } + + /** + * Returns a language selector. + * @param string $language Language code of the language the names should be localised to. + * @param string $selectedId The language code that is selected by default. + * @return string + */ + public static function languageSelector( $language, $selectedId ) { + $selector = self::getLanguageSelector( $language ); + $selector->setDefault( $selectedId ); + $selector->setAttribute( 'id', 'language' ); + $selector->setAttribute( 'name', 'language' ); + + return $selector->getHtml(); + } + + /** + * Standard language selector in Translate extension. + * @param string $language Language code of the language the names should be localised to. + * @param bool $labelOption + * @return XmlSelect + */ + public static function getLanguageSelector( $language, $labelOption = false ) { + $languages = self::getLanguageNames( $language ); + ksort( $languages ); + + $selector = new XmlSelect(); + if ( $labelOption !== false ) { + $selector->addOption( $labelOption, '-' ); + } + + foreach ( $languages as $code => $name ) { + $selector->addOption( "$code - $name", $code ); + } + + return $selector; + } + + /** + * Get translated language names for the languages generally supported for + * translation in the current wiki. Message groups can have further + * exclusions. + * @param string $code + * @return array ( language code => language name ) + */ + public static function getLanguageNames( /*string */$code ) { + $languageNames = Language::fetchLanguageNames( $code ); + + // Remove languages with deprecated codes (bug 35475) + global $wgDummyLanguageCodes; + + foreach ( array_keys( $wgDummyLanguageCodes ) as $dummyLanguageCode ) { + unset( $languageNames[$dummyLanguageCode] ); + } + + wfRunHooks( 'TranslateSupportedLanguages', array( &$languageNames, $code ) ); + + return $languageNames; + } + + /** + * Returns the primary group message belongs to. + * @param int $namespace + * @param string $key + * @return string|null Group id or null. + */ + public static function messageKeyToGroup( $namespace, $key ) { + $groups = self::messageKeyToGroups( $namespace, $key ); + + return count( $groups ) ? $groups[0] : null; + } + + /** + * Returns the all the groups message belongs to. + * @param int $namespace + * @param string $key + * @return string[] Possibly empty list of group ids. + */ + public static function messageKeyToGroups( $namespace, $key ) { + $mi = MessageIndex::singleton()->retrieve(); + $normkey = self::normaliseKey( $namespace, $key ); + + if ( isset( $mi[$normkey] ) ) { + return (array)$mi[$normkey]; + } else { + return array(); + } + } + + /** + * Converts page name and namespace to message index format. + * @param int $namespace + * @param string $key + * @return string + */ + public static function normaliseKey( $namespace, $key ) { + $key = lcfirst( $key ); + + return strtr( "$namespace:$key", " ", "_" ); + } + + /** + * Constructs a fieldset with contents. + * @param string $legend Raw html. + * @param string $contents Raw html. + * @param array $attributes Html attributes for the fieldset. + * @return string Html. + */ + public static function fieldset( $legend, $contents, $attributes = array() ) { + return Xml::openElement( 'fieldset', $attributes ) . + Xml::tags( 'legend', null, $legend ) . $contents . + Xml::closeElement( 'fieldset' ); + } + + /** + * Escapes the message, and does some mangling to whitespace, so that it is + * preserved when outputted as-is to html page. Line feeds are converted to + * \<br /> and occurrences of leading and trailing and multiple consecutive + * spaces to non-breaking spaces. + * + * This is also implemented in JavaScript in ext.translate.quickedit. + * + * @param string $msg Plain text string. + * @return string Text string that is ready for outputting. + */ + public static function convertWhiteSpaceToHTML( $msg ) { + $msg = htmlspecialchars( $msg ); + $msg = preg_replace( '/^ /m', ' ', $msg ); + $msg = preg_replace( '/ $/m', ' ', $msg ); + $msg = preg_replace( '/ /', '  ', $msg ); + $msg = str_replace( "\n", '<br />', $msg ); + + return $msg; + } + + /** + * Construct the web address to given asset. + * @param string $path Path to the resource relative to extensions root directory. + * @return string Full or partial web path. + */ + public static function assetPath( $path ) { + global $wgExtensionAssetsPath; + + return "$wgExtensionAssetsPath/Translate/$path"; + } + + /** + * Gets the path for cache files + * @param string $filename + * @return string Full path. + * @throws MWException If cache directory is not configured. + */ + public static function cacheFile( $filename ) { + global $wgTranslateCacheDirectory, $wgCacheDirectory; + + if ( $wgTranslateCacheDirectory !== false ) { + $dir = $wgTranslateCacheDirectory; + } elseif ( $wgCacheDirectory !== false ) { + $dir = $wgCacheDirectory; + } else { + throw new MWException( "\$wgCacheDirectory must be configured" ); + } + + return "$dir/$filename"; + } + + /** + * 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 + */ + public static function getPlaceholder() { + static $i = 0; + + return "\x7fUNIQ" . dechex( mt_rand( 0, 0x7fffffff ) ) . + dechex( mt_rand( 0, 0x7fffffff ) ) . '-' . $i++; + } + + /** + * Get URLs for icons if available. + * @param MessageGroup $g + * @param int $size Length of the edge of a bounding box to fit the icon. + * @return null|array + * @since 2013-04-01 + */ + public static function getIcon( MessageGroup $g, $size ) { + $icon = $g->getIcon(); + if ( substr( $icon, 0, 7 ) !== 'wiki://' ) { + return null; + } + + $formats = array(); + + $filename = substr( $icon, 7 ); + $file = wfFindFile( $filename ); + if ( !$file ) { + wfWarn( "Unknown message group icon file $icon" ); + + return null; + } + + if ( $file->isVectorized() ) { + $formats['vector'] = $file->getFullUrl(); + } + + $formats['raster'] = $file->createThumb( $size, $size ); + + return $formats; + } + + /** + * Parses list of language codes to an array. + * @param string $codes Comma separated list of language codes. "*" for all. + * @return string[] Language codes. + */ + public static function parseLanguageCodes( $codes ) { + $langs = array_map( 'trim', explode( ',', $codes ) ); + if ( $langs[0] === '*' ) { + $languages = Language::fetchLanguageNames(); + ksort( $languages ); + $langs = array_keys( $languages ); + } + + return $langs; + } +} |