EditActionHookHandler::getHeader()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 7

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 7
rs 10
c 0
b 0
f 0
cc 1
nc 1
nop 1
1
<?php
2
3
declare( strict_types = 1 );
4
5
namespace Wikibase\Client\Hooks;
6
7
use EditPage;
8
use Html;
9
use IContextSource;
10
use MediaWiki\Hook\EditPage__showStandardInputs_optionsHook;
11
use MessageLocalizer;
12
use OutputPage;
13
use Wikibase\Client\RepoLinker;
14
use Wikibase\Client\Usage\EntityUsage;
15
use Wikibase\Client\Usage\UsageLookup;
16
use Wikibase\Client\WikibaseClient;
17
use Wikibase\DataModel\Entity\EntityIdParser;
18
use Wikibase\Lib\Store\LanguageFallbackLabelDescriptionLookupFactory;
19
20
/**
21
 * Adds the Entity usage data in ActionEdit.
22
 *
23
 * @license GPL-2.0-or-later
24
 * @author Amir Sarabadani < [email protected] >
25
 */
26
class EditActionHookHandler implements EditPage__showStandardInputs_optionsHook {
27
28
	/**
29
	 * @var RepoLinker
30
	 */
31
	private $repoLinker;
32
33
	/**
34
	 * @var UsageLookup
35
	 */
36
	private $usageLookup;
37
38
	/**
39
	 * @var LanguageFallbackLabelDescriptionLookupFactory
40
	 */
41
	private $labelDescriptionLookupFactory;
42
43
	/**
44
	 * @var EntityIdParser
45
	 */
46
	private $idParser;
47
48
	public function __construct(
49
		RepoLinker $repoLinker,
50
		UsageLookup $usageLookup,
51
		LanguageFallbackLabelDescriptionLookupFactory $labelDescriptionLookupFactory,
52
		EntityIdParser $idParser
53
	) {
54
		$this->repoLinker = $repoLinker;
55
		$this->usageLookup = $usageLookup;
56
		$this->labelDescriptionLookupFactory = $labelDescriptionLookupFactory;
57
		$this->idParser = $idParser;
58
	}
59
60
	public static function factory(): self {
61
		$wikibaseClient = WikibaseClient::getDefaultInstance();
62
63
		$usageLookup = $wikibaseClient->getStore()->getUsageLookup();
64
		$labelDescriptionLookupFactory = new LanguageFallbackLabelDescriptionLookupFactory(
65
			$wikibaseClient->getLanguageFallbackChainFactory(),
66
			$wikibaseClient->getTermLookup(),
67
			$wikibaseClient->getTermBuffer()
68
		);
69
		$idParser = $wikibaseClient->getEntityIdParser();
70
71
		return new self(
72
			$wikibaseClient->newRepoLinker(),
73
			$usageLookup,
74
			$labelDescriptionLookupFactory,
75
			$idParser
76
		);
77
	}
78
79
	/**
80
	 * @param EditPage $editor
81
	 * @param OutputPage $out
82
	 * @param int $tabindex
83
	 */
84
	// phpcs:ignore MediaWiki.NamingConventions.LowerCamelFunctionsName.FunctionName
85
	public function onEditPage__showStandardInputs_options( $editor, $out, &$tabindex ): void {
86
		if ( $editor->section ) {
87
			// Shorten out, like template transclusion in core
88
			return;
89
		}
90
91
		// Check if there are usages to show
92
		$title = $editor->getTitle();
93
		$usages = $this->usageLookup->getUsagesForPage( $title->getArticleID() );
94
95
		if ( $usages ) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $usages of type Wikibase\Client\Usage\EntityUsage[] is implicitly converted to a boolean; are you sure this is intended? If so, consider using ! empty($expr) instead to make it clear that you intend to check for an array without elements.

This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent.

Consider making the comparison explicit by using empty(..) or ! empty(...) instead.

Loading history...
96
			$header = $this->getHeader( $out );
97
			$usageOutput = $this->formatEntityUsage( $usages, $out );
98
			$output = Html::rawElement(
99
				'div',
100
				[ 'class' => 'wikibase-entity-usage' ],
101
				$header . "\n" . $usageOutput
102
			);
103
			$editor->editFormTextAfterTools .= $output;
104
		}
105
106
		$out->addModules( 'wikibase.client.action.edit.collapsibleFooter' );
107
	}
108
109
	/**
110
	 * @param string[][] $rowAspects
111
	 * @param IContextSource $context
112
	 *
113
	 * @return string HTML
114
	 */
115
	private function formatAspects( array $rowAspects, IContextSource $context ): string {
116
		$aspects = [];
117
118
		foreach ( $rowAspects as $aspect ) {
119
			// Possible messages:
120
			//   wikibase-pageinfo-entity-usage-L
121
			//   wikibase-pageinfo-entity-usage-L-with-modifier
122
			//   wikibase-pageinfo-entity-usage-D
123
			//   wikibase-pageinfo-entity-usage-D-with-modifier
124
			//   wikibase-pageinfo-entity-usage-C
125
			//   wikibase-pageinfo-entity-usage-C-with-modifier
126
			//   wikibase-pageinfo-entity-usage-S
127
			//   wikibase-pageinfo-entity-usage-T
128
			//   wikibase-pageinfo-entity-usage-X
129
			//   wikibase-pageinfo-entity-usage-O
130
			$msgKey = 'wikibase-pageinfo-entity-usage-' . $aspect[0];
131
			if ( $aspect[1] !== null ) {
132
				$msgKey .= '-with-modifier';
133
			}
134
			$aspects[] = $context->msg( $msgKey, $aspect[1] )->parse();
135
		}
136
137
		return $context->getLanguage()->commaList( $aspects );
138
	}
139
140
	/**
141
	 * @param EntityUsage[] $usages
142
	 * @param IContextSource $context
143
	 * @return string HTML
144
	 */
145
	private function formatEntityUsage( array $usages, IContextSource $context ): string {
146
		$usageAspectsByEntity = [];
147
		$entityIds = [];
148
149
		foreach ( $usages as $entityUsage ) {
150
			$entityId = $entityUsage->getEntityId()->getSerialization();
151
			$entityIds[$entityId] = $entityUsage->getEntityId();
152
			$usageAspectsByEntity[$entityId][] = [
153
				$entityUsage->getAspect(),
154
				$entityUsage->getModifier()
155
			];
156
		}
157
158
		$output = '';
159
		$labelLookup = $this->labelDescriptionLookupFactory->newLabelDescriptionLookup(
160
			$context->getLanguage(),
161
			array_values( $entityIds )
162
		);
163
164
		foreach ( $usageAspectsByEntity as $entityId => $aspects ) {
165
			$label = $labelLookup->getLabel( $entityIds[$entityId] );
166
			$text = $label === null ? $entityId : $label->getText();
167
168
			$aspectContent = $this->formatAspects( $aspects, $context );
169
			$colon = $context->msg( 'colon-separator' )->plain();
170
			$output .= Html::rawElement(
171
				'li',
172
				[],
173
				$this->repoLinker->buildEntityLink(
174
					$entityIds[$entityId],
175
					[ 'external' ],
176
					$text
177
				) . $colon . $aspectContent
178
			);
179
		}
180
		return Html::rawElement( 'ul', [], $output );
181
	}
182
183
	/**
184
	 * @param MessageLocalizer $context
185
	 * @return string HTML
186
	 */
187
	private function getHeader( MessageLocalizer $context ): string {
188
		return Html::rawElement(
189
			'div',
190
			[ 'class' => 'wikibase-entityusage-explanation' ],
191
			$context->msg( 'wikibase-pageinfo-entity-usage' )->parseAsBlock()
192
		);
193
	}
194
195
}
196