diff --git a/.github/build-packages.php b/.github/build-packages.php
index 56112b753ad32..b67a699609d66 100644
--- a/.github/build-packages.php
+++ b/.github/build-packages.php
@@ -49,8 +49,8 @@
$packages[$package->name][$package->version] = $package;
- $versions = file_get_contents('https://packagist.org/packages/'.$package->name.'.json');
- $versions = json_decode($versions)->package->versions;
+ $versions = file_get_contents('https://packagist.org/p/'.$package->name.'.json');
+ $versions = json_decode($versions)->packages->{$package->name};
if ($package->version === str_replace('-dev', '.x-dev', $versions->{'dev-master'}->extra->{'branch-alias'}->{'dev-master'})) {
unset($versions->{'dev-master'});
diff --git a/.travis.yml b/.travis.yml
index c60334e87483e..35a0105e7e736 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -195,7 +195,7 @@ install:
elif [[ $deps = low ]]; then
echo "$COMPONENTS" | parallel --gnu -j10% "tfold {} 'cd {} && $COMPOSER_UP --prefer-lowest --prefer-stable && $PHPUNIT_X'"
elif [[ $PHP = hhvm* ]]; then
- $PHPUNIT --exclude-group benchmark,intl-data
+ $PHPUNIT --exclude-group no-hhvm,benchmark,intl-data
else
echo "$COMPONENTS" | parallel --gnu "tfold {} $PHPUNIT_X {}"
tfold tty-group $PHPUNIT --group tty
diff --git a/CHANGELOG-3.3.md b/CHANGELOG-3.3.md
index fe698c1e6dc39..950150a68acf1 100644
--- a/CHANGELOG-3.3.md
+++ b/CHANGELOG-3.3.md
@@ -7,6 +7,43 @@ in 3.3 minor versions.
To get the diff for a specific change, go to https://github.com/symfony/symfony/commit/XXX where XXX is the change hash
To get the diff between two versions, go to https://github.com/symfony/symfony/compare/v3.3.0...v3.3.1
+* 3.3.16 (2018-01-29)
+
+ * bug #25922 [HttpFoundation] Use the correct syntax for session gc based on Pdo driver (tanasecosminromeo)
+ * bug #25933 Disable CSP header on exception pages only in debug (ostrolucky)
+ * bug #25926 [Form] Fixed Button::setParent() when already submitted (HeahDude)
+ * bug #25927 [Form] Fixed submitting disabled buttons (HeahDude)
+ * bug #25891 [DependencyInjection] allow null values for root nodes in YAML configs (xabbuh)
+ * bug #24864 Have weak_vendors ignore deprecations from outside (greg0ire)
+ * bug #25848 [Validator] add missing parent isset and add test (Simperfit)
+ * bug #25869 [Process] Skip environment variables with false value in Process (francoispluchino)
+ * bug #25864 [Yaml] don't split lines on carriage returns when dumping (xabbuh)
+ * bug #25861 do not conflict with egulias/email-validator 2.0+ (xabbuh)
+ * bug #25851 [Validator] Conflict with egulias/email-validator 2.0 (emodric)
+ * bug #25837 [SecurityBundle] Don't register in memory users as services (chalasr)
+ * bug #25835 [HttpKernel] DebugHandlersListener should always replace the existing exception handler (nicolas-grekas)
+ * bug #25829 [Debug] Always decorate existing exception handlers to deal with fatal errors (nicolas-grekas)
+ * bug #25824 Fixing a bug where the dump() function depended on bundle ordering (weaverryan)
+ * bug #25789 Enableable ArrayNodeDefinition is disabled for empty configuration (kejwmen)
+ * bug #25822 [Cache] Fix handling of apcu_fetch() edgy behavior (nicolas-grekas)
+ * bug #25816 Problem in phar see mergerequest #25579 (betzholz)
+ * bug #25781 [Form] Disallow transform dates beyond the year 9999 (curry684)
+ * bug #25287 [Serializer] DateTimeNormalizer handling of null and empty values (returning it instead of new object) (Simperfit)
+ * bug #25812 Copied NO language files to the new NB locale (derrabus)
+ * bug #25801 [Router] Skip anonymous classes when loading annotated routes (pierredup)
+ * bug #25657 [Security] Fix fatal error on non string username (chalasr)
+ * bug #25791 [Routing] Make sure we only build routes once (sroze)
+ * bug #25799 Fixed Request::__toString ignoring cookies (Toflar)
+ * bug #25755 [Debug] prevent infinite loop with faulty exception handlers (nicolas-grekas)
+ * bug #25771 [Validator] 19 digits VISA card numbers are valid (xabbuh)
+ * bug #25751 [FrameworkBundle] Add the missing `enabled` session attribute (sroze)
+ * bug #25750 [HttpKernel] Turn bad hosts into 400 instead of 500 (nicolas-grekas)
+ * bug #25490 [Serializer] Fixed throwing exception with option JSON_PARTIAL_OUTPUT_ON_ERROR (diversantvlz)
+ * bug #25709 Tweaked some styles in the profiler tables (javiereguiluz)
+ * bug #25696 [FrameworkBundle] Fix using "annotations.cached_reader" in after-removing passes (nicolas-grekas)
+ * feature #25669 [Security] Fail gracefully if the security token cannot be unserialized from the session (thewilkybarkid)
+ * bug #25700 Run simple-phpunit with --no-suggest option (ro0NL)
+
* 3.3.15 (2018-01-05)
* bug #25532 [HttpKernel] Disable CSP header on exception pages (ostrolucky)
diff --git a/CONTRIBUTORS.md b/CONTRIBUTORS.md
index 30d8ae3f828ed..85b3003b2abc6 100644
--- a/CONTRIBUTORS.md
+++ b/CONTRIBUTORS.md
@@ -13,13 +13,13 @@ Symfony is the result of the work of many people who made the code better
- Jordi Boggiano (seldaek)
- Victor Berchet (victor)
- Johannes S (johannes)
- - Jakub Zalas (jakubzalas)
- Kévin Dunglas (dunglas)
+ - Jakub Zalas (jakubzalas)
- Kris Wallsmith (kriswallsmith)
- Ryan Weaver (weaverryan)
+ - Robin Chalas (chalas_r)
- Javier Eguiluz (javier.eguiluz)
- Maxime Steinhausser (ogizanagi)
- - Robin Chalas (chalas_r)
- Hugo Hamon (hhamon)
- Abdellatif Ait boudad (aitboudad)
- Grégoire Pineau (lyrixx)
@@ -48,21 +48,22 @@ Symfony is the result of the work of many people who made the code better
- stealth35 (stealth35)
- Alexander Mols (asm89)
- Iltar van der Berg (kjarli)
+ - Yonel Ceruto (yonelceruto)
- Bulat Shakirzyanov (avalanche123)
- Peter Rehm (rpet)
- Saša Stamenković (umpirsky)
- Henrik Bjørnskov (henrikbjorn)
- - Yonel Ceruto (yonelceruto)
- Miha Vrhovnik
- Matthias Pigulla (mpdude)
- Diego Saint Esteben (dii3g0)
+ - Dany Maillard (maidmaid)
- Konstantin Kudryashov (everzet)
- - Bilal Amarni (bamarni)
- Kevin Bond (kbond)
- - Dany Maillard (maidmaid)
+ - Bilal Amarni (bamarni)
- Pierre du Plessis (pierredup)
- Florin Patan (florinpatan)
- Jérémy DERUSSÉ (jderusse)
+ - Amrouche Hamza (simperfit)
- Gábor Egyed (1ed)
- Michel Weimerskirch (mweimerskirch)
- Andrej Hudec (pulzarraider)
@@ -70,16 +71,17 @@ Symfony is the result of the work of many people who made the code better
- Eric Clemmons (ericclemmons)
- Jáchym Toušek (enumag)
- Charles Sarrazin (csarrazi)
+ - Titouan Galopin (tgalopin)
+ - Samuel ROZE (sroze)
- Konstantin Myakshin (koc)
- Christian Raue
- Arnout Boks (aboks)
- Deni
- Henrik Westphal (snc)
- Dariusz Górecki (canni)
- - Titouan Galopin (tgalopin)
+ - Issei Murasawa (issei_m)
- Douglas Greenshields (shieldo)
- Tobias Nyholm (tobias)
- - Issei Murasawa (issei_m)
- Lee McDermott
- Brandon Turner
- Luis Cordova (cordoval)
@@ -97,12 +99,11 @@ Symfony is the result of the work of many people who made the code better
- Arnaud Le Blanc (arnaud-lb)
- Maxime STEINHAUSSER
- Michal Piotrowski (eventhorizon)
- - Samuel ROZE (sroze)
- Tim Nagel (merk)
- - Amrouche Hamza (simperfit)
+ - Vladimir Reznichenko (kalessil)
- Brice BERNARD (brikou)
+ - David Maicher (dmaicher)
- Baptiste Clavié (talus)
- - Vladimir Reznichenko (kalessil)
- marc.weistroff
- lenar
- Alexander Schwenn (xelaris)
@@ -118,17 +119,16 @@ Symfony is the result of the work of many people who made the code better
- Tomáš Votruba (tomas_votruba)
- Fabien Pennequin (fabienpennequin)
- Gordon Franke (gimler)
- - David Maicher (dmaicher)
- Eric GELOEN (gelo)
- Daniel Wehner (dawehner)
- Tugdual Saunier (tucksaun)
+ - Grégoire Paris (greg0ire)
- Théo FIDRY (theofidry)
- Robert Schönthal (digitalkaoz)
- Florian Lonqueu-Brochard (florianlb)
- Sebastiaan Stok (sstok)
- Stefano Sala (stefano.sala)
- Evgeniy (ewgraf)
- - Grégoire Paris (greg0ire)
- Vincent AUBERT (vincent)
- Juti Noppornpitak (shiroyuki)
- Tigran Azatyan (tigranazatyan)
@@ -139,6 +139,8 @@ Symfony is the result of the work of many people who made the code better
- Pablo Godel (pgodel)
- Jérémie Augustin (jaugustin)
- Andréia Bohner (andreia)
+ - Alex Pott
+ - Julien Falque (julienfalque)
- Rafael Dohms (rdohms)
- Arnaud Kleinpeter (nanocom)
- jwdeitch
@@ -147,11 +149,9 @@ Symfony is the result of the work of many people who made the code better
- Jérôme Vasseur (jvasseur)
- Oleg Voronkovich
- Philipp Wahala (hifi)
- - Alex Pott
- Vyacheslav Pavlov
- Richard van Laak (rvanlaak)
- Javier Spagnoletti (phansys)
- - Julien Falque (julienfalque)
- Richard Shank (iampersistent)
- Thomas Rabaix (rande)
- Rouven Weßling (realityking)
@@ -174,6 +174,7 @@ Symfony is the result of the work of many people who made the code better
- Dmitrii Chekaliuk (lazyhammer)
- Clément JOBEILI (dator)
- Daniel Espendiller
+ - Valentin Udaltsov (vudaltsov)
- Possum
- Dorian Villet (gnutix)
- Sergey Linnik (linniksa)
@@ -190,7 +191,6 @@ Symfony is the result of the work of many people who made the code better
- Stepan Anchugov (kix)
- bronze1man
- sun (sun)
- - Valentin Udaltsov (vudaltsov)
- Larry Garfield (crell)
- Martin Schuhfuß (usefulthink)
- apetitpa
@@ -247,11 +247,13 @@ Symfony is the result of the work of many people who made the code better
- Alessandro Chitolina
- Kristen Gilden (kgilden)
- Pierre-Yves LEBECQ (pylebecq)
+ - Niels Keurentjes (curry684)
- Jordan Samouh (jordansamouh)
- Jakub Kucharovic (jkucharovic)
- Uwe Jäger (uwej711)
- Eugene Leonovich (rybakit)
- Filippo Tessarotto
+ - Gabriel Ostrolucký
- Joseph Rouff (rouffj)
- Félix Labrecque (woodspire)
- GordonsLondon
@@ -270,9 +272,11 @@ Symfony is the result of the work of many people who made the code better
- DQNEO
- jdhoek
- Pavel Batanov (scaytrase)
+ - Bob den Otter (bopp)
- Nikita Konstantinov
- Wodor Wodorski
- Oskar Stark (oskarstark)
+ - Dariusz
- Thomas Lallement (raziel057)
- Giorgio Premi
- Matthieu Napoli (mnapoli)
@@ -284,6 +288,7 @@ Symfony is the result of the work of many people who made the code better
- Kim Hemsø Rasmussen (kimhemsoe)
- Wouter Van Hecke
- Jérôme Parmentier (lctrs)
+ - Michael Babker (mbabker)
- Peter Kruithof (pkruithof)
- Michael Holm (hollo)
- Marc Weistroff (futurecat)
@@ -301,6 +306,7 @@ Symfony is the result of the work of many people who made the code better
- Andrey Esaulov (andremaha)
- Grégoire Passault (gregwar)
- Jerzy Zawadzki (jzawadzki)
+ - Wouter J
- Ismael Ambrosi (iambrosi)
- Baptiste Lafontaine
- Aurelijus Valeiša (aurelijus)
@@ -311,7 +317,6 @@ Symfony is the result of the work of many people who made the code better
- Tiago Ribeiro (fixe)
- Hidde Boomsma (hboomsma)
- John Bafford (jbafford)
- - Bob den Otter (bopp)
- Adrian Rudnik (kreischweide)
- Francesc Rosàs (frosas)
- Massimiliano Arione (garak)
@@ -324,7 +329,6 @@ Symfony is the result of the work of many people who made the code better
- Thierry Thuon (lepiaf)
- Ricard Clau (ricardclau)
- Mark Challoner (markchalloner)
- - Dariusz
- Gennady Telegin (gtelegin)
- Ben Davies (bendavies)
- Erin Millard
@@ -339,16 +343,15 @@ Symfony is the result of the work of many people who made the code better
- Inal DJAFAR (inalgnu)
- Christian Gärtner (dagardner)
- Tomasz Kowalczyk (thunderer)
- - Michael Babker (mbabker)
- François-Xavier de Guillebon (de-gui_f)
- Damien Alexandre (damienalexandre)
- Felix Labrecque
- Yaroslav Kiliba
- Terje Bråten
+ - Yanick Witschi (toflar)
- Robbert Klarenbeek (robbertkl)
- Edi Modrić (emodric)
- Thomas Calvet (fancyweb)
- - Niels Keurentjes (curry684)
- JhonnyL
- David Badura (davidbadura)
- hossein zolfi (ocean)
@@ -414,6 +417,7 @@ Symfony is the result of the work of many people who made the code better
- Jan Schumann
- Niklas Fiekas
- Markus Bachmann (baachi)
+ - Gabriel Caruso
- lancergr
- Mihai Stancu
- Olivier Dolbeau (odolbeau)
@@ -450,7 +454,6 @@ Symfony is the result of the work of many people who made the code better
- Anton Bakai
- Maxime Veber (nek-)
- Alex Bakhturin
- - Yanick Witschi (toflar)
- Alexander Obuhovich (aik099)
- boombatower
- Fabrice Bernhard (fabriceb)
@@ -478,7 +481,6 @@ Symfony is the result of the work of many people who made the code better
- Roy Van Ginneken (rvanginneken)
- ondrowan
- Barry vd. Heuvel (barryvdh)
- - Wouter J
- Florent Mata
- Evan S Kaufman (evanskaufman)
- mcben
@@ -562,6 +564,7 @@ Symfony is the result of the work of many people who made the code better
- Max Rath (drak3)
- Stéphane Escandell (sescandell)
- Konstantin S. M. Möllers (ksmmoellers)
+ - Alessandro Lai (jean85)
- James Johnston
- Sinan Eldem
- Alexandre Dupuy (satchette)
@@ -617,6 +620,7 @@ Symfony is the result of the work of many people who made the code better
- Antoine Corcy
- Sascha Grossenbacher
- Szijarto Tamas
+ - Robin Lehrmann (robinlehrmann)
- Catalin Dan
- Stephan Vock
- Benjamin Zikarsky (bzikarsky)
@@ -692,6 +696,7 @@ Symfony is the result of the work of many people who made the code better
- Andrew Hilobok (hilobok)
- Noah Heck (myesain)
- Christian Soronellas (theunic)
+ - Johann Pardanaud
- Adam Szaraniec (mimol)
- Yosmany Garcia (yosmanyga)
- Wouter de Wild
@@ -811,6 +816,7 @@ Symfony is the result of the work of many people who made the code better
- Gábor Tóth
- Daniel Cestari
- David Lima
+ - Brian Freytag (brianfreytag)
- Brunet Laurent (lbrunet)
- Mikhail Yurasov (mym)
- LOUARDI Abdeltif (ouardisoft)
@@ -843,9 +849,9 @@ Symfony is the result of the work of many people who made the code better
- Colin O'Dell (colinodell)
- xaav
- Mahmoud Mostafa (mahmoud)
- - Alessandro Lai
- Pieter
- Michael Tibben
+ - Billie Thompson
- Sander Marechal
- Radosław Benkel
- jean pasqualini (darkilliant)
@@ -898,10 +904,10 @@ Symfony is the result of the work of many people who made the code better
- Goran Juric
- Laurent Ghirardotti (laurentg)
- Nicolas Macherey
+ - Guido Donnari
- AKeeman (akeeman)
- Lin Clark
- Jeremy David (jeremy.david)
- - Robin Lehrmann (robinlehrmann)
- Troy McCabe
- Ville Mattila
- ilyes kooli
@@ -952,6 +958,7 @@ Symfony is the result of the work of many people who made the code better
- DerManoMann
- Olaf Klischat
- orlovv
+ - Haralan Dobrev (hkdobrev)
- Jhonny Lidfors (jhonny)
- Julien Bianchi (jubianchi)
- Robert Meijers
@@ -967,7 +974,6 @@ Symfony is the result of the work of many people who made the code better
- Alex Bowers
- Jeremy Bush
- wizhippo
- - Gabriel Ostrolucký
- Viacheslav Sychov
- Carlos Ortega Huetos
- rpg600
@@ -1033,6 +1039,7 @@ Symfony is the result of the work of many people who made the code better
- Marco
- Marc Torres
- Alberto Aldegheri
+ - Dalibor Karlović
- heccjj
- Alexandre Melard
- Jay Klehr
@@ -1042,6 +1049,7 @@ Symfony is the result of the work of many people who made the code better
- Jakub Kulhan
- Ilia (aliance)
- Mo Di (modi)
+ - Pablo Schläpfer
- Jelte Steijaert (jelte)
- Quique Porta (quiqueporta)
- stoccc
@@ -1084,6 +1092,7 @@ Symfony is the result of the work of many people who made the code better
- Grzegorz Zdanowski (kiler129)
- sl_toto (sl_toto)
- Walter Dal Mut (wdalmut)
+ - Matthieu
- Albin Kerouaton
- Sébastien HOUZÉ
- Jingyu Wang
@@ -1103,6 +1112,7 @@ Symfony is the result of the work of many people who made the code better
- Jules Lamur
- Renato Mendes Figueiredo
- ShiraNai7
+ - Antal Áron (antalaron)
- Markus Fasselt (digilist)
- Vašek Purchart (vasek-purchart)
- Janusz Jabłoński (yanoosh)
@@ -1144,6 +1154,7 @@ Symfony is the result of the work of many people who made the code better
- Tomaz Ahlin
- Marcus Stöhr (dafish)
- Emmanuel Vella (emmanuel.vella)
+ - Jonathan Johnson (jrjohnson)
- Carsten Nielsen (phreaknerd)
- Mathieu Rochette
- Jay Severson
@@ -1218,6 +1229,7 @@ Symfony is the result of the work of many people who made the code better
- Antoine Bellion (abellion)
- Ramon Kleiss (akathos)
- César Suárez (csuarez)
+ - Bjorn Twachtmann (dotbjorn)
- Nicolas Badey (nico-b)
- Shane Preece (shane)
- Johannes Goslar
@@ -1266,6 +1278,7 @@ Symfony is the result of the work of many people who made the code better
- Stefan Hüsges (tronsha)
- Dan Blows
- Matt Wells
+ - Nicolas Appriou
- stloyd
- Chris Tickner
- Andrew Coulton
@@ -1281,7 +1294,9 @@ Symfony is the result of the work of many people who made the code better
- Matthew Donadio
- Andreas
- Thomas Chmielowiec
+ - shdev
- Andrey Ryaguzov
+ - Stefan
- Peter Bex
- Manatsawin Hanmongkolchai
- Gunther Konig
@@ -1350,6 +1365,7 @@ Symfony is the result of the work of many people who made the code better
- Grinbergs Reinis (shima5)
- Artem Lopata (bumz)
- Nicole Cordes
+ - Roman Orlov
- VolCh
- Alexey Popkov
- Gijs Kunze
@@ -1372,12 +1388,13 @@ Symfony is the result of the work of many people who made the code better
- Dmitry Korotovsky
- mcorteel
- Michael van Tricht
+ - Tim Strehle
- Sam Ward
- Walther Lalk
- Adam
+ - Stéphan Kochen
- devel
- taiiiraaa
- - Johann Pardanaud
- Trevor Suarez
- gedrox
- Alan Bondarchuk
@@ -1393,6 +1410,7 @@ Symfony is the result of the work of many people who made the code better
- bertillon
- Bertalan Attila
- Yannick Bensacq (cibou)
+ - Frédéric G. Marand (fgm)
- Freek Van der Herten (freekmurze)
- Luca Genuzio (genuzio)
- Hans Nilsson (hansnilsson)
@@ -1440,9 +1458,11 @@ Symfony is the result of the work of many people who made the code better
- Alex Pods
- hadriengem
- timaschew
+ - Jochen Mandl
- Ian Phillips
- Haritz
- Matthieu Prat
+ - Ion Bazan
- Grummfy
- Filipe Guerra
- Gerben Wijnja
@@ -1469,6 +1489,7 @@ Symfony is the result of the work of many people who made the code better
- Juan M Martínez
- Gilles Gauthier
- ddebree
+ - Kuba Werłos
- Tomas Liubinas
- Alex
- Klaas Naaijkens
@@ -1541,6 +1562,7 @@ Symfony is the result of the work of many people who made the code better
- Kristof Van Cauwenbergh (kristofvc)
- Paulius Jarmalavičius (pjarmalavicius)
- Ramon Henrique Ornelas (ramonornela)
+ - Ricardo de Vries (ricknox)
- Markus S. (staabm)
- Till Klampaeckel (till)
- Tobias Weinert (tweini)
@@ -1548,6 +1570,7 @@ Symfony is the result of the work of many people who made the code better
- Wotre
- goohib
- Xavier HAUSHERR
+ - Ron Gähler
- Edwin Hageman
- Mantas Urnieža
- Cas
@@ -1563,12 +1586,14 @@ Symfony is the result of the work of many people who made the code better
- BenjaminBeck
- Aurelijus Rožėnas
- Vladimir Tsykun
+ - Jordan Hoff
- znerol
- Christian Eikermann
- Antonio Angelino
- Matt Fields
- Niklas Keller
- Vladimir Sazhin
+ - Tomas Kmieliauskas
- Billie Thompson
- lol768
- jamogon
@@ -1582,6 +1607,7 @@ Symfony is the result of the work of many people who made the code better
- patrick-mcdougle
- Dariusz Czech
- Anonymous User
+ - Paweł Tomulik
- Eric J. Duran
- Alexandru Bucur
- cmfcmf
@@ -1605,7 +1631,6 @@ Symfony is the result of the work of many people who made the code better
- vlechemin
- Brian Corrigan
- Ladislav Tánczos
- - Brian Freytag
- Skorney
- fmarchalemisys
- mieszko4
@@ -1617,6 +1642,7 @@ Symfony is the result of the work of many people who made the code better
- Markus Staab
- Pierre-Louis LAUNAY
- djama
+ - Michael Gwynne
- Eduardo Conceição
- Jon Cave
- Sébastien HOUZE
@@ -1626,6 +1652,7 @@ Symfony is the result of the work of many people who made the code better
- Shude
- Ondřej Führer
- Sema
+ - Michael Käfer
- Elan Ruusamäe
- Thorsten Hallwas
- Michael Squires
@@ -1653,6 +1680,7 @@ Symfony is the result of the work of many people who made the code better
- Diego Campoy
- TeLiXj
- Oncle Tom
+ - Sam Anthony
- Christian Stocker
- Dawid Nowak
- Lesnykh Ilia
@@ -1671,6 +1699,7 @@ Symfony is the result of the work of many people who made the code better
- arduanov
- sualko
- Bilge
+ - ADmad
- Nicolas Roudaire
- Alfonso (afgar)
- Andreas Forsblom (aforsblo)
@@ -1764,6 +1793,7 @@ Symfony is the result of the work of many people who made the code better
- Moritz Kraft (userfriendly)
- Víctor Mateo (victormateo)
- Vincent (vincent1870)
+ - Vincent CHALAMON (vincentchalamon)
- Eugene Babushkin (warl)
- Wouter Sioen (wouter_sioen)
- Xavier Amado (xamado)
@@ -1786,6 +1816,7 @@ Symfony is the result of the work of many people who made the code better
- Michael
- fh-github@fholzhauer.de
- AbdElKader Bouadjadja
+ - DSeemiller
- Jan Emrich
- Mark Topper
- Xavier REN
@@ -1799,6 +1830,7 @@ Symfony is the result of the work of many people who made the code better
- Marc Lemay (flug)
- Henne Van Och (hennevo)
- Jeroen De Dauw (jeroendedauw)
+ - Daniel Alejandro Castro Arellano (lexcast)
- Maxime COLIN (maximecolin)
- Muharrem Demirci (mdemirci)
- Evgeny Z (meze)
@@ -1808,3 +1840,4 @@ Symfony is the result of the work of many people who made the code better
- Thomas BERTRAND (sevrahk)
- Matej Žilák (teo_sk)
- Vladislav Vlastovskiy (vlastv)
+ - RENAUDIN Xavier (xorrox)
diff --git a/appveyor.yml b/appveyor.yml
index 6cee17f6feedf..cc1de26c5f8ef 100644
--- a/appveyor.yml
+++ b/appveyor.yml
@@ -27,6 +27,7 @@ install:
- 7z x php_memcache-3.0.8-5.5-nts-vc11-x86.zip -y >nul
- cd ..
- copy /Y php.ini-development php.ini-min
+ - echo memory_limit=-1 >> php.ini-min
- echo serialize_precision=14 >> php.ini-min
- echo max_execution_time=1200 >> php.ini-min
- echo date.timezone="America/Los_Angeles" >> php.ini-min
diff --git a/composer.json b/composer.json
index 202e141f36c28..1ef01f1972e9e 100644
--- a/composer.json
+++ b/composer.json
@@ -30,8 +30,7 @@
"symfony/polyfill-intl-icu": "~1.0",
"symfony/polyfill-mbstring": "~1.0",
"symfony/polyfill-php56": "~1.0",
- "symfony/polyfill-php70": "~1.0",
- "symfony/polyfill-util": "~1.0"
+ "symfony/polyfill-php70": "~1.0"
},
"replace": {
"symfony/asset": "self.version",
diff --git a/src/Symfony/Bridge/PhpUnit/DeprecationErrorHandler.php b/src/Symfony/Bridge/PhpUnit/DeprecationErrorHandler.php
index a108126a2eed8..3fde9ab28b100 100644
--- a/src/Symfony/Bridge/PhpUnit/DeprecationErrorHandler.php
+++ b/src/Symfony/Bridge/PhpUnit/DeprecationErrorHandler.php
@@ -75,9 +75,12 @@ public static function register($mode = 0)
}
}
}
- $path = realpath($path) ?: $path;
+ $realPath = realpath($path);
+ if (false === $realPath && '-' !== $path && 'Standard input code' !== $path) {
+ return true;
+ }
foreach ($vendors as $vendor) {
- if (0 === strpos($path, $vendor) && false !== strpbrk(substr($path, strlen($vendor), 1), '/'.DIRECTORY_SEPARATOR)) {
+ if (0 === strpos($realPath, $vendor) && false !== strpbrk(substr($realPath, strlen($vendor), 1), '/'.DIRECTORY_SEPARATOR)) {
return true;
}
}
@@ -223,7 +226,7 @@ public static function register($mode = 0)
uasort($deprecations[$group], $cmp);
foreach ($deprecations[$group] as $msg => $notices) {
- echo "\n", rtrim($msg, '.'), ': ', $notices['count'], "x\n";
+ echo "\n ", $notices['count'], 'x: ', $msg, "\n";
arsort($notices);
diff --git a/src/Symfony/Bridge/PhpUnit/Tests/DeprecationErrorHandler/default.phpt b/src/Symfony/Bridge/PhpUnit/Tests/DeprecationErrorHandler/default.phpt
index cd733724870cd..39a3e985865fd 100644
--- a/src/Symfony/Bridge/PhpUnit/Tests/DeprecationErrorHandler/default.phpt
+++ b/src/Symfony/Bridge/PhpUnit/Tests/DeprecationErrorHandler/default.phpt
@@ -63,20 +63,20 @@ $foo->testNonLegacyBar();
--EXPECTF--
Unsilenced deprecation notices (3)
-unsilenced foo deprecation: 2x
+ 2x: unsilenced foo deprecation
2x in FooTestCase::testLegacyFoo
-unsilenced bar deprecation: 1x
+ 1x: unsilenced bar deprecation
1x in FooTestCase::testNonLegacyBar
Remaining deprecation notices (1)
-silenced bar deprecation: 1x
+ 1x: silenced bar deprecation
1x in FooTestCase::testNonLegacyBar
Legacy deprecation notices (1)
Other deprecation notices (1)
-root deprecation: 1x
+ 1x: root deprecation
diff --git a/src/Symfony/Bridge/PhpUnit/Tests/DeprecationErrorHandler/deprecation.phar b/src/Symfony/Bridge/PhpUnit/Tests/DeprecationErrorHandler/deprecation.phar
new file mode 100644
index 0000000000000..20e1203bd058a
Binary files /dev/null and b/src/Symfony/Bridge/PhpUnit/Tests/DeprecationErrorHandler/deprecation.phar differ
diff --git a/src/Symfony/Bridge/PhpUnit/Tests/DeprecationErrorHandler/deprecation/deprecation.php b/src/Symfony/Bridge/PhpUnit/Tests/DeprecationErrorHandler/deprecation/deprecation.php
new file mode 100644
index 0000000000000..b9e23e7692156
--- /dev/null
+++ b/src/Symfony/Bridge/PhpUnit/Tests/DeprecationErrorHandler/deprecation/deprecation.php
@@ -0,0 +1,3 @@
+buildFromDirectory(__DIR__.DIRECTORY_SEPARATOR.'deprecation');
diff --git a/src/Symfony/Bridge/PhpUnit/Tests/DeprecationErrorHandler/weak_vendors_on_eval_d_deprecation.phpt b/src/Symfony/Bridge/PhpUnit/Tests/DeprecationErrorHandler/weak_vendors_on_eval_d_deprecation.phpt
new file mode 100644
index 0000000000000..6bba1c86be5ac
--- /dev/null
+++ b/src/Symfony/Bridge/PhpUnit/Tests/DeprecationErrorHandler/weak_vendors_on_eval_d_deprecation.phpt
@@ -0,0 +1,23 @@
+--TEST--
+Test DeprecationErrorHandler in weak vendors mode on eval()'d deprecation
+--FILE--
+
+--EXPECTF--
+
+Other deprecation notices (1)
diff --git a/src/Symfony/Bridge/PhpUnit/Tests/DeprecationErrorHandler/weak_vendors_on_non_vendor.phpt b/src/Symfony/Bridge/PhpUnit/Tests/DeprecationErrorHandler/weak_vendors_on_non_vendor.phpt
index 7568d54a9ce91..e20c7adf6ba1f 100644
--- a/src/Symfony/Bridge/PhpUnit/Tests/DeprecationErrorHandler/weak_vendors_on_non_vendor.phpt
+++ b/src/Symfony/Bridge/PhpUnit/Tests/DeprecationErrorHandler/weak_vendors_on_non_vendor.phpt
@@ -55,20 +55,20 @@ $foo->testNonLegacyBar();
--EXPECTF--
Unsilenced deprecation notices (3)
-unsilenced foo deprecation: 2x
+ 2x: unsilenced foo deprecation
2x in FooTestCase::testLegacyFoo
-unsilenced bar deprecation: 1x
+ 1x: unsilenced bar deprecation
1x in FooTestCase::testNonLegacyBar
Remaining deprecation notices (1)
-silenced bar deprecation: 1x
+ 1x: silenced bar deprecation
1x in FooTestCase::testNonLegacyBar
Legacy deprecation notices (1)
Other deprecation notices (1)
-root deprecation: 1x
+ 1x: root deprecation
diff --git a/src/Symfony/Bridge/PhpUnit/Tests/DeprecationErrorHandler/weak_vendors_on_phar_deprecation.phpt b/src/Symfony/Bridge/PhpUnit/Tests/DeprecationErrorHandler/weak_vendors_on_phar_deprecation.phpt
new file mode 100644
index 0000000000000..4c4879e61156d
--- /dev/null
+++ b/src/Symfony/Bridge/PhpUnit/Tests/DeprecationErrorHandler/weak_vendors_on_phar_deprecation.phpt
@@ -0,0 +1,25 @@
+--TEST--
+Test DeprecationErrorHandler in weak vendors mode on eval()'d deprecation
+The phar can be regenerated by running php src/Symfony/Bridge/PhpUnit/Tests/DeprecationErrorHandler/generate_phar.php
+--FILE--
+
+--EXPECTF--
+
+Other deprecation notices (1)
diff --git a/src/Symfony/Bridge/PhpUnit/bin/simple-phpunit b/src/Symfony/Bridge/PhpUnit/bin/simple-phpunit
index b3f302cd340bf..be0839a9a4075 100755
--- a/src/Symfony/Bridge/PhpUnit/bin/simple-phpunit
+++ b/src/Symfony/Bridge/PhpUnit/bin/simple-phpunit
@@ -76,7 +76,7 @@ if (!file_exists("$PHPUNIT_DIR/phpunit-$PHPUNIT_VERSION/phpunit") || md5_file(__
passthru("$COMPOSER require --no-update symfony/phpunit-bridge \"~3.4-beta5@dev|^4.0-beta5@dev\"");
$prevRoot = getenv('COMPOSER_ROOT_VERSION');
putenv("COMPOSER_ROOT_VERSION=$PHPUNIT_VERSION.99");
- $exit = proc_close(proc_open("$COMPOSER install --no-dev --prefer-dist --no-progress --ansi", array(), $p, getcwd(), null, array('bypass_shell' => true)));
+ $exit = proc_close(proc_open("$COMPOSER install --no-dev --prefer-dist --no-suggest --no-progress --ansi", array(), $p, getcwd(), null, array('bypass_shell' => true)));
putenv('COMPOSER_ROOT_VERSION'.(false !== $prevRoot ? '='.$prevRoot : ''));
if ($exit) {
exit($exit);
diff --git a/src/Symfony/Bundle/FrameworkBundle/Console/Application.php b/src/Symfony/Bundle/FrameworkBundle/Console/Application.php
index 702fece890dbc..062ff3502f4cf 100644
--- a/src/Symfony/Bundle/FrameworkBundle/Console/Application.php
+++ b/src/Symfony/Bundle/FrameworkBundle/Console/Application.php
@@ -35,8 +35,9 @@ public function __construct(KernelInterface $kernel)
parent::__construct('Symfony', Kernel::VERSION);
- $this->getDefinition()->addOption(new InputOption('--env', '-e', InputOption::VALUE_REQUIRED, 'The environment name', $kernel->getEnvironment()));
- $this->getDefinition()->addOption(new InputOption('--no-debug', null, InputOption::VALUE_NONE, 'Switches off debug mode'));
+ $inputDefinition = $this->getDefinition();
+ $inputDefinition->addOption(new InputOption('--env', '-e', InputOption::VALUE_REQUIRED, 'The Environment name.', $kernel->getEnvironment()));
+ $inputDefinition->addOption(new InputOption('--no-debug', null, InputOption::VALUE_NONE, 'Switches off debug mode.'));
}
/**
diff --git a/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Compiler/AddAnnotationsCachedReaderPass.php b/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Compiler/AddAnnotationsCachedReaderPass.php
index 508899379f691..35ea20a89accd 100644
--- a/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Compiler/AddAnnotationsCachedReaderPass.php
+++ b/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Compiler/AddAnnotationsCachedReaderPass.php
@@ -13,7 +13,6 @@
use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
use Symfony\Component\DependencyInjection\ContainerBuilder;
-use Symfony\Component\DependencyInjection\Reference;
/**
* @internal
@@ -29,14 +28,14 @@ public function process(ContainerBuilder $container)
// "annotation_reader" at build time don't get any cache
if ($container->hasDefinition('annotations.cached_reader')) {
$reader = $container->getDefinition('annotations.cached_reader');
- $tags = $reader->getTags();
+ $properties = $reader->getProperties();
- if (isset($tags['annotations.cached_reader'][0]['provider'])) {
- if ($container->hasAlias($provider = $tags['annotations.cached_reader'][0]['provider'])) {
- $provider = (string) $container->getAlias($provider);
- }
+ if (isset($properties['cacheProviderBackup'])) {
+ $provider = $properties['cacheProviderBackup']->getValues()[0];
+ unset($properties['cacheProviderBackup']);
+ $reader->setProperties($properties);
$container->set('annotations.cached_reader', null);
- $container->setDefinition('annotations.cached_reader', $reader->replaceArgument(1, new Reference($provider)));
+ $container->setDefinition('annotations.cached_reader', $reader->replaceArgument(1, $provider));
}
}
}
diff --git a/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/FrameworkExtension.php b/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/FrameworkExtension.php
index 8e561f96a0d5c..c07f07eca16d0 100644
--- a/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/FrameworkExtension.php
+++ b/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/FrameworkExtension.php
@@ -25,6 +25,7 @@
use Symfony\Component\Console\Application;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\DependencyInjection\Alias;
+use Symfony\Component\DependencyInjection\Argument\ServiceClosureArgument;
use Symfony\Component\DependencyInjection\ChildDefinition;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\ContainerInterface;
@@ -757,8 +758,9 @@ private function registerTemplatingConfiguration(array $config, ContainerBuilder
if (1 === count($engines)) {
$container->setAlias('templating', (string) reset($engines));
} else {
+ $templateEngineDefinition = $container->getDefinition('templating.engine.delegating');
foreach ($engines as $engine) {
- $container->getDefinition('templating.engine.delegating')->addMethodCall('addEngine', array($engine));
+ $templateEngineDefinition->addMethodCall('addEngine', array($engine));
}
$container->setAlias('templating', 'templating.engine.delegating');
}
@@ -1131,7 +1133,8 @@ private function registerAnnotationsConfiguration(array $config, ContainerBuilde
$container
->getDefinition('annotations.cached_reader')
->replaceArgument(2, $config['debug'])
- ->addTag('annotations.cached_reader', array('provider' => $cacheService))
+ // temporary property to lazy-reference the cache provider without using it until AddAnnotationsCachedReaderPass runs
+ ->setProperty('cacheProviderBackup', new ServiceClosureArgument(new Reference($cacheService)))
;
$container->setAlias('annotation_reader', 'annotations.cached_reader');
$container->setAlias(Reader::class, new Alias('annotations.cached_reader', false));
diff --git a/src/Symfony/Bundle/FrameworkBundle/FrameworkBundle.php b/src/Symfony/Bundle/FrameworkBundle/FrameworkBundle.php
index a090d9a99cc7a..985b038786b67 100644
--- a/src/Symfony/Bundle/FrameworkBundle/FrameworkBundle.php
+++ b/src/Symfony/Bundle/FrameworkBundle/FrameworkBundle.php
@@ -91,7 +91,7 @@ public function build(ContainerBuilder $container)
$container->addCompilerPass(new RegisterListenersPass(), PassConfig::TYPE_BEFORE_REMOVING);
$container->addCompilerPass(new TemplatingPass());
$this->addCompilerPassIfExists($container, AddConstraintValidatorsPass::class, PassConfig::TYPE_BEFORE_REMOVING);
- $container->addCompilerPass(new AddAnnotationsCachedReaderPass(), PassConfig::TYPE_BEFORE_REMOVING);
+ $container->addCompilerPass(new AddAnnotationsCachedReaderPass(), PassConfig::TYPE_AFTER_REMOVING, -255);
$this->addCompilerPassIfExists($container, AddValidatorInitializersPass::class);
$this->addCompilerPassIfExists($container, AddConsoleCommandPass::class);
$container->addCompilerPass(new TranslatorPass());
diff --git a/src/Symfony/Bundle/FrameworkBundle/Resources/config/schema/symfony-1.0.xsd b/src/Symfony/Bundle/FrameworkBundle/Resources/config/schema/symfony-1.0.xsd
index 5d979c9bb7de6..993cf6f3e57c0 100644
--- a/src/Symfony/Bundle/FrameworkBundle/Resources/config/schema/symfony-1.0.xsd
+++ b/src/Symfony/Bundle/FrameworkBundle/Resources/config/schema/symfony-1.0.xsd
@@ -102,6 +102,7 @@
+
diff --git a/src/Symfony/Bundle/FrameworkBundle/Tests/Functional/Bundle/TestBundle/TestBundle.php b/src/Symfony/Bundle/FrameworkBundle/Tests/Functional/Bundle/TestBundle/TestBundle.php
index d63658bacf021..193442ff956cc 100644
--- a/src/Symfony/Bundle/FrameworkBundle/Tests/Functional/Bundle/TestBundle/TestBundle.php
+++ b/src/Symfony/Bundle/FrameworkBundle/Tests/Functional/Bundle/TestBundle/TestBundle.php
@@ -12,6 +12,7 @@
namespace Symfony\Bundle\FrameworkBundle\Tests\Functional\Bundle\TestBundle;
use Symfony\Component\HttpKernel\Bundle\Bundle;
+use Symfony\Component\DependencyInjection\Compiler\PassConfig;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Bundle\FrameworkBundle\Tests\Functional\Bundle\TestBundle\DependencyInjection\AnnotationReaderPass;
use Symfony\Bundle\FrameworkBundle\Tests\Functional\Bundle\TestBundle\DependencyInjection\Config\CustomConfig;
@@ -27,6 +28,6 @@ public function build(ContainerBuilder $container)
$extension->setCustomConfig(new CustomConfig());
- $container->addCompilerPass(new AnnotationReaderPass());
+ $container->addCompilerPass(new AnnotationReaderPass(), PassConfig::TYPE_AFTER_REMOVING);
}
}
diff --git a/src/Symfony/Bundle/SecurityBundle/DependencyInjection/Security/UserProvider/InMemoryFactory.php b/src/Symfony/Bundle/SecurityBundle/DependencyInjection/Security/UserProvider/InMemoryFactory.php
index f226b47cf5cc5..ab0ada84d6485 100644
--- a/src/Symfony/Bundle/SecurityBundle/DependencyInjection/Security/UserProvider/InMemoryFactory.php
+++ b/src/Symfony/Bundle/SecurityBundle/DependencyInjection/Security/UserProvider/InMemoryFactory.php
@@ -14,7 +14,6 @@
use Symfony\Component\Config\Definition\Builder\NodeDefinition;
use Symfony\Component\DependencyInjection\ChildDefinition;
use Symfony\Component\DependencyInjection\ContainerBuilder;
-use Symfony\Component\DependencyInjection\Reference;
/**
* InMemoryFactory creates services for the memory provider.
@@ -27,17 +26,13 @@ class InMemoryFactory implements UserProviderFactoryInterface
public function create(ContainerBuilder $container, $id, $config)
{
$definition = $container->setDefinition($id, new ChildDefinition('security.user.provider.in_memory'));
+ $users = array();
foreach ($config['users'] as $username => $user) {
- $userId = $id.'_'.$username;
-
- $container
- ->setDefinition($userId, new ChildDefinition('security.user.provider.in_memory.user'))
- ->setArguments(array($username, (string) $user['password'], $user['roles']))
- ;
-
- $definition->addMethodCall('createUser', array(new Reference($userId)));
+ $users[$username] = array('password' => (string) $user['password'], 'roles' => $user['roles']);
}
+
+ $definition->addArgument($users);
}
public function getKey()
diff --git a/src/Symfony/Bundle/SecurityBundle/Tests/DependencyInjection/CompleteConfigurationTest.php b/src/Symfony/Bundle/SecurityBundle/Tests/DependencyInjection/CompleteConfigurationTest.php
index f717c0332c96f..3207430a9dfe9 100644
--- a/src/Symfony/Bundle/SecurityBundle/Tests/DependencyInjection/CompleteConfigurationTest.php
+++ b/src/Symfony/Bundle/SecurityBundle/Tests/DependencyInjection/CompleteConfigurationTest.php
@@ -43,12 +43,8 @@ public function testUserProviders()
$expectedProviders = array(
'security.user.provider.concrete.default',
- 'security.user.provider.concrete.default_foo',
'security.user.provider.concrete.digest',
- 'security.user.provider.concrete.digest_foo',
'security.user.provider.concrete.basic',
- 'security.user.provider.concrete.basic_foo',
- 'security.user.provider.concrete.basic_bar',
'security.user.provider.concrete.service',
'security.user.provider.concrete.chain',
);
diff --git a/src/Symfony/Bundle/SecurityBundle/Tests/DependencyInjection/MainConfigurationTest.php b/src/Symfony/Bundle/SecurityBundle/Tests/DependencyInjection/MainConfigurationTest.php
index 6ecfba2922b67..24447ee89abee 100644
--- a/src/Symfony/Bundle/SecurityBundle/Tests/DependencyInjection/MainConfigurationTest.php
+++ b/src/Symfony/Bundle/SecurityBundle/Tests/DependencyInjection/MainConfigurationTest.php
@@ -84,9 +84,9 @@ public function testCsrfAliases()
$processor = new Processor();
$configuration = new MainConfiguration(array(), array());
$processedConfig = $processor->processConfiguration($configuration, array($config));
- $this->assertTrue(isset($processedConfig['firewalls']['stub']['logout']['csrf_token_generator']));
+ $this->assertArrayHasKey('csrf_token_generator', $processedConfig['firewalls']['stub']['logout']);
$this->assertEquals('a_token_generator', $processedConfig['firewalls']['stub']['logout']['csrf_token_generator']);
- $this->assertTrue(isset($processedConfig['firewalls']['stub']['logout']['csrf_token_id']));
+ $this->assertArrayHasKey('csrf_token_id', $processedConfig['firewalls']['stub']['logout']);
$this->assertEquals('a_token_id', $processedConfig['firewalls']['stub']['logout']['csrf_token_id']);
}
diff --git a/src/Symfony/Bundle/TwigBundle/DependencyInjection/Compiler/ExtensionPass.php b/src/Symfony/Bundle/TwigBundle/DependencyInjection/Compiler/ExtensionPass.php
index 4a642d1e96505..5339f2a4df47b 100644
--- a/src/Symfony/Bundle/TwigBundle/DependencyInjection/Compiler/ExtensionPass.php
+++ b/src/Symfony/Bundle/TwigBundle/DependencyInjection/Compiler/ExtensionPass.php
@@ -82,7 +82,11 @@ public function process(ContainerBuilder $container)
if ($container->getParameter('kernel.debug')) {
$container->getDefinition('twig.extension.profiler')->addTag('twig.extension');
- $container->getDefinition('twig.extension.debug')->addTag('twig.extension');
+
+ // only register if the improved version from DebugBundle is *not* present
+ if (!$container->has('twig.extension.dump')) {
+ $container->getDefinition('twig.extension.debug')->addTag('twig.extension');
+ }
}
$twigLoader = $container->getDefinition('twig.loader.native_filesystem');
diff --git a/src/Symfony/Bundle/TwigBundle/Resources/config/twig.xml b/src/Symfony/Bundle/TwigBundle/Resources/config/twig.xml
index 310ab14063a0b..16881d426c8bd 100644
--- a/src/Symfony/Bundle/TwigBundle/Resources/config/twig.xml
+++ b/src/Symfony/Bundle/TwigBundle/Resources/config/twig.xml
@@ -125,6 +125,7 @@
%twig.exception_listener.controller%
+ %kernel.debug%
diff --git a/src/Symfony/Bundle/WebProfilerBundle/Resources/views/Collector/events.html.twig b/src/Symfony/Bundle/WebProfilerBundle/Resources/views/Collector/events.html.twig
index 238096157acc3..53040a0d9b9b2 100644
--- a/src/Symfony/Bundle/WebProfilerBundle/Resources/views/Collector/events.html.twig
+++ b/src/Symfony/Bundle/WebProfilerBundle/Resources/views/Collector/events.html.twig
@@ -74,7 +74,7 @@
{% endif %}
-
{{ listener.priority|default('-') }}
+
{{ listener.priority|default('-') }}
{{ profiler_dump(listener.stub) }}
diff --git a/src/Symfony/Bundle/WebProfilerBundle/Resources/views/Collector/translation.html.twig b/src/Symfony/Bundle/WebProfilerBundle/Resources/views/Collector/translation.html.twig
index 31881953d8139..ec18aa5a29cdb 100644
--- a/src/Symfony/Bundle/WebProfilerBundle/Resources/views/Collector/translation.html.twig
+++ b/src/Symfony/Bundle/WebProfilerBundle/Resources/views/Collector/translation.html.twig
@@ -168,9 +168,9 @@
{% for message in messages %}
{% if trace.level == 1 %}
Path almost matches, but
diff --git a/src/Symfony/Component/Cache/Adapter/AdapterInterface.php b/src/Symfony/Component/Cache/Adapter/AdapterInterface.php
index 274ebec1ef445..41222c1ab57ce 100644
--- a/src/Symfony/Component/Cache/Adapter/AdapterInterface.php
+++ b/src/Symfony/Component/Cache/Adapter/AdapterInterface.php
@@ -31,7 +31,7 @@ public function getItem($key);
/**
* {@inheritdoc}
*
- * return \Traversable|CacheItem[]
+ * @return \Traversable|CacheItem[]
*/
public function getItems(array $keys = array());
}
diff --git a/src/Symfony/Component/Cache/Tests/Adapter/ApcuAdapterTest.php b/src/Symfony/Component/Cache/Tests/Adapter/ApcuAdapterTest.php
index 75b3fa299ec29..72df12e4b593f 100644
--- a/src/Symfony/Component/Cache/Tests/Adapter/ApcuAdapterTest.php
+++ b/src/Symfony/Component/Cache/Tests/Adapter/ApcuAdapterTest.php
@@ -29,7 +29,7 @@ public function createCachePool($defaultLifetime = 0)
}
if ('cli' === PHP_SAPI && !ini_get('apc.enable_cli')) {
if ('testWithCliSapi' !== $this->getName()) {
- $this->markTestSkipped('APCu extension is required.');
+ $this->markTestSkipped('apc.enable_cli=1 is required.');
}
}
if ('\\' === DIRECTORY_SEPARATOR) {
diff --git a/src/Symfony/Component/Cache/Traits/ApcuTrait.php b/src/Symfony/Component/Cache/Traits/ApcuTrait.php
index 5614b390cf2f4..fe7dfbab7d8c0 100644
--- a/src/Symfony/Component/Cache/Traits/ApcuTrait.php
+++ b/src/Symfony/Component/Cache/Traits/ApcuTrait.php
@@ -52,7 +52,11 @@ private function init($namespace, $defaultLifetime, $version)
protected function doFetch(array $ids)
{
try {
- return apcu_fetch($ids) ?: array();
+ foreach (apcu_fetch($ids, $ok) ?: array() as $k => $v) {
+ if (null !== $v || $ok) {
+ yield $k => $v;
+ }
+ }
} catch (\Error $e) {
throw new \ErrorException($e->getMessage(), $e->getCode(), E_ERROR, $e->getFile(), $e->getLine());
}
diff --git a/src/Symfony/Component/Console/Input/ArgvInput.php b/src/Symfony/Component/Console/Input/ArgvInput.php
index b576cf42a903a..1a430f1ff9641 100644
--- a/src/Symfony/Component/Console/Input/ArgvInput.php
+++ b/src/Symfony/Component/Console/Input/ArgvInput.php
@@ -285,16 +285,6 @@ public function hasParameterOption($values, $onlyParams = false)
if ($token === $value || 0 === strpos($token, $value.'=')) {
return true;
}
-
- if (0 === strpos($token, '-') && 0 !== strpos($token, '--')) {
- $noValue = explode('=', $token);
- $token = $noValue[0];
- $searchableToken = str_replace('-', '', $token);
- $searchableValue = str_replace('-', '', $value);
- if ('' !== $searchableToken && '' !== $searchableValue && false !== strpos($searchableToken, $searchableValue)) {
- return true;
- }
- }
}
}
diff --git a/src/Symfony/Component/Console/Input/StringInput.php b/src/Symfony/Component/Console/Input/StringInput.php
index d3630fc0d6157..969b9da747433 100644
--- a/src/Symfony/Component/Console/Input/StringInput.php
+++ b/src/Symfony/Component/Console/Input/StringInput.php
@@ -28,7 +28,7 @@ class StringInput extends ArgvInput
const REGEX_QUOTED_STRING = '(?:"([^"\\\\]*(?:\\\\.[^"\\\\]*)*)"|\'([^\'\\\\]*(?:\\\\.[^\'\\\\]*)*)\')';
/**
- * @param string $input An array of parameters from the CLI (in the argv format)
+ * @param string $input A string representing the parameters from the CLI
*/
public function __construct($input)
{
diff --git a/src/Symfony/Component/Console/Style/StyleInterface.php b/src/Symfony/Component/Console/Style/StyleInterface.php
index a9205e5a70623..475c268ffe403 100644
--- a/src/Symfony/Component/Console/Style/StyleInterface.php
+++ b/src/Symfony/Component/Console/Style/StyleInterface.php
@@ -91,7 +91,7 @@ public function table(array $headers, array $rows);
* @param string|null $default
* @param callable|null $validator
*
- * @return string
+ * @return mixed
*/
public function ask($question, $default = null, $validator = null);
@@ -101,7 +101,7 @@ public function ask($question, $default = null, $validator = null);
* @param string $question
* @param callable|null $validator
*
- * @return string
+ * @return mixed
*/
public function askHidden($question, $validator = null);
@@ -122,7 +122,7 @@ public function confirm($question, $default = true);
* @param array $choices
* @param string|int|null $default
*
- * @return string
+ * @return mixed
*/
public function choice($question, array $choices, $default = null);
diff --git a/src/Symfony/Component/Console/Style/SymfonyStyle.php b/src/Symfony/Component/Console/Style/SymfonyStyle.php
index 3717f8802e6ff..6cf53cd924255 100644
--- a/src/Symfony/Component/Console/Style/SymfonyStyle.php
+++ b/src/Symfony/Component/Console/Style/SymfonyStyle.php
@@ -279,7 +279,7 @@ public function createProgressBar($max = 0)
}
/**
- * @return string
+ * @return mixed
*/
public function askQuestion(Question $question)
{
diff --git a/src/Symfony/Component/Console/Tests/Input/ArgvInputTest.php b/src/Symfony/Component/Console/Tests/Input/ArgvInputTest.php
index 01d6e4b96a0c2..8287bce521d37 100644
--- a/src/Symfony/Component/Console/Tests/Input/ArgvInputTest.php
+++ b/src/Symfony/Component/Console/Tests/Input/ArgvInputTest.php
@@ -314,12 +314,6 @@ public function testHasParameterOption()
$input = new ArgvInput(array('cli.php', '-f', 'foo'));
$this->assertTrue($input->hasParameterOption('-f'), '->hasParameterOption() returns true if the given short option is in the raw input');
- $input = new ArgvInput(array('cli.php', '-fh'));
- $this->assertTrue($input->hasParameterOption('-fh'), '->hasParameterOption() returns true if the given short option is in the raw input');
-
- $input = new ArgvInput(array('cli.php', '-e=test'));
- $this->assertFalse($input->hasParameterOption('-s'), '->hasParameterOption() returns true if the given short option is in the raw input');
-
$input = new ArgvInput(array('cli.php', '--foo', 'foo'));
$this->assertTrue($input->hasParameterOption('--foo'), '->hasParameterOption() returns true if the given short option is in the raw input');
diff --git a/src/Symfony/Component/Debug/ErrorHandler.php b/src/Symfony/Component/Debug/ErrorHandler.php
index 853e7641392b4..678e42429e74c 100644
--- a/src/Symfony/Component/Debug/ErrorHandler.php
+++ b/src/Symfony/Component/Debug/ErrorHandler.php
@@ -134,11 +134,14 @@ public static function register(self $handler = null, $replace = true)
$handler = $prev[0];
$replace = false;
}
- if ($replace || !$prev) {
- $handler->setExceptionHandler(set_exception_handler(array($handler, 'handleException')));
- } else {
+ if (!$replace && $prev) {
restore_error_handler();
}
+ if (is_array($prev = set_exception_handler(array($handler, 'handleException'))) && $prev[0] === $handler) {
+ restore_exception_handler();
+ } else {
+ $handler->setExceptionHandler($prev);
+ }
$handler->throwAt(E_ALL & $handler->thrownErrors, true);
@@ -592,6 +595,8 @@ public static function handleFatalError(array $error = null)
$handler = self::$reservedMemory = null;
$handlers = array();
+ $previousHandler = null;
+ $sameHandlerLimit = 10;
while (!is_array($handler) || !$handler[0] instanceof self) {
$handler = set_exception_handler('var_dump');
@@ -601,7 +606,14 @@ public static function handleFatalError(array $error = null)
break;
}
restore_exception_handler();
- array_unshift($handlers, $handler);
+
+ if ($handler !== $previousHandler) {
+ array_unshift($handlers, $handler);
+ $previousHandler = $handler;
+ } elseif (0 === --$sameHandlerLimit) {
+ $handler = null;
+ break;
+ }
}
foreach ($handlers as $h) {
set_exception_handler($h);
diff --git a/src/Symfony/Component/Debug/Tests/ErrorHandlerTest.php b/src/Symfony/Component/Debug/Tests/ErrorHandlerTest.php
index a14accf3df9a0..8041b62a4c8b6 100644
--- a/src/Symfony/Component/Debug/Tests/ErrorHandlerTest.php
+++ b/src/Symfony/Component/Debug/Tests/ErrorHandlerTest.php
@@ -301,6 +301,9 @@ public function testHandleDeprecation()
@$handler->handleError(E_USER_DEPRECATED, 'Foo deprecation', __FILE__, __LINE__, array());
}
+ /**
+ * @group no-hhvm
+ */
public function testHandleException()
{
try {
@@ -422,6 +425,9 @@ public function testBootstrappingLogger()
$handler->setLoggers(array(E_DEPRECATED => array($mockLogger, LogLevel::WARNING)));
}
+ /**
+ * @group no-hhvm
+ */
public function testSettingLoggerWhenExceptionIsBuffered()
{
$bootLogger = new BufferingLogger();
@@ -441,6 +447,9 @@ public function testSettingLoggerWhenExceptionIsBuffered()
$handler->handleException($exception);
}
+ /**
+ * @group no-hhvm
+ */
public function testHandleFatalError()
{
try {
@@ -499,6 +508,9 @@ public function testHandleErrorException()
$this->assertStringStartsWith("Attempted to load class \"Foo\" from the global namespace.\nDid you forget a \"use\" statement", $args[0]->getMessage());
}
+ /**
+ * @group no-hhvm
+ */
public function testHandleFatalErrorOnHHVM()
{
try {
diff --git a/src/Symfony/Component/Debug/Tests/phpt/decorate_exception_hander.phpt b/src/Symfony/Component/Debug/Tests/phpt/decorate_exception_hander.phpt
new file mode 100644
index 0000000000000..7ce7b9dc6f7dd
--- /dev/null
+++ b/src/Symfony/Component/Debug/Tests/phpt/decorate_exception_hander.phpt
@@ -0,0 +1,47 @@
+--TEST--
+Test catching fatal errors when handlers are nested
+--FILE--
+
+--EXPECTF--
+Fatal error: Class 'Symfony\Component\Debug\missing' not found in %s on line %d
+object(Symfony\Component\Debug\Exception\ClassNotFoundException)#%d (8) {
+ ["message":protected]=>
+ string(131) "Attempted to load class "missing" from namespace "Symfony\Component\Debug".
+Did you forget a "use" statement for another namespace?"
+ ["string":"Exception":private]=>
+ string(0) ""
+ ["code":protected]=>
+ int(0)
+ ["file":protected]=>
+ string(%d) "%s"
+ ["line":protected]=>
+ int(%d)
+ ["trace":"Exception":private]=>
+ array(0) {
+ }
+ ["previous":"Exception":private]=>
+ NULL
+ ["severity":protected]=>
+ int(1)
+}
diff --git a/src/Symfony/Component/DependencyInjection/Compiler/AbstractRecursivePass.php b/src/Symfony/Component/DependencyInjection/Compiler/AbstractRecursivePass.php
index 8ded4ba6d1cdf..8576ed207ab9a 100644
--- a/src/Symfony/Component/DependencyInjection/Compiler/AbstractRecursivePass.php
+++ b/src/Symfony/Component/DependencyInjection/Compiler/AbstractRecursivePass.php
@@ -49,7 +49,7 @@ public function process(ContainerBuilder $container)
*/
protected function processValue($value, $isRoot = false)
{
- if (is_array($value)) {
+ if (\is_array($value)) {
foreach ($value as $k => $v) {
if ($isRoot) {
$this->currentId = $k;
diff --git a/src/Symfony/Component/DependencyInjection/ContainerBuilder.php b/src/Symfony/Component/DependencyInjection/ContainerBuilder.php
index 75181796b4ac6..8c63380329a25 100644
--- a/src/Symfony/Component/DependencyInjection/ContainerBuilder.php
+++ b/src/Symfony/Component/DependencyInjection/ContainerBuilder.php
@@ -419,12 +419,16 @@ public function fileExists($path, $trackContents = true)
* @throws BadMethodCallException When this ContainerBuilder is compiled
* @throws \LogicException if the extension is not registered
*/
- public function loadFromExtension($extension, array $values = array())
+ public function loadFromExtension($extension, array $values = null)
{
if ($this->isCompiled()) {
throw new BadMethodCallException('Cannot load from an extension on a compiled container.');
}
+ if (func_num_args() < 2) {
+ $values = array();
+ }
+
$namespace = $this->getExtension($extension)->getAlias();
$this->extensionConfigs[$namespace][] = $values;
diff --git a/src/Symfony/Component/DependencyInjection/Loader/XmlFileLoader.php b/src/Symfony/Component/DependencyInjection/Loader/XmlFileLoader.php
index 63e524661e1b5..b29c1f283b457 100644
--- a/src/Symfony/Component/DependencyInjection/Loader/XmlFileLoader.php
+++ b/src/Symfony/Component/DependencyInjection/Loader/XmlFileLoader.php
@@ -573,16 +573,20 @@ public function validateSchema(\DOMDocument $dom)
$imports = '';
foreach ($schemaLocations as $namespace => $location) {
$parts = explode('/', $location);
+ $locationstart = 'file:///';
if (0 === stripos($location, 'phar://')) {
$tmpfile = tempnam(sys_get_temp_dir(), 'sf2');
if ($tmpfile) {
copy($location, $tmpfile);
$tmpfiles[] = $tmpfile;
$parts = explode('/', str_replace('\\', '/', $tmpfile));
+ } else {
+ array_shift($parts);
+ $locationstart = 'phar:///';
}
}
$drive = '\\' === DIRECTORY_SEPARATOR ? array_shift($parts).'/' : '';
- $location = 'file:///'.$drive.implode('/', array_map('rawurlencode', $parts));
+ $location = $locationstart.$drive.implode('/', array_map('rawurlencode', $parts));
$imports .= sprintf(' '."\n", $namespace, $location);
}
diff --git a/src/Symfony/Component/DependencyInjection/Loader/YamlFileLoader.php b/src/Symfony/Component/DependencyInjection/Loader/YamlFileLoader.php
index 76e9f34185034..1008671386574 100644
--- a/src/Symfony/Component/DependencyInjection/Loader/YamlFileLoader.php
+++ b/src/Symfony/Component/DependencyInjection/Loader/YamlFileLoader.php
@@ -755,7 +755,7 @@ private function loadFromExtensions(array $content)
continue;
}
- if (!is_array($values)) {
+ if (!is_array($values) && null !== $values) {
$values = array();
}
diff --git a/src/Symfony/Component/DependencyInjection/Tests/Compiler/ResolveDefinitionTemplatesPassTest.php b/src/Symfony/Component/DependencyInjection/Tests/Compiler/ResolveDefinitionTemplatesPassTest.php
index 9c64c502f659a..4c2f65208ad5e 100644
--- a/src/Symfony/Component/DependencyInjection/Tests/Compiler/ResolveDefinitionTemplatesPassTest.php
+++ b/src/Symfony/Component/DependencyInjection/Tests/Compiler/ResolveDefinitionTemplatesPassTest.php
@@ -259,23 +259,23 @@ public function testDeepDefinitionsResolving()
$this->process($container);
$configurator = $container->getDefinition('sibling')->getConfigurator();
- $this->assertSame('Symfony\Component\DependencyInjection\Definition', get_class($configurator));
+ $this->assertInstanceOf('Symfony\Component\DependencyInjection\Definition', $configurator);
$this->assertSame('parentClass', $configurator->getClass());
$factory = $container->getDefinition('sibling')->getFactory();
- $this->assertSame('Symfony\Component\DependencyInjection\Definition', get_class($factory[0]));
+ $this->assertInstanceOf('Symfony\Component\DependencyInjection\Definition', $factory[0]);
$this->assertSame('parentClass', $factory[0]->getClass());
$argument = $container->getDefinition('sibling')->getArgument(0);
- $this->assertSame('Symfony\Component\DependencyInjection\Definition', get_class($argument));
+ $this->assertInstanceOf('Symfony\Component\DependencyInjection\Definition', $argument);
$this->assertSame('parentClass', $argument->getClass());
$properties = $container->getDefinition('sibling')->getProperties();
- $this->assertSame('Symfony\Component\DependencyInjection\Definition', get_class($properties['prop']));
+ $this->assertInstanceOf('Symfony\Component\DependencyInjection\Definition', $properties['prop']);
$this->assertSame('parentClass', $properties['prop']->getClass());
$methodCalls = $container->getDefinition('sibling')->getMethodCalls();
- $this->assertSame('Symfony\Component\DependencyInjection\Definition', get_class($methodCalls[0][1][0]));
+ $this->assertInstanceOf('Symfony\Component\DependencyInjection\Definition', $methodCalls[0][1][0]);
$this->assertSame('parentClass', $methodCalls[0][1][0]->getClass());
}
diff --git a/src/Symfony/Component/DependencyInjection/Tests/Fixtures/includes/ProjectExtension.php b/src/Symfony/Component/DependencyInjection/Tests/Fixtures/includes/ProjectExtension.php
index c9f8010268717..ba07d7c44cbd6 100644
--- a/src/Symfony/Component/DependencyInjection/Tests/Fixtures/includes/ProjectExtension.php
+++ b/src/Symfony/Component/DependencyInjection/Tests/Fixtures/includes/ProjectExtension.php
@@ -8,7 +8,14 @@ class ProjectExtension implements ExtensionInterface
{
public function load(array $configs, ContainerBuilder $configuration)
{
- $config = call_user_func_array('array_merge', $configs);
+ $configuration->setParameter('project.configs', $configs);
+ $configs = array_filter($configs);
+
+ if ($configs) {
+ $config = call_user_func_array('array_merge', $configs);
+ } else {
+ $config = array();
+ }
$configuration->setDefinition('project.service.bar', new Definition('FooClass'));
$configuration->setParameter('project.parameter.bar', isset($config['foo']) ? $config['foo'] : 'foobar');
diff --git a/src/Symfony/Component/DependencyInjection/Tests/Fixtures/yaml/null_config.yml b/src/Symfony/Component/DependencyInjection/Tests/Fixtures/yaml/null_config.yml
new file mode 100644
index 0000000000000..e88e12e2f286e
--- /dev/null
+++ b/src/Symfony/Component/DependencyInjection/Tests/Fixtures/yaml/null_config.yml
@@ -0,0 +1 @@
+project: ~
diff --git a/src/Symfony/Component/DependencyInjection/Tests/Loader/YamlFileLoaderTest.php b/src/Symfony/Component/DependencyInjection/Tests/Loader/YamlFileLoaderTest.php
index 0f5147d014d48..bb593b6cf303d 100644
--- a/src/Symfony/Component/DependencyInjection/Tests/Loader/YamlFileLoaderTest.php
+++ b/src/Symfony/Component/DependencyInjection/Tests/Loader/YamlFileLoaderTest.php
@@ -219,6 +219,17 @@ public function testExtensions()
}
}
+ public function testExtensionWithNullConfig()
+ {
+ $container = new ContainerBuilder();
+ $container->registerExtension(new \ProjectExtension());
+ $loader = new YamlFileLoader($container, new FileLocator(self::$fixturesPath.'/yaml'));
+ $loader->load('null_config.yml');
+ $container->compile();
+
+ $this->assertSame(array(null), $container->getParameter('project.configs'));
+ }
+
public function testSupports()
{
$loader = new YamlFileLoader(new ContainerBuilder(), new FileLocator());
diff --git a/src/Symfony/Component/Form/Button.php b/src/Symfony/Component/Form/Button.php
index 3dbe110fcb084..d7832753131d9 100644
--- a/src/Symfony/Component/Form/Button.php
+++ b/src/Symfony/Component/Form/Button.php
@@ -106,6 +106,10 @@ public function offsetUnset($offset)
*/
public function setParent(FormInterface $parent = null)
{
+ if ($this->submitted) {
+ throw new AlreadySubmittedException('You cannot set the parent of a submitted button');
+ }
+
$this->parent = $parent;
}
diff --git a/src/Symfony/Component/Form/Extension/Core/DataTransformer/DateTimeToLocalizedStringTransformer.php b/src/Symfony/Component/Form/Extension/Core/DataTransformer/DateTimeToLocalizedStringTransformer.php
index dda3414b75f2c..69bcd2412fac6 100644
--- a/src/Symfony/Component/Form/Extension/Core/DataTransformer/DateTimeToLocalizedStringTransformer.php
+++ b/src/Symfony/Component/Form/Extension/Core/DataTransformer/DateTimeToLocalizedStringTransformer.php
@@ -122,6 +122,9 @@ public function reverseTransform($value)
if (0 != intl_get_error_code()) {
throw new TransformationFailedException(intl_get_error_message());
+ } elseif ($timestamp > 253402214400) {
+ // This timestamp represents UTC midnight of 9999-12-31 to prevent 5+ digit years
+ throw new TransformationFailedException('Years beyond 9999 are not supported.');
}
try {
diff --git a/src/Symfony/Component/Form/Resources/translations/validators.nb.xlf b/src/Symfony/Component/Form/Resources/translations/validators.nb.xlf
new file mode 100644
index 0000000000000..c64266c99189b
--- /dev/null
+++ b/src/Symfony/Component/Form/Resources/translations/validators.nb.xlf
@@ -0,0 +1,19 @@
+
+
+
+
+
+ This form should not contain extra fields.
+ Feltgruppen må ikke inneholde ekstra felter.
+
+
+ The uploaded file was too large. Please try to upload a smaller file.
+ Den opplastede filen var for stor. Vennligst last opp en mindre fil.
+
+
+ The CSRF token is invalid.
+ CSRF nøkkelen er ugyldig.
+
+
+
+
diff --git a/src/Symfony/Component/Form/Resources/translations/validators.nn.xlf b/src/Symfony/Component/Form/Resources/translations/validators.nn.xlf
new file mode 100644
index 0000000000000..2f5da23444d0b
--- /dev/null
+++ b/src/Symfony/Component/Form/Resources/translations/validators.nn.xlf
@@ -0,0 +1,19 @@
+
+
+
+
+
+ This form should not contain extra fields.
+ Feltgruppa må ikkje innehalde ekstra felt.
+
+
+ The uploaded file was too large. Please try to upload a smaller file.
+ Fila du lasta opp var for stor. Last opp ei mindre fil.
+
+
+ The CSRF token is invalid.
+ CSRF-nøkkelen er ikkje gyldig.
+
+
+
+
diff --git a/src/Symfony/Component/Form/SubmitButton.php b/src/Symfony/Component/Form/SubmitButton.php
index ae69e0426d6b1..2422e11cd898a 100644
--- a/src/Symfony/Component/Form/SubmitButton.php
+++ b/src/Symfony/Component/Form/SubmitButton.php
@@ -43,6 +43,12 @@ public function isClicked()
*/
public function submit($submittedData, $clearMissing = true)
{
+ if ($this->getConfig()->getDisabled()) {
+ $this->clicked = false;
+
+ return $this;
+ }
+
parent::submit($submittedData, $clearMissing);
$this->clicked = null !== $submittedData;
diff --git a/src/Symfony/Component/Form/Test/TypeTestCase.php b/src/Symfony/Component/Form/Test/TypeTestCase.php
index ff3f78292f5f0..9b321d728f0ea 100644
--- a/src/Symfony/Component/Form/Test/TypeTestCase.php
+++ b/src/Symfony/Component/Form/Test/TypeTestCase.php
@@ -34,11 +34,6 @@ protected function setUp()
$this->builder = new FormBuilder(null, null, $this->dispatcher, $this->factory);
}
- public static function assertDateTimeEquals(\DateTime $expected, \DateTime $actual)
- {
- self::assertEquals($expected->format('c'), $actual->format('c'));
- }
-
public static function assertDateIntervalEquals(\DateInterval $expected, \DateInterval $actual)
{
self::assertEquals($expected->format('%RP%yY%mM%dDT%hH%iM%sS'), $actual->format('%RP%yY%mM%dDT%hH%iM%sS'));
diff --git a/src/Symfony/Component/Form/Tests/AbstractLayoutTest.php b/src/Symfony/Component/Form/Tests/AbstractLayoutTest.php
index db6c64d54e3a4..131d66e2c658c 100644
--- a/src/Symfony/Component/Form/Tests/AbstractLayoutTest.php
+++ b/src/Symfony/Component/Form/Tests/AbstractLayoutTest.php
@@ -58,7 +58,7 @@ protected function assertXpathNodeValue(\DOMElement $element, $expression, $node
protected function assertMatchesXpath($html, $expression, $count = 1)
{
- $dom = new \DomDocument('UTF-8');
+ $dom = new \DOMDocument('UTF-8');
try {
// Wrap in node so we can load HTML with multiple tags at
// the top level
diff --git a/src/Symfony/Component/Form/Tests/ButtonTest.php b/src/Symfony/Component/Form/Tests/ButtonTest.php
index 08d2d74e65b37..a81c2db5511c1 100644
--- a/src/Symfony/Component/Form/Tests/ButtonTest.php
+++ b/src/Symfony/Component/Form/Tests/ButtonTest.php
@@ -30,6 +30,20 @@ protected function setUp()
$this->factory = $this->getMockBuilder('Symfony\Component\Form\FormFactoryInterface')->getMock();
}
+ /**
+ * @expectedException \Symfony\Component\Form\Exception\AlreadySubmittedException
+ */
+ public function testSetParentOnSubmittedButton()
+ {
+ $button = $this->getButtonBuilder('button')
+ ->getForm()
+ ;
+
+ $button->submit('');
+
+ $button->setParent($this->getFormBuilder('form')->getForm());
+ }
+
/**
* @dataProvider getDisabledStates
*/
@@ -37,11 +51,13 @@ public function testDisabledIfParentIsDisabled($parentDisabled, $buttonDisabled,
{
$form = $this->getFormBuilder('form')
->setDisabled($parentDisabled)
- ->getForm();
+ ->getForm()
+ ;
$button = $this->getButtonBuilder('button')
->setDisabled($buttonDisabled)
- ->getForm();
+ ->getForm()
+ ;
$button->setParent($form);
diff --git a/src/Symfony/Component/Form/Tests/CompoundFormTest.php b/src/Symfony/Component/Form/Tests/CompoundFormTest.php
index bcf1b8c4f9aa7..85813a1ffbc36 100644
--- a/src/Symfony/Component/Form/Tests/CompoundFormTest.php
+++ b/src/Symfony/Component/Form/Tests/CompoundFormTest.php
@@ -1014,6 +1014,28 @@ public function testClickedButtonFromParentForm()
$this->assertSame($button, $this->form->getClickedButton());
}
+ public function testDisabledButtonIsNotSubmitted()
+ {
+ $button = new SubmitButtonBuilder('submit');
+ $submit = $button
+ ->setDisabled(true)
+ ->getForm();
+
+ $form = $this->createForm()
+ ->add($this->getBuilder('text')->getForm())
+ ->add($submit)
+ ;
+
+ $form->submit(array(
+ 'text' => '',
+ 'submit' => '',
+ ));
+
+ $this->assertTrue($submit->isDisabled());
+ $this->assertFalse($submit->isClicked());
+ $this->assertFalse($submit->isSubmitted());
+ }
+
protected function createForm()
{
return $this->getBuilder()
diff --git a/src/Symfony/Component/Form/Tests/Extension/Core/DataTransformer/DateTimeTestCase.php b/src/Symfony/Component/Form/Tests/Extension/Core/DataTransformer/DateTimeTestCase.php
deleted file mode 100644
index c6d1a07cd7803..0000000000000
--- a/src/Symfony/Component/Form/Tests/Extension/Core/DataTransformer/DateTimeTestCase.php
+++ /dev/null
@@ -1,22 +0,0 @@
-
- *
- * For the full copyright and license information, please view the LICENSE
- * file that was distributed with this source code.
- */
-
-namespace Symfony\Component\Form\Tests\Extension\Core\DataTransformer;
-
-use PHPUnit\Framework\TestCase;
-
-abstract class DateTimeTestCase extends TestCase
-{
- public static function assertDateTimeEquals(\DateTime $expected, \DateTime $actual)
- {
- self::assertEquals($expected->format('U'), $actual->format('U'));
- }
-}
diff --git a/src/Symfony/Component/Form/Tests/Extension/Core/DataTransformer/DateTimeToArrayTransformerTest.php b/src/Symfony/Component/Form/Tests/Extension/Core/DataTransformer/DateTimeToArrayTransformerTest.php
index 7b81f4775c106..e9a0efb3a807a 100644
--- a/src/Symfony/Component/Form/Tests/Extension/Core/DataTransformer/DateTimeToArrayTransformerTest.php
+++ b/src/Symfony/Component/Form/Tests/Extension/Core/DataTransformer/DateTimeToArrayTransformerTest.php
@@ -11,9 +11,10 @@
namespace Symfony\Component\Form\Tests\Extension\Core\DataTransformer;
+use PHPUnit\Framework\TestCase;
use Symfony\Component\Form\Extension\Core\DataTransformer\DateTimeToArrayTransformer;
-class DateTimeToArrayTransformerTest extends DateTimeTestCase
+class DateTimeToArrayTransformerTest extends TestCase
{
public function testTransform()
{
@@ -160,7 +161,7 @@ public function testReverseTransform()
$output = new \DateTime('2010-02-03 04:05:06 UTC');
- $this->assertDateTimeEquals($output, $transformer->reverseTransform($input));
+ $this->assertEquals($output, $transformer->reverseTransform($input));
}
public function testReverseTransformWithSomeZero()
@@ -178,7 +179,7 @@ public function testReverseTransformWithSomeZero()
$output = new \DateTime('2010-02-03 04:00:00 UTC');
- $this->assertDateTimeEquals($output, $transformer->reverseTransform($input));
+ $this->assertEquals($output, $transformer->reverseTransform($input));
}
public function testReverseTransformCompletelyEmpty()
@@ -323,7 +324,7 @@ public function testReverseTransformDifferentTimezones()
$output = new \DateTime('2010-02-03 04:05:06 Asia/Hong_Kong');
$output->setTimezone(new \DateTimeZone('America/New_York'));
- $this->assertDateTimeEquals($output, $transformer->reverseTransform($input));
+ $this->assertEquals($output, $transformer->reverseTransform($input));
}
public function testReverseTransformToDifferentTimezone()
@@ -342,7 +343,7 @@ public function testReverseTransformToDifferentTimezone()
$output = new \DateTime('2010-02-03 04:05:06 UTC');
$output->setTimezone(new \DateTimeZone('Asia/Hong_Kong'));
- $this->assertDateTimeEquals($output, $transformer->reverseTransform($input));
+ $this->assertEquals($output, $transformer->reverseTransform($input));
}
/**
diff --git a/src/Symfony/Component/Form/Tests/Extension/Core/DataTransformer/DateTimeToLocalizedStringTransformerTest.php b/src/Symfony/Component/Form/Tests/Extension/Core/DataTransformer/DateTimeToLocalizedStringTransformerTest.php
index d95a31443865a..8e7ad393ebe7c 100644
--- a/src/Symfony/Component/Form/Tests/Extension/Core/DataTransformer/DateTimeToLocalizedStringTransformerTest.php
+++ b/src/Symfony/Component/Form/Tests/Extension/Core/DataTransformer/DateTimeToLocalizedStringTransformerTest.php
@@ -11,10 +11,11 @@
namespace Symfony\Component\Form\Tests\Extension\Core\DataTransformer;
+use PHPUnit\Framework\TestCase;
use Symfony\Component\Form\Extension\Core\DataTransformer\DateTimeToLocalizedStringTransformer;
use Symfony\Component\Intl\Util\IntlTestHelper;
-class DateTimeToLocalizedStringTransformerTest extends DateTimeTestCase
+class DateTimeToLocalizedStringTransformerTest extends TestCase
{
protected $dateTime;
protected $dateTimeWithoutSeconds;
@@ -223,7 +224,7 @@ public function testReverseTransformFullTime()
{
$transformer = new DateTimeToLocalizedStringTransformer('UTC', 'UTC', null, \IntlDateFormatter::FULL);
- $this->assertDateTimeEquals($this->dateTime, $transformer->reverseTransform('03.02.2010, 04:05:06 GMT+00:00'));
+ $this->assertEquals($this->dateTime, $transformer->reverseTransform('03.02.2010, 04:05:06 GMT+00:00'));
}
public function testReverseTransformFromDifferentLocale()
@@ -232,7 +233,7 @@ public function testReverseTransformFromDifferentLocale()
$transformer = new DateTimeToLocalizedStringTransformer('UTC', 'UTC');
- $this->assertDateTimeEquals($this->dateTimeWithoutSeconds, $transformer->reverseTransform('Feb 3, 2010, 04:05 AM'));
+ $this->assertEquals($this->dateTimeWithoutSeconds, $transformer->reverseTransform('Feb 3, 2010, 04:05 AM'));
}
public function testReverseTransformWithDifferentTimezones()
@@ -242,7 +243,7 @@ public function testReverseTransformWithDifferentTimezones()
$dateTime = new \DateTime('2010-02-03 04:05:00 Asia/Hong_Kong');
$dateTime->setTimezone(new \DateTimeZone('America/New_York'));
- $this->assertDateTimeEquals($dateTime, $transformer->reverseTransform('03.02.2010, 04:05'));
+ $this->assertEquals($dateTime, $transformer->reverseTransform('03.02.2010, 04:05'));
}
public function testReverseTransformOnlyDateWithDifferentTimezones()
@@ -251,21 +252,21 @@ public function testReverseTransformOnlyDateWithDifferentTimezones()
$dateTime = new \DateTime('2017-01-10 11:00', new \DateTimeZone('Europe/Berlin'));
- $this->assertDateTimeEquals($dateTime, $transformer->reverseTransform('2017-01-10'));
+ $this->assertEquals($dateTime, $transformer->reverseTransform('2017-01-10'));
}
public function testReverseTransformWithDifferentPatterns()
{
$transformer = new DateTimeToLocalizedStringTransformer('UTC', 'UTC', \IntlDateFormatter::FULL, \IntlDateFormatter::FULL, \IntlDateFormatter::GREGORIAN, 'MM*yyyy*dd HH|mm|ss');
- $this->assertDateTimeEquals($this->dateTime, $transformer->reverseTransform('02*2010*03 04|05|06'));
+ $this->assertEquals($this->dateTime, $transformer->reverseTransform('02*2010*03 04|05|06'));
}
public function testReverseTransformDateOnlyWithDstIssue()
{
$transformer = new DateTimeToLocalizedStringTransformer('Europe/Rome', 'Europe/Rome', \IntlDateFormatter::FULL, \IntlDateFormatter::FULL, \IntlDateFormatter::GREGORIAN, 'dd/MM/yyyy');
- $this->assertDateTimeEquals(
+ $this->assertEquals(
new \DateTime('1978-05-28', new \DateTimeZone('Europe/Rome')),
$transformer->reverseTransform('28/05/1978')
);
@@ -275,7 +276,7 @@ public function testReverseTransformDateOnlyWithDstIssueAndEscapedText()
{
$transformer = new DateTimeToLocalizedStringTransformer('Europe/Rome', 'Europe/Rome', \IntlDateFormatter::FULL, \IntlDateFormatter::FULL, \IntlDateFormatter::GREGORIAN, "'day': dd 'month': MM 'year': yyyy");
- $this->assertDateTimeEquals(
+ $this->assertEquals(
new \DateTime('1978-05-28', new \DateTimeZone('Europe/Rome')),
$transformer->reverseTransform('day: 28 month: 05 year: 1978')
);
@@ -329,7 +330,7 @@ public function testReverseTransformWithNonExistingDate()
{
$transformer = new DateTimeToLocalizedStringTransformer('UTC', 'UTC', \IntlDateFormatter::SHORT);
- $this->assertDateTimeEquals($this->dateTimeWithoutSeconds, $transformer->reverseTransform('31.04.10 04:05'));
+ $this->assertEquals($this->dateTimeWithoutSeconds, $transformer->reverseTransform('31.04.10 04:05'));
}
/**
@@ -340,4 +341,22 @@ public function testReverseTransformOutOfTimestampRange()
$transformer = new DateTimeToLocalizedStringTransformer('UTC', 'UTC');
$transformer->reverseTransform('1789-07-14');
}
+
+ /**
+ * @expectedException \Symfony\Component\Form\Exception\TransformationFailedException
+ */
+ public function testReverseTransformFiveDigitYears()
+ {
+ $transformer = new DateTimeToLocalizedStringTransformer('UTC', 'UTC', null, null, \IntlDateFormatter::GREGORIAN, 'yyyy-MM-dd');
+ $transformer->reverseTransform('20107-03-21');
+ }
+
+ /**
+ * @expectedException \Symfony\Component\Form\Exception\TransformationFailedException
+ */
+ public function testReverseTransformFiveDigitYearsWithTimestamp()
+ {
+ $transformer = new DateTimeToLocalizedStringTransformer('UTC', 'UTC', null, null, \IntlDateFormatter::GREGORIAN, 'yyyy-MM-dd HH:mm:ss');
+ $transformer->reverseTransform('20107-03-21 12:34:56');
+ }
}
diff --git a/src/Symfony/Component/Form/Tests/Extension/Core/DataTransformer/DateTimeToRfc3339TransformerTest.php b/src/Symfony/Component/Form/Tests/Extension/Core/DataTransformer/DateTimeToRfc3339TransformerTest.php
index 7e9c2e30c93bc..70f8e3edd2912 100644
--- a/src/Symfony/Component/Form/Tests/Extension/Core/DataTransformer/DateTimeToRfc3339TransformerTest.php
+++ b/src/Symfony/Component/Form/Tests/Extension/Core/DataTransformer/DateTimeToRfc3339TransformerTest.php
@@ -11,9 +11,10 @@
namespace Symfony\Component\Form\Tests\Extension\Core\DataTransformer;
+use PHPUnit\Framework\TestCase;
use Symfony\Component\Form\Extension\Core\DataTransformer\DateTimeToRfc3339Transformer;
-class DateTimeToRfc3339TransformerTest extends DateTimeTestCase
+class DateTimeToRfc3339TransformerTest extends TestCase
{
protected $dateTime;
protected $dateTimeWithoutSeconds;
@@ -106,9 +107,9 @@ public function testReverseTransform($toTz, $fromTz, $to, $from)
$transformer = new DateTimeToRfc3339Transformer($toTz, $fromTz);
if (null !== $to) {
- $this->assertDateTimeEquals(new \DateTime($to), $transformer->reverseTransform($from));
+ $this->assertEquals(new \DateTime($to), $transformer->reverseTransform($from));
} else {
- $this->assertSame($to, $transformer->reverseTransform($from));
+ $this->assertNull($transformer->reverseTransform($from));
}
}
diff --git a/src/Symfony/Component/Form/Tests/Extension/Core/DataTransformer/DateTimeToStringTransformerTest.php b/src/Symfony/Component/Form/Tests/Extension/Core/DataTransformer/DateTimeToStringTransformerTest.php
index 6fc0051769dd6..c4d04e0e0f5f5 100644
--- a/src/Symfony/Component/Form/Tests/Extension/Core/DataTransformer/DateTimeToStringTransformerTest.php
+++ b/src/Symfony/Component/Form/Tests/Extension/Core/DataTransformer/DateTimeToStringTransformerTest.php
@@ -11,9 +11,10 @@
namespace Symfony\Component\Form\Tests\Extension\Core\DataTransformer;
+use PHPUnit\Framework\TestCase;
use Symfony\Component\Form\Extension\Core\DataTransformer\DateTimeToStringTransformer;
-class DateTimeToStringTransformerTest extends DateTimeTestCase
+class DateTimeToStringTransformerTest extends TestCase
{
public function dataProvider()
{
@@ -124,7 +125,7 @@ public function testReverseTransform($format, $input, $output)
$output = new \DateTime($output);
- $this->assertDateTimeEquals($output, $reverseTransformer->reverseTransform($input));
+ $this->assertEquals($output, $reverseTransformer->reverseTransform($input));
}
public function testReverseTransformEmpty()
@@ -142,7 +143,7 @@ public function testReverseTransformWithDifferentTimezones()
$input = $output->format('Y-m-d H:i:s');
$output->setTimezone(new \DateTimeZone('America/New_York'));
- $this->assertDateTimeEquals($output, $reverseTransformer->reverseTransform($input));
+ $this->assertEquals($output, $reverseTransformer->reverseTransform($input));
}
public function testReverseTransformExpectsString()
diff --git a/src/Symfony/Component/Form/Tests/Extension/Core/DataTransformer/DateTimeToTimestampTransformerTest.php b/src/Symfony/Component/Form/Tests/Extension/Core/DataTransformer/DateTimeToTimestampTransformerTest.php
index 7ea8e9a09eb5d..ecd5b70b97de6 100644
--- a/src/Symfony/Component/Form/Tests/Extension/Core/DataTransformer/DateTimeToTimestampTransformerTest.php
+++ b/src/Symfony/Component/Form/Tests/Extension/Core/DataTransformer/DateTimeToTimestampTransformerTest.php
@@ -11,9 +11,10 @@
namespace Symfony\Component\Form\Tests\Extension\Core\DataTransformer;
+use PHPUnit\Framework\TestCase;
use Symfony\Component\Form\Extension\Core\DataTransformer\DateTimeToTimestampTransformer;
-class DateTimeToTimestampTransformerTest extends DateTimeTestCase
+class DateTimeToTimestampTransformerTest extends TestCase
{
public function testTransform()
{
@@ -83,7 +84,7 @@ public function testReverseTransform()
$output = new \DateTime('2010-02-03 04:05:06 UTC');
$input = $output->format('U');
- $this->assertDateTimeEquals($output, $reverseTransformer->reverseTransform($input));
+ $this->assertEquals($output, $reverseTransformer->reverseTransform($input));
}
public function testReverseTransformEmpty()
@@ -101,7 +102,7 @@ public function testReverseTransformWithDifferentTimezones()
$input = $output->format('U');
$output->setTimezone(new \DateTimeZone('Asia/Hong_Kong'));
- $this->assertDateTimeEquals($output, $reverseTransformer->reverseTransform($input));
+ $this->assertEquals($output, $reverseTransformer->reverseTransform($input));
}
public function testReverseTransformExpectsValidTimestamp()
diff --git a/src/Symfony/Component/Form/Tests/Extension/Core/Type/DateTimeTypeTest.php b/src/Symfony/Component/Form/Tests/Extension/Core/Type/DateTimeTypeTest.php
index d80e85021b796..a22da49ac5137 100644
--- a/src/Symfony/Component/Form/Tests/Extension/Core/Type/DateTimeTypeTest.php
+++ b/src/Symfony/Component/Form/Tests/Extension/Core/Type/DateTimeTypeTest.php
@@ -49,7 +49,7 @@ public function testSubmitDateTime()
$dateTime = new \DateTime('2010-06-02 03:04:00 UTC');
- $this->assertDateTimeEquals($dateTime, $form->getData());
+ $this->assertEquals($dateTime, $form->getData());
}
public function testSubmitString()
@@ -133,7 +133,7 @@ public function testSubmitWithoutMinutes()
$form->submit($input);
- $this->assertDateTimeEquals(new \DateTime('2010-06-02 03:00:00 UTC'), $form->getData());
+ $this->assertEquals(new \DateTime('2010-06-02 03:00:00 UTC'), $form->getData());
}
public function testSubmitWithSeconds()
@@ -165,7 +165,7 @@ public function testSubmitWithSeconds()
$form->submit($input);
- $this->assertDateTimeEquals(new \DateTime('2010-06-02 03:04:05 UTC'), $form->getData());
+ $this->assertEquals(new \DateTime('2010-06-02 03:04:05 UTC'), $form->getData());
}
public function testSubmitDifferentTimezones()
@@ -215,7 +215,7 @@ public function testSubmitDifferentTimezonesDateTime()
$outputTime->setTimezone(new \DateTimeZone('America/New_York'));
- $this->assertDateTimeEquals($outputTime, $form->getData());
+ $this->assertEquals($outputTime, $form->getData());
$this->assertEquals('2010-06-02T03:04:00-10:00', $form->getViewData());
}
@@ -266,7 +266,7 @@ public function testSubmitDifferentPattern()
'time' => '03:04',
));
- $this->assertDateTimeEquals($dateTime, $form->getData());
+ $this->assertEquals($dateTime, $form->getData());
}
public function testInitializeWithDateTime()
diff --git a/src/Symfony/Component/Form/Tests/Extension/Core/Type/DateTypeTest.php b/src/Symfony/Component/Form/Tests/Extension/Core/Type/DateTypeTest.php
index 02ef678511181..3a0289a4f34e8 100644
--- a/src/Symfony/Component/Form/Tests/Extension/Core/Type/DateTypeTest.php
+++ b/src/Symfony/Component/Form/Tests/Extension/Core/Type/DateTypeTest.php
@@ -64,7 +64,7 @@ public function testSubmitFromSingleTextDateTimeWithDefaultFormat()
$form->submit('2010-06-02');
- $this->assertDateTimeEquals(new \DateTime('2010-06-02 UTC'), $form->getData());
+ $this->assertEquals(new \DateTime('2010-06-02 UTC'), $form->getData());
$this->assertEquals('2010-06-02', $form->getViewData());
}
@@ -80,7 +80,7 @@ public function testSubmitFromSingleTextDateTimeWithCustomFormat()
$form->submit('2010');
- $this->assertDateTimeEquals(new \DateTime('2010-01-01 UTC'), $form->getData());
+ $this->assertEquals(new \DateTime('2010-01-01 UTC'), $form->getData());
$this->assertEquals('2010', $form->getViewData());
}
@@ -101,7 +101,7 @@ public function testSubmitFromSingleTextDateTime()
$form->submit('2.6.2010');
- $this->assertDateTimeEquals(new \DateTime('2010-06-02 UTC'), $form->getData());
+ $this->assertEquals(new \DateTime('2010-06-02 UTC'), $form->getData());
$this->assertEquals('02.06.2010', $form->getViewData());
}
@@ -194,7 +194,7 @@ public function testSubmitFromText()
$dateTime = new \DateTime('2010-06-02 UTC');
- $this->assertDateTimeEquals($dateTime, $form->getData());
+ $this->assertEquals($dateTime, $form->getData());
$this->assertEquals($text, $form->getViewData());
}
@@ -217,7 +217,7 @@ public function testSubmitFromChoice()
$dateTime = new \DateTime('2010-06-02 UTC');
- $this->assertDateTimeEquals($dateTime, $form->getData());
+ $this->assertEquals($dateTime, $form->getData());
$this->assertEquals($text, $form->getViewData());
}
@@ -254,7 +254,7 @@ public function testSubmitFromInputDateTimeDifferentPattern()
$form->submit('06*2010*02');
- $this->assertDateTimeEquals(new \DateTime('2010-06-02 UTC'), $form->getData());
+ $this->assertEquals(new \DateTime('2010-06-02 UTC'), $form->getData());
$this->assertEquals('06*2010*02', $form->getViewData());
}
@@ -468,7 +468,7 @@ public function testSetDataWithNegativeTimezoneOffsetDateTimeInput()
// 2010-06-02 00:00:00 UTC
// 2010-06-01 20:00:00 UTC-4
- $this->assertDateTimeEquals($dateTime, $form->getData());
+ $this->assertEquals($dateTime, $form->getData());
$this->assertEquals('01.06.2010', $form->getViewData());
}
diff --git a/src/Symfony/Component/Form/Tests/Extension/Core/Type/TimeTypeTest.php b/src/Symfony/Component/Form/Tests/Extension/Core/Type/TimeTypeTest.php
index 95e43d8c0f5ff..56b1d14774cd2 100644
--- a/src/Symfony/Component/Form/Tests/Extension/Core/Type/TimeTypeTest.php
+++ b/src/Symfony/Component/Form/Tests/Extension/Core/Type/TimeTypeTest.php
@@ -315,7 +315,7 @@ public function testSetDataDifferentTimezonesDateTime()
'second' => (int) $outputTime->format('s'),
);
- $this->assertDateTimeEquals($dateTime, $form->getData());
+ $this->assertEquals($dateTime, $form->getData());
$this->assertEquals($displayedData, $form->getViewData());
}
diff --git a/src/Symfony/Component/Form/Tests/Resources/TranslationFilesTest.php b/src/Symfony/Component/Form/Tests/Resources/TranslationFilesTest.php
index ba19a6215a7b4..6d3dae218caf6 100644
--- a/src/Symfony/Component/Form/Tests/Resources/TranslationFilesTest.php
+++ b/src/Symfony/Component/Form/Tests/Resources/TranslationFilesTest.php
@@ -36,4 +36,13 @@ function ($filePath) { return (array) $filePath; },
glob(dirname(dirname(__DIR__)).'/Resources/translations/*.xlf')
);
}
+
+ public function testNorwegianAlias()
+ {
+ $this->assertFileEquals(
+ dirname(dirname(__DIR__)).'/Resources/translations/validators.nb.xlf',
+ dirname(dirname(__DIR__)).'/Resources/translations/validators.no.xlf',
+ 'The NO locale should be an alias for the NB variant of the Norwegian language.'
+ );
+ }
}
diff --git a/src/Symfony/Component/HttpFoundation/HeaderBag.php b/src/Symfony/Component/HttpFoundation/HeaderBag.php
index e06713f39e148..74945a02b4e3a 100644
--- a/src/Symfony/Component/HttpFoundation/HeaderBag.php
+++ b/src/Symfony/Component/HttpFoundation/HeaderBag.php
@@ -101,11 +101,11 @@ public function add(array $headers)
/**
* Returns a header value by name.
*
- * @param string $key The header name
- * @param mixed $default The default value
- * @param bool $first Whether to return the first value or all header values
+ * @param string $key The header name
+ * @param string|string[] $default The default value
+ * @param bool $first Whether to return the first value or all header values
*
- * @return string|array The first header value if $first is true, an array of values otherwise
+ * @return string|string[] The first header value or default value if $first is true, an array of values otherwise
*/
public function get($key, $default = null, $first = true)
{
@@ -130,9 +130,9 @@ public function get($key, $default = null, $first = true)
/**
* Sets a header by name.
*
- * @param string $key The key
- * @param string|array $values The value or an array of values
- * @param bool $replace Whether to replace the actual value or not (true by default)
+ * @param string $key The key
+ * @param string|string[] $values The value or an array of values
+ * @param bool $replace Whether to replace the actual value or not (true by default)
*/
public function set($key, $values, $replace = true)
{
diff --git a/src/Symfony/Component/HttpFoundation/Request.php b/src/Symfony/Component/HttpFoundation/Request.php
index 7b47948c676cd..ccb9ad661d8b9 100644
--- a/src/Symfony/Component/HttpFoundation/Request.php
+++ b/src/Symfony/Component/HttpFoundation/Request.php
@@ -329,13 +329,13 @@ public static function createFromGlobals()
* The information contained in the URI always take precedence
* over the other information (server and parameters).
*
- * @param string $uri The URI
- * @param string $method The HTTP method
- * @param array $parameters The query (GET) or request (POST) parameters
- * @param array $cookies The request cookies ($_COOKIE)
- * @param array $files The request files ($_FILES)
- * @param array $server The server parameters ($_SERVER)
- * @param string $content The raw body data
+ * @param string $uri The URI
+ * @param string $method The HTTP method
+ * @param array $parameters The query (GET) or request (POST) parameters
+ * @param array $cookies The request cookies ($_COOKIE)
+ * @param array $files The request files ($_FILES)
+ * @param array $server The server parameters ($_SERVER)
+ * @param string|resource $content The raw body data
*
* @return static
*/
@@ -531,9 +531,21 @@ public function __toString()
return trigger_error($e, E_USER_ERROR);
}
+ $cookieHeader = '';
+ $cookies = array();
+
+ foreach ($this->cookies as $k => $v) {
+ $cookies[] = $k.'='.$v;
+ }
+
+ if (!empty($cookies)) {
+ $cookieHeader = 'Cookie: '.implode('; ', $cookies)."\r\n";
+ }
+
return
sprintf('%s %s %s', $this->getMethod(), $this->getRequestUri(), $this->server->get('SERVER_PROTOCOL'))."\r\n".
- $this->headers."\r\n".
+ $this->headers.
+ $cookieHeader."\r\n".
$content;
}
diff --git a/src/Symfony/Component/HttpFoundation/Session/Storage/Handler/PdoSessionHandler.php b/src/Symfony/Component/HttpFoundation/Session/Storage/Handler/PdoSessionHandler.php
index 15945644a462b..dfd66516062c3 100644
--- a/src/Symfony/Component/HttpFoundation/Session/Storage/Handler/PdoSessionHandler.php
+++ b/src/Symfony/Component/HttpFoundation/Session/Storage/Handler/PdoSessionHandler.php
@@ -375,7 +375,11 @@ public function close()
$this->gcCalled = false;
// delete the session records that have expired
- $sql = "DELETE FROM $this->table WHERE $this->lifetimeCol < :time - $this->timeCol";
+ if ('mysql' === $this->driver) {
+ $sql = "DELETE FROM $this->table WHERE $this->lifetimeCol + $this->timeCol < :time";
+ } else {
+ $sql = "DELETE FROM $this->table WHERE $this->lifetimeCol < :time - $this->timeCol";
+ }
$stmt = $this->pdo->prepare($sql);
$stmt->bindValue(':time', time(), \PDO::PARAM_INT);
diff --git a/src/Symfony/Component/HttpFoundation/Tests/RequestTest.php b/src/Symfony/Component/HttpFoundation/Tests/RequestTest.php
index 444b98820ca91..45bc48b9969d2 100644
--- a/src/Symfony/Component/HttpFoundation/Tests/RequestTest.php
+++ b/src/Symfony/Component/HttpFoundation/Tests/RequestTest.php
@@ -52,18 +52,18 @@ public function testGetLocale()
public function testGetUser()
{
- $request = Request::create('http://user_test:password_test@test.com/');
+ $request = Request::create('http://user:password@test.com');
$user = $request->getUser();
- $this->assertEquals('user_test', $user);
+ $this->assertEquals('user', $user);
}
public function testGetPassword()
{
- $request = Request::create('http://user_test:password_test@test.com/');
+ $request = Request::create('http://user:password@test.com');
$password = $request->getPassword();
- $this->assertEquals('password_test', $password);
+ $this->assertEquals('password', $password);
}
public function testIsNoCache()
@@ -1523,8 +1523,18 @@ public function testToString()
$request = new Request();
$request->headers->set('Accept-language', 'zh, en-us; q=0.8, en; q=0.6');
+ $request->cookies->set('Foo', 'Bar');
- $this->assertContains('Accept-Language: zh, en-us; q=0.8, en; q=0.6', $request->__toString());
+ $asString = (string) $request;
+
+ $this->assertContains('Accept-Language: zh, en-us; q=0.8, en; q=0.6', $asString);
+ $this->assertContains('Cookie: Foo=Bar', $asString);
+
+ $request->cookies->set('Another', 'Cookie');
+
+ $asString = (string) $request;
+
+ $this->assertContains('Cookie: Foo=Bar; Another=Cookie', $asString);
}
public function testIsMethod()
diff --git a/src/Symfony/Component/HttpKernel/EventListener/AddRequestFormatsListener.php b/src/Symfony/Component/HttpKernel/EventListener/AddRequestFormatsListener.php
index ecf6f59190498..f21fc6ab7c785 100644
--- a/src/Symfony/Component/HttpKernel/EventListener/AddRequestFormatsListener.php
+++ b/src/Symfony/Component/HttpKernel/EventListener/AddRequestFormatsListener.php
@@ -34,8 +34,9 @@ public function __construct(array $formats)
*/
public function onKernelRequest(GetResponseEvent $event)
{
+ $request = $event->getRequest();
foreach ($this->formats as $format => $mimeTypes) {
- $event->getRequest()->setFormat($format, $mimeTypes);
+ $request->setFormat($format, $mimeTypes);
}
}
diff --git a/src/Symfony/Component/HttpKernel/EventListener/DebugHandlersListener.php b/src/Symfony/Component/HttpKernel/EventListener/DebugHandlersListener.php
index 5cb2c20f3a807..2911caa115bf2 100644
--- a/src/Symfony/Component/HttpKernel/EventListener/DebugHandlersListener.php
+++ b/src/Symfony/Component/HttpKernel/EventListener/DebugHandlersListener.php
@@ -125,9 +125,13 @@ public function configure(Event $event = null)
}
if ($this->exceptionHandler) {
if ($handler instanceof ErrorHandler) {
- $h = $handler->setExceptionHandler('var_dump') ?: $this->exceptionHandler;
- $handler->setExceptionHandler($h);
- $handler = is_array($h) ? $h[0] : null;
+ $h = $handler->setExceptionHandler('var_dump');
+ if (is_array($h) && $h[0] instanceof ExceptionHandler) {
+ $handler->setExceptionHandler($h);
+ $handler = $h[0];
+ } else {
+ $handler->setExceptionHandler($this->exceptionHandler);
+ }
}
if ($handler instanceof ExceptionHandler) {
$handler->setHandler($this->exceptionHandler);
diff --git a/src/Symfony/Component/HttpKernel/EventListener/ExceptionListener.php b/src/Symfony/Component/HttpKernel/EventListener/ExceptionListener.php
index 937d1bd55eb27..f18e42c7d3693 100644
--- a/src/Symfony/Component/HttpKernel/EventListener/ExceptionListener.php
+++ b/src/Symfony/Component/HttpKernel/EventListener/ExceptionListener.php
@@ -32,11 +32,13 @@ class ExceptionListener implements EventSubscriberInterface
{
protected $controller;
protected $logger;
+ protected $debug;
- public function __construct($controller, LoggerInterface $logger = null)
+ public function __construct($controller, LoggerInterface $logger = null, $debug = false)
{
$this->controller = $controller;
$this->logger = $logger;
+ $this->debug = $debug;
}
public function onKernelException(GetResponseForExceptionEvent $event)
@@ -71,7 +73,7 @@ public function onKernelException(GetResponseForExceptionEvent $event)
$event->setResponse($response);
- if ($eventDispatcher instanceof EventDispatcherInterface) {
+ if ($this->debug && $eventDispatcher instanceof EventDispatcherInterface) {
$cspRemovalListener = function (FilterResponseEvent $event) use (&$cspRemovalListener, $eventDispatcher) {
$event->getResponse()->headers->remove('Content-Security-Policy');
$eventDispatcher->removeListener(KernelEvents::RESPONSE, $cspRemovalListener);
diff --git a/src/Symfony/Component/HttpKernel/EventListener/RouterListener.php b/src/Symfony/Component/HttpKernel/EventListener/RouterListener.php
index 16f31a2d947a7..fc3da3d20292f 100644
--- a/src/Symfony/Component/HttpKernel/EventListener/RouterListener.php
+++ b/src/Symfony/Component/HttpKernel/EventListener/RouterListener.php
@@ -15,6 +15,7 @@
use Symfony\Component\HttpKernel\Event\GetResponseEvent;
use Symfony\Component\HttpKernel\Event\FinishRequestEvent;
use Symfony\Component\HttpKernel\KernelEvents;
+use Symfony\Component\HttpKernel\Exception\BadRequestHttpException;
use Symfony\Component\HttpKernel\Exception\MethodNotAllowedHttpException;
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
use Symfony\Component\HttpFoundation\RequestStack;
@@ -66,7 +67,11 @@ public function __construct($matcher, RequestStack $requestStack, RequestContext
private function setCurrentRequest(Request $request = null)
{
if (null !== $request) {
- $this->context->fromRequest($request);
+ try {
+ $this->context->fromRequest($request);
+ } catch (\UnexpectedValueException $e) {
+ throw new BadRequestHttpException($e->getMessage(), $e, $e->getCode());
+ }
}
}
diff --git a/src/Symfony/Component/HttpKernel/Kernel.php b/src/Symfony/Component/HttpKernel/Kernel.php
index 95238fdb7b070..0476c416dbbc7 100644
--- a/src/Symfony/Component/HttpKernel/Kernel.php
+++ b/src/Symfony/Component/HttpKernel/Kernel.php
@@ -61,11 +61,11 @@ abstract class Kernel implements KernelInterface, TerminableInterface
private $projectDir;
- const VERSION = '3.3.15';
- const VERSION_ID = 30315;
+ const VERSION = '3.3.16';
+ const VERSION_ID = 30316;
const MAJOR_VERSION = 3;
const MINOR_VERSION = 3;
- const RELEASE_VERSION = 15;
+ const RELEASE_VERSION = 16;
const EXTRA_VERSION = '';
const END_OF_MAINTENANCE = '01/2018';
diff --git a/src/Symfony/Component/HttpKernel/Tests/EventListener/DebugHandlersListenerTest.php b/src/Symfony/Component/HttpKernel/Tests/EventListener/DebugHandlersListenerTest.php
index d1349906bbe69..467b8dde8849a 100644
--- a/src/Symfony/Component/HttpKernel/Tests/EventListener/DebugHandlersListenerTest.php
+++ b/src/Symfony/Component/HttpKernel/Tests/EventListener/DebugHandlersListenerTest.php
@@ -29,8 +29,6 @@
use Symfony\Component\HttpKernel\KernelEvents;
/**
- * DebugHandlersListenerTest.
- *
* @author Nicolas Grekas
*/
class DebugHandlersListenerTest extends TestCase
@@ -132,4 +130,26 @@ public function testConsoleEvent()
$xHandler(new \Exception());
}
+
+ public function testReplaceExistingExceptionHandler()
+ {
+ $userHandler = function () {};
+ $listener = new DebugHandlersListener($userHandler);
+ $eHandler = new ErrorHandler();
+ $eHandler->setExceptionHandler('var_dump');
+
+ $exception = null;
+ set_exception_handler(array($eHandler, 'handleException'));
+ try {
+ $listener->configure();
+ } catch (\Exception $exception) {
+ }
+ restore_exception_handler();
+
+ if (null !== $exception) {
+ throw $exception;
+ }
+
+ $this->assertSame($userHandler, $eHandler->setExceptionHandler('var_dump'));
+ }
}
diff --git a/src/Symfony/Component/HttpKernel/Tests/EventListener/ExceptionListenerTest.php b/src/Symfony/Component/HttpKernel/Tests/EventListener/ExceptionListenerTest.php
index db34f9187bd1f..3cb0b298bb07a 100644
--- a/src/Symfony/Component/HttpKernel/Tests/EventListener/ExceptionListenerTest.php
+++ b/src/Symfony/Component/HttpKernel/Tests/EventListener/ExceptionListenerTest.php
@@ -134,7 +134,7 @@ public function testCSPHeaderIsRemoved()
return new Response($request->getRequestFormat());
}));
- $listener = new ExceptionListener('foo', $this->getMockBuilder('Psr\Log\LoggerInterface')->getMock());
+ $listener = new ExceptionListener('foo', $this->getMockBuilder('Psr\Log\LoggerInterface')->getMock(), true);
$dispatcher->addSubscriber($listener);
diff --git a/src/Symfony/Component/HttpKernel/Tests/EventListener/RouterListenerTest.php b/src/Symfony/Component/HttpKernel/Tests/EventListener/RouterListenerTest.php
index a40e57998dee2..c758bfa3959c3 100644
--- a/src/Symfony/Component/HttpKernel/Tests/EventListener/RouterListenerTest.php
+++ b/src/Symfony/Component/HttpKernel/Tests/EventListener/RouterListenerTest.php
@@ -185,4 +185,19 @@ public function testWithBadRequest()
$response = $kernel->handle($request);
$this->assertSame(400, $response->getStatusCode());
}
+
+ /**
+ * @expectedException \Symfony\Component\HttpKernel\Exception\BadRequestHttpException
+ */
+ public function testRequestWithBadHost()
+ {
+ $kernel = $this->getMockBuilder('Symfony\Component\HttpKernel\HttpKernelInterface')->getMock();
+ $request = Request::create('http://bad host %22/');
+ $event = new GetResponseEvent($kernel, $request, HttpKernelInterface::MASTER_REQUEST);
+
+ $requestMatcher = $this->getMockBuilder('Symfony\Component\Routing\Matcher\RequestMatcherInterface')->getMock();
+
+ $listener = new RouterListener($requestMatcher, $this->requestStack, new RequestContext());
+ $listener->onKernelRequest($event);
+ }
}
diff --git a/src/Symfony/Component/Process/InputStream.php b/src/Symfony/Component/Process/InputStream.php
index 831b10932599d..9bd917a7ef7ce 100644
--- a/src/Symfony/Component/Process/InputStream.php
+++ b/src/Symfony/Component/Process/InputStream.php
@@ -20,6 +20,7 @@
*/
class InputStream implements \IteratorAggregate
{
+ /** @var null|callable */
private $onEmpty = null;
private $input = array();
private $open = true;
@@ -35,7 +36,8 @@ public function onEmpty(callable $onEmpty = null)
/**
* Appends an input to the write buffer.
*
- * @param resource|scalar|\Traversable|null The input to append as stream resource, scalar or \Traversable
+ * @param resource|string|int|float|bool|\Traversable|null The input to append as scalar,
+ * stream resource or \Traversable
*/
public function write($input)
{
diff --git a/src/Symfony/Component/Process/Pipes/AbstractPipes.php b/src/Symfony/Component/Process/Pipes/AbstractPipes.php
index ba79c32702df8..2bd1fe75b7ff9 100644
--- a/src/Symfony/Component/Process/Pipes/AbstractPipes.php
+++ b/src/Symfony/Component/Process/Pipes/AbstractPipes.php
@@ -27,7 +27,7 @@ abstract class AbstractPipes implements PipesInterface
private $blocked = true;
/**
- * @param resource|scalar|\Iterator|null $input
+ * @param resource|string|int|float|bool|\Iterator|null $input
*/
public function __construct($input)
{
diff --git a/src/Symfony/Component/Process/Process.php b/src/Symfony/Component/Process/Process.php
index f01a9a1e24ebd..0b3bce9b4e22f 100644
--- a/src/Symfony/Component/Process/Process.php
+++ b/src/Symfony/Component/Process/Process.php
@@ -331,7 +331,9 @@ public function start(callable $callback = null/*, array $env = array()*/)
} else {
$envPairs = array();
foreach ($env as $k => $v) {
- $envPairs[] = $k.'='.$v;
+ if (false !== $v) {
+ $envPairs[] = $k.'='.$v;
+ }
}
}
@@ -1119,7 +1121,7 @@ public function getEnv()
/**
* Sets the environment variables.
*
- * An environment variable value should be a string.
+ * Each environment variable value should be a string.
* If it is an array, the variable is ignored.
* If it is false or null, it will be removed when
* env vars are otherwise inherited.
@@ -1158,7 +1160,7 @@ public function getInput()
*
* This content will be passed to the underlying process standard input.
*
- * @param resource|scalar|\Traversable|null $input The content
+ * @param string|int|float|bool|resource|\Traversable|null $input The content
*
* @return self The current Process instance
*
diff --git a/src/Symfony/Component/Process/ProcessBuilder.php b/src/Symfony/Component/Process/ProcessBuilder.php
index 2afedcc553ac2..50503f5a0445b 100644
--- a/src/Symfony/Component/Process/ProcessBuilder.php
+++ b/src/Symfony/Component/Process/ProcessBuilder.php
@@ -167,7 +167,7 @@ public function addEnvironmentVariables(array $variables)
/**
* Sets the input of the process.
*
- * @param resource|scalar|\Traversable|null $input The input content
+ * @param resource|string|int|float|bool|\Traversable|null $input The input content
*
* @return $this
*
diff --git a/src/Symfony/Component/Routing/Loader/AnnotationFileLoader.php b/src/Symfony/Component/Routing/Loader/AnnotationFileLoader.php
index 0ff9c9647c2cf..cf9f0704c4987 100644
--- a/src/Symfony/Component/Routing/Loader/AnnotationFileLoader.php
+++ b/src/Symfony/Component/Routing/Loader/AnnotationFileLoader.php
@@ -112,22 +112,22 @@ protected function findClass($file)
}
if (T_CLASS === $token[0]) {
- // Skip usage of ::class constant
- $isClassConstant = false;
+ // Skip usage of ::class constant and anonymous classes
+ $skipClassToken = false;
for ($j = $i - 1; $j > 0; --$j) {
if (!isset($tokens[$j][1])) {
break;
}
- if (T_DOUBLE_COLON === $tokens[$j][0]) {
- $isClassConstant = true;
+ if (T_DOUBLE_COLON === $tokens[$j][0] || T_NEW === $tokens[$j][0]) {
+ $skipClassToken = true;
break;
} elseif (!in_array($tokens[$j][0], array(T_WHITESPACE, T_DOC_COMMENT, T_COMMENT))) {
break;
}
}
- if (!$isClassConstant) {
+ if (!$skipClassToken) {
$class = true;
}
}
diff --git a/src/Symfony/Component/Routing/RouteCollectionBuilder.php b/src/Symfony/Component/Routing/RouteCollectionBuilder.php
index 1d9c857aa2e9f..e8a9a165d6734 100644
--- a/src/Symfony/Component/Routing/RouteCollectionBuilder.php
+++ b/src/Symfony/Component/Routing/RouteCollectionBuilder.php
@@ -76,11 +76,11 @@ public function import($resource, $prefix = '/', $type = null)
foreach ($collection->getResources() as $resource) {
$builder->addResource($resource);
}
-
- // mount into this builder
- $this->mount($prefix, $builder);
}
+ // mount into this builder
+ $this->mount($prefix, $builder);
+
return $builder;
}
diff --git a/src/Symfony/Component/Routing/Tests/Fixtures/OtherAnnotatedClasses/AnonymousClassInTrait.php b/src/Symfony/Component/Routing/Tests/Fixtures/OtherAnnotatedClasses/AnonymousClassInTrait.php
new file mode 100644
index 0000000000000..de87895649491
--- /dev/null
+++ b/src/Symfony/Component/Routing/Tests/Fixtures/OtherAnnotatedClasses/AnonymousClassInTrait.php
@@ -0,0 +1,24 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Routing\Tests\Fixtures\OtherAnnotatedClasses;
+
+trait AnonymousClassInTrait
+{
+ public function test()
+ {
+ return new class() {
+ public function foo()
+ {
+ }
+ };
+ }
+}
diff --git a/src/Symfony/Component/Routing/Tests/Loader/AnnotationFileLoaderTest.php b/src/Symfony/Component/Routing/Tests/Loader/AnnotationFileLoaderTest.php
index 5d54f9f99f665..7f1d5765574a4 100644
--- a/src/Symfony/Component/Routing/Tests/Loader/AnnotationFileLoaderTest.php
+++ b/src/Symfony/Component/Routing/Tests/Loader/AnnotationFileLoaderTest.php
@@ -67,6 +67,17 @@ public function testLoadVariadic()
$this->loader->load(__DIR__.'/../Fixtures/OtherAnnotatedClasses/VariadicClass.php');
}
+ /**
+ * @requires PHP 7.0
+ */
+ public function testLoadAnonymousClass()
+ {
+ $this->reader->expects($this->never())->method('getClassAnnotation');
+ $this->reader->expects($this->never())->method('getMethodAnnotations');
+
+ $this->loader->load(__DIR__.'/../Fixtures/OtherAnnotatedClasses/AnonymousClassInTrait.php');
+ }
+
public function testSupports()
{
$fixture = __DIR__.'/../Fixtures/annotated.php';
diff --git a/src/Symfony/Component/Routing/Tests/RouteCollectionBuilderTest.php b/src/Symfony/Component/Routing/Tests/RouteCollectionBuilderTest.php
index 6fc592affc607..f6af600bd4221 100644
--- a/src/Symfony/Component/Routing/Tests/RouteCollectionBuilderTest.php
+++ b/src/Symfony/Component/Routing/Tests/RouteCollectionBuilderTest.php
@@ -335,4 +335,30 @@ public function testAutomaticRouteNamesDoNotConflict()
// there are 2 routes (i.e. with non-conflicting names)
$this->assertCount(3, $collection->all());
}
+
+ public function testAddsThePrefixOnlyOnceWhenLoadingMultipleCollections()
+ {
+ $firstCollection = new RouteCollection();
+ $firstCollection->add('a', new Route('/a'));
+
+ $secondCollection = new RouteCollection();
+ $secondCollection->add('b', new Route('/b'));
+
+ $loader = $this->getMockBuilder('Symfony\Component\Config\Loader\LoaderInterface')->getMock();
+ $loader->expects($this->any())
+ ->method('supports')
+ ->will($this->returnValue(true));
+ $loader
+ ->expects($this->any())
+ ->method('load')
+ ->will($this->returnValue(array($firstCollection, $secondCollection)));
+
+ $routeCollectionBuilder = new RouteCollectionBuilder($loader);
+ $routeCollectionBuilder->import('/directory/recurse/*', '/other/', 'glob');
+ $routes = $routeCollectionBuilder->build()->all();
+
+ $this->assertEquals(2, count($routes));
+ $this->assertEquals('/other/a', $routes['a']->getPath());
+ $this->assertEquals('/other/b', $routes['b']->getPath());
+ }
}
diff --git a/src/Symfony/Component/Security/Core/Authentication/Token/PreAuthenticatedToken.php b/src/Symfony/Component/Security/Core/Authentication/Token/PreAuthenticatedToken.php
index a2c6e0e4f9f16..84fdb4b00c086 100644
--- a/src/Symfony/Component/Security/Core/Authentication/Token/PreAuthenticatedToken.php
+++ b/src/Symfony/Component/Security/Core/Authentication/Token/PreAuthenticatedToken.php
@@ -11,6 +11,8 @@
namespace Symfony\Component\Security\Core\Authentication\Token;
+use Symfony\Component\Security\Core\Role\RoleInterface;
+
/**
* PreAuthenticatedToken implements a pre-authenticated token.
*
diff --git a/src/Symfony/Component/Security/Core/Resources/translations/security.nb.xlf b/src/Symfony/Component/Security/Core/Resources/translations/security.nb.xlf
new file mode 100644
index 0000000000000..3635916971476
--- /dev/null
+++ b/src/Symfony/Component/Security/Core/Resources/translations/security.nb.xlf
@@ -0,0 +1,71 @@
+
+
+
+
+
+ An authentication exception occurred.
+ En autentiseringsfeil har skjedd.
+
+
+ Authentication credentials could not be found.
+ Påloggingsinformasjonen kunne ikke bli funnet.
+
+
+ Authentication request could not be processed due to a system problem.
+ Autentiserings forespørselen kunne ikke bli prosessert grunnet en system feil.
+
+
+ Invalid credentials.
+ Ugyldig påloggingsinformasjonen.
+
+
+ Cookie has already been used by someone else.
+ Cookie har allerede blitt brukt av noen andre.
+
+
+ Not privileged to request the resource.
+ Ingen tilgang til å be om gitt ressurs.
+
+
+ Invalid CSRF token.
+ Ugyldig CSRF token.
+
+
+ Digest nonce has expired.
+ Digest nonce er utløpt.
+
+
+ No authentication provider found to support the authentication token.
+ Ingen autentiserings tilbyder funnet som støtter gitt autentiserings token.
+
+
+ No session available, it either timed out or cookies are not enabled.
+ Ingen sesjon tilgjengelig, sesjonen er enten utløpt eller cookies ikke skrudd på.
+
+
+ No token could be found.
+ Ingen token kunne bli funnet.
+
+
+ Username could not be found.
+ Brukernavn kunne ikke bli funnet.
+
+
+ Account has expired.
+ Brukerkonto har utgått.
+
+
+ Credentials have expired.
+ Påloggingsinformasjon har utløpt.
+
+
+ Account is disabled.
+ Brukerkonto er deaktivert.
+
+
+ Account is locked.
+ Brukerkonto er sperret.
+
+
+
+
diff --git a/src/Symfony/Component/Security/Core/Resources/translations/security.nn.xlf b/src/Symfony/Component/Security/Core/Resources/translations/security.nn.xlf
new file mode 100644
index 0000000000000..c48ce46505738
--- /dev/null
+++ b/src/Symfony/Component/Security/Core/Resources/translations/security.nn.xlf
@@ -0,0 +1,71 @@
+
+
+
+
+
+ An authentication exception occurred.
+ Innlogginga har feila.
+
+
+ Authentication credentials could not be found.
+ Innloggingsinformasjonen vart ikkje funnen.
+
+
+ Authentication request could not be processed due to a system problem.
+ Innlogginga vart ikkje fullført på grunn av ein systemfeil.
+
+
+ Invalid credentials.
+ Ugyldig innloggingsinformasjon.
+
+
+ Cookie has already been used by someone else.
+ Informasjonskapselen er allereie brukt av ein annan brukar.
+
+
+ Not privileged to request the resource.
+ Du har ikkje åtgang til å be om denne ressursen.
+
+
+ Invalid CSRF token.
+ Ugyldig CSRF-teikn.
+
+
+ Digest nonce has expired.
+ Digest nonce er ikkje lenger gyldig.
+
+
+ No authentication provider found to support the authentication token.
+ Fann ingen innloggingstilbydar som støttar dette innloggingsteiknet.
+
+
+ No session available, it either timed out or cookies are not enabled.
+ Ingen sesjon tilgjengeleg. Sesjonen er anten ikkje lenger gyldig, eller informasjonskapslar er ikke skrudd på i nettlesaren.
+
+
+ No token could be found.
+ Fann ingen innloggingsteikn.
+
+
+ Username could not be found.
+ Fann ikkje brukarnamnet.
+
+
+ Account has expired.
+ Brukarkontoen er utgjengen.
+
+
+ Credentials have expired.
+ Innloggingsinformasjonen er utgjengen.
+
+
+ Account is disabled.
+ Brukarkontoen er deaktivert.
+
+
+ Account is locked.
+ Brukarkontoen er sperra.
+
+
+
+
diff --git a/src/Symfony/Component/Security/Core/Tests/Resources/TranslationFilesTest.php b/src/Symfony/Component/Security/Core/Tests/Resources/TranslationFilesTest.php
index 96a1307ed056b..07c5e304b4ad1 100644
--- a/src/Symfony/Component/Security/Core/Tests/Resources/TranslationFilesTest.php
+++ b/src/Symfony/Component/Security/Core/Tests/Resources/TranslationFilesTest.php
@@ -36,4 +36,13 @@ function ($filePath) { return (array) $filePath; },
glob(dirname(dirname(__DIR__)).'/Resources/translations/*.xlf')
);
}
+
+ public function testNorwegianAlias()
+ {
+ $this->assertFileEquals(
+ dirname(dirname(__DIR__)).'/Resources/translations/security.nb.xlf',
+ dirname(dirname(__DIR__)).'/Resources/translations/security.no.xlf',
+ 'The NO locale should be an alias for the NB variant of the Norwegian language.'
+ );
+ }
}
diff --git a/src/Symfony/Component/Security/Http/Firewall/ContextListener.php b/src/Symfony/Component/Security/Http/Firewall/ContextListener.php
index f8d94e5febf73..f9368b8496d39 100644
--- a/src/Symfony/Component/Security/Http/Firewall/ContextListener.php
+++ b/src/Symfony/Component/Security/Http/Firewall/ContextListener.php
@@ -82,7 +82,7 @@ public function handle(GetResponseEvent $event)
return;
}
- $token = unserialize($token);
+ $token = $this->safelyUnserialize($token);
if (null !== $this->logger) {
$this->logger->debug('Read existing security token from the session.', array('key' => $this->sessionKey));
@@ -176,4 +176,43 @@ protected function refreshUser(TokenInterface $token)
throw new \RuntimeException(sprintf('There is no user provider for user "%s".', get_class($user)));
}
+
+ private function safelyUnserialize($serializedToken)
+ {
+ $e = $token = null;
+ $prevUnserializeHandler = ini_set('unserialize_callback_func', __CLASS__.'::handleUnserializeCallback');
+ $prevErrorHandler = set_error_handler(function ($type, $msg, $file, $line, $context = array()) use (&$prevErrorHandler) {
+ if (__FILE__ === $file) {
+ throw new \UnexpectedValueException($msg, 0x37313bc);
+ }
+
+ return $prevErrorHandler ? $prevErrorHandler($type, $msg, $file, $line, $context) : false;
+ });
+
+ try {
+ $token = unserialize($serializedToken);
+ } catch (\Error $e) {
+ } catch (\Exception $e) {
+ }
+ restore_error_handler();
+ ini_set('unserialize_callback_func', $prevUnserializeHandler);
+ if ($e) {
+ if (!$e instanceof \UnexpectedValueException || 0x37313bc !== $e->getCode()) {
+ throw $e;
+ }
+ if ($this->logger) {
+ $this->logger->warning('Failed to unserialize the security token from the session.', array('key' => $this->sessionKey, 'received' => $serializedToken, 'exception' => $e));
+ }
+ }
+
+ return $token;
+ }
+
+ /**
+ * @internal
+ */
+ public static function handleUnserializeCallback($class)
+ {
+ throw new \UnexpectedValueException('Class not found: '.$class, 0x37313bc);
+ }
}
diff --git a/src/Symfony/Component/Security/Http/Firewall/SimpleFormAuthenticationListener.php b/src/Symfony/Component/Security/Http/Firewall/SimpleFormAuthenticationListener.php
index 4d060ab627f7c..9d843667a67e9 100644
--- a/src/Symfony/Component/Security/Http/Firewall/SimpleFormAuthenticationListener.php
+++ b/src/Symfony/Component/Security/Http/Firewall/SimpleFormAuthenticationListener.php
@@ -13,6 +13,7 @@
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
use Symfony\Component\HttpFoundation\Request;
+use Symfony\Component\HttpKernel\Exception\BadRequestHttpException;
use Symfony\Component\Security\Core\Exception\InvalidCsrfTokenException;
use Symfony\Component\Security\Csrf\CsrfToken;
use Symfony\Component\Security\Csrf\CsrfTokenManagerInterface;
@@ -98,15 +99,17 @@ protected function attemptAuthentication(Request $request)
}
}
- if ($this->options['post_only']) {
- $username = trim(ParameterBagUtils::getParameterBagValue($request->request, $this->options['username_parameter']));
- $password = ParameterBagUtils::getParameterBagValue($request->request, $this->options['password_parameter']);
- } else {
- $username = trim(ParameterBagUtils::getRequestParameterValue($request, $this->options['username_parameter']));
- $password = ParameterBagUtils::getRequestParameterValue($request, $this->options['password_parameter']);
+ $requestBag = $this->options['post_only'] ? $request->request : $request;
+ $username = ParameterBagUtils::getParameterBagValue($requestBag, $this->options['username_parameter']);
+ $password = ParameterBagUtils::getParameterBagValue($requestBag, $this->options['password_parameter']);
+
+ if (!\is_string($username) || (\is_object($username) && !\method_exists($username, '__toString'))) {
+ throw new BadRequestHttpException(sprintf('The key "%s" must be a string, "%s" given.', $this->options['username_parameter'], \gettype($username)));
}
- if (strlen($username) > Security::MAX_USERNAME_LENGTH) {
+ $username = trim($username);
+
+ if (\strlen($username) > Security::MAX_USERNAME_LENGTH) {
throw new BadCredentialsException('Invalid username.');
}
diff --git a/src/Symfony/Component/Security/Http/Firewall/UsernamePasswordFormAuthenticationListener.php b/src/Symfony/Component/Security/Http/Firewall/UsernamePasswordFormAuthenticationListener.php
index 426457d18267a..5d0bee3ae27c7 100644
--- a/src/Symfony/Component/Security/Http/Firewall/UsernamePasswordFormAuthenticationListener.php
+++ b/src/Symfony/Component/Security/Http/Firewall/UsernamePasswordFormAuthenticationListener.php
@@ -13,6 +13,7 @@
use Symfony\Component\HttpFoundation\Request;
use Psr\Log\LoggerInterface;
+use Symfony\Component\HttpKernel\Exception\BadRequestHttpException;
use Symfony\Component\Security\Csrf\CsrfToken;
use Symfony\Component\Security\Csrf\CsrfTokenManagerInterface;
use Symfony\Component\Security\Http\Authentication\AuthenticationFailureHandlerInterface;
@@ -76,14 +77,16 @@ protected function attemptAuthentication(Request $request)
}
}
- if ($this->options['post_only']) {
- $username = trim(ParameterBagUtils::getParameterBagValue($request->request, $this->options['username_parameter']));
- $password = ParameterBagUtils::getParameterBagValue($request->request, $this->options['password_parameter']);
- } else {
- $username = trim(ParameterBagUtils::getRequestParameterValue($request, $this->options['username_parameter']));
- $password = ParameterBagUtils::getRequestParameterValue($request, $this->options['password_parameter']);
+ $requestBag = $this->options['post_only'] ? $request->request : $request;
+ $username = ParameterBagUtils::getParameterBagValue($requestBag, $this->options['username_parameter']);
+ $password = ParameterBagUtils::getParameterBagValue($requestBag, $this->options['password_parameter']);
+
+ if (!\is_string($username) || (\is_object($username) && !\method_exists($username, '__toString'))) {
+ throw new BadRequestHttpException(sprintf('The key "%s" must be a string, "%s" given.', $this->options['username_parameter'], \gettype($username)));
}
+ $username = trim($username);
+
if (strlen($username) > Security::MAX_USERNAME_LENGTH) {
throw new BadCredentialsException('Invalid username.');
}
diff --git a/src/Symfony/Component/Security/Http/Tests/Firewall/ContextListenerTest.php b/src/Symfony/Component/Security/Http/Tests/Firewall/ContextListenerTest.php
index 57592d65031f6..9edc2b3e2725f 100644
--- a/src/Symfony/Component/Security/Http/Tests/Firewall/ContextListenerTest.php
+++ b/src/Symfony/Component/Security/Http/Tests/Firewall/ContextListenerTest.php
@@ -177,6 +177,8 @@ public function testInvalidTokenInSession($token)
public function provideInvalidToken()
{
return array(
+ array('foo'),
+ array('O:8:"NotFound":0:{}'),
array(serialize(new \__PHP_Incomplete_Class())),
array(serialize(null)),
array(null),
diff --git a/src/Symfony/Component/Security/Http/Tests/Firewall/UsernamePasswordFormAuthenticationListenerTest.php b/src/Symfony/Component/Security/Http/Tests/Firewall/UsernamePasswordFormAuthenticationListenerTest.php
index 1e7649db97066..f3962a391ed98 100644
--- a/src/Symfony/Component/Security/Http/Tests/Firewall/UsernamePasswordFormAuthenticationListenerTest.php
+++ b/src/Symfony/Component/Security/Http/Tests/Firewall/UsernamePasswordFormAuthenticationListenerTest.php
@@ -14,8 +14,15 @@
use PHPUnit\Framework\TestCase;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
-use Symfony\Component\Security\Http\Firewall\UsernamePasswordFormAuthenticationListener;
+use Symfony\Component\HttpKernel\Event\GetResponseEvent;
+use Symfony\Component\HttpKernel\HttpKernelInterface;
+use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorage;
use Symfony\Component\Security\Core\Security;
+use Symfony\Component\Security\Http\Authentication\DefaultAuthenticationFailureHandler;
+use Symfony\Component\Security\Http\Authentication\DefaultAuthenticationSuccessHandler;
+use Symfony\Component\Security\Http\Firewall\UsernamePasswordFormAuthenticationListener;
+use Symfony\Component\Security\Http\HttpUtils;
+use Symfony\Component\Security\Http\Session\SessionAuthenticationStrategy;
class UsernamePasswordFormAuthenticationListenerTest extends TestCase
{
@@ -69,6 +76,31 @@ public function testHandleWhenUsernameLength($username, $ok)
$listener->handle($event);
}
+ /**
+ * @expectedException \Symfony\Component\HttpKernel\Exception\BadRequestHttpException
+ * @expectedExceptionMessage The key "_username" must be a string, "array" given.
+ */
+ public function testHandleNonStringUsername()
+ {
+ $request = Request::create('/login_check', 'POST', array('_username' => array()));
+ $request->setSession($this->getMockBuilder('Symfony\Component\HttpFoundation\Session\SessionInterface')->getMock());
+
+ $listener = new UsernamePasswordFormAuthenticationListener(
+ new TokenStorage(),
+ $this->getMockBuilder('Symfony\Component\Security\Core\Authentication\AuthenticationManagerInterface')->getMock(),
+ new SessionAuthenticationStrategy(SessionAuthenticationStrategy::NONE),
+ $httpUtils = new HttpUtils(),
+ 'foo',
+ new DefaultAuthenticationSuccessHandler($httpUtils),
+ new DefaultAuthenticationFailureHandler($this->getMockBuilder('Symfony\Component\HttpKernel\HttpKernelInterface')->getMock(), $httpUtils),
+ array('require_previous_session' => false)
+ );
+
+ $event = new GetResponseEvent($this->getMockBuilder('Symfony\Component\HttpKernel\HttpKernelInterface')->getMock(), $request, HttpKernelInterface::MASTER_REQUEST);
+
+ $listener->handle($event);
+ }
+
public function getUsernameForLength()
{
return array(
diff --git a/src/Symfony/Component/Security/composer.json b/src/Symfony/Component/Security/composer.json
index a9760c11ddf48..bd40fd48511d6 100644
--- a/src/Symfony/Component/Security/composer.json
+++ b/src/Symfony/Component/Security/composer.json
@@ -22,7 +22,6 @@
"symfony/http-kernel": "~3.3",
"symfony/polyfill-php56": "~1.0",
"symfony/polyfill-php70": "~1.0",
- "symfony/polyfill-util": "~1.0",
"symfony/property-access": "~2.8|~3.0"
},
"replace": {
diff --git a/src/Symfony/Component/Serializer/Encoder/EncoderInterface.php b/src/Symfony/Component/Serializer/Encoder/EncoderInterface.php
index f31870e1bf9a2..077e4422e484a 100644
--- a/src/Symfony/Component/Serializer/Encoder/EncoderInterface.php
+++ b/src/Symfony/Component/Serializer/Encoder/EncoderInterface.php
@@ -27,7 +27,7 @@ interface EncoderInterface
* @param string $format Format name
* @param array $context Options that normalizers/encoders have access to
*
- * @return scalar
+ * @return string|int|float|bool
*
* @throws UnexpectedValueException
*/
diff --git a/src/Symfony/Component/Serializer/Encoder/JsonEncode.php b/src/Symfony/Component/Serializer/Encoder/JsonEncode.php
index 6ed558f7dc18d..591e6f0496be2 100644
--- a/src/Symfony/Component/Serializer/Encoder/JsonEncode.php
+++ b/src/Symfony/Component/Serializer/Encoder/JsonEncode.php
@@ -38,7 +38,7 @@ public function encode($data, $format, array $context = array())
$encodedJson = json_encode($data, $context['json_encode_options']);
- if (JSON_ERROR_NONE !== json_last_error()) {
+ if (JSON_ERROR_NONE !== json_last_error() && (false === $encodedJson || !($context['json_encode_options'] & JSON_PARTIAL_OUTPUT_ON_ERROR))) {
throw new UnexpectedValueException(json_last_error_msg());
}
diff --git a/src/Symfony/Component/Serializer/Normalizer/DateTimeNormalizer.php b/src/Symfony/Component/Serializer/Normalizer/DateTimeNormalizer.php
index ff121deb807a2..f789011329546 100644
--- a/src/Symfony/Component/Serializer/Normalizer/DateTimeNormalizer.php
+++ b/src/Symfony/Component/Serializer/Normalizer/DateTimeNormalizer.php
@@ -67,6 +67,10 @@ public function denormalize($data, $class, $format = null, array $context = arra
{
$dateTimeFormat = isset($context[self::FORMAT_KEY]) ? $context[self::FORMAT_KEY] : null;
+ if ('' === $data || null === $data) {
+ throw new UnexpectedValueException('The data is either an empty string or null, you should pass a string that can be parsed with the passed format or a valid DateTime string.');
+ }
+
if (null !== $dateTimeFormat) {
$object = \DateTime::class === $class ? \DateTime::createFromFormat($dateTimeFormat, $data) : \DateTimeImmutable::createFromFormat($dateTimeFormat, $data);
diff --git a/src/Symfony/Component/Serializer/Normalizer/DenormalizableInterface.php b/src/Symfony/Component/Serializer/Normalizer/DenormalizableInterface.php
index 702b1bcb59d8c..5db15418b5c02 100644
--- a/src/Symfony/Component/Serializer/Normalizer/DenormalizableInterface.php
+++ b/src/Symfony/Component/Serializer/Normalizer/DenormalizableInterface.php
@@ -27,12 +27,12 @@ interface DenormalizableInterface
* It is important to understand that the denormalize() call should denormalize
* recursively all child objects of the implementor.
*
- * @param DenormalizerInterface $denormalizer The denormalizer is given so that you
- * can use it to denormalize objects contained within this object
- * @param array|scalar $data The data from which to re-create the object
- * @param string|null $format The format is optionally given to be able to denormalize differently
- * based on different input formats
- * @param array $context Options for denormalizing
+ * @param DenormalizerInterface $denormalizer The denormalizer is given so that you
+ * can use it to denormalize objects contained within this object
+ * @param array|string|int|float|bool $data The data from which to re-create the object
+ * @param string|null $format The format is optionally given to be able to denormalize
+ * differently based on different input formats
+ * @param array $context Options for denormalizing
*
* @return object
*/
diff --git a/src/Symfony/Component/Serializer/Normalizer/NormalizableInterface.php b/src/Symfony/Component/Serializer/Normalizer/NormalizableInterface.php
index b275228642e1b..8542e4f80e1c4 100644
--- a/src/Symfony/Component/Serializer/Normalizer/NormalizableInterface.php
+++ b/src/Symfony/Component/Serializer/Normalizer/NormalizableInterface.php
@@ -33,7 +33,7 @@ interface NormalizableInterface
* based on different output formats
* @param array $context Options for normalizing this object
*
- * @return array|scalar
+ * @return array|string|int|float|bool
*/
public function normalize(NormalizerInterface $normalizer, $format = null, array $context = array());
}
diff --git a/src/Symfony/Component/Serializer/Normalizer/NormalizerInterface.php b/src/Symfony/Component/Serializer/Normalizer/NormalizerInterface.php
index 7f26c0404e5a6..5d0e3d14959c6 100644
--- a/src/Symfony/Component/Serializer/Normalizer/NormalizerInterface.php
+++ b/src/Symfony/Component/Serializer/Normalizer/NormalizerInterface.php
@@ -29,7 +29,7 @@ interface NormalizerInterface
* @param string $format Format the normalization result will be encoded as
* @param array $context Context options for the normalizer
*
- * @return array|scalar
+ * @return array|string|int|float|bool
*
* @throws InvalidArgumentException Occurs when the object given is not an attempted type for the normalizer
* @throws CircularReferenceException Occurs when the normalizer detects a circular reference when no circular
diff --git a/src/Symfony/Component/Serializer/Tests/Encoder/JsonEncoderTest.php b/src/Symfony/Component/Serializer/Tests/Encoder/JsonEncoderTest.php
index ad8d57065f721..b08b6d5b50c18 100644
--- a/src/Symfony/Component/Serializer/Tests/Encoder/JsonEncoderTest.php
+++ b/src/Symfony/Component/Serializer/Tests/Encoder/JsonEncoderTest.php
@@ -65,6 +65,44 @@ public function testOptions()
$this->assertEquals($expected, $this->serializer->serialize($arr, 'json'), 'Context should not be persistent');
}
+ /**
+ * @expectedException \Symfony\Component\Serializer\Exception\UnexpectedValueException
+ */
+ public function testEncodeNotUtf8WithoutPartialOnError()
+ {
+ $arr = array(
+ 'utf8' => 'Hello World!',
+ 'notUtf8' => "\xb0\xd0\xb5\xd0",
+ );
+
+ $this->encoder->encode($arr, 'json');
+ }
+
+ public function testEncodeNotUtf8WithPartialOnError()
+ {
+ $context = array('json_encode_options' => JSON_PARTIAL_OUTPUT_ON_ERROR);
+
+ $arr = array(
+ 'utf8' => 'Hello World!',
+ 'notUtf8' => "\xb0\xd0\xb5\xd0",
+ );
+
+ $result = $this->encoder->encode($arr, 'json', $context);
+ $jsonLastError = json_last_error();
+
+ $this->assertSame(JSON_ERROR_UTF8, $jsonLastError);
+ $this->assertEquals('{"utf8":"Hello World!","notUtf8":null}', $result);
+
+ $this->assertEquals('0', $this->serializer->serialize(NAN, 'json', $context));
+ }
+
+ public function testDecodeFalseString()
+ {
+ $result = $this->encoder->decode('false', 'json');
+ $this->assertSame(JSON_ERROR_NONE, json_last_error());
+ $this->assertFalse($result);
+ }
+
protected function getJsonSource()
{
return '{"foo":"foo","bar":["a","b"],"baz":{"key":"val","key2":"val","A B":"bar","item":[{"title":"title1"},{"title":"title2"}],"Barry":{"FooBar":{"Baz":"Ed","@id":1}}},"qux":"1"}';
diff --git a/src/Symfony/Component/Serializer/Tests/Normalizer/DateTimeNormalizerTest.php b/src/Symfony/Component/Serializer/Tests/Normalizer/DateTimeNormalizerTest.php
index 6d622bbcc0e05..73d277b190832 100644
--- a/src/Symfony/Component/Serializer/Tests/Normalizer/DateTimeNormalizerTest.php
+++ b/src/Symfony/Component/Serializer/Tests/Normalizer/DateTimeNormalizerTest.php
@@ -91,6 +91,24 @@ public function testDenormalizeInvalidDataThrowsException()
$this->normalizer->denormalize('invalid date', \DateTimeInterface::class);
}
+ /**
+ * @expectedException \Symfony\Component\Serializer\Exception\UnexpectedValueException
+ * @expectedExceptionMessage The data is either an empty string or null, you should pass a string that can be parsed with the passed format or a valid DateTime string.
+ */
+ public function testDenormalizeNullThrowsException()
+ {
+ $this->normalizer->denormalize(null, \DateTimeInterface::class);
+ }
+
+ /**
+ * @expectedException \Symfony\Component\Serializer\Exception\UnexpectedValueException
+ * @expectedExceptionMessage The data is either an empty string or null, you should pass a string that can be parsed with the passed format or a valid DateTime string.
+ */
+ public function testDenormalizeEmptyStringThrowsException()
+ {
+ $this->normalizer->denormalize('', \DateTimeInterface::class);
+ }
+
/**
* @expectedException \Symfony\Component\Serializer\Exception\UnexpectedValueException
*/
diff --git a/src/Symfony/Component/Translation/Loader/XliffFileLoader.php b/src/Symfony/Component/Translation/Loader/XliffFileLoader.php
index 0beb861d26f86..90d2a3f7f027e 100644
--- a/src/Symfony/Component/Translation/Loader/XliffFileLoader.php
+++ b/src/Symfony/Component/Translation/Loader/XliffFileLoader.php
@@ -221,16 +221,20 @@ private function fixXmlLocation($schemaSource, $xmlUri)
{
$newPath = str_replace('\\', '/', __DIR__).'/schema/dic/xliff-core/xml.xsd';
$parts = explode('/', $newPath);
+ $locationstart = 'file:///';
if (0 === stripos($newPath, 'phar://')) {
$tmpfile = tempnam(sys_get_temp_dir(), 'sf2');
if ($tmpfile) {
copy($newPath, $tmpfile);
$parts = explode('/', str_replace('\\', '/', $tmpfile));
+ } else {
+ array_shift($parts);
+ $locationstart = 'phar:///';
}
}
$drive = '\\' === DIRECTORY_SEPARATOR ? array_shift($parts).'/' : '';
- $newPath = 'file:///'.$drive.implode('/', array_map('rawurlencode', $parts));
+ $newPath = $locationstart.$drive.implode('/', array_map('rawurlencode', $parts));
return str_replace($xmlUri, $newPath, $schemaSource);
}
diff --git a/src/Symfony/Component/Validator/Constraint.php b/src/Symfony/Component/Validator/Constraint.php
index faaa5fb4bcc5b..c5890c658aeae 100644
--- a/src/Symfony/Component/Validator/Constraint.php
+++ b/src/Symfony/Component/Validator/Constraint.php
@@ -214,6 +214,16 @@ public function __get($option)
throw new InvalidOptionsException(sprintf('The option "%s" does not exist in constraint %s', $option, get_class($this)), array($option));
}
+ /**
+ * @param string $option The option name
+ *
+ * @return bool
+ */
+ public function __isset($option)
+ {
+ return 'groups' === $option;
+ }
+
/**
* Adds the given group if this constraint is in the Default group.
*
diff --git a/src/Symfony/Component/Validator/Constraints/CardSchemeValidator.php b/src/Symfony/Component/Validator/Constraints/CardSchemeValidator.php
index 36a9d8ad276d7..dae3412cd7178 100644
--- a/src/Symfony/Component/Validator/Constraints/CardSchemeValidator.php
+++ b/src/Symfony/Component/Validator/Constraints/CardSchemeValidator.php
@@ -78,9 +78,9 @@ class CardSchemeValidator extends ConstraintValidator
'/^5[1-5][0-9]{14}$/',
'/^2(22[1-9][0-9]{12}|2[3-9][0-9]{13}|[3-6][0-9]{14}|7[0-1][0-9]{13}|720[0-9]{12})$/',
),
- // All Visa card numbers start with a 4. New cards have 16 digits. Old cards have 13.
+ // All Visa card numbers start with a 4 and have a length of 13, 16, or 19 digits.
'VISA' => array(
- '/^4([0-9]{12}|[0-9]{15})$/',
+ '/^4([0-9]{12}|[0-9]{15}|[0-9]{18})$/',
),
);
diff --git a/src/Symfony/Component/Validator/Resources/translations/validators.nb.xlf b/src/Symfony/Component/Validator/Resources/translations/validators.nb.xlf
new file mode 100644
index 0000000000000..250576531cfe4
--- /dev/null
+++ b/src/Symfony/Component/Validator/Resources/translations/validators.nb.xlf
@@ -0,0 +1,319 @@
+
+
+
+
+
+ This value should be false.
+ Verdien må være usann.
+
+
+ This value should be true.
+ Verdien må være sann.
+
+
+ This value should be of type {{ type }}.
+ Verdien skal ha typen {{ type }}.
+
+
+ This value should be blank.
+ Verdien skal være blank.
+
+
+ The value you selected is not a valid choice.
+ Den valgte verdien er ikke gyldig.
+
+
+ You must select at least {{ limit }} choice.|You must select at least {{ limit }} choices.
+ Du må velge minst {{ limit }} valg.
+
+
+ You must select at most {{ limit }} choice.|You must select at most {{ limit }} choices.
+ Du kan maks velge {{ limit }} valg.
+
+
+ One or more of the given values is invalid.
+ En eller flere av de oppgitte verdiene er ugyldige.
+
+
+ This field was not expected.
+ Dette feltet var ikke forventet.
+
+
+ This field is missing.
+ Dette feltet mangler.
+
+
+ This value is not a valid date.
+ Verdien er ikke en gyldig dato.
+
+
+ This value is not a valid datetime.
+ Verdien er ikke en gyldig dato/tid.
+
+
+ This value is not a valid email address.
+ Verdien er ikke en gyldig e-postadresse.
+
+
+ The file could not be found.
+ Filen kunne ikke finnes.
+
+
+ The file is not readable.
+ Filen er ikke lesbar.
+
+
+ The file is too large ({{ size }} {{ suffix }}). Allowed maximum size is {{ limit }} {{ suffix }}.
+ Filen er for stor ({{ size }} {{ suffix }}). Tilatte maksimale størrelse {{ limit }} {{ suffix }}.
+
+
+ The mime type of the file is invalid ({{ type }}). Allowed mime types are {{ types }}.
+ Mimetypen av filen er ugyldig ({{ type }}). Tilatte mimetyper er {{ types }}.
+
+
+ This value should be {{ limit }} or less.
+ Verdien må være {{ limit }} tegn lang eller mindre.
+
+
+ This value is too long. It should have {{ limit }} character or less.|This value is too long. It should have {{ limit }} characters or less.
+ Verdien er for lang. Den må ha {{ limit }} tegn eller mindre.
+
+
+ This value should be {{ limit }} or more.
+ Verdien må være {{ limit }} eller mer.
+
+
+ This value is too short. It should have {{ limit }} character or more.|This value is too short. It should have {{ limit }} characters or more.
+ Verdien er for kort. Den må ha {{ limit }} tegn eller flere.
+
+
+ This value should not be blank.
+ Verdien kan ikke være blank.
+
+
+ This value should not be null.
+ Verdien kan ikke være tom (null).
+
+
+ This value should be null.
+ Verdien skal være tom (null).
+
+
+ This value is not valid.
+ Verdien er ugyldig.
+
+
+ This value is not a valid time.
+ Verdien er ikke en gyldig tid.
+
+
+ This value is not a valid URL.
+ Verdien er ikke en gyldig URL.
+
+
+ The two values should be equal.
+ Verdiene skal være identiske.
+
+
+ The file is too large. Allowed maximum size is {{ limit }} {{ suffix }}.
+ Filen er for stor. Den maksimale størrelsen er {{ limit }} {{ suffix }}.
+
+
+ The file is too large.
+ Filen er for stor.
+
+
+ The file could not be uploaded.
+ Filen kunne ikke lastes opp.
+
+
+ This value should be a valid number.
+ Verdien skal være et gyldig tall.
+
+
+ This file is not a valid image.
+ Denne filen er ikke et gyldig bilde.
+
+
+ This is not a valid IP address.
+ Dette er ikke en gyldig IP adresse.
+
+
+ This value is not a valid language.
+ Verdien er ikke et gyldig språk.
+
+
+ This value is not a valid locale.
+ Verdien er ikke en gyldig lokalitet.
+
+
+ This value is not a valid country.
+ Verdien er ikke et gyldig navn på land.
+
+
+ This value is already used.
+ Verdien er allerede brukt.
+
+
+ The size of the image could not be detected.
+ Bildestørrelsen kunne ikke oppdages.
+
+
+ The image width is too big ({{ width }}px). Allowed maximum width is {{ max_width }}px.
+ Bildebredden er for stor ({{ width }} piksler). Tillatt maksimumsbredde er {{ max_width }} piksler.
+
+
+ The image width is too small ({{ width }}px). Minimum width expected is {{ min_width }}px.
+ Bildebredden er for liten ({{ width }} piksler). Forventet minimumsbredde er {{ min_width }} piksler.
+
+
+ The image height is too big ({{ height }}px). Allowed maximum height is {{ max_height }}px.
+ Bildehøyden er for stor ({{ height }} piksler). Tillatt maksimumshøyde er {{ max_height }} piksler.
+
+
+ The image height is too small ({{ height }}px). Minimum height expected is {{ min_height }}px.
+ Bildehøyden er for liten ({{ height }} piksler). Forventet minimumshøyde er {{ min_height }} piksler.
+
+
+ This value should be the user's current password.
+ Verdien skal være brukerens sitt nåværende passord.
+
+
+ This value should have exactly {{ limit }} character.|This value should have exactly {{ limit }} characters.
+ Verdien skal være nøyaktig {{ limit }} tegn.
+
+
+ The file was only partially uploaded.
+ Filen var kun delvis opplastet.
+
+
+ No file was uploaded.
+ Ingen fil var lastet opp.
+
+
+ No temporary folder was configured in php.ini.
+ Den midlertidige mappen (tmp) er ikke konfigurert i php.ini.
+
+
+ Cannot write temporary file to disk.
+ Kan ikke skrive midlertidig fil til disk.
+
+
+ A PHP extension caused the upload to fail.
+ En PHP-utvidelse forårsaket en feil under opplasting.
+
+
+ This collection should contain {{ limit }} element or more.|This collection should contain {{ limit }} elements or more.
+ Denne samlingen må inneholde {{ limit }} element eller flere.|Denne samlingen må inneholde {{ limit }} elementer eller flere.
+
+
+ This collection should contain {{ limit }} element or less.|This collection should contain {{ limit }} elements or less.
+ Denne samlingen må inneholde {{ limit }} element eller færre.|Denne samlingen må inneholde {{ limit }} elementer eller færre.
+
+
+ This collection should contain exactly {{ limit }} element.|This collection should contain exactly {{ limit }} elements.
+ Denne samlingen må inneholde nøyaktig {{ limit }} element.|Denne samlingen må inneholde nøyaktig {{ limit }} elementer.
+
+
+ Invalid card number.
+ Ugyldig kortnummer.
+
+
+ Unsupported card type or invalid card number.
+ Korttypen er ikke støttet eller kortnummeret er ugyldig.
+
+
+ This is not a valid International Bank Account Number (IBAN).
+ Dette er ikke et gyldig IBAN-nummer.
+
+
+ This value is not a valid ISBN-10.
+ Verdien er ikke en gyldig ISBN-10.
+
+
+ This value is not a valid ISBN-13.
+ Verdien er ikke en gyldig ISBN-13.
+
+
+ This value is neither a valid ISBN-10 nor a valid ISBN-13.
+ Verdien er hverken en gyldig ISBN-10 eller ISBN-13.
+
+
+ This value is not a valid ISSN.
+ Verdien er ikke en gyldig ISSN.
+
+
+ This value is not a valid currency.
+ Verdien er ikke gyldig valuta.
+
+
+ This value should be equal to {{ compared_value }}.
+ Verdien skal være lik {{ compared_value }}.
+
+
+ This value should be greater than {{ compared_value }}.
+ Verdien skal være større enn {{ compared_value }}.
+
+
+ This value should be greater than or equal to {{ compared_value }}.
+ Verdien skal være større enn eller lik {{ compared_value }}.
+
+
+ This value should be identical to {{ compared_value_type }} {{ compared_value }}.
+ Verdien skal være identisk med {{ compared_value_type }} {{ compared_value }}.
+
+
+ This value should be less than {{ compared_value }}.
+ Verdien skal være mindre enn {{ compared_value }}.
+
+
+ This value should be less than or equal to {{ compared_value }}.
+ Verdien skal være mindre enn eller lik {{ compared_value }}.
+
+
+ This value should not be equal to {{ compared_value }}.
+ Verdien skal ikke være lik {{ compared_value }}.
+
+
+ This value should not be identical to {{ compared_value_type }} {{ compared_value }}.
+ Verdien skal ikke være identisk med {{ compared_value_type }} {{ compared_value }}.
+
+
+ The image ratio is too big ({{ ratio }}). Allowed maximum ratio is {{ max_ratio }}.
+ Bildeforholdet er for stort ({{ ratio }}). Tillatt bildeforhold er maks {{ max_ratio }}.
+
+
+ The image ratio is too small ({{ ratio }}). Minimum ratio expected is {{ min_ratio }}.
+ Bildeforholdet er for lite ({{ ratio }}). Forventet bildeforhold er minst {{ min_ratio }}.
+
+
+ The image is square ({{ width }}x{{ height }}px). Square images are not allowed.
+ Bildet er en kvadrat ({{ width }}x{{ height }}px). Kvadratiske bilder er ikke tillatt.
+
+
+ The image is landscape oriented ({{ width }}x{{ height }}px). Landscape oriented images are not allowed.
+ Bildet er i liggende retning ({{ width }}x{{ height }}px). Bilder i liggende retning er ikke tillatt.
+
+
+ The image is portrait oriented ({{ width }}x{{ height }}px). Portrait oriented images are not allowed.
+ Bildet er i stående retning ({{ width }}x{{ height }}px). Bilder i stående retning er ikke tillatt.
+
+
+ An empty file is not allowed.
+ Tomme filer er ikke tilatt.
+
+
+ The host could not be resolved.
+ Vertsnavn kunne ikke løses.
+
+
+ This value does not match the expected {{ charset }} charset.
+ Verdien samsvarer ikke med forventet tegnsett {{ charset }}.
+
+
+ This is not a valid Business Identifier Code (BIC).
+ Dette er ikke en gyldig BIC.
+
+
+
+
diff --git a/src/Symfony/Component/Validator/Resources/translations/validators.nn.xlf b/src/Symfony/Component/Validator/Resources/translations/validators.nn.xlf
index ea01c63ee4aa4..e5881330e8eb8 100644
--- a/src/Symfony/Component/Validator/Resources/translations/validators.nn.xlf
+++ b/src/Symfony/Component/Validator/Resources/translations/validators.nn.xlf
@@ -20,15 +20,15 @@
The value you selected is not a valid choice.
- Verdien du valgte er ikkje gyldig.
+ Verdien du valde er ikkje gyldig.You must select at least {{ limit }} choice.|You must select at least {{ limit }} choices.
- Du må velge minst {{ limit }} valg.
+ Du må gjere minst {{ limit }} val.You must select at most {{ limit }} choice.|You must select at most {{ limit }} choices.
- Du kan maksimalt gjere {{ limit }} valg.
+ Du kan maksimalt gjere {{ limit }} val.One or more of the given values is invalid.
@@ -36,7 +36,7 @@
This field was not expected.
- Dette feltet var ikke forventet.
+ Dette feltet var ikke forventa.This field is missing.
@@ -56,7 +56,7 @@
The file could not be found.
- Fila kunne ikkje finnes.
+ Fila er ikkje funnen.The file is not readable.
@@ -64,11 +64,11 @@
The file is too large ({{ size }} {{ suffix }}). Allowed maximum size is {{ limit }} {{ suffix }}.
- Fila er for stor ({{ size }} {{ suffix }}). Tillatt maksimal størrelse er {{ limit }} {{ suffix }}.
+ Fila er for stor ({{ size }} {{ suffix }}). Maksimal storleik er {{ limit }} {{ suffix }}.The mime type of the file is invalid ({{ type }}). Allowed mime types are {{ types }}.
- Mime-typen av fila er ugyldig ({{ type }}). Tillatte mime-typar er {{ types }}.
+ Mime-typen av fila er ugyldig ({{ type }}). Tillatne mime-typar er {{ types }}.This value should be {{ limit }} or less.
@@ -88,11 +88,11 @@
This value should not be blank.
- Verdien må ikkje vere blank.
+ Verdien kan ikkje vere blank.This value should not be null.
- Verdien må ikkje vere tom (null).
+ Verdien kan ikkje vere tom (null).This value should be null.
@@ -104,7 +104,7 @@
This value is not a valid time.
- Verdien er ikkje gyldig tidseining.
+ Verdien er ikkje ei gyldig tidseining.This value is not a valid URL.
@@ -116,7 +116,7 @@
The file is too large. Allowed maximum size is {{ limit }} {{ suffix }}.
- Fila er for stor. Den maksimale storleik er {{ limit }} {{ suffix }}.
+ Fila er for stor. Den maksimale storleiken er {{ limit }} {{ suffix }}.The file is too large.
@@ -160,7 +160,7 @@
The image width is too big ({{ width }}px). Allowed maximum width is {{ max_width }}px.
- Biletbreidda er for stor, ({{ width }} pikslar). Tillatt maksimumsbreidde er {{ max_width }} pikslar.
+ Biletbreidda er for stor, ({{ width }} pikslar). Tillaten maksimumsbreidde er {{ max_width }} pikslar.The image width is too small ({{ width }}px). Minimum width expected is {{ min_width }}px.
@@ -168,7 +168,7 @@
The image height is too big ({{ height }}px). Allowed maximum height is {{ max_height }}px.
- Bilethøgda er for stor, ({{ height }} pikslar). Tillatt maksimumshøgde er {{ max_height }} pikslar.
+ Bilethøgda er for stor, ({{ height }} pikslar). Tillaten maksimumshøgde er {{ max_height }} pikslar.The image height is too small ({{ height }}px). Minimum height expected is {{ min_height }}px.
@@ -184,7 +184,7 @@
The file was only partially uploaded.
- Fila vart kun delvis opplasta.
+ Fila vart berre delvis lasta opp.No file was uploaded.
@@ -220,7 +220,7 @@
Unsupported card type or invalid card number.
- Korttypen er ikkje støtta eller ugyldig kortnummer.
+ Korttypen er ikkje støtta, eller kortnummeret er ugyldig.
Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.