Skip to content

Commit 7f76c7f

Browse files
committed
Add a StatementRank class
1 parent 0361c30 commit 7f76c7f

File tree

4 files changed

+506
-25
lines changed

4 files changed

+506
-25
lines changed

src/Statement/Statement.php

Lines changed: 17 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -25,13 +25,19 @@
2525
class Statement implements Hashable, Comparable, PropertyIdProvider {
2626

2727
/**
28-
* Rank enum. Higher values are more preferred.
29-
*
30-
* @since 2.0
28+
* @deprecated since 4.4, use StatementRank::PREFERRED instead.
29+
*/
30+
const RANK_PREFERRED = StatementRank::PREFERRED;
31+
32+
/**
33+
* @deprecated since 4.4, use StatementRank::NORMAL instead.
3134
*/
32-
const RANK_PREFERRED = 2;
33-
const RANK_NORMAL = 1;
34-
const RANK_DEPRECATED = 0;
35+
const RANK_NORMAL = StatementRank::NORMAL;
36+
37+
/**
38+
* @deprecated since 4.4, use StatementRank::DEPRECATED instead.
39+
*/
40+
const RANK_DEPRECATED = StatementRank::DEPRECATED;
3541

3642
/**
3743
* @var string|null
@@ -56,9 +62,9 @@ class Statement implements Hashable, Comparable, PropertyIdProvider {
5662
private $references;
5763

5864
/**
59-
* @var integer, element of the Statement::RANK_ enum
65+
* @var int One of the StatementRank::... constants.
6066
*/
61-
private $rank = self::RANK_NORMAL;
67+
private $rank = StatementRank::NORMAL;
6268

6369
/**
6470
* @since 2.0
@@ -190,19 +196,15 @@ public function addNewReference( $snaks = [] /*...*/ ) {
190196

191197
/**
192198
* Sets the rank of the statement.
193-
* The rank is an element of the Statement::RANK_ enum.
194199
*
195200
* @since 0.1
196201
*
197-
* @param integer $rank
202+
* @param int $rank One of the StatementRank::... constants.
203+
*
198204
* @throws InvalidArgumentException
199205
*/
200206
public function setRank( $rank ) {
201-
$ranks = [ self::RANK_DEPRECATED, self::RANK_NORMAL, self::RANK_PREFERRED ];
202-
203-
if ( !in_array( $rank, $ranks, true ) ) {
204-
throw new InvalidArgumentException( 'Invalid rank specified for statement: ' . var_export( $rank, true ) );
205-
}
207+
StatementRank::assertIsValid( $rank );
206208

207209
$this->rank = $rank;
208210
}

src/Statement/StatementRank.php

Lines changed: 165 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,165 @@
1+
<?php
2+
3+
namespace Wikibase\DataModel\Statement;
4+
5+
use InvalidArgumentException;
6+
7+
/**
8+
* Everything we know about statement's ranks and what they are supposed to mean.
9+
*
10+
* @see https://www.mediawiki.org/wiki/Wikibase/DataModel#Ranks_of_Statements
11+
* @see https://meta.wikimedia.org/wiki/Wikidata/Data_model_update#Ranks_and_order
12+
*
13+
* @since 4.4
14+
*
15+
* @license GNU GPL v2+
16+
* @author Thiemo Kreuz
17+
*/
18+
class StatementRank {
19+
20+
/**
21+
* Higher values are more preferred.
22+
* TODO: Link to discussion/documentation that guarantees increasing order.
23+
*/
24+
const DEPRECATED = 0;
25+
const NORMAL = 1;
26+
const PREFERRED = 2;
27+
28+
private static $names = [
29+
self::DEPRECATED => 'deprecated',
30+
self::NORMAL => 'normal',
31+
self::PREFERRED => 'preferred',
32+
];
33+
34+
/**
35+
* @return string[] Array mapping all known self::... constants (integers) to string names.
36+
*/
37+
public static function getNames() {
38+
return self::$names;
39+
}
40+
41+
/**
42+
* @return int[] Array mapping string names to all known self::... constants (integers).
43+
*/
44+
public static function getAllRanks() {
45+
return array_flip( self::$names );
46+
}
47+
48+
/**
49+
* @param int $rank
50+
*
51+
* @throws InvalidArgumentException
52+
*/
53+
public static function assertIsValid( $rank ) {
54+
if ( !self::isValid( $rank ) ) {
55+
throw new InvalidArgumentException( 'Invalid rank' );
56+
}
57+
}
58+
59+
/**
60+
* @param int $rank
61+
*
62+
* @return bool
63+
*/
64+
public static function isValid( $rank ) {
65+
return is_int( $rank ) && array_key_exists( $rank, self::$names );
66+
}
67+
68+
/**
69+
* @param int $rank
70+
*
71+
* @throws InvalidArgumentException
72+
* @return bool Statements with a deprecated (or lower) rank are known to be false. But don't be
73+
* fooled, this does not mean higher ranks are known to be true!
74+
*/
75+
public static function isFalse( $rank ) {
76+
self::assertIsValid( $rank );
77+
78+
return $rank === self::DEPRECATED;
79+
}
80+
81+
/**
82+
* @param int|null $rank1
83+
* @param int|null $rank2
84+
*
85+
* @throws InvalidArgumentException
86+
* @return bool True if the given ranks are equal.
87+
*/
88+
public static function isEqual( $rank1, $rank2 ) {
89+
return self::compare( $rank1, $rank2 ) === 0;
90+
}
91+
92+
/**
93+
* @param int|null $rank1
94+
* @param int|null $rank2
95+
*
96+
* @throws InvalidArgumentException
97+
* @return bool True if the first rank is less preferred than the second.
98+
*/
99+
public static function isLower( $rank1, $rank2 ) {
100+
return self::compare( $rank1, $rank2 ) === -1;
101+
}
102+
103+
/**
104+
* @param int|null $rank1
105+
* @param int|null $rank2
106+
*
107+
* @throws InvalidArgumentException
108+
* @return bool True if the first rank is more preferred than the second.
109+
*/
110+
public static function isHigher( $rank1, $rank2 ) {
111+
return self::compare( $rank1, $rank2 ) === 1;
112+
}
113+
114+
/**
115+
* @param int|null $rank1
116+
* @param int|null $rank2
117+
*
118+
* @throws InvalidArgumentException
119+
* @return int 0 if the ranks are equal, -1 if the first rank is less preferred than the second,
120+
* or +1 if the first rank is more preferred than the second.
121+
*/
122+
public static function compare( $rank1, $rank2 ) {
123+
if ( $rank1 !== null ) {
124+
self::assertIsValid( $rank1 );
125+
}
126+
if ( $rank2 !== null ) {
127+
self::assertIsValid( $rank2 );
128+
}
129+
130+
if ( $rank1 === $rank2 ) {
131+
return 0;
132+
} elseif ( $rank1 === null || $rank1 < $rank2 ) {
133+
return -1;
134+
} else {
135+
return 1;
136+
}
137+
}
138+
139+
/**
140+
* @param int[]|int $ranks
141+
* @param int [$rank2,...]
142+
*
143+
* @return int|null Best rank in the array or list of arguments, or null if none given.
144+
*/
145+
public static function findBestRank( $ranks = [] /*...*/ ) {
146+
if ( !is_array( $ranks ) ) {
147+
$ranks = func_get_args();
148+
}
149+
150+
$best = null;
151+
152+
foreach ( $ranks as $rank ) {
153+
if ( self::isHigher( $rank, $best ) ) {
154+
$best = $rank;
155+
156+
if ( $best === self::PREFERRED ) {
157+
break;
158+
}
159+
}
160+
}
161+
162+
return $best;
163+
}
164+
165+
}

0 commit comments

Comments
 (0)