| Current File : /home/jvzmxxx/wiki1/extensions/Wikibase/repo/includes/LabelDescriptionDuplicateDetector.php |
<?php
namespace Wikibase;
use InvalidArgumentException;
use ValueValidators\Result;
use Wikibase\DataModel\Entity\EntityId;
use Wikibase\Lib\Store\LabelConflictFinder;
use Wikibase\Repo\Validators\UniquenessViolation;
/**
* Detector of label/description uniqueness constraint violations.
* Builds on top of LabelConflictFinder adding handling of self-conflicts and localization.
*
* @see LabelConflictFinder
*
* @since 0.5
*
* @license GPL-2.0+
* @author Daniel Kinzler
*/
class LabelDescriptionDuplicateDetector {
/**
* @var LabelConflictFinder
*/
private $conflictFinder;
/**
* @param LabelConflictFinder $conflictFinder
*/
public function __construct( LabelConflictFinder $conflictFinder ) {
$this->conflictFinder = $conflictFinder;
}
/**
* Detects conflicting labels and aliases. A conflict arises when another entity has the same
* label or alias for a given language as is present in $label or $aliases. If $aliases is null,
* only conflicts between labels are considered. If $aliases is not null (but possibly empty),
* conflicts are also detected between labels and aliases, in any combination.
*
* @since 0.5
*
* @param string $entityType The type of entity to search for conflicts.
* @param string[] $labels An associative array of labels,
* with language codes as the keys.
* @param array[]|null $aliases Aliases to be considered to be conflicting with labels.
* Ignored if descriptions are given.
* @param EntityId|null $ignoreEntityId Conflicts with this entity will be
* considered self-conflicts and ignored.
*
* @throws InvalidArgumentException
* @return Result
*/
public function detectLabelConflicts(
$entityType,
array $labels,
array $aliases = null,
EntityId $ignoreEntityId = null
) {
if ( !is_string( $entityType ) ) {
throw new InvalidArgumentException( '$entityType must be a string' );
}
// Conflicts can only arise if labels OR aliases are given.
if ( empty( $labels ) && empty( $aliases ) ) {
return Result::newSuccess();
}
$conflictingTerms = $this->conflictFinder->getLabelConflicts(
$entityType,
$labels,
$aliases
);
if ( $ignoreEntityId ) {
$conflictingTerms = $this->filterSelfConflicts( $conflictingTerms, $ignoreEntityId );
}
if ( !empty( $conflictingTerms ) ) {
$errors = $this->termsToErrors( 'found conflicting terms', 'label-conflict', $conflictingTerms );
return Result::newError( $errors );
} else {
return Result::newSuccess();
}
}
/**
* Detects conflicting combinations of labels and descriptions. A conflict arises when an entity
* (other than the one given by $ignoreEntityId, if any) has the same combination of label and
* non-empty description for a given language as is present tin the $label and $description
* parameters.
*
* @since 0.5
*
* @param string $entityType The type of entity to search for conflicts.
* @param string[] $labels An associative array of labels,
* with language codes as the keys.
* @param string[] $descriptions An associative array of descriptions,
* with language codes as the keys.
* @param EntityId|null $ignoreEntityId Conflicts with this entity will be
* considered self-conflicts and ignored.
*
* @throws InvalidArgumentException
* @return Result
*/
public function detectLabelDescriptionConflicts(
$entityType,
array $labels,
array $descriptions,
EntityId $ignoreEntityId = null
) {
if ( !is_string( $entityType ) ) {
throw new InvalidArgumentException( '$entityType must be a string' );
}
// Conflicts can only arise if both a label AND a description is given.
if ( empty( $labels ) || empty( $descriptions ) ) {
return Result::newSuccess();
}
$conflictingTerms = $this->conflictFinder->getLabelWithDescriptionConflicts(
$entityType,
$labels,
$descriptions
);
if ( $ignoreEntityId ) {
$conflictingTerms = $this->filterSelfConflicts( $conflictingTerms, $ignoreEntityId );
}
if ( !empty( $conflictingTerms ) ) {
$errors = $this->termsToErrors( 'found conflicting terms', 'label-with-description-conflict', $conflictingTerms );
return Result::newError( $errors );
} else {
return Result::newSuccess();
}
}
/**
* @param string $message Plain text message (English)
* @param string $errorCode Error code (for later localization)
* @param TermIndexEntry[] $terms The conflicting terms.
*
* @return UniquenessViolation[]
*/
private function termsToErrors( $message, $errorCode, array $terms ) {
$errors = array();
foreach ( $terms as $term ) {
$errors[] = new UniquenessViolation(
$term->getEntityId(),
$message,
$errorCode,
array(
$term->getText(),
$term->getLanguage(),
$term->getEntityId(),
)
);
}
return $errors;
}
/**
* @param TermIndexEntry[] $terms
* @param EntityId $entityId
*
* @return TermIndexEntry[]
*/
private function filterSelfConflicts( array $terms, EntityId $entityId ) {
return array_filter(
$terms,
function ( TermIndexEntry $term ) use ( $entityId ) {
return !$entityId->equals( $term->getEntityId() );
}
);
}
}