messagegroups/SubsetMessageGroup.php
<?php
declare( strict_types = 1 );
use MediaWiki\Extension\Translate\MessageGroupProcessing\MessageGroups;
use MediaWiki\Logger\LoggerFactory;
use Psr\Log\LoggerInterface;
/**
* Message group that contains a subset of keys of another group.
*
* @author Niklas Laxström
* @license GPL-2.0-or-later
*/
class SubsetMessageGroup extends MessageGroupOld {
private string $parentId;
private array $subsetKeys;
private ?MessageGroup $parentGroup;
private ?array $keyCache = null;
private ?array $tagCache = null;
private ?array $definitionsCache = null;
/** Hack to allow AggregateMessageGroup as a subset and aggregate parent */
private bool $recursion = false;
public function __construct(
string $id,
string $label,
string $parentId,
array $subsetKeys
) {
$this->id = $id;
$this->label = $label;
$this->parentId = $parentId;
$this->subsetKeys = $subsetKeys;
}
/** @internal Factored out only for testing */
protected function getLogger(): LoggerInterface {
return LoggerFactory::getInstance( 'Translate' );
}
/** @inheritDoc */
public function isMeta() {
return true;
}
/** @inheritDoc */
public function exists() {
return true;
}
/** @inheritDoc */
public function load( $code ) {
return [];
}
/** @inheritDoc */
public function getKeys() {
if ( $this->recursion ) {
return [];
}
$this->recursion = true;
if ( $this->keyCache === null ) {
$parentKeys = $this->getParentGroup()->getKeys();
$commonKeys = array_intersect( $this->subsetKeys, $parentKeys );
if ( count( $commonKeys ) < count( $this->subsetKeys ) ) {
$this->getLogger()->warning(
'Invalid top messages: {invalidMessages}',
[ 'invalidMessages' => array_values( array_diff( $this->subsetKeys, $commonKeys ) ) ]
);
}
$this->keyCache = array_values( $commonKeys );
}
$this->recursion = false;
return $this->keyCache;
}
/** @inheritDoc */
public function getDefinitions() {
if ( $this->recursion ) {
return [];
}
// Warning: this must be called outside the recursion guard
$keys = $this->getKeys();
$this->recursion = true;
if ( $this->definitionsCache === null ) {
$parent = $this->getParentGroup();
$sourceLanguage = $parent->getSourceLanguage();
$this->definitionsCache = [];
foreach ( $keys as $key ) {
$this->definitionsCache[$key] = $parent->getMessage( $key, $sourceLanguage );
}
}
$this->recursion = false;
return $this->definitionsCache;
}
/** @inheritDoc */
public function getTags( $type = null ) {
if ( $this->recursion ) {
return [];
}
$this->recursion = true;
$this->tagCache ??= $this->getParentGroup()->getTags( null );
$this->recursion = false;
return $type ? $this->tagCache[$type] ?? [] : $this->tagCache;
}
/** @inheritDoc */
public function getMessage( $key, $code ) {
if ( $this->recursion ) {
return null;
}
$this->recursion = true;
$value = $this->getParentGroup()->getMessage( $key, $code );
$this->recursion = false;
return $value;
}
public function getIcon(): ?string {
return $this->getParentGroup()->getIcon();
}
protected function getParentGroup(): MessageGroup {
// Protected for testing, until this code is refactored to not call static methods
$this->parentGroup ??= MessageGroups::getGroup( $this->parentId );
return $this->parentGroup;
}
}