Skip to content

Commit

Permalink
Add a StatementRank class
Browse files Browse the repository at this point in the history
  • Loading branch information
thiemowmde committed Jun 29, 2016
1 parent ab1db44 commit 1b9cf48
Show file tree
Hide file tree
Showing 4 changed files with 509 additions and 25 deletions.
32 changes: 17 additions & 15 deletions src/Statement/Statement.php
Original file line number Diff line number Diff line change
Expand Up @@ -25,13 +25,19 @@
class Statement implements Hashable, Comparable, PropertyIdProvider {

/**
* Rank enum. Higher values are more preferred.
*
* @since 2.0
* @deprecated since 4.4, use StatementRank::PREFERRED instead.
*/
const RANK_PREFERRED = StatementRank::PREFERRED;

/**
* @deprecated since 4.4, use StatementRank::NORMAL instead.
*/
const RANK_PREFERRED = 2;
const RANK_NORMAL = 1;
const RANK_DEPRECATED = 0;
const RANK_NORMAL = StatementRank::NORMAL;

/**
* @deprecated since 4.4, use StatementRank::DEPRECATED instead.
*/
const RANK_DEPRECATED = StatementRank::DEPRECATED;

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

/**
* @var integer, element of the Statement::RANK_ enum
* @var int One of the StatementRank::... constants.
*/
private $rank = self::RANK_NORMAL;
private $rank = StatementRank::NORMAL;

/**
* @since 2.0
Expand Down Expand Up @@ -192,19 +198,15 @@ public function addNewReference( $snaks = array() /*...*/ ) {

/**
* Sets the rank of the statement.
* The rank is an element of the Statement::RANK_ enum.
*
* @since 0.1
*
* @param integer $rank
* @param int $rank One of the StatementRank::... constants.
*
* @throws InvalidArgumentException
*/
public function setRank( $rank ) {
$ranks = array( self::RANK_DEPRECATED, self::RANK_NORMAL, self::RANK_PREFERRED );

if ( !in_array( $rank, $ranks, true ) ) {
throw new InvalidArgumentException( 'Invalid rank specified for statement: ' . var_export( $rank, true ) );
}
StatementRank::assertIsValid( $rank );

$this->rank = $rank;
}
Expand Down
165 changes: 165 additions & 0 deletions src/Statement/StatementRank.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,165 @@
<?php

namespace Wikibase\DataModel\Statement;

use InvalidArgumentException;

/**
* Everything we know about statement's ranks and what they are supposed to mean.
*
* @see https://www.mediawiki.org/wiki/Wikibase/DataModel#Ranks_of_Statements
* @see https://meta.wikimedia.org/wiki/Wikidata/Data_model_update#Ranks_and_order
*
* @since 4.4
*
* @licence GNU GPL v2+
* @author Thiemo Mättig
*/
class StatementRank {

/**
* Higher values are more preferred.
* TODO: Link to discussion/documentation that guarantees increasing order.
*/
const DEPRECATED = 0;
const NORMAL = 1;
const PREFERRED = 2;

private static $names = array(
self::DEPRECATED => 'deprecated',
self::NORMAL => 'normal',
self::PREFERRED => 'preferred',
);

/**
* @return string[] Array mapping all known self::... constants (integers) to string names.
*/
public static function getNames() {
return self::$names;
}

/**
* @return int[] Array mapping string names to all known self::... constants (integers).
*/
public static function getAllRanks() {
return array_flip( self::$names );
}

/**
* @param int $rank
*
* @throws InvalidArgumentException
*/
public static function assertIsValid( $rank ) {
if ( !self::isValid( $rank ) ) {
throw new InvalidArgumentException( 'Invalid rank' );
}
}

/**
* @param int $rank
*
* @return bool
*/
public static function isValid( $rank ) {
return is_int( $rank ) && array_key_exists( $rank, self::$names );
}

/**
* @param int $rank
*
* @throws InvalidArgumentException
* @return bool Statements with a deprecated (or lower) rank are known to be false. But don't be
* fooled, this does not mean higher ranks are known to be true!
*/
public static function isFalse( $rank ) {
self::assertIsValid( $rank );

return $rank === self::DEPRECATED;
}

/**
* @param int|null $rank1
* @param int|null $rank2
*
* @throws InvalidArgumentException
* @return bool True if the given ranks are equal.
*/
public static function isEqual( $rank1, $rank2 ) {
return self::compare( $rank1, $rank2 ) === 0;
}

/**
* @param int|null $rank1
* @param int|null $rank2
*
* @throws InvalidArgumentException
* @return bool True if the first rank is less preferred than the second.
*/
public static function isLower( $rank1, $rank2 ) {
return self::compare( $rank1, $rank2 ) === -1;
}

/**
* @param int|null $rank1
* @param int|null $rank2
*
* @throws InvalidArgumentException
* @return bool True if the first rank is more preferred than the second.
*/
public static function isHigher( $rank1, $rank2 ) {
return self::compare( $rank1, $rank2 ) === 1;
}

/**
* @param int|null $rank1
* @param int|null $rank2
*
* @throws InvalidArgumentException
* @return int 0 if the ranks are equal, -1 if the first rank is less preferred than the second,
* or +1 if the first rank is more preferred than the second.
*/
public static function compare( $rank1, $rank2 ) {
if ( $rank1 !== null ) {
self::assertIsValid( $rank1 );
}
if ( $rank2 !== null ) {
self::assertIsValid( $rank2 );
}

if ( $rank1 === $rank2 ) {
return 0;
} elseif ( $rank1 === null || $rank1 < $rank2 ) {
return -1;
} else {
return 1;
}
}

/**
* @param int[]|int $ranks
* @param int [$rank2,...]
*
* @return int|null Best rank in the array or list of arguments, or null if none given.
*/
public static function findBestRank( $ranks = array() /*...*/ ) {
if ( !is_array( $ranks ) ) {
$ranks = func_get_args();
}

$best = null;

foreach ( $ranks as $rank ) {
if ( self::isHigher( $rank, $best ) ) {
$best = $rank;

if ( $best === self::PREFERRED ) {
break;
}
}
}

return $best;
}

}
Loading

0 comments on commit 1b9cf48

Please sign in to comment.