diff --git a/.appveyor.yml b/.appveyor.yml
index e0d8c17dc1f56..1a91d001f0bee 100644
--- a/.appveyor.yml
+++ b/.appveyor.yml
@@ -48,7 +48,7 @@ install:
- php composer.phar global require --no-progress --no-scripts --no-plugins symfony/flex
- git config --global user.email ""
- git config --global user.name "Symfony"
- - FOR /F "tokens=* USEBACKQ" %%F IN (`bash -c "grep branch-version composer.json | grep -o '[0-9.]*'"`) DO (SET SYMFONY_VERSION=%%F)
+ - FOR /F "tokens=* USEBACKQ" %%F IN (`bash -c "grep branch-version composer.json | grep -o '[0-9.x]*'"`) DO (SET SYMFONY_VERSION=%%F)
- php .github/build-packages.php "HEAD^" %SYMFONY_VERSION% src\Symfony\Bridge\PhpUnit src\Symfony\Contracts
- SET "SYMFONY_REQUIRE=>=%SYMFONY_VERSION%"
- SET COMPOSER_ROOT_VERSION=%SYMFONY_VERSION%.x-dev
diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md
index df9db03fa8bca..c113ccbf96f1b 100644
--- a/.github/PULL_REQUEST_TEMPLATE.md
+++ b/.github/PULL_REQUEST_TEMPLATE.md
@@ -1,6 +1,6 @@
| Q | A
| ------------- | ---
-| Branch? | 5.x for features / 3.4, 4.4 or 5.1 for bug fixes
+| Branch? | 5.x for features / 4.4 or 5.1 for bug fixes
| Bug fix? | yes/no
| New feature? | yes/no
| Deprecations? | yes/no
diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml
index 2bcc279d84cf2..b9f5438e2e061 100644
--- a/.github/workflows/tests.yml
+++ b/.github/workflows/tests.yml
@@ -15,6 +15,17 @@ jobs:
php: ['7.2', '7.4']
services:
+ ldap:
+ image: bitnami/openldap
+ ports:
+ - 3389:3389
+ env:
+ LDAP_ADMIN_USERNAME: admin
+ LDAP_ADMIN_PASSWORD: symfony
+ LDAP_ROOT: dc=symfony,dc=com
+ LDAP_PORT_NUMBER: 3389
+ LDAP_USERS: a
+ LDAP_PASSWORDS: a
redis:
image: redis:6.0.0
ports:
@@ -29,9 +40,16 @@ jobs:
- 7004:7004
- 7005:7005
- 7006:7006
- - 7007:7007
env:
- STANDALONE: true
+ STANDALONE: 1
+ redis-sentinel:
+ image: bitnami/redis-sentinel:6.0
+ ports:
+ - 26379:26379
+ env:
+ REDIS_MASTER_HOST: redis
+ REDIS_MASTER_SET: redis_sentinel
+ REDIS_SENTINEL_QUORUM: 1
memcached:
image: memcached:1.6.5
ports:
@@ -75,17 +93,12 @@ jobs:
- name: Install system dependencies
run: |
- echo "::group::add apt sources"
- sudo wget -O - http://packages.couchbase.com/ubuntu/couchbase.key | sudo apt-key add -
- echo "deb http://packages.couchbase.com/ubuntu bionic bionic/main" | sudo tee /etc/apt/sources.list.d/couchbase.list
- echo "::endgroup::"
-
echo "::group::apt-get update"
sudo apt-get update
echo "::endgroup::"
echo "::group::install tools & libraries"
- sudo apt-get install libcouchbase-dev librdkafka-dev
+ sudo apt-get install librdkafka-dev
echo "::endgroup::"
- name: Configure Couchbase
@@ -99,16 +112,27 @@ jobs:
uses: shivammathur/setup-php@v2
with:
coverage: "none"
- extensions: "json,couchbase,memcached,mongodb,redis,rdkafka,xsl"
+ extensions: "json,couchbase,memcached,mongodb,redis,rdkafka,xsl,ldap"
ini-values: "memory_limit=-1"
php-version: "${{ matrix.php }}"
tools: pecl
+ - name: Display versions
+ run: |
+ php -r 'foreach (get_loaded_extensions() as $extension) echo $extension . " " . phpversion($extension) . PHP_EOL;'
+ php -i
+
+ - name: Load fixtures
+ uses: docker://bitnami/openldap
+ with:
+ entrypoint: /bin/bash
+ args: -c "(ldapwhoami -h localhost:3389 -D cn=admin,dc=symfony,dc=com -w symfony||sleep 5) && ldapadd -h ldap:3389 -D cn=admin,dc=symfony,dc=com -w symfony -f src/Symfony/Component/Ldap/Tests/Fixtures/data/fixtures.ldif && ldapdelete -h ldap:3389 -D cn=admin,dc=symfony,dc=com -w symfony cn=a,ou=users,dc=symfony,dc=com"
+
- name: Configure composer
run: |
COMPOSER_HOME="$(composer config home)"
([ -d "$COMPOSER_HOME" ] || mkdir "$COMPOSER_HOME") && cp .github/composer-config.json "$COMPOSER_HOME/config.json"
- echo "COMPOSER_ROOT_VERSION=$(grep branch-version composer.json | grep -o '[0-9.]*').x-dev" >> $GITHUB_ENV
+ echo "COMPOSER_ROOT_VERSION=$(grep branch-version composer.json | grep -o '[0-9.x]*').x-dev" >> $GITHUB_ENV
- name: Determine composer cache directory
id: composer-cache
@@ -132,15 +156,19 @@ jobs:
echo "::endgroup::"
- name: Run tests
- run: ./phpunit --group integration
+ run: ./phpunit --group integration -v
env:
REDIS_HOST: localhost
REDIS_CLUSTER_HOSTS: 'localhost:7000 localhost:7001 localhost:7002 localhost:7003 localhost:7004 localhost:7005'
+ REDIS_SENTINEL_HOSTS: 'localhost:26379'
+ REDIS_SENTINEL_SERVICE: redis_sentinel
MESSENGER_REDIS_DSN: redis://127.0.0.1:7006/messages
MESSENGER_AMQP_DSN: amqp://localhost/%2f/messages
MESSENGER_SQS_DSN: "sqs://localhost:9494/messages?sslmode=disable&poll_timeout=0.01"
MESSENGER_SQS_FIFO_QUEUE_DSN: "sqs://localhost:9494/messages.fifo?sslmode=disable&poll_timeout=0.01"
MEMCACHED_HOST: localhost
+ LDAP_HOST: localhost
+ LDAP_PORT: 3389
MONGODB_HOST: localhost
KAFKA_BROKER: localhost:9092
diff --git a/.php_cs.dist b/.php_cs.dist
index 0fd2436e791f7..4767e648853ad 100644
--- a/.php_cs.dist
+++ b/.php_cs.dist
@@ -15,6 +15,7 @@ return PhpCsFixer\Config::create()
'protected_to_private' => false,
'native_constant_invocation' => true,
'combine_nested_dirname' => true,
+ 'list_syntax' => ['syntax' => 'short'],
])
->setRiskyAllowed(true)
->setFinder(
diff --git a/.travis.yml b/.travis.yml
index d1f90d9babcfe..e59103e3a27a1 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -9,8 +9,6 @@ addons:
apt_packages:
- parallel
- language-pack-fr-base
- - ldap-utils
- - slapd
- zookeeperd
- libzookeeper-mt-dev
@@ -28,11 +26,11 @@ matrix:
env: deps=high
- php: 7.4
env: deps=low
- - php: nightly
+ - php: 8.0snapshot
services: [memcached]
fast_finish: true
allow_failures:
- - php: nightly
+ - php: 8.0snapshot
services: [memcached]
cache:
@@ -55,11 +53,6 @@ before_install:
# General configuration
set -e
stty cols 120
- mkdir /tmp/slapd
- if [ ! -e /tmp/slapd-modules ]; then
- [ -d /usr/lib/openldap ] && ln -s /usr/lib/openldap /tmp/slapd-modules || ln -s /usr/lib/ldap /tmp/slapd-modules
- fi
- slapd -f src/Symfony/Component/Ldap/Tests/Fixtures/conf/slapd.conf -h ldap://localhost:3389 &
cp .github/composer-config.json "$(composer config home)/config.json"
export PHPUNIT=$(readlink -f ./phpunit)
export PHPUNIT_X="$PHPUNIT --exclude-group tty,benchmark,intl-data"
@@ -140,7 +133,7 @@ before_install:
echo session.gc_probability = 0 >> $INI
echo opcache.enable_cli = 1 >> $INI
echo apc.enable_cli = 1 >> $INI
- if [[ $PHP != nightly ]]; then
+ if [[ $PHP != 8.* ]]; then
echo extension = memcached.so >> $INI
fi
done
@@ -156,26 +149,19 @@ before_install:
if ! php --ri sodium > /dev/null; then
tfold ext.libsodium tpecl libsodium sodium.so $INI
fi
- if [[ $PHP = nightly ]]; then
+ if [[ $PHP = 8.* ]]; then
tfold ext.memcached tpecl memcached-3.1.5 memcached.so $INI
else
tfold ext.mongodb tpecl mongodb-1.6.16 mongodb.so $INI
tfold ext.zookeeper tpecl zookeeper-0.7.2 zookeeper.so $INI
tfold ext.amqp tpecl amqp-1.10.2 amqp.so $INI
- tfold ext.redis tpecl redis-5.2.2 redis.so $INI "no"
fi
tfold ext.apcu tpecl apcu-5.1.19 apcu.so $INI
tfold ext.igbinary tpecl igbinary-3.1.6 igbinary.so $INI
+ tfold ext.redis tpecl redis-5.2.3 redis.so $INI "no"
done
- - |
- # Load fixtures
- if [[ ! $skip ]]; then
- ldapadd -h localhost:3389 -D cn=admin,dc=symfony,dc=com -w symfony -f src/Symfony/Component/Ldap/Tests/Fixtures/data/base.ldif &&
- ldapadd -h localhost:3389 -D cn=admin,dc=symfony,dc=com -w symfony -f src/Symfony/Component/Ldap/Tests/Fixtures/data/fixtures.ldif
- fi
-
install:
- |
# Install the phpunit-bridge from a PR if required
@@ -199,7 +185,7 @@ install:
git config --global user.email ""
git config --global user.name "Symfony"
- export SYMFONY_VERSION=$(grep branch-version composer.json | grep -o '[0-9.]*')
+ export SYMFONY_VERSION=$(grep branch-version composer.json | grep -o '[0-9.x]*')
if [[ ! $deps ]]; then
php .github/build-packages.php HEAD^ $SYMFONY_VERSION src/Symfony/Bridge/PhpUnit src/Symfony/Contracts
@@ -234,7 +220,7 @@ install:
- |
# Set composer's platform to php 7.4 if we're on php 8.
- if [[ $PHP = nightly ]]; then
+ if [[ $PHP = 8.* ]]; then
composer config platform.php 7.4.99
export SYMFONY_DEPRECATIONS_HELPER=max[total]=999
fi
diff --git a/CHANGELOG-5.1.md b/CHANGELOG-5.1.md
index 0f8e3a5c324dd..3d530f59a41d1 100644
--- a/CHANGELOG-5.1.md
+++ b/CHANGELOG-5.1.md
@@ -7,6 +7,54 @@ in 5.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/v5.1.0...v5.1.1
+* 5.1.9 (2020-11-29)
+
+ * bug #39166 [Messenger] Fix mssql compatibility for doctrine transport. (bill moll)
+ * bug #39211 [HttpClient] fix binding to network interfaces (nicolas-grekas)
+ * bug #39129 [DependencyInjection] Fix circular in DI with lazy + byContruct loop (jderusse)
+ * bug #39068 [DependencyInjection][Translator] Silent deprecation triggered by libxml_disable_entity_loader (jderusse)
+ * bug #39119 [Form] prevent duplicated error message for file upload limits (xabbuh)
+ * bug #39099 [Form] ignore the pattern attribute for textareas (xabbuh)
+ * bug #39154 [Yaml] fix lexing strings containing escaped quotation characters (xabbuh)
+ * bug #39180 [Serializer] Fix denormalizing scalar with UnwrappingDenormalizer (camilledejoye)
+ * bug #38597 [PhpUnitBridge] Fix qualification of deprecations triggered by the debug class loader (fancyweb)
+ * bug #39160 [Console] Use a partial buffer in SymfonyStyle (jderusse)
+ * bug #39168 [Console] Fix console closing tag (jderusse)
+ * bug #39155 [VarDumper] fix casting resources turned into objects on PHP 8 (nicolas-grekas)
+ * bug #39131 [Cache] Fix CI because of Couchbase version (jderusse)
+ * bug #39115 [HttpClient] don't fallback to HTTP/1.1 when HTTP/2 streams break (nicolas-grekas)
+ * bug #33763 [Yaml] fix lexing nested sequences/mappings (xabbuh)
+ * bug #39083 [Dotenv] Check if method inheritEnvironmentVariables exists (Chi-teck)
+ * bug #39094 [Ldap] Fix undefined variable $con (derrabus)
+ * bug #39091 [Config] Recheck glob brace support after GlobResource was serialized (wouterj)
+ * bug #39092 Fix critical extension when reseting paged control (jderusse)
+ * bug #38614 [HttpFoundation] Fix for virtualhosts based on URL path (mvorisek)
+ * bug #39072 [FrameworkBundle] [Notifier] fix firebase transport factory DI tag type (xabbuh)
+ * bug #38387 [Validator] prevent hash collisions caused by reused object hashes (fancyweb, xabbuh)
+ * bug #38999 [DependencyInjection] autoconfigure behavior describing tags on decorators (xabbuh)
+ * bug #39058 [DependencyInjection] Fix circular detection with multiple paths (jderusse)
+ * bug #39059 [Filesystem] fix cleaning up tmp files when dumpFile() fails (nicolas-grekas)
+ * bug #38628 [DoctrineBridge] indexBy could reference to association columns (juanmiguelbesada)
+ * bug #39021 [DependencyInjection] Optimize circular collection by removing flattening (jderusse)
+ * bug #39031 [Ldap] Fix pagination (jderusse)
+ * bug #39038 [DoctrineBridge] also reset id readers (xabbuh)
+ * bug #39026 [Messenger] Fix DBAL deprecations in PostgreSqlConnection (chalasr)
+ * bug #39025 [DoctrineBridge] Fix DBAL deprecations in middlewares (derrabus)
+ * bug #38991 [Console] Fix ANSI when stdErr is not a tty (jderusse)
+ * bug #38980 [DependencyInjection] Fix circular reference with Factory + Lazy Iterrator (jderusse)
+ * bug #38977 [HttpClient] Check status code before decoding content in TraceableResponse (chalasr)
+ * bug #38971 [PhpUnitBridge] fix replaying skipped tests (nicolas-grekas)
+ * bug #38910 [HttpKernel] Fix session initialized several times (jderusse)
+ * bug #38882 [DependencyInjection] Improve performances in CircualReference detection (jderusse)
+ * bug #38950 [Process] Dont test TTY if there is no TTY support (Nyholm)
+ * bug #38921 [PHPUnitBridge] Fixed crash on Windows with PHP 8 (villfa)
+ * bug #38869 [SecurityBundle] inject only compatible token storage implementations for usage tracking (xabbuh)
+ * bug #38894 [HttpKernel] Remove Symfony 3 compatibility code (derrabus)
+ * bug #38895 [PhpUnitBridge] Fix wrong check for exporter in ConstraintTrait (alcaeus)
+ * bug #38879 [Cache] Fixed expiry could be int in ChainAdapter due to race conditions (phamviet)
+ * bug #38867 [FrameworkBundle] Fixing TranslationUpdateCommand failure when using "--no-backup" (liarco)
+ * bug #38856 [Cache] Add missing use statement (fabpot)
+
* 5.1.8 (2020-10-28)
* bug #38713 [DI] Fix Preloader exception when preloading a class with an unknown parent/interface (rgeraads)
diff --git a/CONTRIBUTORS.md b/CONTRIBUTORS.md
index f3217f25a966c..3bed011d06243 100644
--- a/CONTRIBUTORS.md
+++ b/CONTRIBUTORS.md
@@ -12,9 +12,10 @@ Symfony is the result of the work of many people who made the code better
- Robin Chalas (chalas_r)
- Christophe Coevoet (stof)
- Kévin Dunglas (dunglas)
- - Jordi Boggiano (seldaek)
- Maxime Steinhausser (ogizanagi)
+ - Jordi Boggiano (seldaek)
- Victor Berchet (victor)
+ - Alexander M. Turek (derrabus)
- Grégoire Pineau (lyrixx)
- Ryan Weaver (weaverryan)
- Javier Eguiluz (javier.eguiluz)
@@ -24,29 +25,29 @@ Symfony is the result of the work of many people who made the code better
- Kris Wallsmith (kriswallsmith)
- Wouter de Jong (wouterj)
- Yonel Ceruto (yonelceruto)
- - Alexander M. Turek (derrabus)
- - Hugo Hamon (hhamon)
- Thomas Calvet (fancyweb)
+ - Hugo Hamon (hhamon)
+ - Jérémy DERUSSÉ (jderusse)
- Abdellatif Ait boudad (aitboudad)
- Samuel ROZE (sroze)
- Romain Neutron (romain)
- Pascal Borreli (pborreli)
- Joseph Bielawski (stloyd)
- Karma Dordrak (drak)
- - Jérémy DERUSSÉ (jderusse)
- Jules Pietri (heah)
- Lukas Kahwe Smith (lsmith)
- Martin Hasoň (hason)
- Hamza Amrouche (simperfit)
+ - Tobias Nyholm (tobias)
- Jeremy Mikola (jmikola)
- Jean-François Simon (jfsimon)
- Benjamin Eberlei (beberlei)
- Igor Wiedler (igorw)
- Eriksen Costa (eriksencosta)
- - Tobias Nyholm (tobias)
- Guilhem Niot (energetick)
- Sarah Khalil (saro0h)
- Jonathan Wage (jwage)
+ - Jan Schädlich (jschaedl)
- Lynn van der Berg (kjarli)
- Matthias Pigulla (mpdude)
- Diego Saint Esteben (dosten)
@@ -55,28 +56,27 @@ Symfony is the result of the work of many people who made the code better
- William Durand (couac)
- Valentin Udaltsov (vudaltsov)
- ornicar
- - Jan Schädlich (jschaedl)
+ - Grégoire Paris (greg0ire)
- Dany Maillard (maidmaid)
- Francis Besset (francisbesset)
- stealth35 (stealth35)
- Alexander Mols (asm89)
+ - Kevin Bond (kbond)
- Konstantin Myakshin (koc)
- - Grégoire Paris (greg0ire)
- Bulat Shakirzyanov (avalanche123)
- - Kevin Bond (kbond)
- Saša Stamenković (umpirsky)
- Peter Rehm (rpet)
- Gabriel Ostrolucký (gadelat)
+ - Titouan Galopin (tgalopin)
- David Maicher (dmaicher)
- Gábor Egyed (1ed)
- Henrik Bjørnskov (henrikbjorn)
- Miha Vrhovnik
- - Titouan Galopin (tgalopin)
- Diego Saint Esteben (dii3g0)
- Konstantin Kudryashov (everzet)
+ - Mathieu Piot (mpiot)
- Vladimir Reznichenko (kalessil)
- Bilal Amarni (bamarni)
- - Mathieu Piot (mpiot)
- Florin Patan (florinpatan)
- Jáchym Toušek (enumag)
- Andrej Hudec (pulzarraider)
@@ -86,13 +86,13 @@ Symfony is the result of the work of many people who made the code better
- Charles Sarrazin (csarrazi)
- Christian Raue
- Douglas Greenshields (shieldo)
+ - Laurent VOULLEMIER (lvo)
- Arnout Boks (aboks)
+ - Graham Campbell (graham)
- Jérôme Tamarelle (gromnan)
- - Laurent VOULLEMIER (lvo)
- Deni
- Henrik Westphal (snc)
- Dariusz Górecki (canni)
- - Graham Campbell (graham)
- David Buchmann (dbu)
- Dariusz Ruminski
- Fran Moreno (franmomu)
@@ -100,11 +100,11 @@ Symfony is the result of the work of many people who made the code better
- Brandon Turner
- Luis Cordova (cordoval)
- Daniel Holmes (dholmes)
+ - Alex Pott
- Toni Uebernickel (havvg)
- Bart van den Burg (burgov)
- Jordan Alliot (jalliot)
- John Wards (johnwards)
- - Alex Pott
- Antoine Hérault (herzult)
- Paráda József (paradajozsef)
- Arnaud Le Blanc (arnaud-lb)
@@ -116,21 +116,22 @@ Symfony is the result of the work of many people who made the code better
- Tim Nagel (merk)
- Chris Wilkinson (thewilkybarkid)
- Brice BERNARD (brikou)
+ - Alexander Schranz (alexander-schranz)
- marc.weistroff
- Tomáš Votruba (tomas_votruba)
- Peter Kokot (maastermedia)
+ - Lars Strojny (lstrojny)
- lenar
- Alexander Schwenn (xelaris)
+ - Massimiliano Arione (garak)
- Włodzimierz Gajda (gajdaw)
+ - Oskar Stark (oskarstark)
- Adrien Brault (adrienbrault)
- - Lars Strojny (lstrojny)
- - Massimiliano Arione (garak)
- Jacob Dreesen (jdreesen)
- Florian Voutzinos (florianv)
- Teoh Han Hui (teohhanhui)
- Przemysław Bogusz (przemyslaw-bogusz)
- Colin Frei
- - Oskar Stark (oskarstark)
- Javier Spagnoletti (phansys)
- Joshua Thijssen
- Daniel Wehner (dawehner)
@@ -138,12 +139,11 @@ Symfony is the result of the work of many people who made the code better
- excelwebzone
- Gordon Franke (gimler)
- Joel Wurtz (brouznouf)
- - Alexander Schranz (alexander-schranz)
+ - Antoine Makdessi (amakdessi)
- Fabien Pennequin (fabienpennequin)
- Julien Falque (julienfalque)
- Théo FIDRY (theofidry)
- Eric GELOEN (gelo)
- - Antoine Makdessi (amakdessi)
- Jannik Zschiesche (apfelbox)
- jeremyFreeAgent (jeremyfreeagent)
- Robert Schönthal (digitalkaoz)
@@ -166,6 +166,7 @@ Symfony is the result of the work of many people who made the code better
- Guilherme Blanco (guilhermeblanco)
- SpacePossum
- Pablo Godel (pgodel)
+ - Andreas Braun
- Matthieu Napoli (mnapoli)
- Richard van Laak (rvanlaak)
- Jérémie Augustin (jaugustin)
@@ -209,6 +210,7 @@ Symfony is the result of the work of many people who made the code better
- Marek Štípek (maryo)
- Filippo Tessarotto (slamdunk)
- Daniel Espendiller
+ - Maxime Helias (maxhelias)
- Possum
- Dorian Villet (gnutix)
- Michaël Perrin (michael.perrin)
@@ -228,9 +230,9 @@ Symfony is the result of the work of many people who made the code better
- Ruben Gonzalez (rubenrua)
- Benjamin Dulau (dbenjamin)
- Jan Rosier (rosier)
- - Andreas Braun
- Mathieu Lemoine (lemoinem)
- Rémon van de Kamp (rpkamp)
+ - HypeMC
- Christian Schmidt
- Andreas Hucks (meandmymonkey)
- Tom Van Looy (tvlooy)
@@ -246,7 +248,6 @@ Symfony is the result of the work of many people who made the code better
- Nikolay Labinskiy (e-moe)
- Martin Schuhfuß (usefulthink)
- apetitpa
- - Maxime Helias (maxhelias)
- Matthieu Bontemps (mbontemps)
- apetitpa
- Pierre Minnieur (pminnieur)
@@ -255,6 +256,7 @@ Symfony is the result of the work of many people who made the code better
- Dominique Bongiraud
- Hidde Wieringa (hiddewie)
- Jeremy Livingston (jeremylivingston)
+ - Olivier Dolbeau (odolbeau)
- Michael Lee (zerustech)
- Dmitrii Poddubnyi (karser)
- Matthieu Auger (matthieuauger)
@@ -288,13 +290,14 @@ Symfony is the result of the work of many people who made the code better
- Marco Pivetta (ocramius)
- Antonio Pauletich (x-coder264)
- Jeroen Spee (jeroens)
- - Olivier Dolbeau (odolbeau)
- Rob Frawley 2nd (robfrawley)
- julien pauli (jpauli)
- Lorenz Schori
- Sébastien Lavoie (lavoiesl)
- Dariusz
+ - Farhad Safarov (safarov)
- Michael Babker (mbabker)
+ - Thomas Lallement (raziel057)
- Francois Zaninotto
- Colin O'Dell (colinodell)
- Alexander Kotynia (olden)
@@ -304,22 +307,27 @@ Symfony is the result of the work of many people who made the code better
- Elnur Abdurrakhimov (elnur)
- Manuel Reinhard (sprain)
- Danny Berger (dpb587)
+ - zairig imad (zairigimad)
- Antonio J. García Lagar (ajgarlag)
+ - Alessandro Lai (jean85)
- Adam Prager (padam87)
- Benoît Burnichon (bburnichon)
- Maciej Malarz (malarzm)
- Roman Marintšenko (inori)
- Xavier Montaña Carreras (xmontana)
+ - Timothée Barray (tyx)
- Mickaël Andrieu (mickaelandrieu)
- Xavier Perez
- Arjen Brouwer (arjenjb)
- Katsuhiro OGAWA
- Patrick McDougle (patrick-mcdougle)
+ - Rokas Mikalkėnas (rokasm)
- Marc Weistroff (futurecat)
- Alif Rachmawadi
- Anton Chernikov (anton_ch1989)
- Kristen Gilden (kgilden)
- Pierre-Yves LEBECQ (pylebecq)
+ - Benjamin Leveque (benji07)
- Jordan Samouh (jordansamouh)
- Jakub Kucharovic (jkucharovic)
- Loick Piera (pyrech)
@@ -335,16 +343,18 @@ Symfony is the result of the work of many people who made the code better
- Ray
- Chekote
- Thomas Adam
+ - Chi-teck
- Jhonny Lidfors (jhonne)
- Diego Agulló (aeoris)
- jdhoek
+ - Michael Käfer (michael_kaefer)
- Bob den Otter (bopp)
- Thomas Schulz (king2500)
- Frank de Jonge (frenkynet)
- Nikita Konstantinov
- Wodor Wodorski
+ - Timo Bakx (timobakx)
- Joe Bennett (kralos)
- - Thomas Lallement (raziel057)
- soyuka
- Giorgio Premi
- renanbr
@@ -358,7 +368,6 @@ Symfony is the result of the work of many people who made the code better
- Alexander Menshchikov (zmey_kk)
- Emanuele Panzeri (thepanz)
- Kim Hemsø Rasmussen (kimhemsoe)
- - Alessandro Lai (jean85)
- Langlet Vincent (deviling)
- Pascal Luna (skalpa)
- Wouter Van Hecke
@@ -370,8 +379,9 @@ Symfony is the result of the work of many people who made the code better
- Simon Mönch (sm)
- Christian Schmidt
- Patrick Landolt (scube)
- - HypeMC
- MatTheCat
+ - Denis Brumann (dbrumann)
+ - Bohan Yang (brentybh)
- Vilius Grigaliūnas
- David Badura (davidbadura)
- Chad Sikorra (chadsikorra)
@@ -379,7 +389,6 @@ Symfony is the result of the work of many people who made the code better
- Chris Smith (cs278)
- Thomas Bisignani (toma)
- Florian Klein (docteurklein)
- - Benjamin Leveque (benji07)
- Manuel Kiessling (manuelkiessling)
- Alexey Kopytko (sanmai)
- Atsuhiro KUBO (iteman)
@@ -399,7 +408,6 @@ Symfony is the result of the work of many people who made the code better
- Emmanuel BORGES (eborges78)
- Aurelijus Valeiša (aurelijus)
- Jan Decavele (jandc)
- - Chi-teck
- Gustavo Piltcher
- Jesse Rushlow (geeshoe)
- Stepan Tanasiychuk (stfalcon)
@@ -412,7 +420,6 @@ Symfony is the result of the work of many people who made the code better
- Romain Pierre (romain-pierre)
- Julien Galenski (ruian)
- Thomas Landauer (thomas-landauer)
- - Michael Käfer (michael_kaefer)
- Bongiraud Dominique
- janschoenherr
- Emanuele Gaspari (inmarelibero)
@@ -423,6 +430,8 @@ Symfony is the result of the work of many people who made the code better
- Sebastien Morel (plopix)
- Ricard Clau (ricardclau)
- Mark Challoner (markchalloner)
+ - ivan
+ - Karoly Gossler (connorhu)
- Ahmed Raafat
- Philippe Segatori
- Gennady Telegin (gtelegin)
@@ -432,6 +441,7 @@ Symfony is the result of the work of many people who made the code better
- Matthew Lewinski (lewinski)
- Magnus Nordlander (magnusnordlander)
- Thomas Royer (cydonia7)
+ - Nicolas Philippe (nikophil)
- Nicolas LEFEVRE (nicoweb)
- alquerci
- Oleg Andreyev
@@ -441,29 +451,33 @@ Symfony is the result of the work of many people who made the code better
- Vitaliy Zakharov (zakharovvi)
- Tobias Sjösten (tobiassjosten)
- Gyula Sallai (salla)
+ - Romaric Drigon (romaricdrigon)
- Inal DJAFAR (inalgnu)
- Christian Gärtner (dagardner)
- Dmytro Borysovskyi (dmytr0)
- Tomasz Kowalczyk (thunderer)
+ - Sylvain Fabre (sylfabre)
- Artur Eshenbrener
- - Timo Bakx (timobakx)
- Harm van Tilborg (hvt)
- Thomas Perez (scullwm)
- Felix Labrecque
- Yaroslav Kiliba
+ - Ben Hakim
- Terje Bråten
- Gonzalo Vilaseca (gonzalovilaseca)
+ - Marco Petersen (ocrampete16)
- Markus Fasselt (digilist)
- Daniel STANCU
- Robbert Klarenbeek (robbertkl)
- Eric Masoero (eric-masoero)
- Ion Bazan (ionbazan)
- - Denis Brumann (dbrumann)
+ - Vitalii Ekert (comrade42)
- JhonnyL
- Clara van Miert
- Haralan Dobrev (hkdobrev)
- hossein zolfi (ocean)
- Clément Gautier (clementgautier)
+ - Jeroen Noten (jeroennoten)
- Bastien Jaillot (bastnic)
- Dāvis Zālītis (k0d3r1s)
- Sanpi
@@ -477,7 +491,6 @@ Symfony is the result of the work of many people who made the code better
- Dimitri Gritsajuk (ottaviano)
- Kirill chEbba Chebunin (chebba)
-
- - Rokas Mikalkėnas (rokasm)
- Greg Thornton (xdissent)
- Alex Bowers
- Philipp Cordes
@@ -498,7 +511,6 @@ Symfony is the result of the work of many people who made the code better
- Endre Fejes
- Tobias Naumann (tna)
- Daniel Beyer
- - Timothée Barray (tyx)
- Shein Alexey
- Romain Gautier (mykiwi)
- Joe Lencioni
@@ -540,9 +552,11 @@ Symfony is the result of the work of many people who made the code better
- Jeanmonod David (jeanmonod)
- Christopher Davis (chrisguitarguy)
- Webnet team (webnet)
+ - Ben Ramsey (ramsey)
+ - Nate Wiebe (natewiebe13)
- Marcin Szepczynski (czepol)
- Mohammad Emran Hasan (phpfour)
- - Farhad Safarov
+ - Dmitriy Mamontov (mamontovdmitriy)
- Jan Schumann
- Niklas Fiekas
- Markus Bachmann (baachi)
@@ -554,6 +568,7 @@ Symfony is the result of the work of many people who made the code better
- Mihai Stancu
- Ivan Nikolaev (destillat)
- Gildas Quéméner (gquemener)
+ - Baptiste Leduc (korbeil)
- Laurent Masforné (heisenberg)
- Claude Khedhiri (ck-developer)
- Desjardins Jérôme (jewome62)
@@ -563,22 +578,25 @@ Symfony is the result of the work of many people who made the code better
- Toni Rudolf (toooni)
- Asmir Mustafic (goetas)
- DerManoMann
- - Nicolas Philippe (nikophil)
- vagrant
- Aurimas Niekis (gcds)
- EdgarPE
+ - Bob van de Vijver (bobvandevijver)
- Florian Pfitzer (marmelatze)
- Asier Illarramendi (doup)
- - Sylvain Fabre (sylfabre)
- Martijn Cuppens
- Vlad Gregurco (vgregurco)
- Boris Vujicic (boris.vujicic)
- Artem Lopata
- Judicaël RUFFIEUX (axanagor)
- Chris Sedlmayr (catchamonkey)
+ - Indra Gunawan (indragunawan)
- Kamil Kokot (pamil)
- Seb Koelen
- Christoph Mewes (xrstf)
+ - Andrew M-Y (andr)
+ - Krasimir Bosilkov (kbosilkov)
+ - Marcin Michalski (marcinmichalski)
- Vitaliy Tverdokhlib (vitaliytv)
- Ariel Ferrandini (aferrandini)
- Dirk Pahl (dirkaholic)
@@ -586,17 +604,20 @@ Symfony is the result of the work of many people who made the code better
- Arkadius Stefanski (arkadius)
- Tim Goudriaan (codedmonkey)
- Jonas Flodén (flojon)
+ - AnneKir
- Soner Sayakci
- Tobias Weichart
+ - Miro Michalicka
- Tarmo Leppänen (tarlepp)
- Marcin Sikoń (marphi)
- - Bohan Yang (brentybh)
+ - M. Vondano
- Dominik Zogg (dominik.zogg)
- Marek Pietrzak
+ - Tavo Nieves J
- Luc Vieillescazes (iamluc)
+ - Lukáš Holeczy (holicz)
- franek (franek)
- Raulnet
- - Marco Petersen (ocrampete16)
- Christian Wahler
- Giso Stallenberg (gisostallenberg)
- Gintautas Miselis
@@ -645,6 +666,7 @@ Symfony is the result of the work of many people who made the code better
- Roy Van Ginneken (rvanginneken)
- ondrowan
- Barry vd. Heuvel (barryvdh)
+ - Michael Voříšek
- Evan S Kaufman (evanskaufman)
- mcben
- Jérôme Vieilledent (lolautruche)
@@ -659,6 +681,7 @@ Symfony is the result of the work of many people who made the code better
- Leevi Graham (leevigraham)
- Anthony Ferrara
- Ioan Negulescu
+ - Greg ORIOL
- Jakub Škvára (jskvara)
- Andrew Udvare (audvare)
- alexpods
@@ -668,7 +691,6 @@ Symfony is the result of the work of many people who made the code better
- Erik Trapman (eriktrapman)
- De Cock Xavier (xdecock)
- Almog Baku (almogbaku)
- - Karoly Gossler (connorhu)
- Scott Arciszewski
- Xavier HAUSHERR
- Norbert Orzechowicz (norzechowicz)
@@ -735,22 +757,19 @@ Symfony is the result of the work of many people who made the code better
- Julien Montel (julienmgel)
- Mátyás Somfai (smatyas)
- Bastien DURAND (deamon)
- - Ben Ramsey (ramsey)
- Simon DELICATA
- Artem Henvald (artemgenvald)
- Dmitry Simushev
- alcaeus
- Thomas Talbot (ioni)
- - Nate Wiebe (natewiebe13)
- Fred Cox
- vitaliytv
- - ivan
- Philippe Segatori
+ - fd6130 (fdtvui)
- Dalibor Karlović (dkarlovi)
- Andrey Sevastianov
- Sebastian Blum
- Alexis Lefebvre
- - Dmitriy Mamontov (mamontovdmitriy)
- aubx
- Julien Turby
- Marvin Butkereit
@@ -761,7 +780,6 @@ Symfony is the result of the work of many people who made the code better
- Max Rath (drak3)
- marie
- Stéphane Escandell (sescandell)
- - Baptiste Leduc (korbeil)
- Konstantin S. M. Möllers (ksmmoellers)
- James Johnston
- Noémi Salaün (noemi-salaun)
@@ -779,7 +797,6 @@ Symfony is the result of the work of many people who made the code better
- Christophe Villeger (seragan)
- Matthias Krauser (mkrauser)
- Julien Fredon
- - Bob van de Vijver (bobvandevijver)
- Xavier Leune (xleune)
- Stefan Gehrig (sgehrig)
- Hany el-Kerdany
@@ -794,9 +811,10 @@ Symfony is the result of the work of many people who made the code better
- Jérôme Tamarelle (jtamarelle-prismamedia)
- Geoffrey Brier (geoffrey-brier)
- Alexandre Parent
+ - Roger Guasch (rogerguasch)
- Vladimir Tsykun
- - Romaric Drigon (romaricdrigon)
- Dustin Dobervich (dustin10)
+ - Luis Tacón (lutacon)
- dantleech
- Philipp Kolesnikov
- Anne-Sophie Bachelard (annesophie)
@@ -804,7 +822,9 @@ Symfony is the result of the work of many people who made the code better
- Carlos Pereira De Amorim (epitre)
- zenmate
- Michal Trojanowski
+ - Lescot Edouard (idetox)
- David Fuhr
+ - Rodrigo Aguilera
- Mathias STRASSER (roukmoute)
- Max Grigorian (maxakawizard)
- Rostyslav Kinash
@@ -818,17 +838,18 @@ Symfony is the result of the work of many people who made the code better
- Stefan Warman
- Tristan Maindron (tmaindron)
- Behnoush Norouzali (behnoush)
+ - Marko H. Tamminen (gzumba)
- Wesley Lancel
- Xavier Briand (xavierbriand)
- Ke WANG (yktd26)
- Ivo Bathke (ivoba)
+ - David Molineus
- Strate
- Anton A. Sumin
- Israel J. Carberry
- Miquel Rodríguez Telep (mrtorrent)
- Sergey Kolodyazhnyy (skolodyazhnyy)
- umpirski
- - M. Vondano
- Quentin de Longraye (quentinus95)
- Chris Heng (gigablah)
- Shaun Simmons (simshaun)
@@ -843,8 +864,10 @@ Symfony is the result of the work of many people who made the code better
- Michael Devery (mickadoo)
- Antoine Corcy
- Ahmed Ashraf (ahmedash95)
+ - Luca Saba (lucasaba)
- Sascha Grossenbacher
- Szijarto Tamas
+ - Thomas P
- Robin Lehrmann (robinlehrmann)
- Catalin Dan
- Jaroslav Kuba
@@ -908,7 +931,9 @@ Symfony is the result of the work of many people who made the code better
- Peter Ward
- Davide Borsatto (davide.borsatto)
- Julien DIDIER (juliendidier)
+ - Randy Geraads
- Dominik Ritter (dritter)
+ - Andreas Leathley (iquito)
- Sebastian Grodzicki (sgrodzicki)
- Mohamed Gamal
- Jeroen van den Enden (stoefke)
@@ -916,12 +941,12 @@ Symfony is the result of the work of many people who made the code better
- Baldur Rensch (brensch)
- Pierre Rineau
- Fritz Michael Gschwantner
- - Jeroen Noten (jeroennoten)
- Vladyslav Petrovych
- Alex Xandra Albert Sim
- Carson Full
- Sergey Yastrebov
- Trent Steel (trsteel88)
+ - Steve Grunwell
- Yuen-Chi Lian
- Tarjei Huse (tarjei)
- Besnik Br
@@ -949,10 +974,10 @@ Symfony is the result of the work of many people who made the code better
- Casper Valdemar Poulsen
- Josiah (josiah)
- Guillaume Verstraete (versgui)
- - Greg ORIOL
- Joschi Kuphal
- John Bohn (jbohn)
- Marc Morera (mmoreram)
+ - Jason Tan
- BENOIT POLASZEK (bpolaszek)
- Julien Pauli
- Mathieu Rochette (mathroc)
@@ -1026,7 +1051,6 @@ Symfony is the result of the work of many people who made the code better
- Sergey Zolotov (enleur)
- Maksim Kotlyar (makasim)
- Neil Ferreira
- - Indra Gunawan (indragunawan)
- Julie Hourcade (juliehde)
- Dmitry Parnas (parnas)
- Paul LE CORRE
@@ -1038,7 +1062,6 @@ Symfony is the result of the work of many people who made the code better
- Gerard van Helden (drm)
- flack (flack)
- Johnny Peck (johnnypeck)
- - Michael Voříšek
- Stefan Kruppa
- Ivan Menshykov
- David Romaní
@@ -1046,6 +1069,7 @@ Symfony is the result of the work of many people who made the code better
- Gustavo Falco (gfalco)
- Matt Robinson (inanimatt)
- Kristof Van Cauwenbergh (kristofvc)
+ - Marco Lipparini (liarco)
- Peter Bowyer (pbowyer)
- Aleksey Podskrebyshev
- Calin Mihai Pristavu
@@ -1083,6 +1107,7 @@ Symfony is the result of the work of many people who made the code better
- Don Pinkster
- Maksim Muruev
- Emil Einarsson
+ - Anderson Müller
- 243083df
- Thibault Duplessis
- Rimas Kudelis
@@ -1098,6 +1123,7 @@ Symfony is the result of the work of many people who made the code better
- Johnson Page (jwpage)
- Ruben Gonzalez (rubenruateltek)
- Michael Roterman (wtfzdotnet)
+ - Dieter
- Arno Geurts
- Adán Lobato (adanlobato)
- Ian Jenkins (jenkoian)
@@ -1133,6 +1159,7 @@ Symfony is the result of the work of many people who made the code better
- Erik Saunier (snickers)
- Thiago Cordeiro (thiagocordeiro)
- Rootie
+ - Bernd Stellwag
- Alireza Mirsepassi (alirezamirsepassi)
- Daniel Alejandro Castro Arellano (lexcast)
- sensio
@@ -1157,6 +1184,7 @@ Symfony is the result of the work of many people who made the code better
- Christian Jul Jensen
- Alexandre GESLIN (alexandregeslin)
- The Whole Life to Learn
+ - Pierre Tondereau
- Alex Vo (votanlean)
- Mikkel Paulson
- ergiegonzaga
@@ -1180,7 +1208,9 @@ Symfony is the result of the work of many people who made the code better
- Pieter
- Michael Tibben
- Hallison Boaventura (hallisonboaventura)
+ - Mas Iting
- Billie Thompson
+ - Albion Bame (abame)
- Ganesh Chandrasekaran
- Sander Marechal
- Franz Wilding (killerpoke)
@@ -1201,10 +1231,15 @@ Symfony is the result of the work of many people who made the code better
- Nicolas Martin (cocorambo)
- Tom Panier (neemzy)
- Fred Cox
+ - luffy1727
- Luciano Mammino (loige)
- fabios
- Sander Coolen (scoolen)
+ - Amirreza Shafaat (amirrezashafaat)
+ - Laurent Clouet
+ - Adoni Pavlakis (adoni)
- Nicolas Le Goff (nlegoff)
+ - Ahmed EBEN HASSINE (famas23)
- Ben Oman
- Chris de Kok
- Eduard Bulava (nonanerz)
@@ -1213,21 +1248,24 @@ Symfony is the result of the work of many people who made the code better
- Guillaume (guill)
- Igor Timoshenko (igor.timoshenko)
- Manuele Menozzi
- - zairig imad (zairigimad)
+ - “teerasak”
- Anton Babenko (antonbabenko)
- Irmantas Šiupšinskas (irmantas)
- Benoit Mallo
- - Lescot Edouard (idetox)
- Danilo Silva
- Giuseppe Campanelli
+ - Valentin
- pizzaminded
- Arnaud PETITPAS (apetitpa)
- Ken Stanley
+ - ivan
- Zachary Tong (polyfractal)
- linh
+ - Guilherme Augusto Henschel
- Mario Blažek (marioblazek)
- Ashura
- Hryhorii Hrebiniuk
+ - Eric Krona
- johnstevenson
- hamza
- dantleech
@@ -1238,6 +1276,7 @@ Symfony is the result of the work of many people who made the code better
- Stanislav Kocanda
- DerManoMann
- Damien Fayet (rainst0rm)
+ - Ippei SUmida (ippey_s)
- MatTheCat
- Guillaume Royer
- Artem (digi)
@@ -1247,6 +1286,7 @@ Symfony is the result of the work of many people who made the code better
- Pierrick VIGNAND (pierrick)
- Vadim Tyukov (vatson)
- Arman
+ - Adamo Crespi (aerendir)
- David Wolter (davewww)
- Sortex
- chispita
@@ -1260,8 +1300,10 @@ Symfony is the result of the work of many people who made the code better
- Danijel Obradović
- Pablo Borowicz
- Arjan Keeman
+ - Bruno Rodrigues de Araujo (brunosinister)
- Máximo Cuadros (mcuadros)
- Lukas Mencl
+ - Jacek Wilczyński (jacekwilczynski)
- tamirvs
- gauss
- julien.galenski
@@ -1322,12 +1364,14 @@ Symfony is the result of the work of many people who made the code better
- Nikita Konstantinov
- Martijn Evers
- Philipp Fritsche
+ - tarlepp
- Benjamin Paap (benjaminpaap)
- Claus Due (namelesscoder)
- Christian
- Alexandru Patranescu
- Denis Golubovskiy (bukashk0zzz)
- Sergii Smertin (nfx)
+ - Quentin Moreau (sheitak)
- Mikkel Paulson
- Michał Strzelecki
- hugofonseca (fonsecas72)
@@ -1420,13 +1464,14 @@ Symfony is the result of the work of many people who made the code better
- Arun Philip
- Rémi Leclerc
- Jan Vernarsky
+ - Jonas Hünig
- Amine Yakoubi
- Eduardo García Sanz (coma)
- Sergio (deverad)
- Makdessi Alex
- James Gilliland
- fduch (fduch)
- - David Molineus
+ - Juan Miguel Besada Vidal (soutlink)
- Stuart Fyfe
- David de Boer (ddeboer)
- Eno Mullaraj (emullaraj)
@@ -1532,6 +1577,7 @@ Symfony is the result of the work of many people who made the code better
- pthompson
- Malaney J. Hill
- Alexandre Pavy
+ - Adiel Cristo (arcristo)
- Christian Flach (cmfcmf)
- Cédric Girard (enk_)
- Lars Ambrosius Wallenborn (larsborn)
@@ -1547,6 +1593,7 @@ Symfony is the result of the work of many people who made the code better
- Javier Espinosa
- Anton Kroshilin
- Dawid Sajdak
+ - Norman Soetbeer
- Ludek Stepan
- Aaron Stephens (astephens)
- Craig Menning (cmenning)
@@ -1557,7 +1604,6 @@ Symfony is the result of the work of many people who made the code better
- Marc J. Schmidt (marcjs)
- František Maša
- Sebastian Schwarz
- - Jason Tan
- Marco Jantke
- Saem Ghani
- Clément LEFEBVRE
@@ -1622,6 +1668,7 @@ Symfony is the result of the work of many people who made the code better
- JL
- Ilya Biryukov
- Kim Laï Trinh
+ - Johan de Ruijter
- Jason Desrosiers
- m.chwedziak
- Andreas Frömer
@@ -1653,7 +1700,6 @@ Symfony is the result of the work of many people who made the code better
- WedgeSama
- Hugo Sales
- Felds Liscia
- - Randy Geraads
- Chihiro Adachi (chihiro-adachi)
- Raphaëll Roussel
- Tadcka
@@ -1669,7 +1715,6 @@ Symfony is the result of the work of many people who made the code better
- Emmanuel Vella (emmanuel.vella)
- Guillaume BRETOU (guiguiboy)
- Carsten Nielsen (phreaknerd)
- - Roger Guasch (rogerguasch)
- Jay Severson
- Benny Born
- Emirald Mateli
@@ -1694,6 +1739,7 @@ Symfony is the result of the work of many people who made the code better
- Mara Blaga
- Rick Prent
- skalpa
+ - Kai
- Martin Eckhardt
- Bartłomiej Zając
- Pieter Jordaan
@@ -1702,6 +1748,8 @@ Symfony is the result of the work of many people who made the code better
- Michael Dowling (mtdowling)
- Karlos Presumido (oneko)
- Tony Vermeiren (tony)
+ - Bart Wach
+ - Jos Elstgeest
- Thomas Counsell
- BilgeXA
- r1pp3rj4ck
@@ -1773,6 +1821,7 @@ Symfony is the result of the work of many people who made the code better
- Flavian (2much)
- Gautier Deuette
- mike
+ - Gilbertsoft
- tadas
- Kirk Madera
- Keith Maika
@@ -1792,13 +1841,14 @@ Symfony is the result of the work of many people who made the code better
- Zdeněk Drahoš
- Dan Harper
- moldcraft
+ - Marcin Kruk
- Antoine Bellion (abellion)
- Ramon Kleiss (akathos)
- Antonio Peric-Mazar (antonioperic)
- César Suárez (csuarez)
- Bjorn Twachtmann (dotbjorn)
+ - Marek Víger (freezy)
- Tobias Genberg (lorceroth)
- - Luis Tacón (lutacon)
- Nicolas Badey (nico-b)
- Shane Preece (shane)
- Johannes Goslar
@@ -1853,6 +1903,7 @@ Symfony is the result of the work of many people who made the code better
- Wing
- Thomas Bibb
- kick-the-bucket
+ - Joni Halme
- Matt Farmer
- catch
- siganushka
@@ -1966,6 +2017,7 @@ Symfony is the result of the work of many people who made the code better
- Felix Marezki
- Normunds
- Luiz “Felds” Liscia
+ - Johan
- Thomas Rothe
- Adrien Wilmet
- Martin
@@ -2065,6 +2117,8 @@ Symfony is the result of the work of many people who made the code better
- Ali Tavafi
- Trevor Suarez
- gedrox
+ - hugovms
+ - Viet Pham
- Alan Bondarchuk
- Pchol
- dropfen
@@ -2170,7 +2224,6 @@ Symfony is the result of the work of many people who made the code better
- Marin Nicolae
- Alessandro Loffredo
- Ian Phillips
- - Marco Lipparini
- Haritz
- Matthieu Prat
- Grummfy
@@ -2275,6 +2328,7 @@ Symfony is the result of the work of many people who made the code better
- Vladimir Chernyshev (volch)
- Wim Godden (wimg)
- Yorkie Chadwick (yorkie76)
+ - Maxime Aknin (3m1x4m)
- GuillaumeVerdon
- Philipp Keck
- Angel Fernando Quiroz Campos
@@ -2378,12 +2432,13 @@ Symfony is the result of the work of many people who made the code better
- Daniel Bannert
- Karim Miladi
- Michael Genereux
+ - Wojciech Kania
- patrick-mcdougle
- Dariusz Czech
+ - Bruno Baguette
- Jack Wright
- MrNicodemuz
- Anonymous User
- - Dieter
- Paweł Tomulik
- Eric J. Duran
- Alexandru Bucur
@@ -2399,7 +2454,6 @@ Symfony is the result of the work of many people who made the code better
- n-aleha
- Talha Zekeriya Durmuş
- Anatol Belski
- - Anderson Müller
- Şəhriyar İmanov
- Alexis BOYER
- Kaipi Yann
@@ -2454,6 +2508,7 @@ Symfony is the result of the work of many people who made the code better
- Alex Nostadt
- Michael Squires
- Egor Gorbachev
+ - Fabien Villepinte
- Derek Stephen McLean
- Norman Soetbeer
- zorn
@@ -2546,6 +2601,7 @@ Symfony is the result of the work of many people who made the code better
- Damián Nohales (eagleoneraptor)
- Jordane VASPARD (elementaire)
- Elliot Anderson (elliot)
+ - Erwan Nader (ernadoo)
- Fabien D. (fabd)
- Carsten Eilers (fnc)
- Sorin Gitlan (forapathy)
@@ -2619,6 +2675,7 @@ Symfony is the result of the work of many people who made the code better
- Volker (skydiablo)
- Success Go (successgo)
- Julien Sanchez (sumbobyboys)
+ - Stephan Vierkant (svierkant)
- Guillermo Gisinger (t3chn0r)
- Markus Tacker (tacker)
- Tom Newby (tomnewbyau)
@@ -2645,6 +2702,7 @@ Symfony is the result of the work of many people who made the code better
- simpson
- Antoine Leblanc
- drublic
+ - Andre Johnson
- MaPePeR
- Andreas Streichardt
- Alexandre Segura
diff --git a/composer.json b/composer.json
index caf3a939c59d7..2fb8e26fb3bfa 100644
--- a/composer.json
+++ b/composer.json
@@ -114,7 +114,6 @@
"doctrine/data-fixtures": "^1.1",
"doctrine/dbal": "~2.4|^3.0",
"doctrine/orm": "~2.4,>=2.4.5",
- "doctrine/reflection": "~1.0",
"doctrine/doctrine-bundle": "^2.0",
"guzzlehttp/promises": "^1.3.1",
"masterminds/html5": "^2.6",
diff --git a/phpunit b/phpunit
index 71915eecb2b34..03bf63b0aae99 100755
--- a/phpunit
+++ b/phpunit
@@ -8,17 +8,12 @@ if (!file_exists(__DIR__.'/vendor/symfony/phpunit-bridge/bin/simple-phpunit')) {
exit(1);
}
if (!getenv('SYMFONY_PHPUNIT_VERSION')) {
- if (\PHP_VERSION_ID >= 70200) {
- if (false === getenv('SYMFONY_PHPUNIT_REMOVE_RETURN_TYPEHINT') && false !== strpos(@file_get_contents(__DIR__.'/src/Symfony/Component/HttpKernel/Kernel.php'), 'const MAJOR_VERSION = 3;')) {
- putenv('SYMFONY_PHPUNIT_REMOVE_RETURN_TYPEHINT=1');
- }
- if (\PHP_VERSION_ID < 70300) {
- putenv('SYMFONY_PHPUNIT_VERSION=8.5');
- } else {
- putenv('SYMFONY_PHPUNIT_VERSION=9.4');
- }
- } elseif (\PHP_VERSION_ID >= 70000) {
- putenv('SYMFONY_PHPUNIT_VERSION=6.5');
+ if (\PHP_VERSION_ID < 70200) {
+ putenv('SYMFONY_PHPUNIT_VERSION=7.5');
+ } elseif (\PHP_VERSION_ID < 70300) {
+ putenv('SYMFONY_PHPUNIT_VERSION=8.5');
+ } else {
+ putenv('SYMFONY_PHPUNIT_VERSION=9.4');
}
}
if (!getenv('SYMFONY_PATCH_TYPE_DECLARATIONS')) {
diff --git a/phpunit.xml.dist b/phpunit.xml.dist
index d2179994d502e..5bf27434011c1 100644
--- a/phpunit.xml.dist
+++ b/phpunit.xml.dist
@@ -15,7 +15,7 @@
-
+
diff --git a/src/Symfony/Bridge/Doctrine/DataCollector/DoctrineDataCollector.php b/src/Symfony/Bridge/Doctrine/DataCollector/DoctrineDataCollector.php
index 67bf68da01596..8e292cf36b8d7 100644
--- a/src/Symfony/Bridge/Doctrine/DataCollector/DoctrineDataCollector.php
+++ b/src/Symfony/Bridge/Doctrine/DataCollector/DoctrineDataCollector.php
@@ -191,7 +191,7 @@ private function sanitizeQuery(string $connectionName, array $query): array
}
}
- list($query['params'][$j], $explainable, $runnable) = $this->sanitizeParam($param, $e);
+ [$query['params'][$j], $explainable, $runnable] = $this->sanitizeParam($param, $e);
if (!$explainable) {
$query['explainable'] = false;
}
@@ -227,7 +227,7 @@ private function sanitizeParam($var, ?\Throwable $error): array
$a = [];
$explainable = $runnable = true;
foreach ($var as $k => $v) {
- list($value, $e, $r) = $this->sanitizeParam($v, null);
+ [$value, $e, $r] = $this->sanitizeParam($v, null);
$explainable = $explainable && $e;
$runnable = $runnable && $r;
$a[$k] = $value;
diff --git a/src/Symfony/Bridge/Doctrine/DependencyInjection/CompilerPass/RegisterEventListenersAndSubscribersPass.php b/src/Symfony/Bridge/Doctrine/DependencyInjection/CompilerPass/RegisterEventListenersAndSubscribersPass.php
index c1bbde27aa9c6..d2c8343ddb3c1 100644
--- a/src/Symfony/Bridge/Doctrine/DependencyInjection/CompilerPass/RegisterEventListenersAndSubscribersPass.php
+++ b/src/Symfony/Bridge/Doctrine/DependencyInjection/CompilerPass/RegisterEventListenersAndSubscribersPass.php
@@ -65,7 +65,7 @@ private function addTaggedSubscribers(ContainerBuilder $container)
$taggedSubscribers = $this->findAndSortTags($subscriberTag, $container);
foreach ($taggedSubscribers as $taggedSubscriber) {
- list($id, $tag) = $taggedSubscriber;
+ [$id, $tag] = $taggedSubscriber;
$connections = isset($tag['connection']) ? [$tag['connection']] : array_keys($this->connections);
foreach ($connections as $con) {
if (!isset($this->connections[$con])) {
@@ -84,7 +84,7 @@ private function addTaggedListeners(ContainerBuilder $container)
$listenerRefs = [];
foreach ($taggedListeners as $taggedListener) {
- list($id, $tag) = $taggedListener;
+ [$id, $tag] = $taggedListener;
if (!isset($tag['event'])) {
throw new InvalidArgumentException(sprintf('Doctrine event listener "%s" must specify the "event" attribute.', $id));
}
diff --git a/src/Symfony/Bridge/Doctrine/Form/DoctrineOrmTypeGuesser.php b/src/Symfony/Bridge/Doctrine/Form/DoctrineOrmTypeGuesser.php
index ca75617326331..f49eb7f73a642 100644
--- a/src/Symfony/Bridge/Doctrine/Form/DoctrineOrmTypeGuesser.php
+++ b/src/Symfony/Bridge/Doctrine/Form/DoctrineOrmTypeGuesser.php
@@ -49,7 +49,7 @@ public function guessType(string $class, string $property)
return new TypeGuess('Symfony\Component\Form\Extension\Core\Type\TextType', [], Guess::LOW_CONFIDENCE);
}
- list($metadata, $name) = $ret;
+ [$metadata, $name] = $ret;
if ($metadata->hasAssociation($property)) {
$multiple = $metadata->isCollectionValuedAssociation($property);
diff --git a/src/Symfony/Bridge/Doctrine/Form/Type/DoctrineType.php b/src/Symfony/Bridge/Doctrine/Form/Type/DoctrineType.php
index bccb1a9ebdc3e..21b78bada3019 100644
--- a/src/Symfony/Bridge/Doctrine/Form/Type/DoctrineType.php
+++ b/src/Symfony/Bridge/Doctrine/Form/Type/DoctrineType.php
@@ -244,6 +244,7 @@ public function getParent()
public function reset()
{
+ $this->idReaders = [];
$this->entityLoaders = [];
}
diff --git a/src/Symfony/Bridge/Doctrine/Messenger/DoctrinePingConnectionMiddleware.php b/src/Symfony/Bridge/Doctrine/Messenger/DoctrinePingConnectionMiddleware.php
index 3ec525d2cfd41..c6b219aa795ab 100644
--- a/src/Symfony/Bridge/Doctrine/Messenger/DoctrinePingConnectionMiddleware.php
+++ b/src/Symfony/Bridge/Doctrine/Messenger/DoctrinePingConnectionMiddleware.php
@@ -12,6 +12,7 @@
namespace Symfony\Bridge\Doctrine\Messenger;
use Doctrine\DBAL\DBALException;
+use Doctrine\DBAL\Exception;
use Doctrine\ORM\EntityManagerInterface;
use Symfony\Component\Messenger\Envelope;
use Symfony\Component\Messenger\Middleware\StackInterface;
@@ -38,8 +39,8 @@ private function pingConnection(EntityManagerInterface $entityManager)
$connection = $entityManager->getConnection();
try {
- $connection->query($connection->getDatabasePlatform()->getDummySelectSQL());
- } catch (DBALException $e) {
+ $connection->executeQuery($connection->getDatabasePlatform()->getDummySelectSQL());
+ } catch (DBALException | Exception $e) {
$connection->close();
$connection->connect();
}
diff --git a/src/Symfony/Bridge/Doctrine/PropertyInfo/DoctrineExtractor.php b/src/Symfony/Bridge/Doctrine/PropertyInfo/DoctrineExtractor.php
index c4e5b025c3014..732de95f9fd75 100644
--- a/src/Symfony/Bridge/Doctrine/PropertyInfo/DoctrineExtractor.php
+++ b/src/Symfony/Bridge/Doctrine/PropertyInfo/DoctrineExtractor.php
@@ -95,10 +95,24 @@ public function getTypes(string $class, string $property, array $context = [])
$associationMapping = $metadata->getAssociationMapping($property);
if (isset($associationMapping['indexBy'])) {
- $indexColumn = $associationMapping['indexBy'];
/** @var ClassMetadataInfo $subMetadata */
$subMetadata = $this->entityManager ? $this->entityManager->getClassMetadata($associationMapping['targetEntity']) : $this->classMetadataFactory->getMetadataFor($associationMapping['targetEntity']);
- $typeOfField = $subMetadata->getTypeOfField($subMetadata->getFieldForColumn($indexColumn));
+
+ // Check if indexBy value is a property
+ $fieldName = $associationMapping['indexBy'];
+ if (null === ($typeOfField = $subMetadata->getTypeOfField($fieldName))) {
+ $fieldName = $subMetadata->getFieldForColumn($associationMapping['indexBy']);
+ //Not a property, maybe a column name?
+ if (null === ($typeOfField = $subMetadata->getTypeOfField($fieldName))) {
+ //Maybe the column name is the association join column?
+ $associationMapping = $subMetadata->getAssociationMapping($fieldName);
+
+ /** @var ClassMetadataInfo $subMetadata */
+ $indexProperty = $subMetadata->getSingleAssociationReferencedJoinColumnName($fieldName);
+ $subMetadata = $this->entityManager ? $this->entityManager->getClassMetadata($associationMapping['targetEntity']) : $this->classMetadataFactory->getMetadataFor($associationMapping['targetEntity']);
+ $typeOfField = $subMetadata->getTypeOfField($indexProperty);
+ }
+ }
if (!$collectionKeyType = $this->getPhpType($typeOfField)) {
return null;
diff --git a/src/Symfony/Bridge/Doctrine/Tests/Form/Type/EntityTypePerformanceTest.php b/src/Symfony/Bridge/Doctrine/Tests/Form/Type/EntityTypePerformanceTest.php
index 89aa779301350..33e6a6fd87235 100644
--- a/src/Symfony/Bridge/Doctrine/Tests/Form/Type/EntityTypePerformanceTest.php
+++ b/src/Symfony/Bridge/Doctrine/Tests/Form/Type/EntityTypePerformanceTest.php
@@ -24,7 +24,7 @@
*/
class EntityTypePerformanceTest extends FormPerformanceTestCase
{
- const ENTITY_CLASS = 'Symfony\Bridge\Doctrine\Tests\Fixtures\SingleIntIdEntity';
+ private const ENTITY_CLASS = 'Symfony\Bridge\Doctrine\Tests\Fixtures\SingleIntIdEntity';
/**
* @var \Doctrine\ORM\EntityManager
diff --git a/src/Symfony/Bridge/Doctrine/Tests/Form/Type/EntityTypeTest.php b/src/Symfony/Bridge/Doctrine/Tests/Form/Type/EntityTypeTest.php
index ca9ab318d3f48..cc15da57ee6e8 100644
--- a/src/Symfony/Bridge/Doctrine/Tests/Form/Type/EntityTypeTest.php
+++ b/src/Symfony/Bridge/Doctrine/Tests/Form/Type/EntityTypeTest.php
@@ -39,14 +39,14 @@ class EntityTypeTest extends BaseTypeTest
{
const TESTED_TYPE = 'Symfony\Bridge\Doctrine\Form\Type\EntityType';
- const ITEM_GROUP_CLASS = 'Symfony\Bridge\Doctrine\Tests\Fixtures\GroupableEntity';
- const SINGLE_IDENT_CLASS = 'Symfony\Bridge\Doctrine\Tests\Fixtures\SingleIntIdEntity';
- const SINGLE_IDENT_NO_TO_STRING_CLASS = 'Symfony\Bridge\Doctrine\Tests\Fixtures\SingleIntIdNoToStringEntity';
- const SINGLE_STRING_IDENT_CLASS = 'Symfony\Bridge\Doctrine\Tests\Fixtures\SingleStringIdEntity';
- const SINGLE_ASSOC_IDENT_CLASS = 'Symfony\Bridge\Doctrine\Tests\Fixtures\SingleAssociationToIntIdEntity';
- const SINGLE_STRING_CASTABLE_IDENT_CLASS = 'Symfony\Bridge\Doctrine\Tests\Fixtures\SingleStringCastableIdEntity';
- const COMPOSITE_IDENT_CLASS = 'Symfony\Bridge\Doctrine\Tests\Fixtures\CompositeIntIdEntity';
- const COMPOSITE_STRING_IDENT_CLASS = 'Symfony\Bridge\Doctrine\Tests\Fixtures\CompositeStringIdEntity';
+ private const ITEM_GROUP_CLASS = 'Symfony\Bridge\Doctrine\Tests\Fixtures\GroupableEntity';
+ private const SINGLE_IDENT_CLASS = 'Symfony\Bridge\Doctrine\Tests\Fixtures\SingleIntIdEntity';
+ private const SINGLE_IDENT_NO_TO_STRING_CLASS = 'Symfony\Bridge\Doctrine\Tests\Fixtures\SingleIntIdNoToStringEntity';
+ private const SINGLE_STRING_IDENT_CLASS = 'Symfony\Bridge\Doctrine\Tests\Fixtures\SingleStringIdEntity';
+ private const SINGLE_ASSOC_IDENT_CLASS = 'Symfony\Bridge\Doctrine\Tests\Fixtures\SingleAssociationToIntIdEntity';
+ private const SINGLE_STRING_CASTABLE_IDENT_CLASS = 'Symfony\Bridge\Doctrine\Tests\Fixtures\SingleStringCastableIdEntity';
+ private const COMPOSITE_IDENT_CLASS = 'Symfony\Bridge\Doctrine\Tests\Fixtures\CompositeIntIdEntity';
+ private const COMPOSITE_STRING_IDENT_CLASS = 'Symfony\Bridge\Doctrine\Tests\Fixtures\CompositeStringIdEntity';
/**
* @var EntityManager
diff --git a/src/Symfony/Bridge/Doctrine/Tests/Messenger/DoctrinePingConnectionMiddlewareTest.php b/src/Symfony/Bridge/Doctrine/Tests/Messenger/DoctrinePingConnectionMiddlewareTest.php
index e491558a2addf..f99a48527c442 100644
--- a/src/Symfony/Bridge/Doctrine/Tests/Messenger/DoctrinePingConnectionMiddlewareTest.php
+++ b/src/Symfony/Bridge/Doctrine/Tests/Messenger/DoctrinePingConnectionMiddlewareTest.php
@@ -13,6 +13,7 @@
use Doctrine\DBAL\Connection;
use Doctrine\DBAL\DBALException;
+use Doctrine\DBAL\Exception;
use Doctrine\ORM\EntityManagerInterface;
use Doctrine\Persistence\ManagerRegistry;
use Symfony\Bridge\Doctrine\Messenger\DoctrinePingConnectionMiddleware;
@@ -49,7 +50,7 @@ public function testMiddlewarePingOk()
{
$this->connection->expects($this->once())
->method('getDatabasePlatform')
- ->will($this->throwException(new DBALException()));
+ ->will($this->throwException(class_exists(Exception::class) ? new Exception() : new DBALException()));
$this->connection->expects($this->once())
->method('close')
@@ -68,7 +69,7 @@ public function testMiddlewarePingResetEntityManager()
{
$this->connection->expects($this->once())
->method('getDatabasePlatform')
- ->will($this->throwException(new DBALException()));
+ ->will($this->throwException(class_exists(Exception::class) ? new Exception() : new DBALException()));
$this->entityManager->expects($this->once())
->method('isOpen')
diff --git a/src/Symfony/Bridge/Doctrine/Tests/PropertyInfo/DoctrineExtractorTest.php b/src/Symfony/Bridge/Doctrine/Tests/PropertyInfo/DoctrineExtractorTest.php
index 4ea6a678e3eba..52d7a95f38576 100644
--- a/src/Symfony/Bridge/Doctrine/Tests/PropertyInfo/DoctrineExtractorTest.php
+++ b/src/Symfony/Bridge/Doctrine/Tests/PropertyInfo/DoctrineExtractorTest.php
@@ -68,10 +68,13 @@ public function testGetProperties()
$expected = array_merge($expected, [
'foo',
'bar',
+ 'indexedRguid',
'indexedBar',
'indexedFoo',
+ 'indexedBaz',
'indexedByDt',
'indexedByCustomType',
+ 'indexedBuz',
]);
$this->assertEquals(
@@ -147,6 +150,14 @@ public function typesProvider()
new Type(Type::BUILTIN_TYPE_INT),
new Type(Type::BUILTIN_TYPE_OBJECT, false, 'Symfony\Bridge\Doctrine\Tests\PropertyInfo\Fixtures\DoctrineRelation')
)]],
+ ['indexedRguid', [new Type(
+ Type::BUILTIN_TYPE_OBJECT,
+ false,
+ 'Doctrine\Common\Collections\Collection',
+ true,
+ new Type(Type::BUILTIN_TYPE_STRING),
+ new Type(Type::BUILTIN_TYPE_OBJECT, false, 'Symfony\Bridge\Doctrine\Tests\PropertyInfo\Fixtures\DoctrineRelation')
+ )]],
['indexedBar', [new Type(
Type::BUILTIN_TYPE_OBJECT,
false,
@@ -163,6 +174,14 @@ public function typesProvider()
new Type(Type::BUILTIN_TYPE_STRING),
new Type(Type::BUILTIN_TYPE_OBJECT, false, 'Symfony\Bridge\Doctrine\Tests\PropertyInfo\Fixtures\DoctrineRelation')
)]],
+ ['indexedBaz', [new Type(
+ Type::BUILTIN_TYPE_OBJECT,
+ false,
+ Collection::class,
+ true,
+ new Type(Type::BUILTIN_TYPE_INT),
+ new Type(Type::BUILTIN_TYPE_OBJECT, false, DoctrineRelation::class)
+ )]],
['simpleArray', [new Type(Type::BUILTIN_TYPE_ARRAY, false, null, true, new Type(Type::BUILTIN_TYPE_INT), new Type(Type::BUILTIN_TYPE_STRING))]],
['customFoo', null],
['notMapped', null],
@@ -175,6 +194,14 @@ public function typesProvider()
new Type(Type::BUILTIN_TYPE_OBJECT, false, DoctrineRelation::class)
)]],
['indexedByCustomType', null],
+ ['indexedBuz', [new Type(
+ Type::BUILTIN_TYPE_OBJECT,
+ false,
+ Collection::class,
+ true,
+ new Type(Type::BUILTIN_TYPE_STRING),
+ new Type(Type::BUILTIN_TYPE_OBJECT, false, DoctrineRelation::class)
+ )]],
];
if (class_exists(Types::class)) {
diff --git a/src/Symfony/Bridge/Doctrine/Tests/PropertyInfo/Fixtures/DoctrineDummy.php b/src/Symfony/Bridge/Doctrine/Tests/PropertyInfo/Fixtures/DoctrineDummy.php
index 568efce33d382..a065dc49cd2d4 100644
--- a/src/Symfony/Bridge/Doctrine/Tests/PropertyInfo/Fixtures/DoctrineDummy.php
+++ b/src/Symfony/Bridge/Doctrine/Tests/PropertyInfo/Fixtures/DoctrineDummy.php
@@ -41,6 +41,11 @@ class DoctrineDummy
*/
public $bar;
+ /**
+ * @ManyToMany(targetEntity="DoctrineRelation", indexBy="rguid")
+ */
+ protected $indexedRguid;
+
/**
* @ManyToMany(targetEntity="DoctrineRelation", indexBy="rguid_column")
*/
@@ -51,6 +56,11 @@ class DoctrineDummy
*/
protected $indexedFoo;
+ /**
+ * @OneToMany(targetEntity="DoctrineRelation", mappedBy="baz", indexBy="baz_id")
+ */
+ protected $indexedBaz;
+
/**
* @Column(type="guid")
*/
@@ -122,4 +132,9 @@ class DoctrineDummy
* @OneToMany(targetEntity="DoctrineRelation", mappedBy="customType", indexBy="customType")
*/
private $indexedByCustomType;
+
+ /**
+ * @OneToMany(targetEntity="DoctrineRelation", mappedBy="buzField", indexBy="buzField")
+ */
+ protected $indexedBuz;
}
diff --git a/src/Symfony/Bridge/Doctrine/Tests/PropertyInfo/Fixtures/DoctrineFooType.php b/src/Symfony/Bridge/Doctrine/Tests/PropertyInfo/Fixtures/DoctrineFooType.php
index e8f2b454cfa95..1131666483d22 100644
--- a/src/Symfony/Bridge/Doctrine/Tests/PropertyInfo/Fixtures/DoctrineFooType.php
+++ b/src/Symfony/Bridge/Doctrine/Tests/PropertyInfo/Fixtures/DoctrineFooType.php
@@ -23,7 +23,7 @@ class DoctrineFooType extends Type
/**
* Type name.
*/
- const NAME = 'foo';
+ private const NAME = 'foo';
/**
* {@inheritdoc}
diff --git a/src/Symfony/Bridge/Doctrine/Tests/PropertyInfo/Fixtures/DoctrineRelation.php b/src/Symfony/Bridge/Doctrine/Tests/PropertyInfo/Fixtures/DoctrineRelation.php
index e480ca9d777ba..d6d9af6d70c38 100644
--- a/src/Symfony/Bridge/Doctrine/Tests/PropertyInfo/Fixtures/DoctrineRelation.php
+++ b/src/Symfony/Bridge/Doctrine/Tests/PropertyInfo/Fixtures/DoctrineRelation.php
@@ -40,6 +40,11 @@ class DoctrineRelation
*/
protected $foo;
+ /**
+ * @ManyToOne(targetEntity="DoctrineDummy")
+ */
+ protected $baz;
+
/**
* @Column(type="datetime")
*/
@@ -49,4 +54,10 @@ class DoctrineRelation
* @Column(type="foo")
*/
private $customType;
+
+ /**
+ * @Column(type="guid", name="different_than_field")
+ * @ManyToOne(targetEntity="DoctrineDummy", inversedBy="indexedBuz")
+ */
+ protected $buzField;
}
diff --git a/src/Symfony/Bridge/Doctrine/Tests/Validator/Constraints/UniqueEntityValidatorTest.php b/src/Symfony/Bridge/Doctrine/Tests/Validator/Constraints/UniqueEntityValidatorTest.php
index e9e905c89c3a4..1ccc4b7cc4feb 100644
--- a/src/Symfony/Bridge/Doctrine/Tests/Validator/Constraints/UniqueEntityValidatorTest.php
+++ b/src/Symfony/Bridge/Doctrine/Tests/Validator/Constraints/UniqueEntityValidatorTest.php
@@ -40,7 +40,7 @@
*/
class UniqueEntityValidatorTest extends ConstraintValidatorTestCase
{
- const EM_NAME = 'foo';
+ private const EM_NAME = 'foo';
/**
* @var ObjectManager
@@ -114,17 +114,8 @@ protected function createEntityManagerMock($repositoryMock)
->method('hasField')
->willReturn(true)
;
- $reflParser = $this->getMockBuilder('Doctrine\Common\Reflection\StaticReflectionParser')
- ->disableOriginalConstructor()
- ->getMock()
- ;
- $refl = $this->getMockBuilder('Doctrine\Common\Reflection\StaticReflectionProperty')
- ->setConstructorArgs([$reflParser, 'property-name'])
- ->setMethods(['getValue'])
- ->getMock()
- ;
+ $refl = $this->createMock(\ReflectionProperty::class);
$refl
- ->expects($this->any())
->method('getValue')
->willReturn(true)
;
diff --git a/src/Symfony/Bridge/Doctrine/composer.json b/src/Symfony/Bridge/Doctrine/composer.json
index b0189df45993e..2961eca001f58 100644
--- a/src/Symfony/Bridge/Doctrine/composer.json
+++ b/src/Symfony/Bridge/Doctrine/composer.json
@@ -47,8 +47,7 @@
"doctrine/collections": "~1.0",
"doctrine/data-fixtures": "^1.1",
"doctrine/dbal": "~2.4|^3.0",
- "doctrine/orm": "^2.6.3",
- "doctrine/reflection": "~1.0"
+ "doctrine/orm": "^2.6.3"
},
"conflict": {
"phpunit/phpunit": "<5.4.3",
diff --git a/src/Symfony/Bridge/Monolog/Tests/LoggerTest.php b/src/Symfony/Bridge/Monolog/Tests/LoggerTest.php
index f170c526b8f74..f3d2fd8f024bb 100644
--- a/src/Symfony/Bridge/Monolog/Tests/LoggerTest.php
+++ b/src/Symfony/Bridge/Monolog/Tests/LoggerTest.php
@@ -75,7 +75,7 @@ public function testGetLogsWithDebugProcessor2()
$logger->info('test');
$this->assertCount(1, $logger->getLogs());
- list($record) = $logger->getLogs();
+ [$record] = $logger->getLogs();
$this->assertEquals('test', $record['message']);
$this->assertEquals(Logger::INFO, $record['priority']);
diff --git a/src/Symfony/Bridge/Monolog/Tests/Processor/WebProcessorTest.php b/src/Symfony/Bridge/Monolog/Tests/Processor/WebProcessorTest.php
index 321bd7a8eed32..24aed730954e4 100644
--- a/src/Symfony/Bridge/Monolog/Tests/Processor/WebProcessorTest.php
+++ b/src/Symfony/Bridge/Monolog/Tests/Processor/WebProcessorTest.php
@@ -22,7 +22,7 @@ class WebProcessorTest extends TestCase
{
public function testUsesRequestServerData()
{
- list($event, $server) = $this->createRequestEvent();
+ [$event, $server] = $this->createRequestEvent();
$processor = new WebProcessor();
$processor->onKernelRequest($event);
@@ -39,7 +39,7 @@ public function testUsesRequestServerData()
public function testUseRequestClientIp()
{
Request::setTrustedProxies(['192.168.0.1'], Request::HEADER_X_FORWARDED_ALL);
- list($event, $server) = $this->createRequestEvent(['X_FORWARDED_FOR' => '192.168.0.2']);
+ [$event, $server] = $this->createRequestEvent(['X_FORWARDED_FOR' => '192.168.0.2']);
$processor = new WebProcessor();
$processor->onKernelRequest($event);
@@ -61,7 +61,7 @@ public function testCanBeConstructedWithExtraFields()
$this->markTestSkipped('WebProcessor of the installed Monolog version does not support $extraFields parameter');
}
- list($event, $server) = $this->createRequestEvent();
+ [$event, $server] = $this->createRequestEvent();
$processor = new WebProcessor(['url', 'referrer']);
$processor->onKernelRequest($event);
diff --git a/src/Symfony/Bridge/PhpUnit/.gitignore b/src/Symfony/Bridge/PhpUnit/.gitignore
index c49a5d8df5c65..9d8c4aadaf9f5 100644
--- a/src/Symfony/Bridge/PhpUnit/.gitignore
+++ b/src/Symfony/Bridge/PhpUnit/.gitignore
@@ -1,3 +1,4 @@
vendor/
composer.lock
phpunit.xml
+Tests/DeprecationErrorHandler/fake_vendor/symfony/error-handler/DebugClassLoader.php
diff --git a/src/Symfony/Bridge/PhpUnit/DeprecationErrorHandler/Deprecation.php b/src/Symfony/Bridge/PhpUnit/DeprecationErrorHandler/Deprecation.php
index 797ed145bb6b9..85d776638d3bb 100644
--- a/src/Symfony/Bridge/PhpUnit/DeprecationErrorHandler/Deprecation.php
+++ b/src/Symfony/Bridge/PhpUnit/DeprecationErrorHandler/Deprecation.php
@@ -13,6 +13,8 @@
use PHPUnit\Util\Test;
use Symfony\Bridge\PhpUnit\Legacy\SymfonyTestsListenerFor;
+use Symfony\Component\Debug\DebugClassLoader as LegacyDebugClassLoader;
+use Symfony\Component\ErrorHandler\DebugClassLoader;
/**
* @internal
@@ -58,6 +60,18 @@ public function __construct($message, array $trace, $file)
}
$this->trace = $trace;
+
+ if ('trigger_error' === ($trace[1]['function'] ?? null)
+ && (DebugClassLoader::class === ($class = $trace[2]['class'] ?? null) || LegacyDebugClassLoader::class === $class)
+ && 'checkClass' === ($trace[2]['function'] ?? null)
+ && null !== ($extraFile = $trace[2]['args'][1] ?? null)
+ && '' !== $extraFile
+ && false !== $extraFile = realpath($extraFile)
+ ) {
+ $this->getOriginalFilesStack();
+ array_splice($this->originalFilesStack, 2, 1, $extraFile);
+ }
+
$this->message = $message;
$i = \count($this->trace);
while (1 < $i && $this->lineShouldBeSkipped($this->trace[--$i])) {
diff --git a/src/Symfony/Bridge/PhpUnit/Legacy/ConstraintTraitForV7.php b/src/Symfony/Bridge/PhpUnit/Legacy/ConstraintTraitForV7.php
index 1e625e463a1e8..b132f473c547e 100644
--- a/src/Symfony/Bridge/PhpUnit/Legacy/ConstraintTraitForV7.php
+++ b/src/Symfony/Bridge/PhpUnit/Legacy/ConstraintTraitForV7.php
@@ -45,7 +45,7 @@ protected function additionalFailureDescription($other): string
protected function exporter(): Exporter
{
- if (null !== $this->exporter) {
+ if (null === $this->exporter) {
$this->exporter = new Exporter();
}
diff --git a/src/Symfony/Bridge/PhpUnit/Legacy/SymfonyTestsListenerTrait.php b/src/Symfony/Bridge/PhpUnit/Legacy/SymfonyTestsListenerTrait.php
index 693883ed78762..6238fc0281209 100644
--- a/src/Symfony/Bridge/PhpUnit/Legacy/SymfonyTestsListenerTrait.php
+++ b/src/Symfony/Bridge/PhpUnit/Legacy/SymfonyTestsListenerTrait.php
@@ -123,7 +123,7 @@ public function startTestSuite($suite)
$suiteName = $suite->getName();
foreach ($suite->tests() as $test) {
- if (!($test instanceof \PHPUnit\Framework\TestCase || $test instanceof TestCase)) {
+ if (!($test instanceof \PHPUnit_Framework_TestCase || $test instanceof TestCase)) {
continue;
}
if (null === Test::getPreserveGlobalStateSettings(\get_class($test), $test->getName(false))) {
@@ -158,7 +158,7 @@ public function startTestSuite($suite)
$testSuites = [$suite];
for ($i = 0; isset($testSuites[$i]); ++$i) {
foreach ($testSuites[$i]->tests() as $test) {
- if ($test instanceof TestSuite) {
+ if ($test instanceof \PHPUnit_Framework_TestSuite || $test instanceof TestSuite) {
if (!class_exists($test->getName(), false)) {
$testSuites[] = $test;
continue;
@@ -174,12 +174,19 @@ public function startTestSuite($suite)
}
}
} elseif (2 === $this->state) {
+ $suites = [$suite];
$skipped = [];
- foreach ($suite->tests() as $test) {
- if (!($test instanceof \PHPUnit\Framework\TestCase || $test instanceof TestCase)
- || isset($this->wasSkipped[$suiteName]['*'])
- || isset($this->wasSkipped[$suiteName][$test->getName()])) {
- $skipped[] = $test;
+ while ($s = array_shift($suites)) {
+ foreach ($s->tests() as $test) {
+ if ($test instanceof \PHPUnit_Framework_TestSuite || $test instanceof TestSuite) {
+ $suites[] = $test;
+ continue;
+ }
+ if (($test instanceof \PHPUnit_Framework_TestCase || $test instanceof TestCase)
+ && isset($this->wasSkipped[\get_class($test)][$test->getName()])
+ ) {
+ $skipped[] = $test;
+ }
}
}
$suite->setTests($skipped);
@@ -189,21 +196,13 @@ public function startTestSuite($suite)
public function addSkippedTest($test, \Exception $e, $time)
{
if (0 < $this->state) {
- if ($test instanceof \PHPUnit\Framework\TestCase || $test instanceof TestCase) {
- $class = \get_class($test);
- $method = $test->getName();
- } else {
- $class = $test->getName();
- $method = '*';
- }
-
- $this->isSkipped[$class][$method] = 1;
+ $this->isSkipped[\get_class($test)][$test->getName()] = 1;
}
}
public function startTest($test)
{
- if (-2 < $this->state && ($test instanceof \PHPUnit\Framework\TestCase || $test instanceof TestCase)) {
+ if (-2 < $this->state && ($test instanceof \PHPUnit_Framework_TestCase || $test instanceof TestCase)) {
// This event is triggered before the test is re-run in isolation
if ($this->willBeIsolated($test)) {
$this->runsInSeparateProcess = tempnam(sys_get_temp_dir(), 'deprec');
@@ -313,7 +312,7 @@ public function endTest($test, $time)
self::$expectedDeprecations = self::$gatheredDeprecations = [];
self::$previousErrorHandler = null;
}
- if (!$this->runsInSeparateProcess && -2 < $this->state && ($test instanceof \PHPUnit\Framework\TestCase || $test instanceof TestCase)) {
+ if (!$this->runsInSeparateProcess && -2 < $this->state && ($test instanceof \PHPUnit_Framework_TestCase || $test instanceof TestCase)) {
if (\in_array('time-sensitive', $groups, true)) {
ClockMock::withClockMock(false);
}
diff --git a/src/Symfony/Bridge/PhpUnit/Tests/DeprecationErrorHandler/debug_class_loader_autoload.phpt b/src/Symfony/Bridge/PhpUnit/Tests/DeprecationErrorHandler/debug_class_loader_autoload.phpt
new file mode 100644
index 0000000000000..781027e84fe66
--- /dev/null
+++ b/src/Symfony/Bridge/PhpUnit/Tests/DeprecationErrorHandler/debug_class_loader_autoload.phpt
@@ -0,0 +1,51 @@
+--TEST--
+Test that a deprecation from the DebugClassLoader on a vendor class autoload triggered by an app class is considered indirect.
+--FILE--
+
+--EXPECTF--
+Remaining indirect deprecation notices (1)
+
+ 1x: The "acme\lib\ExtendsDeprecatedClassFromOtherVendor" class extends "fcy\lib\DeprecatedClass" that is deprecated.
+ 1x in BarService::__construct from App\Services
diff --git a/src/Symfony/Bridge/PhpUnit/Tests/DeprecationErrorHandler/fake_app/BarService.php b/src/Symfony/Bridge/PhpUnit/Tests/DeprecationErrorHandler/fake_app/BarService.php
new file mode 100644
index 0000000000000..868de5bd443db
--- /dev/null
+++ b/src/Symfony/Bridge/PhpUnit/Tests/DeprecationErrorHandler/fake_app/BarService.php
@@ -0,0 +1,13 @@
+ [__DIR__.'/../../fake_app/'],
'acme\\lib\\' => [__DIR__.'/../acme/lib/'],
'bar\\lib\\' => [__DIR__.'/../bar/lib/'],
+ 'fcy\\lib\\' => [__DIR__.'/../fcy/lib/'],
];
}
public function loadClass($className)
+ {
+ if ($file = $this->findFile($className)) {
+ require $file;
+ }
+ }
+
+ public function findFile($class)
{
foreach ($this->getPrefixesPsr4() as $prefix => $baseDirs) {
- if (strpos($className, $prefix) !== 0) {
+ if (strpos($class, $prefix) !== 0) {
continue;
}
foreach ($baseDirs as $baseDir) {
- $file = str_replace([$prefix, '\\'], [$baseDir, '/'], $className.'.php');
+ $file = str_replace([$prefix, '\\'], [$baseDir, '/'], $class.'.php');
if (file_exists($file)) {
- require $file;
+ return $file;
}
}
}
+
+ return false;
}
}
diff --git a/src/Symfony/Bridge/PhpUnit/Tests/DeprecationErrorHandler/fake_vendor/fcy/lib/DeprecatedClass.php b/src/Symfony/Bridge/PhpUnit/Tests/DeprecationErrorHandler/fake_vendor/fcy/lib/DeprecatedClass.php
new file mode 100644
index 0000000000000..f6672cea20400
--- /dev/null
+++ b/src/Symfony/Bridge/PhpUnit/Tests/DeprecationErrorHandler/fake_vendor/fcy/lib/DeprecatedClass.php
@@ -0,0 +1,10 @@
+=5.5.9"
},
"require-dev": {
- "symfony/deprecation-contracts": "^2.1"
+ "symfony/deprecation-contracts": "^2.1",
+ "symfony/error-handler": "^4.4|^5.0"
},
"suggest": {
"symfony/error-handler": "For tracking deprecated interfaces usages at runtime with DebugClassLoader"
diff --git a/src/Symfony/Bridge/ProxyManager/LazyProxy/PhpDumper/ProxyDumper.php b/src/Symfony/Bridge/ProxyManager/LazyProxy/PhpDumper/ProxyDumper.php
index a9772a2b87342..cd7642911ab87 100644
--- a/src/Symfony/Bridge/ProxyManager/LazyProxy/PhpDumper/ProxyDumper.php
+++ b/src/Symfony/Bridge/ProxyManager/LazyProxy/PhpDumper/ProxyDumper.php
@@ -11,9 +11,10 @@
namespace Symfony\Bridge\ProxyManager\LazyProxy\PhpDumper;
+use ProxyManager\Exception\ExceptionInterface;
use ProxyManager\Generator\ClassGenerator;
+use ProxyManager\Generator\MethodGenerator;
use ProxyManager\GeneratorStrategy\BaseGeneratorStrategy;
-use ProxyManager\Version;
use Symfony\Component\DependencyInjection\Definition;
use Symfony\Component\DependencyInjection\LazyProxy\PhpDumper\DumperInterface;
@@ -83,7 +84,7 @@ public function getProxyCode(Definition $definition): string
$code = $this->classGenerator->generate($this->generateProxyClass($definition));
$code = preg_replace('/^(class [^ ]++ extends )([^\\\\])/', '$1\\\\$2', $code);
- if (version_compare(self::getProxyManagerVersion(), '2.2', '<')) {
+ if (!method_exists(MethodGenerator::class, 'fromReflectionWithoutBodyAndDocBlock')) { // proxy-manager < 2.2
$code = preg_replace(
'/((?:\$(?:this|initializer|instance)->)?(?:publicProperties|initializer|valueHolder))[0-9a-f]++/',
'${1}'.$this->getIdentifierSuffix($definition),
@@ -91,22 +92,13 @@ public function getProxyCode(Definition $definition): string
);
}
- if (version_compare(self::getProxyManagerVersion(), '2.5', '<')) {
+ if (!is_subclass_of(ExceptionInterface::class, 'Throwable')) { // proxy-manager < 2.5
$code = preg_replace('/ \\\\Closure::bind\(function ((?:& )?\(\$instance(?:, \$value)?\))/', ' \Closure::bind(static function \1', $code);
}
return $code;
}
- private static function getProxyManagerVersion(): string
- {
- if (!class_exists(Version::class)) {
- return '0.0.1';
- }
-
- return \defined(Version::class.'::VERSION') ? Version::VERSION : Version::getVersion();
- }
-
/**
* Produces the proxy class name for the given definition.
*/
diff --git a/src/Symfony/Bridge/ProxyManager/Tests/LazyProxy/PhpDumper/Fixtures/proxy-implem.php b/src/Symfony/Bridge/ProxyManager/Tests/LazyProxy/PhpDumper/Fixtures/proxy-implem.php
index 3362aab9fb5eb..684ff36581776 100644
--- a/src/Symfony/Bridge/ProxyManager/Tests/LazyProxy/PhpDumper/Fixtures/proxy-implem.php
+++ b/src/Symfony/Bridge/ProxyManager/Tests/LazyProxy/PhpDumper/Fixtures/proxy-implem.php
@@ -76,7 +76,7 @@ public function & __get($name)
$targetObject = $this->valueHolder%s;
- $backtrace = debug_backtrace(false);
+ $backtrace = debug_backtrace(false%S);
trigger_error(
sprintf(
'Undefined property: %s::$%s in %s on line %s',
@@ -115,8 +115,7 @@ public function __unset($name)
$targetObject = $this->valueHolder%s;
unset($targetObject->$name);
-return;
- }
+%a }
public function __clone()
{
diff --git a/src/Symfony/Bridge/Twig/Command/DebugCommand.php b/src/Symfony/Bridge/Twig/Command/DebugCommand.php
index 974a38a9c3dca..8962a41dd366e 100644
--- a/src/Symfony/Bridge/Twig/Command/DebugCommand.php
+++ b/src/Symfony/Bridge/Twig/Command/DebugCommand.php
@@ -147,7 +147,7 @@ private function displayPathsText(SymfonyStyle $io, string $name)
$shortnames[] = str_replace('\\', '/', $file->getRelativePathname());
}
- list($namespace, $shortname) = $this->parseTemplateName($name);
+ [$namespace, $shortname] = $this->parseTemplateName($name);
$alternatives = $this->findAlternatives($shortname, $shortnames);
if (FilesystemLoader::MAIN_NAMESPACE !== $namespace) {
$alternatives = array_map(function ($shortname) use ($namespace) {
@@ -452,7 +452,7 @@ private function error(SymfonyStyle $io, string $message, array $alternatives =
private function findTemplateFiles(string $name): array
{
- list($namespace, $shortname) = $this->parseTemplateName($name);
+ [$namespace, $shortname] = $this->parseTemplateName($name);
$files = [];
foreach ($this->getFilesystemLoaders() as $loader) {
diff --git a/src/Symfony/Bridge/Twig/Extension/CodeExtension.php b/src/Symfony/Bridge/Twig/Extension/CodeExtension.php
index 0ff70eccd6886..7acf75fb9c17a 100644
--- a/src/Symfony/Bridge/Twig/Extension/CodeExtension.php
+++ b/src/Symfony/Bridge/Twig/Extension/CodeExtension.php
@@ -66,7 +66,7 @@ public function abbrClass(string $class): string
public function abbrMethod(string $method): string
{
if (false !== strpos($method, '::')) {
- list($class, $method) = explode('::', $method, 2);
+ [$class, $method] = explode('::', $method, 2);
$result = sprintf('%s::%s()', $this->abbrClass($class), $method);
} elseif ('Closure' === $method) {
$result = sprintf('%1$s', $method);
diff --git a/src/Symfony/Bridge/Twig/Node/TransNode.php b/src/Symfony/Bridge/Twig/Node/TransNode.php
index da2b85d1c2861..8a126ba569172 100644
--- a/src/Symfony/Bridge/Twig/Node/TransNode.php
+++ b/src/Symfony/Bridge/Twig/Node/TransNode.php
@@ -52,7 +52,7 @@ public function compile(Compiler $compiler): void
$defaults = $this->getNode('vars');
$vars = null;
}
- list($msg, $defaults) = $this->compileString($this->getNode('body'), $defaults, (bool) $vars);
+ [$msg, $defaults] = $this->compileString($this->getNode('body'), $defaults, (bool) $vars);
$compiler
->write('echo $this->env->getExtension(\'Symfony\Bridge\Twig\Extension\TranslationExtension\')->trans(')
diff --git a/src/Symfony/Bridge/Twig/Tests/Extension/AbstractBootstrap3LayoutTest.php b/src/Symfony/Bridge/Twig/Tests/Extension/AbstractBootstrap3LayoutTest.php
index 0a9319472552b..73ec1c18277e2 100644
--- a/src/Symfony/Bridge/Twig/Tests/Extension/AbstractBootstrap3LayoutTest.php
+++ b/src/Symfony/Bridge/Twig/Tests/Extension/AbstractBootstrap3LayoutTest.php
@@ -2393,7 +2393,7 @@ public function testTextarea()
$this->assertWidgetMatchesXpath($form->createView(), ['attr' => ['class' => 'my&class']],
'/textarea
[@name="name"]
- [@pattern="foo"]
+ [not(@pattern)]
[@class="my&class form-control"]
[.="foo&bar"]
'
diff --git a/src/Symfony/Bridge/Twig/composer.json b/src/Symfony/Bridge/Twig/composer.json
index 5454e868e0766..877b7e1c01aad 100644
--- a/src/Symfony/Bridge/Twig/composer.json
+++ b/src/Symfony/Bridge/Twig/composer.json
@@ -26,7 +26,7 @@
"symfony/asset": "^4.4|^5.0",
"symfony/dependency-injection": "^4.4|^5.0",
"symfony/finder": "^4.4|^5.0",
- "symfony/form": "^5.1",
+ "symfony/form": "^5.1.9",
"symfony/http-foundation": "^4.4|^5.0",
"symfony/http-kernel": "^4.4|^5.0",
"symfony/mime": "^4.4|^5.0",
diff --git a/src/Symfony/Bundle/FrameworkBundle/CHANGELOG.md b/src/Symfony/Bundle/FrameworkBundle/CHANGELOG.md
index 9815c8fd12616..1b5fc917beb54 100644
--- a/src/Symfony/Bundle/FrameworkBundle/CHANGELOG.md
+++ b/src/Symfony/Bundle/FrameworkBundle/CHANGELOG.md
@@ -3,7 +3,7 @@ CHANGELOG
5.1.0
-----
-
+ * Removed `--no-backup` option from `translation:update` command (broken since `5.0.0`)
* Added link to source for controllers registered as named services
* Added link to source on controller on `router:match`/`debug:router` (when `framework.ide` is configured)
* Added the `framework.router.default_uri` configuration option to configure the default `RequestContext`
diff --git a/src/Symfony/Bundle/FrameworkBundle/Command/TranslationUpdateCommand.php b/src/Symfony/Bundle/FrameworkBundle/Command/TranslationUpdateCommand.php
index 57a9a19157fa3..f43e236b7a402 100644
--- a/src/Symfony/Bundle/FrameworkBundle/Command/TranslationUpdateCommand.php
+++ b/src/Symfony/Bundle/FrameworkBundle/Command/TranslationUpdateCommand.php
@@ -79,7 +79,6 @@ protected function configure()
new InputOption('output-format', null, InputOption::VALUE_OPTIONAL, 'Override the default output format', 'xlf'),
new InputOption('dump-messages', null, InputOption::VALUE_NONE, 'Should the messages be dumped in the console'),
new InputOption('force', null, InputOption::VALUE_NONE, 'Should the update be done'),
- new InputOption('no-backup', null, InputOption::VALUE_NONE, 'Should backup be disabled'),
new InputOption('clean', null, InputOption::VALUE_NONE, 'Should clean not found messages'),
new InputOption('domain', null, InputOption::VALUE_OPTIONAL, 'Specify the domain to update'),
new InputOption('xliff-version', null, InputOption::VALUE_OPTIONAL, 'Override the default xliff version', '1.2'),
@@ -283,10 +282,6 @@ protected function execute(InputInterface $input, OutputInterface $output): int
$resultMessage = sprintf('%d message%s successfully extracted', $extractedMessagesCount, $extractedMessagesCount > 1 ? 's were' : ' was');
}
- if (true === $input->getOption('no-backup')) {
- $this->writer->disableBackup();
- }
-
// save the files
if (true === $input->getOption('force')) {
$io->comment('Writing files...');
diff --git a/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/FrameworkExtension.php b/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/FrameworkExtension.php
index 60302152b10e7..5b3c3d541cc57 100644
--- a/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/FrameworkExtension.php
+++ b/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/FrameworkExtension.php
@@ -493,6 +493,14 @@ public function load(array $configs, ContainerBuilder $container)
$container->registerForAutoconfiguration(RouteLoaderInterface::class)
->addTag('routing.route_loader');
+
+ $container->setParameter('container.behavior_describing_tags', [
+ 'container.service_locator',
+ 'container.service_subscriber',
+ 'kernel.event_subscriber',
+ 'kernel.locale_aware',
+ 'kernel.reset',
+ ]);
}
/**
@@ -609,7 +617,7 @@ private function registerProfilerConfiguration(array $config, ContainerBuilder $
$container->setParameter('profiler_listener.only_master_requests', $config['only_master_requests']);
// Choose storage class based on the DSN
- list($class) = explode(':', $config['dsn'], 2);
+ [$class] = explode(':', $config['dsn'], 2);
if ('file' !== $class) {
throw new \LogicException(sprintf('Driver "%s" is not supported for the profiler.', $class));
}
diff --git a/src/Symfony/Bundle/FrameworkBundle/KernelBrowser.php b/src/Symfony/Bundle/FrameworkBundle/KernelBrowser.php
index 6e44657cf8181..40381e34aa310 100644
--- a/src/Symfony/Bundle/FrameworkBundle/KernelBrowser.php
+++ b/src/Symfony/Bundle/FrameworkBundle/KernelBrowser.php
@@ -65,7 +65,7 @@ public function getKernel()
/**
* Gets the profile associated with the current Response.
*
- * @return HttpProfile|false A Profile instance
+ * @return HttpProfile|false|null A Profile instance
*/
public function getProfile()
{
diff --git a/src/Symfony/Bundle/FrameworkBundle/Resources/config/mime_type.xml b/src/Symfony/Bundle/FrameworkBundle/Resources/config/mime_type.xml
index d4c1eb15b9088..e91705d1c19ed 100644
--- a/src/Symfony/Bundle/FrameworkBundle/Resources/config/mime_type.xml
+++ b/src/Symfony/Bundle/FrameworkBundle/Resources/config/mime_type.xml
@@ -12,5 +12,7 @@
+
+
diff --git a/src/Symfony/Bundle/FrameworkBundle/Resources/config/notifier_transports.xml b/src/Symfony/Bundle/FrameworkBundle/Resources/config/notifier_transports.xml
index 045eb52a1b96e..42a4f5183f618 100644
--- a/src/Symfony/Bundle/FrameworkBundle/Resources/config/notifier_transports.xml
+++ b/src/Symfony/Bundle/FrameworkBundle/Resources/config/notifier_transports.xml
@@ -35,7 +35,7 @@
-
+
diff --git a/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/FrameworkExtensionTest.php b/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/FrameworkExtensionTest.php
index c6f158eb8c0d0..52b4f481163bd 100644
--- a/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/FrameworkExtensionTest.php
+++ b/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/FrameworkExtensionTest.php
@@ -1477,6 +1477,20 @@ public function testMailerWithSpecificMessageBus(): void
$this->assertEquals(new Reference('app.another_bus'), $container->getDefinition('mailer.mailer')->getArgument(1));
}
+ public function testRegisterParameterCollectingBehaviorDescribingTags()
+ {
+ $container = $this->createContainerFromFile('default_config');
+
+ $this->assertTrue($container->hasParameter('container.behavior_describing_tags'));
+ $this->assertEquals([
+ 'container.service_locator',
+ 'container.service_subscriber',
+ 'kernel.event_subscriber',
+ 'kernel.locale_aware',
+ 'kernel.reset',
+ ], $container->getParameter('container.behavior_describing_tags'));
+ }
+
protected function createContainer(array $data = [])
{
return new ContainerBuilder(new EnvPlaceholderParameterBag(array_merge([
diff --git a/src/Symfony/Bundle/FrameworkBundle/Tests/Functional/Bundle/TestBundle/Controller/SessionController.php b/src/Symfony/Bundle/FrameworkBundle/Tests/Functional/Bundle/TestBundle/Controller/SessionController.php
index 0d9464d7dfab4..168cd2d45a52a 100644
--- a/src/Symfony/Bundle/FrameworkBundle/Tests/Functional/Bundle/TestBundle/Controller/SessionController.php
+++ b/src/Symfony/Bundle/FrameworkBundle/Tests/Functional/Bundle/TestBundle/Controller/SessionController.php
@@ -71,7 +71,7 @@ public function showFlashAction(Request $request)
$session = $request->getSession();
if ($session->getFlashBag()->has('notice')) {
- list($output) = $session->getFlashBag()->get('notice');
+ [$output] = $session->getFlashBag()->get('notice');
} else {
$output = 'No flash was set.';
}
diff --git a/src/Symfony/Bundle/FrameworkBundle/Translation/Translator.php b/src/Symfony/Bundle/FrameworkBundle/Translation/Translator.php
index 8ae38fd392168..08c920fd951c6 100644
--- a/src/Symfony/Bundle/FrameworkBundle/Translation/Translator.php
+++ b/src/Symfony/Bundle/FrameworkBundle/Translation/Translator.php
@@ -155,7 +155,7 @@ protected function initialize()
$this->addResourceFiles();
}
foreach ($this->resources as $key => $params) {
- list($format, $resource, $locale, $domain) = $params;
+ [$format, $resource, $locale, $domain] = $params;
parent::addResource($format, $resource, $locale, $domain);
}
$this->resources = [];
diff --git a/src/Symfony/Bundle/SecurityBundle/DependencyInjection/Compiler/RegisterTokenUsageTrackingPass.php b/src/Symfony/Bundle/SecurityBundle/DependencyInjection/Compiler/RegisterTokenUsageTrackingPass.php
index 94d5a184727e8..1cd90fe70af1a 100644
--- a/src/Symfony/Bundle/SecurityBundle/DependencyInjection/Compiler/RegisterTokenUsageTrackingPass.php
+++ b/src/Symfony/Bundle/SecurityBundle/DependencyInjection/Compiler/RegisterTokenUsageTrackingPass.php
@@ -45,8 +45,12 @@ public function process(ContainerBuilder $container)
$container->setAlias('security.token_storage', 'security.untracked_token_storage')->setPublic(true);
$container->getDefinition('security.untracked_token_storage')->addTag('kernel.reset', ['method' => 'reset']);
} elseif ($container->hasDefinition('security.context_listener')) {
- $container->getDefinition('security.context_listener')
- ->setArgument(6, [new Reference('security.token_storage'), 'enableUsageTracking']);
+ $tokenStorageClass = $container->getParameterBag()->resolveValue($container->findDefinition('security.token_storage')->getClass());
+
+ if (method_exists($tokenStorageClass, 'enableUsageTracking')) {
+ $container->getDefinition('security.context_listener')
+ ->setArgument(6, [new Reference('security.token_storage'), 'enableUsageTracking']);
+ }
}
}
}
diff --git a/src/Symfony/Bundle/SecurityBundle/DependencyInjection/SecurityExtension.php b/src/Symfony/Bundle/SecurityBundle/DependencyInjection/SecurityExtension.php
index 7202b2e5a95e0..a1a972cb32d26 100644
--- a/src/Symfony/Bundle/SecurityBundle/DependencyInjection/SecurityExtension.php
+++ b/src/Symfony/Bundle/SecurityBundle/DependencyInjection/SecurityExtension.php
@@ -271,7 +271,7 @@ private function createFirewalls(array $config, ContainerBuilder $container)
$configId = 'security.firewall.map.config.'.$name;
- list($matcher, $listeners, $exceptionListener, $logoutListener) = $this->createFirewall($container, $name, $firewall, $authenticationProviders, $providerIds, $configId);
+ [$matcher, $listeners, $exceptionListener, $logoutListener] = $this->createFirewall($container, $name, $firewall, $authenticationProviders, $providerIds, $configId);
$contextId = 'security.firewall.map.context.'.$name;
$isLazy = !$firewall['stateless'] && (!empty($firewall['anonymous']['lazy']) || $firewall['lazy']);
@@ -449,7 +449,7 @@ private function createFirewall(ContainerBuilder $container, string $id, array $
// Authentication listeners
$firewallAuthenticationProviders = [];
- list($authListeners, $defaultEntryPoint) = $this->createAuthenticationListeners($container, $id, $firewall, $firewallAuthenticationProviders, $defaultProvider, $providerIds, $configuredEntryPoint, $contextListenerId);
+ [$authListeners, $defaultEntryPoint] = $this->createAuthenticationListeners($container, $id, $firewall, $firewallAuthenticationProviders, $defaultProvider, $providerIds, $configuredEntryPoint, $contextListenerId);
if (!$this->authenticatorManagerEnabled) {
$authenticationProviders = array_merge($authenticationProviders, $firewallAuthenticationProviders);
@@ -567,7 +567,7 @@ private function createAuthenticationListeners(ContainerBuilder $container, stri
$entryPoints[$key] = $entryPoint;
}
} else {
- list($provider, $listenerId, $defaultEntryPoint) = $factory->create($container, $id, $firewall[$key], $userProvider, $defaultEntryPoint);
+ [$provider, $listenerId, $defaultEntryPoint] = $factory->create($container, $id, $firewall[$key], $userProvider, $defaultEntryPoint);
$listeners[] = new Reference($listenerId);
$authenticationProviders[] = $provider;
diff --git a/src/Symfony/Bundle/SecurityBundle/Tests/DependencyInjection/Compiler/RegisterTokenUsageTrackingPassTest.php b/src/Symfony/Bundle/SecurityBundle/Tests/DependencyInjection/Compiler/RegisterTokenUsageTrackingPassTest.php
new file mode 100644
index 0000000000000..afdbf9afaf60f
--- /dev/null
+++ b/src/Symfony/Bundle/SecurityBundle/Tests/DependencyInjection/Compiler/RegisterTokenUsageTrackingPassTest.php
@@ -0,0 +1,89 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Bundle\SecurityBundle\Tests\DependencyInjection\Compiler;
+
+use PHPUnit\Framework\TestCase;
+use Symfony\Bundle\SecurityBundle\DependencyInjection\Compiler\RegisterTokenUsageTrackingPass;
+use Symfony\Component\DependencyInjection\Alias;
+use Symfony\Component\DependencyInjection\ContainerBuilder;
+use Symfony\Component\DependencyInjection\ContainerInterface;
+use Symfony\Component\DependencyInjection\Reference;
+use Symfony\Component\HttpFoundation\Session\Session;
+use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorage;
+use Symfony\Component\Security\Core\Authentication\Token\Storage\UsageTrackingTokenStorage;
+use Symfony\Component\Security\Http\Firewall\ContextListener;
+
+class RegisterTokenUsageTrackingPassTest extends TestCase
+{
+ public function testTokenStorageIsUntrackedIfSessionIsMissing()
+ {
+ $container = new ContainerBuilder();
+ $container->register('security.untracked_token_storage', TokenStorage::class);
+
+ $compilerPass = new RegisterTokenUsageTrackingPass();
+ $compilerPass->process($container);
+
+ $this->assertTrue($container->hasAlias('security.token_storage'));
+ $this->assertEquals(new Alias('security.untracked_token_storage', true), $container->getAlias('security.token_storage'));
+ }
+
+ public function testContextListenerIsNotModifiedIfTokenStorageDoesNotSupportUsageTracking()
+ {
+ $container = new ContainerBuilder();
+
+ $container->setParameter('security.token_storage.class', TokenStorage::class);
+ $container->register('session', Session::class);
+ $container->register('security.context_listener', ContextListener::class)
+ ->setArguments([
+ new Reference('security.untracked_token_storage'),
+ [],
+ 'main',
+ new Reference('logger', ContainerInterface::NULL_ON_INVALID_REFERENCE),
+ new Reference('event_dispatcher', ContainerInterface::NULL_ON_INVALID_REFERENCE),
+ new Reference('security.authentication.trust_resolver'),
+ ]);
+ $container->register('security.token_storage', '%security.token_storage.class%');
+ $container->register('security.untracked_token_storage', TokenStorage::class);
+
+ $compilerPass = new RegisterTokenUsageTrackingPass();
+ $compilerPass->process($container);
+
+ $this->assertCount(6, $container->getDefinition('security.context_listener')->getArguments());
+ }
+
+ public function testContextListenerEnablesUsageTrackingIfSupportedByTokenStorage()
+ {
+ $container = new ContainerBuilder();
+
+ $container->setParameter('security.token_storage.class', UsageTrackingTokenStorage::class);
+ $container->register('session', Session::class);
+ $container->register('security.context_listener', ContextListener::class)
+ ->setArguments([
+ new Reference('security.untracked_token_storage'),
+ [],
+ 'main',
+ new Reference('logger', ContainerInterface::NULL_ON_INVALID_REFERENCE),
+ new Reference('event_dispatcher', ContainerInterface::NULL_ON_INVALID_REFERENCE),
+ new Reference('security.authentication.trust_resolver'),
+ ]);
+ $container->register('security.token_storage', '%security.token_storage.class%');
+ $container->register('security.untracked_token_storage', TokenStorage::class);
+
+ $compilerPass = new RegisterTokenUsageTrackingPass();
+ $compilerPass->process($container);
+
+ $contextListener = $container->getDefinition('security.context_listener');
+
+ $this->assertCount(7, $container->getDefinition('security.context_listener')->getArguments());
+ $this->assertEquals([new Reference('security.token_storage'), 'enableUsageTracking'], $contextListener->getArgument(6));
+ }
+}
diff --git a/src/Symfony/Bundle/SecurityBundle/Tests/DependencyInjection/CompleteConfigurationTest.php b/src/Symfony/Bundle/SecurityBundle/Tests/DependencyInjection/CompleteConfigurationTest.php
index a7f56e9958785..f9d8094fbccd4 100644
--- a/src/Symfony/Bundle/SecurityBundle/Tests/DependencyInjection/CompleteConfigurationTest.php
+++ b/src/Symfony/Bundle/SecurityBundle/Tests/DependencyInjection/CompleteConfigurationTest.php
@@ -235,7 +235,7 @@ public function testAccess()
}
$matcherIds = [];
- foreach ($rules as list($matcherId, $attributes, $channel)) {
+ foreach ($rules as [$matcherId, $attributes, $channel]) {
$requestMatcher = $container->getDefinition($matcherId);
$this->assertArrayNotHasKey($matcherId, $matcherIds);
diff --git a/src/Symfony/Bundle/SecurityBundle/Tests/DependencyInjection/Security/Factory/AbstractFactoryTest.php b/src/Symfony/Bundle/SecurityBundle/Tests/DependencyInjection/Security/Factory/AbstractFactoryTest.php
index 01e03b0312bd9..3360863159a90 100644
--- a/src/Symfony/Bundle/SecurityBundle/Tests/DependencyInjection/Security/Factory/AbstractFactoryTest.php
+++ b/src/Symfony/Bundle/SecurityBundle/Tests/DependencyInjection/Security/Factory/AbstractFactoryTest.php
@@ -19,7 +19,7 @@ class AbstractFactoryTest extends TestCase
{
public function testCreate()
{
- list($container, $authProviderId, $listenerId, $entryPointId) = $this->callFactory('foo', [
+ [$container, $authProviderId, $listenerId, $entryPointId] = $this->callFactory('foo', [
'use_forward' => true,
'failure_path' => '/foo',
'success_handler' => 'custom_success_handler',
@@ -61,7 +61,7 @@ public function testDefaultFailureHandler($serviceId, $defaultHandlerInjection)
$options['failure_handler'] = $serviceId;
}
- list($container) = $this->callFactory('foo', $options, 'user_provider', 'entry_point');
+ [$container] = $this->callFactory('foo', $options, 'user_provider', 'entry_point');
$definition = $container->getDefinition('abstract_listener.foo');
$arguments = $definition->getArguments();
@@ -99,7 +99,7 @@ public function testDefaultSuccessHandler($serviceId, $defaultHandlerInjection)
$options['success_handler'] = $serviceId;
}
- list($container) = $this->callFactory('foo', $options, 'user_provider', 'entry_point');
+ [$container] = $this->callFactory('foo', $options, 'user_provider', 'entry_point');
$definition = $container->getDefinition('abstract_listener.foo');
$arguments = $definition->getArguments();
@@ -150,7 +150,7 @@ protected function callFactory($id, $config, $userProviderId, $defaultEntryPoint
$container->register('custom_success_handler');
$container->register('custom_failure_handler');
- list($authProviderId, $listenerId, $entryPointId) = $factory->create($container, $id, $config, $userProviderId, $defaultEntryPointId);
+ [$authProviderId, $listenerId, $entryPointId] = $factory->create($container, $id, $config, $userProviderId, $defaultEntryPointId);
return [$container, $authProviderId, $listenerId, $entryPointId];
}
diff --git a/src/Symfony/Bundle/SecurityBundle/Tests/DependencyInjection/Security/Factory/GuardAuthenticationFactoryTest.php b/src/Symfony/Bundle/SecurityBundle/Tests/DependencyInjection/Security/Factory/GuardAuthenticationFactoryTest.php
index 8215aaf9c90fb..7d6f5f6591278 100644
--- a/src/Symfony/Bundle/SecurityBundle/Tests/DependencyInjection/Security/Factory/GuardAuthenticationFactoryTest.php
+++ b/src/Symfony/Bundle/SecurityBundle/Tests/DependencyInjection/Security/Factory/GuardAuthenticationFactoryTest.php
@@ -104,7 +104,7 @@ public function testBasicCreate()
'authenticators' => ['authenticator123'],
'entry_point' => null,
];
- list($container, $entryPointId) = $this->executeCreate($config, null);
+ [$container, $entryPointId] = $this->executeCreate($config, null);
$this->assertEquals('authenticator123', $entryPointId);
$providerDefinition = $container->getDefinition('security.authentication.provider.guard.my_firewall');
@@ -127,7 +127,7 @@ public function testExistingDefaultEntryPointUsed()
'authenticators' => ['authenticator123'],
'entry_point' => null,
];
- list(, $entryPointId) = $this->executeCreate($config, 'some_default_entry_point');
+ [, $entryPointId] = $this->executeCreate($config, 'some_default_entry_point');
$this->assertEquals('some_default_entry_point', $entryPointId);
}
@@ -160,7 +160,7 @@ public function testCreateWithEntryPoint()
'authenticators' => ['authenticator123', 'authenticatorABC'],
'entry_point' => 'authenticatorABC',
];
- list(, $entryPointId) = $this->executeCreate($config, null);
+ [, $entryPointId] = $this->executeCreate($config, null);
$this->assertEquals('authenticatorABC', $entryPointId);
}
@@ -196,7 +196,7 @@ private function executeCreate(array $config, $defaultEntryPointId)
$userProviderId = 'my_user_provider';
$factory = new GuardAuthenticationFactory();
- list(, , $entryPointId) = $factory->create($container, $id, $config, $userProviderId, $defaultEntryPointId);
+ [, , $entryPointId] = $factory->create($container, $id, $config, $userProviderId, $defaultEntryPointId);
return [$container, $entryPointId];
}
diff --git a/src/Symfony/Bundle/SecurityBundle/Tests/Security/FirewallMapTest.php b/src/Symfony/Bundle/SecurityBundle/Tests/Security/FirewallMapTest.php
index fa590a54e908d..7e49cd4fde9b5 100644
--- a/src/Symfony/Bundle/SecurityBundle/Tests/Security/FirewallMapTest.php
+++ b/src/Symfony/Bundle/SecurityBundle/Tests/Security/FirewallMapTest.php
@@ -23,7 +23,7 @@
class FirewallMapTest extends TestCase
{
- const ATTRIBUTE_FIREWALL_CONTEXT = '_firewall_context';
+ private const ATTRIBUTE_FIREWALL_CONTEXT = '_firewall_context';
public function testGetListenersWithEmptyMap()
{
diff --git a/src/Symfony/Bundle/WebProfilerBundle/Profiler/TemplateManager.php b/src/Symfony/Bundle/WebProfilerBundle/Profiler/TemplateManager.php
index 30dd95e5c75eb..bb9daab006fce 100644
--- a/src/Symfony/Bundle/WebProfilerBundle/Profiler/TemplateManager.php
+++ b/src/Symfony/Bundle/WebProfilerBundle/Profiler/TemplateManager.php
@@ -72,7 +72,7 @@ public function getNames(Profile $profile)
continue;
}
- list($name, $template) = $arguments;
+ [$name, $template] = $arguments;
if (!$this->profiler->has($name) || !$profile->hasCollector($name)) {
continue;
diff --git a/src/Symfony/Component/BrowserKit/Cookie.php b/src/Symfony/Component/BrowserKit/Cookie.php
index 79ca7943109ff..c24661de76ab5 100644
--- a/src/Symfony/Component/BrowserKit/Cookie.php
+++ b/src/Symfony/Component/BrowserKit/Cookie.php
@@ -133,7 +133,7 @@ public static function fromString(string $cookie, string $url = null)
throw new \InvalidArgumentException(sprintf('The cookie string "%s" is not valid.', $parts[0]));
}
- list($name, $value) = explode('=', array_shift($parts), 2);
+ [$name, $value] = explode('=', array_shift($parts), 2);
$values = [
'name' => trim($name),
diff --git a/src/Symfony/Component/Cache/Adapter/ChainAdapter.php b/src/Symfony/Component/Cache/Adapter/ChainAdapter.php
index efca364ba7ce6..aef2a9a7deb57 100644
--- a/src/Symfony/Component/Cache/Adapter/ChainAdapter.php
+++ b/src/Symfony/Component/Cache/Adapter/ChainAdapter.php
@@ -74,7 +74,7 @@ static function ($sourceItem, $item, $sourceMetadata = null) use ($defaultLifeti
$item->metadata = $item->newMetadata = $sourceItem->metadata = $sourceMetadata;
if (isset($item->metadata[CacheItem::METADATA_EXPIRY])) {
- $item->expiresAt(\DateTime::createFromFormat('U.u', $item->metadata[CacheItem::METADATA_EXPIRY]));
+ $item->expiresAt(\DateTime::createFromFormat('U.u', sprintf('%.6F', $item->metadata[CacheItem::METADATA_EXPIRY])));
} elseif (0 < $defaultLifetime) {
$item->expiresAfter($defaultLifetime);
}
diff --git a/src/Symfony/Component/Cache/Adapter/CouchbaseBucketAdapter.php b/src/Symfony/Component/Cache/Adapter/CouchbaseBucketAdapter.php
index 0fd272700198c..36667f2a0dfb9 100644
--- a/src/Symfony/Component/Cache/Adapter/CouchbaseBucketAdapter.php
+++ b/src/Symfony/Component/Cache/Adapter/CouchbaseBucketAdapter.php
@@ -42,7 +42,7 @@ class CouchbaseBucketAdapter extends AbstractAdapter
public function __construct(\CouchbaseBucket $bucket, string $namespace = '', int $defaultLifetime = 0, MarshallerInterface $marshaller = null)
{
if (!static::isSupported()) {
- throw new CacheException('Couchbase >= 2.6.0 is required.');
+ throw new CacheException('Couchbase >= 2.6.0 < 3.0.0 is required.');
}
$this->maxIdLength = static::MAX_KEY_LENGTH;
@@ -66,7 +66,7 @@ public static function createConnection($servers, array $options = []): \Couchba
}
if (!static::isSupported()) {
- throw new CacheException('Couchbase >= 2.6.0 is required.');
+ throw new CacheException('Couchbase >= 2.6.0 < 3.0.0 is required.');
}
set_error_handler(function ($type, $msg, $file, $line) { throw new \ErrorException($msg, 0, $type, $file, $line); });
@@ -125,7 +125,7 @@ public static function createConnection($servers, array $options = []): \Couchba
public static function isSupported(): bool
{
- return \extension_loaded('couchbase') && version_compare(phpversion('couchbase'), '2.6.0', '>=');
+ return \extension_loaded('couchbase') && version_compare(phpversion('couchbase'), '2.6.0', '>=') && version_compare(phpversion('couchbase'), '3.0', '<');
}
private static function getOptions(string $options): array
@@ -134,7 +134,7 @@ private static function getOptions(string $options): array
$optionsInArray = explode('&', $options);
foreach ($optionsInArray as $option) {
- list($key, $value) = explode('=', $option);
+ [$key, $value] = explode('=', $option);
if (\in_array($key, static::VALID_DSN_OPTIONS, true)) {
$results[$key] = $value;
diff --git a/src/Symfony/Component/Cache/Adapter/MemcachedAdapter.php b/src/Symfony/Component/Cache/Adapter/MemcachedAdapter.php
index 038892eabc3ba..53ead840c4eee 100644
--- a/src/Symfony/Component/Cache/Adapter/MemcachedAdapter.php
+++ b/src/Symfony/Component/Cache/Adapter/MemcachedAdapter.php
@@ -123,7 +123,7 @@ public static function createConnection($servers, array $options = [])
}
$params = preg_replace_callback('#^memcached:(//)?(?:([^@]*+)@)?#', function ($m) use (&$username, &$password) {
if (!empty($m[2])) {
- list($username, $password) = explode(':', $m[2], 2) + [1 => null];
+ [$username, $password] = explode(':', $m[2], 2) + [1 => null];
}
return 'file:'.($m[1] ?? '');
diff --git a/src/Symfony/Component/Cache/Adapter/PhpArrayAdapter.php b/src/Symfony/Component/Cache/Adapter/PhpArrayAdapter.php
index 0abf787f44ddb..a8f8f3038a652 100644
--- a/src/Symfony/Component/Cache/Adapter/PhpArrayAdapter.php
+++ b/src/Symfony/Component/Cache/Adapter/PhpArrayAdapter.php
@@ -401,7 +401,7 @@ private function initialize()
if (2 !== \count($values) || !isset($values[0], $values[1])) {
$this->keys = $this->values = [];
} else {
- list($this->keys, $this->values) = $values;
+ [$this->keys, $this->values] = $values;
}
}
diff --git a/src/Symfony/Component/Cache/Adapter/ProxyAdapter.php b/src/Symfony/Component/Cache/Adapter/ProxyAdapter.php
index 9527fa63ffae9..faba3d8822a75 100644
--- a/src/Symfony/Component/Cache/Adapter/ProxyAdapter.php
+++ b/src/Symfony/Component/Cache/Adapter/ProxyAdapter.php
@@ -88,7 +88,7 @@ static function (CacheItemInterface $innerItem, array $item) {
$item["\0*\0value"] = ["\x9D".pack('VN', (int) (0.1 + $metadata[self::METADATA_EXPIRY] - self::METADATA_EXPIRY_OFFSET), $metadata[self::METADATA_CTIME])."\x5F" => $item["\0*\0value"]];
}
$innerItem->set($item["\0*\0value"]);
- $innerItem->expiresAt(null !== $item["\0*\0expiry"] ? \DateTime::createFromFormat('U.u', sprintf('%.6f', 0 === $item["\0*\0expiry"] ? \PHP_INT_MAX : $item["\0*\0expiry"])) : null);
+ $innerItem->expiresAt(null !== $item["\0*\0expiry"] ? \DateTime::createFromFormat('U.u', sprintf('%.6F', 0 === $item["\0*\0expiry"] ? \PHP_INT_MAX : $item["\0*\0expiry"])) : null);
},
null,
CacheItem::class
diff --git a/src/Symfony/Component/Cache/Tests/Adapter/AdapterTestCase.php b/src/Symfony/Component/Cache/Tests/Adapter/AdapterTestCase.php
index 57c355eaa43a6..d7fe3ebc60b9e 100644
--- a/src/Symfony/Component/Cache/Tests/Adapter/AdapterTestCase.php
+++ b/src/Symfony/Component/Cache/Tests/Adapter/AdapterTestCase.php
@@ -118,9 +118,9 @@ public function testGetMetadata()
$metadata = $item->getMetadata();
$this->assertArrayHasKey(CacheItem::METADATA_CTIME, $metadata);
- $this->assertEqualsWithDelta(1000, $metadata[CacheItem::METADATA_CTIME], 6);
+ $this->assertEqualsWithDelta(999, $metadata[CacheItem::METADATA_CTIME], 10);
$this->assertArrayHasKey(CacheItem::METADATA_EXPIRY, $metadata);
- $this->assertEqualsWithDelta(9.5 + time(), $metadata[CacheItem::METADATA_EXPIRY], 0.6);
+ $this->assertEqualsWithDelta(9 + time(), $metadata[CacheItem::METADATA_EXPIRY], 1);
}
public function testDefaultLifeTime()
diff --git a/src/Symfony/Component/Cache/Tests/Adapter/CouchbaseBucketAdapterTest.php b/src/Symfony/Component/Cache/Tests/Adapter/CouchbaseBucketAdapterTest.php
index 120d0d94c0cc5..c72d6710f22e9 100644
--- a/src/Symfony/Component/Cache/Tests/Adapter/CouchbaseBucketAdapterTest.php
+++ b/src/Symfony/Component/Cache/Tests/Adapter/CouchbaseBucketAdapterTest.php
@@ -16,7 +16,8 @@
use Symfony\Component\Cache\Adapter\CouchbaseBucketAdapter;
/**
- * @requires extension couchbase 2.6.0
+ * @requires extension couchbase <3.0.0
+ * @requires extension couchbase >=2.6.0
* @group integration
*
* @author Antonio Jose Cerezo Aranda
@@ -32,6 +33,10 @@ class CouchbaseBucketAdapterTest extends AdapterTestCase
public static function setupBeforeClass(): void
{
+ if (!CouchbaseBucketAdapter::isSupported()) {
+ self::markTestSkipped('Couchbase >= 2.6.0 < 3.0.0 is required.');
+ }
+
self::$client = AbstractAdapter::createConnection('couchbase://'.getenv('COUCHBASE_HOST').'/cache',
['username' => getenv('COUCHBASE_USER'), 'password' => getenv('COUCHBASE_PASS')]
);
diff --git a/src/Symfony/Component/Cache/Tests/Adapter/PhpArrayAdapterTest.php b/src/Symfony/Component/Cache/Tests/Adapter/PhpArrayAdapterTest.php
index 69f334656d58e..58318f6a25294 100644
--- a/src/Symfony/Component/Cache/Tests/Adapter/PhpArrayAdapterTest.php
+++ b/src/Symfony/Component/Cache/Tests/Adapter/PhpArrayAdapterTest.php
@@ -155,7 +155,7 @@ public function save(CacheItemInterface $item): bool
$this->keys[$key] = $id = \count($this->values);
$this->data[$key] = $this->values[$id] = $item->get();
$this->warmUp($this->data);
- list($this->keys, $this->values) = eval(substr(file_get_contents($this->file), 6));
+ [$this->keys, $this->values] = eval(substr(file_get_contents($this->file), 6));
}, $this, PhpArrayAdapter::class))();
return true;
diff --git a/src/Symfony/Component/Cache/Tests/Adapter/RedisAdapterSentinelTest.php b/src/Symfony/Component/Cache/Tests/Adapter/RedisAdapterSentinelTest.php
index 09f563036bc2f..82b9f08b65474 100644
--- a/src/Symfony/Component/Cache/Tests/Adapter/RedisAdapterSentinelTest.php
+++ b/src/Symfony/Component/Cache/Tests/Adapter/RedisAdapterSentinelTest.php
@@ -37,7 +37,7 @@ public static function setUpBeforeClass(): void
public function testInvalidDSNHasBothClusterAndSentinel()
{
$this->expectException('Symfony\Component\Cache\Exception\InvalidArgumentException');
- $this->expectExceptionMessage('Invalid Redis DSN: cannot use both redis_cluster and redis_sentinel at the same time');
+ $this->expectExceptionMessage('Cannot use both "redis_cluster" and "redis_sentinel" at the same time:');
$dsn = 'redis:?host[redis1]&host[redis2]&host[redis3]&redis_cluster=1&redis_sentinel=mymaster';
RedisAdapter::createConnection($dsn);
}
diff --git a/src/Symfony/Component/Cache/Tests/DataCollector/CacheDataCollectorTest.php b/src/Symfony/Component/Cache/Tests/DataCollector/CacheDataCollectorTest.php
new file mode 100644
index 0000000000000..f704bbfe0e49f
--- /dev/null
+++ b/src/Symfony/Component/Cache/Tests/DataCollector/CacheDataCollectorTest.php
@@ -0,0 +1,98 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Cache\Tests\Marshaller;
+
+use PHPUnit\Framework\TestCase;
+use Symfony\Component\Cache\Adapter\TraceableAdapter;
+use Symfony\Component\Cache\DataCollector\CacheDataCollector;
+use Symfony\Component\HttpFoundation\Request;
+use Symfony\Component\HttpFoundation\Response;
+
+class CacheDataCollectorTest extends TestCase
+{
+ private const INSTANCE_NAME = 'test';
+
+ public function testEmptyDataCollector()
+ {
+ $statistics = $this->getCacheDataCollectorStatisticsFromEvents([]);
+
+ $this->assertEquals($statistics[self::INSTANCE_NAME]['calls'], 0, 'calls');
+ $this->assertEquals($statistics[self::INSTANCE_NAME]['reads'], 0, 'reads');
+ $this->assertEquals($statistics[self::INSTANCE_NAME]['hits'], 0, 'hits');
+ $this->assertEquals($statistics[self::INSTANCE_NAME]['misses'], 0, 'misses');
+ $this->assertEquals($statistics[self::INSTANCE_NAME]['writes'], 0, 'writes');
+ }
+
+ public function testOneEventDataCollector()
+ {
+ $traceableAdapterEvent = new \stdClass();
+ $traceableAdapterEvent->name = 'getItem';
+ $traceableAdapterEvent->start = 0;
+ $traceableAdapterEvent->end = 0;
+ $traceableAdapterEvent->hits = 0;
+
+ $statistics = $this->getCacheDataCollectorStatisticsFromEvents([$traceableAdapterEvent]);
+
+ $this->assertEquals($statistics[self::INSTANCE_NAME]['calls'], 1, 'calls');
+ $this->assertEquals($statistics[self::INSTANCE_NAME]['reads'], 1, 'reads');
+ $this->assertEquals($statistics[self::INSTANCE_NAME]['hits'], 0, 'hits');
+ $this->assertEquals($statistics[self::INSTANCE_NAME]['misses'], 1, 'misses');
+ $this->assertEquals($statistics[self::INSTANCE_NAME]['writes'], 0, 'writes');
+ }
+
+ public function testHitedEventDataCollector()
+ {
+ $traceableAdapterEvent = new \stdClass();
+ $traceableAdapterEvent->name = 'hasItem';
+ $traceableAdapterEvent->start = 0;
+ $traceableAdapterEvent->end = 0;
+ $traceableAdapterEvent->hits = 1;
+ $traceableAdapterEvent->misses = 0;
+ $traceableAdapterEvent->result = ['foo' => false];
+
+ $statistics = $this->getCacheDataCollectorStatisticsFromEvents([$traceableAdapterEvent]);
+
+ $this->assertEquals($statistics[self::INSTANCE_NAME]['calls'], 1, 'calls');
+ $this->assertEquals($statistics[self::INSTANCE_NAME]['reads'], 1, 'reads');
+ $this->assertEquals($statistics[self::INSTANCE_NAME]['hits'], 1, 'hits');
+ $this->assertEquals($statistics[self::INSTANCE_NAME]['misses'], 0, 'misses');
+ $this->assertEquals($statistics[self::INSTANCE_NAME]['writes'], 0, 'writes');
+ }
+
+ public function testSavedEventDataCollector()
+ {
+ $traceableAdapterEvent = new \stdClass();
+ $traceableAdapterEvent->name = 'save';
+ $traceableAdapterEvent->start = 0;
+ $traceableAdapterEvent->end = 0;
+
+ $statistics = $this->getCacheDataCollectorStatisticsFromEvents([$traceableAdapterEvent]);
+
+ $this->assertEquals($statistics[self::INSTANCE_NAME]['calls'], 1, 'calls');
+ $this->assertEquals($statistics[self::INSTANCE_NAME]['reads'], 0, 'reads');
+ $this->assertEquals($statistics[self::INSTANCE_NAME]['hits'], 0, 'hits');
+ $this->assertEquals($statistics[self::INSTANCE_NAME]['misses'], 0, 'misses');
+ $this->assertEquals($statistics[self::INSTANCE_NAME]['writes'], 1, 'writes');
+ }
+
+ private function getCacheDataCollectorStatisticsFromEvents(array $traceableAdapterEvents)
+ {
+ $traceableAdapterMock = $this->createMock(TraceableAdapter::class);
+ $traceableAdapterMock->method('getCalls')->willReturn($traceableAdapterEvents);
+
+ $cacheDataCollector = new CacheDataCollector();
+ $cacheDataCollector->addInstance(self::INSTANCE_NAME, $traceableAdapterMock);
+ $cacheDataCollector->collect(new Request(), new Response());
+
+ return $cacheDataCollector->getStatistics();
+ }
+}
diff --git a/src/Symfony/Component/Cache/Traits/AbstractAdapterTrait.php b/src/Symfony/Component/Cache/Traits/AbstractAdapterTrait.php
index de3dbfc7a8b3c..86c1aac489dd9 100644
--- a/src/Symfony/Component/Cache/Traits/AbstractAdapterTrait.php
+++ b/src/Symfony/Component/Cache/Traits/AbstractAdapterTrait.php
@@ -14,6 +14,7 @@
use Psr\Cache\CacheItemInterface;
use Psr\Log\LoggerAwareTrait;
use Symfony\Component\Cache\CacheItem;
+use Symfony\Component\Cache\Exception\InvalidArgumentException;
/**
* @author Nicolas Grekas
diff --git a/src/Symfony/Component/Cache/Traits/MemcachedTrait.php b/src/Symfony/Component/Cache/Traits/MemcachedTrait.php
index 468656e333fa3..34b8aa73a5fc1 100644
--- a/src/Symfony/Component/Cache/Traits/MemcachedTrait.php
+++ b/src/Symfony/Component/Cache/Traits/MemcachedTrait.php
@@ -111,7 +111,7 @@ public static function createConnection($servers, array $options = [])
}
$params = preg_replace_callback('#^memcached:(//)?(?:([^@]*+)@)?#', function ($m) use (&$username, &$password) {
if (!empty($m[2])) {
- list($username, $password) = explode(':', $m[2], 2) + [1 => null];
+ [$username, $password] = explode(':', $m[2], 2) + [1 => null];
}
return 'file:'.($m[1] ?? '');
diff --git a/src/Symfony/Component/Cache/Traits/RedisTrait.php b/src/Symfony/Component/Cache/Traits/RedisTrait.php
index c7701fbecc147..543e6e9045c15 100644
--- a/src/Symfony/Component/Cache/Traits/RedisTrait.php
+++ b/src/Symfony/Component/Cache/Traits/RedisTrait.php
@@ -469,7 +469,7 @@ private function pipeline(\Closure $generator, $redis = null): \Generator
foreach ($connections as $h => $c) {
$connections[$h] = $c[0]->exec();
}
- foreach ($results as $k => list($h, $c)) {
+ foreach ($results as $k => [$h, $c]) {
$results[$k] = $connections[$h][$c];
}
} else {
diff --git a/src/Symfony/Component/Cache/composer.json b/src/Symfony/Component/Cache/composer.json
index af7827f2bb432..2df9ff4c1fc9c 100644
--- a/src/Symfony/Component/Cache/composer.json
+++ b/src/Symfony/Component/Cache/composer.json
@@ -38,6 +38,7 @@
"symfony/config": "^4.4|^5.0",
"symfony/dependency-injection": "^4.4|^5.0",
"symfony/filesystem": "^4.4|^5.0",
+ "symfony/http-kernel": "^4.4|^5.0",
"symfony/var-dumper": "^4.4|^5.0"
},
"conflict": {
diff --git a/src/Symfony/Component/Config/Definition/ArrayNode.php b/src/Symfony/Component/Config/Definition/ArrayNode.php
index 2a828caf78538..5b1aec59c5926 100644
--- a/src/Symfony/Component/Config/Definition/ArrayNode.php
+++ b/src/Symfony/Component/Config/Definition/ArrayNode.php
@@ -333,7 +333,7 @@ protected function normalizeValue($value)
*/
protected function remapXml(array $value)
{
- foreach ($this->xmlRemappings as list($singular, $plural)) {
+ foreach ($this->xmlRemappings as [$singular, $plural]) {
if (!isset($value[$singular])) {
continue;
}
diff --git a/src/Symfony/Component/Config/Definition/Dumper/XmlReferenceDumper.php b/src/Symfony/Component/Config/Definition/Dumper/XmlReferenceDumper.php
index f686c53b5718f..ef60eff374dba 100644
--- a/src/Symfony/Component/Config/Definition/Dumper/XmlReferenceDumper.php
+++ b/src/Symfony/Component/Config/Definition/Dumper/XmlReferenceDumper.php
@@ -53,7 +53,7 @@ private function writeNode(NodeInterface $node, int $depth = 0, bool $root = fal
});
if (\count($remapping)) {
- list($singular) = current($remapping);
+ [$singular] = current($remapping);
$rootName = $singular;
}
}
diff --git a/src/Symfony/Component/Config/Resource/GlobResource.php b/src/Symfony/Component/Config/Resource/GlobResource.php
index 21777e648eb45..c77e837c245f9 100644
--- a/src/Symfony/Component/Config/Resource/GlobResource.php
+++ b/src/Symfony/Component/Config/Resource/GlobResource.php
@@ -94,6 +94,14 @@ public function __sleep(): array
return ['prefix', 'pattern', 'recursive', 'hash', 'forExclusion', 'excludedPrefixes'];
}
+ /**
+ * @internal
+ */
+ public function __wakeup(): void
+ {
+ $this->globBrace = \defined('GLOB_BRACE') ? \GLOB_BRACE : 0;
+ }
+
public function getIterator(): \Traversable
{
if (!file_exists($this->prefix) || (!$this->recursive && '' === $this->pattern)) {
diff --git a/src/Symfony/Component/Config/Tests/Resource/GlobResourceTest.php b/src/Symfony/Component/Config/Tests/Resource/GlobResourceTest.php
index 2b6609d740c86..a30fbe8c4339b 100644
--- a/src/Symfony/Component/Config/Tests/Resource/GlobResourceTest.php
+++ b/src/Symfony/Component/Config/Tests/Resource/GlobResourceTest.php
@@ -194,4 +194,17 @@ public function testUnbalancedBraceFallback()
$this->assertSame([], array_keys(iterator_to_array($resource)));
}
+
+ public function testSerializeUnserialize()
+ {
+ $dir = \dirname(__DIR__).\DIRECTORY_SEPARATOR.'Fixtures';
+ $resource = new GlobResource($dir, '/Resource', true);
+
+ $newResource = unserialize(serialize($resource));
+
+ $p = new \ReflectionProperty($resource, 'globBrace');
+ $p->setAccessible(true);
+
+ $this->assertEquals($p->getValue($resource), $p->getValue($newResource));
+ }
}
diff --git a/src/Symfony/Component/Console/Formatter/OutputFormatter.php b/src/Symfony/Component/Console/Formatter/OutputFormatter.php
index edc6a1d71d6f9..4ad248868dbfc 100644
--- a/src/Symfony/Component/Console/Formatter/OutputFormatter.php
+++ b/src/Symfony/Component/Console/Formatter/OutputFormatter.php
@@ -25,6 +25,14 @@ class OutputFormatter implements WrappableOutputFormatterInterface
private $styles = [];
private $styleStack;
+ public function __clone()
+ {
+ $this->styleStack = clone $this->styleStack;
+ foreach ($this->styles as $key => $value) {
+ $this->styles[$key] = clone $value;
+ }
+ }
+
/**
* Escapes "<" special char in given text.
*
diff --git a/src/Symfony/Component/Console/Helper/Table.php b/src/Symfony/Component/Console/Helper/Table.php
index fee5a416b73d9..21848e65db03b 100644
--- a/src/Symfony/Component/Console/Helper/Table.php
+++ b/src/Symfony/Component/Console/Helper/Table.php
@@ -418,13 +418,13 @@ private function renderRowSeparator(int $type = self::SEPARATOR_MID, string $tit
$crossings = $this->style->getCrossingChars();
if (self::SEPARATOR_MID === $type) {
- list($horizontal, $leftChar, $midChar, $rightChar) = [$borders[2], $crossings[8], $crossings[0], $crossings[4]];
+ [$horizontal, $leftChar, $midChar, $rightChar] = [$borders[2], $crossings[8], $crossings[0], $crossings[4]];
} elseif (self::SEPARATOR_TOP === $type) {
- list($horizontal, $leftChar, $midChar, $rightChar) = [$borders[0], $crossings[1], $crossings[2], $crossings[3]];
+ [$horizontal, $leftChar, $midChar, $rightChar] = [$borders[0], $crossings[1], $crossings[2], $crossings[3]];
} elseif (self::SEPARATOR_TOP_BOTTOM === $type) {
- list($horizontal, $leftChar, $midChar, $rightChar) = [$borders[0], $crossings[9], $crossings[10], $crossings[11]];
+ [$horizontal, $leftChar, $midChar, $rightChar] = [$borders[0], $crossings[9], $crossings[10], $crossings[11]];
} else {
- list($horizontal, $leftChar, $midChar, $rightChar) = [$borders[0], $crossings[7], $crossings[6], $crossings[5]];
+ [$horizontal, $leftChar, $midChar, $rightChar] = [$borders[0], $crossings[7], $crossings[6], $crossings[5]];
}
$markup = $leftChar;
diff --git a/src/Symfony/Component/Console/Output/ConsoleOutput.php b/src/Symfony/Component/Console/Output/ConsoleOutput.php
index 96664f1508abb..2cda213a04b09 100644
--- a/src/Symfony/Component/Console/Output/ConsoleOutput.php
+++ b/src/Symfony/Component/Console/Output/ConsoleOutput.php
@@ -41,6 +41,13 @@ public function __construct(int $verbosity = self::VERBOSITY_NORMAL, bool $decor
{
parent::__construct($this->openOutputStream(), $verbosity, $decorated, $formatter);
+ if (null === $formatter) {
+ // for BC reasons, stdErr has it own Formatter only when user don't inject a specific formatter.
+ $this->stderr = new StreamOutput($this->openErrorStream(), $verbosity, $decorated);
+
+ return;
+ }
+
$actualDecorated = $this->isDecorated();
$this->stderr = new StreamOutput($this->openErrorStream(), $verbosity, $decorated, $this->getFormatter());
diff --git a/src/Symfony/Component/Console/Output/TrimmedBufferOutput.php b/src/Symfony/Component/Console/Output/TrimmedBufferOutput.php
new file mode 100644
index 0000000000000..a03aa835f0086
--- /dev/null
+++ b/src/Symfony/Component/Console/Output/TrimmedBufferOutput.php
@@ -0,0 +1,67 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Console\Output;
+
+use Symfony\Component\Console\Exception\InvalidArgumentException;
+use Symfony\Component\Console\Formatter\OutputFormatterInterface;
+
+/**
+ * A BufferedOutput that keeps only the last N chars.
+ *
+ * @author Jérémy Derussé
+ */
+class TrimmedBufferOutput extends Output
+{
+ private $maxLength;
+ private $buffer = '';
+
+ public function __construct(
+ int $maxLength,
+ ?int $verbosity = self::VERBOSITY_NORMAL,
+ bool $decorated = false,
+ OutputFormatterInterface $formatter = null
+ ) {
+ if ($maxLength <= 0) {
+ throw new InvalidArgumentException(sprintf('"%s()" expects a strictly positive maxLength. Got %d.', __METHOD__, $maxLength));
+ }
+
+ parent::__construct($verbosity, $decorated, $formatter);
+ $this->maxLength = $maxLength;
+ }
+
+ /**
+ * Empties buffer and returns its content.
+ *
+ * @return string
+ */
+ public function fetch()
+ {
+ $content = $this->buffer;
+ $this->buffer = '';
+
+ return $content;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ protected function doWrite($message, $newline)
+ {
+ $this->buffer .= $message;
+
+ if ($newline) {
+ $this->buffer .= \PHP_EOL;
+ }
+
+ $this->buffer = substr($this->buffer, 0 - $this->maxLength);
+ }
+}
diff --git a/src/Symfony/Component/Console/Style/SymfonyStyle.php b/src/Symfony/Component/Console/Style/SymfonyStyle.php
index fa4dfa018bd15..eb455cda2ea1d 100644
--- a/src/Symfony/Component/Console/Style/SymfonyStyle.php
+++ b/src/Symfony/Component/Console/Style/SymfonyStyle.php
@@ -21,8 +21,8 @@
use Symfony\Component\Console\Helper\TableCell;
use Symfony\Component\Console\Helper\TableSeparator;
use Symfony\Component\Console\Input\InputInterface;
-use Symfony\Component\Console\Output\BufferedOutput;
use Symfony\Component\Console\Output\OutputInterface;
+use Symfony\Component\Console\Output\TrimmedBufferOutput;
use Symfony\Component\Console\Question\ChoiceQuestion;
use Symfony\Component\Console\Question\ConfirmationQuestion;
use Symfony\Component\Console\Question\Question;
@@ -46,7 +46,7 @@ class SymfonyStyle extends OutputStyle
public function __construct(InputInterface $input, OutputInterface $output)
{
$this->input = $input;
- $this->bufferedOutput = new BufferedOutput($output->getVerbosity(), false, clone $output->getFormatter());
+ $this->bufferedOutput = new TrimmedBufferOutput(\DIRECTORY_SEPARATOR === '\\' ? 4 : 2, $output->getVerbosity(), false, clone $output->getFormatter());
// Windows cmd wraps lines as soon as the terminal width is reached, whether there are following chars or not.
$width = (new Terminal())->getWidth() ?: self::MAX_LINE_LENGTH;
$this->lineLength = min($width - (int) (\DIRECTORY_SEPARATOR === '\\'), self::MAX_LINE_LENGTH);
@@ -444,9 +444,8 @@ private function autoPrependText(): void
private function writeBuffer(string $message, bool $newLine, int $type): void
{
- // We need to know if the two last chars are PHP_EOL
- // Preserve the last 4 chars inserted (PHP_EOL on windows is two chars) in the history buffer
- $this->bufferedOutput->write(substr($message, -4), $newLine, $type);
+ // We need to know if the last chars are PHP_EOL
+ $this->bufferedOutput->write($message, $newLine, $type);
}
private function createBlock(iterable $messages, string $type = null, string $style = null, string $prefix = ' ', bool $padding = false, bool $escape = false): array
diff --git a/src/Symfony/Component/Console/Tests/Fixtures/Style/SymfonyStyle/command/command_20.php b/src/Symfony/Component/Console/Tests/Fixtures/Style/SymfonyStyle/command/command_20.php
new file mode 100644
index 0000000000000..6b47969eeeba6
--- /dev/null
+++ b/src/Symfony/Component/Console/Tests/Fixtures/Style/SymfonyStyle/command/command_20.php
@@ -0,0 +1,13 @@
+setDecorated(true);
+ $output = new SymfonyStyle($input, $output);
+ $output->write('do you want something>');
+ $output->writeln('?>');
+};
diff --git a/src/Symfony/Component/Console/Tests/Fixtures/Style/SymfonyStyle/output/output_20.txt b/src/Symfony/Component/Console/Tests/Fixtures/Style/SymfonyStyle/output/output_20.txt
new file mode 100644
index 0000000000000..c082985309229
--- /dev/null
+++ b/src/Symfony/Component/Console/Tests/Fixtures/Style/SymfonyStyle/output/output_20.txt
@@ -0,0 +1 @@
+[30;46mdo you want [39;49m[33msomething[39m[30;46m?[39;49m
diff --git a/src/Symfony/Component/Console/Tests/Output/ConsoleOutputTest.php b/src/Symfony/Component/Console/Tests/Output/ConsoleOutputTest.php
index db39a02b8a616..33a5371d6e4b9 100644
--- a/src/Symfony/Component/Console/Tests/Output/ConsoleOutputTest.php
+++ b/src/Symfony/Component/Console/Tests/Output/ConsoleOutputTest.php
@@ -18,11 +18,19 @@
class ConsoleOutputTest extends TestCase
{
- public function testConstructor()
+ public function testConstructorWithoutFormatter()
{
$output = new ConsoleOutput(Output::VERBOSITY_QUIET, true);
$this->assertEquals(Output::VERBOSITY_QUIET, $output->getVerbosity(), '__construct() takes the verbosity as its first argument');
- $this->assertSame($output->getFormatter(), $output->getErrorOutput()->getFormatter(), '__construct() takes a formatter or null as the third argument');
+ $this->assertNotSame($output->getFormatter(), $output->getErrorOutput()->getFormatter(), 'ErrorOutput should use it own formatter');
+ }
+
+ public function testConstructorWithFormatter()
+ {
+ $output = new ConsoleOutput(Output::VERBOSITY_QUIET, true, $formatter = new OutputFormatter());
+ $this->assertEquals(Output::VERBOSITY_QUIET, $output->getVerbosity(), '__construct() takes the verbosity as its first argument');
+ $this->assertSame($formatter, $output->getFormatter());
+ $this->assertSame($formatter, $output->getErrorOutput()->getFormatter(), 'Output and ErrorOutput should use the same provided formatter');
}
public function testSetFormatter()
@@ -31,6 +39,7 @@ public function testSetFormatter()
$outputFormatter = new OutputFormatter();
$output->setFormatter($outputFormatter);
$this->assertSame($outputFormatter, $output->getFormatter());
+ $this->assertSame($outputFormatter, $output->getErrorOutput()->getFormatter());
}
public function testSetVerbosity()
diff --git a/src/Symfony/Component/Console/Tests/Style/SymfonyStyleTest.php b/src/Symfony/Component/Console/Tests/Style/SymfonyStyleTest.php
index 943b94172a609..16bb2baec4ac7 100644
--- a/src/Symfony/Component/Console/Tests/Style/SymfonyStyleTest.php
+++ b/src/Symfony/Component/Console/Tests/Style/SymfonyStyleTest.php
@@ -14,8 +14,10 @@
use PHPUnit\Framework\TestCase;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Formatter\OutputFormatter;
+use Symfony\Component\Console\Input\ArrayInput;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\ConsoleOutputInterface;
+use Symfony\Component\Console\Output\NullOutput;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\Console\Style\SymfonyStyle;
use Symfony\Component\Console\Tester\CommandTester;
@@ -115,4 +117,18 @@ public function testGetErrorStyleUsesTheCurrentOutputIfNoErrorOutputIsAvailable(
$this->assertInstanceOf(SymfonyStyle::class, $style->getErrorStyle());
}
+
+ public function testMemoryConsumption()
+ {
+ $io = new SymfonyStyle(new ArrayInput([]), new NullOutput());
+ $str = 'teststr';
+ $io->writeln($str, SymfonyStyle::VERBOSITY_QUIET);
+ $io->writeln($str, SymfonyStyle::VERBOSITY_QUIET);
+ $start = memory_get_usage();
+ for ($i = 0; $i < 100; ++$i) {
+ $io->writeln($str, SymfonyStyle::VERBOSITY_QUIET);
+ }
+
+ $this->assertSame(0, memory_get_usage() - $start);
+ }
}
diff --git a/src/Symfony/Component/CssSelector/Parser/Parser.php b/src/Symfony/Component/CssSelector/Parser/Parser.php
index e8a46c062ce7f..a03f1527f144b 100644
--- a/src/Symfony/Component/CssSelector/Parser/Parser.php
+++ b/src/Symfony/Component/CssSelector/Parser/Parser.php
@@ -113,7 +113,7 @@ private function parseSelectorList(TokenStream $stream): array
private function parserSelectorNode(TokenStream $stream): Node\SelectorNode
{
- list($result, $pseudoElement) = $this->parseSimpleSelector($stream);
+ [$result, $pseudoElement] = $this->parseSimpleSelector($stream);
while (true) {
$stream->skipWhitespace();
@@ -134,7 +134,7 @@ private function parserSelectorNode(TokenStream $stream): Node\SelectorNode
$combinator = ' ';
}
- list($nextSelector, $pseudoElement) = $this->parseSimpleSelector($stream);
+ [$nextSelector, $pseudoElement] = $this->parseSimpleSelector($stream);
$result = new Node\CombinedSelectorNode($result, $combinator, $nextSelector);
}
@@ -209,7 +209,7 @@ private function parseSimpleSelector(TokenStream $stream, bool $insideNegation =
throw SyntaxErrorException::nestedNot();
}
- list($argument, $argumentPseudoElement) = $this->parseSimpleSelector($stream, true);
+ [$argument, $argumentPseudoElement] = $this->parseSimpleSelector($stream, true);
$next = $stream->getNext();
if (null !== $argumentPseudoElement) {
diff --git a/src/Symfony/Component/CssSelector/XPath/Extension/FunctionExtension.php b/src/Symfony/Component/CssSelector/XPath/Extension/FunctionExtension.php
index 2b79aaafc9fcb..d3f7222a4d0ab 100644
--- a/src/Symfony/Component/CssSelector/XPath/Extension/FunctionExtension.php
+++ b/src/Symfony/Component/CssSelector/XPath/Extension/FunctionExtension.php
@@ -51,7 +51,7 @@ public function getFunctionTranslators(): array
public function translateNthChild(XPathExpr $xpath, FunctionNode $function, bool $last = false, bool $addNameTest = true): XPathExpr
{
try {
- list($a, $b) = Parser::parseSeries($function->getArguments());
+ [$a, $b] = Parser::parseSeries($function->getArguments());
} catch (SyntaxErrorException $e) {
throw new ExpressionErrorException(sprintf('Invalid series: "%s".', implode('", "', $function->getArguments())), 0, $e);
}
diff --git a/src/Symfony/Component/DependencyInjection/Argument/BoundArgument.php b/src/Symfony/Component/DependencyInjection/Argument/BoundArgument.php
index 60059267beea4..f3535d68b0fe5 100644
--- a/src/Symfony/Component/DependencyInjection/Argument/BoundArgument.php
+++ b/src/Symfony/Component/DependencyInjection/Argument/BoundArgument.php
@@ -54,9 +54,9 @@ public function getValues(): array
public function setValues(array $values)
{
if (5 === \count($values)) {
- list($this->value, $this->identifier, $this->used, $this->type, $this->file) = $values;
+ [$this->value, $this->identifier, $this->used, $this->type, $this->file] = $values;
} else {
- list($this->value, $this->identifier, $this->used) = $values;
+ [$this->value, $this->identifier, $this->used] = $values;
}
}
}
diff --git a/src/Symfony/Component/DependencyInjection/Compiler/AbstractRecursivePass.php b/src/Symfony/Component/DependencyInjection/Compiler/AbstractRecursivePass.php
index 76c954a987245..85478da5e9b16 100644
--- a/src/Symfony/Component/DependencyInjection/Compiler/AbstractRecursivePass.php
+++ b/src/Symfony/Component/DependencyInjection/Compiler/AbstractRecursivePass.php
@@ -127,7 +127,7 @@ protected function getConstructor(Definition $definition, bool $required)
}
if ($factory) {
- list($class, $method) = $factory;
+ [$class, $method] = $factory;
if ($class instanceof Reference) {
$class = $this->container->findDefinition((string) $class)->getClass();
} elseif ($class instanceof Definition) {
diff --git a/src/Symfony/Component/DependencyInjection/Compiler/AnalyzeServiceReferencesPass.php b/src/Symfony/Component/DependencyInjection/Compiler/AnalyzeServiceReferencesPass.php
index beb488236c069..f7dbe6c8a35a4 100644
--- a/src/Symfony/Component/DependencyInjection/Compiler/AnalyzeServiceReferencesPass.php
+++ b/src/Symfony/Component/DependencyInjection/Compiler/AnalyzeServiceReferencesPass.php
@@ -12,6 +12,7 @@
namespace Symfony\Component\DependencyInjection\Compiler;
use Symfony\Component\DependencyInjection\Argument\ArgumentInterface;
+use Symfony\Component\DependencyInjection\Argument\IteratorArgument;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Symfony\Component\DependencyInjection\Definition;
@@ -35,6 +36,7 @@ class AnalyzeServiceReferencesPass extends AbstractRecursivePass
private $hasProxyDumper;
private $lazy;
private $byConstructor;
+ private $byFactory;
private $definitions;
private $aliases;
@@ -58,6 +60,7 @@ public function process(ContainerBuilder $container)
$this->graph->clear();
$this->lazy = false;
$this->byConstructor = false;
+ $this->byFactory = false;
$this->definitions = $container->getDefinitions();
$this->aliases = $container->getAliases();
@@ -79,7 +82,7 @@ protected function processValue($value, bool $isRoot = false)
$inExpression = $this->inExpression();
if ($value instanceof ArgumentInterface) {
- $this->lazy = true;
+ $this->lazy = !$this->byFactory || !$value instanceof IteratorArgument;
parent::processValue($value->getValues());
$this->lazy = $lazy;
@@ -129,7 +132,11 @@ protected function processValue($value, bool $isRoot = false)
$byConstructor = $this->byConstructor;
$this->byConstructor = $isRoot || $byConstructor;
+
+ $byFactory = $this->byFactory;
+ $this->byFactory = true;
$this->processValue($value->getFactory());
+ $this->byFactory = $byFactory;
$this->processValue($value->getArguments());
$properties = $value->getProperties();
diff --git a/src/Symfony/Component/DependencyInjection/Compiler/AutowirePass.php b/src/Symfony/Component/DependencyInjection/Compiler/AutowirePass.php
index ba10e92b1e7c3..d201b58b987aa 100644
--- a/src/Symfony/Component/DependencyInjection/Compiler/AutowirePass.php
+++ b/src/Symfony/Component/DependencyInjection/Compiler/AutowirePass.php
@@ -126,7 +126,7 @@ private function doProcessValue($value, bool $isRoot = false)
$this->methodCalls = $this->autowireCalls($reflectionClass, $isRoot);
if ($constructor) {
- list(, $arguments) = array_shift($this->methodCalls);
+ [, $arguments] = array_shift($this->methodCalls);
if ($arguments !== $value->getArguments()) {
$value->setArguments($arguments);
@@ -152,7 +152,7 @@ private function autowireCalls(\ReflectionClass $reflectionClass, bool $isRoot):
foreach ($this->methodCalls as $i => $call) {
$this->decoratedMethodIndex = $i;
- list($method, $arguments) = $call;
+ [$method, $arguments] = $call;
if ($method instanceof \ReflectionFunctionAbstract) {
$reflectionMethod = $method;
diff --git a/src/Symfony/Component/DependencyInjection/Compiler/AutowireRequiredMethodsPass.php b/src/Symfony/Component/DependencyInjection/Compiler/AutowireRequiredMethodsPass.php
index 2c774f781371c..3ae92beb9aec3 100644
--- a/src/Symfony/Component/DependencyInjection/Compiler/AutowireRequiredMethodsPass.php
+++ b/src/Symfony/Component/DependencyInjection/Compiler/AutowireRequiredMethodsPass.php
@@ -37,7 +37,7 @@ protected function processValue($value, bool $isRoot = false)
$alreadyCalledMethods = [];
$withers = [];
- foreach ($value->getMethodCalls() as list($method)) {
+ foreach ($value->getMethodCalls() as [$method]) {
$alreadyCalledMethods[strtolower($method)] = true;
}
diff --git a/src/Symfony/Component/DependencyInjection/Compiler/DecoratorServicePass.php b/src/Symfony/Component/DependencyInjection/Compiler/DecoratorServicePass.php
index c9931fb72619e..ac2dc2299f70b 100644
--- a/src/Symfony/Component/DependencyInjection/Compiler/DecoratorServicePass.php
+++ b/src/Symfony/Component/DependencyInjection/Compiler/DecoratorServicePass.php
@@ -46,9 +46,9 @@ public function process(ContainerBuilder $container)
}
$decoratingDefinitions = [];
- foreach ($definitions as list($id, $definition)) {
+ foreach ($definitions as [$id, $definition]) {
$decoratedService = $definition->getDecoratedService();
- list($inner, $renamedId) = $decoratedService;
+ [$inner, $renamedId] = $decoratedService;
$invalidBehavior = $decoratedService[3] ?? ContainerInterface::EXCEPTION_ON_INVALID_REFERENCE;
$definition->setDecoratedService(null);
diff --git a/src/Symfony/Component/DependencyInjection/Compiler/ResolveBindingsPass.php b/src/Symfony/Component/DependencyInjection/Compiler/ResolveBindingsPass.php
index b86c1b786477b..61e99d73becf9 100644
--- a/src/Symfony/Component/DependencyInjection/Compiler/ResolveBindingsPass.php
+++ b/src/Symfony/Component/DependencyInjection/Compiler/ResolveBindingsPass.php
@@ -41,11 +41,11 @@ public function process(ContainerBuilder $container)
try {
parent::process($container);
- foreach ($this->unusedBindings as list($key, $serviceId, $bindingType, $file)) {
+ foreach ($this->unusedBindings as [$key, $serviceId, $bindingType, $file]) {
$argumentType = $argumentName = $message = null;
if (false !== strpos($key, ' ')) {
- list($argumentType, $argumentName) = explode(' ', $key, 2);
+ [$argumentType, $argumentName] = explode(' ', $key, 2);
} elseif ('$' === $key[0]) {
$argumentName = $key;
} else {
@@ -117,7 +117,7 @@ protected function processValue($value, bool $isRoot = false)
$bindingNames = [];
foreach ($bindings as $key => $binding) {
- list($bindingValue, $bindingId, $used, $bindingType, $file) = $binding->getValues();
+ [$bindingValue, $bindingId, $used, $bindingType, $file] = $binding->getValues();
if ($used) {
$this->usedBindings[$bindingId] = true;
unset($this->unusedBindings[$bindingId]);
@@ -156,7 +156,7 @@ protected function processValue($value, bool $isRoot = false)
}
foreach ($calls as $i => $call) {
- list($method, $arguments) = $call;
+ [$method, $arguments] = $call;
if ($method instanceof \ReflectionFunctionAbstract) {
$reflectionMethod = $method;
@@ -210,7 +210,7 @@ protected function processValue($value, bool $isRoot = false)
}
if ($constructor) {
- list(, $arguments) = array_pop($calls);
+ [, $arguments] = array_pop($calls);
if ($arguments !== $value->getArguments()) {
$value->setArguments($arguments);
@@ -229,7 +229,7 @@ protected function processValue($value, bool $isRoot = false)
*/
private function getBindingValue(BoundArgument $binding)
{
- list($bindingValue, $bindingId) = $binding->getValues();
+ [$bindingValue, $bindingId] = $binding->getValues();
$this->usedBindings[$bindingId] = true;
unset($this->unusedBindings[$bindingId]);
diff --git a/src/Symfony/Component/DependencyInjection/Compiler/ResolveInstanceofConditionalsPass.php b/src/Symfony/Component/DependencyInjection/Compiler/ResolveInstanceofConditionalsPass.php
index 60d059fb29445..4aa33aad1ac26 100644
--- a/src/Symfony/Component/DependencyInjection/Compiler/ResolveInstanceofConditionalsPass.php
+++ b/src/Symfony/Component/DependencyInjection/Compiler/ResolveInstanceofConditionalsPass.php
@@ -35,12 +35,22 @@ public function process(ContainerBuilder $container)
}
}
+ $tagsToKeep = [];
+
+ if ($container->hasParameter('container.behavior_describing_tags')) {
+ $tagsToKeep = $container->getParameter('container.behavior_describing_tags');
+ }
+
foreach ($container->getDefinitions() as $id => $definition) {
- $container->setDefinition($id, $this->processDefinition($container, $id, $definition));
+ $container->setDefinition($id, $this->processDefinition($container, $id, $definition, $tagsToKeep));
+ }
+
+ if ($container->hasParameter('container.behavior_describing_tags')) {
+ $container->getParameterBag()->remove('container.behavior_describing_tags');
}
}
- private function processDefinition(ContainerBuilder $container, string $id, Definition $definition): Definition
+ private function processDefinition(ContainerBuilder $container, string $id, Definition $definition, array $tagsToKeep): Definition
{
$instanceofConditionals = $definition->getInstanceofConditionals();
$autoconfiguredInstanceof = $definition->isAutoconfigured() ? $container->getAutoconfiguredInstanceof() : [];
@@ -114,10 +124,10 @@ private function processDefinition(ContainerBuilder $container, string $id, Defi
}
// Don't add tags to service decorators
- if (null === $definition->getDecoratedService()) {
- $i = \count($instanceofTags);
- while (0 <= --$i) {
- foreach ($instanceofTags[$i] as $k => $v) {
+ $i = \count($instanceofTags);
+ while (0 <= --$i) {
+ foreach ($instanceofTags[$i] as $k => $v) {
+ if (null === $definition->getDecoratedService() || \in_array($k, $tagsToKeep, true)) {
foreach ($v as $v) {
if ($definition->hasTag($k) && \in_array($v, $definition->getTag($k))) {
continue;
diff --git a/src/Symfony/Component/DependencyInjection/Compiler/ResolveNamedArgumentsPass.php b/src/Symfony/Component/DependencyInjection/Compiler/ResolveNamedArgumentsPass.php
index fd3c5e4d1d9f1..c1c5748e8d601 100644
--- a/src/Symfony/Component/DependencyInjection/Compiler/ResolveNamedArgumentsPass.php
+++ b/src/Symfony/Component/DependencyInjection/Compiler/ResolveNamedArgumentsPass.php
@@ -41,7 +41,7 @@ protected function processValue($value, bool $isRoot = false)
$calls[] = ['__construct', $value->getArguments()];
foreach ($calls as $i => $call) {
- list($method, $arguments) = $call;
+ [$method, $arguments] = $call;
$parameters = null;
$resolvedArguments = [];
@@ -107,7 +107,7 @@ protected function processValue($value, bool $isRoot = false)
}
}
- list(, $arguments) = array_pop($calls);
+ [, $arguments] = array_pop($calls);
if ($arguments !== $value->getArguments()) {
$value->setArguments($arguments);
diff --git a/src/Symfony/Component/DependencyInjection/ContainerBuilder.php b/src/Symfony/Component/DependencyInjection/ContainerBuilder.php
index ec82969d1bb4c..5267f6fbb9ba9 100644
--- a/src/Symfony/Component/DependencyInjection/ContainerBuilder.php
+++ b/src/Symfony/Component/DependencyInjection/ContainerBuilder.php
@@ -1167,7 +1167,7 @@ private function doResolveServices($value, array &$inlineServices = [], bool $is
return $this->resolveServices($reference);
};
} elseif ($value instanceof IteratorArgument) {
- $value = new RewindableGenerator(function () use ($value) {
+ $value = new RewindableGenerator(function () use ($value, &$inlineServices) {
foreach ($value->getValues() as $k => $v) {
foreach (self::getServiceConditionals($v) as $s) {
if (!$this->has($s)) {
@@ -1175,12 +1175,12 @@ private function doResolveServices($value, array &$inlineServices = [], bool $is
}
}
foreach (self::getInitializedConditionals($v) as $s) {
- if (!$this->doGet($s, ContainerInterface::IGNORE_ON_UNINITIALIZED_REFERENCE)) {
+ if (!$this->doGet($s, ContainerInterface::IGNORE_ON_UNINITIALIZED_REFERENCE, $inlineServices)) {
continue 2;
}
}
- yield $k => $this->resolveServices($v);
+ yield $k => $this->doResolveServices($v, $inlineServices);
}
}, function () use ($value): int {
$count = 0;
@@ -1455,7 +1455,7 @@ public function removeBindings(string $id)
{
if ($this->hasDefinition($id)) {
foreach ($this->getDefinition($id)->getBindings() as $key => $binding) {
- list(, $bindingId) = $binding->getValues();
+ [, $bindingId] = $binding->getValues();
$this->removedBindingIds[(int) $bindingId] = true;
}
}
diff --git a/src/Symfony/Component/DependencyInjection/Dumper/PhpDumper.php b/src/Symfony/Component/DependencyInjection/Dumper/PhpDumper.php
index 93b303ea2bf20..5376f38cc83ad 100644
--- a/src/Symfony/Component/DependencyInjection/Dumper/PhpDumper.php
+++ b/src/Symfony/Component/DependencyInjection/Dumper/PhpDumper.php
@@ -185,25 +185,7 @@ public function dump(array $options = [])
}
}
- (new AnalyzeServiceReferencesPass(false, !$this->getProxyDumper() instanceof NullDumper))->process($this->container);
- $checkedNodes = [];
- $this->circularReferences = [];
- $this->singleUsePrivateIds = [];
- foreach ($this->container->getCompiler()->getServiceReferenceGraph()->getNodes() as $id => $node) {
- if (!$node->getValue() instanceof Definition) {
- continue;
- }
- if (!isset($checkedNodes[$id])) {
- $this->analyzeCircularReferences($id, $node->getOutEdges(), $checkedNodes);
- }
- if ($this->isSingleUsePrivateNode($node)) {
- $this->singleUsePrivateIds[$id] = $id;
- }
- }
- $this->container->getCompiler()->getServiceReferenceGraph()->clear();
- $checkedNodes = [];
- $this->singleUsePrivateIds = array_diff_key($this->singleUsePrivateIds, $this->circularReferences);
-
+ $this->analyzeReferences();
$this->docStar = $options['debug'] ? '*' : '';
if (!empty($options['file']) && is_dir($dir = \dirname($options['file']))) {
@@ -429,61 +411,99 @@ private function getProxyDumper(): ProxyDumper
return $this->proxyDumper;
}
- /**
- * @param ServiceReferenceGraphEdge[] $edges
- */
- private function analyzeCircularReferences(string $sourceId, array $edges, array &$checkedNodes, array &$currentPath = [], bool $byConstructor = true)
+ private function analyzeReferences()
{
- $checkedNodes[$sourceId] = true;
- $currentPath[$sourceId] = $byConstructor;
-
- foreach ($edges as $edge) {
- $node = $edge->getDestNode();
- $id = $node->getId();
-
- if (!$node->getValue() instanceof Definition || $sourceId === $id || $edge->isLazy() || $edge->isWeak()) {
- // no-op
- } elseif (isset($currentPath[$id])) {
- $this->addCircularReferences($id, $currentPath, $edge->isReferencedByConstructor());
- } elseif (!isset($checkedNodes[$id])) {
- $this->analyzeCircularReferences($id, $node->getOutEdges(), $checkedNodes, $currentPath, $edge->isReferencedByConstructor());
- } elseif (isset($this->circularReferences[$id])) {
- $this->connectCircularReferences($id, $currentPath, $edge->isReferencedByConstructor());
+ (new AnalyzeServiceReferencesPass(false, !$this->getProxyDumper() instanceof NullDumper))->process($this->container);
+ $checkedNodes = [];
+ $this->circularReferences = [];
+ $this->singleUsePrivateIds = [];
+ foreach ($this->container->getCompiler()->getServiceReferenceGraph()->getNodes() as $id => $node) {
+ if (!$node->getValue() instanceof Definition) {
+ continue;
}
- }
- unset($currentPath[$sourceId]);
- }
-
- private function connectCircularReferences(string $sourceId, array &$currentPath, bool $byConstructor, array &$subPath = [])
- {
- $currentPath[$sourceId] = $subPath[$sourceId] = $byConstructor;
- foreach ($this->circularReferences[$sourceId] as $id => $byConstructor) {
- if (isset($currentPath[$id])) {
- $this->addCircularReferences($id, $currentPath, $byConstructor);
- } elseif (!isset($subPath[$id]) && isset($this->circularReferences[$id])) {
- $this->connectCircularReferences($id, $currentPath, $byConstructor, $subPath);
+ if ($this->isSingleUsePrivateNode($node)) {
+ $this->singleUsePrivateIds[$id] = $id;
}
+
+ $this->collectCircularReferences($id, $node->getOutEdges(), $checkedNodes);
}
- unset($currentPath[$sourceId], $subPath[$sourceId]);
+
+ $this->container->getCompiler()->getServiceReferenceGraph()->clear();
+ $this->singleUsePrivateIds = array_diff_key($this->singleUsePrivateIds, $this->circularReferences);
}
- private function addCircularReferences(string $id, array $currentPath, bool $byConstructor)
+ private function collectCircularReferences(string $sourceId, array $edges, array &$checkedNodes, array &$loops = [], array $path = [], bool $byConstructor = true): void
{
- $currentPath[$id] = $byConstructor;
- $circularRefs = [];
+ $path[$sourceId] = $byConstructor;
+ $checkedNodes[$sourceId] = true;
+ foreach ($edges as $edge) {
+ $node = $edge->getDestNode();
+ $id = $node->getId();
+ if ($sourceId === $id || !$node->getValue() instanceof Definition || $edge->isLazy() || $edge->isWeak()) {
+ continue;
+ }
- foreach (array_reverse($currentPath) as $parentId => $v) {
- $byConstructor = $byConstructor && $v;
- $circularRefs[] = $parentId;
+ if (isset($path[$id])) {
+ $loop = null;
+ $loopByConstructor = $edge->isReferencedByConstructor();
+ $pathInLoop = [$id, []];
+ foreach ($path as $k => $pathByConstructor) {
+ if (null !== $loop) {
+ $loop[] = $k;
+ $pathInLoop[1][$k] = $pathByConstructor;
+ $loops[$k][] = &$pathInLoop;
+ $loopByConstructor = $loopByConstructor && $pathByConstructor;
+ } elseif ($k === $id) {
+ $loop = [];
+ }
+ }
+ $this->addCircularReferences($id, $loop, $loopByConstructor);
+ } elseif (!isset($checkedNodes[$id])) {
+ $this->collectCircularReferences($id, $node->getOutEdges(), $checkedNodes, $loops, $path, $edge->isReferencedByConstructor());
+ } elseif (isset($loops[$id])) {
+ // we already had detected loops for this edge
+ // let's check if we have a common ancestor in one of the detected loops
+ foreach ($loops[$id] as [$first, $loopPath]) {
+ if (!isset($path[$first])) {
+ continue;
+ }
+ // We have a common ancestor, let's fill the current path
+ $fillPath = null;
+ foreach ($loopPath as $k => $pathByConstructor) {
+ if (null !== $fillPath) {
+ $fillPath[$k] = $pathByConstructor;
+ } elseif ($k === $id) {
+ $fillPath = $path;
+ $fillPath[$k] = $pathByConstructor;
+ }
+ }
- if ($parentId === $id) {
- break;
+ // we can now build the loop
+ $loop = null;
+ $loopByConstructor = $edge->isReferencedByConstructor();
+ foreach ($fillPath as $k => $pathByConstructor) {
+ if (null !== $loop) {
+ $loop[] = $k;
+ $loopByConstructor = $loopByConstructor && $pathByConstructor;
+ } elseif ($k === $first) {
+ $loop = [];
+ }
+ }
+ $this->addCircularReferences($first, $loop, true);
+ break;
+ }
}
}
+ unset($path[$sourceId]);
+ }
- $currentId = $id;
- foreach ($circularRefs as $parentId) {
+ private function addCircularReferences(string $sourceId, array $currentPath, bool $byConstructor)
+ {
+ $currentId = $sourceId;
+ $currentPath = array_reverse($currentPath);
+ $currentPath[] = $currentId;
+ foreach ($currentPath as $parentId) {
if (empty($this->circularReferences[$parentId][$currentId])) {
$this->circularReferences[$parentId][$currentId] = $byConstructor;
}
@@ -597,7 +617,7 @@ private function addServiceInclude(string $cId, Definition $definition): string
}
}
- foreach ($this->serviceCalls as $id => list($callCount, $behavior)) {
+ foreach ($this->serviceCalls as $id => [$callCount, $behavior]) {
if ('service_container' !== $id && $id !== $cId
&& ContainerInterface::IGNORE_ON_UNINITIALIZED_REFERENCE !== $behavior
&& $this->container->has($id)
@@ -950,7 +970,7 @@ private function addInlineReference(string $id, Definition $definition, string $
$targetId = (string) $this->container->getAlias($targetId);
}
- list($callCount, $behavior) = $this->serviceCalls[$targetId];
+ [$callCount, $behavior] = $this->serviceCalls[$targetId];
if ($id === $targetId) {
return $this->addInlineService($id, $definition, $definition);
@@ -1006,7 +1026,7 @@ private function addInlineService(string $id, Definition $definition, Definition
$code = '';
if ($isSimpleInstance = $isRootInstance = null === $inlineDef) {
- foreach ($this->serviceCalls as $targetId => list($callCount, $behavior, $byConstructor)) {
+ foreach ($this->serviceCalls as $targetId => [$callCount, $behavior, $byConstructor]) {
if ($byConstructor && isset($this->circularReferences[$id][$targetId]) && !$this->circularReferences[$id][$targetId]) {
$code .= $this->addInlineReference($id, $definition, $targetId, $forConstructor);
}
@@ -1076,7 +1096,7 @@ private function addServices(array &$services = null): string
}
foreach ($definitions as $id => $definition) {
- if (!(list($file, $code) = $services[$id]) || null !== $file) {
+ if (!([$file, $code] = $services[$id]) || null !== $file) {
continue;
}
if ($definition->isPublic()) {
@@ -1094,7 +1114,7 @@ private function generateServiceFiles(array $services): iterable
$definitions = $this->container->getDefinitions();
ksort($definitions);
foreach ($definitions as $id => $definition) {
- if ((list($file, $code) = $services[$id]) && null !== $file && ($definition->isPublic() || !$this->isTrivialInstance($definition) || isset($this->locatedIds[$id]))) {
+ if (([$file, $code] = $services[$id]) && null !== $file && ($definition->isPublic() || !$this->isTrivialInstance($definition) || isset($this->locatedIds[$id]))) {
yield $file => [$code, $definition->hasTag($this->hotPathTag) || !$definition->hasTag($this->preloadTags[1]) && !$definition->isDeprecated() && !$definition->hasErrors()];
}
}
@@ -1796,7 +1816,7 @@ private function dumpValue($value, bool $interpolate = true): string
return sprintf('new \%s($this->getService, [%s%s], [%s%s])', ServiceLocator::class, $serviceMap, $serviceMap ? "\n " : '', $serviceTypes, $serviceTypes ? "\n " : '');
}
} finally {
- list($this->definitionVariables, $this->referenceVariables) = $scope;
+ [$this->definitionVariables, $this->referenceVariables] = $scope;
}
} elseif ($value instanceof Definition) {
if ($value->hasErrors() && $e = $value->getErrors()) {
diff --git a/src/Symfony/Component/DependencyInjection/Dumper/XmlDumper.php b/src/Symfony/Component/DependencyInjection/Dumper/XmlDumper.php
index 2a0ee95de63d9..537a4994fb19a 100644
--- a/src/Symfony/Component/DependencyInjection/Dumper/XmlDumper.php
+++ b/src/Symfony/Component/DependencyInjection/Dumper/XmlDumper.php
@@ -118,7 +118,7 @@ private function addService(Definition $definition, ?string $id, \DOMElement $pa
$service->setAttribute('lazy', 'true');
}
if (null !== $decoratedService = $definition->getDecoratedService()) {
- list($decorated, $renamedId, $priority) = $decoratedService;
+ [$decorated, $renamedId, $priority] = $decoratedService;
$service->setAttribute('decorates', $decorated);
$decorationOnInvalid = $decoratedService[3] ?? ContainerInterface::EXCEPTION_ON_INVALID_REFERENCE;
diff --git a/src/Symfony/Component/DependencyInjection/Dumper/YamlDumper.php b/src/Symfony/Component/DependencyInjection/Dumper/YamlDumper.php
index ca57cbac20108..5f7080f090143 100644
--- a/src/Symfony/Component/DependencyInjection/Dumper/YamlDumper.php
+++ b/src/Symfony/Component/DependencyInjection/Dumper/YamlDumper.php
@@ -138,7 +138,7 @@ private function addService(string $id, Definition $definition): string
}
if (null !== $decoratedService = $definition->getDecoratedService()) {
- list($decorated, $renamedId, $priority) = $decoratedService;
+ [$decorated, $renamedId, $priority] = $decoratedService;
$code .= sprintf(" decorates: %s\n", $decorated);
if (null !== $renamedId) {
$code .= sprintf(" decoration_inner_name: %s\n", $renamedId);
diff --git a/src/Symfony/Component/DependencyInjection/Loader/XmlFileLoader.php b/src/Symfony/Component/DependencyInjection/Loader/XmlFileLoader.php
index 33b5a009f7b4c..42103275f5391 100644
--- a/src/Symfony/Component/DependencyInjection/Loader/XmlFileLoader.php
+++ b/src/Symfony/Component/DependencyInjection/Loader/XmlFileLoader.php
@@ -430,7 +430,7 @@ private function processAnonymousServices(\DOMDocument $xml, string $file)
// resolve definitions
uksort($definitions, 'strnatcmp');
- foreach (array_reverse($definitions) as $id => list($domElement, $file)) {
+ foreach (array_reverse($definitions) as $id => [$domElement, $file]) {
if (null !== $definition = $this->parseDefinition($domElement, $file, new Definition())) {
$this->setDefinition($id, $definition);
}
@@ -624,14 +624,13 @@ public function validateSchema(\DOMDocument $dom)
EOF
;
- if (\LIBXML_VERSION < 20900) {
+ if ($this->shouldEnableEntityLoader()) {
$disableEntities = libxml_disable_entity_loader(false);
$valid = @$dom->schemaValidateSource($source);
libxml_disable_entity_loader($disableEntities);
} else {
$valid = @$dom->schemaValidateSource($source);
}
-
foreach ($tmpfiles as $tmpfile) {
@unlink($tmpfile);
}
@@ -639,6 +638,36 @@ public function validateSchema(\DOMDocument $dom)
return $valid;
}
+ private function shouldEnableEntityLoader(): bool
+ {
+ // Version prior to 8.0 can be enabled without deprecation
+ if (\PHP_VERSION_ID < 80000) {
+ return true;
+ }
+
+ static $dom, $schema;
+ if (null === $dom) {
+ $dom = new \DOMDocument();
+ $dom->loadXML('');
+
+ $tmpfile = tempnam(sys_get_temp_dir(), 'symfony');
+ register_shutdown_function(static function () use ($tmpfile) {
+ @unlink($tmpfile);
+ });
+ $schema = '
+
+
+';
+ file_put_contents($tmpfile, '
+
+
+
+');
+ }
+
+ return !@$dom->schemaValidateSource($schema);
+ }
+
private function validateAlias(\DOMElement $alias, string $file)
{
foreach ($alias->attributes as $name => $node) {
diff --git a/src/Symfony/Component/DependencyInjection/Tests/Compiler/ResolveInstanceofConditionalsPassTest.php b/src/Symfony/Component/DependencyInjection/Tests/Compiler/ResolveInstanceofConditionalsPassTest.php
index 3acfbed776f1f..99aa65b13869b 100644
--- a/src/Symfony/Component/DependencyInjection/Tests/Compiler/ResolveInstanceofConditionalsPassTest.php
+++ b/src/Symfony/Component/DependencyInjection/Tests/Compiler/ResolveInstanceofConditionalsPassTest.php
@@ -12,12 +12,16 @@
namespace Symfony\Component\DependencyInjection\Tests\Compiler;
use PHPUnit\Framework\TestCase;
+use Symfony\Component\Config\Resource\ResourceInterface;
+use Symfony\Component\Config\ResourceCheckerInterface;
use Symfony\Component\DependencyInjection\Argument\BoundArgument;
use Symfony\Component\DependencyInjection\ChildDefinition;
use Symfony\Component\DependencyInjection\Compiler\ResolveChildDefinitionsPass;
use Symfony\Component\DependencyInjection\Compiler\ResolveInstanceofConditionalsPass;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\Reference;
+use Symfony\Contracts\Service\ResetInterface;
+use Symfony\Contracts\Service\ServiceSubscriberInterface;
class ResolveInstanceofConditionalsPassTest extends TestCase
{
@@ -325,4 +329,60 @@ public function testDecoratorsAreNotAutomaticallyTagged()
$this->assertSame(['manual' => [[]]], $container->getDefinition('decorator')->getTags());
}
+
+ public function testDecoratorsKeepBehaviorDescribingTags()
+ {
+ $container = new ContainerBuilder();
+
+ $container->setParameter('container.behavior_describing_tags', [
+ 'container.service_subscriber',
+ 'kernel.reset',
+ ]);
+
+ $container->register('decorator', DecoratorWithBehavior::class)
+ ->setAutoconfigured(true)
+ ->setDecoratedService('decorated')
+ ;
+
+ $container->registerForAutoconfiguration(ResourceCheckerInterface::class)
+ ->addTag('config_cache.resource_checker')
+ ;
+ $container->registerForAutoconfiguration(ServiceSubscriberInterface::class)
+ ->addTag('container.service_subscriber')
+ ;
+ $container->registerForAutoconfiguration(ResetInterface::class)
+ ->addTag('kernel.reset', ['method' => 'reset'])
+ ;
+
+ (new ResolveInstanceofConditionalsPass())->process($container);
+
+ $this->assertEquals([
+ 'container.service_subscriber' => [0 => []],
+ 'kernel.reset' => [
+ [
+ 'method' => 'reset',
+ ],
+ ],
+ ], $container->getDefinition('decorator')->getTags());
+ $this->assertFalse($container->hasParameter('container.behavior_describing_tags'));
+ }
+}
+
+class DecoratorWithBehavior implements ResetInterface, ResourceCheckerInterface, ServiceSubscriberInterface
+{
+ public function reset()
+ {
+ }
+
+ public function supports(ResourceInterface $metadata)
+ {
+ }
+
+ public function isFresh(ResourceInterface $resource, $timestamp)
+ {
+ }
+
+ public static function getSubscribedServices()
+ {
+ }
}
diff --git a/src/Symfony/Component/DependencyInjection/Tests/Compiler/ResolveParameterPlaceHoldersPassTest.php b/src/Symfony/Component/DependencyInjection/Tests/Compiler/ResolveParameterPlaceHoldersPassTest.php
index 2504ff112cf86..c586e72c2acbc 100644
--- a/src/Symfony/Component/DependencyInjection/Tests/Compiler/ResolveParameterPlaceHoldersPassTest.php
+++ b/src/Symfony/Component/DependencyInjection/Tests/Compiler/ResolveParameterPlaceHoldersPassTest.php
@@ -67,7 +67,7 @@ public function testAliasParametersShouldBeResolved()
public function testBindingsShouldBeResolved()
{
- list($boundValue) = $this->container->getDefinition('foo')->getBindings()['$baz']->getValues();
+ [$boundValue] = $this->container->getDefinition('foo')->getBindings()['$baz']->getValues();
$this->assertSame($this->container->getParameterBag()->resolveValue('%env(BAZ)%'), $boundValue);
}
diff --git a/src/Symfony/Component/DependencyInjection/Tests/ContainerBuilderTest.php b/src/Symfony/Component/DependencyInjection/Tests/ContainerBuilderTest.php
index e974f7c2b3a30..8a2d454c5d63d 100644
--- a/src/Symfony/Component/DependencyInjection/Tests/ContainerBuilderTest.php
+++ b/src/Symfony/Component/DependencyInjection/Tests/ContainerBuilderTest.php
@@ -1395,6 +1395,19 @@ public function testUninitializedReference()
public function testAlmostCircular($visibility)
{
$container = include __DIR__.'/Fixtures/containers/container_almost_circular.php';
+ $container->compile();
+
+ $entityManager = $container->get('doctrine.entity_manager');
+ $this->assertEquals(new \stdClass(), $entityManager);
+
+ $pA = $container->get('pA');
+ $this->assertEquals(new \stdClass(), $pA);
+
+ $logger = $container->get('monolog.logger');
+ $this->assertEquals(new \stdClass(), $logger->handler);
+
+ $logger_inline = $container->get('monolog_inline.logger');
+ $this->assertEquals(new \stdClass(), $logger_inline->handler);
$foo = $container->get('foo');
$this->assertSame($foo, $foo->bar->foobar->foo);
diff --git a/src/Symfony/Component/DependencyInjection/Tests/Dumper/PhpDumperTest.php b/src/Symfony/Component/DependencyInjection/Tests/Dumper/PhpDumperTest.php
index 1335d60e6963d..dfbd14e94df58 100644
--- a/src/Symfony/Component/DependencyInjection/Tests/Dumper/PhpDumperTest.php
+++ b/src/Symfony/Component/DependencyInjection/Tests/Dumper/PhpDumperTest.php
@@ -1061,6 +1061,18 @@ public function testAlmostCircular($visibility)
$container = new $container();
+ $entityManager = $container->get('doctrine.entity_manager');
+ $this->assertEquals(new \stdClass(), $entityManager);
+
+ $pA = $container->get('pA');
+ $this->assertEquals(new \stdClass(), $pA);
+
+ $logger = $container->get('monolog.logger');
+ $this->assertEquals(new \stdClass(), $logger->handler);
+
+ $logger_inline = $container->get('monolog_inline.logger');
+ $this->assertEquals(new \stdClass(), $logger_inline->handler);
+
$foo = $container->get('foo');
$this->assertSame($foo, $foo->bar->foobar->foo);
diff --git a/src/Symfony/Component/DependencyInjection/Tests/Fixtures/containers/container_almost_circular.php b/src/Symfony/Component/DependencyInjection/Tests/Fixtures/containers/container_almost_circular.php
index a1f885399bd58..8dd05316969f2 100644
--- a/src/Symfony/Component/DependencyInjection/Tests/Fixtures/containers/container_almost_circular.php
+++ b/src/Symfony/Component/DependencyInjection/Tests/Fixtures/containers/container_almost_circular.php
@@ -1,5 +1,7 @@
register('doctrine.config', 'stdClass')->setPublic(false)
+ ->setProperty('resolver', new Reference('doctrine.entity_listener_resolver'))
+ ->setProperty('flag', 'ok');
+
+$container->register('doctrine.entity_manager', 'stdClass')->setPublic(true)
+ ->setFactory([FactoryChecker::class, 'create'])
+ ->addArgument(new Reference('doctrine.config'));
+$container->register('doctrine.entity_listener_resolver', 'stdClass')->setPublic($public)
+ ->addArgument(new IteratorArgument([new Reference('doctrine.listener')]));
+$container->register('doctrine.listener', 'stdClass')->setPublic($public)
+ ->addArgument(new Reference('doctrine.entity_manager'));
+
+// multiple path detection
+
+$container->register('pA', 'stdClass')->setPublic(true)
+ ->addArgument(new Reference('pB'))
+ ->addArgument(new Reference('pC'));
+
+$container->register('pB', 'stdClass')->setPublic($public)
+ ->setProperty('d', new Reference('pD'));
+$container->register('pC', 'stdClass')->setPublic($public)
+ ->setLazy(true)
+ ->setProperty('d', new Reference('pD'));
+
+$container->register('pD', 'stdClass')->setPublic($public)
+ ->addArgument(new Reference('pA'));
+
+// monolog-like + handler that require monolog
+
+$container->register('monolog.logger', 'stdClass')->setPublic(true)
+ ->setProperty('handler', new Reference('mailer.transport'));
+
+$container->register('mailer.transport', 'stdClass')->setPublic($public)
+ ->setFactory([new Reference('mailer.transport_factory'), 'create']);
+
+$container->register('mailer.transport_factory', FactoryCircular::class)->setPublic($public)
+ ->addArgument(new TaggedIteratorArgument('mailer.transport'));
+
+$container->register('mailer.transport_factory.amazon', 'stdClass')->setPublic($public)
+ ->addArgument(new Reference('monolog.logger_2'))
+ ->addTag('mailer.transport');
+
+$container->register('monolog.logger_2', 'stdClass')->setPublic($public)
+ ->setProperty('handler', new Reference('mailer.transport'));
+
+// monolog-like + handler that require monolog with inlined factory
+
+$container->register('monolog_inline.logger', 'stdClass')->setPublic(true)
+ ->setProperty('handler', new Reference('mailer_inline.mailer'));
+
+$container->register('mailer_inline.mailer', 'stdClass')->setPublic(false)
+ ->addArgument(
+ (new Definition('stdClass'))
+ ->setFactory([new Reference('mailer_inline.transport_factory'), 'create'])
+ );
+
+$container->register('mailer_inline.transport_factory', FactoryCircular::class)->setPublic($public)
+ ->addArgument(new TaggedIteratorArgument('mailer_inline.transport'));
+
+$container->register('mailer_inline.transport_factory.amazon', 'stdClass')->setPublic($public)
+ ->addArgument(new Reference('monolog_inline.logger_2'))
+ ->addTag('mailer.transport');
+
+$container->register('monolog_inline.logger_2', 'stdClass')->setPublic($public)
+ ->setProperty('handler', new Reference('mailer_inline.mailer'));
+
// same visibility for deps
$container->register('foo', FooCircular::class)->setPublic(true)
diff --git a/src/Symfony/Component/DependencyInjection/Tests/Fixtures/includes/classes.php b/src/Symfony/Component/DependencyInjection/Tests/Fixtures/includes/classes.php
index fee80ac779749..39ad97f990e93 100644
--- a/src/Symfony/Component/DependencyInjection/Tests/Fixtures/includes/classes.php
+++ b/src/Symfony/Component/DependencyInjection/Tests/Fixtures/includes/classes.php
@@ -111,6 +111,35 @@ public function __construct($lazyValues, $lazyEmptyValues)
}
}
+class FactoryCircular
+{
+ public $services;
+
+ public function __construct($services)
+ {
+ $this->services = $services;
+ }
+
+ public function create()
+ {
+ foreach ($this->services as $service) {
+ return $service;
+ }
+ }
+}
+
+class FactoryChecker
+{
+ public static function create($config)
+ {
+ if (!isset($config->flag)) {
+ throw new \LogicException('The injected config must contain a "flag" property.');
+ }
+
+ return new stdClass();
+ }
+}
+
class FoobarCircular
{
public function __construct(FooCircular $foo)
diff --git a/src/Symfony/Component/DependencyInjection/Tests/Fixtures/php/services_almost_circular_private.php b/src/Symfony/Component/DependencyInjection/Tests/Fixtures/php/services_almost_circular_private.php
index 60c60b3adfb45..f20be40568b0b 100644
--- a/src/Symfony/Component/DependencyInjection/Tests/Fixtures/php/services_almost_circular_private.php
+++ b/src/Symfony/Component/DependencyInjection/Tests/Fixtures/php/services_almost_circular_private.php
@@ -25,6 +25,7 @@ public function __construct()
'baz6' => 'getBaz6Service',
'connection' => 'getConnectionService',
'connection2' => 'getConnection2Service',
+ 'doctrine.entity_manager' => 'getDoctrine_EntityManagerService',
'foo' => 'getFooService',
'foo2' => 'getFoo2Service',
'foo5' => 'getFoo5Service',
@@ -36,6 +37,9 @@ public function __construct()
'manager' => 'getManagerService',
'manager2' => 'getManager2Service',
'manager3' => 'getManager3Service',
+ 'monolog.logger' => 'getMonolog_LoggerService',
+ 'monolog_inline.logger' => 'getMonologInline_LoggerService',
+ 'pA' => 'getPAService',
'root' => 'getRootService',
'subscriber' => 'getSubscriberService',
];
@@ -67,6 +71,9 @@ public function getRemovedIds(): array
'connection4' => true,
'dispatcher' => true,
'dispatcher2' => true,
+ 'doctrine.config' => true,
+ 'doctrine.entity_listener_resolver' => true,
+ 'doctrine.listener' => true,
'foo4' => true,
'foobar' => true,
'foobar2' => true,
@@ -77,8 +84,19 @@ public function getRemovedIds(): array
'level5' => true,
'level6' => true,
'logger2' => true,
+ 'mailer.transport' => true,
+ 'mailer.transport_factory' => true,
+ 'mailer.transport_factory.amazon' => true,
+ 'mailer_inline.mailer' => true,
+ 'mailer_inline.transport_factory' => true,
+ 'mailer_inline.transport_factory.amazon' => true,
'manager4' => true,
+ 'monolog.logger_2' => true,
+ 'monolog_inline.logger_2' => true,
'multiuse1' => true,
+ 'pB' => true,
+ 'pC' => true,
+ 'pD' => true,
'subscriber2' => true,
];
}
@@ -173,6 +191,22 @@ protected function getConnection2Service()
return $instance;
}
+ /**
+ * Gets the public 'doctrine.entity_manager' shared service.
+ *
+ * @return \stdClass
+ */
+ protected function getDoctrine_EntityManagerService()
+ {
+ $a = new \stdClass();
+ $a->resolver = new \stdClass(new RewindableGenerator(function () {
+ yield 0 => ($this->privates['doctrine.listener'] ?? $this->getDoctrine_ListenerService());
+ }, 1));
+ $a->flag = 'ok';
+
+ return $this->services['doctrine.entity_manager'] = \FactoryChecker::create($a);
+ }
+
/**
* Gets the public 'foo' shared service.
*
@@ -352,6 +386,56 @@ protected function getManager3Service($lazyLoad = true)
return $this->services['manager3'] = new \stdClass($b);
}
+ /**
+ * Gets the public 'monolog.logger' shared service.
+ *
+ * @return \stdClass
+ */
+ protected function getMonolog_LoggerService()
+ {
+ $this->services['monolog.logger'] = $instance = new \stdClass();
+
+ $instance->handler = ($this->privates['mailer.transport'] ?? $this->getMailer_TransportService());
+
+ return $instance;
+ }
+
+ /**
+ * Gets the public 'monolog_inline.logger' shared service.
+ *
+ * @return \stdClass
+ */
+ protected function getMonologInline_LoggerService()
+ {
+ $this->services['monolog_inline.logger'] = $instance = new \stdClass();
+
+ $instance->handler = ($this->privates['mailer_inline.mailer'] ?? $this->getMailerInline_MailerService());
+
+ return $instance;
+ }
+
+ /**
+ * Gets the public 'pA' shared service.
+ *
+ * @return \stdClass
+ */
+ protected function getPAService()
+ {
+ $a = new \stdClass();
+
+ $b = ($this->privates['pC'] ?? $this->getPCService());
+
+ if (isset($this->services['pA'])) {
+ return $this->services['pA'];
+ }
+
+ $this->services['pA'] = $instance = new \stdClass($a, $b);
+
+ $a->d = ($this->privates['pD'] ?? $this->getPDService());
+
+ return $instance;
+ }
+
/**
* Gets the public 'root' shared service.
*
@@ -400,6 +484,16 @@ protected function getBar6Service()
return $this->privates['bar6'] = new \stdClass($a);
}
+ /**
+ * Gets the private 'doctrine.listener' shared service.
+ *
+ * @return \stdClass
+ */
+ protected function getDoctrine_ListenerService()
+ {
+ return $this->privates['doctrine.listener'] = new \stdClass(($this->services['doctrine.entity_manager'] ?? $this->getDoctrine_EntityManagerService()));
+ }
+
/**
* Gets the private 'level5' shared service.
*
@@ -416,6 +510,60 @@ protected function getLevel5Service()
return $instance;
}
+ /**
+ * Gets the private 'mailer.transport' shared service.
+ *
+ * @return \stdClass
+ */
+ protected function getMailer_TransportService()
+ {
+ return $this->privates['mailer.transport'] = (new \FactoryCircular(new RewindableGenerator(function () {
+ yield 0 => ($this->privates['mailer.transport_factory.amazon'] ?? $this->getMailer_TransportFactory_AmazonService());
+ yield 1 => $this->getMailerInline_TransportFactory_AmazonService();
+ }, 2)))->create();
+ }
+
+ /**
+ * Gets the private 'mailer.transport_factory.amazon' shared service.
+ *
+ * @return \stdClass
+ */
+ protected function getMailer_TransportFactory_AmazonService()
+ {
+ $a = new \stdClass();
+
+ $this->privates['mailer.transport_factory.amazon'] = $instance = new \stdClass($a);
+
+ $a->handler = ($this->privates['mailer.transport'] ?? $this->getMailer_TransportService());
+
+ return $instance;
+ }
+
+ /**
+ * Gets the private 'mailer_inline.mailer' shared service.
+ *
+ * @return \stdClass
+ */
+ protected function getMailerInline_MailerService()
+ {
+ return $this->privates['mailer_inline.mailer'] = new \stdClass((new \FactoryCircular(new RewindableGenerator(function () {
+ return new \EmptyIterator();
+ }, 0)))->create());
+ }
+
+ /**
+ * Gets the private 'mailer_inline.transport_factory.amazon' shared service.
+ *
+ * @return \stdClass
+ */
+ protected function getMailerInline_TransportFactory_AmazonService()
+ {
+ $a = new \stdClass();
+ $a->handler = ($this->privates['mailer_inline.mailer'] ?? $this->getMailerInline_MailerService());
+
+ return new \stdClass($a);
+ }
+
/**
* Gets the private 'manager4' shared service.
*
@@ -431,4 +579,34 @@ protected function getManager4Service($lazyLoad = true)
return $instance;
}
+
+ /**
+ * Gets the private 'pC' shared service.
+ *
+ * @return \stdClass
+ */
+ protected function getPCService($lazyLoad = true)
+ {
+ $this->privates['pC'] = $instance = new \stdClass();
+
+ $instance->d = ($this->privates['pD'] ?? $this->getPDService());
+
+ return $instance;
+ }
+
+ /**
+ * Gets the private 'pD' shared service.
+ *
+ * @return \stdClass
+ */
+ protected function getPDService()
+ {
+ $a = ($this->services['pA'] ?? $this->getPAService());
+
+ if (isset($this->privates['pD'])) {
+ return $this->privates['pD'];
+ }
+
+ return $this->privates['pD'] = new \stdClass($a);
+ }
}
diff --git a/src/Symfony/Component/DependencyInjection/Tests/Fixtures/php/services_almost_circular_public.php b/src/Symfony/Component/DependencyInjection/Tests/Fixtures/php/services_almost_circular_public.php
index 4905ade2dd408..666ac0a876995 100644
--- a/src/Symfony/Component/DependencyInjection/Tests/Fixtures/php/services_almost_circular_public.php
+++ b/src/Symfony/Component/DependencyInjection/Tests/Fixtures/php/services_almost_circular_public.php
@@ -30,6 +30,9 @@ public function __construct()
'connection4' => 'getConnection4Service',
'dispatcher' => 'getDispatcherService',
'dispatcher2' => 'getDispatcher2Service',
+ 'doctrine.entity_listener_resolver' => 'getDoctrine_EntityListenerResolverService',
+ 'doctrine.entity_manager' => 'getDoctrine_EntityManagerService',
+ 'doctrine.listener' => 'getDoctrine_ListenerService',
'foo' => 'getFooService',
'foo2' => 'getFoo2Service',
'foo4' => 'getFoo4Service',
@@ -42,9 +45,22 @@ public function __construct()
'listener3' => 'getListener3Service',
'listener4' => 'getListener4Service',
'logger' => 'getLoggerService',
+ 'mailer.transport' => 'getMailer_TransportService',
+ 'mailer.transport_factory' => 'getMailer_TransportFactoryService',
+ 'mailer.transport_factory.amazon' => 'getMailer_TransportFactory_AmazonService',
+ 'mailer_inline.transport_factory' => 'getMailerInline_TransportFactoryService',
+ 'mailer_inline.transport_factory.amazon' => 'getMailerInline_TransportFactory_AmazonService',
'manager' => 'getManagerService',
'manager2' => 'getManager2Service',
'manager3' => 'getManager3Service',
+ 'monolog.logger' => 'getMonolog_LoggerService',
+ 'monolog.logger_2' => 'getMonolog_Logger2Service',
+ 'monolog_inline.logger' => 'getMonologInline_LoggerService',
+ 'monolog_inline.logger_2' => 'getMonologInline_Logger2Service',
+ 'pA' => 'getPAService',
+ 'pB' => 'getPBService',
+ 'pC' => 'getPCService',
+ 'pD' => 'getPDService',
'root' => 'getRootService',
'subscriber' => 'getSubscriberService',
];
@@ -71,12 +87,14 @@ public function getRemovedIds(): array
'bar6' => true,
'config' => true,
'config2' => true,
+ 'doctrine.config' => true,
'level2' => true,
'level3' => true,
'level4' => true,
'level5' => true,
'level6' => true,
'logger2' => true,
+ 'mailer_inline.mailer' => true,
'manager4' => true,
'multiuse1' => true,
'subscriber2' => true,
@@ -248,6 +266,42 @@ protected function getDispatcher2Service($lazyLoad = true)
return $instance;
}
+ /**
+ * Gets the public 'doctrine.entity_listener_resolver' shared service.
+ *
+ * @return \stdClass
+ */
+ protected function getDoctrine_EntityListenerResolverService()
+ {
+ return $this->services['doctrine.entity_listener_resolver'] = new \stdClass(new RewindableGenerator(function () {
+ yield 0 => ($this->services['doctrine.listener'] ?? $this->getDoctrine_ListenerService());
+ }, 1));
+ }
+
+ /**
+ * Gets the public 'doctrine.entity_manager' shared service.
+ *
+ * @return \stdClass
+ */
+ protected function getDoctrine_EntityManagerService()
+ {
+ $a = new \stdClass();
+ $a->resolver = ($this->services['doctrine.entity_listener_resolver'] ?? $this->getDoctrine_EntityListenerResolverService());
+ $a->flag = 'ok';
+
+ return $this->services['doctrine.entity_manager'] = \FactoryChecker::create($a);
+ }
+
+ /**
+ * Gets the public 'doctrine.listener' shared service.
+ *
+ * @return \stdClass
+ */
+ protected function getDoctrine_ListenerService()
+ {
+ return $this->services['doctrine.listener'] = new \stdClass(($this->services['doctrine.entity_manager'] ?? $this->getDoctrine_EntityManagerService()));
+ }
+
/**
* Gets the public 'foo' shared service.
*
@@ -434,6 +488,61 @@ protected function getLoggerService()
return $instance;
}
+ /**
+ * Gets the public 'mailer.transport' shared service.
+ *
+ * @return \stdClass
+ */
+ protected function getMailer_TransportService()
+ {
+ return $this->services['mailer.transport'] = ($this->services['mailer.transport_factory'] ?? $this->getMailer_TransportFactoryService())->create();
+ }
+
+ /**
+ * Gets the public 'mailer.transport_factory' shared service.
+ *
+ * @return \FactoryCircular
+ */
+ protected function getMailer_TransportFactoryService()
+ {
+ return $this->services['mailer.transport_factory'] = new \FactoryCircular(new RewindableGenerator(function () {
+ yield 0 => ($this->services['mailer.transport_factory.amazon'] ?? $this->getMailer_TransportFactory_AmazonService());
+ yield 1 => ($this->services['mailer_inline.transport_factory.amazon'] ?? $this->getMailerInline_TransportFactory_AmazonService());
+ }, 2));
+ }
+
+ /**
+ * Gets the public 'mailer.transport_factory.amazon' shared service.
+ *
+ * @return \stdClass
+ */
+ protected function getMailer_TransportFactory_AmazonService()
+ {
+ return $this->services['mailer.transport_factory.amazon'] = new \stdClass(($this->services['monolog.logger_2'] ?? $this->getMonolog_Logger2Service()));
+ }
+
+ /**
+ * Gets the public 'mailer_inline.transport_factory' shared service.
+ *
+ * @return \FactoryCircular
+ */
+ protected function getMailerInline_TransportFactoryService()
+ {
+ return $this->services['mailer_inline.transport_factory'] = new \FactoryCircular(new RewindableGenerator(function () {
+ return new \EmptyIterator();
+ }, 0));
+ }
+
+ /**
+ * Gets the public 'mailer_inline.transport_factory.amazon' shared service.
+ *
+ * @return \stdClass
+ */
+ protected function getMailerInline_TransportFactory_AmazonService()
+ {
+ return $this->services['mailer_inline.transport_factory.amazon'] = new \stdClass(($this->services['monolog_inline.logger_2'] ?? $this->getMonologInline_Logger2Service()));
+ }
+
/**
* Gets the public 'manager' shared service.
*
@@ -482,6 +591,127 @@ protected function getManager3Service($lazyLoad = true)
return $this->services['manager3'] = new \stdClass($a);
}
+ /**
+ * Gets the public 'monolog.logger' shared service.
+ *
+ * @return \stdClass
+ */
+ protected function getMonolog_LoggerService()
+ {
+ $this->services['monolog.logger'] = $instance = new \stdClass();
+
+ $instance->handler = ($this->services['mailer.transport'] ?? $this->getMailer_TransportService());
+
+ return $instance;
+ }
+
+ /**
+ * Gets the public 'monolog.logger_2' shared service.
+ *
+ * @return \stdClass
+ */
+ protected function getMonolog_Logger2Service()
+ {
+ $this->services['monolog.logger_2'] = $instance = new \stdClass();
+
+ $instance->handler = ($this->services['mailer.transport'] ?? $this->getMailer_TransportService());
+
+ return $instance;
+ }
+
+ /**
+ * Gets the public 'monolog_inline.logger' shared service.
+ *
+ * @return \stdClass
+ */
+ protected function getMonologInline_LoggerService()
+ {
+ $this->services['monolog_inline.logger'] = $instance = new \stdClass();
+
+ $instance->handler = ($this->privates['mailer_inline.mailer'] ?? $this->getMailerInline_MailerService());
+
+ return $instance;
+ }
+
+ /**
+ * Gets the public 'monolog_inline.logger_2' shared service.
+ *
+ * @return \stdClass
+ */
+ protected function getMonologInline_Logger2Service()
+ {
+ $this->services['monolog_inline.logger_2'] = $instance = new \stdClass();
+
+ $instance->handler = ($this->privates['mailer_inline.mailer'] ?? $this->getMailerInline_MailerService());
+
+ return $instance;
+ }
+
+ /**
+ * Gets the public 'pA' shared service.
+ *
+ * @return \stdClass
+ */
+ protected function getPAService()
+ {
+ $a = ($this->services['pB'] ?? $this->getPBService());
+
+ if (isset($this->services['pA'])) {
+ return $this->services['pA'];
+ }
+ $b = ($this->services['pC'] ?? $this->getPCService());
+
+ if (isset($this->services['pA'])) {
+ return $this->services['pA'];
+ }
+
+ return $this->services['pA'] = new \stdClass($a, $b);
+ }
+
+ /**
+ * Gets the public 'pB' shared service.
+ *
+ * @return \stdClass
+ */
+ protected function getPBService()
+ {
+ $this->services['pB'] = $instance = new \stdClass();
+
+ $instance->d = ($this->services['pD'] ?? $this->getPDService());
+
+ return $instance;
+ }
+
+ /**
+ * Gets the public 'pC' shared service.
+ *
+ * @return \stdClass
+ */
+ protected function getPCService($lazyLoad = true)
+ {
+ $this->services['pC'] = $instance = new \stdClass();
+
+ $instance->d = ($this->services['pD'] ?? $this->getPDService());
+
+ return $instance;
+ }
+
+ /**
+ * Gets the public 'pD' shared service.
+ *
+ * @return \stdClass
+ */
+ protected function getPDService()
+ {
+ $a = ($this->services['pA'] ?? $this->getPAService());
+
+ if (isset($this->services['pD'])) {
+ return $this->services['pD'];
+ }
+
+ return $this->services['pD'] = new \stdClass($a);
+ }
+
/**
* Gets the public 'root' shared service.
*
@@ -546,6 +776,16 @@ protected function getLevel5Service()
return $instance;
}
+ /**
+ * Gets the private 'mailer_inline.mailer' shared service.
+ *
+ * @return \stdClass
+ */
+ protected function getMailerInline_MailerService()
+ {
+ return $this->privates['mailer_inline.mailer'] = new \stdClass(($this->services['mailer_inline.transport_factory'] ?? $this->getMailerInline_TransportFactoryService())->create());
+ }
+
/**
* Gets the private 'manager4' shared service.
*
diff --git a/src/Symfony/Component/Dotenv/Dotenv.php b/src/Symfony/Component/Dotenv/Dotenv.php
index 8cb2ba82c278c..21aa729091a7b 100644
--- a/src/Symfony/Component/Dotenv/Dotenv.php
+++ b/src/Symfony/Component/Dotenv/Dotenv.php
@@ -456,7 +456,7 @@ private function resolveCommands(string $value, array $loadedVars): string
$process = method_exists(Process::class, 'fromShellCommandline') ? Process::fromShellCommandline('echo '.$matches[0]) : new Process('echo '.$matches[0]);
- if (!method_exists(Process::class, 'fromShellCommandline')) {
+ if (!method_exists(Process::class, 'fromShellCommandline') && method_exists(Process::class, 'inheritEnvironmentVariables')) {
// Symfony 3.4 does not inherit env vars by default:
$process->inheritEnvironmentVariables();
}
diff --git a/src/Symfony/Component/ErrorHandler/DebugClassLoader.php b/src/Symfony/Component/ErrorHandler/DebugClassLoader.php
index 747db80d805e1..2c216cbe7f850 100644
--- a/src/Symfony/Component/ErrorHandler/DebugClassLoader.php
+++ b/src/Symfony/Component/ErrorHandler/DebugClassLoader.php
@@ -493,7 +493,7 @@ public function checkAnnotations(\ReflectionClass $refl, string $class): array
$hasCall = $refl->hasMethod('__call');
$hasStaticCall = $refl->hasMethod('__callStatic');
foreach (self::$method[$use] as $method) {
- list($interface, $name, $static, $description) = $method;
+ [$interface, $name, $static, $description] = $method;
if ($static ? $hasStaticCall : $hasCall) {
continue;
}
@@ -555,12 +555,12 @@ public function checkAnnotations(\ReflectionClass $refl, string $class): array
}
if ($parent && isset(self::$finalMethods[$parent][$method->name])) {
- list($declaringClass, $message) = self::$finalMethods[$parent][$method->name];
+ [$declaringClass, $message] = self::$finalMethods[$parent][$method->name];
$deprecations[] = sprintf('The "%s::%s()" method is considered final%s. It may change without further notice as of its next major version. You should not extend it from "%s".', $declaringClass, $method->name, $message, $className);
}
if (isset(self::$internalMethods[$class][$method->name])) {
- list($declaringClass, $message) = self::$internalMethods[$class][$method->name];
+ [$declaringClass, $message] = self::$internalMethods[$class][$method->name];
if (strncmp($ns, $declaringClass, $len)) {
$deprecations[] = sprintf('The "%s::%s()" method is considered internal%s. It may change without further notice. You should not extend it from "%s".', $declaringClass, $method->name, $message, $className);
}
@@ -600,7 +600,7 @@ public function checkAnnotations(\ReflectionClass $refl, string $class): array
}
if (null !== ($returnType = self::$returnTypes[$class][$method->name] ?? self::MAGIC_METHODS[$method->name] ?? null) && !$method->hasReturnType() && !($doc && preg_match('/\n\s+\* @return +(\S+)/', $doc))) {
- list($normalizedType, $returnType, $declaringClass, $declaringFile) = \is_string($returnType) ? [$returnType, $returnType, '', ''] : $returnType;
+ [$normalizedType, $returnType, $declaringClass, $declaringFile] = \is_string($returnType) ? [$returnType, $returnType, '', ''] : $returnType;
if ('void' === $normalizedType) {
$canAddReturnType = false;
@@ -668,7 +668,7 @@ public function checkAnnotations(\ReflectionClass $refl, string $class): array
$definedParameters[$parameter->name] = true;
}
}
- foreach ($matches as list(, $parameterType, $parameterName)) {
+ foreach ($matches as [, $parameterType, $parameterName]) {
if (!isset($definedParameters[$parameterName])) {
$parameterType = trim($parameterType);
self::$annotatedParameters[$class][$method->name][$parameterName] = sprintf('The "%%s::%s()" method will require a new "%s$%s" argument in the next major version of its %s "%s", not defining it is deprecated.', $method->name, $parameterType ? $parameterType.' ' : '', $parameterName, interface_exists($className) ? 'interface' : 'parent class', $className);
@@ -939,10 +939,10 @@ private function patchMethod(\ReflectionMethod $method, string $returnType, stri
continue;
}
- list($namespace, $useOffset, $useMap) = $useStatements[$file] ?? $useStatements[$file] = self::getUseStatements($file);
+ [$namespace, $useOffset, $useMap] = $useStatements[$file] ?? $useStatements[$file] = self::getUseStatements($file);
if ('\\' !== $type[0]) {
- list($declaringNamespace, , $declaringUseMap) = $useStatements[$declaringFile] ?? $useStatements[$declaringFile] = self::getUseStatements($declaringFile);
+ [$declaringNamespace, , $declaringUseMap] = $useStatements[$declaringFile] ?? $useStatements[$declaringFile] = self::getUseStatements($declaringFile);
$p = strpos($type, '\\', 1);
$alias = $p ? substr($type, 0, $p) : $type;
diff --git a/src/Symfony/Component/EventDispatcher/Debug/TraceableEventDispatcher.php b/src/Symfony/Component/EventDispatcher/Debug/TraceableEventDispatcher.php
index 11dce4897bc65..87d538eaf8f04 100644
--- a/src/Symfony/Component/EventDispatcher/Debug/TraceableEventDispatcher.php
+++ b/src/Symfony/Component/EventDispatcher/Debug/TraceableEventDispatcher.php
@@ -177,7 +177,7 @@ public function getCalledListeners(Request $request = null)
$hash = $request ? spl_object_hash($request) : null;
$called = [];
foreach ($this->callStack as $listener) {
- list($eventName, $requestHash) = $this->callStack->getInfo();
+ [$eventName, $requestHash] = $this->callStack->getInfo();
if (null === $hash || $hash === $requestHash) {
$called[] = $listener->getInfo($eventName);
}
@@ -207,7 +207,7 @@ public function getNotCalledListeners(Request $request = null)
if (null !== $this->callStack) {
foreach ($this->callStack as $calledListener) {
- list(, $requestHash) = $this->callStack->getInfo();
+ [, $requestHash] = $this->callStack->getInfo();
if (null === $hash || $hash === $requestHash) {
$calledListeners[] = $calledListener->getWrappedListener();
diff --git a/src/Symfony/Component/EventDispatcher/Tests/EventDispatcherTest.php b/src/Symfony/Component/EventDispatcher/Tests/EventDispatcherTest.php
index ea9fe8c1b6cdc..173f4273eb2f4 100644
--- a/src/Symfony/Component/EventDispatcher/Tests/EventDispatcherTest.php
+++ b/src/Symfony/Component/EventDispatcher/Tests/EventDispatcherTest.php
@@ -19,10 +19,9 @@
class EventDispatcherTest extends TestCase
{
/* Some pseudo events */
- const preFoo = 'pre.foo';
- const postFoo = 'post.foo';
- const preBar = 'pre.bar';
- const postBar = 'post.bar';
+ private const preFoo = 'pre.foo';
+ private const postFoo = 'post.foo';
+ private const preBar = 'pre.bar';
/**
* @var EventDispatcher
diff --git a/src/Symfony/Component/ExpressionLanguage/Lexer.php b/src/Symfony/Component/ExpressionLanguage/Lexer.php
index 5a3fb0a0efc17..6e3cc488b1ee3 100644
--- a/src/Symfony/Component/ExpressionLanguage/Lexer.php
+++ b/src/Symfony/Component/ExpressionLanguage/Lexer.php
@@ -60,7 +60,7 @@ public function tokenize(string $expression)
throw new SyntaxError(sprintf('Unexpected "%s".', $expression[$cursor]), $cursor, $expression);
}
- list($expect, $cur) = array_pop($brackets);
+ [$expect, $cur] = array_pop($brackets);
if ($expression[$cursor] != strtr($expect, '([{', ')]}')) {
throw new SyntaxError(sprintf('Unclosed "%s".', $expect), $cur, $expression);
}
@@ -92,7 +92,7 @@ public function tokenize(string $expression)
$tokens[] = new Token(Token::EOF_TYPE, null, $cursor + 1);
if (!empty($brackets)) {
- list($expect, $cur) = array_pop($brackets);
+ [$expect, $cur] = array_pop($brackets);
throw new SyntaxError(sprintf('Unclosed "%s".', $expect), $cur, $expression);
}
diff --git a/src/Symfony/Component/Filesystem/Filesystem.php b/src/Symfony/Component/Filesystem/Filesystem.php
index aaf62d02674f8..a1c53d88bb4b5 100644
--- a/src/Symfony/Component/Filesystem/Filesystem.php
+++ b/src/Symfony/Component/Filesystem/Filesystem.php
@@ -454,8 +454,8 @@ public function makePathRelative(string $endPath, string $startPath)
return $result;
};
- list($endPath, $endDriveLetter) = $splitDriveLetter($endPath);
- list($startPath, $startDriveLetter) = $splitDriveLetter($startPath);
+ [$endPath, $endDriveLetter] = $splitDriveLetter($endPath);
+ [$startPath, $startDriveLetter] = $splitDriveLetter($startPath);
$startPathArr = $splitPath($startPath);
$endPathArr = $splitPath($endPath);
@@ -590,7 +590,7 @@ public function isAbsolutePath(string $file)
public function tempnam(string $dir, string $prefix/*, string $suffix = ''*/)
{
$suffix = \func_num_args() > 2 ? func_get_arg(2) : '';
- list($scheme, $hierarchy) = $this->getSchemeAndHierarchy($dir);
+ [$scheme, $hierarchy] = $this->getSchemeAndHierarchy($dir);
// If no scheme or scheme is "file" or "gs" (Google Cloud) create temp file in local filesystem
if ((null === $scheme || 'file' === $scheme || 'gs' === $scheme) && '' === $suffix) {
@@ -658,13 +658,17 @@ public function dumpFile(string $filename, $content)
// when the filesystem supports chmod.
$tmpFile = $this->tempnam($dir, basename($filename));
- if (false === @file_put_contents($tmpFile, $content)) {
- throw new IOException(sprintf('Failed to write file "%s".', $filename), 0, null, $filename);
- }
+ try {
+ if (false === @file_put_contents($tmpFile, $content)) {
+ throw new IOException(sprintf('Failed to write file "%s".', $filename), 0, null, $filename);
+ }
- @chmod($tmpFile, file_exists($filename) ? fileperms($filename) : 0666 & ~umask());
+ @chmod($tmpFile, file_exists($filename) ? fileperms($filename) : 0666 & ~umask());
- $this->rename($tmpFile, $filename, true);
+ $this->rename($tmpFile, $filename, true);
+ } finally {
+ @unlink($tmpFile);
+ }
}
/**
diff --git a/src/Symfony/Component/Filesystem/Tests/FilesystemTest.php b/src/Symfony/Component/Filesystem/Tests/FilesystemTest.php
index 68542d7b5c97d..4158f88f85aa9 100644
--- a/src/Symfony/Component/Filesystem/Tests/FilesystemTest.php
+++ b/src/Symfony/Component/Filesystem/Tests/FilesystemTest.php
@@ -1720,6 +1720,18 @@ public function testAppendToFileCreateTheFileIfNotExists()
$this->assertStringEqualsFile($filename, 'bar');
}
+ public function testDumpRemovesTmpFilesOnFailure()
+ {
+ $expected = scandir(__DIR__, \SCANDIR_SORT_ASCENDING);
+
+ try {
+ $this->filesystem->dumpFile(__DIR__.'/Fixtures', 'bar');
+ $this->fail('IOException expected.');
+ } catch (IOException $e) {
+ $this->assertSame($expected, scandir(__DIR__, \SCANDIR_SORT_ASCENDING));
+ }
+ }
+
public function testDumpKeepsExistingPermissionsWhenOverwritingAnExistingFile()
{
$this->markAsSkippedIfChmodIsMissing();
diff --git a/src/Symfony/Component/Finder/Finder.php b/src/Symfony/Component/Finder/Finder.php
index 2b13a73ceb42c..10cd62aacd1ba 100644
--- a/src/Symfony/Component/Finder/Finder.php
+++ b/src/Symfony/Component/Finder/Finder.php
@@ -655,7 +655,7 @@ public function append(iterable $iterator)
}
/**
- * Check if the any results were found.
+ * Check if any results were found.
*
* @return bool
*/
diff --git a/src/Symfony/Component/Finder/Tests/Iterator/SortableIteratorTest.php b/src/Symfony/Component/Finder/Tests/Iterator/SortableIteratorTest.php
index 5a47812bd3474..add8e7df596be 100644
--- a/src/Symfony/Component/Finder/Tests/Iterator/SortableIteratorTest.php
+++ b/src/Symfony/Component/Finder/Tests/Iterator/SortableIteratorTest.php
@@ -35,9 +35,10 @@ public function testAccept($mode, $expected)
case SortableIterator::SORT_BY_ACCESSED_TIME:
touch(self::toAbsolute('.git'));
sleep(1);
- file_get_contents(self::toAbsolute('.bar'));
+ touch(self::toAbsolute('.bar'), time());
break;
case SortableIterator::SORT_BY_CHANGED_TIME:
+ sleep(1);
file_put_contents(self::toAbsolute('test.php'), 'foo');
sleep(1);
file_put_contents(self::toAbsolute('test.py'), 'foo');
diff --git a/src/Symfony/Component/Form/Extension/Core/Type/FileType.php b/src/Symfony/Component/Form/Extension/Core/Type/FileType.php
index 57b37ca21c638..f0aee23bfa057 100644
--- a/src/Symfony/Component/Form/Extension/Core/Type/FileType.php
+++ b/src/Symfony/Component/Form/Extension/Core/Type/FileType.php
@@ -12,8 +12,8 @@
namespace Symfony\Component\Form\Extension\Core\Type;
use Symfony\Component\Form\AbstractType;
+use Symfony\Component\Form\FileUploadError;
use Symfony\Component\Form\FormBuilderInterface;
-use Symfony\Component\Form\FormError;
use Symfony\Component\Form\FormEvent;
use Symfony\Component\Form\FormEvents;
use Symfony\Component\Form\FormInterface;
@@ -146,7 +146,7 @@ private function getFileUploadError(int $errorCode)
$messageParameters = [];
if (\UPLOAD_ERR_INI_SIZE === $errorCode) {
- list($limitAsString, $suffix) = $this->factorizeSizes(0, self::getMaxFilesize());
+ [$limitAsString, $suffix] = $this->factorizeSizes(0, self::getMaxFilesize());
$messageTemplate = 'The file is too large. Allowed maximum size is {{ limit }} {{ suffix }}.';
$messageParameters = [
'{{ limit }}' => $limitAsString,
@@ -164,7 +164,7 @@ private function getFileUploadError(int $errorCode)
$message = strtr($messageTemplate, $messageParameters);
}
- return new FormError($message, $messageTemplate, $messageParameters);
+ return new FileUploadError($message, $messageTemplate, $messageParameters);
}
/**
diff --git a/src/Symfony/Component/Form/Extension/Core/Type/TextareaType.php b/src/Symfony/Component/Form/Extension/Core/Type/TextareaType.php
index 7db19d8aedc65..173b7ef53c8a2 100644
--- a/src/Symfony/Component/Form/Extension/Core/Type/TextareaType.php
+++ b/src/Symfony/Component/Form/Extension/Core/Type/TextareaType.php
@@ -23,6 +23,7 @@ class TextareaType extends AbstractType
public function buildView(FormView $view, FormInterface $form, array $options)
{
$view->vars['pattern'] = null;
+ unset($view->vars['attr']['pattern']);
}
/**
diff --git a/src/Symfony/Component/Form/Extension/Validator/Constraints/FormValidator.php b/src/Symfony/Component/Form/Extension/Validator/Constraints/FormValidator.php
index 1c63ecf5f4586..43eaeee4c829c 100644
--- a/src/Symfony/Component/Form/Extension/Validator/Constraints/FormValidator.php
+++ b/src/Symfony/Component/Form/Extension/Validator/Constraints/FormValidator.php
@@ -25,7 +25,6 @@
class FormValidator extends ConstraintValidator
{
private $resolvedGroups;
- private $fieldFormConstraints;
/**
* {@inheritdoc}
@@ -68,7 +67,6 @@ public function validate($form, Constraint $formConstraint)
if ($hasChildren && $form->isRoot()) {
$this->resolvedGroups = new \SplObjectStorage();
- $this->fieldFormConstraints = [];
}
if ($groups instanceof GroupSequence) {
@@ -93,7 +91,6 @@ public function validate($form, Constraint $formConstraint)
$this->resolvedGroups[$field] = (array) $group;
$fieldFormConstraint = new Form();
$fieldFormConstraint->groups = $group;
- $this->fieldFormConstraints[] = $fieldFormConstraint;
$this->context->setNode($this->context->getValue(), $field, $this->context->getMetadata(), $this->context->getPropertyPath());
$validator->atPath(sprintf('children[%s]', $field->getName()))->validate($field, $fieldFormConstraint, $group);
}
@@ -139,10 +136,8 @@ public function validate($form, Constraint $formConstraint)
foreach ($form->all() as $field) {
if ($field->isSubmitted()) {
$this->resolvedGroups[$field] = $groups;
- $fieldFormConstraint = new Form();
- $this->fieldFormConstraints[] = $fieldFormConstraint;
$this->context->setNode($this->context->getValue(), $field, $this->context->getMetadata(), $this->context->getPropertyPath());
- $validator->atPath(sprintf('children[%s]', $field->getName()))->validate($field, $fieldFormConstraint);
+ $validator->atPath(sprintf('children[%s]', $field->getName()))->validate($field, $formConstraint);
}
}
}
@@ -150,7 +145,6 @@ public function validate($form, Constraint $formConstraint)
if ($hasChildren && $form->isRoot()) {
// destroy storage to avoid memory leaks
$this->resolvedGroups = new \SplObjectStorage();
- $this->fieldFormConstraints = [];
}
} elseif (!$form->isSynchronized()) {
$childrenSynchronized = true;
@@ -159,11 +153,8 @@ public function validate($form, Constraint $formConstraint)
foreach ($form as $child) {
if (!$child->isSynchronized()) {
$childrenSynchronized = false;
-
- $fieldFormConstraint = new Form();
- $this->fieldFormConstraints[] = $fieldFormConstraint;
$this->context->setNode($this->context->getValue(), $child, $this->context->getMetadata(), $this->context->getPropertyPath());
- $validator->atPath(sprintf('children[%s]', $child->getName()))->validate($child, $fieldFormConstraint);
+ $validator->atPath(sprintf('children[%s]', $child->getName()))->validate($child, $formConstraint);
}
}
diff --git a/src/Symfony/Component/Form/Extension/Validator/ViolationMapper/ViolationMapper.php b/src/Symfony/Component/Form/Extension/Validator/ViolationMapper/ViolationMapper.php
index 12abef214bd76..c713ba2977383 100644
--- a/src/Symfony/Component/Form/Extension/Validator/ViolationMapper/ViolationMapper.php
+++ b/src/Symfony/Component/Form/Extension/Validator/ViolationMapper/ViolationMapper.php
@@ -11,12 +11,14 @@
namespace Symfony\Component\Form\Extension\Validator\ViolationMapper;
+use Symfony\Component\Form\FileUploadError;
use Symfony\Component\Form\FormError;
use Symfony\Component\Form\FormInterface;
use Symfony\Component\Form\Util\InheritDataAwareIterator;
use Symfony\Component\PropertyAccess\PropertyPathBuilder;
use Symfony\Component\PropertyAccess\PropertyPathIterator;
use Symfony\Component\PropertyAccess\PropertyPathIteratorInterface;
+use Symfony\Component\Validator\Constraints\File;
use Symfony\Component\Validator\ConstraintViolation;
/**
@@ -124,6 +126,23 @@ public function mapViolation(ConstraintViolation $violation, FormInterface $form
// Only add the error if the form is synchronized
if ($this->acceptsErrors($scope)) {
+ if ($violation->getConstraint() instanceof File && (string) \UPLOAD_ERR_INI_SIZE === $violation->getCode()) {
+ $errorsTarget = $scope;
+
+ while (null !== $errorsTarget->getParent() && $errorsTarget->getConfig()->getErrorBubbling()) {
+ $errorsTarget = $errorsTarget->getParent();
+ }
+
+ $errors = $errorsTarget->getErrors();
+ $errorsTarget->clearErrors();
+
+ foreach ($errors as $error) {
+ if (!$error instanceof FileUploadError) {
+ $errorsTarget->addError($error);
+ }
+ }
+ }
+
$scope->addError(new FormError(
$violation->getMessage(),
$violation->getMessageTemplate(),
diff --git a/src/Symfony/Component/Form/FileUploadError.php b/src/Symfony/Component/Form/FileUploadError.php
new file mode 100644
index 0000000000000..20142b20337ea
--- /dev/null
+++ b/src/Symfony/Component/Form/FileUploadError.php
@@ -0,0 +1,19 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Form;
+
+/**
+ * @internal
+ */
+class FileUploadError extends FormError
+{
+}
diff --git a/src/Symfony/Component/Form/FormBuilder.php b/src/Symfony/Component/Form/FormBuilder.php
index 53fbcb51963c2..8c92046ee3590 100644
--- a/src/Symfony/Component/Form/FormBuilder.php
+++ b/src/Symfony/Component/Form/FormBuilder.php
@@ -228,7 +228,7 @@ public function getIterator()
*/
private function resolveChild(string $name): FormBuilderInterface
{
- list($type, $options) = $this->unresolvedChildren[$name];
+ [$type, $options] = $this->unresolvedChildren[$name];
unset($this->unresolvedChildren[$name]);
diff --git a/src/Symfony/Component/Form/Resources/translations/validators.af.xlf b/src/Symfony/Component/Form/Resources/translations/validators.af.xlf
new file mode 100644
index 0000000000000..58cd939cf793f
--- /dev/null
+++ b/src/Symfony/Component/Form/Resources/translations/validators.af.xlf
@@ -0,0 +1,139 @@
+
+
+
+
+
+ This form should not contain extra fields.
+ Hierdie vorm moet nie ekstra velde bevat nie.
+
+
+ The uploaded file was too large. Please try to upload a smaller file.
+ Die opgelaaide lêer was te groot. Probeer asseblief 'n kleiner lêer.
+
+
+ The CSRF token is invalid. Please try to resubmit the form.
+ Die CSRF-teken is ongeldig. Probeer asseblief om die vorm weer in te dien.
+
+
+ This value is not a valid HTML5 color.
+ Hierdie waarde is nie 'n geldige HTML5 kleur nie.
+
+
+ Please enter a valid birthdate.
+ Voer asseblief 'n geldige geboortedatum in.
+
+
+ The selected choice is invalid.
+ Die gekiesde opsie is nie geldig nie.
+
+
+ The collection is invalid.
+ Die versameling is nie geldig nie.
+
+
+ Please select a valid color.
+ Kies asseblief 'n geldige kleur.
+
+
+ Please select a valid country.
+ Kies asseblief 'n geldige land.
+
+
+ Please select a valid currency.
+ Kies asseblief 'n geldige geldeenheid.
+
+
+ Please choose a valid date interval.
+ Kies asseblief 'n geldige datum interval.
+
+
+ Please enter a valid date and time.
+ Voer asseblilef 'n geldige datum en tyd in.
+
+
+ Please enter a valid date.
+ Voer asseblief 'n geldige datum in.
+
+
+ Please select a valid file.
+ Kies asseblief 'n geldige lêer.
+
+
+ The hidden field is invalid.
+ Die versteekte veld is nie geldig nie.
+
+
+ Please enter an integer.
+ Voer asseblief 'n geldige heeltal in.
+
+
+ Please select a valid language.
+ Kies assblief 'n geldige taal.
+
+
+ Please select a valid locale.
+ Voer assebliefn 'n geldige locale in.
+
+
+ Please enter a valid money amount.
+ Voer asseblief 'n geldige bedrag in.
+
+
+ Please enter a number.
+ Voer asseblief 'n nommer in.
+
+
+ The password is invalid.
+ Die wagwoord is ongeldig.
+
+
+ Please enter a percentage value.
+ Voer asseblief 'n geldige persentasie waarde in.
+
+
+ The values do not match.
+ Die waardes is nie dieselfde nie.
+
+
+ Please enter a valid time.
+ Voer asseblief 'n geldige tyd in time.
+
+
+ Please select a valid timezone.
+ Kies asseblief 'n geldige tydsone.
+
+
+ Please enter a valid URL.
+ Voer asseblief 'n geldige URL in.
+
+
+ Please enter a valid search term.
+ Voer asseblief 'n geldige soek term in.
+
+
+ Please provide a valid phone number.
+ Verskaf asseblief 'n geldige telefoonnommer.
+
+
+ The checkbox has an invalid value.
+ Die blokkie het 'n ongeldige waarde.
+
+
+ Please enter a valid email address.
+ Voer asseblief 'n geldige e-pos adres in.
+
+
+ Please select a valid option.
+ Kies asseblief 'n geldige opsie.
+
+
+ Please select a valid range.
+ Kies asseblief 'n geldige reeks.
+
+
+ Please enter a valid week.
+ Voer assblief 'n geldige week in.
+
+
+
+
diff --git a/src/Symfony/Component/Form/Resources/translations/validators.az.xlf b/src/Symfony/Component/Form/Resources/translations/validators.az.xlf
index 69e447385acda..b9269706db3e8 100644
--- a/src/Symfony/Component/Form/Resources/translations/validators.az.xlf
+++ b/src/Symfony/Component/Form/Resources/translations/validators.az.xlf
@@ -14,6 +14,126 @@
The CSRF token is invalid. Please try to resubmit the form.CSRF nişanı yanlışdır. Lütfen formanı yenidən göndərin.
+
+ This value is not a valid HTML5 color.
+ Bu dəyər doğru bir HTML5 rəngi deyil.
+
+
+ Please enter a valid birthdate.
+ Zəhmət olmasa doğru bir doğum günü daxil edin.
+
+
+ The selected choice is invalid.
+ Seçilmiş seçim doğru deyil.
+
+
+ The collection is invalid.
+ Kolleksiya doğru deyil.
+
+
+ Please select a valid color.
+ Zəhmət olmasa doğru bir rəng seçin.
+
+
+ Please select a valid country.
+ Zəhmət olmasa doğru bir ölkə seçin.
+
+
+ Please select a valid currency.
+ Zəhmət olmasa doğru bir valyuta seçin.
+
+
+ Please choose a valid date interval.
+ Zəhmət olmasa doğru bir tarix aralığı seçin.
+
+
+ Please enter a valid date and time.
+ Zəhmət olmasa doğru bir tarix ve saat daxil edin.
+
+
+ Please enter a valid date.
+ Zəhmət olmasa doğru bir tarix daxil edin.
+
+
+ Please select a valid file.
+ Zəhmət olmasa doğru bir fayl seçin.
+
+
+ The hidden field is invalid.
+ Gizli sahə doğru deyil.
+
+
+ Please enter an integer.
+ Zəhmət olmasa bir tam ədəd daxil edin.
+
+
+ Please select a valid language.
+ Zəhmət olmasa doğru bir dil seçin.
+
+
+ Please select a valid locale.
+ Zəhmət olmasa doğru bir yer seçin.
+
+
+ Please enter a valid money amount.
+ Zəhmət olmasa doğru bir pul miqdarı daxil edin.
+
+
+ Please enter a number.
+ Zəhmət olmasa doğru bir rəqəm daxil edin.
+
+
+ The password is invalid.
+ Parol doğru deyil.
+
+
+ Please enter a percentage value.
+ Zəhmət olmasa doğru bir faiz dəyəri daxil edin.
+
+
+ The values do not match.
+ Dəyərlər örtüşmür.
+
+
+ Please enter a valid time.
+ Zəhmət olmasa doğru bir saat daxil edin.
+
+
+ Please select a valid timezone.
+ Zəhmət olmasa doğru bir saat qurşağı seçin.
+
+
+ Please enter a valid URL.
+ Zəhmət olmasa doğru bir URL daxil edin.
+
+
+ Please enter a valid search term.
+ Zəhmət olmasa doğru bir axtarış termini daxil edin.
+
+
+ Please provide a valid phone number.
+ Zəhmət olmasa doğru bir telefon nömrəsi seçin.
+
+
+ The checkbox has an invalid value.
+ Seçim qutusunda doğru olmayan dəyər var.
+
+
+ Please enter a valid email address.
+ Zəhmət olmasa doğru bir e-poçt seçin.
+
+
+ Please select a valid option.
+ Zəhmət olmasa doğru bir variant seçin.
+
+
+ Please select a valid range.
+ Zəhmət olmasa doğru bir aralıq seçin.
+
+
+ Please enter a valid week.
+ Zəhmət olmasa doğru bir həftə seçin.
+
This form should not contain extra fields.
- Este formulário não deveria conter campos extra.
+ Este formulário não deveria possuir mais campos.The uploaded file was too large. Please try to upload a smaller file.
- O arquivo enviado é muito grande. Por favor, tente enviar um ficheiro mais pequeno.
+ O ficheiro enviado é muito grande. Por favor, tente enviar um ficheiro menor.The CSRF token is invalid. Please try to resubmit the form.
- O token CSRF é inválido. Por favor submeta o formulário novamente.
+ O token CSRF está inválido. Por favor, tente enviar o formulário novamente.
+
+
+ This value is not a valid HTML5 color.
+ Este valor não é uma cor HTML5 válida.
+
+
+ Please enter a valid birthdate.
+ Por favor, informe uma data de nascimento válida.
+
+
+ The selected choice is invalid.
+ A escolha seleccionada é inválida.
+
+
+ The collection is invalid.
+ A coleção é inválida.
+
+
+ Please select a valid color.
+ Por favor, selecione uma cor válida.
+
+
+ Please select a valid country.
+ Por favor, selecione um país válido.
+
+
+ Please select a valid currency.
+ Por favor, selecione uma moeda válida.
+
+
+ Please choose a valid date interval.
+ Por favor, escolha um intervalo de datas válido.
+
+
+ Please enter a valid date and time.
+ Por favor, informe uma data e horário válidos.
+
+
+ Please enter a valid date.
+ Por favor, informe uma data válida.
+
+
+ Please select a valid file.
+ Por favor, selecione um ficheiro válido.
+
+
+ The hidden field is invalid.
+ O campo oculto é inválido.
+
+
+ Please enter an integer.
+ Por favor, informe um inteiro.
+
+
+ Please select a valid language.
+ Por favor selecione um idioma válido.
+
+
+ Please select a valid locale.
+ Por favor, selecione um locale válido.
+
+
+ Please enter a valid money amount.
+ Por favor, informe um valor monetário válido.
+
+
+ Please enter a number.
+ Por favor, informe um número.
+
+
+ The password is invalid.
+ A palavra-passe é inválida.
+
+
+ Please enter a percentage value.
+ Por favor, informe um valor percentual.
+
+
+ The values do not match.
+ Os valores não correspondem.
+
+
+ Please enter a valid time.
+ Por favor, informe uma hora válida.
+
+
+ Please select a valid timezone.
+ Por favor, selecione um fuso horário válido.
+
+
+ Please enter a valid URL.
+ Por favor, informe uma URL válida.
+
+
+ Please enter a valid search term.
+ Por favor, informe um termo de busca válido.
+
+
+ Please provide a valid phone number.
+ Por favor, infome um número de telefone válido.
+
+
+ The checkbox has an invalid value.
+ O checkbox possui um valor inválido.
+
+
+ Please enter a valid email address.
+ Por favor, informe um endereço de email válido.
+
+
+ Please select a valid option.
+ Por favor, selecione uma opção válida.
+
+
+ Please select a valid range.
+ Por favor, selecione um intervalo válido.
+
+
+ Please enter a valid week.
+ Por favor, selecione uma semana válida.This form should not contain extra fields.
- Aceast formular nu ar trebui să conțină câmpuri suplimentare.
+ Acest formular nu ar trebui să conțină câmpuri suplimentare.The uploaded file was too large. Please try to upload a smaller file.
@@ -12,8 +12,128 @@
The CSRF token is invalid. Please try to resubmit the form.
- Token-ul CSRF este invalid. Vă rugăm să trimiteți formularul incă o dată.
+ Token-ul CSRF este invalid. Vă rugăm să retrimiteți formularul.
+
+
+ This value is not a valid HTML5 color.
+ Această valoare nu este un cod de culoare HTML5 valid.
+
+
+ Please enter a valid birthdate.
+ Vă rugăm să introduceți o dată de naștere validă.
+
+
+ The selected choice is invalid.
+ Valoarea selectată este invalidă.
+
+
+ The collection is invalid.
+ Colecția nu este validă.
+
+
+ Please select a valid color.
+ Vă rugăm să selectați o culoare validă.
+
+
+ Please select a valid country.
+ Vă rugăm să selectați o țară validă.
+
+
+ Please select a valid currency.
+ Vă rugăm să selectați o monedă validă.
+
+
+ Please choose a valid date interval.
+ Vă rugăm să selectați un interval de zile valid.
+
+
+ Please enter a valid date and time.
+ Vă rugăm să introduceți o dată și o oră validă.
+
+
+ Please enter a valid date.
+ Vă rugăm să introduceți o dată validă.
+
+
+ Please select a valid file.
+ Vă rugăm să selectați un fișier valid.
+
+
+ The hidden field is invalid.
+ Câmpul ascuns este invalid.
+
+
+ Please enter an integer.
+ Vă rugăm să introduceți un număr întreg.
+
+
+ Please select a valid language.
+ Vă rugăm să selectați o limbă validă.
+
+
+ Please select a valid locale.
+ Vă rugăm să selectați o setare locală validă.
+
+
+ Please enter a valid money amount.
+ Vă rugăm să introduceți o valoare monetară corectă.
+
+
+ Please enter a number.
+ Vă rugăm să introduceți un număr.
+
+
+ The password is invalid.
+ Parola nu este validă.
+
+
+ Please enter a percentage value.
+ Vă rugăm să introduceți o valoare procentuală.
+
+
+ The values do not match.
+ Valorile nu coincid.
+
+
+ Please enter a valid time.
+ Vă rugăm să introduceți o oră validă.
+
+
+ Please select a valid timezone.
+ Vă rugăm să selectați un fus orar valid.
+
+
+ Please enter a valid URL.
+ Vă rugăm să introduceți un URL valid.
+
+
+ Please enter a valid search term.
+ Vă rugăm să introduceți un termen de căutare valid.
+
+
+ Please provide a valid phone number.
+ Vă rugăm să introduceți un număr de telefon valid.
+
+
+ The checkbox has an invalid value.
+ Bifa nu are o valoare validă.
+
+
+ Please enter a valid email address.
+ Vă rugăm să introduceți o adresă de email validă.
+
+
+ Please select a valid option.
+ Vă rugăm să selectați o opțiune validă.
+
+
+ Please select a valid range.
+ Vă rugăm să selectați un interval valid.
+
+
+ Please enter a valid week.
+ Vă rugăm să introduceți o săptămână validă.