Skip to content

Commit 9f3072c

Browse files
committed
Merge branch '3.2'
* 3.2: fixed typo fixed composer.json [HttpKernel] Fix Bundle name regression always check for all fields to be mapped clarify exception when no args are configured [PropertyAccess] Handle interfaces in the invalid argument exception [DI] Fix defaults overriding empty strings in AutowirePass [Debug] Workaround "null" $context [Debug] Remove $context arg from handleError(), preparing for PHP 7.2 [FrameworkBundle] Dont wire "annotations.cached_reader" before removing passes [Routing] Fix BC break in AnnotationClassLoader defaults attributes handling Fix tests with ICU 57.1 Fix the condition checking the minimum ICU version
2 parents b9b6ebd + 09d5f4e commit 9f3072c

File tree

28 files changed

+315
-40
lines changed

28 files changed

+315
-40
lines changed

composer.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -93,7 +93,8 @@
9393
"symfony/phpunit-bridge": "~3.2",
9494
"symfony/polyfill-apcu": "~1.1",
9595
"symfony/security-acl": "~2.8|~3.0",
96-
"phpdocumentor/reflection-docblock": "^3.0"
96+
"phpdocumentor/reflection-docblock": "^3.0",
97+
"sensio/framework-extra-bundle": "^3.0.2"
9798
},
9899
"conflict": {
99100
"phpdocumentor/reflection-docblock": "<3.0",

src/Symfony/Bridge/Doctrine/Tests/Validator/Constraints/UniqueEntityValidatorTest.php

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -264,6 +264,23 @@ public function testValidateUniquenessWithIgnoreNull()
264264
->assertRaised();
265265
}
266266

267+
/**
268+
* @expectedException \Symfony\Component\Validator\Exception\ConstraintDefinitionException
269+
*/
270+
public function testAllConfiguredFieldsAreCheckedOfBeingMappedByDoctrineWithIgnoreNullEnabled()
271+
{
272+
$constraint = new UniqueEntity(array(
273+
'message' => 'myMessage',
274+
'fields' => array('name', 'name2'),
275+
'em' => self::EM_NAME,
276+
'ignoreNull' => true,
277+
));
278+
279+
$entity1 = new SingleIntIdEntity(1, null);
280+
281+
$this->validator->validate($entity1, $constraint);
282+
}
283+
267284
public function testValidateUniquenessWithValidCustomErrorPath()
268285
{
269286
$constraint = new UniqueEntity(array(

src/Symfony/Bridge/Doctrine/Validator/Constraints/UniqueEntityValidator.php

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -86,12 +86,14 @@ public function validate($entity, Constraint $constraint)
8686
throw new ConstraintDefinitionException(sprintf('The field "%s" is not mapped by Doctrine, so it cannot be validated for uniqueness.', $fieldName));
8787
}
8888

89-
$criteria[$fieldName] = $class->reflFields[$fieldName]->getValue($entity);
89+
$fieldValue = $class->reflFields[$fieldName]->getValue($entity);
9090

91-
if ($constraint->ignoreNull && null === $criteria[$fieldName]) {
92-
return;
91+
if ($constraint->ignoreNull && null === $fieldValue) {
92+
continue;
9393
}
9494

95+
$criteria[$fieldName] = $fieldValue;
96+
9597
if (null !== $criteria[$fieldName] && $class->hasAssociation($fieldName)) {
9698
/* Ensure the Proxy is initialized before using reflection to
9799
* read its identifiers. This is necessary because the wrapped
@@ -101,6 +103,12 @@ public function validate($entity, Constraint $constraint)
101103
}
102104
}
103105

106+
// skip validation if there are no criteria (this can happen when the
107+
// "ignoreNull" option is enabled and fields to be checked are null
108+
if (empty($criteria)) {
109+
return;
110+
}
111+
104112
if (null !== $constraint->entityClass) {
105113
/* Retrieve repository from given entity name.
106114
* We ensure the retrieved repository can handle the entity
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Symfony package.
5+
*
6+
* (c) Fabien Potencier <[email protected]>
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*/
11+
12+
namespace Symfony\Bundle\FrameworkBundle\DependencyInjection\Compiler;
13+
14+
use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
15+
use Symfony\Component\DependencyInjection\ContainerBuilder;
16+
17+
/**
18+
* @internal
19+
*/
20+
class AddAnnotationsCachedReaderPass implements CompilerPassInterface
21+
{
22+
/**
23+
* {@inheritdoc}
24+
*/
25+
public function process(ContainerBuilder $container)
26+
{
27+
// "annotations.cached_reader" is wired late so that any passes using
28+
// "annotation_reader" at build time don't get any cache
29+
if ($container->hasDefinition('annotations.cached_reader')) {
30+
$container->setAlias('annotation_reader', 'annotations.cached_reader');
31+
}
32+
}
33+
}

src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Compiler/CachePoolClearerPass.php

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,6 @@
1111

1212
namespace Symfony\Bundle\FrameworkBundle\DependencyInjection\Compiler;
1313

14-
use Symfony\Component\Cache\Adapter\AbstractAdapter;
1514
use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
1615
use Symfony\Component\DependencyInjection\ContainerBuilder;
1716
use Symfony\Component\DependencyInjection\Reference;

src/Symfony/Bundle/FrameworkBundle/DependencyInjection/FrameworkExtension.php

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1100,7 +1100,8 @@ private function registerAnnotationsConfiguration(array $config, ContainerBuilde
11001100
->replaceArgument(2, $config['debug'])
11011101
->addAutowiringType(Reader::class)
11021102
;
1103-
$container->setAlias('annotation_reader', 'annotations.cached_reader');
1103+
} else {
1104+
$container->removeDefinition('annotations.cached_reader');
11041105
}
11051106
}
11061107

src/Symfony/Bundle/FrameworkBundle/FrameworkBundle.php

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111

1212
namespace Symfony\Bundle\FrameworkBundle;
1313

14+
use Symfony\Bundle\FrameworkBundle\DependencyInjection\Compiler\AddAnnotationsCachedReaderPass;
1415
use Symfony\Bundle\FrameworkBundle\DependencyInjection\Compiler\AddConstraintValidatorsPass;
1516
use Symfony\Bundle\FrameworkBundle\DependencyInjection\Compiler\AddDebugLogProcessorPass;
1617
use Symfony\Bundle\FrameworkBundle\DependencyInjection\Compiler\AddValidatorInitializersPass;
@@ -80,6 +81,7 @@ public function build(ContainerBuilder $container)
8081
$container->addCompilerPass(new RegisterListenersPass(), PassConfig::TYPE_BEFORE_REMOVING);
8182
$container->addCompilerPass(new TemplatingPass());
8283
$container->addCompilerPass(new AddConstraintValidatorsPass(), PassConfig::TYPE_BEFORE_REMOVING);
84+
$container->addCompilerPass(new AddAnnotationsCachedReaderPass(), PassConfig::TYPE_BEFORE_REMOVING);
8385
$container->addCompilerPass(new AddValidatorInitializersPass());
8486
if (class_exists(AddConsoleCommandPass::class)) {
8587
$container->addCompilerPass(new AddConsoleCommandPass());

src/Symfony/Bundle/FrameworkBundle/Resources/config/cache.xml

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -22,13 +22,8 @@
2222
<tag name="cache.pool" />
2323
</service>
2424

25-
<service id="cache.annotations" class="Symfony\Component\Cache\Adapter\AdapterInterface" public="false">
26-
<factory class="Symfony\Component\Cache\Adapter\AbstractAdapter" method="createSystemCache" />
27-
<tag name="cache.pool" clearer="cache.default_clearer" />
28-
<argument /> <!-- namespace -->
29-
<argument>0</argument> <!-- default lifetime -->
30-
<argument /> <!-- version -->
31-
<argument>%kernel.cache_dir%/pools</argument>
25+
<service id="cache.annotations" parent="cache.system" public="false">
26+
<tag name="cache.pool" />
3227
</service>
3328

3429
<service id="cache.adapter.system" class="Symfony\Component\Cache\Adapter\AdapterInterface" abstract="true">

src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/FrameworkExtensionTest.php

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -471,7 +471,6 @@ public function testAnnotations()
471471
$container = $this->createContainerFromFile('full');
472472

473473
$this->assertEquals($container->getParameter('kernel.cache_dir').'/annotations', $container->getDefinition('annotations.filesystem_cache')->getArgument(0));
474-
$this->assertSame('annotations.cached_reader', (string) $container->getAlias('annotation_reader'));
475474
$this->assertSame('annotations.filesystem_cache', (string) $container->getDefinition('annotations.cached_reader')->getArgument(1));
476475
}
477476

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Symfony package.
5+
*
6+
* (c) Fabien Potencier <[email protected]>
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*/
11+
12+
namespace Symfony\Bundle\FrameworkBundle\Tests\Functional;
13+
14+
class AnnotatedControllerTest extends WebTestCase
15+
{
16+
/**
17+
* @dataProvider getRoutes
18+
*/
19+
public function testAnnotatedController($path, $expectedValue)
20+
{
21+
$client = $this->createClient(array('test_case' => 'AnnotatedController', 'root_config' => 'config.yml'));
22+
$client->request('GET', '/annotated'.$path);
23+
24+
$this->assertSame(200, $client->getResponse()->getStatusCode());
25+
$this->assertSame($expectedValue, $client->getResponse()->getContent());
26+
}
27+
28+
public function getRoutes()
29+
{
30+
return array(
31+
array('/null_request', 'Symfony\Component\HttpFoundation\Request'),
32+
array('/null_argument', ''),
33+
array('/null_argument_with_route_param', ''),
34+
array('/null_argument_with_route_param/value', 'value'),
35+
array('/argument_with_route_param_and_default', 'value'),
36+
array('/argument_with_route_param_and_default/custom', 'custom'),
37+
);
38+
}
39+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Symfony package.
5+
*
6+
* (c) Fabien Potencier <[email protected]>
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*/
11+
12+
namespace Symfony\Bundle\FrameworkBundle\Tests\Functional\Bundle\TestBundle\Controller;
13+
14+
use Symfony\Component\HttpFoundation\Request;
15+
use Symfony\Component\HttpFoundation\Response;
16+
use Symfony\Component\Routing\Annotation\Route;
17+
18+
class AnnotatedController
19+
{
20+
/**
21+
* @Route("/null_request", name="null_request")
22+
*/
23+
public function requestDefaultNullAction(Request $request = null)
24+
{
25+
return new Response($request ? get_class($request) : null);
26+
}
27+
28+
/**
29+
* @Route("/null_argument", name="null_argument")
30+
*/
31+
public function argumentDefaultNullWithoutRouteParamAction($value = null)
32+
{
33+
return new Response($value);
34+
}
35+
36+
/**
37+
* @Route("/null_argument_with_route_param/{value}", name="null_argument_with_route_param")
38+
*/
39+
public function argumentDefaultNullWithRouteParamAction($value = null)
40+
{
41+
return new Response($value);
42+
}
43+
44+
/**
45+
* @Route("/argument_with_route_param_and_default/{value}", defaults={"value": "value"}, name="argument_with_route_param_and_default")
46+
*/
47+
public function argumentWithoutDefaultWithRouteParamAndDefaultAction($value)
48+
{
49+
return new Response($value);
50+
}
51+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Symfony package.
5+
*
6+
* (c) Fabien Potencier <[email protected]>
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*/
11+
12+
namespace Symfony\Bundle\FrameworkBundle\Tests\Functional\Bundle\TestBundle\DependencyInjection;
13+
14+
use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
15+
use Symfony\Component\DependencyInjection\ContainerBuilder;
16+
17+
class AnnotationReaderPass implements CompilerPassInterface
18+
{
19+
public function process(ContainerBuilder $container)
20+
{
21+
// simulate using "annotation_reader" in a compiler pass
22+
$container->get('annotation_reader');
23+
}
24+
}

src/Symfony/Bundle/FrameworkBundle/Tests/Functional/Bundle/TestBundle/TestBundle.php

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313

1414
use Symfony\Component\HttpKernel\Bundle\Bundle;
1515
use Symfony\Component\DependencyInjection\ContainerBuilder;
16+
use Symfony\Bundle\FrameworkBundle\Tests\Functional\Bundle\TestBundle\DependencyInjection\AnnotationReaderPass;
1617
use Symfony\Bundle\FrameworkBundle\Tests\Functional\Bundle\TestBundle\DependencyInjection\Config\CustomConfig;
1718

1819
class TestBundle extends Bundle
@@ -25,5 +26,7 @@ public function build(ContainerBuilder $container)
2526
$extension = $container->getExtension('test');
2627

2728
$extension->setCustomConfig(new CustomConfig());
29+
30+
$container->addCompilerPass(new AnnotationReaderPass());
2831
}
2932
}
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Symfony package.
5+
*
6+
* (c) Fabien Potencier <[email protected]>
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*/
11+
12+
use Symfony\Bundle\FrameworkBundle\Tests\Functional\Bundle\TestBundle\TestBundle;
13+
use Symfony\Bundle\FrameworkBundle\FrameworkBundle;
14+
use Sensio\Bundle\FrameworkExtraBundle\SensioFrameworkExtraBundle;
15+
16+
return array(
17+
new FrameworkBundle(),
18+
new TestBundle(),
19+
new SensioFrameworkExtraBundle(),
20+
);
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
imports:
2+
- { resource: ../config/default.yml }
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
annotated_controller:
2+
prefix: /annotated
3+
resource: "@TestBundle/Controller/AnnotatedController.php"
4+
type: annotation

src/Symfony/Bundle/FrameworkBundle/composer.json

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,9 @@
2727
"symfony/polyfill-mbstring": "~1.0",
2828
"symfony/filesystem": "~2.8|~3.0",
2929
"symfony/finder": "~2.8|~3.0",
30-
"symfony/routing": "~3.0",
30+
"symfony/routing": "~3.1.10|~3.2.3",
31+
"symfony/security-core": "~2.8|~3.0",
32+
"symfony/security-csrf": "~2.8|~3.0",
3133
"symfony/stopwatch": "~2.8|~3.0",
3234
"doctrine/cache": "~1.0"
3335
},
@@ -52,7 +54,8 @@
5254
"symfony/property-info": "~2.8|~3.0",
5355
"doctrine/annotations": "~1.0",
5456
"phpdocumentor/reflection-docblock": "^3.0",
55-
"twig/twig": "~1.26|~2.0"
57+
"twig/twig": "~1.26|~2.0",
58+
"sensio/framework-extra-bundle": "^3.0.2"
5659
},
5760
"conflict": {
5861
"phpdocumentor/reflection-docblock": "<3.0",

src/Symfony/Component/Debug/ErrorHandler.php

Lines changed: 16 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -352,20 +352,18 @@ private function reRegister($prev)
352352
/**
353353
* Handles errors by filtering then logging them according to the configured bit fields.
354354
*
355-
* @param int $type One of the E_* constants
355+
* @param int $type One of the E_* constants
356356
* @param string $message
357357
* @param string $file
358358
* @param int $line
359-
* @param array $context
360-
* @param array $backtrace
361359
*
362360
* @return bool Returns false when no handling happens so that the PHP engine can handle the error itself
363361
*
364362
* @throws \ErrorException When $this->thrownErrors requests so
365363
*
366364
* @internal
367365
*/
368-
public function handleError($type, $message, $file, $line, array $context, array $backtrace = null)
366+
public function handleError($type, $message, $file, $line)
369367
{
370368
// Level is the current error reporting level to manage silent error.
371369
// Strong errors are not authorized to be silenced.
@@ -377,9 +375,20 @@ public function handleError($type, $message, $file, $line, array $context, array
377375
if (!$type || (!$log && !$throw)) {
378376
return $type && $log;
379377
}
378+
$scope = $this->scopedErrors & $type;
380379

381-
if (isset($context['GLOBALS']) && ($this->scopedErrors & $type)) {
382-
unset($context['GLOBALS']);
380+
if (4 < $numArgs = func_num_args()) {
381+
$context = $scope ? (func_get_arg(4) ?: array()) : array();
382+
$backtrace = 5 < $numArgs ? func_get_arg(5) : null; // defined on HHVM
383+
} else {
384+
$context = array();
385+
$backtrace = null;
386+
}
387+
388+
if (isset($context['GLOBALS']) && $scope) {
389+
$e = $context; // Whatever the signature of the method,
390+
unset($e['GLOBALS'], $context); // $context is always a reference in 5.3
391+
$context = $e;
383392
}
384393

385394
if (null !== $backtrace && $type & E_ERROR) {
@@ -399,7 +408,7 @@ public function handleError($type, $message, $file, $line, array $context, array
399408
} elseif (!$throw && !($type & $level)) {
400409
$errorAsException = new SilencedErrorContext($type, $file, $line);
401410
} else {
402-
if ($this->scopedErrors & $type) {
411+
if ($scope) {
403412
$errorAsException = new ContextErrorException($logMessage, 0, $type, $file, $line, $context);
404413
} else {
405414
$errorAsException = new \ErrorException($logMessage, 0, $type, $file, $line);

0 commit comments

Comments
 (0)