Skip to content

Commit

Permalink
Merge branch '1.8' into 2.0
Browse files Browse the repository at this point in the history
  • Loading branch information
GuilhemN committed May 11, 2016
2 parents f4ce3e9 + 932639b commit dc67616
Show file tree
Hide file tree
Showing 14 changed files with 229 additions and 76 deletions.
122 changes: 122 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,122 @@
CHANGELOG
=========

1.8.0
-----

* deprecated the `RedirectView` and `RouteRedirectView` classes, use `View::createRedirect()` and
`View::createRouteRedirect()` instead

* added a `fos_rest.exception.debug` config option that defaults to the `kernel.debug` container
parameter and can be turned on to include the caught exception message in the exception controller's
response

* introduced the concept of REST zones which makes it possible to disable all REST listeners
when a request matches certain attributes

* fixed that serialization groups are always passed to the constructor as an array

* added annotations to support additional HTTP methods defined by RFC 2518 (WebDAV)

* added a new loader that allows to extract REST routes from all controller classes from a
directory

* introduced a serializer adapter layer to ease the integration of custom serialization
implementations

* deprecated the getter methods of the `ViewHandler` class

* fixed an issue that prevented decoration of the `TemplateReferenceInterface` from the Symfony
Templating component

* fixed: no longer overwrite an explicitly configured template in the view response listener

* added support for API versioning in URL parameters, the `Accept` header or using a custom header

* marked some classes and methods as internal, do no longer use them in your code as they are likely
to be removed in future releases

* deprecated the `DoctrineInflector` class and the `InflectorInterface` from the
`FOS\RestBundle\Util\Inflector`in favor of their replacements in the `FOS\RestBundle\Inflector`
namespace

* deprecated the `FormatNegotiator` class and the `FormatNegotiatorInterface` from the
`FOS\RestBundle\Util` namespace in favor of the new `FOS\RestBundle\Negotiation\FormatNegotiator`
class

* deprecated the `FOS\RestBundle\Util\MediaTypeNegotiatorInterface` which should no longer be used

1.7.9
-----

* fixed a BC break that prevented the `CamelKeysNormalizer` from removing leading underscores

* fixed the `AllowedMethodsRouteLoader` to work with Symfony 3.0

1.7.8
-----

* removed uses of the reflection API in favor of faster solutions when possible

* fixed the configuration to use serialization groups and versions at the same time

1.7.7
-----

* when using Symfony 3.x, the bundle doesn't call methods anymore that have been deprecated in
Symfony 2.x and were removed in Symfony 3.0

* the `ViewResponseListener` does not overwrite explicitly configured templates anymore

* fixed the `ParamFetcher` class to properly handle sub requests

1.7.6
-----

* added a `CamelKeysNormalizerWithLeadingUnderscore` that keeps leading underscores when
converting snake case to camel case (for example, leaving `_username` unchanged)

1.7.5
-----

**CAUTION:** Accidentally, this patch release was never published.

1.7.4
-----

* removed some code from the `ViewResponseListener` class that was already present in the parent
`TemplateListener` class

1.7.3
-----

* made it possible to use the bundle with Symfony 3.x and fixed some compatibility issues with
Symfony 3.0

* fixed the exception controller to return a 406 (Not Acceptable) response when the format
negotiator throws an exception

1.7.2
-----

* fixed loading XML schema definition files in case the paths contain special characters (like
spaces)

* return the FQCN in the form type extension's `getExtendedType()` method to be compatible with
Symfony >= 2.8

* added the `extended-type` attribute to the `form.type_extension` tag to be compatible with
Symfony >= 2.8

* fixed some code examples in the documentation

* fixed exception message when using non-numeric identifiers (like UUID or GUID)

* allow version 1.x of `jms/serializer` and `jms/serializer-bundle`

* allow to use the Symfony serializer even if the JMS serializer is present

1.7.1
-----

* fix regression when handling methods in `@Route` annotations
6 changes: 3 additions & 3 deletions Context/Context.php
Original file line number Diff line number Diff line change
Expand Up @@ -149,7 +149,7 @@ public function addGroups(array $groups)
/**
* Gets the normalization groups.
*
* @return array
* @return string[]
*/
public function getGroups()
{
Expand All @@ -159,7 +159,7 @@ public function getGroups()
/**
* Set the normalization groups.
*
* @param array $groups
* @param string[] $groups
*
* @return self
*/
Expand All @@ -173,7 +173,7 @@ public function setGroups(array $groups)
/**
* Sets the normalization max depth.
*
* @param int|null $depth
* @param int|null $maxDepth
*
* @return self
*/
Expand Down
2 changes: 2 additions & 0 deletions Controller/ExceptionController.php
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@
*/
class ExceptionController
{
private $debug;

/**
* @var ViewHandlerInterface
*/
Expand Down
26 changes: 10 additions & 16 deletions Normalizer/CamelKeysNormalizer.php
Original file line number Diff line number Diff line change
Expand Up @@ -39,27 +39,30 @@ public function normalize(array $data)
*/
private function normalizeArray(array &$data)
{
$normalizedData = array();

foreach ($data as $key => $val) {
$normalizedKey = $this->normalizeString($key);

if ($normalizedKey !== $key) {
if (array_key_exists($normalizedKey, $data)) {
if (array_key_exists($normalizedKey, $normalizedData)) {
throw new NormalizationException(sprintf(
'The key "%s" is invalid as it will override the existing key "%s"',
$key,
$normalizedKey
));
}

unset($data[$key]);
$data[$normalizedKey] = $val;
$key = $normalizedKey;
}

$normalizedData[$normalizedKey] = $val;
$key = $normalizedKey;

if (is_array($val)) {
$this->normalizeArray($data[$key]);
$this->normalizeArray($normalizedData[$key]);
}
}

$data = $normalizedData;
}

/**
Expand All @@ -75,17 +78,8 @@ protected function normalizeString($string)
return $string;
}

if (preg_match('/^(_+)(.*)/', $string, $matches)) {
$underscorePrefix = $matches[1];
$string = $matches[2];
} else {
$underscorePrefix = '';
}

$string = preg_replace_callback('/_([a-zA-Z0-9])/', function ($matches) {
return preg_replace_callback('/_([a-zA-Z0-9])/', function ($matches) {
return strtoupper($matches[1]);
}, $string);

return $underscorePrefix.$string;
}
}
2 changes: 1 addition & 1 deletion Resources/config/versioning.xml
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@

<services>
<service id="fos_rest.versioning.listener" class="FOS\RestBundle\EventListener\VersionListener">
<argument type="service" id="fos_rest.view_handler.default" />
<argument type="service" id="fos_rest.view_handler" />
<argument type="service" id="fos_rest.versioning.chain_resolver" />
<argument /> <!-- default media type version -->
<tag name="kernel.event_listener" event="kernel.request" method="onKernelRequest" priority="33" />
Expand Down
19 changes: 19 additions & 0 deletions Resources/doc/3-listener-support.rst
Original file line number Diff line number Diff line change
Expand Up @@ -207,6 +207,25 @@ that the above listeners will not be limited. If at least one zone is configured
be skipped for all requests that do not match at least one zone. For a single zone config entry can contain matching
rules on the request ``path``, ``host``, ``methods`` and ``ip``.

.. code-block:: yaml
# app/config/config.yml
fos_rest:
zone:
- { path: ^/api/* }
Zone Listener
=============

As you can see, FOSRestBundle provides multiple event listeners to enable REST-related features.
By default, these listeners will be registered to all requests and may conflict with other parts of your application.

Using the ``zone`` configuration, you can specify where the event listeners will be enabled. The zone configuration
allows to configure multiple zones in which the above listeners will be active. If no zone is configured, it means
that the above listeners will not be limited. If at least one zone is configured then the above listeners will
be skipped for all requests that do not match at least one zone. For a single zone config entry can contain matching
rules on the request ``path``, ``host``, ``methods`` and ``ip``.

.. code-block:: yaml
# app/config/config.yml
Expand Down
6 changes: 3 additions & 3 deletions Tests/Context/ContextTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -60,10 +60,10 @@ public function testSetGroups()
{
$this->context->setGroups(array('quz', 'foo'));

$this->assertEquals(['quz', 'foo'], $this->context->getGroups());
$this->assertEquals(array('quz', 'foo'), $this->context->getGroups());

$this->context->setGroups(['foo']);
$this->assertEquals(['foo'], $this->context->getGroups());
$this->context->setGroups(array('foo'));
$this->assertEquals(array('foo'), $this->context->getGroups());
}

public function testAlreadyExistentGroupAddition()
Expand Down
54 changes: 27 additions & 27 deletions Tests/DependencyInjection/FOSRestExtensionTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ class FOSRestExtensionTest extends \PHPUnit_Framework_TestCase
public function setUp()
{
$this->container = new ContainerBuilder();
$this->container->setParameter('kernel.bundles', ['JMSSerializerBundle' => true]);
$this->container->setParameter('kernel.bundles', array('JMSSerializerBundle' => true));
$this->container->setParameter('kernel.debug', false);
$this->extension = new FOSRestExtension();
$this->includeFormat = true;
Expand Down Expand Up @@ -551,11 +551,11 @@ public function testExceptionDebug($kernelDebug, $exceptionConfig, $expectedValu
$this->container->setParameter('kernel.debug', $kernelDebug);
$extension = new FOSRestExtension();

$extension->load([
'fos_rest' => [
$extension->load(array(
'fos_rest' => array(
'exception' => $exceptionConfig,
],
], $this->container);
),
), $this->container);

$definition = $this->container->getDefinition('fos_rest.exception.controller');
$this->assertSame($expectedValue, $definition->getArgument(2));
Expand All @@ -569,38 +569,38 @@ public function testExceptionDebug($kernelDebug, $exceptionConfig, $expectedValu

public static function getShowExceptionData()
{
return [
'empty config, kernel.debug is true' => [
return array(
'empty config, kernel.debug is true' => array(
true,
[],
array(),
true,
],
'empty config, kernel.debug is false' => [
),
'empty config, kernel.debug is false' => array(
false,
[],
array(),
false,
],
'config debug true' => [
),
'config debug true' => array(
false,
['debug' => true],
array('debug' => true),
true,
],
'config debug false' => [
),
'config debug false' => array(
true,
['debug' => false],
array('debug' => false),
false,
],
'config debug null, kernel.debug true' => [
),
'config debug null, kernel.debug true' => array(
false,
['debug' => null],
array('debug' => null),
true,
],
'config debug null, kernel.debug false' => [
),
'config debug null, kernel.debug false' => array(
false,
['debug' => null],
array('debug' => null),
true,
],
];
),
);
}

/**
Expand Down Expand Up @@ -698,14 +698,14 @@ public function testZoneMatcherListener()
$this->assertEquals('addRequestMatcher', $addRequestMatcherCalls[0][0]);
$requestMatcherFirstId = (string) $addRequestMatcherCalls[0][1][0];
$requestMatcherFirst = $this->container->getDefinition($requestMatcherFirstId);
$this->assertInstanceOf(DefinitionDecorator::class, $requestMatcherFirst);
$this->assertInstanceOf('Symfony\Component\DependencyInjection\DefinitionDecorator', $requestMatcherFirst);
$this->assertEquals('/api/*', $requestMatcherFirst->getArgument(0));

// Second zone
$this->assertEquals('addRequestMatcher', $addRequestMatcherCalls[1][0]);
$requestMatcherSecondId = (string) $addRequestMatcherCalls[1][1][0];
$requestMatcherSecond = $this->container->getDefinition($requestMatcherSecondId);
$this->assertInstanceOf(DefinitionDecorator::class, $requestMatcherSecond);
$this->assertInstanceOf('Symfony\Component\DependencyInjection\DefinitionDecorator', $requestMatcherSecond);
$this->assertEquals('/^second', $requestMatcherSecond->getArgument(0));
$this->assertEquals(array('127.0.0.1'), $requestMatcherSecond->getArgument(3));
}
Expand Down
Loading

0 comments on commit dc67616

Please sign in to comment.