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" } pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy