/** * @see ValueValidator::validate() * * @param mixed $value The value to validate * * @return Result */ public function validate($value) { $isValid = is_int($value) || is_float($value); if ($isValid) { return Result::newSuccess(); } return Result::newError(array(Error::newError('Bad type, expected an integer or float value', null, 'bad-type', array('number', gettype($value))))); }
/** * Validate an entity by applying each of the validators supplied to the constructor. * * @see EntityValidator::validateEntity * * @since 0.5 * * @param EntityDocument $entity * * @return Result */ public function validateEntity(EntityDocument $entity) { foreach ($this->validators as $validator) { $result = $validator->validateEntity($entity); if (!$result->isValid()) { return $result; } } return Result::newSuccess(); }
public function validEntityProvider() { $success = Result::newSuccess(); $failure = Result::newError(array(Error::newError('Foo!'))); $good = $this->getMock('Wikibase\\Repo\\Validators\\EntityValidator'); $good->expects($this->any())->method('validateEntity')->will($this->returnValue($success)); $bad = $this->getMock('Wikibase\\Repo\\Validators\\EntityValidator'); $bad->expects($this->any())->method('validateEntity')->will($this->returnValue($failure)); return array(array(array($good, $bad), false), array(array($bad, $good), false), array(array($good, $good), true), array(array(), true)); }
/** * Validate a fingerprint by applying each of the validators supplied to the constructor. * * @see FingerprintValidator::validateFingerprint * * @param Fingerprint $fingerprint * @param EntityId $entityId * @param string[]|null $languageCodes * * @return Result */ public function validateFingerprint(Fingerprint $fingerprint, EntityId $entityId, array $languageCodes = null) { foreach ($this->validators as $validator) { $result = $validator->validateFingerprint($fingerprint, $entityId, $languageCodes); if (!$result->isValid()) { return $result; } } return Result::newSuccess(); }
/** * @see ValueValidator::validate * * @param string $value The value to validate * * @return Result */ public function validate($value) { if ($this->normalizer !== null) { $value = call_user_func($this->normalizer, $value); } if (!in_array($value, $this->allowed, true)) { return Result::newError(array(Error::newError('Not a legal value: ' . $value, null, $this->errorCode, array($value)))); } return Result::newSuccess(); }
/** * @see ValueValidator::validate() * * @param int|float $value The numeric value to validate * * @return Result */ public function validate($value) { if ($value < $this->min) { // XXX: having to provide an array is quite inconvenient return Result::newError(array(Error::newError('Value out of range, the minimum value is ' . $this->min, null, 'too-low', array($this->min, $value)))); } if ($value > $this->max) { return Result::newError(array(Error::newError('Value out of range, the maximum value is ' . $this->max, null, 'too-high', array($this->max, $value)))); } return Result::newSuccess(); }
/** * @param string|DataValue $value * * @return Result */ public function validate($value) { if ($value instanceof DataValue) { $value = $value->getArrayValue(); } if (preg_match($this->regex, $value)) { return Result::newSuccess(); } else { return Result::newError(array(Error::newError("doesn't match " . $this->regex))); } }
/** * @see ValueValidator::validate() * * @param string $value The value to validate * * @return Result */ public function validate($value) { $length = call_user_func($this->measure, $value); if ($length < $this->minLength) { // XXX: having to provide an array is quite inconvenient return Result::newError(array(Error::newError('Too short, minimum length is ' . $this->minLength, null, 'too-short', array($this->minLength, $value)))); } if ($length > $this->maxLength) { return Result::newError(array(Error::newError('Too long, maximum length is ' . $this->maxLength, null, 'too-long', array($this->maxLength, $this->truncateValue($value))))); } return Result::newSuccess(); }
/** * @return LabelDescriptionDuplicateDetector */ private function getLabelDescriptionDuplicateDetector() { $detector = $this->getMockBuilder('Wikibase\\LabelDescriptionDuplicateDetector')->disableOriginalConstructor()->getMock(); $self = $this; $detector->expects($this->any())->method('detectLabelDescriptionConflicts')->will($this->returnCallback(function ($entityType, array $labels, array $descriptions, EntityId $ignoreEntityId = null) use($self) { $errors = array(); $errors = array_merge($errors, $self->detectDupes($labels)); $errors = array_merge($errors, $self->detectDupes($descriptions)); $result = empty($errors) ? Result::newSuccess() : Result::newError($errors); return $result; })); return $detector; }
/** * @see ValueValidator::validate() * * @param string $value The value to validate * * @return Result */ public function validate($value) { $match = preg_match($this->expression, $value); if ($match === 0 && !$this->inverse) { // XXX: having to provide an array is quite inconvenient return Result::newError(array(Error::newError('Pattern match failed: ' . $this->expression, null, $this->errorCode, array($value)))); } if ($match === 1 && $this->inverse) { // XXX: having to provide an array is quite inconvenient return Result::newError(array(Error::newError('Negative pattern matched: ' . $this->expression, null, $this->errorCode, array($value)))); } return Result::newSuccess(); }
/** * @see ValueValidator::validate() * * @param mixed $value The value to validate * * @return Result */ public function validate($value) { $type = gettype($value); if ($type === $this->type) { return Result::newSuccess(); } if (is_object($value)) { $type = get_class($value); if (is_a($value, $this->type)) { return Result::newSuccess(); } } return Result::newError(array(Error::newError('Bad type, expected ' . $this->type, null, 'bad-type', array($this->type, $type)))); }
/** * @see EntityValidator::validate() * * @param EntityDocument $entity * * @return Result */ public function validateEntity(EntityDocument $entity) { $errors = array(); if ($entity instanceof Item) { // TODO: do not use global state $db = wfGetDB(DB_MASTER); $conflicts = $this->siteLinkConflictLookup->getConflictsForItem($entity, $db); /* @var ItemId $ignoreConflictsWith */ foreach ($conflicts as $conflict) { $errors[] = $this->getConflictError($conflict); } } return empty($errors) ? Result::newSuccess() : Result::newError($errors); }
/** * @see ValueValidator::validate() * * @param mixed $value The value to validate * * @return Result */ public function validate($value) { $result = Result::newSuccess(); foreach ($this->validators as $validator) { $subResult = $validator->validate($value); if (!$subResult->isValid()) { if ($this->failFast) { return $subResult; } else { $result = Result::merge($result, $subResult); } } } return $result; }
/** * @see FingerprintValidator::validateFingerprint() * * @param Fingerprint $fingerprint * @param EntityId $entityId * @param string[]|null $languageCodes * * @return Result */ public function validateFingerprint(Fingerprint $fingerprint, EntityId $entityId, array $languageCodes = null) { $labels = $fingerprint->getLabels()->toTextArray(); $aliases = $fingerprint->getAliasGroups()->toTextArray(); if ($languageCodes !== null) { $languageKeys = array_flip($languageCodes); $labels = array_intersect_key($labels, $languageKeys); $aliases = array_intersect_key($aliases, $languageKeys); } // Nothing to do if there are no labels AND no aliases. if (empty($labels) && empty($aliases)) { return Result::newSuccess(); } return $this->duplicateDetector->detectLabelConflicts($entityId->getEntityType(), $labels, null, $entityId); }
/** * @see ValueValidator::validate() * * @param string $value The value to validate * * @return Result */ public function validate($value) { $result = Result::newSuccess(); try { $entityId = $this->idParser->parse($value); if ($this->forbiddenTypes === null || in_array($entityId->getEntityType(), $this->forbiddenTypes)) { // The label looks like a valid ID - we don't like that! $error = Error::newError('Looks like an Entity ID: ' . $value, null, $this->errorCode, array($value)); $result = Result::newError(array($error)); } } catch (EntityIdParsingException $parseException) { // All fine, the parsing did not work, so there is no entity id :) } return $result; }
/** * @see FingerprintValidator::validateFingerprint() * * @param Fingerprint $fingerprint * @param EntityId $entityId * @param string[]|null $languageCodes * * @return Result */ public function validateFingerprint(Fingerprint $fingerprint, EntityId $entityId, array $languageCodes = null) { $labels = $fingerprint->getLabels()->toTextArray(); $descriptions = $fingerprint->getDescriptions()->toTextArray(); if ($languageCodes !== null) { $languageKeys = array_flip($languageCodes); $labels = array_intersect_key($labels, $languageKeys); $descriptions = array_intersect_key($descriptions, $languageKeys); } // Nothing to do if there are no labels OR no descriptions, since // a conflict requires a label AND a description. if (empty($labels) || empty($descriptions)) { return Result::newSuccess(); } return $this->duplicateDetector->detectLabelDescriptionConflicts($entityId->getEntityType(), $labels, $descriptions, $entityId); }
/** * @see ValueValidator::validate() * * @param EntityIdValue|EntityId $value The ID to validate * * @return Result * @throws InvalidArgumentException */ public function validate($value) { if ($value instanceof EntityIdValue) { $value = $value->getEntityId(); } if (!$value instanceof EntityId) { throw new InvalidArgumentException("Expected an EntityId object"); } $actualType = $value->getEntityType(); $errors = array(); if ($this->entityType !== null && $actualType !== $this->entityType) { $errors[] = Error::newError("Wrong entity type: " . $actualType, null, 'bad-entity-type', array($actualType)); } if (!$this->entityLookup->hasEntity($value)) { $errors[] = Error::newError("Entity not found: " . $value, null, 'no-such-entity', array($value)); } return empty($errors) ? Result::newSuccess() : Result::newError($errors); }
protected function assertValidation($expected, array $validators, $value, $message) { $result = Result::newSuccess(); foreach ($validators as $validator) { $result = $validator->validate($value); if (!$result->isValid()) { break; } } if ($expected) { $errors = $result->getErrors(); if (!empty($errors)) { $this->fail($message . "\n" . $errors[0]->getText()); } $this->assertEquals($expected, $result->isValid(), $message); } else { $this->assertEquals($expected, $result->isValid(), $message); } }
protected function makeChangeOpsMerge(Item $fromItem, Item $toItem, array $ignoreConflicts = array(), $siteLookup = null) { if ($siteLookup === null) { $siteLookup = MockSiteStore::newFromTestSites(); } // A validator which makes sure that no site link is for page 'DUPE' $siteLinkUniquenessValidator = $this->getMock('Wikibase\\Repo\\Validators\\EntityValidator'); $siteLinkUniquenessValidator->expects($this->any())->method('validateEntity')->will($this->returnCallback(function (Item $item) { $siteLinks = $item->getSiteLinkList(); foreach ($siteLinks as $siteLink) { if ($siteLink->getPageName() === 'DUPE') { return Result::newError(array(Error::newError('SiteLink conflict'))); } } return Result::newSuccess(); })); $constraintProvider = $this->getMockBuilder('Wikibase\\Repo\\Validators\\EntityConstraintProvider')->disableOriginalConstructor()->getMock(); $constraintProvider->expects($this->any())->method('getUpdateValidators')->will($this->returnValue(array($siteLinkUniquenessValidator))); $changeOpFactoryProvider = new ChangeOpFactoryProvider($constraintProvider, $this->mockProvider->getMockGuidGenerator(), $this->mockProvider->getMockGuidValidator(), $this->mockProvider->getMockGuidParser($toItem->getId()), $this->mockProvider->getMockSnakValidator(), $this->mockProvider->getMockTermValidatorFactory(), $siteLookup); return new ChangeOpsMerge($fromItem, $toItem, $ignoreConflicts, $constraintProvider, $changeOpFactoryProvider, $siteLookup); }
/** * @see ChangeOp::validate() * * @since 0.5 * * @param Entity $entity * * @throws ChangeOpException * * @return Result */ public function validate(Entity $entity) { $result = Result::newSuccess(); // deep clone of $entity to avoid side-effects $entity = unserialize(serialize($entity)); foreach ($this->changeOps as $changeOp) { $result = $changeOp->validate($entity); if (!$result->isValid()) { // XXX: alternatively, we could collect all the errors. break; } $changeOp->apply($entity); } return $result; }
/** * Returns a duplicate detector that will, consider the string "DUPE" to be a duplicate, * unless a specific $returnValue is given. The same value is returned for calls to * detectLabelConflicts() and detectLabelDescriptionConflicts(). * * @param null|Result|Error[] $returnValue * * @return LabelDescriptionDuplicateDetector */ public function getMockLabelDescriptionDuplicateDetector($returnValue = null) { if (is_array($returnValue)) { if (empty($returnValue)) { $returnValue = Result::newSuccess(); } else { $returnValue = Result::newError($returnValue); } } if ($returnValue instanceof Result) { $detectLabelConflicts = $detectLabelDescriptionConflicts = function () use($returnValue) { return $returnValue; }; } else { $detectLabelConflicts = array($this, 'detectLabelConflicts'); $detectLabelDescriptionConflicts = array($this, 'detectLabelDescriptionConflicts'); } $dupeDetector = $this->getMockBuilder('Wikibase\\LabelDescriptionDuplicateDetector')->disableOriginalConstructor()->getMock(); $dupeDetector->expects(PHPUnit_Framework_TestCase::any())->method('detectLabelConflicts')->will(PHPUnit_Framework_TestCase::returnCallback($detectLabelConflicts)); $dupeDetector->expects(PHPUnit_Framework_TestCase::any())->method('detectLabelDescriptionConflicts')->will(PHPUnit_Framework_TestCase::returnCallback($detectLabelDescriptionConflicts)); return $dupeDetector; }
public function provideGetResultStatus() { return array(array(Result::newSuccess()), array(Result::newError(array())), array(Result::newError(array(Error::newError('Bla bla')))), array(Result::newError(array(Error::newError('Foo'), Error::newError('Bar'))))); }
/** * Validates the given data value using the given data type. * * @param DataValue $dataValue * @param string $dataTypeId * * @return Result */ public function validateDataValue(DataValue $dataValue, $dataTypeId) { $dataValueType = $this->dataTypeFactory->getType($dataTypeId)->getDataValueType(); if ($dataValue instanceof UnDeserializableValue) { $result = Result::newError(array(Error::newError('Bad snak value: ' . $dataValue->getReason(), null, 'bad-value', array($dataValue->getReason())))); } elseif ($dataValueType != $dataValue->getType()) { $result = Result::newError(array(Error::newError('Bad value type: ' . $dataValue->getType() . ', expected ' . $dataValueType, null, 'bad-value-type', array($dataValue->getType(), $dataValueType)))); } else { $result = Result::newSuccess(); } //XXX: DataTypeValidatorFactory should expose only one validator, which would be a CompositeValidator foreach ($this->validatorFactory->getValidators($dataTypeId) as $validator) { $subResult = $validator->validate($dataValue); //XXX: Some validators should be fatal and cause us to abort the loop. // Others shouldn't. if (!$subResult->isValid()) { //TODO: Don't bail out immediately. Accumulate errors from all validators. // We need Result::merge() for this. return $subResult; } } return $result; }
/** * @see ChangeOp::validate() * * This default implementation always returns Result::newSuccess(). * * @since 0.5 * * @param Entity $entity * * @throws ChangeOpException * * @return Result */ public function validate(Entity $entity) { return Result::newSuccess(); }
public function testValidate_() { $item = new Item(); $changeOp = $this->getMockBuilder('\\Wikibase\\ChangeOp\\ChangeOp')->disableOriginalConstructor()->getMock(); $changeOp->expects($this->any())->method('validate')->will($this->returnCallback(function (Item $item) { // Fail when the label is already set (by a previous apply call). return $item->getFingerprint()->hasLabel('en') ? Result::newError(array()) : Result::newSuccess(); })); $changeOp->expects($this->any())->method('apply')->will($this->returnCallback(function (Item $item) { $item->setLabel('en', 'Label'); })); $changeOps = new ChangeOps(); $changeOps->add($changeOp); $changeOps->add($changeOp); $result = $changeOps->validate($item); $this->assertFalse($result->isValid(), 'Validate must fail with this mock'); $this->assertTrue($item->isEmpty(), 'Item must still be empty'); }
/** * 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(); } }
/** * Apply the given validators. * * @param EntityValidator[] $validators * * @return Result */ private function applyValidators(array $validators) { $result = Result::newSuccess(); /* @var EntityValidator $validator */ foreach ($validators as $validator) { $result = $validator->validateEntity($this->getEntity()); if (!$result->isValid()) { break; } } /* @var EntityHandler $handler */ $handler = $this->getContentHandler(); $status = $handler->getValidationErrorLocalizer()->getResultStatus($result); return $status; }