Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
0.00% covered (danger)
0.00%
0 / 55
0.00% covered (danger)
0.00%
0 / 6
CRAP
0.00% covered (danger)
0.00%
0 / 1
MessageBundleMessageGroupLoader
0.00% covered (danger)
0.00%
0 / 55
0.00% covered (danger)
0.00%
0 / 6
110
0.00% covered (danger)
0.00%
0 / 1
 __construct
0.00% covered (danger)
0.00%
0 / 11
0.00% covered (danger)
0.00%
0 / 1
2
 getGroups
0.00% covered (danger)
0.00%
0 / 4
0.00% covered (danger)
0.00%
0 / 1
6
 getCacheData
0.00% covered (danger)
0.00%
0 / 16
0.00% covered (danger)
0.00%
0 / 1
6
 initGroupsFromConf
0.00% covered (danger)
0.00%
0 / 19
0.00% covered (danger)
0.00%
0 / 1
12
 recache
0.00% covered (danger)
0.00%
0 / 3
0.00% covered (danger)
0.00%
0 / 1
2
 clearCache
0.00% covered (danger)
0.00%
0 / 2
0.00% covered (danger)
0.00%
0 / 1
2
1<?php
2declare( strict_types = 1 );
3
4namespace MediaWiki\Extension\Translate\MessageBundleTranslation;
5
6use CachedMessageGroupLoader;
7use MediaWiki\Extension\Translate\MessageGroupProcessing\MessageGroupWANCache;
8use MediaWiki\Extension\Translate\MessageGroupProcessing\RevTagStore;
9use MediaWiki\Extension\Translate\Services;
10use MediaWiki\Title\Title;
11use MessageGroupLoader;
12use Wikimedia\Rdbms\IDatabase;
13
14/**
15 * @since 2021.12
16 * @author Niklas Laxström
17 * @copyright GPL-2.0-or-later
18 */
19class MessageBundleMessageGroupLoader extends MessageGroupLoader implements CachedMessageGroupLoader {
20    private const CACHE_KEY = 'messageBundle';
21    private const CACHE_VERSION = 1;
22
23    protected MessageGroupWANCache $cache;
24    protected IDatabase $db;
25    /** List of groups */
26    protected ?array $groups = null;
27
28    public function __construct( IDatabase $db, MessageGroupWANCache $cache ) {
29        $this->db = $db;
30        $this->cache = $cache;
31        $this->cache->configure(
32            [
33                'key' => self::CACHE_KEY,
34                'version' => self::CACHE_VERSION,
35                'regenerator' => function () {
36                    return $this->getCacheData();
37                }
38            ]
39        );
40    }
41
42    /** @return MessageBundleMessageGroup[] */
43    public function getGroups(): array {
44        if ( !isset( $this->groups ) ) {
45            $cacheData = $this->cache->getValue();
46            $this->groups = $this->initGroupsFromConf( $cacheData );
47        }
48
49        return $this->groups;
50    }
51
52    public function getCacheData(): array {
53        $cacheData = [];
54        $res = $this->db->newSelectQueryBuilder()
55            ->select( [ 'page_id', 'page_namespace', 'page_title', 'rt_revision' => 'MAX(rt_revision)' ] )
56            ->from( 'page' )
57            ->join( 'revtag', null, [ 'page_id=rt_page', 'rt_type' => RevTagStore::MB_VALID_TAG ] )
58            ->groupBy( [ 'page_id', 'page_namespace', 'page_title' ] )
59            ->caller( __METHOD__ )
60            ->fetchResultSet();
61
62        foreach ( $res as $r ) {
63            $title = Title::newFromRow( $r );
64            $cacheData[] = [
65                $title->getPrefixedText(),
66                (int)$r->page_id,
67                (int)$r->rt_revision,
68            ];
69        }
70
71        return $cacheData;
72    }
73
74    /** @return MessageBundleMessageGroup[] */
75    private function initGroupsFromConf( array $cacheData ): array {
76        $groups = [];
77        $groupIds = [];
78
79        // First get all the group ids
80        foreach ( $cacheData as $conf ) {
81            $groupIds[] = MessageBundleMessageGroup::getGroupId( $conf[0] );
82        }
83
84        // Preload all the metadata
85        $messageGroupMetadata = Services::getInstance()->getMessageGroupMetadata();
86        $messageGroupMetadata->preloadGroups( $groupIds, __METHOD__ );
87
88        // Loop over all the group ids and create the MessageBundleMessageGroup
89        foreach ( $groupIds as $index => $groupId ) {
90            $conf = $cacheData[$index];
91            $description = $messageGroupMetadata->getWithDefaultValue( $groupId, 'description', null );
92            $label = $messageGroupMetadata->getWithDefaultValue( $groupId, 'label', null );
93            $groups[$groupId] = new MessageBundleMessageGroup(
94                $groupId,
95                $conf[0],
96                $conf[1],
97                $conf[2],
98                $description,
99                $label
100            );
101        }
102
103        return $groups;
104    }
105
106    /** @inheritDoc */
107    public function recache(): void {
108        $this->groups = null;
109        $cacheData = $this->cache->getValue( 'recache' );
110        $this->groups = $this->initGroupsFromConf( $cacheData );
111    }
112
113    /** @inheritDoc */
114    public function clearCache(): void {
115        $this->groups = null;
116        $this->cache->delete();
117    }
118}