From 48e33bf1cced7a66b53eb6f2983db938ea0bab41 Mon Sep 17 00:00:00 2001 From: Jonathan Schmid Date: Tue, 1 Dec 2015 02:51:07 +0000 Subject: [PATCH 1/3] Separate metadata class --- Doctrine/Driver/MogrifyDriver.php | 38 +++++++++++++ Doctrine/Mapping/Mogrify.php | 8 ++- Doctrine/Metadata/MogrifyMetadata.php | 11 ++++ Listener/MogrifySubscriber.php | 77 +++++++-------------------- Resources/config/services.yml | 14 ++++- 5 files changed, 87 insertions(+), 61 deletions(-) create mode 100644 Doctrine/Driver/MogrifyDriver.php create mode 100644 Doctrine/Metadata/MogrifyMetadata.php diff --git a/Doctrine/Driver/MogrifyDriver.php b/Doctrine/Driver/MogrifyDriver.php new file mode 100644 index 0000000..01382eb --- /dev/null +++ b/Doctrine/Driver/MogrifyDriver.php @@ -0,0 +1,38 @@ +reader = $reader; + } + + public function loadMetadataForClass(\ReflectionClass $class) + { + $classMetadata = new MergeableClassMetadata($class->getName()); + + foreach ($class->getProperties() as $property) { + $field = $this->reader->getPropertyAnnotation($property, self::MOGRIFY); + + if(!is_null($field)) { + $propertyMetadata = new MogrifyMetadata($class->getName(), $property->getName()); + $propertyMetadata->params = $field->params; + + $classMetadata->addPropertyMetadata($propertyMetadata); + } + } + + return $classMetadata; + } +} diff --git a/Doctrine/Mapping/Mogrify.php b/Doctrine/Mapping/Mogrify.php index 6611506..588d577 100644 --- a/Doctrine/Mapping/Mogrify.php +++ b/Doctrine/Mapping/Mogrify.php @@ -17,10 +17,16 @@ * Annotation definition class * * @Annotation + * @Annotation\Target("PROPERTY") * @codeCoverageIgnore */ class Mogrify extends Annotation { - /** @var array */ + /** + * Identfier of a pre-configured format or key-value pairs of IM parameters + * + * @Required + * @var string|array + */ public $params; } diff --git a/Doctrine/Metadata/MogrifyMetadata.php b/Doctrine/Metadata/MogrifyMetadata.php new file mode 100644 index 0000000..0966e03 --- /dev/null +++ b/Doctrine/Metadata/MogrifyMetadata.php @@ -0,0 +1,11 @@ + */ + public $params; +} diff --git a/Listener/MogrifySubscriber.php b/Listener/MogrifySubscriber.php index 7f8b838..1481687 100644 --- a/Listener/MogrifySubscriber.php +++ b/Listener/MogrifySubscriber.php @@ -19,6 +19,7 @@ use Doctrine\ORM\Event\PreFlushEventArgs; use Snowcap\ImBundle\Manager as ImManager; +use Metadata\MetadataFactoryInterface; /** * Event listener for Doctrine entities to evualuate and execute ImBundle annotations @@ -32,18 +33,25 @@ class MogrifySubscriber implements EventSubscriber */ private $rootDir; + /** + * @var \Metadata\MetadataFactoryInterface + */ + private $metadataFactory; + /** * @var \Snowcap\ImBundle\Manager */ private $imManager; /** - * @param string $rootDir The dir to generate files - * @param ImManager $imManager The ImBundle mamager instance + * @param string $rootDir The dir to generate files + * @param MetadataFactoryInterface $metadataFactory + * @param ImManager $imManager The ImBundle manager instance */ - public function __construct($rootDir, ImManager $imManager) + public function __construct($rootDir, MetadataFactoryInterface $metadataFactory, ImManager $imManager) { $this->rootDir = $rootDir; + $this->metadataFactory = $metadataFactory; $this->imManager = $imManager; } @@ -54,35 +62,7 @@ public function __construct($rootDir, ImManager $imManager) */ public function getSubscribedEvents() { - return array('loadClassMetadata', 'prePersist', 'preFlush'); - } - - /** - * @param LoadClassMetadataEventArgs $eventArgs - */ - public function loadClassMetadata(LoadClassMetadataEventArgs $eventArgs) - { - $reader = new AnnotationReader(); - $meta = $eventArgs->getClassMetadata(); - $reflexionClass = $meta->getReflectionClass(); - if (null !== $reflexionClass) { - foreach ($reflexionClass->getProperties() as $property) { - if ($meta->isMappedSuperclass && !$property->isPrivate() || - $meta->isInheritedField($property->name) || - isset($meta->associationMappings[$property->name]['inherited']) - ) { - continue; - } - /** @var $annotation \Snowcap\ImBundle\Doctrine\Mapping\Mogrify */ - if ($annotation = $reader->getPropertyAnnotation($property, 'Snowcap\\ImBundle\\Doctrine\\Mapping\\Mogrify')) { - $field = $property->getName(); - $this->config[$meta->getTableName()]['fields'][$field] = array( - 'property' => $property, - 'params' => $annotation->params, - ); - } - } - } + return array('prePersist', 'preFlush'); } /** @@ -90,14 +70,12 @@ public function loadClassMetadata(LoadClassMetadataEventArgs $eventArgs) */ public function preFlush(PreFlushEventArgs $ea) { - $entityManager = $ea->getEntityManager(); - - $unitOfWork = $entityManager->getUnitOfWork(); - + $unitOfWork = $ea->getEntityManager()->getUnitOfWork(); $entityMaps = $unitOfWork->getIdentityMap(); + foreach ($entityMaps as $entities) { foreach ($entities as $entity) { - foreach ($this->getFiles($entity, $ea->getEntityManager()) as $file) { + foreach ($this->metadataFactory->getMetadataForClass(get_class($entity))->propertyMetadata as $file) { $this->mogrify($entity, $file); } } @@ -110,43 +88,26 @@ public function preFlush(PreFlushEventArgs $ea) public function prePersist(LifecycleEventArgs $ea) { $entity = $ea->getEntity(); - foreach ($this->getFiles($entity, $ea->getEntityManager()) as $file) { + foreach ($this->metadataFactory->getMetadataForClass(get_class($entity))->propertyMetadata as $file) { $this->mogrify($entity, $file); } } - /** - * @param $entity - * @param EntityManager $entityManager - * @return array - */ - private function getFiles($entity, EntityManager $entityManager) - { - $classMetaData = $entityManager->getClassMetaData(get_class($entity)); - $tableName = $classMetaData->getTableName(); - - if (array_key_exists($tableName, $this->config)) { - return $this->config[$tableName]['fields']; - } else { - return array(); - } - } - /** * @param $entity * @param $file */ private function mogrify($entity, $file) { - $propertyName = $file['property']->name; + $propertyName = $file->name; $getter = 'get' . ucFirst($propertyName); if (method_exists($entity, $getter)) { /** @var $uploadedFile \Symfony\Component\HttpFoundation\File\UploadedFile */ $uploadedFile = $entity->$getter(); if (null !== $uploadedFile) { - $this->imManager->mogrify($file['params'], $uploadedFile->getPathName()); + $this->imManager->mogrify($file->params, $uploadedFile->getPathName()); } } } -} \ No newline at end of file +} diff --git a/Resources/config/services.yml b/Resources/config/services.yml index f63a46e..9d994af 100644 --- a/Resources/config/services.yml +++ b/Resources/config/services.yml @@ -16,11 +16,21 @@ services: tags: - { name: twig.extension } + snowcap_im.metadata.mogrify_driver: + class: Snowcap\ImBundle\Doctrine\Driver\MogrifyDriver + public: false + arguments: [@annotation_reader] + + snowcap_im.metadata.mogrify_factory: + class: Metadata\MetadataFactory + public: false + arguments: [@snowcap_im.metadata.mogrify_driver] + snowcap_im.mogrify_subscriber: class: Snowcap\ImBundle\Listener\MogrifySubscriber - arguments: [%kernel.root_dir%, @snowcap_im.manager] + arguments: [%kernel.root_dir%, @snowcap_im.metadata.mogrify_factory, @snowcap_im.manager] tags: - - { name: doctrine.event_subscriber} + - { name: doctrine.event_subscriber, priority: 1 } snowcap_im.form_extension: class: Snowcap\ImBundle\Form\Extension\ImageTypeExtension From f3b49e90e9f578e2f93f77087f78c0fe46beadff Mon Sep 17 00:00:00 2001 From: Jonathan Schmid Date: Tue, 1 Dec 2015 02:56:30 +0000 Subject: [PATCH 2/3] Use property accessor --- Listener/MogrifySubscriber.php | 26 ++++++++++++-------------- 1 file changed, 12 insertions(+), 14 deletions(-) diff --git a/Listener/MogrifySubscriber.php b/Listener/MogrifySubscriber.php index 1481687..8a4d278 100644 --- a/Listener/MogrifySubscriber.php +++ b/Listener/MogrifySubscriber.php @@ -11,15 +11,13 @@ namespace Snowcap\ImBundle\Listener; -use Doctrine\Common\Annotations\AnnotationReader; use Doctrine\Common\EventSubscriber; -use Doctrine\Common\Persistence\Event\LoadClassMetadataEventArgs; -use Doctrine\ORM\EntityManager; use Doctrine\ORM\Event\LifecycleEventArgs; use Doctrine\ORM\Event\PreFlushEventArgs; -use Snowcap\ImBundle\Manager as ImManager; - use Metadata\MetadataFactoryInterface; +use Snowcap\ImBundle\Manager as ImManager; +use Symfony\Component\PropertyAccess\PropertyAccess; +use Symfony\Component\HttpFoundation\File\UploadedFile; /** * Event listener for Doctrine entities to evualuate and execute ImBundle annotations @@ -43,6 +41,11 @@ class MogrifySubscriber implements EventSubscriber */ private $imManager; + /** + * @var \Symfony\Component\PropertyAccess\PropertyAccessor + */ + private $propertyAccessor; + /** * @param string $rootDir The dir to generate files * @param MetadataFactoryInterface $metadataFactory @@ -53,6 +56,7 @@ public function __construct($rootDir, MetadataFactoryInterface $metadataFactory, $this->rootDir = $rootDir; $this->metadataFactory = $metadataFactory; $this->imManager = $imManager; + $this->propertyAccessor = PropertyAccess::createPropertyAccessor(); } /** @@ -99,15 +103,9 @@ public function prePersist(LifecycleEventArgs $ea) */ private function mogrify($entity, $file) { - $propertyName = $file->name; - - $getter = 'get' . ucFirst($propertyName); - if (method_exists($entity, $getter)) { - /** @var $uploadedFile \Symfony\Component\HttpFoundation\File\UploadedFile */ - $uploadedFile = $entity->$getter(); - if (null !== $uploadedFile) { - $this->imManager->mogrify($file->params, $uploadedFile->getPathName()); - } + $uploadedFile = $this->propertyAccessor->getValue($entity, $file->name); + if ($uploadedFile instanceof UploadedFile) { + $this->imManager->mogrify($file->params, $uploadedFile->getPathName()); } } } From 79c2996480bbe3650a6b745a074f77459a87beee Mon Sep 17 00:00:00 2001 From: Jonathan Schmid Date: Tue, 1 Dec 2015 03:08:53 +0000 Subject: [PATCH 3/3] Cache metadata --- DependencyInjection/SnowcapImExtension.php | 10 ++++++++++ Doctrine/Metadata/MogrifyMetadata.php | 21 ++++++++++++++++++++- Listener/MogrifySubscriber.php | 11 +---------- Resources/config/services.yml | 10 +++++++++- 4 files changed, 40 insertions(+), 12 deletions(-) diff --git a/DependencyInjection/SnowcapImExtension.php b/DependencyInjection/SnowcapImExtension.php index bb596fd..4e8bf7a 100644 --- a/DependencyInjection/SnowcapImExtension.php +++ b/DependencyInjection/SnowcapImExtension.php @@ -41,5 +41,15 @@ public function load(array $configs, ContainerBuilder $container) $container->setParameter('snowcap_im.cache_path', $config['cache_path']); $container->setParameter('snowcap_im.timeout', $config['timeout']); $container->setParameter('snowcap_im.binary_path', $config['binary_path']); + + $metadataCache = '%kernel.cache_dir%/snowcap_im'; + $metadataCache = $container->getParameterBag()->resolveValue($metadataCache); + if (!is_dir($metadataCache)) { + mkdir($metadataCache, 0777, true); + } + $container + ->getDefinition('snowcap_im.metadata.cache') + ->replaceArgument(0, $metadataCache) + ; } } diff --git a/Doctrine/Metadata/MogrifyMetadata.php b/Doctrine/Metadata/MogrifyMetadata.php index 0966e03..6be90f0 100644 --- a/Doctrine/Metadata/MogrifyMetadata.php +++ b/Doctrine/Metadata/MogrifyMetadata.php @@ -6,6 +6,25 @@ class MogrifyMetadata extends BasePropertyMetadata { - /** @var string|array */ + /** + * @var string|array + */ public $params; + + public function serialize() + { + return serialize(array( + $this->class, + $this->name, + $this->params, + )); + } + + public function unserialize($str) + { + list($this->class, $this->name, $this->params) = unserialize($str); + + $this->reflection = new \ReflectionProperty($this->class, $this->name); + $this->reflection->setAccessible(true); + } } diff --git a/Listener/MogrifySubscriber.php b/Listener/MogrifySubscriber.php index 8a4d278..2c09649 100644 --- a/Listener/MogrifySubscriber.php +++ b/Listener/MogrifySubscriber.php @@ -24,13 +24,6 @@ */ class MogrifySubscriber implements EventSubscriber { - private $config = array(); - - /** - * @var string - */ - private $rootDir; - /** * @var \Metadata\MetadataFactoryInterface */ @@ -47,13 +40,11 @@ class MogrifySubscriber implements EventSubscriber private $propertyAccessor; /** - * @param string $rootDir The dir to generate files * @param MetadataFactoryInterface $metadataFactory * @param ImManager $imManager The ImBundle manager instance */ - public function __construct($rootDir, MetadataFactoryInterface $metadataFactory, ImManager $imManager) + public function __construct(MetadataFactoryInterface $metadataFactory, ImManager $imManager) { - $this->rootDir = $rootDir; $this->metadataFactory = $metadataFactory; $this->imManager = $imManager; $this->propertyAccessor = PropertyAccess::createPropertyAccessor(); diff --git a/Resources/config/services.yml b/Resources/config/services.yml index 9d994af..8ea715e 100644 --- a/Resources/config/services.yml +++ b/Resources/config/services.yml @@ -21,14 +21,22 @@ services: public: false arguments: [@annotation_reader] + snowcap_im.metadata.cache: + class: Metadata\Cache\FileCache + public: false + arguments: + - {} + snowcap_im.metadata.mogrify_factory: class: Metadata\MetadataFactory public: false arguments: [@snowcap_im.metadata.mogrify_driver] + calls: + - [setCache, ["@snowcap_im.metadata.cache"]] snowcap_im.mogrify_subscriber: class: Snowcap\ImBundle\Listener\MogrifySubscriber - arguments: [%kernel.root_dir%, @snowcap_im.metadata.mogrify_factory, @snowcap_im.manager] + arguments: [@snowcap_im.metadata.mogrify_factory, @snowcap_im.manager] tags: - { name: doctrine.event_subscriber, priority: 1 }