diff --git a/composer.json b/composer.json index d7f3a3c..cad813c 100644 --- a/composer.json +++ b/composer.json @@ -41,7 +41,7 @@ }, "require" : { - "php" : ">=7.3.0", + "php" : ">=7.2.0", "doctrine/orm" : "~2.5", diff --git a/src/IPub/DoctrineCrud/Crud/Create/EntityCreator.php b/src/IPub/DoctrineCrud/Crud/Create/EntityCreator.php index f9f8ffd..8136cee 100644 --- a/src/IPub/DoctrineCrud/Crud/Create/EntityCreator.php +++ b/src/IPub/DoctrineCrud/Crud/Create/EntityCreator.php @@ -68,11 +68,23 @@ public function __construct( * * @return Entities\IEntity */ - public function create(Utils\ArrayHash $values, Entities\IEntity $entity = NULL) : Entities\IEntity + public function create(Utils\ArrayHash $values, Entities\IEntity $entity = null): Entities\IEntity { if (!$entity instanceof Entities\IEntity) { try { - $rc = new ReflectionClass($this->entityName); + // Entity name is overriden + if ($values->offsetExists('entity') && class_exists($values->offsetGet('entity'))) { + $entityClass = $values->offsetGet('entity'); + + } else { + $entityClass = $this->entityName; + } + + $rc = new ReflectionClass($entityClass); + + if ($rc->isAbstract()) { + throw new Exceptions\InvalidArgumentException(sprintf('Abstract entity "%s" can not be used.', $entityClass)); + } if ($constructor = $rc->getConstructor()) { $entity = $rc->newInstanceArgs(DoctrineCrud\Helpers::autowireArguments($constructor, (array) $values)); @@ -92,7 +104,7 @@ public function create(Utils\ArrayHash $values, Entities\IEntity $entity = NULL) $this->processHooks($this->beforeAction, [$entity, $values]); - $this->entityMapper->fillEntity($values, $entity, TRUE); + $this->entityMapper->fillEntity($values, $entity, true); $this->entityManager->persist($entity); diff --git a/src/IPub/DoctrineCrud/DI/DoctrineCrudExtension.php b/src/IPub/DoctrineCrud/DI/DoctrineCrudExtension.php index 8c1ff38..43b99b7 100644 --- a/src/IPub/DoctrineCrud/DI/DoctrineCrudExtension.php +++ b/src/IPub/DoctrineCrud/DI/DoctrineCrudExtension.php @@ -37,9 +37,6 @@ */ class DoctrineCrudExtension extends DI\CompilerExtension { - // Define tag string for validator - const TAG_VALIDATOR = 'ipub.doctrine.validator'; - /** * @return void * @@ -62,14 +59,9 @@ public function loadConfiguration() : void * Extensions helpers */ - $builder->addDefinition($this->prefix('entity.validator')) - ->setType(DoctrineCrud\Validation\ValidatorProxy::class) - ->setArguments([$annotationReader]) - ->setAutowired(FALSE); - $builder->addDefinition($this->prefix('entity.mapper')) ->setType(Mapping\EntityMapper::class) - ->setArguments(['@' . $this->prefix('entity.validator'), $annotationReader]) + ->setArguments([$annotationReader]) ->setAutowired(FALSE); /** @@ -119,14 +111,6 @@ public function beforeCompile() : void // Get container builder $builder = $this->getContainerBuilder(); - // Get validators service - $validator = $builder->getDefinition($this->prefix('entity.validator')); - - foreach (array_keys($builder->findByTag(self::TAG_VALIDATOR)) as $serviceName) { - // Register validator to proxy validator - $validator->addSetup('registerValidator', ['@' . $serviceName, $serviceName]); - } - $builder->getDefinition($builder->getByType(Doctrine\ORM\EntityManagerInterface::class, TRUE)) ->addSetup( '?->getConfiguration()->addCustomStringFunction(?, ?)', diff --git a/src/IPub/DoctrineCrud/Entities/IEntity.php b/src/IPub/DoctrineCrud/Entities/IEntity.php index 5714d53..cf61d99 100644 --- a/src/IPub/DoctrineCrud/Entities/IEntity.php +++ b/src/IPub/DoctrineCrud/Entities/IEntity.php @@ -26,20 +26,5 @@ */ interface IEntity { - /** - * @param int $maxLevel - * - * @return array - */ - public function toArray(int $maxLevel = 1) : array; - /** - * @return array - */ - public function toSimpleArray() : array; - - /** - * @return string - */ - public function __toString(); } diff --git a/src/IPub/DoctrineCrud/Entities/TEntity.php b/src/IPub/DoctrineCrud/Entities/TEntity.php deleted file mode 100644 index e0be60d..0000000 --- a/src/IPub/DoctrineCrud/Entities/TEntity.php +++ /dev/null @@ -1,101 +0,0 @@ - - * @package iPublikuj:DoctrineCrud! - * @subpackage Entities - * @since 1.0.0 - * - * @date 29.01.14 - */ - -declare(strict_types = 1); - -namespace IPub\DoctrineCrud\Entities; - -use ReflectionException; - -use Doctrine\Common; - -use IPub\DoctrineCrud\Mapping; - -/** - * Doctrine CRUD identified entity helper trait - * - * @package iPublikuj:DoctrineCrud! - * @subpackage Entities - * - * @author Adam Kadlec - * - * @ORM\MappedSuperclass - */ -trait TEntity -{ - /** - * @var Mapping\EntityHydrator - */ - protected $hydrator; - - /** - * @return string - */ - public static function getClassName() : string - { - return get_called_class(); - } - - /** - * @param int $maxLevel - * - * @return mixed[] - * - * @throws Common\Annotations\AnnotationException - * @throws ReflectionException - */ - public function toArray(int $maxLevel = 1) : array - { - return $this->getHydrator()->extract($this, $maxLevel, 1); - } - - /** - * @return mixed[] - * - * @throws Common\Annotations\AnnotationException - * @throws ReflectionException - */ - public function toSimpleArray() : array - { - return $this->getHydrator()->simpleExtract($this); - } - - /** - * @return string - */ - public function __toString() - { - if (isset($this->name) && $this->name !== NULL) { - return (string) $this->name; - - } elseif (property_exists($this, 'id')) { - return (string) $this->id; - - } else { - return ''; - } - } - - /** - * @return Mapping\EntityHydrator - */ - protected function getHydrator() : Mapping\EntityHydrator - { - if ($this->hydrator === NULL) { - $this->hydrator = new Mapping\EntityHydrator; - } - - return $this->hydrator; - } -} diff --git a/src/IPub/DoctrineCrud/Mapping/Annotation/Crud.php b/src/IPub/DoctrineCrud/Mapping/Annotation/Crud.php index 0b2ab39..c29aba2 100644 --- a/src/IPub/DoctrineCrud/Mapping/Annotation/Crud.php +++ b/src/IPub/DoctrineCrud/Mapping/Annotation/Crud.php @@ -38,11 +38,6 @@ final class Crud extends Annotation */ public $is; - /** - * @var string|array - */ - public $validator; - /** * @return bool */ diff --git a/src/IPub/DoctrineCrud/Mapping/EntityHydrator.php b/src/IPub/DoctrineCrud/Mapping/EntityHydrator.php deleted file mode 100644 index e4628d4..0000000 --- a/src/IPub/DoctrineCrud/Mapping/EntityHydrator.php +++ /dev/null @@ -1,239 +0,0 @@ - - * @package iPublikuj:DoctrineCrud! - * @subpackage Mapping - * @since 1.0.0 - * - * @date 29.01.14 - */ - -namespace IPub\DoctrineCrud\Mapping; - -use ReflectionClass; -use ReflectionProperty; -use ReflectionException; - -use Doctrine\Common; -use Doctrine\ORM; - -use Nette; - -use IPub\DoctrineCrud; -use IPub\DoctrineCrud\Entities; - -/** - * Doctrine CRUD entity hydrator - * - * @package iPublikuj:DoctrineCrud! - * @subpackage Mapping - * - * @author Adam Kadlec - */ -final class EntityHydrator implements IEntityHydrator -{ - /** - * Implement nette smart magic - */ - use Nette\SmartObject; - - /** - * Property needs to have at least one of these annotations to be serialized - * - * @var array - */ - public static $mappedPropertyAnnotations = [ - ORM\Mapping\Column::class, - ORM\Mapping\OneToMany::class, - ORM\Mapping\OneToOne::class, - ORM\Mapping\ManyToOne::class, - ORM\Mapping\ManyToMany::class, - ]; - - /** - * {@inheritdoc} - */ - public function hydrate($values, Entities\IEntity $entity) : Entities\IEntity - { - if (count($values)) { - foreach ($values as $name => $value) { - $method = 'set' . ucfirst($name); - - if (method_exists($entity, $method)) { - call_user_func_array([$entity, $method], [$value]); - } - } - } - - return $entity; - } - - /** - * {@inheritdoc} - * - * @throws Common\Annotations\AnnotationException - * @throws ReflectionException - */ - public function extract(Entities\IEntity $entity, int $maxLevel = 1, int $level = 1) : array - { - $values = []; - - $properties = $this->getEntityProperties($entity); - $reader = $this->getDefaultAnnotationReader(); - - foreach ($properties as $property) { - if (!$property->isStatic()) { - $propertyAnnotations = $reader->getPropertyAnnotations($property); - - foreach ($propertyAnnotations as $propertyAnnotation) { - if (in_array(get_class($propertyAnnotation), self::$mappedPropertyAnnotations, TRUE)) { - $method = 'get' . ucfirst($property->getName()); - - if (method_exists($entity, $method)) { - $value = call_user_func([$entity, $method]); - $values[$property->getName()] = $this->extractor($value, $maxLevel, $level); - } - - continue; - } - } - } - } - - return $values; - } - - /** - * {@inheritdoc} - * - * @throws Common\Annotations\AnnotationException - * @throws ReflectionException - */ - public function simpleExtract(Entities\IEntity $entity) : array - { - $values = []; - - $properties = $this->getEntityProperties($entity); - $reader = $this->getDefaultAnnotationReader(); - - foreach ($properties as $property) { - if (!$property->isStatic()) { - $propertyAnnotations = $reader->getPropertyAnnotations($property); - - foreach ($propertyAnnotations as $propertyAnnotation) { - if (in_array(get_class($propertyAnnotation), self::$mappedPropertyAnnotations, TRUE)) { - $method = 'get' . ucfirst($property->getName()); - - if (method_exists($entity, $method)) { - $value = call_user_func([$entity, $method]); - $values[$property->getName()] = $this->simpleExtractor($value); - } - - continue; - } - } - } - } - - return $values; - } - - /** - * @param mixed $value - * @param int $maxLevel - * @param int $level - * - * @return mixed|mixed[] - * - * @throws Common\Annotations\AnnotationException - * @throws ReflectionException - */ - private function extractor($value, int $maxLevel = 1, int $level = 1) - { - if ($value instanceof Entities\IEntity) { - if ($level < $maxLevel) { - $level++; - - $value = $this->extract($value, $maxLevel, $level); - } - - } else { - if ($value instanceof Common\Collections\Collection) { - $value = array_map(function ($entity) use ($maxLevel, $level) { - if ($entity instanceof Entities\IEntity && $level < $maxLevel) { - $level++; - - $entity = $this->extract($entity, $maxLevel, $level); - } - - return $entity; - }, $value->toArray()); - } - } - - return $value; - } - - /** - * @param $value - * - * @return mixed|mixed[] - */ - private function simpleExtractor($value) - { - if ($value instanceof DoctrineCrud\Entities\IIdentifiedEntity) { - $value = $value->getId(); - - } else { - if ($value instanceof Common\Collections\Collection) { - $value = array_map(function ($entity) { - if ($entity instanceof DoctrineCrud\Entities\IIdentifiedEntity) { - $entity = $entity->getId(); - } - - return $entity; - }, $value->toArray()); - } - } - - return $value; - } - - /** - * @param Entities\IEntity $entity - * - * @return ReflectionProperty[] - * - * @throws ReflectionException - */ - private function getEntityProperties(Entities\IEntity $entity) : array - { - $entityReflection = new ReflectionClass(get_class($entity)); - - return $entityReflection->getProperties(); - } - - /** - * Create default annotation reader for extensions - * - * @return Common\Annotations\CachedReader - * - * @throws Common\Annotations\AnnotationException - */ - private function getDefaultAnnotationReader() : Common\Annotations\CachedReader - { - $reader = new Common\Annotations\AnnotationReader; - - Common\Annotations\AnnotationRegistry::registerAutoloadNamespace( - 'IPub\\Doctrine\\Entities\\IEntity' - ); - - $reader = new Common\Annotations\CachedReader($reader, new Common\Cache\ArrayCache); - - return $reader; - } -} diff --git a/src/IPub/DoctrineCrud/Mapping/EntityMapper.php b/src/IPub/DoctrineCrud/Mapping/EntityMapper.php index 2d2beab..0aa13ba 100644 --- a/src/IPub/DoctrineCrud/Mapping/EntityMapper.php +++ b/src/IPub/DoctrineCrud/Mapping/EntityMapper.php @@ -34,7 +34,6 @@ use IPub\DoctrineCrud\Exceptions; use IPub\DoctrineCrud\Helpers; use IPub\DoctrineCrud\Mapping; -use IPub\DoctrineCrud\Validation; /** * Doctrine CRUD entity mapper @@ -51,11 +50,6 @@ final class EntityMapper implements IEntityMapper */ use Nette\SmartObject; - /** - * @var Validation\ValidatorProxy|Validation\IValidator - */ - private $validators; - /** * @var Common\Persistence\ManagerRegistry */ @@ -67,16 +61,13 @@ final class EntityMapper implements IEntityMapper private $annotationReader; /** - * @param Validation\IValidator $validators * @param Common\Annotations\Reader $annotationReader * @param Common\Persistence\ManagerRegistry $managerRegistry */ public function __construct( - Validation\IValidator $validators, Common\Annotations\Reader $annotationReader, Common\Persistence\ManagerRegistry $managerRegistry ) { - $this->validators = $validators; $this->annotationReader = $annotationReader; $this->managerRegistry = $managerRegistry; } @@ -354,10 +345,6 @@ private function setFieldValue(ORM\Mapping\ClassMetadata $classMetadata, Entitie try { $propertyReflection = new ReflectionMethod(get_class($entity), $methodName); - //if (!$this->validators->validate($value, $propertyReflection)) { - // // Validation fail - //} - if ($propertyReflection->isPublic()) { // Try to call entity setter call_user_func_array([$entity, $methodName], [$value]); diff --git a/src/IPub/DoctrineCrud/Mapping/IEntityHydrator.php b/src/IPub/DoctrineCrud/Mapping/IEntityHydrator.php deleted file mode 100644 index ddb29c0..0000000 --- a/src/IPub/DoctrineCrud/Mapping/IEntityHydrator.php +++ /dev/null @@ -1,52 +0,0 @@ - - * @package iPublikuj:DoctrineCrud! - * @subpackage Mapping - * @since 1.0.0 - * - * @date 29.01.14 - */ - -namespace IPub\DoctrineCrud\Mapping; - -use IPub\DoctrineCrud\Entities; - -/** - * Doctrine CRUD entity hydrator interface - * - * @package iPublikuj:DoctrineCrud! - * @subpackage Mapping - * - * @author Adam Kadlec - */ -interface IEntityHydrator -{ - /** - * @param mixed $values - * @param Entities\IEntity $entity - * - * @return Entities\IEntity - */ - public function hydrate($values, Entities\IEntity $entity) : Entities\IEntity; - - /** - * @param Entities\IEntity $entity - * @param int $maxLevel - * @param int $level - * - * @return array - */ - public function extract(Entities\IEntity $entity, int $maxLevel = 1, int $level = 1) : array; - - /** - * @param Entities\IEntity $entity - * - * @return array - */ - public function simpleExtract(Entities\IEntity $entity) : array; -} diff --git a/src/IPub/DoctrineCrud/Mapping/IEntityMapper.php b/src/IPub/DoctrineCrud/Mapping/IEntityMapper.php index daebd89..7893b4b 100644 --- a/src/IPub/DoctrineCrud/Mapping/IEntityMapper.php +++ b/src/IPub/DoctrineCrud/Mapping/IEntityMapper.php @@ -35,7 +35,6 @@ interface IEntityMapper */ public const ANNOTATION_REQUIRED = 'required'; public const ANNOTATION_WRITABLE = 'writable'; - public const ANNOTATION_VALIDATOR = 'validator'; /** * @param Utils\ArrayHash $values diff --git a/src/IPub/DoctrineCrud/Validation/IValidator.php b/src/IPub/DoctrineCrud/Validation/IValidator.php deleted file mode 100644 index f44348c..0000000 --- a/src/IPub/DoctrineCrud/Validation/IValidator.php +++ /dev/null @@ -1,35 +0,0 @@ - - * @package iPublikuj:DoctrineCrud! - * @subpackage Validation - * @since 1.0.0 - * - * @date 29.01.14 - */ - -declare(strict_types = 1); - -namespace IPub\DoctrineCrud\Validation; - -/** - * Doctrine CRUD validator interface - * - * @package iPublikuj:DoctrineCrud! - * @subpackage Validation - * - * @author Adam Kadlec - */ -interface IValidator -{ - /** - * @param mixed $data - * - * @return bool - */ - public function validate($data) : bool; -} diff --git a/src/IPub/DoctrineCrud/Validation/ValidatorProxy.php b/src/IPub/DoctrineCrud/Validation/ValidatorProxy.php deleted file mode 100644 index 9a65deb..0000000 --- a/src/IPub/DoctrineCrud/Validation/ValidatorProxy.php +++ /dev/null @@ -1,89 +0,0 @@ - - * @package iPublikuj:DoctrineCrud! - * @subpackage common - * @since 1.0.0 - * - * @date 06.12.15 - */ - -declare(strict_types = 1); - -namespace IPub\DoctrineCrud\Validation; - -use Doctrine\Common; - -use Nette; - -use IPub\DoctrineCrud\Mapping; - -/** - * Doctrine CRUD validators container - * - * @package iPublikuj:DoctrineCrud! - * @subpackage common - * - * @author Adam Kadlec - */ -final class ValidatorProxy implements IValidator -{ - /** - * Implement nette smart magic - */ - use Nette\SmartObject; - - /** - * @var IValidator[] - */ - private $validators = []; - - /** - * @var Common\Annotations\CachedReader - */ - private $annotationReader; - - /** - * @param Common\Annotations\Reader $annotationReader - */ - public function __construct(Common\Annotations\Reader $annotationReader) - { - $this->annotationReader = $annotationReader; - } - - /** - * {@inheritdoc} - */ - public function validate($data) : bool - { - list($data, $field) = func_get_args() + [NULL, NULL]; - - $crud = $this->annotationReader->getPropertyAnnotation($field, Mapping\Annotation\Crud::class); - - $validators = is_array($crud->validator) ? $crud->validator : [$crud->validator]; - - $result = TRUE; - - foreach ($validators as $validator) { - if ($result && isset($this->validators[$validator])) { - $result = $this->validators[$validator]->validate($data); - } - } - - return $result; - } - - /** - * @param IValidator $validator - * - * @return void - */ - public function registerValidator(IValidator $validator) : void - { - $this->validators[get_class($validator)] = $validator; - } -} diff --git a/tests/IPubTests/DoctrineCrud/CRUDTest.phpt b/tests/IPubTests/DoctrineCrud/CRUDTest.phpt index ff49276..63e10aa 100644 --- a/tests/IPubTests/DoctrineCrud/CRUDTest.phpt +++ b/tests/IPubTests/DoctrineCrud/CRUDTest.phpt @@ -172,66 +172,6 @@ class CRUDTest extends Tester\TestCase Assert::null($entity); } - public function testEntityTraits() : void - { - $this->generateDbSchema(); - - $user = new Models\UserEntity; - $user->setUsername('tester'); - $user->setName('Tester'); - $user->setNotWritable('White side'); - - $this->em->persist($user); - $this->em->flush(); - - $article = new Models\ArticleEntity(); - $article->setTitle('Testing article'); - $article->setOwner($user); - - $this->em->persist($article); - $this->em->flush(); - - Assert::same((string) $user->getName(), (string) $user, 'UserEntity toString'); - Assert::same('', (string) $article, 'ArticleEntity toString'); - - Assert::same([ - 'id' => $user->getId(), - 'username' => 'tester', - 'name' => 'Tester', - 'notWritable' => 'White side', - 'createdAt' => NULL, - 'updatedAt' => NULL, - ], $user->toArray(), 'UserEntity - toArray()'); - Assert::same([ - 'id' => $user->getId(), - 'username' => 'tester', - 'name' => 'Tester', - 'notWritable' => 'White side', - 'createdAt' => NULL, - 'updatedAt' => NULL, - ], $user->toSimpleArray(), 'UserEntity - toSimpleArray()'); - - Assert::same([ - 'title' => 'Testing article', - 'owner' => $user, - ], $article->toArray(), 'ArticleEntity - toArray()'); - Assert::same([ - 'title' => 'Testing article', - 'owner' => [ - 'id' => $user->getId(), - 'username' => 'tester', - 'name' => 'Tester', - 'notWritable' => 'White side', - 'createdAt' => NULL, - 'updatedAt' => NULL, - ], - ], $article->toArray(2), 'ArticleEntity - toArray(2)'); - Assert::same([ - 'title' => 'Testing article', - 'owner' => $user->getId(), - ], $article->toSimpleArray(), 'ArticleEntity - toSimpleArray()'); - } - /** * @return void */ diff --git a/tests/IPubTests/DoctrineCrud/models/ArticleEntity.php b/tests/IPubTests/DoctrineCrud/models/ArticleEntity.php index 92c1a51..25108e9 100644 --- a/tests/IPubTests/DoctrineCrud/models/ArticleEntity.php +++ b/tests/IPubTests/DoctrineCrud/models/ArticleEntity.php @@ -27,8 +27,6 @@ */ class ArticleEntity implements Entities\IEntity { - use Entities\TEntity; - /** * @var int * diff --git a/tests/IPubTests/DoctrineCrud/models/UserEntity.php b/tests/IPubTests/DoctrineCrud/models/UserEntity.php index f58f730..a47f935 100644 --- a/tests/IPubTests/DoctrineCrud/models/UserEntity.php +++ b/tests/IPubTests/DoctrineCrud/models/UserEntity.php @@ -28,7 +28,6 @@ */ class UserEntity implements Entities\IIdentifiedEntity { - use Entities\TEntity; use Entities\TIdentifiedEntity; /**