19 public const UNIT_MARKER_INVALID_CHARS =
"_/\n<>";
20 public const NEW_UNIT_ID =
'-1';
22 public const TVAR_OLD_SYNTAX_REGEX =
'~<tvar\|([^>]+)>(.*?)</>~us';
24 public const TVAR_NEW_SYNTAX_REGEX = <<<
'REGEXP'
26<tvar \s+ name \s* = \s*
27( (
' (?<key1> [^']* )
' ) | ( " (?<key2> [^"]* ) " ) | (?<key3> [^"'\s>]* ) )
28\s* > (?<value>.*?) </tvar \s* >
39 public $oldText =
null;
44 protected $inline =
false;
46 private $canWrap =
true;
50 private static $properties = [
'version',
'id',
'text',
'type',
'oldText',
'inline' ];
52 public function __construct(
54 string $id = self::NEW_UNIT_ID,
56 string $oldText =
null
61 $this->oldText = $oldText;
64 public function setIsInline(
bool $value ):
void {
65 $this->
inline = $value;
68 public function isInline():
bool {
72 public function setCanWrap(
bool $value ):
void {
73 $this->canWrap = $value;
76 public function canWrap():
bool {
77 return $this->canWrap;
87 $variableReplacements = [];
88 foreach ( $this->getVariables() as $variable ) {
89 $variableReplacements[$variable->getDefinition()] = $variable->getName();
92 return strtr( $this->text, $variableReplacements );
97 $variableReplacements = [];
98 foreach ( $this->getVariables() as $variable ) {
99 $variableReplacements[$variable->getDefinition()] = $variable->getValue();
102 return strtr( $this->text, $variableReplacements );
108 $header =
"<!--T:$id-->";
109 $re =
'~^(=+.*?=+\s*?$)~m';
110 $rep =
"\\1 $header";
113 $text = preg_replace( $re, $rep, $this->text, 1, $count );
115 if ( $count === 0 ) {
116 if ( $this->
inline ) {
117 $text = $header .
' ' . $this->text;
119 $text = $header .
"\n" . $this->text;
128 return $this->oldText ?? $this->text;
136 preg_match_all( self::TVAR_OLD_SYNTAX_REGEX, $this->text, $matches, PREG_SET_ORDER );
137 foreach ( $matches as $m ) {
142 preg_match_all( self::TVAR_NEW_SYNTAX_REGEX, $this->text, $matches, PREG_SET_ORDER );
143 foreach ( $matches as $m ) {
147 '$' . ( $m[
'key1'] . $m[
'key2'] . $m[
'key3'] ),
158 foreach ( self::$properties as $index => $property ) {
161 $data[$index] = $this->$property;
167 public static function unserializeFromArray( array $data ): self {
169 $unit = new self(
'' );
170 foreach ( self::$properties as $index => $property ) {
171 $unit->$property = $data[$index];
177 public function getTextForRendering(
179 Language $sourceLanguage,
180 Language $targetLanguage,
181 bool $wrapUntranslated
187 if ( $msg->
hasTag(
'fuzzy' ) ) {
189 $content = str_replace( TRANSLATE_FUZZY,
'', $content );
190 $attributes[
'class'] =
'mw-translate-fuzzy';
192 $translationLanguage = $targetLanguage->getCode();
194 $content = $this->getTextWithVariables();
195 if ( $wrapUntranslated ) {
196 $attributes[
'lang'] = $sourceLanguage->getHtmlCode();
197 $attributes[
'dir'] = $sourceLanguage->getDir();
198 $attributes[
'class'] =
'mw-content-' . $sourceLanguage->getDir();
200 $translationLanguage = $sourceLanguage->getCode();
203 if ( $this->canWrap() && $attributes ) {
204 $tag = $this->isInline() ?
'span' :
'div';
205 $content = $this->isInline() ? $content :
"\n$content\n";
206 $content = Html::rawElement( $tag, $attributes, $content );
209 $variableReplacements = [];
210 foreach ( $this->getVariables() as $variable ) {
211 $variableReplacements[$variable->getName()] = $variable->getValue();
214 $content = strtr( $content, $variableReplacements );
217 $content = preg_replace(
218 '/{{\s*TRANSLATIONLANGUAGE\s*}}/',
219 $translationLanguage,
228 $issues = $usedNames = [];
229 foreach ( $this->getVariables() as $variable ) {
230 $name = $variable->getName();
231 $pattern =
'/^' . TranslatablePageInsertablesSuggester::NAME_PATTERN .
'$/u';
232 if ( !preg_match( $pattern, $name ) ) {
235 TranslationUnitIssue::WARNING,
236 'tpt-validation-not-insertable',
237 [ wfEscapeWikiText( $name ) ]
241 $usedNames[ $name ][] = $variable->getValue();
244 foreach ( $usedNames as $name => $contents ) {
245 $uniqueValueCount = count( array_unique( $contents ) );
246 if ( $uniqueValueCount > 1 ) {
248 TranslationUnitIssue::ERROR,
249 'tpt-validation-name-reuse',
250 [ wfEscapeWikiText( $name ) ]
255 return array_values( $issues );
return[ 'Translate:ConfigHelper'=> static function():ConfigHelper { return new ConfigHelper();}, 'Translate:CsvTranslationImporter'=> static function(MediaWikiServices $services):CsvTranslationImporter { return new CsvTranslationImporter( $services->getWikiPageFactory());}, 'Translate:EntitySearch'=> static function(MediaWikiServices $services):EntitySearch { return new EntitySearch($services->getMainWANObjectCache(), $services->getCollationFactory() ->makeCollation( 'uca-default-u-kn'), MessageGroups::singleton(), $services->getNamespaceInfo(), $services->get( 'Translate:MessageIndex'), $services->getTitleParser(), $services->getTitleFormatter());}, 'Translate:ExternalMessageSourceStateImporter'=> static function(MediaWikiServices $services):ExternalMessageSourceStateImporter { return new ExternalMessageSourceStateImporter($services->getMainConfig(), $services->get( 'Translate:GroupSynchronizationCache'), $services->getJobQueueGroup(), LoggerFactory::getInstance( 'Translate.GroupSynchronization'), MessageIndex::singleton());}, 'Translate:GroupSynchronizationCache'=> static function(MediaWikiServices $services):GroupSynchronizationCache { return new GroupSynchronizationCache( $services->get( 'Translate:PersistentCache'));}, 'Translate:MessageBundleStore'=> static function(MediaWikiServices $services):MessageBundleStore { return new MessageBundleStore(new RevTagStore(), $services->getJobQueueGroup(), $services->getLanguageNameUtils(), $services->get( 'Translate:MessageIndex'));}, 'Translate:MessageGroupReview'=> static function(MediaWikiServices $services):MessageGroupReview { return new MessageGroupReview($services->getDBLoadBalancer(), $services->getHookContainer());}, 'Translate:MessageIndex'=> static function(MediaWikiServices $services):MessageIndex { $params=$services->getMainConfig() ->get( 'TranslateMessageIndex');if(is_string( $params)) { $params=(array) $params;} $class=array_shift( $params);return new $class( $params);}, 'Translate:ParsingPlaceholderFactory'=> static function():ParsingPlaceholderFactory { return new ParsingPlaceholderFactory();}, 'Translate:PersistentCache'=> static function(MediaWikiServices $services):PersistentCache { return new PersistentDatabaseCache($services->getDBLoadBalancer(), $services->getJsonCodec());}, 'Translate:ProgressStatsTableFactory'=> static function(MediaWikiServices $services):ProgressStatsTableFactory { return new ProgressStatsTableFactory($services->getLinkRenderer(), $services->get( 'Translate:ConfigHelper'));}, 'Translate:SubpageListBuilder'=> static function(MediaWikiServices $services):SubpageListBuilder { return new SubpageListBuilder($services->get( 'Translate:TranslatableBundleFactory'), $services->getLinkBatchFactory());}, 'Translate:TranslatableBundleFactory'=> static function(MediaWikiServices $services):TranslatableBundleFactory { return new TranslatableBundleFactory($services->get( 'Translate:TranslatablePageStore'), $services->get( 'Translate:MessageBundleStore'));}, 'Translate:TranslatableBundleMover'=> static function(MediaWikiServices $services):TranslatableBundleMover { return new TranslatableBundleMover($services->getMovePageFactory(), $services->getJobQueueGroup(), $services->getLinkBatchFactory(), $services->get( 'Translate:TranslatableBundleFactory'), $services->get( 'Translate:SubpageListBuilder'), $services->getMainConfig() ->get( 'TranslatePageMoveLimit'));}, 'Translate:TranslatablePageParser'=> static function(MediaWikiServices $services):TranslatablePageParser { return new TranslatablePageParser($services->get( 'Translate:ParsingPlaceholderFactory'));}, 'Translate:TranslatablePageStore'=> static function(MediaWikiServices $services):TranslatablePageStore { return new TranslatablePageStore($services->get( 'Translate:MessageIndex'), $services->getJobQueueGroup(), new RevTagStore(), $services->getDBLoadBalancer());}, 'Translate:TranslationStashReader'=> static function(MediaWikiServices $services):TranslationStashReader { $db=$services->getDBLoadBalancer() ->getConnectionRef(DB_REPLICA);return new TranslationStashStorage( $db);}, 'Translate:TranslationStatsDataProvider'=> static function(MediaWikiServices $services):TranslationStatsDataProvider { return new TranslationStatsDataProvider(new ServiceOptions(TranslationStatsDataProvider::CONSTRUCTOR_OPTIONS, $services->getMainConfig()), $services->getObjectFactory());}, 'Translate:TranslationUnitStoreFactory'=> static function(MediaWikiServices $services):TranslationUnitStoreFactory { return new TranslationUnitStoreFactory( $services->getDBLoadBalancer());}, 'Translate:TranslatorActivity'=> static function(MediaWikiServices $services):TranslatorActivity { $query=new TranslatorActivityQuery($services->getMainConfig(), $services->getDBLoadBalancer());return new TranslatorActivity($services->getMainObjectStash(), $query, $services->getJobQueueGroup());}, 'Translate:TtmServerFactory'=> static function(MediaWikiServices $services):TtmServerFactory { $config=$services->getMainConfig();$default=$config->get( 'TranslateTranslationDefaultService');if( $default===false) { $default=null;} return new TtmServerFactory( $config->get( 'TranslateTranslationServices'), $default);}]
@phpcs-require-sorted-array