diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md new file mode 100644 index 0000000000000..b03e61ef338c1 --- /dev/null +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -0,0 +1,11 @@ +| Q | A +| ------------- | --- +| Branch | master for features and deprecations / lowest applicable and maintained version otherwise +| Bug fix? | yes/no +| New feature? | yes/no +| BC breaks? | yes/no +| Deprecations? | yes/no +| Tests pass? | yes/no +| Fixed tickets | comma-separated list of tickets fixed by the PR, if any +| License | MIT +| Doc PR | reference to the documentation PR, if any diff --git a/.travis.yml b/.travis.yml index 99b2dc0671b9d..6d6101dccaf8d 100644 --- a/.travis.yml +++ b/.travis.yml @@ -2,6 +2,9 @@ language: php sudo: false +git: + depth: 1 + addons: apt_packages: - parallel @@ -31,16 +34,19 @@ cache: services: mongodb before_install: + # Matrix lines for intermediate PHP versions are skipped for pull requests - if [[ ! $deps && ! $TRAVIS_PHP_VERSION = ${MIN_PHP%.*} && $TRAVIS_PHP_VERSION != hhvm && $TRAVIS_PULL_REQUEST != false ]]; then deps=skip; fi; + # A sigchild-enabled-PHP is used to test the Process component on the lowest PHP matrix line - if [[ ! $deps && $TRAVIS_PHP_VERSION = ${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 [[ $TRAVIS_PHP_VERSION != hhvm ]]; then INI_FILE=~/.phpenv/versions/$(phpenv version-name)/etc/conf.d/travis.ini; else INI_FILE=/etc/hhvm/php.ini; fi; - echo memory_limit = -1 >> $INI_FILE - echo session.gc_probability = 0 >> $INI_FILE - if [[ $TRAVIS_PHP_VERSION = 5.* ]]; then echo extension = mongo.so >> $INI_FILE; fi; - if [[ $TRAVIS_PHP_VERSION = 5.* ]]; then echo extension = memcache.so >> $INI_FILE; fi; - - if [[ $TRAVIS_PHP_VERSION = 5.* ]]; then (echo yes | pecl install -f apcu-4.0.10 && echo apc.enable_cli = 1 >> $INI_FILE) || echo "Let's continue without apcu extension"; fi; - - if [[ $TRAVIS_PHP_VERSION = 5.* ]]; then pecl install -f memcached-2.1.0 || echo "Let's continue without memcached extension"; fi; + - if [[ $TRAVIS_PHP_VERSION = 5.* ]]; then (echo yes | pecl install -f apcu-4.0.10 && echo apc.enable_cli = 1 >> $INI_FILE); fi; + - if [[ $TRAVIS_PHP_VERSION = 7.* ]]; then (echo yes | pecl install -f apcu-5.1.2 && echo apc.enable_cli = 1 >> $INI_FILE); fi; - if [[ $TRAVIS_PHP_VERSION = 5.* && ! $deps ]]; then (cd src/Symfony/Component/Debug/Resources/ext && phpize && ./configure && make && echo extension = $(pwd)/modules/symfony_debug.so >> $INI_FILE); fi; + - if [[ $TRAVIS_PHP_VERSION = 5.* ]]; then pecl install -f memcached-2.1.0; fi; - if [[ $TRAVIS_PHP_VERSION != hhvm ]]; then echo extension = ldap.so >> $INI_FILE; fi; - if [[ $TRAVIS_PHP_VERSION != hhvm ]]; then phpenv config-rm xdebug.ini; fi; - if [[ $TRAVIS_REPO_SLUG = symfony/symfony ]]; then cp .composer-auth.json ~/.composer/auth.json; fi; @@ -50,9 +56,12 @@ before_install: install: - if [[ $deps != skip ]]; then COMPONENTS=$(find src/Symfony -mindepth 3 -type f -name phpunit.xml.dist -printf '%h\n'); fi; + # Create local composer packages for each patched components and reference them in composer.json files when cross-testing components - if [[ $deps != skip && $deps ]]; then php .travis.php $TRAVIS_COMMIT_RANGE $TRAVIS_BRANCH $COMPONENTS; fi; + # For the master branch when deps=high, the version before master is checked out and tested with the locally patched components - if [[ $deps = high && $TRAVIS_BRANCH = master ]]; then SYMFONY_VERSION=$(git ls-remote --heads | grep -o '/[1-9].*' | tail -n 1 | sed s/.//); else SYMFONY_VERSION=$(cat composer.json | grep '^ *"dev-master". *"[1-9]' | grep -o '[0-9.]*'); fi; - - if [[ $deps = high && $TRAVIS_BRANCH = master ]]; then git fetch origin $SYMFONY_VERSION; git checkout -m FETCH_HEAD; fi; + - if [[ $deps = high && $TRAVIS_BRANCH = master ]]; then git fetch origin $SYMFONY_VERSION; git checkout -m FETCH_HEAD; COMPONENTS=$(find src/Symfony -mindepth 3 -type f -name phpunit.xml.dist -printf '%h\n'); fi; + # Legacy tests are skipped when deps=high and when the current branch version has not the same major version number than the next one - if [[ $deps = high && ${SYMFONY_VERSION%.*} != $(git show $(git ls-remote --heads | grep -FA1 /$SYMFONY_VERSION | tail -n 1):composer.json | grep '^ *"dev-master". *"[1-9]' | grep -o '[0-9]*' | head -n 1) ]]; then LEGACY=,legacy; fi; - export COMPOSER_ROOT_VERSION=$SYMFONY_VERSION.x-dev; - if [[ ! $deps ]]; then composer update --prefer-dist; else export SYMFONY_DEPRECATIONS_HELPER=weak; fi; diff --git a/CHANGELOG-2.3.md b/CHANGELOG-2.3.md index f520c60219662..c8daee4e9253b 100644 --- a/CHANGELOG-2.3.md +++ b/CHANGELOG-2.3.md @@ -7,6 +7,21 @@ in 2.3 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/v2.3.0...v2.3.1 +* 2.3.37 (2016-01-14) + + * security #17359 do not ship with a custom rng implementation (xabbuh, fabpot) + * bug #17326 [Console] Display console application name even when no version set (polc) + * bug #17140 [Serializer] Remove normalizer cache in Serializer class (jvasseur) + * bug #17307 [FrameworkBundle] Fix paths with % in it (like urlencoded) (scaytrase) + * bug #17078 [Bridge] [Doctrine] [Validator] Added support \IteratorAggregate for UniqueEntityValidator (Disparity) + * bug #17287 [HttpKernel] Forcing string comparison on query parameters sort in UriSigner (Tim van Densen) + * bug #17278 [FrameworkBundle] Add case in Kernel directory guess for PHPUnit (tgalopin) + * bug #17276 [Process] Fix potential race condition (nicolas-grekas) + * bug #17183 [FrameworkBundle] Set the kernel.name properly after a cache warmup (jakzal) + * bug #17159 [Yaml] recognize when a block scalar is left (xabbuh) + * bug #17195 bug #14246 [Filesystem] dumpFile() non atomic (Hidde Boomsma) + * bug #17177 [Process] Fix potential race condition leading to transient tests (nicolas-grekas) + * 2.3.36 (2015-12-26) * bug #16864 [Yaml] fix indented line handling in folded blocks (xabbuh) @@ -14,7 +29,7 @@ To get the diff between two versions, go to https://github.com/symfony/symfony/c * bug #17129 [Config] Fix array sort on normalization in edge case (romainneutron) * bug #17094 [Process] More robustness and deterministic tests (nicolas-grekas) * bug #17112 [PropertyAccess] Reorder elements array after PropertyPathBuilder::replace (alekitto) - * bug #16797 [Filesystem] Recursivly widen non-executable directories (Slamdunk) + * bug #16797 [Filesystem] Recursively widen non-executable directories (Slamdunk) * bug #17040 [Console] Avoid extra blank lines when rendering exceptions (ogizanagi) * bug #17055 [Security] Verify if a password encoded with bcrypt is no longer than 72 characters (jakzal) * bug #16959 [Form] fix #15544 when a collection type attribute "required" is false, "prototype" should too (HeahDude) diff --git a/CHANGELOG-2.7.md b/CHANGELOG-2.7.md index 2b6005c098882..329281615440f 100644 --- a/CHANGELOG-2.7.md +++ b/CHANGELOG-2.7.md @@ -7,6 +7,79 @@ in 2.7 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/v2.7.0...v2.7.1 +* 2.7.10 (2016-02-28) + + * bug #17947 Fix - #17676 (backport #17919 to 2.3) (Ocramius) + * bug #17942 Fix bug when using an private aliased factory service (WouterJ) + * bug #17798 [Form] Fix BC break by allowing 'choice_label' option to be 'false' in ChoiceType (HeahDude) + * bug #17542 ChoiceFormField of type "select" could be "disabled" (bouland) + * bug #17602 [HttpFoundation] Fix BinaryFileResponse incorrect behavior with if-range header (bburnichon) + * bug #17760 [Form] fix choice value "false" in ChoiceType (HeahDude) + * bug #17914 [Console] Fix escaping of trailing backslashes (nicolas-grekas) + * bug #17074 Fix constraint validator alias being required (Triiistan) + * bug #17866 [DependencyInjection] replace alias in factories (xabbuh) + * bug #17867 [DependencyInjection] replace alias in factory services (xabbuh) + * bug #17569 [FrameworkBundle] read commands from bundles when accessing list (havvg) + * bug #16987 [FileSystem] Windows fix (flip111) + * bug #17787 [Form] Fix choice placeholder edge cases (Tobion) + * bug #17835 [Yaml] fix default timezone to be UTC (xabbuh) + * bug #17823 [DependencyInjection] fix dumped YAML string (xabbuh) + * bug #17818 [Console] InvalidArgumentException is thrown under wrong condition (robinkanters) + * bug #17819 [HttpKernel] Prevent a fatal error when DebugHandlersListener is used with a kernel with no terminateWithException() method (jakzal) + * bug #17814 [DependencyInjection] fix dumped YAML snytax (xabbuh) + * bug #17099 [Form] Fixed violation mapping if multiple forms are using the same (or part of the same) property path (alekitto) + * bug #17694 [DoctrineBridge] [Form] fix choice_value in EntityType (HeahDude) + * bug #17719 [DependencyInjection] fixed exceptions thrown by get method of ContainerBuilder (lukaszmakuch) + * bug #17742 [DependencyInjection] Fix #16461 Container::set() replace aliases (mnapoli) + * bug #17745 Added more exceptions to singularify method (javiereguiluz) + * bug #17691 Fixed (string) catchable fatal error for PHP Incomplete Class instances (yceruto) + * bug #17766 Fixed (string) catchable fatal error for PHP Incomplete Class instances (yceruto) + * bug #17757 [HttpFoundation] BinaryFileResponse sendContent return as parent. (2.3) (SpacePossum) + * bug #17702 [TwigBridge] forward compatibility with Yaml 3.1 (xabbuh) + * bug #17672 [DependencyInjection][Routing] add files used in FileResource objects (xabbuh) + * bug #17600 Fixed the Bootstrap form theme for inlined checkbox/radio (javiereguiluz) + * bug #17596 [Translation] Add resources from fallback locale to parent catalogue (c960657) + * bug #17605 [FrameworkBundle] remove default null value for asset version (xabbuh) + * bug #17606 [DependencyInjection] pass triggerDeprecationError arg to parent class (xabbuh) + * bug #16956 [DependencyInjection] XmlFileLoader: enforce tags to have a name (xabbuh) + * bug #16265 [BrowserKit] Corrected HTTP_HOST logic (Naktibalda) + * bug #17554 [DependencyInjection] resolve aliases in factories (xabbuh) + * bug #17555 [DependencyInjection] resolve aliases in factory services (xabbuh) + * bug #17511 [Form] ArrayChoiceList can now deal with a null in choices (issei-m) + * bug #17430 [Serializer] Ensure that groups are strings (dunglas) + * bug #15272 [FrameworkBundle] Fix template location for PHP templates (jakzal) + * bug #11232 [Routing] Fixes fatal errors with object resources in AnnotationDirectoryLoader::supports (Tischoi) + * bug #17526 Escape the delimiter in Glob::toRegex (javiereguiluz) + * bug #17527 fixed undefined variable (fabpot) + * bug #15706 [framework-bundle] Added support for the `0.0.0.0/0` trusted proxy (zerkms) + * bug #16274 [HttpKernel] Lookup the response even if the lock was released after two second wait (jakzal) + * bug #17355 [DoctrineBridge][Validator] >= 2.3 Pass association instead of ID as argument (xavismeh) + * bug #17454 Allow absolute URLs to be displayed in the debug toolbar (javiereguiluz) + * bug #16736 [Request] Ignore invalid IP addresses sent by proxies (GromNaN) + * bug #17486 [FrameworkBundle] Throw for missing container extensions (kix) + * bug #16873 Able to load big xml files with DomCrawler (zorn-v) + * bug #16897 [Form] Fix constraints could be null if not set (DZunke) + * bug #16912 [Translation][Writer] avoid calling setBackup if the dumper is not FileDumper (aitboudad) + * bug #17505 sort bundles in config:dump-reference command (xabbuh) + * bug #17514 [Asset] Add defaultNull to version configuration (ewgRa) + * bug #16511 [Asset] Ability to set empty version strategy in packages (ewgRa) + * bug #17503 [Asset] CLI: use request context to generate absolute URLs (xabbuh) + * bug #17478 [HttpFoundation] Do not overwrite the Authorization header if it is already set (jakzal) + * bug #17461 [Yaml] tag for dumped PHP objects must be a local one (xabbuh) + * bug #17456 [DX] Remove default match from AbstractConfigCommand::findExtension (kix) + * bug #17424 [Process] Update in 2.7 for stream-based output storage (romainneutron) + * bug #17423 [Process] Use stream based storage to avoid memory issues (romainneutron) + * bug #17406 [Form] ChoiceType: Fix a notice when 'choices' normalizer is replaced (paradajozsef) + * bug #17433 [FrameworkBundle] Don't log twice with the error handler (nicolas-grekas) + * bug #17418 Fixed Bootstrap form theme form "reset" buttons (javiereguiluz) + * bug #17404 fix merge 2.3 into 2.7 for SecureRandom dependency (Tobion) + * bug #17373 [SecurityBundle] fix SecureRandom service constructor args (Tobion) + * bug #17380 [TwigBridge] Use label_format option for checkbox and radio labels (enumag) + * bug #17377 Fix performance (PHP5) and memory (PHP7) issues when using token_get_all (nicolas-grekas, peteward) + * bug #17389 [Routing] Fixed correct class name in thrown exception (fixes #17388) (robinvdvleuten) + * bug #17358 [ClassLoader] Use symfony/polyfill-apcu (nicolas-grekas) + * bug #17370 [HttpFoundation][Cookie] Cookie DateTimeInterface fix (wildewouter) + * 2.7.9 (2016-01-14) * security #17359 do not ship with a custom rng implementation (xabbuh, fabpot) @@ -40,7 +113,7 @@ To get the diff between two versions, go to https://github.com/symfony/symfony/c * bug #17129 [Config] Fix array sort on normalization in edge case (romainneutron) * bug #17094 [Process] More robustness and deterministic tests (nicolas-grekas) * bug #17112 [PropertyAccess] Reorder elements array after PropertyPathBuilder::replace (alekitto) - * bug #16797 [Filesystem] Recursivly widen non-executable directories (Slamdunk) + * bug #16797 [Filesystem] Recursively widen non-executable directories (Slamdunk) * bug #17040 [Console] Avoid extra blank lines when rendering exceptions (ogizanagi) * bug #17055 [Security] Verify if a password encoded with bcrypt is no longer than 72 characters (jakzal) * bug #16959 [Form] fix #15544 when a collection type attribute "required" is false, "prototype" should too (HeahDude) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 123d5aa755911..ae18925cb6e20 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -5,29 +5,20 @@ Symfony is an open source, community-driven project. If you'd like to contribute, please read the following documents: -* [Contributing Code][1]: The document index related to contributions; - -* [Submitting a Patch][2]: Guidelines for submitting a pull request; - -* [Pull Request Template][3]: Template header to use in your pull request - description; - -```markdown -| Q | A -| ------------- | --- -| Bug fix? | yes/no -| New feature? | yes/no -| BC breaks? | no -| Deprecations? | no -| Tests pass? | yes -| Fixed tickets | #1234 -| License | MIT -| Doc PR | symfony/symfony-docs#1234 -``` - -* [Backwards Compatibility][4]: Backward compatibility rules. - -[1]: https://symfony.com/doc/current/contributing/code/index.html -[2]: https://symfony.com/doc/current/contributing/code/patches.html#check-list -[3]: https://symfony.com/doc/current/contributing/code/patches.html#make-a-pull-request -[4]: https://symfony.com/doc/current/contributing/code/bc.html#working-on-symfony-code +* [Reporting a Bug][1] +* [Submitting a Patch][2] +* [Symfony Core Team][3] +* [Security Issues][4] +* [Running Symfony Tests][5] +* [Our Backwards Compatibility Promise][6] +* [Coding Standards][7] +* [Conventions][8] + +[1]: https://symfony.com/doc/current/contributing/code/bugs.html +[2]: https://symfony.com/doc/current/contributing/code/patches.html +[3]: https://symfony.com/doc/current/contributing/code/core_team.html +[4]: https://symfony.com/doc/current/contributing/code/security.html +[5]: https://symfony.com/doc/current/contributing/code/tests.html +[6]: https://symfony.com/doc/current/contributing/code/bc.html +[7]: https://symfony.com/doc/current/contributing/code/standards.html +[8]: https://symfony.com/doc/current/contributing/code/conventions.html diff --git a/CONTRIBUTORS.md b/CONTRIBUTORS.md index e131844910157..5786f19dde7d6 100644 --- a/CONTRIBUTORS.md +++ b/CONTRIBUTORS.md @@ -75,45 +75,45 @@ Symfony is the result of the work of many people who made the code better - Arnaud Le Blanc (arnaud-lb) - Tim Nagel (merk) - Brice BERNARD (brikou) + - Graham Campbell (graham) - Jérôme Tamarelle (gromnan) - marc.weistroff + - Michal Piotrowski (eventhorizon) - lenar - - Graham Campbell (graham) - Włodzimierz Gajda (gajdaw) - - Michal Piotrowski (eventhorizon) - Florian Voutzinos (florianv) - Peter Rehm (rpet) - Colin Frei + - Dariusz Ruminski - Adrien Brault (adrienbrault) - excelwebzone - Jacob Dreesen (jdreesen) - - Dariusz Ruminski - Peter Kokot (maastermedia) - Fabien Pennequin (fabienpennequin) - Pierre du Plessis (pierredup) - Alexander Schwenn (xelaris) - Gordon Franke (gimler) + - Iltar van der Berg (kjarli) - Robert Schönthal (digitalkaoz) - Jérémy DERUSSÉ (jderusse) - Joshua Thijssen - Stefano Sala (stefano.sala) - David Buchmann (dbu) - Issei Murasawa (issei_m) - - Iltar van der Berg (kjarli) - Juti Noppornpitak (shiroyuki) - Eric GELOEN (gelo) - Sebastian Hörl (blogsh) - Daniel Gomes (danielcsgomes) - Hidenori Goto (hidenorigoto) + - Vladimir Reznichenko (kalessil) - Guilherme Blanco (guilhermeblanco) - Pablo Godel (pgodel) - - Vladimir Reznichenko (kalessil) + - Tigran Azatyan (tigranazatyan) - Jérémie Augustin (jaugustin) - Sebastiaan Stok (sstok) - Rafael Dohms (rdohms) - Arnaud Kleinpeter (nanocom) - Alexander M. Turek (derrabus) - - Tigran Azatyan (tigranazatyan) - Richard Shank (iampersistent) - Charles Sarrazin (csarrazi) - Clemens Tolboom @@ -149,6 +149,7 @@ Symfony is the result of the work of many people who made the code better - sun (sun) - Larry Garfield (crell) - Martin Schuhfuß (usefulthink) + - Jáchym Toušek - Matthieu Bontemps (mbontemps) - Pierre Minnieur (pminnieur) - fivestar @@ -166,7 +167,6 @@ Symfony is the result of the work of many people who made the code better - Rui Marinho (ruimarinho) - Julien Brochet (mewt) - Sergey Linnik (linniksa) - - Jáchym Toušek - Marcel Beerta (mazen) - Vincent AUBERT (vincent) - julien pauli (jpauli) @@ -177,6 +177,7 @@ Symfony is the result of the work of many people who made the code better - Elnur Abdurrakhimov (elnur) - Manuel Reinhard (sprain) - Danny Berger (dpb587) + - Diego Saint Esteben (dosten) - Roman Marintšenko (inori) - Xavier Montaña Carreras (xmontana) - Chris Wilkinson (thewilkybarkid) @@ -207,7 +208,6 @@ Symfony is the result of the work of many people who made the code better - Ruben Gonzalez (rubenrua) - Marcos Sánchez - Kim Hemsø Rasmussen (kimhemsoe) - - Diego Saint Esteben (dosten) - Tom Van Looy (tvlooy) - Wouter Van Hecke - Peter Kruithof (pkruithof) @@ -237,6 +237,7 @@ Symfony is the result of the work of many people who made the code better - Jan Decavele (jandc) - Gustavo Piltcher - Stepan Tanasiychuk (stfalcon) + - Titouan Galopin (tgalopin) - Tiago Ribeiro (fixe) - Bob den Otter (bopp) - Adrian Rudnik (kreischweide) @@ -321,6 +322,7 @@ Symfony is the result of the work of many people who made the code better - Jan Schumann - Niklas Fiekas - Mark Challoner (markchalloner) + - Gregor Harlan (gharlan) - Markus Bachmann (baachi) - lancergr - Olivier Dolbeau (odolbeau) @@ -337,6 +339,7 @@ Symfony is the result of the work of many people who made the code better - cedric lombardot (cedriclombardot) - Jonas Flodén (flojon) - Christian Schmidt + - Jakub Kucharovic (jkucharovic) - Marcin Sikoń (marphi) - Dominik Zogg (dominik.zogg) - Mathieu Lemoine @@ -396,7 +399,6 @@ Symfony is the result of the work of many people who made the code better - MatTheCat - John Bafford (jbafford) - Denis Gorbachev (starfall) - - Titouan Galopin (tgalopin) - Steven Surowiec - Kevin Saliou (kbsali) - Ryan @@ -440,7 +442,6 @@ Symfony is the result of the work of many people who made the code better - Wang Jingyu - Åsmund Garfors - Maxime Douailin - - Gregor Harlan - Michael Hirschler (mvhirsch) - Javier López (loalf) - Reinier Kip @@ -457,7 +458,6 @@ Symfony is the result of the work of many people who made the code better - Tristan Maindron (tmaindron) - Ke WANG (yktd26) - Strate - - Jakub Kucharovic - Miquel Rodríguez Telep (mrtorrent) - Sergey Kolodyazhnyy (skolodyazhnyy) - umpirski @@ -507,6 +507,7 @@ Symfony is the result of the work of many people who made the code better - Joshua Nye - Dave Marshall (davedevelopment) - avorobiev + - Gladhon - Venu - Lars Vierbergen - Dennis Hotson @@ -572,6 +573,7 @@ Symfony is the result of the work of many people who made the code better - Aleksey Podskrebyshev - Steffen Roßkamp - David Marín Carreño (davefx) + - Hidde Boomsma (hboomsma) - Jörn Lang (j.lang) - mwsaz - Benoît Bourgeois @@ -615,6 +617,7 @@ Symfony is the result of the work of many people who made the code better - Benoît Merlet (trompette) - Koen Kuipers - datibbaw + - Sébastien Santoro - Raul Fraile (raulfraile) - sensio - Patrick Kaufmann @@ -686,6 +689,7 @@ Symfony is the result of the work of many people who made the code better - Max Beutel - Michal Trojanowski - Catalin Dan + - Mihai Stancu - nacho - Piotr Antosik (antek88) - Artem Lopata @@ -698,6 +702,7 @@ Symfony is the result of the work of many people who made the code better - Max Grigorian (maxakawizard) - benatespina (benatespina) - Denis Kop + - EdgarPE - jfcixmedia - Martijn Evers - Benjamin Paap (benjaminpaap) @@ -980,6 +985,7 @@ Symfony is the result of the work of many people who made the code better - Michal Gebauer - Gleb Sidora - David Stone + - Adrien Lucas (adrienlucas) - Pablo Maria Martelletti (pmartelletti) - Yassine Guedidi (yguedidi) - Luis Muñoz @@ -1056,6 +1062,7 @@ Symfony is the result of the work of many people who made the code better - devel - Trevor Suarez - gedrox + - Mathieu MARCHOIS - dropfen - Andrey Chernykh - Edvinas Klovas @@ -1179,7 +1186,6 @@ Symfony is the result of the work of many people who made the code better - srsbiz - Taylan Kasap - Nicolas A. Bérard-Nault - - Gladhon - Saem Ghani - Stefan Oderbolz - Curtis @@ -1233,6 +1239,7 @@ Symfony is the result of the work of many people who made the code better - Eric J. Duran - cmfcmf - Drew Butler + - pawel-lewtak - Steve Müller - Andras Ratz - andreabreu98 @@ -1260,7 +1267,6 @@ Symfony is the result of the work of many people who made the code better - Pierre-Louis LAUNAY - djama - Eduardo Conceição - - Sébastien Santoro - Jon Cave - Sébastien HOUZE - Abdulkadir N. A. diff --git a/UPGRADE-2.7.md b/UPGRADE-2.7.md index f52220fadc2ed..5de67ebede36c 100644 --- a/UPGRADE-2.7.md +++ b/UPGRADE-2.7.md @@ -596,11 +596,11 @@ TwigBundle FrameworkBundle --------------- - * The `templating.helper.assets` was refactored and returns now an object of the type + * The `templating.helper.assets` service was refactored and now returns an object of type `Symfony\Bundle\FrameworkBundle\Templating\Helper\AssetsHelper` instead of `Symfony\Component\Templating\Helper\CoreAssetsHelper`. You can update your class definition or use the `assets.packages` service instead. Using the `assets.packages` service is the recommended - way. The `templating.helper.assets` service will be removed in Symfony 3.0. + way. Before: diff --git a/UPGRADE-3.0.md b/UPGRADE-3.0.md index ed919803eba7c..475fcbbc80d56 100644 --- a/UPGRADE-3.0.md +++ b/UPGRADE-3.0.md @@ -20,6 +20,12 @@ UPGRADE FROM 2.x to 3.0 `DebugClassLoader`. The difference is that the constructor now takes a loader to wrap. + +### Config + + * The `__toString()` method of the `\Symfony\Component\Config\ConfigCache` class + was removed in favor of the new `getPath()` method. + ### Console * The `dialog` helper has been removed in favor of the `question` helper. @@ -99,6 +105,26 @@ UPGRADE FROM 2.x to 3.0 removed: `ContainerBuilder::synchronize()`, `Definition::isSynchronized()`, and `Definition::setSynchronized()`. +### DoctrineBridge + + * The `property` option of `DoctrineType` was removed in favor of the `choice_label` option. + + * The `loader` option of `DoctrineType` was removed. You now have to override the `getLoader()` + method in your custom type. + + * The `Symfony\Bridge\Doctrine\Form\ChoiceList\EntityChoiceList` was removed in favor + of `Symfony\Bridge\Doctrine\Form\ChoiceList\DoctrineChoiceLoader`. + + * Passing a query builder closure to `ORMQueryBuilderLoader` is not supported anymore. + You should pass resolved query builders only. + + Consequently, the arguments `$manager` and `$class` of `ORMQueryBuilderLoader` + have been removed as well. + + Note that the `query_builder` option of `DoctrineType` *does* support + closures, but the closure is now resolved in the type instead of in the + loader. + ### EventDispatcher * The interface `Symfony\Component\EventDispatcher\Debug\TraceableEventDispatcherInterface` @@ -106,6 +132,11 @@ UPGRADE FROM 2.x to 3.0 ### Form + * The `ChoiceToBooleanArrayTransformer`, `ChoicesToBooleanArrayTransformer`, + `FixRadioInputListener`, and `FixCheckboxInputListener` classes were removed. + + * The `choice_list` option of `ChoiceType` was removed. + * The option "precision" was renamed to "scale". Before: @@ -271,11 +302,11 @@ UPGRADE FROM 2.x to 3.0 `NumberToLocalizedStringTransformer` were renamed to `ROUND_HALF_EVEN`, `ROUND_HALF_UP` and `ROUND_HALF_DOWN`. - * The methods `ChoiceListInterface::getIndicesForChoices()` and - `ChoiceListInterface::getIndicesForValues()` were removed. No direct - replacement exists, although in most cases - `ChoiceListInterface::getChoicesForValues()` and - `ChoiceListInterface::getValuesForChoices()` should be sufficient. + * The `Symfony\Component\Form\Extension\Core\ChoiceList\ChoiceListInterface` was + removed in favor of `Symfony\Component\Form\ChoiceList\ChoiceListInterface`. + + * `Symfony\Component\Form\Extension\Core\View\ChoiceView` was removed in favor of + `Symfony\Component\Form\ChoiceList\View\ChoiceView`. * The interface `Symfony\Component\Form\Extension\Csrf\CsrfProvider\CsrfProviderInterface` and all of its implementations were removed. Use the new interface @@ -357,51 +388,6 @@ UPGRADE FROM 2.x to 3.0 * The `request` service was removed. You must inject the `request_stack` service instead. - * The `templating.helper.assets` was removed in Symfony 3.0. You should - use the `assets.package` service instead. - - Before: - - ```php - use Symfony\Component\Templating\Helper\CoreAssetsHelper; - - class DemoService - { - private $assetsHelper; - - public function __construct(CoreAssetsHelper $assetsHelper) - { - $this->assetsHelper = $assetsHelper; - } - - public function testMethod() - { - return $this->assetsHelper->getUrl('thumbnail.png', null, $this->assetsHelper->getVersion()); - } - } - ``` - - After: - - ```php - use Symfony\Component\Asset\Packages; - - class DemoService - { - private $assetPackages; - - public function __construct(Packages $assetPackages) - { - $this->assetPackages = $assetPackages; - } - - public function testMethod() - { - return $this->assetPackages->getUrl('thumbnail.png').$this->assetPackages->getVersion(); - } - } - ``` - * The `enctype` method of the `form` helper was removed. You should use the new method `start` instead. @@ -544,7 +530,7 @@ UPGRADE FROM 2.x to 3.0 * Some route settings have been renamed: - * The `pattern` setting for a route has been deprecated in favor of `path` + * The `pattern` setting has been removed in favor of `path` * The `_scheme` and `_method` requirements have been moved to the `schemes` and `methods` settings Before: @@ -597,10 +583,23 @@ UPGRADE FROM 2.x to 3.0 the performance gains were minimal and it's hard to replicate the behaviour of PHP implementation. + * The `getMatcherDumperInstance()` and `getGeneratorDumperInstance()` methods in the + `Symfony\Component\Routing\Router` have been changed from `public` to `protected`. + ### Security * The `Resources/` directory was moved to `Core/Resources/` +### Serializer + + * The `setCamelizedAttributes()` method of the + `Symfony\Component\Serializer\Normalizer\GetSetMethodNormalizer` and + `Symfony\Component\Serializer\Normalizer\PropertyNormalizer` classes + was removed. + + * The `Symfony\Component\Serializer\Exception\Exception` interface was removed + in favor of the new `Symfony\Component\Serializer\Exception\ExceptionInterface`. + ### Translator * The `Translator::setFallbackLocale()` method has been removed in favor of @@ -665,11 +664,18 @@ UPGRADE FROM 2.x to 3.0 ### TwigBundle + * The `Symfony\Bundle\TwigBundle\TwigDefaultEscapingStrategy` was removed + in favor of `Twig_FileExtensionEscapingStrategy`. + * The `twig:debug` command has been deprecated since Symfony 2.7 and will be removed in Symfony 3.0. Use the `debug:twig` command instead. ### Validator + * The PHP7-incompatible constraints (`Null`, `True`, `False`) and their related + validators (`NullValidator`, `TrueValidator`, `FalseValidator`) have been + removed in favor of their `Is`-prefixed equivalent. + * The class `Symfony\Component\Validator\Mapping\Cache\ApcCache` has been removed in favor of `Symfony\Component\Validator\Mapping\Cache\DoctrineCache`. diff --git a/appveyor.yml b/appveyor.yml index 1c4e53cb93a62..7e498dc44a093 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -1,6 +1,5 @@ build: false -shallow_clone: true -platform: x86 +clone_depth: 1 clone_folder: c:\projects\symfony cache: @@ -14,6 +13,7 @@ init: - SET PHP=1 - SET ANSICON=121x90 (121x90) - SET SYMFONY_PHPUNIT_SKIPPED_TESTS=phpunit.skipped + - REG ADD "HKEY_CURRENT_USER\Software\Microsoft\Command Processor" /v DelayedExpansion /t REG_DWORD /d 1 /f install: - IF EXIST c:\php (SET PHP=0) ELSE (mkdir c:\php) @@ -57,7 +57,6 @@ install: test_script: - cd c:\projects\symfony - - Setlocal EnableDelayedExpansion - SET X=0 - copy /Y c:\php\php.ini-min c:\php\php.ini - php phpunit symfony --exclude-group benchmark,intl-data || SET X=!errorlevel! diff --git a/composer.json b/composer.json index 5efdcd3402399..3afdc35caff76 100644 --- a/composer.json +++ b/composer.json @@ -19,6 +19,7 @@ "php": ">=5.3.9", "doctrine/common": "~2.4", "paragonie/random_compat": "~1.0", + "symfony/polyfill-apcu": "~1.1", "twig/twig": "~1.23|~2.0", "psr/log": "~1.0" }, @@ -75,7 +76,7 @@ "doctrine/doctrine-bundle": "~1.2", "monolog/monolog": "~1.11", "ircmaxell/password-compat": "~1.0", - "ocramius/proxy-manager": "~0.4|~1.0", + "ocramius/proxy-manager": "~0.4|~1.0|~2.0", "egulias/email-validator": "~1.2" }, "autoload": { diff --git a/phpunit b/phpunit index 0517719add9e6..9cf03f071ecbf 100755 --- a/phpunit +++ b/phpunit @@ -27,7 +27,7 @@ if ('phpdbg' === PHP_SAPI) { $PHP .= ' -qrr'; } -$COMPOSER = file_exists($COMPOSER = __DIR__.'/composer.phar') || ($COMPOSER = rtrim('\\' === DIRECTORY_SEPARATOR ? `where.exe composer.phar` : `which composer.phar`)) +$COMPOSER = file_exists($COMPOSER = __DIR__.'/composer.phar') || ($COMPOSER = rtrim('\\' === DIRECTORY_SEPARATOR ? preg_replace('/[\r\n].*/', '', `where.exe composer.phar`) : `which composer.phar`)) ? $PHP.' '.ProcessUtils::escapeArgument($COMPOSER) : 'composer'; @@ -160,8 +160,8 @@ if (isset($argv[1]) && 'symfony' === $argv[1]) { unlink($file); } - // Fail on any individual component failures but ignore STATUS_STACK_BUFFER_OVERRUN (-1073740791) on Windows when APCu is enabled - if ($procStatus && ('\\' !== DIRECTORY_SEPARATOR || !extension_loaded('apcu') || !ini_get('apc.enable_cli') || -1073740791 !== $procStatus)) { + // Fail on any individual component failures but ignore STATUS_STACK_BUFFER_OVERRUN (-1073740791/0xC0000409) and STATUS_ACCESS_VIOLATION (-1073741819/0xC0000005) on Windows when APCu is enabled + if ($procStatus && ('\\' !== DIRECTORY_SEPARATOR || !extension_loaded('apcu') || !ini_get('apc.enable_cli') || (-1073740791 !== $procStatus && -1073741819 !== $procStatus))) { $exit = $procStatus; echo "\033[41mKO\033[0m $component\n\n"; } else { diff --git a/src/Symfony/Bridge/Doctrine/DependencyInjection/AbstractDoctrineExtension.php b/src/Symfony/Bridge/Doctrine/DependencyInjection/AbstractDoctrineExtension.php index 063b9359c7978..af584579c8a6c 100644 --- a/src/Symfony/Bridge/Doctrine/DependencyInjection/AbstractDoctrineExtension.php +++ b/src/Symfony/Bridge/Doctrine/DependencyInjection/AbstractDoctrineExtension.php @@ -153,7 +153,7 @@ protected function setMappingDriverConfig(array $mappingConfig, $mappingName) */ protected function getMappingDriverBundleConfigDefaults(array $bundleConfig, \ReflectionClass $bundle, ContainerBuilder $container) { - $bundleDir = dirname($bundle->getFilename()); + $bundleDir = dirname($bundle->getFileName()); if (!$bundleConfig['type']) { $bundleConfig['type'] = $this->detectMetadataDriver($bundleDir, $container); diff --git a/src/Symfony/Bridge/Doctrine/DependencyInjection/CompilerPass/DoctrineValidationPass.php b/src/Symfony/Bridge/Doctrine/DependencyInjection/CompilerPass/DoctrineValidationPass.php index de35c55219f2e..96f05eb5b60c9 100644 --- a/src/Symfony/Bridge/Doctrine/DependencyInjection/CompilerPass/DoctrineValidationPass.php +++ b/src/Symfony/Bridge/Doctrine/DependencyInjection/CompilerPass/DoctrineValidationPass.php @@ -60,7 +60,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)) { + if (is_file($file = dirname($reflection->getFileName()).'/'.$validationPath)) { $files[] = realpath($file); $container->addResource(new FileResource($file)); } diff --git a/src/Symfony/Bridge/Doctrine/Form/ChoiceList/DoctrineChoiceLoader.php b/src/Symfony/Bridge/Doctrine/Form/ChoiceList/DoctrineChoiceLoader.php index 1a09609b28556..2dc8c2cb2b28d 100644 --- a/src/Symfony/Bridge/Doctrine/Form/ChoiceList/DoctrineChoiceLoader.php +++ b/src/Symfony/Bridge/Doctrine/Form/ChoiceList/DoctrineChoiceLoader.php @@ -146,7 +146,7 @@ public function loadChoicesForValues(array $values, $value = null) // Optimize performance in case we have an object loader and // a single-field identifier - if (!$this->choiceList && $this->objectLoader && $this->idReader->isSingleId()) { + if (null === $value && !$this->choiceList && $this->objectLoader && $this->idReader->isSingleId()) { $unorderedObjects = $this->objectLoader->getEntitiesByIds($this->idReader->getIdField(), $values); $objectsById = array(); $objects = array(); diff --git a/src/Symfony/Bridge/Doctrine/Logger/DbalLogger.php b/src/Symfony/Bridge/Doctrine/Logger/DbalLogger.php index 2d834d7d404cd..acd8cc0fcd510 100644 --- a/src/Symfony/Bridge/Doctrine/Logger/DbalLogger.php +++ b/src/Symfony/Bridge/Doctrine/Logger/DbalLogger.php @@ -49,12 +49,8 @@ public function startQuery($sql, array $params = null, array $types = null) $this->stopwatch->start('doctrine', 'doctrine'); } - if (is_array($params)) { - $params = $this->normalizeParams($params); - } - if (null !== $this->logger) { - $this->log($sql, null === $params ? array() : $params); + $this->log($sql, null === $params ? array() : $this->normalizeParams($params)); } } diff --git a/src/Symfony/Bridge/Doctrine/Tests/Form/Type/EntityTypeTest.php b/src/Symfony/Bridge/Doctrine/Tests/Form/Type/EntityTypeTest.php index c5cdc60bbd342..c9ea820d95e97 100644 --- a/src/Symfony/Bridge/Doctrine/Tests/Form/Type/EntityTypeTest.php +++ b/src/Symfony/Bridge/Doctrine/Tests/Form/Type/EntityTypeTest.php @@ -740,6 +740,55 @@ public function testOverrideChoices() $this->assertSame('2', $field->getViewData()); } + public function testOverrideChoicesValues() + { + $entity1 = new SingleIntIdEntity(1, 'Foo'); + $entity2 = new SingleIntIdEntity(2, 'Bar'); + + $this->persist(array($entity1, $entity2)); + + $field = $this->factory->createNamed('name', 'entity', null, array( + 'em' => 'default', + 'class' => self::SINGLE_IDENT_CLASS, + 'choice_label' => 'name', + 'choice_value' => 'name', + )); + + $field->submit('Bar'); + + $this->assertEquals(array('Foo' => new ChoiceView($entity1, 'Foo', 'Foo'), 'Bar' => new ChoiceView($entity2, 'Bar', 'Bar')), $field->createView()->vars['choices']); + $this->assertTrue($field->isSynchronized(), 'Field should be synchronized.'); + $this->assertSame($entity2, $field->getData(), 'Entity should be loaded by custom value.'); + $this->assertSame('Bar', $field->getViewData()); + } + + public function testOverrideChoicesValuesWithCallable() + { + $entity1 = new GroupableEntity(1, 'Foo', 'BazGroup'); + $entity2 = new GroupableEntity(2, 'Bar', 'BooGroup'); + + $this->persist(array($entity1, $entity2)); + + $field = $this->factory->createNamed('name', 'entity', null, array( + 'em' => 'default', + 'class' => self::ITEM_GROUP_CLASS, + 'choice_label' => 'name', + 'choice_value' => function (GroupableEntity $entity) { + return $entity->groupName.'/'.$entity->name; + }, + )); + + $field->submit('BooGroup/Bar'); + + $this->assertEquals(array( + 'BazGroup/Foo' => new ChoiceView($entity1, 'BazGroup/Foo', 'Foo'), + 'BooGroup/Bar' => new ChoiceView($entity2, 'BooGroup/Bar', 'Bar'), + ), $field->createView()->vars['choices']); + $this->assertTrue($field->isSynchronized(), 'Field should be synchronized.'); + $this->assertSame($entity2, $field->getData(), 'Entity should be loaded by custom value.'); + $this->assertSame('BooGroup/Bar', $field->getViewData()); + } + public function testGroupByChoices() { $item1 = new GroupableEntity(1, 'Foo', 'Group1'); diff --git a/src/Symfony/Bridge/Doctrine/Tests/Validator/Constraints/UniqueEntityValidatorTest.php b/src/Symfony/Bridge/Doctrine/Tests/Validator/Constraints/UniqueEntityValidatorTest.php index c54556b243475..33e484320a56a 100644 --- a/src/Symfony/Bridge/Doctrine/Tests/Validator/Constraints/UniqueEntityValidatorTest.php +++ b/src/Symfony/Bridge/Doctrine/Tests/Validator/Constraints/UniqueEntityValidatorTest.php @@ -16,7 +16,6 @@ use Doctrine\Common\Persistence\ObjectManager; use Doctrine\Common\Persistence\ObjectRepository; use Symfony\Bridge\Doctrine\Test\DoctrineTestHelper; -use Symfony\Bridge\Doctrine\Tests\Fixtures\CompositeIntIdEntity; use Symfony\Bridge\Doctrine\Tests\Fixtures\SingleIntIdEntity; use Symfony\Bridge\Doctrine\Tests\Fixtures\DoubleNameEntity; use Symfony\Bridge\Doctrine\Tests\Fixtures\AssociationEntity; @@ -404,7 +403,7 @@ public function testAssociatedEntity() $this->buildViolation('myMessage') ->atPath('property.path.single') - ->setInvalidValue(1) + ->setInvalidValue($entity1) ->assertRaised(); } @@ -428,29 +427,6 @@ public function testAssociatedEntityWithNull() $this->assertNoViolation(); } - /** - * @expectedException \Symfony\Component\Validator\Exception\ConstraintDefinitionException - * @expectedExceptionMessage Associated entities are not allowed to have more than one identifier field - */ - public function testAssociatedCompositeEntity() - { - $constraint = new UniqueEntity(array( - 'message' => 'myMessage', - 'fields' => array('composite'), - 'em' => self::EM_NAME, - )); - - $composite = new CompositeIntIdEntity(1, 1, 'test'); - $associated = new AssociationEntity(); - $associated->composite = $composite; - - $this->em->persist($composite); - $this->em->persist($associated); - $this->em->flush(); - - $this->validator->validate($associated, $constraint); - } - /** * @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 edd972b9831fe..f4c8671abae9a 100644 --- a/src/Symfony/Bridge/Doctrine/Validator/Constraints/UniqueEntityValidator.php +++ b/src/Symfony/Bridge/Doctrine/Validator/Constraints/UniqueEntityValidator.php @@ -97,17 +97,6 @@ public function validate($entity, Constraint $constraint) * getter methods in the Proxy are being bypassed. */ $em->initializeObject($criteria[$fieldName]); - - $relatedClass = $em->getClassMetadata($class->getAssociationTargetClass($fieldName)); - $relatedId = $relatedClass->getIdentifierValues($criteria[$fieldName]); - - if (count($relatedId) > 1) { - throw new ConstraintDefinitionException( - 'Associated entities are not allowed to have more than one identifier field to be '. - 'part of a unique constraint in: '.$class->getName().'#'.$fieldName - ); - } - $criteria[$fieldName] = array_pop($relatedId); } } diff --git a/src/Symfony/Bridge/ProxyManager/LazyProxy/PhpDumper/ProxyDumper.php b/src/Symfony/Bridge/ProxyManager/LazyProxy/PhpDumper/ProxyDumper.php index bba5055d0085d..eb72a7d5d83cb 100644 --- a/src/Symfony/Bridge/ProxyManager/LazyProxy/PhpDumper/ProxyDumper.php +++ b/src/Symfony/Bridge/ProxyManager/LazyProxy/PhpDumper/ProxyDumper.php @@ -77,11 +77,17 @@ public function getProxyFactoryCode(Definition $definition, $id) $methodName = 'get'.Container::camelize($id).'Service'; $proxyClass = $this->getProxyClassName($definition); + $generatedClass = $this->generateProxyClass($definition); + + $constructorCall = $generatedClass->hasMethod('staticProxyConstructor') + ? $proxyClass.'::staticProxyConstructor' + : 'new '.$proxyClass; + return <<$methodName(false); @@ -101,11 +107,7 @@ function (&\$wrappedInstance, \ProxyManager\Proxy\LazyLoadingInterface \$proxy) */ public function getProxyCode(Definition $definition) { - $generatedClass = new ClassGenerator($this->getProxyClassName($definition)); - - $this->proxyGenerator->generate(new \ReflectionClass($definition->getClass()), $generatedClass); - - return $this->classGenerator->generate($generatedClass); + return $this->classGenerator->generate($this->generateProxyClass($definition)); } /** @@ -119,4 +121,18 @@ private function getProxyClassName(Definition $definition) { return str_replace('\\', '', $definition->getClass()).'_'.spl_object_hash($definition).$this->salt; } + + /** + * @param Definition $definition + * + * @return ClassGenerator + */ + private function generateProxyClass(Definition $definition) + { + $generatedClass = new ClassGenerator($this->getProxyClassName($definition)); + + $this->proxyGenerator->generate(new \ReflectionClass($definition->getClass()), $generatedClass); + + return $generatedClass; + } } diff --git a/src/Symfony/Bridge/ProxyManager/Tests/LazyProxy/Dumper/PhpDumperTest.php b/src/Symfony/Bridge/ProxyManager/Tests/LazyProxy/Dumper/PhpDumperTest.php index 412674ee3f680..5e451c122f3c4 100644 --- a/src/Symfony/Bridge/ProxyManager/Tests/LazyProxy/Dumper/PhpDumperTest.php +++ b/src/Symfony/Bridge/ProxyManager/Tests/LazyProxy/Dumper/PhpDumperTest.php @@ -49,7 +49,12 @@ public function testDumpContainerWithProxyService() */ public function testDumpContainerWithProxyServiceWillShareProxies() { - require_once __DIR__.'/../Fixtures/php/lazy_service.php'; + // detecting ProxyManager v2 + if (class_exists('ProxyManager\ProxyGenerator\LazyLoading\MethodGenerator\StaticProxyConstructor')) { + require_once __DIR__.'/../Fixtures/php/lazy_service_with_hints.php'; + } else { + require_once __DIR__.'/../Fixtures/php/lazy_service.php'; + } $container = new \LazyServiceProjectServiceContainer(); diff --git a/src/Symfony/Bridge/ProxyManager/Tests/LazyProxy/Fixtures/php/lazy_service_structure.txt b/src/Symfony/Bridge/ProxyManager/Tests/LazyProxy/Fixtures/php/lazy_service_structure.txt index 332370c87eb11..e2775cfa5f3d3 100644 --- a/src/Symfony/Bridge/ProxyManager/Tests/LazyProxy/Fixtures/php/lazy_service_structure.txt +++ b/src/Symfony/Bridge/ProxyManager/Tests/LazyProxy/Fixtures/php/lazy_service_structure.txt @@ -8,7 +8,7 @@ class ProjectServiceContainer extends Container if ($lazyLoad) { $container = $this; - return $this->services['foo'] = new stdClass_%s( + return $this->services['foo'] =%sstdClass_%s( function (&$wrappedInstance, \ProxyManager\Proxy\LazyLoadingInterface $proxy) use ($container) { $wrappedInstance = $container->getFooService(false); @@ -23,5 +23,5 @@ class ProjectServiceContainer extends Container } } -class stdClass_%s extends \stdClass implements \ProxyManager\Proxy\VirtualProxyInterface +class stdClass_%s extends \stdClass implements \ProxyManager\%s {%a}%A \ No newline at end of file diff --git a/src/Symfony/Bridge/ProxyManager/Tests/LazyProxy/Fixtures/php/lazy_service_with_hints.php b/src/Symfony/Bridge/ProxyManager/Tests/LazyProxy/Fixtures/php/lazy_service_with_hints.php new file mode 100644 index 0000000000000..349d899649c92 --- /dev/null +++ b/src/Symfony/Bridge/ProxyManager/Tests/LazyProxy/Fixtures/php/lazy_service_with_hints.php @@ -0,0 +1,189 @@ +services = array(); + } + + /** + * Gets the 'foo' service. + * + * This service is shared. + * This method always returns the same instance of the service. + * + * @param bool $lazyLoad whether to try lazy-loading the service with a proxy + * + * @return stdClass A stdClass instance. + */ + public function getFooService($lazyLoad = true) + { + if ($lazyLoad) { + $container = $this; + + return $this->services['foo'] = new stdClass_c1d194250ee2e2b7d2eab8b8212368a8( + function (&$wrappedInstance, \ProxyManager\Proxy\LazyLoadingInterface $proxy) use ($container) { + $wrappedInstance = $this->getFooService(false); + + $proxy->setProxyInitializer(null); + + return true; + } + ); + } + + return new \stdClass(); + } +} + +class stdClass_c1d194250ee2e2b7d2eab8b8212368a8 extends \stdClass implements \ProxyManager\Proxy\LazyLoadingInterface, \ProxyManager\Proxy\ValueHolderInterface +{ + /** + * @var \Closure|null initializer responsible for generating the wrapped object + */ + private $valueHolder5157dd96e88c0 = null; + + /** + * @var \Closure|null initializer responsible for generating the wrapped object + */ + private $initializer5157dd96e8924 = null; + + /** + * @override constructor for lazy initialization + * + * @param \Closure|null $initializer + */ + public function __construct($initializer) + { + $this->initializer5157dd96e8924 = $initializer; + } + + /** + * @param string $name + */ + public function __get($name) + { + $this->initializer5157dd96e8924 && $this->initializer5157dd96e8924->__invoke($this->valueHolder5157dd96e88c0, $this, '__get', array('name' => $name)); + + return $this->valueHolder5157dd96e88c0->$name; + } + + /** + * @param string $name + * @param mixed $value + */ + public function __set($name, $value) + { + $this->initializer5157dd96e8924 && $this->initializer5157dd96e8924->__invoke($this->valueHolder5157dd96e88c0, $this, '__set', array('name' => $name, 'value' => $value)); + + $this->valueHolder5157dd96e88c0->$name = $value; + } + + /** + * @param string $name + * + * @return bool + */ + public function __isset($name) + { + $this->initializer5157dd96e8924 && $this->initializer5157dd96e8924->__invoke($this->valueHolder5157dd96e88c0, $this, '__isset', array('name' => $name)); + + return isset($this->valueHolder5157dd96e88c0->$name); + } + + /** + * @param string $name + */ + public function __unset($name) + { + $this->initializer5157dd96e8924 && $this->initializer5157dd96e8924->__invoke($this->valueHolder5157dd96e88c0, $this, '__unset', array('name' => $name)); + + unset($this->valueHolder5157dd96e88c0->$name); + } + + /** + * + */ + public function __clone() + { + $this->initializer5157dd96e8924 && $this->initializer5157dd96e8924->__invoke($this->valueHolder5157dd96e88c0, $this, '__clone', array()); + + $this->valueHolder5157dd96e88c0 = clone $this->valueHolder5157dd96e88c0; + } + + /** + * + */ + public function __sleep() + { + $this->initializer5157dd96e8924 && $this->initializer5157dd96e8924->__invoke($this->valueHolder5157dd96e88c0, $this, '__sleep', array()); + + return array('valueHolder5157dd96e88c0'); + } + + /** + * + */ + public function __wakeup() + { + } + + /** + * {@inheritdoc} + */ + public function setProxyInitializer(\Closure $initializer = null) + { + $this->initializer5157dd96e8924 = $initializer; + } + + /** + * {@inheritdoc} + */ + public function getProxyInitializer() + { + return $this->initializer5157dd96e8924; + } + + /** + * {@inheritdoc} + */ + public function initializeProxy() : bool + { + return $this->initializer5157dd96e8924 && $this->initializer5157dd96e8924->__invoke($this->valueHolder5157dd96e88c0, $this, 'initializeProxy', array()); + } + + /** + * {@inheritdoc} + */ + public function isProxyInitialized() : bool + { + return null !== $this->valueHolder5157dd96e88c0; + } + + /** + * {@inheritdoc} + */ + public function getWrappedValueHolderValue() + { + return $this->valueHolder5157dd96e88c0; + } +} diff --git a/src/Symfony/Bridge/ProxyManager/Tests/LazyProxy/PhpDumper/ProxyDumperTest.php b/src/Symfony/Bridge/ProxyManager/Tests/LazyProxy/PhpDumper/ProxyDumperTest.php index fd20192d86e4f..0b98419f16203 100644 --- a/src/Symfony/Bridge/ProxyManager/Tests/LazyProxy/PhpDumper/ProxyDumperTest.php +++ b/src/Symfony/Bridge/ProxyManager/Tests/LazyProxy/PhpDumper/ProxyDumperTest.php @@ -69,7 +69,7 @@ public function testGetProxyFactoryCode() $code = $this->dumper->getProxyFactoryCode($definition, 'foo'); $this->assertStringMatchesFormat( - '%wif ($lazyLoad) {%w$container = $this;%wreturn $this->services[\'foo\'] = new ' + '%wif ($lazyLoad) {%w$container = $this;%wreturn $this->services[\'foo\'] =%s' .'SymfonyBridgeProxyManagerTestsLazyProxyPhpDumperProxyDumperTest_%s(%wfunction ' .'(&$wrappedInstance, \ProxyManager\Proxy\LazyLoadingInterface $proxy) use ($container) {' .'%w$wrappedInstance = $container->getFooService(false);%w$proxy->setProxyInitializer(null);' diff --git a/src/Symfony/Bridge/ProxyManager/composer.json b/src/Symfony/Bridge/ProxyManager/composer.json index 137d24b9e82e3..667d7b50c9837 100644 --- a/src/Symfony/Bridge/ProxyManager/composer.json +++ b/src/Symfony/Bridge/ProxyManager/composer.json @@ -18,7 +18,7 @@ "require": { "php": ">=5.3.9", "symfony/dependency-injection": "~2.3", - "ocramius/proxy-manager": "~0.4|~1.0" + "ocramius/proxy-manager": "~0.4|~1.0|~2.0" }, "require-dev": { "symfony/config": "~2.3" diff --git a/src/Symfony/Bridge/Twig/Extension/HttpFoundationExtension.php b/src/Symfony/Bridge/Twig/Extension/HttpFoundationExtension.php index ad7949dfaa682..69d6d326f4d08 100644 --- a/src/Symfony/Bridge/Twig/Extension/HttpFoundationExtension.php +++ b/src/Symfony/Bridge/Twig/Extension/HttpFoundationExtension.php @@ -13,6 +13,7 @@ use Symfony\Component\HttpFoundation\RequestStack; use Symfony\Component\HttpFoundation\Request; +use Symfony\Component\Routing\RequestContext; /** * Twig extension for the Symfony HttpFoundation component. @@ -22,10 +23,12 @@ class HttpFoundationExtension extends \Twig_Extension { private $requestStack; + private $requestContext; - public function __construct(RequestStack $requestStack) + public function __construct(RequestStack $requestStack, RequestContext $requestContext = null) { $this->requestStack = $requestStack; + $this->requestContext = $requestContext; } /** @@ -57,6 +60,23 @@ public function generateAbsoluteUrl($path) } if (!$request = $this->requestStack->getMasterRequest()) { + if (null !== $this->requestContext && '' !== $host = $this->requestContext->getHost()) { + $scheme = $this->requestContext->getScheme(); + $port = ''; + + if ('http' === $scheme && 80 != $this->requestContext->getHttpPort()) { + $port = ':'.$this->requestContext->getHttpPort(); + } elseif ('https' === $scheme && 443 != $this->requestContext->getHttpsPort()) { + $port = ':'.$this->requestContext->getHttpsPort(); + } + + if ('/' !== $path[0]) { + $path = rtrim($this->requestContext->getBaseUrl(), '/').'/'.$path; + } + + return $scheme.'://'.$host.$port.$path; + } + return $path; } diff --git a/src/Symfony/Bridge/Twig/Extension/YamlExtension.php b/src/Symfony/Bridge/Twig/Extension/YamlExtension.php index fc9bf0e9e3308..2d46795b4a81e 100644 --- a/src/Symfony/Bridge/Twig/Extension/YamlExtension.php +++ b/src/Symfony/Bridge/Twig/Extension/YamlExtension.php @@ -12,6 +12,7 @@ namespace Symfony\Bridge\Twig\Extension; use Symfony\Component\Yaml\Dumper as YamlDumper; +use Symfony\Component\Yaml\Yaml; /** * Provides integration of the Yaml component with Twig. @@ -39,6 +40,10 @@ public function encode($input, $inline = 0, $dumpObjects = false) $dumper = new YamlDumper(); } + if (defined('Symfony\Component\Yaml\Yaml::DUMP_OBJECT')) { + return $dumper->dump($input, $inline, 0, is_bool($dumpObjects) ? Yaml::DUMP_OBJECT : 0); + } + return $dumper->dump($input, $inline, 0, false, $dumpObjects); } diff --git a/src/Symfony/Bridge/Twig/Resources/views/Form/bootstrap_3_horizontal_layout.html.twig b/src/Symfony/Bridge/Twig/Resources/views/Form/bootstrap_3_horizontal_layout.html.twig index e997615d11378..5de20b1b8f181 100644 --- a/src/Symfony/Bridge/Twig/Resources/views/Form/bootstrap_3_horizontal_layout.html.twig +++ b/src/Symfony/Bridge/Twig/Resources/views/Form/bootstrap_3_horizontal_layout.html.twig @@ -65,6 +65,17 @@ col-sm-2 {% endspaceless %} {% endblock submit_row %} +{% block reset_row -%} +{% spaceless %} +
+
+
+ {{ form_widget(form) }} +
+
+{% endspaceless %} +{% endblock reset_row %} + {% block form_group_class -%} col-sm-10 {%- endblock form_group_class %} diff --git a/src/Symfony/Bridge/Twig/Resources/views/Form/bootstrap_3_layout.html.twig b/src/Symfony/Bridge/Twig/Resources/views/Form/bootstrap_3_layout.html.twig index 165236ef613ec..dfb1965ca1048 100644 --- a/src/Symfony/Bridge/Twig/Resources/views/Form/bootstrap_3_layout.html.twig +++ b/src/Symfony/Bridge/Twig/Resources/views/Form/bootstrap_3_layout.html.twig @@ -115,7 +115,7 @@ {%- endblock choice_widget_expanded %} {% block checkbox_widget -%} - {% set parent_label_class = parent_label_class|default('') -%} + {%- set parent_label_class = parent_label_class|default(label_attr.class|default('')) -%} {% if 'checkbox-inline' in parent_label_class %} {{- form_label(form, null, { widget: parent() }) -}} {% else -%} @@ -126,7 +126,7 @@ {%- endblock checkbox_widget %} {% block radio_widget -%} - {%- set parent_label_class = parent_label_class|default('') -%} + {%- set parent_label_class = parent_label_class|default(label_attr.class|default('')) -%} {% if 'radio-inline' in parent_label_class %} {{- form_label(form, null, { widget: parent() }) -}} {% else -%} @@ -167,7 +167,14 @@ {% set label_attr = label_attr|merge({class: (label_attr.class|default('') ~ ' ' ~ parent_label_class)|trim}) %} {% endif %} {% if label is not same as(false) and label is empty %} - {% set label = name|humanize %} + {%- if label_format is not empty -%} + {% set label = label_format|replace({ + '%name%': name, + '%id%': id, + }) %} + {%- else -%} + {% set label = name|humanize %} + {%- endif -%} {% endif %} {{- widget|raw }} {{ label is not same as(false) ? (translation_domain is same as(false) ? label : label|trans({}, translation_domain)) -}} diff --git a/src/Symfony/Bridge/Twig/Resources/views/Form/form_div_layout.html.twig b/src/Symfony/Bridge/Twig/Resources/views/Form/form_div_layout.html.twig index e3a611c38ffc7..ae5d7fbed4a4a 100644 --- a/src/Symfony/Bridge/Twig/Resources/views/Form/form_div_layout.html.twig +++ b/src/Symfony/Bridge/Twig/Resources/views/Form/form_div_layout.html.twig @@ -52,7 +52,7 @@ {%- endblock choice_widget_expanded -%} {%- block choice_widget_collapsed -%} - {%- if required and placeholder is none and not placeholder_in_choices and not multiple -%} + {%- if required and placeholder is none and not placeholder_in_choices and not multiple and (attr.size is not defined or attr.size <= 1) -%} {% set required = false %} {%- endif -%} block($form, 'widget_attributes', array( @@ -7,7 +7,7 @@ )) ?> multiple="multiple" > - + 0): ?> block($form, 'choice_widget_options', array('choices' => $preferred_choices)) ?> 0 && null !== $separator): ?> diff --git a/src/Symfony/Bundle/FrameworkBundle/Templating/TemplateNameParser.php b/src/Symfony/Bundle/FrameworkBundle/Templating/TemplateNameParser.php index e4a7053d25719..92fb94419d5af 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Templating/TemplateNameParser.php +++ b/src/Symfony/Bundle/FrameworkBundle/Templating/TemplateNameParser.php @@ -55,7 +55,7 @@ public function parse($name) throw new \RuntimeException(sprintf('Template name "%s" contains invalid characters.', $name)); } - if (!preg_match('/^([^:]*):([^:]*):(.+)\.([^\.]+)\.([^\.]+)$/', $name, $matches)) { + if (!preg_match('/^(?:([^:]*):)?(?:([^:]*):)?(.+)\.([^\.]+)\.([^\.]+)$/', $name, $matches)) { return parent::parse($name); } diff --git a/src/Symfony/Bundle/FrameworkBundle/Tests/Console/ApplicationTest.php b/src/Symfony/Bundle/FrameworkBundle/Tests/Console/ApplicationTest.php index 612d6325dd26d..fc0e7654db2ca 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Tests/Console/ApplicationTest.php +++ b/src/Symfony/Bundle/FrameworkBundle/Tests/Console/ApplicationTest.php @@ -11,8 +11,9 @@ namespace Symfony\Bundle\FrameworkBundle\Tests\Console; -use Symfony\Bundle\FrameworkBundle\Tests\TestCase; use Symfony\Bundle\FrameworkBundle\Console\Application; +use Symfony\Bundle\FrameworkBundle\Tests\TestCase; +use Symfony\Component\Console\Command\Command; use Symfony\Component\Console\Input\ArrayInput; use Symfony\Component\Console\Output\NullOutput; use Symfony\Component\Console\Tester\ApplicationTester; @@ -23,7 +24,7 @@ public function testBundleInterfaceImplementation() { $bundle = $this->getMock('Symfony\Component\HttpKernel\Bundle\BundleInterface'); - $kernel = $this->getKernel(array($bundle)); + $kernel = $this->getKernel(array($bundle), true); $application = new Application($kernel); $application->doRun(new ArrayInput(array('list')), new NullOutput()); @@ -34,10 +35,73 @@ public function testBundleCommandsAreRegistered() $bundle = $this->getMock('Symfony\Component\HttpKernel\Bundle\Bundle'); $bundle->expects($this->once())->method('registerCommands'); - $kernel = $this->getKernel(array($bundle)); + $kernel = $this->getKernel(array($bundle), true); $application = new Application($kernel); $application->doRun(new ArrayInput(array('list')), new NullOutput()); + + // Calling twice: registration should only be done once. + $application->doRun(new ArrayInput(array('list')), new NullOutput()); + } + + public function testBundleCommandsAreRetrievable() + { + $bundle = $this->getMock('Symfony\Component\HttpKernel\Bundle\Bundle'); + $bundle->expects($this->once())->method('registerCommands'); + + $kernel = $this->getKernel(array($bundle)); + + $application = new Application($kernel); + $application->all(); + + // Calling twice: registration should only be done once. + $application->all(); + } + + public function testBundleSingleCommandIsRetrievable() + { + $bundle = $this->getMock('Symfony\Component\HttpKernel\Bundle\Bundle'); + $bundle->expects($this->once())->method('registerCommands'); + + $kernel = $this->getKernel(array($bundle)); + + $application = new Application($kernel); + + $command = new Command('example'); + $application->add($command); + + $this->assertSame($command, $application->get('example')); + } + + public function testBundleCommandCanBeFound() + { + $bundle = $this->getMock('Symfony\Component\HttpKernel\Bundle\Bundle'); + $bundle->expects($this->once())->method('registerCommands'); + + $kernel = $this->getKernel(array($bundle)); + + $application = new Application($kernel); + + $command = new Command('example'); + $application->add($command); + + $this->assertSame($command, $application->find('example')); + } + + public function testBundleCommandCanBeFoundByAlias() + { + $bundle = $this->getMock('Symfony\Component\HttpKernel\Bundle\Bundle'); + $bundle->expects($this->once())->method('registerCommands'); + + $kernel = $this->getKernel(array($bundle)); + + $application = new Application($kernel); + + $command = new Command('example'); + $command->setAliases(array('alias')); + $application->add($command); + + $this->assertSame($command, $application->find('alias')); } public function testBundleCommandsHaveRightContainer() @@ -46,7 +110,7 @@ public function testBundleCommandsHaveRightContainer() $command->setCode(function () {}); $command->expects($this->exactly(2))->method('setContainer'); - $application = new Application($this->getKernel(array())); + $application = new Application($this->getKernel(array(), true)); $application->setAutoExit(false); $application->setCatchExceptions(false); $application->add($command); @@ -59,21 +123,23 @@ public function testBundleCommandsHaveRightContainer() $tester->run(array('command' => 'foo')); } - private function getKernel(array $bundles) + private function getKernel(array $bundles, $useDispatcher = false) { - $dispatcher = $this->getMock('Symfony\Component\EventDispatcher\EventDispatcherInterface'); - $dispatcher - ->expects($this->atLeastOnce()) - ->method('dispatch') - ; - $container = $this->getMock('Symfony\Component\DependencyInjection\ContainerInterface'); - $container - ->expects($this->atLeastOnce()) - ->method('get') - ->with($this->equalTo('event_dispatcher')) - ->will($this->returnValue($dispatcher)) - ; + + if ($useDispatcher) { + $dispatcher = $this->getMock('Symfony\Component\EventDispatcher\EventDispatcherInterface'); + $dispatcher + ->expects($this->atLeastOnce()) + ->method('dispatch') + ; + $container + ->expects($this->atLeastOnce()) + ->method('get') + ->with($this->equalTo('event_dispatcher')) + ->will($this->returnValue($dispatcher)); + } + $container ->expects($this->once()) ->method('hasParameter') diff --git a/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Compiler/AddConstraintValidatorsPassTest.php b/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Compiler/AddConstraintValidatorsPassTest.php new file mode 100644 index 0000000000000..0629d1ebafd1f --- /dev/null +++ b/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Compiler/AddConstraintValidatorsPassTest.php @@ -0,0 +1,87 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +use Symfony\Bundle\FrameworkBundle\DependencyInjection\Compiler\AddConstraintValidatorsPass; + +class AddConstraintValidatorsPassTest extends \PHPUnit_Framework_TestCase +{ + public function testThatConstraintValidatorServicesAreProcessed() + { + $services = array( + 'my_constraint_validator_service1' => array(0 => array('alias' => 'my_constraint_validator_alias1')), + 'my_constraint_validator_service2' => array(), + ); + + $validatorFactoryDefinition = $this->getMock('Symfony\Component\DependencyInjection\Definition'); + $container = $this->getMock( + 'Symfony\Component\DependencyInjection\ContainerBuilder', + array('findTaggedServiceIds', 'getDefinition', 'hasDefinition') + ); + + $validatorDefinition1 = $this->getMock('Symfony\Component\DependencyInjection\Definition', array('getClass')); + $validatorDefinition2 = $this->getMock('Symfony\Component\DependencyInjection\Definition', array('getClass')); + + $validatorDefinition1->expects($this->atLeastOnce()) + ->method('getClass') + ->willReturn('My\Fully\Qualified\Class\Named\Validator1'); + $validatorDefinition2->expects($this->atLeastOnce()) + ->method('getClass') + ->willReturn('My\Fully\Qualified\Class\Named\Validator2'); + + $container->expects($this->any()) + ->method('getDefinition') + ->with($this->anything()) + ->will($this->returnValueMap(array( + array('my_constraint_validator_service1', $validatorDefinition1), + array('my_constraint_validator_service2', $validatorDefinition2), + array('validator.validator_factory', $validatorFactoryDefinition), + ))); + + $container->expects($this->atLeastOnce()) + ->method('findTaggedServiceIds') + ->will($this->returnValue($services)); + $container->expects($this->atLeastOnce()) + ->method('hasDefinition') + ->with('validator.validator_factory') + ->will($this->returnValue(true)); + + $validatorFactoryDefinition->expects($this->once()) + ->method('replaceArgument') + ->with(1, array( + 'My\Fully\Qualified\Class\Named\Validator1' => 'my_constraint_validator_service1', + 'my_constraint_validator_alias1' => 'my_constraint_validator_service1', + 'My\Fully\Qualified\Class\Named\Validator2' => 'my_constraint_validator_service2', + )); + + $addConstraintValidatorsPass = new AddConstraintValidatorsPass(); + $addConstraintValidatorsPass->process($container); + } + + public function testThatCompilerPassIsIgnoredIfThereIsNoConstraintValidatorFactoryDefinition() + { + $definition = $this->getMock('Symfony\Component\DependencyInjection\Definition'); + $container = $this->getMock( + 'Symfony\Component\DependencyInjection\ContainerBuilder', + array('hasDefinition', 'findTaggedServiceIds', 'getDefinition') + ); + + $container->expects($this->never())->method('findTaggedServiceIds'); + $container->expects($this->never())->method('getDefinition'); + $container->expects($this->atLeastOnce()) + ->method('hasDefinition') + ->with('validator.validator_factory') + ->will($this->returnValue(false)); + $definition->expects($this->never())->method('replaceArgument'); + + $addConstraintValidatorsPass = new AddConstraintValidatorsPass(); + $addConstraintValidatorsPass->process($container); + } +} diff --git a/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/ConfigurationTest.php b/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/ConfigurationTest.php index f8bb4cb2fc735..e2c46c2ef67b6 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/ConfigurationTest.php +++ b/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/ConfigurationTest.php @@ -66,6 +66,7 @@ public function getTestValidTrustedProxiesData() array(array(), array()), array(array('10.0.0.0/8'), array('10.0.0.0/8')), array(array('::ffff:0:0/96'), array('::ffff:0:0/96')), + array(array('0.0.0.0/0'), array('0.0.0.0/0')), ); } diff --git a/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/php/assets.php b/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/php/assets.php index e3532a7747cc6..1055251004bd9 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/php/assets.php +++ b/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/php/assets.php @@ -20,6 +20,10 @@ 'bar' => array( 'base_urls' => array('https://bar2.example.com'), ), + 'bar_null_version' => array( + 'version' => null, + 'base_urls' => array('https://bar3.example.com'), + ), ), ), )); diff --git a/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/php/legacy_templating_assets.php b/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/php/legacy_templating_assets.php index 32bd56b3587d5..15df1015be15d 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/php/legacy_templating_assets.php +++ b/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/php/legacy_templating_assets.php @@ -18,6 +18,10 @@ 'bar' => array( 'base_urls' => array('https://bar2.example.com'), ), + 'bar_null_version' => array( + 'version' => null, + 'base_urls' => array('https://bar3.example.com'), + ), ), ), )); diff --git a/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/xml/assets.xml b/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/xml/assets.xml index e39e15f900528..3e057d5b90254 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/xml/assets.xml +++ b/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/xml/assets.xml @@ -18,6 +18,9 @@ https://bar2.example.com + + https://bar3.example.com + diff --git a/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/xml/legacy_templating_assets.xml b/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/xml/legacy_templating_assets.xml index 963848f767763..3b21e2cb4ed49 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/xml/legacy_templating_assets.xml +++ b/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/xml/legacy_templating_assets.xml @@ -18,6 +18,9 @@ https://bar2.example.com + + https://bar3.example.com + diff --git a/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/yml/assets.yml b/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/yml/assets.yml index 193dc59dfba3a..ba87d98b42ba6 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/yml/assets.yml +++ b/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/yml/assets.yml @@ -1,7 +1,7 @@ framework: assets: version: SomeVersionScheme - version_format: %%s?version=%%s + version_format: '%%s?version=%%s' base_urls: http://cdn.example.com packages: images_path: @@ -11,6 +11,9 @@ framework: base_urls: ["http://images1.example.com", "http://images2.example.com"] foo: version: 1.0.0 - version_format: %%s-%%s + version_format: '%%s-%%s' bar: base_urls: ["https://bar2.example.com"] + bar_null_version: + version: null + base_urls: "https://bar3.example.com" diff --git a/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/yml/full.yml b/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/yml/full.yml index be1b41e25f894..47dcb575317e3 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/yml/full.yml +++ b/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/yml/full.yml @@ -14,7 +14,7 @@ framework: only_exceptions: true enabled: false router: - resource: %kernel.root_dir%/config/routing.xml + resource: '%kernel.root_dir%/config/routing.xml' type: xml session: storage_id: session.storage.native @@ -45,7 +45,7 @@ framework: annotations: cache: file debug: true - file_cache_dir: %kernel.cache_dir%/annotations + file_cache_dir: '%kernel.cache_dir%/annotations' serializer: { enabled: true } ide: file%%link%%format request: diff --git a/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/yml/legacy_templating_assets.yml b/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/yml/legacy_templating_assets.yml index e8cc6ce41d31c..f2c8ecfec6701 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/yml/legacy_templating_assets.yml +++ b/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/yml/legacy_templating_assets.yml @@ -13,3 +13,6 @@ framework: version_format: %%s-%%s bar: base_urls: "https://bar2.example.com" + bar_null_version: + version: null + base_urls: "https://bar3.example.com" diff --git a/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/FrameworkExtensionTest.php b/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/FrameworkExtensionTest.php index 9f2482d5ad6b7..fd6c2ccaf2fcb 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/FrameworkExtensionTest.php +++ b/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/FrameworkExtensionTest.php @@ -22,6 +22,8 @@ abstract class FrameworkExtensionTest extends TestCase { + private static $containerCache = array(); + abstract protected function loadFromFile(ContainerBuilder $container, $file); public function testCsrfProtection() @@ -470,6 +472,10 @@ protected function createContainer(array $data = array()) protected function createContainerFromFile($file, $data = array()) { + $cacheKey = md5(get_class($this).$file.serialize($data)); + if (isset(self::$containerCache[$cacheKey])) { + return self::$containerCache[$cacheKey]; + } $container = $this->createContainer($data); $container->registerExtension(new FrameworkExtension()); $this->loadFromFile($container, $file); @@ -478,7 +484,7 @@ protected function createContainerFromFile($file, $data = array()) $container->getCompilerPassConfig()->setRemovingPasses(array()); $container->compile(); - return $container; + return self::$containerCache[$cacheKey] = $container; } protected function createContainerFromClosure($closure, $data = array()) @@ -505,7 +511,7 @@ private function checkAssetsPackages(ContainerBuilder $container, $legacy = fals // packages $packages = $packages->getArgument(1); - $this->assertCount($legacy ? 3 : 4, $packages); + $this->assertCount($legacy ? 4 : 5, $packages); if (!$legacy) { $package = $container->getDefinition($packages['images_path']); @@ -519,7 +525,10 @@ private function checkAssetsPackages(ContainerBuilder $container, $legacy = fals $this->assertPathPackage($container, $package, '', '1.0.0', '%%s-%%s'); $package = $container->getDefinition($packages['bar']); - $this->assertUrlPackage($container, $package, array('https://bar2.example.com'), $legacy ? '' : 'SomeVersionScheme', $legacy ? '%%s?%%s' : '%%s?version=%%s'); + $this->assertUrlPackage($container, $package, array('https://bar2.example.com'), $legacy ? null : 'SomeVersionScheme', $legacy ? '%%s?%%s' : '%%s?version=%%s'); + + $this->assertEquals($legacy ? 'assets.empty_version_strategy' : 'assets._version__default', (string) $container->getDefinition('assets._package_bar')->getArgument(1)); + $this->assertEquals('assets.empty_version_strategy', (string) $container->getDefinition('assets._package_bar_null_version')->getArgument(1)); } private function assertPathPackage(ContainerBuilder $container, DefinitionDecorator $package, $basePath, $version, $format) diff --git a/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/PhpFrameworkExtensionTest.php b/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/PhpFrameworkExtensionTest.php index 01c73930db8b1..b077e80dc43e3 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/PhpFrameworkExtensionTest.php +++ b/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/PhpFrameworkExtensionTest.php @@ -28,7 +28,7 @@ protected function loadFromFile(ContainerBuilder $container, $file) */ public function testAssetsCannotHavePathAndUrl() { - $container = $this->createContainerFromClosure(function ($container) { + $this->createContainerFromClosure(function ($container) { $container->loadFromExtension('framework', array( 'assets' => array( 'base_urls' => 'http://cdn.example.com', @@ -43,7 +43,7 @@ public function testAssetsCannotHavePathAndUrl() */ public function testAssetPackageCannotHavePathAndUrl() { - $container = $this->createContainerFromClosure(function ($container) { + $this->createContainerFromClosure(function ($container) { $container->loadFromExtension('framework', array( 'assets' => array( 'packages' => array( diff --git a/src/Symfony/Bundle/FrameworkBundle/Tests/Functional/app/Resources/fragment.html.php b/src/Symfony/Bundle/FrameworkBundle/Tests/Functional/app/Resources/views/fragment.html.php similarity index 100% rename from src/Symfony/Bundle/FrameworkBundle/Tests/Functional/app/Resources/fragment.html.php rename to src/Symfony/Bundle/FrameworkBundle/Tests/Functional/app/Resources/views/fragment.html.php diff --git a/src/Symfony/Bundle/FrameworkBundle/Tests/Templating/TemplateNameParserTest.php b/src/Symfony/Bundle/FrameworkBundle/Tests/Templating/TemplateNameParserTest.php index ca10c3a8fe861..4ff824bf7ca82 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Tests/Templating/TemplateNameParserTest.php +++ b/src/Symfony/Bundle/FrameworkBundle/Tests/Templating/TemplateNameParserTest.php @@ -43,30 +43,33 @@ protected function tearDown() } /** - * @dataProvider getLogicalNameToTemplateProvider + * @dataProvider parseProvider */ - public function testParse($name, $ref) + public function testParse($name, $logicalName, $path, $ref) { $template = $this->parser->parse($name); - $this->assertEquals($template->getLogicalName(), $ref->getLogicalName()); - $this->assertEquals($template->getLogicalName(), $name); + $this->assertSame($ref->getLogicalName(), $template->getLogicalName()); + $this->assertSame($logicalName, $template->getLogicalName()); + $this->assertSame($path, $template->getPath()); } - public function getLogicalNameToTemplateProvider() + public function parseProvider() { return array( - array('FooBundle:Post:index.html.php', new TemplateReference('FooBundle', 'Post', 'index', 'html', 'php')), - array('FooBundle:Post:index.html.twig', new TemplateReference('FooBundle', 'Post', 'index', 'html', 'twig')), - array('FooBundle:Post:index.xml.php', new TemplateReference('FooBundle', 'Post', 'index', 'xml', 'php')), - array('SensioFooBundle:Post:index.html.php', new TemplateReference('SensioFooBundle', 'Post', 'index', 'html', 'php')), - array('SensioCmsFooBundle:Post:index.html.php', new TemplateReference('SensioCmsFooBundle', 'Post', 'index', 'html', 'php')), - array(':Post:index.html.php', new TemplateReference('', 'Post', 'index', 'html', 'php')), - array('::index.html.php', new TemplateReference('', '', 'index', 'html', 'php')), - array('FooBundle:Post:foo.bar.index.html.php', new TemplateReference('FooBundle', 'Post', 'foo.bar.index', 'html', 'php')), - array('/path/to/section/name.php', new BaseTemplateReference('/path/to/section/name.php', 'php')), - array('name.twig', new BaseTemplateReference('name.twig', 'twig')), - array('name', new BaseTemplateReference('name')), + array('FooBundle:Post:index.html.php', 'FooBundle:Post:index.html.php', '@FooBundle/Resources/views/Post/index.html.php', new TemplateReference('FooBundle', 'Post', 'index', 'html', 'php')), + array('FooBundle:Post:index.html.twig', 'FooBundle:Post:index.html.twig', '@FooBundle/Resources/views/Post/index.html.twig', new TemplateReference('FooBundle', 'Post', 'index', 'html', 'twig')), + array('FooBundle:Post:index.xml.php', 'FooBundle:Post:index.xml.php', '@FooBundle/Resources/views/Post/index.xml.php', new TemplateReference('FooBundle', 'Post', 'index', 'xml', 'php')), + array('SensioFooBundle:Post:index.html.php', 'SensioFooBundle:Post:index.html.php', '@SensioFooBundle/Resources/views/Post/index.html.php', new TemplateReference('SensioFooBundle', 'Post', 'index', 'html', 'php')), + array('SensioCmsFooBundle:Post:index.html.php', 'SensioCmsFooBundle:Post:index.html.php', '@SensioCmsFooBundle/Resources/views/Post/index.html.php', new TemplateReference('SensioCmsFooBundle', 'Post', 'index', 'html', 'php')), + array(':Post:index.html.php', ':Post:index.html.php', 'views/Post/index.html.php', new TemplateReference('', 'Post', 'index', 'html', 'php')), + array('::index.html.php', '::index.html.php', 'views/index.html.php', new TemplateReference('', '', 'index', 'html', 'php')), + array('index.html.php', '::index.html.php', 'views/index.html.php', new TemplateReference('', '', 'index', 'html', 'php')), + array('FooBundle:Post:foo.bar.index.html.php', 'FooBundle:Post:foo.bar.index.html.php', '@FooBundle/Resources/views/Post/foo.bar.index.html.php', new TemplateReference('FooBundle', 'Post', 'foo.bar.index', 'html', 'php')), + array('/path/to/section/name.php', '/path/to/section/name.php', '/path/to/section/name.php', new BaseTemplateReference('/path/to/section/name.php', 'php')), + array('name.twig', 'name.twig', 'name.twig', new BaseTemplateReference('name.twig', 'twig')), + array('name', 'name', 'name', new BaseTemplateReference('name')), + array('default/index.html.php', '::default/index.html.php', 'views/default/index.html.php', new TemplateReference(null, null, 'default/index', 'html', 'php')), ); } diff --git a/src/Symfony/Bundle/FrameworkBundle/Translation/PhpExtractor.php b/src/Symfony/Bundle/FrameworkBundle/Translation/PhpExtractor.php index 21406feb49a5f..ca9e7f994c090 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Translation/PhpExtractor.php +++ b/src/Symfony/Bundle/FrameworkBundle/Translation/PhpExtractor.php @@ -60,6 +60,11 @@ public function extract($resource, MessageCatalogue $catalog) $files = $this->extractFiles($resource); foreach ($files as $file) { $this->parseTokens(token_get_all(file_get_contents($file)), $catalog); + + if (PHP_VERSION_ID >= 70000) { + // PHP 7 memory manager will not release after token_get_all(), see https://bugs.php.net/70098 + gc_mem_caches(); + } } } @@ -80,7 +85,7 @@ public function setPrefix($prefix) */ protected function normalizeToken($token) { - if (is_array($token)) { + if (isset($token[1]) && 'b"' !== $token) { return $token[1]; } @@ -94,7 +99,7 @@ private function seekToNextRelevantToken(\Iterator $tokenIterator) { for (; $tokenIterator->valid(); $tokenIterator->next()) { $t = $tokenIterator->current(); - if (!is_array($t) || ($t[0] !== T_WHITESPACE)) { + if (T_WHITESPACE !== $t[0]) { break; } } @@ -111,7 +116,7 @@ private function getMessage(\Iterator $tokenIterator) for (; $tokenIterator->valid(); $tokenIterator->next()) { $t = $tokenIterator->current(); - if (!is_array($t)) { + if (!isset($t[1])) { break; } diff --git a/src/Symfony/Bundle/FrameworkBundle/composer.json b/src/Symfony/Bundle/FrameworkBundle/composer.json index 045d19c354e73..bcfce7b707007 100644 --- a/src/Symfony/Bundle/FrameworkBundle/composer.json +++ b/src/Symfony/Bundle/FrameworkBundle/composer.json @@ -26,7 +26,7 @@ "symfony/http-kernel": "~2.7", "symfony/filesystem": "~2.3", "symfony/routing": "~2.6,>2.6.4", - "symfony/security-core": "~2.6", + "symfony/security-core": "~2.6.13|~2.7.9|~2.8", "symfony/security-csrf": "~2.6", "symfony/stopwatch": "~2.3", "symfony/templating": "~2.1", diff --git a/src/Symfony/Bundle/SecurityBundle/Resources/meta/LICENSE b/src/Symfony/Bundle/SecurityBundle/LICENSE similarity index 100% rename from src/Symfony/Bundle/SecurityBundle/Resources/meta/LICENSE rename to src/Symfony/Bundle/SecurityBundle/LICENSE diff --git a/src/Symfony/Bundle/SecurityBundle/Tests/DependencyInjection/CompleteConfigurationTest.php b/src/Symfony/Bundle/SecurityBundle/Tests/DependencyInjection/CompleteConfigurationTest.php index 5f139ca6e1157..8a0a14ddb32a8 100644 --- a/src/Symfony/Bundle/SecurityBundle/Tests/DependencyInjection/CompleteConfigurationTest.php +++ b/src/Symfony/Bundle/SecurityBundle/Tests/DependencyInjection/CompleteConfigurationTest.php @@ -19,6 +19,8 @@ abstract class CompleteConfigurationTest extends \PHPUnit_Framework_TestCase { + private static $containerCache = array(); + abstract protected function loadFromFile(ContainerBuilder $container, $file); public function testRolesHierarchy() @@ -235,6 +237,9 @@ public function testRememberMeThrowExceptions() protected function getContainer($file) { + if (isset(self::$containerCache[$file])) { + return self::$containerCache[$file]; + } $container = new ContainerBuilder(); $security = new SecurityExtension(); $container->registerExtension($security); @@ -247,6 +252,6 @@ protected function getContainer($file) $container->getCompilerPassConfig()->setRemovingPasses(array()); $container->compile(); - return $container; + return self::$containerCache[$file] = $container; } } diff --git a/src/Symfony/Bundle/SecurityBundle/Tests/Functional/app/config/twig.yml b/src/Symfony/Bundle/SecurityBundle/Tests/Functional/app/config/twig.yml index 861b1e709fd13..61c1a54d99ba5 100644 --- a/src/Symfony/Bundle/SecurityBundle/Tests/Functional/app/config/twig.yml +++ b/src/Symfony/Bundle/SecurityBundle/Tests/Functional/app/config/twig.yml @@ -3,5 +3,5 @@ framework: # Twig Configuration twig: - debug: %kernel.debug% - strict_variables: %kernel.debug% + debug: '%kernel.debug%' + strict_variables: '%kernel.debug%' diff --git a/src/Symfony/Bundle/TwigBundle/Resources/meta/LICENSE b/src/Symfony/Bundle/TwigBundle/LICENSE similarity index 100% rename from src/Symfony/Bundle/TwigBundle/Resources/meta/LICENSE rename to src/Symfony/Bundle/TwigBundle/LICENSE diff --git a/src/Symfony/Bundle/TwigBundle/Resources/config/twig.xml b/src/Symfony/Bundle/TwigBundle/Resources/config/twig.xml index 6a13980fcd048..f2c2a4cee007c 100644 --- a/src/Symfony/Bundle/TwigBundle/Resources/config/twig.xml +++ b/src/Symfony/Bundle/TwigBundle/Resources/config/twig.xml @@ -127,6 +127,7 @@ + diff --git a/src/Symfony/Bundle/WebProfilerBundle/Resources/meta/LICENSE b/src/Symfony/Bundle/WebProfilerBundle/LICENSE similarity index 100% rename from src/Symfony/Bundle/WebProfilerBundle/Resources/meta/LICENSE rename to src/Symfony/Bundle/WebProfilerBundle/LICENSE diff --git a/src/Symfony/Bundle/WebProfilerBundle/Resources/views/Collector/exception.css.twig b/src/Symfony/Bundle/WebProfilerBundle/Resources/views/Collector/exception.css.twig index 1224081bd600a..7730f55f09416 100644 --- a/src/Symfony/Bundle/WebProfilerBundle/Resources/views/Collector/exception.css.twig +++ b/src/Symfony/Bundle/WebProfilerBundle/Resources/views/Collector/exception.css.twig @@ -7,7 +7,6 @@ padding: 5px 4px; list-style-type: decimal; margin-left: 20px; - white-space: break-word; } .sf-reset #logs .traces li.error { font-style: normal; diff --git a/src/Symfony/Bundle/WebProfilerBundle/Resources/views/Collector/twig.html.twig b/src/Symfony/Bundle/WebProfilerBundle/Resources/views/Collector/twig.html.twig index 0ecd469bd0732..ba23a3c83db6b 100644 --- a/src/Symfony/Bundle/WebProfilerBundle/Resources/views/Collector/twig.html.twig +++ b/src/Symfony/Bundle/WebProfilerBundle/Resources/views/Collector/twig.html.twig @@ -3,7 +3,13 @@ {% block toolbar %} {% set time = collector.templatecount ? '%0.0f ms'|format(collector.time) : 'n/a' %} {% set icon %} - Twig + + + + + + + {{ time }} {% endset %} {% set text %} @@ -29,7 +35,15 @@ {% block menu %} - Twig + + + + + + + + + Twig {{ collector.templatecount }} diff --git a/src/Symfony/Bundle/WebProfilerBundle/Resources/views/Profiler/base_js.html.twig b/src/Symfony/Bundle/WebProfilerBundle/Resources/views/Profiler/base_js.html.twig index e313380e51095..8c10c95655317 100644 --- a/src/Symfony/Bundle/WebProfilerBundle/Resources/views/Profiler/base_js.html.twig +++ b/src/Symfony/Bundle/WebProfilerBundle/Resources/views/Profiler/base_js.html.twig @@ -223,7 +223,7 @@ path = url.substr({{ (request.schemeAndHttpHost ~ request.basePath)|length }}); } - if (path.substr(0, 1) === '/' && !path.match(new RegExp({{ excluded_ajax_paths|json_encode|raw }}))) { + if (!path.match(new RegExp({{ excluded_ajax_paths|json_encode|raw }}))) { var stackElement = { loading: true, error: false, diff --git a/src/Symfony/Bundle/WebProfilerBundle/Resources/views/Profiler/body.css.twig b/src/Symfony/Bundle/WebProfilerBundle/Resources/views/Profiler/body.css.twig index fa4d076917434..8373e44d0ac8d 100644 --- a/src/Symfony/Bundle/WebProfilerBundle/Resources/views/Profiler/body.css.twig +++ b/src/Symfony/Bundle/WebProfilerBundle/Resources/views/Profiler/body.css.twig @@ -116,7 +116,7 @@ build: 56 background: transparent url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAcAAAAcCAYAAACtQ6WLAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAR1JREFUeNpiPHnyZCMDA8MNID5gZmb2nAEJMH7//v3N169fX969e/cYkL8WqGAHXPLv37//QYzfv39/fvPmzbUnT56sAXInmJub/2H5/x8sx8DCwsIrISFhDmQyPX78+CmQXs70798/BmQsKipqBNTgdvz4cWkmkE5kDATMioqKZkCFdiwg1eiAi4tLGqhQF24nMmBmZuYEigth1QkEbEBxTlySYPvJkwSJ00AnjYylgU6gxB8g/oFVEphkvgLF32KNMmCCewYUv4qhEyj47+HDhyeBzIMYOoEp8CxQw56wsLAncJ1//vz5/P79+2svX74EJc2V4BT58+fPd8CE/QKYHMGJOiIiAp6oWW7evDkNSF8DZYfIyEiU7AAQYACJ2vxVdJW4eQAAAABJRU5ErkJggg==) right top no-repeat; } .sf-button .btn-bg { - padding: 0px 14px; + padding: 0 14px; color: #636363; line-height: 28px; background: transparent url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAAcCAYAAACgXdXMAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAClJREFUeNpiPnny5EKGf//+/Wf6//8/A4QAcrGzKCZwGc9sa2urBBBgAIbDUoYVp9lmAAAAAElFTkSuQmCC) repeat-x top left; 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 12728b964df0f..6be34406e6196 100644 --- a/src/Symfony/Bundle/WebProfilerBundle/Resources/views/Profiler/layout.html.twig +++ b/src/Symfony/Bundle/WebProfilerBundle/Resources/views/Profiler/layout.html.twig @@ -63,8 +63,7 @@