Skip to content

Commit

Permalink
Merge pull request #14 from jolicode/feature/13-use-exception-event
Browse files Browse the repository at this point in the history
Replace image using Kernel event listener 🚿
  • Loading branch information
pyrech committed Mar 12, 2016
2 parents 6417a38 + 889a4b4 commit 9040378
Show file tree
Hide file tree
Showing 8 changed files with 244 additions and 214 deletions.
5 changes: 3 additions & 2 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ matrix:
include:
- php: hhvm
- php: 5.3
env: deps=low
- php: 5.4
- php: 5.5
- php: 5.6
Expand All @@ -22,8 +23,8 @@ matrix:
env: deps=low

install:
- if [ "$deps" = "low" ]; then composer --prefer-source --prefer-lowest update; fi;
- if [ "$deps" != "low" ]; then composer --prefer-source update; fi;
- if [ "$deps" = "low" ]; then composer update --prefer-dist --prefer-lowest; fi;
- if [ "$deps" != "low" ]; then composer update --prefer-dist; fi;

script:
- make test
57 changes: 0 additions & 57 deletions DependencyInjection/Compiler/PrepareTwigPass.php

This file was deleted.

76 changes: 76 additions & 0 deletions DependencyInjection/GifExceptionExtension.php
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');
}
}
}
141 changes: 141 additions & 0 deletions EventListener/ReplaceImageListener.php
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;
}
}
4 changes: 1 addition & 3 deletions GifExceptionBundle.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,6 @@

namespace Joli\GifExceptionBundle;

use Joli\GifExceptionBundle\DependencyInjection\Compiler\PrepareTwigPass;
use Symfony\Component\DependencyInjection\Compiler\PassConfig;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\HttpKernel\Bundle\Bundle;

Expand All @@ -19,7 +17,7 @@ public function build(ContainerBuilder $container)
{
parent::build($container);

$container->addCompilerPass(new PrepareTwigPass(), PassConfig::TYPE_BEFORE_REMOVING);
$container->addCompilerPass($this->getContainerExtension());
}

public function getParent()
Expand Down
Loading

0 comments on commit 9040378

Please sign in to comment.