Merge branch '4.4' into 5.0

* 4.4:
  Fix versions
  [Security/Http] Allow setting cookie security settings for delete_cookies
  [DI] fix generating TypedReference from PriorityTaggedServiceTrait
  [FrameworkBundle] revert to legacy wiring of the session when circular refs are detected
  bumped Symfony version to 3.4.40
  updated VERSION for 3.4.39
  update CONTRIBUTORS for 3.4.39
  updated CHANGELOG for 3.4.39
  [DomCrawler] Fix BC break in assertions breaking Panther
  [BrowserKit] fixed missing post request parameters in file uploads
  update Italian translation
  [Validator] Add missing Hungarian translations
  [Validator] Add the missing translations for the Arabic (ar) locale
  [Validator] Add missing vietnamese translations
  [Console] Fix OutputStream for PHP 7.4
  add German translations
  bug #36157 [Validator] Assert Valid with many groups
  [Validator] Add missing Lithuanian translations
  Fixed some typos
  Add french "at least" constraint translations
This commit is contained in:
Nicolas Grekas 2020-03-30 13:42:42 +02:00
commit 6b0ad43856
31 changed files with 334 additions and 63 deletions

View File

@ -16,27 +16,27 @@ Symfony is the result of the work of many people who made the code better
- Victor Berchet (victor) - Victor Berchet (victor)
- Maxime Steinhausser (ogizanagi) - Maxime Steinhausser (ogizanagi)
- Ryan Weaver (weaverryan) - Ryan Weaver (weaverryan)
- Javier Eguiluz (javier.eguiluz)
- Grégoire Pineau (lyrixx) - Grégoire Pineau (lyrixx)
- Jakub Zalas (jakubzalas) - Javier Eguiluz (javier.eguiluz)
- Roland Franssen (ro0) - Roland Franssen (ro0)
- Jakub Zalas (jakubzalas)
- Johannes S (johannes) - Johannes S (johannes)
- Kris Wallsmith (kriswallsmith) - Kris Wallsmith (kriswallsmith)
- Yonel Ceruto (yonelceruto) - Yonel Ceruto (yonelceruto)
- Hugo Hamon (hhamon) - Hugo Hamon (hhamon)
- Abdellatif Ait boudad (aitboudad) - Abdellatif Ait boudad (aitboudad)
- Samuel ROZE (sroze) - Samuel ROZE (sroze)
- Romain Neutron (romain)
- Wouter de Jong (wouterj)
- Pascal Borreli (pborreli)
- Thomas Calvet (fancyweb) - Thomas Calvet (fancyweb)
- Wouter de Jong (wouterj)
- Romain Neutron (romain)
- Pascal Borreli (pborreli)
- Joseph Bielawski (stloyd) - Joseph Bielawski (stloyd)
- Alexander M. Turek (derrabus) - Alexander M. Turek (derrabus)
- Karma Dordrak (drak) - Karma Dordrak (drak)
- Lukas Kahwe Smith (lsmith) - Lukas Kahwe Smith (lsmith)
- Martin Hasoň (hason)
- Hamza Amrouche (simperfit)
- Jules Pietri (heah) - Jules Pietri (heah)
- Hamza Amrouche (simperfit)
- Martin Hasoň (hason)
- Jeremy Mikola (jmikola) - Jeremy Mikola (jmikola)
- Jérémy DERUSSÉ (jderusse) - Jérémy DERUSSÉ (jderusse)
- Jean-François Simon (jfsimon) - Jean-François Simon (jfsimon)
@ -66,17 +66,17 @@ Symfony is the result of the work of many people who made the code better
- Saša Stamenković (umpirsky) - Saša Stamenković (umpirsky)
- Peter Rehm (rpet) - Peter Rehm (rpet)
- Henrik Bjørnskov (henrikbjorn) - Henrik Bjørnskov (henrikbjorn)
- Miha Vrhovnik
- Gabriel Ostrolucký (gadelat) - Gabriel Ostrolucký (gadelat)
- Miha Vrhovnik
- David Maicher (dmaicher)
- Diego Saint Esteben (dii3g0) - Diego Saint Esteben (dii3g0)
- Gábor Egyed (1ed) - Gábor Egyed (1ed)
- Titouan Galopin (tgalopin) - Titouan Galopin (tgalopin)
- David Maicher (dmaicher) - Jan Schädlich (jschaedl)
- Konstantin Kudryashov (everzet) - Konstantin Kudryashov (everzet)
- Bilal Amarni (bamarni) - Bilal Amarni (bamarni)
- Mathieu Piot (mpiot) - Mathieu Piot (mpiot)
- Vladimir Reznichenko (kalessil) - Vladimir Reznichenko (kalessil)
- Jan Schädlich (jschaedl)
- Florin Patan (florinpatan) - Florin Patan (florinpatan)
- Jáchym Toušek (enumag) - Jáchym Toušek (enumag)
- Andrej Hudec (pulzarraider) - Andrej Hudec (pulzarraider)
@ -136,6 +136,7 @@ Symfony is the result of the work of many people who made the code better
- Joel Wurtz (brouznouf) - Joel Wurtz (brouznouf)
- Fabien Pennequin (fabienpennequin) - Fabien Pennequin (fabienpennequin)
- Théo FIDRY (theofidry) - Théo FIDRY (theofidry)
- Przemysław Bogusz (przemyslaw-bogusz)
- Eric GELOEN (gelo) - Eric GELOEN (gelo)
- Lars Strojny (lstrojny) - Lars Strojny (lstrojny)
- Jannik Zschiesche (apfelbox) - Jannik Zschiesche (apfelbox)
@ -155,6 +156,7 @@ Symfony is the result of the work of many people who made the code better
- Sebastian Hörl (blogsh) - Sebastian Hörl (blogsh)
- Daniel Gomes (danielcsgomes) - Daniel Gomes (danielcsgomes)
- Hidenori Goto (hidenorigoto) - Hidenori Goto (hidenorigoto)
- Alessandro Chitolina (alekitto)
- Andréia Bohner (andreia) - Andréia Bohner (andreia)
- Yanick Witschi (toflar) - Yanick Witschi (toflar)
- Arnaud Kleinpeter (nanocom) - Arnaud Kleinpeter (nanocom)
@ -164,7 +166,6 @@ Symfony is the result of the work of many people who made the code better
- Jérémie Augustin (jaugustin) - Jérémie Augustin (jaugustin)
- François-Xavier de Guillebon (de-gui_f) - François-Xavier de Guillebon (de-gui_f)
- Oleg Voronkovich - Oleg Voronkovich
- Alessandro Chitolina (alekitto)
- Philipp Wahala (hifi) - Philipp Wahala (hifi)
- Rafael Dohms (rdohms) - Rafael Dohms (rdohms)
- jwdeitch - jwdeitch
@ -239,8 +240,10 @@ Symfony is the result of the work of many people who made the code better
- fivestar - fivestar
- Dominique Bongiraud - Dominique Bongiraud
- Jeremy Livingston (jeremylivingston) - Jeremy Livingston (jeremylivingston)
- Laurent VOULLEMIER (lvo)
- Michael Lee (zerustech) - Michael Lee (zerustech)
- Matthieu Auger (matthieuauger) - Matthieu Auger (matthieuauger)
- Ahmed TAILOULOUTE (ahmedtai)
- Leszek Prabucki (l3l0) - Leszek Prabucki (l3l0)
- Fabien Bourigault (fbourigault) - Fabien Bourigault (fbourigault)
- François Zaninotto (fzaninotto) - François Zaninotto (fzaninotto)
@ -248,7 +251,6 @@ Symfony is the result of the work of many people who made the code better
- jeff - jeff
- John Kary (johnkary) - John Kary (johnkary)
- Jan Rosier (rosier) - Jan Rosier (rosier)
- Przemysław Bogusz (przemyslaw-bogusz)
- Justin Hileman (bobthecow) - Justin Hileman (bobthecow)
- Blanchon Vincent (blanchonvincent) - Blanchon Vincent (blanchonvincent)
- Michele Orselli (orso) - Michele Orselli (orso)
@ -280,7 +282,6 @@ Symfony is the result of the work of many people who made the code better
- julien pauli (jpauli) - julien pauli (jpauli)
- Lorenz Schori - Lorenz Schori
- Sébastien Lavoie (lavoiesl) - Sébastien Lavoie (lavoiesl)
- Ahmed TAILOULOUTE (ahmedtai)
- Dariusz - Dariusz
- Saif (╯°□°)╯ (azjezz) - Saif (╯°□°)╯ (azjezz)
- Dmitrii Poddubnyi (karser) - Dmitrii Poddubnyi (karser)
@ -306,6 +307,7 @@ Symfony is the result of the work of many people who made the code better
- Arjen Brouwer (arjenjb) - Arjen Brouwer (arjenjb)
- Katsuhiro OGAWA - Katsuhiro OGAWA
- Patrick McDougle (patrick-mcdougle) - Patrick McDougle (patrick-mcdougle)
- Guillaume Pédelagrabe
- Alif Rachmawadi - Alif Rachmawadi
- Anton Chernikov (anton_ch1989) - Anton Chernikov (anton_ch1989)
- Kristen Gilden (kgilden) - Kristen Gilden (kgilden)
@ -336,6 +338,7 @@ Symfony is the result of the work of many people who made the code better
- Wodor Wodorski - Wodor Wodorski
- Thomas Lallement (raziel057) - Thomas Lallement (raziel057)
- Colin O'Dell (colinodell) - Colin O'Dell (colinodell)
- Mathias Arlaud (mtarld)
- Giorgio Premi - Giorgio Premi
- renanbr - renanbr
- Alex Rock (pierstoval) - Alex Rock (pierstoval)
@ -398,13 +401,11 @@ Symfony is the result of the work of many people who made the code better
- Emanuele Gaspari (inmarelibero) - Emanuele Gaspari (inmarelibero)
- Dariusz Rumiński - Dariusz Rumiński
- Berny Cantos (xphere81) - Berny Cantos (xphere81)
- Laurent VOULLEMIER (lvo)
- Thierry Thuon (lepiaf) - Thierry Thuon (lepiaf)
- Ricard Clau (ricardclau) - Ricard Clau (ricardclau)
- Mark Challoner (markchalloner) - Mark Challoner (markchalloner)
- Philippe Segatori - Philippe Segatori
- Gennady Telegin (gtelegin) - Gennady Telegin (gtelegin)
- Mathias Arlaud (mtarld)
- Erin Millard - Erin Millard
- Artur Melo (restless) - Artur Melo (restless)
- Matthew Lewinski (lewinski) - Matthew Lewinski (lewinski)
@ -433,6 +434,7 @@ Symfony is the result of the work of many people who made the code better
- Eric Masoero (eric-masoero) - Eric Masoero (eric-masoero)
- Denis Brumann (dbrumann) - Denis Brumann (dbrumann)
- JhonnyL - JhonnyL
- Haralan Dobrev (hkdobrev)
- hossein zolfi (ocean) - hossein zolfi (ocean)
- Clément Gautier (clementgautier) - Clément Gautier (clementgautier)
- Bastien Jaillot (bastnic) - Bastien Jaillot (bastnic)
@ -486,6 +488,7 @@ Symfony is the result of the work of many people who made the code better
- Xavier HAUSHERR - Xavier HAUSHERR
- Albert Jessurum (ajessu) - Albert Jessurum (ajessu)
- Laszlo Korte - Laszlo Korte
- Jesse Rushlow (geeshoe)
- Miha Vrhovnik - Miha Vrhovnik
- Alessandro Desantis - Alessandro Desantis
- hubert lecorche (hlecorche) - hubert lecorche (hlecorche)
@ -561,6 +564,7 @@ Symfony is the result of the work of many people who made the code better
- Gintautas Miselis - Gintautas Miselis
- Rob Bast - Rob Bast
- Roberto Espinoza (respinoza) - Roberto Espinoza (respinoza)
- HypeMC
- Soufian EZ-ZANTAR (soezz) - Soufian EZ-ZANTAR (soezz)
- Zander Baldwin - Zander Baldwin
- Gocha Ossinkine (ossinkine) - Gocha Ossinkine (ossinkine)
@ -586,7 +590,6 @@ Symfony is the result of the work of many people who made the code better
- Yoshio HANAWA - Yoshio HANAWA
- Jan van Thoor (janvt) - Jan van Thoor (janvt)
- Gladhon - Gladhon
- Haralan Dobrev (hkdobrev)
- Sebastian Bergmann - Sebastian Bergmann
- Miroslav Sustek - Miroslav Sustek
- Pablo Díez (pablodip) - Pablo Díez (pablodip)
@ -716,6 +719,7 @@ Symfony is the result of the work of many people who made the code better
- Stéphane Escandell (sescandell) - Stéphane Escandell (sescandell)
- Konstantin S. M. Möllers (ksmmoellers) - Konstantin S. M. Möllers (ksmmoellers)
- James Johnston - James Johnston
- Noémi Salaün (noemi-salaun)
- Sinan Eldem - Sinan Eldem
- BoShurik - BoShurik
- Alexandre Dupuy (satchette) - Alexandre Dupuy (satchette)
@ -732,6 +736,7 @@ Symfony is the result of the work of many people who made the code better
- Stefan Gehrig (sgehrig) - Stefan Gehrig (sgehrig)
- Hany el-Kerdany - Hany el-Kerdany
- Wang Jingyu - Wang Jingyu
- Langlet Vincent (deviling)
- Åsmund Garfors - Åsmund Garfors
- Gunnstein Lye (glye) - Gunnstein Lye (glye)
- Maxime Douailin - Maxime Douailin
@ -802,7 +807,6 @@ Symfony is the result of the work of many people who made the code better
- Simon Schick (simonsimcity) - Simon Schick (simonsimcity)
- redstar504 - redstar504
- Tristan Roussel - Tristan Roussel
- HypeMC
- Cameron Porter - Cameron Porter
- Hossein Bukhamsin - Hossein Bukhamsin
- Oliver Hoff - Oliver Hoff
@ -835,6 +839,7 @@ Symfony is the result of the work of many people who made the code better
- Richard Quadling - Richard Quadling
- Raphaëll Roussel - Raphaëll Roussel
- Michael Lutz - Michael Lutz
- Koen Reiniers (koenre)
- jochenvdv - jochenvdv
- Reedy - Reedy
- Arturas Smorgun (asarturas) - Arturas Smorgun (asarturas)
@ -883,6 +888,7 @@ Symfony is the result of the work of many people who made the code better
- Dennis Hotson - Dennis Hotson
- Andrew Tchircoff (andrewtch) - Andrew Tchircoff (andrewtch)
- michaelwilliams - michaelwilliams
- Martin Kirilov
- 1emming - 1emming
- Nykopol (nykopol) - Nykopol (nykopol)
- Tri Pham (phamuyentri) - Tri Pham (phamuyentri)
@ -951,9 +957,11 @@ Symfony is the result of the work of many people who made the code better
- Roy Klutman (royklutman) - Roy Klutman (royklutman)
- Sofiane HADDAG (sofhad) - Sofiane HADDAG (sofhad)
- frost-nzcr4 - frost-nzcr4
- arai
- Laurent Bassin (lbassin) - Laurent Bassin (lbassin)
- andrey1s - andrey1s
- Abhoryo - Abhoryo
- Daniel STANCU
- Fabian Vogler (fabian) - Fabian Vogler (fabian)
- Korvin Szanto - Korvin Szanto
- soyuka - soyuka
@ -1003,13 +1011,13 @@ Symfony is the result of the work of many people who made the code better
- Shin Ohno (ganchiku) - Shin Ohno (ganchiku)
- Geert De Deckere (geertdd) - Geert De Deckere (geertdd)
- Jan Kramer (jankramer) - Jan Kramer (jankramer)
- Matthieu Mota (matthieumota)
- abdul malik ikhsan (samsonasik) - abdul malik ikhsan (samsonasik)
- Henry Snoek (snoek09) - Henry Snoek (snoek09)
- Jérémy M (th3mouk) - Jérémy M (th3mouk)
- Simone Di Maulo (toretto460) - Simone Di Maulo (toretto460)
- Christian Morgan - Christian Morgan
- Alexander Miehe (engerim) - Alexander Miehe (engerim)
- Jesse Rushlow (geeshoe)
- Morgan Auchede (mauchede) - Morgan Auchede (mauchede)
- Sascha Dens (saschadens) - Sascha Dens (saschadens)
- Don Pinkster - Don Pinkster
@ -1037,6 +1045,7 @@ Symfony is the result of the work of many people who made the code better
- Marcos Gómez Vilches (markitosgv) - Marcos Gómez Vilches (markitosgv)
- Matthew Davis (mdavis1982) - Matthew Davis (mdavis1982)
- Markus S. (staabm) - Markus S. (staabm)
- Benjamin Morel
- Maks - Maks
- Antoine LA - Antoine LA
- den - den
@ -1228,6 +1237,7 @@ Symfony is the result of the work of many people who made the code better
- Benjamin Paap (benjaminpaap) - Benjamin Paap (benjaminpaap)
- Claus Due (namelesscoder) - Claus Due (namelesscoder)
- Christian - Christian
- William Arslett
- Denis Golubovskiy (bukashk0zzz) - Denis Golubovskiy (bukashk0zzz)
- Sergii Smertin (nfx) - Sergii Smertin (nfx)
- Mikkel Paulson - Mikkel Paulson
@ -1309,6 +1319,7 @@ Symfony is the result of the work of many people who made the code better
- BRAMILLE Sébastien (oktapodia) - BRAMILLE Sébastien (oktapodia)
- Artem Kolesnikov (tyomo4ka) - Artem Kolesnikov (tyomo4ka)
- Gustavo Adrian - Gustavo Adrian
- Jorrit Schippers (jorrit)
- Yannick - Yannick
- Vladimir Luchaninov (luchaninov) - Vladimir Luchaninov (luchaninov)
- spdionis - spdionis
@ -1346,7 +1357,6 @@ Symfony is the result of the work of many people who made the code better
- Oxan van Leeuwen - Oxan van Leeuwen
- pkowalczyk - pkowalczyk
- Soner Sayakci - Soner Sayakci
- Koen Reiniers (koenre)
- Max Voloshin (maxvoloshin) - Max Voloshin (maxvoloshin)
- Nicolas Fabre (nfabre) - Nicolas Fabre (nfabre)
- Raul Rodriguez (raul782) - Raul Rodriguez (raul782)
@ -1593,6 +1603,7 @@ Symfony is the result of the work of many people who made the code better
- Felipy Tavares Amorim (felipyamorim) - Felipy Tavares Amorim (felipyamorim)
- Guillaume Loulier (guikingone) - Guillaume Loulier (guikingone)
- Klaus Silveira (klaussilveira) - Klaus Silveira (klaussilveira)
- Pierre Grimaud (pgrimaud)
- Thomas Chmielowiec (chmielot) - Thomas Chmielowiec (chmielot)
- Jānis Lukss - Jānis Lukss
- rkerner - rkerner
@ -1645,7 +1656,9 @@ Symfony is the result of the work of many people who made the code better
- Mephistofeles - Mephistofeles
- Hoffmann András - Hoffmann András
- LubenZA - LubenZA
- Victor Garcia
- Olivier - Olivier
- Denis Yuzhanin
- knezmilos13 - knezmilos13
- Cyril PASCAL - Cyril PASCAL
- Michael Bessolov - Michael Bessolov
@ -1732,6 +1745,7 @@ Symfony is the result of the work of many people who made the code better
- Stefan Hüsges (tronsha) - Stefan Hüsges (tronsha)
- Jake Bishop (yakobeyak) - Jake Bishop (yakobeyak)
- Dan Blows - Dan Blows
- popnikos
- Matt Wells - Matt Wells
- Sander van der Vlugt - Sander van der Vlugt
- Nicolas Appriou - Nicolas Appriou
@ -1828,6 +1842,7 @@ Symfony is the result of the work of many people who made the code better
- Aarón Nieves Fernández - Aarón Nieves Fernández
- Mike Meier - Mike Meier
- Kirill Saksin - Kirill Saksin
- Reda DAOUDI
- Koalabaerchen - Koalabaerchen
- michalmarcinkowski - michalmarcinkowski
- Warwick - Warwick
@ -1873,7 +1888,6 @@ Symfony is the result of the work of many people who made the code better
- ged15 - ged15
- Daan van Renterghem - Daan van Renterghem
- Nicole Cordes - Nicole Cordes
- Martin Kirilov
- Bálint Szekeres - Bálint Szekeres
- amcastror - amcastror
- Alexander Li (aweelex) - Alexander Li (aweelex)
@ -2174,7 +2188,6 @@ Symfony is the result of the work of many people who made the code better
- Karolis - Karolis
- Myke79 - Myke79
- Brian Debuire - Brian Debuire
- Benjamin Morel
- Eric Grimois - Eric Grimois
- Piers Warmers - Piers Warmers
- Sylvain Lorinet - Sylvain Lorinet
@ -2240,7 +2253,6 @@ Symfony is the result of the work of many people who made the code better
- James Michael DuPont - James Michael DuPont
- Kasperki - Kasperki
- Tammy D - Tammy D
- Daniel STANCU
- Ryan Rud - Ryan Rud
- Ondrej Slinták - Ondrej Slinták
- vlechemin - vlechemin
@ -2267,6 +2279,7 @@ Symfony is the result of the work of many people who made the code better
- Abdulkadir N. A. - Abdulkadir N. A.
- Adam Klvač - Adam Klvač
- Bruno Nogueira Nascimento Wowk - Bruno Nogueira Nascimento Wowk
- jonmldr
- Yevgen Kovalienia - Yevgen Kovalienia
- Lebnik - Lebnik
- nsbx - nsbx
@ -2385,6 +2398,7 @@ Symfony is the result of the work of many people who made the code better
- Jose Manuel Gonzalez (jgonzalez) - Jose Manuel Gonzalez (jgonzalez)
- Joachim Krempel (jkrempel) - Joachim Krempel (jkrempel)
- Jorge Maiden (jorgemaiden) - Jorge Maiden (jorgemaiden)
- Joao Paulo V Martins (jpjoao)
- Justin Rainbow (jrainbow) - Justin Rainbow (jrainbow)
- Juan Luis (juanlugb) - Juan Luis (juanlugb)
- JuntaTom (juntatom) - JuntaTom (juntatom)
@ -2398,7 +2412,6 @@ Symfony is the result of the work of many people who made the code better
- Luís Cobucci (lcobucci) - Luís Cobucci (lcobucci)
- Jérémy (libertjeremy) - Jérémy (libertjeremy)
- Mehdi Achour (machour) - Mehdi Achour (machour)
- Matthieu Mota (matthieumota)
- Matthieu Moquet (mattketmo) - Matthieu Moquet (mattketmo)
- Moritz Borgmann (mborgmann) - Moritz Borgmann (mborgmann)
- Michal Čihař (mcihar) - Michal Čihař (mcihar)
@ -2442,6 +2455,7 @@ Symfony is the result of the work of many people who made the code better
- Markus Tacker (tacker) - Markus Tacker (tacker)
- Tom Newby (tomnewbyau) - Tom Newby (tomnewbyau)
- Andrew Clark (tqt_andrew_clark) - Andrew Clark (tqt_andrew_clark)
- Aaron Piotrowski (trowski)
- David Lumaye (tux1124) - David Lumaye (tux1124)
- Roman Tymoshyk (tymoshyk) - Roman Tymoshyk (tymoshyk)
- Tyler Stroud (tystr) - Tyler Stroud (tystr)

View File

@ -383,8 +383,8 @@ class XmlDescriptor extends Descriptor
} elseif (\is_array($argument)) { } elseif (\is_array($argument)) {
$argumentXML->setAttribute('type', 'collection'); $argumentXML->setAttribute('type', 'collection');
foreach ($this->getArgumentNodes($argument, $dom) as $childArgumenXML) { foreach ($this->getArgumentNodes($argument, $dom) as $childArgumentXML) {
$argumentXML->appendChild($childArgumenXML); $argumentXML->appendChild($childArgumentXML);
} }
} else { } else {
$argumentXML->appendChild(new \DOMText($argument)); $argumentXML->appendChild(new \DOMText($argument));

View File

@ -0,0 +1,50 @@
<?php
/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Symfony\Bundle\FrameworkBundle\DependencyInjection\Compiler;
use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\Reference;
/**
* @internal to be removed in 6.0
*/
class SessionPass implements CompilerPassInterface
{
public function process(ContainerBuilder $container)
{
if (!$container->hasDefinition('session')) {
return;
}
$bags = [
'session.flash_bag' => $container->hasDefinition('session.flash_bag') ? $container->getDefinition('session.flash_bag') : null,
'session.attribute_bag' => $container->hasDefinition('session.attribute_bag') ? $container->getDefinition('session.attribute_bag') : null,
];
foreach ($container->getDefinition('session')->getArguments() as $v) {
if (!$v instanceof Reference || !isset($bags[$bag = (string) $v]) || !\is_array($factory = $bags[$bag]->getFactory())) {
continue;
}
if ([0, 1] !== array_keys($factory) || !$factory[0] instanceof Reference || 'session' !== (string) $factory[0]) {
continue;
}
if ('get'.ucfirst(substr($bag, 8, -4)).'Bag' !== $factory[1]) {
continue;
}
$bags[$bag]->setFactory(null);
}
}
}

View File

@ -18,6 +18,7 @@ use Symfony\Bundle\FrameworkBundle\DependencyInjection\Compiler\ContainerBuilder
use Symfony\Bundle\FrameworkBundle\DependencyInjection\Compiler\DataCollectorTranslatorPass; use Symfony\Bundle\FrameworkBundle\DependencyInjection\Compiler\DataCollectorTranslatorPass;
use Symfony\Bundle\FrameworkBundle\DependencyInjection\Compiler\LoggingTranslatorPass; use Symfony\Bundle\FrameworkBundle\DependencyInjection\Compiler\LoggingTranslatorPass;
use Symfony\Bundle\FrameworkBundle\DependencyInjection\Compiler\ProfilerPass; use Symfony\Bundle\FrameworkBundle\DependencyInjection\Compiler\ProfilerPass;
use Symfony\Bundle\FrameworkBundle\DependencyInjection\Compiler\SessionPass;
use Symfony\Bundle\FrameworkBundle\DependencyInjection\Compiler\TestServiceContainerRealRefPass; use Symfony\Bundle\FrameworkBundle\DependencyInjection\Compiler\TestServiceContainerRealRefPass;
use Symfony\Bundle\FrameworkBundle\DependencyInjection\Compiler\TestServiceContainerWeakRefPass; use Symfony\Bundle\FrameworkBundle\DependencyInjection\Compiler\TestServiceContainerWeakRefPass;
use Symfony\Bundle\FrameworkBundle\DependencyInjection\Compiler\UnusedTagsPass; use Symfony\Bundle\FrameworkBundle\DependencyInjection\Compiler\UnusedTagsPass;
@ -149,6 +150,7 @@ class FrameworkBundle extends Bundle
$this->addCompilerPassIfExists($container, AddAutoMappingConfigurationPass::class); $this->addCompilerPassIfExists($container, AddAutoMappingConfigurationPass::class);
$container->addCompilerPass(new RegisterReverseContainerPass(true)); $container->addCompilerPass(new RegisterReverseContainerPass(true));
$container->addCompilerPass(new RegisterReverseContainerPass(false), PassConfig::TYPE_AFTER_REMOVING); $container->addCompilerPass(new RegisterReverseContainerPass(false), PassConfig::TYPE_AFTER_REMOVING);
$container->addCompilerPass(new SessionPass());
if ($container->getParameter('kernel.debug')) { if ($container->getParameter('kernel.debug')) {
$container->addCompilerPass(new AddDebugLogProcessorPass(), PassConfig::TYPE_BEFORE_OPTIMIZATION, 2); $container->addCompilerPass(new AddDebugLogProcessorPass(), PassConfig::TYPE_BEFORE_OPTIMIZATION, 2);

View File

@ -0,0 +1,44 @@
<?php
/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Symfony\Bundle\FrameworkBundle\Tests\DependencyInjection\Compiler;
use PHPUnit\Framework\TestCase;
use Symfony\Bundle\FrameworkBundle\DependencyInjection\Compiler\SessionPass;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\Reference;
class SessionPassTest extends TestCase
{
public function testProcess()
{
$arguments = [
new Reference('session.flash_bag'),
new Reference('session.attribute_bag'),
];
$container = new ContainerBuilder();
$container
->register('session')
->setArguments($arguments);
$container
->register('session.flash_bag')
->setFactory([new Reference('session'), 'getFlashBag']);
$container
->register('session.attribute_bag')
->setFactory([new Reference('session'), 'getAttributeBag']);
(new SessionPass())->process($container);
$this->assertSame($arguments, $container->getDefinition('session')->getArguments());
$this->assertNull($container->getDefinition('session.flash_bag')->getFactory());
$this->assertNull($container->getDefinition('session.attribute_bag')->getFactory());
}
}

View File

@ -221,6 +221,8 @@ class MainConfiguration implements ConfigurationInterface
->children() ->children()
->scalarNode('path')->defaultNull()->end() ->scalarNode('path')->defaultNull()->end()
->scalarNode('domain')->defaultNull()->end() ->scalarNode('domain')->defaultNull()->end()
->scalarNode('secure')->defaultFalse()->end()
->scalarNode('samesite')->defaultNull()->end()
->end() ->end()
->end() ->end()
->end() ->end()

View File

@ -75,7 +75,7 @@ class HttpBrowser extends AbstractBrowser
$fields = $request->getParameters(); $fields = $request->getParameters();
if ($uploadedFiles = $this->getUploadedFiles($request->getFiles())) { if ($uploadedFiles = $this->getUploadedFiles($request->getFiles())) {
$part = new FormDataPart($uploadedFiles); $part = new FormDataPart(array_merge($fields, $uploadedFiles));
return [$part->bodyToIterable(), $part->getPreparedHeaders()->toArray()]; return [$part->bodyToIterable(), $part->getPreparedHeaders()->toArray()];
} }

View File

@ -134,6 +134,28 @@ class HttpBrowserTest extends AbstractBrowserTest
]); ]);
} }
public function testMultiPartRequestWithAdditionalParameters()
{
$client = $this->createMock(HttpClientInterface::class);
$this->expectClientToSendRequestWithFiles($client, ['file1_content', 'baz']);
$browser = new HttpBrowser($client);
$browser->request('POST', 'http://example.com/', ['bar' => 'baz'], [
'file1' => $this->getUploadedFile('file1'),
]);
}
public function testMultiPartRequestWithAdditionalParametersOfTheSameName()
{
$client = $this->createMock(HttpClientInterface::class);
$this->expectClientToNotSendRequestWithFiles($client, ['baz']);
$browser = new HttpBrowser($client);
$browser->request('POST', 'http://example.com/', ['file1' => 'baz'], [
'file1' => $this->getUploadedFile('file1'),
]);
}
private function uploadFile(string $data): string private function uploadFile(string $data): string
{ {
$path = tempnam(sys_get_temp_dir(), 'http'); $path = tempnam(sys_get_temp_dir(), 'http');
@ -167,4 +189,22 @@ class HttpBrowserTest extends AbstractBrowserTest
})) }))
->willReturn($this->createMock(ResponseInterface::class)); ->willReturn($this->createMock(ResponseInterface::class));
} }
protected function expectClientToNotSendRequestWithFiles(HttpClientInterface $client, $fileContents)
{
$client
->expects($this->once())
->method('request')
->with('POST', 'http://example.com/', $this->callback(function ($options) use ($fileContents) {
$this->assertStringContainsString('Content-Type: multipart/form-data', implode('', $options['headers']));
$this->assertInstanceOf('\Generator', $options['body']);
$body = implode('', iterator_to_array($options['body'], false));
foreach ($fileContents as $content) {
$this->assertStringNotContainsString($content, $body);
}
return true;
}))
->willReturn($this->createMock(ResponseInterface::class));
}
} }

View File

@ -12,7 +12,6 @@
namespace Symfony\Component\Console\Output; namespace Symfony\Component\Console\Output;
use Symfony\Component\Console\Exception\InvalidArgumentException; use Symfony\Component\Console\Exception\InvalidArgumentException;
use Symfony\Component\Console\Exception\RuntimeException;
use Symfony\Component\Console\Formatter\OutputFormatterInterface; use Symfony\Component\Console\Formatter\OutputFormatterInterface;
/** /**
@ -74,10 +73,7 @@ class StreamOutput extends Output
$message .= PHP_EOL; $message .= PHP_EOL;
} }
if (false === @fwrite($this->stream, $message)) { @fwrite($this->stream, $message);
// should never happen
throw new RuntimeException('Unable to write output.');
}
fflush($this->stream); fflush($this->stream);
} }

View File

@ -56,4 +56,12 @@ class StreamOutputTest extends TestCase
rewind($output->getStream()); rewind($output->getStream());
$this->assertEquals('foo'.PHP_EOL, stream_get_contents($output->getStream()), '->doWrite() writes to the stream'); $this->assertEquals('foo'.PHP_EOL, stream_get_contents($output->getStream()), '->doWrite() writes to the stream');
} }
public function testDoWriteOnFailure()
{
$resource = fopen(__DIR__.'/../Fixtures/stream_output_file.txt', 'r', false);
$output = new StreamOutput($resource);
rewind($output->getStream());
$this->assertEquals('', stream_get_contents($output->getStream()));
}
} }

View File

@ -15,6 +15,7 @@ use Symfony\Component\DependencyInjection\Argument\TaggedIteratorArgument;
use Symfony\Component\DependencyInjection\ContainerBuilder; use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\Exception\InvalidArgumentException; use Symfony\Component\DependencyInjection\Exception\InvalidArgumentException;
use Symfony\Component\DependencyInjection\Reference; use Symfony\Component\DependencyInjection\Reference;
use Symfony\Component\DependencyInjection\TypedReference;
/** /**
* Trait that allows a generic method to find and sort service by priority option in the tag. * Trait that allows a generic method to find and sort service by priority option in the tag.
@ -55,41 +56,51 @@ trait PriorityTaggedServiceTrait
foreach ($container->findTaggedServiceIds($tagName, true) as $serviceId => $attributes) { foreach ($container->findTaggedServiceIds($tagName, true) as $serviceId => $attributes) {
$defaultPriority = null; $defaultPriority = null;
$defaultIndex = null; $defaultIndex = null;
$class = $container->getDefinition($serviceId)->getClass();
$class = $container->getParameterBag()->resolveValue($class) ?: null;
foreach ($attributes as $attribute) { foreach ($attributes as $attribute) {
$index = $priority = null; $index = $priority = null;
if (isset($attribute['priority'])) { if (isset($attribute['priority'])) {
$priority = $attribute['priority']; $priority = $attribute['priority'];
} elseif (null === $defaultPriority && $defaultPriorityMethod) { } elseif (null === $defaultPriority && $defaultPriorityMethod && $class) {
$defaultPriority = PriorityTaggedServiceUtil::getDefaultPriority($container, $serviceId, $defaultPriorityMethod, $tagName); $defaultPriority = PriorityTaggedServiceUtil::getDefaultPriority($container, $serviceId, $class, $defaultPriorityMethod, $tagName);
} }
$priority = $priority ?? $defaultPriority ?? $defaultPriority = 0; $priority = $priority ?? $defaultPriority ?? $defaultPriority = 0;
if (null === $indexAttribute && !$needsIndexes) { if (null === $indexAttribute && !$needsIndexes) {
$services[] = [$priority, ++$i, null, $serviceId]; $services[] = [$priority, ++$i, null, $serviceId, null];
continue 2; continue 2;
} }
if (null !== $indexAttribute && isset($attribute[$indexAttribute])) { if (null !== $indexAttribute && isset($attribute[$indexAttribute])) {
$index = $attribute[$indexAttribute]; $index = $attribute[$indexAttribute];
} elseif (null === $defaultIndex && $defaultIndexMethod) { } elseif (null === $defaultIndex && $defaultIndexMethod && $class) {
$defaultIndex = PriorityTaggedServiceUtil::getDefaultIndex($container, $serviceId, $defaultIndexMethod, $tagName, $indexAttribute); $defaultIndex = PriorityTaggedServiceUtil::getDefaultIndex($container, $serviceId, $class, $defaultIndexMethod, $tagName, $indexAttribute);
} }
$index = $index ?? $defaultIndex ?? $defaultIndex = $serviceId; $index = $index ?? $defaultIndex ?? $defaultIndex = $serviceId;
$services[] = [$priority, ++$i, $index, $serviceId]; $services[] = [$priority, ++$i, $index, $serviceId, $class];
} }
} }
uasort($services, static function ($a, $b) { return $b[0] <=> $a[0] ?: $a[1] <=> $b[1]; }); uasort($services, static function ($a, $b) { return $b[0] <=> $a[0] ?: $a[1] <=> $b[1]; });
$refs = []; $refs = [];
foreach ($services as [, , $index, $serviceId]) { foreach ($services as [, , $index, $serviceId, $class]) {
if (null === $index) { if (!$class) {
$refs[] = new Reference($serviceId); $reference = new Reference($serviceId);
} elseif ($index === $serviceId) {
$reference = new TypedReference($serviceId, $class);
} else { } else {
$refs[$index] = new Reference($serviceId); $reference = new TypedReference($serviceId, $class, ContainerBuilder::EXCEPTION_ON_INVALID_REFERENCE, $index);
}
if (null === $index) {
$refs[] = $reference;
} else {
$refs[$index] = $reference;
} }
} }
@ -105,11 +116,8 @@ class PriorityTaggedServiceUtil
/** /**
* Gets the index defined by the default index method. * Gets the index defined by the default index method.
*/ */
public static function getDefaultIndex(ContainerBuilder $container, string $serviceId, string $defaultIndexMethod, string $tagName, string $indexAttribute): ?string public static function getDefaultIndex(ContainerBuilder $container, string $serviceId, string $class, string $defaultIndexMethod, string $tagName, string $indexAttribute): ?string
{ {
$class = $container->getDefinition($serviceId)->getClass();
$class = $container->getParameterBag()->resolveValue($class) ?: null;
if (!($r = $container->getReflectionClass($class)) || !$r->hasMethod($defaultIndexMethod)) { if (!($r = $container->getReflectionClass($class)) || !$r->hasMethod($defaultIndexMethod)) {
return null; return null;
} }
@ -134,11 +142,8 @@ class PriorityTaggedServiceUtil
/** /**
* Gets the priority defined by the default priority method. * Gets the priority defined by the default priority method.
*/ */
public static function getDefaultPriority(ContainerBuilder $container, string $serviceId, string $defaultPriorityMethod, string $tagName): ?int public static function getDefaultPriority(ContainerBuilder $container, string $serviceId, string $class, string $defaultPriorityMethod, string $tagName): ?int
{ {
$class = $container->getDefinition($serviceId)->getClass();
$class = $container->getParameterBag()->resolveValue($class) ?: null;
if (!($r = $container->getReflectionClass($class)) || !$r->hasMethod($defaultPriorityMethod)) { if (!($r = $container->getReflectionClass($class)) || !$r->hasMethod($defaultPriorityMethod)) {
return null; return null;
} }

View File

@ -17,6 +17,7 @@ use Symfony\Component\DependencyInjection\Compiler\PriorityTaggedServiceTrait;
use Symfony\Component\DependencyInjection\ContainerBuilder; use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\Reference; use Symfony\Component\DependencyInjection\Reference;
use Symfony\Component\DependencyInjection\Tests\Fixtures\BarTagClass; use Symfony\Component\DependencyInjection\Tests\Fixtures\BarTagClass;
use Symfony\Component\DependencyInjection\TypedReference;
class PriorityTaggedServiceTraitTest extends TestCase class PriorityTaggedServiceTraitTest extends TestCase
{ {
@ -122,10 +123,10 @@ class PriorityTaggedServiceTraitTest extends TestCase
$tag = new TaggedIteratorArgument('my_custom_tag', 'foo'); $tag = new TaggedIteratorArgument('my_custom_tag', 'foo');
$expected = [ $expected = [
'bar_tag_class' => new Reference('service2'), 'bar_tag_class' => new TypedReference('service2', BarTagClass::class),
'b' => new Reference('service2'), 'b' => new TypedReference('service2', BarTagClass::class),
'bar' => new Reference('service1'), 'bar' => new Reference('service1'),
'a' => new Reference('service2'), 'a' => new TypedReference('service2', BarTagClass::class),
]; ];
$services = $priorityTaggedServiceTraitImplementation->test($tag, $container); $services = $priorityTaggedServiceTraitImplementation->test($tag, $container);
$this->assertSame(array_keys($expected), array_keys($services)); $this->assertSame(array_keys($expected), array_keys($services));

View File

@ -16,6 +16,7 @@ use Symfony\Component\DependencyInjection\Argument\TaggedIteratorArgument;
use Symfony\Component\DependencyInjection\Compiler\ResolveTaggedIteratorArgumentPass; use Symfony\Component\DependencyInjection\Compiler\ResolveTaggedIteratorArgumentPass;
use Symfony\Component\DependencyInjection\ContainerBuilder; use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\Reference; use Symfony\Component\DependencyInjection\Reference;
use Symfony\Component\DependencyInjection\TypedReference;
/** /**
* @author Roland Franssen <franssen.roland@gmail.com> * @author Roland Franssen <franssen.roland@gmail.com>
@ -50,7 +51,7 @@ class ResolveTaggedIteratorArgumentPassTest extends TestCase
$properties = $container->getDefinition('service_c')->getProperties(); $properties = $container->getDefinition('service_c')->getProperties();
$expected = new TaggedIteratorArgument('foo', 'key'); $expected = new TaggedIteratorArgument('foo', 'key');
$expected->setValues(['1' => new Reference('service_a'), '2' => new Reference('service_b')]); $expected->setValues(['1' => new TypedReference('service_a', 'stdClass'), '2' => new TypedReference('service_b', 'stdClass')]);
$this->assertEquals($expected, $properties['foos']); $this->assertEquals($expected, $properties['foos']);
} }
} }

View File

@ -45,7 +45,7 @@ final class CrawlerSelectorTextContains extends Constraint
return false; return false;
} }
return false !== mb_strpos($crawler->text(null, false), $this->expectedText); return false !== mb_strpos($crawler->text(null, true), $this->expectedText);
} }
/** /**

View File

@ -45,7 +45,7 @@ final class CrawlerSelectorTextSame extends Constraint
return false; return false;
} }
return $this->expectedText === trim($crawler->text(null, false)); return $this->expectedText === trim($crawler->text(null, true));
} }
/** /**

View File

@ -256,7 +256,7 @@ class RouteCollectionBuilderTest extends TestCase
// shows that a prefix will always be given the starting slash // shows that a prefix will always be given the starting slash
$tests[] = ['0', '/foo', '/0/foo']; $tests[] = ['0', '/foo', '/0/foo'];
// spaces are ok, and double slahses at the end are cleaned // spaces are ok, and double slashes at the end are cleaned
$tests[] = ['/ /', '/foo', '/ /foo']; $tests[] = ['/ /', '/foo', '/ /foo'];
return $tests; return $tests;

View File

@ -38,7 +38,7 @@ class CookieClearingLogoutHandler implements LogoutHandlerInterface
public function logout(Request $request, Response $response, TokenInterface $token) public function logout(Request $request, Response $response, TokenInterface $token)
{ {
foreach ($this->cookies as $cookieName => $cookieData) { foreach ($this->cookies as $cookieName => $cookieData) {
$response->headers->clearCookie($cookieName, $cookieData['path'], $cookieData['domain']); $response->headers->clearCookie($cookieName, $cookieData['path'], $cookieData['domain'], isset($cookieData['secure']) ? $cookieData['secure'] : false, true, isset($cookieData['samesite']) ? $cookieData['samesite'] : null);
} }
} }
} }

View File

@ -355,7 +355,7 @@ class SwitchUserListenerTest extends TestCase
$this->assertSame($replacedToken, $this->tokenStorage->getToken()); $this->assertSame($replacedToken, $this->tokenStorage->getToken());
} }
public function testSwitchtUserThrowsAuthenticationExceptionIfNoCurrentToken() public function testSwitchUserThrowsAuthenticationExceptionIfNoCurrentToken()
{ {
$this->expectException('Symfony\Component\Security\Core\Exception\AuthenticationCredentialsNotFoundException'); $this->expectException('Symfony\Component\Security\Core\Exception\AuthenticationCredentialsNotFoundException');
$this->tokenStorage->setToken(null); $this->tokenStorage->setToken(null);

View File

@ -12,6 +12,7 @@
namespace Symfony\Component\Security\Http\Tests\Logout; namespace Symfony\Component\Security\Http\Tests\Logout;
use PHPUnit\Framework\TestCase; use PHPUnit\Framework\TestCase;
use Symfony\Component\HttpFoundation\Cookie;
use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response; use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpFoundation\ResponseHeaderBag; use Symfony\Component\HttpFoundation\ResponseHeaderBag;
@ -25,7 +26,7 @@ class CookieClearingLogoutHandlerTest extends TestCase
$response = new Response(); $response = new Response();
$token = $this->getMockBuilder('Symfony\Component\Security\Core\Authentication\Token\TokenInterface')->getMock(); $token = $this->getMockBuilder('Symfony\Component\Security\Core\Authentication\Token\TokenInterface')->getMock();
$handler = new CookieClearingLogoutHandler(['foo' => ['path' => '/foo', 'domain' => 'foo.foo'], 'foo2' => ['path' => null, 'domain' => null]]); $handler = new CookieClearingLogoutHandler(['foo' => ['path' => '/foo', 'domain' => 'foo.foo', 'secure' => true, 'samesite' => Cookie::SAMESITE_STRICT], 'foo2' => ['path' => null, 'domain' => null]]);
$cookies = $response->headers->getCookies(); $cookies = $response->headers->getCookies();
$this->assertCount(0, $cookies); $this->assertCount(0, $cookies);
@ -39,12 +40,16 @@ class CookieClearingLogoutHandlerTest extends TestCase
$this->assertEquals('foo', $cookie->getName()); $this->assertEquals('foo', $cookie->getName());
$this->assertEquals('/foo', $cookie->getPath()); $this->assertEquals('/foo', $cookie->getPath());
$this->assertEquals('foo.foo', $cookie->getDomain()); $this->assertEquals('foo.foo', $cookie->getDomain());
$this->assertEquals(Cookie::SAMESITE_STRICT, $cookie->getSameSite());
$this->assertTrue($cookie->isSecure());
$this->assertTrue($cookie->isCleared()); $this->assertTrue($cookie->isCleared());
$cookie = $cookies['']['/']['foo2']; $cookie = $cookies['']['/']['foo2'];
$this->assertStringStartsWith('foo2', $cookie->getName()); $this->assertStringStartsWith('foo2', $cookie->getName());
$this->assertEquals('/', $cookie->getPath()); $this->assertEquals('/', $cookie->getPath());
$this->assertNull($cookie->getDomain()); $this->assertNull($cookie->getDomain());
$this->assertNull($cookie->getSameSite());
$this->assertFalse($cookie->isSecure());
$this->assertTrue($cookie->isCleared()); $this->assertTrue($cookie->isCleared());
} }
} }

View File

@ -18,7 +18,7 @@
"require": { "require": {
"php": "^7.2.5", "php": "^7.2.5",
"symfony/security-core": "^4.4|^5.0", "symfony/security-core": "^4.4|^5.0",
"symfony/http-foundation": "^4.4|^5.0", "symfony/http-foundation": "^4.4.7|^5.0.7",
"symfony/http-kernel": "^4.4|^5.0", "symfony/http-kernel": "^4.4|^5.0",
"symfony/property-access": "^4.4|^5.0" "symfony/property-access": "^4.4|^5.0"
}, },

View File

@ -374,6 +374,14 @@
<source>The number of elements in this collection should be a multiple of {{ compared_value }}.</source> <source>The number of elements in this collection should be a multiple of {{ compared_value }}.</source>
<target>يجب أن يكون عدد العناصر في هذه المجموعة مضاعف {{ compared_value }}.</target> <target>يجب أن يكون عدد العناصر في هذه المجموعة مضاعف {{ compared_value }}.</target>
</trans-unit> </trans-unit>
<trans-unit id="97">
<source>This value should satisfy at least one of the following constraints:</source>
<target>يجب أن تستوفي هذه القيمة واحدة من القيود التالية:</target>
</trans-unit>
<trans-unit id="98">
<source>Each element of this collection should satisfy its own set of constraints.</source>
<target>يجب أن يفي كل عنصر من عناصر هذه المجموعة بمجموعة القيود الخاصة به.</target>
</trans-unit>
</body> </body>
</file> </file>
</xliff> </xliff>

View File

@ -374,6 +374,14 @@
<source>The number of elements in this collection should be a multiple of {{ compared_value }}.</source> <source>The number of elements in this collection should be a multiple of {{ compared_value }}.</source>
<target>Die Anzahl an Elementen in dieser Sammlung sollte ein Vielfaches von {{ compared_value }} sein.</target> <target>Die Anzahl an Elementen in dieser Sammlung sollte ein Vielfaches von {{ compared_value }} sein.</target>
</trans-unit> </trans-unit>
<trans-unit id="97">
<source>This value should satisfy at least one of the following constraints:</source>
<target>Dieser Wert sollte eine der folgenden Bedingungen erfüllen:</target>
</trans-unit>
<trans-unit id="98">
<source>Each element of this collection should satisfy its own set of constraints.</source>
<target>Jedes Element dieser Sammlung sollte seine eigene Menge an Bedingungen erfüllen.</target>
</trans-unit>
</body> </body>
</file> </file>
</xliff> </xliff>

View File

@ -374,6 +374,14 @@
<source>The number of elements in this collection should be a multiple of {{ compared_value }}.</source> <source>The number of elements in this collection should be a multiple of {{ compared_value }}.</source>
<target>Le nombre d'éléments de cette collection doit être un multiple de {{ compared_value }}.</target> <target>Le nombre d'éléments de cette collection doit être un multiple de {{ compared_value }}.</target>
</trans-unit> </trans-unit>
<trans-unit id="97">
<source>This value should satisfy at least one of the following constraints:</source>
<target>Cette valeur doit satisfaire à au moins une des contraintes suivantes :</target>
</trans-unit>
<trans-unit id="98">
<source>Each element of this collection should satisfy its own set of constraints.</source>
<target>Chaque élément de cette collection doit satisfaire à son propre jeu de contraintes.</target>
</trans-unit>
</body> </body>
</file> </file>
</xliff> </xliff>

View File

@ -366,6 +366,22 @@
<source>This value should be between {{ min }} and {{ max }}.</source> <source>This value should be between {{ min }} and {{ max }}.</source>
<target>Ennek az értéknek {{ min }} és {{ max }} között kell lennie.</target> <target>Ennek az értéknek {{ min }} és {{ max }} között kell lennie.</target>
</trans-unit> </trans-unit>
<trans-unit id="95">
<source>This value is not a valid hostname.</source>
<target>Ez az érték nem egy érvényes állomásnév (hosztnév).</target>
</trans-unit>
<trans-unit id="96">
<source>The number of elements in this collection should be a multiple of {{ compared_value }}.</source>
<target>A gyűjteményben lévő elemek számának oszthatónak kell lennie a következővel: {{ compared_value }}.</target>
</trans-unit>
<trans-unit id="97">
<source>This value should satisfy at least one of the following constraints:</source>
<target>Ennek az értéknek meg kell felelni legalább egynek a következő feltételek közül:</target>
</trans-unit>
<trans-unit id="98">
<source>Each element of this collection should satisfy its own set of constraints.</source>
<target>A gyűjtemény minden elemének meg kell felelni a saját feltételeinek.</target>
</trans-unit>
</body> </body>
</file> </file>
</xliff> </xliff>

View File

@ -366,6 +366,22 @@
<source>This value should be between {{ min }} and {{ max }}.</source> <source>This value should be between {{ min }} and {{ max }}.</source>
<target>Questo valore dovrebbe essere compreso tra {{ min }} e {{ max }}.</target> <target>Questo valore dovrebbe essere compreso tra {{ min }} e {{ max }}.</target>
</trans-unit> </trans-unit>
<trans-unit id="95">
<source>This value is not a valid hostname.</source>
<target>Questo valore non è un nome di host valido.</target>
</trans-unit>
<trans-unit id="96">
<source>The number of elements in this collection should be a multiple of {{ compared_value }}.</source>
<target>Il numero di elementi in questa collezione dovrebbe essere un multiplo di {{ compared_value }}.</target>
</trans-unit>
<trans-unit id="97">
<source>This value should satisfy at least one of the following constraints:</source>
<target>Questo valore dovrebbe soddisfare almeno uno dei vincoli seguenti:</target>
</trans-unit>
<trans-unit id="98">
<source>Each element of this collection should satisfy its own set of constraints.</source>
<target>Ciascun elemento di questa collezione dovrebbe soddisfare il suo insieme di vincoli.</target>
</trans-unit>
</body> </body>
</file> </file>
</xliff> </xliff>

View File

@ -366,6 +366,22 @@
<source>This value should be between {{ min }} and {{ max }}.</source> <source>This value should be between {{ min }} and {{ max }}.</source>
<target>Ši reikšmė turi būti tarp {{ min }} ir {{ max }}.</target> <target>Ši reikšmė turi būti tarp {{ min }} ir {{ max }}.</target>
</trans-unit> </trans-unit>
<trans-unit id="95">
<source>This value is not a valid hostname.</source>
<target>Ši reikšmė nėra tinkamas svetainės adresas.</target>
</trans-unit>
<trans-unit id="96">
<source>The number of elements in this collection should be a multiple of {{ compared_value }}.</source>
<target>Šio sąrašo elementų skaičius turėtų būti skaičiaus {{ compared_value }} kartotinis.</target>
</trans-unit>
<trans-unit id="97">
<source>This value should satisfy at least one of the following constraints:</source>
<target>Ši reikšmė turėtų atitikti bent vieną iš šių nurodymų:</target>
</trans-unit>
<trans-unit id="98">
<source>Each element of this collection should satisfy its own set of constraints.</source>
<target>Kiekvienas šio sąrašo elementas turi atitikti savo nurodymų rinkinį.</target>
</trans-unit>
</body> </body>
</file> </file>
</xliff> </xliff>

View File

@ -374,6 +374,14 @@
<source>The number of elements in this collection should be a multiple of {{ compared_value }}.</source> <source>The number of elements in this collection should be a multiple of {{ compared_value }}.</source>
<target>Số lượng các phần tử trong bộ sưu tập này nên là bội số của {{ compared_value }}.</target> <target>Số lượng các phần tử trong bộ sưu tập này nên là bội số của {{ compared_value }}.</target>
</trans-unit> </trans-unit>
<trans-unit id="97">
<source>This value should satisfy at least one of the following constraints:</source>
<target>Giá trị này nên thỏa mãn ít nhất một trong những ràng buộc sau:</target>
</trans-unit>
<trans-unit id="98">
<source>Each element of this collection should satisfy its own set of constraints.</source>
<target>Mỗi phần tử trong bộ sưu tập này nên thỏa mãn những ràng buộc của nó.</target>
</trans-unit>
</body> </body>
</file> </file>
</xliff> </xliff>

View File

@ -698,4 +698,25 @@ abstract class AbstractTest extends AbstractValidatorTest
$this->assertCount(2, $violations); $this->assertCount(2, $violations);
} }
public function testNestedObjectIsValidatedInMultipleGroupsIfGroupInValidConstraintIsValidated()
{
$entity = new Entity();
$entity->firstName = null;
$reference = new Reference();
$reference->value = null;
$entity->childA = $reference;
$this->metadata->addPropertyConstraint('firstName', new NotBlank());
$this->metadata->addPropertyConstraint('childA', new Valid(['groups' => ['group1', 'group2']]));
$this->referenceMetadata->addPropertyConstraint('value', new NotBlank(['groups' => 'group1']));
$this->referenceMetadata->addPropertyConstraint('value', new NotNull(['groups' => 'group2']));
$violations = $this->validator->validate($entity, null, ['Default', 'group1', 'group2']);
$this->assertCount(3, $violations);
}
} }

View File

@ -14,6 +14,7 @@ namespace Symfony\Component\Validator\Validator;
use Symfony\Component\Validator\Constraint; use Symfony\Component\Validator\Constraint;
use Symfony\Component\Validator\Constraints\Composite; use Symfony\Component\Validator\Constraints\Composite;
use Symfony\Component\Validator\Constraints\GroupSequence; use Symfony\Component\Validator\Constraints\GroupSequence;
use Symfony\Component\Validator\Constraints\Valid;
use Symfony\Component\Validator\ConstraintValidatorFactoryInterface; use Symfony\Component\Validator\ConstraintValidatorFactoryInterface;
use Symfony\Component\Validator\Context\ExecutionContext; use Symfony\Component\Validator\Context\ExecutionContext;
use Symfony\Component\Validator\Context\ExecutionContextInterface; use Symfony\Component\Validator\Context\ExecutionContextInterface;
@ -710,8 +711,9 @@ class RecursiveContextualValidator implements ContextualValidatorInterface
// that constraints belong to multiple validated groups // that constraints belong to multiple validated groups
if (null !== $cacheKey) { if (null !== $cacheKey) {
$constraintHash = spl_object_hash($constraint); $constraintHash = spl_object_hash($constraint);
// instanceof Valid: In case of using a Valid constraint with many groups
if ($constraint instanceof Composite) { // it makes a reference object get validated by each group
if ($constraint instanceof Composite || $constraint instanceof Valid) {
$constraintHash .= $group; $constraintHash .= $group;
} }

View File

@ -1899,7 +1899,7 @@ YAML
$this->parser->parse('!!iterator foo'); $this->parser->parse('!!iterator foo');
} }
public function testExceptionWhenUsingUnsuportedBuiltInTags() public function testExceptionWhenUsingUnsupportedBuiltInTags()
{ {
$this->expectException('Symfony\Component\Yaml\Exception\ParseException'); $this->expectException('Symfony\Component\Yaml\Exception\ParseException');
$this->expectExceptionMessage('The built-in tag "!!foo" is not implemented at line 1 (near "!!foo").'); $this->expectExceptionMessage('The built-in tag "!!foo" is not implemented at line 1 (near "!!foo").');