Skip to content

Commit accb50f

Browse files
committed
Refactoring of event listeners(closes #8, #89, #123, #297)
1 parent 0ecb31a commit accb50f

25 files changed

+342
-446
lines changed

DependencyInjection/Compiler/RegisterPropelModelsPass.php

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -5,12 +5,14 @@
55
use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
66
use Symfony\Component\DependencyInjection\ContainerBuilder;
77

8+
use Symfony\Component\DependencyInjection\DefinitionDecorator;
89
use Vich\UploaderBundle\Exception\MappingNotFoundException;
910

1011
/**
1112
* Register the uploadable models in BazingaPropelEventDispatcherBundle
1213
*
1314
* @author Kévin Gomez <[email protected]>
15+
* @author Konstantin Myakshin <[email protected]>
1416
*/
1517
class RegisterPropelModelsPass implements CompilerPassInterface
1618
{
@@ -23,9 +25,7 @@ public function process(ContainerBuilder $container)
2325
return;
2426
}
2527

26-
$serviceTypes = array(
27-
'inject', 'clean', 'remove', 'upload',
28-
);
28+
$serviceTypes = array('inject', 'clean', 'remove', 'upload',);
2929

3030
$metadata = $container->get('vich_uploader.metadata_reader');
3131
$mappings = $container->getParameter('vich_uploader.mappings');
@@ -43,11 +43,12 @@ public function process(ContainerBuilder $container)
4343
}
4444

4545
foreach ($serviceTypes as $type) {
46-
if (!$container->has(sprintf('vich_uploader.listener.%s.%s', $type, $field['mapping']))) {
47-
continue;
48-
}
46+
$listenerId = sprintf('vich_uploader.listener.%s.propel.%s', $type, $field['mapping']);
47+
48+
$definition = $container
49+
->setDefinition($listenerId, new DefinitionDecorator(sprintf('vich_uploader.listener.%s.propel', $type)))
50+
->replaceArgument(1, new Reference('vich_uploader.adapter.propel'));
4951

50-
$definition = $container->getDefinition(sprintf('vich_uploader.listener.%s.%s', $type, $field['mapping']));
5152
$definition->setClass($container->getDefinition($definition->getParent())->getClass());
5253
$definition->setPublic(true);
5354
$definition->addTag('propel.event_subscriber', array('class' => $class));

DependencyInjection/VichUploaderExtension.php

Lines changed: 19 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ class VichUploaderExtension extends Extension
2424
protected $tagMap = array(
2525
'orm' => 'doctrine.event_subscriber',
2626
'mongodb' => 'doctrine_mongodb.odm.event_subscriber',
27-
'phpcr' => 'doctrine_phpcr.event_subscriber'
27+
'phpcr' => 'doctrine_phpcr.event_subscriber',
2828
);
2929

3030
/**
@@ -153,26 +153,24 @@ protected function fixDbDriverConfig(array $config)
153153

154154
protected function registerListeners(ContainerBuilder $container, array $config)
155155
{
156-
$servicesMap = array(
157-
'inject_on_load' => array('name' => 'inject', 'priority' => 0),
158-
'delete_on_update' => array('name' => 'clean', 'priority' => 50),
159-
'delete_on_remove' => array('name' => 'remove', 'priority' => 0)
156+
$dbDrivers = array();
157+
foreach ($config['mappings'] as $mapping) {
158+
$dbDrivers[$mapping['db_driver']] = true;
159+
}
160+
// register propel via compiler pass
161+
unset($dbDrivers['propel']);
162+
163+
$serviceTypes = array(
164+
'upload' => 0,
165+
'inject' => 0,
166+
'clean' => 50,
167+
'remove' => 0,
160168
);
161169

162-
foreach ($config['mappings'] as $name => $mapping) {
163-
$driver = $mapping['db_driver'];
164-
165-
// create optionnal listeners
166-
foreach ($servicesMap as $configOption => $service) {
167-
if (!$mapping[$configOption]) {
168-
continue;
169-
}
170-
171-
$this->createListener($container, $name, $service['name'], $driver, $service['priority']);
170+
foreach (array_keys($dbDrivers) as $driver) {
171+
foreach ($serviceTypes as $serviceType => $priority) {
172+
$this->createListener($container, $serviceType, $driver, $priority);
172173
}
173-
174-
// the upload listener is mandatory
175-
$this->createListener($container, $name, 'upload', $driver);
176174
}
177175
}
178176

@@ -199,16 +197,12 @@ protected function createNamerService(ContainerBuilder $container, $mappingName,
199197
return $mapping;
200198
}
201199

202-
protected function createListener(ContainerBuilder $container, $name, $type, $driver, $priority = 0)
200+
protected function createListener(ContainerBuilder $container, $type, $driver, $priority = 0)
203201
{
204202
$definition = $container
205-
->setDefinition(sprintf('vich_uploader.listener.%s.%s', $type, $name), new DefinitionDecorator(sprintf('vich_uploader.listener.%s.%s', $type, $driver)))
206-
->replaceArgument(0, $name)
203+
->getDefinition(sprintf('vich_uploader.listener.%s.%s', $type, $driver))
207204
->replaceArgument(1, new Reference('vich_uploader.adapter.'.$driver));
208205

209-
// propel does not require tags to work
210-
if (isset($this->tagMap[$driver])) {
211-
$definition->addTag($this->tagMap[$driver], array('priority' => $priority));
212-
}
206+
$definition->addTag($this->tagMap[$driver], array('priority' => $priority));
213207
}
214208
}

EventListener/BaseListener.php

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
<?php
2+
3+
namespace Vich\UploaderBundle\EventListener;
4+
5+
use Vich\UploaderBundle\Util\ClassUtils;
6+
use Vich\UploaderBundle\Adapter\AdapterInterface;
7+
use Vich\UploaderBundle\Handler\UploadHandler;
8+
use Vich\UploaderBundle\Metadata\MetadataReader;
9+
10+
/**
11+
* BaseListener
12+
*
13+
* @author Konstantin Myakshin <[email protected]>
14+
*/
15+
abstract class BaseListener
16+
{
17+
/**
18+
* @var array
19+
*/
20+
protected $mappings;
21+
22+
/**
23+
* @var AdapterInterface $adapter
24+
*/
25+
protected $adapter;
26+
27+
/**
28+
* @var MetadataReader $metadata
29+
*/
30+
protected $metadata;
31+
32+
/**
33+
* @var UploadHandler $handler
34+
*/
35+
protected $handler;
36+
37+
/**
38+
* Constructs a new instance of listener.
39+
*
40+
* @param array $mappings The mappings configuration.
41+
* @param AdapterInterface $adapter The adapter.
42+
* @param MetadataReader $metadata The metadata reader.
43+
* @param UploadHandler $handler The upload handler.
44+
*/
45+
public function __construct(array $mappings, AdapterInterface $adapter, MetadataReader $metadata, UploadHandler $handler)
46+
{
47+
$this->mappings = $mappings;
48+
$this->adapter = $adapter;
49+
$this->metadata = $metadata;
50+
$this->handler = $handler;
51+
}
52+
53+
protected function isFlagEnabledForField($flag, array $field)
54+
{
55+
return true === $this->mappings[$field['mapping']][$flag];
56+
}
57+
58+
protected function getUploadableFields($object)
59+
{
60+
return $this->metadata->getUploadableFields(ClassUtils::getClass($object));
61+
}
62+
}

EventListener/Doctrine/BaseListener.php

Lines changed: 3 additions & 69 deletions
Original file line numberDiff line numberDiff line change
@@ -3,80 +3,14 @@
33
namespace Vich\UploaderBundle\EventListener\Doctrine;
44

55
use Doctrine\Common\EventSubscriber;
6-
7-
use Vich\UploaderBundle\Adapter\AdapterInterface;
8-
use Vich\UploaderBundle\Handler\UploadHandler;
9-
use Vich\UploaderBundle\Metadata\MetadataReader;
10-
use Vich\UploaderBundle\Util\ClassUtils;
6+
use Vich\UploaderBundle\EventListener\BaseListener as CommonListener;
117

128
/**
139
* BaseListener
1410
*
15-
* @author Kévin Gomez <[email protected]>
11+
* @author Konstantin Myakshin <[email protected]>
1612
*/
17-
abstract class BaseListener implements EventSubscriber
13+
abstract class BaseListener extends CommonListener implements EventSubscriber
1814
{
19-
/**
20-
* @var string
21-
*/
22-
protected $mapping;
23-
24-
/**
25-
* @var AdapterInterface $adapter
26-
*/
27-
protected $adapter;
28-
29-
/**
30-
* @var MetadataReader $metadata
31-
*/
32-
protected $metadata;
33-
34-
/**
35-
* @var UploadHandler $handler
36-
*/
37-
protected $handler;
38-
39-
/**
40-
* Constructs a new instance of UploaderListener.
41-
*
42-
* @param string $mapping The mapping name.
43-
* @param AdapterInterface $adapter The adapter.
44-
* @param MetadataReader $metadata The metadata reader.
45-
* @param UploadHandler $handler The upload handler.
46-
*/
47-
public function __construct($mapping, AdapterInterface $adapter, MetadataReader $metadata, UploadHandler $handler)
48-
{
49-
$this->mapping = $mapping;
50-
$this->adapter = $adapter;
51-
$this->metadata = $metadata;
52-
$this->handler = $handler;
53-
}
54-
55-
/**
56-
* Checks if the given object is uploadable using the current mapping.
57-
*
58-
* @param mixed $object The object to test.
59-
*
60-
* @return bool
61-
*/
62-
protected function isUploadable($object)
63-
{
64-
return $this->metadata->isUploadable(ClassUtils::getClass($object), $this->mapping);
65-
}
66-
67-
/**
68-
* Returns a list of uploadable fields for the given object and mapping.
69-
*
70-
* @param mixed $object The object to use.
71-
*
72-
* @return array<string> A list of field names.
73-
*/
74-
protected function getUploadableFields($object)
75-
{
76-
$fields = $this->metadata->getUploadableFields(ClassUtils::getClass($object), $this->mapping);
7715

78-
return array_map(function($data) {
79-
return $data['propertyName'];
80-
}, $fields);
81-
}
8216
}

EventListener/Doctrine/CleanListener.php

Lines changed: 20 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -2,43 +2,47 @@
22

33
namespace Vich\UploaderBundle\EventListener\Doctrine;
44

5-
use Doctrine\Common\EventArgs;
5+
use Doctrine\ORM\Event\PreFlushEventArgs;
6+
use Doctrine\ORM\Events;
67

78
/**
89
* CleanListener
910
*
1011
* Listen to the update event to delete old files accordingly.
1112
*
13+
* @author Konstantin Myakshin <[email protected]>
1214
* @author Kévin Gomez <[email protected]>
1315
*/
1416
class CleanListener extends BaseListener
1517
{
1618
/**
17-
* The events the listener is subscribed to.
18-
*
19-
* @return array The array of events.
19+
* {@inheritdoc}
2020
*/
2121
public function getSubscribedEvents()
2222
{
23-
return array(
24-
'preUpdate',
25-
);
23+
return array(Events::preFlush);
2624
}
2725

2826
/**
29-
* @param EventArgs $event The event.
27+
* @param PreFlushEventArgs $event
3028
*/
31-
public function preUpdate(EventArgs $event)
29+
public function preFlush(PreFlushEventArgs $event)
3230
{
33-
$object = $this->adapter->getObjectFromArgs($event);
31+
$em = $event->getEntityManager();
32+
$identityMap = $em->getUnitOfWork()->getIdentityMap();
3433

35-
if (!$this->isUploadable($object)) {
36-
return;
37-
}
34+
foreach ($identityMap as $class => $entities) {
35+
$fields = $this->metadata->getUploadableFields($class);
36+
37+
foreach ($fields as $field) {
38+
if (!$this->isFlagEnabledForField('delete_on_update', $field)) {
39+
continue;
40+
}
3841

39-
foreach ($this->getUploadableFields($object) as $field) {
40-
$this->handler->clean($object, $field);
41-
$this->adapter->recomputeChangeSet($event);
42+
foreach ($entities as $entity) {
43+
$this->handler->clean($entity, $field['propertyName']);
44+
}
45+
}
4246
}
4347
}
4448
}

EventListener/Doctrine/InjectListener.php

Lines changed: 12 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -2,42 +2,40 @@
22

33
namespace Vich\UploaderBundle\EventListener\Doctrine;
44

5-
use Doctrine\Common\EventArgs;
5+
use Doctrine\ORM\Event\LifecycleEventArgs;
6+
use Doctrine\ORM\Events;
67

78
/**
89
* InjectListener
910
*
1011
* Listen to the load event in order to inject File objects.
1112
*
13+
* @author Konstantin Myakshin <[email protected]>
1214
* @author Kévin Gomez <[email protected]>
1315
*/
1416
class InjectListener extends BaseListener
1517
{
1618
/**
17-
* The events the listener is subscribed to.
18-
*
19-
* @return array The array of events.
19+
* {@inheritdoc}
2020
*/
2121
public function getSubscribedEvents()
2222
{
23-
return array(
24-
'postLoad',
25-
);
23+
return array(Events::postLoad);
2624
}
2725

2826
/**
29-
* @param EventArgs $event The event.
27+
* @param LifecycleEventArgs $event
3028
*/
31-
public function postLoad(EventArgs $event)
29+
public function postLoad(LifecycleEventArgs $event)
3230
{
3331
$object = $this->adapter->getObjectFromArgs($event);
3432

35-
if (!$this->isUploadable($object)) {
36-
return;
37-
}
38-
3933
foreach ($this->getUploadableFields($object) as $field) {
40-
$this->handler->inject($object, $field);
34+
if (!$this->isFlagEnabledForField('inject_on_load', $field)) {
35+
continue;
36+
}
37+
38+
$this->handler->inject($object, $field['propertyName']);
4139
}
4240
}
4341
}

0 commit comments

Comments
 (0)