Completed
Push — master ( c5411a...4acbd7 )
by
unknown
02:00 queued 11s
created

LanguageChecker::checkConstraintParameters()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 15

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 15
rs 9.7666
c 0
b 0
f 0
cc 2
nc 2
nop 1
1
<?php
2
3
namespace WikibaseQuality\ConstraintReport\ConstraintCheck\Checker\Lexeme;
4
5
use ExtensionRegistry;
6
use Wikibase\DataModel\Entity\EntityDocument;
7
use Wikibase\DataModel\Services\Lookup\EntityLookup;
8
use Wikibase\DataModel\Statement\Statement;
9
use Wikibase\Lexeme\Domain\Model\Form;
10
use Wikibase\Lexeme\Domain\Model\Lexeme;
11
use Wikibase\Lexeme\Domain\Model\LexemeSubEntityId;
12
use Wikibase\Lexeme\Domain\Model\Sense;
13
use WikibaseQuality\ConstraintReport\Constraint;
14
use WikibaseQuality\ConstraintReport\ConstraintCheck\ConstraintChecker;
15
use WikibaseQuality\ConstraintReport\ConstraintCheck\Context\Context;
16
use WikibaseQuality\ConstraintReport\ConstraintCheck\Helper\ConstraintParameterException;
17
use WikibaseQuality\ConstraintReport\ConstraintCheck\Helper\ConstraintParameterParser;
18
use WikibaseQuality\ConstraintReport\ConstraintCheck\Message\ViolationMessage;
19
use WikibaseQuality\ConstraintReport\ConstraintCheck\Result\CheckResult;
20
use WikibaseQuality\ConstraintReport\Role;
21
22
/**
23
 * @license GPL-2.0-or-later
24
 */
25
class LanguageChecker implements ConstraintChecker {
26
27
	/**
28
	 * @var EntityLookup
29
	 */
30
	private $entityLookup;
31
32
	/**
33
	 * @var ConstraintParameterParser
34
	 */
35
	private $constraintParameterParser;
36
37
	public function __construct(
38
		ConstraintParameterParser $constraintParameterParser,
39
		EntityLookup $lookup
40
	) {
41
		$this->constraintParameterParser = $constraintParameterParser;
42
		$this->entityLookup = $lookup;
43
	}
44
45
	/**
46
	 * @codeCoverageIgnore This method is purely declarative.
47
	 */
48
	public function getSupportedContextTypes() {
49
		return [
50
			Context::TYPE_STATEMENT => CheckResult::STATUS_COMPLIANCE,
51
			Context::TYPE_QUALIFIER => CheckResult::STATUS_COMPLIANCE,
52
			Context::TYPE_REFERENCE => CheckResult::STATUS_COMPLIANCE,
53
		];
54
	}
55
56
	/**
57
	 * @codeCoverageIgnore This method is purely declarative.
58
	 */
59
	public function getDefaultContextTypes() {
60
		return [
61
			Context::TYPE_STATEMENT,
62
			Context::TYPE_QUALIFIER,
63
			Context::TYPE_REFERENCE,
64
		];
65
	}
66
67
	/**
68
	 * Checks 'Language' constraint.
69
	 *
70
	 * @param Context $context
71
	 * @param Constraint $constraint
72
	 *
73
	 * @throws ConstraintParameterException
74
	 * @return CheckResult
75
	 */
76
	public function checkConstraint( Context $context, Constraint $constraint ) {
77
		if ( !ExtensionRegistry::getInstance()->isLoaded( 'WikibaseLexeme' ) ) {
78
			return new CheckResult( $context, $constraint, [], CheckResult::STATUS_NOT_IN_SCOPE );
79
		}
80
		$entityType = $context->getEntity()->getType();
81
		if ( !in_array( $entityType, [ Lexeme::ENTITY_TYPE, Sense::ENTITY_TYPE, Form::ENTITY_TYPE ] ) ) {
82
			return new CheckResult( $context, $constraint, [], CheckResult::STATUS_NOT_IN_SCOPE );
83
		}
84
		if ( $context->getSnakRank() === Statement::RANK_DEPRECATED ) {
85
			return new CheckResult( $context, $constraint, [], CheckResult::STATUS_DEPRECATED );
86
		}
87
88
		$parameters = [];
89
		$constraintParameters = $constraint->getConstraintParameters();
90
		$constraintTypeItemId = $constraint->getConstraintTypeItemId();
91
92
		$languages = $this->constraintParameterParser->parseItemsParameter(
93
			$constraintParameters,
94
			$constraintTypeItemId,
95
			true
96
		);
97
		$parameters['languages'] = $languages;
98
99
		$message = ( new ViolationMessage( 'wbqc-violation-message-language' ) )
100
			->withEntityId( $context->getSnak()->getPropertyId(), Role::PREDICATE )
101
			->withItemIdSnakValueList( $languages, Role::OBJECT );
102
		$status = CheckResult::STATUS_VIOLATION;
103
104
		$lexeme = $this->getLexeme( $context );
105
		if ( !$lexeme ) {
106
			// Lexeme doesn't exist, let's not bother
107
			return new CheckResult( $context, $constraint, [], CheckResult::STATUS_NOT_IN_SCOPE );
108
		}
109
110
		/** @var Lexeme $lexeme */
111
		'@phan-var Lexeme $lexeme';
112
113
		foreach ( $languages as $language ) {
114
			if ( $language->isNoValue() || $language->isSomeValue() ) {
115
				continue;
116
			}
117
			if ( $lexeme->getLanguage()->equals( $language->getItemId() ) ) {
118
				$message = null;
119
				$status = CheckResult::STATUS_COMPLIANCE;
120
				break;
121
			}
122
		}
123
124
		return new CheckResult( $context, $constraint, $parameters, $status, $message );
125
	}
126
127
	private function getLexeme( Context $context ): ?EntityDocument {
128
		$entityType = $context->getEntity()->getType();
129
130
		if ( $entityType === Lexeme::ENTITY_TYPE ) {
131
			return $context->getEntity();
132
		}
133
134
		if ( in_array( $entityType, [ Form::ENTITY_TYPE, Sense::ENTITY_TYPE ] ) ) {
135
			/** @var LexemeSubEntityId $id */
136
			$id = $context->getEntity()->getId();
137
			'@phan-var LexemeSubEntityId $id';
138
			return $this->entityLookup->getEntity( $id->getLexemeId() );
139
		}
140
	}
141
142
	public function checkConstraintParameters( Constraint $constraint ): array {
143
		$constraintParameters = $constraint->getConstraintParameters();
144
		$constraintTypeItemId = $constraint->getConstraintTypeItemId();
145
		$exceptions = [];
146
		try {
147
			$this->constraintParameterParser->parseItemsParameter(
148
				$constraintParameters,
149
				$constraintTypeItemId,
150
				true
151
			);
152
		} catch ( ConstraintParameterException $e ) {
153
			$exceptions[] = $e;
154
		}
155
		return $exceptions;
156
	}
157
158
}
159