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 %} - {{ message.locale }} + {{ message.locale }} {{ message.domain }} - {{ message.count }} + {{ message.count }} {{ message.id }} diff --git a/src/Symfony/Bundle/WebProfilerBundle/Resources/views/Profiler/profiler.css.twig b/src/Symfony/Bundle/WebProfilerBundle/Resources/views/Profiler/profiler.css.twig index ca55b28672d03..164f91054f8ef 100644 --- a/src/Symfony/Bundle/WebProfilerBundle/Resources/views/Profiler/profiler.css.twig +++ b/src/Symfony/Bundle/WebProfilerBundle/Resources/views/Profiler/profiler.css.twig @@ -178,10 +178,6 @@ table tbody td { border-width: 1px 0; } -table tbody td { - {{ mixins.break_long_words|raw }} -} - table tbody div { margin: .25em 0; } diff --git a/src/Symfony/Bundle/WebProfilerBundle/Resources/views/Router/panel.html.twig b/src/Symfony/Bundle/WebProfilerBundle/Resources/views/Router/panel.html.twig index 1cfa085089685..ea8600a2d083b 100644 --- a/src/Symfony/Bundle/WebProfilerBundle/Resources/views/Router/panel.html.twig +++ b/src/Symfony/Bundle/WebProfilerBundle/Resources/views/Router/panel.html.twig @@ -55,8 +55,8 @@ {% for trace in traces %} {{ loop.index }} - {{ trace.name }} - {{ trace.path }} + {{ trace.name }} + {{ trace.path }} {% 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. diff --git a/src/Symfony/Component/Validator/Tests/Constraints/CardSchemeValidatorTest.php b/src/Symfony/Component/Validator/Tests/Constraints/CardSchemeValidatorTest.php index f83fc71da959d..40c0ce43cfb95 100644 --- a/src/Symfony/Component/Validator/Tests/Constraints/CardSchemeValidatorTest.php +++ b/src/Symfony/Component/Validator/Tests/Constraints/CardSchemeValidatorTest.php @@ -106,6 +106,7 @@ public function getValidNumbers() array('VISA', '4111111111111111'), array('VISA', '4012888888881881'), array('VISA', '4222222222222'), + array('VISA', '4917610000000000003'), array(array('AMEX', 'VISA'), '4111111111111111'), array(array('AMEX', 'VISA'), '378282246310005'), array(array('JCB', 'MASTERCARD'), '5105105105105100'), diff --git a/src/Symfony/Component/Validator/Tests/Constraints/FileTest.php b/src/Symfony/Component/Validator/Tests/Constraints/FileTest.php index 18b68f5f11740..b7745f44fa13a 100644 --- a/src/Symfony/Component/Validator/Tests/Constraints/FileTest.php +++ b/src/Symfony/Component/Validator/Tests/Constraints/FileTest.php @@ -26,6 +26,16 @@ public function testMaxSize($maxSize, $bytes, $binaryFormat) $this->assertSame($bytes, $file->maxSize); $this->assertSame($binaryFormat, $file->binaryFormat); + $this->assertTrue($file->__isset('maxSize')); + } + + public function testMagicIsset() + { + $file = new File(array('maxSize' => 1)); + + $this->assertTrue($file->__isset('maxSize')); + $this->assertTrue($file->__isset('groups')); + $this->assertFalse($file->__isset('toto')); } /** diff --git a/src/Symfony/Component/Validator/Tests/Resources/TranslationFilesTest.php b/src/Symfony/Component/Validator/Tests/Resources/TranslationFilesTest.php index 96311cfeff326..d2b8a99011721 100644 --- a/src/Symfony/Component/Validator/Tests/Resources/TranslationFilesTest.php +++ b/src/Symfony/Component/Validator/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/VarDumper/Cloner/Data.php b/src/Symfony/Component/VarDumper/Cloner/Data.php index 9f523d3bfa608..6343c45dd4454 100644 --- a/src/Symfony/Component/VarDumper/Cloner/Data.php +++ b/src/Symfony/Component/VarDumper/Cloner/Data.php @@ -63,7 +63,7 @@ public function getType() /** * @param bool $recursive Whether values should be resolved recursively or not * - * @return scalar|array|null|Data[] A native representation of the original value + * @return string|int|float|bool|array|null|Data[] A native representation of the original value */ public function getValue($recursive = false) { diff --git a/src/Symfony/Component/VarDumper/Cloner/DumperInterface.php b/src/Symfony/Component/VarDumper/Cloner/DumperInterface.php index cb7981694f981..cb498ff70657c 100644 --- a/src/Symfony/Component/VarDumper/Cloner/DumperInterface.php +++ b/src/Symfony/Component/VarDumper/Cloner/DumperInterface.php @@ -21,9 +21,9 @@ interface DumperInterface /** * Dumps a scalar value. * - * @param Cursor $cursor The Cursor position in the dump - * @param string $type The PHP type of the value being dumped - * @param scalar $value The scalar value being dumped + * @param Cursor $cursor The Cursor position in the dump + * @param string $type The PHP type of the value being dumped + * @param string|int|float|bool $value The scalar value being dumped */ public function dumpScalar(Cursor $cursor, $type, $value); diff --git a/src/Symfony/Component/VarDumper/Dumper/AbstractDumper.php b/src/Symfony/Component/VarDumper/Dumper/AbstractDumper.php index 0fbd213abe987..e27675ad13c9f 100644 --- a/src/Symfony/Component/VarDumper/Dumper/AbstractDumper.php +++ b/src/Symfony/Component/VarDumper/Dumper/AbstractDumper.php @@ -101,9 +101,9 @@ public function setCharset($charset) /** * Sets the indentation pad string. * - * @param string $pad A string the will be prepended to dumped lines, repeated by nesting level + * @param string $pad A string that will be prepended to dumped lines, repeated by nesting level * - * @return string The indent pad + * @return string The previous indent pad */ public function setIndentPad($pad) { diff --git a/src/Symfony/Component/Yaml/Dumper.php b/src/Symfony/Component/Yaml/Dumper.php index 121edcf391f12..1ab58871a955f 100644 --- a/src/Symfony/Component/Yaml/Dumper.php +++ b/src/Symfony/Component/Yaml/Dumper.php @@ -95,7 +95,7 @@ public function dump($input, $inline = 0, $indent = 0, $flags = 0) $dumpAsMap = Inline::isHash($input); foreach ($input as $key => $value) { - if ($inline >= 1 && Yaml::DUMP_MULTI_LINE_LITERAL_BLOCK & $flags && is_string($value) && false !== strpos($value, "\n")) { + if ($inline >= 1 && Yaml::DUMP_MULTI_LINE_LITERAL_BLOCK & $flags && is_string($value) && false !== strpos($value, "\n") && false === strpos($value, "\r\n")) { $output .= sprintf("%s%s%s |\n", $prefix, $dumpAsMap ? Inline::dump($key, $flags).':' : '-', ''); foreach (preg_split('/\n|\r\n/', $value) as $row) { diff --git a/src/Symfony/Component/Yaml/Tests/DumperTest.php b/src/Symfony/Component/Yaml/Tests/DumperTest.php index 1c80bec6506c2..9d470b5b1fac9 100644 --- a/src/Symfony/Component/Yaml/Tests/DumperTest.php +++ b/src/Symfony/Component/Yaml/Tests/DumperTest.php @@ -443,7 +443,8 @@ public function testDumpMultiLineStringAsScalarBlock() $data = array( 'data' => array( 'single_line' => 'foo bar baz', - 'multi_line' => "foo\nline with trailing spaces:\n \nbar\r\ninteger like line:\n123456789\nempty line:\n\nbaz", + 'multi_line' => "foo\nline with trailing spaces:\n \nbar\ninteger like line:\n123456789\nempty line:\n\nbaz", + 'multi_line_with_carriage_return' => "foo\nbar\r\nbaz", 'nested_inlined_multi_line_string' => array( 'inlined_multi_line' => "foo\nbar\r\nempty line:\n\nbaz", ), @@ -453,6 +454,11 @@ public function testDumpMultiLineStringAsScalarBlock() $this->assertSame(file_get_contents(__DIR__.'/Fixtures/multiple_lines_as_literal_block.yml'), $this->dumper->dump($data, 2, 0, Yaml::DUMP_MULTI_LINE_LITERAL_BLOCK)); } + public function testCarriageReturnIsMaintainedWhenDumpingAsMultiLineLiteralBlock() + { + $this->assertSame("- \"a\\r\\nb\\nc\"\n", $this->dumper->dump(array("a\r\nb\nc"), 2, 0, Yaml::DUMP_MULTI_LINE_LITERAL_BLOCK)); + } + /** * @expectedException \InvalidArgumentException * @expectedExceptionMessage The indentation must be greater than zero diff --git a/src/Symfony/Component/Yaml/Tests/Fixtures/multiple_lines_as_literal_block.yml b/src/Symfony/Component/Yaml/Tests/Fixtures/multiple_lines_as_literal_block.yml index b4903d30a11c0..9d72f09be8a4c 100644 --- a/src/Symfony/Component/Yaml/Tests/Fixtures/multiple_lines_as_literal_block.yml +++ b/src/Symfony/Component/Yaml/Tests/Fixtures/multiple_lines_as_literal_block.yml @@ -10,4 +10,5 @@ data: empty line: baz + multi_line_with_carriage_return: "foo\nbar\r\nbaz" nested_inlined_multi_line_string: { inlined_multi_line: "foo\nbar\r\nempty line:\n\nbaz" }