Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
0.00% covered (danger)
0.00%
0 / 50
0.00% covered (danger)
0.00%
0 / 4
CRAP
0.00% covered (danger)
0.00%
0 / 1
MediaWikiCoreHooksHandler
0.00% covered (danger)
0.00%
0 / 50
0.00% covered (danger)
0.00%
0 / 4
272
0.00% covered (danger)
0.00%
0 / 1
 onSetupAfterCache
0.00% covered (danger)
0.00%
0 / 6
0.00% covered (danger)
0.00%
0 / 1
12
 onApiOpenSearchSuggest
0.00% covered (danger)
0.00%
0 / 5
0.00% covered (danger)
0.00%
0 / 1
12
 onSpecialPage_initList
0.00% covered (danger)
0.00%
0 / 8
0.00% covered (danger)
0.00%
0 / 1
2
 amendSearchResults
0.00% covered (danger)
0.00%
0 / 31
0.00% covered (danger)
0.00%
0 / 1
90
1<?php
2
3declare( strict_types = 1 );
4
5namespace Wikibase\Search\Elastic\Hooks;
6
7use MediaWiki\Api\Hook\ApiOpenSearchSuggestHook;
8use MediaWiki\Context\RequestContext;
9use MediaWiki\Hook\SetupAfterCacheHook;
10use MediaWiki\Language\Language;
11use MediaWiki\SpecialPage\Hook\SpecialPage_initListHook;
12use Wikibase\DataModel\Entity\EntityIdParsingException;
13use Wikibase\Repo\WikibaseRepo;
14use Wikibase\Search\Elastic\SpecialEntitiesWithoutPageFactory;
15
16class MediaWikiCoreHooksHandler    implements SetupAfterCacheHook, ApiOpenSearchSuggestHook, SpecialPage_initListHook {
17
18    /**
19     * Setup hook.
20     * Enables/disables CirrusSearch depending on request settings.
21     */
22    public function onSetupAfterCache() {
23        $request = RequestContext::getMain()->getRequest();
24        $useCirrus = $request->getVal( 'useCirrus' );
25        if ( $useCirrus !== null ) {
26            $GLOBALS['wgWBCSUseCirrus'] = wfStringToBool( $useCirrus );
27        }
28        if ( CirrusSearchConfiguration::isWBCSEnabled() ) {
29            global $wgCirrusSearchExtraIndexSettings;
30            // Bump max fields so that labels/descriptions fields fit in.
31            $wgCirrusSearchExtraIndexSettings['index.mapping.total_fields.limit'] = 5000;
32        }
33    }
34
35    /**
36     * Will instantiate descriptions for search results.
37     * @param array &$results
38     */
39    public function onApiOpenSearchSuggest( &$results ) {
40        if ( !CirrusSearchConfiguration::isWBCSEnabled() ) {
41            return;
42        }
43
44        if ( !$results ) {
45            return;
46        }
47
48        self::amendSearchResults( RequestContext::getMain()->getLanguage(), $results );
49    }
50
51    /**
52     * Register special pages.
53     *
54     * @param array &$list
55     */
56    public function onSpecialPage_initList( &$list ) {
57        $list['EntitiesWithoutLabel'] = [
58            SpecialEntitiesWithoutPageFactory::class,
59            'newSpecialEntitiesWithoutLabel'
60        ];
61
62        $list['EntitiesWithoutDescription'] = [
63            SpecialEntitiesWithoutPageFactory::class,
64            'newSpecialEntitiesWithoutDescription'
65        ];
66    }
67
68    /**
69     * Will instantiate descriptions for search results.
70     *
71     * This is public because we want also to be able to use it from tests, and with the
72     * TestingAccessWrapper it isn't possible to call the function at runtime with a pass-by-reference
73     * parameter.
74     *
75     * @param Language $lang
76     * @param array &$results
77     */
78    public static function amendSearchResults( Language $lang, array &$results ) {
79        $idParser = WikibaseRepo::getEntityIdParser();
80        $entityIds = [];
81        $namespaceLookup = WikibaseRepo::getEntityNamespaceLookup();
82
83        foreach ( $results as &$result ) {
84            if ( empty( $result['title'] ) ||
85                !$namespaceLookup->isEntityNamespace( $result['title']->getNamespace() ) ) {
86                continue;
87            }
88            try {
89                $title = $result['title']->getText();
90                $entityId = $idParser->parse( $title );
91                $entityIds[] = $entityId;
92                $result['entityId'] = $entityId;
93            } catch ( EntityIdParsingException ) {
94                continue;
95            }
96        }
97        if ( !$entityIds ) {
98            return;
99        }
100        $lookup = WikibaseRepo::getFallbackLabelDescriptionLookupFactory()
101            ->newLabelDescriptionLookup( $lang, $entityIds );
102        $formatterFactory = WikibaseRepo::getEntityLinkFormatterFactory();
103        foreach ( $results as &$result ) {
104            if ( empty( $result['entityId'] ) ) {
105                continue;
106            }
107            $entityId = $result['entityId'];
108            unset( $result['entityId'] );
109            $label = $lookup->getLabel( $entityId );
110            if ( !$label ) {
111                continue;
112            }
113            $linkFormatter = $formatterFactory->getLinkFormatter( $entityId->getEntityType(), $lang );
114            $result['extract'] = strip_tags( $linkFormatter->getHtml( $entityId, [
115                'value' => $label->getText(),
116                'language' => $label->getActualLanguageCode(),
117            ] ) );
118        }
119    }
120
121}