Merge branch '2.3'

* 2.3:
  moved some fixed dep versions from 2.2.* to ~2.2 (refs #8613)
  [HttpKernel] added a missing dep for dev
  [Form] fixed wrong call to setTimeZone() (closes #8644)
  Fix issue with \DateTimeZone::UTC / 'UTC' for PHP 5.4
  [Form] Fixed patched forms to be valid even if children are not submitted
  Revert "[Form] Fix of "PATCH'ed forms are never valid""
  [Form] Fixed: If a form is not present in a request, it is not automatically submitted
  Fixes link indices
  [Form] Removed the "disabled" attribute from the placeholder option in select fields due to problems with the BlackBerry 10 browser
  Revert "[Form] Remove "value" attribute on empty_value option"
  [routing] added ability for apache matcher to handle array values
  removed dead code and fixed CS
  [Validator] fixed StaticMethodLoader trying to invoke methods of abstract classes (closes #8589)
This commit is contained in:
Fabien Potencier 2013-08-02 22:53:46 +02:00
commit 4ee3d7f11a
32 changed files with 211 additions and 217 deletions

View File

@ -145,8 +145,6 @@ class DoctrineOrmTypeGuesser implements FormTypeGuesserInterface
{
$ret = $this->getMetadata($class);
if ($ret && $ret[0]->hasField($property) && !$ret[0]->hasAssociation($property)) {
$mapping = $ret[0]->getFieldMapping($property);
if (in_array($ret[0]->getTypeOfField($property), array('decimal', 'float'))) {
return new ValueGuess(null, Guess::MEDIUM_CONFIDENCE);
}

View File

@ -12,7 +12,6 @@
namespace Symfony\Bridge\Monolog\Processor;
use Monolog\Processor\WebProcessor as BaseWebProcessor;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpKernel\Event\GetResponseEvent;
use Symfony\Component\HttpKernel\HttpKernelInterface;

View File

@ -69,7 +69,7 @@
{% spaceless %}
<select {{ block('widget_attributes') }}{% if multiple %} multiple="multiple"{% endif %}>
{% if empty_value is not none %}
<option {% if required %} disabled="disabled"{% if value is empty %} selected="selected"{% endif %}{% else %} value=""{% endif %}>{{ empty_value|trans({}, translation_domain) }}</option>
<option value=""{% if required and value is empty %} selected="selected"{% endif %}>{{ empty_value|trans({}, translation_domain) }}</option>
{% endif %}
{% if preferred_choices|length > 0 %}
{% set options = preferred_choices %}

View File

@ -20,7 +20,7 @@
"twig/twig": "~1.11"
},
"require-dev": {
"symfony/form": "2.2.*",
"symfony/form": "~2.2",
"symfony/http-kernel": "~2.2",
"symfony/routing": "~2.2",
"symfony/templating": "~2.1",

View File

@ -2,7 +2,7 @@
<?php echo $view['form']->block($form, 'widget_attributes') ?>
<?php if ($multiple): ?> multiple="multiple"<?php endif ?>
>
<?php if (null !== $empty_value): ?><option <?php if ($required):?> disabled="disabled"<?php if (empty($value) && "0" !== $value): ?> selected="selected"<?php endif ?><?php else: ?> value=""<?php endif?>><?php echo $view->escape($view['translator']->trans($empty_value, array(), $translation_domain)) ?></option><?php endif; ?>
<?php if (null !== $empty_value): ?><option value=""<?php if ($required and empty($value) && "0" !== $value): ?> selected="selected"<?php endif?>><?php echo $view->escape($view['translator']->trans($empty_value, array(), $translation_domain)) ?></option><?php endif; ?>
<?php if (count($preferred_choices) > 0): ?>
<?php echo $view['form']->block($form, 'choice_widget_options', array('choices' => $preferred_choices)) ?>
<?php if (count($choices) > 0 && null !== $separator): ?>

View File

@ -11,7 +11,6 @@
namespace Symfony\Bundle\FrameworkBundle\Tests\Functional\Bundle\TestBundle\Controller;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\DependencyInjection\ContainerAware;

View File

@ -240,7 +240,6 @@ class SecurityExtension extends Extension
private function createFirewall(ContainerBuilder $container, $id, $firewall, &$authenticationProviders, $providerIds)
{
// Matcher
$i = 0;
$matcher = null;
if (isset($firewall['request_matcher'])) {
$matcher = new Reference($firewall['request_matcher']);

View File

@ -78,9 +78,9 @@ class PropertyPathMapper implements DataMapperInterface
$propertyPath = $form->getPropertyPath();
$config = $form->getConfig();
// Write-back is disabled if the form is not synchronized (transformation failed)
// and if the form is disabled (modification not allowed)
if (null !== $propertyPath && $config->getMapped() && $form->isSynchronized() && !$form->isDisabled()) {
// Write-back is disabled if the form is not synchronized (transformation failed),
// if the form was not submitted and if the form is disabled (modification not allowed)
if (null !== $propertyPath && $config->getMapped() && $form->isSubmitted() && $form->isSynchronized() && !$form->isDisabled()) {
// If the data is identical to the value in $data, we are
// dealing with a reference
if (!is_object($data) || !$config->getByReference() || $form->getData() !== $this->propertyAccessor->getValue($data, $propertyPath)) {

View File

@ -248,9 +248,9 @@ class DateType extends AbstractType
$timezone = $formatter->getTimezoneId();
if (version_compare(\PHP_VERSION, '5.5.0-dev', '>=')) {
$formatter->setTimeZone(\DateTimeZone::UTC);
$formatter->setTimeZone('UTC');
} else {
$formatter->setTimeZoneId(\DateTimeZone::UTC);
$formatter->setTimeZoneId('UTC');
}
if (preg_match($regex, $pattern, $matches)) {

View File

@ -56,10 +56,13 @@ class HttpFoundationRequestHandler implements RequestHandlerInterface
if ('' === $name) {
$params = $request->request->all();
$files = $request->files->all();
} else {
} elseif ($request->request->has($name) || $request->files->has($name)) {
$default = $form->getConfig()->getCompound() ? array() : null;
$params = $request->request->get($name, $default);
$files = $request->files->get($name, $default);
} else {
// Don't submit the form if it is not present in the request
return;
}
if (is_array($params) && is_array($files)) {

View File

@ -500,14 +500,6 @@ class Form implements \IteratorAggregate, FormInterface
return $this;
}
// In order to process patch requests we need to "submit" null values
// Later this value will be mapped via DataMapper and InheritDataAwareIterator
if ($submittedData === null && !$clearMissing) {
$this->submitted = true;
return $this;
}
// The data must be initialized if it was not initialized yet.
// This is necessary to guarantee that the *_SET_DATA listeners
// are always invoked before submit() takes place.
@ -545,12 +537,10 @@ class Form implements \IteratorAggregate, FormInterface
}
foreach ($this->children as $name => $child) {
$fieldValue = null;
if (array_key_exists($name, $submittedData)) {
$fieldValue = $submittedData[$name];
if (array_key_exists($name, $submittedData) || $clearMissing) {
$child->submit(isset($submittedData[$name]) ? $submittedData[$name] : null, $clearMissing);
unset($submittedData[$name]);
}
$child->submit($fieldValue, $clearMissing);
}
$this->extraData = $submittedData;
@ -720,11 +710,13 @@ class Form implements \IteratorAggregate, FormInterface
return false;
}
if (!$this->isDisabled()) {
foreach ($this->children as $child) {
if (!$child->isValid()) {
return false;
}
if ($this->isDisabled()) {
return true;
}
foreach ($this->children as $child) {
if ($child->isSubmitted() && !$child->isValid()) {
return false;
}
}

View File

@ -72,10 +72,13 @@ class NativeRequestHandler implements RequestHandlerInterface
if ('' === $name) {
$params = $_POST;
$files = $fixedFiles;
} else {
} elseif (array_key_exists($name, $_POST) || array_key_exists($name, $fixedFiles)) {
$default = $form->getConfig()->getCompound() ? array() : null;
$params = isset($_POST[$name]) ? $_POST[$name] : $default;
$files = isset($fixedFiles[$name]) ? $fixedFiles[$name] : $default;
$params = array_key_exists($name, $_POST) ? $_POST[$name] : $default;
$files = array_key_exists($name, $fixedFiles) ? $fixedFiles[$name] : $default;
} else {
// Don't submit the form if it is not present in the request
return;
}
if (is_array($params) && is_array($files)) {

View File

@ -89,38 +89,6 @@ abstract class AbstractFormTest extends \PHPUnit_Framework_TestCase
return $form;
}
/**
* @param string $name
*
* @return \PHPUnit_Framework_MockObject_MockObject
*/
protected function getValidForm($name)
{
$form = $this->getMockForm($name);
$form->expects($this->any())
->method('isValid')
->will($this->returnValue(true));
return $form;
}
/**
* @param string $name
*
* @return \PHPUnit_Framework_MockObject_MockObject
*/
protected function getInvalidForm($name)
{
$form = $this->getMockForm($name);
$form->expects($this->any())
->method('isValid')
->will($this->returnValue(false));
return $form;
}
/**
* @return \PHPUnit_Framework_MockObject_MockObject
*/

View File

@ -546,12 +546,15 @@ abstract class AbstractLayoutTest extends \Symfony\Component\Form\Test\FormInteg
'empty_value' => 'Test&Me'
));
// The "disabled" attribute was removed again due to a bug in the
// BlackBerry 10 browser.
// See https://github.com/symfony/symfony/pull/7678
$this->assertWidgetMatchesXpath($form->createView(), array(),
'/select
[@name="name"]
[@required="required"]
[
./option[not(@value)][not(@selected)][@disabled][.="[trans]Test&Me[/trans]"]
./option[@value=""][not(@selected)][not(@disabled)][.="[trans]Test&Me[/trans]"]
/following-sibling::option[@value="&a"][@selected="selected"][.="[trans]Choice&A[/trans]"]
/following-sibling::option[@value="&b"][not(@selected)][.="[trans]Choice&B[/trans]"]
]
@ -569,12 +572,15 @@ abstract class AbstractLayoutTest extends \Symfony\Component\Form\Test\FormInteg
'expanded' => false,
));
// The "disabled" attribute was removed again due to a bug in the
// BlackBerry 10 browser.
// See https://github.com/symfony/symfony/pull/7678
$this->assertWidgetMatchesXpath($form->createView(), array('empty_value' => ''),
'/select
[@name="name"]
[@required="required"]
[
./option[not(@value)][not(@selected)][@disabled][.="[trans][/trans]"]
./option[@value=""][not(@selected)][not(@disabled)][.="[trans][/trans]"]
/following-sibling::option[@value="&a"][@selected="selected"][.="[trans]Choice&A[/trans]"]
/following-sibling::option[@value="&b"][not(@selected)][.="[trans]Choice&B[/trans]"]
]

View File

@ -86,7 +86,7 @@ abstract class AbstractRequestHandlerTest extends \PHPUnit_Framework_TestCase
/**
* @dataProvider methodExceptGetProvider
*/
public function testSubmitSimpleFormWithNullIfNameNotInRequestAndNotGetRequest($method)
public function testDoNoSubmitSimpleFormIfNameNotInRequestAndNotGetRequest($method)
{
$form = $this->getMockForm('param1', $method, false);
@ -94,9 +94,8 @@ abstract class AbstractRequestHandlerTest extends \PHPUnit_Framework_TestCase
'paramx' => array(),
));
$form->expects($this->once())
->method('submit')
->with($this->identicalTo(null), 'PATCH' !== $method);
$form->expects($this->never())
->method('submit');
$this->requestHandler->handleRequest($form, $this->request);
}
@ -104,7 +103,7 @@ abstract class AbstractRequestHandlerTest extends \PHPUnit_Framework_TestCase
/**
* @dataProvider methodExceptGetProvider
*/
public function testSubmitCompoundFormWithArrayIfNameNotInRequestAndNotGetRequest($method)
public function testDoNotSubmitCompoundFormIfNameNotInRequestAndNotGetRequest($method)
{
$form = $this->getMockForm('param1', $method, true);
@ -112,9 +111,8 @@ abstract class AbstractRequestHandlerTest extends \PHPUnit_Framework_TestCase
'paramx' => array(),
));
$form->expects($this->once())
->method('submit')
->with($this->identicalTo(array()), 'PATCH' !== $method);
$form->expects($this->never())
->method('submit');
$this->requestHandler->handleRequest($form, $this->request);
}

View File

@ -22,8 +22,8 @@ class CompoundFormTest extends AbstractFormTest
{
public function testValidIfAllChildrenAreValid()
{
$this->form->add($this->getValidForm('firstName'));
$this->form->add($this->getValidForm('lastName'));
$this->form->add($this->getBuilder('firstName')->getForm());
$this->form->add($this->getBuilder('lastName')->getForm());
$this->form->submit(array(
'firstName' => 'Bernhard',
@ -35,17 +35,51 @@ class CompoundFormTest extends AbstractFormTest
public function testInvalidIfChildIsInvalid()
{
$this->form->add($this->getValidForm('firstName'));
$this->form->add($this->getInvalidForm('lastName'));
$this->form->add($this->getBuilder('firstName')->getForm());
$this->form->add($this->getBuilder('lastName')->getForm());
$this->form->submit(array(
'firstName' => 'Bernhard',
'lastName' => 'Schussek',
));
$this->form->get('lastName')->addError(new FormError('Invalid'));
$this->assertFalse($this->form->isValid());
}
public function testValidIfChildIsNotSubmitted()
{
$this->form->add($this->getBuilder('firstName')->getForm());
$this->form->add($this->getBuilder('lastName')->getForm());
$this->form->submit(array(
'firstName' => 'Bernhard',
));
// "lastName" is not "valid" because it was not submitted. This happens
// for example in PATCH requests. The parent form should still be
// considered valid.
$this->assertTrue($this->form->isValid());
}
public function testDisabledFormsValidEvenIfChildrenInvalid()
{
$form = $this->getBuilder('person')
->setDisabled(true)
->setCompound(true)
->setDataMapper($this->getDataMapper())
->add($this->getBuilder('name'))
->getForm();
$form->submit(array('name' => 'Jacques Doe'));
$form->get('name')->addError(new FormError('Invalid'));
$this->assertTrue($form->isValid());
}
public function testSubmitForwardsNullIfValueIsMissing()
{
$child = $this->getMockForm('firstName');
@ -59,17 +93,14 @@ class CompoundFormTest extends AbstractFormTest
$this->form->submit(array());
}
public function testSubmitDoesNotSaveNullIfNotClearMissing()
public function testSubmitDoesNotForwardNullIfNotClearMissing()
{
$child = $this->getMockForm('firstName');
$this->form->add($child);
$child->expects($this->once())
->method('submit');
$child->expects($this->never())
->method('setData');
->method('submit');
$this->form->submit(array(), false);
}
@ -124,37 +155,6 @@ class CompoundFormTest extends AbstractFormTest
$this->assertFalse($this->form->isEmpty());
}
public function testValidIfSubmittedAndDisabledWithChildren()
{
$this->factory->expects($this->once())
->method('createNamedBuilder')
->with('name', 'text', null, array())
->will($this->returnValue($this->getBuilder('name')));
$form = $this->getBuilder('person')
->setDisabled(true)
->setCompound(true)
->setDataMapper($this->getDataMapper())
->add('name', 'text')
->getForm();
$form->submit(array('name' => 'Jacques Doe'));
$this->assertTrue($form->isValid());
}
public function testNotValidIfChildNotValid()
{
$child = $this->getMockForm();
$child->expects($this->once())
->method('isValid')
->will($this->returnValue(false));
$this->form->add($child);
$this->form->submit(array());
$this->assertFalse($this->form->isValid());
}
public function testAdd()
{
$child = $this->getBuilder('foo')->getForm();
@ -564,74 +564,6 @@ class CompoundFormTest extends AbstractFormTest
unlink($path);
}
public function testSubmitPatchRequest()
{
if (!class_exists('Symfony\Component\HttpFoundation\Request')) {
$this->markTestSkipped('The "HttpFoundation" component is not available');
}
$object = new \stdClass();
$object->name = 'Bernhard';
$object->name2 = 'Me';
//$values = array();
$values = array(
'author' => array(
'name2' => 'Artem',
),
);
$request = new Request(array(), $values, array(), array(), array(), array(
'REQUEST_METHOD' => 'PATCH',
));
$mapper = $this->getDataMapper();
$mapper->expects($this->any())
->method('mapDataToForms')
->will($this->returnCallback(function($data, $forms){
foreach ($forms as $form) {
$propertyPath = $form->getPropertyPath();
if (null !== $propertyPath) {
$form->setData($data->{$propertyPath});
}
}
}));
$mapper->expects($this->any())
->method('mapFormsToData')
->will($this->returnCallback(function($forms, &$data){
foreach ($forms as $form) {
$propertyPath = $form->getPropertyPath();
if (null !== $propertyPath) {
if (!is_object($data) || $form->getData() !== $data->{$propertyPath}) {
$data->{$propertyPath} = $form->getData();
}
}
}
}));
/** @var Form $form */
$form = $this->getBuilder('author', null, 'stdClass')
->setMethod('PATCH')
->setData($object)
->setCompound(true)
->setDataMapper($mapper)
->setRequestHandler(new HttpFoundationRequestHandler())
->getForm();
$form->add($this->getBuilder('name')->getForm());
$form->add($this->getBuilder('name2')->getForm());
$form->handleRequest($request);
$this->assertTrue($form->isValid());
$this->assertEquals('Bernhard', $form['name']->getData());
$this->assertEquals('Artem', $form['name2']->getData());
}
/**
* @dataProvider requestMethodProvider
*/

View File

@ -64,17 +64,21 @@ class PropertyPathMapperTest extends \PHPUnit_Framework_TestCase
* @param Boolean $synchronized
* @return \PHPUnit_Framework_MockObject_MockObject
*/
private function getForm(FormConfigInterface $config, $synchronized = true)
private function getForm(FormConfigInterface $config, $synchronized = true, $submitted = true)
{
$form = $this->getMockBuilder('Symfony\Component\Form\Form')
->setConstructorArgs(array($config))
->setMethods(array('isSynchronized'))
->setMethods(array('isSynchronized', 'isSubmitted'))
->getMock();
$form->expects($this->any())
->method('isSynchronized')
->will($this->returnValue($synchronized));
$form->expects($this->any())
->method('isSubmitted')
->will($this->returnValue($submitted));
return $form;
}
@ -263,6 +267,24 @@ class PropertyPathMapperTest extends \PHPUnit_Framework_TestCase
$this->mapper->mapFormsToData(array($form), $car);
}
public function testMapFormsToDataIgnoresUnsubmittedForms()
{
$car = new \stdClass();
$engine = new \stdClass();
$propertyPath = $this->getPropertyPath('engine');
$this->propertyAccessor->expects($this->never())
->method('setValue');
$config = new FormConfigBuilder('name', '\stdClass', $this->dispatcher);
$config->setByReference(true);
$config->setPropertyPath($propertyPath);
$config->setData($engine);
$form = $this->getForm($config, true, false);
$this->mapper->mapFormsToData(array($form), $car);
}
public function testMapFormsToDataIgnoresEmptyData()
{
$car = new \stdClass();

View File

@ -29,11 +29,6 @@ class MockFileSessionStorage extends MockArraySessionStorage
*/
private $savePath;
/**
* @var array
*/
private $sessionData;
/**
* Constructor.
*

View File

@ -12,7 +12,6 @@
namespace Symfony\Component\HttpKernel\DependencyInjection;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpKernel\HttpKernelInterface;
use Symfony\Component\HttpKernel\HttpKernel;
use Symfony\Component\HttpKernel\Controller\ControllerResolverInterface;

View File

@ -11,7 +11,6 @@
namespace Symfony\Component\HttpKernel\EventListener;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpKernel\HttpKernelInterface;
use Symfony\Component\HttpKernel\Event\FilterResponseEvent;
use Symfony\Component\HttpKernel\KernelEvents;

View File

@ -11,7 +11,6 @@
namespace Symfony\Component\HttpKernel\Fragment;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpFoundation\StreamedResponse;
use Symfony\Component\HttpKernel\Controller\ControllerReference;

View File

@ -23,15 +23,16 @@
"psr/log": "~1.0"
},
"require-dev": {
"symfony/browser-kit": "2.2.*",
"symfony/browser-kit": "~2.2",
"symfony/class-loader": "~2.1",
"symfony/config": "~2.0",
"symfony/console": "2.2.*",
"symfony/console": "~2.2",
"symfony/dependency-injection": "~2.0",
"symfony/finder": "~2.0",
"symfony/process": "~2.0",
"symfony/routing": "~2.2",
"symfony/stopwatch": "~2.2"
"symfony/templating": "~2.2"
},
"suggest": {
"symfony/browser-kit": "",

View File

@ -5,12 +5,12 @@ A PHP replacement layer for the C intl extension that includes additional data
from the ICU library.
The replacement layer is limited to the locale "en". If you want to use other
locales, you should [install the intl extension] [1] instead.
locales, you should [install the intl extension] [0] instead.
Documentation
-------------
The documentation for the component can be found [online] [2].
The documentation for the component can be found [online] [1].
Resources
---------

View File

@ -77,7 +77,7 @@ class StringUtil
// moves (move)
array('sevom', 5, true, true, 'move'),
// hooves (hoof), dwarves (dwarf), elves (elf), leaves (leaf)
array('sev', 3, true, true, 'f'),

View File

@ -39,7 +39,7 @@ class ApacheUrlMatcher extends UrlMatcher
$allow = array();
$route = null;
foreach ($_SERVER as $key => $value) {
foreach ($this->denormalizeValues($_SERVER) as $key => $value) {
$name = $key;
// skip non-routing variables
@ -91,4 +91,28 @@ class ApacheUrlMatcher extends UrlMatcher
return parent::match($pathinfo);
}
}
/**
* Denormalizes an array of values.
*
* @param string[] $values
*
* @return array
*/
private function denormalizeValues(array $values)
{
$normalizedValues = array();
foreach ($values as $key => $value) {
if (preg_match('~^(.*)\[(\d+)\]$~', $key, $matches)) {
if (!isset($normalizedValues[$matches[1]])) {
$normalizedValues[$matches[1]] = array();
}
$normalizedValues[$matches[1]][(int) $matches[2]] = $value;
} else {
$normalizedValues[$key] = $value;
}
}
return $normalizedValues;
}
}

View File

@ -132,7 +132,7 @@ class ApacheMatcherDumper extends MatcherDumper
foreach ($compiledRoute->getPathVariables() as $i => $variable) {
$variables[] = 'E=_ROUTING_param_'.$variable.':%'.($i + 1);
}
foreach ($route->getDefaults() as $key => $value) {
foreach ($this->normalizeValues($route->getDefaults()) as $key => $value) {
$variables[] = 'E=_ROUTING_default_'.$key.':'.strtr($value, array(
':' => '\\:',
'=' => '\\=',
@ -151,7 +151,7 @@ class ApacheMatcherDumper extends MatcherDumper
$allow[] = 'E=_ROUTING_allow_'.$method.':1';
}
if ($hostRegex = $compiledRoute->getHostRegex()) {
if ($compiledRoute->getHostRegex()) {
$rule[] = sprintf("RewriteCond %%{ENV:__ROUTING_host_%s} =1", $hostRegexUnique);
}
@ -162,8 +162,7 @@ class ApacheMatcherDumper extends MatcherDumper
// redirect with trailing slash appended
if ($hasTrailingSlash) {
if ($hostRegex = $compiledRoute->getHostRegex()) {
if ($compiledRoute->getHostRegex()) {
$rule[] = sprintf("RewriteCond %%{ENV:__ROUTING_host_%s} =1", $hostRegexUnique);
}
@ -173,7 +172,7 @@ class ApacheMatcherDumper extends MatcherDumper
// the main rule
if ($hostRegex = $compiledRoute->getHostRegex()) {
if ($compiledRoute->getHostRegex()) {
$rule[] = sprintf("RewriteCond %%{ENV:__ROUTING_host_%s} =1", $hostRegexUnique);
}
@ -249,4 +248,27 @@ class ApacheMatcherDumper extends MatcherDumper
return $output;
}
/**
* Normalizes an array of values.
*
* @param array $values
*
* @return string[]
*/
private function normalizeValues(array $values)
{
$normalizedValues = array();
foreach ($values as $key => $value) {
if (is_array($value)) {
foreach ($value as $index => $bit) {
$normalizedValues[sprintf('%s[%s]', $key, $index)] = $bit;
}
} else {
$normalizedValues[$key] = (string) $value;
}
}
return $normalizedValues;
}
}

View File

@ -90,6 +90,21 @@ class ApacheUrlMatcherTest extends \PHPUnit_Framework_TestCase
'_route' => 'hello',
),
),
array(
'Redirect with many ignored attributes',
'/legacy/{cat1}/{cat2}/{id}.html',
array(
'_ROUTING_route' => 'product_view',
'_ROUTING_param__controller' => 'FrameworkBundle:Redirect:redirect',
'_ROUTING_default_ignoreAttributes[0]' => 'attr_a',
'_ROUTING_default_ignoreAttributes[1]' => 'attr_b',
),
array(
'ignoreAttributes' => array('attr_a', 'attr_b'),
'_controller' => 'FrameworkBundle:Redirect:redirect',
'_route' => 'product_view',
)
),
array(
'REDIRECT_ envs',
'/hello/world',
@ -131,7 +146,7 @@ class ApacheUrlMatcherTest extends \PHPUnit_Framework_TestCase
'name' => 'world',
'_route' => 'hello',
),
),
)
);
}
}

View File

@ -64,6 +64,7 @@ abstract class AbstractPreAuthenticatedListener implements ListenerInterface
list($user, $credentials) = $this->getPreAuthenticatedData($request);
} catch (BadCredentialsException $exception) {
$this->clearToken();
return;
}

View File

@ -100,12 +100,15 @@ class MoFileLoader extends ArrayLoader implements LoaderInterface
throw new InvalidResourceException("MO stream content has an invalid format.");
}
$formatRevision = $this->readLong($stream, $isBigEndian);
// formatRevision
$this->readLong($stream, $isBigEndian);
$count = $this->readLong($stream, $isBigEndian);
$offsetId = $this->readLong($stream, $isBigEndian);
$offsetTranslated = $this->readLong($stream, $isBigEndian);
$sizeHashes = $this->readLong($stream, $isBigEndian);
$offsetHashes = $this->readLong($stream, $isBigEndian);
// sizeHashes
$this->readLong($stream, $isBigEndian);
// offsetHashes
$this->readLong($stream, $isBigEndian);
$messages = array();

View File

@ -31,7 +31,7 @@ class StaticMethodLoader implements LoaderInterface
/** @var \ReflectionClass $reflClass */
$reflClass = $metadata->getReflectionClass();
if (!$reflClass->isInterface() && $reflClass->hasMethod($this->methodName)) {
if (!$reflClass->isInterface() && !$reflClass->isAbstract() && $reflClass->hasMethod($this->methodName)) {
$reflMethod = $reflClass->getMethod($this->methodName);
if (!$reflMethod->isStatic()) {

View File

@ -276,7 +276,7 @@ class ExecutionContextTest extends \PHPUnit_Framework_TestCase
$this->assertEquals('bam.baz', $this->context->getPropertyPath('bam.baz'));
}
public function testGetPropertyPathWithNestedCollectionsMixed()
{
$constraints = new Collection(array(
@ -286,13 +286,13 @@ class ExecutionContextTest extends \PHPUnit_Framework_TestCase
)),
'name' => new ConstraintA()
));
$visitor = new ValidationVisitor('Root', $this->metadataFactory, new ConstraintValidatorFactory(), $this->translator);
$context = new ExecutionContext($visitor, $this->translator, self::TRANS_DOMAIN);
$context->validateValue(array('foo' => array('foo' => 'VALID')), $constraints);
$violations = $context->getViolations();
$this->assertEquals('[name]', $violations[1]->getPropertyPath());
$this->assertEquals('[name]', $violations[1]->getPropertyPath());
}
}

View File

@ -48,12 +48,12 @@ class StaticMethodLoaderTest extends \PHPUnit_Framework_TestCase
$loader = new StaticMethodLoader('loadMetadata');
$metadata = new ClassMetadata(__NAMESPACE__.'\StaticLoaderDocument');
$loader->loadClassMetadata($metadata);
$this->assertSame(0, count($metadata->getConstraints()));
$this->assertCount(0, $metadata->getConstraints());
$loader = new StaticMethodLoader('loadMetadata');
$metadata = new ClassMetadata(__NAMESPACE__.'\BaseStaticLoaderDocument');
$loader->loadClassMetadata($metadata);
$this->assertSame(1, count($metadata->getConstraints()));
$this->assertCount(1, $metadata->getConstraints());
}
public function testLoadClassMetadataIgnoresInterfaces()
@ -63,7 +63,17 @@ class StaticMethodLoaderTest extends \PHPUnit_Framework_TestCase
$loader->loadClassMetadata($metadata);
$this->assertSame(0, count($metadata->getConstraints()));
$this->assertCount(0, $metadata->getConstraints());
}
public function testLoadClassMetadataIgnoresAbstractClasses()
{
$loader = new StaticMethodLoader('loadMetadata');
$metadata = new ClassMetadata(__NAMESPACE__.'\AbstractStaticLoader');
$loader->loadClassMetadata($metadata);
$this->assertCount(0, $metadata->getConstraints());
}
}
@ -72,6 +82,13 @@ interface StaticLoaderInterface
public static function loadMetadata(ClassMetadata $metadata);
}
abstract class AbstractStaticLoader
{
public static function loadMetadata(ClassMetadata $metadata)
{
}
}
class StaticLoaderEntity
{
public static $invokedWith = null;