Merge branch '2.8'
* 2.8: [HttpKernel] clearstatcache() so the Cache sees when a .lck file has been released [WIP] [Form] [TwigBridge] Bootstrap horizontal theme missing tests [Serializer] Improve ObjectNormalizer performance AssetBundle - fix docs [Yaml] more fixes to changelog and upgrade files CS: remove impossible default argument value
This commit is contained in:
commit
7ba5f7acb3
@ -1341,8 +1341,21 @@ UPGRADE FROM 2.x to 3.0
|
|||||||
|
|
||||||
* Using a colon in an unquoted mapping value leads to a `ParseException`.
|
* Using a colon in an unquoted mapping value leads to a `ParseException`.
|
||||||
* Starting an unquoted string with `@`, `` ` ``, `|`, or `>` leads to a `ParseException`.
|
* Starting an unquoted string with `@`, `` ` ``, `|`, or `>` leads to a `ParseException`.
|
||||||
* Deprecated non-escaped \ in double-quoted strings when parsing Yaml
|
* When surrounding strings with double-quotes, you must now escape `\` characters. Not
|
||||||
("Foo\Var" is not valid whereas "Foo\\Var" is)
|
escaping those characters (when surrounded by double-quotes) leads to a `ParseException`.
|
||||||
|
|
||||||
|
Before:
|
||||||
|
|
||||||
|
```yml
|
||||||
|
class: "Foo\Var"
|
||||||
|
```
|
||||||
|
|
||||||
|
After:
|
||||||
|
|
||||||
|
```yml
|
||||||
|
class: "Foo\\Var"
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
* The ability to pass file names to `Yaml::parse()` has been removed.
|
* The ability to pass file names to `Yaml::parse()` has been removed.
|
||||||
|
|
||||||
|
@ -25,15 +25,13 @@ col-sm-2
|
|||||||
{# Rows #}
|
{# Rows #}
|
||||||
|
|
||||||
{% block form_row -%}
|
{% block form_row -%}
|
||||||
{% spaceless %}
|
|
||||||
<div class="form-group{% if (not compound or force_error|default(false)) and not valid %} has-error{% endif %}">
|
<div class="form-group{% if (not compound or force_error|default(false)) and not valid %} has-error{% endif %}">
|
||||||
{{ form_label(form) }}
|
{{- form_label(form) -}}
|
||||||
<div class="{{ block('form_group_class') }}">
|
<div class="{{ block('form_group_class') }}">
|
||||||
{{ form_widget(form) }}
|
{{- form_widget(form) -}}
|
||||||
{{ form_errors(form) }}
|
{{- form_errors(form) -}}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
{##}</div>
|
||||||
{% endspaceless %}
|
|
||||||
{%- endblock form_row %}
|
{%- endblock form_row %}
|
||||||
|
|
||||||
{% block checkbox_row -%}
|
{% block checkbox_row -%}
|
||||||
|
@ -0,0 +1,118 @@
|
|||||||
|
<?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\Bridge\Twig\Tests\Extension;
|
||||||
|
|
||||||
|
use Symfony\Bridge\Twig\Extension\FormExtension;
|
||||||
|
use Symfony\Bridge\Twig\Form\TwigRenderer;
|
||||||
|
use Symfony\Bridge\Twig\Form\TwigRendererEngine;
|
||||||
|
use Symfony\Bridge\Twig\Extension\TranslationExtension;
|
||||||
|
use Symfony\Bridge\Twig\Tests\Extension\Fixtures\StubTranslator;
|
||||||
|
use Symfony\Bridge\Twig\Tests\Extension\Fixtures\StubFilesystemLoader;
|
||||||
|
use Symfony\Component\Form\FormView;
|
||||||
|
use Symfony\Component\Form\Tests\AbstractBootstrap3HorizontalLayoutTest;
|
||||||
|
|
||||||
|
class FormExtensionBootstrap3HorizontalLayoutTest extends AbstractBootstrap3HorizontalLayoutTest
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* @var FormExtension
|
||||||
|
*/
|
||||||
|
protected $extension;
|
||||||
|
|
||||||
|
protected $testableFeatures = array(
|
||||||
|
'choice_attr',
|
||||||
|
);
|
||||||
|
|
||||||
|
protected function setUp()
|
||||||
|
{
|
||||||
|
parent::setUp();
|
||||||
|
|
||||||
|
$rendererEngine = new TwigRendererEngine(array(
|
||||||
|
'bootstrap_3_horizontal_layout.html.twig',
|
||||||
|
'custom_widgets.html.twig',
|
||||||
|
));
|
||||||
|
$renderer = new TwigRenderer($rendererEngine, $this->getMock('Symfony\Component\Security\Csrf\CsrfTokenManagerInterface'));
|
||||||
|
|
||||||
|
$this->extension = new FormExtension($renderer);
|
||||||
|
|
||||||
|
$loader = new StubFilesystemLoader(array(
|
||||||
|
__DIR__.'/../../Resources/views/Form',
|
||||||
|
__DIR__.'/Fixtures/templates/form',
|
||||||
|
));
|
||||||
|
|
||||||
|
$environment = new \Twig_Environment($loader, array('strict_variables' => true));
|
||||||
|
$environment->addExtension(new TranslationExtension(new StubTranslator()));
|
||||||
|
$environment->addExtension($this->extension);
|
||||||
|
|
||||||
|
$this->extension->initRuntime($environment);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function tearDown()
|
||||||
|
{
|
||||||
|
parent::tearDown();
|
||||||
|
|
||||||
|
$this->extension = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function renderForm(FormView $view, array $vars = array())
|
||||||
|
{
|
||||||
|
return (string) $this->extension->renderer->renderBlock($view, 'form', $vars);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function renderEnctype(FormView $view)
|
||||||
|
{
|
||||||
|
return (string) $this->extension->renderer->searchAndRenderBlock($view, 'enctype');
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function renderLabel(FormView $view, $label = null, array $vars = array())
|
||||||
|
{
|
||||||
|
if ($label !== null) {
|
||||||
|
$vars += array('label' => $label);
|
||||||
|
}
|
||||||
|
|
||||||
|
return (string) $this->extension->renderer->searchAndRenderBlock($view, 'label', $vars);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function renderErrors(FormView $view)
|
||||||
|
{
|
||||||
|
return (string) $this->extension->renderer->searchAndRenderBlock($view, 'errors');
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function renderWidget(FormView $view, array $vars = array())
|
||||||
|
{
|
||||||
|
return (string) $this->extension->renderer->searchAndRenderBlock($view, 'widget', $vars);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function renderRow(FormView $view, array $vars = array())
|
||||||
|
{
|
||||||
|
return (string) $this->extension->renderer->searchAndRenderBlock($view, 'row', $vars);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function renderRest(FormView $view, array $vars = array())
|
||||||
|
{
|
||||||
|
return (string) $this->extension->renderer->searchAndRenderBlock($view, 'rest', $vars);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function renderStart(FormView $view, array $vars = array())
|
||||||
|
{
|
||||||
|
return (string) $this->extension->renderer->renderBlock($view, 'form_start', $vars);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function renderEnd(FormView $view, array $vars = array())
|
||||||
|
{
|
||||||
|
return (string) $this->extension->renderer->renderBlock($view, 'form_end', $vars);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function setTheme(FormView $view, array $themes)
|
||||||
|
{
|
||||||
|
$this->extension->renderer->setTheme($view, $themes);
|
||||||
|
}
|
||||||
|
}
|
@ -60,6 +60,9 @@ class Package implements PackageInterface
|
|||||||
return $this->context;
|
return $this->context;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return VersionStrategyInterface
|
||||||
|
*/
|
||||||
protected function getVersionStrategy()
|
protected function getVersionStrategy()
|
||||||
{
|
{
|
||||||
return $this->versionStrategy;
|
return $this->versionStrategy;
|
||||||
|
@ -39,10 +39,11 @@ class UrlPackage extends Package
|
|||||||
private $sslPackage;
|
private $sslPackage;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param string|array $baseUrls Base asset URLs
|
* @param string|string[] $baseUrls Base asset URLs
|
||||||
* @param VersionStrategyInterface $versionStrategy The version strategy
|
* @param VersionStrategyInterface $versionStrategy The version strategy
|
||||||
|
* @param ContextInterface|null $context Context
|
||||||
*/
|
*/
|
||||||
public function __construct($baseUrls = array(), VersionStrategyInterface $versionStrategy, ContextInterface $context = null)
|
public function __construct($baseUrls, VersionStrategyInterface $versionStrategy, ContextInterface $context = null)
|
||||||
{
|
{
|
||||||
parent::__construct($versionStrategy, $context);
|
parent::__construct($versionStrategy, $context);
|
||||||
|
|
||||||
|
@ -21,6 +21,10 @@ class StaticVersionStrategy implements VersionStrategyInterface
|
|||||||
private $version;
|
private $version;
|
||||||
private $format;
|
private $format;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param string $version Version number
|
||||||
|
* @param string $format Url format
|
||||||
|
*/
|
||||||
public function __construct($version, $format = null)
|
public function __construct($version, $format = null)
|
||||||
{
|
{
|
||||||
$this->version = $version;
|
$this->version = $version;
|
||||||
|
@ -217,7 +217,7 @@ class FormDataCollector extends DataCollector implements FormDataCollectorInterf
|
|||||||
return $this->data;
|
return $this->data;
|
||||||
}
|
}
|
||||||
|
|
||||||
private function recursiveBuildPreliminaryFormTree(FormInterface $form, &$output = null, array &$outputByHash)
|
private function recursiveBuildPreliminaryFormTree(FormInterface $form, &$output, array &$outputByHash)
|
||||||
{
|
{
|
||||||
$hash = spl_object_hash($form);
|
$hash = spl_object_hash($form);
|
||||||
|
|
||||||
@ -236,7 +236,7 @@ class FormDataCollector extends DataCollector implements FormDataCollectorInterf
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private function recursiveBuildFinalFormTree(FormInterface $form = null, FormView $view, &$output = null, array &$outputByHash)
|
private function recursiveBuildFinalFormTree(FormInterface $form = null, FormView $view, &$output, array &$outputByHash)
|
||||||
{
|
{
|
||||||
$viewHash = spl_object_hash($view);
|
$viewHash = spl_object_hash($view);
|
||||||
$formHash = null;
|
$formHash = null;
|
||||||
|
@ -0,0 +1,157 @@
|
|||||||
|
<?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\Form\Tests;
|
||||||
|
|
||||||
|
abstract class AbstractBootstrap3HorizontalLayoutTest extends AbstractBootstrap3LayoutTest
|
||||||
|
{
|
||||||
|
public function testLabelOnForm()
|
||||||
|
{
|
||||||
|
$form = $this->factory->createNamed('name', 'Symfony\Component\Form\Extension\Core\Type\DateType');
|
||||||
|
$view = $form->createView();
|
||||||
|
$this->renderWidget($view, array('label' => 'foo'));
|
||||||
|
$html = $this->renderLabel($view);
|
||||||
|
|
||||||
|
$this->assertMatchesXpath($html,
|
||||||
|
'/label
|
||||||
|
[@class="col-sm-2 control-label required"]
|
||||||
|
[.="[trans]Name[/trans]"]
|
||||||
|
'
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testLabelDoesNotRenderFieldAttributes()
|
||||||
|
{
|
||||||
|
$form = $this->factory->createNamed('name', 'Symfony\Component\Form\Extension\Core\Type\TextType');
|
||||||
|
$html = $this->renderLabel($form->createView(), null, array(
|
||||||
|
'attr' => array(
|
||||||
|
'class' => 'my&class',
|
||||||
|
),
|
||||||
|
));
|
||||||
|
|
||||||
|
$this->assertMatchesXpath($html,
|
||||||
|
'/label
|
||||||
|
[@for="name"]
|
||||||
|
[@class="col-sm-2 control-label required"]
|
||||||
|
'
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testLabelWithCustomAttributesPassedDirectly()
|
||||||
|
{
|
||||||
|
$form = $this->factory->createNamed('name', 'Symfony\Component\Form\Extension\Core\Type\TextType');
|
||||||
|
$html = $this->renderLabel($form->createView(), null, array(
|
||||||
|
'label_attr' => array(
|
||||||
|
'class' => 'my&class',
|
||||||
|
),
|
||||||
|
));
|
||||||
|
|
||||||
|
$this->assertMatchesXpath($html,
|
||||||
|
'/label
|
||||||
|
[@for="name"]
|
||||||
|
[@class="my&class col-sm-2 control-label required"]
|
||||||
|
'
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testLabelWithCustomTextAndCustomAttributesPassedDirectly()
|
||||||
|
{
|
||||||
|
$form = $this->factory->createNamed('name', 'Symfony\Component\Form\Extension\Core\Type\TextType');
|
||||||
|
$html = $this->renderLabel($form->createView(), 'Custom label', array(
|
||||||
|
'label_attr' => array(
|
||||||
|
'class' => 'my&class',
|
||||||
|
),
|
||||||
|
));
|
||||||
|
|
||||||
|
$this->assertMatchesXpath($html,
|
||||||
|
'/label
|
||||||
|
[@for="name"]
|
||||||
|
[@class="my&class col-sm-2 control-label required"]
|
||||||
|
[.="[trans]Custom label[/trans]"]
|
||||||
|
'
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testLabelWithCustomTextAsOptionAndCustomAttributesPassedDirectly()
|
||||||
|
{
|
||||||
|
$form = $this->factory->createNamed('name', 'Symfony\Component\Form\Extension\Core\Type\TextType', null, array(
|
||||||
|
'label' => 'Custom label',
|
||||||
|
));
|
||||||
|
$html = $this->renderLabel($form->createView(), null, array(
|
||||||
|
'label_attr' => array(
|
||||||
|
'class' => 'my&class',
|
||||||
|
),
|
||||||
|
));
|
||||||
|
|
||||||
|
$this->assertMatchesXpath($html,
|
||||||
|
'/label
|
||||||
|
[@for="name"]
|
||||||
|
[@class="my&class col-sm-2 control-label required"]
|
||||||
|
[.="[trans]Custom label[/trans]"]
|
||||||
|
'
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testStartTag()
|
||||||
|
{
|
||||||
|
$form = $this->factory->create('Symfony\Component\Form\Extension\Core\Type\FormType', null, array(
|
||||||
|
'method' => 'get',
|
||||||
|
'action' => 'http://example.com/directory',
|
||||||
|
));
|
||||||
|
|
||||||
|
$html = $this->renderStart($form->createView());
|
||||||
|
|
||||||
|
$this->assertSame('<form name="form" method="get" action="http://example.com/directory" class="form-horizontal">', $html);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testStartTagWithOverriddenVars()
|
||||||
|
{
|
||||||
|
$form = $this->factory->create('Symfony\Component\Form\Extension\Core\Type\FormType', null, array(
|
||||||
|
'method' => 'put',
|
||||||
|
'action' => 'http://example.com/directory',
|
||||||
|
));
|
||||||
|
|
||||||
|
$html = $this->renderStart($form->createView(), array(
|
||||||
|
'method' => 'post',
|
||||||
|
'action' => 'http://foo.com/directory',
|
||||||
|
));
|
||||||
|
|
||||||
|
$this->assertSame('<form name="form" method="post" action="http://foo.com/directory" class="form-horizontal">', $html);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testStartTagForMultipartForm()
|
||||||
|
{
|
||||||
|
$form = $this->factory->createBuilder('Symfony\Component\Form\Extension\Core\Type\FormType', null, array(
|
||||||
|
'method' => 'get',
|
||||||
|
'action' => 'http://example.com/directory',
|
||||||
|
))
|
||||||
|
->add('file', 'Symfony\Component\Form\Extension\Core\Type\FileType')
|
||||||
|
->getForm();
|
||||||
|
|
||||||
|
$html = $this->renderStart($form->createView());
|
||||||
|
|
||||||
|
$this->assertSame('<form name="form" method="get" action="http://example.com/directory" class="form-horizontal" enctype="multipart/form-data">', $html);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testStartTagWithExtraAttributes()
|
||||||
|
{
|
||||||
|
$form = $this->factory->create('Symfony\Component\Form\Extension\Core\Type\FormType', null, array(
|
||||||
|
'method' => 'get',
|
||||||
|
'action' => 'http://example.com/directory',
|
||||||
|
));
|
||||||
|
|
||||||
|
$html = $this->renderStart($form->createView(), array(
|
||||||
|
'attr' => array('class' => 'foobar'),
|
||||||
|
));
|
||||||
|
|
||||||
|
$this->assertSame('<form name="form" method="get" action="http://example.com/directory" class="foobar form-horizontal">', $html);
|
||||||
|
}
|
||||||
|
}
|
@ -110,7 +110,10 @@ class Store implements StoreInterface
|
|||||||
|
|
||||||
public function isLocked(Request $request)
|
public function isLocked(Request $request)
|
||||||
{
|
{
|
||||||
return is_file($this->getPath($this->getCacheKey($request).'.lck'));
|
$path = $this->getPath($this->getCacheKey($request).'.lck');
|
||||||
|
clearstatcache(true, $path);
|
||||||
|
|
||||||
|
return is_file($path);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -224,7 +224,7 @@ class ControllerResolverTest extends \PHPUnit_Framework_TestCase
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
protected function controllerMethod3($foo, $bar = null, $foobar)
|
protected function controllerMethod3($foo, $bar, $foobar)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -26,6 +26,8 @@ use Symfony\Component\Serializer\NameConverter\NameConverterInterface;
|
|||||||
*/
|
*/
|
||||||
class ObjectNormalizer extends AbstractNormalizer
|
class ObjectNormalizer extends AbstractNormalizer
|
||||||
{
|
{
|
||||||
|
private static $attributesCache = array();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @var PropertyAccessorInterface
|
* @var PropertyAccessorInterface
|
||||||
*/
|
*/
|
||||||
@ -58,42 +60,7 @@ class ObjectNormalizer extends AbstractNormalizer
|
|||||||
}
|
}
|
||||||
|
|
||||||
$data = array();
|
$data = array();
|
||||||
$attributes = $this->getAllowedAttributes($object, $context, true);
|
$attributes = $this->getAttributes($object, $context);
|
||||||
|
|
||||||
// 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->isStatic() &&
|
|
||||||
!$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) {
|
|
||||||
if (!$reflProperty->isStatic()) {
|
|
||||||
$attributes[$reflProperty->getName()] = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
$attributes = array_keys($attributes);
|
|
||||||
}
|
|
||||||
|
|
||||||
foreach ($attributes as $attribute) {
|
foreach ($attributes as $attribute) {
|
||||||
if (in_array($attribute, $this->ignoredAttributes)) {
|
if (in_array($attribute, $this->ignoredAttributes)) {
|
||||||
@ -162,4 +129,64 @@ class ObjectNormalizer extends AbstractNormalizer
|
|||||||
|
|
||||||
return $object;
|
return $object;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets and caches attributes for this class and context.
|
||||||
|
*
|
||||||
|
* @param object $object
|
||||||
|
* @param array $context
|
||||||
|
*
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
private function getAttributes($object, array $context)
|
||||||
|
{
|
||||||
|
$key = sprintf('%s-%s', get_class($object), serialize($context));
|
||||||
|
|
||||||
|
if (isset(self::$attributesCache[$key])) {
|
||||||
|
return self::$attributesCache[$key];
|
||||||
|
}
|
||||||
|
|
||||||
|
$allowedAttributes = $this->getAllowedAttributes($object, $context, true);
|
||||||
|
|
||||||
|
if (false !== $allowedAttributes) {
|
||||||
|
return self::$attributesCache[$key] = $allowedAttributes;
|
||||||
|
}
|
||||||
|
|
||||||
|
// If not using groups, detect manually
|
||||||
|
$attributes = array();
|
||||||
|
|
||||||
|
// methods
|
||||||
|
$reflClass = new \ReflectionClass($object);
|
||||||
|
foreach ($reflClass->getMethods(\ReflectionMethod::IS_PUBLIC) as $reflMethod) {
|
||||||
|
if (
|
||||||
|
$reflMethod->getNumberOfRequiredParameters() !== 0 ||
|
||||||
|
$reflMethod->isStatic() ||
|
||||||
|
$reflMethod->isConstructor() ||
|
||||||
|
$reflMethod->isDestructor()
|
||||||
|
) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
$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) {
|
||||||
|
if ($reflProperty->isStatic()) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
$attributes[$reflProperty->getName()] = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return self::$attributesCache[$key] = array_keys($attributes);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -29,7 +29,7 @@ use Symfony\Component\Serializer\Tests\Fixtures\GroupDummy;
|
|||||||
class ObjectNormalizerTest extends \PHPUnit_Framework_TestCase
|
class ObjectNormalizerTest extends \PHPUnit_Framework_TestCase
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
* @var ObjectNormalizerTest
|
* @var ObjectNormalizer
|
||||||
*/
|
*/
|
||||||
private $normalizer;
|
private $normalizer;
|
||||||
/**
|
/**
|
||||||
@ -211,6 +211,18 @@ class ObjectNormalizerTest extends \PHPUnit_Framework_TestCase
|
|||||||
$this->assertEquals($obj, $normalized);
|
$this->assertEquals($obj, $normalized);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function testNormalizeNoPropertyInGroup()
|
||||||
|
{
|
||||||
|
$classMetadataFactory = new ClassMetadataFactory(new AnnotationLoader(new AnnotationReader()));
|
||||||
|
$this->normalizer = new ObjectNormalizer($classMetadataFactory);
|
||||||
|
$this->normalizer->setSerializer($this->serializer);
|
||||||
|
|
||||||
|
$obj = new GroupDummy();
|
||||||
|
$obj->setFoo('foo');
|
||||||
|
|
||||||
|
$this->assertEquals(array(), $this->normalizer->normalize($obj, null, array('groups' => array('notExist'))));
|
||||||
|
}
|
||||||
|
|
||||||
public function testGroupsNormalizeWithNameConverter()
|
public function testGroupsNormalizeWithNameConverter()
|
||||||
{
|
{
|
||||||
$classMetadataFactory = new ClassMetadataFactory(new AnnotationLoader(new AnnotationReader()));
|
$classMetadataFactory = new ClassMetadataFactory(new AnnotationLoader(new AnnotationReader()));
|
||||||
|
@ -12,8 +12,20 @@ CHANGELOG
|
|||||||
|
|
||||||
* Deprecated usage of a colon in an unquoted mapping value
|
* Deprecated usage of a colon in an unquoted mapping value
|
||||||
* Deprecated usage of @, \`, | and > at the beginning of an unquoted string
|
* Deprecated usage of @, \`, | and > at the beginning of an unquoted string
|
||||||
* Deprecated non-escaped \ in double-quoted strings when parsing Yaml
|
* When surrounding strings with double-quotes, you must now escape `\` characters. Not
|
||||||
("Foo\Var" is not valid whereas "Foo\\Var" is)
|
escaping those characters (when surrounded by double-quotes) is deprecated.
|
||||||
|
|
||||||
|
Before:
|
||||||
|
|
||||||
|
```yml
|
||||||
|
class: "Foo\Var"
|
||||||
|
```
|
||||||
|
|
||||||
|
After:
|
||||||
|
|
||||||
|
```yml
|
||||||
|
class: "Foo\\Var"
|
||||||
|
```
|
||||||
|
|
||||||
2.1.0
|
2.1.0
|
||||||
-----
|
-----
|
||||||
|
Reference in New Issue
Block a user