wikimedia/mediawiki-extensions-Translate

View on GitHub
messagegroups/SubsetMessageGroup.php

Summary

Maintainability
A
0 mins
Test Coverage
<?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;
    }
}