Skip to content

Commit ae12eca

Browse files
author
Jérôme Poskin
committed
Merge pull request snowcap#26 from foaly-nr1/patch-cacheable
Cache metadata
2 parents e0c77fa + 79c2996 commit ae12eca

File tree

6 files changed

+128
-76
lines changed

6 files changed

+128
-76
lines changed

DependencyInjection/SnowcapImExtension.php

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,5 +41,15 @@ public function load(array $configs, ContainerBuilder $container)
4141
$container->setParameter('snowcap_im.cache_path', $config['cache_path']);
4242
$container->setParameter('snowcap_im.timeout', $config['timeout']);
4343
$container->setParameter('snowcap_im.binary_path', $config['binary_path']);
44+
45+
$metadataCache = '%kernel.cache_dir%/snowcap_im';
46+
$metadataCache = $container->getParameterBag()->resolveValue($metadataCache);
47+
if (!is_dir($metadataCache)) {
48+
mkdir($metadataCache, 0777, true);
49+
}
50+
$container
51+
->getDefinition('snowcap_im.metadata.cache')
52+
->replaceArgument(0, $metadataCache)
53+
;
4454
}
4555
}

Doctrine/Driver/MogrifyDriver.php

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
<?php
2+
3+
namespace Snowcap\ImBundle\Doctrine\Driver;
4+
5+
use Metadata\Driver\DriverInterface;
6+
use Metadata\MergeableClassMetadata;
7+
use Doctrine\Common\Annotations\Reader;
8+
use Snowcap\ImBundle\Doctrine\Metadata\MogrifyMetadata;
9+
10+
class MogrifyDriver implements DriverInterface
11+
{
12+
const MOGRIFY = 'Snowcap\ImBundle\Doctrine\Mapping\Mogrify';
13+
14+
private $reader;
15+
16+
public function __construct(Reader $reader)
17+
{
18+
$this->reader = $reader;
19+
}
20+
21+
public function loadMetadataForClass(\ReflectionClass $class)
22+
{
23+
$classMetadata = new MergeableClassMetadata($class->getName());
24+
25+
foreach ($class->getProperties() as $property) {
26+
$field = $this->reader->getPropertyAnnotation($property, self::MOGRIFY);
27+
28+
if(!is_null($field)) {
29+
$propertyMetadata = new MogrifyMetadata($class->getName(), $property->getName());
30+
$propertyMetadata->params = $field->params;
31+
32+
$classMetadata->addPropertyMetadata($propertyMetadata);
33+
}
34+
}
35+
36+
return $classMetadata;
37+
}
38+
}

Doctrine/Mapping/Mogrify.php

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,10 +17,16 @@
1717
* Annotation definition class
1818
*
1919
* @Annotation
20+
* @Annotation\Target("PROPERTY")
2021
* @codeCoverageIgnore
2122
*/
2223
class Mogrify extends Annotation
2324
{
24-
/** @var array */
25+
/**
26+
* Identfier of a pre-configured format or key-value pairs of IM parameters
27+
*
28+
* @Required
29+
* @var string|array<string>
30+
*/
2531
public $params;
2632
}

Doctrine/Metadata/MogrifyMetadata.php

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
<?php
2+
3+
namespace Snowcap\ImBundle\Doctrine\Metadata;
4+
5+
use Metadata\PropertyMetadata as BasePropertyMetadata;
6+
7+
class MogrifyMetadata extends BasePropertyMetadata
8+
{
9+
/**
10+
* @var string|array<string>
11+
*/
12+
public $params;
13+
14+
public function serialize()
15+
{
16+
return serialize(array(
17+
$this->class,
18+
$this->name,
19+
$this->params,
20+
));
21+
}
22+
23+
public function unserialize($str)
24+
{
25+
list($this->class, $this->name, $this->params) = unserialize($str);
26+
27+
$this->reflection = new \ReflectionProperty($this->class, $this->name);
28+
$this->reflection->setAccessible(true);
29+
}
30+
}

Listener/MogrifySubscriber.php

Lines changed: 24 additions & 74 deletions
Original file line numberDiff line numberDiff line change
@@ -11,40 +11,43 @@
1111

1212
namespace Snowcap\ImBundle\Listener;
1313

14-
use Doctrine\Common\Annotations\AnnotationReader;
1514
use Doctrine\Common\EventSubscriber;
16-
use Doctrine\Common\Persistence\Event\LoadClassMetadataEventArgs;
17-
use Doctrine\ORM\EntityManager;
1815
use Doctrine\ORM\Event\LifecycleEventArgs;
1916
use Doctrine\ORM\Event\PreFlushEventArgs;
17+
use Metadata\MetadataFactoryInterface;
2018
use Snowcap\ImBundle\Manager as ImManager;
21-
19+
use Symfony\Component\PropertyAccess\PropertyAccess;
20+
use Symfony\Component\HttpFoundation\File\UploadedFile;
2221

2322
/**
2423
* Event listener for Doctrine entities to evualuate and execute ImBundle annotations
2524
*/
2625
class MogrifySubscriber implements EventSubscriber
2726
{
28-
private $config = array();
29-
3027
/**
31-
* @var string
28+
* @var \Metadata\MetadataFactoryInterface
3229
*/
33-
private $rootDir;
30+
private $metadataFactory;
3431

3532
/**
3633
* @var \Snowcap\ImBundle\Manager
3734
*/
3835
private $imManager;
3936

4037
/**
41-
* @param string $rootDir The dir to generate files
42-
* @param ImManager $imManager The ImBundle mamager instance
38+
* @var \Symfony\Component\PropertyAccess\PropertyAccessor
4339
*/
44-
public function __construct($rootDir, ImManager $imManager)
40+
private $propertyAccessor;
41+
42+
/**
43+
* @param MetadataFactoryInterface $metadataFactory
44+
* @param ImManager $imManager The ImBundle manager instance
45+
*/
46+
public function __construct(MetadataFactoryInterface $metadataFactory, ImManager $imManager)
4547
{
46-
$this->rootDir = $rootDir;
48+
$this->metadataFactory = $metadataFactory;
4749
$this->imManager = $imManager;
50+
$this->propertyAccessor = PropertyAccess::createPropertyAccessor();
4851
}
4952

5053
/**
@@ -54,50 +57,20 @@ public function __construct($rootDir, ImManager $imManager)
5457
*/
5558
public function getSubscribedEvents()
5659
{
57-
return array('loadClassMetadata', 'prePersist', 'preFlush');
58-
}
59-
60-
/**
61-
* @param LoadClassMetadataEventArgs $eventArgs
62-
*/
63-
public function loadClassMetadata(LoadClassMetadataEventArgs $eventArgs)
64-
{
65-
$reader = new AnnotationReader();
66-
$meta = $eventArgs->getClassMetadata();
67-
$reflexionClass = $meta->getReflectionClass();
68-
if (null !== $reflexionClass) {
69-
foreach ($reflexionClass->getProperties() as $property) {
70-
if ($meta->isMappedSuperclass && !$property->isPrivate() ||
71-
$meta->isInheritedField($property->name) ||
72-
isset($meta->associationMappings[$property->name]['inherited'])
73-
) {
74-
continue;
75-
}
76-
/** @var $annotation \Snowcap\ImBundle\Doctrine\Mapping\Mogrify */
77-
if ($annotation = $reader->getPropertyAnnotation($property, 'Snowcap\\ImBundle\\Doctrine\\Mapping\\Mogrify')) {
78-
$field = $property->getName();
79-
$this->config[$meta->getTableName()]['fields'][$field] = array(
80-
'property' => $property,
81-
'params' => $annotation->params,
82-
);
83-
}
84-
}
85-
}
60+
return array('prePersist', 'preFlush');
8661
}
8762

8863
/**
8964
* @param PreFlushEventArgs $ea
9065
*/
9166
public function preFlush(PreFlushEventArgs $ea)
9267
{
93-
$entityManager = $ea->getEntityManager();
94-
95-
$unitOfWork = $entityManager->getUnitOfWork();
96-
68+
$unitOfWork = $ea->getEntityManager()->getUnitOfWork();
9769
$entityMaps = $unitOfWork->getIdentityMap();
70+
9871
foreach ($entityMaps as $entities) {
9972
foreach ($entities as $entity) {
100-
foreach ($this->getFiles($entity, $ea->getEntityManager()) as $file) {
73+
foreach ($this->metadataFactory->getMetadataForClass(get_class($entity))->propertyMetadata as $file) {
10174
$this->mogrify($entity, $file);
10275
}
10376
}
@@ -110,43 +83,20 @@ public function preFlush(PreFlushEventArgs $ea)
11083
public function prePersist(LifecycleEventArgs $ea)
11184
{
11285
$entity = $ea->getEntity();
113-
foreach ($this->getFiles($entity, $ea->getEntityManager()) as $file) {
86+
foreach ($this->metadataFactory->getMetadataForClass(get_class($entity))->propertyMetadata as $file) {
11487
$this->mogrify($entity, $file);
11588
}
11689
}
11790

118-
/**
119-
* @param $entity
120-
* @param EntityManager $entityManager
121-
* @return array
122-
*/
123-
private function getFiles($entity, EntityManager $entityManager)
124-
{
125-
$classMetaData = $entityManager->getClassMetaData(get_class($entity));
126-
$tableName = $classMetaData->getTableName();
127-
128-
if (array_key_exists($tableName, $this->config)) {
129-
return $this->config[$tableName]['fields'];
130-
} else {
131-
return array();
132-
}
133-
}
134-
13591
/**
13692
* @param $entity
13793
* @param $file
13894
*/
13995
private function mogrify($entity, $file)
14096
{
141-
$propertyName = $file['property']->name;
142-
143-
$getter = 'get' . ucFirst($propertyName);
144-
if (method_exists($entity, $getter)) {
145-
/** @var $uploadedFile \Symfony\Component\HttpFoundation\File\UploadedFile */
146-
$uploadedFile = $entity->$getter();
147-
if (null !== $uploadedFile) {
148-
$this->imManager->mogrify($file['params'], $uploadedFile->getPathName());
149-
}
97+
$uploadedFile = $this->propertyAccessor->getValue($entity, $file->name);
98+
if ($uploadedFile instanceof UploadedFile) {
99+
$this->imManager->mogrify($file->params, $uploadedFile->getPathName());
150100
}
151101
}
152-
}
102+
}

Resources/config/services.yml

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,9 +16,27 @@ services:
1616
tags:
1717
- { name: twig.extension }
1818

19+
snowcap_im.metadata.mogrify_driver:
20+
class: Snowcap\ImBundle\Doctrine\Driver\MogrifyDriver
21+
public: false
22+
arguments: [@annotation_reader]
23+
24+
snowcap_im.metadata.cache:
25+
class: Metadata\Cache\FileCache
26+
public: false
27+
arguments:
28+
- {}
29+
30+
snowcap_im.metadata.mogrify_factory:
31+
class: Metadata\MetadataFactory
32+
public: false
33+
arguments: [@snowcap_im.metadata.mogrify_driver]
34+
calls:
35+
- [setCache, ["@snowcap_im.metadata.cache"]]
36+
1937
snowcap_im.mogrify_subscriber:
2038
class: Snowcap\ImBundle\Listener\MogrifySubscriber
21-
arguments: [%kernel.root_dir%, @snowcap_im.manager]
39+
arguments: [@snowcap_im.metadata.mogrify_factory, @snowcap_im.manager]
2240
tags:
2341
- { name: doctrine.event_subscriber, priority: 1 }
2442

0 commit comments

Comments
 (0)