Skip to content

Commit

Permalink
Merge pull request #544 from schmittjoh/expression-language
Browse files Browse the repository at this point in the history
Added expression language support
  • Loading branch information
goetas authored Feb 17, 2017
2 parents d936231 + 644c952 commit edf55a5
Show file tree
Hide file tree
Showing 8 changed files with 169 additions and 2 deletions.
20 changes: 20 additions & 0 deletions DependencyInjection/Configuration.php
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,26 @@ private function addSerializersSection(NodeBuilder $builder)
->booleanNode('enable_cache')->defaultTrue()->end()
->end()
->end()
->arrayNode('expression_evaluator')
->addDefaultsIfNotSet()
->children()
->scalarNode('id')
->defaultValue(function () {
if (interface_exists('Symfony\Component\ExpressionLanguage\ExpressionFunctionProviderInterface')) {
return 'jms_serializer.expression_evaluator';
}
return null;
})
->validate()
->always(function($v) {
if (!empty($v) && !class_exists('Symfony\Component\ExpressionLanguage\ExpressionFunctionProviderInterface')) {
throw new InvalidArgumentException('You need at least symfony/expression language v2.6 or v3.0 to use the expression evaluator features');
}
return $v;
})
->end()
->end()
->end()
;
}

Expand Down
8 changes: 8 additions & 0 deletions DependencyInjection/JMSSerializerExtension.php
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,14 @@ public function loadInternal(array $config, ContainerBuilder $container)

$bundles = $container->getParameter('kernel.bundles');

if (!empty($config['expression_evaluator']['id'])) {
$container
->getDefinition('jms_serializer.serializer')
->replaceArgument(7, new Reference($config['expression_evaluator']['id']));
} else {
$container->removeDefinition('jms_serializer.expression_evaluator');
}

// metadata
if ('none' === $config['metadata']['cache']) {
$container->removeAlias('jms_serializer.metadata.cache');
Expand Down
33 changes: 33 additions & 0 deletions ExpressionLanguage/BasicSerializerFunctionsProvider.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
<?php

namespace JMS\SerializerBundle\ExpressionLanguage;

use Symfony\Component\ExpressionLanguage\ExpressionFunction;
use Symfony\Component\ExpressionLanguage\ExpressionFunctionProviderInterface;

class BasicSerializerFunctionsProvider implements ExpressionFunctionProviderInterface
{
public function getFunctions()
{
return [
new ExpressionFunction('service', function ($arg) {
return sprintf('$this->get(%s)', $arg);
}, function (array $variables, $value) {
return $variables['container']->get($value);
}),
new ExpressionFunction('parameter', function ($arg) {
return sprintf('$this->getParameter(%s)', $arg);
}, function (array $variables, $value) {
return $variables['container']->getParameter($value);
}),
new ExpressionFunction('is_granted', function ($attribute, $object = null) {
return sprintf('call_user_func_array(array($this->get(security.authorization_checker), isGranted), array(%s, %s))', $attribute, $object);
}, function (array $variables, $attribute, $object = null) {
return call_user_func_array(
array($variables['container']->get('security.authorization_checker'), 'isGranted'),
[$attribute, $object]
);
}),
];
}
}
20 changes: 20 additions & 0 deletions Resources/config/services.xml
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,10 @@

<parameter key="jms_serializer.context_factory.serialization.class">JMS\Serializer\ContextFactory\DefaultSerializationContextFactory</parameter>
<parameter key="jms_serializer.context_factory.deserialization.class">JMS\Serializer\ContextFactory\DefaultDeserializationContextFactory</parameter>

<parameter key="jms_serializer.expression_evaluator.class">JMS\Serializer\Expression\ExpressionEvaluator</parameter>
<parameter key="jms_serializer.expression_language.class">Symfony\Component\ExpressionLanguage\ExpressionLanguage</parameter>
<parameter key="jms_serializer.expression_language.function_provider.class">JMS\SerializerBundle\ExpressionLanguage\BasicSerializerFunctionsProvider</parameter>
</parameters>

<services>
Expand Down Expand Up @@ -176,6 +180,8 @@
<argument type="collection" /><!-- Serialization Visitors -->
<argument type="collection" /><!-- Deserialization Visitors -->
<argument type="service" id="jms_serializer.event_dispatcher" />
<argument type="service" id="jms_serializer.type_parser" on-invalid="null" />
<argument type="constant">NULL</argument> <!-- expression evaluator -->

<call method="setSerializationContextFactory">
<argument type="service" id="jms_serializer.serialization_context_factory" />
Expand All @@ -188,6 +194,20 @@
<service id="jms_serializer" alias="jms_serializer.serializer" /><!-- Preferred Alias -->
<service id="serializer" alias="jms_serializer.serializer" /><!-- Here for BC, may be disabled in the config -->

<!-- expression language components -->
<service id="jms_serializer.expression_evaluator" class="%jms_serializer.expression_evaluator.class%">
<argument type="service" id="jms_serializer.expression_language"/>
<argument type="collection">
<argument type="service" key="container" id="service_container"/>
</argument>
</service>
<service id="jms_serializer.expression_language" class="%jms_serializer.expression_language.class%" public="false">
<call method="registerProvider">
<argument type="service" id="jms_serializer.expression_language.function_provider" />
</call>
</service>
<service id="jms_serializer.expression_language.function_provider" class="%jms_serializer.expression_language.function_provider.class%" public="false"/>

<!-- Twig Extension -->
<service id="jms_serializer.twig_extension.serializer" class="%jms_serializer.twig_extension.class%" public="false">
<argument type="service" id="jms_serializer" />
Expand Down
3 changes: 3 additions & 0 deletions Resources/doc/configuration.rst
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,9 @@ values:
namespace_prefix: "My\\BarBundle"
path: "@MyBarBundle/Resources/config/serializer"
expression_evaluator:
id: jms_serializer.expression_evaluator # auto detected
visitors:
json:
options: 0 # json_encode options bitmask
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
<?php

/*
* Copyright 2011 Johannes M. Schmitt <[email protected]>
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

namespace JMS\SerializerBundle\Tests\DependencyInjection\Fixture;

use JMS\Serializer\Annotation as Serializer;

class ObjectUsingExpressionLanguage
{
/**
* @Serializer\Expose(if="object.isAllowed()")
*/
private $name;

/**
* @Serializer\Exclude()
*/
private $isAllowed;

public function __construct($name, $isAllowed)
{
$this->name = $name;
$this->isAllowed = $isAllowed;
}

public function isAllowed()
{
return $this->isAllowed;
}
}
37 changes: 37 additions & 0 deletions Tests/DependencyInjection/JMSSerializerExtensionTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
namespace JMS\SerializerBundle\Tests\DependencyInjection;

use JMS\Serializer\SerializationContext;
use JMS\SerializerBundle\Tests\DependencyInjection\Fixture\ObjectUsingExpressionLanguage;
use Symfony\Component\DependencyInjection\Compiler\ResolveParameterPlaceHoldersPass;
use Doctrine\Common\Annotations\AnnotationReader;
use JMS\SerializerBundle\JMSSerializerBundle;
Expand Down Expand Up @@ -149,6 +150,42 @@ public function getJsonVisitorConfigs()
return $configs;
}

public function testExpressionLanguage()
{
if (!interface_exists('Symfony\Component\ExpressionLanguage\ExpressionFunctionProviderInterface')) {
$this->markTestSkipped("The Symfony Expression Language is not available");
}
$container = $this->getContainerForConfig(array(array()));
$serializer = $container->get('serializer');
// test that all components have been wired correctly
$object = new ObjectUsingExpressionLanguage('foo', true);
$this->assertEquals('{"name":"foo"}', $serializer->serialize($object, 'json'));
$object = new ObjectUsingExpressionLanguage('foo', false);
$this->assertEquals('{}', $serializer->serialize($object, 'json'));
}

/**
* @expectedException \JMS\Serializer\Exception\ExpressionLanguageRequiredException
* @expectedExceptionMessage To use conditional exclude/expose in JMS\SerializerBundle\Tests\DependencyInjection\Fixture\ObjectUsingExpressionLanguage you must configure the expression language.
*/
public function testExpressionLanguageNotLoaded()
{
$container = $this->getContainerForConfig(array(array('expression_evaluator' => array('id' => null))));
$serializer = $container->get('serializer');
// test that all components have been wired correctly
$object = new ObjectUsingExpressionLanguage('foo', true);
$serializer->serialize($object, 'json');
}

/**
* @expectedException \Symfony\Component\Config\Definition\Exception\InvalidConfigurationException
* @expectedExceptionMessage Invalid configuration for path "jms_serializer.expression_evaluator.id": You need at least symfony/expression language v2.6 or v3.0 to use the expression evaluator features
*/
public function testExpressionInvalidEvaluator()
{
$this->getContainerForConfig(array(array('expression_evaluator' => array('id' => 'foo'))));
}

/**
* @dataProvider getXmlVisitorWhitelists
*/
Expand Down
5 changes: 3 additions & 2 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,12 +13,13 @@
],
"require": {
"php": ">=5.4.0",
"jms/serializer": "^1.4",
"jms/serializer": "^1.5",
"phpoption/phpoption": "^1.1.0",
"symfony/framework-bundle": "~2.3|~3.0"
},
"require-dev": {
"phpunit/phpunit": "^4.0|^5.0",
"phpunit/phpunit": "^4.2|^5.0",
"symfony/expression-language": "~2.6|~3.0",
"symfony/yaml": "*",
"symfony/browser-kit": "*",
"symfony/class-loader": "*",
Expand Down

0 comments on commit edf55a5

Please sign in to comment.