Skip to content

Instantly share code, notes, and snippets.

@RafaelKa
Last active December 11, 2015 07:19
Show Gist options
  • Save RafaelKa/4565540 to your computer and use it in GitHub Desktop.
Save RafaelKa/4565540 to your computer and use it in GitHub Desktop.
only isTrustedProperty() method to implement
<?php
namespace TYPO3\Flow\Validation\Validator;
/* *
* This script belongs to the TYPO3 Flow framework. *
* *
* It is free software; you can redistribute it and/or modify it under *
* the terms of the GNU Lesser General Public License, either version 3 *
* of the License, or (at your option) any later version. *
* *
* The TYPO3 project - inspiring people to share! *
* */
use TYPO3\Flow\Annotations as Flow,
TYPO3\Flow\Reflection\ObjectAccess,
TYPO3\Flow\Validation\Exception\InvalidValidationOptionsException;
/**
* Validator for unique entity object.
*
* @api
* @Flow\Scope("singleton")
*/
class UniqueEntityValidator extends AbstractValidator {
/**
* @Flow\Inject
* @var \TYPO3\Flow\Reflection\ReflectionService
*/
protected $reflectionService;
/**
* @Flow\Inject
* @var \TYPO3\Flow\Persistence\PersistenceManagerInterface
*/
protected $persistenceManager;
/**
* @var object
*/
protected $object;
/**
* @var object
*/
protected $persistedObject;
/**
* @var \TYPO3\Flow\Reflection\ClassSchema
*/
protected $objectsClassSchema;
/**
* @var string
*/
protected $objectIdentifierPropertyName = 'Persistence_Object_Identifier';
/**
* Checks if the given property ($object) is unique entity according to it's identity properties.
*
* @param object $object The object that should be validated
* @return void
*/
protected function isValid($object) {
$this->object = $object;
$this->objectsClassSchema = $this->reflectionService->getClassSchema($object);
if ($this->objectsClassSchema->getModelType() !== \TYPO3\Flow\Reflection\ClassSchema::MODELTYPE_ENTITY) {
throw new InvalidValidationOptionsException('The object supplied for the UniqueEntityValidator must be an entity.', 1358454270);
}
$identityProperties = $this->objectsClassSchema->getIdentityProperties();
if (count($identityProperties) === 0) {
throw new InvalidValidationOptionsException('The object supplied for the UniqueEntityValidator must have at least one identity property.', 1358459831);
}
$this->setCustomPersistence_Object_IdentifierIfNeedet();
$query = $this->persistenceManager->createQueryForType($this->objectsClassSchema->getClassName());
$constraints = array();
if ($this->isPersistedObject()) {
foreach ($identityProperties as $propertyName => $type) {
$propertyValue = ObjectAccess::getProperty($object, $propertyName);
if ((empty($propertyValue) && !$this->isNullableIdentityProperty($propertyName))
|| (empty($propertyValue) && !$this->isTrustedProperty($propertyName))) {
ObjectAccess::setProperty($object, $propertyName, ObjectAccess::getProperty($this->persistedObject, $propertyName));
}
}
$constraints[] = $query->logicalNot($query->equals($this->objectIdentifierPropertyName, $this->persistenceManager->getIdentifierByObject($object)));
}
foreach ($identityProperties as $propertyName => $type) {
$constraints[] = $query->equals($propertyName, ObjectAccess::getProperty($object, $propertyName));
}
if ($query->matching($query->logicalAnd($constraints))->count() > 0) {
$this->addError('An object with the same unique identifiers already exists', 1355785874);
}
}
/**
* Sets persisted object if this is present in repository.
*
* @return boolean TRUE if the same object is present in repository, if not FALSE
*/
private function isPersistedObject() {
$persistedObjectQuery = $this->persistenceManager->createQueryForType($this->objectsClassSchema->getClassName());
$result = $persistedObjectQuery->matching($persistedObjectQuery->equals($this->objectIdentifierPropertyName, $this->persistenceManager->getIdentifierByObject($this->object)))->execute();
if ($result->count() === 1) {
$this->persistedObject = $result->getFirst();
return TRUE;
}
return FALSE;
}
/**
* Sets objectIdentifierPropertyName properly.
*
* @return void
*/
private function setCustomPersistence_Object_IdentifierIfNeedet() {
$objectIdentifierPropertyNames = $this->reflectionService->getPropertyNamesByAnnotation($this->objectsClassSchema->getClassName(), 'Doctrine\ORM\Mapping\Id');
if (count($objectIdentifierPropertyNames) > 1) {
throw new InvalidValidationOptionsException('The object supplied for the UniqueEntityValidator must have only one Identifier Property @ORM\Id.', 1358501745);
}
if (!empty($objectIdentifierPropertyNames)) {
$this->objectIdentifierPropertyName = reset($objectIdentifierPropertyNames);
}
}
/**
*
* @param string $propertyName Description
* @return boolean TRUE if the same object is present in repository, if not FALSE
*/
private function isNullableIdentityProperty($propertyName) {
$propertyAnnotations = $this->reflectionService->getPropertyAnnotations($this->objectsClassSchema->getClassName(), $propertyName);
if(isset($propertyAnnotations['Doctrine\ORM\Mapping\Column'])) {
$columnAnnotationsObject = $propertyAnnotations['Doctrine\ORM\Mapping\Column'];
return ObjectAccess::getProperty($columnAnnotationsObject, 'nullable');
}
return FALSE;
}
/**
* is for content security part
*
* @param string $propertyName
* @return boolean
*/
private function isTrustedProperty($propertyName) {
/**
* @todo check if property is allowed
*/
return FALSE;
}
}
?>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment