Merge branch '2.2' into 2.3

* 2.2:
  [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] Removed the "disabled" attribute from the placeholder option in select fields due to problems with the BlackBerry 10 browser
  [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)

Conflicts:
	src/Symfony/Bundle/TwigBundle/TokenParser/RenderTokenParser.php
	src/Symfony/Component/Form/FormConfigBuilder.php
	src/Symfony/Component/HttpKernel/composer.json
	src/Symfony/Component/Validator/Tests/GraphWalkerTest.php
This commit is contained in:
Fabien Potencier 2013-08-02 22:53:38 +02:00
commit 64535bbcb2
22 changed files with 114 additions and 38 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 value=""{% if required %} disabled="disabled"{% if value is empty %} selected="selected"{% endif %}{% 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

@ -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 value=""<?php if ($required):?> disabled="disabled"<?php if (empty($value) && "0" !== $value): ?> selected="selected"<?php endif ?><?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

@ -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

@ -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[@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[@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

@ -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

@ -32,6 +32,7 @@
"symfony/process": "~2.0",
"symfony/routing": "~2.2",
"symfony/stopwatch": "~2.2"
"symfony/templating": "~2.2"
},
"suggest": {
"symfony/browser-kit": "",

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;