Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
75.76% covered (warning)
75.76%
25 / 33
60.00% covered (warning)
60.00%
3 / 5
CRAP
0.00% covered (danger)
0.00%
0 / 1
SidebarBeforeOutputHookHandler
75.76% covered (warning)
75.76%
25 / 33
60.00% covered (warning)
60.00%
3 / 5
12.72
0.00% covered (danger)
0.00%
0 / 1
 newFromGlobalState
0.00% covered (danger)
0.00%
0 / 5
0.00% covered (danger)
0.00%
0 / 1
2
 __construct
100.00% covered (success)
100.00%
3 / 3
100.00% covered (success)
100.00%
1 / 1
1
 onSidebarBeforeOutput
0.00% covered (danger)
0.00%
0 / 3
0.00% covered (danger)
0.00%
0 / 1
6
 buildSidebarLink
100.00% covered (success)
100.00%
10 / 10
100.00% covered (success)
100.00%
1 / 1
4
 getItemId
100.00% covered (success)
100.00%
12 / 12
100.00% covered (success)
100.00%
1 / 1
3
1<?php
2
3namespace ArticlePlaceholder;
4
5use MediaWiki\Hook\SidebarBeforeOutputHook;
6use MediaWiki\MediaWikiServices;
7use Skin;
8use Wikibase\Client\RepoLinker;
9use Wikibase\Client\WikibaseClient;
10use Wikibase\DataModel\Entity\EntityIdParser;
11use Wikibase\DataModel\Entity\EntityIdParsingException;
12use Wikibase\DataModel\Entity\ItemId;
13use Wikibase\DataModel\Services\Lookup\EntityLookup;
14
15/**
16 * Add Wikibase item link in toolbox for placeholders: Handler for the "SidebarBeforeOutput" hook.
17 *
18 * @license GPL-2.0-or-later
19 * @author Marius Hoch < hoo@online.de >
20 */
21class SidebarBeforeOutputHookHandler implements SidebarBeforeOutputHook {
22
23    /**
24     * @var EntityIdParser
25     */
26    private $entityIdParser;
27
28    /**
29     * @var RepoLinker
30     */
31    private $repoLinker;
32
33    /**
34     * @var EntityLookup
35     */
36    private $entityLookup;
37
38    /**
39     * @return self
40     */
41    public static function newFromGlobalState() {
42        return new self(
43            WikibaseClient::getEntityIdParser(),
44            WikibaseClient::getRepoLinker(),
45            WikibaseClient::getStore()->getEntityLookup()
46        );
47    }
48
49    /**
50     * @param EntityIdParser $entityIdParser
51     * @param RepoLinker $repoLinker
52     * @param EntityLookup $entityLookup
53     */
54    public function __construct(
55        EntityIdParser $entityIdParser,
56        RepoLinker $repoLinker,
57        EntityLookup $entityLookup
58    ) {
59        $this->entityIdParser = $entityIdParser;
60        $this->repoLinker = $repoLinker;
61        $this->entityLookup = $entityLookup;
62    }
63
64    /**
65     * @param Skin $skin
66     * @param array[] &$sidebar
67     *
68     * @return void
69     */
70    public function onSidebarBeforeOutput( $skin, &$sidebar ): void {
71        $sidebarLink = $this->buildSidebarLink( $skin );
72        if ( $sidebarLink ) {
73            // Append link
74            $sidebar['TOOLBOX']['wikibase'] = $sidebarLink;
75        }
76    }
77
78    /**
79     * Do checks. Build link array, if possible.
80     *
81     * @param Skin $skin
82     *
83     * @return bool|string[] Array of link elements or False if link cannot be created
84     */
85    public function buildSidebarLink( Skin $skin ) {
86        // Return early (for performance reasons) in case we're not on
87        // Special:AboutTopic (even before calling newFromGlobalState)
88        if ( !$skin->getTitle()->isSpecial( 'AboutTopic' ) ) {
89            return false;
90        }
91
92        $itemId = $this->getItemId( $skin );
93        if ( !$itemId || !$this->entityLookup->hasEntity( $itemId ) ) {
94            return false;
95        }
96
97        // Duplicated from Wikibase\ClientHooks::buildWikidataItemLink
98        return [
99            'id' => 't-wikibase',
100            'text' => $skin->msg( 'wikibase-dataitem' )->text(),
101            'href' => $this->repoLinker->getEntityUrl( $itemId )
102        ];
103    }
104
105    /**
106     * @param Skin $skin
107     *
108     * @return ItemId|null
109     */
110    private function getItemId( Skin $skin ): ?ItemId {
111        $title = $skin->getTitle();
112        $request = $skin->getRequest();
113
114        $factory = MediaWikiServices::getInstance()->getSpecialPageFactory();
115        $idSerialization = $request->getText(
116            'entityid',
117            $factory->resolveAlias( $title->getText() )[1]
118        );
119
120        if ( !$idSerialization ) {
121            return null;
122        }
123
124        try {
125            // @phan-suppress-next-line PhanTypeMismatchReturn
126            return $this->entityIdParser->parse( $idSerialization );
127        } catch ( EntityIdParsingException $ex ) {
128            // Ignore
129        }
130
131        return null;
132    }
133
134}