Completed
Push — master ( c10acf...f9d335 )
by
unknown
05:55
created

SingleBestValueChecker::getViolationMessage()   B

Complexity

Conditions 4
Paths 4

Size

Total Lines 24
Code Lines 18

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
c 0
b 0
f 0
dl 0
loc 24
rs 8.6845
cc 4
eloc 18
nc 4
nop 4
1
<?php
2
3
namespace WikibaseQuality\ConstraintReport\ConstraintCheck\Checker;
4
5
use Wikibase\DataModel\Entity\PropertyId;
6
use Wikibase\DataModel\Statement\Statement;
7
use WikibaseQuality\ConstraintReport\Constraint;
8
use WikibaseQuality\ConstraintReport\ConstraintCheck\ConstraintChecker;
9
use WikibaseQuality\ConstraintReport\ConstraintCheck\Context\Context;
10
use WikibaseQuality\ConstraintReport\ConstraintCheck\Helper\ConstraintParameterException;
11
use WikibaseQuality\ConstraintReport\ConstraintCheck\Helper\ConstraintParameterParser;
12
use WikibaseQuality\ConstraintReport\ConstraintCheck\Helper\ValueCountCheckerHelper;
13
use WikibaseQuality\ConstraintReport\ConstraintCheck\Message\ViolationMessage;
14
use WikibaseQuality\ConstraintReport\ConstraintCheck\Result\CheckResult;
15
16
/**
17
 * @author Lucas Werkmeister
18
 * @license GPL-2.0-or-later
19
 */
20
class SingleBestValueChecker implements ConstraintChecker {
21
22
	/**
23
	 * @var ConstraintParameterParser
24
	 */
25
	private $constraintParameterParser;
26
27
	/**
28
	 * @var ValueCountCheckerHelper
29
	 */
30
	private $valueCountCheckerHelper;
31
32
	public function __construct(
33
		ConstraintParameterParser $constraintParameterParser
34
	) {
35
		$this->constraintParameterParser = $constraintParameterParser;
36
		$this->valueCountCheckerHelper = new ValueCountCheckerHelper();
37
	}
38
39
	/**
40
	 * @codeCoverageIgnore This method is purely declarative.
41
	 */
42
	public function getSupportedContextTypes() {
43
		return [
44
			Context::TYPE_STATEMENT => CheckResult::STATUS_COMPLIANCE,
45
			Context::TYPE_QUALIFIER => CheckResult::STATUS_COMPLIANCE,
46
			Context::TYPE_REFERENCE => CheckResult::STATUS_COMPLIANCE,
47
		];
48
	}
49
50
	/**
51
	 * @codeCoverageIgnore This method is purely declarative.
52
	 */
53
	public function getDefaultContextTypes() {
54
		return [
55
			Context::TYPE_STATEMENT,
56
			Context::TYPE_QUALIFIER,
57
			Context::TYPE_REFERENCE,
58
		];
59
	}
60
61
	/**
62
	 * Checks 'Single best value' constraint.
63
	 *
64
	 * @param Context $context
65
	 * @param Constraint $constraint
66
	 *
67
	 * @return CheckResult
68
	 */
69
	public function checkConstraint( Context $context, Constraint $constraint ) {
70
		if ( $context->getSnakRank() === Statement::RANK_DEPRECATED ) {
71
			return new CheckResult( $context, $constraint, [], CheckResult::STATUS_DEPRECATED );
72
		}
73
74
		$parameters = [];
75
76
		$separators = $this->constraintParameterParser->parseSeparatorsParameter(
77
			$constraint->getConstraintParameters()
78
		);
79
		$parameters['separator'] = $separators;
80
81
		$propertyId = $context->getSnak()->getPropertyId();
82
		$bestRankCount = $this->valueCountCheckerHelper->getPropertyCount(
83
			$context->getSnakGroup( Context::GROUP_BEST_RANK, $separators ),
84
			$propertyId
85
		);
86
87
		if ( $bestRankCount > 1 ) {
88
			$nonDeprecatedCount = $this->valueCountCheckerHelper->getPropertyCount(
89
				$context->getSnakGroup( Context::GROUP_NON_DEPRECATED ),
90
				$propertyId
91
			);
92
			$message = $this->getViolationMessage(
93
				$bestRankCount,
94
				$nonDeprecatedCount,
95
				$separators,
96
				$propertyId
97
			);
98
			$status = CheckResult::STATUS_VIOLATION;
99
		} else {
100
			$message = null;
101
			$status = CheckResult::STATUS_COMPLIANCE;
102
		}
103
104
		return new CheckResult( $context, $constraint, $parameters, $status, $message );
105
	}
106
107
	public function checkConstraintParameters( Constraint $constraint ) {
108
		$constraintParameters = $constraint->getConstraintParameters();
109
		$exceptions = [];
110
		try {
111
			$this->constraintParameterParser->parseSeparatorsParameter( $constraintParameters );
112
		} catch ( ConstraintParameterException $e ) {
113
			$exceptions[] = $e;
114
		}
115
		return $exceptions;
116
	}
117
118
	/**
119
	 * @param int $bestRankCount
120
	 * @param int $nonDeprecatedCount
121
	 * @param PropertyId[] $separators
122
	 * @param PropertyId $propertyId
123
	 * @return ViolationMessage
124
	 */
125
	private function getViolationMessage(
126
		$bestRankCount,
127
		$nonDeprecatedCount,
128
		$separators,
129
		$propertyId
130
	) {
131
		if ( $bestRankCount === $nonDeprecatedCount ) {
132
			if ( $separators === [] ) {
133
				$messageKey = 'wbqc-violation-message-single-best-value-no-preferred';
134
			} else {
135
				$messageKey = 'wbqc-violation-message-single-best-value-no-preferred-separators';
136
			}
137
		} else {
138
			if ( $separators === [] ) {
139
				$messageKey = 'wbqc-violation-message-single-best-value-multi-preferred';
140
			} else {
141
				$messageKey = 'wbqc-violation-message-single-best-value-multi-preferred-separators';
142
			}
143
		}
144
145
		return ( new ViolationMessage( $messageKey ) )
146
			->withEntityId( $propertyId )
147
			->withEntityIdList( $separators );
148
	}
149
150
}
151