Merge branch '2.7'
* 2.7: (22 commits) Php Inspections (EA Extended): squash all PR-13813 commits replaced the last remaining is_integer() call [2.3] [Config] [Console] [DependencyInjection] [DomCrawler] [Form] [HttpKernel] [PropertyAccess] [Security] [Translation] [Yaml] static code analysis, code cleanup [FrameworkBundle] simplify dep declaration [VarDumper] Fix "next element is already occupied" [Serializer] Introduce ObjectNormalizer [Serializer] Refactoring of metadata [Validator] Added missing galician (gl) translations [WebProfilerBundle] Update ajax calls in toolbar to add the css error class [PropertyAccess] stop overwriting once a reference is reached (3rd) [OptionsResolver] Remove Unused Variable from Foreach Cycles [travis] Tests Security sub-components [Serializer] Test that normalizers ignore non-existing attributes. [Twig] bootstrap_3_layout.html.twig is usable as a trait [travis] Tests Security sub-components [Serializer] Fix ClassMetadataFactory PHPDoc CS fixes [Serializer] rename exception interface [Serializer] Optimize GetSetMethodNormalizer and PropertyNormalizer [TwigBridge] Bootstrap Layout - Fix the label of checkbox cannot be empty ... Conflicts: src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Configuration.php src/Symfony/Component/Console/Tests/Helper/LegacyDialogHelperTest.php src/Symfony/Component/Serializer/composer.json
This commit is contained in:
commit
13bf31bcf3
21
.travis.yml
21
.travis.yml
|
@ -9,8 +9,10 @@ matrix:
|
||||||
env: deps=low
|
env: deps=low
|
||||||
- php: 5.6
|
- php: 5.6
|
||||||
env: deps=high
|
env: deps=high
|
||||||
|
- php: nightly
|
||||||
- php: hhvm-nightly
|
- php: hhvm-nightly
|
||||||
allow_failures:
|
allow_failures:
|
||||||
|
- php: nightly
|
||||||
- php: hhvm-nightly
|
- php: hhvm-nightly
|
||||||
fast_finish: true
|
fast_finish: true
|
||||||
|
|
||||||
|
@ -24,12 +26,12 @@ env:
|
||||||
before_install:
|
before_install:
|
||||||
- travis_retry sudo apt-get install parallel
|
- travis_retry sudo apt-get install parallel
|
||||||
- composer self-update
|
- composer self-update
|
||||||
- if [ "$TRAVIS_PHP_VERSION" != "hhvm-nightly" ]; then phpenv config-rm xdebug.ini; fi;
|
- if [[ "$TRAVIS_PHP_VERSION" != *"nightly" ]]; then phpenv config-rm xdebug.ini; fi;
|
||||||
- if [ "$TRAVIS_PHP_VERSION" != "hhvm-nightly" ]; then echo "extension = mongo.so" >> ~/.phpenv/versions/$(phpenv version-name)/etc/php.ini; fi;
|
- if [[ "$TRAVIS_PHP_VERSION" != *"nightly" ]]; then echo "extension = mongo.so" >> ~/.phpenv/versions/$(phpenv version-name)/etc/php.ini; fi;
|
||||||
- if [ "$TRAVIS_PHP_VERSION" != "hhvm-nightly" ] && [ $(php -r "echo PHP_MINOR_VERSION;") -le 4 ]; then echo "extension = apc.so" >> ~/.phpenv/versions/$(phpenv version-name)/etc/php.ini; fi;
|
- if [[ "$TRAVIS_PHP_VERSION" != *"nightly" ]] && [ $(php -r "echo PHP_MINOR_VERSION;") -le 4 ]; then echo "extension = apc.so" >> ~/.phpenv/versions/$(phpenv version-name)/etc/php.ini; fi;
|
||||||
- if [ "$TRAVIS_PHP_VERSION" != "hhvm-nightly" ]; then pecl install -f memcached-2.1.0; fi;
|
- if [[ "$TRAVIS_PHP_VERSION" != *"nightly" ]]; then pecl install -f memcached-2.1.0; fi;
|
||||||
- if [ "$TRAVIS_PHP_VERSION" != "hhvm-nightly" ]; then echo "extension = memcache.so" >> ~/.phpenv/versions/$(phpenv version-name)/etc/php.ini; fi;
|
- if [[ "$TRAVIS_PHP_VERSION" != *"nightly" ]]; then echo "extension = memcache.so" >> ~/.phpenv/versions/$(phpenv version-name)/etc/php.ini; fi;
|
||||||
- if [ "$TRAVIS_PHP_VERSION" != "hhvm-nightly" ]; then php -i; fi;
|
- if [[ "$TRAVIS_PHP_VERSION" != *"nightly" ]]; then php -i; fi;
|
||||||
- sudo locale-gen fr_FR.UTF-8 && sudo update-locale
|
- sudo locale-gen fr_FR.UTF-8 && sudo update-locale
|
||||||
# Set the COMPOSER_ROOT_VERSION to the right version according to the branch being built
|
# Set the COMPOSER_ROOT_VERSION to the right version according to the branch being built
|
||||||
- if [ "$TRAVIS_BRANCH" = "master" ]; then export COMPOSER_ROOT_VERSION=dev-master; else export COMPOSER_ROOT_VERSION="$TRAVIS_BRANCH".x-dev; fi;
|
- if [ "$TRAVIS_BRANCH" = "master" ]; then export COMPOSER_ROOT_VERSION=dev-master; else export COMPOSER_ROOT_VERSION="$TRAVIS_BRANCH".x-dev; fi;
|
||||||
|
@ -38,8 +40,9 @@ install:
|
||||||
- if [ "$deps" = "no" ]; then composer --prefer-source install; fi;
|
- if [ "$deps" = "no" ]; then composer --prefer-source install; fi;
|
||||||
|
|
||||||
script:
|
script:
|
||||||
|
- components=$(find src/Symfony -mindepth 3 -type f -name phpunit.xml.dist -printf '%h\n')
|
||||||
- if [ "$deps" = "no" ]; then export SYMFONY_DEPRECATIONS_HELPER=strict; fi;
|
- if [ "$deps" = "no" ]; then export SYMFONY_DEPRECATIONS_HELPER=strict; fi;
|
||||||
- if [ "$deps" = "no" ]; then ls -d src/Symfony/*/* | parallel --gnu --keep-order 'echo -e "\\nRunning {} tests"; phpunit --exclude-group tty,benchmark,intl-data {} || (echo -e "\\e[41mKO\\e[0m {}" && $(exit 1));'; fi;
|
- if [ "$deps" = "no" ]; then echo "$components" | parallel --gnu --keep-order 'echo -e "\\nRunning {} tests"; phpunit --exclude-group tty,benchmark,intl-data {} || (echo -e "\\e[41mKO\\e[0m {}" && $(exit 1));'; fi;
|
||||||
- if [ "$deps" = "no" ]; then echo -e "\\nRunning tests requiring tty"; phpunit --group tty || (echo -e "\\e[41mKO\\e[0m tty group" && $(exit 1)); fi;
|
- if [ "$deps" = "no" ]; then echo -e "\\nRunning tests requiring tty"; phpunit --group tty || (echo -e "\\e[41mKO\\e[0m tty group" && $(exit 1)); fi;
|
||||||
- if [ "$deps" = "high" ]; then find src/Symfony -mindepth 3 -type f -name phpunit.xml.dist | sed 's#\(.*\)/.*#\1#' | parallel --gnu --keep-order -j25% 'echo -e "\\nRunning {} tests"; cd {}; composer --prefer-source update; phpunit --exclude-group tty,benchmark,intl-data,legacy || (echo -e "\\e[41mKO\\e[0m {}" && $(exit 1));'; fi;
|
- if [ "$deps" = "high" ]; then echo "$components" | parallel --gnu --keep-order -j25% 'echo -e "\\nRunning {} tests"; cd {}; composer --prefer-source update; phpunit --exclude-group tty,benchmark,intl-data,legacy || (echo -e "\\e[41mKO\\e[0m {}" && $(exit 1));'; fi;
|
||||||
- if [ "$deps" = "low" ]; then find src/Symfony -mindepth 3 -type f -name phpunit.xml.dist | sed 's#\(.*\)/.*#\1#' | parallel --gnu --keep-order -j25% 'echo -e "\\nRunning {} tests"; cd {}; composer --prefer-source --prefer-lowest --prefer-stable update; phpunit --exclude-group tty,benchmark,intl-data || (echo -e "\\e[41mKO\\e[0m {}" && $(exit 1));'; fi;
|
- if [ "$deps" = "low" ]; then echo "$components" | parallel --gnu --keep-order -j25% 'echo -e "\\nRunning {} tests"; cd {}; composer --prefer-source --prefer-lowest --prefer-stable update; phpunit --exclude-group tty,benchmark,intl-data || (echo -e "\\e[41mKO\\e[0m {}" && $(exit 1));'; fi;
|
||||||
|
|
|
@ -84,6 +84,9 @@ Serializer
|
||||||
$normalizer = new GetSetMethodNormalizer(null, $nameConverter);
|
$normalizer = new GetSetMethodNormalizer(null, $nameConverter);
|
||||||
```
|
```
|
||||||
|
|
||||||
|
* `Symfony\Component\Serializer\Exception\ExceptionInterface` is the new name for the now
|
||||||
|
deprecated `Symfony\Component\Serializer\Exception\Exception` interface.
|
||||||
|
|
||||||
PropertyAccess
|
PropertyAccess
|
||||||
--------------
|
--------------
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
{% extends "form_div_layout.html.twig" %}
|
{% use "form_div_layout.html.twig" %}
|
||||||
|
|
||||||
{# Widgets #}
|
{# Widgets #}
|
||||||
|
|
||||||
|
@ -164,12 +164,12 @@
|
||||||
{% if parent_label_class is defined %}
|
{% if parent_label_class is defined %}
|
||||||
{% set label_attr = label_attr|merge({class: (label_attr.class|default('') ~ ' ' ~ parent_label_class)|trim}) %}
|
{% set label_attr = label_attr|merge({class: (label_attr.class|default('') ~ ' ' ~ parent_label_class)|trim}) %}
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% if label is empty %}
|
{% if label is not sameas(false) and label is empty %}
|
||||||
{% set label = name|humanize %}
|
{% set label = name|humanize %}
|
||||||
{% endif %}
|
{% endif %}
|
||||||
<label{% for attrname, attrvalue in label_attr %} {{ attrname }}="{{ attrvalue }}"{% endfor %}>
|
<label{% for attrname, attrvalue in label_attr %} {{ attrname }}="{{ attrvalue }}"{% endfor %}>
|
||||||
{{ widget|raw }}
|
{{ widget|raw }}
|
||||||
{{ label|trans({}, translation_domain) }}
|
{{ label is not sameas(false) ? label|trans({}, translation_domain) }}
|
||||||
</label>
|
</label>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% endblock checkbox_radio_label %}
|
{% endblock checkbox_radio_label %}
|
||||||
|
|
|
@ -303,7 +303,7 @@ class FrameworkExtension extends Extension
|
||||||
'memcached' => 'Symfony\Component\HttpKernel\Profiler\MemcachedProfilerStorage',
|
'memcached' => 'Symfony\Component\HttpKernel\Profiler\MemcachedProfilerStorage',
|
||||||
'redis' => 'Symfony\Component\HttpKernel\Profiler\RedisProfilerStorage',
|
'redis' => 'Symfony\Component\HttpKernel\Profiler\RedisProfilerStorage',
|
||||||
);
|
);
|
||||||
list($class, ) = explode(':', $config['dsn'], 2);
|
list($class) = explode(':', $config['dsn'], 2);
|
||||||
if (!isset($supported[$class])) {
|
if (!isset($supported[$class])) {
|
||||||
throw new \LogicException(sprintf('Driver "%s" is not supported for the profiler.', $class));
|
throw new \LogicException(sprintf('Driver "%s" is not supported for the profiler.', $class));
|
||||||
}
|
}
|
||||||
|
|
|
@ -90,6 +90,9 @@
|
||||||
rows.appendChild(row);
|
rows.appendChild(row);
|
||||||
|
|
||||||
var methodCell = document.createElement('td');
|
var methodCell = document.createElement('td');
|
||||||
|
if (request.error) {
|
||||||
|
methodCell.className = 'sf-ajax-request-error';
|
||||||
|
}
|
||||||
methodCell.textContent = request.method;
|
methodCell.textContent = request.method;
|
||||||
row.appendChild(methodCell);
|
row.appendChild(methodCell);
|
||||||
|
|
||||||
|
|
|
@ -315,7 +315,7 @@
|
||||||
text-align: right;
|
text-align: right;
|
||||||
}
|
}
|
||||||
.sf-ajax-request-error {
|
.sf-ajax-request-error {
|
||||||
color: #a33;
|
color: #a33 !important;
|
||||||
}
|
}
|
||||||
.sf-ajax-request-loading {
|
.sf-ajax-request-loading {
|
||||||
-webkit-animation: sf-blink .5s ease-in-out infinite;
|
-webkit-animation: sf-blink .5s ease-in-out infinite;
|
||||||
|
|
|
@ -472,7 +472,7 @@ class ArrayNodeDefinition extends NodeDefinition implements ParentNodeDefinition
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (null !== $this->key && (null === $this->addDefaultChildren || is_integer($this->addDefaultChildren) && $this->addDefaultChildren > 0)) {
|
if (null !== $this->key && (null === $this->addDefaultChildren || is_int($this->addDefaultChildren) && $this->addDefaultChildren > 0)) {
|
||||||
throw new InvalidDefinitionException(
|
throw new InvalidDefinitionException(
|
||||||
sprintf('->addDefaultChildrenIfNoneSet() should set default children names as ->useAttributeAsKey() is used at path "%s"', $path)
|
sprintf('->addDefaultChildrenIfNoneSet() should set default children names as ->useAttributeAsKey() is used at path "%s"', $path)
|
||||||
);
|
);
|
||||||
|
|
|
@ -117,7 +117,7 @@ class PrototypedArrayNode extends ArrayNode
|
||||||
if (null === $children) {
|
if (null === $children) {
|
||||||
$this->defaultChildren = array('defaults');
|
$this->defaultChildren = array('defaults');
|
||||||
} else {
|
} else {
|
||||||
$this->defaultChildren = is_integer($children) && $children > 0 ? range(1, $children) : (array) $children;
|
$this->defaultChildren = is_int($children) && $children > 0 ? range(1, $children) : (array) $children;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -222,7 +222,7 @@ class XmlUtils
|
||||||
LIBXML_ERR_WARNING == $error->level ? 'WARNING' : 'ERROR',
|
LIBXML_ERR_WARNING == $error->level ? 'WARNING' : 'ERROR',
|
||||||
$error->code,
|
$error->code,
|
||||||
trim($error->message),
|
trim($error->message),
|
||||||
$error->file ? $error->file : 'n/a',
|
$error->file ?: 'n/a',
|
||||||
$error->line,
|
$error->line,
|
||||||
$error->column
|
$error->column
|
||||||
);
|
);
|
||||||
|
|
|
@ -149,7 +149,7 @@ class OutputFormatterStyle implements OutputFormatterStyleInterface
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (false === array_search(static::$availableOptions[$option], $this->options)) {
|
if (!in_array(static::$availableOptions[$option], $this->options)) {
|
||||||
$this->options[] = static::$availableOptions[$option];
|
$this->options[] = static::$availableOptions[$option];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -274,7 +274,7 @@ class QuestionHelperTest extends \PHPUnit_Framework_TestCase
|
||||||
protected function getInputStream($input)
|
protected function getInputStream($input)
|
||||||
{
|
{
|
||||||
$stream = fopen('php://memory', 'r+', false);
|
$stream = fopen('php://memory', 'r+', false);
|
||||||
fputs($stream, $input);
|
fwrite($stream, $input);
|
||||||
rewind($stream);
|
rewind($stream);
|
||||||
|
|
||||||
return $stream;
|
return $stream;
|
||||||
|
|
|
@ -1175,7 +1175,7 @@ EOF;
|
||||||
$behavior[$id] = $argument->getInvalidBehavior();
|
$behavior[$id] = $argument->getInvalidBehavior();
|
||||||
}
|
}
|
||||||
|
|
||||||
$calls[$id] += 1;
|
++$calls[$id];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1486,12 +1486,12 @@ EOF;
|
||||||
}
|
}
|
||||||
|
|
||||||
while ($i > 0) {
|
while ($i > 0) {
|
||||||
$i -= 1;
|
--$i;
|
||||||
$name .= $nonFirstChars[$i%$nonFirstCharsLength];
|
$name .= $nonFirstChars[$i%$nonFirstCharsLength];
|
||||||
$i = intval($i/$nonFirstCharsLength);
|
$i = intval($i/$nonFirstCharsLength);
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->variableCount += 1;
|
++$this->variableCount;
|
||||||
|
|
||||||
// check that the name is not reserved
|
// check that the name is not reserved
|
||||||
if (in_array($name, $this->reservedVariables, true)) {
|
if (in_array($name, $this->reservedVariables, true)) {
|
||||||
|
|
|
@ -260,7 +260,8 @@ class ContainerBuilderTest extends \PHPUnit_Framework_TestCase
|
||||||
$builder->setResourceTracking(false);
|
$builder->setResourceTracking(false);
|
||||||
$builderCompilerPasses = $builder->getCompiler()->getPassConfig()->getPasses();
|
$builderCompilerPasses = $builder->getCompiler()->getPassConfig()->getPasses();
|
||||||
$builder->addCompilerPass($this->getMock('Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface'));
|
$builder->addCompilerPass($this->getMock('Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface'));
|
||||||
$this->assertEquals(sizeof($builderCompilerPasses) + 1, sizeof($builder->getCompiler()->getPassConfig()->getPasses()));
|
|
||||||
|
$this->assertCount(count($builder->getCompiler()->getPassConfig()->getPasses()) - 1, $builderCompilerPasses);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -74,8 +74,8 @@ class PhpDumperTest extends \PHPUnit_Framework_TestCase
|
||||||
|
|
||||||
$container = new ContainerBuilder();
|
$container = new ContainerBuilder();
|
||||||
$container->setDefinition('test', $definition);
|
$container->setDefinition('test', $definition);
|
||||||
$container->setParameter('foo', 'wiz'.dirname(dirname(__FILE__)));
|
$container->setParameter('foo', 'wiz'.dirname(__DIR__));
|
||||||
$container->setParameter('bar', dirname(__FILE__));
|
$container->setParameter('bar', __DIR__);
|
||||||
$container->setParameter('baz', '%bar%/PhpDumperTest.php');
|
$container->setParameter('baz', '%bar%/PhpDumperTest.php');
|
||||||
$container->setParameter('buz', dirname(dirname(__DIR__)));
|
$container->setParameter('buz', dirname(dirname(__DIR__)));
|
||||||
$container->compile();
|
$container->compile();
|
||||||
|
|
|
@ -45,9 +45,10 @@ class Crawler extends \SplObjectStorage
|
||||||
/**
|
/**
|
||||||
* Constructor.
|
* Constructor.
|
||||||
*
|
*
|
||||||
* @param mixed $node A Node to use as the base for the crawling
|
* @param mixed $node A Node to use as the base for the crawling
|
||||||
* @param string $currentUri The current URI
|
* @param string $currentUri The current URI
|
||||||
* @param string $baseHref The base href value
|
* @param string $baseHref The base href value
|
||||||
|
*
|
||||||
* @api
|
* @api
|
||||||
*/
|
*/
|
||||||
public function __construct($node = null, $currentUri = null, $baseHref = null)
|
public function __construct($node = null, $currentUri = null, $baseHref = null)
|
||||||
|
|
|
@ -327,7 +327,7 @@ EOF
|
||||||
{
|
{
|
||||||
$crawler = $this->createTestCrawler()->filterXPath('//ul[1]/li');
|
$crawler = $this->createTestCrawler()->filterXPath('//ul[1]/li');
|
||||||
$nodes = $crawler->reduce(function ($node, $i) {
|
$nodes = $crawler->reduce(function ($node, $i) {
|
||||||
return $i == 1 ? false : true;
|
return $i !== 1;
|
||||||
});
|
});
|
||||||
$this->assertNotSame($nodes, $crawler, '->reduce() returns a new instance of a crawler');
|
$this->assertNotSame($nodes, $crawler, '->reduce() returns a new instance of a crawler');
|
||||||
$this->assertInstanceOf('Symfony\\Component\\DomCrawler\\Crawler', $nodes, '->reduce() returns a new instance of a crawler');
|
$this->assertInstanceOf('Symfony\\Component\\DomCrawler\\Crawler', $nodes, '->reduce() returns a new instance of a crawler');
|
||||||
|
|
|
@ -67,8 +67,7 @@ abstract class AbstractRendererEngine implements FormRendererEngineInterface
|
||||||
// Unset instead of resetting to an empty array, in order to allow
|
// Unset instead of resetting to an empty array, in order to allow
|
||||||
// implementations (like TwigRendererEngine) to check whether $cacheKey
|
// implementations (like TwigRendererEngine) to check whether $cacheKey
|
||||||
// is set at all.
|
// is set at all.
|
||||||
unset($this->resources[$cacheKey]);
|
unset($this->resources[$cacheKey], $this->resourceHierarchyLevels[$cacheKey]);
|
||||||
unset($this->resourceHierarchyLevels[$cacheKey]);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -138,8 +138,7 @@ class FormBuilder extends FormConfigBuilder implements \IteratorAggregate, FormB
|
||||||
throw new BadMethodCallException('FormBuilder methods cannot be accessed anymore once the builder is turned into a FormConfigInterface instance.');
|
throw new BadMethodCallException('FormBuilder methods cannot be accessed anymore once the builder is turned into a FormConfigInterface instance.');
|
||||||
}
|
}
|
||||||
|
|
||||||
unset($this->unresolvedChildren[$name]);
|
unset($this->unresolvedChildren[$name], $this->children[$name]);
|
||||||
unset($this->children[$name]);
|
|
||||||
|
|
||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,10 +12,10 @@ namespace Symfony\Component\Form;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* To learn more about how form events work check the documentation
|
* To learn more about how form events work check the documentation
|
||||||
* entry at {@link http://symfony.com/doc/any/components/form/form_events.html}
|
* entry at {@link http://symfony.com/doc/any/components/form/form_events.html}.
|
||||||
*
|
*
|
||||||
* To learn how to dynamically modify forms using events check the cookbook
|
* To learn how to dynamically modify forms using events check the cookbook
|
||||||
* entry at {@link http://symfony.com/doc/any/cookbook/form/dynamic_form_modification.html}
|
* entry at {@link http://symfony.com/doc/any/cookbook/form/dynamic_form_modification.html}.
|
||||||
*
|
*
|
||||||
* @author Bernhard Schussek <bschussek@gmail.com>
|
* @author Bernhard Schussek <bschussek@gmail.com>
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -296,8 +296,7 @@ class FormRenderer implements FormRendererInterface
|
||||||
// Clear the caches if they were filled for the first time within
|
// Clear the caches if they were filled for the first time within
|
||||||
// this function call
|
// this function call
|
||||||
if ($hierarchyInit) {
|
if ($hierarchyInit) {
|
||||||
unset($this->blockNameHierarchyMap[$viewAndSuffixCacheKey]);
|
unset($this->blockNameHierarchyMap[$viewAndSuffixCacheKey], $this->hierarchyLevelMap[$viewAndSuffixCacheKey]);
|
||||||
unset($this->hierarchyLevelMap[$viewAndSuffixCacheKey]);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($varInit) {
|
if ($varInit) {
|
||||||
|
|
|
@ -54,7 +54,7 @@ abstract class FormPerformanceTestCase extends FormIntegrationTestCase
|
||||||
*/
|
*/
|
||||||
public function setMaxRunningTime($maxRunningTime)
|
public function setMaxRunningTime($maxRunningTime)
|
||||||
{
|
{
|
||||||
if (is_integer($maxRunningTime) && $maxRunningTime >= 0) {
|
if (is_int($maxRunningTime) && $maxRunningTime >= 0) {
|
||||||
$this->maxRunningTime = $maxRunningTime;
|
$this->maxRunningTime = $maxRunningTime;
|
||||||
} else {
|
} else {
|
||||||
throw new \InvalidArgumentException();
|
throw new \InvalidArgumentException();
|
||||||
|
|
|
@ -147,8 +147,7 @@ class RouterListener implements EventSubscriberInterface
|
||||||
}
|
}
|
||||||
|
|
||||||
$request->attributes->add($parameters);
|
$request->attributes->add($parameters);
|
||||||
unset($parameters['_route']);
|
unset($parameters['_route'], $parameters['_controller']);
|
||||||
unset($parameters['_controller']);
|
|
||||||
$request->attributes->set('_route_params', $parameters);
|
$request->attributes->set('_route_params', $parameters);
|
||||||
} catch (ResourceNotFoundException $e) {
|
} catch (ResourceNotFoundException $e) {
|
||||||
$message = sprintf('No route found for "%s %s"', $request->getMethod(), $request->getPathInfo());
|
$message = sprintf('No route found for "%s %s"', $request->getMethod(), $request->getPathInfo());
|
||||||
|
|
|
@ -29,7 +29,7 @@ class LoggerDataCollectorTest extends \PHPUnit_Framework_TestCase
|
||||||
|
|
||||||
$this->assertSame('logger', $c->getName());
|
$this->assertSame('logger', $c->getName());
|
||||||
$this->assertSame($nb, $c->countErrors());
|
$this->assertSame($nb, $c->countErrors());
|
||||||
$this->assertSame($expectedLogs ? $expectedLogs : $logs, $c->getLogs());
|
$this->assertSame($expectedLogs ?: $logs, $c->getLogs());
|
||||||
$this->assertSame($expectedDeprecationCount, $c->countDeprecations());
|
$this->assertSame($expectedDeprecationCount, $c->countDeprecations());
|
||||||
$this->assertSame($expectedScreamCount, $c->countScreams());
|
$this->assertSame($expectedScreamCount, $c->countScreams());
|
||||||
|
|
||||||
|
|
|
@ -258,7 +258,7 @@ class OptionsResolver implements Options
|
||||||
throw new AccessException('Options cannot be made required from a lazy option or normalizer.');
|
throw new AccessException('Options cannot be made required from a lazy option or normalizer.');
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach ((array) $optionNames as $key => $option) {
|
foreach ((array) $optionNames as $option) {
|
||||||
$this->defined[$option] = true;
|
$this->defined[$option] = true;
|
||||||
$this->required[$option] = true;
|
$this->required[$option] = true;
|
||||||
}
|
}
|
||||||
|
@ -339,7 +339,7 @@ class OptionsResolver implements Options
|
||||||
throw new AccessException('Options cannot be defined from a lazy option or normalizer.');
|
throw new AccessException('Options cannot be defined from a lazy option or normalizer.');
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach ((array) $optionNames as $key => $option) {
|
foreach ((array) $optionNames as $option) {
|
||||||
$this->defined[$option] = true;
|
$this->defined[$option] = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -617,14 +617,8 @@ class OptionsResolver implements Options
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach ((array) $optionNames as $option) {
|
foreach ((array) $optionNames as $option) {
|
||||||
unset($this->defined[$option]);
|
unset($this->defined[$option], $this->defaults[$option], $this->required[$option], $this->resolved[$option]);
|
||||||
unset($this->defaults[$option]);
|
unset($this->lazy[$option], $this->normalizers[$option], $this->allowedTypes[$option], $this->allowedValues[$option]);
|
||||||
unset($this->required[$option]);
|
|
||||||
unset($this->resolved[$option]);
|
|
||||||
unset($this->lazy[$option]);
|
|
||||||
unset($this->normalizers[$option]);
|
|
||||||
unset($this->allowedTypes[$option]);
|
|
||||||
unset($this->allowedValues[$option]);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return $this;
|
return $this;
|
||||||
|
|
|
@ -70,7 +70,6 @@ class PropertyAccessor implements PropertyAccessorInterface
|
||||||
}
|
}
|
||||||
|
|
||||||
$propertyValues = & $this->readPropertiesUntil($objectOrArray, $propertyPath, $propertyPath->getLength() - 1);
|
$propertyValues = & $this->readPropertiesUntil($objectOrArray, $propertyPath, $propertyPath->getLength() - 1);
|
||||||
$overwrite = true;
|
|
||||||
|
|
||||||
// Add the root object to the list
|
// Add the root object to the list
|
||||||
array_unshift($propertyValues, array(
|
array_unshift($propertyValues, array(
|
||||||
|
@ -81,18 +80,19 @@ class PropertyAccessor implements PropertyAccessorInterface
|
||||||
for ($i = count($propertyValues) - 1; $i >= 0; --$i) {
|
for ($i = count($propertyValues) - 1; $i >= 0; --$i) {
|
||||||
$objectOrArray = & $propertyValues[$i][self::VALUE];
|
$objectOrArray = & $propertyValues[$i][self::VALUE];
|
||||||
|
|
||||||
if ($overwrite) {
|
$property = $propertyPath->getElement($i);
|
||||||
$property = $propertyPath->getElement($i);
|
|
||||||
|
|
||||||
if ($propertyPath->isIndex($i)) {
|
if ($propertyPath->isIndex($i)) {
|
||||||
$this->writeIndex($objectOrArray, $property, $value);
|
$this->writeIndex($objectOrArray, $property, $value);
|
||||||
} else {
|
} else {
|
||||||
$this->writeProperty($objectOrArray, $property, $value);
|
$this->writeProperty($objectOrArray, $property, $value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ($propertyValues[$i][self::IS_REF]) {
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
$value = & $objectOrArray;
|
$value = & $objectOrArray;
|
||||||
$overwrite = !$propertyValues[$i][self::IS_REF];
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -127,7 +127,6 @@ class PropertyAccessor implements PropertyAccessorInterface
|
||||||
|
|
||||||
try {
|
try {
|
||||||
$propertyValues = $this->readPropertiesUntil($objectOrArray, $propertyPath, $propertyPath->getLength() - 1);
|
$propertyValues = $this->readPropertiesUntil($objectOrArray, $propertyPath, $propertyPath->getLength() - 1);
|
||||||
$overwrite = true;
|
|
||||||
|
|
||||||
// Add the root object to the list
|
// Add the root object to the list
|
||||||
array_unshift($propertyValues, array(
|
array_unshift($propertyValues, array(
|
||||||
|
@ -138,21 +137,21 @@ class PropertyAccessor implements PropertyAccessorInterface
|
||||||
for ($i = count($propertyValues) - 1; $i >= 0; --$i) {
|
for ($i = count($propertyValues) - 1; $i >= 0; --$i) {
|
||||||
$objectOrArray = $propertyValues[$i][self::VALUE];
|
$objectOrArray = $propertyValues[$i][self::VALUE];
|
||||||
|
|
||||||
if ($overwrite) {
|
$property = $propertyPath->getElement($i);
|
||||||
$property = $propertyPath->getElement($i);
|
|
||||||
|
|
||||||
if ($propertyPath->isIndex($i)) {
|
if ($propertyPath->isIndex($i)) {
|
||||||
if (!$objectOrArray instanceof \ArrayAccess && !is_array($objectOrArray)) {
|
if (!$objectOrArray instanceof \ArrayAccess && !is_array($objectOrArray)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (!$this->isPropertyWritable($objectOrArray, $property)) {
|
if (!$this->isPropertyWritable($objectOrArray, $property)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
$overwrite = !$propertyValues[$i][self::IS_REF];
|
if ($propertyValues[$i][self::IS_REF]) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
|
|
@ -264,8 +264,7 @@ class PropertyPathBuilder
|
||||||
|
|
||||||
// All remaining elements should be removed
|
// All remaining elements should be removed
|
||||||
for (; $i < $length; ++$i) {
|
for (; $i < $length; ++$i) {
|
||||||
unset($this->elements[$i]);
|
unset($this->elements[$i], $this->isIndex[$i]);
|
||||||
unset($this->isIndex[$i]);
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
$diff = $insertionLength - $cutLength;
|
$diff = $insertionLength - $cutLength;
|
||||||
|
|
|
@ -25,6 +25,7 @@ class TestClass
|
||||||
private $publicAccessorWithMoreRequiredParameters;
|
private $publicAccessorWithMoreRequiredParameters;
|
||||||
private $publicIsAccessor;
|
private $publicIsAccessor;
|
||||||
private $publicHasAccessor;
|
private $publicHasAccessor;
|
||||||
|
private $publicGetter;
|
||||||
|
|
||||||
public function __construct($value)
|
public function __construct($value)
|
||||||
{
|
{
|
||||||
|
@ -37,6 +38,7 @@ class TestClass
|
||||||
$this->publicAccessorWithMoreRequiredParameters = $value;
|
$this->publicAccessorWithMoreRequiredParameters = $value;
|
||||||
$this->publicIsAccessor = $value;
|
$this->publicIsAccessor = $value;
|
||||||
$this->publicHasAccessor = $value;
|
$this->publicHasAccessor = $value;
|
||||||
|
$this->publicGetter = $value;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function setPublicAccessor($value)
|
public function setPublicAccessor($value)
|
||||||
|
@ -166,4 +168,9 @@ class TestClass
|
||||||
{
|
{
|
||||||
return 'foobar';
|
return 'foobar';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function getPublicGetter()
|
||||||
|
{
|
||||||
|
return $this->publicGetter;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -419,6 +419,14 @@ class PropertyAccessorTest extends \PHPUnit_Framework_TestCase
|
||||||
array(array('index' => array('%!@$§.' => 'Bernhard')), '[index][%!@$§.]', 'Bernhard'),
|
array(array('index' => array('%!@$§.' => 'Bernhard')), '[index][%!@$§.]', 'Bernhard'),
|
||||||
array((object) array('%!@$§' => 'Bernhard'), '%!@$§', 'Bernhard'),
|
array((object) array('%!@$§' => 'Bernhard'), '%!@$§', 'Bernhard'),
|
||||||
array((object) array('property' => (object) array('%!@$§' => 'Bernhard')), 'property.%!@$§', 'Bernhard'),
|
array((object) array('property' => (object) array('%!@$§' => 'Bernhard')), 'property.%!@$§', 'Bernhard'),
|
||||||
|
|
||||||
|
// nested objects and arrays
|
||||||
|
array(array('foo' => new TestClass('bar')), '[foo].publicGetSetter', 'bar'),
|
||||||
|
array(new TestClass(array('foo' => 'bar')), 'publicGetSetter[foo]', 'bar'),
|
||||||
|
array(new TestClass(new TestClass('bar')), 'publicGetter.publicGetSetter', 'bar'),
|
||||||
|
array(new TestClass(array('foo' => new TestClass('bar'))), 'publicGetter[foo].publicGetSetter', 'bar'),
|
||||||
|
array(new TestClass(new TestClass(new TestClass('bar'))), 'publicGetter.publicGetter.publicGetSetter', 'bar'),
|
||||||
|
array(new TestClass(array('foo' => array('baz' => new TestClass('bar')))), 'publicGetter[foo][baz].publicGetSetter', 'bar'),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -173,7 +173,8 @@ class AclProvider implements AclProviderInterface
|
||||||
}
|
}
|
||||||
|
|
||||||
// Is it time to load the current batch?
|
// Is it time to load the current batch?
|
||||||
if ((self::MAX_BATCH_SIZE === count($currentBatch) || ($i + 1) === $c) && count($currentBatch) > 0) {
|
$currentBatchesCount = count($currentBatch);
|
||||||
|
if ($currentBatchesCount > 0 && (self::MAX_BATCH_SIZE === $currentBatchesCount || ($i + 1) === $c)) {
|
||||||
try {
|
try {
|
||||||
$loadedBatch = $this->lookupObjectIdentities($currentBatch, $sids, $oidLookup);
|
$loadedBatch = $this->lookupObjectIdentities($currentBatch, $sids, $oidLookup);
|
||||||
} catch (AclNotFoundException $aclNotFoundException) {
|
} catch (AclNotFoundException $aclNotFoundException) {
|
||||||
|
@ -559,10 +560,11 @@ QUERY;
|
||||||
// attach ACL to the result set; even though we do not enforce that every
|
// attach ACL to the result set; even though we do not enforce that every
|
||||||
// object identity has only one instance, we must make sure to maintain
|
// object identity has only one instance, we must make sure to maintain
|
||||||
// referential equality with the oids passed to findAcls()
|
// referential equality with the oids passed to findAcls()
|
||||||
if (!isset($oidCache[$objectIdentifier.$classType])) {
|
$oidCacheKey = $objectIdentifier.$classType;
|
||||||
$oidCache[$objectIdentifier.$classType] = $acl->getObjectIdentity();
|
if (!isset($oidCache[$oidCacheKey])) {
|
||||||
|
$oidCache[$oidCacheKey] = $acl->getObjectIdentity();
|
||||||
}
|
}
|
||||||
$result->attach($oidCache[$objectIdentifier.$classType], $acl);
|
$result->attach($oidCache[$oidCacheKey], $acl);
|
||||||
// so, this hasn't been hydrated yet
|
// so, this hasn't been hydrated yet
|
||||||
} else {
|
} else {
|
||||||
// create object identity if we haven't done so yet
|
// create object identity if we haven't done so yet
|
||||||
|
@ -670,7 +672,7 @@ QUERY;
|
||||||
// let's see if we have already hydrated this
|
// let's see if we have already hydrated this
|
||||||
if (isset($acls[$parentId])) {
|
if (isset($acls[$parentId])) {
|
||||||
$aclParentAclProperty->setValue($acl, $acls[$parentId]);
|
$aclParentAclProperty->setValue($acl, $acls[$parentId]);
|
||||||
$processed += 1;
|
++$processed;
|
||||||
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
|
@ -122,7 +122,7 @@ class AclProviderBenchmarkTest extends \PHPUnit_Framework_TestCase
|
||||||
|
|
||||||
if ($id === 1000 || ($id < 1500 && rand(0, 1))) {
|
if ($id === 1000 || ($id < 1500 && rand(0, 1))) {
|
||||||
$this->insertClassStmt->execute(array($id, $this->getRandomString(rand(20, 100), 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789\\_')));
|
$this->insertClassStmt->execute(array($id, $this->getRandomString(rand(20, 100), 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789\\_')));
|
||||||
$id += 1;
|
++$id;
|
||||||
|
|
||||||
return $id-1;
|
return $id-1;
|
||||||
} else {
|
} else {
|
||||||
|
@ -148,7 +148,7 @@ class AclProviderBenchmarkTest extends \PHPUnit_Framework_TestCase
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->generateAces($classId, $id);
|
$this->generateAces($classId, $id);
|
||||||
$id += 1;
|
++$id;
|
||||||
|
|
||||||
return $id-1;
|
return $id-1;
|
||||||
}
|
}
|
||||||
|
@ -163,7 +163,7 @@ class AclProviderBenchmarkTest extends \PHPUnit_Framework_TestCase
|
||||||
$this->getRandomString(rand(5, 30)),
|
$this->getRandomString(rand(5, 30)),
|
||||||
rand(0, 1),
|
rand(0, 1),
|
||||||
));
|
));
|
||||||
$id += 1;
|
++$id;
|
||||||
|
|
||||||
return $id-1;
|
return $id-1;
|
||||||
} else {
|
} else {
|
||||||
|
@ -215,7 +215,7 @@ class AclProviderBenchmarkTest extends \PHPUnit_Framework_TestCase
|
||||||
rand(0, 1),
|
rand(0, 1),
|
||||||
));
|
));
|
||||||
|
|
||||||
$id += 1;
|
++$id;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -27,7 +27,7 @@ class AclVoterTest extends \PHPUnit_Framework_TestCase
|
||||||
*/
|
*/
|
||||||
public function testSupportsAttribute($attribute, $supported)
|
public function testSupportsAttribute($attribute, $supported)
|
||||||
{
|
{
|
||||||
list($voter, , $permissionMap, ,) = $this->getVoter(true, false);
|
list($voter, , $permissionMap) = $this->getVoter(true, false);
|
||||||
|
|
||||||
$permissionMap
|
$permissionMap
|
||||||
->expects($this->once())
|
->expects($this->once())
|
||||||
|
@ -44,7 +44,7 @@ class AclVoterTest extends \PHPUnit_Framework_TestCase
|
||||||
*/
|
*/
|
||||||
public function testSupportsAttributeNonString($attribute)
|
public function testSupportsAttributeNonString($attribute)
|
||||||
{
|
{
|
||||||
list($voter, , , , ,) = $this->getVoter(true, false);
|
list($voter) = $this->getVoter(true, false);
|
||||||
|
|
||||||
$this->assertFalse($voter->supportsAttribute($attribute));
|
$this->assertFalse($voter->supportsAttribute($attribute));
|
||||||
}
|
}
|
||||||
|
@ -72,7 +72,7 @@ class AclVoterTest extends \PHPUnit_Framework_TestCase
|
||||||
*/
|
*/
|
||||||
public function testSupportsClass($class)
|
public function testSupportsClass($class)
|
||||||
{
|
{
|
||||||
list($voter, , , ,) = $this->getVoter();
|
list($voter) = $this->getVoter();
|
||||||
|
|
||||||
$this->assertTrue($voter->supportsClass($class));
|
$this->assertTrue($voter->supportsClass($class));
|
||||||
}
|
}
|
||||||
|
@ -88,7 +88,7 @@ class AclVoterTest extends \PHPUnit_Framework_TestCase
|
||||||
|
|
||||||
public function testVote()
|
public function testVote()
|
||||||
{
|
{
|
||||||
list($voter, , $permissionMap, ,) = $this->getVoter();
|
list($voter, , $permissionMap) = $this->getVoter();
|
||||||
$permissionMap
|
$permissionMap
|
||||||
->expects($this->atLeastOnce())
|
->expects($this->atLeastOnce())
|
||||||
->method('getMasks')
|
->method('getMasks')
|
||||||
|
@ -103,7 +103,7 @@ class AclVoterTest extends \PHPUnit_Framework_TestCase
|
||||||
*/
|
*/
|
||||||
public function testVoteWhenNoObjectIsPassed($allowIfObjectIdentityUnavailable)
|
public function testVoteWhenNoObjectIsPassed($allowIfObjectIdentityUnavailable)
|
||||||
{
|
{
|
||||||
list($voter, , $permissionMap, ,) = $this->getVoter($allowIfObjectIdentityUnavailable);
|
list($voter, , $permissionMap) = $this->getVoter($allowIfObjectIdentityUnavailable);
|
||||||
$permissionMap
|
$permissionMap
|
||||||
->expects($this->once())
|
->expects($this->once())
|
||||||
->method('getMasks')
|
->method('getMasks')
|
||||||
|
@ -124,7 +124,7 @@ class AclVoterTest extends \PHPUnit_Framework_TestCase
|
||||||
*/
|
*/
|
||||||
public function testVoteWhenOidStrategyReturnsNull($allowIfUnavailable)
|
public function testVoteWhenOidStrategyReturnsNull($allowIfUnavailable)
|
||||||
{
|
{
|
||||||
list($voter, , $permissionMap, $oidStrategy,) = $this->getVoter($allowIfUnavailable);
|
list($voter, , $permissionMap, $oidStrategy) = $this->getVoter($allowIfUnavailable);
|
||||||
$permissionMap
|
$permissionMap
|
||||||
->expects($this->once())
|
->expects($this->once())
|
||||||
->method('getMasks')
|
->method('getMasks')
|
||||||
|
|
|
@ -60,7 +60,7 @@ class PreAuthenticatedAuthenticationProvider implements AuthenticationProviderIn
|
||||||
throw new BadCredentialsException('No pre-authenticated principal found in request.');
|
throw new BadCredentialsException('No pre-authenticated principal found in request.');
|
||||||
}
|
}
|
||||||
|
|
||||||
$user = $this->userProvider->loadUserByUsername($user);
|
$user = $this->userProvider->loadUserByUsername($user);
|
||||||
|
|
||||||
$this->userChecker->checkPostAuth($user);
|
$this->userChecker->checkPostAuth($user);
|
||||||
|
|
||||||
|
|
|
@ -41,7 +41,7 @@ class SecureRandomTest extends \PHPUnit_Framework_TestCase
|
||||||
|
|
||||||
for ($j = 1; $j <= 5000; $j++) {
|
for ($j = 1; $j <= 5000; $j++) {
|
||||||
$k = 4 * $j - 1;
|
$k = 4 * $j - 1;
|
||||||
$c[8 * $b[$k - 3] + 4 * $b[$k - 2] + 2 * $b[$k - 1] + $b[$k]] += 1;
|
++$c[8 * $b[$k - 3] + 4 * $b[$k - 2] + 2 * $b[$k - 1] + $b[$k]];
|
||||||
}
|
}
|
||||||
|
|
||||||
$f = 0;
|
$f = 0;
|
||||||
|
@ -73,14 +73,14 @@ class SecureRandomTest extends \PHPUnit_Framework_TestCase
|
||||||
$run = 6;
|
$run = 6;
|
||||||
}
|
}
|
||||||
|
|
||||||
$runs[$run] += 1;
|
++$runs[$run];
|
||||||
};
|
};
|
||||||
|
|
||||||
$currentRun = 0;
|
$currentRun = 0;
|
||||||
$lastBit = null;
|
$lastBit = null;
|
||||||
for ($i = 0; $i < 20000; $i++) {
|
for ($i = 0; $i < 20000; $i++) {
|
||||||
if ($lastBit === $b[$i]) {
|
if ($lastBit === $b[$i]) {
|
||||||
$currentRun += 1;
|
++$currentRun;
|
||||||
} else {
|
} else {
|
||||||
if ($currentRun > 0) {
|
if ($currentRun > 0) {
|
||||||
$addRun($currentRun);
|
$addRun($currentRun);
|
||||||
|
@ -115,7 +115,7 @@ class SecureRandomTest extends \PHPUnit_Framework_TestCase
|
||||||
$lastBit = null;
|
$lastBit = null;
|
||||||
for ($i = 0; $i < 20000; $i++) {
|
for ($i = 0; $i < 20000; $i++) {
|
||||||
if ($lastBit === $b[$i]) {
|
if ($lastBit === $b[$i]) {
|
||||||
$currentRun += 1;
|
++$currentRun;
|
||||||
} else {
|
} else {
|
||||||
if ($currentRun > $longestRun) {
|
if ($currentRun > $longestRun) {
|
||||||
$longestRun = $currentRun;
|
$longestRun = $currentRun;
|
||||||
|
|
|
@ -172,9 +172,9 @@ class ExceptionListenerTest extends \PHPUnit_Framework_TestCase
|
||||||
private function createExceptionListener(TokenStorageInterface $tokenStorage = null, AuthenticationTrustResolverInterface $trustResolver = null, HttpUtils $httpUtils = null, AuthenticationEntryPointInterface $authenticationEntryPoint = null, $errorPage = null, AccessDeniedHandlerInterface $accessDeniedHandler = null)
|
private function createExceptionListener(TokenStorageInterface $tokenStorage = null, AuthenticationTrustResolverInterface $trustResolver = null, HttpUtils $httpUtils = null, AuthenticationEntryPointInterface $authenticationEntryPoint = null, $errorPage = null, AccessDeniedHandlerInterface $accessDeniedHandler = null)
|
||||||
{
|
{
|
||||||
return new ExceptionListener(
|
return new ExceptionListener(
|
||||||
$tokenStorage ? $tokenStorage : $this->getMock('Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface'),
|
$tokenStorage ?: $this->getMock('Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface'),
|
||||||
$trustResolver ? $trustResolver : $this->getMock('Symfony\Component\Security\Core\Authentication\AuthenticationTrustResolverInterface'),
|
$trustResolver ?: $this->getMock('Symfony\Component\Security\Core\Authentication\AuthenticationTrustResolverInterface'),
|
||||||
$httpUtils ? $httpUtils : $this->getMock('Symfony\Component\Security\Http\HttpUtils'),
|
$httpUtils ?: $this->getMock('Symfony\Component\Security\Http\HttpUtils'),
|
||||||
'key',
|
'key',
|
||||||
$authenticationEntryPoint,
|
$authenticationEntryPoint,
|
||||||
$errorPage,
|
$errorPage,
|
||||||
|
|
|
@ -20,7 +20,7 @@ class RememberMeListenerTest extends \PHPUnit_Framework_TestCase
|
||||||
{
|
{
|
||||||
public function testOnCoreSecurityDoesNotTryToPopulateNonEmptyTokenStorage()
|
public function testOnCoreSecurityDoesNotTryToPopulateNonEmptyTokenStorage()
|
||||||
{
|
{
|
||||||
list($listener, $tokenStorage, , , ,) = $this->getListener();
|
list($listener, $tokenStorage) = $this->getListener();
|
||||||
|
|
||||||
$tokenStorage
|
$tokenStorage
|
||||||
->expects($this->once())
|
->expects($this->once())
|
||||||
|
@ -38,7 +38,7 @@ class RememberMeListenerTest extends \PHPUnit_Framework_TestCase
|
||||||
|
|
||||||
public function testOnCoreSecurityDoesNothingWhenNoCookieIsSet()
|
public function testOnCoreSecurityDoesNothingWhenNoCookieIsSet()
|
||||||
{
|
{
|
||||||
list($listener, $tokenStorage, $service, ,) = $this->getListener();
|
list($listener, $tokenStorage, $service) = $this->getListener();
|
||||||
|
|
||||||
$tokenStorage
|
$tokenStorage
|
||||||
->expects($this->once())
|
->expects($this->once())
|
||||||
|
@ -64,7 +64,7 @@ class RememberMeListenerTest extends \PHPUnit_Framework_TestCase
|
||||||
|
|
||||||
public function testOnCoreSecurityIgnoresAuthenticationExceptionThrownByAuthenticationManagerImplementation()
|
public function testOnCoreSecurityIgnoresAuthenticationExceptionThrownByAuthenticationManagerImplementation()
|
||||||
{
|
{
|
||||||
list($listener, $tokenStorage, $service, $manager,) = $this->getListener();
|
list($listener, $tokenStorage, $service, $manager) = $this->getListener();
|
||||||
|
|
||||||
$tokenStorage
|
$tokenStorage
|
||||||
->expects($this->once())
|
->expects($this->once())
|
||||||
|
@ -144,7 +144,7 @@ class RememberMeListenerTest extends \PHPUnit_Framework_TestCase
|
||||||
|
|
||||||
public function testOnCoreSecurity()
|
public function testOnCoreSecurity()
|
||||||
{
|
{
|
||||||
list($listener, $tokenStorage, $service, $manager,) = $this->getListener();
|
list($listener, $tokenStorage, $service, $manager) = $this->getListener();
|
||||||
|
|
||||||
$tokenStorage
|
$tokenStorage
|
||||||
->expects($this->once())
|
->expects($this->once())
|
||||||
|
|
|
@ -14,6 +14,9 @@ CHANGELOG
|
||||||
* [DEPRECATION] `GetSetMethodNormalizer::setCamelizedAttributes()` and
|
* [DEPRECATION] `GetSetMethodNormalizer::setCamelizedAttributes()` and
|
||||||
`PropertyNormalizer::setCamelizedAttributes()` are replaced by
|
`PropertyNormalizer::setCamelizedAttributes()` are replaced by
|
||||||
`CamelCaseToSnakeCaseNameConverter`
|
`CamelCaseToSnakeCaseNameConverter`
|
||||||
|
* [DEPRECATION] the `Exception` interface has been renamed to `ExceptionInterface`
|
||||||
|
* added `ObjectNormalizer` leveraging the `PropertyAccess` component to normalize
|
||||||
|
objects containing both properties and getters / setters / issers / hassers methods.
|
||||||
|
|
||||||
2.6.0
|
2.6.0
|
||||||
-----
|
-----
|
||||||
|
|
|
@ -14,7 +14,7 @@ namespace Symfony\Component\Serializer\Exception;
|
||||||
/**
|
/**
|
||||||
* Base exception.
|
* Base exception.
|
||||||
*
|
*
|
||||||
* @author Johannes M. Schmitt <schmittjoh@gmail.com>
|
* @deprecated since version 2.7, to be removed in 3.0. Use ExceptionInterface instead.
|
||||||
*/
|
*/
|
||||||
interface Exception
|
interface Exception
|
||||||
{
|
{
|
||||||
|
|
|
@ -0,0 +1,21 @@
|
||||||
|
<?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\Serializer\Exception;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Base exception interface.
|
||||||
|
*
|
||||||
|
* @author Johannes M. Schmitt <schmittjoh@gmail.com>
|
||||||
|
*/
|
||||||
|
interface ExceptionInterface extends Exception
|
||||||
|
{
|
||||||
|
}
|
|
@ -16,6 +16,6 @@ namespace Symfony\Component\Serializer\Exception;
|
||||||
*
|
*
|
||||||
* @author Johannes M. Schmitt <schmittjoh@gmail.com>
|
* @author Johannes M. Schmitt <schmittjoh@gmail.com>
|
||||||
*/
|
*/
|
||||||
class InvalidArgumentException extends \InvalidArgumentException implements Exception
|
class InvalidArgumentException extends \InvalidArgumentException implements ExceptionInterface
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,6 +16,6 @@ namespace Symfony\Component\Serializer\Exception;
|
||||||
*
|
*
|
||||||
* @author Lukas Kahwe Smith <smith@pooteeweet.org>
|
* @author Lukas Kahwe Smith <smith@pooteeweet.org>
|
||||||
*/
|
*/
|
||||||
class LogicException extends \LogicException implements Exception
|
class LogicException extends \LogicException implements ExceptionInterface
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,6 +16,6 @@ namespace Symfony\Component\Serializer\Exception;
|
||||||
*
|
*
|
||||||
* @author Johannes M. Schmitt <schmittjoh@gmail.com>
|
* @author Johannes M. Schmitt <schmittjoh@gmail.com>
|
||||||
*/
|
*/
|
||||||
class RuntimeException extends \RuntimeException implements Exception
|
class RuntimeException extends \RuntimeException implements ExceptionInterface
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,6 +16,6 @@ namespace Symfony\Component\Serializer\Exception;
|
||||||
*
|
*
|
||||||
* @author Lukas Kahwe Smith <smith@pooteeweet.org>
|
* @author Lukas Kahwe Smith <smith@pooteeweet.org>
|
||||||
*/
|
*/
|
||||||
class UnexpectedValueException extends \UnexpectedValueException implements Exception
|
class UnexpectedValueException extends \UnexpectedValueException implements ExceptionInterface
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,94 @@
|
||||||
|
<?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\Serializer\Mapping;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*
|
||||||
|
* @author Kévin Dunglas <dunglas@gmail.com>
|
||||||
|
*/
|
||||||
|
class AttributeMetadata implements AttributeMetadataInterface
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* @var string
|
||||||
|
*
|
||||||
|
* @internal This property is public in order to reduce the size of the
|
||||||
|
* class' serialized representation. Do not access it. Use
|
||||||
|
* {@link getName()} instead.
|
||||||
|
*/
|
||||||
|
public $name;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var array
|
||||||
|
*
|
||||||
|
* @internal This property is public in order to reduce the size of the
|
||||||
|
* class' serialized representation. Do not access it. Use
|
||||||
|
* {@link getGroups()} instead.
|
||||||
|
*/
|
||||||
|
public $groups = array();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructs a metadata for the given attribute.
|
||||||
|
*
|
||||||
|
* @param string $name
|
||||||
|
*/
|
||||||
|
public function __construct($name)
|
||||||
|
{
|
||||||
|
$this->name = $name;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*/
|
||||||
|
public function getName()
|
||||||
|
{
|
||||||
|
return $this->name;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*/
|
||||||
|
public function addGroup($group)
|
||||||
|
{
|
||||||
|
if (!in_array($group, $this->groups)) {
|
||||||
|
$this->groups[] = $group;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*/
|
||||||
|
public function getGroups()
|
||||||
|
{
|
||||||
|
return $this->groups;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*/
|
||||||
|
public function merge(AttributeMetadataInterface $attributeMetadata)
|
||||||
|
{
|
||||||
|
foreach ($attributeMetadata->getGroups() as $group) {
|
||||||
|
$this->addGroup($group);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the names of the properties that should be serialized.
|
||||||
|
*
|
||||||
|
* @return string[]
|
||||||
|
*/
|
||||||
|
public function __sleep()
|
||||||
|
{
|
||||||
|
return array('name', 'groups');
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,50 @@
|
||||||
|
<?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\Serializer\Mapping;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Stores metadata needed for serializing and deserializing attributes.
|
||||||
|
*
|
||||||
|
* Primarily, the metadata stores serialization groups.
|
||||||
|
*
|
||||||
|
* @author Kévin Dunglas <dunglas@gmail.com>
|
||||||
|
*/
|
||||||
|
interface AttributeMetadataInterface
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Gets the attribute name.
|
||||||
|
*
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
public function getName();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Adds this attribute to the given group.
|
||||||
|
*
|
||||||
|
* @param string $group
|
||||||
|
*/
|
||||||
|
public function addGroup($group);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets groups of this attribute.
|
||||||
|
*
|
||||||
|
* @return string[]
|
||||||
|
*/
|
||||||
|
public function getGroups();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Merges an {@see AttributeMetadataInterface} with in the current one.
|
||||||
|
*
|
||||||
|
* @param AttributeMetadataInterface $attributeMetadata
|
||||||
|
*/
|
||||||
|
public function merge(AttributeMetadataInterface $attributeMetadata);
|
||||||
|
}
|
|
@ -12,31 +12,29 @@
|
||||||
namespace Symfony\Component\Serializer\Mapping;
|
namespace Symfony\Component\Serializer\Mapping;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Stores all metadata needed for serializing objects of specific class.
|
* {@inheritdoc}
|
||||||
*
|
|
||||||
* Primarily, the metadata stores serialization groups.
|
|
||||||
*
|
*
|
||||||
* @author Kévin Dunglas <dunglas@gmail.com>
|
* @author Kévin Dunglas <dunglas@gmail.com>
|
||||||
*/
|
*/
|
||||||
class ClassMetadata
|
class ClassMetadata implements ClassMetadataInterface
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
* @var string
|
* @var string
|
||||||
*
|
*
|
||||||
* @internal This property is public in order to reduce the size of the
|
* @internal This property is public in order to reduce the size of the
|
||||||
* class' serialized representation. Do not access it. Use
|
* class' serialized representation. Do not access it. Use
|
||||||
* {@link getClassName()} instead.
|
* {@link getName()} instead.
|
||||||
*/
|
*/
|
||||||
public $name;
|
public $name;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @var array
|
* @var AttributeMetadataInterface[]
|
||||||
*
|
*
|
||||||
* @internal This property is public in order to reduce the size of the
|
* @internal This property is public in order to reduce the size of the
|
||||||
* class' serialized representation. Do not access it. Use
|
* class' serialized representation. Do not access it. Use
|
||||||
* {@link getGroups()} instead.
|
* {@link getAttributesMetadata()} instead.
|
||||||
*/
|
*/
|
||||||
public $attributesGroups = array();
|
public $attributesMetadata = array();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @var \ReflectionClass
|
* @var \ReflectionClass
|
||||||
|
@ -54,66 +52,50 @@ class ClassMetadata
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the name of the backing PHP class.
|
* {@inheritdoc}
|
||||||
*
|
|
||||||
* @return string The name of the backing class.
|
|
||||||
*/
|
*/
|
||||||
public function getClassName()
|
public function getName()
|
||||||
{
|
{
|
||||||
return $this->name;
|
return $this->name;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets serialization groups.
|
* {@inheritdoc}
|
||||||
*
|
|
||||||
* @return array
|
|
||||||
*/
|
*/
|
||||||
public function getAttributesGroups()
|
public function addAttributeMetadata(AttributeMetadataInterface $attributeMetadata)
|
||||||
{
|
{
|
||||||
return $this->attributesGroups;
|
$this->attributesMetadata[$attributeMetadata->getName()] = $attributeMetadata;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Adds an attribute to a serialization group
|
* {@inheritdoc}
|
||||||
*
|
|
||||||
* @param string $attribute
|
|
||||||
* @param string $group
|
|
||||||
* @throws \InvalidArgumentException
|
|
||||||
*/
|
*/
|
||||||
public function addAttributeGroup($attribute, $group)
|
public function getAttributesMetadata()
|
||||||
{
|
{
|
||||||
if (!is_string($attribute) || !is_string($group)) {
|
return $this->attributesMetadata;
|
||||||
throw new \InvalidArgumentException('Arguments must be strings.');
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!isset($this->groups[$group]) || !in_array($attribute, $this->attributesGroups[$group])) {
|
|
||||||
$this->attributesGroups[$group][] = $attribute;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Merges attributes' groups.
|
* {@inheritdoc}
|
||||||
*
|
|
||||||
* @param ClassMetadata $classMetadata
|
|
||||||
*/
|
*/
|
||||||
public function mergeAttributesGroups(ClassMetadata $classMetadata)
|
public function merge(ClassMetadataInterface $classMetadata)
|
||||||
{
|
{
|
||||||
foreach ($classMetadata->getAttributesGroups() as $group => $attributes) {
|
foreach ($classMetadata->getAttributesMetadata() as $attributeMetadata) {
|
||||||
foreach ($attributes as $attribute) {
|
if (isset($this->attributesMetadata[$attributeMetadata->getName()])) {
|
||||||
$this->addAttributeGroup($attribute, $group);
|
$this->attributesMetadata[$attributeMetadata->getName()]->merge($attributeMetadata);
|
||||||
|
} else {
|
||||||
|
$this->addAttributeMetadata($attributeMetadata);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns a ReflectionClass instance for this class.
|
* {@inheritdoc}
|
||||||
*
|
|
||||||
* @return \ReflectionClass
|
|
||||||
*/
|
*/
|
||||||
public function getReflectionClass()
|
public function getReflectionClass()
|
||||||
{
|
{
|
||||||
if (!$this->reflClass) {
|
if (!$this->reflClass) {
|
||||||
$this->reflClass = new \ReflectionClass($this->getClassName());
|
$this->reflClass = new \ReflectionClass($this->getName());
|
||||||
}
|
}
|
||||||
|
|
||||||
return $this->reflClass;
|
return $this->reflClass;
|
||||||
|
@ -128,7 +110,7 @@ class ClassMetadata
|
||||||
{
|
{
|
||||||
return array(
|
return array(
|
||||||
'name',
|
'name',
|
||||||
'attributesGroups',
|
'attributes',
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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\Serializer\Mapping;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Stores metadata needed for serializing and deserializing objects of specific class.
|
||||||
|
*
|
||||||
|
* Primarily, the metadata stores the list of attributes to serialize or deserialize.
|
||||||
|
*
|
||||||
|
* @author Kévin Dunglas <dunglas@gmail.com>
|
||||||
|
*/
|
||||||
|
interface ClassMetadataInterface
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Returns the name of the backing PHP class.
|
||||||
|
*
|
||||||
|
* @return string The name of the backing class.
|
||||||
|
*/
|
||||||
|
public function getName();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Adds an {@link AttributeMetadataInterface}.
|
||||||
|
*
|
||||||
|
* @param AttributeMetadataInterface $attributeMetadata
|
||||||
|
*/
|
||||||
|
public function addAttributeMetadata(AttributeMetadataInterface $attributeMetadata);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the list of {@link AttributeMetadataInterface}.
|
||||||
|
*
|
||||||
|
* @return AttributeMetadataInterface[]
|
||||||
|
*/
|
||||||
|
public function getAttributesMetadata();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Merges a {@link ClassMetadataInterface} in the current one.
|
||||||
|
*
|
||||||
|
* @param ClassMetadataInterface $classMetadata
|
||||||
|
*/
|
||||||
|
public function merge(ClassMetadataInterface $classMetadata);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a {@link \ReflectionClass} instance for this class.
|
||||||
|
*
|
||||||
|
* @return \ReflectionClass
|
||||||
|
*/
|
||||||
|
public function getReflectionClass();
|
||||||
|
}
|
|
@ -12,6 +12,7 @@
|
||||||
namespace Symfony\Component\Serializer\Mapping\Factory;
|
namespace Symfony\Component\Serializer\Mapping\Factory;
|
||||||
|
|
||||||
use Doctrine\Common\Cache\Cache;
|
use Doctrine\Common\Cache\Cache;
|
||||||
|
use Symfony\Component\Serializer\Exception\InvalidArgumentException;
|
||||||
use Symfony\Component\Serializer\Mapping\ClassMetadata;
|
use Symfony\Component\Serializer\Mapping\ClassMetadata;
|
||||||
use Symfony\Component\Serializer\Mapping\Loader\LoaderInterface;
|
use Symfony\Component\Serializer\Mapping\Loader\LoaderInterface;
|
||||||
|
|
||||||
|
@ -20,7 +21,7 @@ use Symfony\Component\Serializer\Mapping\Loader\LoaderInterface;
|
||||||
*
|
*
|
||||||
* @author Kévin Dunglas <dunglas@gmail.com>
|
* @author Kévin Dunglas <dunglas@gmail.com>
|
||||||
*/
|
*/
|
||||||
class ClassMetadataFactory
|
class ClassMetadataFactory implements ClassMetadataFactoryInterface
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
* @var LoaderInterface
|
* @var LoaderInterface
|
||||||
|
@ -46,28 +47,13 @@ class ClassMetadataFactory
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* If the method was called with the same class name (or an object of that
|
* {@inheritdoc}
|
||||||
* class) before, the same metadata instance is returned.
|
|
||||||
*
|
|
||||||
* If the factory was configured with a cache, this method will first look
|
|
||||||
* for an existing metadata instance in the cache. If an existing instance
|
|
||||||
* is found, it will be returned without further ado.
|
|
||||||
*
|
|
||||||
* Otherwise, a new metadata instance is created. If the factory was
|
|
||||||
* configured with a loader, the metadata is passed to the
|
|
||||||
* {@link LoaderInterface::loadClassMetadata()} method for further
|
|
||||||
* configuration. At last, the new object is returned.
|
|
||||||
*
|
|
||||||
* @param string|object $value
|
|
||||||
* @return ClassMetadata
|
|
||||||
* @throws \InvalidArgumentException
|
|
||||||
|
|
||||||
*/
|
*/
|
||||||
public function getMetadataFor($value)
|
public function getMetadataFor($value)
|
||||||
{
|
{
|
||||||
$class = $this->getClass($value);
|
$class = $this->getClass($value);
|
||||||
if (!$class) {
|
if (!$class) {
|
||||||
throw new \InvalidArgumentException(sprintf('Cannot create metadata for non-objects. Got: %s', gettype($value)));
|
throw new InvalidArgumentException(sprintf('Cannot create metadata for non-objects. Got: "%s"', gettype($value)));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isset($this->loadedClasses[$class])) {
|
if (isset($this->loadedClasses[$class])) {
|
||||||
|
@ -79,39 +65,33 @@ class ClassMetadataFactory
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!class_exists($class) && !interface_exists($class)) {
|
if (!class_exists($class) && !interface_exists($class)) {
|
||||||
throw new \InvalidArgumentException(sprintf('The class or interface "%s" does not exist.', $class));
|
throw new InvalidArgumentException(sprintf('The class or interface "%s" does not exist.', $class));
|
||||||
}
|
}
|
||||||
|
|
||||||
$metadata = new ClassMetadata($class);
|
$classMetadata = new ClassMetadata($class);
|
||||||
|
$this->loader->loadClassMetadata($classMetadata);
|
||||||
|
|
||||||
$reflClass = $metadata->getReflectionClass();
|
$reflectionClass = $classMetadata->getReflectionClass();
|
||||||
|
|
||||||
// Include groups from the parent class
|
// Include metadata from the parent class
|
||||||
if ($parent = $reflClass->getParentClass()) {
|
if ($parent = $reflectionClass->getParentClass()) {
|
||||||
$metadata->mergeAttributesGroups($this->getMetadataFor($parent->name));
|
$classMetadata->merge($this->getMetadataFor($parent->name));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Include groups from all implemented interfaces
|
// Include metadata from all implemented interfaces
|
||||||
foreach ($reflClass->getInterfaces() as $interface) {
|
foreach ($reflectionClass->getInterfaces() as $interface) {
|
||||||
$metadata->mergeAttributesGroups($this->getMetadataFor($interface->name));
|
$classMetadata->merge($this->getMetadataFor($interface->name));
|
||||||
}
|
|
||||||
|
|
||||||
if ($this->loader) {
|
|
||||||
$this->loader->loadClassMetadata($metadata);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($this->cache) {
|
if ($this->cache) {
|
||||||
$this->cache->save($class, $metadata);
|
$this->cache->save($class, $classMetadata);
|
||||||
}
|
}
|
||||||
|
|
||||||
return $this->loadedClasses[$class] = $metadata;
|
return $this->loadedClasses[$class] = $classMetadata;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Checks if class has metadata.
|
* {@inheritdoc}
|
||||||
*
|
|
||||||
* @param mixed $value
|
|
||||||
* @return bool
|
|
||||||
*/
|
*/
|
||||||
public function hasMetadataFor($value)
|
public function hasMetadataFor($value)
|
||||||
{
|
{
|
||||||
|
@ -123,7 +103,8 @@ class ClassMetadataFactory
|
||||||
/**
|
/**
|
||||||
* Gets a class name for a given class or instance.
|
* Gets a class name for a given class or instance.
|
||||||
*
|
*
|
||||||
* @param $value
|
* @param mixed $value
|
||||||
|
*
|
||||||
* @return string|bool
|
* @return string|bool
|
||||||
*/
|
*/
|
||||||
private function getClass($value)
|
private function getClass($value)
|
||||||
|
|
|
@ -0,0 +1,53 @@
|
||||||
|
<?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\Serializer\Mapping\Factory;
|
||||||
|
|
||||||
|
use Symfony\Component\Serializer\Exception\InvalidArgumentException;
|
||||||
|
use Symfony\Component\Serializer\Mapping\ClassMetadataInterface;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a {@see ClassMetadataInterface}.
|
||||||
|
*
|
||||||
|
* @author Kévin Dunglas <dunglas@gmail.com>
|
||||||
|
*/
|
||||||
|
interface ClassMetadataFactoryInterface
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* If the method was called with the same class name (or an object of that
|
||||||
|
* class) before, the same metadata instance is returned.
|
||||||
|
*
|
||||||
|
* If the factory was configured with a cache, this method will first look
|
||||||
|
* for an existing metadata instance in the cache. If an existing instance
|
||||||
|
* is found, it will be returned without further ado.
|
||||||
|
*
|
||||||
|
* Otherwise, a new metadata instance is created. If the factory was
|
||||||
|
* configured with a loader, the metadata is passed to the
|
||||||
|
* {@link LoaderInterface::loadClassMetadata()} method for further
|
||||||
|
* configuration. At last, the new object is returned.
|
||||||
|
*
|
||||||
|
* @param string|object $value
|
||||||
|
*
|
||||||
|
* @return ClassMetadataInterface
|
||||||
|
*
|
||||||
|
* @throws InvalidArgumentException
|
||||||
|
*/
|
||||||
|
public function getMetadataFor($value);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks if class has metadata.
|
||||||
|
*
|
||||||
|
* @param mixed $value
|
||||||
|
*
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
public function hasMetadataFor($value);
|
||||||
|
}
|
|
@ -13,7 +13,9 @@ namespace Symfony\Component\Serializer\Mapping\Loader;
|
||||||
|
|
||||||
use Doctrine\Common\Annotations\Reader;
|
use Doctrine\Common\Annotations\Reader;
|
||||||
use Symfony\Component\Serializer\Annotation\Groups;
|
use Symfony\Component\Serializer\Annotation\Groups;
|
||||||
use Symfony\Component\Serializer\Mapping\ClassMetadata;
|
use Symfony\Component\Serializer\Exception\MappingException;
|
||||||
|
use Symfony\Component\Serializer\Mapping\AttributeMetadata;
|
||||||
|
use Symfony\Component\Serializer\Mapping\ClassMetadataInterface;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Annotation loader.
|
* Annotation loader.
|
||||||
|
@ -38,18 +40,25 @@ class AnnotationLoader implements LoaderInterface
|
||||||
/**
|
/**
|
||||||
* {@inheritdoc}
|
* {@inheritdoc}
|
||||||
*/
|
*/
|
||||||
public function loadClassMetadata(ClassMetadata $metadata)
|
public function loadClassMetadata(ClassMetadataInterface $classMetadata)
|
||||||
{
|
{
|
||||||
$reflClass = $metadata->getReflectionClass();
|
$reflectionClass = $classMetadata->getReflectionClass();
|
||||||
$className = $reflClass->name;
|
$className = $reflectionClass->name;
|
||||||
$loaded = false;
|
$loaded = false;
|
||||||
|
|
||||||
foreach ($reflClass->getProperties() as $property) {
|
$attributesMetadata = $classMetadata->getAttributesMetadata();
|
||||||
|
|
||||||
|
foreach ($reflectionClass->getProperties() as $property) {
|
||||||
|
if (!isset($attributeMetadata[$property->name])) {
|
||||||
|
$attributesMetadata[$property->name] = new AttributeMetadata($property->name);
|
||||||
|
$classMetadata->addAttributeMetadata($attributesMetadata[$property->name]);
|
||||||
|
}
|
||||||
|
|
||||||
if ($property->getDeclaringClass()->name == $className) {
|
if ($property->getDeclaringClass()->name == $className) {
|
||||||
foreach ($this->reader->getPropertyAnnotations($property) as $groups) {
|
foreach ($this->reader->getPropertyAnnotations($property) as $groups) {
|
||||||
if ($groups instanceof Groups) {
|
if ($groups instanceof Groups) {
|
||||||
foreach ($groups->getGroups() as $group) {
|
foreach ($groups->getGroups() as $group) {
|
||||||
$metadata->addAttributeGroup($property->name, $group);
|
$attributesMetadata[$property->name]->addGroup($group);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -58,16 +67,25 @@ class AnnotationLoader implements LoaderInterface
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach ($reflClass->getMethods() as $method) {
|
foreach ($reflectionClass->getMethods() as $method) {
|
||||||
if ($method->getDeclaringClass()->name == $className) {
|
if ($method->getDeclaringClass()->name == $className) {
|
||||||
foreach ($this->reader->getMethodAnnotations($method) as $groups) {
|
foreach ($this->reader->getMethodAnnotations($method) as $groups) {
|
||||||
if ($groups instanceof Groups) {
|
if ($groups instanceof Groups) {
|
||||||
if (preg_match('/^(get|is)(.+)$/i', $method->name, $matches)) {
|
if (preg_match('/^(get|is)(.+)$/i', $method->name, $matches)) {
|
||||||
|
$attributeName = lcfirst($matches[2]);
|
||||||
|
|
||||||
|
if (isset($attributesMetadata[$attributeName])) {
|
||||||
|
$attributeMetadata = $attributesMetadata[$attributeName];
|
||||||
|
} else {
|
||||||
|
$attributesMetadata[$attributeName] = $attributeMetadata = new AttributeMetadata($attributeName);
|
||||||
|
$classMetadata->addAttributeMetadata($attributeMetadata);
|
||||||
|
}
|
||||||
|
|
||||||
foreach ($groups->getGroups() as $group) {
|
foreach ($groups->getGroups() as $group) {
|
||||||
$metadata->addAttributeGroup(lcfirst($matches[2]), $group);
|
$attributeMetadata->addGroup($group);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
throw new \BadMethodCallException(sprintf('Groups on "%s::%s" cannot be added. Groups can only be added on methods beginning with "get" or "is".', $className, $method->name));
|
throw new MappingException(sprintf('Groups on "%s::%s" cannot be added. Groups can only be added on methods beginning with "get" or "is".', $className, $method->name));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -13,8 +13,16 @@ namespace Symfony\Component\Serializer\Mapping\Loader;
|
||||||
|
|
||||||
use Symfony\Component\Serializer\Exception\MappingException;
|
use Symfony\Component\Serializer\Exception\MappingException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Base class for all file based loaders.
|
||||||
|
*
|
||||||
|
* @author Kévin Dunglas <dunglas@gmail.com>
|
||||||
|
*/
|
||||||
abstract class FileLoader implements LoaderInterface
|
abstract class FileLoader implements LoaderInterface
|
||||||
{
|
{
|
||||||
|
/**
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
protected $file;
|
protected $file;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -22,8 +30,7 @@ abstract class FileLoader implements LoaderInterface
|
||||||
*
|
*
|
||||||
* @param string $file The mapping file to load
|
* @param string $file The mapping file to load
|
||||||
*
|
*
|
||||||
* @throws MappingException if the mapping file does not exist
|
* @throws MappingException if the mapping file does not exist or is not readable
|
||||||
* @throws MappingException if the mapping file is not readable
|
|
||||||
*/
|
*/
|
||||||
public function __construct($file)
|
public function __construct($file)
|
||||||
{
|
{
|
||||||
|
|
|
@ -12,24 +12,28 @@
|
||||||
namespace Symfony\Component\Serializer\Mapping\Loader;
|
namespace Symfony\Component\Serializer\Mapping\Loader;
|
||||||
|
|
||||||
use Symfony\Component\Serializer\Exception\MappingException;
|
use Symfony\Component\Serializer\Exception\MappingException;
|
||||||
use Symfony\Component\Serializer\Mapping\ClassMetadata;
|
use Symfony\Component\Serializer\Mapping\ClassMetadataInterface;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Calls multiple LoaderInterface instances in a chain
|
* Calls multiple {@link LoaderInterface} instances in a chain.
|
||||||
*
|
*
|
||||||
* This class accepts multiple instances of LoaderInterface to be passed to the
|
* This class accepts multiple instances of LoaderInterface to be passed to the
|
||||||
* constructor. When loadClassMetadata() is called, the same method is called
|
* constructor. When {@link loadClassMetadata()} is called, the same method is called
|
||||||
* in <em>all</em> of these loaders, regardless of whether any of them was
|
* in <em>all</em> of these loaders, regardless of whether any of them was
|
||||||
* successful or not.
|
* successful or not.
|
||||||
*
|
*
|
||||||
* @author Bernhard Schussek <bschussek@gmail.com>
|
* @author Bernhard Schussek <bschussek@gmail.com>
|
||||||
|
* @author Kévin Dunglas <dunglas@gmail.com>
|
||||||
*/
|
*/
|
||||||
class LoaderChain implements LoaderInterface
|
class LoaderChain implements LoaderInterface
|
||||||
{
|
{
|
||||||
protected $loaders;
|
/**
|
||||||
|
* @var LoaderInterface[]
|
||||||
|
*/
|
||||||
|
private $loaders;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Accepts a list of LoaderInterface instances
|
* Accepts a list of LoaderInterface instances.
|
||||||
*
|
*
|
||||||
* @param LoaderInterface[] $loaders An array of LoaderInterface instances
|
* @param LoaderInterface[] $loaders An array of LoaderInterface instances
|
||||||
*
|
*
|
||||||
|
@ -49,7 +53,7 @@ class LoaderChain implements LoaderInterface
|
||||||
/**
|
/**
|
||||||
* {@inheritdoc}
|
* {@inheritdoc}
|
||||||
*/
|
*/
|
||||||
public function loadClassMetadata(ClassMetadata $metadata)
|
public function loadClassMetadata(ClassMetadataInterface $metadata)
|
||||||
{
|
{
|
||||||
$success = false;
|
$success = false;
|
||||||
|
|
||||||
|
|
|
@ -11,10 +11,10 @@
|
||||||
|
|
||||||
namespace Symfony\Component\Serializer\Mapping\Loader;
|
namespace Symfony\Component\Serializer\Mapping\Loader;
|
||||||
|
|
||||||
use Symfony\Component\Serializer\Mapping\ClassMetadata;
|
use Symfony\Component\Serializer\Mapping\ClassMetadataInterface;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Loads class metadata.
|
* Loads {@link ClassMetadataInterface}.
|
||||||
*
|
*
|
||||||
* @author Kévin Dunglas <dunglas@gmail.com>
|
* @author Kévin Dunglas <dunglas@gmail.com>
|
||||||
*/
|
*/
|
||||||
|
@ -23,9 +23,9 @@ interface LoaderInterface
|
||||||
/**
|
/**
|
||||||
* Load class metadata.
|
* Load class metadata.
|
||||||
*
|
*
|
||||||
* @param ClassMetadata $metadata A metadata
|
* @param ClassMetadataInterface $classMetadata A metadata
|
||||||
*
|
*
|
||||||
* @return bool
|
* @return bool
|
||||||
*/
|
*/
|
||||||
public function loadClassMetadata(ClassMetadata $metadata);
|
public function loadClassMetadata(ClassMetadataInterface $classMetadata);
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,7 +13,8 @@ namespace Symfony\Component\Serializer\Mapping\Loader;
|
||||||
|
|
||||||
use Symfony\Component\Config\Util\XmlUtils;
|
use Symfony\Component\Config\Util\XmlUtils;
|
||||||
use Symfony\Component\Serializer\Exception\MappingException;
|
use Symfony\Component\Serializer\Exception\MappingException;
|
||||||
use Symfony\Component\Serializer\Mapping\ClassMetadata;
|
use Symfony\Component\Serializer\Mapping\AttributeMetadata;
|
||||||
|
use Symfony\Component\Serializer\Mapping\ClassMetadataInterface;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Loads XML mapping files.
|
* Loads XML mapping files.
|
||||||
|
@ -23,7 +24,7 @@ use Symfony\Component\Serializer\Mapping\ClassMetadata;
|
||||||
class XmlFileLoader extends FileLoader
|
class XmlFileLoader extends FileLoader
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
* An array of SimpleXMLElement instances.
|
* An array of {@class \SimpleXMLElement} instances.
|
||||||
*
|
*
|
||||||
* @var \SimpleXMLElement[]|null
|
* @var \SimpleXMLElement[]|null
|
||||||
*/
|
*/
|
||||||
|
@ -32,7 +33,7 @@ class XmlFileLoader extends FileLoader
|
||||||
/**
|
/**
|
||||||
* {@inheritdoc}
|
* {@inheritdoc}
|
||||||
*/
|
*/
|
||||||
public function loadClassMetadata(ClassMetadata $metadata)
|
public function loadClassMetadata(ClassMetadataInterface $classMetadata)
|
||||||
{
|
{
|
||||||
if (null === $this->classes) {
|
if (null === $this->classes) {
|
||||||
$this->classes = array();
|
$this->classes = array();
|
||||||
|
@ -43,12 +44,23 @@ class XmlFileLoader extends FileLoader
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isset($this->classes[$metadata->getClassName()])) {
|
$attributesMetadata = $classMetadata->getAttributesMetadata();
|
||||||
$xml = $this->classes[$metadata->getClassName()];
|
|
||||||
|
if (isset($this->classes[$classMetadata->getName()])) {
|
||||||
|
$xml = $this->classes[$classMetadata->getName()];
|
||||||
|
|
||||||
foreach ($xml->attribute as $attribute) {
|
foreach ($xml->attribute as $attribute) {
|
||||||
|
$attributeName = (string) $attribute['name'];
|
||||||
|
|
||||||
|
if (isset($attributesMetadata[$attributeName])) {
|
||||||
|
$attributeMetadata = $attributesMetadata[$attributeName];
|
||||||
|
} else {
|
||||||
|
$attributeMetadata = new AttributeMetadata($attributeName);
|
||||||
|
$classMetadata->addAttributeMetadata($attributeMetadata);
|
||||||
|
}
|
||||||
|
|
||||||
foreach ($attribute->group as $group) {
|
foreach ($attribute->group as $group) {
|
||||||
$metadata->addAttributeGroup((string) $attribute['name'], (string) $group);
|
$attributeMetadata->addGroup((string) $group);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -59,7 +71,7 @@ class XmlFileLoader extends FileLoader
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Parse a XML File.
|
* Parses a XML File.
|
||||||
*
|
*
|
||||||
* @param string $file Path of file
|
* @param string $file Path of file
|
||||||
*
|
*
|
||||||
|
|
|
@ -12,11 +12,12 @@
|
||||||
namespace Symfony\Component\Serializer\Mapping\Loader;
|
namespace Symfony\Component\Serializer\Mapping\Loader;
|
||||||
|
|
||||||
use Symfony\Component\Serializer\Exception\MappingException;
|
use Symfony\Component\Serializer\Exception\MappingException;
|
||||||
use Symfony\Component\Serializer\Mapping\ClassMetadata;
|
use Symfony\Component\Serializer\Mapping\AttributeMetadata;
|
||||||
|
use Symfony\Component\Serializer\Mapping\ClassMetadataInterface;
|
||||||
use Symfony\Component\Yaml\Parser;
|
use Symfony\Component\Yaml\Parser;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* YAML File Loader
|
* YAML File Loader.
|
||||||
*
|
*
|
||||||
* @author Kévin Dunglas <dunglas@gmail.com>
|
* @author Kévin Dunglas <dunglas@gmail.com>
|
||||||
*/
|
*/
|
||||||
|
@ -34,7 +35,7 @@ class YamlFileLoader extends FileLoader
|
||||||
/**
|
/**
|
||||||
* {@inheritdoc}
|
* {@inheritdoc}
|
||||||
*/
|
*/
|
||||||
public function loadClassMetadata(ClassMetadata $metadata)
|
public function loadClassMetadata(ClassMetadataInterface $classMetadata)
|
||||||
{
|
{
|
||||||
if (null === $this->classes) {
|
if (null === $this->classes) {
|
||||||
if (!stream_is_local($this->file)) {
|
if (!stream_is_local($this->file)) {
|
||||||
|
@ -59,14 +60,22 @@ class YamlFileLoader extends FileLoader
|
||||||
$this->classes = $classes;
|
$this->classes = $classes;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isset($this->classes[$metadata->getClassName()])) {
|
if (isset($this->classes[$classMetadata->getName()])) {
|
||||||
$yaml = $this->classes[$metadata->getClassName()];
|
$yaml = $this->classes[$classMetadata->getName()];
|
||||||
|
|
||||||
if (isset($yaml['attributes']) && is_array($yaml['attributes'])) {
|
if (isset($yaml['attributes']) && is_array($yaml['attributes'])) {
|
||||||
|
$attributesMetadata = $classMetadata->getAttributesMetadata();
|
||||||
foreach ($yaml['attributes'] as $attribute => $data) {
|
foreach ($yaml['attributes'] as $attribute => $data) {
|
||||||
|
if (isset($attributesMetadata[$attribute])) {
|
||||||
|
$attributeMetadata = $attributesMetadata[$attribute];
|
||||||
|
} else {
|
||||||
|
$attributeMetadata = new AttributeMetadata($attribute);
|
||||||
|
$classMetadata->addAttributeMetadata($attributeMetadata);
|
||||||
|
}
|
||||||
|
|
||||||
if (isset($data['groups'])) {
|
if (isset($data['groups'])) {
|
||||||
foreach ($data['groups'] as $group) {
|
foreach ($data['groups'] as $group) {
|
||||||
$metadata->addAttributeGroup($attribute, $group);
|
$attributeMetadata->addGroup($group);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,7 +15,8 @@ use Symfony\Component\Serializer\Exception\CircularReferenceException;
|
||||||
use Symfony\Component\Serializer\Exception\InvalidArgumentException;
|
use Symfony\Component\Serializer\Exception\InvalidArgumentException;
|
||||||
use Symfony\Component\Serializer\Exception\LogicException;
|
use Symfony\Component\Serializer\Exception\LogicException;
|
||||||
use Symfony\Component\Serializer\Exception\RuntimeException;
|
use Symfony\Component\Serializer\Exception\RuntimeException;
|
||||||
use Symfony\Component\Serializer\Mapping\Factory\ClassMetadataFactory;
|
use Symfony\Component\Serializer\Mapping\Factory\ClassMetadataFactoryInterface;
|
||||||
|
use Symfony\Component\Serializer\Mapping\AttributeMetadataInterface;
|
||||||
use Symfony\Component\Serializer\NameConverter\CamelCaseToSnakeCaseNameConverter;
|
use Symfony\Component\Serializer\NameConverter\CamelCaseToSnakeCaseNameConverter;
|
||||||
use Symfony\Component\Serializer\NameConverter\NameConverterInterface;
|
use Symfony\Component\Serializer\NameConverter\NameConverterInterface;
|
||||||
|
|
||||||
|
@ -26,21 +27,42 @@ use Symfony\Component\Serializer\NameConverter\NameConverterInterface;
|
||||||
*/
|
*/
|
||||||
abstract class AbstractNormalizer extends SerializerAwareNormalizer implements NormalizerInterface, DenormalizerInterface
|
abstract class AbstractNormalizer extends SerializerAwareNormalizer implements NormalizerInterface, DenormalizerInterface
|
||||||
{
|
{
|
||||||
|
/**
|
||||||
|
* @var int
|
||||||
|
*/
|
||||||
protected $circularReferenceLimit = 1;
|
protected $circularReferenceLimit = 1;
|
||||||
|
/**
|
||||||
|
* @var callable
|
||||||
|
*/
|
||||||
protected $circularReferenceHandler;
|
protected $circularReferenceHandler;
|
||||||
|
/**
|
||||||
|
* @var ClassMetadataFactoryInterface|null
|
||||||
|
*/
|
||||||
protected $classMetadataFactory;
|
protected $classMetadataFactory;
|
||||||
|
/**
|
||||||
|
* @var NameConverterInterface|null
|
||||||
|
*/
|
||||||
protected $nameConverter;
|
protected $nameConverter;
|
||||||
|
/**
|
||||||
|
* @var array
|
||||||
|
*/
|
||||||
protected $callbacks = array();
|
protected $callbacks = array();
|
||||||
|
/**
|
||||||
|
* @var array
|
||||||
|
*/
|
||||||
protected $ignoredAttributes = array();
|
protected $ignoredAttributes = array();
|
||||||
|
/**
|
||||||
|
* @var array
|
||||||
|
*/
|
||||||
protected $camelizedAttributes = array();
|
protected $camelizedAttributes = array();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets the {@link ClassMetadataFactory} to use.
|
* Sets the {@link ClassMetadataFactoryInterface} to use.
|
||||||
*
|
*
|
||||||
* @param ClassMetadataFactory|null $classMetadataFactory
|
* @param ClassMetadataFactoryInterface|null $classMetadataFactory
|
||||||
* @param NameConverterInterface|null $nameConverter
|
* @param NameConverterInterface|null $nameConverter
|
||||||
*/
|
*/
|
||||||
public function __construct(ClassMetadataFactory $classMetadataFactory = null, NameConverterInterface $nameConverter = null)
|
public function __construct(ClassMetadataFactoryInterface $classMetadataFactory = null, NameConverterInterface $nameConverter = null)
|
||||||
{
|
{
|
||||||
$this->classMetadataFactory = $classMetadataFactory;
|
$this->classMetadataFactory = $classMetadataFactory;
|
||||||
$this->nameConverter = $nameConverter;
|
$this->nameConverter = $nameConverter;
|
||||||
|
@ -219,19 +241,21 @@ abstract class AbstractNormalizer extends SerializerAwareNormalizer implements N
|
||||||
* Gets attributes to normalize using groups.
|
* Gets attributes to normalize using groups.
|
||||||
*
|
*
|
||||||
* @param string|object $classOrObject
|
* @param string|object $classOrObject
|
||||||
* @param array $context
|
* @param array $context
|
||||||
* @return array|bool
|
* @param bool $attributesAsString If false, return an array of {@link AttributeMetadataInterface}
|
||||||
|
*
|
||||||
|
* @return string[]|AttributeMetadataInterface[]|bool
|
||||||
*/
|
*/
|
||||||
protected function getAllowedAttributes($classOrObject, array $context)
|
protected function getAllowedAttributes($classOrObject, array $context, $attributesAsString = false)
|
||||||
{
|
{
|
||||||
if (!$this->classMetadataFactory || !isset($context['groups']) || !is_array($context['groups'])) {
|
if (!$this->classMetadataFactory || !isset($context['groups']) || !is_array($context['groups'])) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
$allowedAttributes = array();
|
$allowedAttributes = array();
|
||||||
foreach ($this->classMetadataFactory->getMetadataFor($classOrObject)->getAttributesGroups() as $group => $attributes) {
|
foreach ($this->classMetadataFactory->getMetadataFor($classOrObject)->getAttributesMetadata() as $attributeMetadata) {
|
||||||
if (in_array($group, $context['groups'])) {
|
if (count(array_intersect($attributeMetadata->getGroups(), $context['groups']))) {
|
||||||
$allowedAttributes = array_merge($allowedAttributes, $attributes);
|
$allowedAttributes[] = $attributesAsString ? $attributeMetadata->getName() : $attributeMetadata;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -52,7 +52,7 @@ class GetSetMethodNormalizer extends AbstractNormalizer
|
||||||
|
|
||||||
$reflectionObject = new \ReflectionObject($object);
|
$reflectionObject = new \ReflectionObject($object);
|
||||||
$reflectionMethods = $reflectionObject->getMethods(\ReflectionMethod::IS_PUBLIC);
|
$reflectionMethods = $reflectionObject->getMethods(\ReflectionMethod::IS_PUBLIC);
|
||||||
$allowedAttributes = $this->getAllowedAttributes($object, $context);
|
$allowedAttributes = $this->getAllowedAttributes($object, $context, true);
|
||||||
|
|
||||||
$attributes = array();
|
$attributes = array();
|
||||||
foreach ($reflectionMethods as $method) {
|
foreach ($reflectionMethods as $method) {
|
||||||
|
@ -68,7 +68,7 @@ class GetSetMethodNormalizer extends AbstractNormalizer
|
||||||
}
|
}
|
||||||
|
|
||||||
$attributeValue = $method->invoke($object);
|
$attributeValue = $method->invoke($object);
|
||||||
if (array_key_exists($attributeName, $this->callbacks)) {
|
if (isset($this->callbacks[$attributeName])) {
|
||||||
$attributeValue = call_user_func($this->callbacks[$attributeName], $attributeValue);
|
$attributeValue = call_user_func($this->callbacks[$attributeName], $attributeValue);
|
||||||
}
|
}
|
||||||
if (null !== $attributeValue && !is_scalar($attributeValue)) {
|
if (null !== $attributeValue && !is_scalar($attributeValue)) {
|
||||||
|
@ -97,7 +97,7 @@ class GetSetMethodNormalizer extends AbstractNormalizer
|
||||||
*/
|
*/
|
||||||
public function denormalize($data, $class, $format = null, array $context = array())
|
public function denormalize($data, $class, $format = null, array $context = array())
|
||||||
{
|
{
|
||||||
$allowedAttributes = $this->getAllowedAttributes($class, $context);
|
$allowedAttributes = $this->getAllowedAttributes($class, $context, true);
|
||||||
$normalizedData = $this->prepareForDenormalization($data);
|
$normalizedData = $this->prepareForDenormalization($data);
|
||||||
|
|
||||||
$reflectionClass = new \ReflectionClass($class);
|
$reflectionClass = new \ReflectionClass($class);
|
||||||
|
|
|
@ -0,0 +1,162 @@
|
||||||
|
<?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\Serializer\Normalizer;
|
||||||
|
|
||||||
|
use Symfony\Component\PropertyAccess\Exception\NoSuchPropertyException;
|
||||||
|
use Symfony\Component\PropertyAccess\PropertyAccess;
|
||||||
|
use Symfony\Component\PropertyAccess\PropertyAccessorInterface;
|
||||||
|
use Symfony\Component\Serializer\Exception\CircularReferenceException;
|
||||||
|
use Symfony\Component\Serializer\Exception\LogicException;
|
||||||
|
use Symfony\Component\Serializer\Mapping\Factory\ClassMetadataFactoryInterface;
|
||||||
|
use Symfony\Component\Serializer\NameConverter\NameConverterInterface;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Converts between objects and arrays using the PropertyAccess component.
|
||||||
|
*
|
||||||
|
* @author Kévin Dunglas <dunglas@gmail.com>
|
||||||
|
*/
|
||||||
|
class ObjectNormalizer extends AbstractNormalizer
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* @var PropertyAccessorInterface
|
||||||
|
*/
|
||||||
|
protected $propertyAccessor;
|
||||||
|
|
||||||
|
public function __construct(ClassMetadataFactoryInterface $classMetadataFactory = null, NameConverterInterface $nameConverter = null, PropertyAccessorInterface $propertyAccessor = null)
|
||||||
|
{
|
||||||
|
parent::__construct($classMetadataFactory, $nameConverter);
|
||||||
|
|
||||||
|
$this->propertyAccessor = $propertyAccessor ?: PropertyAccess::createPropertyAccessor();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*/
|
||||||
|
public function supportsNormalization($data, $format = null)
|
||||||
|
{
|
||||||
|
return is_object($data);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*
|
||||||
|
* @throws CircularReferenceException
|
||||||
|
*/
|
||||||
|
public function normalize($object, $format = null, array $context = array())
|
||||||
|
{
|
||||||
|
if ($this->isCircularReference($object, $context)) {
|
||||||
|
return $this->handleCircularReference($object);
|
||||||
|
}
|
||||||
|
|
||||||
|
$data = array();
|
||||||
|
$attributes = $this->getAllowedAttributes($object, $context, true);
|
||||||
|
|
||||||
|
// If not using groups, detect manually
|
||||||
|
if (false === $attributes) {
|
||||||
|
$attributes = array();
|
||||||
|
|
||||||
|
// methods
|
||||||
|
$reflClass = new \ReflectionClass($object);
|
||||||
|
foreach ($reflClass->getMethods(\ReflectionMethod::IS_PUBLIC) as $reflMethod) {
|
||||||
|
if (
|
||||||
|
!$reflMethod->isConstructor() &&
|
||||||
|
!$reflMethod->isDestructor() &&
|
||||||
|
0 === $reflMethod->getNumberOfRequiredParameters()
|
||||||
|
) {
|
||||||
|
$name = $reflMethod->getName();
|
||||||
|
|
||||||
|
if (strpos($name, 'get') === 0 || strpos($name, 'has') === 0) {
|
||||||
|
// getters and hassers
|
||||||
|
$attributes[lcfirst(substr($name, 3))] = true;
|
||||||
|
} elseif (strpos($name, 'is') === 0) {
|
||||||
|
// issers
|
||||||
|
$attributes[lcfirst(substr($name, 2))] = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// properties
|
||||||
|
foreach ($reflClass->getProperties(\ReflectionProperty::IS_PUBLIC) as $reflProperty) {
|
||||||
|
$attributes[$reflProperty->getName()] = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
$attributes = array_keys($attributes);
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach ($attributes as $attribute) {
|
||||||
|
if (in_array($attribute, $this->ignoredAttributes)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
$attributeValue = $this->propertyAccessor->getValue($object, $attribute);
|
||||||
|
|
||||||
|
if (isset($this->callbacks[$attribute])) {
|
||||||
|
$attributeValue = call_user_func($this->callbacks[$attribute], $attributeValue);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (null !== $attributeValue && !is_scalar($attributeValue)) {
|
||||||
|
if (!$this->serializer instanceof NormalizerInterface) {
|
||||||
|
throw new LogicException(sprintf('Cannot normalize attribute "%s" because injected serializer is not a normalizer', $attribute));
|
||||||
|
}
|
||||||
|
|
||||||
|
$attributeValue = $this->serializer->normalize($attributeValue, $format, $context);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($this->nameConverter) {
|
||||||
|
$attribute = $this->nameConverter->normalize($attribute);
|
||||||
|
}
|
||||||
|
|
||||||
|
$data[$attribute] = $attributeValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
return $data;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*/
|
||||||
|
public function supportsDenormalization($data, $type, $format = null)
|
||||||
|
{
|
||||||
|
return class_exists($type);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*/
|
||||||
|
public function denormalize($data, $class, $format = null, array $context = array())
|
||||||
|
{
|
||||||
|
$allowedAttributes = $this->getAllowedAttributes($class, $context, true);
|
||||||
|
$normalizedData = $this->prepareForDenormalization($data);
|
||||||
|
|
||||||
|
$reflectionClass = new \ReflectionClass($class);
|
||||||
|
$object = $this->instantiateObject($normalizedData, $class, $context, $reflectionClass, $allowedAttributes);
|
||||||
|
|
||||||
|
foreach ($normalizedData as $attribute => $value) {
|
||||||
|
$allowed = $allowedAttributes === false || in_array($attribute, $allowedAttributes);
|
||||||
|
$ignored = in_array($attribute, $this->ignoredAttributes);
|
||||||
|
|
||||||
|
if ($allowed && !$ignored) {
|
||||||
|
if ($this->nameConverter) {
|
||||||
|
$attribute = $this->nameConverter->normalize($attribute);
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
$this->propertyAccessor->setValue($object, $attribute, $value);
|
||||||
|
} catch (NoSuchPropertyException $exception) {
|
||||||
|
// Properties not found are ignored
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return $object;
|
||||||
|
}
|
||||||
|
}
|
|
@ -46,7 +46,7 @@ class PropertyNormalizer extends AbstractNormalizer
|
||||||
|
|
||||||
$reflectionObject = new \ReflectionObject($object);
|
$reflectionObject = new \ReflectionObject($object);
|
||||||
$attributes = array();
|
$attributes = array();
|
||||||
$allowedAttributes = $this->getAllowedAttributes($object, $context);
|
$allowedAttributes = $this->getAllowedAttributes($object, $context, true);
|
||||||
|
|
||||||
foreach ($reflectionObject->getProperties() as $property) {
|
foreach ($reflectionObject->getProperties() as $property) {
|
||||||
if (in_array($property->name, $this->ignoredAttributes)) {
|
if (in_array($property->name, $this->ignoredAttributes)) {
|
||||||
|
@ -64,7 +64,7 @@ class PropertyNormalizer extends AbstractNormalizer
|
||||||
|
|
||||||
$attributeValue = $property->getValue($object);
|
$attributeValue = $property->getValue($object);
|
||||||
|
|
||||||
if (array_key_exists($property->name, $this->callbacks)) {
|
if (isset($this->callbacks[$property->name])) {
|
||||||
$attributeValue = call_user_func($this->callbacks[$property->name], $attributeValue);
|
$attributeValue = call_user_func($this->callbacks[$property->name], $attributeValue);
|
||||||
}
|
}
|
||||||
if (null !== $attributeValue && !is_scalar($attributeValue)) {
|
if (null !== $attributeValue && !is_scalar($attributeValue)) {
|
||||||
|
@ -89,7 +89,7 @@ class PropertyNormalizer extends AbstractNormalizer
|
||||||
*/
|
*/
|
||||||
public function denormalize($data, $class, $format = null, array $context = array())
|
public function denormalize($data, $class, $format = null, array $context = array())
|
||||||
{
|
{
|
||||||
$allowedAttributes = $this->getAllowedAttributes($class, $context);
|
$allowedAttributes = $this->getAllowedAttributes($class, $context, true);
|
||||||
$data = $this->prepareForDenormalization($data);
|
$data = $this->prepareForDenormalization($data);
|
||||||
|
|
||||||
$reflectionClass = new \ReflectionClass($class);
|
$reflectionClass = new \ReflectionClass($class);
|
||||||
|
|
|
@ -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\Serializer\Tests\Mapping;
|
||||||
|
|
||||||
|
use Symfony\Component\Serializer\Mapping\AttributeMetadata;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Kévin Dunglas <dunglas@gmail.com>
|
||||||
|
*/
|
||||||
|
class AttributeMetadataTest extends \PHPUnit_Framework_TestCase
|
||||||
|
{
|
||||||
|
public function testInterface()
|
||||||
|
{
|
||||||
|
$attributeMetadata = new AttributeMetadata('name');
|
||||||
|
$this->assertInstanceOf('Symfony\Component\Serializer\Mapping\AttributeMetadataInterface', $attributeMetadata);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testGetName()
|
||||||
|
{
|
||||||
|
$attributeMetadata = new AttributeMetadata('name');
|
||||||
|
$this->assertEquals('name', $attributeMetadata->getName());
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testGroups()
|
||||||
|
{
|
||||||
|
$attributeMetadata = new AttributeMetadata('group');
|
||||||
|
$attributeMetadata->addGroup('a');
|
||||||
|
$attributeMetadata->addGroup('a');
|
||||||
|
$attributeMetadata->addGroup('b');
|
||||||
|
|
||||||
|
$this->assertEquals(array('a', 'b'), $attributeMetadata->getGroups());
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testMerge()
|
||||||
|
{
|
||||||
|
$attributeMetadata1 = new AttributeMetadata('a1');
|
||||||
|
$attributeMetadata1->addGroup('a');
|
||||||
|
$attributeMetadata1->addGroup('b');
|
||||||
|
|
||||||
|
$attributeMetadata2 = new AttributeMetadata('a2');
|
||||||
|
$attributeMetadata2->addGroup('a');
|
||||||
|
$attributeMetadata2->addGroup('c');
|
||||||
|
|
||||||
|
$attributeMetadata1->merge($attributeMetadata2);
|
||||||
|
|
||||||
|
$this->assertEquals(array('a', 'b', 'c'), $attributeMetadata1->getGroups());
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,65 @@
|
||||||
|
<?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\Serializer\Tests\Mapping;
|
||||||
|
|
||||||
|
use Symfony\Component\Serializer\Mapping\ClassMetadata;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Kévin Dunglas <dunglas@gmail.com>
|
||||||
|
*/
|
||||||
|
class ClassMetadataTest extends \PHPUnit_Framework_TestCase
|
||||||
|
{
|
||||||
|
public function testInterface()
|
||||||
|
{
|
||||||
|
$classMetadata = new ClassMetadata('name');
|
||||||
|
$this->assertInstanceOf('Symfony\Component\Serializer\Mapping\ClassMetadataInterface', $classMetadata);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testAttributeMetadata()
|
||||||
|
{
|
||||||
|
$classMetadata = new ClassMetadata('c');
|
||||||
|
|
||||||
|
$a1 = $this->getMock('Symfony\Component\Serializer\Mapping\AttributeMetadataInterface');
|
||||||
|
$a1->method('getName')->willReturn('a1');
|
||||||
|
|
||||||
|
$a2 = $this->getMock('Symfony\Component\Serializer\Mapping\AttributeMetadataInterface');
|
||||||
|
$a2->method('getName')->willReturn('a2');
|
||||||
|
|
||||||
|
$classMetadata->addAttributeMetadata($a1);
|
||||||
|
$classMetadata->addAttributeMetadata($a2);
|
||||||
|
|
||||||
|
$this->assertEquals(array('a1' => $a1, 'a2' => $a2), $classMetadata->getAttributesMetadata());
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testMerge()
|
||||||
|
{
|
||||||
|
$classMetadata1 = new ClassMetadata('c1');
|
||||||
|
$classMetadata2 = new ClassMetadata('c2');
|
||||||
|
|
||||||
|
$ac1 = $this->getMock('Symfony\Component\Serializer\Mapping\AttributeMetadataInterface');
|
||||||
|
$ac1->method('getName')->willReturn('a1');
|
||||||
|
$ac1->method('getGroups')->willReturn(array('a', 'b'));
|
||||||
|
|
||||||
|
$ac2 = $this->getMock('Symfony\Component\Serializer\Mapping\AttributeMetadataInterface');
|
||||||
|
$ac2->method('getName')->willReturn('a1');
|
||||||
|
$ac2->method('getGroups')->willReturn(array('b', 'c'));
|
||||||
|
|
||||||
|
$classMetadata1->addAttributeMetadata($ac1);
|
||||||
|
$classMetadata2->addAttributeMetadata($ac2);
|
||||||
|
|
||||||
|
$classMetadata1->merge($classMetadata2);
|
||||||
|
|
||||||
|
$ac1->method('getGroups')->willReturn('a', 'b', 'c');
|
||||||
|
|
||||||
|
$this->assertEquals(array('a1' => $ac1), $classMetadata2->getAttributesMetadata());
|
||||||
|
}
|
||||||
|
}
|
|
@ -14,21 +14,26 @@ namespace Symfony\Component\Serializer\Tests\Mapping\Factory;
|
||||||
use Doctrine\Common\Annotations\AnnotationReader;
|
use Doctrine\Common\Annotations\AnnotationReader;
|
||||||
use Symfony\Component\Serializer\Mapping\Factory\ClassMetadataFactory;
|
use Symfony\Component\Serializer\Mapping\Factory\ClassMetadataFactory;
|
||||||
use Symfony\Component\Serializer\Mapping\Loader\AnnotationLoader;
|
use Symfony\Component\Serializer\Mapping\Loader\AnnotationLoader;
|
||||||
|
use Symfony\Component\Serializer\Mapping\Loader\LoaderChain;
|
||||||
use Symfony\Component\Serializer\Tests\Mapping\TestClassMetadataFactory;
|
use Symfony\Component\Serializer\Tests\Mapping\TestClassMetadataFactory;
|
||||||
|
|
||||||
require_once __DIR__.'/../../../Annotation/Groups.php';
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author Kévin Dunglas <dunglas@gmail.com>
|
* @author Kévin Dunglas <dunglas@gmail.com>
|
||||||
*/
|
*/
|
||||||
class ClassMetadataFactoryTest extends \PHPUnit_Framework_TestCase
|
class ClassMetadataFactoryTest extends \PHPUnit_Framework_TestCase
|
||||||
{
|
{
|
||||||
|
public function testInterface()
|
||||||
|
{
|
||||||
|
$classMetadata = new ClassMetadataFactory(new LoaderChain(array()));
|
||||||
|
$this->assertInstanceOf('Symfony\Component\Serializer\Mapping\Factory\ClassMetadataFactory', $classMetadata);
|
||||||
|
}
|
||||||
|
|
||||||
public function testGetMetadataFor()
|
public function testGetMetadataFor()
|
||||||
{
|
{
|
||||||
$factory = new ClassMetadataFactory(new AnnotationLoader(new AnnotationReader()));
|
$factory = new ClassMetadataFactory(new AnnotationLoader(new AnnotationReader()));
|
||||||
$metadata = $factory->getMetadataFor('Symfony\Component\Serializer\Tests\Fixtures\GroupDummy');
|
$classMetadata = $factory->getMetadataFor('Symfony\Component\Serializer\Tests\Fixtures\GroupDummy');
|
||||||
|
|
||||||
$this->assertEquals(TestClassMetadataFactory::createClassMetadata(true, true), $metadata);
|
$this->assertEquals(TestClassMetadataFactory::createClassMetadata(true, true), $classMetadata);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testHasMetadataFor()
|
public function testHasMetadataFor()
|
||||||
|
|
|
@ -16,42 +16,51 @@ use Symfony\Component\Serializer\Mapping\ClassMetadata;
|
||||||
use Symfony\Component\Serializer\Mapping\Loader\AnnotationLoader;
|
use Symfony\Component\Serializer\Mapping\Loader\AnnotationLoader;
|
||||||
use Symfony\Component\Serializer\Tests\Mapping\TestClassMetadataFactory;
|
use Symfony\Component\Serializer\Tests\Mapping\TestClassMetadataFactory;
|
||||||
|
|
||||||
require_once __DIR__.'/../../../Annotation/Groups.php';
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author Kévin Dunglas <dunglas@gmail.com>
|
* @author Kévin Dunglas <dunglas@gmail.com>
|
||||||
*/
|
*/
|
||||||
class AnnotationLoaderTest extends \PHPUnit_Framework_TestCase
|
class AnnotationLoaderTest extends \PHPUnit_Framework_TestCase
|
||||||
{
|
{
|
||||||
|
/**
|
||||||
|
* @var AnnotationLoader
|
||||||
|
*/
|
||||||
|
private $loader;
|
||||||
|
|
||||||
|
protected function setUp()
|
||||||
|
{
|
||||||
|
$this->loader = new AnnotationLoader(new AnnotationReader());
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testInterface()
|
||||||
|
{
|
||||||
|
$this->assertInstanceOf('Symfony\Component\Serializer\Mapping\Loader\LoaderInterface', $this->loader);
|
||||||
|
}
|
||||||
|
|
||||||
public function testLoadClassMetadataReturnsTrueIfSuccessful()
|
public function testLoadClassMetadataReturnsTrueIfSuccessful()
|
||||||
{
|
{
|
||||||
$loader = new AnnotationLoader(new AnnotationReader());
|
$classMetadata = new ClassMetadata('Symfony\Component\Serializer\Tests\Fixtures\GroupDummy');
|
||||||
$metadata = new ClassMetadata('Symfony\Component\Serializer\Tests\Fixtures\GroupDummy');
|
|
||||||
|
|
||||||
$this->assertTrue($loader->loadClassMetadata($metadata));
|
$this->assertTrue($this->loader->loadClassMetadata($classMetadata));
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testLoadClassMetadata()
|
public function testLoadClassMetadata()
|
||||||
{
|
{
|
||||||
$loader = new AnnotationLoader(new AnnotationReader());
|
$classMetadata = new ClassMetadata('Symfony\Component\Serializer\Tests\Fixtures\GroupDummy');
|
||||||
$metadata = new ClassMetadata('Symfony\Component\Serializer\Tests\Fixtures\GroupDummy');
|
$this->loader->loadClassMetadata($classMetadata);
|
||||||
|
|
||||||
$loader->loadClassMetadata($metadata);
|
$this->assertEquals(TestClassMetadataFactory::createClassMetadata(), $classMetadata);
|
||||||
|
|
||||||
$this->assertEquals(TestClassMetadataFactory::createClassMetadata(), $metadata);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testLoadClassMetadataAndMerge()
|
public function testLoadClassMetadataAndMerge()
|
||||||
{
|
{
|
||||||
$loader = new AnnotationLoader(new AnnotationReader());
|
$classMetadata = new ClassMetadata('Symfony\Component\Serializer\Tests\Fixtures\GroupDummy');
|
||||||
$metadata = new ClassMetadata('Symfony\Component\Serializer\Tests\Fixtures\GroupDummy');
|
$parentClassMetadata = new ClassMetadata('Symfony\Component\Serializer\Tests\Fixtures\GroupDummyParent');
|
||||||
$parentMetadata = new ClassMetadata('Symfony\Component\Serializer\Tests\Fixtures\GroupDummyParent');
|
|
||||||
|
|
||||||
$loader->loadClassMetadata($parentMetadata);
|
$this->loader->loadClassMetadata($parentClassMetadata);
|
||||||
$metadata->mergeAttributesGroups($parentMetadata);
|
$classMetadata->merge($parentClassMetadata);
|
||||||
|
|
||||||
$loader->loadClassMetadata($metadata);
|
$this->loader->loadClassMetadata($classMetadata);
|
||||||
|
|
||||||
$this->assertEquals(TestClassMetadataFactory::createClassMetadata(true), $metadata);
|
$this->assertEquals(TestClassMetadataFactory::createClassMetadata(true), $classMetadata);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -20,7 +20,13 @@ use Symfony\Component\Serializer\Tests\Mapping\TestClassMetadataFactory;
|
||||||
*/
|
*/
|
||||||
class XmlFileLoaderTest extends \PHPUnit_Framework_TestCase
|
class XmlFileLoaderTest extends \PHPUnit_Framework_TestCase
|
||||||
{
|
{
|
||||||
|
/**
|
||||||
|
* @var XmlFileLoader
|
||||||
|
*/
|
||||||
private $loader;
|
private $loader;
|
||||||
|
/**
|
||||||
|
* @var ClassMetadata
|
||||||
|
*/
|
||||||
private $metadata;
|
private $metadata;
|
||||||
|
|
||||||
public function setUp()
|
public function setUp()
|
||||||
|
@ -29,6 +35,11 @@ class XmlFileLoaderTest extends \PHPUnit_Framework_TestCase
|
||||||
$this->metadata = new ClassMetadata('Symfony\Component\Serializer\Tests\Fixtures\GroupDummy');
|
$this->metadata = new ClassMetadata('Symfony\Component\Serializer\Tests\Fixtures\GroupDummy');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function testInterface()
|
||||||
|
{
|
||||||
|
$this->assertInstanceOf('Symfony\Component\Serializer\Mapping\Loader\LoaderInterface', $this->loader);
|
||||||
|
}
|
||||||
|
|
||||||
public function testLoadClassMetadataReturnsTrueIfSuccessful()
|
public function testLoadClassMetadataReturnsTrueIfSuccessful()
|
||||||
{
|
{
|
||||||
$this->assertTrue($this->loader->loadClassMetadata($this->metadata));
|
$this->assertTrue($this->loader->loadClassMetadata($this->metadata));
|
||||||
|
|
|
@ -20,7 +20,13 @@ use Symfony\Component\Serializer\Tests\Mapping\TestClassMetadataFactory;
|
||||||
*/
|
*/
|
||||||
class YamlFileLoaderTest extends \PHPUnit_Framework_TestCase
|
class YamlFileLoaderTest extends \PHPUnit_Framework_TestCase
|
||||||
{
|
{
|
||||||
|
/**
|
||||||
|
* @var YamlFileLoader
|
||||||
|
*/
|
||||||
private $loader;
|
private $loader;
|
||||||
|
/**
|
||||||
|
* @var ClassMetadata
|
||||||
|
*/
|
||||||
private $metadata;
|
private $metadata;
|
||||||
|
|
||||||
public function setUp()
|
public function setUp()
|
||||||
|
@ -29,6 +35,11 @@ class YamlFileLoaderTest extends \PHPUnit_Framework_TestCase
|
||||||
$this->metadata = new ClassMetadata('Symfony\Component\Serializer\Tests\Fixtures\GroupDummy');
|
$this->metadata = new ClassMetadata('Symfony\Component\Serializer\Tests\Fixtures\GroupDummy');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function testInterface()
|
||||||
|
{
|
||||||
|
$this->assertInstanceOf('Symfony\Component\Serializer\Mapping\Loader\LoaderInterface', $this->loader);
|
||||||
|
}
|
||||||
|
|
||||||
public function testLoadClassMetadataReturnsTrueIfSuccessful()
|
public function testLoadClassMetadataReturnsTrueIfSuccessful()
|
||||||
{
|
{
|
||||||
$this->assertTrue($this->loader->loadClassMetadata($this->metadata));
|
$this->assertTrue($this->loader->loadClassMetadata($this->metadata));
|
||||||
|
|
|
@ -11,6 +11,7 @@
|
||||||
|
|
||||||
namespace Symfony\Component\Serializer\Tests\Mapping;
|
namespace Symfony\Component\Serializer\Tests\Mapping;
|
||||||
|
|
||||||
|
use Symfony\Component\Serializer\Mapping\AttributeMetadata;
|
||||||
use Symfony\Component\Serializer\Mapping\ClassMetadata;
|
use Symfony\Component\Serializer\Mapping\ClassMetadata;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -22,22 +23,38 @@ class TestClassMetadataFactory
|
||||||
{
|
{
|
||||||
$expected = new ClassMetadata('Symfony\Component\Serializer\Tests\Fixtures\GroupDummy');
|
$expected = new ClassMetadata('Symfony\Component\Serializer\Tests\Fixtures\GroupDummy');
|
||||||
|
|
||||||
|
$foo = new AttributeMetadata('foo');
|
||||||
|
$foo->addGroup('a');
|
||||||
|
$expected->addAttributeMetadata($foo);
|
||||||
|
|
||||||
|
$bar = new AttributeMetadata('bar');
|
||||||
|
$bar->addGroup('b');
|
||||||
|
$bar->addGroup('c');
|
||||||
|
$expected->addAttributeMetadata($bar);
|
||||||
|
|
||||||
|
$fooBar = new AttributeMetadata('fooBar');
|
||||||
|
$fooBar->addGroup('a');
|
||||||
|
$fooBar->addGroup('b');
|
||||||
|
$expected->addAttributeMetadata($fooBar);
|
||||||
|
|
||||||
|
$symfony = new AttributeMetadata('symfony');
|
||||||
|
$expected->addAttributeMetadata($symfony);
|
||||||
|
|
||||||
if ($withParent) {
|
if ($withParent) {
|
||||||
$expected->addAttributeGroup('kevin', 'a');
|
$kevin = new AttributeMetadata('kevin');
|
||||||
$expected->addAttributeGroup('coopTilleuls', 'a');
|
$kevin->addGroup('a');
|
||||||
$expected->addAttributeGroup('coopTilleuls', 'b');
|
$expected->addAttributeMetadata($kevin);
|
||||||
|
|
||||||
|
$coopTilleuls = new AttributeMetadata('coopTilleuls');
|
||||||
|
$coopTilleuls->addGroup('a');
|
||||||
|
$coopTilleuls->addGroup('b');
|
||||||
|
$expected->addAttributeMetadata($coopTilleuls);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($withInterface) {
|
if ($withInterface) {
|
||||||
$expected->addAttributeGroup('symfony', 'a');
|
$symfony->addGroup('a');
|
||||||
}
|
}
|
||||||
|
|
||||||
$expected->addAttributeGroup('foo', 'a');
|
|
||||||
$expected->addAttributeGroup('bar', 'b');
|
|
||||||
$expected->addAttributeGroup('bar', 'c');
|
|
||||||
$expected->addAttributeGroup('fooBar', 'a');
|
|
||||||
$expected->addAttributeGroup('fooBar', 'b');
|
|
||||||
|
|
||||||
// load reflection class so that the comparison passes
|
// load reflection class so that the comparison passes
|
||||||
$expected->getReflectionClass();
|
$expected->getReflectionClass();
|
||||||
|
|
||||||
|
@ -47,9 +64,15 @@ class TestClassMetadataFactory
|
||||||
public static function createXmlCLassMetadata()
|
public static function createXmlCLassMetadata()
|
||||||
{
|
{
|
||||||
$expected = new ClassMetadata('Symfony\Component\Serializer\Tests\Fixtures\GroupDummy');
|
$expected = new ClassMetadata('Symfony\Component\Serializer\Tests\Fixtures\GroupDummy');
|
||||||
$expected->addAttributeGroup('foo', 'group1');
|
|
||||||
$expected->addAttributeGroup('foo', 'group2');
|
$foo = new AttributeMetadata('foo');
|
||||||
$expected->addAttributeGroup('bar', 'group2');
|
$foo->addGroup('group1');
|
||||||
|
$foo->addGroup('group2');
|
||||||
|
$expected->addAttributeMetadata($foo);
|
||||||
|
|
||||||
|
$bar = new AttributeMetadata('bar');
|
||||||
|
$bar->addGroup('group2');
|
||||||
|
$expected->addAttributeMetadata($bar);
|
||||||
|
|
||||||
return $expected;
|
return $expected;
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,6 +18,12 @@ use Symfony\Component\Serializer\NameConverter\CamelCaseToSnakeCaseNameConverter
|
||||||
*/
|
*/
|
||||||
class CamelCaseToSnakeCaseNameConverterTest extends \PHPUnit_Framework_TestCase
|
class CamelCaseToSnakeCaseNameConverterTest extends \PHPUnit_Framework_TestCase
|
||||||
{
|
{
|
||||||
|
public function testInterface()
|
||||||
|
{
|
||||||
|
$attributeMetadata = new CamelCaseToSnakeCaseNameConverter();
|
||||||
|
$this->assertInstanceOf('Symfony\Component\Serializer\NameConverter\NameConverterInterface', $attributeMetadata);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @dataProvider attributeProvider
|
* @dataProvider attributeProvider
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -17,12 +17,23 @@ use Symfony\Component\Serializer\Serializer;
|
||||||
|
|
||||||
class CustomNormalizerTest extends \PHPUnit_Framework_TestCase
|
class CustomNormalizerTest extends \PHPUnit_Framework_TestCase
|
||||||
{
|
{
|
||||||
|
/**
|
||||||
|
* @var CustomNormalizer
|
||||||
|
*/
|
||||||
|
private $normalizer;
|
||||||
|
|
||||||
protected function setUp()
|
protected function setUp()
|
||||||
{
|
{
|
||||||
$this->normalizer = new CustomNormalizer();
|
$this->normalizer = new CustomNormalizer();
|
||||||
$this->normalizer->setSerializer(new Serializer());
|
$this->normalizer->setSerializer(new Serializer());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function testInterface()
|
||||||
|
{
|
||||||
|
$this->assertInstanceOf('Symfony\Component\Serializer\Normalizer\NormalizerInterface', $this->normalizer);
|
||||||
|
$this->assertInstanceOf('Symfony\Component\Serializer\Normalizer\DenormalizerInterface', $this->normalizer);
|
||||||
|
}
|
||||||
|
|
||||||
public function testSerialize()
|
public function testSerialize()
|
||||||
{
|
{
|
||||||
$obj = new ScalarDummy();
|
$obj = new ScalarDummy();
|
||||||
|
|
|
@ -40,6 +40,12 @@ class GetSetMethodNormalizerTest extends \PHPUnit_Framework_TestCase
|
||||||
$this->normalizer->setSerializer($this->serializer);
|
$this->normalizer->setSerializer($this->serializer);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function testInterface()
|
||||||
|
{
|
||||||
|
$this->assertInstanceOf('Symfony\Component\Serializer\Normalizer\NormalizerInterface', $this->normalizer);
|
||||||
|
$this->assertInstanceOf('Symfony\Component\Serializer\Normalizer\DenormalizerInterface', $this->normalizer);
|
||||||
|
}
|
||||||
|
|
||||||
public function testNormalize()
|
public function testNormalize()
|
||||||
{
|
{
|
||||||
$obj = new GetSetDummy();
|
$obj = new GetSetDummy();
|
||||||
|
@ -426,6 +432,14 @@ class GetSetMethodNormalizerTest extends \PHPUnit_Framework_TestCase
|
||||||
$this->assertEquals('foo', $obj->getFoo());
|
$this->assertEquals('foo', $obj->getFoo());
|
||||||
$this->assertEquals('bar', $obj->getBar());
|
$this->assertEquals('bar', $obj->getBar());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function testDenormalizeNonExistingAttribute()
|
||||||
|
{
|
||||||
|
$this->assertEquals(
|
||||||
|
new PropertyDummy(),
|
||||||
|
$this->normalizer->denormalize(array('non_existing' => true), __NAMESPACE__.'\PropertyDummy')
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class GetSetDummy
|
class GetSetDummy
|
||||||
|
|
|
@ -0,0 +1,497 @@
|
||||||
|
<?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\Serializer\Tests\Normalizer;
|
||||||
|
|
||||||
|
use Doctrine\Common\Annotations\AnnotationReader;
|
||||||
|
use Symfony\Component\Serializer\Normalizer\ObjectNormalizer;
|
||||||
|
use Symfony\Component\Serializer\Serializer;
|
||||||
|
use Symfony\Component\Serializer\SerializerInterface;
|
||||||
|
use Symfony\Component\Serializer\Normalizer\NormalizerInterface;
|
||||||
|
use Symfony\Component\Serializer\Tests\Fixtures\CircularReferenceDummy;
|
||||||
|
use Symfony\Component\Serializer\Tests\Fixtures\SiblingHolder;
|
||||||
|
use Symfony\Component\Serializer\Mapping\Loader\AnnotationLoader;
|
||||||
|
use Symfony\Component\Serializer\Mapping\Factory\ClassMetadataFactory;
|
||||||
|
use Symfony\Component\Serializer\Tests\Fixtures\GroupDummy;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Kévin Dunglas <dunglas@gmail.com>
|
||||||
|
*/
|
||||||
|
class ObjectNormalizerTest extends \PHPUnit_Framework_TestCase
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* @var ObjectNormalizerTest
|
||||||
|
*/
|
||||||
|
private $normalizer;
|
||||||
|
/**
|
||||||
|
* @var SerializerInterface
|
||||||
|
*/
|
||||||
|
private $serializer;
|
||||||
|
|
||||||
|
protected function setUp()
|
||||||
|
{
|
||||||
|
$this->serializer = $this->getMock(__NAMESPACE__.'\ObjectSerializerNormalizer');
|
||||||
|
$this->normalizer = new ObjectNormalizer();
|
||||||
|
$this->normalizer->setSerializer($this->serializer);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testNormalize()
|
||||||
|
{
|
||||||
|
$obj = new ObjectDummy();
|
||||||
|
$object = new \stdClass();
|
||||||
|
$obj->setFoo('foo');
|
||||||
|
$obj->bar = 'bar';
|
||||||
|
$obj->setBaz(true);
|
||||||
|
$obj->setCamelCase('camelcase');
|
||||||
|
$obj->setObject($object);
|
||||||
|
|
||||||
|
$this->serializer
|
||||||
|
->expects($this->once())
|
||||||
|
->method('normalize')
|
||||||
|
->with($object, 'any')
|
||||||
|
->will($this->returnValue('string_object'))
|
||||||
|
;
|
||||||
|
|
||||||
|
$this->assertEquals(
|
||||||
|
array(
|
||||||
|
'foo' => 'foo',
|
||||||
|
'bar' => 'bar',
|
||||||
|
'baz' => true,
|
||||||
|
'fooBar' => 'foobar',
|
||||||
|
'camelCase' => 'camelcase',
|
||||||
|
'object' => 'string_object',
|
||||||
|
),
|
||||||
|
$this->normalizer->normalize($obj, 'any')
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testDenormalize()
|
||||||
|
{
|
||||||
|
$obj = $this->normalizer->denormalize(
|
||||||
|
array('foo' => 'foo', 'bar' => 'bar', 'baz' => true, 'fooBar' => 'foobar'),
|
||||||
|
__NAMESPACE__.'\ObjectDummy',
|
||||||
|
'any'
|
||||||
|
);
|
||||||
|
$this->assertEquals('foo', $obj->getFoo());
|
||||||
|
$this->assertEquals('bar', $obj->bar);
|
||||||
|
$this->assertTrue($obj->isBaz());
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testDenormalizeWithObject()
|
||||||
|
{
|
||||||
|
$data = new \stdClass();
|
||||||
|
$data->foo = 'foo';
|
||||||
|
$data->bar = 'bar';
|
||||||
|
$data->fooBar = 'foobar';
|
||||||
|
$obj = $this->normalizer->denormalize($data, __NAMESPACE__.'\ObjectDummy', 'any');
|
||||||
|
$this->assertEquals('foo', $obj->getFoo());
|
||||||
|
$this->assertEquals('bar', $obj->bar);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testLegacyDenormalizeOnCamelCaseFormat()
|
||||||
|
{
|
||||||
|
$this->iniSet('error_reporting', -1 & ~E_USER_DEPRECATED);
|
||||||
|
|
||||||
|
$this->normalizer->setCamelizedAttributes(array('camel_case'));
|
||||||
|
$obj = $this->normalizer->denormalize(
|
||||||
|
array('camel_case' => 'camelCase'),
|
||||||
|
__NAMESPACE__.'\ObjectDummy'
|
||||||
|
);
|
||||||
|
$this->assertEquals('camelCase', $obj->getCamelCase());
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testDenormalizeNull()
|
||||||
|
{
|
||||||
|
$this->assertEquals(new ObjectDummy(), $this->normalizer->denormalize(null, __NAMESPACE__.'\ObjectDummy'));
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testConstructorDenormalize()
|
||||||
|
{
|
||||||
|
$obj = $this->normalizer->denormalize(
|
||||||
|
array('foo' => 'foo', 'bar' => 'bar', 'baz' => true, 'fooBar' => 'foobar'),
|
||||||
|
__NAMESPACE__.'\ObjectConstructorDummy', 'any');
|
||||||
|
$this->assertEquals('foo', $obj->getFoo());
|
||||||
|
$this->assertEquals('bar', $obj->bar);
|
||||||
|
$this->assertTrue($obj->isBaz());
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testConstructorDenormalizeWithMissingOptionalArgument()
|
||||||
|
{
|
||||||
|
$obj = $this->normalizer->denormalize(
|
||||||
|
array('foo' => 'test', 'baz' => array(1, 2, 3)),
|
||||||
|
__NAMESPACE__.'\ObjectConstructorOptionalArgsDummy', 'any');
|
||||||
|
$this->assertEquals('test', $obj->getFoo());
|
||||||
|
$this->assertEquals(array(), $obj->bar);
|
||||||
|
$this->assertEquals(array(1, 2, 3), $obj->getBaz());
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testConstructorWithObjectDenormalize()
|
||||||
|
{
|
||||||
|
$data = new \stdClass();
|
||||||
|
$data->foo = 'foo';
|
||||||
|
$data->bar = 'bar';
|
||||||
|
$data->baz = true;
|
||||||
|
$data->fooBar = 'foobar';
|
||||||
|
$obj = $this->normalizer->denormalize($data, __NAMESPACE__.'\ObjectConstructorDummy', 'any');
|
||||||
|
$this->assertEquals('foo', $obj->getFoo());
|
||||||
|
$this->assertEquals('bar', $obj->bar);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testGroupsNormalize()
|
||||||
|
{
|
||||||
|
$classMetadataFactory = new ClassMetadataFactory(new AnnotationLoader(new AnnotationReader()));
|
||||||
|
$this->normalizer = new ObjectNormalizer($classMetadataFactory);
|
||||||
|
$this->normalizer->setSerializer($this->serializer);
|
||||||
|
|
||||||
|
$obj = new GroupDummy();
|
||||||
|
$obj->setFoo('foo');
|
||||||
|
$obj->setBar('bar');
|
||||||
|
$obj->setFooBar('fooBar');
|
||||||
|
$obj->setSymfony('symfony');
|
||||||
|
$obj->setKevin('kevin');
|
||||||
|
$obj->setCoopTilleuls('coopTilleuls');
|
||||||
|
|
||||||
|
$this->assertEquals(array(
|
||||||
|
'bar' => 'bar',
|
||||||
|
), $this->normalizer->normalize($obj, null, array('groups' => array('c'))));
|
||||||
|
|
||||||
|
$this->assertEquals(array(
|
||||||
|
'symfony' => 'symfony',
|
||||||
|
'foo' => 'foo',
|
||||||
|
'fooBar' => 'fooBar',
|
||||||
|
'bar' => 'bar',
|
||||||
|
'kevin' => 'kevin',
|
||||||
|
'coopTilleuls' => 'coopTilleuls',
|
||||||
|
), $this->normalizer->normalize($obj, null, array('groups' => array('a', 'c'))));
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testGroupsDenormalize()
|
||||||
|
{
|
||||||
|
$classMetadataFactory = new ClassMetadataFactory(new AnnotationLoader(new AnnotationReader()));
|
||||||
|
$this->normalizer = new ObjectNormalizer($classMetadataFactory);
|
||||||
|
$this->normalizer->setSerializer($this->serializer);
|
||||||
|
|
||||||
|
$obj = new GroupDummy();
|
||||||
|
$obj->setFoo('foo');
|
||||||
|
|
||||||
|
$toNormalize = array('foo' => 'foo', 'bar' => 'bar');
|
||||||
|
|
||||||
|
$normalized = $this->normalizer->denormalize(
|
||||||
|
$toNormalize,
|
||||||
|
'Symfony\Component\Serializer\Tests\Fixtures\GroupDummy',
|
||||||
|
null,
|
||||||
|
array('groups' => array('a'))
|
||||||
|
);
|
||||||
|
$this->assertEquals($obj, $normalized);
|
||||||
|
|
||||||
|
$obj->setBar('bar');
|
||||||
|
|
||||||
|
$normalized = $this->normalizer->denormalize(
|
||||||
|
$toNormalize,
|
||||||
|
'Symfony\Component\Serializer\Tests\Fixtures\GroupDummy',
|
||||||
|
null,
|
||||||
|
array('groups' => array('a', 'b'))
|
||||||
|
);
|
||||||
|
$this->assertEquals($obj, $normalized);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @dataProvider provideCallbacks
|
||||||
|
*/
|
||||||
|
public function testCallbacks($callbacks, $value, $result, $message)
|
||||||
|
{
|
||||||
|
$this->normalizer->setCallbacks($callbacks);
|
||||||
|
|
||||||
|
$obj = new ObjectConstructorDummy('', $value, true);
|
||||||
|
|
||||||
|
$this->assertEquals(
|
||||||
|
$result,
|
||||||
|
$this->normalizer->normalize($obj, 'any'),
|
||||||
|
$message
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @expectedException \InvalidArgumentException
|
||||||
|
*/
|
||||||
|
public function testUncallableCallbacks()
|
||||||
|
{
|
||||||
|
$this->normalizer->setCallbacks(array('bar' => null));
|
||||||
|
|
||||||
|
$obj = new ObjectConstructorDummy('baz', 'quux', true);
|
||||||
|
|
||||||
|
$this->normalizer->normalize($obj, 'any');
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testIgnoredAttributes()
|
||||||
|
{
|
||||||
|
$this->normalizer->setIgnoredAttributes(array('foo', 'bar', 'baz', 'camelCase', 'object'));
|
||||||
|
|
||||||
|
$obj = new ObjectDummy();
|
||||||
|
$obj->setFoo('foo');
|
||||||
|
$obj->bar = 'bar';
|
||||||
|
$obj->setBaz(true);
|
||||||
|
|
||||||
|
$this->assertEquals(
|
||||||
|
array('fooBar' => 'foobar'),
|
||||||
|
$this->normalizer->normalize($obj, 'any')
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function provideCallbacks()
|
||||||
|
{
|
||||||
|
return array(
|
||||||
|
array(
|
||||||
|
array(
|
||||||
|
'bar' => function ($bar) {
|
||||||
|
return 'baz';
|
||||||
|
},
|
||||||
|
),
|
||||||
|
'baz',
|
||||||
|
array('foo' => '', 'bar' => 'baz', 'baz' => true),
|
||||||
|
'Change a string',
|
||||||
|
),
|
||||||
|
array(
|
||||||
|
array(
|
||||||
|
'bar' => function ($bar) {
|
||||||
|
return;
|
||||||
|
},
|
||||||
|
),
|
||||||
|
'baz',
|
||||||
|
array('foo' => '', 'bar' => null, 'baz' => true),
|
||||||
|
'Null an item',
|
||||||
|
),
|
||||||
|
array(
|
||||||
|
array(
|
||||||
|
'bar' => function ($bar) {
|
||||||
|
return $bar->format('d-m-Y H:i:s');
|
||||||
|
},
|
||||||
|
),
|
||||||
|
new \DateTime('2011-09-10 06:30:00'),
|
||||||
|
array('foo' => '', 'bar' => '10-09-2011 06:30:00', 'baz' => true),
|
||||||
|
'Format a date',
|
||||||
|
),
|
||||||
|
array(
|
||||||
|
array(
|
||||||
|
'bar' => function ($bars) {
|
||||||
|
$foos = '';
|
||||||
|
foreach ($bars as $bar) {
|
||||||
|
$foos .= $bar->getFoo();
|
||||||
|
}
|
||||||
|
|
||||||
|
return $foos;
|
||||||
|
},
|
||||||
|
),
|
||||||
|
array(new ObjectConstructorDummy('baz', '', false), new ObjectConstructorDummy('quux', '', false)),
|
||||||
|
array('foo' => '', 'bar' => 'bazquux', 'baz' => true),
|
||||||
|
'Collect a property',
|
||||||
|
),
|
||||||
|
array(
|
||||||
|
array(
|
||||||
|
'bar' => function ($bars) {
|
||||||
|
return count($bars);
|
||||||
|
},
|
||||||
|
),
|
||||||
|
array(new ObjectConstructorDummy('baz', '', false), new ObjectConstructorDummy('quux', '', false)),
|
||||||
|
array('foo' => '', 'bar' => 2, 'baz' => true),
|
||||||
|
'Count a property',
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @expectedException \Symfony\Component\Serializer\Exception\LogicException
|
||||||
|
* @expectedExceptionMessage Cannot normalize attribute "object" because injected serializer is not a normalizer
|
||||||
|
*/
|
||||||
|
public function testUnableToNormalizeObjectAttribute()
|
||||||
|
{
|
||||||
|
$serializer = $this->getMock('Symfony\Component\Serializer\SerializerInterface');
|
||||||
|
$this->normalizer->setSerializer($serializer);
|
||||||
|
|
||||||
|
$obj = new ObjectDummy();
|
||||||
|
$object = new \stdClass();
|
||||||
|
$obj->setObject($object);
|
||||||
|
|
||||||
|
$this->normalizer->normalize($obj, 'any');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @expectedException \Symfony\Component\Serializer\Exception\CircularReferenceException
|
||||||
|
*/
|
||||||
|
public function testUnableToNormalizeCircularReference()
|
||||||
|
{
|
||||||
|
$serializer = new Serializer(array($this->normalizer));
|
||||||
|
$this->normalizer->setSerializer($serializer);
|
||||||
|
$this->normalizer->setCircularReferenceLimit(2);
|
||||||
|
|
||||||
|
$obj = new CircularReferenceDummy();
|
||||||
|
|
||||||
|
$this->normalizer->normalize($obj);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testSiblingReference()
|
||||||
|
{
|
||||||
|
$serializer = new Serializer(array($this->normalizer));
|
||||||
|
$this->normalizer->setSerializer($serializer);
|
||||||
|
|
||||||
|
$siblingHolder = new SiblingHolder();
|
||||||
|
|
||||||
|
$expected = array(
|
||||||
|
'sibling0' => array('coopTilleuls' => 'Les-Tilleuls.coop'),
|
||||||
|
'sibling1' => array('coopTilleuls' => 'Les-Tilleuls.coop'),
|
||||||
|
'sibling2' => array('coopTilleuls' => 'Les-Tilleuls.coop'),
|
||||||
|
);
|
||||||
|
$this->assertEquals($expected, $this->normalizer->normalize($siblingHolder));
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testCircularReferenceHandler()
|
||||||
|
{
|
||||||
|
$serializer = new Serializer(array($this->normalizer));
|
||||||
|
$this->normalizer->setSerializer($serializer);
|
||||||
|
$this->normalizer->setCircularReferenceHandler(function ($obj) {
|
||||||
|
return get_class($obj);
|
||||||
|
});
|
||||||
|
|
||||||
|
$obj = new CircularReferenceDummy();
|
||||||
|
|
||||||
|
$expected = array('me' => 'Symfony\Component\Serializer\Tests\Fixtures\CircularReferenceDummy');
|
||||||
|
$this->assertEquals($expected, $this->normalizer->normalize($obj));
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testDenormalizeNonExistingAttribute()
|
||||||
|
{
|
||||||
|
$this->assertEquals(
|
||||||
|
new ObjectDummy(),
|
||||||
|
$this->normalizer->denormalize(array('non_existing' => true), __NAMESPACE__.'\ObjectDummy')
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class ObjectDummy
|
||||||
|
{
|
||||||
|
protected $foo;
|
||||||
|
public $bar;
|
||||||
|
private $baz;
|
||||||
|
protected $camelCase;
|
||||||
|
protected $object;
|
||||||
|
|
||||||
|
public function getFoo()
|
||||||
|
{
|
||||||
|
return $this->foo;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function setFoo($foo)
|
||||||
|
{
|
||||||
|
$this->foo = $foo;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function isBaz()
|
||||||
|
{
|
||||||
|
return $this->baz;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function setBaz($baz)
|
||||||
|
{
|
||||||
|
$this->baz = $baz;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getFooBar()
|
||||||
|
{
|
||||||
|
return $this->foo.$this->bar;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getCamelCase()
|
||||||
|
{
|
||||||
|
return $this->camelCase;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function setCamelCase($camelCase)
|
||||||
|
{
|
||||||
|
$this->camelCase = $camelCase;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function otherMethod()
|
||||||
|
{
|
||||||
|
throw new \RuntimeException("Dummy::otherMethod() should not be called");
|
||||||
|
}
|
||||||
|
|
||||||
|
public function setObject($object)
|
||||||
|
{
|
||||||
|
$this->object = $object;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getObject()
|
||||||
|
{
|
||||||
|
return $this->object;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class ObjectConstructorDummy
|
||||||
|
{
|
||||||
|
protected $foo;
|
||||||
|
public $bar;
|
||||||
|
private $baz;
|
||||||
|
|
||||||
|
public function __construct($foo, $bar, $baz)
|
||||||
|
{
|
||||||
|
$this->foo = $foo;
|
||||||
|
$this->bar = $bar;
|
||||||
|
$this->baz = $baz;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getFoo()
|
||||||
|
{
|
||||||
|
return $this->foo;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function isBaz()
|
||||||
|
{
|
||||||
|
return $this->baz;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function otherMethod()
|
||||||
|
{
|
||||||
|
throw new \RuntimeException("Dummy::otherMethod() should not be called");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
abstract class ObjectSerializerNormalizer implements SerializerInterface, NormalizerInterface
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
class ObjectConstructorOptionalArgsDummy
|
||||||
|
{
|
||||||
|
protected $foo;
|
||||||
|
public $bar;
|
||||||
|
private $baz;
|
||||||
|
|
||||||
|
public function __construct($foo, $bar = array(), $baz = array())
|
||||||
|
{
|
||||||
|
$this->foo = $foo;
|
||||||
|
$this->bar = $bar;
|
||||||
|
$this->baz = $baz;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getFoo()
|
||||||
|
{
|
||||||
|
return $this->foo;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getBaz()
|
||||||
|
{
|
||||||
|
return $this->baz;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function otherMethod()
|
||||||
|
{
|
||||||
|
throw new \RuntimeException("Dummy::otherMethod() should not be called");
|
||||||
|
}
|
||||||
|
}
|
|
@ -333,6 +333,14 @@ class PropertyNormalizerTest extends \PHPUnit_Framework_TestCase
|
||||||
$expected = array('me' => 'Symfony\Component\Serializer\Tests\Fixtures\PropertyCircularReferenceDummy');
|
$expected = array('me' => 'Symfony\Component\Serializer\Tests\Fixtures\PropertyCircularReferenceDummy');
|
||||||
$this->assertEquals($expected, $this->normalizer->normalize($obj));
|
$this->assertEquals($expected, $this->normalizer->normalize($obj));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function testDenormalizeNonExistingAttribute()
|
||||||
|
{
|
||||||
|
$this->assertEquals(
|
||||||
|
new PropertyDummy(),
|
||||||
|
$this->normalizer->denormalize(array('non_existing' => true), __NAMESPACE__.'\PropertyDummy')
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class PropertyDummy
|
class PropertyDummy
|
||||||
|
|
|
@ -22,6 +22,17 @@ use Symfony\Component\Serializer\Tests\Normalizer\TestDenormalizer;
|
||||||
|
|
||||||
class SerializerTest extends \PHPUnit_Framework_TestCase
|
class SerializerTest extends \PHPUnit_Framework_TestCase
|
||||||
{
|
{
|
||||||
|
public function testInterface()
|
||||||
|
{
|
||||||
|
$serializer = new Serializer();
|
||||||
|
|
||||||
|
$this->assertInstanceOf('Symfony\Component\Serializer\SerializerInterface', $serializer);
|
||||||
|
$this->assertInstanceOf('Symfony\Component\Serializer\Normalizer\NormalizerInterface', $serializer);
|
||||||
|
$this->assertInstanceOf('Symfony\Component\Serializer\Normalizer\DenormalizerInterface', $serializer);
|
||||||
|
$this->assertInstanceOf('Symfony\Component\Serializer\Encoder\EncoderInterface', $serializer);
|
||||||
|
$this->assertInstanceOf('Symfony\Component\Serializer\Encoder\DecoderInterface', $serializer);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @expectedException \Symfony\Component\Serializer\Exception\UnexpectedValueException
|
* @expectedException \Symfony\Component\Serializer\Exception\UnexpectedValueException
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -22,6 +22,7 @@
|
||||||
"symfony/phpunit-bridge": "~2.7|~3.0",
|
"symfony/phpunit-bridge": "~2.7|~3.0",
|
||||||
"symfony/yaml": "~2.7|~3.0",
|
"symfony/yaml": "~2.7|~3.0",
|
||||||
"symfony/config": "~2.7|~3.0",
|
"symfony/config": "~2.7|~3.0",
|
||||||
|
"symfony/property-access": "~2.7|~3.0.0",
|
||||||
"doctrine/annotations": "~1.0",
|
"doctrine/annotations": "~1.0",
|
||||||
"doctrine/cache": "~1.0"
|
"doctrine/cache": "~1.0"
|
||||||
},
|
},
|
||||||
|
@ -29,7 +30,8 @@
|
||||||
"doctrine/annotations": "For using the annotation mapping. You will also need doctrine/cache.",
|
"doctrine/annotations": "For using the annotation mapping. You will also need doctrine/cache.",
|
||||||
"doctrine/cache": "For using the default cached annotation reader and metadata cache.",
|
"doctrine/cache": "For using the default cached annotation reader and metadata cache.",
|
||||||
"symfony/yaml": "For using the default YAML mapping loader.",
|
"symfony/yaml": "For using the default YAML mapping loader.",
|
||||||
"symfony/config": "For using the XML mapping loader."
|
"symfony/config": "For using the XML mapping loader.",
|
||||||
|
"symfony/property-access": "For using the ObjectNormalizer."
|
||||||
},
|
},
|
||||||
"autoload": {
|
"autoload": {
|
||||||
"psr-0": { "Symfony\\Component\\Serializer\\": "" }
|
"psr-0": { "Symfony\\Component\\Serializer\\": "" }
|
||||||
|
|
|
@ -171,7 +171,7 @@ class XliffFileLoader implements LoaderInterface
|
||||||
LIBXML_ERR_WARNING == $error->level ? 'WARNING' : 'ERROR',
|
LIBXML_ERR_WARNING == $error->level ? 'WARNING' : 'ERROR',
|
||||||
$error->code,
|
$error->code,
|
||||||
trim($error->message),
|
trim($error->message),
|
||||||
$error->file ? $error->file : 'n/a',
|
$error->file ?: 'n/a',
|
||||||
$error->line,
|
$error->line,
|
||||||
$error->column
|
$error->column
|
||||||
);
|
);
|
||||||
|
|
|
@ -58,13 +58,13 @@ abstract class AbstractLoader implements LoaderInterface
|
||||||
/**
|
/**
|
||||||
* Creates a new constraint instance for the given constraint name.
|
* Creates a new constraint instance for the given constraint name.
|
||||||
*
|
*
|
||||||
* @param string $name The constraint name. Either a constraint relative
|
* @param string $name The constraint name. Either a constraint relative
|
||||||
* to the default constraint namespace, or a fully
|
* to the default constraint namespace, or a fully
|
||||||
* qualified class name. Alternatively, the constraint
|
* qualified class name. Alternatively, the constraint
|
||||||
* may be preceded by a namespace alias and a colon.
|
* may be preceded by a namespace alias and a colon.
|
||||||
* The namespace alias must have been defined using
|
* The namespace alias must have been defined using
|
||||||
* {@link addNamespaceAlias()}.
|
* {@link addNamespaceAlias()}.
|
||||||
* @param mixed $options The constraint options
|
* @param mixed $options The constraint options
|
||||||
*
|
*
|
||||||
* @return Constraint
|
* @return Constraint
|
||||||
*
|
*
|
||||||
|
|
|
@ -278,6 +278,38 @@
|
||||||
<source>This value should not be identical to {{ compared_value_type }} {{ compared_value }}.</source>
|
<source>This value should not be identical to {{ compared_value_type }} {{ compared_value }}.</source>
|
||||||
<target>Este valor non debería ser identico a {{ compared_value_type }} {{ compared_value }}.</target>
|
<target>Este valor non debería ser identico a {{ compared_value_type }} {{ compared_value }}.</target>
|
||||||
</trans-unit>
|
</trans-unit>
|
||||||
|
<trans-unit id="73">
|
||||||
|
<source>The image ratio is too big ({{ ratio }}). Allowed maximum ratio is {{ max_ratio }}.</source>
|
||||||
|
<target>A proporción da imaxe é demasiado grande ({{ ratio }}). A proporción máxima permitida é {{ max_ratio }}.</target>
|
||||||
|
</trans-unit>
|
||||||
|
<trans-unit id="74">
|
||||||
|
<source>The image ratio is too small ({{ ratio }}). Minimum ratio expected is {{ min_ratio }}.</source>
|
||||||
|
<target>A proporción da é demasiado pequena ({{ ratio }}). A proporción mínima permitida é {{ min_ratio }}.</target>
|
||||||
|
</trans-unit>
|
||||||
|
<trans-unit id="75">
|
||||||
|
<source>The image is square ({{ width }}x{{ height }}px). Square images are not allowed.</source>
|
||||||
|
<target>A imaxe é cadrada ({{ width }}x{{ height }}px). As imáxenes cadradas non están permitidas.</target>
|
||||||
|
</trans-unit>
|
||||||
|
<trans-unit id="76">
|
||||||
|
<source>The image is landscape oriented ({{ width }}x{{ height }}px). Landscape oriented images are not allowed.</source>
|
||||||
|
<target>A imaxe está orientada horizontalmente ({{ width }}x{{ height }}px). As imáxenes orientadas horizontalmente non están permitidas.</target>
|
||||||
|
</trans-unit>
|
||||||
|
<trans-unit id="77">
|
||||||
|
<source>The image is portrait oriented ({{ width }}x{{ height }}px). Portrait oriented images are not allowed.</source>
|
||||||
|
<target>A imaxe está orientada verticalmente ({{ width }}x{{ height }}px). As imáxenes orientadas verticalmente non están permitidas.</target>
|
||||||
|
</trans-unit>
|
||||||
|
<trans-unit id="78">
|
||||||
|
<source>An empty file is not allowed.</source>
|
||||||
|
<target>Non está permitido un arquivo baleiro.</target>
|
||||||
|
</trans-unit>
|
||||||
|
<trans-unit id="79">
|
||||||
|
<source>The host could not be resolved.</source>
|
||||||
|
<target>Non se puido resolver o host.</target>
|
||||||
|
</trans-unit>
|
||||||
|
<trans-unit id="80">
|
||||||
|
<source>This value does not match the expected {{ charset }} charset.</source>
|
||||||
|
<target>A codificación de caracteres para este valor debería ser {{ charset }}.</target>
|
||||||
|
</trans-unit>
|
||||||
</body>
|
</body>
|
||||||
</file>
|
</file>
|
||||||
</xliff>
|
</xliff>
|
||||||
|
|
|
@ -38,8 +38,9 @@ class VarCloner extends AbstractCloner
|
||||||
$maxItems = $this->maxItems;
|
$maxItems = $this->maxItems;
|
||||||
$maxString = $this->maxString;
|
$maxString = $this->maxString;
|
||||||
$cookie = (object) array(); // Unique object used to detect hard references
|
$cookie = (object) array(); // Unique object used to detect hard references
|
||||||
|
$gid = uniqid(mt_rand(), true); // Unique string used to detect the special $GLOBALS variable
|
||||||
$a = null; // Array cast for nested structures
|
$a = null; // Array cast for nested structures
|
||||||
$stub = null; // Stub capturing the main properties of an original item value,
|
$stub = null; // Stub capturing the main properties of an original item value
|
||||||
// or null if the original value is used directly
|
// or null if the original value is used directly
|
||||||
$zval = array( // Main properties of the current value
|
$zval = array( // Main properties of the current value
|
||||||
'type' => null,
|
'type' => null,
|
||||||
|
@ -121,16 +122,20 @@ class VarCloner extends AbstractCloner
|
||||||
$stub->value = $zval['array_count'] ?: count($v);
|
$stub->value = $zval['array_count'] ?: count($v);
|
||||||
|
|
||||||
$a = $v;
|
$a = $v;
|
||||||
$a[] = null;
|
|
||||||
$h = count($v);
|
// Copies of $GLOBALS have very strange behavior,
|
||||||
array_pop($a);
|
// let's detect them with some black magic
|
||||||
|
$a[$gid] = true;
|
||||||
|
|
||||||
// Happens with copies of $GLOBALS
|
// Happens with copies of $GLOBALS
|
||||||
if ($h !== $stub->value) {
|
if (isset($v[$gid])) {
|
||||||
|
unset($v[$gid]);
|
||||||
$a = array();
|
$a = array();
|
||||||
foreach ($v as $gk => &$gv) {
|
foreach ($v as $gk => &$gv) {
|
||||||
$a[$gk] =& $gv;
|
$a[$gk] =& $gv;
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
$a = $v;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -18,6 +18,49 @@ use Symfony\Component\VarDumper\Cloner\VarCloner;
|
||||||
*/
|
*/
|
||||||
class VarClonerTest extends \PHPUnit_Framework_TestCase
|
class VarClonerTest extends \PHPUnit_Framework_TestCase
|
||||||
{
|
{
|
||||||
|
public function testMaxIntBoundary()
|
||||||
|
{
|
||||||
|
$data = array(PHP_INT_MAX => 123);
|
||||||
|
|
||||||
|
$cloner = new VarCloner();
|
||||||
|
$clone = $cloner->cloneVar($data);
|
||||||
|
|
||||||
|
$expected = <<<EOTXT
|
||||||
|
Symfony\Component\VarDumper\Cloner\Data Object
|
||||||
|
(
|
||||||
|
[data:Symfony\Component\VarDumper\Cloner\Data:private] => Array
|
||||||
|
(
|
||||||
|
[0] => Array
|
||||||
|
(
|
||||||
|
[0] => Symfony\Component\VarDumper\Cloner\Stub Object
|
||||||
|
(
|
||||||
|
[type] => array
|
||||||
|
[class] => assoc
|
||||||
|
[value] => 1
|
||||||
|
[cut] => 0
|
||||||
|
[handle] => 0
|
||||||
|
[refCount] => 0
|
||||||
|
[position] => 1
|
||||||
|
)
|
||||||
|
|
||||||
|
)
|
||||||
|
|
||||||
|
[1] => Array
|
||||||
|
(
|
||||||
|
[%s] => 123
|
||||||
|
)
|
||||||
|
|
||||||
|
)
|
||||||
|
|
||||||
|
[maxDepth:Symfony\Component\VarDumper\Cloner\Data:private] => 20
|
||||||
|
[maxItemsPerDepth:Symfony\Component\VarDumper\Cloner\Data:private] => -1
|
||||||
|
[useRefHandles:Symfony\Component\VarDumper\Cloner\Data:private] => -1
|
||||||
|
)
|
||||||
|
|
||||||
|
EOTXT;
|
||||||
|
$this->assertSame(sprintf($expected, PHP_INT_MAX), print_r($clone, true));
|
||||||
|
}
|
||||||
|
|
||||||
public function testClone()
|
public function testClone()
|
||||||
{
|
{
|
||||||
$json = json_decode('{"1":{"var":"val"},"2":{"var":"val"}}');
|
$json = json_decode('{"1":{"var":"val"},"2":{"var":"val"}}');
|
||||||
|
|
|
@ -285,7 +285,7 @@ class Inline
|
||||||
{
|
{
|
||||||
$output = array();
|
$output = array();
|
||||||
$len = strlen($sequence);
|
$len = strlen($sequence);
|
||||||
$i += 1;
|
++$i;
|
||||||
|
|
||||||
// [foo, bar, ...]
|
// [foo, bar, ...]
|
||||||
while ($i < $len) {
|
while ($i < $len) {
|
||||||
|
@ -344,7 +344,7 @@ class Inline
|
||||||
{
|
{
|
||||||
$output = array();
|
$output = array();
|
||||||
$len = strlen($mapping);
|
$len = strlen($mapping);
|
||||||
$i += 1;
|
++$i;
|
||||||
|
|
||||||
// {foo: bar, bar:foo, ...}
|
// {foo: bar, bar:foo, ...}
|
||||||
while ($i < $len) {
|
while ($i < $len) {
|
||||||
|
|
Reference in New Issue