Skip to content
Browse files

feature #9862 [FrameworkBundle] Added configuration for additionnal r…

…equest 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 | #8934
| License       | MIT
| Doc PR        |  symfony/symfony-docs#3402

Reopening of #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
  • Loading branch information...
2 parents 6e9358a + f90ba11 commit aca3271cb8b9583692ca33b2cac9620b44a45599 @fabpot fabpot committed Feb 20, 2014
View
30 src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Configuration.php
@@ -85,6 +85,7 @@ public function getConfigTreeBuilder()
$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 @@ private function addSessionSection(ArrayNodeDefinition $rootNode)
;
}
+ 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) {
View
22 src/Symfony/Bundle/FrameworkBundle/DependencyInjection/FrameworkExtension.php
@@ -91,6 +91,10 @@ public function load(array $configs, ContainerBuilder $container)
$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'])) {
@@ -383,6 +387,24 @@ private function registerSessionConfiguration(array $config, ContainerBuilder $c
}
/**
+ * 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.
*
* @param array $config A templating configuration array
View
17 src/Symfony/Bundle/FrameworkBundle/Resources/config/request.xml
@@ -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>
View
14 src/Symfony/Bundle/FrameworkBundle/Resources/config/schema/symfony-1.0.xsd
@@ -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" />
View
11 src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/php/full.php
@@ -70,5 +70,14 @@
'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'
+ )
+ )
));
View
7 src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/php/request.php
@@ -0,0 +1,7 @@
+<?php
+
+$container->loadFromExtension('framework', array(
+ 'request' => array(
+ 'formats' => array(),
+ ),
+));
View
9 src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/xml/full.xml
@@ -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>
View
11 src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/xml/request.xml
@@ -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>
View
4 src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/yml/full.yml
@@ -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'
View
3 src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/yml/request.yml
@@ -0,0 +1,3 @@
+framework:
+ request:
+ formats: ~
View
16 src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/FrameworkExtensionTest.php
@@ -145,6 +145,22 @@ public function testNullSessionHandler()
$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');
View
57 src/Symfony/Component/HttpKernel/EventListener/AddRequestFormatsListener.php
@@ -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');
+ }
+}
View
83 src/Symfony/Component/HttpKernel/Tests/EventListener/AddRequestFormatsListenerTest.php
@@ -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;
+ }
+}

0 comments on commit aca3271

Please sign in to comment.
Something went wrong with that request. Please try again.