diff --git a/DependencyInjection/Configuration.php b/DependencyInjection/Configuration.php index 362c570b..f599d740 100644 --- a/DependencyInjection/Configuration.php +++ b/DependencyInjection/Configuration.php @@ -28,6 +28,9 @@ public function getConfigTreeBuilder() ->scalarNode('storage')->defaultValue('vich_uploader.storage.file_system')->end() ->scalarNode('twig')->defaultTrue()->end() ->scalarNode('gaufrette')->defaultFalse()->end() + ->scalarNode('upload_on_persist')->defaultTrue()->end() + ->scalarNode('unlink_on_remove')->defaultTrue()->end() + ->scalarNode('inject_on_load')->defaultTrue()->end() ->arrayNode('mappings') ->useAttributeAsKey('id') ->prototype('array') diff --git a/DependencyInjection/VichUploaderExtension.php b/DependencyInjection/VichUploaderExtension.php index d3aa3dc2..20dd0020 100644 --- a/DependencyInjection/VichUploaderExtension.php +++ b/DependencyInjection/VichUploaderExtension.php @@ -9,6 +9,9 @@ use Vich\UploaderBundle\DependencyInjection\Configuration; use Symfony\Component\HttpKernel\Kernel; +use Symfony\Component\DependencyInjection\Definition; +use Symfony\Component\DependencyInjection\DefinitionDecorator; + /** * VichUploaderExtension. * @@ -84,4 +87,32 @@ public function load(array $configs, ContainerBuilder $container) $container->setParameter('vich_uploader.adapter.class', $this->adapterMap[$driver]); $container->getDefinition('vich_uploader.listener.uploader')->addTag($this->tagMap[$driver]); } + + private function loadEventListeners(array $config, ContainerBuilder $container) + { + if ($config['inject_on_load']) { + $container + ->setDefinition('vich_uploader.listener.inject', new DefinitionDecorator('vich_uploader.event_listener.abstract')) + ->setClass('vich_uploader.listener.inject.class') + ->setPublic(false) + ->addTag('doctrine.event_listener', array('event' => 'postLoad')); + } + + if ($config['upload_on_persist']) { + $container + ->setDefinition('vich_uploader.listener.upload', new DefinitionDecorator('vich_uploader.event_listener.abstract')) + ->setClass('vich_uploader.listener.upload.class') + ->setPublic(false) + ->addTag('doctrine.event_listener', array('event' => 'prePersist')) + ->addTag('doctrine.event_listener', array('event' => 'preUpdate')); + } + + if ($config['unlink_on_remove']) { + $container + ->setDefinition('vich_uploader.listener.inject', new DefinitionDecorator('vich_uploader.event_listener.abstract')) + ->setClass('vich_uploader.listener.inject.class') + ->setPublic(false) + ->addTag('doctrine.event_listener', array('event' => 'postRemove')); + } + } } diff --git a/EventListener/AbstractListener.php b/EventListener/AbstractListener.php new file mode 100644 index 00000000..9813bebf --- /dev/null +++ b/EventListener/AbstractListener.php @@ -0,0 +1,60 @@ +adapter = $adapter; + $this->driver = $driver; + $this->storage = $storage; + $this->injector = $injector; + } + + /** + * Tests if the object is Uploadable. + * + * @param object $obj The object. + * @return boolean True if uploadable, false otherwise. + */ + protected function isUploadable($obj) + { + $class = $this->adapter->getReflectionClass($obj); + + return null !== $this->driver->readUploadable($class); + } +} \ No newline at end of file diff --git a/EventListener/InjectListener.php b/EventListener/InjectListener.php new file mode 100644 index 00000000..3e5881c0 --- /dev/null +++ b/EventListener/InjectListener.php @@ -0,0 +1,21 @@ +adapter->getObjectFromArgs($args); + if ($this->isUploadable($obj)) { + $this->injector->injectFiles($obj); + } + }} \ No newline at end of file diff --git a/EventListener/UnlinkListener.php b/EventListener/UnlinkListener.php new file mode 100644 index 00000000..757986f4 --- /dev/null +++ b/EventListener/UnlinkListener.php @@ -0,0 +1,21 @@ +adapter->getObjectFromArgs($args); + if ($this->isUploadable($obj)) { + $this->storage->remove($obj); + } + } +} \ No newline at end of file diff --git a/EventListener/UploadListener.php b/EventListener/UploadListener.php new file mode 100644 index 00000000..e00b379f --- /dev/null +++ b/EventListener/UploadListener.php @@ -0,0 +1,36 @@ +adapter->getObjectFromArgs($args); + if ($this->isUploadable($obj)) { + $this->storage->upload($obj); + } + } + + /** + * Update the file and file name if necessary. + * + * @param EventArgs $args The event arguments. + */ + public function preUpdate(EventArgs $args) + { + $obj = $this->adapter->getObjectFromArgs($args); + if ($this->isUploadable($obj)) { + $this->storage->upload($obj); + + $this->adapter->recomputeChangeSet($args); + } + } +} diff --git a/EventListener/UploaderListener.php b/EventListener/UploaderListener.php deleted file mode 100644 index 426b4fe4..00000000 --- a/EventListener/UploaderListener.php +++ /dev/null @@ -1,137 +0,0 @@ - - */ -class UploaderListener implements EventSubscriber -{ - /** - * @var \Vich\UploaderBundle\Adapter\AdapterInterface $adapter - */ - protected $adapter; - - /** - * @var \Vich\UploaderBundle\Driver\AnnotationDriver $driver - */ - protected $driver; - - /** - * @var \Vich\UploaderBundle\Storage\StorageInterface $storage - */ - protected $storage; - - /** - * @var \Vich\UploaderBundle\Injector\FileInjectorInterface $injector - */ - protected $injector; - - /** - * Constructs a new instance of UploaderListener. - * - * @param \Vich\UploaderBundle\Adapter\AdapterInterface $adapter The adapter. - * @param \Vich\UploaderBundle\Driver\AnnotationDriver $driver The driver. - * @param \Vich\UploaderBundle\Storage\StorageInterface $storage The storage. - * @param \Vich\UploaderBundle\Injector\FileInjectorInterface $injector The injector. - */ - public function __construct(AdapterInterface $adapter, AnnotationDriver $driver, StorageInterface $storage, FileInjectorInterface $injector) - { - $this->adapter = $adapter; - $this->driver = $driver; - $this->storage = $storage; - $this->injector = $injector; - } - - /** - * The events the listener is subscribed to. - * - * @return array The array of events. - */ - public function getSubscribedEvents() - { - return array( - 'prePersist', - 'preUpdate', - 'postLoad', - 'postRemove', - ); - } - - /** - * Checks for for file to upload. - * - * @param \Doctrine\Common\EventArgs $args The event arguments. - */ - public function prePersist(EventArgs $args) - { - $obj = $this->adapter->getObjectFromArgs($args); - if ($this->isUploadable($obj)) { - $this->storage->upload($obj); - } - } - - /** - * Update the file and file name if necessary. - * - * @param EventArgs $args The event arguments. - */ - public function preUpdate(EventArgs $args) - { - $obj = $this->adapter->getObjectFromArgs($args); - if ($this->isUploadable($obj)) { - $this->storage->upload($obj); - - $this->adapter->recomputeChangeSet($args); - } - } - - /** - * Populates uploadable fields from filename properties - * if necessary. - * - * @param \Doctrine\Common\EventArgs $args - */ - public function postLoad(EventArgs $args) - { - $obj = $this->adapter->getObjectFromArgs($args); - if ($this->isUploadable($obj)) { - $this->injector->injectFiles($obj); - } - } - - /** - * Removes the file if necessary. - * - * @param EventArgs $args The event arguments. - */ - public function postRemove(EventArgs $args) - { - $obj = $this->adapter->getObjectFromArgs($args); - if ($this->isUploadable($obj)) { - $this->storage->remove($obj); - } - } - - /** - * Tests if the object is Uploadable. - * - * @param object $obj The object. - * @return boolean True if uploadable, false otherwise. - */ - protected function isUploadable($obj) - { - $class = $this->adapter->getReflectionClass($obj); - - return null !== $this->driver->readUploadable($class); - } -} diff --git a/Resources/config/listener.xml b/Resources/config/listener.xml index 5456fdca..e9eb607a 100644 --- a/Resources/config/listener.xml +++ b/Resources/config/listener.xml @@ -4,9 +4,15 @@ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://symfony.com/schema/dic/services http://symfony.com/schema/dic/services/services-1.0.xsd"> - + + Vich\UploaderBundle\EventListener\AbstractListener + Vich\UploaderBundle\EventListener\InjectListener + Vich\UploaderBundle\EventListener\UploadListener + Vich\UploaderBundle\EventListener\UnlinkListener + - + + diff --git a/Tests/EventListener/UploaderListenerTest.php b/Tests/EventListener/UploaderListenerTest.php deleted file mode 100644 index 8f55c04e..00000000 --- a/Tests/EventListener/UploaderListenerTest.php +++ /dev/null @@ -1,424 +0,0 @@ - - */ -class UploaderListenerTest extends \PHPUnit_Framework_TestCase -{ - /** - * @var \Vich\UploaderBundle\Adapter\AdapterInterface $adapter - */ - protected $adapter; - - /** - * @var \Vich\UploaderBundle\Driver\AnnotationDriver $driver - */ - protected $driver; - - /** - * @var \Vich\UploaderBundle\Storage\StorageInterface $storage - */ - protected $storage; - - /** - * @var \Vich\UploaderBundle\Injector\FileInjectorInterface $injector - */ - protected $injector; - - /** - * Sets up the test - */ - public function setUp() - { - $this->adapter = $this->getAdapterMock(); - $this->driver = $this->getDriverMock(); - $this->storage = $this->getStorageMock(); - $this->injector = $this->getInjectorMock(); - } - - /** - * Test the getSubscribedEvents method. - */ - public function testGetSubscribedEvents() - { - $listener = new UploaderListener($this->adapter, $this->driver, $this->storage, $this->injector); - $events = $listener->getSubscribedEvents(); - - $this->assertTrue(in_array('prePersist', $events)); - $this->assertTrue(in_array('preUpdate', $events)); - $this->assertTrue(in_array('postLoad', $events)); - $this->assertTrue(in_array('postRemove', $events)); - } - - /** - * Tests the prePersist method. - */ - public function testPrePersist() - { - $obj = new DummyEntity(); - $class = new \ReflectionClass($obj); - - $args = $this->getMockBuilder('Doctrine\Common\EventArgs') - ->disableOriginalConstructor() - ->getMock(); - - $this->adapter - ->expects($this->once()) - ->method('getObjectFromArgs') - ->will($this->returnValue($obj)); - - $this->adapter - ->expects($this->once()) - ->method('getReflectionClass') - ->will($this->returnValue($class)); - - $uploadable = $this->getMockBuilder('Vich\UploaderBundle\Mapping\Annotation\Uploadable') - ->disableOriginalConstructor() - ->getMock(); - - $this->driver - ->expects($this->once()) - ->method('readUploadable') - ->with($class) - ->will($this->returnValue($uploadable)); - - $this->storage - ->expects($this->once()) - ->method('upload') - ->with($obj); - - $listener = new UploaderListener($this->adapter, $this->driver, $this->storage, $this->injector); - $listener->prePersist($args); - } - - /** - * Tests that prePersist skips non-uploadable entity. - */ - public function testPrePersistSkipsNonUploadable() - { - $obj = new DummyEntity(); - $class = new \ReflectionClass($obj); - - $args = $this->getMockBuilder('Doctrine\Common\EventArgs') - ->disableOriginalConstructor() - ->getMock(); - - $this->adapter - ->expects($this->once()) - ->method('getObjectFromArgs') - ->will($this->returnValue($obj)); - - $this->adapter - ->expects($this->once()) - ->method('getReflectionClass') - ->will($this->returnValue($class)); - - $this->driver - ->expects($this->once()) - ->method('readUploadable') - ->with($class) - ->will($this->returnValue(null)); - - $this->storage - ->expects($this->never()) - ->method('upload'); - - $listener = new UploaderListener($this->adapter, $this->driver, $this->storage, $this->injector); - $listener->prePersist($args); - } - - /** - * Test the preUpdate method. - */ - public function testPreUpdate() - { - $obj = new DummyEntity(); - $class = new \ReflectionClass($obj); - - $args = $this->getMockBuilder('Doctrine\Common\EventArgs') - ->disableOriginalConstructor() - ->getMock(); - - $this->adapter - ->expects($this->once()) - ->method('getObjectFromArgs') - ->will($this->returnValue($obj)); - - $this->adapter - ->expects($this->once()) - ->method('getReflectionClass') - ->will($this->returnValue($class)); - - $this->adapter - ->expects($this->once()) - ->method('recomputeChangeSet') - ->with($args); - - $uploadable = $this->getMockBuilder('Vich\UploaderBundle\Mapping\Annotation\Uploadable') - ->disableOriginalConstructor() - ->getMock(); - - $this->driver - ->expects($this->once()) - ->method('readUploadable') - ->with($class) - ->will($this->returnValue($uploadable)); - - $this->storage - ->expects($this->once()) - ->method('upload') - ->with($obj); - - $listener = new UploaderListener($this->adapter, $this->driver, $this->storage, $this->injector); - $listener->preUpdate($args); - } - - /** - * Test that preUpdate skips non uploadable entity. - */ - public function testPreUpdateSkipsNonUploadable() - { - $obj = new DummyEntity(); - $class = new \ReflectionClass($obj); - - $args = $this->getMockBuilder('Doctrine\Common\EventArgs') - ->disableOriginalConstructor() - ->getMock(); - - $this->adapter - ->expects($this->once()) - ->method('getObjectFromArgs') - ->will($this->returnValue($obj)); - - $this->adapter - ->expects($this->once()) - ->method('getReflectionClass') - ->will($this->returnValue($class)); - - $this->driver - ->expects($this->once()) - ->method('readUploadable') - ->with($class) - ->will($this->returnValue(null)); - - $this->storage - ->expects($this->never()) - ->method('upload'); - - $this->adapter - ->expects($this->never()) - ->method('recomputeChangeSet'); - - $listener = new UploaderListener($this->adapter, $this->driver, $this->storage, $this->injector); - $listener->preUpdate($args); - } - - /** - * Test the postLoad method. - */ - public function testPostLoad() - { - $obj = new DummyEntity(); - $class = new \ReflectionClass($obj); - - $args = $this->getMockBuilder('Doctrine\Common\EventArgs') - ->disableOriginalConstructor() - ->getMock(); - - $this->adapter - ->expects($this->once()) - ->method('getObjectFromArgs') - ->will($this->returnValue($obj)); - - $this->adapter - ->expects($this->once()) - ->method('getReflectionClass') - ->will($this->returnValue($class)); - - $uploadable = $this->getMockBuilder('Vich\UploaderBundle\Mapping\Annotation\Uploadable') - ->disableOriginalConstructor() - ->getMock(); - - $this->driver - ->expects($this->once()) - ->method('readUploadable') - ->with($class) - ->will($this->returnValue($uploadable)); - - $this->injector - ->expects($this->once()) - ->method('injectFiles') - ->with($obj); - - $listener = new UploaderListener($this->adapter, $this->driver, $this->storage, $this->injector); - $listener->postLoad($args); - } - - /** - * Test that postLoad skips non uploadable entity. - */ - public function testPostLoadSkipsNonUploadable() - { - $obj = new DummyEntity(); - $class = new \ReflectionClass($obj); - - $args = $this->getMockBuilder('Doctrine\Common\EventArgs') - ->disableOriginalConstructor() - ->getMock(); - - $this->adapter - ->expects($this->once()) - ->method('getObjectFromArgs') - ->will($this->returnValue($obj)); - - $this->adapter - ->expects($this->once()) - ->method('getReflectionClass') - ->will($this->returnValue($class)); - - $this->driver - ->expects($this->once()) - ->method('readUploadable') - ->with($class) - ->will($this->returnValue(null)); - - $this->injector - ->expects($this->never()) - ->method('injectFiles'); - - $listener = new UploaderListener($this->adapter, $this->driver, $this->storage, $this->injector); - $listener->postLoad($args); - } - - /** - * Test the postRemove method. - */ - public function testPostRemove() - { - $obj = new DummyEntity(); - $class = new \ReflectionClass($obj); - - $args = $this->getMockBuilder('Doctrine\Common\EventArgs') - ->disableOriginalConstructor() - ->getMock(); - - $this->adapter - ->expects($this->once()) - ->method('getObjectFromArgs') - ->will($this->returnValue($obj)); - - $this->adapter - ->expects($this->once()) - ->method('getReflectionClass') - ->will($this->returnValue($class)); - - $uploadable = $this->getMockBuilder('Vich\UploaderBundle\Mapping\Annotation\Uploadable') - ->disableOriginalConstructor() - ->getMock(); - - $this->driver - ->expects($this->once()) - ->method('readUploadable') - ->with($class) - ->will($this->returnValue($uploadable)); - - $this->storage - ->expects($this->once()) - ->method('remove') - ->with($obj); - - $listener = new UploaderListener($this->adapter, $this->driver, $this->storage, $this->injector); - $listener->postRemove($args); - } - - /** - * Test that postRemove skips non uploadable entity. - */ - public function testPostRemoveSkipsNonUploadable() - { - $obj = new DummyEntity(); - $class = new \ReflectionClass($obj); - - $args = $this->getMockBuilder('Doctrine\Common\EventArgs') - ->disableOriginalConstructor() - ->getMock(); - - $this->adapter - ->expects($this->once()) - ->method('getObjectFromArgs') - ->will($this->returnValue($obj)); - - $this->adapter - ->expects($this->once()) - ->method('getReflectionClass') - ->will($this->returnValue($class)); - - $this->driver - ->expects($this->once()) - ->method('readUploadable') - ->with($class) - ->will($this->returnValue(null)); - - $this->storage - ->expects($this->never()) - ->method('remove'); - - $listener = new UploaderListener($this->adapter, $this->driver, $this->storage, $this->injector); - $listener->postRemove($args); - } - - /** - * Creates a mock adapter. - * - * @return \Vich\UploaderBundle\Adapter\AdapterInterface The mock adapter. - */ - protected function getAdapterMock() - { - return $this->getMockBuilder('Vich\UploaderBundle\Adapter\AdapterInterface') - ->disableOriginalConstructor() - ->getMock(); - } - - /** - * Creates a mock annotation driver. - * - * @return \Vich\UploaderBundle\Driver\AnnotationDriver The mock driver. - */ - protected function getDriverMock() - { - return $this->getMockBuilder('Vich\UploaderBundle\Driver\AnnotationDriver') - ->disableOriginalConstructor() - ->getMock(); - } - - /** - * Creates a mock storage. - * - * @return \Vich\UploaderBundle\Storage\StorageInterface The mock storage. - */ - protected function getStorageMock() - { - return $this->getMockBuilder('Vich\UploaderBundle\Storage\StorageInterface') - ->disableOriginalConstructor() - ->getMock(); - } - - /** - * Creates a mock injector. - * - * @return \Vich\UploaderBundle\Injector\FileInjectorInterface The mock injector. - */ - protected function getInjectorMock() - { - return $this->getMockBuilder('Vich\UploaderBundle\Injector\FileInjectorInterface') - ->disableOriginalConstructor() - ->getMock(); - } -} diff --git a/Tests/Storage/GaufretteStorageTest.php b/Tests/Storage/GaufretteStorageTest.php index 441c5346..88c3b37c 100644 --- a/Tests/Storage/GaufretteStorageTest.php +++ b/Tests/Storage/GaufretteStorageTest.php @@ -23,6 +23,13 @@ class GaufretteStorageTest extends \PHPUnit_Framework_TestCase */ protected $filesystemMap; + static public function setUpBeforeClass() + { + if (!class_exists('Gaufrette\Filesystem')) { + self::markTestSkipped('Gaufrette not installed'); + } + } + /** * Sets up the test. */