Skip to content

Instantly share code, notes, and snippets.

@stevelacey
Created March 7, 2013 10:59
Show Gist options
  • Save stevelacey/5107279 to your computer and use it in GitHub Desktop.
Save stevelacey/5107279 to your computer and use it in GitHub Desktop.
/** * @route("/{permalink}", name="category", requirements={"permalink": ".+"}) */
<?php
namespace WiredMedia\CatalogBundle\Request\ParamConverter;
use Sensio\Bundle\FrameworkExtraBundle\Request\ParamConverter\DoctrineParamConverter;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\ConfigurationInterface;
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
use Symfony\Component\HttpFoundation\Request;
use Doctrine\Common\Persistence\ManagerRegistry;
use Doctrine\ORM\Query\ResultSetMappingBuilder;
use JMS\DiExtraBundle\Annotation\Service;
use JMS\DiExtraBundle\Annotation\Tag;
use JMS\DiExtraBundle\Annotation\InjectParams;
use JMS\DiExtraBundle\Annotation\Inject;
/**
* CatalogParamConverter.
*
* @Service
* @Tag("request.param_converter", attributes = {"priority" = 1})
*
* @author Steve Lacey <steve.lacey@wiredmedia.co.uk>
*/
class CatalogParamConverter extends DoctrineParamConverter
{
/**
* @InjectParams({
* "registry" = @Inject("doctrine")
* })
*/
public function __construct(ManagerRegistry $registry = null)
{
$this->registry = $registry;
}
public function apply(Request $request, ConfigurationInterface $configuration)
{
$name = $configuration->getName();
$class = $configuration->getClass();
$options = $this->getOptions($configuration);
if (false === $object = $this->findOneByPermalink($class, $request, $options)) {
if ($configuration->isOptional()) {
$object = null;
} else {
throw new \LogicException('Unable to guess how to get a Doctrine instance from the request information.');
}
}
if (null === $object && false === $configuration->isOptional()) {
throw new NotFoundHttpException(sprintf('%s object not found.', $class));
}
$request->attributes->set($name, $object);
return true;
}
protected function findOneByPermalink($class, Request $request, $options)
{
if (!$options['mapping']) {
$keys = $request->attributes->keys();
$options['mapping'] = $keys ? array_combine($keys, $keys) : array();
}
foreach ($options['exclude'] as $exclude) {
unset($options['mapping'][$exclude]);
}
if ($options['mapping'] && array_key_exists('permalink', $options['mapping'])) {
$permalink = $request->attributes->get('permalink');
} else {
return false;
}
$em = $this->registry->getManager($options['entity_manager']);
return $em->createQuery('
select c from '.$class.' c where (
select permalink(a.slug) from '.$class.' a where a.lft <= c.lft and a.rgt >= c.rgt and a.root = c.root
) = :permalink
')
->setParameter('permalink', $permalink)
->getOneOrNullResult()
;
}
public function supports(ConfigurationInterface $configuration)
{
if ('WiredMedia\CatalogBundle\Entity\Category' !== $configuration->getClass()) {
return false;
}
return parent::supports($configuration);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment