feature #9862 [FrameworkBundle] Added configuration for additionnal request formats (gquemener)
This PR was squashed before being merged into the 2.5-dev branch (closes #9862).
Discussion
----------
[FrameworkBundle] Added configuration for additionnal request formats
| Q | A
| ------------- | ---
| Bug fix? | no
| New feature? | yes
| BC breaks? | no
| Deprecations? | no
| Tests pass? | yes
| Fixed tickets | https://github.com/symfony/symfony/issues/8934
| License | MIT
| Doc PR | https://github.com/symfony/symfony-docs/pull/3402
Reopening of https://github.com/symfony/symfony/pull/8944
# TODO
- [x] Fix wrong xml configuration definition (Thanks @WouterJ)
- [x] Change configuration key `additional_formats` to a more meaningful one
- [x] Write documentation (new entry or replace http://symfony.com/doc/current/cookbook/request/mime_type.html ?)
Commits
-------
f90ba11
[FrameworkBundle] Added configuration for additionnal request formats
This commit is contained in:
commit
aca3271cb8
@ -85,6 +85,7 @@ class Configuration implements ConfigurationInterface
|
||||
$this->addProfilerSection($rootNode);
|
||||
$this->addRouterSection($rootNode);
|
||||
$this->addSessionSection($rootNode);
|
||||
$this->addRequestSection($rootNode);
|
||||
$this->addTemplatingSection($rootNode);
|
||||
$this->addTranslatorSection($rootNode);
|
||||
$this->addValidationSection($rootNode);
|
||||
@ -256,6 +257,35 @@ class Configuration implements ConfigurationInterface
|
||||
;
|
||||
}
|
||||
|
||||
private function addRequestSection(ArrayNodeDefinition $rootNode)
|
||||
{
|
||||
$rootNode
|
||||
->children()
|
||||
->arrayNode('request')
|
||||
->info('request configuration')
|
||||
->canBeUnset()
|
||||
->fixXmlConfig('format')
|
||||
->children()
|
||||
->arrayNode('formats')
|
||||
->useAttributeAsKey('name')
|
||||
->prototype('array')
|
||||
->beforeNormalization()
|
||||
->ifTrue(function ($v) { return is_array($v) && isset($v['mime_type']); })
|
||||
->then(function ($v) { return $v['mime_type']; })
|
||||
->end()
|
||||
->beforeNormalization()
|
||||
->ifTrue(function ($v) { return !is_array($v); })
|
||||
->then(function ($v) { return array($v); })
|
||||
->end()
|
||||
->prototype('scalar')->end()
|
||||
->end()
|
||||
->end()
|
||||
->end()
|
||||
->end()
|
||||
->end()
|
||||
;
|
||||
}
|
||||
|
||||
private function addTemplatingSection(ArrayNodeDefinition $rootNode)
|
||||
{
|
||||
$organizeUrls = function ($urls) {
|
||||
|
@ -91,6 +91,10 @@ class FrameworkExtension extends Extension
|
||||
$this->registerSessionConfiguration($config['session'], $container, $loader);
|
||||
}
|
||||
|
||||
if (isset($config['request'])) {
|
||||
$this->registerRequestConfiguration($config['request'], $container, $loader);
|
||||
}
|
||||
|
||||
$loader->load('security.xml');
|
||||
|
||||
if ($this->isConfigEnabled($container, $config['form'])) {
|
||||
@ -382,6 +386,24 @@ class FrameworkExtension extends Extension
|
||||
$container->setParameter('session.metadata.update_threshold', $config['metadata_update_threshold']);
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads the request configuration.
|
||||
*
|
||||
* @param array $config A session configuration array
|
||||
* @param ContainerBuilder $container A ContainerBuilder instance
|
||||
* @param XmlFileLoader $loader An XmlFileLoader instance
|
||||
*/
|
||||
private function registerRequestConfiguration(array $config, ContainerBuilder $container, XmlFileLoader $loader)
|
||||
{
|
||||
if ($config['formats']) {
|
||||
$loader->load('request.xml');
|
||||
$container
|
||||
->getDefinition('request.add_request_formats_listener')
|
||||
->replaceArgument(0, $config['formats'])
|
||||
;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads the templating configuration.
|
||||
*
|
||||
|
@ -0,0 +1,17 @@
|
||||
<?xml version="1.0" ?>
|
||||
|
||||
<container xmlns="http://symfony.com/schema/dic/services"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://symfony.com/schema/dic/services http://symfony.com/schema/dic/services/services-1.0.xsd">
|
||||
|
||||
<parameters>
|
||||
<parameter key="request.add_request_formats_listener.class">Symfony\Component\HttpKernel\EventListener\AddRequestFormatsListener</parameter>
|
||||
</parameters>
|
||||
|
||||
<services>
|
||||
<service id="request.add_request_formats_listener" class="%request.add_request_formats_listener.class%">
|
||||
<tag name="kernel.event_subscriber" />
|
||||
<argument/>
|
||||
</service>
|
||||
</services>
|
||||
</container>
|
@ -16,6 +16,7 @@
|
||||
<xsd:element name="profiler" type="profiler" minOccurs="0" maxOccurs="1" />
|
||||
<xsd:element name="router" type="router" minOccurs="0" maxOccurs="1" />
|
||||
<xsd:element name="session" type="session" minOccurs="0" maxOccurs="1" />
|
||||
<xsd:element name="request" type="request" 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="validation" type="validation" minOccurs="0" maxOccurs="1" />
|
||||
@ -101,6 +102,19 @@
|
||||
<xsd:attribute name="save-path" type="xsd:string" />
|
||||
</xsd:complexType>
|
||||
|
||||
<xsd:complexType name="request">
|
||||
<xsd:sequence>
|
||||
<xsd:element name="format" type="format" minOccurs="0" maxOccurs="unbounded" />
|
||||
</xsd:sequence>
|
||||
</xsd:complexType>
|
||||
|
||||
<xsd:complexType name="format">
|
||||
<xsd:choice minOccurs="1" maxOccurs="unbounded">
|
||||
<xsd:element name="mime-type" type="xsd:string" />
|
||||
</xsd:choice>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required"/>
|
||||
</xsd:complexType>
|
||||
|
||||
<xsd:complexType name="templating">
|
||||
<xsd:sequence>
|
||||
<xsd:element name="loader" type="xsd:string" minOccurs="0" maxOccurs="unbounded" />
|
||||
|
@ -70,5 +70,14 @@ $container->loadFromExtension('framework', array(
|
||||
'debug' => true,
|
||||
'file_cache_dir' => '%kernel.cache_dir%/annotations',
|
||||
),
|
||||
'ide' => 'file%%link%%format'
|
||||
'ide' => 'file%%link%%format',
|
||||
'request' => array(
|
||||
'formats' => array(
|
||||
'csv' => array(
|
||||
'text/csv',
|
||||
'text/plain',
|
||||
),
|
||||
'pdf' => 'application/pdf'
|
||||
)
|
||||
)
|
||||
));
|
||||
|
@ -0,0 +1,7 @@
|
||||
<?php
|
||||
|
||||
$container->loadFromExtension('framework', array(
|
||||
'request' => array(
|
||||
'formats' => array(),
|
||||
),
|
||||
));
|
@ -13,6 +13,15 @@
|
||||
<framework:profiler only-exceptions="true" enabled="false" />
|
||||
<framework:router resource="%kernel.root_dir%/config/routing.xml" type="xml" />
|
||||
<framework:session gc-maxlifetime="90000" gc-probability="1" gc-divisor="108" storage-id="session.storage.native" handler-id="session.handler.native_file" name="_SYMFONY" cookie-lifetime="86400" cookie-path="/" cookie-domain="example.com" cookie-secure="true" cookie-httponly="true" save-path="/path/to/sessions" />
|
||||
<framework:request>
|
||||
<framework:format name="csv">
|
||||
<framework:mime-type>text/csv</framework:mime-type>
|
||||
<framework:mime-type>text/plain</framework:mime-type>
|
||||
</framework:format>
|
||||
<framework:format name="pdf">
|
||||
<framework:mime-type>application/pdf</framework:mime-type>
|
||||
</framework:format>
|
||||
</framework:request>
|
||||
<framework:templating assets-version="SomeVersionScheme" cache="/path/to/cache" >
|
||||
<framework:loader>loader.foo</framework:loader>
|
||||
<framework:loader>loader.bar</framework:loader>
|
||||
|
@ -0,0 +1,11 @@
|
||||
<?xml version="1.0" ?>
|
||||
|
||||
<container xmlns="http://symfony.com/schema/dic/services"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xmlns:framework="http://symfony.com/schema/dic/symfony"
|
||||
xsi:schemaLocation="http://symfony.com/schema/dic/services http://symfony.com/schema/dic/services/services-1.0.xsd
|
||||
http://symfony.com/schema/dic/symfony http://symfony.com/schema/dic/symfony/symfony-1.0.xsd">
|
||||
<framework:config>
|
||||
<framework:request />
|
||||
</framework:config>
|
||||
</container>
|
@ -55,3 +55,7 @@ framework:
|
||||
debug: true
|
||||
file_cache_dir: %kernel.cache_dir%/annotations
|
||||
ide: file%%link%%format
|
||||
request:
|
||||
formats:
|
||||
csv: ['text/csv', 'text/plain']
|
||||
pdf: 'application/pdf'
|
||||
|
@ -0,0 +1,3 @@
|
||||
framework:
|
||||
request:
|
||||
formats: ~
|
@ -145,6 +145,22 @@ abstract class FrameworkExtensionTest extends TestCase
|
||||
$this->assertNull($container->getDefinition('session.storage.php_bridge')->getArgument(0));
|
||||
}
|
||||
|
||||
public function testRequest()
|
||||
{
|
||||
$container = $this->createContainerFromFile('full');
|
||||
|
||||
$this->assertTrue($container->hasDefinition('request.add_request_formats_listener'), '->registerRequestConfiguration() loads request.xml');
|
||||
$listenerDef = $container->getDefinition('request.add_request_formats_listener');
|
||||
$this->assertEquals(array('csv' => array('text/csv', 'text/plain'), 'pdf' => array('application/pdf')), $listenerDef->getArgument(0));
|
||||
}
|
||||
|
||||
public function testEmptyRequestFormats()
|
||||
{
|
||||
$container = $this->createContainerFromFile('request');
|
||||
|
||||
$this->assertFalse($container->hasDefinition('request.add_request_formats_listener'), '->registerRequestConfiguration() does not load request.xml when no request formats are defined');
|
||||
}
|
||||
|
||||
public function testTemplating()
|
||||
{
|
||||
$container = $this->createContainerFromFile('full');
|
||||
|
@ -0,0 +1,57 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\HttpKernel\EventListener;
|
||||
|
||||
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
|
||||
use Symfony\Component\HttpKernel\KernelEvents;
|
||||
use Symfony\Component\HttpKernel\Event\GetResponseEvent;
|
||||
|
||||
/**
|
||||
* Adds configured formats to each request
|
||||
*
|
||||
* @author Gildas Quemener <gildas.quemener@gmail.com>
|
||||
*/
|
||||
class AddRequestFormatsListener implements EventSubscriberInterface
|
||||
{
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
protected $formats;
|
||||
|
||||
/**
|
||||
* @param array $formats
|
||||
*/
|
||||
public function __construct(array $formats)
|
||||
{
|
||||
$this->formats = $formats;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds request formats
|
||||
*
|
||||
* @param GetResponseEvent $event
|
||||
*/
|
||||
public function onKernelRequest(GetResponseEvent $event)
|
||||
{
|
||||
foreach ($this->formats as $format => $mimeTypes) {
|
||||
$event->getRequest()->setFormat($format, $mimeTypes);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public static function getSubscribedEvents()
|
||||
{
|
||||
return array(KernelEvents::REQUEST => 'onKernelRequest');
|
||||
}
|
||||
}
|
@ -0,0 +1,83 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\HttpKernel\Tests\EventListener;
|
||||
|
||||
use Symfony\Component\HttpKernel\EventListener\AddRequestFormatsListener;
|
||||
use Symfony\Component\HttpFoundation\Request;
|
||||
use Symfony\Component\HttpKernel\KernelEvents;
|
||||
|
||||
/**
|
||||
* Test AddRequestFormatsListener class
|
||||
*
|
||||
* @author Gildas Quemener <gildas.quemener@gmail.com>
|
||||
*/
|
||||
class AddRequestFormatsListenerTest extends \PHPUnit_Framework_TestCase
|
||||
{
|
||||
/**
|
||||
* @var AddRequestFormatsListener
|
||||
*/
|
||||
private $listener;
|
||||
|
||||
protected function setUp()
|
||||
{
|
||||
$this->listener = new AddRequestFormatsListener(array('csv' => array('text/csv', 'text/plain')));
|
||||
}
|
||||
|
||||
protected function tearDown()
|
||||
{
|
||||
$this->listener = null;
|
||||
}
|
||||
|
||||
public function testIsAnEventSubscriber()
|
||||
{
|
||||
$this->assertInstanceOf('Symfony\Component\EventDispatcher\EventSubscriberInterface', $this->listener);
|
||||
}
|
||||
|
||||
public function testRegisteredEvent()
|
||||
{
|
||||
$this->assertEquals(
|
||||
array(KernelEvents::REQUEST => 'onKernelRequest'),
|
||||
AddRequestFormatsListener::getSubscribedEvents()
|
||||
);
|
||||
}
|
||||
|
||||
public function testSetAdditionalFormats()
|
||||
{
|
||||
$request = $this->getRequestMock();
|
||||
$event = $this->getGetResponseEventMock($request);
|
||||
|
||||
$request->expects($this->once())
|
||||
->method('setFormat')
|
||||
->with('csv', array('text/csv', 'text/plain'));
|
||||
|
||||
$this->listener->onKernelRequest($event);
|
||||
}
|
||||
|
||||
protected function getRequestMock()
|
||||
{
|
||||
return $this->getMock('Symfony\Component\HttpFoundation\Request');
|
||||
}
|
||||
|
||||
protected function getGetResponseEventMock(Request $request)
|
||||
{
|
||||
$event = $this
|
||||
->getMockBuilder('Symfony\Component\HttpKernel\Event\GetResponseEvent')
|
||||
->disableOriginalConstructor()
|
||||
->getMock();
|
||||
|
||||
$event->expects($this->any())
|
||||
->method('getRequest')
|
||||
->will($this->returnValue($request));
|
||||
|
||||
return $event;
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user