SpecialModifyTerm   A
last analyzed

Complexity

Total Complexity 29

Size/Duplication

Total Lines 298
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 9

Importance

Changes 0
Metric Value
wmc 29
lcom 1
cbo 9
dl 0
loc 298
rs 10
c 0
b 0
f 0

12 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 22 1
A doesWrites() 0 3 1
B processArguments() 0 26 6
A checkSubPageLanguage() 0 10 3
A validateInput() 0 21 5
A modifyEntity() 0 13 3
A checkTermChangePermissions() 0 7 1
B getForm() 0 76 6
A setValueIfNull() 0 9 3
getPostedValue() 0 1 ?
getValue() 0 1 ?
setValue() 0 1 ?
1
<?php
2
3
namespace Wikibase\Repo\Specials;
4
5
use Html;
6
use HTMLForm;
7
use Language;
8
use Status;
9
use Wikibase\DataModel\Entity\EntityDocument;
10
use Wikibase\DataModel\Entity\EntityId;
11
use Wikibase\Lib\ContentLanguages;
12
use Wikibase\Lib\Store\EntityTitleLookup;
13
use Wikibase\Lib\Summary;
14
use Wikibase\Lib\UserInputException;
15
use Wikibase\Repo\ChangeOp\ChangeOpException;
16
use Wikibase\Repo\ChangeOp\FingerprintChangeOpFactory;
17
use Wikibase\Repo\EditEntity\MediawikiEditEntityFactory;
18
use Wikibase\Repo\Store\EntityPermissionChecker;
19
use Wikibase\Repo\SummaryFormatter;
20
use Wikibase\Repo\WikibaseRepo;
21
22
/**
23
 * Abstract special page for setting a value of a Wikibase entity.
24
 *
25
 * @license GPL-2.0-or-later
26
 * @author Bene* < [email protected] >
27
 * @author Daniel Kinzler
28
 */
29
abstract class SpecialModifyTerm extends SpecialModifyEntity {
30
31
	use ParameterizedDescriptionTrait;
32
33
	/**
34
	 * The language the value is set in.
35
	 *
36
	 * @var string
37
	 */
38
	private $languageCode;
39
40
	/**
41
	 * The value to set.
42
	 *
43
	 * @var string
44
	 */
45
	private $value;
46
47
	/**
48
	 * @var FingerprintChangeOpFactory
49
	 */
50
	protected $termChangeOpFactory;
51
52
	/**
53
	 * @var ContentLanguages
54
	 */
55
	private $termsLanguages;
56
57
	/**
58
	 * @var EntityPermissionChecker
59
	 */
60
	private $permissionChecker;
61
62
	/**
63
	 * @param string $title The title of the special page
64
	 * @param SpecialPageCopyrightView $copyrightView
65
	 * @param SummaryFormatter $summaryFormatter
66
	 * @param EntityTitleLookup $entityTitleLookup
67
	 * @param MediawikiEditEntityFactory $editEntityFactory
68
	 * @param EntityPermissionChecker $permissionChecker
69
	 */
70
	public function __construct(
71
		$title,
72
		SpecialPageCopyrightView $copyrightView,
73
		SummaryFormatter $summaryFormatter,
74
		EntityTitleLookup $entityTitleLookup,
75
		MediawikiEditEntityFactory $editEntityFactory,
76
		EntityPermissionChecker $permissionChecker
77
	) {
78
		parent::__construct(
79
			$title,
80
			$copyrightView,
81
			$summaryFormatter,
82
			$entityTitleLookup,
83
			$editEntityFactory
84
		);
85
86
		$wikibaseRepo = WikibaseRepo::getDefaultInstance();
87
		$changeOpFactoryProvider = $wikibaseRepo->getChangeOpFactoryProvider();
88
		$this->termChangeOpFactory = $changeOpFactoryProvider->getFingerprintChangeOpFactory();
89
		$this->termsLanguages = $wikibaseRepo->getTermsLanguages();
90
		$this->permissionChecker = $permissionChecker;
91
	}
92
93
	public function doesWrites() {
94
		return true;
95
	}
96
97
	/**
98
	 * @see SpecialModifyEntity::processArguments()
99
	 *
100
	 * @param string|null $subPage
101
	 */
102
	protected function processArguments( $subPage ) {
103
		parent::processArguments( $subPage );
104
105
		$request = $this->getRequest();
106
		$parts = ( $subPage === '' ) ? [] : explode( '/', $subPage, 2 );
107
108
		$this->languageCode = $request->getRawVal( 'language', $parts[1] ?? '' );
109
110
		if ( $this->languageCode === '' ) {
111
			$this->languageCode = null;
112
		}
113
114
		$this->checkSubPageLanguage();
115
116
		$this->value = $this->getPostedValue();
117
		if ( $this->value === null ) {
118
			$this->value = $request->getVal( 'value' );
119
		}
120
121
		// If the user just enters an item id and a language, dont remove the term.
122
		// The user can remove the term in the second form where it has to be
123
		// actually removed. This prevents users from removing terms accidentally.
124
		if ( !$request->getCheck( 'remove' ) && $this->value === '' ) {
125
			$this->value = null;
126
		}
127
	}
128
129
	/**
130
	 * Check the language given as sup page argument.
131
	 */
132
	private function checkSubPageLanguage() {
133
		if ( $this->languageCode !== null && !$this->termsLanguages->hasLanguage( $this->languageCode ) ) {
134
			$errorMessage = $this->msg(
135
				'wikibase-wikibaserepopage-invalid-langcode',
136
				wfEscapeWikiText( $this->languageCode )
137
			)->parse();
138
139
			$this->showErrorHTML( $errorMessage );
140
		}
141
	}
142
143
	/**
144
	 * @see SpecialModifyEntity::validateInput()
145
	 *
146
	 * @return bool
147
	 */
148
	protected function validateInput() {
149
		if ( !parent::validateInput() ) {
150
			return false;
151
		}
152
153
		if ( $this->value === null ) {
154
			return false;
155
		}
156
157
		$entityId = $this->getEntityId();
158
		if ( $entityId ) {
159
			$status = $this->checkTermChangePermissions( $entityId );
160
161
			if ( !$status->isOK() ) {
162
				$this->showErrorHTML( $this->msg( 'permissionserrors' )->parse() );
163
				return false;
164
			}
165
		}
166
167
		return true;
168
	}
169
170
	/**
171
	 * @see SpecialModifyEntity::modifyEntity()
172
	 *
173
	 * @param EntityDocument $entity
174
	 *
175
	 * @return Summary|bool
176
	 */
177
	protected function modifyEntity( EntityDocument $entity ) {
178
		try {
179
			$summary = $this->setValue( $entity, $this->languageCode, $this->value );
180
		} catch ( ChangeOpException $e ) {
181
			$this->showErrorHTML( $e->getMessage() );
182
			return false;
183
		} catch ( UserInputException $e ) {
184
			$this->showErrorHTML( $e->getMessage() );
185
			return false;
186
		}
187
188
		return $summary;
189
	}
190
191
	/**
192
	 * @param EntityId $entityId
193
	 *
194
	 * @return Status
195
	 */
196
	private function checkTermChangePermissions( EntityId $entityId ) {
197
		return $this->permissionChecker->getPermissionStatusForEntityId(
198
			$this->getUser(),
199
			EntityPermissionChecker::ACTION_EDIT_TERMS,
200
			$entityId
201
		);
202
	}
203
204
	/**
205
	 * @see SpecialModifyEntity::getForm()
206
	 *
207
	 * @param EntityDocument|null $entity
208
	 *
209
	 * @return HTMLForm
210
	 */
211
	protected function getForm( EntityDocument $entity = null ) {
212
		if ( $this->languageCode === null ) {
213
			$this->languageCode = $this->getLanguage()->getCode();
214
		}
215
216
		$this->setValueIfNull( $entity );
217
218
		$valueinput = [
219
			'name' => 'value',
220
			'cssclass' => 'wb-input',
221
			'id' => 'wb-modifyterm-value',
222
			'type' => 'text',
223
			'default' => $this->getRequest()->getVal( 'value' ) ?: $this->value,
224
			'nodata' => true
225
		];
226
227
		$languageName = Language::fetchLanguageName( $this->languageCode, $this->getLanguage()->getCode() );
228
229
		if ( $entity !== null && $this->languageCode !== null && $languageName !== '' ) {
230
			// Messages:
231
			// wikibase-setlabel-introfull
232
			// wikibase-setdescription-introfull
233
			// wikibase-setaliases-introfull
234
			$intro = $this->msg(
235
				'wikibase-' . strtolower( $this->getName() ) . '-introfull',
0 ignored issues
show
Bug introduced by
Consider using $this->name. There is an issue with getName() and APC-enabled PHP versions.
Loading history...
236
				$this->getEntityTitle( $entity->getId() )->getPrefixedText(),
237
				$languageName
238
			)->parse();
239
			$formDescriptor = [
240
				'language' => [
241
					'name' => 'language',
242
					'type' => 'hidden',
243
					'default' => $this->languageCode
244
				],
245
				'id' => [
246
					'name' => 'id',
247
					'type' => 'hidden',
248
					'default' => $entity->getId()->getSerialization()
249
				],
250
				'remove' => [
251
					'name' => 'remove',
252
					'type' => 'hidden',
253
					'default' => 'remove'
254
				],
255
				'value' => $valueinput,
256
				'revid' => [
257
					'name' => 'revid',
258
					'type' => 'hidden',
259
					'default' => $this->getBaseRevision()->getRevisionId(),
260
				],
261
			];
262
		} else {
263
			// Messages:
264
			// wikibase-setlabel-intro
265
			// wikibase-setdescription-intro
266
			// wikibase-setaliases-intro
267
			$intro = $this->msg( 'wikibase-' . strtolower( $this->getName() ) . '-intro' )->parse();
0 ignored issues
show
Bug introduced by
Consider using $this->name. There is an issue with getName() and APC-enabled PHP versions.
Loading history...
268
			$formDescriptor = $this->getFormElements( $entity );
269
			$formDescriptor['language'] = [
270
				'name' => 'language',
271
				'label-message' => 'wikibase-modifyterm-language',
272
				'type' => 'text',
273
				'default' => $this->languageCode,
274
				'id' => 'wb-modifyterm-language'
275
			];
276
			// Messages:
277
			// wikibase-setlabel-label
278
			// wikibase-setdescription-label
279
			// wikibase-setaliases-label
280
			$valueinput['label-message'] = 'wikibase-' . strtolower( $this->getName() ) . '-label';
0 ignored issues
show
Bug introduced by
Consider using $this->name. There is an issue with getName() and APC-enabled PHP versions.
Loading history...
281
			$formDescriptor['value'] = $valueinput;
282
		}
283
284
		return HTMLForm::factory( 'ooui', $formDescriptor, $this->getContext() )
285
			->setHeaderText( Html::rawElement( 'p', [], $intro ) );
286
	}
287
288
	private function setValueIfNull( EntityDocument $entity = null ) {
289
		if ( $this->value === null ) {
290
			if ( $entity === null ) {
291
				$this->value = '';
292
			} else {
293
				$this->value = $this->getValue( $entity, $this->languageCode );
294
			}
295
		}
296
	}
297
298
	/**
299
	 * Returning the posted value of the request.
300
	 *
301
	 * @return string|null
302
	 */
303
	abstract protected function getPostedValue();
304
305
	/**
306
	 * Returning the value of the entity name by the given language
307
	 *
308
	 * @param EntityDocument $entity
309
	 * @param string $languageCode
310
	 *
311
	 * @return string
312
	 */
313
	abstract protected function getValue( EntityDocument $entity, $languageCode );
314
315
	/**
316
	 * Setting the value of the entity name by the given language
317
	 *
318
	 * @param EntityDocument $entity
319
	 * @param string $languageCode
320
	 * @param string $value
321
	 *
322
	 * @return Summary
323
	 */
324
	abstract protected function setValue( EntityDocument $entity, $languageCode, $value );
325
326
}
327