Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
32.35% covered (danger)
32.35%
33 / 102
15.38% covered (danger)
15.38%
2 / 13
CRAP
0.00% covered (danger)
0.00%
0 / 1
WikibaseLexemeHooks
32.35% covered (danger)
32.35%
33 / 102
15.38% covered (danger)
15.38%
2 / 13
252.67
0.00% covered (danger)
0.00%
0 / 1
 onWikibaseRepoEntityNamespaces
0.00% covered (danger)
0.00%
0 / 4
0.00% covered (danger)
0.00%
0 / 1
6
 onCanonicalNamespaces
96.00% covered (success)
96.00%
24 / 25
0.00% covered (danger)
0.00%
0 / 1
6
 onWikibaseClientEntityTypes
0.00% covered (danger)
0.00%
0 / 4
0.00% covered (danger)
0.00%
0 / 1
2
 onWikibaseRepoEntityTypes
0.00% covered (danger)
0.00%
0 / 10
0.00% covered (danger)
0.00%
0 / 1
6
 onWikibaseDataTypes
0.00% covered (danger)
0.00%
0 / 7
0.00% covered (danger)
0.00%
0 / 1
6
 onWikibaseClientDataTypes
0.00% covered (danger)
0.00%
0 / 4
0.00% covered (danger)
0.00%
0 / 1
2
 onWikibaseContentLanguages
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 registerNamespace
100.00% covered (success)
100.00%
8 / 8
100.00% covered (success)
100.00%
1 / 1
3
 onParserOutputUpdaterConstruction
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 onInfoAction
0.00% covered (danger)
0.00%
0 / 12
0.00% covered (danger)
0.00%
0 / 1
6
 onScribuntoExternalLibraries
0.00% covered (danger)
0.00%
0 / 21
0.00% covered (danger)
0.00%
0 / 1
20
 getLexemeViewLanguages
0.00% covered (danger)
0.00%
0 / 4
0.00% covered (danger)
0.00%
0 / 1
2
 onLoadExtensionSchemaUpdates
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
1<?php
2
3namespace Wikibase\Lexeme;
4
5use IContextSource;
6use MediaWiki\Hook\CanonicalNamespacesHook;
7use MediaWiki\Hook\InfoActionHook;
8use MediaWiki\Installer\Hook\LoadExtensionSchemaUpdatesHook;
9use MediaWiki\MediaWikiServices;
10use Wikibase\Client\WikibaseClient;
11use Wikibase\Lexeme\Maintenance\FixPagePropsSortkey;
12use Wikibase\Lexeme\MediaWiki\Actions\InfoActionHookHandler;
13use Wikibase\Lexeme\MediaWiki\ParserOutput\LexemeParserOutputUpdater;
14use Wikibase\Lexeme\MediaWiki\Scribunto\Scribunto_LuaWikibaseLexemeEntityFormLibrary;
15use Wikibase\Lexeme\MediaWiki\Scribunto\Scribunto_LuaWikibaseLexemeEntityLexemeLibrary;
16use Wikibase\Lexeme\MediaWiki\Scribunto\Scribunto_LuaWikibaseLexemeEntitySenseLibrary;
17use Wikibase\Lexeme\MediaWiki\Scribunto\Scribunto_LuaWikibaseLexemeLibrary;
18use Wikibase\Lib\WikibaseSettings;
19use Wikibase\Repo\ParserOutput\CompositeStatementDataUpdater;
20use Wikibase\Repo\WikibaseRepo;
21use Wikimedia\Assert\Assert;
22
23/**
24 * MediaWiki hook handlers for the Wikibase Lexeme extension.
25 *
26 * @license GPL-2.0-or-later
27 * @author Amir Sarabadani <ladsgroup@gmail.com>
28 */
29class WikibaseLexemeHooks implements
30    InfoActionHook,
31    CanonicalNamespacesHook,
32    LoadExtensionSchemaUpdatesHook
33{
34
35    /**
36     * Hook to register the lexeme and other entity namespaces for EntityNamespaceLookup.
37     *
38     * @param int[] $entityNamespacesSetting
39     */
40    public static function onWikibaseRepoEntityNamespaces( array &$entityNamespacesSetting ) {
41        // XXX: ExtensionProcessor should define an extra config object for every extension.
42        $config = MediaWikiServices::getInstance()->getMainConfig();
43
44        if ( !$config->get( 'LexemeEnableRepo' ) ) {
45            return;
46        }
47
48        // Setting the namespace to false disabled automatic registration.
49        $entityNamespacesSetting['lexeme'] = $config->get( 'LexemeNamespace' );
50    }
51
52    /**
53     * Hook to register the default namespace names.
54     *
55     * @see https://www.mediawiki.org/wiki/Manual:Hooks/CanonicalNamespaces
56     */
57    public function onCanonicalNamespaces( &$namespaces ) {
58        // XXX: ExtensionProcessor should define an extra config object for every extension.
59        $config = MediaWikiServices::getInstance()->getMainConfig();
60
61        // Do not register lexeme namespaces when the repo is not enabled.
62        if ( !WikibaseSettings::isRepoEnabled() || !$config->get( 'LexemeEnableRepo' ) ) {
63            return;
64        }
65
66        // Setting the namespace to false disabled automatic registration.
67        $lexemeNamespaceId = $config->get( 'LexemeNamespace' );
68        if ( $lexemeNamespaceId !== false ) {
69            Assert::parameter(
70                is_int( $lexemeNamespaceId ) &&
71                    $lexemeNamespaceId >= 100 &&
72                    ( $lexemeNamespaceId % 2 ) === 0,
73                '$wgLexemeNamespace',
74                'Namespace ID must be an even integer, at least 100'
75            );
76            $lexemeNamespaceName = 'Lexeme';
77            $namespaces = self::registerNamespace(
78                $namespaces,
79                $lexemeNamespaceId,
80                $lexemeNamespaceName
81            );
82
83            $talkNamespaceId = $lexemeNamespaceId + 1;
84            $talkNamespaceName = $lexemeNamespaceName . '_talk';
85            $namespaces = self::registerNamespace(
86                $namespaces,
87                $talkNamespaceId,
88                $talkNamespaceName
89            );
90        }
91    }
92
93    /**
94     * Adds the definition of the lexeme entity type to the definitions array Wikibase uses.
95     *
96     * @see WikibaseLexeme.entitytypes.php
97     *
98     * @note This is bootstrap code, it is executed for EVERY request. Avoid instantiating
99     * objects or loading classes here!
100     *
101     * @param array[] $entityTypeDefinitions
102     */
103    public static function onWikibaseClientEntityTypes( array &$entityTypeDefinitions ) {
104        $entityTypeDefinitions = array_merge(
105            $entityTypeDefinitions,
106            require __DIR__ . '/../WikibaseLexeme.entitytypes.php'
107        );
108    }
109
110    /**
111     * Adds the definition of the lexeme entity type to the definitions array Wikibase uses.
112     *
113     * @see WikibaseLexeme.entitytypes.php
114     * @see WikibaseLexeme.entitytypes.repo.php
115     *
116     * @param array[] $entityTypeDefinitions
117     */
118    public static function onWikibaseRepoEntityTypes( array &$entityTypeDefinitions ) {
119        $config = MediaWikiServices::getInstance()->getMainConfig();
120        if ( !$config->get( 'LexemeEnableRepo' ) ) {
121            return;
122        }
123
124        $entityTypeDefinitions = array_merge(
125            $entityTypeDefinitions,
126            wfArrayPlus2d(
127                require __DIR__ . '/../WikibaseLexeme.entitytypes.repo.php',
128                require __DIR__ . '/../WikibaseLexeme.entitytypes.php'
129            )
130        );
131    }
132
133    /**
134     * Adds the definition of the data types related to lexeme to the definitions array
135     * Wikibase uses.
136     *
137     * @see WikibaseLexeme.datatypes.php
138     *
139     * @note This is bootstrap code, it is executed for EVERY request. Avoid instantiating
140     * objects or loading classes here!
141     *
142     * @param array[] $dataTypeDefinitions
143     */
144    public static function onWikibaseDataTypes( array &$dataTypeDefinitions ) {
145        $config = MediaWikiServices::getInstance()->getMainConfig();
146        if ( !$config->get( 'LexemeEnableRepo' ) ) {
147            return;
148        }
149
150        $dataTypeDefinitions = array_merge(
151            $dataTypeDefinitions,
152            require __DIR__ . '/../WikibaseLexeme.datatypes.php'
153        );
154    }
155
156    /**
157     * Adds the definition of the data types related to lexeme to the definitions array
158     * Wikibase uses.
159     *
160     * @see WikibaseLexeme.datatypes.client.php
161     *
162     * @param array[] $dataTypeDefinitions
163     */
164    public static function onWikibaseClientDataTypes( array &$dataTypeDefinitions ) {
165        $dataTypeDefinitions = array_merge(
166            $dataTypeDefinitions,
167            require __DIR__ . '/../WikibaseLexeme.datatypes.client.php'
168        );
169    }
170
171    public static function onWikibaseContentLanguages( array &$contentLanguages ) {
172        $contentLanguages['term-lexicographical'] = WikibaseLexemeServices::getTermLanguages();
173    }
174
175    /**
176     * @param string[] $namespaces
177     * @param int $namespaceId
178     * @param string $namespaceName
179     *
180     * @return string[]
181     * @throws \RuntimeException If namespace ID is already registered with another name
182     */
183    private static function registerNamespace( array $namespaces, $namespaceId, $namespaceName ) {
184        if (
185            isset( $namespaces[$namespaceId] ) &&
186            $namespaces[$namespaceId] !== $namespaceName
187        ) {
188            throw new \RuntimeException(
189                "Tried to register `$namespaceName` namespace with ID `$namespaceId`, " .
190                "but ID was already occupied by `{$namespaces[$namespaceId]} namespace`"
191            );
192        }
193
194        $namespaces[$namespaceId] = $namespaceName;
195
196        return $namespaces;
197    }
198
199    public static function onParserOutputUpdaterConstruction(
200        CompositeStatementDataUpdater $statementUpdater, array &$entityUpdaters
201    ) {
202        $entityUpdaters[] = new LexemeParserOutputUpdater( $statementUpdater );
203    }
204
205    /**
206     * Adds the Wikis using the entity in action=info
207     *
208     * @param IContextSource $context
209     * @param array[] &$pageInfo
210     */
211    public function onInfoAction( $context, &$pageInfo ) {
212        $services = MediaWikiServices::getInstance();
213        $config = $services->getMainConfig();
214        if ( !$config->get( 'LexemeEnableRepo' ) ) {
215            return;
216        }
217
218        $namespaceChecker = WikibaseRepo::getEntityNamespaceLookup();
219        $infoActionHookHandler = new InfoActionHookHandler(
220            $namespaceChecker,
221            WikibaseRepo::getEntityIdLookup(),
222            $services->getPageProps(),
223            $context
224        );
225
226        $pageInfo = $infoActionHookHandler->handle( $context, $pageInfo );
227    }
228
229    public static function onScribuntoExternalLibraries( $engine, array &$extraLibraries ) {
230        $config = MediaWikiServices::getInstance()->getMainConfig();
231        if ( !$config->get( 'LexemeEnableDataTransclusion' ) ) {
232            return;
233        }
234        $clientSettings = WikibaseClient::getSettings();
235        if ( !$clientSettings->getSetting( 'allowDataTransclusion' ) ) {
236            return;
237        }
238
239        if ( $engine == 'lua' ) {
240            $extraLibraries['mw.wikibase.lexeme']
241                = Scribunto_LuaWikibaseLexemeLibrary::class;
242            $extraLibraries['mw.wikibase.lexeme.entity.lexeme'] = [
243                'class' => Scribunto_LuaWikibaseLexemeEntityLexemeLibrary::class,
244                'deferLoad' => true,
245            ];
246            $extraLibraries['mw.wikibase.lexeme.entity.form'] = [
247                'class' => Scribunto_LuaWikibaseLexemeEntityFormLibrary::class,
248                'deferLoad' => true,
249            ];
250            $extraLibraries['mw.wikibase.lexeme.entity.sense'] = [
251                'class' => Scribunto_LuaWikibaseLexemeEntitySenseLibrary::class,
252                'deferLoad' => true,
253            ];
254        }
255    }
256
257    public static function getLexemeViewLanguages(): array {
258        return [
259            'lexemeTermLanguages' => MediaWikiServices::getInstance()
260                ->getService( 'WikibaseLexemeTermLanguages' )->getLanguages(),
261        ];
262    }
263
264    public function onLoadExtensionSchemaUpdates( $updater ) {
265        $updater->addPostDatabaseUpdateMaintenance( FixPagePropsSortkey::class );
266    }
267
268}