SidebarHookHandler::onOutputPageParserOutput()   B
last analyzed

Complexity

Conditions 7
Paths 17

Size

Total Lines 31

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 31
rs 8.4906
c 0
b 0
f 0
cc 7
nc 17
nop 2
1
<?php
2
3
declare( strict_types = 1 );
4
5
namespace Wikibase\Client\Hooks;
6
7
use MediaWiki\Hook\OutputPageParserOutputHook;
8
use MediaWiki\Hook\SidebarBeforeOutputHook;
9
use MediaWiki\Hook\SkinTemplateGetLanguageLinkHook;
10
use OutputPage;
11
use ParserOutput;
12
use Skin;
13
use Title;
14
use Wikibase\Client\ClientHooks;
15
use Wikibase\Client\NamespaceChecker;
16
use Wikibase\Client\WikibaseClient;
17
18
/**
19
 * Handler for ParserOutput-related hooks.
20
 *
21
 * @license GPL-2.0-or-later
22
 */
23
class SidebarHookHandler implements
24
	OutputPageParserOutputHook,
25
	SkinTemplateGetLanguageLinkHook,
26
	SidebarBeforeOutputHook
27
{
28
29
	/**
30
	 * @var NamespaceChecker
31
	 */
32
	private $namespaceChecker;
33
34
	/**
35
	 * @var LanguageLinkBadgeDisplay
36
	 */
37
	private $badgeDisplay;
38
39
	public function __construct(
40
		NamespaceChecker $namespaceChecker,
41
		LanguageLinkBadgeDisplay $badgeDisplay
42
	) {
43
		$this->namespaceChecker = $namespaceChecker;
44
		$this->badgeDisplay = $badgeDisplay;
45
	}
46
47
	public static function factory(): self {
48
		$wikibaseClient = WikibaseClient::getDefaultInstance();
49
50
		return new self(
51
			$wikibaseClient->getNamespaceChecker(),
52
			$wikibaseClient->getLanguageLinkBadgeDisplay()
53
		);
54
	}
55
56
	/**
57
	 * Add output page property if repo links are suppressed, and property for item id
58
	 *
59
	 * @param OutputPage $out
60
	 * @param ParserOutput $parserOutput
61
	 */
62
	public function onOutputPageParserOutput( $out, $parserOutput ): void {
63
		$title = $out->getTitle();
64
		if ( !$title || !$this->namespaceChecker->isWikibaseEnabled( $title->getNamespace() ) ) {
65
			// shorten out
66
			return;
67
		}
68
69
		$noExternalLangLinks = NoLangLinkHandler::getNoExternalLangLinks( $parserOutput );
70
71
		if ( !empty( $noExternalLangLinks ) ) {
72
			$out->setProperty( 'noexternallanglinks', $noExternalLangLinks );
73
		}
74
75
		$itemId = $parserOutput->getProperty( 'wikibase_item' );
76
77
		if ( $itemId !== false ) {
78
			$out->setProperty( 'wikibase_item', $itemId );
79
		}
80
81
		$otherProjects = $parserOutput->getExtensionData( 'wikibase-otherprojects-sidebar' );
82
83
		if ( $otherProjects !== null ) {
84
			$out->setProperty( 'wikibase-otherprojects-sidebar', $otherProjects );
85
		}
86
87
		$badges = $parserOutput->getExtensionData( 'wikibase_badges' );
88
89
		if ( $badges !== null ) {
90
			$out->setProperty( 'wikibase_badges', $badges );
91
		}
92
	}
93
94
	/**
95
	 * Add badges to the language links.
96
	 *
97
	 * @param array &$languageLink
98
	 * @param Title $languageLinkTitle
99
	 * @param Title $title
100
	 * @param OutputPage|null $output
101
	 */
102
	public function onSkinTemplateGetLanguageLink(
103
		&$languageLink,
104
		$languageLinkTitle,
105
		$title,
106
		$output
107
	): void {
108
		$this->badgeDisplay->applyBadges( $languageLink, $languageLinkTitle, $output );
0 ignored issues
show
Bug introduced by
It seems like $output defined by parameter $output on line 106 can be null; however, Wikibase\Client\Hooks\La...eDisplay::applyBadges() does not accept null, maybe add an additional type check?

It seems like you allow that null is being passed for a parameter, however the function which is called does not seem to accept null.

We recommend to add an additional type check (or disallow null for the parameter):

function notNullable(stdClass $x) { }

// Unsafe
function withoutCheck(stdClass $x = null) {
    notNullable($x);
}

// Safe - Alternative 1: Adding Additional Type-Check
function withCheck(stdClass $x = null) {
    if ($x instanceof stdClass) {
        notNullable($x);
    }
}

// Safe - Alternative 2: Changing Parameter
function withNonNullableParam(stdClass $x) {
    notNullable($x);
}
Loading history...
109
	}
110
111
	/**
112
	 * SidebarBeforeOutput hook handler
113
	 *
114
	 * This handler adds too items to the sidebar section.
115
	 * First it adds the 'Wikidata items' to the 'toolbox' section of the sidebar.
116
	 * Second it adds the 'In other projects' item which lives in its own section.
117
	 *
118
	 * The items generation logic are handled separately for each. This callback
119
	 * is only concerned with adding them to the &$sidebar array (if they exist).
120
	 *
121
	 * If current page cannot have 'Wikidata item' link, this callback will receive
122
	 * null value from ClientHooks::buildWikidataItemLink() method and so it will
123
	 * skip attempting to add the link. Same thing repeats for the second case.
124
	 *
125
	 * @param Skin $skin
126
	 * @param array &$sidebar
127
	 */
128
	public function onSidebarBeforeOutput( $skin, &$sidebar ): void {
129
		// Add 'Wikidata item' to the toolbox
130
		$wikidataItemLink = ClientHooks::buildWikidataItemLink( $skin );
131
132
		if ( $wikidataItemLink !== null ) {
133
			$sidebar['TOOLBOX']['wikibase'] = $wikidataItemLink;
134
		}
135
136
		// Add the 'In other projects' section
137
		$otherProjectsSidebar = $this->buildOtherProjectsSidebar( $skin );
138
139
		if ( $otherProjectsSidebar !== null ) {
140
			$sidebar['wikibase-otherprojects'] = $otherProjectsSidebar;
141
		}
142
	}
143
144
	/**
145
	 * Build 'In other projects' section of the sidebar, if enabled project wide or
146
	 * the user has the beta featured enabled.
147
	 *
148
	 * @param Skin $skin
149
	 *
150
	 * @return null|array[] Array of 'In other projects' contents or null if there are none
151
	 */
152
	public function buildOtherProjectsSidebar( Skin $skin ): ?array {
153
		$outputPage = $skin->getContext()->getOutput();
154
155
		$otherProjectsSidebar = $outputPage->getProperty( 'wikibase-otherprojects-sidebar' );
156
157
		if ( empty( $otherProjectsSidebar ) ) {
158
			return null;
159
		}
160
161
		return $otherProjectsSidebar;
162
	}
163
164
}
165