From 4fc0ecbf90cb8d34189e11dc70445d801ed99cc7 Mon Sep 17 00:00:00 2001 From: Iltar van der Berg Date: Fri, 2 Feb 2018 08:30:49 +0100 Subject: [PATCH 01/75] Fixed being logged out on failed attempt in guard --- .../Security/Guard/GuardAuthenticatorHandler.php | 6 ------ .../Guard/Tests/GuardAuthenticatorHandlerTest.php | 15 +++++---------- 2 files changed, 5 insertions(+), 16 deletions(-) diff --git a/src/Symfony/Component/Security/Guard/GuardAuthenticatorHandler.php b/src/Symfony/Component/Security/Guard/GuardAuthenticatorHandler.php index 507e5362123b..3b62c41253a2 100644 --- a/src/Symfony/Component/Security/Guard/GuardAuthenticatorHandler.php +++ b/src/Symfony/Component/Security/Guard/GuardAuthenticatorHandler.php @@ -18,7 +18,6 @@ use Symfony\Component\Security\Core\Authentication\Token\TokenInterface; use Symfony\Component\Security\Core\Exception\AuthenticationException; use Symfony\Component\Security\Core\User\UserInterface; -use Symfony\Component\Security\Guard\Token\PostAuthenticationGuardToken; use Symfony\Component\Security\Http\Event\InteractiveLoginEvent; use Symfony\Component\Security\Http\SecurityEvents; @@ -116,11 +115,6 @@ public function authenticateUserAndHandleSuccess(UserInterface $user, Request $r */ public function handleAuthenticationFailure(AuthenticationException $authenticationException, Request $request, GuardAuthenticatorInterface $guardAuthenticator, $providerKey) { - $token = $this->tokenStorage->getToken(); - if ($token instanceof PostAuthenticationGuardToken && $providerKey === $token->getProviderKey()) { - $this->tokenStorage->setToken(null); - } - $response = $guardAuthenticator->onAuthenticationFailure($request, $authenticationException); if ($response instanceof Response || null === $response) { // returning null is ok, it means they want the request to continue diff --git a/src/Symfony/Component/Security/Guard/Tests/GuardAuthenticatorHandlerTest.php b/src/Symfony/Component/Security/Guard/Tests/GuardAuthenticatorHandlerTest.php index b46bc4a78d4f..662bace30877 100644 --- a/src/Symfony/Component/Security/Guard/Tests/GuardAuthenticatorHandlerTest.php +++ b/src/Symfony/Component/Security/Guard/Tests/GuardAuthenticatorHandlerTest.php @@ -81,7 +81,7 @@ public function testHandleAuthenticationFailure() /** * @dataProvider getTokenClearingTests */ - public function testHandleAuthenticationClearsToken($tokenClass, $tokenProviderKey, $actualProviderKey, $shouldTokenBeCleared) + public function testHandleAuthenticationClearsToken($tokenClass, $tokenProviderKey, $actualProviderKey) { $token = $this->getMockBuilder($tokenClass) ->disableOriginalConstructor() @@ -90,12 +90,7 @@ public function testHandleAuthenticationClearsToken($tokenClass, $tokenProviderK ->method('getProviderKey') ->will($this->returnValue($tokenProviderKey)); - // make the $token be the current token - $this->tokenStorage->expects($this->once()) - ->method('getToken') - ->will($this->returnValue($token)); - - $this->tokenStorage->expects($shouldTokenBeCleared ? $this->once() : $this->never()) + $this->tokenStorage->expects($this->never()) ->method('setToken') ->with(null); $authException = new AuthenticationException('Bad password!'); @@ -115,9 +110,9 @@ public function getTokenClearingTests() { $tests = array(); // correct token class and matching firewall => clear the token - $tests[] = array('Symfony\Component\Security\Guard\Token\PostAuthenticationGuardToken', 'the_firewall_key', 'the_firewall_key', true); - $tests[] = array('Symfony\Component\Security\Guard\Token\PostAuthenticationGuardToken', 'the_firewall_key', 'different_key', false); - $tests[] = array('Symfony\Component\Security\Core\Authentication\Token\UsernamePasswordToken', 'the_firewall_key', 'the_firewall_key', false); + $tests[] = array('Symfony\Component\Security\Guard\Token\PostAuthenticationGuardToken', 'the_firewall_key', 'the_firewall_key'); + $tests[] = array('Symfony\Component\Security\Guard\Token\PostAuthenticationGuardToken', 'the_firewall_key', 'different_key'); + $tests[] = array('Symfony\Component\Security\Core\Authentication\Token\UsernamePasswordToken', 'the_firewall_key', 'the_firewall_key'); return $tests; } From 43599362a2c33fa065164d8fe52d8ef5348389dc Mon Sep 17 00:00:00 2001 From: Nicolas Grekas Date: Fri, 6 Apr 2018 13:01:31 +0200 Subject: [PATCH 02/75] [Yaml] Throw parse error on unfinished inline map --- src/Symfony/Component/Yaml/Inline.php | 3 +++ src/Symfony/Component/Yaml/Tests/InlineTest.php | 9 +++++++++ 2 files changed, 12 insertions(+) diff --git a/src/Symfony/Component/Yaml/Inline.php b/src/Symfony/Component/Yaml/Inline.php index 31a0514fd497..5e5b1a1767ee 100644 --- a/src/Symfony/Component/Yaml/Inline.php +++ b/src/Symfony/Component/Yaml/Inline.php @@ -231,6 +231,9 @@ public static function parseScalar($scalar, $delimiters = null, $stringDelimiter if (null !== $delimiters) { $tmp = ltrim(substr($scalar, $i), ' '); + if ('' === $tmp) { + throw new ParseException(sprintf('Unexpected end of line, expected one of "%s".', implode($delimiters))); + } if (!in_array($tmp[0], $delimiters)) { throw new ParseException(sprintf('Unexpected characters (%s).', substr($scalar, $i))); } diff --git a/src/Symfony/Component/Yaml/Tests/InlineTest.php b/src/Symfony/Component/Yaml/Tests/InlineTest.php index f28f360489f6..418c7876a13c 100644 --- a/src/Symfony/Component/Yaml/Tests/InlineTest.php +++ b/src/Symfony/Component/Yaml/Tests/InlineTest.php @@ -432,4 +432,13 @@ public function testTheEmptyStringIsAValidMappingKey() { $this->assertSame(array('' => 'foo'), Inline::parse('{ "": foo }')); } + + /** + * @expectedException \Symfony\Component\Yaml\Exception\ParseException + * @expectedExceptionMessage Unexpected end of line, expected one of ",}". + */ + public function testUnfinishedInlineMap() + { + Inline::parse("{abc: 'def'"); + } } From e350ea000ff34ef15aa50f161b3fad17e81e079d Mon Sep 17 00:00:00 2001 From: Nicolas Grekas Date: Wed, 6 Dec 2017 10:31:46 +0100 Subject: [PATCH 03/75] [HttpFoundation] Send cookies using header() to fix "SameSite" ones --- src/Symfony/Component/HttpFoundation/Response.php | 11 +---------- 1 file changed, 1 insertion(+), 10 deletions(-) diff --git a/src/Symfony/Component/HttpFoundation/Response.php b/src/Symfony/Component/HttpFoundation/Response.php index 6f8a6239593b..f3e45b57cbc7 100644 --- a/src/Symfony/Component/HttpFoundation/Response.php +++ b/src/Symfony/Component/HttpFoundation/Response.php @@ -327,7 +327,7 @@ public function sendHeaders() } // headers - foreach ($this->headers->allPreserveCaseWithoutCookies() as $name => $values) { + foreach ($this->headers->allPreserveCase() as $name => $values) { foreach ($values as $value) { header($name.': '.$value, false, $this->statusCode); } @@ -336,15 +336,6 @@ public function sendHeaders() // status header(sprintf('HTTP/%s %s %s', $this->version, $this->statusCode, $this->statusText), true, $this->statusCode); - // cookies - foreach ($this->headers->getCookies() as $cookie) { - if ($cookie->isRaw()) { - setrawcookie($cookie->getName(), $cookie->getValue(), $cookie->getExpiresTime(), $cookie->getPath(), $cookie->getDomain(), $cookie->isSecure(), $cookie->isHttpOnly()); - } else { - setcookie($cookie->getName(), $cookie->getValue(), $cookie->getExpiresTime(), $cookie->getPath(), $cookie->getDomain(), $cookie->isSecure(), $cookie->isHttpOnly()); - } - } - return $this; } From f331d964d9c0d6daa7d701b3bb885a52018e44df Mon Sep 17 00:00:00 2001 From: Fabien Potencier Date: Fri, 6 Apr 2018 14:49:17 +0200 Subject: [PATCH 04/75] updated CHANGELOG for 2.7.45 --- CHANGELOG-2.7.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/CHANGELOG-2.7.md b/CHANGELOG-2.7.md index 70677f3d18e3..6c8ff11ea85c 100644 --- a/CHANGELOG-2.7.md +++ b/CHANGELOG-2.7.md @@ -7,6 +7,12 @@ in 2.7 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/v2.7.0...v2.7.1 +* 2.7.45 (2018-04-06) + + * bug #26763 [Finder] Remove duplicate slashes in filenames (helhum) + * bug #26749 Add PHPDbg support to HTTP components (hkdobrev) + * bug #26609 [Console] Fix check of color support on Windows (mlocati) + * 2.7.44 (2018-04-02) * bug #26727 [HttpCache] Unlink tmp file on error (Chansig) From 175e883e6cc80ff8f148b649eb5bd9edf946a797 Mon Sep 17 00:00:00 2001 From: Fabien Potencier Date: Fri, 6 Apr 2018 14:49:33 +0200 Subject: [PATCH 05/75] update CONTRIBUTORS for 2.7.45 --- CONTRIBUTORS.md | 40 ++++++++++++++++++++++++++-------------- 1 file changed, 26 insertions(+), 14 deletions(-) diff --git a/CONTRIBUTORS.md b/CONTRIBUTORS.md index 1cb4373ec203..57bd22e5c521 100644 --- a/CONTRIBUTORS.md +++ b/CONTRIBUTORS.md @@ -14,14 +14,14 @@ Symfony is the result of the work of many people who made the code better - Victor Berchet (victor) - Kévin Dunglas (dunglas) - Johannes S (johannes) - - Jakub Zalas (jakubzalas) - Robin Chalas (chalas_r) + - Jakub Zalas (jakubzalas) - Kris Wallsmith (kriswallsmith) - Ryan Weaver (weaverryan) - Javier Eguiluz (javier.eguiluz) - Maxime Steinhausser (ogizanagi) - - Hugo Hamon (hhamon) - Grégoire Pineau (lyrixx) + - Hugo Hamon (hhamon) - Abdellatif Ait boudad (aitboudad) - Romain Neutron (romain) - Pascal Borreli (pborreli) @@ -49,16 +49,16 @@ Symfony is the result of the work of many people who made the code better - Iltar van der Berg (kjarli) - stealth35 ‏ (stealth35) - Alexander Mols (asm89) + - Samuel ROZE (sroze) - Yonel Ceruto (yonelceruto) - Bulat Shakirzyanov (avalanche123) - Peter Rehm (rpet) - Saša Stamenković (umpirsky) - Matthias Pigulla (mpdude) - - Samuel ROZE (sroze) + - Pierre du Plessis (pierredup) - Henrik Bjørnskov (henrikbjorn) - Dany Maillard (maidmaid) - Miha Vrhovnik - - Pierre du Plessis (pierredup) - Tobias Nyholm (tobias) - Diego Saint Esteben (dii3g0) - Konstantin Kudryashov (everzet) @@ -81,8 +81,8 @@ Symfony is the result of the work of many people who made the code better - Deni - Henrik Westphal (snc) - Dariusz Górecki (canni) - - Douglas Greenshields (shieldo) - Issei Murasawa (issei_m) + - Douglas Greenshields (shieldo) - Lee McDermott - Brandon Turner - Luis Cordova (cordoval) @@ -94,10 +94,10 @@ Symfony is the result of the work of many people who made the code better - Jordan Alliot (jalliot) - Jérôme Tamarelle (gromnan) - John Wards (johnwards) + - David Maicher (dmaicher) - Fran Moreno (franmomu) - Antoine Hérault (herzult) - Paráda József (paradajozsef) - - David Maicher (dmaicher) - Vladimir Reznichenko (kalessil) - Arnaud Le Blanc (arnaud-lb) - Maxime STEINHAUSSER @@ -148,6 +148,7 @@ Symfony is the result of the work of many people who made the code better - Julien Falque (julienfalque) - Rafael Dohms (rdohms) - Arnaud Kleinpeter (nanocom) + - gadelat (gadelat) - jwdeitch - Mikael Pajunen - Joel Wurtz (brouznouf) @@ -158,7 +159,6 @@ Symfony is the result of the work of many people who made the code better - Richard van Laak (rvanlaak) - Richard Shank (iampersistent) - Thomas Rabaix (rande) - - gadelat (gadelat) - Rouven Weßling (realityking) - Teoh Han Hui (teohhanhui) - Clemens Tolboom @@ -292,6 +292,7 @@ Symfony is the result of the work of many people who made the code better - Roumen Damianoff (roumen) - Antonio J. García Lagar (ajgarlag) - Kim Hemsø Rasmussen (kimhemsoe) + - Florent Mata (fmata) - Wouter Van Hecke - Jérôme Parmentier (lctrs) - Michael Babker (mbabker) @@ -371,13 +372,13 @@ Symfony is the result of the work of many people who made the code better - Philipp Kräutli (pkraeutli) - Kirill chEbba Chebunin (chebba) - Greg Thornton (xdissent) - - Florent Mata (fmata) - Costin Bereveanu (schniper) - Loïc Chardonnet (gnusat) - Marek Kalnik (marekkalnik) - Vyacheslav Salakhutdinov (megazoll) - Hassan Amouhzi - Tamas Szijarto + - Michele Locati - Pavel Volokitin (pvolok) - Arthur de Moulins (4rthem) - Nicolas Dewez (nicolas_dewez) @@ -435,6 +436,7 @@ Symfony is the result of the work of many people who made the code better - Florian Pfitzer (marmelatze) - Asier Illarramendi (doup) - Andreas Braun + - Boris Vujicic (boris.vujicic) - Chris Sedlmayr (catchamonkey) - Seb Koelen - Christoph Mewes (xrstf) @@ -467,6 +469,7 @@ Symfony is the result of the work of many people who made the code better - Roman Lapin (memphys) - Yoshio HANAWA - Gladhon + - Haralan Dobrev (hkdobrev) - Sebastian Bergmann - Miroslav Sustek - Sullivan SENECHAL (soullivaneuh) @@ -499,7 +502,6 @@ Symfony is the result of the work of many people who made the code better - Andrew Udvare (audvare) - alexpods - Arjen van der Meijden - - Michele Locati - Dariusz Ruminski - Mathieu Lechat - Erik Trapman (eriktrapman) @@ -588,7 +590,6 @@ Symfony is the result of the work of many people who made the code better - Javier López (loalf) - Reinier Kip - Geoffrey Brier (geoffrey-brier) - - Boris Vujicic (boris.vujicic) - Dustin Dobervich (dustin10) - dantleech - Anne-Sophie Bachelard (annesophie) @@ -603,6 +604,7 @@ Symfony is the result of the work of many people who made the code better - mcfedr (mcfedr) - Rostyslav Kinash - Maciej Malarz (malarzm) + - Pascal Luna (skalpa) - Daisuke Ohata - Vincent Simonin - Alex Bogomazov (alebo) @@ -623,6 +625,7 @@ Symfony is the result of the work of many people who made the code better - Denis Brumann (dbrumann) - Quentin de Longraye (quentinus95) - Chris Heng (gigablah) + - Shaun Simmons (simshaun) - Richard Bradley - Ulumuddin Yunus (joenoez) - Johann Saunier (prophet777) @@ -765,6 +768,7 @@ Symfony is the result of the work of many people who made the code better - Maksim Kotlyar (makasim) - Neil Ferreira - Nathanael Noblet (gnat) + - Indra Gunawan (indragunawan) - Dmitry Parnas (parnas) - Paul LE CORRE - Emanuele Iannone @@ -951,6 +955,7 @@ Symfony is the result of the work of many people who made the code better - Ken Marfilla (marfillaster) - benatespina (benatespina) - Denis Kop + - Jean-Guilhem Rouel (jean-gui) - jfcixmedia - Nikita Konstantinov - Martijn Evers @@ -982,7 +987,6 @@ Symfony is the result of the work of many people who made the code better - Olaf Klischat - orlovv - Peter Smeets (darkspartan) - - Haralan Dobrev (hkdobrev) - Jhonny Lidfors (jhonny) - Julien Bianchi (jubianchi) - Robert Meijers @@ -1001,6 +1005,7 @@ Symfony is the result of the work of many people who made the code better - Jeremy Bush - wizhippo - Viacheslav Sychov + - Helmut Hummel (helhum) - Matt Brunt - Carlos Ortega Huetos - rpg600 @@ -1025,6 +1030,7 @@ Symfony is the result of the work of many people who made the code better - rchoquet - gitlost - Taras Girnyk + - Anthony GRASSIOT (antograssiot) - Eduardo García Sanz (coma) - James Gilliland - fduch (fduch) @@ -1054,6 +1060,7 @@ Symfony is the result of the work of many people who made the code better - Peter Thompson (petert82) - Felicitus - Krzysztof Przybyszewski + - alexpozzi - Paul Matthews - Jakub Kisielewski - Vacheslav Silyutin @@ -1133,6 +1140,7 @@ Symfony is the result of the work of many people who made the code better - Berat Doğan - Guillaume LECERF - Juanmi Rodriguez Cerón + - Sergey Yastrebov - Andy Raines - Anthony Ferrara - Klaas Cuvelier (kcuvelier) @@ -1226,6 +1234,7 @@ Symfony is the result of the work of many people who made the code better - Ergie Gonzaga - Matthew J Mucklo - AnrDaemon + - Smaine Milianni (ismail1432) - fdgdfg (psampaz) - Stéphane Seng - Maxwell Vandervelde @@ -1362,7 +1371,6 @@ Symfony is the result of the work of many people who made the code better - Christopher Parotat - 蝦米 - Grayson Koonce (breerly) - - Indra Gunawan (indragunawan) - Karim Cassam Chenaï (ka) - Michal Kurzeja (mkurzeja) - Nicolas Bastien (nicolas_bastien) @@ -1446,6 +1454,7 @@ Symfony is the result of the work of many people who made the code better - Edvinas Klovas - Drew Butler - Peter Breuls + - Chansig - Tischoi - J Bruni - Alexey Prilipko @@ -1530,6 +1539,7 @@ Symfony is the result of the work of many people who made the code better - Erik van Wingerden - Valouleloup - Dane Powell + - mweimerskirch - Gerrit Drost - Linnaea Von Lavia - Simon Mönch @@ -1633,6 +1643,7 @@ Symfony is the result of the work of many people who made the code better - temperatur - Cas - Dusan Kasan + - Karolis - Myke79 - Brian Debuire - Piers Warmers @@ -1703,7 +1714,6 @@ Symfony is the result of the work of many people who made the code better - Neophy7e - bokonet - Arrilot - - Shaun Simmons - Markus Staab - Pierre-Louis LAUNAY - djama @@ -1832,6 +1842,7 @@ Symfony is the result of the work of many people who made the code better - emilienbouard (neime) - Nicholas Byfleet (nickbyfleet) - Tomas Norkūnas (norkunas) + - Marco Petersen (ocrampete16) - ollie harridge (ollietb) - Paul Andrieux (paulandrieux) - Paweł Szczepanek (pauluz) @@ -1851,11 +1862,11 @@ Symfony is the result of the work of many people who made the code better - scourgen hung (scourgen) - Sébastien Alfaiate (seb33300) - Sebastian Busch (sebu) + - Christophe Villeger (seragan) - André Filipe Gonçalves Neves (seven) - Bruno Ziegler (sfcoder) - Andrea Giuliano (shark) - Schuyler Jager (sjager) - - Pascal Luna (skalpa) - Volker (skydiablo) - Serkan Yildiz (srknyldz) - Julien Sanchez (sumbobyboys) @@ -1886,6 +1897,7 @@ Symfony is the result of the work of many people who made the code better - Ben Scott - Dionysis Arvanitis - Sergey Fedotov + - Konstantin Scheumann - Michael - fh-github@fholzhauer.de - AbdElKader Bouadjadja From 952879e147e9bf93f576056e6d798ae9184d52f3 Mon Sep 17 00:00:00 2001 From: Fabien Potencier Date: Fri, 6 Apr 2018 14:49:33 +0200 Subject: [PATCH 06/75] updated VERSION for 2.7.45 --- src/Symfony/Component/HttpKernel/Kernel.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Symfony/Component/HttpKernel/Kernel.php b/src/Symfony/Component/HttpKernel/Kernel.php index 687760865b6e..ca42a5e29958 100644 --- a/src/Symfony/Component/HttpKernel/Kernel.php +++ b/src/Symfony/Component/HttpKernel/Kernel.php @@ -58,12 +58,12 @@ abstract class Kernel implements KernelInterface, TerminableInterface protected $startTime; protected $loadClassCache; - const VERSION = '2.7.45-DEV'; + const VERSION = '2.7.45'; const VERSION_ID = 20745; const MAJOR_VERSION = 2; const MINOR_VERSION = 7; const RELEASE_VERSION = 45; - const EXTRA_VERSION = 'DEV'; + const EXTRA_VERSION = ''; const END_OF_MAINTENANCE = '05/2018'; const END_OF_LIFE = '05/2019'; From e73aa2985b435400ed76c6fd7bea80366dc21b67 Mon Sep 17 00:00:00 2001 From: Fabien Potencier Date: Fri, 6 Apr 2018 16:50:48 +0200 Subject: [PATCH 07/75] bumped Symfony version to 2.7.46 --- src/Symfony/Component/HttpKernel/Kernel.php | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/Symfony/Component/HttpKernel/Kernel.php b/src/Symfony/Component/HttpKernel/Kernel.php index ca42a5e29958..1b8abba1474d 100644 --- a/src/Symfony/Component/HttpKernel/Kernel.php +++ b/src/Symfony/Component/HttpKernel/Kernel.php @@ -58,12 +58,12 @@ abstract class Kernel implements KernelInterface, TerminableInterface protected $startTime; protected $loadClassCache; - const VERSION = '2.7.45'; - const VERSION_ID = 20745; + const VERSION = '2.7.46-DEV'; + const VERSION_ID = 20746; const MAJOR_VERSION = 2; const MINOR_VERSION = 7; - const RELEASE_VERSION = 45; - const EXTRA_VERSION = ''; + const RELEASE_VERSION = 46; + const EXTRA_VERSION = 'DEV'; const END_OF_MAINTENANCE = '05/2018'; const END_OF_LIFE = '05/2019'; From fa3f105f61d7068592d40cd2217397a20d81b745 Mon Sep 17 00:00:00 2001 From: Fabien Potencier Date: Fri, 6 Apr 2018 16:51:52 +0200 Subject: [PATCH 08/75] updated CHANGELOG for 2.8.38 --- CHANGELOG-2.8.md | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/CHANGELOG-2.8.md b/CHANGELOG-2.8.md index e933be2021ab..e53256bdc832 100644 --- a/CHANGELOG-2.8.md +++ b/CHANGELOG-2.8.md @@ -7,6 +7,14 @@ in 2.8 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/v2.8.0...v2.8.1 +* 2.8.38 (2018-04-06) + + * bug #26788 [Security] Load the user before pre/post auth checks when needed (chalasr) + * bug #26774 [SecurityBundle] Add missing argument to security.authentication.provider.simple (i3or1s, chalasr) + * bug #26763 [Finder] Remove duplicate slashes in filenames (helhum) + * bug #26749 Add PHPDbg support to HTTP components (hkdobrev) + * bug #26609 [Console] Fix check of color support on Windows (mlocati) + * 2.8.37 (2018-04-02) * bug #26727 [HttpCache] Unlink tmp file on error (Chansig) From 47b29834cb08e20c4618eab9973a5e03d13a8814 Mon Sep 17 00:00:00 2001 From: Fabien Potencier Date: Fri, 6 Apr 2018 16:52:08 +0200 Subject: [PATCH 09/75] updated VERSION for 2.8.38 --- src/Symfony/Component/HttpKernel/Kernel.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Symfony/Component/HttpKernel/Kernel.php b/src/Symfony/Component/HttpKernel/Kernel.php index defbf43974e4..3d54fdffcfa1 100644 --- a/src/Symfony/Component/HttpKernel/Kernel.php +++ b/src/Symfony/Component/HttpKernel/Kernel.php @@ -59,12 +59,12 @@ abstract class Kernel implements KernelInterface, TerminableInterface protected $startTime; protected $loadClassCache; - const VERSION = '2.8.38-DEV'; + const VERSION = '2.8.38'; const VERSION_ID = 20838; const MAJOR_VERSION = 2; const MINOR_VERSION = 8; const RELEASE_VERSION = 38; - const EXTRA_VERSION = 'DEV'; + const EXTRA_VERSION = ''; const END_OF_MAINTENANCE = '11/2018'; const END_OF_LIFE = '11/2019'; From b04452a223f9ce4279d18795745351aeb6581fd4 Mon Sep 17 00:00:00 2001 From: Fabien Potencier Date: Fri, 6 Apr 2018 17:19:00 +0200 Subject: [PATCH 10/75] bumped Symfony version to 2.8.39 --- src/Symfony/Component/HttpKernel/Kernel.php | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/Symfony/Component/HttpKernel/Kernel.php b/src/Symfony/Component/HttpKernel/Kernel.php index 3d54fdffcfa1..3193b61e8b18 100644 --- a/src/Symfony/Component/HttpKernel/Kernel.php +++ b/src/Symfony/Component/HttpKernel/Kernel.php @@ -59,12 +59,12 @@ abstract class Kernel implements KernelInterface, TerminableInterface protected $startTime; protected $loadClassCache; - const VERSION = '2.8.38'; - const VERSION_ID = 20838; + const VERSION = '2.8.39-DEV'; + const VERSION_ID = 20839; const MAJOR_VERSION = 2; const MINOR_VERSION = 8; - const RELEASE_VERSION = 38; - const EXTRA_VERSION = ''; + const RELEASE_VERSION = 39; + const EXTRA_VERSION = 'DEV'; const END_OF_MAINTENANCE = '11/2018'; const END_OF_LIFE = '11/2019'; From 0cbee5e9aa1ef7c5d6582e4370596a6e63a20fc8 Mon Sep 17 00:00:00 2001 From: Fabien Potencier Date: Fri, 6 Apr 2018 17:19:35 +0200 Subject: [PATCH 11/75] updated CHANGELOG for 3.4.8 --- CHANGELOG-3.4.md | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/CHANGELOG-3.4.md b/CHANGELOG-3.4.md index ee69e43fc838..abc5e0a9f4da 100644 --- a/CHANGELOG-3.4.md +++ b/CHANGELOG-3.4.md @@ -7,6 +7,16 @@ in 3.4 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.4.0...v3.4.1 +* 3.4.8 (2018-04-06) + + * bug #26802 [Security] register custom providers on ExpressionLanguage directly (dmaicher) + * bug #26794 [PhpUnitBridge] Catch deprecation error handler (cvilleger) + * bug #26788 [Security] Load the user before pre/post auth checks when needed (chalasr) + * bug #26792 [Routing] Fix throwing NoConfigurationException instead of 405 (nicolas-grekas) + * bug #26774 [SecurityBundle] Add missing argument to security.authentication.provider.simple (i3or1s, chalasr) + * bug #26763 [Finder] Remove duplicate slashes in filenames (helhum) + * bug #26758 [WebProfilerBundle][HttpKernel] Make FileLinkFormatter URL format generation lazy (nicolas-grekas) + * 3.4.7 (2018-04-03) * bug #26387 [Yaml] Fix regression when trying to parse multiline (antograssiot) From 884b994be98571ead1f30fa86a5aabd89f3c6ec1 Mon Sep 17 00:00:00 2001 From: Fabien Potencier Date: Fri, 6 Apr 2018 17:19:48 +0200 Subject: [PATCH 12/75] updated VERSION for 3.4.8 --- src/Symfony/Component/HttpKernel/Kernel.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Symfony/Component/HttpKernel/Kernel.php b/src/Symfony/Component/HttpKernel/Kernel.php index 7cb3621744d3..03cd708ebf24 100644 --- a/src/Symfony/Component/HttpKernel/Kernel.php +++ b/src/Symfony/Component/HttpKernel/Kernel.php @@ -67,12 +67,12 @@ abstract class Kernel implements KernelInterface, RebootableInterface, Terminabl private $requestStackSize = 0; private $resetServices = false; - const VERSION = '3.4.8-DEV'; + const VERSION = '3.4.8'; const VERSION_ID = 30408; const MAJOR_VERSION = 3; const MINOR_VERSION = 4; const RELEASE_VERSION = 8; - const EXTRA_VERSION = 'DEV'; + const EXTRA_VERSION = ''; const END_OF_MAINTENANCE = '11/2020'; const END_OF_LIFE = '11/2021'; From 4dda7abdce442b97acea21256e7044309630966d Mon Sep 17 00:00:00 2001 From: Fabien Potencier Date: Fri, 6 Apr 2018 18:24:29 +0200 Subject: [PATCH 13/75] bumped Symfony version to 3.4.9 --- src/Symfony/Component/HttpKernel/Kernel.php | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/Symfony/Component/HttpKernel/Kernel.php b/src/Symfony/Component/HttpKernel/Kernel.php index 03cd708ebf24..0d68c4f7ff04 100644 --- a/src/Symfony/Component/HttpKernel/Kernel.php +++ b/src/Symfony/Component/HttpKernel/Kernel.php @@ -67,12 +67,12 @@ abstract class Kernel implements KernelInterface, RebootableInterface, Terminabl private $requestStackSize = 0; private $resetServices = false; - const VERSION = '3.4.8'; - const VERSION_ID = 30408; + const VERSION = '3.4.9-DEV'; + const VERSION_ID = 30409; const MAJOR_VERSION = 3; const MINOR_VERSION = 4; - const RELEASE_VERSION = 8; - const EXTRA_VERSION = ''; + const RELEASE_VERSION = 9; + const EXTRA_VERSION = 'DEV'; const END_OF_MAINTENANCE = '11/2020'; const END_OF_LIFE = '11/2021'; From 02e5fbceeaeacf7265ad7276a63f3d804e49f483 Mon Sep 17 00:00:00 2001 From: Fabien Potencier Date: Fri, 6 Apr 2018 18:49:36 +0200 Subject: [PATCH 14/75] bumped Symfony version to 4.0.9 --- src/Symfony/Component/HttpKernel/Kernel.php | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/Symfony/Component/HttpKernel/Kernel.php b/src/Symfony/Component/HttpKernel/Kernel.php index db80323c206d..1c87544c6b93 100644 --- a/src/Symfony/Component/HttpKernel/Kernel.php +++ b/src/Symfony/Component/HttpKernel/Kernel.php @@ -63,12 +63,12 @@ abstract class Kernel implements KernelInterface, RebootableInterface, Terminabl private $requestStackSize = 0; private $resetServices = false; - const VERSION = '4.0.8'; - const VERSION_ID = 40008; + const VERSION = '4.0.9-DEV'; + const VERSION_ID = 40009; const MAJOR_VERSION = 4; const MINOR_VERSION = 0; - const RELEASE_VERSION = 8; - const EXTRA_VERSION = ''; + const RELEASE_VERSION = 9; + const EXTRA_VERSION = 'DEV'; const END_OF_MAINTENANCE = '07/2018'; const END_OF_LIFE = '01/2019'; From c36f6db14b42a68e5ddafc05bfbad5839f643c8c Mon Sep 17 00:00:00 2001 From: Nicolas Grekas Date: Sat, 7 Apr 2018 15:20:24 +0200 Subject: [PATCH 15/75] [Translation] Use unix-style EOL for xliff-core-1.2-strict.xsd --- .../schemas/xliff-core-1.2-strict.xsd | 4446 ++++++++--------- 1 file changed, 2223 insertions(+), 2223 deletions(-) diff --git a/src/Symfony/Component/Translation/Resources/schemas/xliff-core-1.2-strict.xsd b/src/Symfony/Component/Translation/Resources/schemas/xliff-core-1.2-strict.xsd index 803eb602def5..dface628ce3e 100644 --- a/src/Symfony/Component/Translation/Resources/schemas/xliff-core-1.2-strict.xsd +++ b/src/Symfony/Component/Translation/Resources/schemas/xliff-core-1.2-strict.xsd @@ -1,2223 +1,2223 @@ - - - - - - - - - - - - - - - Values for the attribute 'context-type'. - - - - - Indicates a database content. - - - - - Indicates the content of an element within an XML document. - - - - - Indicates the name of an element within an XML document. - - - - - Indicates the line number from the sourcefile (see context-type="sourcefile") where the <source> is found. - - - - - Indicates a the number of parameters contained within the <source>. - - - - - Indicates notes pertaining to the parameters in the <source>. - - - - - Indicates the content of a record within a database. - - - - - Indicates the name of a record within a database. - - - - - Indicates the original source file in the case that multiple files are merged to form the original file from which the XLIFF file is created. This differs from the original <file> attribute in that this sourcefile is one of many that make up that file. - - - - - - - Values for the attribute 'count-type'. - - - - - Indicates the count units are items that are used X times in a certain context; example: this is a reusable text unit which is used 42 times in other texts. - - - - - Indicates the count units are translation units existing already in the same document. - - - - - Indicates a total count. - - - - - - - Values for the attribute 'ctype' when used other elements than <ph> or <x>. - - - - - Indicates a run of bolded text. - - - - - Indicates a run of text in italics. - - - - - Indicates a run of underlined text. - - - - - Indicates a run of hyper-text. - - - - - - - Values for the attribute 'ctype' when used with <ph> or <x>. - - - - - Indicates a inline image. - - - - - Indicates a page break. - - - - - Indicates a line break. - - - - - - - - - - - - Values for the attribute 'datatype'. - - - - - Indicates Active Server Page data. - - - - - Indicates C source file data. - - - - - Indicates Channel Definition Format (CDF) data. - - - - - Indicates ColdFusion data. - - - - - Indicates C++ source file data. - - - - - Indicates C-Sharp data. - - - - - Indicates strings from C, ASM, and driver files data. - - - - - Indicates comma-separated values data. - - - - - Indicates database data. - - - - - Indicates portions of document that follows data and contains metadata. - - - - - Indicates portions of document that precedes data and contains metadata. - - - - - Indicates data from standard UI file operations dialogs (e.g., Open, Save, Save As, Export, Import). - - - - - Indicates standard user input screen data. - - - - - Indicates HyperText Markup Language (HTML) data - document instance. - - - - - Indicates content within an HTML document’s <body> element. - - - - - Indicates Windows INI file data. - - - - - Indicates Interleaf data. - - - - - Indicates Java source file data (extension '.java'). - - - - - Indicates Java property resource bundle data. - - - - - Indicates Java list resource bundle data. - - - - - Indicates JavaScript source file data. - - - - - Indicates JScript source file data. - - - - - Indicates information relating to formatting. - - - - - Indicates LISP source file data. - - - - - Indicates information relating to margin formats. - - - - - Indicates a file containing menu. - - - - - Indicates numerically identified string table. - - - - - Indicates Maker Interchange Format (MIF) data. - - - - - Indicates that the datatype attribute value is a MIME Type value and is defined in the mime-type attribute. - - - - - Indicates GNU Machine Object data. - - - - - Indicates Message Librarian strings created by Novell's Message Librarian Tool. - - - - - Indicates information to be displayed at the bottom of each page of a document. - - - - - Indicates information to be displayed at the top of each page of a document. - - - - - Indicates a list of property values (e.g., settings within INI files or preferences dialog). - - - - - Indicates Pascal source file data. - - - - - Indicates Hypertext Preprocessor data. - - - - - Indicates plain text file (no formatting other than, possibly, wrapping). - - - - - Indicates GNU Portable Object file. - - - - - Indicates dynamically generated user defined document. e.g. Oracle Report, Crystal Report, etc. - - - - - Indicates Windows .NET binary resources. - - - - - Indicates Windows .NET Resources. - - - - - Indicates Rich Text Format (RTF) data. - - - - - Indicates Standard Generalized Markup Language (SGML) data - document instance. - - - - - Indicates Standard Generalized Markup Language (SGML) data - Document Type Definition (DTD). - - - - - Indicates Scalable Vector Graphic (SVG) data. - - - - - Indicates VisualBasic Script source file. - - - - - Indicates warning message. - - - - - Indicates Windows (Win32) resources (i.e. resources extracted from an RC script, a message file, or a compiled file). - - - - - Indicates Extensible HyperText Markup Language (XHTML) data - document instance. - - - - - Indicates Extensible Markup Language (XML) data - document instance. - - - - - Indicates Extensible Markup Language (XML) data - Document Type Definition (DTD). - - - - - Indicates Extensible Stylesheet Language (XSL) data. - - - - - Indicates XUL elements. - - - - - - - Values for the attribute 'mtype'. - - - - - Indicates the marked text is an abbreviation. - - - - - ISO-12620 2.1.8: A term resulting from the omission of any part of the full term while designating the same concept. - - - - - ISO-12620 2.1.8.1: An abbreviated form of a simple term resulting from the omission of some of its letters (e.g. 'adj.' for 'adjective'). - - - - - ISO-12620 2.1.8.4: An abbreviated form of a term made up of letters from the full form of a multiword term strung together into a sequence pronounced only syllabically (e.g. 'radar' for 'radio detecting and ranging'). - - - - - ISO-12620: A proper-name term, such as the name of an agency or other proper entity. - - - - - ISO-12620 2.1.18.1: A recurrent word combination characterized by cohesion in that the components of the collocation must co-occur within an utterance or series of utterances, even though they do not necessarily have to maintain immediate proximity to one another. - - - - - ISO-12620 2.1.5: A synonym for an international scientific term that is used in general discourse in a given language. - - - - - Indicates the marked text is a date and/or time. - - - - - ISO-12620 2.1.15: An expression used to represent a concept based on a statement that two mathematical expressions are, for instance, equal as identified by the equal sign (=), or assigned to one another by a similar sign. - - - - - ISO-12620 2.1.7: The complete representation of a term for which there is an abbreviated form. - - - - - ISO-12620 2.1.14: Figures, symbols or the like used to express a concept briefly, such as a mathematical or chemical formula. - - - - - ISO-12620 2.1.1: The concept designation that has been chosen to head a terminological record. - - - - - ISO-12620 2.1.8.3: An abbreviated form of a term consisting of some of the initial letters of the words making up a multiword term or the term elements making up a compound term when these letters are pronounced individually (e.g. 'BSE' for 'bovine spongiform encephalopathy'). - - - - - ISO-12620 2.1.4: A term that is part of an international scientific nomenclature as adopted by an appropriate scientific body. - - - - - ISO-12620 2.1.6: A term that has the same or nearly identical orthographic or phonemic form in many languages. - - - - - ISO-12620 2.1.16: An expression used to represent a concept based on mathematical or logical relations, such as statements of inequality, set relationships, Boolean operations, and the like. - - - - - ISO-12620 2.1.17: A unit to track object. - - - - - Indicates the marked text is a name. - - - - - ISO-12620 2.1.3: A term that represents the same or a very similar concept as another term in the same language, but for which interchangeability is limited to some contexts and inapplicable in others. - - - - - ISO-12620 2.1.17.2: A unique alphanumeric designation assigned to an object in a manufacturing system. - - - - - Indicates the marked text is a phrase. - - - - - ISO-12620 2.1.18: Any group of two or more words that form a unit, the meaning of which frequently cannot be deduced based on the combined sense of the words making up the phrase. - - - - - Indicates the marked text should not be translated. - - - - - ISO-12620 2.1.12: A form of a term resulting from an operation whereby non-Latin writing systems are converted to the Latin alphabet. - - - - - Indicates that the marked text represents a segment. - - - - - ISO-12620 2.1.18.2: A fixed, lexicalized phrase. - - - - - ISO-12620 2.1.8.2: A variant of a multiword term that includes fewer words than the full form of the term (e.g. 'Group of Twenty-four' for 'Intergovernmental Group of Twenty-four on International Monetary Affairs'). - - - - - ISO-12620 2.1.17.1: Stock keeping unit, an inventory item identified by a unique alphanumeric designation assigned to an object in an inventory control system. - - - - - ISO-12620 2.1.19: A fixed chunk of recurring text. - - - - - ISO-12620 2.1.13: A designation of a concept by letters, numerals, pictograms or any combination thereof. - - - - - ISO-12620 2.1.2: Any term that represents the same or a very similar concept as the main entry term in a term entry. - - - - - ISO-12620 2.1.18.3: Phraseological unit in a language that expresses the same semantic content as another phrase in that same language. - - - - - Indicates the marked text is a term. - - - - - ISO-12620 2.1.11: A form of a term resulting from an operation whereby the characters of one writing system are represented by characters from another writing system, taking into account the pronunciation of the characters converted. - - - - - ISO-12620 2.1.10: A form of a term resulting from an operation whereby the characters of an alphabetic writing system are represented by characters from another alphabetic writing system. - - - - - ISO-12620 2.1.8.5: An abbreviated form of a term resulting from the omission of one or more term elements or syllables (e.g. 'flu' for 'influenza'). - - - - - ISO-12620 2.1.9: One of the alternate forms of a term. - - - - - - - Values for the attribute 'restype'. - - - - - Indicates a Windows RC AUTO3STATE control. - - - - - Indicates a Windows RC AUTOCHECKBOX control. - - - - - Indicates a Windows RC AUTORADIOBUTTON control. - - - - - Indicates a Windows RC BEDIT control. - - - - - Indicates a bitmap, for example a BITMAP resource in Windows. - - - - - Indicates a button object, for example a BUTTON control Windows. - - - - - Indicates a caption, such as the caption of a dialog box. - - - - - Indicates the cell in a table, for example the content of the <td> element in HTML. - - - - - Indicates check box object, for example a CHECKBOX control in Windows. - - - - - Indicates a menu item with an associated checkbox. - - - - - Indicates a list box, but with a check-box for each item. - - - - - Indicates a color selection dialog. - - - - - Indicates a combination of edit box and listbox object, for example a COMBOBOX control in Windows. - - - - - Indicates an initialization entry of an extended combobox DLGINIT resource block. (code 0x1234). - - - - - Indicates an initialization entry of a combobox DLGINIT resource block (code 0x0403). - - - - - Indicates a UI base class element that cannot be represented by any other element. - - - - - Indicates a context menu. - - - - - Indicates a Windows RC CTEXT control. - - - - - Indicates a cursor, for example a CURSOR resource in Windows. - - - - - Indicates a date/time picker. - - - - - Indicates a Windows RC DEFPUSHBUTTON control. - - - - - Indicates a dialog box. - - - - - Indicates a Windows RC DLGINIT resource block. - - - - - Indicates an edit box object, for example an EDIT control in Windows. - - - - - Indicates a filename. - - - - - Indicates a file dialog. - - - - - Indicates a footnote. - - - - - Indicates a font name. - - - - - Indicates a footer. - - - - - Indicates a frame object. - - - - - Indicates a XUL grid element. - - - - - Indicates a groupbox object, for example a GROUPBOX control in Windows. - - - - - Indicates a header item. - - - - - Indicates a heading, such has the content of <h1>, <h2>, etc. in HTML. - - - - - Indicates a Windows RC HEDIT control. - - - - - Indicates a horizontal scrollbar. - - - - - Indicates an icon, for example an ICON resource in Windows. - - - - - Indicates a Windows RC IEDIT control. - - - - - Indicates keyword list, such as the content of the Keywords meta-data in HTML, or a K footnote in WinHelp RTF. - - - - - Indicates a label object. - - - - - Indicates a label that is also a HTML link (not necessarily a URL). - - - - - Indicates a list (a group of list-items, for example an <ol> or <ul> element in HTML). - - - - - Indicates a listbox object, for example an LISTBOX control in Windows. - - - - - Indicates an list item (an entry in a list). - - - - - Indicates a Windows RC LTEXT control. - - - - - Indicates a menu (a group of menu-items). - - - - - Indicates a toolbar containing one or more tope level menus. - - - - - Indicates a menu item (an entry in a menu). - - - - - Indicates a XUL menuseparator element. - - - - - Indicates a message, for example an entry in a MESSAGETABLE resource in Windows. - - - - - Indicates a calendar control. - - - - - Indicates an edit box beside a spin control. - - - - - Indicates a catch all for rectangular areas. - - - - - Indicates a standalone menu not necessarily associated with a menubar. - - - - - Indicates a pushbox object, for example a PUSHBOX control in Windows. - - - - - Indicates a Windows RC PUSHBUTTON control. - - - - - Indicates a radio button object. - - - - - Indicates a menuitem with associated radio button. - - - - - Indicates raw data resources for an application. - - - - - Indicates a row in a table. - - - - - Indicates a Windows RC RTEXT control. - - - - - Indicates a user navigable container used to show a portion of a document. - - - - - Indicates a generic divider object (e.g. menu group separator). - - - - - Windows accelerators, shortcuts in resource or property files. - - - - - Indicates a UI control to indicate process activity but not progress. - - - - - Indicates a splitter bar. - - - - - Indicates a Windows RC STATE3 control. - - - - - Indicates a window for providing feedback to the users, like 'read-only', etc. - - - - - Indicates a string, for example an entry in a STRINGTABLE resource in Windows. - - - - - Indicates a layers of controls with a tab to select layers. - - - - - Indicates a display and edits regular two-dimensional tables of cells. - - - - - Indicates a XUL textbox element. - - - - - Indicates a UI button that can be toggled to on or off state. - - - - - Indicates an array of controls, usually buttons. - - - - - Indicates a pop up tool tip text. - - - - - Indicates a bar with a pointer indicating a position within a certain range. - - - - - Indicates a control that displays a set of hierarchical data. - - - - - Indicates a URI (URN or URL). - - - - - Indicates a Windows RC USERBUTTON control. - - - - - Indicates a user-defined control like CONTROL control in Windows. - - - - - Indicates the text of a variable. - - - - - Indicates version information about a resource like VERSIONINFO in Windows. - - - - - Indicates a vertical scrollbar. - - - - - Indicates a graphical window. - - - - - - - Values for the attribute 'size-unit'. - - - - - Indicates a size in 8-bit bytes. - - - - - Indicates a size in Unicode characters. - - - - - Indicates a size in columns. Used for HTML text area. - - - - - Indicates a size in centimeters. - - - - - Indicates a size in dialog units, as defined in Windows resources. - - - - - Indicates a size in 'font-size' units (as defined in CSS). - - - - - Indicates a size in 'x-height' units (as defined in CSS). - - - - - Indicates a size in glyphs. A glyph is considered to be one or more combined Unicode characters that represent a single displayable text character. Sometimes referred to as a 'grapheme cluster' - - - - - Indicates a size in inches. - - - - - Indicates a size in millimeters. - - - - - Indicates a size in percentage. - - - - - Indicates a size in pixels. - - - - - Indicates a size in point. - - - - - Indicates a size in rows. Used for HTML text area. - - - - - - - Values for the attribute 'state'. - - - - - Indicates the terminating state. - - - - - Indicates only non-textual information needs adaptation. - - - - - Indicates both text and non-textual information needs adaptation. - - - - - Indicates only non-textual information needs review. - - - - - Indicates both text and non-textual information needs review. - - - - - Indicates that only the text of the item needs to be reviewed. - - - - - Indicates that the item needs to be translated. - - - - - Indicates that the item is new. For example, translation units that were not in a previous version of the document. - - - - - Indicates that changes are reviewed and approved. - - - - - Indicates that the item has been translated. - - - - - - - Values for the attribute 'state-qualifier'. - - - - - Indicates an exact match. An exact match occurs when a source text of a segment is exactly the same as the source text of a segment that was translated previously. - - - - - Indicates a fuzzy match. A fuzzy match occurs when a source text of a segment is very similar to the source text of a segment that was translated previously (e.g. when the difference is casing, a few changed words, white-space discripancy, etc.). - - - - - Indicates a match based on matching IDs (in addition to matching text). - - - - - Indicates a translation derived from a glossary. - - - - - Indicates a translation derived from existing translation. - - - - - Indicates a translation derived from machine translation. - - - - - Indicates a translation derived from a translation repository. - - - - - Indicates a translation derived from a translation memory. - - - - - Indicates the translation is suggested by machine translation. - - - - - Indicates that the item has been rejected because of incorrect grammar. - - - - - Indicates that the item has been rejected because it is incorrect. - - - - - Indicates that the item has been rejected because it is too long or too short. - - - - - Indicates that the item has been rejected because of incorrect spelling. - - - - - Indicates the translation is suggested by translation memory. - - - - - - - Values for the attribute 'unit'. - - - - - Refers to words. - - - - - Refers to pages. - - - - - Refers to <trans-unit> elements. - - - - - Refers to <bin-unit> elements. - - - - - Refers to glyphs. - - - - - Refers to <trans-unit> and/or <bin-unit> elements. - - - - - Refers to the occurrences of instances defined by the count-type value. - - - - - Refers to characters. - - - - - Refers to lines. - - - - - Refers to sentences. - - - - - Refers to paragraphs. - - - - - Refers to segments. - - - - - Refers to placeables (inline elements). - - - - - - - Values for the attribute 'priority'. - - - - - Highest priority. - - - - - High priority. - - - - - High priority, but not as important as 2. - - - - - High priority, but not as important as 3. - - - - - Medium priority, but more important than 6. - - - - - Medium priority, but less important than 5. - - - - - Low priority, but more important than 8. - - - - - Low priority, but more important than 9. - - - - - Low priority. - - - - - Lowest priority. - - - - - - - - - This value indicates that all properties can be reformatted. This value must be used alone. - - - - - This value indicates that no properties should be reformatted. This value must be used alone. - - - - - - - - - - - - - This value indicates that all information in the coord attribute can be modified. - - - - - This value indicates that the x information in the coord attribute can be modified. - - - - - This value indicates that the y information in the coord attribute can be modified. - - - - - This value indicates that the cx information in the coord attribute can be modified. - - - - - This value indicates that the cy information in the coord attribute can be modified. - - - - - This value indicates that all the information in the font attribute can be modified. - - - - - This value indicates that the name information in the font attribute can be modified. - - - - - This value indicates that the size information in the font attribute can be modified. - - - - - This value indicates that the weight information in the font attribute can be modified. - - - - - This value indicates that the information in the css-style attribute can be modified. - - - - - This value indicates that the information in the style attribute can be modified. - - - - - This value indicates that the information in the exstyle attribute can be modified. - - - - - - - - - - - - - Indicates that the context is informational in nature, specifying for example, how a term should be translated. Thus, should be displayed to anyone editing the XLIFF document. - - - - - Indicates that the context-group is used to specify where the term was found in the translatable source. Thus, it is not displayed. - - - - - Indicates that the context information should be used during translation memory lookups. Thus, it is not displayed. - - - - - - - - - Represents a translation proposal from a translation memory or other resource. - - - - - Represents a previous version of the target element. - - - - - Represents a rejected version of the target element. - - - - - Represents a translation to be used for reference purposes only, for example from a related product or a different language. - - - - - Represents a proposed translation that was used for the translation of the trans-unit, possibly modified. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Values for the attribute 'coord'. - - - - - - - - Version values: 1.0 and 1.1 are allowed for backward compatibility. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file + + + + + + + + + + + + + + + Values for the attribute 'context-type'. + + + + + Indicates a database content. + + + + + Indicates the content of an element within an XML document. + + + + + Indicates the name of an element within an XML document. + + + + + Indicates the line number from the sourcefile (see context-type="sourcefile") where the <source> is found. + + + + + Indicates a the number of parameters contained within the <source>. + + + + + Indicates notes pertaining to the parameters in the <source>. + + + + + Indicates the content of a record within a database. + + + + + Indicates the name of a record within a database. + + + + + Indicates the original source file in the case that multiple files are merged to form the original file from which the XLIFF file is created. This differs from the original <file> attribute in that this sourcefile is one of many that make up that file. + + + + + + + Values for the attribute 'count-type'. + + + + + Indicates the count units are items that are used X times in a certain context; example: this is a reusable text unit which is used 42 times in other texts. + + + + + Indicates the count units are translation units existing already in the same document. + + + + + Indicates a total count. + + + + + + + Values for the attribute 'ctype' when used other elements than <ph> or <x>. + + + + + Indicates a run of bolded text. + + + + + Indicates a run of text in italics. + + + + + Indicates a run of underlined text. + + + + + Indicates a run of hyper-text. + + + + + + + Values for the attribute 'ctype' when used with <ph> or <x>. + + + + + Indicates a inline image. + + + + + Indicates a page break. + + + + + Indicates a line break. + + + + + + + + + + + + Values for the attribute 'datatype'. + + + + + Indicates Active Server Page data. + + + + + Indicates C source file data. + + + + + Indicates Channel Definition Format (CDF) data. + + + + + Indicates ColdFusion data. + + + + + Indicates C++ source file data. + + + + + Indicates C-Sharp data. + + + + + Indicates strings from C, ASM, and driver files data. + + + + + Indicates comma-separated values data. + + + + + Indicates database data. + + + + + Indicates portions of document that follows data and contains metadata. + + + + + Indicates portions of document that precedes data and contains metadata. + + + + + Indicates data from standard UI file operations dialogs (e.g., Open, Save, Save As, Export, Import). + + + + + Indicates standard user input screen data. + + + + + Indicates HyperText Markup Language (HTML) data - document instance. + + + + + Indicates content within an HTML document’s <body> element. + + + + + Indicates Windows INI file data. + + + + + Indicates Interleaf data. + + + + + Indicates Java source file data (extension '.java'). + + + + + Indicates Java property resource bundle data. + + + + + Indicates Java list resource bundle data. + + + + + Indicates JavaScript source file data. + + + + + Indicates JScript source file data. + + + + + Indicates information relating to formatting. + + + + + Indicates LISP source file data. + + + + + Indicates information relating to margin formats. + + + + + Indicates a file containing menu. + + + + + Indicates numerically identified string table. + + + + + Indicates Maker Interchange Format (MIF) data. + + + + + Indicates that the datatype attribute value is a MIME Type value and is defined in the mime-type attribute. + + + + + Indicates GNU Machine Object data. + + + + + Indicates Message Librarian strings created by Novell's Message Librarian Tool. + + + + + Indicates information to be displayed at the bottom of each page of a document. + + + + + Indicates information to be displayed at the top of each page of a document. + + + + + Indicates a list of property values (e.g., settings within INI files or preferences dialog). + + + + + Indicates Pascal source file data. + + + + + Indicates Hypertext Preprocessor data. + + + + + Indicates plain text file (no formatting other than, possibly, wrapping). + + + + + Indicates GNU Portable Object file. + + + + + Indicates dynamically generated user defined document. e.g. Oracle Report, Crystal Report, etc. + + + + + Indicates Windows .NET binary resources. + + + + + Indicates Windows .NET Resources. + + + + + Indicates Rich Text Format (RTF) data. + + + + + Indicates Standard Generalized Markup Language (SGML) data - document instance. + + + + + Indicates Standard Generalized Markup Language (SGML) data - Document Type Definition (DTD). + + + + + Indicates Scalable Vector Graphic (SVG) data. + + + + + Indicates VisualBasic Script source file. + + + + + Indicates warning message. + + + + + Indicates Windows (Win32) resources (i.e. resources extracted from an RC script, a message file, or a compiled file). + + + + + Indicates Extensible HyperText Markup Language (XHTML) data - document instance. + + + + + Indicates Extensible Markup Language (XML) data - document instance. + + + + + Indicates Extensible Markup Language (XML) data - Document Type Definition (DTD). + + + + + Indicates Extensible Stylesheet Language (XSL) data. + + + + + Indicates XUL elements. + + + + + + + Values for the attribute 'mtype'. + + + + + Indicates the marked text is an abbreviation. + + + + + ISO-12620 2.1.8: A term resulting from the omission of any part of the full term while designating the same concept. + + + + + ISO-12620 2.1.8.1: An abbreviated form of a simple term resulting from the omission of some of its letters (e.g. 'adj.' for 'adjective'). + + + + + ISO-12620 2.1.8.4: An abbreviated form of a term made up of letters from the full form of a multiword term strung together into a sequence pronounced only syllabically (e.g. 'radar' for 'radio detecting and ranging'). + + + + + ISO-12620: A proper-name term, such as the name of an agency or other proper entity. + + + + + ISO-12620 2.1.18.1: A recurrent word combination characterized by cohesion in that the components of the collocation must co-occur within an utterance or series of utterances, even though they do not necessarily have to maintain immediate proximity to one another. + + + + + ISO-12620 2.1.5: A synonym for an international scientific term that is used in general discourse in a given language. + + + + + Indicates the marked text is a date and/or time. + + + + + ISO-12620 2.1.15: An expression used to represent a concept based on a statement that two mathematical expressions are, for instance, equal as identified by the equal sign (=), or assigned to one another by a similar sign. + + + + + ISO-12620 2.1.7: The complete representation of a term for which there is an abbreviated form. + + + + + ISO-12620 2.1.14: Figures, symbols or the like used to express a concept briefly, such as a mathematical or chemical formula. + + + + + ISO-12620 2.1.1: The concept designation that has been chosen to head a terminological record. + + + + + ISO-12620 2.1.8.3: An abbreviated form of a term consisting of some of the initial letters of the words making up a multiword term or the term elements making up a compound term when these letters are pronounced individually (e.g. 'BSE' for 'bovine spongiform encephalopathy'). + + + + + ISO-12620 2.1.4: A term that is part of an international scientific nomenclature as adopted by an appropriate scientific body. + + + + + ISO-12620 2.1.6: A term that has the same or nearly identical orthographic or phonemic form in many languages. + + + + + ISO-12620 2.1.16: An expression used to represent a concept based on mathematical or logical relations, such as statements of inequality, set relationships, Boolean operations, and the like. + + + + + ISO-12620 2.1.17: A unit to track object. + + + + + Indicates the marked text is a name. + + + + + ISO-12620 2.1.3: A term that represents the same or a very similar concept as another term in the same language, but for which interchangeability is limited to some contexts and inapplicable in others. + + + + + ISO-12620 2.1.17.2: A unique alphanumeric designation assigned to an object in a manufacturing system. + + + + + Indicates the marked text is a phrase. + + + + + ISO-12620 2.1.18: Any group of two or more words that form a unit, the meaning of which frequently cannot be deduced based on the combined sense of the words making up the phrase. + + + + + Indicates the marked text should not be translated. + + + + + ISO-12620 2.1.12: A form of a term resulting from an operation whereby non-Latin writing systems are converted to the Latin alphabet. + + + + + Indicates that the marked text represents a segment. + + + + + ISO-12620 2.1.18.2: A fixed, lexicalized phrase. + + + + + ISO-12620 2.1.8.2: A variant of a multiword term that includes fewer words than the full form of the term (e.g. 'Group of Twenty-four' for 'Intergovernmental Group of Twenty-four on International Monetary Affairs'). + + + + + ISO-12620 2.1.17.1: Stock keeping unit, an inventory item identified by a unique alphanumeric designation assigned to an object in an inventory control system. + + + + + ISO-12620 2.1.19: A fixed chunk of recurring text. + + + + + ISO-12620 2.1.13: A designation of a concept by letters, numerals, pictograms or any combination thereof. + + + + + ISO-12620 2.1.2: Any term that represents the same or a very similar concept as the main entry term in a term entry. + + + + + ISO-12620 2.1.18.3: Phraseological unit in a language that expresses the same semantic content as another phrase in that same language. + + + + + Indicates the marked text is a term. + + + + + ISO-12620 2.1.11: A form of a term resulting from an operation whereby the characters of one writing system are represented by characters from another writing system, taking into account the pronunciation of the characters converted. + + + + + ISO-12620 2.1.10: A form of a term resulting from an operation whereby the characters of an alphabetic writing system are represented by characters from another alphabetic writing system. + + + + + ISO-12620 2.1.8.5: An abbreviated form of a term resulting from the omission of one or more term elements or syllables (e.g. 'flu' for 'influenza'). + + + + + ISO-12620 2.1.9: One of the alternate forms of a term. + + + + + + + Values for the attribute 'restype'. + + + + + Indicates a Windows RC AUTO3STATE control. + + + + + Indicates a Windows RC AUTOCHECKBOX control. + + + + + Indicates a Windows RC AUTORADIOBUTTON control. + + + + + Indicates a Windows RC BEDIT control. + + + + + Indicates a bitmap, for example a BITMAP resource in Windows. + + + + + Indicates a button object, for example a BUTTON control Windows. + + + + + Indicates a caption, such as the caption of a dialog box. + + + + + Indicates the cell in a table, for example the content of the <td> element in HTML. + + + + + Indicates check box object, for example a CHECKBOX control in Windows. + + + + + Indicates a menu item with an associated checkbox. + + + + + Indicates a list box, but with a check-box for each item. + + + + + Indicates a color selection dialog. + + + + + Indicates a combination of edit box and listbox object, for example a COMBOBOX control in Windows. + + + + + Indicates an initialization entry of an extended combobox DLGINIT resource block. (code 0x1234). + + + + + Indicates an initialization entry of a combobox DLGINIT resource block (code 0x0403). + + + + + Indicates a UI base class element that cannot be represented by any other element. + + + + + Indicates a context menu. + + + + + Indicates a Windows RC CTEXT control. + + + + + Indicates a cursor, for example a CURSOR resource in Windows. + + + + + Indicates a date/time picker. + + + + + Indicates a Windows RC DEFPUSHBUTTON control. + + + + + Indicates a dialog box. + + + + + Indicates a Windows RC DLGINIT resource block. + + + + + Indicates an edit box object, for example an EDIT control in Windows. + + + + + Indicates a filename. + + + + + Indicates a file dialog. + + + + + Indicates a footnote. + + + + + Indicates a font name. + + + + + Indicates a footer. + + + + + Indicates a frame object. + + + + + Indicates a XUL grid element. + + + + + Indicates a groupbox object, for example a GROUPBOX control in Windows. + + + + + Indicates a header item. + + + + + Indicates a heading, such has the content of <h1>, <h2>, etc. in HTML. + + + + + Indicates a Windows RC HEDIT control. + + + + + Indicates a horizontal scrollbar. + + + + + Indicates an icon, for example an ICON resource in Windows. + + + + + Indicates a Windows RC IEDIT control. + + + + + Indicates keyword list, such as the content of the Keywords meta-data in HTML, or a K footnote in WinHelp RTF. + + + + + Indicates a label object. + + + + + Indicates a label that is also a HTML link (not necessarily a URL). + + + + + Indicates a list (a group of list-items, for example an <ol> or <ul> element in HTML). + + + + + Indicates a listbox object, for example an LISTBOX control in Windows. + + + + + Indicates an list item (an entry in a list). + + + + + Indicates a Windows RC LTEXT control. + + + + + Indicates a menu (a group of menu-items). + + + + + Indicates a toolbar containing one or more tope level menus. + + + + + Indicates a menu item (an entry in a menu). + + + + + Indicates a XUL menuseparator element. + + + + + Indicates a message, for example an entry in a MESSAGETABLE resource in Windows. + + + + + Indicates a calendar control. + + + + + Indicates an edit box beside a spin control. + + + + + Indicates a catch all for rectangular areas. + + + + + Indicates a standalone menu not necessarily associated with a menubar. + + + + + Indicates a pushbox object, for example a PUSHBOX control in Windows. + + + + + Indicates a Windows RC PUSHBUTTON control. + + + + + Indicates a radio button object. + + + + + Indicates a menuitem with associated radio button. + + + + + Indicates raw data resources for an application. + + + + + Indicates a row in a table. + + + + + Indicates a Windows RC RTEXT control. + + + + + Indicates a user navigable container used to show a portion of a document. + + + + + Indicates a generic divider object (e.g. menu group separator). + + + + + Windows accelerators, shortcuts in resource or property files. + + + + + Indicates a UI control to indicate process activity but not progress. + + + + + Indicates a splitter bar. + + + + + Indicates a Windows RC STATE3 control. + + + + + Indicates a window for providing feedback to the users, like 'read-only', etc. + + + + + Indicates a string, for example an entry in a STRINGTABLE resource in Windows. + + + + + Indicates a layers of controls with a tab to select layers. + + + + + Indicates a display and edits regular two-dimensional tables of cells. + + + + + Indicates a XUL textbox element. + + + + + Indicates a UI button that can be toggled to on or off state. + + + + + Indicates an array of controls, usually buttons. + + + + + Indicates a pop up tool tip text. + + + + + Indicates a bar with a pointer indicating a position within a certain range. + + + + + Indicates a control that displays a set of hierarchical data. + + + + + Indicates a URI (URN or URL). + + + + + Indicates a Windows RC USERBUTTON control. + + + + + Indicates a user-defined control like CONTROL control in Windows. + + + + + Indicates the text of a variable. + + + + + Indicates version information about a resource like VERSIONINFO in Windows. + + + + + Indicates a vertical scrollbar. + + + + + Indicates a graphical window. + + + + + + + Values for the attribute 'size-unit'. + + + + + Indicates a size in 8-bit bytes. + + + + + Indicates a size in Unicode characters. + + + + + Indicates a size in columns. Used for HTML text area. + + + + + Indicates a size in centimeters. + + + + + Indicates a size in dialog units, as defined in Windows resources. + + + + + Indicates a size in 'font-size' units (as defined in CSS). + + + + + Indicates a size in 'x-height' units (as defined in CSS). + + + + + Indicates a size in glyphs. A glyph is considered to be one or more combined Unicode characters that represent a single displayable text character. Sometimes referred to as a 'grapheme cluster' + + + + + Indicates a size in inches. + + + + + Indicates a size in millimeters. + + + + + Indicates a size in percentage. + + + + + Indicates a size in pixels. + + + + + Indicates a size in point. + + + + + Indicates a size in rows. Used for HTML text area. + + + + + + + Values for the attribute 'state'. + + + + + Indicates the terminating state. + + + + + Indicates only non-textual information needs adaptation. + + + + + Indicates both text and non-textual information needs adaptation. + + + + + Indicates only non-textual information needs review. + + + + + Indicates both text and non-textual information needs review. + + + + + Indicates that only the text of the item needs to be reviewed. + + + + + Indicates that the item needs to be translated. + + + + + Indicates that the item is new. For example, translation units that were not in a previous version of the document. + + + + + Indicates that changes are reviewed and approved. + + + + + Indicates that the item has been translated. + + + + + + + Values for the attribute 'state-qualifier'. + + + + + Indicates an exact match. An exact match occurs when a source text of a segment is exactly the same as the source text of a segment that was translated previously. + + + + + Indicates a fuzzy match. A fuzzy match occurs when a source text of a segment is very similar to the source text of a segment that was translated previously (e.g. when the difference is casing, a few changed words, white-space discripancy, etc.). + + + + + Indicates a match based on matching IDs (in addition to matching text). + + + + + Indicates a translation derived from a glossary. + + + + + Indicates a translation derived from existing translation. + + + + + Indicates a translation derived from machine translation. + + + + + Indicates a translation derived from a translation repository. + + + + + Indicates a translation derived from a translation memory. + + + + + Indicates the translation is suggested by machine translation. + + + + + Indicates that the item has been rejected because of incorrect grammar. + + + + + Indicates that the item has been rejected because it is incorrect. + + + + + Indicates that the item has been rejected because it is too long or too short. + + + + + Indicates that the item has been rejected because of incorrect spelling. + + + + + Indicates the translation is suggested by translation memory. + + + + + + + Values for the attribute 'unit'. + + + + + Refers to words. + + + + + Refers to pages. + + + + + Refers to <trans-unit> elements. + + + + + Refers to <bin-unit> elements. + + + + + Refers to glyphs. + + + + + Refers to <trans-unit> and/or <bin-unit> elements. + + + + + Refers to the occurrences of instances defined by the count-type value. + + + + + Refers to characters. + + + + + Refers to lines. + + + + + Refers to sentences. + + + + + Refers to paragraphs. + + + + + Refers to segments. + + + + + Refers to placeables (inline elements). + + + + + + + Values for the attribute 'priority'. + + + + + Highest priority. + + + + + High priority. + + + + + High priority, but not as important as 2. + + + + + High priority, but not as important as 3. + + + + + Medium priority, but more important than 6. + + + + + Medium priority, but less important than 5. + + + + + Low priority, but more important than 8. + + + + + Low priority, but more important than 9. + + + + + Low priority. + + + + + Lowest priority. + + + + + + + + + This value indicates that all properties can be reformatted. This value must be used alone. + + + + + This value indicates that no properties should be reformatted. This value must be used alone. + + + + + + + + + + + + + This value indicates that all information in the coord attribute can be modified. + + + + + This value indicates that the x information in the coord attribute can be modified. + + + + + This value indicates that the y information in the coord attribute can be modified. + + + + + This value indicates that the cx information in the coord attribute can be modified. + + + + + This value indicates that the cy information in the coord attribute can be modified. + + + + + This value indicates that all the information in the font attribute can be modified. + + + + + This value indicates that the name information in the font attribute can be modified. + + + + + This value indicates that the size information in the font attribute can be modified. + + + + + This value indicates that the weight information in the font attribute can be modified. + + + + + This value indicates that the information in the css-style attribute can be modified. + + + + + This value indicates that the information in the style attribute can be modified. + + + + + This value indicates that the information in the exstyle attribute can be modified. + + + + + + + + + + + + + Indicates that the context is informational in nature, specifying for example, how a term should be translated. Thus, should be displayed to anyone editing the XLIFF document. + + + + + Indicates that the context-group is used to specify where the term was found in the translatable source. Thus, it is not displayed. + + + + + Indicates that the context information should be used during translation memory lookups. Thus, it is not displayed. + + + + + + + + + Represents a translation proposal from a translation memory or other resource. + + + + + Represents a previous version of the target element. + + + + + Represents a rejected version of the target element. + + + + + Represents a translation to be used for reference purposes only, for example from a related product or a different language. + + + + + Represents a proposed translation that was used for the translation of the trans-unit, possibly modified. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Values for the attribute 'coord'. + + + + + + + + Version values: 1.0 and 1.1 are allowed for backward compatibility. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + From 86b850ebd8f7843a8a85cbe8a48953811c5ef32e Mon Sep 17 00:00:00 2001 From: Nicolas Grekas Date: Sat, 7 Apr 2018 16:29:23 +0200 Subject: [PATCH 16/75] [HttpKernel] Dont create mock cookie for new sessions in tests --- .../EventListener/AbstractTestSessionListener.php | 2 +- .../Tests/EventListener/TestSessionListenerTest.php | 6 ++++-- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/src/Symfony/Component/HttpKernel/EventListener/AbstractTestSessionListener.php b/src/Symfony/Component/HttpKernel/EventListener/AbstractTestSessionListener.php index 0a153dd94329..82061fd6ea0f 100644 --- a/src/Symfony/Component/HttpKernel/EventListener/AbstractTestSessionListener.php +++ b/src/Symfony/Component/HttpKernel/EventListener/AbstractTestSessionListener.php @@ -69,7 +69,7 @@ public function onKernelResponse(FilterResponseEvent $event) $session->save(); } - if ($session instanceof Session ? !$session->isEmpty() || $session->getId() !== $this->sessionId : $wasStarted) { + if ($session instanceof Session ? !$session->isEmpty() || (null !== $this->sessionId && $session->getId() !== $this->sessionId) : $wasStarted) { $params = session_get_cookie_params(); $event->getResponse()->headers->setCookie(new Cookie($session->getName(), $session->getId(), 0 === $params['lifetime'] ? 0 : time() + $params['lifetime'], $params['path'], $params['domain'], $params['secure'], $params['httponly'])); $this->sessionId = $session->getId(); diff --git a/src/Symfony/Component/HttpKernel/Tests/EventListener/TestSessionListenerTest.php b/src/Symfony/Component/HttpKernel/Tests/EventListener/TestSessionListenerTest.php index 0a2263d5a8e7..22a2b7123987 100644 --- a/src/Symfony/Component/HttpKernel/Tests/EventListener/TestSessionListenerTest.php +++ b/src/Symfony/Component/HttpKernel/Tests/EventListener/TestSessionListenerTest.php @@ -13,7 +13,6 @@ use PHPUnit\Framework\TestCase; use Symfony\Component\DependencyInjection\ServiceSubscriberInterface; -use Symfony\Component\HttpFoundation\Cookie; use Symfony\Component\HttpFoundation\Response; use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpKernel\Event\GetResponseEvent; @@ -46,6 +45,9 @@ protected function setUp() { $this->listener = $this->getMockForAbstractClass('Symfony\Component\HttpKernel\EventListener\AbstractTestSessionListener'); $this->session = $this->getSession(); + $this->listener->expects($this->any()) + ->method('getSession') + ->will($this->returnValue($this->session)); } public function testShouldSaveMasterRequestSession() @@ -95,7 +97,7 @@ public function testEmptySessionWithNewSessionIdDoesSendCookie() $this->fixSessionId('456'); $kernel = $this->getMockBuilder('Symfony\Component\HttpKernel\HttpKernelInterface')->getMock(); - $request = Request::create('/', 'GET', array(), array(new Cookie('MOCKSESSID', '123'))); + $request = Request::create('/', 'GET', array(), array('MOCKSESSID' => '123')); $event = new GetResponseEvent($kernel, $request, HttpKernelInterface::MASTER_REQUEST); $this->listener->onKernelRequest($event); From cd914209bd3acbc637c4b435626f003696ebacb7 Mon Sep 17 00:00:00 2001 From: Pascal Montoya <> Date: Fri, 6 Apr 2018 07:52:15 +0200 Subject: [PATCH 17/75] [Validator] Fix LazyLoadingMetadataFactory with PSR6Cache for non classname if tested values isn't an existing class --- .../Factory/LazyLoadingMetadataFactory.php | 8 ++++---- .../Factory/LazyLoadingMetadataFactoryTest.php | 15 +++++++++++++++ 2 files changed, 19 insertions(+), 4 deletions(-) diff --git a/src/Symfony/Component/Validator/Mapping/Factory/LazyLoadingMetadataFactory.php b/src/Symfony/Component/Validator/Mapping/Factory/LazyLoadingMetadataFactory.php index 1a4f3074b6e4..84375ec69495 100644 --- a/src/Symfony/Component/Validator/Mapping/Factory/LazyLoadingMetadataFactory.php +++ b/src/Symfony/Component/Validator/Mapping/Factory/LazyLoadingMetadataFactory.php @@ -90,6 +90,10 @@ public function getMetadataFor($value) return $this->loadedClasses[$class]; } + if (!class_exists($class) && !interface_exists($class)) { + throw new NoSuchMetadataException(sprintf('The class or interface "%s" does not exist.', $class)); + } + if (null !== $this->cache && false !== ($metadata = $this->cache->read($class))) { // Include constraints from the parent class $this->mergeConstraints($metadata); @@ -97,10 +101,6 @@ public function getMetadataFor($value) return $this->loadedClasses[$class] = $metadata; } - if (!class_exists($class) && !interface_exists($class)) { - throw new NoSuchMetadataException(sprintf('The class or interface "%s" does not exist.', $class)); - } - $metadata = new ClassMetadata($class); if (null !== $this->loader) { diff --git a/src/Symfony/Component/Validator/Tests/Mapping/Factory/LazyLoadingMetadataFactoryTest.php b/src/Symfony/Component/Validator/Tests/Mapping/Factory/LazyLoadingMetadataFactoryTest.php index b5d1a9dc84d4..de6852271e17 100644 --- a/src/Symfony/Component/Validator/Tests/Mapping/Factory/LazyLoadingMetadataFactoryTest.php +++ b/src/Symfony/Component/Validator/Tests/Mapping/Factory/LazyLoadingMetadataFactoryTest.php @@ -149,6 +149,21 @@ public function testReadMetadataFromCache() $this->assertEquals($metadata, $factory->getMetadataFor(self::PARENT_CLASS)); } + /** + * @expectedException \Symfony\Component\Validator\Exception\NoSuchMetadataException + */ + public function testNonClassNameStringValues() + { + $testedValue = 'error@example.com'; + $loader = $this->getMockBuilder('Symfony\Component\Validator\Mapping\Loader\LoaderInterface')->getMock(); + $cache = $this->getMockBuilder('Symfony\Component\Validator\Mapping\Cache\CacheInterface')->getMock(); + $factory = new LazyLoadingMetadataFactory($loader, $cache); + $cache + ->expects($this->never()) + ->method('read'); + $factory->getMetadataFor($testedValue); + } + public function testMetadataCacheWithRuntimeConstraint() { $cache = $this->getMockBuilder('Symfony\Component\Validator\Mapping\Cache\CacheInterface')->getMock(); From 5198f435a047aad8d5ed119e918cf8c008ea65b7 Mon Sep 17 00:00:00 2001 From: Pascal Montoya Date: Mon, 9 Apr 2018 10:29:56 +0200 Subject: [PATCH 18/75] Disable autoloader call on interface_exists check --- .../Validator/Mapping/Factory/LazyLoadingMetadataFactory.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Symfony/Component/Validator/Mapping/Factory/LazyLoadingMetadataFactory.php b/src/Symfony/Component/Validator/Mapping/Factory/LazyLoadingMetadataFactory.php index 84375ec69495..e088caa897a7 100644 --- a/src/Symfony/Component/Validator/Mapping/Factory/LazyLoadingMetadataFactory.php +++ b/src/Symfony/Component/Validator/Mapping/Factory/LazyLoadingMetadataFactory.php @@ -90,7 +90,7 @@ public function getMetadataFor($value) return $this->loadedClasses[$class]; } - if (!class_exists($class) && !interface_exists($class)) { + if (!class_exists($class) && !interface_exists($class, false)) { throw new NoSuchMetadataException(sprintf('The class or interface "%s" does not exist.', $class)); } From 7f398117f490b724dcfedd3663c76dfc49553392 Mon Sep 17 00:00:00 2001 From: Nicolas Grekas Date: Sat, 7 Apr 2018 15:42:06 +0200 Subject: [PATCH 19/75] [DI] Improve error message for non-autowirable scalar argument --- .../Compiler/AutowirePass.php | 5 ++++- .../Tests/Compiler/AutowirePassTest.php | 22 ++++++++++++++++++- .../Fixtures/includes/autowiring_classes.php | 2 +- 3 files changed, 26 insertions(+), 3 deletions(-) diff --git a/src/Symfony/Component/DependencyInjection/Compiler/AutowirePass.php b/src/Symfony/Component/DependencyInjection/Compiler/AutowirePass.php index 8bfc3cd9d967..803490cecd29 100644 --- a/src/Symfony/Component/DependencyInjection/Compiler/AutowirePass.php +++ b/src/Symfony/Component/DependencyInjection/Compiler/AutowirePass.php @@ -233,7 +233,10 @@ private function autowireMethod(\ReflectionFunctionAbstract $reflectionMethod, a if ($parameter->isOptional()) { continue; } - throw new AutowiringFailedException($this->currentId, sprintf('Cannot autowire service "%s": argument "$%s" of method "%s()" must have a type-hint or be given a value explicitly.', $this->currentId, $parameter->name, $class !== $this->currentId ? $class.'::'.$method : $method)); + $type = ProxyHelper::getTypeHint($reflectionMethod, $parameter, false); + $type = $type ? sprintf('is type-hinted "%s"', $type) : 'has no type-hint'; + + throw new AutowiringFailedException($this->currentId, sprintf('Cannot autowire service "%s": argument "$%s" of method "%s()" %s, you should configure its value explicitly.', $this->currentId, $parameter->name, $class !== $this->currentId ? $class.'::'.$method : $method, $type)); } // specifically pass the default value diff --git a/src/Symfony/Component/DependencyInjection/Tests/Compiler/AutowirePassTest.php b/src/Symfony/Component/DependencyInjection/Tests/Compiler/AutowirePassTest.php index ee0b4baef845..924a49094249 100644 --- a/src/Symfony/Component/DependencyInjection/Tests/Compiler/AutowirePassTest.php +++ b/src/Symfony/Component/DependencyInjection/Tests/Compiler/AutowirePassTest.php @@ -436,6 +436,7 @@ public function testSomeSpecificArgumentsAreSet() // args are: A, Foo, Dunglas ->setArguments(array( 1 => new Reference('foo'), + 3 => array('bar'), )); (new ResolveClassPass())->process($container); @@ -447,6 +448,7 @@ public function testSomeSpecificArgumentsAreSet() new TypedReference(A::class, A::class, MultipleArguments::class), new Reference('foo'), new TypedReference(Dunglas::class, Dunglas::class, MultipleArguments::class), + array('bar'), ), $definition->getArguments() ); @@ -454,12 +456,30 @@ public function testSomeSpecificArgumentsAreSet() /** * @expectedException \Symfony\Component\DependencyInjection\Exception\AutowiringFailedException - * @expectedExceptionMessage Cannot autowire service "arg_no_type_hint": argument "$foo" of method "Symfony\Component\DependencyInjection\Tests\Compiler\MultipleArguments::__construct()" must have a type-hint or be given a value explicitly. + * @expectedExceptionMessage Cannot autowire service "arg_no_type_hint": argument "$bar" of method "Symfony\Component\DependencyInjection\Tests\Compiler\MultipleArguments::__construct()" is type-hinted "array", you should configure its value explicitly. */ public function testScalarArgsCannotBeAutowired() { $container = new ContainerBuilder(); + $container->register(A::class); + $container->register(Dunglas::class); + $container->register('arg_no_type_hint', __NAMESPACE__.'\MultipleArguments') + ->setArguments(array(1 => 'foo')) + ->setAutowired(true); + + (new ResolveClassPass())->process($container); + (new AutowirePass())->process($container); + } + + /** + * @expectedException \Symfony\Component\DependencyInjection\Exception\AutowiringFailedException + * @expectedExceptionMessage Cannot autowire service "arg_no_type_hint": argument "$foo" of method "Symfony\Component\DependencyInjection\Tests\Compiler\MultipleArguments::__construct()" has no type-hint, you should configure its value explicitly. + */ + public function testNoTypeArgsCannotBeAutowired() + { + $container = new ContainerBuilder(); + $container->register(A::class); $container->register(Dunglas::class); $container->register('arg_no_type_hint', __NAMESPACE__.'\MultipleArguments') diff --git a/src/Symfony/Component/DependencyInjection/Tests/Fixtures/includes/autowiring_classes.php b/src/Symfony/Component/DependencyInjection/Tests/Fixtures/includes/autowiring_classes.php index 990a873f3498..6f93957753a4 100644 --- a/src/Symfony/Component/DependencyInjection/Tests/Fixtures/includes/autowiring_classes.php +++ b/src/Symfony/Component/DependencyInjection/Tests/Fixtures/includes/autowiring_classes.php @@ -181,7 +181,7 @@ public function __construct(A $k) } class MultipleArguments { - public function __construct(A $k, $foo, Dunglas $dunglas) + public function __construct(A $k, $foo, Dunglas $dunglas, array $bar) { } } From adba79a6b01800bd7cc0bc9795dcb46539330f7f Mon Sep 17 00:00:00 2001 From: Nicolas Grekas Date: Mon, 9 Apr 2018 12:07:56 -0500 Subject: [PATCH 20/75] [Console] Don't go past exact matches when autocompleting --- .../Console/Helper/QuestionHelper.php | 2 +- .../Tests/Helper/QuestionHelperTest.php | 24 +++++++++++++++++++ 2 files changed, 25 insertions(+), 1 deletion(-) diff --git a/src/Symfony/Component/Console/Helper/QuestionHelper.php b/src/Symfony/Component/Console/Helper/QuestionHelper.php index bce0534ed099..36187f8cea48 100644 --- a/src/Symfony/Component/Console/Helper/QuestionHelper.php +++ b/src/Symfony/Component/Console/Helper/QuestionHelper.php @@ -284,7 +284,7 @@ private function autocomplete(OutputInterface $output, Question $question, $inpu foreach ($autocomplete as $value) { // If typed characters match the beginning chunk of value (e.g. [AcmeDe]moBundle) - if (0 === strpos($value, $ret) && $i !== strlen($value)) { + if (0 === strpos($value, $ret)) { $matches[$numMatches++] = $value; } } diff --git a/src/Symfony/Component/Console/Tests/Helper/QuestionHelperTest.php b/src/Symfony/Component/Console/Tests/Helper/QuestionHelperTest.php index d9bdb606ac34..9f837d0f9ed4 100644 --- a/src/Symfony/Component/Console/Tests/Helper/QuestionHelperTest.php +++ b/src/Symfony/Component/Console/Tests/Helper/QuestionHelperTest.php @@ -160,6 +160,30 @@ public function testAskWithAutocompleteWithNonSequentialKeys() $this->assertEquals('AsseticBundle', $dialog->ask($this->createInputInterfaceMock(), $this->createOutputInterface(), $question)); } + public function testAskWithAutocompleteWithExactMatch() + { + if (!$this->hasSttyAvailable()) { + $this->markTestSkipped('`stty` is required to test autocomplete functionality'); + } + + $inputStream = $this->getInputStream("b\n"); + + $possibleChoices = array( + 'a' => 'berlin', + 'b' => 'copenhagen', + 'c' => 'amsterdam', + ); + + $dialog = new QuestionHelper(); + $dialog->setInputStream($inputStream); + $dialog->setHelperSet(new HelperSet(array(new FormatterHelper()))); + + $question = new ChoiceQuestion('Please select a city', $possibleChoices); + $question->setMaxAttempts(1); + + $this->assertSame('b', $dialog->ask($this->createInputInterfaceMock(), $this->createOutputInterface(), $question)); + } + public function testAutocompleteWithTrailingBackslash() { if (!$this->hasSttyAvailable()) { From 2a9c668ad7f187a94e8d071d51ad300b22c57520 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?G=C3=A1bor=20Egyed?= Date: Tue, 10 Apr 2018 18:33:39 +0200 Subject: [PATCH 21/75] [Routing] Fix loading multiple class annotations for invokable classes --- .../Routing/Loader/AnnotationClassLoader.php | 13 +++-- .../Loader/AnnotationClassLoaderTest.php | 51 +++++++++++++++++-- .../Loader/AnnotationDirectoryLoaderTest.php | 15 +++++- 3 files changed, 68 insertions(+), 11 deletions(-) diff --git a/src/Symfony/Component/Routing/Loader/AnnotationClassLoader.php b/src/Symfony/Component/Routing/Loader/AnnotationClassLoader.php index 2fe6fb596e42..fd1d2b655ab2 100644 --- a/src/Symfony/Component/Routing/Loader/AnnotationClassLoader.php +++ b/src/Symfony/Component/Routing/Loader/AnnotationClassLoader.php @@ -119,10 +119,15 @@ public function load($class, $type = null) } } - if (0 === $collection->count() && $class->hasMethod('__invoke') && $annot = $this->reader->getClassAnnotation($class, $this->routeAnnotationClass)) { - $globals['path'] = ''; - $globals['name'] = ''; - $this->addRoute($collection, $annot, $globals, $class, $class->getMethod('__invoke')); + if (0 === $collection->count() && $class->hasMethod('__invoke')) { + foreach ($this->reader->getClassAnnotations($class) as $annot) { + if ($annot instanceof $this->routeAnnotationClass) { + $globals['path'] = ''; + $globals['name'] = ''; + + $this->addRoute($collection, $annot, $globals, $class, $class->getMethod('__invoke')); + } + } } return $collection; diff --git a/src/Symfony/Component/Routing/Tests/Loader/AnnotationClassLoaderTest.php b/src/Symfony/Component/Routing/Tests/Loader/AnnotationClassLoaderTest.php index 70db1ccd9ad6..32e401294ec8 100644 --- a/src/Symfony/Component/Routing/Tests/Loader/AnnotationClassLoaderTest.php +++ b/src/Symfony/Component/Routing/Tests/Loader/AnnotationClassLoaderTest.php @@ -191,9 +191,9 @@ public function testInvokableClassRouteLoad() ); $this->reader - ->expects($this->exactly(2)) - ->method('getClassAnnotation') - ->will($this->returnValue($this->getAnnotatedRoute($classRouteData))) + ->expects($this->exactly(1)) + ->method('getClassAnnotations') + ->will($this->returnValue(array($this->getAnnotatedRoute($classRouteData)))) ; $this->reader ->expects($this->once()) @@ -205,8 +205,49 @@ public function testInvokableClassRouteLoad() $route = $routeCollection->get($classRouteData['name']); $this->assertSame($classRouteData['path'], $route->getPath(), '->load preserves class route path'); - $this->assertEquals(array_merge($classRouteData['schemes'], $classRouteData['schemes']), $route->getSchemes(), '->load preserves class route schemes'); - $this->assertEquals(array_merge($classRouteData['methods'], $classRouteData['methods']), $route->getMethods(), '->load preserves class route methods'); + $this->assertEquals($classRouteData['schemes'], $route->getSchemes(), '->load preserves class route schemes'); + $this->assertEquals($classRouteData['methods'], $route->getMethods(), '->load preserves class route methods'); + } + + public function testInvokableClassMultipleRouteLoad() + { + $classRouteData1 = array( + 'name' => 'route1', + 'path' => '/1', + 'schemes' => array('https'), + 'methods' => array('GET'), + ); + + $classRouteData2 = array( + 'name' => 'route2', + 'path' => '/2', + 'schemes' => array('https'), + 'methods' => array('GET'), + ); + + $this->reader + ->expects($this->exactly(1)) + ->method('getClassAnnotations') + ->will($this->returnValue(array($this->getAnnotatedRoute($classRouteData1), $this->getAnnotatedRoute($classRouteData2)))) + ; + $this->reader + ->expects($this->once()) + ->method('getMethodAnnotations') + ->will($this->returnValue(array())) + ; + + $routeCollection = $this->loader->load('Symfony\Component\Routing\Tests\Fixtures\AnnotatedClasses\BazClass'); + $route = $routeCollection->get($classRouteData1['name']); + + $this->assertSame($classRouteData1['path'], $route->getPath(), '->load preserves class route path'); + $this->assertEquals($classRouteData1['schemes'], $route->getSchemes(), '->load preserves class route schemes'); + $this->assertEquals($classRouteData1['methods'], $route->getMethods(), '->load preserves class route methods'); + + $route = $routeCollection->get($classRouteData2['name']); + + $this->assertSame($classRouteData2['path'], $route->getPath(), '->load preserves class route path'); + $this->assertEquals($classRouteData2['schemes'], $route->getSchemes(), '->load preserves class route schemes'); + $this->assertEquals($classRouteData2['methods'], $route->getMethods(), '->load preserves class route methods'); } public function testInvokableClassWithMethodRouteLoad() diff --git a/src/Symfony/Component/Routing/Tests/Loader/AnnotationDirectoryLoaderTest.php b/src/Symfony/Component/Routing/Tests/Loader/AnnotationDirectoryLoaderTest.php index 1e8ee394015e..8a6668e0c2be 100644 --- a/src/Symfony/Component/Routing/Tests/Loader/AnnotationDirectoryLoaderTest.php +++ b/src/Symfony/Component/Routing/Tests/Loader/AnnotationDirectoryLoaderTest.php @@ -29,7 +29,7 @@ protected function setUp() public function testLoad() { - $this->reader->expects($this->exactly(4))->method('getClassAnnotation'); + $this->reader->expects($this->exactly(3))->method('getClassAnnotation'); $this->reader ->expects($this->any()) @@ -37,6 +37,12 @@ public function testLoad() ->will($this->returnValue(array())) ; + $this->reader + ->expects($this->any()) + ->method('getClassAnnotations') + ->will($this->returnValue(array())) + ; + $this->loader->load(__DIR__.'/../Fixtures/AnnotatedClasses'); } @@ -45,7 +51,6 @@ public function testLoadIgnoresHiddenDirectories() $this->expectAnnotationsToBeReadFrom(array( 'Symfony\Component\Routing\Tests\Fixtures\AnnotatedClasses\BarClass', 'Symfony\Component\Routing\Tests\Fixtures\AnnotatedClasses\BazClass', - 'Symfony\Component\Routing\Tests\Fixtures\AnnotatedClasses\BazClass', 'Symfony\Component\Routing\Tests\Fixtures\AnnotatedClasses\FooClass', )); @@ -55,6 +60,12 @@ public function testLoadIgnoresHiddenDirectories() ->will($this->returnValue(array())) ; + $this->reader + ->expects($this->any()) + ->method('getClassAnnotations') + ->will($this->returnValue(array())) + ; + $this->loader->load(__DIR__.'/../Fixtures/AnnotatedClasses'); } From 99302e72fca92e53b3555981a563889043750453 Mon Sep 17 00:00:00 2001 From: Christian Flothmann Date: Fri, 13 Apr 2018 17:39:33 +0200 Subject: [PATCH 22/75] fix rendering exception stack traces --- .../TwigBundle/Resources/views/Exception/traces.txt.twig | 2 -- .../Resources/views/Exception/traces_text.html.twig | 8 +++++++- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/src/Symfony/Bundle/TwigBundle/Resources/views/Exception/traces.txt.twig b/src/Symfony/Bundle/TwigBundle/Resources/views/Exception/traces.txt.twig index 96ecd4448081..88a2d6922d6c 100644 --- a/src/Symfony/Bundle/TwigBundle/Resources/views/Exception/traces.txt.twig +++ b/src/Symfony/Bundle/TwigBundle/Resources/views/Exception/traces.txt.twig @@ -1,5 +1,4 @@ {% if exception.trace|length %} -
 {{ exception.class }}:
 {% if exception.message is not empty %}
     {{- exception.message }}
@@ -8,5 +7,4 @@
 {% for trace in exception.trace %}
   {{ include('@Twig/Exception/trace.txt.twig', { trace: trace }, with_context = false) }}
 {% endfor %}
-
{% endif %} diff --git a/src/Symfony/Bundle/TwigBundle/Resources/views/Exception/traces_text.html.twig b/src/Symfony/Bundle/TwigBundle/Resources/views/Exception/traces_text.html.twig index ffe7f31ad5ec..318a5bbeeb0c 100644 --- a/src/Symfony/Bundle/TwigBundle/Resources/views/Exception/traces_text.html.twig +++ b/src/Symfony/Bundle/TwigBundle/Resources/views/Exception/traces_text.html.twig @@ -17,7 +17,13 @@ - {{ include('@Twig/Exception/traces.txt.twig', { exception: exception }, with_context = false) }} + {% if exception.trace|length %} +
+                {%- filter escape('html') -%}
+                    {{- include('@Twig/Exception/traces.txt.twig', { exception: exception, format: 'html' }, with_context = false) }}
+                {% endfilter %}
+                
+ {% endif %} From 40bd8bd797ae8921e2a04f71a1ba7e1d3c0c29a3 Mon Sep 17 00:00:00 2001 From: Normunds Date: Mon, 9 Apr 2018 15:54:29 +0300 Subject: [PATCH 23/75] Add d-block to bootstrap 4 alerts --- .../Twig/Resources/views/Form/bootstrap_4_layout.html.twig | 2 +- .../Form/Tests/AbstractBootstrap4HorizontalLayoutTest.php | 2 +- .../Component/Form/Tests/AbstractBootstrap4LayoutTest.php | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/Symfony/Bridge/Twig/Resources/views/Form/bootstrap_4_layout.html.twig b/src/Symfony/Bridge/Twig/Resources/views/Form/bootstrap_4_layout.html.twig index df88a0001188..1c5c39095479 100644 --- a/src/Symfony/Bridge/Twig/Resources/views/Form/bootstrap_4_layout.html.twig +++ b/src/Symfony/Bridge/Twig/Resources/views/Form/bootstrap_4_layout.html.twig @@ -267,7 +267,7 @@ {% block form_errors -%} {%- if errors|length > 0 -%} - + {%- for error in errors -%} {{ 'Error'|trans({}, 'validators') }} {{ error.message }} diff --git a/src/Symfony/Component/Form/Tests/AbstractBootstrap4HorizontalLayoutTest.php b/src/Symfony/Component/Form/Tests/AbstractBootstrap4HorizontalLayoutTest.php index c906c6549ad2..016792e0edaf 100644 --- a/src/Symfony/Component/Form/Tests/AbstractBootstrap4HorizontalLayoutTest.php +++ b/src/Symfony/Component/Form/Tests/AbstractBootstrap4HorizontalLayoutTest.php @@ -32,7 +32,7 @@ public function testRow() [ ./label[@for="name"] [ - ./span[@class="alert alert-danger"] + ./span[@class="alert alert-danger d-block"] [./span[@class="mb-0 d-block"] [./span[.="[trans]Error[/trans]"]] [./span[.="[trans]Error![/trans]"]] diff --git a/src/Symfony/Component/Form/Tests/AbstractBootstrap4LayoutTest.php b/src/Symfony/Component/Form/Tests/AbstractBootstrap4LayoutTest.php index beabaa21cdb1..2cadba0ba9e6 100644 --- a/src/Symfony/Component/Form/Tests/AbstractBootstrap4LayoutTest.php +++ b/src/Symfony/Component/Form/Tests/AbstractBootstrap4LayoutTest.php @@ -32,7 +32,7 @@ public function testRow() [ ./label[@for="name"] [ - ./span[@class="alert alert-danger"] + ./span[@class="alert alert-danger d-block"] [./span[@class="mb-0 d-block"] [./span[.="[trans]Error[/trans]"]] [./span[.="[trans]Error![/trans]"]] @@ -161,7 +161,7 @@ public function testErrors() $this->assertMatchesXpath($html, '/span - [@class="alert alert-danger"] + [@class="alert alert-danger d-block"] [ ./span[@class="mb-0 d-block"] [./span[.="[trans]Error[/trans]"]] From 3b47441fd5be8714ea7086c581a2f8d07fc64173 Mon Sep 17 00:00:00 2001 From: Mathieu TUDISCO Date: Tue, 3 Apr 2018 15:10:16 +0200 Subject: [PATCH 24/75] [HttpKernel] Make ServiceValueResolver work if controller namespace starts with a backslash in routing --- .../ArgumentResolver/ServiceValueResolver.php | 12 +++++++++++- .../ServiceValueResolverTest.php | 19 +++++++++++++++++++ 2 files changed, 30 insertions(+), 1 deletion(-) diff --git a/src/Symfony/Component/HttpKernel/Controller/ArgumentResolver/ServiceValueResolver.php b/src/Symfony/Component/HttpKernel/Controller/ArgumentResolver/ServiceValueResolver.php index c55564c0467e..7bc195f23311 100644 --- a/src/Symfony/Component/HttpKernel/Controller/ArgumentResolver/ServiceValueResolver.php +++ b/src/Symfony/Component/HttpKernel/Controller/ArgumentResolver/ServiceValueResolver.php @@ -39,9 +39,15 @@ public function supports(Request $request, ArgumentMetadata $argument) if (\is_array($controller) && \is_callable($controller, true) && \is_string($controller[0])) { $controller = $controller[0].'::'.$controller[1]; + } elseif (!\is_string($controller) || '' === $controller) { + return false; } - return \is_string($controller) && $this->container->has($controller) && $this->container->get($controller)->has($argument->getName()); + if ('\\' === $controller[0]) { + $controller = ltrim($controller, '\\'); + } + + return $this->container->has($controller) && $this->container->get($controller)->has($argument->getName()); } /** @@ -53,6 +59,10 @@ public function resolve(Request $request, ArgumentMetadata $argument) $controller = $controller[0].'::'.$controller[1]; } + if ('\\' === $controller[0]) { + $controller = ltrim($controller, '\\'); + } + yield $this->container->get($controller)->get($argument->getName()); } } diff --git a/src/Symfony/Component/HttpKernel/Tests/Controller/ArgumentResolver/ServiceValueResolverTest.php b/src/Symfony/Component/HttpKernel/Tests/Controller/ArgumentResolver/ServiceValueResolverTest.php index b05828f5bf6d..7d34172ce3d8 100644 --- a/src/Symfony/Component/HttpKernel/Tests/Controller/ArgumentResolver/ServiceValueResolverTest.php +++ b/src/Symfony/Component/HttpKernel/Tests/Controller/ArgumentResolver/ServiceValueResolverTest.php @@ -47,6 +47,25 @@ public function testExistingController() $this->assertYieldEquals(array(new DummyService()), $resolver->resolve($request, $argument)); } + public function testExistingControllerWithATrailingBackSlash() + { + $resolver = new ServiceValueResolver(new ServiceLocator(array( + 'App\\Controller\\Mine::method' => function () { + return new ServiceLocator(array( + 'dummy' => function () { + return new DummyService(); + }, + )); + }, + ))); + + $request = $this->requestWithAttributes(array('_controller' => '\\App\\Controller\\Mine::method')); + $argument = new ArgumentMetadata('dummy', DummyService::class, false, false, null); + + $this->assertTrue($resolver->supports($request, $argument)); + $this->assertYieldEquals(array(new DummyService()), $resolver->resolve($request, $argument)); + } + public function testControllerNameIsAnArray() { $resolver = new ServiceValueResolver(new ServiceLocator(array( From 00cdf5e0a51e302cf65220f4dcf049688e0114fa Mon Sep 17 00:00:00 2001 From: HeahDude Date: Sun, 15 Apr 2018 09:55:18 +0200 Subject: [PATCH 25/75] [Form] Fixed trimming choice values --- .../Form/Extension/Core/Type/ChoiceType.php | 1 + .../Extension/Core/Type/ChoiceTypeTest.php | 55 +++++++++++++++++++ 2 files changed, 56 insertions(+) diff --git a/src/Symfony/Component/Form/Extension/Core/Type/ChoiceType.php b/src/Symfony/Component/Form/Extension/Core/Type/ChoiceType.php index 601583b7839f..19f1d62e4f37 100644 --- a/src/Symfony/Component/Form/Extension/Core/Type/ChoiceType.php +++ b/src/Symfony/Component/Form/Extension/Core/Type/ChoiceType.php @@ -413,6 +413,7 @@ public function configureOptions(OptionsResolver $resolver) // See https://github.com/symfony/symfony/pull/5582 'data_class' => null, 'choice_translation_domain' => true, + 'trim' => false, )); $resolver->setNormalizer('choices', $choicesNormalizer); diff --git a/src/Symfony/Component/Form/Tests/Extension/Core/Type/ChoiceTypeTest.php b/src/Symfony/Component/Form/Tests/Extension/Core/Type/ChoiceTypeTest.php index 842136e14c67..875a0ba0f60b 100644 --- a/src/Symfony/Component/Form/Tests/Extension/Core/Type/ChoiceTypeTest.php +++ b/src/Symfony/Component/Form/Tests/Extension/Core/Type/ChoiceTypeTest.php @@ -2421,4 +2421,59 @@ public function invalidNestedValueTestMatrix() 'multiple, expanded' => array(true, true, array(array())), ); } + + /** + * @dataProvider provideTrimCases + */ + public function testTrimIsDisabled($multiple, $expanded) + { + $form = $this->factory->create(static::TESTED_TYPE, null, array( + 'multiple' => $multiple, + 'expanded' => $expanded, + 'choices' => array( + 'a' => '1', + ), + 'choices_as_values' => true, + )); + + $submittedData = ' 1'; + + $form->submit($multiple ? (array) $submittedData : $submittedData); + + // When the choice does not exist the transformation fails + $this->assertFalse($form->isSynchronized()); + $this->assertNull($form->getData()); + } + + /** + * @dataProvider provideTrimCases + */ + public function testSubmitValueWithWhiteSpace($multiple, $expanded) + { + $valueWhitWhiteSpace = '1 '; + + $form = $this->factory->create(static::TESTED_TYPE, null, array( + 'multiple' => $multiple, + 'expanded' => $expanded, + 'choices' => array( + 'a' => $valueWhitWhiteSpace, + ), + 'choices_as_values' => true, + )); + + $form->submit($multiple ? (array) $valueWhitWhiteSpace : $valueWhitWhiteSpace); + + $this->assertTrue($form->isSynchronized()); + $this->assertSame($multiple ? (array) $valueWhitWhiteSpace : $valueWhitWhiteSpace, $form->getData()); + } + + public function provideTrimCases() + { + return array( + 'Simple' => array(false, false), + 'Multiple' => array(true, false), + 'Simple expanded' => array(false, true), + 'Multiple expanded' => array(true, true), + ); + } } From 3d27b5946db147da7d96b14bb2a89b8a25d8a58b Mon Sep 17 00:00:00 2001 From: Matthias Pigulla Date: Thu, 22 Mar 2018 20:40:31 +0100 Subject: [PATCH 26/75] Fix that ESI/SSI processing can turn a \"private\" response \"public\" --- .../Component/HttpFoundation/Response.php | 10 +++++++-- .../HttpCache/ResponseCacheStrategy.php | 2 +- .../HttpCache/ResponseCacheStrategyTest.php | 22 +++++++++++++++++-- 3 files changed, 29 insertions(+), 5 deletions(-) diff --git a/src/Symfony/Component/HttpFoundation/Response.php b/src/Symfony/Component/HttpFoundation/Response.php index 4aabc0da236b..cbeaf27621f2 100644 --- a/src/Symfony/Component/HttpFoundation/Response.php +++ b/src/Symfony/Component/HttpFoundation/Response.php @@ -507,13 +507,19 @@ public function getCharset() } /** - * Returns true if the response is worth caching under any circumstance. + * Returns true if the response may safely be kept in a shared (surrogate) cache. * * Responses marked "private" with an explicit Cache-Control directive are * considered uncacheable. * * Responses with neither a freshness lifetime (Expires, max-age) nor cache - * validator (Last-Modified, ETag) are considered uncacheable. + * validator (Last-Modified, ETag) are considered uncacheable because there is + * no way to tell when or how to remove them from the cache. + * + * Note that RFC 7231 and RFC 7234 possibly allow for a more permissive implementation, + * for example "status codes that are defined as cacheable by default [...] + * can be reused by a cache with heuristic expiration unless otherwise indicated" + * (https://tools.ietf.org/html/rfc7231#section-6.1) * * @return bool true if the response is worth caching, false otherwise */ diff --git a/src/Symfony/Component/HttpKernel/HttpCache/ResponseCacheStrategy.php b/src/Symfony/Component/HttpKernel/HttpCache/ResponseCacheStrategy.php index 027b2b176133..672cc893feb6 100644 --- a/src/Symfony/Component/HttpKernel/HttpCache/ResponseCacheStrategy.php +++ b/src/Symfony/Component/HttpKernel/HttpCache/ResponseCacheStrategy.php @@ -72,7 +72,7 @@ public function update(Response $response) $response->setLastModified(null); } - if (!$response->isFresh()) { + if (!$response->isFresh() || !$response->isCacheable()) { $this->cacheable = false; } diff --git a/src/Symfony/Component/HttpKernel/Tests/HttpCache/ResponseCacheStrategyTest.php b/src/Symfony/Component/HttpKernel/Tests/HttpCache/ResponseCacheStrategyTest.php index 5e4c322223eb..6d67a177398c 100644 --- a/src/Symfony/Component/HttpKernel/Tests/HttpCache/ResponseCacheStrategyTest.php +++ b/src/Symfony/Component/HttpKernel/Tests/HttpCache/ResponseCacheStrategyTest.php @@ -175,8 +175,26 @@ public function testEmbeddingPrivateResponseMakesMainResponsePrivate() $cacheStrategy->update($masterResponse); $this->assertTrue($masterResponse->headers->hasCacheControlDirective('private')); - // Not sure if we should pass "max-age: 60" in this case, as long as the response is private and - // that's the more conservative of both the master and embedded response...? + $this->assertFalse($masterResponse->headers->hasCacheControlDirective('public')); + } + + public function testEmbeddingPublicResponseDoesNotMakeMainResponsePublic() + { + $cacheStrategy = new ResponseCacheStrategy(); + + $masterResponse = new Response(); + $masterResponse->setPrivate(); // this is the default, but let's be explicit + $masterResponse->setMaxAge(100); + + $embeddedResponse = new Response(); + $embeddedResponse->setPublic(); + $embeddedResponse->setSharedMaxAge(100); + + $cacheStrategy->add($embeddedResponse); + $cacheStrategy->update($masterResponse); + + $this->assertTrue($masterResponse->headers->hasCacheControlDirective('private')); + $this->assertFalse($masterResponse->headers->hasCacheControlDirective('public')); } public function testResponseIsExiprableWhenEmbeddedResponseCombinesExpiryAndValidation() From e2c1f24fbd17c47e32ecc2531950ab8d79ce4a7f Mon Sep 17 00:00:00 2001 From: Teoh Han Hui Date: Wed, 11 Apr 2018 14:53:24 +0200 Subject: [PATCH 27/75] Don't assume that file binary exists on *nix OS Certain lightweight distributions such as Alpine Linux (popular for smaller Docker images) do not include it by default. --- .../File/MimeType/FileBinaryMimeTypeGuesser.php | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/src/Symfony/Component/HttpFoundation/File/MimeType/FileBinaryMimeTypeGuesser.php b/src/Symfony/Component/HttpFoundation/File/MimeType/FileBinaryMimeTypeGuesser.php index c2ac6768c301..3c358104651b 100644 --- a/src/Symfony/Component/HttpFoundation/File/MimeType/FileBinaryMimeTypeGuesser.php +++ b/src/Symfony/Component/HttpFoundation/File/MimeType/FileBinaryMimeTypeGuesser.php @@ -43,7 +43,21 @@ public function __construct($cmd = 'file -b --mime %s 2>/dev/null') */ public static function isSupported() { - return '\\' !== DIRECTORY_SEPARATOR && function_exists('passthru') && function_exists('escapeshellarg'); + static $supported = null; + + if (null !== $supported) { + return $supported; + } + + if ('\\' === DIRECTORY_SEPARATOR || !function_exists('passthru') || !function_exists('escapeshellarg')) { + return $supported = false; + } + + ob_start(); + passthru('command -v file', $exitStatus); + $binPath = trim(ob_get_clean()); + + return $supported = 0 === $exitStatus && '' !== $binPath; } /** From a28393e482ec6f45f1e6693eb0876f61ffb4b54c Mon Sep 17 00:00:00 2001 From: "Pavel.Batanov" Date: Tue, 17 Apr 2018 11:56:08 +0300 Subject: [PATCH 28/75] Fix PSR exception context key --- src/Symfony/Component/Console/EventListener/ErrorListener.php | 4 ++-- .../Console/Tests/EventListener/ErrorListenerTest.php | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/Symfony/Component/Console/EventListener/ErrorListener.php b/src/Symfony/Component/Console/EventListener/ErrorListener.php index 3774f9e6666d..909d6ea3a1dd 100644 --- a/src/Symfony/Component/Console/EventListener/ErrorListener.php +++ b/src/Symfony/Component/Console/EventListener/ErrorListener.php @@ -40,10 +40,10 @@ public function onConsoleError(ConsoleErrorEvent $event) $error = $event->getError(); if (!$inputString = $this->getInputString($event)) { - return $this->logger->error('An error occurred while using the console. Message: "{message}"', array('error' => $error, 'message' => $error->getMessage())); + return $this->logger->error('An error occurred while using the console. Message: "{message}"', array('exception' => $error, 'message' => $error->getMessage())); } - $this->logger->error('Error thrown while running command "{command}". Message: "{message}"', array('error' => $error, 'command' => $inputString, 'message' => $error->getMessage())); + $this->logger->error('Error thrown while running command "{command}". Message: "{message}"', array('exception' => $error, 'command' => $inputString, 'message' => $error->getMessage())); } public function onConsoleTerminate(ConsoleTerminateEvent $event) diff --git a/src/Symfony/Component/Console/Tests/EventListener/ErrorListenerTest.php b/src/Symfony/Component/Console/Tests/EventListener/ErrorListenerTest.php index 17eaae09084c..3794a2660ab5 100644 --- a/src/Symfony/Component/Console/Tests/EventListener/ErrorListenerTest.php +++ b/src/Symfony/Component/Console/Tests/EventListener/ErrorListenerTest.php @@ -34,7 +34,7 @@ public function testOnConsoleError() $logger ->expects($this->once()) ->method('error') - ->with('Error thrown while running command "{command}". Message: "{message}"', array('error' => $error, 'command' => 'test:run --foo=baz buzz', 'message' => 'An error occurred')) + ->with('Error thrown while running command "{command}". Message: "{message}"', array('exception' => $error, 'command' => 'test:run --foo=baz buzz', 'message' => 'An error occurred')) ; $listener = new ErrorListener($logger); @@ -49,7 +49,7 @@ public function testOnConsoleErrorWithNoCommandAndNoInputString() $logger ->expects($this->once()) ->method('error') - ->with('An error occurred while using the console. Message: "{message}"', array('error' => $error, 'message' => 'An error occurred')) + ->with('An error occurred while using the console. Message: "{message}"', array('exception' => $error, 'message' => 'An error occurred')) ; $listener = new ErrorListener($logger); From f1c1d36fdaf0080aeacc3a6479839b22437a795c Mon Sep 17 00:00:00 2001 From: Christian Flothmann Date: Thu, 19 Apr 2018 10:26:28 +0200 Subject: [PATCH 29/75] fix formatting arguments in plaintext format --- .../Bundle/TwigBundle/Resources/views/Exception/trace.txt.twig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Symfony/Bundle/TwigBundle/Resources/views/Exception/trace.txt.twig b/src/Symfony/Bundle/TwigBundle/Resources/views/Exception/trace.txt.twig index fb1e49d826eb..538355cbe17f 100644 --- a/src/Symfony/Bundle/TwigBundle/Resources/views/Exception/trace.txt.twig +++ b/src/Symfony/Bundle/TwigBundle/Resources/views/Exception/trace.txt.twig @@ -1,5 +1,5 @@ {% if trace.function %} -at {{ trace.class ~ trace.type ~ trace.function }}({{ trace.args|format_args }}) +at {{ trace.class ~ trace.type ~ trace.function }}({{ trace.args|format_args_as_text }}) {%- endif -%} {% if trace.file|default('') is not empty and trace.line|default('') is not empty %} {{- trace.function ? '\n (' : 'at '}}{{ trace.file|format_file(trace.line)|striptags|replace({ (' at line ' ~ trace.line): '' }) }}:{{ trace.line }}{{ trace.function ? ')' }} From 3d7c7cf39a91a7608bdd4ab8500e9dce2f13d016 Mon Sep 17 00:00:00 2001 From: Nicolas Grekas Date: Thu, 19 Apr 2018 13:01:15 +0200 Subject: [PATCH 30/75] [Cache] Add missing `@internal` tag on ProxyTrait --- src/Symfony/Component/Cache/Traits/ProxyTrait.php | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/Symfony/Component/Cache/Traits/ProxyTrait.php b/src/Symfony/Component/Cache/Traits/ProxyTrait.php index 06dba7e59bf7..d9e085b9ea88 100644 --- a/src/Symfony/Component/Cache/Traits/ProxyTrait.php +++ b/src/Symfony/Component/Cache/Traits/ProxyTrait.php @@ -16,6 +16,8 @@ /** * @author Nicolas Grekas + * + * @internal */ trait ProxyTrait { From f981f7aae849418d7e9af9f4d393c934b6da0ba4 Mon Sep 17 00:00:00 2001 From: Fabien Potencier Date: Fri, 20 Apr 2018 08:14:58 +0200 Subject: [PATCH 31/75] fixed Twig URL --- src/Symfony/Bridge/Twig/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Symfony/Bridge/Twig/README.md b/src/Symfony/Bridge/Twig/README.md index eb084147c37f..602f5a54c3dd 100644 --- a/src/Symfony/Bridge/Twig/README.md +++ b/src/Symfony/Bridge/Twig/README.md @@ -1,7 +1,7 @@ Twig Bridge =========== -Provides integration for [Twig](http://twig.sensiolabs.org/) with various +Provides integration for [Twig](https://twig.symfony.com/) with various Symfony components. Resources From f180bfe2a2e4a63205df23587a11e78d37f95148 Mon Sep 17 00:00:00 2001 From: Fabien Potencier Date: Fri, 20 Apr 2018 08:20:06 +0200 Subject: [PATCH 32/75] fixed deprecations in tests --- .../Extension/Core/Type/ChoiceTypeTest.php | 34 ++++--------------- 1 file changed, 7 insertions(+), 27 deletions(-) diff --git a/src/Symfony/Component/Form/Tests/Extension/Core/Type/ChoiceTypeTest.php b/src/Symfony/Component/Form/Tests/Extension/Core/Type/ChoiceTypeTest.php index fc9f2f8d95a6..9cbe94158141 100644 --- a/src/Symfony/Component/Form/Tests/Extension/Core/Type/ChoiceTypeTest.php +++ b/src/Symfony/Component/Form/Tests/Extension/Core/Type/ChoiceTypeTest.php @@ -1887,9 +1887,7 @@ public function testInheritTranslationDomainFromParent() ->createNamedBuilder('parent', FormTypeTest::TESTED_TYPE, null, array( 'translation_domain' => 'domain', )) - ->add('child', static::TESTED_TYPE, array( - 'choices_as_values' => true, - )) + ->add('child', static::TESTED_TYPE) ->getForm() ->createView(); @@ -1899,7 +1897,6 @@ public function testInheritTranslationDomainFromParent() public function testPassTranslationDomainToView() { $view = $this->factory->create(static::TESTED_TYPE, null, array( - 'choices_as_values' => true, 'translation_domain' => 'domain', )) ->createView(); @@ -1914,7 +1911,6 @@ public function testPreferOwnTranslationDomain() 'translation_domain' => 'parent_domain', )) ->add('child', static::TESTED_TYPE, array( - 'choices_as_values' => true, 'translation_domain' => 'domain', )) ->getForm() @@ -1926,9 +1922,7 @@ public function testPreferOwnTranslationDomain() public function testDefaultTranslationDomain() { $view = $this->factory->createNamedBuilder('parent', FormTypeTest::TESTED_TYPE) - ->add('child', static::TESTED_TYPE, array( - 'choices_as_values' => true, - )) + ->add('child', static::TESTED_TYPE) ->getForm() ->createView(); @@ -1937,9 +1931,7 @@ public function testDefaultTranslationDomain() public function testPassMultipartFalseToView() { - $view = $this->factory->create(static::TESTED_TYPE, null, array( - 'choices_as_values' => true, - )) + $view = $this->factory->create(static::TESTED_TYPE, null) ->createView(); $this->assertFalse($view->vars['multipart']); @@ -1949,7 +1941,6 @@ public function testPassLabelToView() { $view = $this->factory->createNamed('__test___field', static::TESTED_TYPE, null, array( 'label' => 'My label', - 'choices_as_values' => true, )) ->createView(); @@ -1960,9 +1951,7 @@ public function testPassIdAndNameToViewWithGrandParent() { $builder = $this->factory->createNamedBuilder('parent', FormTypeTest::TESTED_TYPE) ->add('child', FormTypeTest::TESTED_TYPE); - $builder->get('child')->add('grand_child', static::TESTED_TYPE, array( - 'choices_as_values' => true, - )); + $builder->get('child')->add('grand_child', static::TESTED_TYPE); $view = $builder->getForm()->createView(); $this->assertEquals('parent_child_grand_child', $view['child']['grand_child']->vars['id']); @@ -1973,9 +1962,7 @@ public function testPassIdAndNameToViewWithGrandParent() public function testPassIdAndNameToViewWithParent() { $view = $this->factory->createNamedBuilder('parent', FormTypeTest::TESTED_TYPE) - ->add('child', static::TESTED_TYPE, array( - 'choices_as_values' => true, - )) + ->add('child', static::TESTED_TYPE) ->getForm() ->createView(); @@ -1988,7 +1975,6 @@ public function testPassDisabledAsOption() { $form = $this->factory->create(static::TESTED_TYPE, null, array( 'disabled' => true, - 'choices_as_values' => true, )); $this->assertTrue($form->isDisabled()); @@ -1996,9 +1982,7 @@ public function testPassDisabledAsOption() public function testPassIdAndNameToView() { - $view = $this->factory->createNamed('name', static::TESTED_TYPE, null, array( - 'choices_as_values' => true, - )) + $view = $this->factory->createNamed('name', static::TESTED_TYPE, null) ->createView(); $this->assertEquals('name', $view->vars['id']); @@ -2008,9 +1992,7 @@ public function testPassIdAndNameToView() public function testStripLeadingUnderscoresAndDigitsFromId() { - $view = $this->factory->createNamed('_09name', static::TESTED_TYPE, null, array( - 'choices_as_values' => true, - )) + $view = $this->factory->createNamed('_09name', static::TESTED_TYPE, null) ->createView(); $this->assertEquals('name', $view->vars['id']); @@ -2029,7 +2011,6 @@ public function testTrimIsDisabled($multiple, $expanded) 'choices' => array( 'a' => '1', ), - 'choices_as_values' => true, )); $submittedData = ' 1'; @@ -2054,7 +2035,6 @@ public function testSubmitValueWithWhiteSpace($multiple, $expanded) 'choices' => array( 'a' => $valueWhitWhiteSpace, ), - 'choices_as_values' => true, )); $form->submit($multiple ? (array) $valueWhitWhiteSpace : $valueWhitWhiteSpace); From d05f0a0e038f44da0448467a6d024223fb33b89b Mon Sep 17 00:00:00 2001 From: Fabien Potencier Date: Fri, 20 Apr 2018 08:21:07 +0200 Subject: [PATCH 33/75] fixed Silex project's URL --- .../Resources/views/Collector/config.html.twig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Symfony/Bundle/WebProfilerBundle/Resources/views/Collector/config.html.twig b/src/Symfony/Bundle/WebProfilerBundle/Resources/views/Collector/config.html.twig index 6b84aaf65663..76061d39a7a9 100644 --- a/src/Symfony/Bundle/WebProfilerBundle/Resources/views/Collector/config.html.twig +++ b/src/Symfony/Bundle/WebProfilerBundle/Resources/views/Collector/config.html.twig @@ -99,7 +99,7 @@ Resources {% if 'Silex' == collector.applicationname %} - + Read Silex Docs {% else %} From 52b4bfc042b344c6ff141c8071e515ca447acb7e Mon Sep 17 00:00:00 2001 From: Nicolas Grekas Date: Thu, 19 Apr 2018 16:46:47 +0200 Subject: [PATCH 34/75] [Cache] Inline some hot function calls --- .../Cache/Adapter/AbstractAdapter.php | 2 +- .../Component/Cache/Adapter/ChainAdapter.php | 39 ++++++++++++------- .../Cache/Adapter/PhpArrayAdapter.php | 14 +++---- .../Cache/Adapter/TagAwareAdapter.php | 6 +-- src/Symfony/Component/Cache/CacheItem.php | 12 +++--- .../Component/Cache/Simple/AbstractCache.php | 12 +++--- .../Component/Cache/Simple/ArrayCache.php | 10 ++--- .../Component/Cache/Simple/ChainCache.php | 4 +- .../Component/Cache/Simple/PhpArrayCache.php | 24 ++++++------ .../Component/Cache/Simple/Psr6Cache.php | 10 ++--- .../Component/Cache/Simple/TraceableCache.php | 6 +-- .../Component/Cache/Traits/AbstractTrait.php | 2 +- .../Component/Cache/Traits/PhpArrayTrait.php | 10 ++--- .../Component/Cache/Traits/PhpFilesTrait.php | 10 ++--- .../Component/Cache/Traits/RedisTrait.php | 2 +- 15 files changed, 86 insertions(+), 77 deletions(-) diff --git a/src/Symfony/Component/Cache/Adapter/AbstractAdapter.php b/src/Symfony/Component/Cache/Adapter/AbstractAdapter.php index 727fc84c9847..5861cd3cd238 100644 --- a/src/Symfony/Component/Cache/Adapter/AbstractAdapter.php +++ b/src/Symfony/Component/Cache/Adapter/AbstractAdapter.php @@ -237,7 +237,7 @@ public function commit() if (true === $e || array() === $e) { continue; } - if (is_array($e) || 1 === count($values)) { + if (\is_array($e) || 1 === \count($values)) { foreach (is_array($e) ? $e : array_keys($values) as $id) { $ok = false; $v = $values[$id]; diff --git a/src/Symfony/Component/Cache/Adapter/ChainAdapter.php b/src/Symfony/Component/Cache/Adapter/ChainAdapter.php index 6bdf6b2d54f1..9334ce3d3bed 100644 --- a/src/Symfony/Component/Cache/Adapter/ChainAdapter.php +++ b/src/Symfony/Component/Cache/Adapter/ChainAdapter.php @@ -30,13 +30,13 @@ class ChainAdapter implements AdapterInterface, PruneableInterface, ResettableIn { private $adapters = array(); private $adapterCount; - private $saveUp; + private $syncItem; /** - * @param CacheItemPoolInterface[] $adapters The ordered list of adapters used to fetch cached items - * @param int $maxLifetime The max lifetime of items propagated from lower adapters to upper ones + * @param CacheItemPoolInterface[] $adapters The ordered list of adapters used to fetch cached items + * @param int $defaultLifetime The default lifetime of items propagated from lower adapters to upper ones */ - public function __construct(array $adapters, $maxLifetime = 0) + public function __construct(array $adapters, $defaultLifetime = 0) { if (!$adapters) { throw new InvalidArgumentException('At least one adapter must be specified.'); @@ -55,16 +55,20 @@ public function __construct(array $adapters, $maxLifetime = 0) } $this->adapterCount = count($this->adapters); - $this->saveUp = \Closure::bind( - function ($adapter, $item) use ($maxLifetime) { - $origDefaultLifetime = $item->defaultLifetime; + $this->syncItem = \Closure::bind( + function ($sourceItem, $item) use ($defaultLifetime) { + $item->value = $sourceItem->value; + $item->expiry = $sourceItem->expiry; + $item->isHit = $sourceItem->isHit; - if (0 < $maxLifetime && ($origDefaultLifetime <= 0 || $maxLifetime < $origDefaultLifetime)) { - $item->defaultLifetime = $maxLifetime; + if (0 < $sourceItem->defaultLifetime && $sourceItem->defaultLifetime < $defaultLifetime) { + $defaultLifetime = $sourceItem->defaultLifetime; + } + if (0 < $defaultLifetime && ($item->defaultLifetime <= 0 || $defaultLifetime < $item->defaultLifetime)) { + $item->defaultLifetime = $defaultLifetime; } - $adapter->save($item); - $item->defaultLifetime = $origDefaultLifetime; + return $item; }, null, CacheItem::class @@ -76,18 +80,21 @@ function ($adapter, $item) use ($maxLifetime) { */ public function getItem($key) { - $saveUp = $this->saveUp; + $syncItem = $this->syncItem; + $misses = array(); foreach ($this->adapters as $i => $adapter) { $item = $adapter->getItem($key); if ($item->isHit()) { while (0 <= --$i) { - $saveUp($this->adapters[$i], $item); + $this->adapters[$i]->save($syncItem($item, $misses[$i])); } return $item; } + + $misses[$i] = $item; } return $item; @@ -104,6 +111,7 @@ public function getItems(array $keys = array()) private function generateItems($items, $adapterIndex) { $missing = array(); + $misses = array(); $nextAdapterIndex = $adapterIndex + 1; $nextAdapter = isset($this->adapters[$nextAdapterIndex]) ? $this->adapters[$nextAdapterIndex] : null; @@ -112,17 +120,18 @@ private function generateItems($items, $adapterIndex) yield $k => $item; } else { $missing[] = $k; + $misses[$k] = $item; } } if ($missing) { - $saveUp = $this->saveUp; + $syncItem = $this->syncItem; $adapter = $this->adapters[$adapterIndex]; $items = $this->generateItems($nextAdapter->getItems($missing), $nextAdapterIndex); foreach ($items as $k => $item) { if ($item->isHit()) { - $saveUp($adapter, $item); + $adapter->save($syncItem($item, $misses[$k])); } yield $k => $item; diff --git a/src/Symfony/Component/Cache/Adapter/PhpArrayAdapter.php b/src/Symfony/Component/Cache/Adapter/PhpArrayAdapter.php index d3b9d77d45bb..e84b0ba0c41d 100644 --- a/src/Symfony/Component/Cache/Adapter/PhpArrayAdapter.php +++ b/src/Symfony/Component/Cache/Adapter/PhpArrayAdapter.php @@ -84,7 +84,7 @@ public static function create($file, CacheItemPoolInterface $fallbackPool) */ public function getItem($key) { - if (!is_string($key)) { + if (!\is_string($key)) { throw new InvalidArgumentException(sprintf('Cache key must be string, "%s" given.', is_object($key) ? get_class($key) : gettype($key))); } if (null === $this->values) { @@ -99,7 +99,7 @@ public function getItem($key) if ('N;' === $value) { $value = null; - } elseif (is_string($value) && isset($value[2]) && ':' === $value[1]) { + } elseif (\is_string($value) && isset($value[2]) && ':' === $value[1]) { try { $e = null; $value = unserialize($value); @@ -123,7 +123,7 @@ public function getItem($key) public function getItems(array $keys = array()) { foreach ($keys as $key) { - if (!is_string($key)) { + if (!\is_string($key)) { throw new InvalidArgumentException(sprintf('Cache key must be string, "%s" given.', is_object($key) ? get_class($key) : gettype($key))); } } @@ -139,7 +139,7 @@ public function getItems(array $keys = array()) */ public function hasItem($key) { - if (!is_string($key)) { + if (!\is_string($key)) { throw new InvalidArgumentException(sprintf('Cache key must be string, "%s" given.', is_object($key) ? get_class($key) : gettype($key))); } if (null === $this->values) { @@ -154,7 +154,7 @@ public function hasItem($key) */ public function deleteItem($key) { - if (!is_string($key)) { + if (!\is_string($key)) { throw new InvalidArgumentException(sprintf('Cache key must be string, "%s" given.', is_object($key) ? get_class($key) : gettype($key))); } if (null === $this->values) { @@ -173,7 +173,7 @@ public function deleteItems(array $keys) $fallbackKeys = array(); foreach ($keys as $key) { - if (!is_string($key)) { + if (!\is_string($key)) { throw new InvalidArgumentException(sprintf('Cache key must be string, "%s" given.', is_object($key) ? get_class($key) : gettype($key))); } @@ -240,7 +240,7 @@ private function generateItems(array $keys) if ('N;' === $value) { yield $key => $f($key, null, true); - } elseif (is_string($value) && isset($value[2]) && ':' === $value[1]) { + } elseif (\is_string($value) && isset($value[2]) && ':' === $value[1]) { try { yield $key => $f($key, unserialize($value), true); } catch (\Error $e) { diff --git a/src/Symfony/Component/Cache/Adapter/TagAwareAdapter.php b/src/Symfony/Component/Cache/Adapter/TagAwareAdapter.php index 72bbc143cedf..a71b903d734f 100644 --- a/src/Symfony/Component/Cache/Adapter/TagAwareAdapter.php +++ b/src/Symfony/Component/Cache/Adapter/TagAwareAdapter.php @@ -107,7 +107,7 @@ function (AdapterInterface $tagsAdapter, array $tags) { public function invalidateTags(array $tags) { foreach ($tags as $k => $tag) { - if ('' !== $tag && is_string($tag)) { + if ('' !== $tag && \is_string($tag)) { $tags[$k] = $tag.static::TAGS_PREFIX; } } @@ -161,7 +161,7 @@ public function getItems(array $keys = array()) $tagKeys = array(); foreach ($keys as $key) { - if ('' !== $key && is_string($key)) { + if ('' !== $key && \is_string($key)) { $key = static::TAGS_PREFIX.$key; $tagKeys[$key] = $key; } @@ -202,7 +202,7 @@ public function deleteItem($key) public function deleteItems(array $keys) { foreach ($keys as $key) { - if ('' !== $key && is_string($key)) { + if ('' !== $key && \is_string($key)) { $keys[] = static::TAGS_PREFIX.$key; } } diff --git a/src/Symfony/Component/Cache/CacheItem.php b/src/Symfony/Component/Cache/CacheItem.php index 93ffea495e88..cecaa126d912 100644 --- a/src/Symfony/Component/Cache/CacheItem.php +++ b/src/Symfony/Component/Cache/CacheItem.php @@ -89,7 +89,7 @@ public function expiresAfter($time) $this->expiry = $this->defaultLifetime > 0 ? time() + $this->defaultLifetime : null; } elseif ($time instanceof \DateInterval) { $this->expiry = (int) \DateTime::createFromFormat('U', time())->add($time)->format('U'); - } elseif (is_int($time)) { + } elseif (\is_int($time)) { $this->expiry = $time + time(); } else { throw new InvalidArgumentException(sprintf('Expiration date must be an integer, a DateInterval or null, "%s" given', is_object($time) ? get_class($time) : gettype($time))); @@ -109,17 +109,17 @@ public function expiresAfter($time) */ public function tag($tags) { - if (!is_array($tags)) { + if (!\is_array($tags)) { $tags = array($tags); } foreach ($tags as $tag) { - if (!is_string($tag)) { + if (!\is_string($tag)) { throw new InvalidArgumentException(sprintf('Cache tag must be string, "%s" given', is_object($tag) ? get_class($tag) : gettype($tag))); } if (isset($this->tags[$tag])) { continue; } - if (!isset($tag[0])) { + if ('' === $tag) { throw new InvalidArgumentException('Cache tag length must be greater than zero'); } if (false !== strpbrk($tag, '{}()/\@:')) { @@ -152,10 +152,10 @@ public function getPreviousTags() */ public static function validateKey($key) { - if (!is_string($key)) { + if (!\is_string($key)) { throw new InvalidArgumentException(sprintf('Cache key must be string, "%s" given', is_object($key) ? get_class($key) : gettype($key))); } - if (!isset($key[0])) { + if ('' === $key) { throw new InvalidArgumentException('Cache key length must be greater than zero'); } if (false !== strpbrk($key, '{}()/\@:')) { diff --git a/src/Symfony/Component/Cache/Simple/AbstractCache.php b/src/Symfony/Component/Cache/Simple/AbstractCache.php index e666effaf93f..e3fc790479dc 100644 --- a/src/Symfony/Component/Cache/Simple/AbstractCache.php +++ b/src/Symfony/Component/Cache/Simple/AbstractCache.php @@ -79,7 +79,7 @@ public function getMultiple($keys, $default = null) { if ($keys instanceof \Traversable) { $keys = iterator_to_array($keys, false); - } elseif (!is_array($keys)) { + } elseif (!\is_array($keys)) { throw new InvalidArgumentException(sprintf('Cache keys must be array or Traversable, "%s" given', is_object($keys) ? get_class($keys) : gettype($keys))); } $ids = array(); @@ -103,13 +103,13 @@ public function getMultiple($keys, $default = null) */ public function setMultiple($values, $ttl = null) { - if (!is_array($values) && !$values instanceof \Traversable) { + if (!\is_array($values) && !$values instanceof \Traversable) { throw new InvalidArgumentException(sprintf('Cache values must be array or Traversable, "%s" given', is_object($values) ? get_class($values) : gettype($values))); } $valuesById = array(); foreach ($values as $key => $value) { - if (is_int($key)) { + if (\is_int($key)) { $key = (string) $key; } $valuesById[$this->getId($key)] = $value; @@ -126,7 +126,7 @@ public function setMultiple($values, $ttl = null) return true; } $keys = array(); - foreach (is_array($e) ? $e : array_keys($valuesById) as $id) { + foreach (\is_array($e) ? $e : array_keys($valuesById) as $id) { $keys[] = substr($id, strlen($this->namespace)); } CacheItem::log($this->logger, 'Failed to save values', array('keys' => $keys, 'exception' => $e instanceof \Exception ? $e : null)); @@ -141,7 +141,7 @@ public function deleteMultiple($keys) { if ($keys instanceof \Traversable) { $keys = iterator_to_array($keys, false); - } elseif (!is_array($keys)) { + } elseif (!\is_array($keys)) { throw new InvalidArgumentException(sprintf('Cache keys must be array or Traversable, "%s" given', is_object($keys) ? get_class($keys) : gettype($keys))); } @@ -156,7 +156,7 @@ private function normalizeTtl($ttl) if ($ttl instanceof \DateInterval) { $ttl = (int) \DateTime::createFromFormat('U', 0)->add($ttl)->format('U'); } - if (is_int($ttl)) { + if (\is_int($ttl)) { return 0 < $ttl ? $ttl : false; } diff --git a/src/Symfony/Component/Cache/Simple/ArrayCache.php b/src/Symfony/Component/Cache/Simple/ArrayCache.php index 8d027cd2a372..8657573e3511 100644 --- a/src/Symfony/Component/Cache/Simple/ArrayCache.php +++ b/src/Symfony/Component/Cache/Simple/ArrayCache.php @@ -57,7 +57,7 @@ public function getMultiple($keys, $default = null) { if ($keys instanceof \Traversable) { $keys = iterator_to_array($keys, false); - } elseif (!is_array($keys)) { + } elseif (!\is_array($keys)) { throw new InvalidArgumentException(sprintf('Cache keys must be array or Traversable, "%s" given', is_object($keys) ? get_class($keys) : gettype($keys))); } foreach ($keys as $key) { @@ -72,7 +72,7 @@ public function getMultiple($keys, $default = null) */ public function deleteMultiple($keys) { - if (!is_array($keys) && !$keys instanceof \Traversable) { + if (!\is_array($keys) && !$keys instanceof \Traversable) { throw new InvalidArgumentException(sprintf('Cache keys must be array or Traversable, "%s" given', is_object($keys) ? get_class($keys) : gettype($keys))); } foreach ($keys as $key) { @@ -97,13 +97,13 @@ public function set($key, $value, $ttl = null) */ public function setMultiple($values, $ttl = null) { - if (!is_array($values) && !$values instanceof \Traversable) { + if (!\is_array($values) && !$values instanceof \Traversable) { throw new InvalidArgumentException(sprintf('Cache values must be array or Traversable, "%s" given', is_object($values) ? get_class($values) : gettype($values))); } $valuesArray = array(); foreach ($values as $key => $value) { - is_int($key) || CacheItem::validateKey($key); + \is_int($key) || CacheItem::validateKey($key); $valuesArray[$key] = $value; } if (false === $ttl = $this->normalizeTtl($ttl)) { @@ -139,7 +139,7 @@ private function normalizeTtl($ttl) if ($ttl instanceof \DateInterval) { $ttl = (int) \DateTime::createFromFormat('U', 0)->add($ttl)->format('U'); } - if (is_int($ttl)) { + if (\is_int($ttl)) { return 0 < $ttl ? $ttl : false; } diff --git a/src/Symfony/Component/Cache/Simple/ChainCache.php b/src/Symfony/Component/Cache/Simple/ChainCache.php index 9d0c75870eb7..dd825f268af9 100644 --- a/src/Symfony/Component/Cache/Simple/ChainCache.php +++ b/src/Symfony/Component/Cache/Simple/ChainCache.php @@ -58,7 +58,7 @@ public function __construct(array $caches, $defaultLifetime = 0) */ public function get($key, $default = null) { - $miss = null !== $default && is_object($default) ? $default : $this->miss; + $miss = null !== $default && \is_object($default) ? $default : $this->miss; foreach ($this->caches as $i => $cache) { $value = $cache->get($key, $miss); @@ -80,7 +80,7 @@ public function get($key, $default = null) */ public function getMultiple($keys, $default = null) { - $miss = null !== $default && is_object($default) ? $default : $this->miss; + $miss = null !== $default && \is_object($default) ? $default : $this->miss; return $this->generateItems($this->caches[0]->getMultiple($keys, $miss), 0, $miss, $default); } diff --git a/src/Symfony/Component/Cache/Simple/PhpArrayCache.php b/src/Symfony/Component/Cache/Simple/PhpArrayCache.php index 3db8a2ac1c04..35a82b65158b 100644 --- a/src/Symfony/Component/Cache/Simple/PhpArrayCache.php +++ b/src/Symfony/Component/Cache/Simple/PhpArrayCache.php @@ -63,7 +63,7 @@ public static function create($file, CacheInterface $fallbackPool) */ public function get($key, $default = null) { - if (!is_string($key)) { + if (!\is_string($key)) { throw new InvalidArgumentException(sprintf('Cache key must be string, "%s" given.', is_object($key) ? get_class($key) : gettype($key))); } if (null === $this->values) { @@ -77,7 +77,7 @@ public function get($key, $default = null) if ('N;' === $value) { $value = null; - } elseif (is_string($value) && isset($value[2]) && ':' === $value[1]) { + } elseif (\is_string($value) && isset($value[2]) && ':' === $value[1]) { try { $e = null; $value = unserialize($value); @@ -99,11 +99,11 @@ public function getMultiple($keys, $default = null) { if ($keys instanceof \Traversable) { $keys = iterator_to_array($keys, false); - } elseif (!is_array($keys)) { + } elseif (!\is_array($keys)) { throw new InvalidArgumentException(sprintf('Cache keys must be array or Traversable, "%s" given', is_object($keys) ? get_class($keys) : gettype($keys))); } foreach ($keys as $key) { - if (!is_string($key)) { + if (!\is_string($key)) { throw new InvalidArgumentException(sprintf('Cache key must be string, "%s" given.', is_object($key) ? get_class($key) : gettype($key))); } } @@ -119,7 +119,7 @@ public function getMultiple($keys, $default = null) */ public function has($key) { - if (!is_string($key)) { + if (!\is_string($key)) { throw new InvalidArgumentException(sprintf('Cache key must be string, "%s" given.', is_object($key) ? get_class($key) : gettype($key))); } if (null === $this->values) { @@ -134,7 +134,7 @@ public function has($key) */ public function delete($key) { - if (!is_string($key)) { + if (!\is_string($key)) { throw new InvalidArgumentException(sprintf('Cache key must be string, "%s" given.', is_object($key) ? get_class($key) : gettype($key))); } if (null === $this->values) { @@ -149,7 +149,7 @@ public function delete($key) */ public function deleteMultiple($keys) { - if (!is_array($keys) && !$keys instanceof \Traversable) { + if (!\is_array($keys) && !$keys instanceof \Traversable) { throw new InvalidArgumentException(sprintf('Cache keys must be array or Traversable, "%s" given', is_object($keys) ? get_class($keys) : gettype($keys))); } @@ -157,7 +157,7 @@ public function deleteMultiple($keys) $fallbackKeys = array(); foreach ($keys as $key) { - if (!is_string($key)) { + if (!\is_string($key)) { throw new InvalidArgumentException(sprintf('Cache key must be string, "%s" given.', is_object($key) ? get_class($key) : gettype($key))); } @@ -183,7 +183,7 @@ public function deleteMultiple($keys) */ public function set($key, $value, $ttl = null) { - if (!is_string($key)) { + if (!\is_string($key)) { throw new InvalidArgumentException(sprintf('Cache key must be string, "%s" given.', is_object($key) ? get_class($key) : gettype($key))); } if (null === $this->values) { @@ -198,7 +198,7 @@ public function set($key, $value, $ttl = null) */ public function setMultiple($values, $ttl = null) { - if (!is_array($values) && !$values instanceof \Traversable) { + if (!\is_array($values) && !$values instanceof \Traversable) { throw new InvalidArgumentException(sprintf('Cache values must be array or Traversable, "%s" given', is_object($values) ? get_class($values) : gettype($values))); } @@ -206,7 +206,7 @@ public function setMultiple($values, $ttl = null) $fallbackValues = array(); foreach ($values as $key => $value) { - if (!is_string($key) && !is_int($key)) { + if (!\is_string($key) && !\is_int($key)) { throw new InvalidArgumentException(sprintf('Cache key must be string, "%s" given.', is_object($key) ? get_class($key) : gettype($key))); } @@ -234,7 +234,7 @@ private function generateItems(array $keys, $default) if ('N;' === $value) { yield $key => null; - } elseif (is_string($value) && isset($value[2]) && ':' === $value[1]) { + } elseif (\is_string($value) && isset($value[2]) && ':' === $value[1]) { try { yield $key => unserialize($value); } catch (\Error $e) { diff --git a/src/Symfony/Component/Cache/Simple/Psr6Cache.php b/src/Symfony/Component/Cache/Simple/Psr6Cache.php index 81f14d4a7045..4a71346d2ce5 100644 --- a/src/Symfony/Component/Cache/Simple/Psr6Cache.php +++ b/src/Symfony/Component/Cache/Simple/Psr6Cache.php @@ -38,7 +38,7 @@ public function __construct(CacheItemPoolInterface $pool) if ($pool instanceof AbstractAdapter) { $this->createCacheItem = \Closure::bind( function ($key, $value, $allowInt = false) { - if ($allowInt && is_int($key)) { + if ($allowInt && \is_int($key)) { $key = (string) $key; } else { CacheItem::validateKey($key); @@ -121,7 +121,7 @@ public function getMultiple($keys, $default = null) { if ($keys instanceof \Traversable) { $keys = iterator_to_array($keys, false); - } elseif (!is_array($keys)) { + } elseif (!\is_array($keys)) { throw new InvalidArgumentException(sprintf('Cache keys must be array or Traversable, "%s" given', is_object($keys) ? get_class($keys) : gettype($keys))); } @@ -146,7 +146,7 @@ public function getMultiple($keys, $default = null) */ public function setMultiple($values, $ttl = null) { - $valuesIsArray = is_array($values); + $valuesIsArray = \is_array($values); if (!$valuesIsArray && !$values instanceof \Traversable) { throw new InvalidArgumentException(sprintf('Cache values must be array or Traversable, "%s" given', is_object($values) ? get_class($values) : gettype($values))); } @@ -166,7 +166,7 @@ public function setMultiple($values, $ttl = null) $items = $this->pool->getItems($items); } else { foreach ($values as $key => $value) { - if (is_int($key)) { + if (\is_int($key)) { $key = (string) $key; } $items[$key] = $this->pool->getItem($key)->set($value); @@ -199,7 +199,7 @@ public function deleteMultiple($keys) { if ($keys instanceof \Traversable) { $keys = iterator_to_array($keys, false); - } elseif (!is_array($keys)) { + } elseif (!\is_array($keys)) { throw new InvalidArgumentException(sprintf('Cache keys must be array or Traversable, "%s" given', is_object($keys) ? get_class($keys) : gettype($keys))); } diff --git a/src/Symfony/Component/Cache/Simple/TraceableCache.php b/src/Symfony/Component/Cache/Simple/TraceableCache.php index 756403bf1430..181934eff501 100644 --- a/src/Symfony/Component/Cache/Simple/TraceableCache.php +++ b/src/Symfony/Component/Cache/Simple/TraceableCache.php @@ -37,7 +37,7 @@ public function __construct(CacheInterface $pool) */ public function get($key, $default = null) { - $miss = null !== $default && is_object($default) ? $default : $this->miss; + $miss = null !== $default && \is_object($default) ? $default : $this->miss; $event = $this->start(__FUNCTION__); try { $value = $this->pool->get($key, $miss); @@ -109,7 +109,7 @@ public function setMultiple($values, $ttl = null) } }; $values = $values(); - } elseif (is_array($values)) { + } elseif (\is_array($values)) { $event->result['keys'] = array_keys($values); } @@ -125,7 +125,7 @@ public function setMultiple($values, $ttl = null) */ public function getMultiple($keys, $default = null) { - $miss = null !== $default && is_object($default) ? $default : $this->miss; + $miss = null !== $default && \is_object($default) ? $default : $this->miss; $event = $this->start(__FUNCTION__); try { $result = $this->pool->getMultiple($keys, $miss); diff --git a/src/Symfony/Component/Cache/Traits/AbstractTrait.php b/src/Symfony/Component/Cache/Traits/AbstractTrait.php index d7af3b559e0e..92999a2f3c34 100644 --- a/src/Symfony/Component/Cache/Traits/AbstractTrait.php +++ b/src/Symfony/Component/Cache/Traits/AbstractTrait.php @@ -241,7 +241,7 @@ private function getId($key) if (null === $this->maxIdLength) { return $this->namespace.$this->namespaceVersion.$key; } - if (strlen($id = $this->namespace.$this->namespaceVersion.$key) > $this->maxIdLength) { + if (\strlen($id = $this->namespace.$this->namespaceVersion.$key) > $this->maxIdLength) { $id = $this->namespace.$this->namespaceVersion.substr_replace(base64_encode(hash('sha256', $key, true)), ':', -22); } diff --git a/src/Symfony/Component/Cache/Traits/PhpArrayTrait.php b/src/Symfony/Component/Cache/Traits/PhpArrayTrait.php index ae634d6baa29..e90492b3a14d 100644 --- a/src/Symfony/Component/Cache/Traits/PhpArrayTrait.php +++ b/src/Symfony/Component/Cache/Traits/PhpArrayTrait.php @@ -66,15 +66,15 @@ public function warmUp(array $values) EOF; foreach ($values as $key => $value) { - CacheItem::validateKey(is_int($key) ? (string) $key : $key); + CacheItem::validateKey(\is_int($key) ? (string) $key : $key); - if (null === $value || is_object($value)) { + if (null === $value || \is_object($value)) { try { $value = serialize($value); } catch (\Exception $e) { throw new InvalidArgumentException(sprintf('Cache key "%s" has non-serializable %s value.', $key, get_class($value)), 0, $e); } - } elseif (is_array($value)) { + } elseif (\is_array($value)) { try { $serialized = serialize($value); $unserialized = unserialize($serialized); @@ -85,12 +85,12 @@ public function warmUp(array $values) if ($unserialized !== $value || (false !== strpos($serialized, ';R:') && preg_match('/;R:[1-9]/', $serialized))) { $value = $serialized; } - } elseif (is_string($value)) { + } elseif (\is_string($value)) { // Serialize strings if they could be confused with serialized objects or arrays if ('N;' === $value || (isset($value[2]) && ':' === $value[1])) { $value = serialize($value); } - } elseif (!is_scalar($value)) { + } elseif (!\is_scalar($value)) { throw new InvalidArgumentException(sprintf('Cache key "%s" has non-serializable %s value.', $key, gettype($value))); } diff --git a/src/Symfony/Component/Cache/Traits/PhpFilesTrait.php b/src/Symfony/Component/Cache/Traits/PhpFilesTrait.php index c800e1a1798e..32bbeb71237e 100644 --- a/src/Symfony/Component/Cache/Traits/PhpFilesTrait.php +++ b/src/Symfony/Component/Cache/Traits/PhpFilesTrait.php @@ -96,7 +96,7 @@ protected function doFetch(array $ids) foreach ($values as $id => $value) { if ('N;' === $value) { $values[$id] = null; - } elseif (is_string($value) && isset($value[2]) && ':' === $value[1]) { + } elseif (\is_string($value) && isset($value[2]) && ':' === $value[1]) { $values[$id] = parent::unserialize($value); } } @@ -122,21 +122,21 @@ protected function doSave(array $values, $lifetime) $allowCompile = 'cli' !== PHP_SAPI || ini_get('opcache.enable_cli'); foreach ($values as $key => $value) { - if (null === $value || is_object($value)) { + if (null === $value || \is_object($value)) { $value = serialize($value); - } elseif (is_array($value)) { + } elseif (\is_array($value)) { $serialized = serialize($value); $unserialized = parent::unserialize($serialized); // Store arrays serialized if they contain any objects or references if ($unserialized !== $value || (false !== strpos($serialized, ';R:') && preg_match('/;R:[1-9]/', $serialized))) { $value = $serialized; } - } elseif (is_string($value)) { + } elseif (\is_string($value)) { // Serialize strings if they could be confused with serialized objects or arrays if ('N;' === $value || (isset($value[2]) && ':' === $value[1])) { $value = serialize($value); } - } elseif (!is_scalar($value)) { + } elseif (!\is_scalar($value)) { throw new InvalidArgumentException(sprintf('Cache key "%s" has non-serializable %s value.', $key, gettype($value))); } diff --git a/src/Symfony/Component/Cache/Traits/RedisTrait.php b/src/Symfony/Component/Cache/Traits/RedisTrait.php index ac8b5a5fccda..b8e05d9e417c 100644 --- a/src/Symfony/Component/Cache/Traits/RedisTrait.php +++ b/src/Symfony/Component/Cache/Traits/RedisTrait.php @@ -240,7 +240,7 @@ protected function doClear($namespace) $cursor = null; do { $keys = $host instanceof \Predis\Client ? $host->scan($cursor, 'MATCH', $namespace.'*', 'COUNT', 1000) : $host->scan($cursor, $namespace.'*', 1000); - if (isset($keys[1]) && is_array($keys[1])) { + if (isset($keys[1]) && \is_array($keys[1])) { $cursor = $keys[0]; $keys = $keys[1]; } From 877e67883cd3c440bc16e124dd8da216f9c3babd Mon Sep 17 00:00:00 2001 From: Vladimir Reznichenko Date: Sun, 15 Apr 2018 22:26:30 +0200 Subject: [PATCH 35/75] [minor] SCA --- .../Bundle/FrameworkBundle/CacheWarmer/TemplateFinder.php | 5 ++--- .../Bundle/FrameworkBundle/Templating/Helper/CodeHelper.php | 2 +- src/Symfony/Component/Console/Descriptor/JsonDescriptor.php | 2 +- .../Component/Console/Descriptor/MarkdownDescriptor.php | 2 +- src/Symfony/Component/Console/Descriptor/XmlDescriptor.php | 2 +- src/Symfony/Component/Console/Input/InputOption.php | 2 +- .../Mapping/Factory/LazyLoadingMetadataFactory.php | 6 +----- 7 files changed, 8 insertions(+), 13 deletions(-) diff --git a/src/Symfony/Bundle/FrameworkBundle/CacheWarmer/TemplateFinder.php b/src/Symfony/Bundle/FrameworkBundle/CacheWarmer/TemplateFinder.php index d68fa7ce7767..e49bf22a3562 100644 --- a/src/Symfony/Bundle/FrameworkBundle/CacheWarmer/TemplateFinder.php +++ b/src/Symfony/Bundle/FrameworkBundle/CacheWarmer/TemplateFinder.php @@ -96,11 +96,10 @@ private function findTemplatesInFolder($dir) private function findTemplatesInBundle(BundleInterface $bundle) { $name = $bundle->getName(); - $templates = array_merge( + $templates = array_unique(array_merge( $this->findTemplatesInFolder($bundle->getPath().'/Resources/views'), $this->findTemplatesInFolder($this->rootDir.'/'.$name.'/views') - ); - $templates = array_unique($templates); + )); foreach ($templates as $i => $template) { $templates[$i] = $template->set('bundle', $name); diff --git a/src/Symfony/Bundle/FrameworkBundle/Templating/Helper/CodeHelper.php b/src/Symfony/Bundle/FrameworkBundle/Templating/Helper/CodeHelper.php index 7390144dc8dd..7a1eb9700aad 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Templating/Helper/CodeHelper.php +++ b/src/Symfony/Bundle/FrameworkBundle/Templating/Helper/CodeHelper.php @@ -160,7 +160,7 @@ public function formatFile($file, $line, $text = null) $file = trim($file); $fileStr = $file; if (0 === strpos($fileStr, $this->rootDir)) { - $fileStr = str_replace($this->rootDir, '', str_replace('\\', '/', $fileStr)); + $fileStr = str_replace(array('\\', $this->rootDir), array('/', ''), $fileStr); $fileStr = htmlspecialchars($fileStr, $flags, $this->charset); $fileStr = sprintf('kernel.root_dir/%s', htmlspecialchars($this->rootDir, $flags, $this->charset), $fileStr); } diff --git a/src/Symfony/Component/Console/Descriptor/JsonDescriptor.php b/src/Symfony/Component/Console/Descriptor/JsonDescriptor.php index 51c4d2ef0e61..0a22274b3508 100644 --- a/src/Symfony/Component/Console/Descriptor/JsonDescriptor.php +++ b/src/Symfony/Component/Console/Descriptor/JsonDescriptor.php @@ -109,7 +109,7 @@ private function getInputOptionData(InputOption $option) { return array( 'name' => '--'.$option->getName(), - 'shortcut' => $option->getShortcut() ? '-'.implode('|-', explode('|', $option->getShortcut())) : '', + 'shortcut' => $option->getShortcut() ? '-'.str_replace('|', '|-', $option->getShortcut()) : '', 'accept_value' => $option->acceptValue(), 'is_value_required' => $option->isValueRequired(), 'is_multiple' => $option->isArray(), diff --git a/src/Symfony/Component/Console/Descriptor/MarkdownDescriptor.php b/src/Symfony/Component/Console/Descriptor/MarkdownDescriptor.php index c2d6243e280c..76399cae7d40 100644 --- a/src/Symfony/Component/Console/Descriptor/MarkdownDescriptor.php +++ b/src/Symfony/Component/Console/Descriptor/MarkdownDescriptor.php @@ -50,7 +50,7 @@ protected function describeInputOption(InputOption $option, array $options = arr $this->write( '**'.$option->getName().':**'."\n\n" .'* Name: `--'.$option->getName().'`'."\n" - .'* Shortcut: '.($option->getShortcut() ? '`-'.implode('|-', explode('|', $option->getShortcut())).'`' : '')."\n" + .'* Shortcut: '.($option->getShortcut() ? '`-'.str_replace('|', '|-', $option->getShortcut()).'`' : '')."\n" .'* Accept value: '.($option->acceptValue() ? 'yes' : 'no')."\n" .'* Is value required: '.($option->isValueRequired() ? 'yes' : 'no')."\n" .'* Is multiple: '.($option->isArray() ? 'yes' : 'no')."\n" diff --git a/src/Symfony/Component/Console/Descriptor/XmlDescriptor.php b/src/Symfony/Component/Console/Descriptor/XmlDescriptor.php index 177a054cc18d..c42fa429dcf6 100644 --- a/src/Symfony/Component/Console/Descriptor/XmlDescriptor.php +++ b/src/Symfony/Component/Console/Descriptor/XmlDescriptor.php @@ -223,7 +223,7 @@ private function getInputOptionDocument(InputOption $option) $pos = strpos($option->getShortcut(), '|'); if (false !== $pos) { $objectXML->setAttribute('shortcut', '-'.substr($option->getShortcut(), 0, $pos)); - $objectXML->setAttribute('shortcuts', '-'.implode('|-', explode('|', $option->getShortcut()))); + $objectXML->setAttribute('shortcuts', '-'.str_replace('|', '|-', $option->getShortcut())); } else { $objectXML->setAttribute('shortcut', $option->getShortcut() ? '-'.$option->getShortcut() : ''); } diff --git a/src/Symfony/Component/Console/Input/InputOption.php b/src/Symfony/Component/Console/Input/InputOption.php index e6ca45aa42c5..c2b57c7c27a3 100644 --- a/src/Symfony/Component/Console/Input/InputOption.php +++ b/src/Symfony/Component/Console/Input/InputOption.php @@ -192,7 +192,7 @@ public function getDescription() * * @return bool */ - public function equals(InputOption $option) + public function equals(self $option) { return $option->getName() === $this->getName() && $option->getShortcut() === $this->getShortcut() diff --git a/src/Symfony/Component/Validator/Mapping/Factory/LazyLoadingMetadataFactory.php b/src/Symfony/Component/Validator/Mapping/Factory/LazyLoadingMetadataFactory.php index e088caa897a7..cb253f844ba7 100644 --- a/src/Symfony/Component/Validator/Mapping/Factory/LazyLoadingMetadataFactory.php +++ b/src/Symfony/Component/Validator/Mapping/Factory/LazyLoadingMetadataFactory.php @@ -162,10 +162,6 @@ public function hasMetadataFor($value) $class = ltrim(is_object($value) ? get_class($value) : $value, '\\'); - if (class_exists($class) || interface_exists($class)) { - return true; - } - - return false; + return class_exists($class) || interface_exists($class, false); } } From 47153979792dc10fd6c1c25a7e89ca05ec7b9d80 Mon Sep 17 00:00:00 2001 From: Alexis MARQUIS Date: Thu, 19 Apr 2018 15:21:21 +0200 Subject: [PATCH 36/75] Fix PercentType error rendering. --- .../Twig/Resources/views/Form/bootstrap_4_layout.html.twig | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/Symfony/Bridge/Twig/Resources/views/Form/bootstrap_4_layout.html.twig b/src/Symfony/Bridge/Twig/Resources/views/Form/bootstrap_4_layout.html.twig index 44141f1b383b..43c031b93336 100644 --- a/src/Symfony/Bridge/Twig/Resources/views/Form/bootstrap_4_layout.html.twig +++ b/src/Symfony/Bridge/Twig/Resources/views/Form/bootstrap_4_layout.html.twig @@ -106,8 +106,7 @@ {%- endblock dateinterval_widget %} {% block percent_widget -%} -
- {% set valid = true %} +
{{- block('form_widget_simple') -}}
% From 583759f0b6006e1e910f34227ad3b4914695463c Mon Sep 17 00:00:00 2001 From: insekticid Date: Sat, 31 Mar 2018 01:03:42 +0200 Subject: [PATCH 37/75] PropertyInfo\DoctrineExtractor - There is bug when indexBy is meta key --- .../Bridge/Doctrine/PropertyInfo/DoctrineExtractor.php | 10 ++++++++++ .../Tests/PropertyInfo/DoctrineExtractorTest.php | 9 +++++++++ .../Tests/PropertyInfo/Fixtures/DoctrineDummy.php | 6 ++++++ .../Tests/PropertyInfo/Fixtures/DoctrineRelation.php | 7 +++++++ 4 files changed, 32 insertions(+) diff --git a/src/Symfony/Bridge/Doctrine/PropertyInfo/DoctrineExtractor.php b/src/Symfony/Bridge/Doctrine/PropertyInfo/DoctrineExtractor.php index fee254da65ab..4bf684bf3aec 100644 --- a/src/Symfony/Bridge/Doctrine/PropertyInfo/DoctrineExtractor.php +++ b/src/Symfony/Bridge/Doctrine/PropertyInfo/DoctrineExtractor.php @@ -95,9 +95,19 @@ public function getTypes($class, $property, array $context = array()) if (isset($associationMapping['indexBy'])) { $indexProperty = $associationMapping['indexBy']; + /** @var ClassMetadataInfo $subMetadata */ $subMetadata = $this->classMetadataFactory->getMetadataFor($associationMapping['targetEntity']); $typeOfField = $subMetadata->getTypeOfField($indexProperty); + if (null === $typeOfField) { + $associationMapping = $subMetadata->getAssociationMapping($indexProperty); + + /** @var ClassMetadataInfo $subMetadata */ + $indexProperty = $subMetadata->getSingleAssociationReferencedJoinColumnName($indexProperty); + $subMetadata = $this->classMetadataFactory->getMetadataFor($associationMapping['targetEntity']); + $typeOfField = $subMetadata->getTypeOfField($indexProperty); + } + $collectionKeyType = $this->getPhpType($typeOfField); } } diff --git a/src/Symfony/Bridge/Doctrine/Tests/PropertyInfo/DoctrineExtractorTest.php b/src/Symfony/Bridge/Doctrine/Tests/PropertyInfo/DoctrineExtractorTest.php index 139601710ede..8bc25718ecd6 100644 --- a/src/Symfony/Bridge/Doctrine/Tests/PropertyInfo/DoctrineExtractorTest.php +++ b/src/Symfony/Bridge/Doctrine/Tests/PropertyInfo/DoctrineExtractorTest.php @@ -59,6 +59,7 @@ public function testGetProperties() 'foo', 'bar', 'indexedBar', + 'indexedFoo', ), $this->extractor->getProperties('Symfony\Bridge\Doctrine\Tests\PropertyInfo\Fixtures\DoctrineDummy') ); @@ -136,6 +137,14 @@ public function typesProvider() new Type(Type::BUILTIN_TYPE_STRING), new Type(Type::BUILTIN_TYPE_OBJECT, false, 'Symfony\Bridge\Doctrine\Tests\PropertyInfo\Fixtures\DoctrineRelation') ))), + array('indexedFoo', array(new Type( + Type::BUILTIN_TYPE_OBJECT, + false, + 'Doctrine\Common\Collections\Collection', + true, + new Type(Type::BUILTIN_TYPE_STRING), + new Type(Type::BUILTIN_TYPE_OBJECT, false, 'Symfony\Bridge\Doctrine\Tests\PropertyInfo\Fixtures\DoctrineRelation') + ))), array('simpleArray', array(new Type(Type::BUILTIN_TYPE_ARRAY, false, null, true, new Type(Type::BUILTIN_TYPE_INT), new Type(Type::BUILTIN_TYPE_STRING)))), array('customFoo', null), array('notMapped', null), diff --git a/src/Symfony/Bridge/Doctrine/Tests/PropertyInfo/Fixtures/DoctrineDummy.php b/src/Symfony/Bridge/Doctrine/Tests/PropertyInfo/Fixtures/DoctrineDummy.php index 580e75803db8..60fce8954cec 100644 --- a/src/Symfony/Bridge/Doctrine/Tests/PropertyInfo/Fixtures/DoctrineDummy.php +++ b/src/Symfony/Bridge/Doctrine/Tests/PropertyInfo/Fixtures/DoctrineDummy.php @@ -14,6 +14,7 @@ use Doctrine\ORM\Mapping\Column; use Doctrine\ORM\Mapping\Entity; use Doctrine\ORM\Mapping\Id; +use Doctrine\ORM\Mapping\OneToMany; use Doctrine\ORM\Mapping\ManyToMany; use Doctrine\ORM\Mapping\ManyToOne; @@ -45,6 +46,11 @@ class DoctrineDummy */ protected $indexedBar; + /** + * @OneToMany(targetEntity="DoctrineRelation", mappedBy="foo", indexBy="foo") + */ + protected $indexedFoo; + /** * @Column(type="guid") */ diff --git a/src/Symfony/Bridge/Doctrine/Tests/PropertyInfo/Fixtures/DoctrineRelation.php b/src/Symfony/Bridge/Doctrine/Tests/PropertyInfo/Fixtures/DoctrineRelation.php index 6e94e028faa7..85660d3d6b66 100644 --- a/src/Symfony/Bridge/Doctrine/Tests/PropertyInfo/Fixtures/DoctrineRelation.php +++ b/src/Symfony/Bridge/Doctrine/Tests/PropertyInfo/Fixtures/DoctrineRelation.php @@ -14,6 +14,7 @@ use Doctrine\ORM\Mapping\Column; use Doctrine\ORM\Mapping\Entity; use Doctrine\ORM\Mapping\Id; +use Doctrine\ORM\Mapping\ManyToOne; /** * @Entity @@ -32,4 +33,10 @@ class DoctrineRelation * @Column(type="guid") */ protected $rguid; + + /** + * @Column(type="guid") + * @ManyToOne(targetEntity="DoctrineDummy", inversedBy="indexedFoo") + */ + protected $foo; } From 939a42f623062232b8c59ff2fcfe72f657fc0d80 Mon Sep 17 00:00:00 2001 From: Nicolas Grekas Date: Fri, 20 Apr 2018 11:55:01 +0200 Subject: [PATCH 38/75] Fix tests --- .../Form/Tests/Fixtures/Descriptor/resolved_form_type_1.json | 4 ++-- .../Form/Tests/Fixtures/Descriptor/resolved_form_type_1.txt | 3 +-- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/src/Symfony/Component/Form/Tests/Fixtures/Descriptor/resolved_form_type_1.json b/src/Symfony/Component/Form/Tests/Fixtures/Descriptor/resolved_form_type_1.json index b0c083b5b71d..6aba3b60ecb1 100644 --- a/src/Symfony/Component/Form/Tests/Fixtures/Descriptor/resolved_form_type_1.json +++ b/src/Symfony/Component/Form/Tests/Fixtures/Descriptor/resolved_form_type_1.json @@ -22,7 +22,8 @@ "compound", "data_class", "empty_data", - "error_bubbling" + "error_bubbling", + "trim" ] }, "parent": { @@ -44,7 +45,6 @@ "property_path", "required", "translation_domain", - "trim", "upload_max_size_message" ] }, diff --git a/src/Symfony/Component/Form/Tests/Fixtures/Descriptor/resolved_form_type_1.txt b/src/Symfony/Component/Form/Tests/Fixtures/Descriptor/resolved_form_type_1.txt index 2b34ad960d67..874dede77f7f 100644 --- a/src/Symfony/Component/Form/Tests/Fixtures/Descriptor/resolved_form_type_1.txt +++ b/src/Symfony/Component/Form/Tests/Fixtures/Descriptor/resolved_form_type_1.txt @@ -11,7 +11,7 @@ Symfony\Component\Form\Extension\Core\Type\ChoiceType (Block prefix: "choice") choice_name data_class attr csrf_message choice_translation_domain empty_data auto_initialize csrf_protection choice_value error_bubbling block_name csrf_token_id - choices by_reference csrf_token_manager + choices trim by_reference csrf_token_manager choices_as_values data expanded disabled group_by inherit_data @@ -24,7 +24,6 @@ Symfony\Component\Form\Extension\Core\Type\ChoiceType (Block prefix: "choice") property_path required translation_domain - trim upload_max_size_message --------------------------- -------------------- ------------------------- ----------------------- From 73fec237daf1ac550a76a41fb43bf7628d236299 Mon Sep 17 00:00:00 2001 From: cvilleger Date: Thu, 5 Apr 2018 14:19:22 +0200 Subject: [PATCH 39/75] [HttpFoundation] Add functional tests for Response::sendHeaders() --- .../Component/HttpFoundation/Cookie.php | 8 ++- .../HttpFoundation/Tests/CookieTest.php | 8 +-- .../Fixtures/response-functional/common.inc | 39 +++++++++++++ .../cookie_max_age.expected | 11 ++++ .../response-functional/cookie_max_age.php | 10 ++++ .../cookie_raw_urlencode.expected | 10 ++++ .../cookie_raw_urlencode.php | 12 ++++ .../cookie_samesite_lax.expected | 9 +++ .../cookie_samesite_lax.php | 8 +++ .../cookie_samesite_strict.expected | 9 +++ .../cookie_samesite_strict.php | 8 +++ .../cookie_urlencode.expected | 10 ++++ .../response-functional/cookie_urlencode.php | 12 ++++ .../invalid_cookie_name.expected | 6 ++ .../invalid_cookie_name.php | 11 ++++ .../Tests/ResponseFunctionalTest.php | 58 +++++++++++++++++++ .../Tests/ResponseHeaderBagTest.php | 4 +- .../Component/HttpKernel/Tests/ClientTest.php | 17 ++---- 18 files changed, 230 insertions(+), 20 deletions(-) create mode 100644 src/Symfony/Component/HttpFoundation/Tests/Fixtures/response-functional/common.inc create mode 100644 src/Symfony/Component/HttpFoundation/Tests/Fixtures/response-functional/cookie_max_age.expected create mode 100644 src/Symfony/Component/HttpFoundation/Tests/Fixtures/response-functional/cookie_max_age.php create mode 100644 src/Symfony/Component/HttpFoundation/Tests/Fixtures/response-functional/cookie_raw_urlencode.expected create mode 100644 src/Symfony/Component/HttpFoundation/Tests/Fixtures/response-functional/cookie_raw_urlencode.php create mode 100644 src/Symfony/Component/HttpFoundation/Tests/Fixtures/response-functional/cookie_samesite_lax.expected create mode 100644 src/Symfony/Component/HttpFoundation/Tests/Fixtures/response-functional/cookie_samesite_lax.php create mode 100644 src/Symfony/Component/HttpFoundation/Tests/Fixtures/response-functional/cookie_samesite_strict.expected create mode 100644 src/Symfony/Component/HttpFoundation/Tests/Fixtures/response-functional/cookie_samesite_strict.php create mode 100644 src/Symfony/Component/HttpFoundation/Tests/Fixtures/response-functional/cookie_urlencode.expected create mode 100644 src/Symfony/Component/HttpFoundation/Tests/Fixtures/response-functional/cookie_urlencode.php create mode 100644 src/Symfony/Component/HttpFoundation/Tests/Fixtures/response-functional/invalid_cookie_name.expected create mode 100644 src/Symfony/Component/HttpFoundation/Tests/Fixtures/response-functional/invalid_cookie_name.php create mode 100644 src/Symfony/Component/HttpFoundation/Tests/ResponseFunctionalTest.php diff --git a/src/Symfony/Component/HttpFoundation/Cookie.php b/src/Symfony/Component/HttpFoundation/Cookie.php index 4519a6adaeda..d202dc6c1efb 100644 --- a/src/Symfony/Component/HttpFoundation/Cookie.php +++ b/src/Symfony/Component/HttpFoundation/Cookie.php @@ -145,12 +145,12 @@ public function __toString() $str = ($this->isRaw() ? $this->getName() : urlencode($this->getName())).'='; if ('' === (string) $this->getValue()) { - $str .= 'deleted; expires='.gmdate('D, d-M-Y H:i:s T', time() - 31536001).'; max-age=-31536001'; + $str .= 'deleted; expires='.gmdate('D, d-M-Y H:i:s T', time() - 31536001).'; Max-Age=0'; } else { $str .= $this->isRaw() ? $this->getValue() : rawurlencode($this->getValue()); if (0 !== $this->getExpiresTime()) { - $str .= '; expires='.gmdate('D, d-M-Y H:i:s T', $this->getExpiresTime()).'; max-age='.$this->getMaxAge(); + $str .= '; expires='.gmdate('D, d-M-Y H:i:s T', $this->getExpiresTime()).'; Max-Age='.$this->getMaxAge(); } } @@ -224,7 +224,9 @@ public function getExpiresTime() */ public function getMaxAge() { - return 0 !== $this->expire ? $this->expire - time() : 0; + $maxAge = $this->expire - time(); + + return 0 >= $maxAge ? 0 : $maxAge; } /** diff --git a/src/Symfony/Component/HttpFoundation/Tests/CookieTest.php b/src/Symfony/Component/HttpFoundation/Tests/CookieTest.php index 070b7dd4290e..a47b71e1d425 100644 --- a/src/Symfony/Component/HttpFoundation/Tests/CookieTest.php +++ b/src/Symfony/Component/HttpFoundation/Tests/CookieTest.php @@ -162,13 +162,13 @@ public function testCookieIsCleared() public function testToString() { $cookie = new Cookie('foo', 'bar', $expire = strtotime('Fri, 20-May-2011 15:25:52 GMT'), '/', '.myfoodomain.com', true); - $this->assertEquals('foo=bar; expires=Fri, 20-May-2011 15:25:52 GMT; max-age='.($expire - time()).'; path=/; domain=.myfoodomain.com; secure; httponly', (string) $cookie, '->__toString() returns string representation of the cookie'); + $this->assertEquals('foo=bar; expires=Fri, 20-May-2011 15:25:52 GMT; Max-Age=0; path=/; domain=.myfoodomain.com; secure; httponly', (string) $cookie, '->__toString() returns string representation of the cookie'); $cookie = new Cookie('foo', 'bar with white spaces', strtotime('Fri, 20-May-2011 15:25:52 GMT'), '/', '.myfoodomain.com', true); - $this->assertEquals('foo=bar%20with%20white%20spaces; expires=Fri, 20-May-2011 15:25:52 GMT; max-age='.($expire - time()).'; path=/; domain=.myfoodomain.com; secure; httponly', (string) $cookie, '->__toString() encodes the value of the cookie according to RFC 3986 (white space = %20)'); + $this->assertEquals('foo=bar%20with%20white%20spaces; expires=Fri, 20-May-2011 15:25:52 GMT; Max-Age=0; path=/; domain=.myfoodomain.com; secure; httponly', (string) $cookie, '->__toString() encodes the value of the cookie according to RFC 3986 (white space = %20)'); $cookie = new Cookie('foo', null, 1, '/admin/', '.myfoodomain.com'); - $this->assertEquals('foo=deleted; expires='.gmdate('D, d-M-Y H:i:s T', $expire = time() - 31536001).'; max-age='.($expire - time()).'; path=/admin/; domain=.myfoodomain.com; httponly', (string) $cookie, '->__toString() returns string representation of a cleared cookie if value is NULL'); + $this->assertEquals('foo=deleted; expires='.gmdate('D, d-M-Y H:i:s T', $expire = time() - 31536001).'; Max-Age=0; path=/admin/; domain=.myfoodomain.com; httponly', (string) $cookie, '->__toString() returns string representation of a cleared cookie if value is NULL'); $cookie = new Cookie('foo', 'bar', 0, '/', ''); $this->assertEquals('foo=bar; path=/; httponly', (string) $cookie); @@ -194,7 +194,7 @@ public function testGetMaxAge() $this->assertEquals($expire - time(), $cookie->getMaxAge()); $cookie = new Cookie('foo', 'bar', $expire = time() - 100); - $this->assertEquals($expire - time(), $cookie->getMaxAge()); + $this->assertEquals(0, $cookie->getMaxAge()); } public function testFromString() diff --git a/src/Symfony/Component/HttpFoundation/Tests/Fixtures/response-functional/common.inc b/src/Symfony/Component/HttpFoundation/Tests/Fixtures/response-functional/common.inc new file mode 100644 index 000000000000..ba101d357852 --- /dev/null +++ b/src/Symfony/Component/HttpFoundation/Tests/Fixtures/response-functional/common.inc @@ -0,0 +1,39 @@ +headers->set('Date', 'Sat, 12 Nov 1955 20:04:00 GMT'); + +return $r; diff --git a/src/Symfony/Component/HttpFoundation/Tests/Fixtures/response-functional/cookie_max_age.expected b/src/Symfony/Component/HttpFoundation/Tests/Fixtures/response-functional/cookie_max_age.expected new file mode 100644 index 000000000000..bdb9d023f8f3 --- /dev/null +++ b/src/Symfony/Component/HttpFoundation/Tests/Fixtures/response-functional/cookie_max_age.expected @@ -0,0 +1,11 @@ + +Warning: Expiry date cannot have a year greater than 9999 in %scookie_max_age.php on line 10 + +Array +( + [0] => Content-Type: text/plain; charset=utf-8 + [1] => Cache-Control: no-cache, private + [2] => Date: Sat, 12 Nov 1955 20:04:00 GMT + [3] => Set-Cookie: foo=bar; expires=Sat, 01-Jan-10000 02:46:40 GMT; Max-Age=%d; path=/ +) +shutdown diff --git a/src/Symfony/Component/HttpFoundation/Tests/Fixtures/response-functional/cookie_max_age.php b/src/Symfony/Component/HttpFoundation/Tests/Fixtures/response-functional/cookie_max_age.php new file mode 100644 index 000000000000..8775a5cceeb8 --- /dev/null +++ b/src/Symfony/Component/HttpFoundation/Tests/Fixtures/response-functional/cookie_max_age.php @@ -0,0 +1,10 @@ +headers->setCookie(new Cookie('foo', 'bar', 253402310800, '', null, false, false)); +$r->sendHeaders(); + +setcookie('foo2', 'bar', 253402310800, '/'); diff --git a/src/Symfony/Component/HttpFoundation/Tests/Fixtures/response-functional/cookie_raw_urlencode.expected b/src/Symfony/Component/HttpFoundation/Tests/Fixtures/response-functional/cookie_raw_urlencode.expected new file mode 100644 index 000000000000..0c097972e78e --- /dev/null +++ b/src/Symfony/Component/HttpFoundation/Tests/Fixtures/response-functional/cookie_raw_urlencode.expected @@ -0,0 +1,10 @@ + +Array +( + [0] => Content-Type: text/plain; charset=utf-8 + [1] => Cache-Control: no-cache, private + [2] => Date: Sat, 12 Nov 1955 20:04:00 GMT + [3] => Set-Cookie: ?*():@&+$/%#[]=?*():@&+$/%#[]; path=/ + [4] => Set-Cookie: ?*():@&+$/%#[]=?*():@&+$/%#[]; path=/ +) +shutdown diff --git a/src/Symfony/Component/HttpFoundation/Tests/Fixtures/response-functional/cookie_raw_urlencode.php b/src/Symfony/Component/HttpFoundation/Tests/Fixtures/response-functional/cookie_raw_urlencode.php new file mode 100644 index 000000000000..2ca5b59f1a3e --- /dev/null +++ b/src/Symfony/Component/HttpFoundation/Tests/Fixtures/response-functional/cookie_raw_urlencode.php @@ -0,0 +1,12 @@ +headers->setCookie(new Cookie($str, $str, 0, '/', null, false, false, true)); +$r->sendHeaders(); + +setrawcookie($str, $str, 0, '/', null, false, false); diff --git a/src/Symfony/Component/HttpFoundation/Tests/Fixtures/response-functional/cookie_samesite_lax.expected b/src/Symfony/Component/HttpFoundation/Tests/Fixtures/response-functional/cookie_samesite_lax.expected new file mode 100644 index 000000000000..cbde2cbfe13f --- /dev/null +++ b/src/Symfony/Component/HttpFoundation/Tests/Fixtures/response-functional/cookie_samesite_lax.expected @@ -0,0 +1,9 @@ + +Array +( + [0] => Content-Type: text/plain; charset=utf-8 + [1] => Cache-Control: no-cache, private + [2] => Date: Sat, 12 Nov 1955 20:04:00 GMT + [3] => Set-Cookie: CookieSamesiteLaxTest=LaxValue; path=/; httponly; samesite=lax +) +shutdown diff --git a/src/Symfony/Component/HttpFoundation/Tests/Fixtures/response-functional/cookie_samesite_lax.php b/src/Symfony/Component/HttpFoundation/Tests/Fixtures/response-functional/cookie_samesite_lax.php new file mode 100644 index 000000000000..9a476f1d23fa --- /dev/null +++ b/src/Symfony/Component/HttpFoundation/Tests/Fixtures/response-functional/cookie_samesite_lax.php @@ -0,0 +1,8 @@ +headers->setCookie(new Cookie('CookieSamesiteLaxTest', 'LaxValue', 0, '/', null, false, true, false, Cookie::SAMESITE_LAX)); +$r->sendHeaders(); diff --git a/src/Symfony/Component/HttpFoundation/Tests/Fixtures/response-functional/cookie_samesite_strict.expected b/src/Symfony/Component/HttpFoundation/Tests/Fixtures/response-functional/cookie_samesite_strict.expected new file mode 100644 index 000000000000..adc491fd2bc5 --- /dev/null +++ b/src/Symfony/Component/HttpFoundation/Tests/Fixtures/response-functional/cookie_samesite_strict.expected @@ -0,0 +1,9 @@ + +Array +( + [0] => Content-Type: text/plain; charset=utf-8 + [1] => Cache-Control: no-cache, private + [2] => Date: Sat, 12 Nov 1955 20:04:00 GMT + [3] => Set-Cookie: CookieSamesiteStrictTest=StrictValue; path=/; httponly; samesite=strict +) +shutdown diff --git a/src/Symfony/Component/HttpFoundation/Tests/Fixtures/response-functional/cookie_samesite_strict.php b/src/Symfony/Component/HttpFoundation/Tests/Fixtures/response-functional/cookie_samesite_strict.php new file mode 100644 index 000000000000..3bcb41f8f059 --- /dev/null +++ b/src/Symfony/Component/HttpFoundation/Tests/Fixtures/response-functional/cookie_samesite_strict.php @@ -0,0 +1,8 @@ +headers->setCookie(new Cookie('CookieSamesiteStrictTest', 'StrictValue', 0, '/', null, false, true, false, Cookie::SAMESITE_STRICT)); +$r->sendHeaders(); diff --git a/src/Symfony/Component/HttpFoundation/Tests/Fixtures/response-functional/cookie_urlencode.expected b/src/Symfony/Component/HttpFoundation/Tests/Fixtures/response-functional/cookie_urlencode.expected new file mode 100644 index 000000000000..4e9c4c075f5e --- /dev/null +++ b/src/Symfony/Component/HttpFoundation/Tests/Fixtures/response-functional/cookie_urlencode.expected @@ -0,0 +1,10 @@ + +Array +( + [0] => Content-Type: text/plain; charset=utf-8 + [1] => Cache-Control: no-cache, private + [2] => Date: Sat, 12 Nov 1955 20:04:00 GMT + [3] => Set-Cookie: %3F%2A%28%29%3A%40%26%2B%24%2F%25%23%5B%5D=%3F%2A%28%29%3A%40%26%2B%24%2F%25%23%5B%5D; path=/ + [4] => Set-Cookie: ?*():@&+$/%#[]=%3F%2A%28%29%3A%40%26%2B%24%2F%25%23%5B%5D; path=/ +) +shutdown diff --git a/src/Symfony/Component/HttpFoundation/Tests/Fixtures/response-functional/cookie_urlencode.php b/src/Symfony/Component/HttpFoundation/Tests/Fixtures/response-functional/cookie_urlencode.php new file mode 100644 index 000000000000..05b9af30d58f --- /dev/null +++ b/src/Symfony/Component/HttpFoundation/Tests/Fixtures/response-functional/cookie_urlencode.php @@ -0,0 +1,12 @@ +headers->setCookie(new Cookie($str, $str, 0, '', null, false, false)); +$r->sendHeaders(); + +setcookie($str, $str, 0, '/'); diff --git a/src/Symfony/Component/HttpFoundation/Tests/Fixtures/response-functional/invalid_cookie_name.expected b/src/Symfony/Component/HttpFoundation/Tests/Fixtures/response-functional/invalid_cookie_name.expected new file mode 100644 index 000000000000..2b560f0bd568 --- /dev/null +++ b/src/Symfony/Component/HttpFoundation/Tests/Fixtures/response-functional/invalid_cookie_name.expected @@ -0,0 +1,6 @@ +The cookie name "Hello + world" contains invalid characters. +Array +( + [0] => Content-Type: text/plain; charset=utf-8 +) +shutdown diff --git a/src/Symfony/Component/HttpFoundation/Tests/Fixtures/response-functional/invalid_cookie_name.php b/src/Symfony/Component/HttpFoundation/Tests/Fixtures/response-functional/invalid_cookie_name.php new file mode 100644 index 000000000000..3fe157184562 --- /dev/null +++ b/src/Symfony/Component/HttpFoundation/Tests/Fixtures/response-functional/invalid_cookie_name.php @@ -0,0 +1,11 @@ +headers->setCookie(new Cookie('Hello + world', 'hodor')); +} catch (\InvalidArgumentException $e) { + echo $e->getMessage(); +} diff --git a/src/Symfony/Component/HttpFoundation/Tests/ResponseFunctionalTest.php b/src/Symfony/Component/HttpFoundation/Tests/ResponseFunctionalTest.php new file mode 100644 index 000000000000..22f25e978e5a --- /dev/null +++ b/src/Symfony/Component/HttpFoundation/Tests/ResponseFunctionalTest.php @@ -0,0 +1,58 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\HttpFoundation\Tests; + +use PHPUnit\Framework\TestCase; + +/** + * @requires PHP 7.0 + */ +class ResponseFunctionalTest extends TestCase +{ + private static $server; + + public static function setUpBeforeClass() + { + $spec = array( + 1 => array('file', '/dev/null', 'w'), + 2 => array('file', '/dev/null', 'w'), + ); + if (!self::$server = @proc_open('exec php -S localhost:8054', $spec, $pipes, __DIR__.'/Fixtures/response-functional')) { + self::markTestSkipped('PHP server unable to start.'); + } + sleep(1); + } + + public static function tearDownAfterClass() + { + if (self::$server) { + proc_terminate(self::$server); + proc_close(self::$server); + } + } + + /** + * @dataProvider provideCookie + */ + public function testCookie($fixture) + { + $result = file_get_contents(sprintf('http://localhost:8054/%s.php', $fixture)); + $this->assertStringMatchesFormatFile(__DIR__.sprintf('/Fixtures/response-functional/%s.expected', $fixture), $result); + } + + public function provideCookie() + { + foreach (glob(__DIR__.'/Fixtures/response-functional/*.php') as $file) { + yield array(pathinfo($file, PATHINFO_FILENAME)); + } + } +} diff --git a/src/Symfony/Component/HttpFoundation/Tests/ResponseHeaderBagTest.php b/src/Symfony/Component/HttpFoundation/Tests/ResponseHeaderBagTest.php index ce8553590dcd..7b5e720afdb6 100644 --- a/src/Symfony/Component/HttpFoundation/Tests/ResponseHeaderBagTest.php +++ b/src/Symfony/Component/HttpFoundation/Tests/ResponseHeaderBagTest.php @@ -116,7 +116,7 @@ public function testToStringIncludesCookieHeaders() $bag->clearCookie('foo'); - $this->assertSetCookieHeader('foo=deleted; expires='.gmdate('D, d-M-Y H:i:s T', time() - 31536001).'; max-age=-31536001; path=/; httponly', $bag); + $this->assertSetCookieHeader('foo=deleted; expires='.gmdate('D, d-M-Y H:i:s T', time() - 31536001).'; Max-Age=0; path=/; httponly', $bag); } public function testClearCookieSecureNotHttpOnly() @@ -125,7 +125,7 @@ public function testClearCookieSecureNotHttpOnly() $bag->clearCookie('foo', '/', null, true, false); - $this->assertSetCookieHeader('foo=deleted; expires='.gmdate('D, d-M-Y H:i:s T', time() - 31536001).'; max-age=-31536001; path=/; secure', $bag); + $this->assertSetCookieHeader('foo=deleted; expires='.gmdate('D, d-M-Y H:i:s T', time() - 31536001).'; Max-Age=0; path=/; secure', $bag); } public function testReplace() diff --git a/src/Symfony/Component/HttpKernel/Tests/ClientTest.php b/src/Symfony/Component/HttpKernel/Tests/ClientTest.php index 051d5d47c026..b774d8ec7ae1 100644 --- a/src/Symfony/Component/HttpKernel/Tests/ClientTest.php +++ b/src/Symfony/Component/HttpKernel/Tests/ClientTest.php @@ -60,22 +60,17 @@ public function testFilterResponseConvertsCookies() $m = $r->getMethod('filterResponse'); $m->setAccessible(true); - $expected = array( - 'foo=bar; expires=Sun, 15-Feb-2009 20:00:00 GMT; max-age='.(strtotime('Sun, 15-Feb-2009 20:00:00 GMT') - time()).'; path=/foo; domain=http://example.com; secure; httponly', - 'foo1=bar1; expires=Sun, 15-Feb-2009 20:00:00 GMT; max-age='.(strtotime('Sun, 15-Feb-2009 20:00:00 GMT') - time()).'; path=/foo; domain=http://example.com; secure; httponly', - ); - $response = new Response(); - $response->headers->setCookie(new Cookie('foo', 'bar', \DateTime::createFromFormat('j-M-Y H:i:s T', '15-Feb-2009 20:00:00 GMT')->format('U'), '/foo', 'http://example.com', true, true)); + $response->headers->setCookie($cookie1 = new Cookie('foo', 'bar', \DateTime::createFromFormat('j-M-Y H:i:s T', '15-Feb-2009 20:00:00 GMT')->format('U'), '/foo', 'http://example.com', true, true)); $domResponse = $m->invoke($client, $response); - $this->assertEquals($expected[0], $domResponse->getHeader('Set-Cookie')); + $this->assertSame((string) $cookie1, $domResponse->getHeader('Set-Cookie')); $response = new Response(); - $response->headers->setCookie(new Cookie('foo', 'bar', \DateTime::createFromFormat('j-M-Y H:i:s T', '15-Feb-2009 20:00:00 GMT')->format('U'), '/foo', 'http://example.com', true, true)); - $response->headers->setCookie(new Cookie('foo1', 'bar1', \DateTime::createFromFormat('j-M-Y H:i:s T', '15-Feb-2009 20:00:00 GMT')->format('U'), '/foo', 'http://example.com', true, true)); + $response->headers->setCookie($cookie1 = new Cookie('foo', 'bar', \DateTime::createFromFormat('j-M-Y H:i:s T', '15-Feb-2009 20:00:00 GMT')->format('U'), '/foo', 'http://example.com', true, true)); + $response->headers->setCookie($cookie2 = new Cookie('foo1', 'bar1', \DateTime::createFromFormat('j-M-Y H:i:s T', '15-Feb-2009 20:00:00 GMT')->format('U'), '/foo', 'http://example.com', true, true)); $domResponse = $m->invoke($client, $response); - $this->assertEquals($expected[0], $domResponse->getHeader('Set-Cookie')); - $this->assertEquals($expected, $domResponse->getHeader('Set-Cookie', false)); + $this->assertSame((string) $cookie1, $domResponse->getHeader('Set-Cookie')); + $this->assertSame(array((string) $cookie1, (string) $cookie2), $domResponse->getHeader('Set-Cookie', false)); } public function testFilterResponseSupportsStreamedResponses() From b2ac6b6fbfdcd6894538786b44bccd37afa7eed2 Mon Sep 17 00:00:00 2001 From: Philipp Cordes Date: Sat, 21 Apr 2018 15:09:06 +0200 Subject: [PATCH 40/75] [VarDumper] Fix dumping of SplObjectStorage --- .../Component/VarDumper/Caster/SplCaster.php | 5 +++-- .../VarDumper/Tests/Caster/SplCasterTest.php | 19 +++++++++++++++++++ 2 files changed, 22 insertions(+), 2 deletions(-) diff --git a/src/Symfony/Component/VarDumper/Caster/SplCaster.php b/src/Symfony/Component/VarDumper/Caster/SplCaster.php index 835837266128..f3fcf9748fb1 100644 --- a/src/Symfony/Component/VarDumper/Caster/SplCaster.php +++ b/src/Symfony/Component/VarDumper/Caster/SplCaster.php @@ -86,10 +86,11 @@ public static function castObjectStorage(\SplObjectStorage $c, array $a, Stub $s $storage = array(); unset($a[Caster::PREFIX_DYNAMIC."\0gcdata"]); // Don't hit https://bugs.php.net/65967 - foreach (clone $c as $obj) { + $clone = clone $c; + foreach ($clone as $obj) { $storage[spl_object_hash($obj)] = array( 'object' => $obj, - 'info' => $c->getInfo(), + 'info' => $clone->getInfo(), ); } diff --git a/src/Symfony/Component/VarDumper/Tests/Caster/SplCasterTest.php b/src/Symfony/Component/VarDumper/Tests/Caster/SplCasterTest.php index 96e0307385fb..ece69424943a 100644 --- a/src/Symfony/Component/VarDumper/Tests/Caster/SplCasterTest.php +++ b/src/Symfony/Component/VarDumper/Tests/Caster/SplCasterTest.php @@ -40,4 +40,23 @@ public function provideCastSplDoublyLinkedList() array(\SplDoublyLinkedList::IT_MODE_LIFO | \SplDoublyLinkedList::IT_MODE_DELETE, 'IT_MODE_LIFO | IT_MODE_DELETE'), ); } + + public function testCastObjectStorageIsntModified() + { + $var = new \SplObjectStorage(); + $var->attach(new \stdClass()); + $var->rewind(); + $current = $var->current(); + + $this->assertDumpMatchesFormat('%A', $var); + $this->assertSame($current, $var->current()); + } + + public function testCastObjectStorageDumpsInfo() + { + $var = new \SplObjectStorage(); + $var->attach(new \stdClass(), new \DateTime()); + + $this->assertDumpMatchesFormat('%ADateTime%A', $var); + } } From b0c92254a0ac4ca214f63c8f21080e50228000d3 Mon Sep 17 00:00:00 2001 From: johnstevenson Date: Thu, 12 Apr 2018 21:07:25 +0100 Subject: [PATCH 41/75] Use new PHP7.2 functions in hasColorSupport --- .../PhpUnit/DeprecationErrorHandler.php | 31 +++++-- .../Component/Console/Output/StreamOutput.php | 33 +++---- .../Component/VarDumper/Dumper/CliDumper.php | 88 +++++++++++++++---- 3 files changed, 114 insertions(+), 38 deletions(-) diff --git a/src/Symfony/Bridge/PhpUnit/DeprecationErrorHandler.php b/src/Symfony/Bridge/PhpUnit/DeprecationErrorHandler.php index b0f241c86249..2b5c734c54c0 100644 --- a/src/Symfony/Bridge/PhpUnit/DeprecationErrorHandler.php +++ b/src/Symfony/Bridge/PhpUnit/DeprecationErrorHandler.php @@ -178,17 +178,38 @@ public static function register($mode = false) } } + /** + * Returns true if STDOUT is defined and supports colorization. + * + * Reference: Composer\XdebugHandler\Process::supportsColor + * https://github.com/composer/xdebug-handler + * + * @return bool + */ private static function hasColorSupport() { - if ('\\' === DIRECTORY_SEPARATOR) { - return - defined('STDOUT') && function_exists('sapi_windows_vt100_support') && sapi_windows_vt100_support(STDOUT) - || '10.0.10586' === PHP_WINDOWS_VERSION_MAJOR.'.'.PHP_WINDOWS_VERSION_MINOR.'.'.PHP_WINDOWS_VERSION_BUILD + if (!defined('STDOUT')) { + return false; + } + + if (DIRECTORY_SEPARATOR === '\\') { + return (function_exists('sapi_windows_vt100_support') + && sapi_windows_vt100_support(STDOUT)) || false !== getenv('ANSICON') || 'ON' === getenv('ConEmuANSI') || 'xterm' === getenv('TERM'); } - return defined('STDOUT') && function_exists('posix_isatty') && @posix_isatty(STDOUT); + if (function_exists('stream_isatty')) { + return stream_isatty(STDOUT); + } + + if (function_exists('posix_isatty')) { + return posix_isatty(STDOUT); + } + + $stat = fstat(STDOUT); + // Check if formatted mode is S_IFCHR + return $stat ? 0020000 === ($stat['mode'] & 0170000) : false; } } diff --git a/src/Symfony/Component/Console/Output/StreamOutput.php b/src/Symfony/Component/Console/Output/StreamOutput.php index 182622a29a5c..b0897b206f70 100644 --- a/src/Symfony/Component/Console/Output/StreamOutput.php +++ b/src/Symfony/Component/Console/Output/StreamOutput.php @@ -81,31 +81,34 @@ protected function doWrite($message, $newline) * * Colorization is disabled if not supported by the stream: * - * - the stream is redirected (eg php file.php >log) - * - Windows without VT100 support, Ansicon, ConEmu, Mintty - * - non tty consoles + * This is tricky on Windows, because Cygwin, Msys2 etc emulate pseudo + * terminals via named pipes, so we can only check the environment. + * + * Reference: Composer\XdebugHandler\Process::supportsColor + * https://github.com/composer/xdebug-handler * * @return bool true if the stream supports colorization, false otherwise */ protected function hasColorSupport() { - if (function_exists('stream_isatty') && !@stream_isatty($this->stream)) { - return false; - } if (DIRECTORY_SEPARATOR === '\\') { - if (function_exists('sapi_windows_vt100_support')) { - $vt100Enabled = @sapi_windows_vt100_support($this->stream); - } else { - $vt100Enabled = '10.0.10586' === PHP_WINDOWS_VERSION_MAJOR.'.'.PHP_WINDOWS_VERSION_MINOR.'.'.PHP_WINDOWS_VERSION_BUILD; - } - - return - $vt100Enabled + return (function_exists('sapi_windows_vt100_support') + && @sapi_windows_vt100_support($this->stream)) || false !== getenv('ANSICON') || 'ON' === getenv('ConEmuANSI') || 'xterm' === getenv('TERM'); } - return function_exists('posix_isatty') && @posix_isatty($this->stream); + if (function_exists('stream_isatty')) { + return @stream_isatty($this->stream); + } + + if (function_exists('posix_isatty')) { + return @posix_isatty($this->stream); + } + + $stat = @fstat($this->stream); + // Check if formatted mode is S_IFCHR + return $stat ? 0020000 === ($stat['mode'] & 0170000) : false; } } diff --git a/src/Symfony/Component/VarDumper/Dumper/CliDumper.php b/src/Symfony/Component/VarDumper/Dumper/CliDumper.php index 689ada77c246..8f3f7c7e9901 100644 --- a/src/Symfony/Component/VarDumper/Dumper/CliDumper.php +++ b/src/Symfony/Component/VarDumper/Dumper/CliDumper.php @@ -58,7 +58,7 @@ public function __construct($output = null, $charset = null) { parent::__construct($output, $charset); - if ('\\' === DIRECTORY_SEPARATOR && 'ON' !== @getenv('ConEmuANSI') && 'xterm' !== @getenv('TERM')) { + if ('\\' === DIRECTORY_SEPARATOR && !$this->isWindowsTrueColor()) { // Use only the base 16 xterm colors when using ANSICON or standard Windows 10 CLI $this->setStyles(array( 'default' => '31', @@ -420,7 +420,7 @@ protected function style($style, $value, $attr = array()) protected function supportsColors() { if ($this->outputStream !== static::$defaultOutput) { - return @(is_resource($this->outputStream) && function_exists('posix_isatty') && posix_isatty($this->outputStream)); + return $this->hasColorSupport($this->outputStream); } if (null !== static::$defaultColors) { return static::$defaultColors; @@ -448,23 +448,10 @@ protected function supportsColors() } } - if ('\\' === DIRECTORY_SEPARATOR) { - static::$defaultColors = @( - function_exists('sapi_windows_vt100_support') && sapi_windows_vt100_support($this->outputStream) - || '10.0.10586' === PHP_WINDOWS_VERSION_MAJOR.'.'.PHP_WINDOWS_VERSION_MINOR.'.'.PHP_WINDOWS_VERSION_BUILD - || false !== getenv('ANSICON') - || 'ON' === getenv('ConEmuANSI') - || 'xterm' === getenv('TERM') - ); - } elseif (function_exists('posix_isatty')) { - $h = stream_get_meta_data($this->outputStream) + array('wrapper_type' => null); - $h = 'Output' === $h['stream_type'] && 'PHP' === $h['wrapper_type'] ? fopen('php://stdout', 'wb') : $this->outputStream; - static::$defaultColors = @posix_isatty($h); - } else { - static::$defaultColors = false; - } + $h = stream_get_meta_data($this->outputStream) + array('wrapper_type' => null); + $h = 'Output' === $h['stream_type'] && 'PHP' === $h['wrapper_type'] ? fopen('php://stdout', 'wb') : $this->outputStream; - return static::$defaultColors; + return static::$defaultColors = $this->hasColorSupport($h); } /** @@ -477,4 +464,69 @@ protected function dumpLine($depth, $endOfValue = false) } parent::dumpLine($depth); } + + /** + * Returns true if the stream supports colorization. + * + * Reference: Composer\XdebugHandler\Process::supportsColor + * https://github.com/composer/xdebug-handler + * + * @param mixed $stream A CLI output stream + * + * @return bool + */ + private function hasColorSupport($stream) + { + if (!is_resource($stream) || 'stream' !== get_resource_type($stream)) { + return false; + } + + if (DIRECTORY_SEPARATOR === '\\') { + return (function_exists('sapi_windows_vt100_support') + && @sapi_windows_vt100_support($stream)) + || false !== getenv('ANSICON') + || 'ON' === getenv('ConEmuANSI') + || 'xterm' === getenv('TERM'); + } + + if (function_exists('stream_isatty')) { + return @stream_isatty($stream); + } + + if (function_exists('posix_isatty')) { + return @posix_isatty($stream); + } + + $stat = @fstat($stream); + // Check if formatted mode is S_IFCHR + return $stat ? 0020000 === ($stat['mode'] & 0170000) : false; + } + + /** + * Returns true if the Windows terminal supports true color. + * + * Note that this does not check an output stream, but relies on environment + * variables from known implementations, or a PHP and Windows version that + * supports true color. + * + * @return bool + */ + private function isWindowsTrueColor() + { + $result = strval(getenv('ANSICON_VER')) >= '183' + || 'ON' === getenv('ConEmuANSI') + || 'xterm' === getenv('TERM'); + + if (!$result && PHP_VERSION_ID >= 70200) { + $version = sprintf( + '%s.%s.%s', + PHP_WINDOWS_VERSION_MAJOR, + PHP_WINDOWS_VERSION_MINOR, + PHP_WINDOWS_VERSION_BUILD + ); + $result = $version >= '10.0.15063'; + } + + return $result; + } } From 923417122abcf5eb4b8d0df84cc0730bdf4123b9 Mon Sep 17 00:00:00 2001 From: Fabien Potencier Date: Sun, 22 Apr 2018 07:56:10 +0200 Subject: [PATCH 42/75] fixed CS --- src/Symfony/Component/VarDumper/Dumper/CliDumper.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Symfony/Component/VarDumper/Dumper/CliDumper.php b/src/Symfony/Component/VarDumper/Dumper/CliDumper.php index 8f3f7c7e9901..bc80e9f65b9a 100644 --- a/src/Symfony/Component/VarDumper/Dumper/CliDumper.php +++ b/src/Symfony/Component/VarDumper/Dumper/CliDumper.php @@ -513,7 +513,7 @@ private function hasColorSupport($stream) */ private function isWindowsTrueColor() { - $result = strval(getenv('ANSICON_VER')) >= '183' + $result = 183 <= getenv('ANSICON_VER') || 'ON' === getenv('ConEmuANSI') || 'xterm' === getenv('TERM'); From 6fbcc515664429c54c28c92dc46c9307a7bc552b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gr=C3=A9goire=20Paris?= Date: Sat, 21 Apr 2018 00:19:27 +0200 Subject: [PATCH 43/75] Add type hints This makes classes inheriting from phpunit classes compatible with phpunit 7. Fixes #26931 --- .../Legacy/{Command.php => CommandForV5.php} | 2 +- .../Bridge/PhpUnit/Legacy/CommandForV6.php | 32 ++++++++++++ .../{TestRunner.php => TestRunnerForV5.php} | 2 +- .../Bridge/PhpUnit/Legacy/TestRunnerForV6.php | 49 +++++++++++++++++++ src/Symfony/Bridge/PhpUnit/TextUI/Command.php | 22 +++------ .../Bridge/PhpUnit/TextUI/TestRunner.php | 43 +++------------- 6 files changed, 95 insertions(+), 55 deletions(-) rename src/Symfony/Bridge/PhpUnit/Legacy/{Command.php => CommandForV5.php} (90%) create mode 100644 src/Symfony/Bridge/PhpUnit/Legacy/CommandForV6.php rename src/Symfony/Bridge/PhpUnit/Legacy/{TestRunner.php => TestRunnerForV5.php} (95%) create mode 100644 src/Symfony/Bridge/PhpUnit/Legacy/TestRunnerForV6.php diff --git a/src/Symfony/Bridge/PhpUnit/Legacy/Command.php b/src/Symfony/Bridge/PhpUnit/Legacy/CommandForV5.php similarity index 90% rename from src/Symfony/Bridge/PhpUnit/Legacy/Command.php rename to src/Symfony/Bridge/PhpUnit/Legacy/CommandForV5.php index 0aec8ab67f33..d727881a11d8 100644 --- a/src/Symfony/Bridge/PhpUnit/Legacy/Command.php +++ b/src/Symfony/Bridge/PhpUnit/Legacy/CommandForV5.php @@ -16,7 +16,7 @@ * * @internal */ -class Command extends \PHPUnit_TextUI_Command +class CommandForV5 extends \PHPUnit_TextUI_Command { /** * {@inheritdoc} diff --git a/src/Symfony/Bridge/PhpUnit/Legacy/CommandForV6.php b/src/Symfony/Bridge/PhpUnit/Legacy/CommandForV6.php new file mode 100644 index 000000000000..fc717ef415cb --- /dev/null +++ b/src/Symfony/Bridge/PhpUnit/Legacy/CommandForV6.php @@ -0,0 +1,32 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Bridge\PhpUnit\Legacy; + +use PHPUnit\TextUI\Command as BaseCommand; +use PHPUnit\TextUI\TestRunner as BaseRunner; +use Symfony\Bridge\PhpUnit\TextUI\TestRunner; + +/** + * {@inheritdoc} + * + * @internal + */ +class CommandForV6 extends BaseCommand +{ + /** + * {@inheritdoc} + */ + protected function createRunner(): BaseRunner + { + return new TestRunner($this->arguments['loader']); + } +} diff --git a/src/Symfony/Bridge/PhpUnit/Legacy/TestRunner.php b/src/Symfony/Bridge/PhpUnit/Legacy/TestRunnerForV5.php similarity index 95% rename from src/Symfony/Bridge/PhpUnit/Legacy/TestRunner.php rename to src/Symfony/Bridge/PhpUnit/Legacy/TestRunnerForV5.php index 8a57416bd241..7897861cf52f 100644 --- a/src/Symfony/Bridge/PhpUnit/Legacy/TestRunner.php +++ b/src/Symfony/Bridge/PhpUnit/Legacy/TestRunnerForV5.php @@ -16,7 +16,7 @@ * * @internal */ -class TestRunner extends \PHPUnit_TextUI_TestRunner +class TestRunnerForV5 extends \PHPUnit_TextUI_TestRunner { /** * {@inheritdoc} diff --git a/src/Symfony/Bridge/PhpUnit/Legacy/TestRunnerForV6.php b/src/Symfony/Bridge/PhpUnit/Legacy/TestRunnerForV6.php new file mode 100644 index 000000000000..d709b873874f --- /dev/null +++ b/src/Symfony/Bridge/PhpUnit/Legacy/TestRunnerForV6.php @@ -0,0 +1,49 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Bridge\PhpUnit\Legacy; + +use PHPUnit\TextUI\TestRunner as BaseRunner; +use Symfony\Bridge\PhpUnit\SymfonyTestsListener; + +/** + * {@inheritdoc} + * + * @internal + */ +class TestRunnerForV6 extends BaseRunner +{ + /** + * {@inheritdoc} + */ + protected function handleConfiguration(array &$arguments): void + { + $listener = new SymfonyTestsListener(); + + parent::handleConfiguration($arguments); + + $arguments['listeners'] = isset($arguments['listeners']) ? $arguments['listeners'] : array(); + + $registeredLocally = false; + + foreach ($arguments['listeners'] as $registeredListener) { + if ($registeredListener instanceof SymfonyTestsListener) { + $registeredListener->globalListenerDisabled(); + $registeredLocally = true; + break; + } + } + + if (!$registeredLocally) { + $arguments['listeners'][] = $listener; + } + } +} diff --git a/src/Symfony/Bridge/PhpUnit/TextUI/Command.php b/src/Symfony/Bridge/PhpUnit/TextUI/Command.php index 869a8a8dbe85..4a26fc7fad27 100644 --- a/src/Symfony/Bridge/PhpUnit/TextUI/Command.php +++ b/src/Symfony/Bridge/PhpUnit/TextUI/Command.php @@ -11,24 +11,14 @@ namespace Symfony\Bridge\PhpUnit\TextUI; -use PHPUnit\TextUI\Command as BaseCommand; - if (class_exists('PHPUnit_Runner_Version') && version_compare(\PHPUnit_Runner_Version::id(), '6.0.0', '<')) { - class_alias('Symfony\Bridge\PhpUnit\Legacy\Command', 'Symfony\Bridge\PhpUnit\TextUI\Command'); + class_alias('Symfony\Bridge\PhpUnit\Legacy\CommandForV5', 'Symfony\Bridge\PhpUnit\TextUI\Command'); } else { - /** - * {@inheritdoc} - * - * @internal - */ - class Command extends BaseCommand + class_alias('Symfony\Bridge\PhpUnit\Legacy\CommandForV6', 'Symfony\Bridge\PhpUnit\TextUI\Command'); +} + +if (false) { + class Command { - /** - * {@inheritdoc} - */ - protected function createRunner() - { - return new TestRunner($this->arguments['loader']); - } } } diff --git a/src/Symfony/Bridge/PhpUnit/TextUI/TestRunner.php b/src/Symfony/Bridge/PhpUnit/TextUI/TestRunner.php index 4e1fdca4d54b..af1abd386678 100644 --- a/src/Symfony/Bridge/PhpUnit/TextUI/TestRunner.php +++ b/src/Symfony/Bridge/PhpUnit/TextUI/TestRunner.php @@ -11,45 +11,14 @@ namespace Symfony\Bridge\PhpUnit\TextUI; -use PHPUnit\TextUI\TestRunner as BaseRunner; -use Symfony\Bridge\PhpUnit\SymfonyTestsListener; - if (class_exists('PHPUnit_Runner_Version') && version_compare(\PHPUnit_Runner_Version::id(), '6.0.0', '<')) { - class_alias('Symfony\Bridge\PhpUnit\Legacy\TestRunner', 'Symfony\Bridge\PhpUnit\TextUI\TestRunner'); + class_alias('Symfony\Bridge\PhpUnit\Legacy\TestRunnerForV5', 'Symfony\Bridge\PhpUnit\TextUI\TestRunner'); } else { - /** - * {@inheritdoc} - * - * @internal - */ - class TestRunner extends BaseRunner - { - /** - * {@inheritdoc} - */ - protected function handleConfiguration(array &$arguments) - { - $listener = new SymfonyTestsListener(); - - $result = parent::handleConfiguration($arguments); - - $arguments['listeners'] = isset($arguments['listeners']) ? $arguments['listeners'] : array(); - - $registeredLocally = false; - - foreach ($arguments['listeners'] as $registeredListener) { - if ($registeredListener instanceof SymfonyTestsListener) { - $registeredListener->globalListenerDisabled(); - $registeredLocally = true; - break; - } - } - - if (!$registeredLocally) { - $arguments['listeners'][] = $listener; - } + class_alias('Symfony\Bridge\PhpUnit\Legacy\TestRunnerForV6', 'Symfony\Bridge\PhpUnit\TextUI\TestRunner'); +} - return $result; - } +if (false) { + class TestRunner + { } } From 5e98478d94a4f4c48bef5fb5b7cdb37d6f54ec12 Mon Sep 17 00:00:00 2001 From: Javier Spagnoletti Date: Sun, 22 Apr 2018 20:12:04 -0300 Subject: [PATCH 44/75] [DoctrineBridge] Improve exception message at `IdReader::getIdValue()` --- src/Symfony/Bridge/Doctrine/Form/ChoiceList/IdReader.php | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/src/Symfony/Bridge/Doctrine/Form/ChoiceList/IdReader.php b/src/Symfony/Bridge/Doctrine/Form/ChoiceList/IdReader.php index ee8ec2ddaba7..1d881849267d 100644 --- a/src/Symfony/Bridge/Doctrine/Form/ChoiceList/IdReader.php +++ b/src/Symfony/Bridge/Doctrine/Form/ChoiceList/IdReader.php @@ -95,10 +95,7 @@ public function getIdValue($object) } if (!$this->om->contains($object)) { - throw new RuntimeException( - 'Entities passed to the choice field must be managed. Maybe '. - 'persist them in the entity manager?' - ); + throw new RuntimeException(sprintf('Entity of type "%s" passed to the choice field must be managed. Maybe you forget to persist it in the entity manager?', get_class($object))); } $this->om->initializeObject($object); From c606d60c54ce0b03f3e736dee9b0e8f72f35d130 Mon Sep 17 00:00:00 2001 From: Ahmad Mayahi Date: Mon, 23 Apr 2018 10:51:32 +0200 Subject: [PATCH 45/75] [HttpFoundation] Add HTTP_EARLY_HINTS const --- src/Symfony/Component/HttpFoundation/Response.php | 1 + 1 file changed, 1 insertion(+) diff --git a/src/Symfony/Component/HttpFoundation/Response.php b/src/Symfony/Component/HttpFoundation/Response.php index ad551a85b9a8..13b85b15d4e8 100644 --- a/src/Symfony/Component/HttpFoundation/Response.php +++ b/src/Symfony/Component/HttpFoundation/Response.php @@ -21,6 +21,7 @@ class Response const HTTP_CONTINUE = 100; const HTTP_SWITCHING_PROTOCOLS = 101; const HTTP_PROCESSING = 102; // RFC2518 + const HTTP_EARLY_HINTS = 103; // RFC8297 const HTTP_OK = 200; const HTTP_CREATED = 201; const HTTP_ACCEPTED = 202; From 314e8813b3e730bf09c3e6ee7280d93046a47a37 Mon Sep 17 00:00:00 2001 From: Sergey Rabochiy Date: Tue, 24 Apr 2018 14:18:57 +0700 Subject: [PATCH 46/75] [DI] Add check of internal type to ContainerBuilder::getReflectionClass --- .../DependencyInjection/ContainerBuilder.php | 19 +++++++++++++++++++ .../Tests/ContainerBuilderTest.php | 17 +++++++++++++++++ 2 files changed, 36 insertions(+) diff --git a/src/Symfony/Component/DependencyInjection/ContainerBuilder.php b/src/Symfony/Component/DependencyInjection/ContainerBuilder.php index 512abd1d271a..7f79e2f4ffc5 100644 --- a/src/Symfony/Component/DependencyInjection/ContainerBuilder.php +++ b/src/Symfony/Component/DependencyInjection/ContainerBuilder.php @@ -124,6 +124,20 @@ class ContainerBuilder extends Container implements TaggedContainerInterface private $removedIds = array(); private $alreadyLoading = array(); + private static $internalTypes = array( + 'int' => true, + 'float' => true, + 'string' => true, + 'bool' => true, + 'resource' => true, + 'object' => true, + 'array' => true, + 'null' => true, + 'callable' => true, + 'iterable' => true, + 'mixed' => true, + ); + public function __construct(ParameterBagInterface $parameterBag = null) { parent::__construct($parameterBag); @@ -341,6 +355,11 @@ public function getReflectionClass($class, $throw = true) if (!$class = $this->getParameterBag()->resolveValue($class)) { return; } + + if (isset(self::$internalTypes[$class])) { + return null; + } + $resource = null; try { diff --git a/src/Symfony/Component/DependencyInjection/Tests/ContainerBuilderTest.php b/src/Symfony/Component/DependencyInjection/Tests/ContainerBuilderTest.php index 197bfae84453..51038b6b1550 100644 --- a/src/Symfony/Component/DependencyInjection/Tests/ContainerBuilderTest.php +++ b/src/Symfony/Component/DependencyInjection/Tests/ContainerBuilderTest.php @@ -906,6 +906,23 @@ public function testGetReflectionClass() $this->assertSame('BarMissingClass', (string) end($resources)); } + public function testGetReflectionClassOnInternalTypes() + { + $container = new ContainerBuilder(); + + $this->assertNull($container->getReflectionClass('int')); + $this->assertNull($container->getReflectionClass('float')); + $this->assertNull($container->getReflectionClass('string')); + $this->assertNull($container->getReflectionClass('bool')); + $this->assertNull($container->getReflectionClass('resource')); + $this->assertNull($container->getReflectionClass('object')); + $this->assertNull($container->getReflectionClass('array')); + $this->assertNull($container->getReflectionClass('null')); + $this->assertNull($container->getReflectionClass('callable')); + $this->assertNull($container->getReflectionClass('iterable')); + $this->assertNull($container->getReflectionClass('mixed')); + } + public function testCompilesClassDefinitionsOfLazyServices() { $container = new ContainerBuilder(); From 384acf9f7f33c37f2a1dc475169256bd72b7711d Mon Sep 17 00:00:00 2001 From: Robin Chalas Date: Wed, 25 Apr 2018 13:23:26 +0200 Subject: [PATCH 47/75] [Security] Skip user checks if not implementing UserInterface --- .../Provider/SimpleAuthenticationProvider.php | 6 ++++++ .../Provider/SimpleAuthenticationProviderTest.php | 15 +++++++++++++++ 2 files changed, 21 insertions(+) diff --git a/src/Symfony/Component/Security/Core/Authentication/Provider/SimpleAuthenticationProvider.php b/src/Symfony/Component/Security/Core/Authentication/Provider/SimpleAuthenticationProvider.php index a82fb7eea427..b4bdbf40c097 100644 --- a/src/Symfony/Component/Security/Core/Authentication/Provider/SimpleAuthenticationProvider.php +++ b/src/Symfony/Component/Security/Core/Authentication/Provider/SimpleAuthenticationProvider.php @@ -13,6 +13,7 @@ use Symfony\Component\Security\Core\User\UserChecker; use Symfony\Component\Security\Core\User\UserCheckerInterface; +use Symfony\Component\Security\Core\User\UserInterface; use Symfony\Component\Security\Core\User\UserProviderInterface; use Symfony\Component\Security\Core\Authentication\Token\TokenInterface; use Symfony\Component\Security\Core\Authentication\SimpleAuthenticatorInterface; @@ -45,6 +46,11 @@ public function authenticate(TokenInterface $token) } $user = $authToken->getUser(); + + if (!$user instanceof UserInterface) { + return $authToken; + } + $this->userChecker->checkPreAuth($user); $this->userChecker->checkPostAuth($user); diff --git a/src/Symfony/Component/Security/Core/Tests/Authentication/Provider/SimpleAuthenticationProviderTest.php b/src/Symfony/Component/Security/Core/Tests/Authentication/Provider/SimpleAuthenticationProviderTest.php index 1e7069c1fa0b..35247abe99c4 100644 --- a/src/Symfony/Component/Security/Core/Tests/Authentication/Provider/SimpleAuthenticationProviderTest.php +++ b/src/Symfony/Component/Security/Core/Tests/Authentication/Provider/SimpleAuthenticationProviderTest.php @@ -15,6 +15,7 @@ use Symfony\Component\Security\Core\Exception\DisabledException; use Symfony\Component\Security\Core\Authentication\Provider\SimpleAuthenticationProvider; use Symfony\Component\Security\Core\Exception\LockedException; +use Symfony\Component\Security\Core\User\UserChecker; class SimpleAuthenticationProviderTest extends TestCase { @@ -72,6 +73,20 @@ public function testAuthenticateWhenPostChecksFails() $provider->authenticate($token); } + public function testAuthenticateSkipsUserChecksForNonUserInterfaceObjects() + { + $token = $this->getMockBuilder('Symfony\Component\Security\Core\Authentication\Token\TokenInterface')->getMock(); + $token->expects($this->any()) + ->method('getUser') + ->will($this->returnValue('string-user')); + $authenticator = $this->getMockBuilder('Symfony\Component\Security\Core\Authentication\SimpleAuthenticatorInterface')->getMock(); + $authenticator->expects($this->once()) + ->method('authenticateToken') + ->will($this->returnValue($token)); + + $this->assertSame($token, $this->getProvider($authenticator, null, new UserChecker())->authenticate($token)); + } + protected function getProvider($simpleAuthenticator = null, $userProvider = null, $userChecker = null, $key = 'test') { if (null === $userChecker) { From 715373fea6ed721bfc3b92ad9056701c35c0e076 Mon Sep 17 00:00:00 2001 From: gpenverne Date: Fri, 6 Apr 2018 11:56:21 +0200 Subject: [PATCH 48/75] [Bridge/Doctrine] fix count() notice on PHP 7.2 --- .../Constraints/UniqueEntityValidatorTest.php | 28 +++++++++++++++++++ .../Constraints/UniqueEntityValidator.php | 12 ++++++-- 2 files changed, 38 insertions(+), 2 deletions(-) diff --git a/src/Symfony/Bridge/Doctrine/Tests/Validator/Constraints/UniqueEntityValidatorTest.php b/src/Symfony/Bridge/Doctrine/Tests/Validator/Constraints/UniqueEntityValidatorTest.php index 61131e47045a..510c0f227afc 100644 --- a/src/Symfony/Bridge/Doctrine/Tests/Validator/Constraints/UniqueEntityValidatorTest.php +++ b/src/Symfony/Bridge/Doctrine/Tests/Validator/Constraints/UniqueEntityValidatorTest.php @@ -517,4 +517,32 @@ public function testEntityManagerNullObject() $this->validator->validate($entity, $constraint); } + + public function testValidateUniquenessOnNullResult() + { + $repository = $this->createRepositoryMock(); + $repository + ->method('find') + ->will($this->returnValue(null)) + ; + + $this->em = $this->createEntityManagerMock($repository); + $this->registry = $this->createRegistryMock($this->em); + $this->validator = $this->createValidator(); + $this->validator->initialize($this->context); + + $constraint = new UniqueEntity(array( + 'message' => 'myMessage', + 'fields' => array('name'), + 'em' => self::EM_NAME, + )); + + $entity = new SingleIntIdEntity(1, null); + + $this->em->persist($entity); + $this->em->flush(); + + $this->validator->validate($entity, $constraint); + $this->assertNoViolation(); + } } diff --git a/src/Symfony/Bridge/Doctrine/Validator/Constraints/UniqueEntityValidator.php b/src/Symfony/Bridge/Doctrine/Validator/Constraints/UniqueEntityValidator.php index 8c7876eae342..3effc89ca09a 100644 --- a/src/Symfony/Bridge/Doctrine/Validator/Constraints/UniqueEntityValidator.php +++ b/src/Symfony/Bridge/Doctrine/Validator/Constraints/UniqueEntityValidator.php @@ -133,15 +133,23 @@ public function validate($entity, Constraint $constraint) */ if ($result instanceof \Iterator) { $result->rewind(); - } elseif (is_array($result)) { + if ($result instanceof \Countable && 1 < \count($result)) { + $result = array($result->current(), $result->current()); + } else { + $result = $result->current(); + $result = null === $result ? array() : array($result); + } + } elseif (\is_array($result)) { reset($result); + } else { + $result = null === $result ? array() : array($result); } /* If no entity matched the query criteria or a single entity matched, * which is the same as the entity being validated, the criteria is * unique. */ - if (0 === count($result) || (1 === count($result) && $entity === ($result instanceof \Iterator ? $result->current() : current($result)))) { + if (!$result || (1 === \count($result) && current($result) === $entity)) { return; } From 4a8306e7be9398656012ccd344319f59f32ca991 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?K=C3=A9vin=20Dunglas?= Date: Sun, 22 Apr 2018 11:17:37 +0200 Subject: [PATCH 49/75] [PropertyInfo] Minor cleanup and perf improvement --- .../Component/PropertyInfo/Extractor/PhpDocExtractor.php | 6 +++--- .../PropertyInfo/Extractor/ReflectionExtractor.php | 4 ++-- .../PropertyInfo/PropertyDescriptionExtractorInterface.php | 2 +- .../Component/PropertyInfo/PropertyInfoExtractor.php | 2 +- 4 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/Symfony/Component/PropertyInfo/Extractor/PhpDocExtractor.php b/src/Symfony/Component/PropertyInfo/Extractor/PhpDocExtractor.php index 6be39d29d225..717baddab2b5 100644 --- a/src/Symfony/Component/PropertyInfo/Extractor/PhpDocExtractor.php +++ b/src/Symfony/Component/PropertyInfo/Extractor/PhpDocExtractor.php @@ -111,7 +111,7 @@ public function getTypes($class, $property, array $context = array()) $nullable = false !== $nullKey; // Remove the null type from the type if other types are defined - if ($nullable && count($varTypes) > 1) { + if ($nullable && \count($varTypes) > 1) { unset($varTypes[$nullKey]); } @@ -127,7 +127,7 @@ public function getTypes($class, $property, array $context = array()) return; } - if (!in_array($prefix, ReflectionExtractor::$arrayMutatorPrefixes)) { + if (!\in_array($prefix, ReflectionExtractor::$arrayMutatorPrefixes)) { return $types; } @@ -386,7 +386,7 @@ private function normalizeType($docType) */ private function getPhpTypeAndClass($docType) { - if (in_array($docType, Type::$builtinTypes)) { + if (\in_array($docType, Type::$builtinTypes)) { return array($docType, null); } diff --git a/src/Symfony/Component/PropertyInfo/Extractor/ReflectionExtractor.php b/src/Symfony/Component/PropertyInfo/Extractor/ReflectionExtractor.php index 3ec1d8d6eab0..fcd443de9bcd 100644 --- a/src/Symfony/Component/PropertyInfo/Extractor/ReflectionExtractor.php +++ b/src/Symfony/Component/PropertyInfo/Extractor/ReflectionExtractor.php @@ -161,7 +161,7 @@ private function extractFromMutator($class, $property) return; } - if (in_array($prefix, self::$arrayMutatorPrefixes)) { + if (\in_array($prefix, self::$arrayMutatorPrefixes)) { $type = new Type(Type::BUILTIN_TYPE_ARRAY, false, null, true, new Type(Type::BUILTIN_TYPE_INT), $type); } @@ -187,7 +187,7 @@ private function extractFromAccessor($class, $property) return array($this->extractFromReflectionType($reflectionType)); } - if (in_array($prefix, array('is', 'can'))) { + if (\in_array($prefix, array('is', 'can'))) { return array(new Type(Type::BUILTIN_TYPE_BOOL)); } } diff --git a/src/Symfony/Component/PropertyInfo/PropertyDescriptionExtractorInterface.php b/src/Symfony/Component/PropertyInfo/PropertyDescriptionExtractorInterface.php index a2e98d0febb2..3f400a8fa53e 100644 --- a/src/Symfony/Component/PropertyInfo/PropertyDescriptionExtractorInterface.php +++ b/src/Symfony/Component/PropertyInfo/PropertyDescriptionExtractorInterface.php @@ -12,7 +12,7 @@ namespace Symfony\Component\PropertyInfo; /** - * Description extractor Interface. + * Guesses the property's human readable description. * * @author Kévin Dunglas */ diff --git a/src/Symfony/Component/PropertyInfo/PropertyInfoExtractor.php b/src/Symfony/Component/PropertyInfo/PropertyInfoExtractor.php index 031c8ac05e26..1361a9437843 100644 --- a/src/Symfony/Component/PropertyInfo/PropertyInfoExtractor.php +++ b/src/Symfony/Component/PropertyInfo/PropertyInfoExtractor.php @@ -112,7 +112,7 @@ public function isWritable($class, $property, array $context = array()) private function extract(array $extractors, $method, array $arguments) { foreach ($extractors as $extractor) { - $value = call_user_func_array(array($extractor, $method), $arguments); + $value = \call_user_func_array(array($extractor, $method), $arguments); if (null !== $value) { return $value; } From c4daef9db6d50e5aeb1ae17275b07eed25288a56 Mon Sep 17 00:00:00 2001 From: Robin Chalas Date: Wed, 25 Apr 2018 16:05:38 +0200 Subject: [PATCH 50/75] [VarDumper] Remove decoration from actual output in tests --- .../Tests/DataCollector/DumpDataCollectorTest.php | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/src/Symfony/Component/HttpKernel/Tests/DataCollector/DumpDataCollectorTest.php b/src/Symfony/Component/HttpKernel/Tests/DataCollector/DumpDataCollectorTest.php index 2dbb79910970..4c7cd9a51c0e 100644 --- a/src/Symfony/Component/HttpKernel/Tests/DataCollector/DumpDataCollectorTest.php +++ b/src/Symfony/Component/HttpKernel/Tests/DataCollector/DumpDataCollectorTest.php @@ -67,7 +67,7 @@ public function testCollectDefault() ob_start(); $collector->collect(new Request(), new Response()); - $output = ob_get_clean(); + $output = preg_replace("/\033\[[^m]*m/", '', ob_get_clean()); if (\PHP_VERSION_ID >= 50400) { $this->assertSame("DumpDataCollectorTest.php on line {$line}:\n123\n", $output); @@ -125,10 +125,11 @@ public function testFlush() ob_start(); $collector->__destruct(); + $output = preg_replace("/\033\[[^m]*m/", '', ob_get_clean()); if (\PHP_VERSION_ID >= 50400) { - $this->assertSame("DumpDataCollectorTest.php on line {$line}:\n456\n", ob_get_clean()); + $this->assertSame("DumpDataCollectorTest.php on line {$line}:\n456\n", $output); } else { - $this->assertSame("\"DumpDataCollectorTest.php on line {$line}:\"\n456\n", ob_get_clean()); + $this->assertSame("\"DumpDataCollectorTest.php on line {$line}:\"\n456\n", $output); } } @@ -141,10 +142,11 @@ public function testFlushNothingWhenDataDumperIsProvided() ob_start(); $collector->dump($data); $line = __LINE__ - 1; + $output = preg_replace("/\033\[[^m]*m/", '', ob_get_clean()); if (\PHP_VERSION_ID >= 50400) { - $this->assertSame("DumpDataCollectorTest.php on line {$line}:\n456\n", ob_get_clean()); + $this->assertSame("DumpDataCollectorTest.php on line {$line}:\n456\n", $output); } else { - $this->assertSame("\"DumpDataCollectorTest.php on line {$line}:\"\n456\n", ob_get_clean()); + $this->assertSame("\"DumpDataCollectorTest.php on line {$line}:\"\n456\n", $output); } ob_start(); From e9cc947aef3db8675161741237f288fb5a5ecd0c Mon Sep 17 00:00:00 2001 From: Nicolas Grekas Date: Wed, 25 Apr 2018 16:21:38 +0200 Subject: [PATCH 51/75] [PhpUnitBridge] Fix #26994 --- src/Symfony/Bridge/PhpUnit/Legacy/CommandForV5.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Symfony/Bridge/PhpUnit/Legacy/CommandForV5.php b/src/Symfony/Bridge/PhpUnit/Legacy/CommandForV5.php index d727881a11d8..d4b5ea26d8cd 100644 --- a/src/Symfony/Bridge/PhpUnit/Legacy/CommandForV5.php +++ b/src/Symfony/Bridge/PhpUnit/Legacy/CommandForV5.php @@ -23,6 +23,6 @@ class CommandForV5 extends \PHPUnit_TextUI_Command */ protected function createRunner() { - return new TestRunner($this->arguments['loader']); + return new TestRunnerForV5($this->arguments['loader']); } } From 9dff22ca9911d4bc478b04933a571cfe95eb9be3 Mon Sep 17 00:00:00 2001 From: Thomas Date: Mon, 23 Apr 2018 14:06:09 +0200 Subject: [PATCH 52/75] [Security] guardAuthenticationProvider::authenticate cannot return null according to interface specification --- .../Provider/GuardAuthenticationProvider.php | 57 +++++++++++-------- .../GuardAuthenticationProviderTest.php | 35 ++++++++++++ 2 files changed, 67 insertions(+), 25 deletions(-) diff --git a/src/Symfony/Component/Security/Guard/Provider/GuardAuthenticationProvider.php b/src/Symfony/Component/Security/Guard/Provider/GuardAuthenticationProvider.php index 4347e020021f..b9e1f66abb85 100644 --- a/src/Symfony/Component/Security/Guard/Provider/GuardAuthenticationProvider.php +++ b/src/Symfony/Component/Security/Guard/Provider/GuardAuthenticationProvider.php @@ -13,6 +13,7 @@ use Symfony\Component\Security\Core\Authentication\Provider\AuthenticationProviderInterface; use Symfony\Component\Security\Core\Authentication\Token\AnonymousToken; +use Symfony\Component\Security\Core\Exception\AuthenticationException; use Symfony\Component\Security\Core\Exception\BadCredentialsException; use Symfony\Component\Security\Core\Exception\UsernameNotFoundException; use Symfony\Component\Security\Guard\GuardAuthenticatorInterface; @@ -63,7 +64,7 @@ public function __construct(array $guardAuthenticators, UserProviderInterface $u */ public function authenticate(TokenInterface $token) { - if (!$this->supports($token)) { + if (!$token instanceof GuardTokenInterface) { throw new \InvalidArgumentException('GuardAuthenticationProvider only supports GuardTokenInterface.'); } @@ -87,19 +88,13 @@ public function authenticate(TokenInterface $token) throw new AuthenticationExpiredException(); } - // find the *one* GuardAuthenticator that this token originated from - foreach ($this->guardAuthenticators as $key => $guardAuthenticator) { - // get a key that's unique to *this* guard authenticator - // this MUST be the same as GuardAuthenticationListener - $uniqueGuardKey = $this->providerKey.'_'.$key; + $guardAuthenticator = $this->findOriginatingAuthenticator($token); - if ($uniqueGuardKey == $token->getGuardProviderKey()) { - return $this->authenticateViaGuard($guardAuthenticator, $token); - } + if (null === $guardAuthenticator) { + throw new AuthenticationException(sprintf('Token with provider key "%s" did not originate from any of the guard authenticators of provider "%s".', $token->getGuardProviderKey(), $this->providerKey)); } - // no matching authenticator found - but there will be multiple GuardAuthenticationProvider - // instances that will be checked if you have multiple firewalls. + return $this->authenticateViaGuard($guardAuthenticator, $token); } private function authenticateViaGuard(GuardAuthenticatorInterface $guardAuthenticator, PreAuthenticationGuardToken $token) @@ -108,18 +103,11 @@ private function authenticateViaGuard(GuardAuthenticatorInterface $guardAuthenti $user = $guardAuthenticator->getUser($token->getCredentials(), $this->userProvider); if (null === $user) { - throw new UsernameNotFoundException(sprintf( - 'Null returned from %s::getUser()', - get_class($guardAuthenticator) - )); + throw new UsernameNotFoundException(sprintf('Null returned from %s::getUser()', get_class($guardAuthenticator))); } if (!$user instanceof UserInterface) { - throw new \UnexpectedValueException(sprintf( - 'The %s::getUser() method must return a UserInterface. You returned %s.', - get_class($guardAuthenticator), - is_object($user) ? get_class($user) : gettype($user) - )); + throw new \UnexpectedValueException(sprintf('The %s::getUser() method must return a UserInterface. You returned %s.', get_class($guardAuthenticator), is_object($user) ? get_class($user) : gettype($user))); } $this->userChecker->checkPreAuth($user); @@ -131,18 +119,37 @@ private function authenticateViaGuard(GuardAuthenticatorInterface $guardAuthenti // turn the UserInterface into a TokenInterface $authenticatedToken = $guardAuthenticator->createAuthenticatedToken($user, $this->providerKey); if (!$authenticatedToken instanceof TokenInterface) { - throw new \UnexpectedValueException(sprintf( - 'The %s::createAuthenticatedToken() method must return a TokenInterface. You returned %s.', - get_class($guardAuthenticator), - is_object($authenticatedToken) ? get_class($authenticatedToken) : gettype($authenticatedToken) - )); + throw new \UnexpectedValueException(sprintf('The %s::createAuthenticatedToken() method must return a TokenInterface. You returned %s.', get_class($guardAuthenticator), is_object($authenticatedToken) ? get_class($authenticatedToken) : gettype($authenticatedToken))); } return $authenticatedToken; } + private function findOriginatingAuthenticator(PreAuthenticationGuardToken $token) + { + // find the *one* GuardAuthenticator that this token originated from + foreach ($this->guardAuthenticators as $key => $guardAuthenticator) { + // get a key that's unique to *this* guard authenticator + // this MUST be the same as GuardAuthenticationListener + $uniqueGuardKey = $this->providerKey.'_'.$key; + + if ($uniqueGuardKey === $token->getGuardProviderKey()) { + return $guardAuthenticator; + } + } + + // no matching authenticator found - but there will be multiple GuardAuthenticationProvider + // instances that will be checked if you have multiple firewalls. + + return null; + } + public function supports(TokenInterface $token) { + if ($token instanceof PreAuthenticationGuardToken) { + return null !== $this->findOriginatingAuthenticator($token); + } + return $token instanceof GuardTokenInterface; } } diff --git a/src/Symfony/Component/Security/Guard/Tests/Provider/GuardAuthenticationProviderTest.php b/src/Symfony/Component/Security/Guard/Tests/Provider/GuardAuthenticationProviderTest.php index ed3920533fe9..847947110d99 100644 --- a/src/Symfony/Component/Security/Guard/Tests/Provider/GuardAuthenticationProviderTest.php +++ b/src/Symfony/Component/Security/Guard/Tests/Provider/GuardAuthenticationProviderTest.php @@ -14,6 +14,7 @@ use PHPUnit\Framework\TestCase; use Symfony\Component\Security\Guard\Provider\GuardAuthenticationProvider; use Symfony\Component\Security\Guard\Token\PostAuthenticationGuardToken; +use Symfony\Component\Security\Guard\Token\PreAuthenticationGuardToken; /** * @author Ryan Weaver @@ -133,6 +134,40 @@ public function testGuardWithNoLongerAuthenticatedTriggersLogout() $actualToken = $provider->authenticate($token); } + public function testSupportsChecksGuardAuthenticatorsTokenOrigin() + { + $authenticatorA = $this->getMockBuilder('Symfony\Component\Security\Guard\GuardAuthenticatorInterface')->getMock(); + $authenticatorB = $this->getMockBuilder('Symfony\Component\Security\Guard\GuardAuthenticatorInterface')->getMock(); + $authenticators = array($authenticatorA, $authenticatorB); + + $mockedUser = $this->getMockBuilder('Symfony\Component\Security\Core\User\UserInterface')->getMock(); + $provider = new GuardAuthenticationProvider($authenticators, $this->userProvider, 'first_firewall', $this->userChecker); + + $token = new PreAuthenticationGuardToken($mockedUser, 'first_firewall_1'); + $supports = $provider->supports($token); + $this->assertTrue($supports); + + $token = new PreAuthenticationGuardToken($mockedUser, 'second_firewall_0'); + $supports = $provider->supports($token); + $this->assertFalse($supports); + } + + /** + * @expectedException \Symfony\Component\Security\Core\Exception\AuthenticationException + * @expectedExceptionMessageRegExp /second_firewall_0/ + */ + public function testAuthenticateFailsOnNonOriginatingToken() + { + $authenticatorA = $this->getMockBuilder('Symfony\Component\Security\Guard\GuardAuthenticatorInterface')->getMock(); + $authenticators = array($authenticatorA); + + $mockedUser = $this->getMockBuilder('Symfony\Component\Security\Core\User\UserInterface')->getMock(); + $provider = new GuardAuthenticationProvider($authenticators, $this->userProvider, 'first_firewall', $this->userChecker); + + $token = new PreAuthenticationGuardToken($mockedUser, 'second_firewall_0'); + $provider->authenticate($token); + } + protected function setUp() { $this->userProvider = $this->getMockBuilder('Symfony\Component\Security\Core\User\UserProviderInterface')->getMock(); From 4e527aa790f41e18a82cb9c53e782549fb564802 Mon Sep 17 00:00:00 2001 From: Chris McCafferty Date: Sat, 10 Feb 2018 19:57:41 -0500 Subject: [PATCH 53/75] bug #25844 [HttpKernel] Catch HttpExceptions when templating is not installed --- .../FrameworkBundle/Resources/config/web.xml | 9 +++++++++ .../EventListener/ExceptionListener.php | 14 +++++++++++--- .../EventListener/ExceptionListenerTest.php | 17 +++++++++++++++++ 3 files changed, 37 insertions(+), 3 deletions(-) diff --git a/src/Symfony/Bundle/FrameworkBundle/Resources/config/web.xml b/src/Symfony/Bundle/FrameworkBundle/Resources/config/web.xml index 0622c4196c10..565aef68fd45 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Resources/config/web.xml +++ b/src/Symfony/Bundle/FrameworkBundle/Resources/config/web.xml @@ -67,6 +67,15 @@ + + + + null + + %kernel.debug% + %kernel.charset% + + diff --git a/src/Symfony/Component/HttpKernel/EventListener/ExceptionListener.php b/src/Symfony/Component/HttpKernel/EventListener/ExceptionListener.php index f18e42c7d369..3dfa4cd8ea79 100644 --- a/src/Symfony/Component/HttpKernel/EventListener/ExceptionListener.php +++ b/src/Symfony/Component/HttpKernel/EventListener/ExceptionListener.php @@ -12,9 +12,11 @@ namespace Symfony\Component\HttpKernel\EventListener; use Psr\Log\LoggerInterface; +use Symfony\Component\Debug\ExceptionHandler; use Symfony\Component\Debug\Exception\FlattenException; use Symfony\Component\EventDispatcher\EventDispatcherInterface; use Symfony\Component\HttpFoundation\Request; +use Symfony\Component\HttpFoundation\Response; use Symfony\Component\HttpKernel\Event\FilterResponseEvent; use Symfony\Component\HttpKernel\Log\DebugLoggerInterface; use Symfony\Component\HttpKernel\Event\GetResponseForExceptionEvent; @@ -33,12 +35,14 @@ class ExceptionListener implements EventSubscriberInterface protected $controller; protected $logger; protected $debug; + private $charset; - public function __construct($controller, LoggerInterface $logger = null, $debug = false) + public function __construct($controller, LoggerInterface $logger = null, $debug = false, $charset = null) { $this->controller = $controller; $this->logger = $logger; $this->debug = $debug; + $this->charset = $charset; } public function onKernelException(GetResponseForExceptionEvent $event) @@ -117,8 +121,12 @@ protected function logException(\Exception $exception, $message) protected function duplicateRequest(\Exception $exception, Request $request) { $attributes = array( - '_controller' => $this->controller, - 'exception' => FlattenException::create($exception), + 'exception' => $exception = FlattenException::create($exception), + '_controller' => $this->controller ?: function () use ($exception) { + $handler = new ExceptionHandler($this->debug, $this->charset); + + return new Response($handler->getHtml($exception), $exception->getStatusCode(), $exception->getHeaders()); + }, 'logger' => $this->logger instanceof DebugLoggerInterface ? $this->logger : null, ); $request = $request->duplicate(null, null, $attributes); diff --git a/src/Symfony/Component/HttpKernel/Tests/EventListener/ExceptionListenerTest.php b/src/Symfony/Component/HttpKernel/Tests/EventListener/ExceptionListenerTest.php index 3cb0b298bb07..b607bf900ae9 100644 --- a/src/Symfony/Component/HttpKernel/Tests/EventListener/ExceptionListenerTest.php +++ b/src/Symfony/Component/HttpKernel/Tests/EventListener/ExceptionListenerTest.php @@ -151,6 +151,23 @@ public function testCSPHeaderIsRemoved() $this->assertFalse($response->headers->has('content-security-policy'), 'CSP header has been removed'); $this->assertFalse($dispatcher->hasListeners(KernelEvents::RESPONSE), 'CSP removal listener has been removed'); } + + public function testNullController() + { + $listener = new ExceptionListener(null); + $kernel = $this->getMockBuilder('Symfony\Component\HttpKernel\HttpKernelInterface')->getMock(); + $kernel->expects($this->once())->method('handle')->will($this->returnCallback(function (Request $request) { + $controller = $request->attributes->get('_controller'); + + return $controller(); + })); + $request = Request::create('/'); + $event = new GetResponseForExceptionEvent($kernel, $request, HttpKernelInterface::MASTER_REQUEST, new \Exception('foo')); + + $listener->onKernelException($event); + + $this->assertContains('Whoops, looks like something went wrong.', $event->getResponse()->getContent()); + } } class TestLogger extends Logger implements DebugLoggerInterface From 36f384984272fd720e6e6bb4c8deac7edbcabeed Mon Sep 17 00:00:00 2001 From: Nicolas Grekas Date: Wed, 25 Apr 2018 18:20:53 +0200 Subject: [PATCH 54/75] fix merge --- .../Tests/Provider/GuardAuthenticationProviderTest.php | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/Symfony/Component/Security/Guard/Tests/Provider/GuardAuthenticationProviderTest.php b/src/Symfony/Component/Security/Guard/Tests/Provider/GuardAuthenticationProviderTest.php index 17ea596d15ba..04c16dfd4d14 100644 --- a/src/Symfony/Component/Security/Guard/Tests/Provider/GuardAuthenticationProviderTest.php +++ b/src/Symfony/Component/Security/Guard/Tests/Provider/GuardAuthenticationProviderTest.php @@ -156,7 +156,7 @@ public function testCheckCredentialsReturningNonTrueFailsAuthentication() { $providerKey = 'my_uncool_firewall'; - $authenticator = $this->getMockBuilder('Symfony\Component\Security\Guard\GuardAuthenticatorInterface')->getMock(); + $authenticator = $this->getMockBuilder(AuthenticatorInterface::class)->getMock(); // make sure the authenticator is used $this->preAuthenticationToken->expects($this->any()) @@ -201,8 +201,8 @@ public function testGuardWithNoLongerAuthenticatedTriggersLogout() public function testSupportsChecksGuardAuthenticatorsTokenOrigin() { - $authenticatorA = $this->getMockBuilder('Symfony\Component\Security\Guard\GuardAuthenticatorInterface')->getMock(); - $authenticatorB = $this->getMockBuilder('Symfony\Component\Security\Guard\GuardAuthenticatorInterface')->getMock(); + $authenticatorA = $this->getMockBuilder(AuthenticatorInterface::class)->getMock(); + $authenticatorB = $this->getMockBuilder(AuthenticatorInterface::class)->getMock(); $authenticators = array($authenticatorA, $authenticatorB); $mockedUser = $this->getMockBuilder('Symfony\Component\Security\Core\User\UserInterface')->getMock(); @@ -223,7 +223,7 @@ public function testSupportsChecksGuardAuthenticatorsTokenOrigin() */ public function testAuthenticateFailsOnNonOriginatingToken() { - $authenticatorA = $this->getMockBuilder('Symfony\Component\Security\Guard\GuardAuthenticatorInterface')->getMock(); + $authenticatorA = $this->getMockBuilder(AuthenticatorInterface::class)->getMock(); $authenticators = array($authenticatorA); $mockedUser = $this->getMockBuilder('Symfony\Component\Security\Core\User\UserInterface')->getMock(); From a8e284f986a9a4d2244d054e6999dc9ffa586033 Mon Sep 17 00:00:00 2001 From: Nicolas Grekas Date: Thu, 26 Apr 2018 11:45:21 +0200 Subject: [PATCH 55/75] [PhpUnitBridge] silence wget --- src/Symfony/Bridge/PhpUnit/bin/simple-phpunit | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Symfony/Bridge/PhpUnit/bin/simple-phpunit b/src/Symfony/Bridge/PhpUnit/bin/simple-phpunit index a549cd7da4fb..a824eae8f2ab 100755 --- a/src/Symfony/Bridge/PhpUnit/bin/simple-phpunit +++ b/src/Symfony/Bridge/PhpUnit/bin/simple-phpunit @@ -72,7 +72,7 @@ if (!file_exists("$PHPUNIT_DIR/phpunit-$PHPUNIT_VERSION/phpunit") || md5_file(__ stream_copy_to_stream($remoteZipStream, fopen("$PHPUNIT_VERSION.zip", 'wb')); } else { @unlink("$PHPUNIT_VERSION.zip"); - passthru("wget https://github.com/sebastianbergmann/phpunit/archive/$PHPUNIT_VERSION.zip"); + passthru("wget -q https://github.com/sebastianbergmann/phpunit/archive/$PHPUNIT_VERSION.zip"); } if (!class_exists('ZipArchive')) { throw new \Exception('simple-phpunit requires the "zip" PHP extension to be installed and enabled in order to uncompress the downloaded PHPUnit packages.'); From 9afad9decd0d30e87e2fc760fe26ddfd1b27e813 Mon Sep 17 00:00:00 2001 From: Leo Feyer Date: Thu, 26 Apr 2018 12:21:35 +0200 Subject: [PATCH 56/75] Make the simple auth provider the same as in Symfony 2.7. --- .../Provider/SimpleAuthenticationProvider.php | 17 +------ .../SimpleAuthenticationProviderTest.php | 49 ------------------- 2 files changed, 1 insertion(+), 65 deletions(-) diff --git a/src/Symfony/Component/Security/Core/Authentication/Provider/SimpleAuthenticationProvider.php b/src/Symfony/Component/Security/Core/Authentication/Provider/SimpleAuthenticationProvider.php index 22f3c4da859d..b4bdbf40c097 100644 --- a/src/Symfony/Component/Security/Core/Authentication/Provider/SimpleAuthenticationProvider.php +++ b/src/Symfony/Component/Security/Core/Authentication/Provider/SimpleAuthenticationProvider.php @@ -11,8 +11,6 @@ namespace Symfony\Component\Security\Core\Authentication\Provider; -use Symfony\Component\Security\Core\Exception\AuthenticationServiceException; -use Symfony\Component\Security\Core\Exception\UsernameNotFoundException; use Symfony\Component\Security\Core\User\UserChecker; use Symfony\Component\Security\Core\User\UserCheckerInterface; use Symfony\Component\Security\Core\User\UserInterface; @@ -50,20 +48,7 @@ public function authenticate(TokenInterface $token) $user = $authToken->getUser(); if (!$user instanceof UserInterface) { - try { - $user = $this->userProvider->loadUserByUsername($user); - - if (!$user instanceof UserInterface) { - return $authToken; - } - } catch (UsernameNotFoundException $e) { - $e->setUsername($user); - throw $e; - } catch (\Exception $e) { - $e = new AuthenticationServiceException($e->getMessage(), 0, $e); - $e->setToken($token); - throw $e; - } + return $authToken; } $this->userChecker->checkPreAuth($user); diff --git a/src/Symfony/Component/Security/Core/Tests/Authentication/Provider/SimpleAuthenticationProviderTest.php b/src/Symfony/Component/Security/Core/Tests/Authentication/Provider/SimpleAuthenticationProviderTest.php index 752c9d2aa478..3694d996feda 100644 --- a/src/Symfony/Component/Security/Core/Tests/Authentication/Provider/SimpleAuthenticationProviderTest.php +++ b/src/Symfony/Component/Security/Core/Tests/Authentication/Provider/SimpleAuthenticationProviderTest.php @@ -15,7 +15,6 @@ use Symfony\Component\Security\Core\Authentication\Provider\SimpleAuthenticationProvider; use Symfony\Component\Security\Core\Exception\DisabledException; use Symfony\Component\Security\Core\Exception\LockedException; -use Symfony\Component\Security\Core\Exception\UsernameNotFoundException; use Symfony\Component\Security\Core\User\UserChecker; class SimpleAuthenticationProviderTest extends TestCase @@ -74,54 +73,6 @@ public function testAuthenticateWhenPostChecksFails() $provider->authenticate($token); } - public function testAuthenticateFromString() - { - $user = $this->getMockBuilder('Symfony\Component\Security\Core\User\UserInterface')->getMock(); - - $token = $this->getMockBuilder('Symfony\Component\Security\Core\Authentication\Token\TokenInterface')->getMock(); - $token->expects($this->any()) - ->method('getUser') - ->will($this->returnValue('foo')); - - $authenticator = $this->getMockBuilder('Symfony\Component\Security\Core\Authentication\SimpleAuthenticatorInterface')->getMock(); - $authenticator->expects($this->once()) - ->method('authenticateToken') - ->will($this->returnValue($token)); - - $userProvider = $this->getMockBuilder('Symfony\Component\Security\Core\User\UserProviderInterface')->getMock(); - $userProvider->expects($this->once()) - ->method('loadUserByUsername') - ->willReturn($this->getMockBuilder('Symfony\Component\Security\Core\User\UserInterface')->getMock()); - $provider = $this->getProvider($authenticator, $userProvider); - - $this->assertSame($token, $provider->authenticate($token)); - } - - /** - * @expectedException \Symfony\Component\Security\Core\Exception\UsernameNotFoundException - */ - public function testUsernameNotFound() - { - $user = $this->getMockBuilder('Symfony\Component\Security\Core\User\UserInterface')->getMock(); - - $token = $this->getMockBuilder('Symfony\Component\Security\Core\Authentication\Token\TokenInterface')->getMock(); - $token->expects($this->any()) - ->method('getUser') - ->will($this->returnValue('foo')); - - $authenticator = $this->getMockBuilder('Symfony\Component\Security\Core\Authentication\SimpleAuthenticatorInterface')->getMock(); - $authenticator->expects($this->once()) - ->method('authenticateToken') - ->will($this->returnValue($token)); - - $userProvider = $this->getMockBuilder('Symfony\Component\Security\Core\User\UserProviderInterface')->getMock(); - $userProvider->expects($this->once()) - ->method('loadUserByUsername') - ->willThrowException(new UsernameNotFoundException()); - - $this->getProvider($authenticator, $userProvider)->authenticate($token); - } - public function testAuthenticateSkipsUserChecksForNonUserInterfaceObjects() { $token = $this->getMockBuilder('Symfony\Component\Security\Core\Authentication\Token\TokenInterface')->getMock(); From 229430fdbde34bc158049e74f5615fc843460b21 Mon Sep 17 00:00:00 2001 From: Maxime Steinhausser Date: Thu, 26 Apr 2018 14:40:54 +0200 Subject: [PATCH 57/75] [VarDumper] Fix HtmlDumper classes match --- .../Component/VarDumper/Dumper/HtmlDumper.php | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/src/Symfony/Component/VarDumper/Dumper/HtmlDumper.php b/src/Symfony/Component/VarDumper/Dumper/HtmlDumper.php index c1263026b8c6..2ba7ebf57090 100644 --- a/src/Symfony/Component/VarDumper/Dumper/HtmlDumper.php +++ b/src/Symfony/Component/VarDumper/Dumper/HtmlDumper.php @@ -310,6 +310,9 @@ function xpathString(str) { return "concat(" + parts.join(",") + ", '')"; } + function xpathHasClass(className) { + return "contains(concat(' ', normalize-space(@class), ' '), ' " + className +" ')"; + } addEventListener(root, 'mouseover', function (e) { if ('' != refStyle.innerHTML) { refStyle.innerHTML = ''; @@ -516,7 +519,15 @@ function showCurrent(state) return; } - var xpathResult = doc.evaluate('//pre[@id="' + root.id + '"]//span[@class="sf-dump-str" or @class="sf-dump-key" or @class="sf-dump-public" or @class="sf-dump-protected" or @class="sf-dump-private"][contains(translate(child::text(), ' + xpathString(searchQuery.toUpperCase()) + ', ' + xpathString(searchQuery.toLowerCase()) + '), ' + xpathString(searchQuery.toLowerCase()) + ')]', document, null, XPathResult.ORDERED_NODE_ITERATOR_TYPE, null); + var classMatches = [ + "sf-dump-str", + "sf-dump-key", + "sf-dump-public", + "sf-dump-protected", + "sf-dump-private", + ].map(xpathHasClass).join(' or '); + + var xpathResult = doc.evaluate('.//span[' + classMatches + '][contains(translate(child::text(), ' + xpathString(searchQuery.toUpperCase()) + ', ' + xpathString(searchQuery.toLowerCase()) + '), ' + xpathString(searchQuery.toLowerCase()) + ')]', root, null, XPathResult.ORDERED_NODE_ITERATOR_TYPE, null); while (node = xpathResult.iterateNext()) state.nodes.push(node); From be8dbc36603d9aefc5d5f662df727819f010bbc9 Mon Sep 17 00:00:00 2001 From: Nicolas Grekas Date: Thu, 26 Apr 2018 13:28:24 +0200 Subject: [PATCH 58/75] [HttpKernel] Don't clean legacy containers that are still loaded --- src/Symfony/Component/HttpKernel/Kernel.php | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/Symfony/Component/HttpKernel/Kernel.php b/src/Symfony/Component/HttpKernel/Kernel.php index 0d68c4f7ff04..247bea208af8 100644 --- a/src/Symfony/Component/HttpKernel/Kernel.php +++ b/src/Symfony/Component/HttpKernel/Kernel.php @@ -670,9 +670,11 @@ protected function initializeContainer() // Because concurrent requests might still be using them, // old container files are not removed immediately, // but on a next dump of the container. + static $legacyContainers = array(); $oldContainerDir = dirname($oldContainer->getFileName()); - foreach (glob(dirname($oldContainerDir).'/*.legacy') as $legacyContainer) { - if ($oldContainerDir.'.legacy' !== $legacyContainer && @unlink($legacyContainer)) { + $legacyContainers[$oldContainerDir.'.legacy'] = true; + foreach (glob(dirname($oldContainerDir).DIRECTORY_SEPARATOR.'*.legacy') as $legacyContainer) { + if (!isset($legacyContainers[$legacyContainer]) && @unlink($legacyContainer)) { (new Filesystem())->remove(substr($legacyContainer, 0, -7)); } } From 43e733f8fe289b58a9e71b0b7a94c69925ad4356 Mon Sep 17 00:00:00 2001 From: Nicolas Grekas Date: Thu, 26 Apr 2018 17:59:35 +0200 Subject: [PATCH 59/75] [appveyor] use PHP 7.1 to run composer --- appveyor.yml | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/appveyor.yml b/appveyor.yml index cc1de26c5f8e..bd35af195d13 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -18,8 +18,8 @@ install: - mkdir c:\php && cd c:\php - appveyor DownloadFile https://raw.githubusercontent.com/symfony/binary-utils/master/cacert.pem - appveyor DownloadFile https://github.com/symfony/binary-utils/releases/download/v0.1/php-5.5.9-nts-Win32-VC11-x86.zip - - 7z x php-5.5.9-nts-Win32-VC11-x86.zip -y >nul - appveyor DownloadFile https://github.com/symfony/binary-utils/releases/download/v0.1/php-7.1.3-Win32-VC14-x86.zip + - 7z x php-7.1.3-Win32-VC14-x86.zip -y >nul - cd ext - appveyor DownloadFile https://github.com/symfony/binary-utils/releases/download/v0.1/php_apcu-4.0.10-5.5-nts-vc11-x86.zip - 7z x php_apcu-4.0.10-5.5-nts-vc11-x86.zip -y >nul @@ -45,19 +45,21 @@ install: - echo extension=php_pdo_sqlite.dll >> php.ini-max - echo extension=php_curl.dll >> php.ini-max - echo curl.cainfo=c:\php\cacert.pem >> php.ini-max - - copy /Y php.ini-max php.ini + - copy /Y php.ini-min php.ini + - echo extension=php_openssl.dll >> php.ini - cd c:\projects\symfony - IF NOT EXIST composer.phar (appveyor DownloadFile https://getcomposer.org/download/1.3.0/composer.phar) - php composer.phar self-update - copy /Y .composer\* %APPDATA%\Composer\ - php .github/build-packages.php "HEAD^" src\Symfony\Bridge\PhpUnit - IF %APPVEYOR_REPO_BRANCH%==master (SET COMPOSER_ROOT_VERSION=dev-master) ELSE (SET COMPOSER_ROOT_VERSION=%APPVEYOR_REPO_BRANCH%.x-dev) - - php -dmemory_limit=-1 composer.phar update --no-progress --no-suggest --ansi + - php composer.phar config platform.php 5.5.9 + - php composer.phar update --no-progress --no-suggest --ansi - php phpunit install test_script: - SET X=0 - - cd c:\php && 7z x php-7.1.3-Win32-VC14-x86.zip -y >nul && copy /Y php.ini-min php.ini + - cd c:\php && copy /Y php.ini-min php.ini - cd c:\projects\symfony - php phpunit src\Symfony --exclude-group benchmark,intl-data || SET X=!errorlevel! - cd c:\php && 7z x php-5.5.9-nts-Win32-VC11-x86.zip -y >nul && copy /Y php.ini-min php.ini From 79ffd31af818c1ad5584e5a7aef920b25d9dab49 Mon Sep 17 00:00:00 2001 From: Fabien Potencier Date: Fri, 27 Apr 2018 07:41:13 +0200 Subject: [PATCH 60/75] updated CHANGELOG for 2.7.46 --- CHANGELOG-2.7.md | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/CHANGELOG-2.7.md b/CHANGELOG-2.7.md index 6c8ff11ea85c..2f6ece9b9280 100644 --- a/CHANGELOG-2.7.md +++ b/CHANGELOG-2.7.md @@ -7,6 +7,19 @@ in 2.7 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/v2.7.0...v2.7.1 +* 2.7.46 (2018-04-27) + + * bug #26831 [Bridge/Doctrine] count(): Parameter must be an array or an object that implements Countable (gpenverne) + * bug #27044 [Security] Skip user checks if not implementing UserInterface (chalasr) + * bug #26910 Use new PHP7.2 functions in hasColorSupport (johnstevenson) + * bug #26999 [VarDumper] Fix dumping of SplObjectStorage (corphi) + * bug #26886 Don't assume that file binary exists on *nix OS (teohhanhui) + * bug #26643 Fix that ESI/SSI processing can turn a "private" response "public" (mpdude) + * bug #26932 [Form] Fixed trimming choice values (HeahDude) + * bug #26875 [Console] Don't go past exact matches when autocompleting (nicolas-grekas) + * bug #26823 [Validator] Fix LazyLoadingMetadataFactory with PSR6Cache for non classname if tested values isn't existing class (Pascal Montoya, pmontoya) + * bug #26834 [Yaml] Throw parse error on unfinished inline map (nicolas-grekas) + * 2.7.45 (2018-04-06) * bug #26763 [Finder] Remove duplicate slashes in filenames (helhum) From 029b182a5d611d7a07588ec3cf422d763e1f4d51 Mon Sep 17 00:00:00 2001 From: Fabien Potencier Date: Fri, 27 Apr 2018 07:41:29 +0200 Subject: [PATCH 61/75] update CONTRIBUTORS for 2.7.46 --- CONTRIBUTORS.md | 68 +++++++++++++++++++++++++++++++------------------ 1 file changed, 43 insertions(+), 25 deletions(-) diff --git a/CONTRIBUTORS.md b/CONTRIBUTORS.md index 57bd22e5c521..bc4ebf6f7813 100644 --- a/CONTRIBUTORS.md +++ b/CONTRIBUTORS.md @@ -13,8 +13,8 @@ Symfony is the result of the work of many people who made the code better - Jordi Boggiano (seldaek) - Victor Berchet (victor) - Kévin Dunglas (dunglas) - - Johannes S (johannes) - Robin Chalas (chalas_r) + - Johannes S (johannes) - Jakub Zalas (jakubzalas) - Kris Wallsmith (kriswallsmith) - Ryan Weaver (weaverryan) @@ -26,8 +26,8 @@ Symfony is the result of the work of many people who made the code better - Romain Neutron (romain) - Pascal Borreli (pborreli) - Wouter De Jong (wouterj) - - Joseph Bielawski (stloyd) - Roland Franssen (ro0) + - Joseph Bielawski (stloyd) - Karma Dordrak (drak) - Lukas Kahwe Smith (lsmith) - Martin Hasoň (hason) @@ -39,32 +39,32 @@ Symfony is the result of the work of many people who made the code better - Eriksen Costa (eriksencosta) - Guilhem Niot (energetick) - Sarah Khalil (saro0h) + - Samuel ROZE (sroze) - Jonathan Wage (jwage) - Hamza Amrouche (simperfit) - Diego Saint Esteben (dosten) + - Yonel Ceruto (yonelceruto) - Alexandre Salomé (alexandresalome) + - Iltar van der Berg (kjarli) - William Durand (couac) - ornicar - Francis Besset (francisbesset) - - Iltar van der Berg (kjarli) - stealth35 ‏ (stealth35) - Alexander Mols (asm89) - - Samuel ROZE (sroze) - - Yonel Ceruto (yonelceruto) - Bulat Shakirzyanov (avalanche123) - Peter Rehm (rpet) - - Saša Stamenković (umpirsky) - Matthias Pigulla (mpdude) + - Saša Stamenković (umpirsky) - Pierre du Plessis (pierredup) - Henrik Bjørnskov (henrikbjorn) - Dany Maillard (maidmaid) - Miha Vrhovnik - Tobias Nyholm (tobias) - Diego Saint Esteben (dii3g0) - - Konstantin Kudryashov (everzet) - Kevin Bond (kbond) - - Bilal Amarni (bamarni) + - Konstantin Kudryashov (everzet) - Alexander M. Turek (derrabus) + - Bilal Amarni (bamarni) - Jérémy DERUSSÉ (jderusse) - Florin Patan (florinpatan) - Mathieu Piot (mpiot) @@ -88,28 +88,28 @@ Symfony is the result of the work of many people who made the code better - Luis Cordova (cordoval) - Graham Campbell (graham) - Daniel Holmes (dholmes) + - David Maicher (dmaicher) - Dariusz Ruminski - Toni Uebernickel (havvg) - Bart van den Burg (burgov) - Jordan Alliot (jalliot) - Jérôme Tamarelle (gromnan) - John Wards (johnwards) - - David Maicher (dmaicher) - Fran Moreno (franmomu) + - Vladimir Reznichenko (kalessil) - Antoine Hérault (herzult) - Paráda József (paradajozsef) - - Vladimir Reznichenko (kalessil) - Arnaud Le Blanc (arnaud-lb) - Maxime STEINHAUSSER - Michal Piotrowski (eventhorizon) - Tim Nagel (merk) - Brice BERNARD (brikou) - Baptiste Clavié (talus) + - Grégoire Paris (greg0ire) - marc.weistroff - lenar - Alexander Schwenn (xelaris) - Włodzimierz Gajda (gajdaw) - - Grégoire Paris (greg0ire) - Jacob Dreesen (jdreesen) - Florian Voutzinos (florianv) - Colin Frei @@ -122,17 +122,17 @@ Symfony is the result of the work of many people who made the code better - Fabien Pennequin (fabienpennequin) - Gordon Franke (gimler) - Eric GELOEN (gelo) + - Lars Strojny (lstrojny) - Daniel Wehner (dawehner) - Tugdual Saunier (tucksaun) + - Javier Spagnoletti (phansys) - Théo FIDRY (theofidry) - Robert Schönthal (digitalkaoz) - Florian Lonqueu-Brochard (florianlb) - Sebastiaan Stok (sstok) - Stefano Sala (stefano.sala) - Evgeniy (ewgraf) - - Lars Strojny (lstrojny) - Alex Pott - - Javier Spagnoletti (phansys) - Vincent AUBERT (vincent) - Juti Noppornpitak (shiroyuki) - Tigran Azatyan (tigranazatyan) @@ -150,6 +150,7 @@ Symfony is the result of the work of many people who made the code better - Arnaud Kleinpeter (nanocom) - gadelat (gadelat) - jwdeitch + - Teoh Han Hui (teohhanhui) - Mikael Pajunen - Joel Wurtz (brouznouf) - Valentin Udaltsov (vudaltsov) @@ -160,7 +161,6 @@ Symfony is the result of the work of many people who made the code better - Richard Shank (iampersistent) - Thomas Rabaix (rande) - Rouven Weßling (realityking) - - Teoh Han Hui (teohhanhui) - Clemens Tolboom - Helmer Aaviksoo - Hiromi Hishida (77web) @@ -186,6 +186,7 @@ Symfony is the result of the work of many people who made the code better - Gabriel Ostrolucký - Mario A. Alvarez Garcia (nomack84) - Dennis Benkert (denderello) + - DQNEO - SpacePossum - Benjamin Dulau (dbenjamin) - Mathieu Lemoine (lemoinem) @@ -223,6 +224,7 @@ Symfony is the result of the work of many people who made the code better - Niels Keurentjes (curry684) - Eugene Wissner - Julien Brochet (mewt) + - Leo Feyer - Tristan Darricau (nicofuma) - Michaël Perrin (michael.perrin) - Marcel Beerta (mazen) @@ -269,7 +271,6 @@ Symfony is the result of the work of many people who made the code better - Ray - Tyson Andre - Nikolay Labinskiy (e-moe) - - Leo Feyer - Chekote - Thomas Adam - Albert Casademont (acasademont) @@ -277,7 +278,6 @@ Symfony is the result of the work of many people who made the code better - Jhonny Lidfors (jhonne) - Diego Agulló (aeoris) - Andreas Schempp (aschempp) - - DQNEO - jdhoek - Pavel Batanov (scaytrase) - Bob den Otter (bopp) @@ -300,6 +300,7 @@ Symfony is the result of the work of many people who made the code better - Michael Holm (hollo) - Marc Weistroff (futurecat) - Christian Schmidt + - Maxime Veber (nek-) - Edi Modrić (emodric) - Chad Sikorra (chadsikorra) - Chris Smith (cs278) @@ -327,6 +328,7 @@ Symfony is the result of the work of many people who made the code better - John Bafford (jbafford) - Adrian Rudnik (kreischweide) - Francesc Rosàs (frosas) + - Romain Pierre (romain-pierre) - Massimiliano Arione (garak) - Julien Galenski (ruian) - Bongiraud Dominique @@ -357,8 +359,8 @@ Symfony is the result of the work of many people who made the code better - Damien Alexandre (damienalexandre) - Felix Labrecque - Yaroslav Kiliba - - Maxime Veber (nek-) - Terje Bråten + - Mathieu Lechat - Robbert Klarenbeek (robbertkl) - JhonnyL - David Badura (davidbadura) @@ -372,6 +374,7 @@ Symfony is the result of the work of many people who made the code better - Philipp Kräutli (pkraeutli) - Kirill chEbba Chebunin (chebba) - Greg Thornton (xdissent) + - Gary PEGEOT (gary-p) - Costin Bereveanu (schniper) - Loïc Chardonnet (gnusat) - Marek Kalnik (marekkalnik) @@ -421,9 +424,11 @@ Symfony is the result of the work of many people who made the code better - Jeanmonod David (jeanmonod) - Christopher Davis (chrisguitarguy) - Jan Schumann + - Christian Schmidt - Niklas Fiekas - Markus Bachmann (baachi) - lancergr + - Zan Baldwin - Mihai Stancu - Olivier Dolbeau (odolbeau) - Jan Rosier (rosier) @@ -438,6 +443,7 @@ Symfony is the result of the work of many people who made the code better - Andreas Braun - Boris Vujicic (boris.vujicic) - Chris Sedlmayr (catchamonkey) + - Mateusz Sip (mateusz_sip) - Seb Koelen - Christoph Mewes (xrstf) - Vitaliy Tverdokhlib (vitaliytv) @@ -458,6 +464,7 @@ Symfony is the result of the work of many people who made the code better - Adam Harvey - Anton Bakai - Alex Bakhturin + - insekticid - Alexander Obuhovich (aik099) - boombatower - Fabrice Bernhard (fabriceb) @@ -503,7 +510,6 @@ Symfony is the result of the work of many people who made the code better - alexpods - Arjen van der Meijden - Dariusz Ruminski - - Mathieu Lechat - Erik Trapman (eriktrapman) - De Cock Xavier (xdecock) - Almog Baku (almogbaku) @@ -552,7 +558,6 @@ Symfony is the result of the work of many people who made the code better - Disquedur - Michiel Boeckaert (milio) - Geoffrey Tran (geoff) - - Romain Pierre (romain-pierre) - David Prévot - Jan Behrens - Mantas Var (mvar) @@ -566,7 +571,6 @@ Symfony is the result of the work of many people who made the code better - aubx - Marvin Butkereit - Ricky Su (ricky) - - Zan Baldwin - Gildas Quéméner (gquemener) - Charles-Henri Bruyand - Max Rath (drak3) @@ -579,6 +583,7 @@ Symfony is the result of the work of many people who made the code better - Andre Rømcke (andrerom) - Nahuel Cuesta (ncuesta) - Chris Boden (cboden) + - Christophe Villeger (seragan) - Stefan Gehrig (sgehrig) - Hany el-Kerdany - Wang Jingyu @@ -590,13 +595,13 @@ Symfony is the result of the work of many people who made the code better - Javier López (loalf) - Reinier Kip - Geoffrey Brier (geoffrey-brier) + - Vladimir Tsykun - Dustin Dobervich (dustin10) - dantleech - Anne-Sophie Bachelard (annesophie) - Sebastian Marek (proofek) - Erkhembayar Gantulga (erheme318) - Michal Trojanowski - - Mateusz Sip - David Fuhr - Kamil Kokot (pamil) - Aurimas Niekis (gcds) @@ -673,7 +678,6 @@ Symfony is the result of the work of many people who made the code better - twifty - Indra Gunawan (guind) - Peter Ward - - insekticid - Julien DIDIER (juliendidier) - Dominik Ritter (dritter) - Sebastian Grodzicki (sgrodzicki) @@ -880,6 +884,7 @@ Symfony is the result of the work of many people who made the code better - Sander Marechal - Radosław Benkel - jean pasqualini (darkilliant) + - Ross Motley (rossmotley) - ttomor - Mei Gwilym (meigwilym) - Michael H. Arieli (excelwebzone) @@ -899,6 +904,7 @@ Symfony is the result of the work of many people who made the code better - Zachary Tong (polyfractal) - Ashura - Hryhorii Hrebiniuk + - johnstevenson - Dennis Fridrich (dfridrich) - hamza - dantleech @@ -942,6 +948,7 @@ Symfony is the result of the work of many people who made the code better - mlazovla - Max Beutel - Antanas Arvasevicius + - Thomas - Maximilian Berghoff (electricmaxxx) - nacho - Piotr Antosik (antek88) @@ -1085,6 +1092,7 @@ Symfony is the result of the work of many people who made the code better - Tobias Stöckler - Mario Young - Ilia (aliance) + - Grégoire Penverne (gpenverne) - Mo Di (modi) - Pablo Schläpfer - Jelte Steijaert (jelte) @@ -1105,6 +1113,7 @@ Symfony is the result of the work of many people who made the code better - Lars Ambrosius Wallenborn (larsborn) - Oriol Mangas Abellan (oriolman) - Sebastian Göttschkes (sgoettschkes) + - Sergey (upyx) - Tatsuya Tsuruoka - Ross Tuck - Kévin Gomez (kevin) @@ -1128,6 +1137,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) + - abluchet - Matthieu - Albin Kerouaton - Sébastien HOUZÉ @@ -1144,6 +1154,7 @@ Symfony is the result of the work of many people who made the code better - Andy Raines - Anthony Ferrara - Klaas Cuvelier (kcuvelier) + - Mathieu TUDISCO (mathieutu) - markusu49 - Steve Frécinaux - Jules Lamur @@ -1186,6 +1197,7 @@ Symfony is the result of the work of many people who made the code better - Tadcka - Beth Binkovitz - Gonzalo Míguez + - Philipp Cordes - Pierre Rineau - Romain Geissler - Adrien Moiruad @@ -1198,6 +1210,7 @@ Symfony is the result of the work of many people who made the code better - Jay Severson - René Kerner - Nathaniel Catchpole + - - Adrien Samson (adriensamson) - Samuel Gordalina (gordalina) - Max Romanovsky (maxromanovsky) @@ -1246,6 +1259,7 @@ Symfony is the result of the work of many people who made the code better - Simon Neidhold - Valentin VALCIU - Jeremiah VALERIE + - Julien Menth - Kevin Dew - James Cowgill - 1ma (jautenim) @@ -1302,7 +1316,6 @@ Symfony is the result of the work of many people who made the code better - ryunosuke - zenmate - victoria - - Christian Schmidt - Francisco Facioni (fran6co) - Iwan van Staveren (istaveren) - Povilas S. (povilas) @@ -1379,10 +1392,13 @@ Symfony is the result of the work of many people who made the code better - Oleksii Zhurbytskyi - Andy Stanberry - Felix Marezki + - Normunds - Luiz “Felds” Liscia - Thomas Rothe - nietonfir - alefranz + - David Barratt + - Pavel.Batanov - avi123 - alsar - Aarón Nieves Fernández @@ -1612,6 +1628,7 @@ Symfony is the result of the work of many people who made the code better - Gabriel Moreira - Alexey Popkov - ChS + - Alexis MARQUIS - Joseph Deray - Damian Sromek - Ben @@ -1654,12 +1671,12 @@ Symfony is the result of the work of many people who made the code better - jc - BenjaminBeck - Aurelijus Rožėnas - - Vladimir Tsykun - Jordan Hoff - znerol - Christian Eikermann - Kai Eichinger - Antonio Angelino + - Pascal Montoya - Matt Fields - Niklas Keller - Vladimir Sazhin @@ -1814,6 +1831,7 @@ Symfony is the result of the work of many people who made the code better - Arash Tabriziyan (ghost098) - ibasaw (ibasaw) - Vladislav Krupenkin (ideea) + - Peter Orosz (ill_logical) - Imangazaliev Muhammad (imangazaliev) - j0k (j0k) - joris de wit (jdewit) @@ -1862,7 +1880,6 @@ Symfony is the result of the work of many people who made the code better - scourgen hung (scourgen) - Sébastien Alfaiate (seb33300) - Sebastian Busch (sebu) - - Christophe Villeger (seragan) - André Filipe Gonçalves Neves (seven) - Bruno Ziegler (sfcoder) - Andrea Giuliano (shark) @@ -1908,6 +1925,7 @@ Symfony is the result of the work of many people who made the code better - Zander Baldwin - Philipp Scheit - max + - Ahmad Mayahi (ahmadmayahi) - Mohamed Karnichi (amiral) - Andrew Carter (andrewcarteruk) - Adam Elsodaney (archfizz) From 436fd79a205d35a0a78e0f9886ddb43f2ef2184d Mon Sep 17 00:00:00 2001 From: Fabien Potencier Date: Fri, 27 Apr 2018 07:41:32 +0200 Subject: [PATCH 62/75] updated VERSION for 2.7.46 --- src/Symfony/Component/HttpKernel/Kernel.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Symfony/Component/HttpKernel/Kernel.php b/src/Symfony/Component/HttpKernel/Kernel.php index 1b8abba1474d..43a441fbe25d 100644 --- a/src/Symfony/Component/HttpKernel/Kernel.php +++ b/src/Symfony/Component/HttpKernel/Kernel.php @@ -58,12 +58,12 @@ abstract class Kernel implements KernelInterface, TerminableInterface protected $startTime; protected $loadClassCache; - const VERSION = '2.7.46-DEV'; + const VERSION = '2.7.46'; const VERSION_ID = 20746; const MAJOR_VERSION = 2; const MINOR_VERSION = 7; const RELEASE_VERSION = 46; - const EXTRA_VERSION = 'DEV'; + const EXTRA_VERSION = ''; const END_OF_MAINTENANCE = '05/2018'; const END_OF_LIFE = '05/2019'; From 212c469ebfbbd2d38981eef123b75cb7e4159cc5 Mon Sep 17 00:00:00 2001 From: Nicolas Grekas Date: Sun, 22 Apr 2018 21:20:57 +0200 Subject: [PATCH 63/75] [Cache] TagAwareAdapterInterface::invalidateTags() should commit deferred items --- .../Cache/Adapter/TagAwareAdapter.php | 123 ++++++++++++------ .../Tests/Adapter/TagAwareAdapterTest.php | 16 +++ 2 files changed, 97 insertions(+), 42 deletions(-) diff --git a/src/Symfony/Component/Cache/Adapter/TagAwareAdapter.php b/src/Symfony/Component/Cache/Adapter/TagAwareAdapter.php index a71b903d734f..67f9477ae363 100644 --- a/src/Symfony/Component/Cache/Adapter/TagAwareAdapter.php +++ b/src/Symfony/Component/Cache/Adapter/TagAwareAdapter.php @@ -33,11 +33,14 @@ class TagAwareAdapter implements TagAwareAdapterInterface, PruneableInterface, R private $getTagsByKey; private $invalidateTags; private $tags; + private $knownTagVersions = array(); + private $knownTagVersionsTtl; - public function __construct(AdapterInterface $itemsPool, AdapterInterface $tagsPool = null) + public function __construct(AdapterInterface $itemsPool, AdapterInterface $tagsPool = null, $knownTagVersionsTtl = 0.15) { $this->pool = $itemsPool; $this->tags = $tagsPool ?: $itemsPool; + $this->knownTagVersionsTtl = $knownTagVersionsTtl; $this->createCacheItem = \Closure::bind( function ($key, $value, CacheItem $protoItem) { $item = new CacheItem(); @@ -87,8 +90,7 @@ function ($deferred) { ); $this->invalidateTags = \Closure::bind( function (AdapterInterface $tagsAdapter, array $tags) { - foreach ($tagsAdapter->getItems($tags) as $v) { - $v->set(1 + (int) $v->get()); + foreach ($tags as $v) { $v->defaultLifetime = 0; $v->expiry = null; $tagsAdapter->saveDeferred($v); @@ -106,14 +108,42 @@ function (AdapterInterface $tagsAdapter, array $tags) { */ public function invalidateTags(array $tags) { - foreach ($tags as $k => $tag) { - if ('' !== $tag && \is_string($tag)) { - $tags[$k] = $tag.static::TAGS_PREFIX; + $ok = true; + $tagsByKey = array(); + $invalidatedTags = array(); + foreach ($tags as $tag) { + CacheItem::validateKey($tag); + $invalidatedTags[$tag] = 0; + } + + if ($this->deferred) { + $items = $this->deferred; + foreach ($items as $key => $item) { + if (!$this->pool->saveDeferred($item)) { + unset($this->deferred[$key]); + $ok = false; + } } + + $f = $this->getTagsByKey; + $tagsByKey = $f($items); + $this->deferred = array(); + } + + $tagVersions = $this->getTagVersions($tagsByKey, $invalidatedTags); + $f = $this->createCacheItem; + + foreach ($tagsByKey as $key => $tags) { + $this->pool->saveDeferred($f(static::TAGS_PREFIX.$key, array_intersect_key($tagVersions, $tags), $items[$key])); + } + $ok = $this->pool->commit() && $ok; + + if ($invalidatedTags) { + $f = $this->invalidateTags; + $ok = $f($this->tags, $invalidatedTags) && $ok; } - $f = $this->invalidateTags; - return $f($this->tags, $tags); + return $ok; } /** @@ -132,7 +162,7 @@ public function hasItem($key) } foreach ($this->getTagVersions(array($itemTags)) as $tag => $version) { - if ($itemTags[$tag] !== $version) { + if ($itemTags[$tag] !== $version && 1 !== $itemTags[$tag] - $version) { return false; } } @@ -241,29 +271,7 @@ public function saveDeferred(CacheItemInterface $item) */ public function commit() { - $ok = true; - - if ($this->deferred) { - $items = $this->deferred; - foreach ($items as $key => $item) { - if (!$this->pool->saveDeferred($item)) { - unset($this->deferred[$key]); - $ok = false; - } - } - - $f = $this->getTagsByKey; - $tagsByKey = $f($items); - $this->deferred = array(); - $tagVersions = $this->getTagVersions($tagsByKey); - $f = $this->createCacheItem; - - foreach ($tagsByKey as $key => $tags) { - $this->pool->saveDeferred($f(static::TAGS_PREFIX.$key, array_intersect_key($tagVersions, $tags), $items[$key])); - } - } - - return $this->pool->commit() && $ok; + return $this->invalidateTags(array()); } public function __destruct() @@ -294,7 +302,7 @@ private function generateItems($items, array $tagKeys) foreach ($itemTags as $key => $tags) { foreach ($tags as $tag => $version) { - if ($tagVersions[$tag] !== $version) { + if ($tagVersions[$tag] !== $version && 1 !== $version - $tagVersions[$tag]) { unset($itemTags[$key]); continue 2; } @@ -310,23 +318,54 @@ private function generateItems($items, array $tagKeys) } } - private function getTagVersions(array $tagsByKey) + private function getTagVersions(array $tagsByKey, array &$invalidatedTags = array()) { - $tagVersions = array(); + $tagVersions = $invalidatedTags; foreach ($tagsByKey as $tags) { $tagVersions += $tags; } - if ($tagVersions) { - $tags = array(); - foreach ($tagVersions as $tag => $version) { - $tagVersions[$tag] = $tag.static::TAGS_PREFIX; - $tags[$tag.static::TAGS_PREFIX] = $tag; + if (!$tagVersions) { + return array(); + } + + if (!$fetchTagVersions = 1 !== \func_num_args()) { + foreach ($tagsByKey as $tags) { + foreach ($tags as $tag => $version) { + if ($tagVersions[$tag] > $version) { + $tagVersions[$tag] = $version; + } + } + } + } + + $now = microtime(true); + $tags = array(); + foreach ($tagVersions as $tag => $version) { + $tags[$tag.static::TAGS_PREFIX] = $tag; + if ($fetchTagVersions || !isset($this->knownTagVersions[$tag])) { + continue; + } + $version -= $this->knownTagVersions[$tag][1]; + if ((0 !== $version && 1 !== $version) || $this->knownTagVersionsTtl > $now - $this->knownTagVersions[$tag][0]) { + // reuse previously fetched tag versions up to the ttl, unless we are storing items or a potential miss arises + $fetchTagVersions = true; + } else { + $this->knownTagVersions[$tag][1] += $version; } - foreach ($this->tags->getItems($tagVersions) as $tag => $version) { - $tagVersions[$tags[$tag]] = $version->get() ?: 0; + } + + if (!$fetchTagVersions) { + return $tagVersions; + } + + foreach ($this->tags->getItems(array_keys($tags)) as $tag => $version) { + $tagVersions[$tag = $tags[$tag]] = $version->get() ?: 0; + if (isset($invalidatedTags[$tag])) { + $invalidatedTags[$tag] = $version->set(++$tagVersions[$tag]); } + $this->knownTagVersions[$tag] = array($now, $tagVersions[$tag]); } return $tagVersions; diff --git a/src/Symfony/Component/Cache/Tests/Adapter/TagAwareAdapterTest.php b/src/Symfony/Component/Cache/Tests/Adapter/TagAwareAdapterTest.php index 0e4e07a16d51..094fa9558bfd 100644 --- a/src/Symfony/Component/Cache/Tests/Adapter/TagAwareAdapterTest.php +++ b/src/Symfony/Component/Cache/Tests/Adapter/TagAwareAdapterTest.php @@ -71,6 +71,22 @@ public function testInvalidateTags() $this->assertTrue($pool->getItem('foo')->isHit()); } + public function testInvalidateCommits() + { + $pool1 = $this->createCachePool(); + + $foo = $pool1->getItem('foo'); + $foo->tag('tag'); + + $pool1->saveDeferred($foo->set('foo')); + $pool1->invalidateTags(array('tag')); + + $pool2 = $this->createCachePool(); + $foo = $pool2->getItem('foo'); + + $this->assertTrue($foo->isHit()); + } + public function testTagsAreCleanedOnSave() { $pool = $this->createCachePool(); From 64a0f23affd4646983aca7e96daf44ef236df8d7 Mon Sep 17 00:00:00 2001 From: Nikolay Labinskiy Date: Thu, 26 Apr 2018 17:44:59 +0300 Subject: [PATCH 64/75] Fix #27011: Session ini_set bug --- .../Session/Storage/NativeSessionStorage.php | 6 +++--- .../Storage/NativeSessionStorageTest.php | 17 +++++++++++++++++ 2 files changed, 20 insertions(+), 3 deletions(-) diff --git a/src/Symfony/Component/HttpFoundation/Session/Storage/NativeSessionStorage.php b/src/Symfony/Component/HttpFoundation/Session/Storage/NativeSessionStorage.php index f03cdf343024..34d94c55bcc9 100644 --- a/src/Symfony/Component/HttpFoundation/Session/Storage/NativeSessionStorage.php +++ b/src/Symfony/Component/HttpFoundation/Session/Storage/NativeSessionStorage.php @@ -340,7 +340,7 @@ public function setOptions(array $options) } $validOptions = array_flip(array( - 'cache_limiter', 'cookie_domain', 'cookie_httponly', + 'cache_expire', 'cache_limiter', 'cookie_domain', 'cookie_httponly', 'cookie_lifetime', 'cookie_path', 'cookie_secure', 'entropy_file', 'entropy_length', 'gc_divisor', 'gc_maxlifetime', 'gc_probability', 'hash_bits_per_character', @@ -348,13 +348,13 @@ public function setOptions(array $options) 'serialize_handler', 'use_strict_mode', 'use_cookies', 'use_only_cookies', 'use_trans_sid', 'upload_progress.enabled', 'upload_progress.cleanup', 'upload_progress.prefix', 'upload_progress.name', - 'upload_progress.freq', 'upload_progress.min-freq', 'url_rewriter.tags', + 'upload_progress.freq', 'upload_progress.min_freq', 'url_rewriter.tags', 'sid_length', 'sid_bits_per_character', 'trans_sid_hosts', 'trans_sid_tags', )); foreach ($options as $key => $value) { if (isset($validOptions[$key])) { - ini_set('session.'.$key, $value); + ini_set('url_rewriter.tags' !== $key ? 'session.'.$key : $key, $value); } } } diff --git a/src/Symfony/Component/HttpFoundation/Tests/Session/Storage/NativeSessionStorageTest.php b/src/Symfony/Component/HttpFoundation/Tests/Session/Storage/NativeSessionStorageTest.php index 3501f74784a9..529583c01aad 100644 --- a/src/Symfony/Component/HttpFoundation/Tests/Session/Storage/NativeSessionStorageTest.php +++ b/src/Symfony/Component/HttpFoundation/Tests/Session/Storage/NativeSessionStorageTest.php @@ -183,6 +183,23 @@ public function testCookieOptions() $this->assertEquals($options, $gco); } + public function testSessionOptions() + { + if (defined('HHVM_VERSION')) { + $this->markTestSkipped('HHVM is not handled in this test case.'); + } + + $options = array( + 'url_rewriter.tags' => 'a=href', + 'cache_expire' => '200', + ); + + $this->getStorage($options); + + $this->assertSame('a=href', ini_get('url_rewriter.tags')); + $this->assertSame('200', ini_get('session.cache_expire')); + } + /** * @expectedException \InvalidArgumentException */ From aa05f055262afa8531b1261ce9ae7a3fc5c5a73c Mon Sep 17 00:00:00 2001 From: Fabien Potencier Date: Fri, 27 Apr 2018 11:17:42 +0200 Subject: [PATCH 65/75] bumped Symfony version to 2.7.47 --- src/Symfony/Component/HttpKernel/Kernel.php | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/Symfony/Component/HttpKernel/Kernel.php b/src/Symfony/Component/HttpKernel/Kernel.php index 43a441fbe25d..33bbddabc9ef 100644 --- a/src/Symfony/Component/HttpKernel/Kernel.php +++ b/src/Symfony/Component/HttpKernel/Kernel.php @@ -58,12 +58,12 @@ abstract class Kernel implements KernelInterface, TerminableInterface protected $startTime; protected $loadClassCache; - const VERSION = '2.7.46'; - const VERSION_ID = 20746; + const VERSION = '2.7.47-DEV'; + const VERSION_ID = 20747; const MAJOR_VERSION = 2; const MINOR_VERSION = 7; - const RELEASE_VERSION = 46; - const EXTRA_VERSION = ''; + const RELEASE_VERSION = 47; + const EXTRA_VERSION = 'DEV'; const END_OF_MAINTENANCE = '05/2018'; const END_OF_LIFE = '05/2019'; From fc693078652aad47c5fb12c585789a0eaf11a806 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gr=C3=A9goire=20Paris?= Date: Sun, 29 Apr 2018 10:04:33 +0200 Subject: [PATCH 66/75] Add an implementation just for php 7.0 php 7 does not have the void return type. --- .../Bridge/PhpUnit/Legacy/TestRunnerForV6.php | 2 +- .../Bridge/PhpUnit/Legacy/TestRunnerForV7.php | 49 +++++++++++++++++++ .../Bridge/PhpUnit/TextUI/TestRunner.php | 4 +- 3 files changed, 53 insertions(+), 2 deletions(-) create mode 100644 src/Symfony/Bridge/PhpUnit/Legacy/TestRunnerForV7.php diff --git a/src/Symfony/Bridge/PhpUnit/Legacy/TestRunnerForV6.php b/src/Symfony/Bridge/PhpUnit/Legacy/TestRunnerForV6.php index d709b873874f..6da7c6544853 100644 --- a/src/Symfony/Bridge/PhpUnit/Legacy/TestRunnerForV6.php +++ b/src/Symfony/Bridge/PhpUnit/Legacy/TestRunnerForV6.php @@ -24,7 +24,7 @@ class TestRunnerForV6 extends BaseRunner /** * {@inheritdoc} */ - protected function handleConfiguration(array &$arguments): void + protected function handleConfiguration(array &$arguments) { $listener = new SymfonyTestsListener(); diff --git a/src/Symfony/Bridge/PhpUnit/Legacy/TestRunnerForV7.php b/src/Symfony/Bridge/PhpUnit/Legacy/TestRunnerForV7.php new file mode 100644 index 000000000000..a175fb65d7f5 --- /dev/null +++ b/src/Symfony/Bridge/PhpUnit/Legacy/TestRunnerForV7.php @@ -0,0 +1,49 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Bridge\PhpUnit\Legacy; + +use PHPUnit\TextUI\TestRunner as BaseRunner; +use Symfony\Bridge\PhpUnit\SymfonyTestsListener; + +/** + * {@inheritdoc} + * + * @internal + */ +class TestRunnerForV7 extends BaseRunner +{ + /** + * {@inheritdoc} + */ + protected function handleConfiguration(array &$arguments): void + { + $listener = new SymfonyTestsListener(); + + parent::handleConfiguration($arguments); + + $arguments['listeners'] = isset($arguments['listeners']) ? $arguments['listeners'] : array(); + + $registeredLocally = false; + + foreach ($arguments['listeners'] as $registeredListener) { + if ($registeredListener instanceof SymfonyTestsListener) { + $registeredListener->globalListenerDisabled(); + $registeredLocally = true; + break; + } + } + + if (!$registeredLocally) { + $arguments['listeners'][] = $listener; + } + } +} diff --git a/src/Symfony/Bridge/PhpUnit/TextUI/TestRunner.php b/src/Symfony/Bridge/PhpUnit/TextUI/TestRunner.php index af1abd386678..7b8d162e5336 100644 --- a/src/Symfony/Bridge/PhpUnit/TextUI/TestRunner.php +++ b/src/Symfony/Bridge/PhpUnit/TextUI/TestRunner.php @@ -13,8 +13,10 @@ if (class_exists('PHPUnit_Runner_Version') && version_compare(\PHPUnit_Runner_Version::id(), '6.0.0', '<')) { class_alias('Symfony\Bridge\PhpUnit\Legacy\TestRunnerForV5', 'Symfony\Bridge\PhpUnit\TextUI\TestRunner'); -} else { +} elseif (class_exists('PHPUnit_Runner_Version') && version_compare(\PHPUnit_Runner_Version::id(), '7.0.0', '<')) { class_alias('Symfony\Bridge\PhpUnit\Legacy\TestRunnerForV6', 'Symfony\Bridge\PhpUnit\TextUI\TestRunner'); +} else { + class_alias('Symfony\Bridge\PhpUnit\Legacy\TestRunnerForV7', 'Symfony\Bridge\PhpUnit\TextUI\TestRunner'); } if (false) { From 309da927e3aaa5ae7c50ed48f3bc3cc2a68af0e6 Mon Sep 17 00:00:00 2001 From: Ryan Weaver Date: Sun, 29 Apr 2018 10:04:08 -0400 Subject: [PATCH 67/75] Avoiding an error when an unused service has a missing base class This mirrors what was already done in AutowirePass --- .../Compiler/ResolveBindingsPass.php | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/src/Symfony/Component/DependencyInjection/Compiler/ResolveBindingsPass.php b/src/Symfony/Component/DependencyInjection/Compiler/ResolveBindingsPass.php index 63f2a470bac6..024523e15585 100644 --- a/src/Symfony/Component/DependencyInjection/Compiler/ResolveBindingsPass.php +++ b/src/Symfony/Component/DependencyInjection/Compiler/ResolveBindingsPass.php @@ -15,6 +15,7 @@ use Symfony\Component\DependencyInjection\ContainerBuilder; use Symfony\Component\DependencyInjection\Definition; use Symfony\Component\DependencyInjection\Exception\InvalidArgumentException; +use Symfony\Component\DependencyInjection\Exception\RuntimeException; use Symfony\Component\DependencyInjection\LazyProxy\ProxyHelper; use Symfony\Component\DependencyInjection\TypedReference; use Symfony\Component\DependencyInjection\Reference; @@ -88,8 +89,14 @@ protected function processValue($value, $isRoot = false) $calls = $value->getMethodCalls(); - if ($constructor = $this->getConstructor($value, false)) { - $calls[] = array($constructor, $value->getArguments()); + try { + if ($constructor = $this->getConstructor($value, false)) { + $calls[] = array($constructor, $value->getArguments()); + } + } catch (RuntimeException $e) { + $this->container->getDefinition($this->currentId)->addError($e->getMessage()); + + return parent::processValue($value, $isRoot); } foreach ($calls as $i => $call) { From 93a9bd39b2b8cb19b9d2b4985207f87c93de3462 Mon Sep 17 00:00:00 2001 From: Philipp Cordes Date: Sun, 29 Apr 2018 16:44:26 +0200 Subject: [PATCH 68/75] PhpDoc: There is no attempt to create the directory --- src/Symfony/Component/Lock/Store/FlockStore.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Symfony/Component/Lock/Store/FlockStore.php b/src/Symfony/Component/Lock/Store/FlockStore.php index 5babc7f610bc..287d6fb58316 100644 --- a/src/Symfony/Component/Lock/Store/FlockStore.php +++ b/src/Symfony/Component/Lock/Store/FlockStore.php @@ -34,7 +34,7 @@ class FlockStore implements StoreInterface /** * @param string|null $lockPath the directory to store the lock, defaults to the system's temporary directory * - * @throws LockStorageException If the lock directory could not be created or is not writable + * @throws LockStorageException If the lock directory doesn’t exist or is not writable */ public function __construct($lockPath = null) { From f0affb72926bcd20aab28bf4b444c2d69e67a143 Mon Sep 17 00:00:00 2001 From: Nicolas Grekas Date: Sun, 29 Apr 2018 18:19:41 -0700 Subject: [PATCH 69/75] Fix suggest.psr/*-implementation in composer.json files --- src/Symfony/Component/Console/composer.json | 2 +- src/Symfony/Component/Templating/composer.json | 2 +- src/Symfony/Component/Translation/composer.json | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/Symfony/Component/Console/composer.json b/src/Symfony/Component/Console/composer.json index c4fb8c192a40..9f6355986181 100644 --- a/src/Symfony/Component/Console/composer.json +++ b/src/Symfony/Component/Console/composer.json @@ -27,7 +27,7 @@ "suggest": { "symfony/event-dispatcher": "", "symfony/process": "", - "psr/log": "For using the console logger" + "psr/log-implementation": "For using the console logger" }, "autoload": { "psr-4": { "Symfony\\Component\\Console\\": "" }, diff --git a/src/Symfony/Component/Templating/composer.json b/src/Symfony/Component/Templating/composer.json index 74f441262332..334909c1a3a6 100644 --- a/src/Symfony/Component/Templating/composer.json +++ b/src/Symfony/Component/Templating/composer.json @@ -22,7 +22,7 @@ "psr/log": "~1.0" }, "suggest": { - "psr/log": "For using debug logging in loaders" + "psr/log-implementation": "For using debug logging in loaders" }, "autoload": { "psr-4": { "Symfony\\Component\\Templating\\": "" }, diff --git a/src/Symfony/Component/Translation/composer.json b/src/Symfony/Component/Translation/composer.json index 3ba1a6436789..128f37f0d7f5 100644 --- a/src/Symfony/Component/Translation/composer.json +++ b/src/Symfony/Component/Translation/composer.json @@ -30,7 +30,7 @@ "suggest": { "symfony/config": "", "symfony/yaml": "", - "psr/log": "To use logging capability in translator" + "psr/log-implementation": "To use logging capability in translator" }, "autoload": { "psr-4": { "Symfony\\Component\\Translation\\": "" }, From bcbd3a2902b4fc4aae1d99872d482381fc353619 Mon Sep 17 00:00:00 2001 From: Nicolas Grekas Date: Mon, 30 Apr 2018 08:25:36 -0700 Subject: [PATCH 70/75] [PhpUnitBridge] Fix --- src/Symfony/Bridge/PhpUnit/TextUI/TestRunner.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Symfony/Bridge/PhpUnit/TextUI/TestRunner.php b/src/Symfony/Bridge/PhpUnit/TextUI/TestRunner.php index 7b8d162e5336..1464557619cb 100644 --- a/src/Symfony/Bridge/PhpUnit/TextUI/TestRunner.php +++ b/src/Symfony/Bridge/PhpUnit/TextUI/TestRunner.php @@ -13,7 +13,7 @@ if (class_exists('PHPUnit_Runner_Version') && version_compare(\PHPUnit_Runner_Version::id(), '6.0.0', '<')) { class_alias('Symfony\Bridge\PhpUnit\Legacy\TestRunnerForV5', 'Symfony\Bridge\PhpUnit\TextUI\TestRunner'); -} elseif (class_exists('PHPUnit_Runner_Version') && version_compare(\PHPUnit_Runner_Version::id(), '7.0.0', '<')) { +} elseif (version_compare(\PHPUnit_Runner_Version::id(), '7.0.0', '<')) { class_alias('Symfony\Bridge\PhpUnit\Legacy\TestRunnerForV6', 'Symfony\Bridge\PhpUnit\TextUI\TestRunner'); } else { class_alias('Symfony\Bridge\PhpUnit\Legacy\TestRunnerForV7', 'Symfony\Bridge\PhpUnit\TextUI\TestRunner'); From b1fb985ebc7c6dbdf032af34a6f6d37fc4583adb Mon Sep 17 00:00:00 2001 From: Nicolas Grekas Date: Mon, 30 Apr 2018 08:36:51 -0700 Subject: [PATCH 71/75] [PhpUnitBridge] Fix --- src/Symfony/Bridge/PhpUnit/TextUI/TestRunner.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Symfony/Bridge/PhpUnit/TextUI/TestRunner.php b/src/Symfony/Bridge/PhpUnit/TextUI/TestRunner.php index 1464557619cb..cda59209790d 100644 --- a/src/Symfony/Bridge/PhpUnit/TextUI/TestRunner.php +++ b/src/Symfony/Bridge/PhpUnit/TextUI/TestRunner.php @@ -13,7 +13,7 @@ if (class_exists('PHPUnit_Runner_Version') && version_compare(\PHPUnit_Runner_Version::id(), '6.0.0', '<')) { class_alias('Symfony\Bridge\PhpUnit\Legacy\TestRunnerForV5', 'Symfony\Bridge\PhpUnit\TextUI\TestRunner'); -} elseif (version_compare(\PHPUnit_Runner_Version::id(), '7.0.0', '<')) { +} elseif (version_compare(\PHPUnit\Runner\Version::id(), '7.0.0', '<')) { class_alias('Symfony\Bridge\PhpUnit\Legacy\TestRunnerForV6', 'Symfony\Bridge\PhpUnit\TextUI\TestRunner'); } else { class_alias('Symfony\Bridge\PhpUnit\Legacy\TestRunnerForV7', 'Symfony\Bridge\PhpUnit\TextUI\TestRunner'); From 620f90d200e1836a6602317615c33bd529d6042c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gr=C3=A9goire=20Pineau?= Date: Mon, 30 Apr 2018 14:25:22 +0200 Subject: [PATCH 72/75] [Debug] Fixed the formatPath when a custom fileLinkFormat is defined --- .../Component/Debug/ExceptionHandler.php | 26 +++++++++++++++---- 1 file changed, 21 insertions(+), 5 deletions(-) diff --git a/src/Symfony/Component/Debug/ExceptionHandler.php b/src/Symfony/Component/Debug/ExceptionHandler.php index 97470cb6b4d0..f22b70f6e8c6 100644 --- a/src/Symfony/Component/Debug/ExceptionHandler.php +++ b/src/Symfony/Component/Debug/ExceptionHandler.php @@ -40,7 +40,7 @@ public function __construct($debug = true, $charset = null, $fileLinkFormat = nu { $this->debug = $debug; $this->charset = $charset ?: ini_get('default_charset') ?: 'UTF-8'; - $this->fileLinkFormat = $fileLinkFormat ?: ini_get('xdebug.file_link_format') ?: get_cfg_var('xdebug.file_link_format'); + $this->fileLinkFormat = $fileLinkFormat; } /** @@ -355,13 +355,29 @@ private function formatClass($class) private function formatPath($path, $line) { $file = $this->escapeHtml(preg_match('#[^/\\\\]*+$#', $path, $file) ? $file[0] : $path); - $fmt = $this->fileLinkFormat; + $fmt = $this->fileLinkFormat ?: ini_get('xdebug.file_link_format') ?: get_cfg_var('xdebug.file_link_format'); + + if (!$fmt) { + return sprintf('in %s%s', $this->escapeHtml($path), $file, 0 < $line ? ' line '.$line : ''); + } + + if (\is_string($fmt)) { + $i = strpos($f = $fmt, '&', max(strrpos($f, '%f'), strrpos($f, '%l'))) ?: strlen($f); + $fmt = array(substr($f, 0, $i)) + preg_split('/&([^>]++)>/', substr($f, $i), -1, PREG_SPLIT_DELIM_CAPTURE); + + for ($i = 1; isset($fmt[$i]); ++$i) { + if (0 === strpos($path, $k = $fmt[$i++])) { + $path = substr_replace($path, $fmt[$i], 0, strlen($k)); + break; + } + } - if ($fmt && $link = is_string($fmt) ? strtr($fmt, array('%f' => $path, '%l' => $line)) : $fmt->format($path, $line)) { - return sprintf('in %s (line %d)', $this->escapeHtml($link), $file, $line); + $link = strtr($fmt[0], array('%f' => $path, '%l' => $line)); + } else { + $link = $fmt->format($path, $line); } - return sprintf('in %s (line %d)', $this->escapeHtml($path), $file, $line); + return sprintf('in %s%s', $this->escapeHtml($link), $file, 0 < $line ? ' line '.$line : ''); } /** From a4a1645d4475f08e08c54bec91184d8d1e061c2f Mon Sep 17 00:00:00 2001 From: Nicolas Grekas Date: Fri, 27 Apr 2018 12:57:32 +0200 Subject: [PATCH 73/75] [Debug][WebProfilerBundle] Fix setting file link format --- src/Symfony/Bridge/Twig/Extension/CodeExtension.php | 4 +++- src/Symfony/Bundle/FrameworkBundle/FrameworkBundle.php | 3 +++ .../WebProfilerBundle/Controller/ExceptionController.php | 8 +++++--- .../WebProfilerBundle/Resources/config/profiler.xml | 1 + .../Resources/views/Profiler/open.html.twig | 2 +- .../DependencyInjection/WebProfilerExtensionTest.php | 1 + 6 files changed, 14 insertions(+), 5 deletions(-) diff --git a/src/Symfony/Bridge/Twig/Extension/CodeExtension.php b/src/Symfony/Bridge/Twig/Extension/CodeExtension.php index f37d8100fbb4..c8b48fc6663f 100644 --- a/src/Symfony/Bridge/Twig/Extension/CodeExtension.php +++ b/src/Symfony/Bridge/Twig/Extension/CodeExtension.php @@ -181,7 +181,9 @@ public function formatFile($file, $line, $text = null) } } - $text = "$text at line $line"; + if (0 < $line) { + $text .= ' at line '.$line; + } if (false !== $link = $this->getFileLink($file, $line)) { return sprintf('%s', htmlspecialchars($link, ENT_COMPAT | ENT_SUBSTITUTE, $this->charset), $text); diff --git a/src/Symfony/Bundle/FrameworkBundle/FrameworkBundle.php b/src/Symfony/Bundle/FrameworkBundle/FrameworkBundle.php index 2a62d391a7b2..17c12686dad2 100644 --- a/src/Symfony/Bundle/FrameworkBundle/FrameworkBundle.php +++ b/src/Symfony/Bundle/FrameworkBundle/FrameworkBundle.php @@ -61,6 +61,9 @@ class FrameworkBundle extends Bundle { public function boot() { + if (!ini_get('xdebug.file_link_format') && !get_cfg_var('xdebug.file_link_format')) { + ini_set('xdebug.file_link_format', $this->container->getParameter('debug.file_link_format')); + } ErrorHandler::register(null, false)->throwAt($this->container->getParameter('debug.error_handler.throw_at'), true); if ($this->container->hasParameter('kernel.trusted_proxies')) { diff --git a/src/Symfony/Bundle/WebProfilerBundle/Controller/ExceptionController.php b/src/Symfony/Bundle/WebProfilerBundle/Controller/ExceptionController.php index 3f9d873e1d40..f008b0b5284f 100644 --- a/src/Symfony/Bundle/WebProfilerBundle/Controller/ExceptionController.php +++ b/src/Symfony/Bundle/WebProfilerBundle/Controller/ExceptionController.php @@ -11,6 +11,7 @@ namespace Symfony\Bundle\WebProfilerBundle\Controller; +use Symfony\Component\HttpKernel\Debug\FileLinkFormatter; use Symfony\Component\HttpKernel\Profiler\Profiler; use Symfony\Component\Debug\ExceptionHandler; use Symfony\Component\HttpKernel\Exception\NotFoundHttpException; @@ -30,11 +31,12 @@ class ExceptionController protected $debug; protected $profiler; - public function __construct(Profiler $profiler = null, Environment $twig, $debug) + public function __construct(Profiler $profiler = null, Environment $twig, $debug, FileLinkFormatter $fileLinkFormat = null) { $this->profiler = $profiler; $this->twig = $twig; $this->debug = $debug; + $this->fileLinkFormat = $fileLinkFormat; } /** @@ -58,7 +60,7 @@ public function showAction($token) $template = $this->getTemplate(); if (!$this->twig->getLoader()->exists($template)) { - $handler = new ExceptionHandler($this->debug, $this->twig->getCharset()); + $handler = new ExceptionHandler($this->debug, $this->twig->getCharset(), $this->fileLinkFormat); return new Response($handler->getContent($exception), 200, array('Content-Type' => 'text/html')); } @@ -98,7 +100,7 @@ public function cssAction($token) $template = $this->getTemplate(); if (!$this->templateExists($template)) { - $handler = new ExceptionHandler($this->debug, $this->twig->getCharset()); + $handler = new ExceptionHandler($this->debug, $this->twig->getCharset(), $this->fileLinkFormat); return new Response($handler->getStylesheet($exception), 200, array('Content-Type' => 'text/css')); } diff --git a/src/Symfony/Bundle/WebProfilerBundle/Resources/config/profiler.xml b/src/Symfony/Bundle/WebProfilerBundle/Resources/config/profiler.xml index 7854bc199cb2..4eb44972e72d 100644 --- a/src/Symfony/Bundle/WebProfilerBundle/Resources/config/profiler.xml +++ b/src/Symfony/Bundle/WebProfilerBundle/Resources/config/profiler.xml @@ -27,6 +27,7 @@ %kernel.debug% + diff --git a/src/Symfony/Bundle/WebProfilerBundle/Resources/views/Profiler/open.html.twig b/src/Symfony/Bundle/WebProfilerBundle/Resources/views/Profiler/open.html.twig index 9b482f1f0aa9..58e1fe355621 100644 --- a/src/Symfony/Bundle/WebProfilerBundle/Resources/views/Profiler/open.html.twig +++ b/src/Symfony/Bundle/WebProfilerBundle/Resources/views/Profiler/open.html.twig @@ -8,7 +8,7 @@ {% block body %}
-

{{ file }} line {{ line }}

+

{{ file }}{% if 0 < line %} line {{ line }}{% endif %}

Open in your IDE?
diff --git a/src/Symfony/Bundle/WebProfilerBundle/Tests/DependencyInjection/WebProfilerExtensionTest.php b/src/Symfony/Bundle/WebProfilerBundle/Tests/DependencyInjection/WebProfilerExtensionTest.php index 316bd13f2f6e..c055d46f2ebf 100644 --- a/src/Symfony/Bundle/WebProfilerBundle/Tests/DependencyInjection/WebProfilerExtensionTest.php +++ b/src/Symfony/Bundle/WebProfilerBundle/Tests/DependencyInjection/WebProfilerExtensionTest.php @@ -31,6 +31,7 @@ class WebProfilerExtensionTest extends TestCase public static function assertSaneContainer(Container $container, $message = '', $knownPrivates = array()) { $errors = array(); + $knownPrivates[] = 'debug.file_link_formatter.url_format'; foreach ($container->getServiceIds() as $id) { if (in_array($id, $knownPrivates, true)) { // to be removed in 4.0 continue; From fb98ef384be5db94390baab0024365d438cfff90 Mon Sep 17 00:00:00 2001 From: Fabien Potencier Date: Mon, 30 Apr 2018 21:45:53 +0200 Subject: [PATCH 74/75] updated CHANGELOG for 4.0.9 --- CHANGELOG-4.0.md | 35 +++++++++++++++++++++++++++++++++++ 1 file changed, 35 insertions(+) diff --git a/CHANGELOG-4.0.md b/CHANGELOG-4.0.md index cbd0ed892c1d..9abb4a61a663 100644 --- a/CHANGELOG-4.0.md +++ b/CHANGELOG-4.0.md @@ -7,6 +7,41 @@ in 4.0 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/v4.0.0...v4.0.1 +* 4.0.9 (2018-04-30) + + * bug #27074 [Debug][WebProfilerBundle] Fix setting file link format (lyrixx, nicolas-grekas) + * bug #27088 ResolveBindingsPass: Don't throw error for unused service, missing parent class (weaverryan) + * bug #27086 [PHPUnitBridge] Add an implementation just for php 7.0 (greg0ire) + * bug #26138 [HttpKernel] Catch HttpExceptions when templating is not installed (cilefen) + * bug #27007 [Cache] TagAwareAdapterInterface::invalidateTags() should commit deferred items (nicolas-grekas) + * bug #27067 [HttpFoundation] Fix setting session-related ini settings (e-moe) + * bug #27061 [HttpKernel] Don't clean legacy containers that are still loaded (nicolas-grekas) + * bug #27064 [VarDumper] Fix HtmlDumper classes match (ogizanagi) + * bug #27016 [Security][Guard] GuardAuthenticationProvider::authenticate cannot return null (biomedia-thomas) + * bug #26831 [Bridge/Doctrine] count(): Parameter must be an array or an object that implements Countable (gpenverne) + * bug #27044 [Security] Skip user checks if not implementing UserInterface (chalasr) + * bug #27025 [DI] Add check of internal type to ContainerBuilder::getReflectionClass (upyx) + * bug #26994 [PhpUnitBridge] Add type hints (greg0ire) + * bug #26014 [Security] Fixed being logged out on failed attempt in guard (iltar) + * bug #25348 [HttpFoundation] Send cookies using header() to fix "SameSite" ones (nicolas-grekas, cvilleger) + * bug #26910 Use new PHP7.2 functions in hasColorSupport (johnstevenson) + * bug #26999 [VarDumper] Fix dumping of SplObjectStorage (corphi) + * bug #25841 [DoctrineBridge] Fix bug when indexBy is meta key in PropertyInfo\DoctrineExtractor (insekticid) + * bug #26983 [TwigBridge] [Bootstrap 4] Fix PercentType error rendering. (alexismarquis) + * bug #26980 [TwigBundle] fix formatting arguments in plaintext format (xabbuh) + * bug #26886 Don't assume that file binary exists on *nix OS (teohhanhui) + * bug #26959 [Console] Fix PSR exception context key (scaytrase) + * bug #26899 [Routing] Fix loading multiple class annotations for invokable classes (1ed) + * bug #26643 Fix that ESI/SSI processing can turn a "private" response "public" (mpdude) + * bug #26932 [Form] Fixed trimming choice values (HeahDude) + * bug #26922 [TwigBundle] fix rendering exception stack traces (xabbuh) + * bug #26773 [HttpKernel] Make ServiceValueResolver work if controller namespace starts with a backslash in routing (mathieutu) + * bug #26870 Add d-block to bootstrap 4 alerts (Normunds) + * bug #26857 [HttpKernel] Dont create mock cookie for new sessions in tests (nicolas-grekas) + * bug #26875 [Console] Don't go past exact matches when autocompleting (nicolas-grekas) + * bug #26823 [Validator] Fix LazyLoadingMetadataFactory with PSR6Cache for non classname if tested values isn't existing class (Pascal Montoya, pmontoya) + * bug #26834 [Yaml] Throw parse error on unfinished inline map (nicolas-grekas) + * 4.0.8 (2018-04-06) * bug #26802 [Security] register custom providers on ExpressionLanguage directly (dmaicher) From 2e856cda07c30ce2c2b57f82db58c76be9c14618 Mon Sep 17 00:00:00 2001 From: Fabien Potencier Date: Mon, 30 Apr 2018 21:45:57 +0200 Subject: [PATCH 75/75] updated VERSION for 4.0.9 --- src/Symfony/Component/HttpKernel/Kernel.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Symfony/Component/HttpKernel/Kernel.php b/src/Symfony/Component/HttpKernel/Kernel.php index 5ca41c8502d2..24cce648ef44 100644 --- a/src/Symfony/Component/HttpKernel/Kernel.php +++ b/src/Symfony/Component/HttpKernel/Kernel.php @@ -63,12 +63,12 @@ abstract class Kernel implements KernelInterface, RebootableInterface, Terminabl private $requestStackSize = 0; private $resetServices = false; - const VERSION = '4.0.9-DEV'; + const VERSION = '4.0.9'; const VERSION_ID = 40009; const MAJOR_VERSION = 4; const MINOR_VERSION = 0; const RELEASE_VERSION = 9; - const EXTRA_VERSION = 'DEV'; + const EXTRA_VERSION = ''; const END_OF_MAINTENANCE = '07/2018'; const END_OF_LIFE = '01/2019'; 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