diff --git a/.travis.yml b/.travis.yml index 2f310a2dd3179..e61f0a59c4ff9 100644 --- a/.travis.yml +++ b/.travis.yml @@ -51,6 +51,7 @@ before_install: # A sigchild-enabled-PHP is used to test the Process component on the lowest PHP matrix line - if [[ ! $deps && $PHP = ${MIN_PHP%.*} && ! -d php-$MIN_PHP/sapi ]]; then wget http://museum.php.net/php5/php-$MIN_PHP.tar.bz2 -O - | tar -xj; (cd php-$MIN_PHP; ./configure --enable-sigchild --enable-pcntl; make -j2); fi - if [[ ! $PHP = hhvm* ]]; then INI_FILE=~/.phpenv/versions/$(phpenv version-name)/etc/conf.d/travis.ini; else INI_FILE=/etc/hhvm/php.ini; fi + - if [[ ! $skip ]]; then echo date.timezone = Europe/Paris >> $INI_FILE; fi - if [[ ! $skip ]]; then echo memory_limit = -1 >> $INI_FILE; fi - if [[ ! $skip ]]; then echo session.gc_probability = 0 >> $INI_FILE; fi - if [[ ! $skip && $PHP = 5.* ]]; then echo extension = mongo.so >> $INI_FILE; fi diff --git a/CHANGELOG-3.1.md b/CHANGELOG-3.1.md index 07d0350ddfada..228cbff557b8e 100644 --- a/CHANGELOG-3.1.md +++ b/CHANGELOG-3.1.md @@ -7,6 +7,33 @@ in 3.1 minor versions. To get the diff for a specific change, go to https://github.com/symfony/symfony/commit/XXX where XXX is the change hash To get the diff between two versions, go to https://github.com/symfony/symfony/compare/v3.1.0...v3.1.1 +* 3.1.7 (2016-11-21) + + * bug #20550 [YAML] Fix processing timestamp strings with timezone (myesain) + * bug #20543 [DI] Fix error when trying to resolve a DefinitionDecorator (nicolas-grekas) + * bug #20544 [PhpUnitBridge] Fix time-sensitive tests that use data providers (julienfalque) + * bug #20484 bumped min version of Twig to 1.28 (fabpot) + * bug #20519 [Debug] Remove GLOBALS from exception context to avoid endless recursion (Seldaek) + * bug #20455 [ClassLoader] Fix ClassCollectionLoader inlining with __halt_compiler (giosh94mhz) + * bug #20307 [Form] Fix Date\TimeType marked as invalid on request with single_text and zero seconds (LuisDeimos) + * bug #20480 [FrameworkBundle] Register the ArrayDenormalizer (dunglas) + * bug #20286 [Serializer] Fix DataUriNormalizer's regex (dunglas) + * bug #20466 [Translation] fixed nested fallback catalogue using multiple locales. (aitboudad) + * bug #20465 [#18637][TranslationDebug] workaround for getFallbackLocales. (aitboudad) + * bug #20453 [Cache] Make directory hashing case insensitive (nicolas-grekas) + * bug #20440 [TwigBridge][TwigBundle][HttpKernel] prefer getSourceContext() over getSource() (xabbuh) + * bug #20287 Properly format value in UniqueEntityValidator (alcaeus) + * bug #20422 [Translation][fallback] add missing resources in parent catalogues. (aitboudad) + * bug #20378 [Form] Fixed show float values as choice value in ChoiceType (yceruto) + * bug #20294 Improved the design of the metrics in the profiler (javiereguiluz) + * bug #20375 [HttpFoundation][Session] Fix memcache session handler (klandaika) + * bug #20377 [Console] Fix infinite loop on missing input (chalasr) + * bug #20372 [Console] simplified code (fabpot) + * bug #20342 [Form] Fix UrlType transforms valid protocols (ogizanagi) + * bug #20292 Enhance GAE compat by removing some realpath() (nicolas-grekas) + * bug #20326 [VarDumper] Fix dumping Twig source in stack traces (nicolas-grekas) + * bug #20321 Compatibility with Twig 1.27 (xkobal) + * 3.1.6 (2016-10-27) * bug #20291 [Yaml] Fix 7.1 compat (nicolas-grekas) diff --git a/CONTRIBUTORS.md b/CONTRIBUTORS.md index b0646cc1303cd..41c883159c8e2 100644 --- a/CONTRIBUTORS.md +++ b/CONTRIBUTORS.md @@ -33,8 +33,8 @@ Symfony is the result of the work of many people who made the code better - Igor Wiedler (igorw) - Grégoire Pineau (lyrixx) - Eriksen Costa (eriksencosta) - - Sarah Khalil (saro0h) - Jules Pietri (heah) + - Sarah Khalil (saro0h) - Maxime Steinhausser (ogizanagi) - Jonathan Wage (jwage) - Diego Saint Esteben (dosten) @@ -49,13 +49,13 @@ Symfony is the result of the work of many people who made the code better - Henrik Bjørnskov (henrikbjorn) - Miha Vrhovnik - Diego Saint Esteben (dii3g0) + - Robin Chalas (chalas_r) - Ener-Getick (energetick) - Konstantin Kudryashov (everzet) - Bilal Amarni (bamarni) - Florin Patan (florinpatan) - Peter Rehm (rpet) - Iltar van der Berg (kjarli) - - Robin Chalas (chalas_r) - Kevin Bond (kbond) - Andrej Hudec (pulzarraider) - Gábor Egyed (1ed) @@ -69,6 +69,7 @@ Symfony is the result of the work of many people who made the code better - Henrik Westphal (snc) - Dariusz Górecki (canni) - Douglas Greenshields (shieldo) + - Konstantin Myakshin (koc) - Lee McDermott - Brandon Turner - Luis Cordova (cordoval) @@ -76,7 +77,6 @@ Symfony is the result of the work of many people who made the code better - Titouan Galopin (tgalopin) - Daniel Holmes (dholmes) - Pierre du Plessis (pierredup) - - Konstantin Myakshin (koc) - Bart van den Burg (burgov) - Jordan Alliot (jalliot) - John Wards (johnwards) @@ -84,17 +84,19 @@ Symfony is the result of the work of many people who made the code better - Fran Moreno (franmomu) - Antoine Hérault (herzult) - Paráda József (paradajozsef) + - Jáchym Toušek (enumag) - Arnaud Le Blanc (arnaud-lb) - Jérôme Tamarelle (gromnan) - Michal Piotrowski (eventhorizon) - Tim Nagel (merk) + - Dariusz Ruminski - Brice BERNARD (brikou) - Alexander M. Turek (derrabus) - - Dariusz Ruminski - marc.weistroff - Issei Murasawa (issei_m) - lenar - Włodzimierz Gajda (gajdaw) + - Roland Franssen (ro0) - Baptiste Clavié (talus) - Alexander Schwenn (xelaris) - Florian Voutzinos (florianv) @@ -104,8 +106,6 @@ Symfony is the result of the work of many people who made the code better - Peter Kokot (maastermedia) - excelwebzone - Jacob Dreesen (jdreesen) - - Jáchym Toušek (enumag) - - Roland Franssen (ro0) - Jérémy DERUSSÉ (jderusse) - Vladimir Reznichenko (kalessil) - Tomáš Votruba (tomas_votruba) @@ -131,6 +131,7 @@ Symfony is the result of the work of many people who made the code better - Andréia Bohner (andreia) - Rafael Dohms (rdohms) - Arnaud Kleinpeter (nanocom) + - jwdeitch - Joel Wurtz (brouznouf) - Philipp Wahala (hifi) - Vyacheslav Pavlov @@ -139,6 +140,7 @@ Symfony is the result of the work of many people who made the code better - Thomas Rabaix (rande) - Vincent AUBERT (vincent) - Rouven Weßling (realityking) + - Teoh Han Hui (teohhanhui) - Mikael Pajunen - Clemens Tolboom - Helmer Aaviksoo @@ -149,7 +151,6 @@ Symfony is the result of the work of many people who made the code better - Amal Raghav (kertz) - Jonathan Ingram (jonathaningram) - Artur Kotyrba - - Teoh Han Hui (teohhanhui) - Warnar Boekkooi (boekkooi) - Dmitrii Chekaliuk (lazyhammer) - Clément JOBEILI (dator) @@ -159,10 +160,12 @@ Symfony is the result of the work of many people who made the code better - Richard Miller (mr_r_miller) - Mario A. Alvarez Garcia (nomack84) - Dennis Benkert (denderello) + - jeremyFreeAgent (Jérémy Romey) (jeremyfreeagent) - Benjamin Dulau (dbenjamin) - Mathieu Lemoine (lemoinem) - Andreas Hucks (meandmymonkey) - Noel Guilbert (noel) + - Lars Strojny (lstrojny) - Yonel Ceruto González (yonelceruto) - Stepan Anchugov (kix) - bronze1man @@ -185,13 +188,11 @@ Symfony is the result of the work of many people who made the code better - Michele Orselli (orso) - Tom Van Looy (tvlooy) - Sven Paulus (subsven) - - Lars Strojny (lstrojny) - Rui Marinho (ruimarinho) - Daniel Espendiller - Dawid Nowak - Eugene Wissner - Julien Brochet (mewt) - - jeremyFreeAgent (jeremyfreeagent) - Sergey Linnik (linniksa) - Michaël Perrin (michael.perrin) - Marcel Beerta (mazen) @@ -226,6 +227,7 @@ Symfony is the result of the work of many people who made the code better - Jakub Kucharovic (jkucharovic) - Eugene Leonovich (rybakit) - Filippo Tessarotto + - Tristan Darricau (nicofuma) - Joseph Rouff (rouffj) - Félix Labrecque (woodspire) - GordonsLondon @@ -262,7 +264,6 @@ Symfony is the result of the work of many people who made the code better - Oleg Voronkovich - Manuel Kiessling (manuelkiessling) - Daniel Wehner - - Tristan Darricau (nicofuma) - Atsuhiro KUBO (iteman) - Andrew Moore (finewolf) - Bertrand Zuchuat (garfield-fr) @@ -387,6 +388,7 @@ Symfony is the result of the work of many people who made the code better - Ariel Ferrandini (aferrandini) - Dirk Pahl (dirkaholic) - cedric lombardot (cedriclombardot) + - David Maicher (dmaicher) - Jonas Flodén (flojon) - Christian Schmidt - Marcin Sikoń (marphi) @@ -535,6 +537,7 @@ Symfony is the result of the work of many people who made the code better - Daisuke Ohata - Vincent Simonin - Alex Bogomazov (alebo) + - maxime.steinhausser - Stefan Warman - Tristan Maindron (tmaindron) - Ke WANG (yktd26) @@ -546,11 +549,11 @@ Symfony is the result of the work of many people who made the code better - Ulumuddin Yunus (joenoez) - Luc Vieillescazes (iamluc) - Johann Saunier (prophet777) + - Michael Devery (mickadoo) - Antoine Corcy - Artur Eshenbrener - Arturs Vonda - Sascha Grossenbacher - - David Maicher (dmaicher) - Szijarto Tamas - Catalin Dan - Stephan Vock @@ -593,6 +596,7 @@ Symfony is the result of the work of many people who made the code better - Vladyslav Petrovych - Alex Xandra Albert Sim - Carson Full + - Andrey Astakhov (aast) - Trent Steel (trsteel88) - Yuen-Chi Lian - Besnik Br @@ -602,12 +606,14 @@ Symfony is the result of the work of many people who made the code better - avorobiev - Venu - Lars Vierbergen + - Jonatan Männchen - Dennis Hotson - Andrew Tchircoff (andrewtch) - michaelwilliams - 1emming - Victor Bocharsky (bocharsky_bw) - Leevi Graham (leevigraham) + - Jordan Deitch - Casper Valdemar Poulsen - Josiah (josiah) - Joschi Kuphal @@ -740,6 +746,7 @@ Symfony is the result of the work of many people who made the code better - Alexandru Furculita (afurculita) - Ben Ramsey (ramsey) - Christian Jul Jensen + - Alexandre GESLIN (alexandregeslin) - The Whole Life to Learn - Farhad Safarov - Liverbool (liverbool) @@ -870,12 +877,14 @@ Symfony is the result of the work of many people who made the code better - James Gilliland - Rhodri Pugh (rodnaph) - David de Boer (ddeboer) + - Klaus Purer - Gilles Doge (gido) - abulford - antograssiot - Brooks Boyd - Roger Webb - Dmitriy Simushev + - Ivo Bathke (ivoba) - Max Voloshin (maxvoloshin) - Nicolas Fabre (nfabre) - Raul Rodriguez (raul782) @@ -964,7 +973,6 @@ Symfony is the result of the work of many people who made the code better - ChrisC - Ilya Biryukov - Kim Laï Trinh - - Jonatan Männchen - Jason Desrosiers - m.chwedziak - Philip Frank @@ -994,7 +1002,6 @@ Symfony is the result of the work of many people who made the code better - Emmanuel Vella (emmanuel.vella) - Carsten Nielsen (phreaknerd) - Mathieu Rochette - - maxime.steinhausser - Jay Severson - René Kerner - Nathaniel Catchpole @@ -1044,7 +1051,6 @@ Symfony is the result of the work of many people who made the code better - Benjamin Bender - Konrad Mohrfeldt - Lance Chen - - Andrey Astakhov (aast) - Andrew (drew) - Nikolay Labinskiy (e-moe) - kor3k kor3k (kor3k) @@ -1055,6 +1061,7 @@ Symfony is the result of the work of many people who made the code better - Mephistofeles - Hoffmann András - Olivier + - Wesley Lancel - pscheit - Zdeněk Drahoš - Dan Harper @@ -1160,6 +1167,7 @@ Symfony is the result of the work of many people who made the code better - JakeFr - Simon Sargeant - efeen + - Muhammed Akbulut - Michał Dąbrowski (defrag) - Simone Fumagalli (hpatoio) - Brian Graham (incognito) @@ -1176,6 +1184,7 @@ Symfony is the result of the work of many people who made the code better - Artem Lopata (bumz) - Nicole Cordes - Alexey Popkov + - Gijs Kunze - Artyom Protaskin - Nathanael d. Noblet - helmer @@ -1445,6 +1454,7 @@ Symfony is the result of the work of many people who made the code better - Matthias Althaus - Michaël VEROUX - Julia + - Lin Lu - arduanov - sualko - Nicolas Roudaire diff --git a/UPGRADE-3.0.md b/UPGRADE-3.0.md index fc81eae24fc3b..866bd981cce79 100644 --- a/UPGRADE-3.0.md +++ b/UPGRADE-3.0.md @@ -253,6 +253,9 @@ UPGRADE FROM 2.x to 3.0 closures, but the closure is now resolved in the type instead of in the loader. + * Using the entity provider with a Doctrine repository implementing `UserProviderInterface` is not supported anymore. + You should make the repository implement `UserLoaderInterface` instead. + ### EventDispatcher * The method `getListenerPriority($eventName, $listener)` has been added to the @@ -1902,5 +1905,5 @@ UPGRADE FROM 2.x to 3.0 After: ```php - $request->query->get('foo')[bar]; + $request->query->get('foo')['bar']; ``` diff --git a/appveyor.yml b/appveyor.yml index 42b5a5113ac93..302f898e72ad4 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -29,7 +29,7 @@ install: - cd .. - copy /Y php.ini-development php.ini-min - echo max_execution_time=1200 >> php.ini-min - - echo date.timezone="UTC" >> php.ini-min + - echo date.timezone="America/Los_Angeles" >> php.ini-min - echo extension_dir=ext >> php.ini-min - copy /Y php.ini-min php.ini-max - echo extension=php_openssl.dll >> php.ini-max diff --git a/composer.json b/composer.json index fcbb0475f03fa..9f36a1e5bf1b4 100644 --- a/composer.json +++ b/composer.json @@ -18,7 +18,7 @@ "require": { "php": ">=5.5.9", "doctrine/common": "~2.4", - "twig/twig": "~1.27|~2.0", + "twig/twig": "~1.28|~2.0", "psr/cache": "~1.0", "psr/log": "~1.0", "symfony/polyfill-intl-icu": "~1.0", diff --git a/src/Symfony/Bridge/Doctrine/CHANGELOG.md b/src/Symfony/Bridge/Doctrine/CHANGELOG.md index f187e970f98fe..3dcb8770ec8cc 100644 --- a/src/Symfony/Bridge/Doctrine/CHANGELOG.md +++ b/src/Symfony/Bridge/Doctrine/CHANGELOG.md @@ -18,6 +18,12 @@ CHANGELOG * removed passing a query builder closure to `ORMQueryBuilderLoader` * removed `loader` and `property` options of the `DoctrineType` +2.8.0 +----- + + * deprecated using the entity provider with a Doctrine repository implementing UserProviderInterface + * added UserLoaderInterface for loading users through Doctrine. + 2.7.0 ----- diff --git a/src/Symfony/Bridge/Doctrine/DependencyInjection/AbstractDoctrineExtension.php b/src/Symfony/Bridge/Doctrine/DependencyInjection/AbstractDoctrineExtension.php index a0f8b5c46ad06..3a6a877e1fc4e 100644 --- a/src/Symfony/Bridge/Doctrine/DependencyInjection/AbstractDoctrineExtension.php +++ b/src/Symfony/Bridge/Doctrine/DependencyInjection/AbstractDoctrineExtension.php @@ -134,10 +134,7 @@ protected function setMappingDriverConfig(array $mappingConfig, $mappingName) throw new \InvalidArgumentException(sprintf('Invalid Doctrine mapping path given. Cannot load Doctrine mapping/bundle named "%s".', $mappingName)); } - if (substr($mappingDirectory, 0, 7) !== 'phar://') { - $mappingDirectory = realpath($mappingDirectory); - } - $this->drivers[$mappingConfig['type']][$mappingConfig['prefix']] = $mappingDirectory; + $this->drivers[$mappingConfig['type']][$mappingConfig['prefix']] = realpath($mappingDirectory) ?: $mappingDirectory; } /** diff --git a/src/Symfony/Bridge/Doctrine/DependencyInjection/CompilerPass/DoctrineValidationPass.php b/src/Symfony/Bridge/Doctrine/DependencyInjection/CompilerPass/DoctrineValidationPass.php index 96f05eb5b60c9..f8382ed2ebfb8 100644 --- a/src/Symfony/Bridge/Doctrine/DependencyInjection/CompilerPass/DoctrineValidationPass.php +++ b/src/Symfony/Bridge/Doctrine/DependencyInjection/CompilerPass/DoctrineValidationPass.php @@ -61,7 +61,7 @@ private function updateValidatorMappingFiles(ContainerBuilder $container, $mappi foreach ($container->getParameter('kernel.bundles') as $bundle) { $reflection = new \ReflectionClass($bundle); if (is_file($file = dirname($reflection->getFileName()).'/'.$validationPath)) { - $files[] = realpath($file); + $files[] = $file; $container->addResource(new FileResource($file)); } } diff --git a/src/Symfony/Bridge/Doctrine/Form/Type/DoctrineType.php b/src/Symfony/Bridge/Doctrine/Form/Type/DoctrineType.php index 5919ca95734a0..b28b9d51ad67b 100644 --- a/src/Symfony/Bridge/Doctrine/Form/Type/DoctrineType.php +++ b/src/Symfony/Bridge/Doctrine/Form/Type/DoctrineType.php @@ -20,14 +20,10 @@ use Symfony\Bridge\Doctrine\Form\EventListener\MergeDoctrineCollectionListener; use Symfony\Component\Form\AbstractType; use Symfony\Component\Form\ChoiceList\Factory\CachingFactoryDecorator; -use Symfony\Component\Form\ChoiceList\Factory\ChoiceListFactoryInterface; -use Symfony\Component\Form\ChoiceList\Factory\DefaultChoiceListFactory; -use Symfony\Component\Form\ChoiceList\Factory\PropertyAccessDecorator; use Symfony\Component\Form\Exception\RuntimeException; use Symfony\Component\Form\FormBuilderInterface; use Symfony\Component\OptionsResolver\Options; use Symfony\Component\OptionsResolver\OptionsResolver; -use Symfony\Component\PropertyAccess\PropertyAccessorInterface; abstract class DoctrineType extends AbstractType { @@ -36,11 +32,6 @@ abstract class DoctrineType extends AbstractType */ protected $registry; - /** - * @var ChoiceListFactoryInterface - */ - private $choiceListFactory; - /** * @var IdReader[] */ @@ -108,15 +99,9 @@ public function getQueryBuilderPartsForCachingHash($queryBuilder) return false; } - public function __construct(ManagerRegistry $registry, PropertyAccessorInterface $propertyAccessor = null, ChoiceListFactoryInterface $choiceListFactory = null) + public function __construct(ManagerRegistry $registry) { $this->registry = $registry; - $this->choiceListFactory = $choiceListFactory ?: new CachingFactoryDecorator( - new PropertyAccessDecorator( - new DefaultChoiceListFactory(), - $propertyAccessor - ) - ); } public function buildForm(FormBuilderInterface $builder, array $options) diff --git a/src/Symfony/Bridge/Doctrine/Test/DoctrineTestHelper.php b/src/Symfony/Bridge/Doctrine/Test/DoctrineTestHelper.php index 962099e36a7bc..e7f4555d07d2e 100644 --- a/src/Symfony/Bridge/Doctrine/Test/DoctrineTestHelper.php +++ b/src/Symfony/Bridge/Doctrine/Test/DoctrineTestHelper.php @@ -12,6 +12,8 @@ namespace Symfony\Bridge\Doctrine\Test; use Doctrine\Common\Annotations\AnnotationReader; +use Doctrine\Common\Cache\ArrayCache; +use Doctrine\ORM\Configuration; use Doctrine\ORM\Mapping\Driver\AnnotationDriver; use Doctrine\ORM\EntityManager; @@ -25,22 +27,19 @@ class DoctrineTestHelper /** * Returns an entity manager for testing. * + * @param Configuration|null $config + * * @return EntityManager */ - public static function createTestEntityManager() + public static function createTestEntityManager(Configuration $config = null) { if (!extension_loaded('pdo_sqlite')) { \PHPUnit_Framework_TestCase::markTestSkipped('Extension pdo_sqlite is required.'); } - $config = new \Doctrine\ORM\Configuration(); - $config->setEntityNamespaces(array('SymfonyTestsDoctrine' => 'Symfony\Bridge\Doctrine\Tests\Fixtures')); - $config->setAutoGenerateProxyClasses(true); - $config->setProxyDir(\sys_get_temp_dir()); - $config->setProxyNamespace('SymfonyTests\Doctrine'); - $config->setMetadataDriverImpl(new AnnotationDriver(new AnnotationReader())); - $config->setQueryCacheImpl(new \Doctrine\Common\Cache\ArrayCache()); - $config->setMetadataCacheImpl(new \Doctrine\Common\Cache\ArrayCache()); + if (null === $config) { + $config = self::createTestConfiguration(); + } $params = array( 'driver' => 'pdo_sqlite', @@ -50,6 +49,23 @@ public static function createTestEntityManager() return EntityManager::create($params, $config); } + /** + * @return Configuration + */ + public static function createTestConfiguration() + { + $config = new Configuration(); + $config->setEntityNamespaces(array('SymfonyTestsDoctrine' => 'Symfony\Bridge\Doctrine\Tests\Fixtures')); + $config->setAutoGenerateProxyClasses(true); + $config->setProxyDir(\sys_get_temp_dir()); + $config->setProxyNamespace('SymfonyTests\Doctrine'); + $config->setMetadataDriverImpl(new AnnotationDriver(new AnnotationReader())); + $config->setQueryCacheImpl(new ArrayCache()); + $config->setMetadataCacheImpl(new ArrayCache()); + + return $config; + } + /** * This class cannot be instantiated. */ diff --git a/src/Symfony/Bridge/Doctrine/Test/TestRepositoryFactory.php b/src/Symfony/Bridge/Doctrine/Test/TestRepositoryFactory.php new file mode 100644 index 0000000000000..b7cbafa947aef --- /dev/null +++ b/src/Symfony/Bridge/Doctrine/Test/TestRepositoryFactory.php @@ -0,0 +1,66 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Bridge\Doctrine\Test; + +use Doctrine\Common\Persistence\ObjectRepository; +use Doctrine\ORM\EntityManagerInterface; +use Doctrine\ORM\Mapping\ClassMetadata; +use Doctrine\ORM\Repository\RepositoryFactory; + +/** + * @author Andreas Braun + */ +final class TestRepositoryFactory implements RepositoryFactory +{ + /** + * @var ObjectRepository[] + */ + private $repositoryList = array(); + + /** + * {@inheritdoc} + */ + public function getRepository(EntityManagerInterface $entityManager, $entityName) + { + $repositoryHash = $this->getRepositoryHash($entityManager, $entityName); + + if (isset($this->repositoryList[$repositoryHash])) { + return $this->repositoryList[$repositoryHash]; + } + + return $this->repositoryList[$repositoryHash] = $this->createRepository($entityManager, $entityName); + } + + public function setRepository(EntityManagerInterface $entityManager, $entityName, ObjectRepository $repository) + { + $repositoryHash = $this->getRepositoryHash($entityManager, $entityName); + + $this->repositoryList[$repositoryHash] = $repository; + } + + /** + * @return ObjectRepository + */ + private function createRepository(EntityManagerInterface $entityManager, $entityName) + { + /* @var $metadata ClassMetadata */ + $metadata = $entityManager->getClassMetadata($entityName); + $repositoryClassName = $metadata->customRepositoryClassName ?: $entityManager->getConfiguration()->getDefaultRepositoryClassName(); + + return new $repositoryClassName($entityManager, $metadata); + } + + private function getRepositoryHash(EntityManagerInterface $entityManager, $entityName) + { + return $entityManager->getClassMetadata($entityName)->getName().spl_object_hash($entityManager); + } +} diff --git a/src/Symfony/Bridge/Doctrine/Tests/DependencyInjection/DoctrineExtensionTest.php b/src/Symfony/Bridge/Doctrine/Tests/DependencyInjection/DoctrineExtensionTest.php index 94f0787b44ff2..9fe29a3f54bc6 100644 --- a/src/Symfony/Bridge/Doctrine/Tests/DependencyInjection/DoctrineExtensionTest.php +++ b/src/Symfony/Bridge/Doctrine/Tests/DependencyInjection/DoctrineExtensionTest.php @@ -44,7 +44,7 @@ protected function setUp() $this->extension->expects($this->any()) ->method('getObjectManagerElementName') ->will($this->returnCallback(function ($name) { - return 'doctrine.orm.'.$name; + return 'doctrine.orm.'.$name; })); } diff --git a/src/Symfony/Bridge/Doctrine/Tests/Fixtures/SingleIntIdEntity.php b/src/Symfony/Bridge/Doctrine/Tests/Fixtures/SingleIntIdEntity.php index 44630a1fc51f1..6ee360e6a10aa 100644 --- a/src/Symfony/Bridge/Doctrine/Tests/Fixtures/SingleIntIdEntity.php +++ b/src/Symfony/Bridge/Doctrine/Tests/Fixtures/SingleIntIdEntity.php @@ -24,6 +24,9 @@ class SingleIntIdEntity /** @Column(type="string", nullable=true) */ public $name; + /** @Column(type="array", nullable=true) */ + public $phoneNumbers = array(); + public function __construct($id, $name) { $this->id = $id; diff --git a/src/Symfony/Bridge/Doctrine/Tests/Validator/Constraints/UniqueEntityValidatorTest.php b/src/Symfony/Bridge/Doctrine/Tests/Validator/Constraints/UniqueEntityValidatorTest.php index 7299f106b8967..2e2f2952e004e 100644 --- a/src/Symfony/Bridge/Doctrine/Tests/Validator/Constraints/UniqueEntityValidatorTest.php +++ b/src/Symfony/Bridge/Doctrine/Tests/Validator/Constraints/UniqueEntityValidatorTest.php @@ -16,6 +16,7 @@ use Doctrine\Common\Persistence\ObjectManager; use Doctrine\Common\Persistence\ObjectRepository; use Symfony\Bridge\Doctrine\Test\DoctrineTestHelper; +use Symfony\Bridge\Doctrine\Test\TestRepositoryFactory; use Symfony\Bridge\Doctrine\Tests\Fixtures\SingleIntIdEntity; use Symfony\Bridge\Doctrine\Tests\Fixtures\DoubleNameEntity; use Symfony\Bridge\Doctrine\Tests\Fixtures\AssociationEntity; @@ -48,9 +49,16 @@ class UniqueEntityValidatorTest extends AbstractConstraintValidatorTest */ protected $repository; + protected $repositoryFactory; + protected function setUp() { - $this->em = DoctrineTestHelper::createTestEntityManager(); + $this->repositoryFactory = new TestRepositoryFactory(); + + $config = DoctrineTestHelper::createTestConfiguration(); + $config->setRepositoryFactory($this->repositoryFactory); + + $this->em = DoctrineTestHelper::createTestEntityManager($config); $this->registry = $this->createRegistryMock($this->em); $this->createSchema($this->em); @@ -164,7 +172,7 @@ public function testValidateUniqueness() $this->buildViolation('myMessage') ->atPath('property.path.name') - ->setParameter('{{ value }}', 'Foo') + ->setParameter('{{ value }}', '"Foo"') ->setInvalidValue('Foo') ->setCode(UniqueEntity::NOT_UNIQUE_ERROR) ->assertRaised(); @@ -189,7 +197,7 @@ public function testValidateCustomErrorPath() $this->buildViolation('myMessage') ->atPath('property.path.bar') - ->setParameter('{{ value }}', 'Foo') + ->setParameter('{{ value }}', '"Foo"') ->setInvalidValue('Foo') ->setCode(UniqueEntity::NOT_UNIQUE_ERROR) ->assertRaised(); @@ -242,7 +250,7 @@ public function testValidateUniquenessWithIgnoreNull() $this->buildViolation('myMessage') ->atPath('property.path.name') - ->setParameter('{{ value }}', 'Foo') + ->setParameter('{{ value }}', '"Foo"') ->setInvalidValue('Foo') ->setCode(UniqueEntity::NOT_UNIQUE_ERROR) ->assertRaised(); @@ -275,7 +283,7 @@ public function testValidateUniquenessWithValidCustomErrorPath() $this->buildViolation('myMessage') ->atPath('property.path.name2') - ->setParameter('{{ value }}', 'Bar') + ->setParameter('{{ value }}', '"Bar"') ->setInvalidValue('Bar') ->setCode(UniqueEntity::NOT_UNIQUE_ERROR) ->assertRaised(); @@ -446,7 +454,7 @@ public function testValidateUniquenessNotToStringEntityWithAssociatedEntity() $this->buildViolation('myMessage') ->atPath('property.path.single') - ->setParameter('{{ value }}', $expectedValue) + ->setParameter('{{ value }}', '"'.$expectedValue.'"') ->setInvalidValue($expectedValue) ->setCode(UniqueEntity::NOT_UNIQUE_ERROR) ->assertRaised(); @@ -472,6 +480,44 @@ public function testAssociatedEntityWithNull() $this->assertNoViolation(); } + public function testValidateUniquenessWithArrayValue() + { + $repository = $this->createRepositoryMock(); + $this->repositoryFactory->setRepository($this->em, 'Symfony\Bridge\Doctrine\Tests\Fixtures\SingleIntIdEntity', $repository); + + $constraint = new UniqueEntity(array( + 'message' => 'myMessage', + 'fields' => array('phoneNumbers'), + 'em' => self::EM_NAME, + 'repositoryMethod' => 'findByCustom', + )); + + $entity1 = new SingleIntIdEntity(1, 'foo'); + $entity1->phoneNumbers[] = 123; + + $repository->expects($this->once()) + ->method('findByCustom') + ->will($this->returnValue(array($entity1))) + ; + + $this->em->persist($entity1); + $this->em->flush(); + + $entity2 = new SingleIntIdEntity(2, 'bar'); + $entity2->phoneNumbers[] = 123; + $this->em->persist($entity2); + $this->em->flush(); + + $this->validator->validate($entity2, $constraint); + + $this->buildViolation('myMessage') + ->atPath('property.path.phoneNumbers') + ->setParameter('{{ value }}', 'array') + ->setInvalidValue(array(123)) + ->setCode(UniqueEntity::NOT_UNIQUE_ERROR) + ->assertRaised(); + } + /** * @expectedException \Symfony\Component\Validator\Exception\ConstraintDefinitionException * @expectedExceptionMessage Object manager "foo" does not exist. diff --git a/src/Symfony/Bridge/Doctrine/Validator/Constraints/UniqueEntityValidator.php b/src/Symfony/Bridge/Doctrine/Validator/Constraints/UniqueEntityValidator.php index 4fd8afff171b3..eb90b78af2f7d 100644 --- a/src/Symfony/Bridge/Doctrine/Validator/Constraints/UniqueEntityValidator.php +++ b/src/Symfony/Bridge/Doctrine/Validator/Constraints/UniqueEntityValidator.php @@ -133,7 +133,7 @@ public function validate($entity, Constraint $constraint) $this->context->buildViolation($constraint->message) ->atPath($errorPath) - ->setParameter('{{ value }}', $invalidValue) + ->setParameter('{{ value }}', $this->formatValue($invalidValue, static::OBJECT_TO_STRING | static::PRETTY_DATE)) ->setInvalidValue($invalidValue) ->setCode(UniqueEntity::NOT_UNIQUE_ERROR) ->addViolation(); diff --git a/src/Symfony/Bridge/PhpUnit/DeprecationErrorHandler.php b/src/Symfony/Bridge/PhpUnit/DeprecationErrorHandler.php index cdf36b479dbba..0d4deb9a9bdcb 100644 --- a/src/Symfony/Bridge/PhpUnit/DeprecationErrorHandler.php +++ b/src/Symfony/Bridge/PhpUnit/DeprecationErrorHandler.php @@ -68,7 +68,8 @@ public static function register($mode = 0) 'other' => array(), ); $deprecationHandler = function ($type, $msg, $file, $line, $context) use (&$deprecations, $getMode) { - if (E_USER_DEPRECATED !== $type || DeprecationErrorHandler::MODE_DISABLED === $mode = $getMode()) { + $mode = $getMode(); + if (E_USER_DEPRECATED !== $type || DeprecationErrorHandler::MODE_DISABLED === $mode) { return \PHPUnit_Util_ErrorHandler::handleError($type, $msg, $file, $line, $context); } diff --git a/src/Symfony/Bridge/PhpUnit/SymfonyTestsListener.php b/src/Symfony/Bridge/PhpUnit/SymfonyTestsListener.php index a60206647a283..0db9e32658817 100644 --- a/src/Symfony/Bridge/PhpUnit/SymfonyTestsListener.php +++ b/src/Symfony/Bridge/PhpUnit/SymfonyTestsListener.php @@ -142,7 +142,7 @@ public function addSkippedTest(\PHPUnit_Framework_Test $test, \Exception $e, $ti public function startTest(\PHPUnit_Framework_Test $test) { if (-2 < $this->state && $test instanceof \PHPUnit_Framework_TestCase) { - $groups = \PHPUnit_Util_Test::getGroups(get_class($test), $test->getName()); + $groups = \PHPUnit_Util_Test::getGroups(get_class($test), $test->getName(false)); if (in_array('time-sensitive', $groups, true)) { ClockMock::register(get_class($test)); @@ -157,7 +157,7 @@ public function startTest(\PHPUnit_Framework_Test $test) public function endTest(\PHPUnit_Framework_Test $test, $time) { if (-2 < $this->state && $test instanceof \PHPUnit_Framework_TestCase) { - $groups = \PHPUnit_Util_Test::getGroups(get_class($test), $test->getName()); + $groups = \PHPUnit_Util_Test::getGroups(get_class($test), $test->getName(false)); if (in_array('time-sensitive', $groups, true)) { ClockMock::withClockMock(false); diff --git a/src/Symfony/Bridge/Twig/Command/DebugCommand.php b/src/Symfony/Bridge/Twig/Command/DebugCommand.php index a18b817870f5e..44e23902e03de 100644 --- a/src/Symfony/Bridge/Twig/Command/DebugCommand.php +++ b/src/Symfony/Bridge/Twig/Command/DebugCommand.php @@ -61,7 +61,7 @@ protected function configure() new InputOption('format', null, InputOption::VALUE_REQUIRED, 'The output format (text or json)', 'text'), )) ->setDescription('Shows a list of twig functions, filters, globals and tests') - ->setHelp(<<setHelp(<<<'EOF' The %command.name% command outputs a list of twig functions, filters, globals and tests. Output can be filtered with an optional argument. diff --git a/src/Symfony/Bridge/Twig/Command/LintCommand.php b/src/Symfony/Bridge/Twig/Command/LintCommand.php index abcfcccaee86a..ebbfde12c2058 100644 --- a/src/Symfony/Bridge/Twig/Command/LintCommand.php +++ b/src/Symfony/Bridge/Twig/Command/LintCommand.php @@ -61,7 +61,7 @@ protected function configure() ->setDescription('Lints a template and outputs encountered errors') ->addOption('format', null, InputOption::VALUE_REQUIRED, 'The output format', 'txt') ->addArgument('filename', InputArgument::IS_ARRAY) - ->setHelp(<<setHelp(<<<'EOF' The %command.name% command lints a template and outputs to STDOUT the first encountered syntax error. diff --git a/src/Symfony/Bridge/Twig/NodeVisitor/TranslationDefaultDomainNodeVisitor.php b/src/Symfony/Bridge/Twig/NodeVisitor/TranslationDefaultDomainNodeVisitor.php index b226d91adfe48..e64d6eae2347d 100644 --- a/src/Symfony/Bridge/Twig/NodeVisitor/TranslationDefaultDomainNodeVisitor.php +++ b/src/Symfony/Bridge/Twig/NodeVisitor/TranslationDefaultDomainNodeVisitor.php @@ -49,7 +49,7 @@ protected function doEnterNode(\Twig_Node $node, \Twig_Environment $env) return $node; } else { - $var = $env->getParser()->getVarName(); + $var = $this->getVarName(); $name = new \Twig_Node_Expression_AssignName($var, $node->getTemplateLine()); $this->scope->set('domain', new \Twig_Node_Expression_Name($var, $node->getTemplateLine())); @@ -123,4 +123,9 @@ private function isNamedArguments($arguments) return false; } + + private function getVarName() + { + return sprintf('__internal_%s', hash('sha256', uniqid(mt_rand(), true), false)); + } } diff --git a/src/Symfony/Bridge/Twig/Tests/Extension/TranslationExtensionTest.php b/src/Symfony/Bridge/Twig/Tests/Extension/TranslationExtensionTest.php index 0235c4da327a0..e96bd4f9a3bef 100644 --- a/src/Symfony/Bridge/Twig/Tests/Extension/TranslationExtensionTest.php +++ b/src/Symfony/Bridge/Twig/Tests/Extension/TranslationExtensionTest.php @@ -36,7 +36,7 @@ public function testTrans($template, $expected, array $variables = array()) $twig = new \Twig_Environment($loader, array('debug' => true, 'cache' => false)); $twig->addExtension(new TranslationExtension(new Translator('en', new MessageSelector()))); - echo $twig->compile($twig->parse($twig->tokenize(new \Twig_Source($twig->getLoader()->getSource('index'), 'index'))))."\n\n"; + echo $twig->compile($twig->parse($twig->tokenize($twig->getLoader()->getSourceContext('index'))))."\n\n"; $this->assertEquals($expected, $this->getTemplate($template)->render($variables)); } diff --git a/src/Symfony/Bridge/Twig/Tests/Node/DumpNodeTest.php b/src/Symfony/Bridge/Twig/Tests/Node/DumpNodeTest.php index 8e5b933c81da7..5d669cde7ac94 100644 --- a/src/Symfony/Bridge/Twig/Tests/Node/DumpNodeTest.php +++ b/src/Symfony/Bridge/Twig/Tests/Node/DumpNodeTest.php @@ -80,7 +80,12 @@ public function testOneVar() } EOTXT; - $expected = preg_replace('/%(.*?)%/', '(isset($context["$1"]) ? $context["$1"] : null)', $expected); + + if (PHP_VERSION_ID >= 70000) { + $expected = preg_replace('/%(.*?)%/', '($context["$1"] ?? null)', $expected); + } else { + $expected = preg_replace('/%(.*?)%/', '(isset($context["$1"]) ? $context["$1"] : null)', $expected); + } $this->assertSame($expected, $compiler->compile($node)->getSource()); } @@ -106,7 +111,12 @@ public function testMultiVars() } EOTXT; - $expected = preg_replace('/%(.*?)%/', '(isset($context["$1"]) ? $context["$1"] : null)', $expected); + + if (PHP_VERSION_ID >= 70000) { + $expected = preg_replace('/%(.*?)%/', '($context["$1"] ?? null)', $expected); + } else { + $expected = preg_replace('/%(.*?)%/', '(isset($context["$1"]) ? $context["$1"] : null)', $expected); + } $this->assertSame($expected, $compiler->compile($node)->getSource()); } diff --git a/src/Symfony/Bridge/Twig/Tests/Node/FormThemeTest.php b/src/Symfony/Bridge/Twig/Tests/Node/FormThemeTest.php index 52d79eb6129f8..ce0eade671c25 100644 --- a/src/Symfony/Bridge/Twig/Tests/Node/FormThemeTest.php +++ b/src/Symfony/Bridge/Twig/Tests/Node/FormThemeTest.php @@ -66,6 +66,10 @@ public function testCompile() protected function getVariableGetter($name) { + if (PHP_VERSION_ID >= 70000) { + return sprintf('($context["%s"] ?? null)', $name, $name); + } + return sprintf('(isset($context["%s"]) ? $context["%s"] : null)', $name, $name); } } diff --git a/src/Symfony/Bridge/Twig/Tests/Node/SearchAndRenderBlockNodeTest.php b/src/Symfony/Bridge/Twig/Tests/Node/SearchAndRenderBlockNodeTest.php index 599f2c8c34b00..3cf2ceb5a2fe5 100644 --- a/src/Symfony/Bridge/Twig/Tests/Node/SearchAndRenderBlockNodeTest.php +++ b/src/Symfony/Bridge/Twig/Tests/Node/SearchAndRenderBlockNodeTest.php @@ -263,6 +263,10 @@ public function testCompileLabelWithLabelThatEvaluatesToNullAndAttributes() protected function getVariableGetter($name) { + if (PHP_VERSION_ID >= 70000) { + return sprintf('($context["%s"] ?? null)', $name, $name); + } + return sprintf('(isset($context["%s"]) ? $context["%s"] : null)', $name, $name); } } diff --git a/src/Symfony/Bridge/Twig/Tests/Node/TransNodeTest.php b/src/Symfony/Bridge/Twig/Tests/Node/TransNodeTest.php index 9798e6ddf4b0c..4c00cdab50ade 100644 --- a/src/Symfony/Bridge/Twig/Tests/Node/TransNodeTest.php +++ b/src/Symfony/Bridge/Twig/Tests/Node/TransNodeTest.php @@ -39,15 +39,23 @@ public function testCompileStrict() protected function getVariableGetterWithoutStrictCheck($name) { + if (PHP_VERSION_ID >= 70000) { + return sprintf('($context["%s"] ?? null)', $name, $name); + } + return sprintf('(isset($context["%s"]) ? $context["%s"] : null)', $name, $name); } protected function getVariableGetterWithStrictCheck($name) { - if (version_compare(\Twig_Environment::VERSION, '2.0.0-DEV', '>=')) { + if (\Twig_Environment::MAJOR_VERSION >= 2) { return sprintf('(isset($context["%s"]) || array_key_exists("%s", $context) ? $context["%s"] : $this->notFound("%s", 0))', $name, $name, $name, $name); } - return sprintf('(isset($context["%1$s"]) ? $context["%1$s"] : $this->getContext($context, "%1$s"))', $name); + if (PHP_VERSION_ID >= 70000) { + return sprintf('($context["%s"] ?? $this->getContext($context, "%s"))', $name, $name, $name); + } + + return sprintf('(isset($context["%s"]) ? $context["%s"] : $this->getContext($context, "%s"))', $name, $name, $name); } } diff --git a/src/Symfony/Bridge/Twig/Translation/TwigExtractor.php b/src/Symfony/Bridge/Twig/Translation/TwigExtractor.php index 917687ad34eee..950c4d0810db0 100644 --- a/src/Symfony/Bridge/Twig/Translation/TwigExtractor.php +++ b/src/Symfony/Bridge/Twig/Translation/TwigExtractor.php @@ -64,7 +64,7 @@ public function extract($resource, MessageCatalogue $catalogue) if ($file instanceof SplFileInfo) { $e->setTemplateName($file->getRelativePathname()); } elseif ($file instanceof \SplFileInfo) { - $e->setTemplateName($file->getRealPath()); + $e->setTemplateName($file->getRealPath() ?: $file->getPathname()); } throw $e; diff --git a/src/Symfony/Bridge/Twig/TwigEngine.php b/src/Symfony/Bridge/Twig/TwigEngine.php index 3e3257e7fa0f5..1ac9d0102e63b 100644 --- a/src/Symfony/Bridge/Twig/TwigEngine.php +++ b/src/Symfony/Bridge/Twig/TwigEngine.php @@ -75,14 +75,14 @@ public function exists($name) $loader = $this->environment->getLoader(); - if ($loader instanceof \Twig_ExistsLoaderInterface) { + if ($loader instanceof \Twig_ExistsLoaderInterface || method_exists($loader, 'exists')) { return $loader->exists((string) $name); } try { // cast possible TemplateReferenceInterface to string because the // EngineInterface supports them but Twig_LoaderInterface does not - $loader->getSource((string) $name); + $loader->getSourceContext((string) $name)->getCode(); } catch (\Twig_Error_Loader $e) { return false; } diff --git a/src/Symfony/Bridge/Twig/composer.json b/src/Symfony/Bridge/Twig/composer.json index f61a045f57189..c38a72d3787c8 100644 --- a/src/Symfony/Bridge/Twig/composer.json +++ b/src/Symfony/Bridge/Twig/composer.json @@ -17,7 +17,7 @@ ], "require": { "php": ">=5.5.9", - "twig/twig": "~1.27|~2.0" + "twig/twig": "~1.28|~2.0" }, "require-dev": { "symfony/asset": "~2.8|~3.0", diff --git a/src/Symfony/Bundle/FrameworkBundle/Command/ConfigDebugCommand.php b/src/Symfony/Bundle/FrameworkBundle/Command/ConfigDebugCommand.php index 140d12fe35560..6f2021d1a0da8 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Command/ConfigDebugCommand.php +++ b/src/Symfony/Bundle/FrameworkBundle/Command/ConfigDebugCommand.php @@ -36,7 +36,7 @@ protected function configure() new InputArgument('name', InputArgument::OPTIONAL, 'The bundle name or the extension alias'), )) ->setDescription('Dumps the current configuration for an extension') - ->setHelp(<<setHelp(<<<'EOF' The %command.name% command dumps the current configuration for an extension/bundle. diff --git a/src/Symfony/Bundle/FrameworkBundle/Command/EventDispatcherDebugCommand.php b/src/Symfony/Bundle/FrameworkBundle/Command/EventDispatcherDebugCommand.php index 9732537362f1e..2eb310ddf1701 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Command/EventDispatcherDebugCommand.php +++ b/src/Symfony/Bundle/FrameworkBundle/Command/EventDispatcherDebugCommand.php @@ -39,7 +39,7 @@ protected function configure() new InputOption('raw', null, InputOption::VALUE_NONE, 'To output raw description'), )) ->setDescription('Displays configured listeners for an application') - ->setHelp(<<setHelp(<<<'EOF' The %command.name% command displays all configured listeners: php %command.full_name% diff --git a/src/Symfony/Bundle/FrameworkBundle/Command/ServerStartCommand.php b/src/Symfony/Bundle/FrameworkBundle/Command/ServerStartCommand.php index fdec77788d952..5e2f273ac8784 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Command/ServerStartCommand.php +++ b/src/Symfony/Bundle/FrameworkBundle/Command/ServerStartCommand.php @@ -41,7 +41,7 @@ protected function configure() )) ->setName('server:start') ->setDescription('Starts PHP built-in web server in the background') - ->setHelp(<<setHelp(<<<'EOF' The %command.name% runs PHP's built-in web server: php %command.full_name% diff --git a/src/Symfony/Bundle/FrameworkBundle/Command/ServerStopCommand.php b/src/Symfony/Bundle/FrameworkBundle/Command/ServerStopCommand.php index 9ce6c3b15e841..8f79978a9a845 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Command/ServerStopCommand.php +++ b/src/Symfony/Bundle/FrameworkBundle/Command/ServerStopCommand.php @@ -36,7 +36,7 @@ protected function configure() )) ->setName('server:stop') ->setDescription('Stops PHP\'s built-in web server that was started with the server:start command') - ->setHelp(<<setHelp(<<<'EOF' The %command.name% stops PHP's built-in web server: php %command.full_name% diff --git a/src/Symfony/Bundle/FrameworkBundle/Command/TranslationDebugCommand.php b/src/Symfony/Bundle/FrameworkBundle/Command/TranslationDebugCommand.php index 138964e286e53..3f0f2908a5ffa 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Command/TranslationDebugCommand.php +++ b/src/Symfony/Bundle/FrameworkBundle/Command/TranslationDebugCommand.php @@ -21,6 +21,8 @@ use Symfony\Component\Translation\Catalogue\MergeOperation; use Symfony\Component\Translation\MessageCatalogue; use Symfony\Component\Translation\Translator; +use Symfony\Component\Translation\DataCollectorTranslator; +use Symfony\Component\Translation\LoggingTranslator; /** * Helps finding unused or missing translation messages in a given locale @@ -50,7 +52,7 @@ protected function configure() new InputOption('all', null, InputOption::VALUE_NONE, 'Load messages from all registered bundles'), )) ->setDescription('Displays translation messages information') - ->setHelp(<<setHelp(<<<'EOF' The %command.name% command helps finding unused or missing translation messages and comparing them with the fallback ones by inspecting the templates and translation files of a given bundle or the app folder. @@ -295,7 +297,7 @@ private function loadFallbackCatalogues($locale, $transPaths, TranslationLoader { $fallbackCatalogues = array(); $translator = $this->getContainer()->get('translator'); - if ($translator instanceof Translator) { + if ($translator instanceof Translator || $translator instanceof DataCollectorTranslator || $translator instanceof LoggingTranslator) { foreach ($translator->getFallbackLocales() as $fallbackLocale) { if ($fallbackLocale === $locale) { continue; diff --git a/src/Symfony/Bundle/FrameworkBundle/Command/TranslationUpdateCommand.php b/src/Symfony/Bundle/FrameworkBundle/Command/TranslationUpdateCommand.php index 64874e70ef2cc..72298480b4e31 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Command/TranslationUpdateCommand.php +++ b/src/Symfony/Bundle/FrameworkBundle/Command/TranslationUpdateCommand.php @@ -119,9 +119,8 @@ protected function execute(InputInterface $input, OutputInterface $output) // load any messages from templates $extractedCatalogue = new MessageCatalogue($input->getArgument('locale')); $io->comment('Parsing templates...'); - $prefix = $input->getOption('prefix'); $extractor = $this->getContainer()->get('translation.extractor'); - $extractor->setPrefix(null === $prefix ? '' : $prefix); + $extractor->setPrefix($input->getOption('prefix')); foreach ($transPaths as $path) { $path .= 'views'; if (is_dir($path)) { diff --git a/src/Symfony/Bundle/FrameworkBundle/Command/YamlLintCommand.php b/src/Symfony/Bundle/FrameworkBundle/Command/YamlLintCommand.php index 19195674c0300..f7258c5771134 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Command/YamlLintCommand.php +++ b/src/Symfony/Bundle/FrameworkBundle/Command/YamlLintCommand.php @@ -34,7 +34,7 @@ protected function configure() ->setDescription('Lints a file and outputs encountered errors') ->addArgument('filename', null, 'A file or a directory or STDIN') ->addOption('format', null, InputOption::VALUE_REQUIRED, 'The output format', 'txt') - ->setHelp(<<setHelp(<<<'EOF' The %command.name% command lints a YAML file and outputs to STDOUT the first encountered syntax error. diff --git a/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Compiler/CachePoolPass.php b/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Compiler/CachePoolPass.php index 49e97b73c6402..1748862219ddf 100644 --- a/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Compiler/CachePoolPass.php +++ b/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Compiler/CachePoolPass.php @@ -84,7 +84,7 @@ public function process(ContainerBuilder $container) private function getNamespace($namespaceSuffix, $id) { - return substr(str_replace('/', '-', base64_encode(md5($id.$namespaceSuffix, true))), 0, 10); + return substr(str_replace('/', '-', base64_encode(hash('sha256', $id.$namespaceSuffix, true))), 0, 10); } /** diff --git a/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/FrameworkExtension.php b/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/FrameworkExtension.php index 2888ce4e5ba10..9e9d797191a4e 100644 --- a/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/FrameworkExtension.php +++ b/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/FrameworkExtension.php @@ -58,7 +58,7 @@ class FrameworkExtension extends Extension */ public function load(array $configs, ContainerBuilder $container) { - $loader = new XmlFileLoader($container, new FileLocator(__DIR__.'/../Resources/config')); + $loader = new XmlFileLoader($container, new FileLocator(dirname(__DIR__).'/Resources/config')); $loader->load('web.xml'); $loader->load('services.xml'); @@ -686,7 +686,7 @@ private function registerTranslatorConfiguration(array $config, ContainerBuilder if (class_exists('Symfony\Component\Security\Core\Exception\AuthenticationException')) { $r = new \ReflectionClass('Symfony\Component\Security\Core\Exception\AuthenticationException'); - $dirs[] = dirname($r->getFileName()).'/../Resources/translations'; + $dirs[] = dirname(dirname($r->getFileName())).'/Resources/translations'; } $rootDir = $container->getParameter('kernel.root_dir'); foreach ($container->getParameter('kernel.bundles') as $bundle => $class) { @@ -811,21 +811,21 @@ private function getValidatorMappingFiles(ContainerBuilder $container) $dirname = dirname($reflection->getFileName()); if (is_file($file = $dirname.'/Resources/config/validation.xml')) { - $files[0][] = realpath($file); + $files[0][] = $file; $container->addResource(new FileResource($file)); } if (is_file($file = $dirname.'/Resources/config/validation.yml')) { - $files[1][] = realpath($file); + $files[1][] = $file; $container->addResource(new FileResource($file)); } if (is_dir($dir = $dirname.'/Resources/config/validation')) { foreach (Finder::create()->files()->in($dir)->name('*.xml') as $file) { - $files[0][] = $file->getRealPath(); + $files[0][] = $file->getPathname(); } foreach (Finder::create()->files()->in($dir)->name('*.yml') as $file) { - $files[1][] = $file->getRealPath(); + $files[1][] = $file->getPathname(); } $container->addResource(new DirectoryResource($dir)); @@ -948,7 +948,7 @@ private function registerSerializerConfiguration(array $config, ContainerBuilder $dirname = dirname($reflection->getFileName()); if (is_file($file = $dirname.'/Resources/config/serialization.xml')) { - $definition = new Definition('Symfony\Component\Serializer\Mapping\Loader\XmlFileLoader', array(realpath($file))); + $definition = new Definition('Symfony\Component\Serializer\Mapping\Loader\XmlFileLoader', array($file)); $definition->setPublic(false); $serializerLoaders[] = $definition; @@ -956,7 +956,7 @@ private function registerSerializerConfiguration(array $config, ContainerBuilder } if (is_file($file = $dirname.'/Resources/config/serialization.yml')) { - $definition = new Definition('Symfony\Component\Serializer\Mapping\Loader\YamlFileLoader', array(realpath($file))); + $definition = new Definition('Symfony\Component\Serializer\Mapping\Loader\YamlFileLoader', array($file)); $definition->setPublic(false); $serializerLoaders[] = $definition; @@ -965,13 +965,13 @@ private function registerSerializerConfiguration(array $config, ContainerBuilder if (is_dir($dir = $dirname.'/Resources/config/serialization')) { foreach (Finder::create()->files()->in($dir)->name('*.xml') as $file) { - $definition = new Definition('Symfony\Component\Serializer\Mapping\Loader\XmlFileLoader', array($file->getRealPath())); + $definition = new Definition('Symfony\Component\Serializer\Mapping\Loader\XmlFileLoader', array($file->getPathname())); $definition->setPublic(false); $serializerLoaders[] = $definition; } foreach (Finder::create()->files()->in($dir)->name('*.yml') as $file) { - $definition = new Definition('Symfony\Component\Serializer\Mapping\Loader\YamlFileLoader', array($file->getRealPath())); + $definition = new Definition('Symfony\Component\Serializer\Mapping\Loader\YamlFileLoader', array($file->getPathname())); $definition->setPublic(false); $serializerLoaders[] = $definition; @@ -1037,7 +1037,7 @@ private function registerPropertyInfoConfiguration(array $config, ContainerBuild private function registerCacheConfiguration(array $config, ContainerBuilder $container) { - $version = substr(str_replace('/', '-', base64_encode(md5(uniqid(mt_rand(), true), true))), 0, -2); + $version = substr(str_replace('/', '-', base64_encode(hash('sha256', uniqid(mt_rand(), true), true))), 0, 22); $container->getDefinition('cache.adapter.apcu')->replaceArgument(2, $version); $container->getDefinition('cache.adapter.system')->replaceArgument(2, $version); $container->getDefinition('cache.adapter.filesystem')->replaceArgument(2, $config['directory']); @@ -1094,7 +1094,7 @@ private function getKernelRootHash(ContainerBuilder $container) */ public function getXsdValidationBasePath() { - return __DIR__.'/../Resources/config/schema'; + return dirname(__DIR__).'/Resources/config/schema'; } public function getNamespace() diff --git a/src/Symfony/Bundle/FrameworkBundle/Resources/config/serializer.xml b/src/Symfony/Bundle/FrameworkBundle/Resources/config/serializer.xml index 370b364cd9e78..c96e42c6084cb 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Resources/config/serializer.xml +++ b/src/Symfony/Bundle/FrameworkBundle/Resources/config/serializer.xml @@ -23,10 +23,15 @@ - + + + + + + diff --git a/src/Symfony/Bundle/FrameworkBundle/Resources/views/Form/number_widget.html.php b/src/Symfony/Bundle/FrameworkBundle/Resources/views/Form/number_widget.html.php index 324eb4782c2cc..bf4a4c478502b 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Resources/views/Form/number_widget.html.php +++ b/src/Symfony/Bundle/FrameworkBundle/Resources/views/Form/number_widget.html.php @@ -1 +1 @@ -block($form, 'form_widget_simple', array('type' => isset($type) ? $type : 'text')) ?> +block($form, 'form_widget_simple', array('type' => isset($type) ? $type : 'text')) ?> diff --git a/src/Symfony/Bundle/FrameworkBundle/Resources/views/Form/password_widget.html.php b/src/Symfony/Bundle/FrameworkBundle/Resources/views/Form/password_widget.html.php index 4390687a69330..ec96cfb46b24c 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Resources/views/Form/password_widget.html.php +++ b/src/Symfony/Bundle/FrameworkBundle/Resources/views/Form/password_widget.html.php @@ -1 +1 @@ -block($form, 'form_widget_simple', array('type' => isset($type) ? $type : 'password')) ?> +block($form, 'form_widget_simple', array('type' => isset($type) ? $type : 'password')) ?> diff --git a/src/Symfony/Bundle/FrameworkBundle/Resources/views/Form/percent_widget.html.php b/src/Symfony/Bundle/FrameworkBundle/Resources/views/Form/percent_widget.html.php index 59b29f4cbcfaa..8519da429b188 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Resources/views/Form/percent_widget.html.php +++ b/src/Symfony/Bundle/FrameworkBundle/Resources/views/Form/percent_widget.html.php @@ -1 +1 @@ -block($form, 'form_widget_simple', array('type' => isset($type) ? $type : 'text')) ?> % +block($form, 'form_widget_simple', array('type' => isset($type) ? $type : 'text')) ?> % diff --git a/src/Symfony/Bundle/FrameworkBundle/Resources/views/Form/reset_widget.html.php b/src/Symfony/Bundle/FrameworkBundle/Resources/views/Form/reset_widget.html.php index 1575e8292801e..e8fa18e488df8 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Resources/views/Form/reset_widget.html.php +++ b/src/Symfony/Bundle/FrameworkBundle/Resources/views/Form/reset_widget.html.php @@ -1 +1 @@ -block($form, 'button_widget', array('type' => isset($type) ? $type : 'reset')) ?> +block($form, 'button_widget', array('type' => isset($type) ? $type : 'reset')) ?> diff --git a/src/Symfony/Bundle/FrameworkBundle/Resources/views/Form/search_widget.html.php b/src/Symfony/Bundle/FrameworkBundle/Resources/views/Form/search_widget.html.php index 4e442f6ef47ae..48a33f4aa2dbc 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Resources/views/Form/search_widget.html.php +++ b/src/Symfony/Bundle/FrameworkBundle/Resources/views/Form/search_widget.html.php @@ -1 +1 @@ -block($form, 'form_widget_simple', array('type' => isset($type) ? $type : 'search')) ?> +block($form, 'form_widget_simple', array('type' => isset($type) ? $type : 'search')) ?> diff --git a/src/Symfony/Bundle/FrameworkBundle/Resources/views/Form/submit_widget.html.php b/src/Symfony/Bundle/FrameworkBundle/Resources/views/Form/submit_widget.html.php index d42bb2a78ffe9..6bf71f5a1e1c9 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Resources/views/Form/submit_widget.html.php +++ b/src/Symfony/Bundle/FrameworkBundle/Resources/views/Form/submit_widget.html.php @@ -1 +1 @@ -block($form, 'button_widget', array('type' => isset($type) ? $type : 'submit')) ?> +block($form, 'button_widget', array('type' => isset($type) ? $type : 'submit')) ?> diff --git a/src/Symfony/Bundle/FrameworkBundle/Resources/views/Form/url_widget.html.php b/src/Symfony/Bundle/FrameworkBundle/Resources/views/Form/url_widget.html.php index 0ce4ed2ca79fd..9e26318497b3c 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Resources/views/Form/url_widget.html.php +++ b/src/Symfony/Bundle/FrameworkBundle/Resources/views/Form/url_widget.html.php @@ -1 +1 @@ -block($form, 'form_widget_simple', array('type' => isset($type) ? $type : 'url')) ?> +block($form, 'form_widget_simple', array('type' => isset($type) ? $type : 'url')) ?> diff --git a/src/Symfony/Bundle/FrameworkBundle/Routing/Router.php b/src/Symfony/Bundle/FrameworkBundle/Routing/Router.php index 76bf546690725..afef4093db290 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Routing/Router.php +++ b/src/Symfony/Bundle/FrameworkBundle/Routing/Router.php @@ -160,7 +160,6 @@ private function resolve($value) gettype($resolved) ) ); - }, $value); return str_replace('%%', '%', $escapedValue); diff --git a/src/Symfony/Bundle/FrameworkBundle/Tests/Command/RouterMatchCommandTest.php b/src/Symfony/Bundle/FrameworkBundle/Tests/Command/RouterMatchCommandTest.php index 3c1728575081e..3dc64a300e8c6 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Tests/Command/RouterMatchCommandTest.php +++ b/src/Symfony/Bundle/FrameworkBundle/Tests/Command/RouterMatchCommandTest.php @@ -88,7 +88,6 @@ private function getContainer() ->will($this->returnValueMap(array( array('router', 1, $router), array('controller_name_converter', 1, $loader), - ))); return $container; diff --git a/src/Symfony/Bundle/FrameworkBundle/Tests/Command/TranslationDebugCommandTest.php b/src/Symfony/Bundle/FrameworkBundle/Tests/Command/TranslationDebugCommandTest.php index c99c0ace2ac77..27f61c4383f24 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Tests/Command/TranslationDebugCommandTest.php +++ b/src/Symfony/Bundle/FrameworkBundle/Tests/Command/TranslationDebugCommandTest.php @@ -136,7 +136,7 @@ private function getContainer($extractedMessages = array(), $loadedMessages = ar ->method('extract') ->will( $this->returnCallback(function ($path, $catalogue) use ($extractedMessages) { - $catalogue->add($extractedMessages); + $catalogue->add($extractedMessages); }) ); @@ -146,7 +146,7 @@ private function getContainer($extractedMessages = array(), $loadedMessages = ar ->method('loadMessages') ->will( $this->returnCallback(function ($path, $catalogue) use ($loadedMessages) { - $catalogue->add($loadedMessages); + $catalogue->add($loadedMessages); }) ); diff --git a/src/Symfony/Bundle/FrameworkBundle/Tests/Command/TranslationUpdateCommandTest.php b/src/Symfony/Bundle/FrameworkBundle/Tests/Command/TranslationUpdateCommandTest.php index 40eab748c62bf..536c59fae4709 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Tests/Command/TranslationUpdateCommandTest.php +++ b/src/Symfony/Bundle/FrameworkBundle/Tests/Command/TranslationUpdateCommandTest.php @@ -91,7 +91,7 @@ private function getContainer($extractedMessages = array(), $loadedMessages = ar ->method('extract') ->will( $this->returnCallback(function ($path, $catalogue) use ($extractedMessages) { - $catalogue->add($extractedMessages); + $catalogue->add($extractedMessages); }) ); @@ -101,7 +101,7 @@ private function getContainer($extractedMessages = array(), $loadedMessages = ar ->method('loadMessages') ->will( $this->returnCallback(function ($path, $catalogue) use ($loadedMessages) { - $catalogue->add($loadedMessages); + $catalogue->add($loadedMessages); }) ); diff --git a/src/Symfony/Bundle/FrameworkBundle/Tests/Console/Descriptor/AbstractDescriptorTest.php b/src/Symfony/Bundle/FrameworkBundle/Tests/Console/Descriptor/AbstractDescriptorTest.php index 6644bb2a5c2e2..78a770da85a05 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Tests/Console/Descriptor/AbstractDescriptorTest.php +++ b/src/Symfony/Bundle/FrameworkBundle/Tests/Console/Descriptor/AbstractDescriptorTest.php @@ -129,6 +129,7 @@ public function getDescribeCallableTestData() } abstract protected function getDescriptor(); + abstract protected function getFormat(); private function assertDescription($expectedDescription, $describedObject, array $options = array()) diff --git a/src/Symfony/Bundle/FrameworkBundle/Tests/Console/Descriptor/ObjectsProvider.php b/src/Symfony/Bundle/FrameworkBundle/Tests/Console/Descriptor/ObjectsProvider.php index 4bd93f2ba3f71..5244072ae85cd 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Tests/Console/Descriptor/ObjectsProvider.php +++ b/src/Symfony/Bundle/FrameworkBundle/Tests/Console/Descriptor/ObjectsProvider.php @@ -158,9 +158,11 @@ class CallableClass public function __invoke() { } + public static function staticMethod() { } + public function method() { } diff --git a/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Compiler/CachePoolPassTest.php b/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Compiler/CachePoolPassTest.php index 1f77cdd0fe60b..53cb95837f7e8 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Compiler/CachePoolPassTest.php +++ b/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Compiler/CachePoolPassTest.php @@ -41,7 +41,7 @@ public function testNamespaceArgumentIsReplaced() $this->cachePoolPass->process($container); - $this->assertSame('VcRIZlUhEv', $cachePool->getArgument(0)); + $this->assertSame('kRFqMp5odS', $cachePool->getArgument(0)); } public function testArgsAreReplaced() @@ -61,7 +61,7 @@ public function testArgsAreReplaced() $this->assertInstanceOf(Reference::class, $cachePool->getArgument(0)); $this->assertSame('foobar', (string) $cachePool->getArgument(0)); - $this->assertSame('VcRIZlUhEv', $cachePool->getArgument(1)); + $this->assertSame('kRFqMp5odS', $cachePool->getArgument(1)); $this->assertSame(3, $cachePool->getArgument(2)); } diff --git a/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/FrameworkExtensionTest.php b/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/FrameworkExtensionTest.php index 6f3149f083957..4e93a0e4f424c 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/FrameworkExtensionTest.php +++ b/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/FrameworkExtensionTest.php @@ -398,11 +398,11 @@ public function testValidationPaths() // Testing symfony/framework-bundle with deps=high $this->assertStringEndsWith('symfony'.DIRECTORY_SEPARATOR.'form/Resources/config/validation.xml', $xmlMappings[0]); } - $this->assertStringEndsWith('TestBundle'.DIRECTORY_SEPARATOR.'Resources'.DIRECTORY_SEPARATOR.'config'.DIRECTORY_SEPARATOR.'validation.xml', $xmlMappings[1]); + $this->assertStringEndsWith('TestBundle/Resources/config/validation.xml', $xmlMappings[1]); $yamlMappings = $calls[4][1][0]; $this->assertCount(1, $yamlMappings); - $this->assertStringEndsWith('TestBundle'.DIRECTORY_SEPARATOR.'Resources'.DIRECTORY_SEPARATOR.'config'.DIRECTORY_SEPARATOR.'validation.yml', $yamlMappings[0]); + $this->assertStringEndsWith('TestBundle/Resources/config/validation.yml', $yamlMappings[0]); } public function testValidationNoStaticMethod() diff --git a/src/Symfony/Bundle/FrameworkBundle/Tests/Fixtures/Resources/views/translation.html.php b/src/Symfony/Bundle/FrameworkBundle/Tests/Fixtures/Resources/views/translation.html.php index 04df261863f48..c0ae6ec5c6604 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Tests/Fixtures/Resources/views/translation.html.php +++ b/src/Symfony/Bundle/FrameworkBundle/Tests/Fixtures/Resources/views/translation.html.php @@ -1,7 +1,7 @@ This template is used for translation message extraction tests trans('single-quoted key') ?> trans('double-quoted key') ?> -trans(<<trans(<<<'EOF' heredoc key EOF ) ?> diff --git a/src/Symfony/Bundle/FrameworkBundle/Tests/Functional/SerializerTest.php b/src/Symfony/Bundle/FrameworkBundle/Tests/Functional/SerializerTest.php new file mode 100644 index 0000000000000..ee79850c47dfb --- /dev/null +++ b/src/Symfony/Bundle/FrameworkBundle/Tests/Functional/SerializerTest.php @@ -0,0 +1,58 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Bundle\FrameworkBundle\Tests\Functional; + +use Symfony\Component\Serializer\Normalizer\DataUriNormalizer; + +/** + * @author Kévin Dunglas + */ +class SerializerTest extends WebTestCase +{ + public function testDeserializeArrayOfObject() + { + if (!class_exists(DataUriNormalizer::class)) { + $this->markTestSkipped('This test is only applicable when using the Symfony Serializer Component version 3.1 or superior.'); + } + + static::bootKernel(array('test_case' => 'Serializer')); + $container = static::$kernel->getContainer(); + + $result = $container->get('serializer')->deserialize('{"bars": [{"id": 1}, {"id": 2}]}', Foo::class, 'json'); + + $bar1 = new Bar(); + $bar1->id = 1; + $bar2 = new Bar(); + $bar2->id = 2; + + $expected = new Foo(); + $expected->bars = array($bar1, $bar2); + + $this->assertEquals($expected, $result); + } +} + +class Foo +{ + /** + * @var Bar[] + */ + public $bars; +} + +class Bar +{ + /** + * @var int + */ + public $id; +} diff --git a/src/Symfony/Bundle/FrameworkBundle/Tests/Functional/app/Serializer/bundles.php b/src/Symfony/Bundle/FrameworkBundle/Tests/Functional/app/Serializer/bundles.php new file mode 100644 index 0000000000000..144db90236034 --- /dev/null +++ b/src/Symfony/Bundle/FrameworkBundle/Tests/Functional/app/Serializer/bundles.php @@ -0,0 +1,16 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +use Symfony\Bundle\FrameworkBundle\FrameworkBundle; + +return array( + new FrameworkBundle(), +); diff --git a/src/Symfony/Bundle/FrameworkBundle/Tests/Functional/app/Serializer/config.yml b/src/Symfony/Bundle/FrameworkBundle/Tests/Functional/app/Serializer/config.yml new file mode 100644 index 0000000000000..cac135c315d00 --- /dev/null +++ b/src/Symfony/Bundle/FrameworkBundle/Tests/Functional/app/Serializer/config.yml @@ -0,0 +1,6 @@ +imports: + - { resource: ../config/default.yml } + +framework: + serializer: { enabled: true } + property_info: { enabled: true } diff --git a/src/Symfony/Bundle/SecurityBundle/DataCollector/SecurityDataCollector.php b/src/Symfony/Bundle/SecurityBundle/DataCollector/SecurityDataCollector.php index 867a828a98cee..c0d702a3944ee 100644 --- a/src/Symfony/Bundle/SecurityBundle/DataCollector/SecurityDataCollector.php +++ b/src/Symfony/Bundle/SecurityBundle/DataCollector/SecurityDataCollector.php @@ -104,7 +104,7 @@ public function collect(Request $request, Response $response, \Exception $except 'token_class' => get_class($token), 'logout_url' => $logoutUrl, 'user' => $token->getUsername(), - 'roles' => array_map(function (RoleInterface $role) { return $role->getRole();}, $assignedRoles), + 'roles' => array_map(function (RoleInterface $role) { return $role->getRole(); }, $assignedRoles), 'inherited_roles' => array_map(function (RoleInterface $role) { return $role->getRole(); }, $inheritedRoles), 'supports_role_hierarchy' => null !== $this->roleHierarchy, ); diff --git a/src/Symfony/Bundle/SecurityBundle/DependencyInjection/MainConfiguration.php b/src/Symfony/Bundle/SecurityBundle/DependencyInjection/MainConfiguration.php index bf828ed22aa0e..b0aadc2f19e43 100644 --- a/src/Symfony/Bundle/SecurityBundle/DependencyInjection/MainConfiguration.php +++ b/src/Symfony/Bundle/SecurityBundle/DependencyInjection/MainConfiguration.php @@ -386,11 +386,10 @@ private function addEncodersSection(ArrayNodeDefinition $rootNode) ->children() ->arrayNode('encoders') ->example(array( - 'Acme\DemoBundle\Entity\User1' => 'sha512', - 'Acme\DemoBundle\Entity\User2' => array( - 'algorithm' => 'sha512', - 'encode_as_base64' => 'true', - 'iterations' => 5000, + 'AppBundle\Entity\User1' => 'bcrypt', + 'AppBundle\Entity\User2' => array( + 'algorithm' => 'bcrypt', + 'cost' => 13, ), )) ->requiresAtLeastOneElement() diff --git a/src/Symfony/Bundle/SecurityBundle/DependencyInjection/Security/Factory/SecurityFactoryInterface.php b/src/Symfony/Bundle/SecurityBundle/DependencyInjection/Security/Factory/SecurityFactoryInterface.php index 2b3310c61aae4..028e885246f61 100644 --- a/src/Symfony/Bundle/SecurityBundle/DependencyInjection/Security/Factory/SecurityFactoryInterface.php +++ b/src/Symfony/Bundle/SecurityBundle/DependencyInjection/Security/Factory/SecurityFactoryInterface.php @@ -25,7 +25,7 @@ interface SecurityFactoryInterface * Configures the container services required to use the authentication listener. * * @param ContainerBuilder $container - * @param string $id The unique id of the firewall + * @param string $id The unique id of the firewall * @param array $config The options array for the listener * @param string $userProvider The service id of the user provider * @param string $defaultEntryPoint @@ -48,7 +48,7 @@ public function getPosition(); /** * Defines the configuration key used to reference the provider * in the firewall configuration. - * + * * @return string */ public function getKey(); diff --git a/src/Symfony/Bundle/SecurityBundle/Tests/Functional/UserPasswordEncoderCommandTest.php b/src/Symfony/Bundle/SecurityBundle/Tests/Functional/UserPasswordEncoderCommandTest.php index 86a69fdb7624c..844349ff8c576 100644 --- a/src/Symfony/Bundle/SecurityBundle/Tests/Functional/UserPasswordEncoderCommandTest.php +++ b/src/Symfony/Bundle/SecurityBundle/Tests/Functional/UserPasswordEncoderCommandTest.php @@ -144,6 +144,7 @@ protected function setUp() $kernel->boot(); $application = new Application($kernel); + $application->setTerminalDimensions(119 + strlen(PHP_EOL), 80); $application->add(new UserPasswordEncoderCommand()); $passwordEncoderCommand = $application->find('security:encode-password'); diff --git a/src/Symfony/Bundle/SecurityBundle/composer.json b/src/Symfony/Bundle/SecurityBundle/composer.json index ca986735e2dcd..e14cde825bc17 100644 --- a/src/Symfony/Bundle/SecurityBundle/composer.json +++ b/src/Symfony/Bundle/SecurityBundle/composer.json @@ -39,7 +39,7 @@ "symfony/yaml": "~2.8|~3.0", "symfony/expression-language": "~2.8|~3.0", "doctrine/doctrine-bundle": "~1.4", - "twig/twig": "~1.27|~2.0" + "twig/twig": "~1.28|~2.0" }, "suggest": { "symfony/security-acl": "For using the ACL functionality of this bundle" diff --git a/src/Symfony/Bundle/TwigBundle/Controller/ExceptionController.php b/src/Symfony/Bundle/TwigBundle/Controller/ExceptionController.php index 1d348e8c31e07..f9e86c4daa21d 100644 --- a/src/Symfony/Bundle/TwigBundle/Controller/ExceptionController.php +++ b/src/Symfony/Bundle/TwigBundle/Controller/ExceptionController.php @@ -129,12 +129,12 @@ protected function templateExists($template) $template = (string) $template; $loader = $this->twig->getLoader(); - if ($loader instanceof \Twig_ExistsLoaderInterface) { + if ($loader instanceof \Twig_ExistsLoaderInterface || method_exists($loader, 'exists')) { return $loader->exists($template); } try { - $loader->getSource($template); + $loader->getSourceContext($template)->getCode(); return true; } catch (\Twig_Error_Loader $e) { diff --git a/src/Symfony/Bundle/TwigBundle/Loader/FilesystemLoader.php b/src/Symfony/Bundle/TwigBundle/Loader/FilesystemLoader.php index 4e0bef365ebbb..53fe300e29a62 100644 --- a/src/Symfony/Bundle/TwigBundle/Loader/FilesystemLoader.php +++ b/src/Symfony/Bundle/TwigBundle/Loader/FilesystemLoader.php @@ -58,6 +58,7 @@ public function exists($name) * Otherwise the template is located using the locator from the twig library. * * @param string|TemplateReferenceInterface $template The template + * @param bool $throw When true, a \Twig_Error_Loader exception will be thrown if a template could not be found * * @return string The path to the template file * @@ -87,7 +88,11 @@ protected function findTemplate($template, $throw = true) } if (false === $file || null === $file) { - throw $twigLoaderException; + if ($throw) { + throw $twigLoaderException; + } + + return false; } return $this->cache[$logicalName] = $file; diff --git a/src/Symfony/Bundle/TwigBundle/Tests/Controller/PreviewErrorControllerTest.php b/src/Symfony/Bundle/TwigBundle/Tests/Controller/PreviewErrorControllerTest.php index d64fc4a6b0f74..c8cdc305c30af 100644 --- a/src/Symfony/Bundle/TwigBundle/Tests/Controller/PreviewErrorControllerTest.php +++ b/src/Symfony/Bundle/TwigBundle/Tests/Controller/PreviewErrorControllerTest.php @@ -33,7 +33,6 @@ public function testForwardRequestToConfiguredController() ->method('handle') ->with( $this->callback(function (Request $request) use ($logicalControllerName, $code) { - $this->assertEquals($logicalControllerName, $request->attributes->get('_controller')); $exception = $request->attributes->get('exception'); diff --git a/src/Symfony/Bundle/TwigBundle/Tests/Loader/FilesystemLoaderTest.php b/src/Symfony/Bundle/TwigBundle/Tests/Loader/FilesystemLoaderTest.php index 9804c08a1923b..64ba490388f9f 100644 --- a/src/Symfony/Bundle/TwigBundle/Tests/Loader/FilesystemLoaderTest.php +++ b/src/Symfony/Bundle/TwigBundle/Tests/Loader/FilesystemLoaderTest.php @@ -115,4 +115,17 @@ public function testTwigErrorIfTemplateDoesNotExist() $method->setAccessible(true); $method->invoke($loader, 'name.format.engine'); } + + public function testTwigSoftErrorIfTemplateDoesNotExist() + { + $parser = $this->getMock('Symfony\Component\Templating\TemplateNameParserInterface'); + $locator = $this->getMock('Symfony\Component\Config\FileLocatorInterface'); + + $loader = new FilesystemLoader($locator, $parser); + $loader->addPath(__DIR__.'/../DependencyInjection/Fixtures/Resources/views'); + + $method = new \ReflectionMethod('Symfony\Bundle\TwigBundle\Loader\FilesystemLoader', 'findTemplate'); + $method->setAccessible(true); + $this->assertFalse($method->invoke($loader, 'name.format.engine', false)); + } } diff --git a/src/Symfony/Bundle/TwigBundle/composer.json b/src/Symfony/Bundle/TwigBundle/composer.json index 89b16de7f81eb..70649a3c64c03 100644 --- a/src/Symfony/Bundle/TwigBundle/composer.json +++ b/src/Symfony/Bundle/TwigBundle/composer.json @@ -21,7 +21,7 @@ "symfony/twig-bridge": "~2.8|~3.0", "symfony/http-foundation": "~2.8|~3.0", "symfony/http-kernel": "~2.8|~3.0", - "twig/twig": "~1.27|~2.0" + "twig/twig": "~1.28|~2.0" }, "require-dev": { "symfony/stopwatch": "~2.8|~3.0", diff --git a/src/Symfony/Bundle/WebProfilerBundle/Controller/ProfilerController.php b/src/Symfony/Bundle/WebProfilerBundle/Controller/ProfilerController.php index b6744c585579e..51dae4bb76dae 100644 --- a/src/Symfony/Bundle/WebProfilerBundle/Controller/ProfilerController.php +++ b/src/Symfony/Bundle/WebProfilerBundle/Controller/ProfilerController.php @@ -110,7 +110,7 @@ public function panelAction(Request $request, $token) 'panel' => $panel, 'page' => $page, 'request' => $request, - 'templates' => $this->getTemplateManager()->getTemplates($profile), + 'templates' => $this->getTemplateManager()->getNames($profile), 'is_ajax' => $request->isXmlHttpRequest(), 'profiler_markup_version' => 2, // 1 = original profiler, 2 = Symfony 2.8+ profiler )), 200, array('Content-Type' => 'text/html')); @@ -189,7 +189,7 @@ public function toolbarAction(Request $request, $token) 'request' => $request, 'position' => $position, 'profile' => $profile, - 'templates' => $this->getTemplateManager()->getTemplates($profile), + 'templates' => $this->getTemplateManager()->getNames($profile), 'profiler_url' => $url, 'token' => $token, 'profiler_markup_version' => 2, // 1 = original toolbar, 2 = Symfony 2.8+ toolbar diff --git a/src/Symfony/Bundle/WebProfilerBundle/Profiler/TemplateManager.php b/src/Symfony/Bundle/WebProfilerBundle/Profiler/TemplateManager.php index b0181afe87c12..696687fe019f9 100644 --- a/src/Symfony/Bundle/WebProfilerBundle/Profiler/TemplateManager.php +++ b/src/Symfony/Bundle/WebProfilerBundle/Profiler/TemplateManager.php @@ -67,7 +67,9 @@ public function getName(Profile $profile, $panel) * * @param Profile $profile * - * @return array + * @return Twig_Template[] + * + * @deprecated not used anymore internally */ public function getTemplates(Profile $profile) { @@ -89,7 +91,7 @@ public function getTemplates(Profile $profile) * * @throws \UnexpectedValueException */ - protected function getNames(Profile $profile) + public function getNames(Profile $profile) { $templates = array(); diff --git a/src/Symfony/Bundle/WebProfilerBundle/Resources/views/Collector/time.html.twig b/src/Symfony/Bundle/WebProfilerBundle/Resources/views/Collector/time.html.twig index 98ea6c3265d2a..6860230243106 100644 --- a/src/Symfony/Bundle/WebProfilerBundle/Resources/views/Collector/time.html.twig +++ b/src/Symfony/Bundle/WebProfilerBundle/Resources/views/Collector/time.html.twig @@ -60,10 +60,19 @@ Symfony initialization + {% if profile.collectors.memory %} +
+ {{ '%.2f'|format(profile.collectors.memory.memory / 1024 / 1024) }} MB + Peak memory usage +
+ {% endif %} + {% if profile.children|length > 0 %} +
+
{{ profile.children|length }} - Sub-Requests + Sub-Request{{ profile.children|length > 1 ? 's' }}
{% set subrequests_time = 0 %} @@ -73,14 +82,7 @@
{{ subrequests_time }} ms - Sub-Requests time -
- {% endif %} - - {% if profile.collectors.memory %} -
- {{ '%.2f'|format(profile.collectors.memory.memory / 1024 / 1024) }} MB - Peak memory usage + Sub-Request{{ profile.children|length > 1 ? 's' }} time
{% endif %} diff --git a/src/Symfony/Bundle/WebProfilerBundle/Resources/views/Profiler/layout.html.twig b/src/Symfony/Bundle/WebProfilerBundle/Resources/views/Profiler/layout.html.twig index 3207b3c95a4b2..146718ac30c7f 100644 --- a/src/Symfony/Bundle/WebProfilerBundle/Resources/views/Profiler/layout.html.twig +++ b/src/Symfony/Bundle/WebProfilerBundle/Resources/views/Profiler/layout.html.twig @@ -112,7 +112,11 @@ {% if templates is defined %}