removed parameter converters as decided during IRC meeting (supported is still provided by FrameworkExtraBundle)

You must remove the configuration element if you had enabled the feature:

         <app:param-converter />
This commit is contained in:
Fabien Potencier 2011-01-29 14:58:48 +01:00
parent 36e30e21cd
commit 025e142dd4
13 changed files with 0 additions and 690 deletions

View File

@ -1,104 +0,0 @@
<?php
/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien.potencier@symfony-project.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Symfony\Bundle\DoctrineBundle\Request\ParamConverter;
use Symfony\Bundle\FrameworkBundle\Request\ParamConverter\ConverterInterface;
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
use Symfony\Component\HttpFoundation\Request;
use Doctrine\ORM\NoResultException;
use Doctrine\ORM\EntityManager;
use Doctrine\ORM\Mapping\MappingException;
/**
* DoctrineConverter.
*
* @author Fabien Potencier <fabien.potencier@symfony-project.com>
*/
class DoctrineConverter implements ConverterInterface
{
protected $manager;
public function __construct(EntityManager $manager)
{
$this->manager = $manager;
}
/**
* Convert the \ReflectionParameter to something else.
*
* @param Request $request
* @param \ReflectionParameter $property
*/
public function apply(Request $request, \ReflectionParameter $parameter)
{
$class = $parameter->getClass()->getName();
// find by identifier?
if (false === $object = $this->find($class, $request)) {
// find by criteria
if (false === $object = $this->findOneBy($class, $request)) {
throw new \LogicException('Unable to guess how to get a Doctrine instance from the request information.');
}
}
if (null === $object) {
throw new NotFoundHttpException(sprintf('%s object not found.', $class));
}
$request->attributes->set($parameter->getName(), $object);
}
protected function find($class, Request $request)
{
if (!$request->attributes->has('id')) {
return false;
}
return $this->manager->getRepository($class)->find($request->attributes->get('id'));
}
protected function findOneBy($class, Request $request)
{
$criteria = array();
$metadata = $this->manager->getClassMetadata($class);
foreach ($request->attributes->all() as $key => $value) {
if ($metadata->hasField($key)) {
$criteria[$key] = $value;
}
}
if (!$criteria) {
return false;
}
return $this->manager->getRepository($class)->findOneBy($criteria);
}
/**
* Returns boolean true if the ReflectionClass is supported, false otherwise
*
* @param \ReflectionParameter $parameter
*
* @return Boolean
*/
public function supports(\ReflectionClass $class)
{
// Doctrine Entity?
try {
$this->manager->getClassMetadata($class->getName());
return true;
} catch (MappingException $e) {
return false;
}
}
}

View File

@ -58,11 +58,6 @@
<service id="security.user.entity_manager" alias="doctrine.orm.default_entity_manager" public="false" />
<service id="request.param_converter.doctrine" class="Symfony\Bundle\DoctrineBundle\Request\ParamConverter\DoctrineConverter" public="false">
<tag name="request.param_converter" />
<argument type="service" id="doctrine.orm.default_entity_manager" />
</service>
<service id="doctrine.orm.proxy_cache_warmer" class="%doctrine.orm.proxy_cache_warmer.class%" public="false">
<tag name="kernel.cache_warmer" />
<argument type="service" id="service_container" />

View File

@ -1,197 +0,0 @@
<?php
/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien.potencier@symfony-project.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Symfony\Bundle\FrameworkBundle\Tests\Request\ParamConverter;
use Doctrine\ORM\Tools\SchemaTool;
use Doctrine\Common\Collections\ArrayCollection;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Bundle\DoctrineBundle\Tests\TestCase;
use Symfony\Bundle\DoctrineBundle\Request\ParamConverter\DoctrineConverter;
class DoctrineConverterTest extends TestCase
{
/**
* @var EntityManager
*/
protected $em;
protected function setUp()
{
parent::setUp();
$this->em = $this->createTestEntityManager();
$schemaTool = new SchemaTool($this->em);
$classes = array($this->em->getClassMetadata(__NAMESPACE__.'\Article'));
try {
$schemaTool->dropSchema($classes);
} catch(\Exception $e) {
}
try {
$schemaTool->createSchema($classes);
} catch(\Exception $e) {
}
}
public function testSupports()
{
$converter = new DoctrineConverter($this->em);
$this->assertTrue($converter->supports(new \ReflectionClass(__NAMESPACE__.'\Article')));
$this->assertFalse($converter->supports(new \ReflectionClass('stdClass')));
}
public function testFindEntityByIdentifier()
{
$articles = $this->createArticleFixtures();
$converter = new DoctrineConverter($this->em);
$reflectionParam = new \ReflectionParameter(array(__NAMESPACE__.'\ArticleController', 'showAction'), 0);
$request = $this->buildRequestWithAttributes(array('id' => $articles->get(2)->id));
$converter->apply($request, $reflectionParam);
$article = $request->attributes->get($reflectionParam->getName());
$this->assertTrue($article instanceof Article);
$this->assertEquals($articles->get(2), $article);
}
/**
* @expectedException Symfony\Component\HttpKernel\Exception\NotFoundHttpException
*/
public function testFindEntityByIdentifierWithInvalidId()
{
$articles = $this->createArticleFixtures();
$converter = new DoctrineConverter($this->em);
$reflectionParam = new \ReflectionParameter(array(__NAMESPACE__.'\ArticleController', 'showAction'), 0);
$request = $this->buildRequestWithAttributes(array('id' => $articles->get(4)->id+1));
$converter->apply($request, $reflectionParam);
}
public function testFindEntityByField()
{
$articles = $this->createArticleFixtures();
$converter = new DoctrineConverter($this->em);
$reflectionParam = new \ReflectionParameter(array(__NAMESPACE__.'\ArticleController', 'showAction'), 0);
$request = $this->buildRequestWithAttributes(array('name' => $articles->get(4)->name));
$converter->apply($request, $reflectionParam);
$article = $request->attributes->get($reflectionParam->getName());
$this->assertTrue($article instanceof Article);
$this->assertEquals($articles->get(4), $article);
}
public function testFindEntityByFields()
{
$articles = $this->createArticleFixtures();
$converter = new DoctrineConverter($this->em);
$reflectionParam = new \ReflectionParameter(array(__NAMESPACE__.'\ArticleController', 'showAction'), 0);
$request = $this->buildRequestWithAttributes(array(
'name' => $articles->get(2)->name,
'author' => $articles->get(2)->author,
));
$converter->apply($request, $reflectionParam);
$article = $request->attributes->get($reflectionParam->getName());
$this->assertTrue($article instanceof Article);
$this->assertEquals($articles->get(2), $article);
}
/**
* @expectedException LogicException
*/
public function testCannotFindEntityByFieldWithInvalidFieldName()
{
$articles = $this->createArticleFixtures();
$converter = new DoctrineConverter($this->em);
$reflectionParam = new \ReflectionParameter(array(__NAMESPACE__.'\ArticleController', 'showAction'), 0);
$request = $this->buildRequestWithAttributes(array('title' => 'foo'));
$converter->apply($request, $reflectionParam);
}
/**
* @expectedException Symfony\Component\HttpKernel\Exception\NotFoundHttpException
*/
public function testCannotFindEntityByFieldWithInvalidFieldValue()
{
$articles = $this->createArticleFixtures();
$converter = new DoctrineConverter($this->em);
$reflectionParam = new \ReflectionParameter(array(__NAMESPACE__.'\ArticleController', 'showAction'), 0);
$request = $this->buildRequestWithAttributes(array('name' => 'foooo'));
$converter->apply($request, $reflectionParam);
}
protected function createArticleFixtures()
{
$articles = new ArrayCollection();
$articles->add(new Article('foo', 'toto'));
$articles->add(new Article('bar', 'toto'));
$articles->add(new Article('bar', 'titi'));
$articles->add(new Article('foo', 'titi'));
$articles->add(new Article('barfoo', 'tata'));
foreach ($articles as $article) {
$this->em->persist($article);
}
$this->em->flush();
$this->em->clear();
return $articles;
}
protected function buildRequestWithAttributes(array $attributes)
{
return new Request(array(), array(), $attributes);
}
}
/**
* @Entity
*/
class Article
{
/**
* @Id
* @Column(type="integer")
* @GeneratedValue(strategy="AUTO")
*/
public $id;
/**
* @Column(type="string")
*/
public $name;
/**
* @Column(type="string")
*/
public $author;
public function __construct($name, $author)
{
$this->name = $name;
$this->author = $author;
}
}
class ArticleController
{
public function showAction(Article $article)
{
}
}

View File

@ -1,76 +0,0 @@
<?php
/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien.potencier@symfony-project.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Symfony\Bundle\FrameworkBundle\Controller;
use Symfony\Bundle\FrameworkBundle\Request\ParamConverter\ConverterManager;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Symfony\Component\EventDispatcher\EventInterface;
/**
* Converts \ReflectionParameters for Controller actions into Objects if the \ReflectionParameter have a class
* (Typehinted).
*
* The filterController method must be connected to the core.controller event.
*
* @author Fabien Potencier <fabien.potencier@symfony-project.org>
* @author Henrik Bjornskov <hb@peytz.dk>
*/
class ParamConverterListener
{
/**
* @var ConverterManager
*/
protected $manager;
/**
* @param ConverterManager $manager
*/
public function __construct(ConverterManager $manager)
{
$this->manager = $manager;
}
/**
* @param EventInterface $event
* @param mixed $controller
*
* @return mixed
*
* @throws NotFoundHttpException
*/
public function filterController(EventInterface $event, $controller)
{
if (!is_array($controller)) {
return $controller;
}
$request = $event->get('request');
$method = new \ReflectionMethod($controller[0], $controller[1]);
foreach ($method->getParameters() as $param) {
if (null !== $param->getClass() && false === $request->attributes->has($param->getName())) {
try {
$this->manager->apply($request, $param);
} catch (\InvalidArgumentException $e) {
if (false === $param->isOptional()) {
throw new NotFoundHttpException(sprintf('Unable to convert parameter "%s".', $param->getName()), $e);
}
}
}
}
return $controller;
}
}

View File

@ -1,43 +0,0 @@
<?php
/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien.potencier@symfony-project.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Symfony\Bundle\FrameworkBundle\DependencyInjection\Compiler;
use Symfony\Component\DependencyInjection\Reference;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
/**
* Adds tagged request.param_converter to request.param_converter.manager service
*
* @author Henrik Bjornskov <hb@peytz.dk>
*/
class ConverterManagerPass implements CompilerPassInterface
{
/**
* Adds ParamConverters to ConverterManager
*
* @param ContainerBuilder $container
*/
public function process(ContainerBuilder $container)
{
if (false === $container->hasDefinition('request.param_converter.manager')) {
return;
}
$definition = $container->getDefinition('request.param_converter.manager');
foreach ($container->findTaggedServiceIds('request.param_converter') as $serviceId => $attributes) {
$priority = isset($attributes[0]['priority']) ? $attributes[0]['priority'] : 0;
$definition->addMethodCall('add', array(new Reference($serviceId), $priority));
}
}
}

View File

@ -141,10 +141,6 @@ class FrameworkExtension extends Extension
$this->registerTestConfiguration($config, $container);
}
if (array_key_exists('param_converter', $config) || array_key_exists('param-converter', $config)) {
$this->registerParamConverterConfiguration($config, $container);
}
if (array_key_exists('session', $config)) {
$this->registerSessionConfiguration($config, $container);
}
@ -192,18 +188,6 @@ class FrameworkExtension extends Extension
));
}
/**
* Loads the parameter converter configuration.
*
* @param array $config An array of configuration settings
* @param ContainerBuilder $container A ContainerBuilder instance
*/
protected function registerParamConverterConfiguration(array $config, ContainerBuilder $container)
{
$loader = new XmlFileLoader($container, __DIR__.'/../Resources/config');
$loader->load('param_converter.xml');
}
/**
* Loads the templating configuration.
*

View File

@ -15,7 +15,6 @@ use Symfony\Bundle\FrameworkBundle\DependencyInjection\Compiler\AddConstraintVal
use Symfony\Bundle\FrameworkBundle\DependencyInjection\Compiler\AddFieldFactoryGuessersPass;
use Symfony\Bundle\FrameworkBundle\DependencyInjection\Compiler\TemplatingPass;
use Symfony\Bundle\FrameworkBundle\DependencyInjection\Compiler\RegisterKernelListenersPass;
use Symfony\Bundle\FrameworkBundle\DependencyInjection\Compiler\ConverterManagerPass;
use Symfony\Bundle\FrameworkBundle\DependencyInjection\Compiler\RoutingResolverPass;
use Symfony\Bundle\FrameworkBundle\DependencyInjection\Compiler\ProfilerPass;
use Symfony\Bundle\FrameworkBundle\DependencyInjection\Compiler\AddClassesToCachePass;
@ -70,7 +69,6 @@ class FrameworkBundle extends Bundle
$container->addScope('request');
$container->addCompilerPass(new ConverterManagerPass());
$container->addCompilerPass(new RoutingResolverPass());
$container->addCompilerPass(new ProfilerPass());
$container->addCompilerPass(new RegisterKernelListenersPass());

View File

@ -1,34 +0,0 @@
<?php
/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien.potencier@symfony-project.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Symfony\Bundle\FrameworkBundle\Request\ParamConverter;
use Symfony\Component\HttpFoundation\Request;
interface ConverterInterface
{
/**
* Convert the \ReflectionParameter to something else.
*
* @param Request $request
* @param \ReflectionParameter $property
*/
function apply(Request $request, \ReflectionParameter $parameter);
/**
* Returns boolean true if the ReflectionClass is supported, false otherwise
*
* @param \ReflectionParameter $parameter
*
* @return Boolean
*/
function supports(\ReflectionClass $class);
}

View File

@ -1,91 +0,0 @@
<?php
/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien.potencier@symfony-project.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Symfony\Bundle\FrameworkBundle\Request\ParamConverter;
use Symfony\Bundle\FrameworkBundle\Request\ParamConverter\ConverterInterface;
use Symfony\Component\HttpFoundation\Request;
/**
* Keeps track of param converters.
*
* @author Fabien Potencier <fabien.potencier@symfony-project.com>
* @author Henrik Bjornskov <hb@peytz.dk>
*/
class ConverterManager
{
/**
* @var array
*/
protected $converters = array();
/**
* Cycles through all converters and if a converter supports the class it applies
* the converter. If no converter matches the ReflectionParameters::getClass() value
* a InvalidArgumentException is thrown.
*
* @param Request $request
* @param array $reflectionParam An array of ReflectionParameter objects
*
* @throws InvalidArgumentException
*/
public function apply(Request $request, \ReflectionParameter $reflectionParam)
{
$converted = false;
$converters = $this->all();
$reflectionClass = $reflectionParam->getClass();
foreach ($this->all() as $converter) {
if ($converter->supports($reflectionClass)) {
$converter->apply($request, $reflectionParam);
$converted = true;
break;
}
}
if (true !== $converted) {
throw new \InvalidArgumentException(sprintf('Could not convert attribute "%s" into an instance of "%s"', $reflectionParam->getName(), $reflectionClass->getName()));
}
}
/**
* Add a converter
*
* @param ConverterInterface $converter
* @param integer $prioriry = 0
*/
public function add(ConverterInterface $converter, $priority = 0)
{
if (!isset($this->converters[$priority])) {
$this->converters[$priority] = array();
}
$this->converters[$priority][] = $converter;
}
/**
* Returns all converters sorted after their priorities
*
* @return array
*/
public function all()
{
$all = $this->converters;
$converters = array();
krsort($this->converters);
foreach ($all as $c) {
$converters = array_merge($converters, $c);
}
return $converters;
}
}

View File

@ -1,22 +0,0 @@
<?xml version="1.0" ?>
<container xmlns="http://www.symfony-project.org/schema/dic/services"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.symfony-project.org/schema/dic/services http://www.symfony-project.org/schema/dic/services/services-1.0.xsd">
<parameters>
<parameter key="request.param_converter.manager.class">Symfony\Bundle\FrameworkBundle\Request\ParamConverter\ConverterManager</parameter>
<parameter key="request.param_converter.listener.class">Symfony\Bundle\FrameworkBundle\Controller\ParamConverterListener</parameter>
</parameters>
<services>
<!-- ConverterManager -->
<service id="request.param_converter.manager" class="%request.param_converter.manager.class%" public="false" />
<!-- ParamConverterListener -->
<service id="request.param_converter.listener" class="%request.param_converter.listener.class%">
<tag name="kernel.listener" event="core.controller" method="filterController" />
<argument type="service" id="request.param_converter.manager" />
</service>
</services>
</container>

View File

@ -15,7 +15,6 @@
<xsd:element name="session" type="session" minOccurs="0" maxOccurs="1" />
<xsd:element name="templating" type="templating" minOccurs="0" maxOccurs="1" />
<xsd:element name="translator" type="translator" minOccurs="0" maxOccurs="1" />
<xsd:element name="param-converter" type="param-converter" minOccurs="0" maxOccurs="1" />
<xsd:element name="csrf-protection" type="csrf_protection" minOccurs="0" maxOccurs="1" />
<xsd:element name="esi" type="esi" minOccurs="0" maxOccurs="1" />
</xsd:all>
@ -88,9 +87,6 @@
<xsd:attribute name="fallback" type="xsd:string" />
</xsd:complexType>
<xsd:complexType name="param-converter">
</xsd:complexType>
<xsd:complexType name="csrf_protection">
<xsd:attribute name="enabled" type="xsd:boolean" />
<xsd:attribute name="field-name" type="xsd:string" />

View File

@ -1,86 +0,0 @@
<?php
/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien.potencier@symfony-project.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Symfony\Bundle\FrameworkBundle\Tests\Request\ParamConverter;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Bundle\FrameworkBundle\Request\ParamConverter\ConverterManager;
class ConverterManagerTest extends \PHPUnit_Framework_TestCase
{
public function testManagerCanContainerConverters()
{
$manager = new ConverterManager();
$importantConverter = $this->getConverterInterfaceMock();
$lessImportantConverter = $this->getConverterInterfaceMock();
$manager->add($importantConverter, 10);
$this->assertEquals($manager->all(), array($importantConverter));
$manager->add($lessImportantConverter);
$this->assertEquals($manager->all(), array(
$importantConverter,
$lessImportantConverter,
));
}
/**
* @expectedException InvalidArgumentException
*/
public function testManagerCantApplyConvertersAndThrowsException()
{
$request = new Request();
$parameter = $this->getReflectionParameter();
$converter = $this->getConverterInterfaceMock();
$converter->expects($this->once())
->method('supports')
->with($parameter->getClass())
->will($this->returnValue(false));
$manager = new ConverterManager();
$manager->add($converter);
$manager->apply($request, $parameter);
}
public function testManagerWillApplyConvertersSuccessfully()
{
$request = new Request();
$parameter = $this->getReflectionParameter();
$converter = $this->getConverterInterfaceMock();
$converter->expects($this->once())
->method('supports')
->with($parameter->getClass())
->will($this->returnValue(true));
$converter->expects($this->once())
->method('apply')
->with($request, $parameter)
->will($this->returnValue(null));
$manager = new ConverterManager();
$manager->add($converter);
$manager->apply($request, $parameter);
}
private function getReflectionParameter()
{
return new \ReflectionParameter(array('Symfony\Bundle\FrameworkBundle\Tests\Request\ParamConverter\Fixtures\ConvertableObject', 'typehintedMethod'), 'object');
}
private function getConverterInterfaceMock()
{
return $this->getMock('Symfony\Bundle\FrameworkBundle\Request\ParamConverter\ConverterInterface');
}
}

View File

@ -1,10 +0,0 @@
<?php
namespace Symfony\Bundle\FrameworkBundle\Tests\Request\ParamConverter\Fixtures;
class ConvertableObject
{
public function typehintedMethod(ConvertableObject $object)
{
}
}