Code Coverage |
||||||||||
Lines |
Functions and Methods |
Classes and Traits |
||||||||
Total | |
75.76% |
25 / 33 |
|
60.00% |
3 / 5 |
CRAP | |
0.00% |
0 / 1 |
SidebarBeforeOutputHookHandler | |
75.76% |
25 / 33 |
|
60.00% |
3 / 5 |
12.72 | |
0.00% |
0 / 1 |
newFromGlobalState | |
0.00% |
0 / 5 |
|
0.00% |
0 / 1 |
2 | |||
__construct | |
100.00% |
3 / 3 |
|
100.00% |
1 / 1 |
1 | |||
onSidebarBeforeOutput | |
0.00% |
0 / 3 |
|
0.00% |
0 / 1 |
6 | |||
buildSidebarLink | |
100.00% |
10 / 10 |
|
100.00% |
1 / 1 |
4 | |||
getItemId | |
100.00% |
12 / 12 |
|
100.00% |
1 / 1 |
3 |
1 | <?php |
2 | |
3 | namespace ArticlePlaceholder; |
4 | |
5 | use MediaWiki\Hook\SidebarBeforeOutputHook; |
6 | use MediaWiki\MediaWikiServices; |
7 | use Skin; |
8 | use Wikibase\Client\RepoLinker; |
9 | use Wikibase\Client\WikibaseClient; |
10 | use Wikibase\DataModel\Entity\EntityIdParser; |
11 | use Wikibase\DataModel\Entity\EntityIdParsingException; |
12 | use Wikibase\DataModel\Entity\ItemId; |
13 | use 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 | */ |
21 | class 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 | } |