Merge branch '3.2'
* 3.2: [WebProfilerBundle] Fix AJAX panel with fetch requests Don’t compile when Opcache is not enabled on CLI DateIntervalType: 'invert' should not inherit the 'required' option [Form] DateIntervalType: Do not try to translate choices [TwigBridge] fix constructor args check Allow simple-phpunit to be used with an HTTP proxy Minor fixes for 3.2 Fix a web profiler form issue with fields added to the form after the form was built do not trigger deprecations for valid YAML Write an exception message in a one heading line [Workflow] Added missing docblock [Finder] Refine phpdoc about argument for NumberComparator Fixed max width from ajax request url element (td) Fix unresolved parameters from default bundle configs in debug:config [github] Tweak PR template [Serializer] Optimize max depth checking
This commit is contained in:
commit
40280f203c
14
.github/PULL_REQUEST_TEMPLATE.md
vendored
14
.github/PULL_REQUEST_TEMPLATE.md
vendored
@ -1,11 +1,19 @@
|
|||||||
| Q | A
|
| Q | A
|
||||||
| ------------- | ---
|
| ------------- | ---
|
||||||
| Branch? | "master" for new features / 2.7, 2.8 or 3.1 for fixes
|
| Branch? | master / 2.7, 2.8, 3.1 or 3.2 <!--see comment below-->
|
||||||
| Bug fix? | yes/no
|
| Bug fix? | yes/no
|
||||||
| New feature? | yes/no
|
| New feature? | yes/no
|
||||||
| BC breaks? | yes/no
|
| BC breaks? | yes/no
|
||||||
| Deprecations? | yes/no
|
| Deprecations? | yes/no
|
||||||
| Tests pass? | yes/no
|
| Tests pass? | yes/no
|
||||||
| Fixed tickets | comma-separated list of tickets fixed by the PR, if any
|
| Fixed tickets | #... <!-- #-prefixed issue number(s), if any -->
|
||||||
| License | MIT
|
| License | MIT
|
||||||
| Doc PR | reference to the documentation PR, if any
|
| Doc PR | symfony/symfony-docs#... <!--highly recommended for new features-->
|
||||||
|
|
||||||
|
<!--
|
||||||
|
- Bug fixes must be submitted against the lowest branch where they apply
|
||||||
|
(lowest branches are regularly merged to upper ones so they get the fixes too).
|
||||||
|
- Features and deprecations must be submitted against the master branch.
|
||||||
|
- Please fill in this template according to the PR you're about to submit.
|
||||||
|
- Replace this comment by a description of what your PR is solving.
|
||||||
|
-->
|
||||||
|
@ -37,7 +37,7 @@ if (!file_exists("$PHPUNIT_DIR/phpunit-$PHPUNIT_VERSION/phpunit") || md5_file(__
|
|||||||
if (file_exists("phpunit-$PHPUNIT_VERSION")) {
|
if (file_exists("phpunit-$PHPUNIT_VERSION")) {
|
||||||
passthru(sprintf('\\' === DIRECTORY_SEPARATOR ? '(del /S /F /Q %s & rmdir %1$s) >nul': 'rm -rf %s', "phpunit-$PHPUNIT_VERSION"));
|
passthru(sprintf('\\' === DIRECTORY_SEPARATOR ? '(del /S /F /Q %s & rmdir %1$s) >nul': 'rm -rf %s', "phpunit-$PHPUNIT_VERSION"));
|
||||||
}
|
}
|
||||||
if (extension_loaded('openssl') && ini_get('allow_url_fopen')) {
|
if (extension_loaded('openssl') && ini_get('allow_url_fopen') && !isset($_SERVER['http_proxy']) && !isset($_SERVER['https_proxy'])) {
|
||||||
stream_copy_to_stream(fopen("https://github.com/sebastianbergmann/phpunit/archive/$PHPUNIT_VERSION.zip", 'rb'), fopen("$PHPUNIT_VERSION.zip", 'wb'));
|
stream_copy_to_stream(fopen("https://github.com/sebastianbergmann/phpunit/archive/$PHPUNIT_VERSION.zip", 'rb'), fopen("$PHPUNIT_VERSION.zip", 'wb'));
|
||||||
} else {
|
} else {
|
||||||
@unlink("$PHPUNIT_VERSION.zip");
|
@unlink("$PHPUNIT_VERSION.zip");
|
||||||
|
@ -31,7 +31,7 @@ class FormExtension extends \Twig_Extension implements \Twig_Extension_InitRunti
|
|||||||
|
|
||||||
public function __construct($renderer = null)
|
public function __construct($renderer = null)
|
||||||
{
|
{
|
||||||
if ($this->renderer instanceof TwigRendererInterface) {
|
if ($renderer instanceof TwigRendererInterface) {
|
||||||
@trigger_error(sprintf('Passing a Twig Form Renderer to the "%s" constructor is deprecated since version 3.2 and won\'t be possible in 4.0. Pass the Twig_Environment to the TwigRendererEngine constructor instead.', static::class), E_USER_DEPRECATED);
|
@trigger_error(sprintf('Passing a Twig Form Renderer to the "%s" constructor is deprecated since version 3.2 and won\'t be possible in 4.0. Pass the Twig_Environment to the TwigRendererEngine constructor instead.', static::class), E_USER_DEPRECATED);
|
||||||
} elseif (null !== $renderer && !(is_array($renderer) && isset($renderer[0], $renderer[1]) && $renderer[0] instanceof ContainerInterface)) {
|
} elseif (null !== $renderer && !(is_array($renderer) && isset($renderer[0], $renderer[1]) && $renderer[0] instanceof ContainerInterface)) {
|
||||||
throw new \InvalidArgumentException(sprintf('Passing any arguments the constructor of %s is reserved for internal use.', __CLASS__));
|
throw new \InvalidArgumentException(sprintf('Passing any arguments the constructor of %s is reserved for internal use.', __CLASS__));
|
||||||
|
@ -105,7 +105,7 @@ EOF
|
|||||||
|
|
||||||
$io->title(sprintf('Current configuration for "%s.%s"', $extensionAlias, $path));
|
$io->title(sprintf('Current configuration for "%s.%s"', $extensionAlias, $path));
|
||||||
|
|
||||||
$io->writeln(Yaml::dump($config, 10));
|
$io->writeln(Yaml::dump($container->getParameterBag()->resolveValue($config), 10));
|
||||||
}
|
}
|
||||||
|
|
||||||
private function compileContainer()
|
private function compileContainer()
|
||||||
|
@ -17,7 +17,6 @@ use Symfony\Component\Console\Output\OutputInterface;
|
|||||||
use Symfony\Component\Workflow\Dumper\GraphvizDumper;
|
use Symfony\Component\Workflow\Dumper\GraphvizDumper;
|
||||||
use Symfony\Component\Workflow\Dumper\StateMachineGraphvizDumper;
|
use Symfony\Component\Workflow\Dumper\StateMachineGraphvizDumper;
|
||||||
use Symfony\Component\Workflow\Marking;
|
use Symfony\Component\Workflow\Marking;
|
||||||
use Symfony\Component\Workflow\Workflow;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author Grégoire Pineau <lyrixx@lyrixx.info>
|
* @author Grégoire Pineau <lyrixx@lyrixx.info>
|
||||||
|
@ -137,7 +137,7 @@ abstract class Controller implements ContainerAwareInterface
|
|||||||
protected function file($file, $fileName = null, $disposition = ResponseHeaderBag::DISPOSITION_ATTACHMENT)
|
protected function file($file, $fileName = null, $disposition = ResponseHeaderBag::DISPOSITION_ATTACHMENT)
|
||||||
{
|
{
|
||||||
$response = new BinaryFileResponse($file);
|
$response = new BinaryFileResponse($file);
|
||||||
$response->setContentDisposition($disposition, $fileName === null ? $response->getFile()->getFileName() : $fileName);
|
$response->setContentDisposition($disposition, $fileName === null ? $response->getFile()->getFilename() : $fileName);
|
||||||
|
|
||||||
return $response;
|
return $response;
|
||||||
}
|
}
|
||||||
|
@ -20,7 +20,6 @@ use Symfony\Component\Cache\Adapter\FilesystemAdapter;
|
|||||||
use Symfony\Component\Cache\Adapter\ProxyAdapter;
|
use Symfony\Component\Cache\Adapter\ProxyAdapter;
|
||||||
use Symfony\Component\Cache\Adapter\RedisAdapter;
|
use Symfony\Component\Cache\Adapter\RedisAdapter;
|
||||||
use Symfony\Component\DependencyInjection\ContainerBuilder;
|
use Symfony\Component\DependencyInjection\ContainerBuilder;
|
||||||
use Symfony\Component\DependencyInjection\Definition;
|
|
||||||
use Symfony\Component\DependencyInjection\DefinitionDecorator;
|
use Symfony\Component\DependencyInjection\DefinitionDecorator;
|
||||||
use Symfony\Component\DependencyInjection\Loader\ClosureLoader;
|
use Symfony\Component\DependencyInjection\Loader\ClosureLoader;
|
||||||
use Symfony\Component\DependencyInjection\ParameterBag\ParameterBag;
|
use Symfony\Component\DependencyInjection\ParameterBag\ParameterBag;
|
||||||
|
@ -9,9 +9,7 @@
|
|||||||
<div class="text-exception">
|
<div class="text-exception">
|
||||||
<div class="open-quote">“</div>
|
<div class="open-quote">“</div>
|
||||||
|
|
||||||
<h1>
|
<h1>{{ exception.message|nl2br|format_file_from_text }}</h1>
|
||||||
{{ exception.message|nl2br|format_file_from_text }}
|
|
||||||
</h1>
|
|
||||||
|
|
||||||
<div>
|
<div>
|
||||||
<strong>{{ status_code }}</strong> {{ status_text }} - {{ exception.class|abbr_class }}
|
<strong>{{ status_code }}</strong> {{ status_text }} - {{ exception.class|abbr_class }}
|
||||||
|
@ -457,7 +457,7 @@
|
|||||||
{% import _self as tree %}
|
{% import _self as tree %}
|
||||||
<div class="tree-details{% if not show|default(false) %} hidden{% endif %}" {% if data.id is defined %}id="{{ data.id }}-details"{% endif %}>
|
<div class="tree-details{% if not show|default(false) %} hidden{% endif %}" {% if data.id is defined %}id="{{ data.id }}-details"{% endif %}>
|
||||||
<h2 class="dump-inline">
|
<h2 class="dump-inline">
|
||||||
{{ name|default('(no name)') }} ({{ profiler_dump(data.type_class) }})
|
{{ name|default('(no name)') }} {% if data.type_class is defined %}({{ profiler_dump(data.type_class) }}){% endif %}
|
||||||
</h2>
|
</h2>
|
||||||
|
|
||||||
{% if data.errors is defined and data.errors|length > 0 %}
|
{% if data.errors is defined and data.errors|length > 0 %}
|
||||||
|
@ -234,15 +234,28 @@
|
|||||||
var oldFetch = window.fetch;
|
var oldFetch = window.fetch;
|
||||||
window.fetch = function () {
|
window.fetch = function () {
|
||||||
var promise = oldFetch.apply(this, arguments);
|
var promise = oldFetch.apply(this, arguments);
|
||||||
if (!arguments[0].match(new RegExp({{ excluded_ajax_paths|json_encode|raw }}))) {
|
var url = arguments[0];
|
||||||
|
var params = arguments[1];
|
||||||
|
var paramType = Object.prototype.toString.call(arguments[0]);
|
||||||
|
if (paramType === '[object Request]') {
|
||||||
|
url = arguments[0].url;
|
||||||
|
params = {
|
||||||
|
method: arguments[0].method,
|
||||||
|
credentials: arguments[0].credentials,
|
||||||
|
headers: arguments[0].headers,
|
||||||
|
mode: arguments[0].mode,
|
||||||
|
redirect: arguments[0].redirect
|
||||||
|
};
|
||||||
|
}
|
||||||
|
if (!url.match(new RegExp({{ excluded_ajax_paths|json_encode|raw }}))) {
|
||||||
var method = 'GET';
|
var method = 'GET';
|
||||||
if (arguments[1] && arguments[1].method !== undefined) {
|
if (params && params.method !== undefined) {
|
||||||
method = arguments[1].method;
|
method = params.method;
|
||||||
}
|
}
|
||||||
|
|
||||||
var stackElement = {
|
var stackElement = {
|
||||||
error: false,
|
error: false,
|
||||||
url: arguments[0],
|
url: url,
|
||||||
method: method,
|
method: method,
|
||||||
type: 'fetch',
|
type: 'fetch',
|
||||||
start: new Date()
|
start: new Date()
|
||||||
|
@ -93,7 +93,7 @@ class PhpFilesAdapter extends AbstractAdapter
|
|||||||
$ok = true;
|
$ok = true;
|
||||||
$data = array($lifetime ? time() + $lifetime : PHP_INT_MAX, '');
|
$data = array($lifetime ? time() + $lifetime : PHP_INT_MAX, '');
|
||||||
|
|
||||||
foreach ($values as $id => $value) {
|
foreach ($values as $key => $value) {
|
||||||
if (null === $value || is_object($value)) {
|
if (null === $value || is_object($value)) {
|
||||||
$value = serialize($value);
|
$value = serialize($value);
|
||||||
} elseif (is_array($value)) {
|
} elseif (is_array($value)) {
|
||||||
@ -109,13 +109,16 @@ class PhpFilesAdapter extends AbstractAdapter
|
|||||||
$value = serialize($value);
|
$value = serialize($value);
|
||||||
}
|
}
|
||||||
} elseif (!is_scalar($value)) {
|
} elseif (!is_scalar($value)) {
|
||||||
throw new InvalidArgumentException(sprintf('Value of type "%s" is not serializable', $key, gettype($value)));
|
throw new InvalidArgumentException(sprintf('Cache key "%s" has non-serializable %s value.', $key, gettype($value)));
|
||||||
}
|
}
|
||||||
|
|
||||||
$data[1] = $value;
|
$data[1] = $value;
|
||||||
$file = $this->getFile($id, true);
|
$file = $this->getFile($key, true);
|
||||||
$ok = $this->write($file, '<?php return '.var_export($data, true).';') && $ok;
|
$ok = $this->write($file, '<?php return '.var_export($data, true).';') && $ok;
|
||||||
@opcache_compile_file($file);
|
|
||||||
|
if ('cli' !== PHP_SAPI || ini_get('opcache.enable_cli')) {
|
||||||
|
@opcache_compile_file($file);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return $ok;
|
return $ok;
|
||||||
|
@ -30,7 +30,7 @@ class TagAwareAdapterTest extends AdapterTestCase
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @expectedException Psr\Cache\InvalidArgumentException
|
* @expectedException \Psr\Cache\InvalidArgumentException
|
||||||
*/
|
*/
|
||||||
public function testInvalidTag()
|
public function testInvalidTag()
|
||||||
{
|
{
|
||||||
|
@ -65,7 +65,7 @@ class CacheItemTest extends \PHPUnit_Framework_TestCase
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* @dataProvider provideInvalidKey
|
* @dataProvider provideInvalidKey
|
||||||
* @expectedException Symfony\Component\Cache\Exception\InvalidArgumentException
|
* @expectedException \Symfony\Component\Cache\Exception\InvalidArgumentException
|
||||||
* @expectedExceptionMessage Cache tag
|
* @expectedExceptionMessage Cache tag
|
||||||
*/
|
*/
|
||||||
public function testInvalidTag($tag)
|
public function testInvalidTag($tag)
|
||||||
|
@ -13,7 +13,6 @@ namespace Symfony\Component\Console\Tests\Style;
|
|||||||
|
|
||||||
use PHPUnit_Framework_TestCase;
|
use PHPUnit_Framework_TestCase;
|
||||||
use Symfony\Component\Console\Command\Command;
|
use Symfony\Component\Console\Command\Command;
|
||||||
use Symfony\Component\Console\Style\SymfonyStyle;
|
|
||||||
use Symfony\Component\Console\Tester\CommandTester;
|
use Symfony\Component\Console\Tester\CommandTester;
|
||||||
|
|
||||||
class SymfonyStyleTest extends PHPUnit_Framework_TestCase
|
class SymfonyStyleTest extends PHPUnit_Framework_TestCase
|
||||||
|
@ -37,7 +37,7 @@ class NumberComparator extends Comparator
|
|||||||
/**
|
/**
|
||||||
* Constructor.
|
* Constructor.
|
||||||
*
|
*
|
||||||
* @param string $test A comparison string
|
* @param string|int $test A comparison string or an integer
|
||||||
*
|
*
|
||||||
* @throws \InvalidArgumentException If the test is not understood
|
* @throws \InvalidArgumentException If the test is not understood
|
||||||
*/
|
*/
|
||||||
|
@ -111,7 +111,7 @@ class Finder implements \IteratorAggregate, \Countable
|
|||||||
* $finder->depth('> 1') // the Finder will start matching at level 1.
|
* $finder->depth('> 1') // the Finder will start matching at level 1.
|
||||||
* $finder->depth('< 3') // the Finder will descend at most 3 levels of directories below the starting point.
|
* $finder->depth('< 3') // the Finder will descend at most 3 levels of directories below the starting point.
|
||||||
*
|
*
|
||||||
* @param int $level The depth level expression
|
* @param string|int $level The depth level expression
|
||||||
*
|
*
|
||||||
* @return Finder|SplFileInfo[] The current Finder instance
|
* @return Finder|SplFileInfo[] The current Finder instance
|
||||||
*
|
*
|
||||||
@ -283,7 +283,7 @@ class Finder implements \IteratorAggregate, \Countable
|
|||||||
* $finder->size('<= 1Ki');
|
* $finder->size('<= 1Ki');
|
||||||
* $finder->size(4);
|
* $finder->size(4);
|
||||||
*
|
*
|
||||||
* @param string $size A size range string
|
* @param string|int $size A size range string or an integer
|
||||||
*
|
*
|
||||||
* @return Finder|SplFileInfo[] The current Finder instance
|
* @return Finder|SplFileInfo[] The current Finder instance
|
||||||
*
|
*
|
||||||
|
@ -102,14 +102,12 @@ class DateIntervalType extends AbstractType
|
|||||||
$childOptions[$part] = array();
|
$childOptions[$part] = array();
|
||||||
$childOptions[$part]['error_bubbling'] = true;
|
$childOptions[$part]['error_bubbling'] = true;
|
||||||
if ('choice' === $options['widget']) {
|
if ('choice' === $options['widget']) {
|
||||||
|
$childOptions[$part]['choice_translation_domain'] = false;
|
||||||
$childOptions[$part]['choices'] = $options[$part];
|
$childOptions[$part]['choices'] = $options[$part];
|
||||||
$childOptions[$part]['placeholder'] = $options['placeholder'][$part];
|
$childOptions[$part]['placeholder'] = $options['placeholder'][$part];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
$invertOptions = array(
|
|
||||||
'error_bubbling' => true,
|
|
||||||
);
|
|
||||||
// Append generic carry-along options
|
// Append generic carry-along options
|
||||||
foreach (array('required', 'translation_domain') as $passOpt) {
|
foreach (array('required', 'translation_domain') as $passOpt) {
|
||||||
foreach ($this->timeParts as $part) {
|
foreach ($this->timeParts as $part) {
|
||||||
@ -117,9 +115,6 @@ class DateIntervalType extends AbstractType
|
|||||||
$childOptions[$part][$passOpt] = $options[$passOpt];
|
$childOptions[$part][$passOpt] = $options[$passOpt];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if ($options['with_invert']) {
|
|
||||||
$invertOptions[$passOpt] = $options[$passOpt];
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
foreach ($this->timeParts as $part) {
|
foreach ($this->timeParts as $part) {
|
||||||
if ($options['with_'.$part]) {
|
if ($options['with_'.$part]) {
|
||||||
@ -135,7 +130,11 @@ class DateIntervalType extends AbstractType
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if ($options['with_invert']) {
|
if ($options['with_invert']) {
|
||||||
$builder->add('invert', 'Symfony\Component\Form\Extension\Core\Type\CheckboxType', $invertOptions);
|
$builder->add('invert', 'Symfony\Component\Form\Extension\Core\Type\CheckboxType', array(
|
||||||
|
'error_bubbling' => true,
|
||||||
|
'required' => false,
|
||||||
|
'translation_domain' => $options['translation_domain'],
|
||||||
|
));
|
||||||
}
|
}
|
||||||
$builder->addViewTransformer(new DateIntervalToArrayTransformer($parts, 'text' === $options['widget']));
|
$builder->addViewTransformer(new DateIntervalToArrayTransformer($parts, 'text' === $options['widget']));
|
||||||
}
|
}
|
||||||
|
@ -11,6 +11,7 @@
|
|||||||
|
|
||||||
namespace Symfony\Component\Form\Tests\Extension\Core\Type;
|
namespace Symfony\Component\Form\Tests\Extension\Core\Type;
|
||||||
|
|
||||||
|
use Symfony\Component\Form\Extension\Core\Type\DateIntervalType;
|
||||||
use Symfony\Component\Form\FormError;
|
use Symfony\Component\Form\FormError;
|
||||||
use Symfony\Component\Form\Test\TypeTestCase as TestCase;
|
use Symfony\Component\Form\Test\TypeTestCase as TestCase;
|
||||||
|
|
||||||
@ -364,4 +365,38 @@ class DateIntervalTypeTest extends TestCase
|
|||||||
$this->assertSame(array(), iterator_to_array($form['years']->getErrors()));
|
$this->assertSame(array(), iterator_to_array($form['years']->getErrors()));
|
||||||
$this->assertSame(array($error), iterator_to_array($form->getErrors()));
|
$this->assertSame(array($error), iterator_to_array($form->getErrors()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function testTranslationsAreDisabledForChoiceWidget()
|
||||||
|
{
|
||||||
|
$form = $this->factory->create(
|
||||||
|
DateIntervalType::class,
|
||||||
|
null,
|
||||||
|
array(
|
||||||
|
'widget' => 'choice',
|
||||||
|
'with_hours' => true,
|
||||||
|
'with_minutes' => true,
|
||||||
|
'with_seconds' => true,
|
||||||
|
)
|
||||||
|
);
|
||||||
|
$this->assertFalse($form->get('years')->getConfig()->getOption('choice_translation_domain'));
|
||||||
|
$this->assertFalse($form->get('months')->getConfig()->getOption('choice_translation_domain'));
|
||||||
|
$this->assertFalse($form->get('days')->getConfig()->getOption('choice_translation_domain'));
|
||||||
|
$this->assertFalse($form->get('hours')->getConfig()->getOption('choice_translation_domain'));
|
||||||
|
$this->assertFalse($form->get('minutes')->getConfig()->getOption('choice_translation_domain'));
|
||||||
|
$this->assertFalse($form->get('seconds')->getConfig()->getOption('choice_translation_domain'));
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testInvertDoesNotInheritRequiredOption()
|
||||||
|
{
|
||||||
|
$form = $this->factory->create(
|
||||||
|
'Symfony\Component\Form\Extension\Core\Type\DateIntervalType',
|
||||||
|
null,
|
||||||
|
array(
|
||||||
|
'input' => 'dateinterval',
|
||||||
|
'with_invert' => true,
|
||||||
|
'required' => true,
|
||||||
|
)
|
||||||
|
);
|
||||||
|
$this->assertFalse($form->get('invert')->getConfig()->getOption('required'));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -13,7 +13,6 @@ namespace Symfony\Component\Serializer\Encoder;
|
|||||||
|
|
||||||
use Symfony\Component\Yaml\Dumper;
|
use Symfony\Component\Yaml\Dumper;
|
||||||
use Symfony\Component\Yaml\Parser;
|
use Symfony\Component\Yaml\Parser;
|
||||||
use Symfony\Component\Yaml\Yaml;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Encodes YAML data.
|
* Encodes YAML data.
|
||||||
|
@ -18,6 +18,7 @@ use Symfony\Component\Serializer\Exception\LogicException;
|
|||||||
use Symfony\Component\Serializer\Exception\UnexpectedValueException;
|
use Symfony\Component\Serializer\Exception\UnexpectedValueException;
|
||||||
use Symfony\Component\PropertyInfo\PropertyTypeExtractorInterface;
|
use Symfony\Component\PropertyInfo\PropertyTypeExtractorInterface;
|
||||||
use Symfony\Component\PropertyInfo\Type;
|
use Symfony\Component\PropertyInfo\Type;
|
||||||
|
use Symfony\Component\Serializer\Mapping\AttributeMetadataInterface;
|
||||||
use Symfony\Component\Serializer\Mapping\Factory\ClassMetadataFactoryInterface;
|
use Symfony\Component\Serializer\Mapping\Factory\ClassMetadataFactoryInterface;
|
||||||
use Symfony\Component\Serializer\NameConverter\NameConverterInterface;
|
use Symfony\Component\Serializer\NameConverter\NameConverterInterface;
|
||||||
|
|
||||||
@ -68,9 +69,10 @@ abstract class AbstractObjectNormalizer extends AbstractNormalizer
|
|||||||
$stack = array();
|
$stack = array();
|
||||||
$attributes = $this->getAttributes($object, $format, $context);
|
$attributes = $this->getAttributes($object, $format, $context);
|
||||||
$class = get_class($object);
|
$class = get_class($object);
|
||||||
|
$attributesMetadata = $this->classMetadataFactory ? $this->classMetadataFactory->getMetadataFor($class)->getAttributesMetadata() : null;
|
||||||
|
|
||||||
foreach ($attributes as $attribute) {
|
foreach ($attributes as $attribute) {
|
||||||
if ($this->isMaxDepthReached($class, $attribute, $context)) {
|
if (null !== $attributesMetadata && $this->isMaxDepthReached($attributesMetadata, $class, $attribute, $context)) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -300,42 +302,35 @@ abstract class AbstractObjectNormalizer extends AbstractNormalizer
|
|||||||
/**
|
/**
|
||||||
* Is the max depth reached for the given attribute?
|
* Is the max depth reached for the given attribute?
|
||||||
*
|
*
|
||||||
* @param string $class
|
* @param AttributeMetadataInterface[] $attributesMetadata
|
||||||
* @param string $attribute
|
* @param string $class
|
||||||
* @param array $context
|
* @param string $attribute
|
||||||
|
* @param array $context
|
||||||
*
|
*
|
||||||
* @return bool
|
* @return bool
|
||||||
*/
|
*/
|
||||||
private function isMaxDepthReached($class, $attribute, array &$context)
|
private function isMaxDepthReached(array $attributesMetadata, $class, $attribute, array &$context)
|
||||||
{
|
{
|
||||||
if (!$this->classMetadataFactory || !isset($context[static::ENABLE_MAX_DEPTH])) {
|
if (
|
||||||
return false;
|
!isset($context[static::ENABLE_MAX_DEPTH]) ||
|
||||||
}
|
!isset($attributesMetadata[$attribute]) ||
|
||||||
|
null === $maxDepth = $attributesMetadata[$attribute]->getMaxDepth()
|
||||||
$classMetadata = $this->classMetadataFactory->getMetadataFor($class);
|
) {
|
||||||
$attributesMetadata = $classMetadata->getAttributesMetadata();
|
|
||||||
|
|
||||||
if (!isset($attributesMetadata[$attribute])) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
$maxDepth = $attributesMetadata[$attribute]->getMaxDepth();
|
|
||||||
if (null === $maxDepth) {
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
$key = sprintf(static::DEPTH_KEY_PATTERN, $class, $attribute);
|
$key = sprintf(static::DEPTH_KEY_PATTERN, $class, $attribute);
|
||||||
$keyExist = isset($context[$key]);
|
if (!isset($context[$key])) {
|
||||||
|
$context[$key] = 1;
|
||||||
|
|
||||||
if ($keyExist && $context[$key] === $maxDepth) {
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($context[$key] === $maxDepth) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($keyExist) {
|
++$context[$key];
|
||||||
++$context[$key];
|
|
||||||
} else {
|
|
||||||
$context[$key] = 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -31,8 +31,8 @@ class StubCaster
|
|||||||
$stub->attr = $c->attr;
|
$stub->attr = $c->attr;
|
||||||
|
|
||||||
if (Stub::TYPE_REF === $c->type && !$c->class && is_string($c->value) && !preg_match('//u', $c->value)) {
|
if (Stub::TYPE_REF === $c->type && !$c->class && is_string($c->value) && !preg_match('//u', $c->value)) {
|
||||||
$stub->type = self::TYPE_STRING;
|
$stub->type = Stub::TYPE_STRING;
|
||||||
$stub->class = self::STRING_BINARY;
|
$stub->class = Stub::STRING_BINARY;
|
||||||
}
|
}
|
||||||
|
|
||||||
return array();
|
return array();
|
||||||
|
@ -79,6 +79,9 @@ class DefinitionBuilder
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param Transition[] $transitions
|
||||||
|
*/
|
||||||
public function addTransitions(array $transitions)
|
public function addTransitions(array $transitions)
|
||||||
{
|
{
|
||||||
foreach ($transitions as $transition) {
|
foreach ($transitions as $transition) {
|
||||||
|
@ -30,6 +30,12 @@ class Registry
|
|||||||
$this->workflows[] = array($workflow, $className);
|
$this->workflows[] = array($workflow, $className);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param object $subject
|
||||||
|
* @param string|null $workflowName
|
||||||
|
*
|
||||||
|
* @return Workflow
|
||||||
|
*/
|
||||||
public function get($subject, $workflowName = null)
|
public function get($subject, $workflowName = null)
|
||||||
{
|
{
|
||||||
$matched = null;
|
$matched = null;
|
||||||
|
@ -2,7 +2,6 @@
|
|||||||
|
|
||||||
namespace Symfony\Component\Workflow\Tests;
|
namespace Symfony\Component\Workflow\Tests;
|
||||||
|
|
||||||
use Symfony\Component\Workflow\Marking;
|
|
||||||
use Symfony\Component\Workflow\StateMachine;
|
use Symfony\Component\Workflow\StateMachine;
|
||||||
|
|
||||||
class StateMachineTest extends \PHPUnit_Framework_TestCase
|
class StateMachineTest extends \PHPUnit_Framework_TestCase
|
||||||
|
@ -463,8 +463,8 @@ class Inline
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!isset($mapping[$i + 1]) || ' ' !== $mapping[$i + 1]) {
|
if (!isset($mapping[$i + 1]) || !in_array($mapping[$i + 1], array(' ', '[', ']', '{', '}'), true)) {
|
||||||
@trigger_error('Omitting the space after the colon that follows a mapping key definition is deprecated since version 3.2 and will throw a ParseException in 4.0.', E_USER_DEPRECATED);
|
@trigger_error('Using a colon that is not followed by an indication character (i.e. " ", ",", "[", "]", "{", "}" is deprecated since version 3.2 and will throw a ParseException in 4.0.', E_USER_DEPRECATED);
|
||||||
}
|
}
|
||||||
|
|
||||||
// value
|
// value
|
||||||
|
@ -166,7 +166,7 @@ class InlineTest extends \PHPUnit_Framework_TestCase
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* @group legacy
|
* @group legacy
|
||||||
* @expectedDeprecation Omitting the space after the colon that follows a mapping key definition is deprecated since version 3.2 and will throw a ParseException in 4.0.
|
* @expectedDeprecation Using a colon that is not followed by an indication character (i.e. " ", ",", "[", "]", "{", "}" is deprecated since version 3.2 and will throw a ParseException in 4.0.
|
||||||
* throws \Symfony\Component\Yaml\Exception\ParseException in 4.0
|
* throws \Symfony\Component\Yaml\Exception\ParseException in 4.0
|
||||||
*/
|
*/
|
||||||
public function testParseMappingKeyWithColonNotFollowedBySpace()
|
public function testParseMappingKeyWithColonNotFollowedBySpace()
|
||||||
@ -395,6 +395,8 @@ class InlineTest extends \PHPUnit_Framework_TestCase
|
|||||||
array('[foo, {bar: foo}]', array('foo', array('bar' => 'foo'))),
|
array('[foo, {bar: foo}]', array('foo', array('bar' => 'foo'))),
|
||||||
array('{ foo: {bar: foo} }', array('foo' => array('bar' => 'foo'))),
|
array('{ foo: {bar: foo} }', array('foo' => array('bar' => 'foo'))),
|
||||||
array('{ foo: [bar, foo] }', array('foo' => array('bar', 'foo'))),
|
array('{ foo: [bar, foo] }', array('foo' => array('bar', 'foo'))),
|
||||||
|
array('{ foo:{bar: foo} }', array('foo' => array('bar' => 'foo'))),
|
||||||
|
array('{ foo:[bar, foo] }', array('foo' => array('bar', 'foo'))),
|
||||||
|
|
||||||
array('[ foo, [ bar, foo ] ]', array('foo', array('bar', 'foo'))),
|
array('[ foo, [ bar, foo ] ]', array('foo', array('bar', 'foo'))),
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user