-
Notifications
You must be signed in to change notification settings - Fork 15
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #14 from jolicode/feature/13-use-exception-event
Replace image using Kernel event listener 🚿
- Loading branch information
Showing
8 changed files
with
244 additions
and
214 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,76 @@ | ||
<?php | ||
|
||
/* | ||
* This file is part of the GifExceptionBundle Project. | ||
* | ||
* (c) Loïck Piera <[email protected]> | ||
*/ | ||
|
||
namespace Joli\GifExceptionBundle\DependencyInjection; | ||
|
||
use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface; | ||
use Symfony\Component\DependencyInjection\ContainerBuilder; | ||
use Symfony\Component\DependencyInjection\Definition; | ||
use Symfony\Component\DependencyInjection\Reference; | ||
use Symfony\Component\HttpKernel\DependencyInjection\Extension; | ||
use Symfony\Component\HttpKernel\KernelEvents; | ||
|
||
class GifExceptionExtension extends Extension implements CompilerPassInterface | ||
{ | ||
/** | ||
* {@inheritdoc} | ||
*/ | ||
public function load(array $configs, ContainerBuilder $container) | ||
{ | ||
if (!$container->getParameter('kernel.debug')) { | ||
return; | ||
} | ||
|
||
$definition = new Definition('Joli\GifExceptionBundle\EventListener\ReplaceImageListener'); | ||
$definition->addTag('kernel.event_listener', array( | ||
'event' => KernelEvents::RESPONSE, | ||
'priority' => -1000, | ||
)); | ||
|
||
$gifs = array(); | ||
|
||
$pattern = __DIR__ . '/../Resources/public/images/*/*.gif'; | ||
foreach (glob($pattern) as $path) { | ||
$gifs[basename(dirname($path))][] = basename($path); | ||
} | ||
|
||
$pattern = __DIR__ . '/../Resources/public/images/other/*.gif'; | ||
foreach (glob($pattern) as $path) { | ||
$gifs['other'][] = basename($path); | ||
} | ||
|
||
// Set first argument. Next ones will be added by the compiler pass. | ||
$definition->addArgument($gifs); | ||
$container->setDefinition('gif_exception.listener.replace_image', $definition); | ||
} | ||
|
||
/** | ||
* This CompilerPassInterface method completes the listener definition with | ||
* the parameter and service coming from other bundles. It allows our | ||
* bundle to be registered anytime before or after others. | ||
* | ||
* {@inheritdoc} | ||
*/ | ||
public function process(ContainerBuilder $container) | ||
{ | ||
$definition = $container->getDefinition('gif_exception.listener.replace_image'); | ||
|
||
$definition->addArgument($container->getParameter('twig.exception_listener.controller')); | ||
|
||
if ($container->has('assets.packages')) { | ||
// New Asset component to generate asset url (SF >=2.8) | ||
$definition->addArgument(new Reference('assets.packages')); | ||
$definition->addArgument(null); | ||
} elseif ($container->has('templating.helper.assets')) { | ||
// Old way of generating asset url (SF ~2.3) | ||
$definition->addArgument(null); | ||
$definition->addArgument(new Reference('templating.helper.assets')); | ||
$definition->setScope('request'); | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,141 @@ | ||
<?php | ||
|
||
/* | ||
* This file is part of the GifExceptionBundle Project. | ||
* | ||
* (c) Loïck Piera <[email protected]> | ||
*/ | ||
|
||
namespace Joli\GifExceptionBundle\EventListener; | ||
|
||
use Symfony\Component\Asset\Packages; | ||
use Symfony\Component\HttpKernel\Event\FilterResponseEvent; | ||
use Symfony\Component\HttpKernel\HttpKernelInterface; | ||
use Symfony\Component\Templating\Helper\CoreAssetsHelper; | ||
|
||
class ReplaceImageListener | ||
{ | ||
const IMAGES_DIR = '../../Resources/public/images'; | ||
|
||
/** @var string[][] */ | ||
private $gifs; | ||
|
||
/** @var string */ | ||
private $exceptionController; | ||
|
||
/** @var Packages **/ | ||
private $packages; | ||
|
||
/** @var CoreAssetsHelper **/ | ||
private $coreAssetsHelper; | ||
|
||
/** | ||
* @param string[][] $gifs | ||
* @param string $exceptionController | ||
* @param Packages $packages | ||
* @param CoreAssetsHelper $coreAssetsHelper | ||
*/ | ||
public function __construct(array $gifs, $exceptionController, Packages $packages = null, CoreAssetsHelper $coreAssetsHelper = null) | ||
{ | ||
$this->gifs = $gifs; | ||
$this->exceptionController = $exceptionController; | ||
$this->packages = $packages; | ||
$this->coreAssetsHelper = $coreAssetsHelper; | ||
} | ||
|
||
/** | ||
* Handle the response for exception and replace the little Phantom by a random Gif. | ||
* | ||
* @param FilterResponseEvent $event | ||
*/ | ||
public function onKernelResponse(FilterResponseEvent $event) | ||
{ | ||
// $event->isMasterRequest() method was added in Symfony 2.4 | ||
if (HttpKernelInterface::MASTER_REQUEST === $event->getRequestType() | ||
|| $event->getRequest()->attributes->get('_controller') !== $this->exceptionController) { | ||
return; | ||
} | ||
|
||
// Status code is not set by the exception controller but only by the | ||
// kernel at the very end. | ||
// So lets use the status code from the flatten exception instead. | ||
$statusCode = $event->getRequest()->attributes->get('exception')->getStatusCode(); | ||
|
||
$dir = $this->getGifDir($statusCode); | ||
$gif = $this->getRandomGif($dir); | ||
$url = $this->getGifUrl($dir, $gif); | ||
|
||
$content = $event->getResponse()->getContent(); | ||
|
||
$content = preg_replace( | ||
'/<img alt="Exception detected!" src=".*" \/>/', | ||
sprintf('<img alt="Exception detected!" src="%s" data-gif style="width:145px" />', $url), | ||
$content | ||
); | ||
|
||
$event->getResponse()->setContent($content); | ||
} | ||
|
||
/** | ||
* Return the gif folder for the given status code. | ||
* | ||
* @param int $statusCode | ||
* | ||
* @return string | ||
*/ | ||
private function getGifDir($statusCode) | ||
{ | ||
if (array_key_exists($statusCode, $this->gifs) && count($this->gifs[$statusCode]) > 0) { | ||
return $statusCode; | ||
} | ||
|
||
return 'other'; | ||
} | ||
|
||
/** | ||
* Return a random gif name for the given directory. | ||
* | ||
* @param string $dir | ||
* | ||
* @return string | ||
*/ | ||
private function getRandomGif($dir) | ||
{ | ||
$imageIndex = rand(0, count($this->gifs[$dir]) - 1); | ||
|
||
return $this->gifs[$dir][$imageIndex]; | ||
} | ||
|
||
/** | ||
* Return a the url of given gif in the given directory. | ||
* | ||
* @param string $dir | ||
* @param string $gif | ||
* | ||
* @return string | ||
*/ | ||
private function getGifUrl($dir, $gif) | ||
{ | ||
return $this->generateUrl(sprintf('bundles/gifexception/images/%s/%s', $dir, $gif)); | ||
} | ||
|
||
/** | ||
* Generate an url in both Symfony 2 and Symfony 3 compatible ways. | ||
* | ||
* @param string $url | ||
* | ||
* @return string | ||
*/ | ||
private function generateUrl($url) | ||
{ | ||
if ($this->packages) { | ||
return $this->packages->getUrl($url); | ||
} | ||
|
||
if ($this->coreAssetsHelper) { | ||
return $this->coreAssetsHelper->getUrl($url); | ||
} | ||
|
||
return $url; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.