diff --git a/Events/CacheResolveEvent.php b/Events/CacheResolveEvent.php
new file mode 100644
index 000000000..325d0ff7e
--- /dev/null
+++ b/Events/CacheResolveEvent.php
@@ -0,0 +1,99 @@
+path = $path;
+ $this->filter = $filter;
+ $this->url = $url;
+ }
+
+ /**
+ * Sets resource path
+ *
+ * @param $path
+ */
+ public function setPath($path)
+ {
+ $this->path = $path;
+ }
+
+ /**
+ * Returns resource path
+ *
+ * @return string
+ */
+ public function getPath()
+ {
+ return $this->path;
+ }
+
+ /**
+ * Sets filter name
+ *
+ * @param $filter
+ */
+ public function setFilter($filter)
+ {
+ $this->filter = $filter;
+ }
+
+ /**
+ * Returns filter name
+ *
+ * @return string
+ */
+ public function getFilter()
+ {
+ return $this->filter;
+ }
+
+ /**
+ * Sets resource url
+ *
+ * @param $url
+ */
+ public function setUrl($url)
+ {
+ $this->url = $url;
+ }
+
+ /**
+ * Returns resource url
+ *
+ * @return null
+ */
+ public function getUrl()
+ {
+ return $this->url;
+ }
+}
diff --git a/Imagine/Cache/CacheManager.php b/Imagine/Cache/CacheManager.php
index e9c6f6810..d0c270b64 100644
--- a/Imagine/Cache/CacheManager.php
+++ b/Imagine/Cache/CacheManager.php
@@ -8,6 +8,10 @@
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
use Symfony\Component\HttpKernel\UriSigner;
use Symfony\Component\Routing\RouterInterface;
+use Symfony\Component\EventDispatcher\EventDispatcherInterface;
+use Symfony\Component\EventDispatcher\Event;
+use Liip\ImagineBundle\ImagineEvents;
+use Liip\ImagineBundle\Events\CacheResolveEvent;
class CacheManager
{
@@ -31,6 +35,11 @@ class CacheManager
*/
protected $uriSigner;
+ /**
+ * @var \Symfony\Component\EventDispatcher\EventDispatcherInterface
+ */
+ protected $dispatcher;
+
/**
* @var string
*/
@@ -44,11 +53,17 @@ class CacheManager
* @param UriSigner $uriSigner
* @param string $defaultResolver
*/
- public function __construct(FilterConfiguration $filterConfig, RouterInterface $router, UriSigner $uriSigner, $defaultResolver = null)
- {
+ public function __construct(
+ FilterConfiguration $filterConfig,
+ RouterInterface $router,
+ UriSigner $uriSigner,
+ EventDispatcherInterface $dispatcher,
+ $defaultResolver = null
+ ) {
$this->filterConfig = $filterConfig;
$this->router = $router;
$this->uriSigner = $uriSigner;
+ $this->dispatcher = $dispatcher;
$this->defaultResolver = $defaultResolver ?: 'default';
}
@@ -176,7 +191,15 @@ public function resolve($path, $filter)
throw new NotFoundHttpException(sprintf("Source image was searched with '%s' outside of the defined root path", $path));
}
- return $this->getResolver($filter)->resolve($path, $filter);
+ $preEvent = new CacheResolveEvent($path, $filter);
+ $this->dispatcher->dispatch(ImagineEvents::PRE_RESOLVE, $preEvent);
+
+ $url = $this->getResolver($preEvent->getFilter())->resolve($preEvent->getPath(), $preEvent->getFilter());
+
+ $postEvent = new CacheResolveEvent($preEvent->getPath(), $preEvent->getFilter(), $url);
+ $this->dispatcher->dispatch(ImagineEvents::POST_RESOLVE, $postEvent);
+
+ return $postEvent->getUrl();
}
/**
diff --git a/ImagineEvents.php b/ImagineEvents.php
new file mode 100644
index 000000000..cce7bb1cf
--- /dev/null
+++ b/ImagineEvents.php
@@ -0,0 +1,14 @@
+
+
%liip_imagine.cache.resolver.default%
diff --git a/Tests/AbstractTest.php b/Tests/AbstractTest.php
index 9e5ea46fd..ea355f251 100644
--- a/Tests/AbstractTest.php
+++ b/Tests/AbstractTest.php
@@ -6,6 +6,7 @@
use Liip\ImagineBundle\Imagine\Filter\FilterConfiguration;
use Symfony\Component\Filesystem\Filesystem;
use Symfony\Component\Routing\RouterInterface;
+use Symfony\Component\EventDispatcher\EventDispatcherInterface;
abstract class AbstractTest extends \PHPUnit_Framework_TestCase
{
@@ -81,6 +82,11 @@ protected function createResolverMock()
return $this->getMock('Liip\ImagineBundle\Imagine\Cache\Resolver\ResolverInterface');
}
+ protected function createEventDispatcherMock()
+ {
+ return $this->getMock('Symfony\Component\EventDispatcher\EventDispatcherInterface');
+ }
+
protected function getMockImage()
{
return $this->getMock('Imagine\Image\ImageInterface');
diff --git a/Tests/Events/CacheResolveEventTest.php b/Tests/Events/CacheResolveEventTest.php
new file mode 100644
index 000000000..41e826345
--- /dev/null
+++ b/Tests/Events/CacheResolveEventTest.php
@@ -0,0 +1,105 @@
+assertAttributeEquals('default_path', 'path', $event);
+ }
+
+ public function testShouldAllowSetPathByMethod()
+ {
+ $event = new CacheResolveEvent('default_path', 'default_filter');
+ $event->setPath('new_path');
+
+ $this->assertAttributeEquals('new_path', 'path', $event);
+ }
+
+ public function testShouldAllowGetPathWhichWasSetInConstruct()
+ {
+ $event = new CacheResolveEvent('default_path', 'default_filter');
+
+ $this->assertEquals('default_path', $event->getPath());
+ }
+
+ public function testShouldAllowGetPathWhichWasSetByMethod()
+ {
+ $event = new CacheResolveEvent('default_path', 'default_filter');
+ $event->setPath('new_path');
+
+ $this->assertEquals('new_path', $event->getPath());
+ }
+
+ public function testShouldAllowSetFilterInConstruct()
+ {
+ $event = new CacheResolveEvent('default_path', 'default_filter');
+
+ $this->assertAttributeEquals('default_filter', 'filter', $event);
+ }
+
+ public function testShouldAllowSetFilterByMethod()
+ {
+ $event = new CacheResolveEvent('default_path', 'default_filter');
+ $event->setFilter('new_filter');
+
+ $this->assertAttributeEquals('new_filter', 'filter', $event);
+ }
+
+ public function testShouldAllowGetFilterWhichWasSetInConstruct()
+ {
+ $event = new CacheResolveEvent('default_path', 'default_filter');
+
+ $this->assertEquals('default_filter', $event->getFilter());
+ }
+
+ public function testShouldAllowGetFilterWhichWasSetByMethod()
+ {
+ $event = new CacheResolveEvent('default_path', 'default_filter');
+ $event->setFilter('new_filter');
+
+ $this->assertEquals('new_filter', $event->getFilter());
+ }
+
+ public function testShouldAllowSetUrlInConstruct()
+ {
+ $event = new CacheResolveEvent('default_path', 'default_filter', 'default_url');
+
+ $this->assertAttributeEquals('default_url', 'url', $event);
+ }
+
+ public function testShouldAllowSetUrlByMethod()
+ {
+ $event = new CacheResolveEvent('default_path', 'default_filter');
+ $event->setUrl('new_url');
+
+ $this->assertAttributeEquals('new_url', 'url', $event);
+ }
+
+ public function testShouldAllowGetUrlWhichWasSetInConstruct()
+ {
+ $event = new CacheResolveEvent('default_path', 'default_filter', 'default_url');
+
+ $this->assertEquals('default_url', $event->getUrl());
+ }
+
+ public function testShouldAllowGetUrlWhichWasSetByMethod()
+ {
+ $event = new CacheResolveEvent('default_path', 'default_filter');
+ $event->setUrl('new_url');
+
+ $this->assertEquals('new_url', $event->getUrl());
+ }
+}
diff --git a/Tests/Imagine/Cache/CacheManagerTest.php b/Tests/Imagine/Cache/CacheManagerTest.php
index 31f72debe..1ccbefeee 100644
--- a/Tests/Imagine/Cache/CacheManagerTest.php
+++ b/Tests/Imagine/Cache/CacheManagerTest.php
@@ -7,6 +7,8 @@
use Liip\ImagineBundle\Tests\AbstractTest;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpKernel\UriSigner;
+use Liip\ImagineBundle\ImagineEvents;
+use Liip\ImagineBundle\Events\CacheResolveEvent;
/**
* @covers Liip\ImagineBundle\Imagine\Cache\CacheManager
@@ -17,7 +19,7 @@ class CacheManagerTest extends AbstractTest
public function testAddCacheManagerAwareResolver()
{
- $cacheManager = new CacheManager($this->createFilterConfigurationMock(), $this->createRouterMock(), new UriSigner('secret'));
+ $cacheManager = new CacheManager($this->createFilterConfigurationMock(), $this->createRouterMock(), new UriSigner('secret'), $this->createEventDispatcherMock());
$resolver = $this->getMock('Liip\ImagineBundle\Tests\Fixtures\CacheManagerAwareResolver');
$resolver
@@ -43,7 +45,7 @@ public function testGetBrowserPathWithoutResolver()
)))
;
- $cacheManager = new CacheManager($config, $this->createRouterMock(), new UriSigner('secret'));
+ $cacheManager = new CacheManager($config, $this->createRouterMock(), new UriSigner('secret'), $this->createEventDispatcherMock());
$this->setExpectedException('OutOfBoundsException', 'Could not find resolver "default" for "thumbnail" filter type');
$cacheManager->getBrowserPath('cats.jpeg', 'thumbnail');
@@ -83,7 +85,7 @@ public function testDefaultResolverUsedIfNoneSetOnGetBrowserPath()
->method('generate')
;
- $cacheManager = new CacheManager($config, $router, new UriSigner('secret'));
+ $cacheManager = new CacheManager($config, $router, new UriSigner('secret'), $this->createEventDispatcherMock());
$cacheManager->addResolver('default', $resolver);
$actualBrowserPath = $cacheManager->getBrowserPath('cats.jpeg', 'thumbnail');
@@ -124,7 +126,7 @@ public function testFilterActionUrlGeneratedAndReturnIfResolverReturnNullOnGetBr
->will($this->returnValue('/media/cache/thumbnail/cats.jpeg'))
;
- $cacheManager = new CacheManager($config, $router, new UriSigner('secret'));
+ $cacheManager = new CacheManager($config, $router, new UriSigner('secret'), $this->createEventDispatcherMock());
$cacheManager->addResolver('default', $resolver);
$actualBrowserPath = $cacheManager->getBrowserPath('cats.jpeg', 'thumbnail');
@@ -137,7 +139,12 @@ public function testFilterActionUrlGeneratedAndReturnIfResolverReturnNullOnGetBr
*/
public function testResolveInvalidPath($path)
{
- $cacheManager = new CacheManager($this->createFilterConfigurationMock(), $this->createRouterMock(), new UriSigner('secret'));
+ $cacheManager = new CacheManager(
+ $this->createFilterConfigurationMock(),
+ $this->createRouterMock(),
+ new UriSigner('secret'),
+ $this->createEventDispatcherMock()
+ );
$this->setExpectedException('Symfony\Component\HttpKernel\Exception\NotFoundHttpException');
$cacheManager->resolve($path, 'thumbnail');
@@ -145,7 +152,12 @@ public function testResolveInvalidPath($path)
public function testThrowsIfConcreteResolverNotExists()
{
- $cacheManager = new CacheManager($this->createFilterConfigurationMock(), $this->createRouterMock(), new UriSigner('secret'));
+ $cacheManager = new CacheManager(
+ $this->createFilterConfigurationMock(),
+ $this->createRouterMock(),
+ new UriSigner('secret'),
+ $this->createEventDispatcherMock()
+ );
$this->setExpectedException('OutOfBoundsException', 'Could not find resolver "default" for "thumbnail" filter type');
$this->assertFalse($cacheManager->resolve('cats.jpeg', 'thumbnail'));
@@ -189,7 +201,8 @@ public function testFallbackToDefaultResolver()
$cacheManager = new CacheManager(
$config,
$this->createRouterMock(),
- new UriSigner('secret')
+ new UriSigner('secret'),
+ $this->createEventDispatcherMock()
);
$cacheManager->addResolver('default', $resolver);
@@ -224,7 +237,8 @@ public function testGenerateUrl()
$cacheManager = new CacheManager(
$this->createFilterConfigurationMock(),
$routerMock,
- new UriSigner('secret')
+ new UriSigner('secret'),
+ $this->createEventDispatcherMock()
);
$this->assertEquals(
@@ -256,7 +270,7 @@ public function testRemoveCacheForPathAndFilterOnRemove()
}))
;
- $cacheManager = new CacheManager($config, $this->createRouterMock(), new UriSigner('secret'));
+ $cacheManager = new CacheManager($config, $this->createRouterMock(), new UriSigner('secret'), $this->createEventDispatcherMock());
$cacheManager->addResolver($expectedFilter, $resolver);
$cacheManager->remove($expectedPath, $expectedFilter);
@@ -293,7 +307,7 @@ public function testRemoveCacheForPathAndSomeFiltersOnRemove()
}))
;
- $cacheManager = new CacheManager($config, $this->createRouterMock(), new UriSigner('secret'));
+ $cacheManager = new CacheManager($config, $this->createRouterMock(), new UriSigner('secret'), $this->createEventDispatcherMock());
$cacheManager->addResolver($expectedFilterOne, $resolverOne);
$cacheManager->addResolver($expectedFilterTwo, $resolverTwo);
@@ -327,7 +341,7 @@ public function testRemoveCacheForSomePathsAndFilterOnRemove()
}))
;
- $cacheManager = new CacheManager($config, $this->createRouterMock(), new UriSigner('secret'));
+ $cacheManager = new CacheManager($config, $this->createRouterMock(), new UriSigner('secret'), $this->createEventDispatcherMock());
$cacheManager->addResolver($expectedFilter, $resolver);
$cacheManager->remove(array($expectedPathOne, $expectedPathTwo), $expectedFilter);
@@ -365,7 +379,7 @@ public function testRemoveCacheForSomePathsAndSomeFiltersOnRemove()
}))
;
- $cacheManager = new CacheManager($config, $this->createRouterMock(), new UriSigner('secret'));
+ $cacheManager = new CacheManager($config, $this->createRouterMock(), new UriSigner('secret'), $this->createEventDispatcherMock());
$cacheManager->addResolver($expectedFilterOne, $resolverOne);
$cacheManager->addResolver($expectedFilterTwo, $resolverTwo);
@@ -413,7 +427,7 @@ public function testRemoveCacheForAllFiltersOnRemove()
)))
;
- $cacheManager = new CacheManager($config, $this->createRouterMock(), new UriSigner('secret'));
+ $cacheManager = new CacheManager($config, $this->createRouterMock(), new UriSigner('secret'), $this->createEventDispatcherMock());
$cacheManager->addResolver($expectedFilterOne, $resolverOne);
$cacheManager->addResolver($expectedFilterTwo, $resolverTwo);
@@ -459,7 +473,7 @@ public function testRemoveCacheForPathAndAllFiltersOnRemove()
)))
;
- $cacheManager = new CacheManager($config, $this->createRouterMock(), new UriSigner('secret'));
+ $cacheManager = new CacheManager($config, $this->createRouterMock(), new UriSigner('secret'), $this->createEventDispatcherMock());
$cacheManager->addResolver($expectedFilterOne, $resolverOne);
$cacheManager->addResolver($expectedFilterTwo, $resolverTwo);
@@ -489,10 +503,170 @@ public function testAggregateFiltersByResolverOnRemove()
}))
;
- $cacheManager = new CacheManager($config, $this->createRouterMock(), new UriSigner('secret'));
+ $cacheManager = new CacheManager($config, $this->createRouterMock(), new UriSigner('secret'), $this->createEventDispatcherMock());
$cacheManager->addResolver($expectedFilterOne, $resolver);
$cacheManager->addResolver($expectedFilterTwo, $resolver);
$cacheManager->remove(null, array($expectedFilterOne, $expectedFilterTwo));
}
+
+ public function testShouldDispatchCachePreResolveEvent()
+ {
+ $dispatcher = $this->createEventDispatcherMock();
+ $dispatcher
+ ->expects($this->at(0))
+ ->method('dispatch')
+ ->with(ImagineEvents::PRE_RESOLVE, new CacheResolveEvent('cats.jpg', 'thumbnail'))
+ ;
+
+ $cacheManager = new CacheManager(
+ $this->createFilterConfigurationMock(),
+ $this->createRouterMock(),
+ new UriSigner('secret'),
+ $dispatcher
+ );
+ $cacheManager->addResolver('default', $this->createResolverMock());
+
+ $cacheManager->resolve('cats.jpg', 'thumbnail');
+ }
+
+ public function testShouldDispatchCachePostResolveEvent()
+ {
+ $dispatcher = $this->createEventDispatcherMock();
+ $dispatcher
+ ->expects($this->at(1))
+ ->method('dispatch')
+ ->with(ImagineEvents::POST_RESOLVE, new CacheResolveEvent('cats.jpg', 'thumbnail'))
+ ;
+
+ $cacheManager = new CacheManager(
+ $this->createFilterConfigurationMock(),
+ $this->createRouterMock(),
+ new UriSigner('secret'),
+ $dispatcher
+ );
+ $cacheManager->addResolver('default', $this->createResolverMock());
+
+ $cacheManager->resolve('cats.jpg', 'thumbnail');
+ }
+
+ public function testShouldAllowToPassChangedDataFromPreResolveEventToResolver()
+ {
+ $dispatcher = $this->createEventDispatcherMock();
+ $dispatcher
+ ->expects($this->at(0))
+ ->method('dispatch')
+ ->with(ImagineEvents::PRE_RESOLVE, $this->isInstanceOf('Liip\ImagineBundle\Events\CacheResolveEvent'))
+ ->will($this->returnCallback(function ($name, $event) {
+ $event->setPath('changed_path');
+ $event->setFilter('changed_filter');
+ }))
+ ;
+
+ $resolver = $this->createResolverMock();
+ $resolver
+ ->expects($this->once())
+ ->method('resolve')
+ ->with('changed_path', 'changed_filter')
+ ;
+
+ $cacheManager = new CacheManager(
+ $this->createFilterConfigurationMock(),
+ $this->createRouterMock(),
+ new UriSigner('secret'),
+ $dispatcher
+ );
+ $cacheManager->addResolver('default', $resolver);
+
+ $cacheManager->resolve('cats.jpg', 'thumbnail');
+ }
+
+ public function testShouldAllowToGetResolverByFilterChangedInPreResolveEvent()
+ {
+ $dispatcher = $this->createEventDispatcherMock();
+ $dispatcher
+ ->expects($this->at(0))
+ ->method('dispatch')
+ ->will($this->returnCallback(function ($name, $event) {
+ $event->setFilter('thumbnail');
+ }))
+ ;
+
+ $cacheManager = $this->getMock('Liip\ImagineBundle\Imagine\Cache\CacheManager', array('getResolver'), array(
+ $this->createFilterConfigurationMock(),
+ $this->createRouterMock(),
+ new UriSigner('secret'),
+ $dispatcher
+ ));
+
+ $cacheManager
+ ->expects($this->once())
+ ->method('getResolver')
+ ->with('thumbnail')
+ ->will($this->returnValue($this->createResolverMock()))
+ ;
+
+ $cacheManager->resolve('cats.jpg', 'default');
+ }
+
+ public function testShouldAllowToPassChangedDataFromPreResolveEventToPostResolveEvent()
+ {
+ $dispatcher = $this->createEventDispatcherMock();
+ $dispatcher
+ ->expects($this->at(0))
+ ->method('dispatch')
+ ->with(ImagineEvents::PRE_RESOLVE, $this->isInstanceOf('Liip\ImagineBundle\Events\CacheResolveEvent'))
+ ->will($this->returnCallback(function ($name, $event) {
+ $event->setPath('changed_path');
+ $event->setFilter('changed_filter');
+ }))
+ ;
+
+ $dispatcher
+ ->expects($this->at(1))
+ ->method('dispatch')
+ ->with(
+ ImagineEvents::POST_RESOLVE,
+ $this->logicalAnd(
+ $this->isInstanceOf('Liip\ImagineBundle\Events\CacheResolveEvent'),
+ $this->attributeEqualTo('path', 'changed_path'),
+ $this->attributeEqualTo('filter', 'changed_filter')
+ ))
+ ;
+
+ $cacheManager = new CacheManager(
+ $this->createFilterConfigurationMock(),
+ $this->createRouterMock(),
+ new UriSigner('secret'),
+ $dispatcher
+ );
+ $cacheManager->addResolver('default', $this->createResolverMock());
+
+ $cacheManager->resolve('cats.jpg', 'thumbnail');
+ }
+
+ public function testShouldReturnUrlChangedInPostResolveEvent()
+ {
+ $dispatcher = $this->createEventDispatcherMock();
+ $dispatcher
+ ->expects($this->at(1))
+ ->method('dispatch')
+ ->with(ImagineEvents::POST_RESOLVE, $this->isInstanceOf('Liip\ImagineBundle\Events\CacheResolveEvent'))
+ ->will($this->returnCallback(function ($name, $event) {
+ $event->setUrl('changed_url');
+ }))
+ ;
+
+ $cacheManager = new CacheManager(
+ $this->createFilterConfigurationMock(),
+ $this->createRouterMock(),
+ new UriSigner('secret'),
+ $dispatcher
+ );
+ $cacheManager->addResolver('default', $this->createResolverMock());
+
+ $url = $cacheManager->resolve('cats.jpg', 'thumbnail');
+
+ $this->assertEquals('changed_url', $url);
+ }
}