diff options
author | Yaco <franco@reevo.org> | 2020-06-04 11:01:00 -0300 |
---|---|---|
committer | Yaco <franco@reevo.org> | 2020-06-04 11:01:00 -0300 |
commit | fc7369835258467bf97eb64f184b93691f9a9fd5 (patch) | |
tree | daabd60089d2dd76d9f5fb416b005fbe159c799d /www/wiki/extensions/Translate/translationaids |
first commit
Diffstat (limited to 'www/wiki/extensions/Translate/translationaids')
14 files changed, 972 insertions, 0 deletions
diff --git a/www/wiki/extensions/Translate/translationaids/CurrentTranslationAid.php b/www/wiki/extensions/Translate/translationaids/CurrentTranslationAid.php new file mode 100644 index 00000000..df1c38d2 --- /dev/null +++ b/www/wiki/extensions/Translate/translationaids/CurrentTranslationAid.php @@ -0,0 +1,37 @@ +<?php +/** + * Translation aid provider. + * + * @file + * @author Niklas Laxström + * @license GPL-2.0-or-later + */ + +/** + * Translation aid which gives the current saved translation. + * + * @ingroup TranslationAids + * @since 2013-01-01 + */ +class CurrentTranslationAid extends TranslationAid { + public function getData() { + $translation = null; + + $title = $this->handle->getTitle(); + $translation = TranslateUtils::getMessageContent( + $this->handle->getKey(), + $this->handle->getCode(), + $title->getNamespace() + ); + + Hooks::run( 'TranslatePrefillTranslation', [ &$translation, $this->handle ] ); + $fuzzy = MessageHandle::hasFuzzyString( $translation ) || $this->handle->isFuzzy(); + $translation = str_replace( TRANSLATE_FUZZY, '', $translation ); + + return [ + 'language' => $this->handle->getCode(), + 'fuzzy' => $fuzzy, + 'value' => $translation, + ]; + } +} diff --git a/www/wiki/extensions/Translate/translationaids/DocumentationAid.php b/www/wiki/extensions/Translate/translationaids/DocumentationAid.php new file mode 100644 index 00000000..f19c03ba --- /dev/null +++ b/www/wiki/extensions/Translate/translationaids/DocumentationAid.php @@ -0,0 +1,37 @@ +<?php +/** + * Translation aid provider. + * + * @file + * @author Niklas Laxström + * @copyright Copyright © 2012-2013, Niklas Laxström + * @license GPL-2.0-or-later + */ + +/** + * Translation aid which gives the message documentation. + * + * @ingroup TranslationAids + * @since 2013-01-01 + */ +class DocumentationAid extends TranslationAid { + public function getData() { + global $wgTranslateDocumentationLanguageCode, $wgContLang; + if ( !$wgTranslateDocumentationLanguageCode ) { + throw new TranslationHelperException( 'Message documentation is disabled' ); + } + + $page = $this->handle->getKey(); + $ns = $this->handle->getTitle()->getNamespace(); + + $info = TranslateUtils::getMessageContent( $page, $wgTranslateDocumentationLanguageCode, $ns ); + + return [ + 'language' => $wgContLang->getCode(), + 'value' => $info, + 'html' => TranslateUtils::parseAsInterface( + $this->context->getOutput(), $info + ), + ]; + } +} diff --git a/www/wiki/extensions/Translate/translationaids/GettextDocumentationAid.php b/www/wiki/extensions/Translate/translationaids/GettextDocumentationAid.php new file mode 100644 index 00000000..b7cd68cf --- /dev/null +++ b/www/wiki/extensions/Translate/translationaids/GettextDocumentationAid.php @@ -0,0 +1,69 @@ +<?php +/** + * Translation aid provider. + * + * @file + * @author Niklas Laxström + * @copyright Copyright © 2013, Niklas Laxström + * @license GPL-2.0-or-later + */ + +/** + * Translation aid which gives Gettext documentation. + * + * @ingroup TranslationAids + * @since 2013-01-01 + */ +class GettextDocumentationAid extends TranslationAid { + public function getData() { + // We need to get the primary group to get the correct file + // So $group can be different from $this->group + $group = $this->handle->getGroup(); + if ( !$group instanceof FileBasedMessageGroup ) { + throw new TranslationHelperException( 'Not a Gettext group' ); + } + + $ffs = $group->getFFS(); + if ( !$ffs instanceof GettextFFS ) { + throw new TranslationHelperException( 'Not a Gettext group' ); + } + + global $wgContLang; + $mykey = $wgContLang->lcfirst( $this->handle->getKey() ); + $mykey = str_replace( ' ', '_', $mykey ); + $data = $ffs->read( $group->getSourceLanguage() ); + $help = $data['TEMPLATE'][$mykey]['comments']; + + $conf = $group->getConfiguration(); + if ( isset( $conf['BASIC']['codeBrowser'] ) ) { + $pattern = $conf['BASIC']['codeBrowser']; + $pattern = str_replace( '%FILE%', '\1', $pattern ); + $pattern = str_replace( '%LINE%', '\2', $pattern ); + $pattern = "[$pattern \\1:\\2]"; + } else { + $pattern = "\\1:\\2"; + } + + $out = ''; + foreach ( $help as $type => $lines ) { + if ( $type === ':' ) { + $files = ''; + foreach ( $lines as $line ) { + $files .= ' ' . preg_replace( '/([^ :]+):(\d+)/', $pattern, $line ); + } + $out .= "<nowiki>#:</nowiki> $files<br />"; + } else { + foreach ( $lines as $line ) { + $out .= "<nowiki>#$type</nowiki> $line<br />"; + } + } + } + + return [ + 'language' => $wgContLang->getCode(), + // @todo Provide raw data when possible + // 'value' => $help, + 'html' => $this->context->getOutput()->parse( $out ), + ]; + } +} diff --git a/www/wiki/extensions/Translate/translationaids/InOtherLanguagesAid.php b/www/wiki/extensions/Translate/translationaids/InOtherLanguagesAid.php new file mode 100644 index 00000000..41570860 --- /dev/null +++ b/www/wiki/extensions/Translate/translationaids/InOtherLanguagesAid.php @@ -0,0 +1,81 @@ +<?php +/** + * Translation aid provider. + * + * @file + * @author Niklas Laxström + * @copyright Copyright © 2012-2013, Niklas Laxström + * @license GPL-2.0-or-later + */ + +/** + * Translation aid which gives the "in other languages" suggestions. + * + * @ingroup TranslationAids + * @since 2013-01-01 + */ +class InOtherLanguagesAid extends TranslationAid { + public function getData() { + $suggestions = [ + '**' => 'suggestion', + ]; + + // Fuzzy translations are not included in these + $translations = $this->dataProvider->getGoodTranslations(); + $code = $this->handle->getCode(); + + $sourceLanguage = $this->handle->getGroup()->getSourceLanguage(); + + foreach ( $this->getFallbacks( $code ) as $fbcode ) { + if ( !isset( $translations[$fbcode] ) ) { + continue; + } + + if ( $fbcode === $sourceLanguage ) { + continue; + } + + $suggestions[] = [ + 'language' => $fbcode, + 'value' => $translations[$fbcode], + ]; + } + + return $suggestions; + } + + /** + * Get the languages for "in other languages". That would be translation + * assistant languages with defined language fallbacks additionally. + * @param string $code + * @return string[] List of language codes + */ + protected function getFallbacks( $code ) { + global $wgTranslateLanguageFallbacks; + + // User preference has the final say + $preference = $this->context->getUser()->getOption( 'translate-editlangs' ); + if ( $preference !== 'default' ) { + $fallbacks = array_map( 'trim', explode( ',', $preference ) ); + foreach ( $fallbacks as $k => $v ) { + if ( $v === $code ) { + unset( $fallbacks[$k] ); + } + } + + return $fallbacks; + } + + // Global configuration settings + $fallbacks = []; + if ( isset( $wgTranslateLanguageFallbacks[$code] ) ) { + $fallbacks = (array)$wgTranslateLanguageFallbacks[$code]; + } + + $list = Language::getFallbacksFor( $code ); + array_pop( $list ); // Get 'en' away from the end + $fallbacks = array_merge( $list, $fallbacks ); + + return array_unique( $fallbacks ); + } +} diff --git a/www/wiki/extensions/Translate/translationaids/InsertablesAid.php b/www/wiki/extensions/Translate/translationaids/InsertablesAid.php new file mode 100644 index 00000000..0bd964f5 --- /dev/null +++ b/www/wiki/extensions/Translate/translationaids/InsertablesAid.php @@ -0,0 +1,55 @@ +<?php +/** + * Translation aid provider. + * + * @file + * @author Niklas Laxström + * @license GPL-2.0-or-later + */ + +/** + * Translation aid which suggests insertables. Insertable is a string that + * usually does not need translation and is difficult to type manually. + * + * @ingroup TranslationAids + * @since 2013.09 + */ +class InsertablesAid extends TranslationAid { + public function getData() { + // We need to get the primary group to get the correct file + // So $group can be different from $this->group + $group = $this->handle->getGroup(); + + // This was added later, so not all classes have it. In addition + // the message group class hierarche doesn't lend itself easily + // to the user of interfaces for this purpose. + if ( !method_exists( $group, 'getInsertablesSuggester' ) ) { + throw new TranslationHelperException( 'Group does not have a suggester' ); + } + + $suggester = $group->getInsertablesSuggester(); + + // It is okay to return null suggester + if ( !$suggester ) { + throw new TranslationHelperException( 'Group does not have a suggester' ); + } + + $insertables = $suggester->getInsertables( $this->dataProvider->getDefinition() ); + $blob = []; + foreach ( $insertables as $insertable ) { + $displayText = $insertable->getDisplayText(); + + // The keys are used for de-duplication + $blob[$displayText] = [ + 'display' => $displayText, + 'pre' => $insertable->getPreText(), + 'post' => $insertable->getPostText(), + ]; + } + + $blob = array_values( $blob ); + $blob['**'] = 'insertable'; + + return $blob; + } +} diff --git a/www/wiki/extensions/Translate/translationaids/MachineTranslationAid.php b/www/wiki/extensions/Translate/translationaids/MachineTranslationAid.php new file mode 100644 index 00000000..fa14a13b --- /dev/null +++ b/www/wiki/extensions/Translate/translationaids/MachineTranslationAid.php @@ -0,0 +1,87 @@ +<?php +/** + * Translation aid provider. + * + * @file + * @author Niklas Laxström + * @copyright Copyright © 2012-2013, Niklas Laxström + * @license GPL-2.0-or-later + */ + +/** + * Translation aid which gives suggestion from machine translation services. + * + * @ingroup TranslationAids + * @since 2013-01-01 | 2015.02 extends QueryAggregatorAwareTranslationAid + */ +class MachineTranslationAid extends QueryAggregatorAwareTranslationAid { + public function populateQueries() { + $definition = $this->dataProvider->getDefinition(); + $translations = $this->dataProvider->getGoodTranslations(); + $from = $this->group->getSourceLanguage(); + $to = $this->handle->getCode(); + + if ( trim( $definition ) === '' ) { + return; + } + + foreach ( $this->getWebServices( 'mt' ) as $service ) { + if ( $service->checkTranslationServiceFailure() ) { + continue; + } + + try { + if ( $service->isSupportedLanguagePair( $from, $to ) ) { + $this->storeQuery( $service, $from, $to, $definition ); + continue; + } + + // Search for translations which we can use as a source for MT + // @todo: Support setting priority of languages like Yandex used to have + foreach ( $translations as $from => $text ) { + if ( !$service->isSupportedLanguagePair( $from, $to ) ) { + continue; + } + + $this->storeQuery( $service, $from, $to, $text ); + break; + } + } catch ( TranslationWebServiceConfigurationException $e ) { + throw new TranslationHelperException( $service->getName() . ': ' . $e->getMessage() ); + } + } + } + + public function getData() { + $suggestions = [ '**' => 'suggestion' ]; + + foreach ( $this->getQueryData() as $queryData ) { + $suggestions[] = $this->formatSuggestion( $queryData ); + } + + return array_filter( $suggestions ); + } + + /** + * @param array $queryData + * @return array|null + */ + protected function formatSuggestion( array $queryData ) { + $service = $queryData['service']; + $response = $queryData['response']; + $sourceLanguage = $queryData['language']; + $sourceText = $queryData['text']; + + $result = $service->getResultData( $response ); + if ( $result === null ) { + return null; + } + + return [ + 'target' => $result, + 'service' => $service->getName(), + 'source_language' => $sourceLanguage, + 'source' => $sourceText, + ]; + } +} diff --git a/www/wiki/extensions/Translate/translationaids/MessageDefinitionAid.php b/www/wiki/extensions/Translate/translationaids/MessageDefinitionAid.php new file mode 100644 index 00000000..257435c5 --- /dev/null +++ b/www/wiki/extensions/Translate/translationaids/MessageDefinitionAid.php @@ -0,0 +1,27 @@ +<?php +/** + * Translation aid provider. + * + * @file + * @author Niklas Laxström + * @copyright Copyright © 2012-2013, Niklas Laxström + * @license GPL-2.0-or-later + */ + +/** + * Translation aid which gives the message definition. + * This usually matches the content of the page ns:key/source_language. + * + * @ingroup TranslationAids + * @since 2013-01-01 + */ +class MessageDefinitionAid extends TranslationAid { + public function getData() { + $language = $this->group->getSourceLanguage(); + + return [ + 'value' => $this->dataProvider->getDefinition(), + 'language' => $language, + ]; + } +} diff --git a/www/wiki/extensions/Translate/translationaids/QueryAggregatorAwareTranslationAid.php b/www/wiki/extensions/Translate/translationaids/QueryAggregatorAwareTranslationAid.php new file mode 100644 index 00000000..11358315 --- /dev/null +++ b/www/wiki/extensions/Translate/translationaids/QueryAggregatorAwareTranslationAid.php @@ -0,0 +1,83 @@ +<?php +/** + * Translation aid helper class. + * + * @file + * @author Niklas Laxström + * @license GPL-2.0-or-later + */ + +/** + * Helper class for translation aids which use web services. + * + * @ingroup TranslationAids + * @since 2015.02 + */ +abstract class QueryAggregatorAwareTranslationAid + extends TranslationAid + implements QueryAggregatorAware +{ + private $queries = []; + private $aggregator; + + // Interface: QueryAggregatorAware + public function setQueryAggregator( QueryAggregator $aggregator ) { + $this->aggregator = $aggregator; + } + + /** + * Stores a web service query for later execution. + * @param TranslationWebService $service + * @param string $from Source language + * @param string $to Target language + * @param string $text Source text + */ + protected function storeQuery( TranslationWebService $service, $from, $to, $text ) { + $queries = $service->getQueries( $text, $from, $to ); + foreach ( $queries as $query ) { + $this->queries[] = [ + 'id' => $this->aggregator->addQuery( $query ), + 'language' => $from, + 'text' => $text, + 'service' => $service, + ]; + } + } + + /** + * Returns all stored queries. + * @return array Map of executed queries: + * - language: string: source language + * - text: string: source text + * - response: TranslationQueryResponse + */ + protected function getQueryData() { + foreach ( $this->queries as &$queryData ) { + $queryData['response'] = $this->aggregator->getResponse( $queryData['id'] ); + unset( $queryData['id'] ); + } + + return $this->queries; + } + + /** + * Returns all web services of given type. + * @param string $type + * @return TranslationWebService[] + */ + protected function getWebServices( $type ) { + global $wgTranslateTranslationServices; + + $services = []; + foreach ( $wgTranslateTranslationServices as $name => $config ) { + $service = TranslationWebService::factory( $name, $config ); + if ( !$service || $service->getType() !== $type ) { + continue; + } + + $services[$name] = $service; + } + + return $services; + } +} diff --git a/www/wiki/extensions/Translate/translationaids/SupportAid.php b/www/wiki/extensions/Translate/translationaids/SupportAid.php new file mode 100644 index 00000000..b4a65c12 --- /dev/null +++ b/www/wiki/extensions/Translate/translationaids/SupportAid.php @@ -0,0 +1,66 @@ +<?php +/** + * Translation aid provider. + * + * @file + * @author Niklas Laxström + * @copyright Copyright © 2013, Niklas Laxström + * @license GPL-2.0-or-later + */ + +/** + * Translation aid which gives an url where users can ask for help + * + * @ingroup TranslationAids + * @since 2013-01-02 + */ +class SupportAid extends TranslationAid { + public function getData() { + return [ + 'url' => self::getSupportUrl( $this->handle->getTitle() ), + ]; + } + + /** + * Target URL for a link provided by a support button/aid. + * + * @param Title $title Title object for the translation message. + * @since 2015.09 + * @return string + * @throws TranslationHelperException + */ + public static function getSupportUrl( Title $title ) { + global $wgTranslateSupportUrl, $wgTranslateSupportUrlNamespace; + $namespace = $title->getNamespace(); + + // Fetch the configuration for this namespace if possible, or the default. + if ( isset( $wgTranslateSupportUrlNamespace[$namespace] ) ) { + $config = $wgTranslateSupportUrlNamespace[$namespace]; + } elseif ( $wgTranslateSupportUrl ) { + $config = $wgTranslateSupportUrl; + } else { + throw new TranslationHelperException( 'Support page not configured' ); + } + + // Preprocess params + $params = []; + if ( isset( $config['params'] ) ) { + foreach ( $config['params'] as $key => $value ) { + $params[$key] = str_replace( '%MESSAGE%', $title->getPrefixedText(), $value ); + } + } + + // Return the URL or make one from the page + if ( isset( $config['url'] ) ) { + return wfAppendQuery( $config['url'], $params ); + } elseif ( isset( $config['page'] ) ) { + $page = Title::newFromText( $config['page'] ); + if ( !$page ) { + throw new TranslationHelperException( 'Support page not configured properly' ); + } + return $page->getFullURL( $params ); + } else { + throw new TranslationHelperException( 'Support page not configured properly' ); + } + } +} diff --git a/www/wiki/extensions/Translate/translationaids/TTMServerAid.php b/www/wiki/extensions/Translate/translationaids/TTMServerAid.php new file mode 100644 index 00000000..6f4f69a5 --- /dev/null +++ b/www/wiki/extensions/Translate/translationaids/TTMServerAid.php @@ -0,0 +1,102 @@ +<?php +/** + * Translation aid provider. + * + * @file + * @author Niklas Laxström + * @license GPL-2.0-or-later + */ + +/** + * Translation aid which gives suggestion from translation memory. + * + * @ingroup TranslationAids + * @since 2013-01-01 | 2015.02 extends QueryAggregatorAwareTranslationAid + */ +class TTMServerAid extends QueryAggregatorAwareTranslationAid { + public function populateQueries() { + $text = $this->dataProvider->getDefinition(); + $from = $this->group->getSourceLanguage(); + $to = $this->handle->getCode(); + + foreach ( $this->getWebServices( 'ttmserver' ) as $service ) { + $this->storeQuery( $service, $from, $to, $text ); + } + } + + public function getData() { + $suggestions = []; + + $text = $this->dataProvider->getDefinition(); + $from = $this->group->getSourceLanguage(); + $to = $this->handle->getCode(); + + if ( trim( $text ) === '' ) { + return $suggestions; + } + + // "Local" queries using a client can't be run in parallel with web services + global $wgTranslateTranslationServices; + foreach ( $wgTranslateTranslationServices as $name => $config ) { + $server = TTMServer::factory( $config ); + + try { + if ( $server instanceof ReadableTTMServer ) { + // Except if they are public, we can call back via API + if ( isset( $config['public'] ) && $config['public'] === true ) { + continue; + } + + $query = $server->query( $from, $to, $text ); + } else { + continue; + } + } catch ( Exception $e ) { + // Not ideal to catch all exceptions + continue; + } + + foreach ( $query as $item ) { + $item['service'] = $name; + $item['source_language'] = $from; + $item['local'] = $server->isLocalSuggestion( $item ); + $item['uri'] = $server->expandLocation( $item ); + $suggestions[] = $item; + } + } + + // Results from web services + foreach ( $this->getQueryData() as $queryData ) { + $sugs = $this->formatSuggestions( $queryData ); + $suggestions = array_merge( $suggestions, $sugs ); + } + + $suggestions = TTMServer::sortSuggestions( $suggestions ); + // Must be here to not mess up the sorting function + $suggestions['**'] = 'suggestion'; + + return $suggestions; + } + + protected function formatSuggestions( array $queryData ) { + $service = $queryData['service']; + $response = $queryData['response']; + $sourceLanguage = $queryData['language']; + $sourceText = $queryData['text']; + + // getResultData returns a null on failure instead of throwing an exception + $sugs = $service->getResultData( $response ); + if ( $sugs === null ) { + return []; + } + + foreach ( $sugs as &$sug ) { + $sug += [ + 'service' => $service->getName(), + 'source_language' => $sourceLanguage, + 'source' => $sourceText, + ]; + } + return $sugs; + } +} diff --git a/www/wiki/extensions/Translate/translationaids/TranslationAid.php b/www/wiki/extensions/Translate/translationaids/TranslationAid.php new file mode 100644 index 00000000..a8068a34 --- /dev/null +++ b/www/wiki/extensions/Translate/translationaids/TranslationAid.php @@ -0,0 +1,88 @@ +<?php +/** + * Translation aid code. + * + * @file + * @author Niklas Laxström + * @license GPL-2.0-or-later + */ + +/** + * Multipurpose class for translation aids: + * - interface for translation aid classes + * - listing of available translation aids + * + * @defgroup TranslationAids Translation Aids + * @since 2013-01-01 + */ +abstract class TranslationAid { + /** + * @var MessageGroup + */ + protected $group; + + /** + * @var MessageHandle + */ + protected $handle; + + /** + * @var IContextSource + */ + protected $context; + + /** + * @var TranslationAidDataProvider + */ + protected $dataProvider; + + public function __construct( + MessageGroup $group, + MessageHandle $handle, + IContextSource $context, + TranslationAidDataProvider $dataProvider + ) { + $this->group = $group; + $this->handle = $handle; + $this->context = $context; + $this->dataProvider = $dataProvider; + } + + /** + * Translation aid class should implement this function. Return value should + * be an array with keys and values. Because these are used in the MediaWiki + * API, lists (numeric keys) should have key '**' set to element name that + * describes the list values. For example if the translation aid provides + * translation suggestions, it would return an array which has key '**' set + * to 'suggestion' and then list of arrays, each containing fields for the + * information of the suggestions. See InOtherLanguagesAid for example. + * + * @throws TranslationHelperException Used to signal unexpected errors to aid + * debugging + * @return array + */ + abstract public function getData(); + + /** + * List of available message types mapped to the classes + * implementing them. + * + * @return array + */ + public static function getTypes() { + $types = [ + 'definition' => 'MessageDefinitionAid', + 'translation' => 'CurrentTranslationAid', + 'inotherlanguages' => 'InOtherLanguagesAid', + 'documentation' => 'DocumentationAid', + 'mt' => 'MachineTranslationAid', + 'definitiondiff' => 'UpdatedDefinitionAid', + 'ttmserver' => 'TTMServerAid', + 'support' => 'SupportAid', + 'gettext' => 'GettextDocumentationAid', + 'insertables' => 'InsertablesAid', + ]; + + return $types; + } +} diff --git a/www/wiki/extensions/Translate/translationaids/TranslationAidDataProvider.php b/www/wiki/extensions/Translate/translationaids/TranslationAidDataProvider.php new file mode 100644 index 00000000..2f6672ef --- /dev/null +++ b/www/wiki/extensions/Translate/translationaids/TranslationAidDataProvider.php @@ -0,0 +1,135 @@ +<?php +/** + * Translation aid code. + * + * @file + * @author Niklas Laxström + * @license GPL-2.0-or-later + */ + +use Wikimedia\Rdbms\IDatabase; + +/** + * @since 2018.01 + */ +class TranslationAidDataProvider { + private $handle; + private $group; + + private $definition; + private $translations; + + public function __construct( MessageHandle $handle ) { + $this->handle = $handle; + $this->group = $handle->getGroup(); + } + + /** + * Get the message definition. Cached for performance. + * + * @return string + */ + public function getDefinition() { + if ( $this->definition !== null ) { + return $this->definition; + } + + // Optional performance optimization + if ( method_exists( $this->group, 'getMessageContent' ) ) { + $this->definition = $this->group->getMessageContent( $this->handle ); + } else { + $this->definition = $this->group->getMessage( + $this->handle->getKey(), + $this->group->getSourceLanguage() + ); + } + + return $this->definition; + } + + /** + * @return Content + */ + public function getDefinitionContent() { + return ContentHandler::makeContent( $this->getDefinition(), $this->handle->getTitle() ); + } + + /** + * Get the translations in all languages. Cached for performance. + * Fuzzy translation are not included. + * + * @return array Language code => Translation + */ + public function getGoodTranslations() { + if ( $this->translations !== null ) { + return $this->translations; + } + + $data = self::loadTranslationData( wfGetDB( DB_REPLICA ), $this->handle ); + $translations = []; + $prefixLength = strlen( $this->handle->getTitleForBase()->getDBKey() . '/' ); + + foreach ( $data as $page => $translation ) { + // Could use MessageHandle here, but that queries the message index. + // Instead we can get away with simple string manipulation. + $code = substr( $page, $prefixLength ); + if ( !Language::isKnownLanguageTag( $code ) ) { + continue; + } + + $translations[ $code ] = $translation; + } + + $this->translations = $translations; + + return $translations; + } + + private static function loadTranslationData( IDatabase $db, MessageHandle $handle ) { + if ( method_exists( 'Revision', 'getQueryInfo' ) ) { + $queryInfo = Revision::getQueryInfo( [ 'page', 'text' ] ); + $tables = $queryInfo[ 'tables' ]; + $fields = $queryInfo[ 'fields' ]; + $conds = []; + $options = []; + $joins = $queryInfo[ 'joins' ]; + } else { + // BC for <= MW 1.31 + $tables = [ 'page', 'text', 'revision' ]; + $fields = array_merge( + Revision::selectFields(), + Revision::selectPageFields(), + Revision::selectTextFields() + ); + $conds = []; + $options = []; + $joins = [ + 'page' => Revision::pageJoinCond(), + 'text' => [ 'INNER JOIN', [ 'rev_text_id=old_id' ] ] + ]; + } + + // The list of pages we want to select, and their latest versions + $conds['page_namespace'] = $handle->getTitle()->getNamespace(); + $base = $handle->getKey(); + $conds[] = 'page_title ' . $db->buildLike( "$base/", $db->anyString() ); + $conds[] = 'rev_id=page_latest'; + + // For fuzzy tags we also need: + $tables[] = 'revtag'; + $conds[ 'rt_type' ] = null; + $joins[ 'revtag' ] = [ + 'LEFT JOIN', + [ 'page_id=rt_page', 'page_latest=rt_revision', 'rt_type' => 'fuzzy' ] + ]; + + $rows = $db->select( $tables, $fields, $conds, __METHOD__, $options, $joins ); + + $pages = []; + foreach ( $rows as $row ) { + $pages[$row->page_title] = Revision::getRevisionText( $row ); + } + + return $pages; + } +} diff --git a/www/wiki/extensions/Translate/translationaids/UnsupportedTranslationAid.php b/www/wiki/extensions/Translate/translationaids/UnsupportedTranslationAid.php new file mode 100644 index 00000000..af118e73 --- /dev/null +++ b/www/wiki/extensions/Translate/translationaids/UnsupportedTranslationAid.php @@ -0,0 +1,21 @@ +<?php +/** + * Translation aid provider. + * + * @file + * @author Harry Burt + * @copyright Copyright © 2013, Harry Burt + * @license GPL-2.0-or-later + */ + +/** + * Dummy translation aid that always errors + * + * @ingroup TranslationAids + * @since 2013-03-29 + */ +class UnsupportedTranslationAid extends TranslationAid { + public function getData() { + throw new TranslationHelperException( 'This translation aid is disabled' ); + } +} diff --git a/www/wiki/extensions/Translate/translationaids/UpdatedDefinitionAid.php b/www/wiki/extensions/Translate/translationaids/UpdatedDefinitionAid.php new file mode 100644 index 00000000..42ece6b6 --- /dev/null +++ b/www/wiki/extensions/Translate/translationaids/UpdatedDefinitionAid.php @@ -0,0 +1,84 @@ +<?php +/** + * Translation aid provider. + * + * @file + * @author Niklas Laxström + * @copyright Copyright © 2012-2013, Niklas Laxström + * @license GPL-2.0-or-later + */ + +/** + * Translation aid which gives the message definition. + * This usually matches the content of the page ns:key/source_language. + * + * @ingroup TranslationAids + * @since 2013-01-01 + */ +class UpdatedDefinitionAid extends TranslationAid { + public function getData() { + $db = TranslateUtils::getSafeReadDB(); + $conds = [ + 'rt_page' => $this->handle->getTitle()->getArticleID(), + 'rt_type' => RevTag::getType( 'tp:transver' ), + ]; + $options = [ + 'ORDER BY' => 'rt_revision DESC', + ]; + + $translationRevision = $db->selectField( 'revtag', 'rt_value', $conds, __METHOD__, $options ); + if ( $translationRevision === false ) { + throw new TranslationHelperException( 'No definition revision recorded' ); + } + + $definitionTitle = Title::makeTitleSafe( + $this->handle->getTitle()->getNamespace(), + $this->handle->getKey() . '/' . $this->group->getSourceLanguage() + ); + + if ( !$definitionTitle || !$definitionTitle->exists() ) { + throw new TranslationHelperException( 'Definition page does not exist' ); + } + + // Using newFromId instead of newFromTitle, because the page might have been renamed + $oldrev = Revision::newFromId( $translationRevision ); + if ( !$oldrev ) { + throw new TranslationHelperException( 'Old definition version does not exist anymore' ); + } + + $oldContent = $oldrev->getContent(); + $newContent = $this->dataProvider->getDefinitionContent(); + + if ( !$oldContent ) { + throw new TranslationHelperException( 'Old definition version does not exist anymore' ); + } + + if ( !$oldContent instanceof WikitextContent || !$newContent instanceof WikitextContent ) { + throw new TranslationHelperException( 'Can only work on Wikitext content' ); + } + + if ( $oldContent->equals( $newContent ) ) { + throw new TranslationHelperException( 'No changes' ); + } + + $diff = new DifferenceEngine( $this->context ); + $diff->setTextLanguage( wfGetLangObj( $this->group->getSourceLanguage() ) ); + $diff->setContent( $oldContent, $newContent ); + $diff->setReducedLineNumbers(); + $diff->showDiffStyle(); + + $html = $diff->getDiff( + $this->context->msg( 'tpt-diff-old' )->escaped(), + $this->context->msg( 'tpt-diff-new' )->escaped() + ); + + return [ + 'value_old' => $oldContent->getNativeData(), + 'value_new' => $newContent->getNativeData(), + 'revisionid_old' => $oldrev->getId(), + 'revisionid_new' => $definitionTitle->getLatestRevID(), + 'language' => $this->group->getSourceLanguage(), + 'html' => $html, + ]; + } +} |