From 11ee84c09ea9dfa4a433932ddc7fcb34c74a34aa Mon Sep 17 00:00:00 2001 From: Hamza Amrouche Date: Wed, 17 Apr 2019 16:07:28 +0200 Subject: [PATCH 01/10] minor: ChoiceType callable deprecation after/before seems wrong That is on me 3 years ago ! --- UPGRADE-4.0.md | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/UPGRADE-4.0.md b/UPGRADE-4.0.md index fbe988fa34..5703b4a5a7 100644 --- a/UPGRADE-4.0.md +++ b/UPGRADE-4.0.md @@ -297,19 +297,17 @@ Form `ArrayAccess` in `ResizeFormListener::preSubmit` method has been removed. * Using callable strings as choice options in ChoiceType is not supported - anymore in favor of passing PropertyPath instances. + anymore. Before: ```php - 'choice_value' => new PropertyPath('range'), 'choice_label' => 'strtoupper', ``` After: ```php - 'choice_value' => 'range', 'choice_label' => function ($choice) { return strtoupper($choice); }, From b5e6c99a3b1aa46ffeb859111e5b0fde4678bde4 Mon Sep 17 00:00:00 2001 From: Ivo Date: Wed, 5 Jun 2019 10:24:41 +0200 Subject: [PATCH 02/10] [HttpFoundation] Fixed case-sensitive handling of cache-control header in RedirectResponse constructor. --- src/Symfony/Component/HttpFoundation/RedirectResponse.php | 2 +- .../Component/HttpFoundation/Tests/RedirectResponseTest.php | 4 ++++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/src/Symfony/Component/HttpFoundation/RedirectResponse.php b/src/Symfony/Component/HttpFoundation/RedirectResponse.php index 5e1dfe5850..51fd869abe 100644 --- a/src/Symfony/Component/HttpFoundation/RedirectResponse.php +++ b/src/Symfony/Component/HttpFoundation/RedirectResponse.php @@ -42,7 +42,7 @@ class RedirectResponse extends Response throw new \InvalidArgumentException(sprintf('The HTTP status code is not a redirect ("%s" given).', $status)); } - if (301 == $status && !\array_key_exists('cache-control', $headers)) { + if (301 == $status && !\array_key_exists('cache-control', array_change_key_case($headers, \CASE_LOWER))) { $this->headers->remove('cache-control'); } } diff --git a/src/Symfony/Component/HttpFoundation/Tests/RedirectResponseTest.php b/src/Symfony/Component/HttpFoundation/Tests/RedirectResponseTest.php index 64c3e73ee2..5f6a8ac088 100644 --- a/src/Symfony/Component/HttpFoundation/Tests/RedirectResponseTest.php +++ b/src/Symfony/Component/HttpFoundation/Tests/RedirectResponseTest.php @@ -91,6 +91,10 @@ class RedirectResponseTest extends TestCase $this->assertFalse($response->headers->hasCacheControlDirective('no-cache')); $this->assertTrue($response->headers->hasCacheControlDirective('max-age')); + $response = new RedirectResponse('foo.bar', 301, ['Cache-Control' => 'max-age=86400']); + $this->assertFalse($response->headers->hasCacheControlDirective('no-cache')); + $this->assertTrue($response->headers->hasCacheControlDirective('max-age')); + $response = new RedirectResponse('foo.bar', 302); $this->assertTrue($response->headers->hasCacheControlDirective('no-cache')); } From 07603da06c609084c791674da9458af9c5443d57 Mon Sep 17 00:00:00 2001 From: Robin Chalas Date: Wed, 5 Jun 2019 15:18:16 +0200 Subject: [PATCH 03/10] [Messenger] Add runtime check for ext redis version --- .../Component/Messenger/Transport/RedisExt/Connection.php | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/Symfony/Component/Messenger/Transport/RedisExt/Connection.php b/src/Symfony/Component/Messenger/Transport/RedisExt/Connection.php index 5757f0be7f..7688503264 100644 --- a/src/Symfony/Component/Messenger/Transport/RedisExt/Connection.php +++ b/src/Symfony/Component/Messenger/Transport/RedisExt/Connection.php @@ -12,6 +12,7 @@ namespace Symfony\Component\Messenger\Transport\RedisExt; use Symfony\Component\Messenger\Exception\InvalidArgumentException; +use Symfony\Component\Messenger\Exception\LogicException; use Symfony\Component\Messenger\Exception\TransportException; /** @@ -43,6 +44,10 @@ class Connection public function __construct(array $configuration, array $connectionCredentials = [], array $redisOptions = [], \Redis $redis = null) { + if (version_compare(phpversion('redis'), '4.3.0', '<')) { + throw new LogicException('The redis transport requires php-redis 4.3.0 or higher.'); + } + $this->connection = $redis ?: new \Redis(); $this->connection->connect($connectionCredentials['host'] ?? '127.0.0.1', $connectionCredentials['port'] ?? 6379); $this->connection->setOption(\Redis::OPT_SERIALIZER, $redisOptions['serializer'] ?? \Redis::SERIALIZER_PHP); From fd17ff005de2c9ef17a0d7667e81cd177eb00db6 Mon Sep 17 00:00:00 2001 From: Julien Manganne Date: Wed, 5 Jun 2019 17:56:22 +0200 Subject: [PATCH 04/10] Add a missing quote in getValue() DocBlock --- .../Component/PropertyAccess/PropertyAccessorInterface.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Symfony/Component/PropertyAccess/PropertyAccessorInterface.php b/src/Symfony/Component/PropertyAccess/PropertyAccessorInterface.php index 51fa0cc76f..aa81bfc42d 100644 --- a/src/Symfony/Component/PropertyAccess/PropertyAccessorInterface.php +++ b/src/Symfony/Component/PropertyAccess/PropertyAccessorInterface.php @@ -58,7 +58,7 @@ interface PropertyAccessorInterface * * $propertyAccessor = PropertyAccess::createPropertyAccessor(); * - * echo $propertyAccessor->getValue($object, 'child.name); + * echo $propertyAccessor->getValue($object, 'child.name'); * // equals echo $object->getChild()->getName(); * * This method first tries to find a public getter for each property in the From 1a4c2548d5fd8fa0e8b0266a8fbe0e7063da75bb Mon Sep 17 00:00:00 2001 From: Nicolas Grekas Date: Wed, 5 Jun 2019 18:17:19 +0200 Subject: [PATCH 05/10] [FramworkBundle][HttpKernel] fix KernelBrowser BC layer --- src/Symfony/Bundle/FrameworkBundle/Client.php | 192 +++++++++++++++++- .../Bundle/FrameworkBundle/KernelBrowser.php | 187 +---------------- src/Symfony/Component/HttpKernel/Client.php | 187 ++++++++++++++++- .../HttpKernel/HttpKernelBrowser.php | 182 +---------------- 4 files changed, 377 insertions(+), 371 deletions(-) diff --git a/src/Symfony/Bundle/FrameworkBundle/Client.php b/src/Symfony/Bundle/FrameworkBundle/Client.php index e36f0cac68..f33808db04 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Client.php +++ b/src/Symfony/Bundle/FrameworkBundle/Client.php @@ -11,8 +11,196 @@ namespace Symfony\Bundle\FrameworkBundle; -@trigger_error(sprintf('The "%s" class is deprecated since Symfony 4.3, use "%s" instead.', Client::class, KernelBrowser::class), E_USER_DEPRECATED); +use Symfony\Component\BrowserKit\CookieJar; +use Symfony\Component\BrowserKit\History; +use Symfony\Component\DependencyInjection\ContainerInterface; +use Symfony\Component\HttpFoundation\Request; +use Symfony\Component\HttpFoundation\Response; +use Symfony\Component\HttpKernel\HttpKernelBrowser; +use Symfony\Component\HttpKernel\KernelInterface; +use Symfony\Component\HttpKernel\Profiler\Profile as HttpProfile; -class Client extends KernelBrowser +/** + * Client simulates a browser and makes requests to a Kernel object. + * + * @deprecated since Symfony 4.3, use KernelBrowser instead. + */ +class Client extends HttpKernelBrowser { + private $hasPerformedRequest = false; + private $profiler = false; + private $reboot = true; + + /** + * {@inheritdoc} + */ + public function __construct(KernelInterface $kernel, array $server = [], History $history = null, CookieJar $cookieJar = null) + { + parent::__construct($kernel, $server, $history, $cookieJar); + } + + /** + * Returns the container. + * + * @return ContainerInterface|null Returns null when the Kernel has been shutdown or not started yet + */ + public function getContainer() + { + return $this->kernel->getContainer(); + } + + /** + * Returns the kernel. + * + * @return KernelInterface + */ + public function getKernel() + { + return $this->kernel; + } + + /** + * Gets the profile associated with the current Response. + * + * @return HttpProfile|false A Profile instance + */ + public function getProfile() + { + if (!$this->kernel->getContainer()->has('profiler')) { + return false; + } + + return $this->kernel->getContainer()->get('profiler')->loadProfileFromResponse($this->response); + } + + /** + * Enables the profiler for the very next request. + * + * If the profiler is not enabled, the call to this method does nothing. + */ + public function enableProfiler() + { + if ($this->kernel->getContainer()->has('profiler')) { + $this->profiler = true; + } + } + + /** + * Disables kernel reboot between requests. + * + * By default, the Client reboots the Kernel for each request. This method + * allows to keep the same kernel across requests. + */ + public function disableReboot() + { + $this->reboot = false; + } + + /** + * Enables kernel reboot between requests. + */ + public function enableReboot() + { + $this->reboot = true; + } + + /** + * {@inheritdoc} + * + * @param Request $request A Request instance + * + * @return Response A Response instance + */ + protected function doRequest($request) + { + // avoid shutting down the Kernel if no request has been performed yet + // WebTestCase::createClient() boots the Kernel but do not handle a request + if ($this->hasPerformedRequest && $this->reboot) { + $this->kernel->shutdown(); + } else { + $this->hasPerformedRequest = true; + } + + if ($this->profiler) { + $this->profiler = false; + + $this->kernel->boot(); + $this->kernel->getContainer()->get('profiler')->enable(); + } + + return parent::doRequest($request); + } + + /** + * {@inheritdoc} + * + * @param Request $request A Request instance + * + * @return Response A Response instance + */ + protected function doRequestInProcess($request) + { + $response = parent::doRequestInProcess($request); + + $this->profiler = false; + + return $response; + } + + /** + * Returns the script to execute when the request must be insulated. + * + * It assumes that the autoloader is named 'autoload.php' and that it is + * stored in the same directory as the kernel (this is the case for the + * Symfony Standard Edition). If this is not your case, create your own + * client and override this method. + * + * @param Request $request A Request instance + * + * @return string The script content + */ + protected function getScript($request) + { + $kernel = var_export(serialize($this->kernel), true); + $request = var_export(serialize($request), true); + $errorReporting = error_reporting(); + + $requires = ''; + foreach (get_declared_classes() as $class) { + if (0 === strpos($class, 'ComposerAutoloaderInit')) { + $r = new \ReflectionClass($class); + $file = \dirname(\dirname($r->getFileName())).'/autoload.php'; + if (file_exists($file)) { + $requires .= 'require_once '.var_export($file, true).";\n"; + } + } + } + + if (!$requires) { + throw new \RuntimeException('Composer autoloader not found.'); + } + + $requires .= 'require_once '.var_export((new \ReflectionObject($this->kernel))->getFileName(), true).";\n"; + + $profilerCode = ''; + if ($this->profiler) { + $profilerCode = '$kernel->getContainer()->get(\'profiler\')->enable();'; + } + + $code = <<boot(); +$profilerCode + +\$request = unserialize($request); +EOF; + + return $code.$this->getHandleScript(); + } } diff --git a/src/Symfony/Bundle/FrameworkBundle/KernelBrowser.php b/src/Symfony/Bundle/FrameworkBundle/KernelBrowser.php index b86c1b5c34..b05b60def1 100644 --- a/src/Symfony/Bundle/FrameworkBundle/KernelBrowser.php +++ b/src/Symfony/Bundle/FrameworkBundle/KernelBrowser.php @@ -11,196 +11,11 @@ namespace Symfony\Bundle\FrameworkBundle; -use Symfony\Component\BrowserKit\CookieJar; -use Symfony\Component\BrowserKit\History; -use Symfony\Component\DependencyInjection\ContainerInterface; -use Symfony\Component\HttpFoundation\Request; -use Symfony\Component\HttpFoundation\Response; -use Symfony\Component\HttpKernel\HttpKernelBrowser; -use Symfony\Component\HttpKernel\KernelInterface; -use Symfony\Component\HttpKernel\Profiler\Profile as HttpProfile; - /** * Client simulates a browser and makes requests to a Kernel object. * * @author Fabien Potencier */ -class KernelBrowser extends HttpKernelBrowser +class KernelBrowser extends Client { - private $hasPerformedRequest = false; - private $profiler = false; - private $reboot = true; - - /** - * {@inheritdoc} - */ - public function __construct(KernelInterface $kernel, array $server = [], History $history = null, CookieJar $cookieJar = null) - { - parent::__construct($kernel, $server, $history, $cookieJar); - } - - /** - * Returns the container. - * - * @return ContainerInterface|null Returns null when the Kernel has been shutdown or not started yet - */ - public function getContainer() - { - return $this->kernel->getContainer(); - } - - /** - * Returns the kernel. - * - * @return KernelInterface - */ - public function getKernel() - { - return $this->kernel; - } - - /** - * Gets the profile associated with the current Response. - * - * @return HttpProfile|false A Profile instance - */ - public function getProfile() - { - if (!$this->kernel->getContainer()->has('profiler')) { - return false; - } - - return $this->kernel->getContainer()->get('profiler')->loadProfileFromResponse($this->response); - } - - /** - * Enables the profiler for the very next request. - * - * If the profiler is not enabled, the call to this method does nothing. - */ - public function enableProfiler() - { - if ($this->kernel->getContainer()->has('profiler')) { - $this->profiler = true; - } - } - - /** - * Disables kernel reboot between requests. - * - * By default, the Client reboots the Kernel for each request. This method - * allows to keep the same kernel across requests. - */ - public function disableReboot() - { - $this->reboot = false; - } - - /** - * Enables kernel reboot between requests. - */ - public function enableReboot() - { - $this->reboot = true; - } - - /** - * {@inheritdoc} - * - * @param Request $request A Request instance - * - * @return Response A Response instance - */ - protected function doRequest($request) - { - // avoid shutting down the Kernel if no request has been performed yet - // WebTestCase::createClient() boots the Kernel but do not handle a request - if ($this->hasPerformedRequest && $this->reboot) { - $this->kernel->shutdown(); - } else { - $this->hasPerformedRequest = true; - } - - if ($this->profiler) { - $this->profiler = false; - - $this->kernel->boot(); - $this->kernel->getContainer()->get('profiler')->enable(); - } - - return parent::doRequest($request); - } - - /** - * {@inheritdoc} - * - * @param Request $request A Request instance - * - * @return Response A Response instance - */ - protected function doRequestInProcess($request) - { - $response = parent::doRequestInProcess($request); - - $this->profiler = false; - - return $response; - } - - /** - * Returns the script to execute when the request must be insulated. - * - * It assumes that the autoloader is named 'autoload.php' and that it is - * stored in the same directory as the kernel (this is the case for the - * Symfony Standard Edition). If this is not your case, create your own - * client and override this method. - * - * @param Request $request A Request instance - * - * @return string The script content - */ - protected function getScript($request) - { - $kernel = var_export(serialize($this->kernel), true); - $request = var_export(serialize($request), true); - $errorReporting = error_reporting(); - - $requires = ''; - foreach (get_declared_classes() as $class) { - if (0 === strpos($class, 'ComposerAutoloaderInit')) { - $r = new \ReflectionClass($class); - $file = \dirname(\dirname($r->getFileName())).'/autoload.php'; - if (file_exists($file)) { - $requires .= 'require_once '.var_export($file, true).";\n"; - } - } - } - - if (!$requires) { - throw new \RuntimeException('Composer autoloader not found.'); - } - - $requires .= 'require_once '.var_export((new \ReflectionObject($this->kernel))->getFileName(), true).";\n"; - - $profilerCode = ''; - if ($this->profiler) { - $profilerCode = '$kernel->getContainer()->get(\'profiler\')->enable();'; - } - - $code = <<boot(); -$profilerCode - -\$request = unserialize($request); -EOF; - - return $code.$this->getHandleScript(); - } } diff --git a/src/Symfony/Component/HttpKernel/Client.php b/src/Symfony/Component/HttpKernel/Client.php index ed1e1382ea..66ce0649f0 100644 --- a/src/Symfony/Component/HttpKernel/Client.php +++ b/src/Symfony/Component/HttpKernel/Client.php @@ -11,8 +11,191 @@ namespace Symfony\Component\HttpKernel; -@trigger_error(sprintf('The "%s" class is deprecated since Symfony 4.3, use "%s" instead.', Client::class, HttpKernelBrowser::class), E_USER_DEPRECATED); +use Symfony\Component\BrowserKit\AbstractBrowser; +use Symfony\Component\BrowserKit\CookieJar; +use Symfony\Component\BrowserKit\History; +use Symfony\Component\BrowserKit\Request as DomRequest; +use Symfony\Component\BrowserKit\Response as DomResponse; +use Symfony\Component\HttpFoundation\File\UploadedFile; +use Symfony\Component\HttpFoundation\Request; +use Symfony\Component\HttpFoundation\Response; -class Client extends HttpKernelBrowser +/** + * Client simulates a browser and makes requests to an HttpKernel instance. + * + * @deprecated since Symfony 4.3, use HttpKernelBrowser instead. + */ +class Client extends AbstractBrowser { + protected $kernel; + private $catchExceptions = true; + + /** + * @param HttpKernelInterface $kernel An HttpKernel instance + * @param array $server The server parameters (equivalent of $_SERVER) + * @param History $history A History instance to store the browser history + * @param CookieJar $cookieJar A CookieJar instance to store the cookies + */ + public function __construct(HttpKernelInterface $kernel, array $server = [], History $history = null, CookieJar $cookieJar = null) + { + // These class properties must be set before calling the parent constructor, as it may depend on it. + $this->kernel = $kernel; + $this->followRedirects = false; + + parent::__construct($server, $history, $cookieJar); + } + + /** + * Sets whether to catch exceptions when the kernel is handling a request. + * + * @param bool $catchExceptions Whether to catch exceptions + */ + public function catchExceptions($catchExceptions) + { + $this->catchExceptions = $catchExceptions; + } + + /** + * Makes a request. + * + * @return Response A Response instance + */ + protected function doRequest($request) + { + $response = $this->kernel->handle($request, HttpKernelInterface::MASTER_REQUEST, $this->catchExceptions); + + if ($this->kernel instanceof TerminableInterface) { + $this->kernel->terminate($request, $response); + } + + return $response; + } + + /** + * Returns the script to execute when the request must be insulated. + * + * @return string + */ + protected function getScript($request) + { + $kernel = var_export(serialize($this->kernel), true); + $request = var_export(serialize($request), true); + + $errorReporting = error_reporting(); + + $requires = ''; + foreach (get_declared_classes() as $class) { + if (0 === strpos($class, 'ComposerAutoloaderInit')) { + $r = new \ReflectionClass($class); + $file = \dirname(\dirname($r->getFileName())).'/autoload.php'; + if (file_exists($file)) { + $requires .= 'require_once '.var_export($file, true).";\n"; + } + } + } + + if (!$requires) { + throw new \RuntimeException('Composer autoloader not found.'); + } + + $code = <<getHandleScript(); + } + + protected function getHandleScript() + { + return <<<'EOF' +$response = $kernel->handle($request); + +if ($kernel instanceof Symfony\Component\HttpKernel\TerminableInterface) { + $kernel->terminate($request, $response); +} + +echo serialize($response); +EOF; + } + + /** + * Converts the BrowserKit request to a HttpKernel request. + * + * @return Request A Request instance + */ + protected function filterRequest(DomRequest $request) + { + $httpRequest = Request::create($request->getUri(), $request->getMethod(), $request->getParameters(), $request->getCookies(), $request->getFiles(), $request->getServer(), $request->getContent()); + + foreach ($this->filterFiles($httpRequest->files->all()) as $key => $value) { + $httpRequest->files->set($key, $value); + } + + return $httpRequest; + } + + /** + * Filters an array of files. + * + * This method created test instances of UploadedFile so that the move() + * method can be called on those instances. + * + * If the size of a file is greater than the allowed size (from php.ini) then + * an invalid UploadedFile is returned with an error set to UPLOAD_ERR_INI_SIZE. + * + * @see UploadedFile + * + * @return array An array with all uploaded files marked as already moved + */ + protected function filterFiles(array $files) + { + $filtered = []; + foreach ($files as $key => $value) { + if (\is_array($value)) { + $filtered[$key] = $this->filterFiles($value); + } elseif ($value instanceof UploadedFile) { + if ($value->isValid() && $value->getSize() > UploadedFile::getMaxFilesize()) { + $filtered[$key] = new UploadedFile( + '', + $value->getClientOriginalName(), + $value->getClientMimeType(), + UPLOAD_ERR_INI_SIZE, + true + ); + } else { + $filtered[$key] = new UploadedFile( + $value->getPathname(), + $value->getClientOriginalName(), + $value->getClientMimeType(), + $value->getError(), + true + ); + } + } + } + + return $filtered; + } + + /** + * Converts the HttpKernel response to a BrowserKit response. + * + * @return DomResponse A DomResponse instance + */ + protected function filterResponse($response) + { + // this is needed to support StreamedResponse + ob_start(); + $response->sendContent(); + $content = ob_get_clean(); + + return new DomResponse($content, $response->getStatusCode(), $response->headers->all()); + } } diff --git a/src/Symfony/Component/HttpKernel/HttpKernelBrowser.php b/src/Symfony/Component/HttpKernel/HttpKernelBrowser.php index 76f964ce6a..ab52df14ed 100644 --- a/src/Symfony/Component/HttpKernel/HttpKernelBrowser.php +++ b/src/Symfony/Component/HttpKernel/HttpKernelBrowser.php @@ -11,15 +11,6 @@ namespace Symfony\Component\HttpKernel; -use Symfony\Component\BrowserKit\AbstractBrowser; -use Symfony\Component\BrowserKit\CookieJar; -use Symfony\Component\BrowserKit\History; -use Symfony\Component\BrowserKit\Request as DomRequest; -use Symfony\Component\BrowserKit\Response as DomResponse; -use Symfony\Component\HttpFoundation\File\UploadedFile; -use Symfony\Component\HttpFoundation\Request; -use Symfony\Component\HttpFoundation\Response; - /** * Client simulates a browser and makes requests to an HttpKernel instance. * @@ -28,177 +19,6 @@ use Symfony\Component\HttpFoundation\Response; * @method Request getRequest() A Request instance * @method Response getResponse() A Response instance */ -class HttpKernelBrowser extends AbstractBrowser +class HttpKernelBrowser extends Client { - protected $kernel; - private $catchExceptions = true; - - /** - * @param HttpKernelInterface $kernel An HttpKernel instance - * @param array $server The server parameters (equivalent of $_SERVER) - * @param History $history A History instance to store the browser history - * @param CookieJar $cookieJar A CookieJar instance to store the cookies - */ - public function __construct(HttpKernelInterface $kernel, array $server = [], History $history = null, CookieJar $cookieJar = null) - { - // These class properties must be set before calling the parent constructor, as it may depend on it. - $this->kernel = $kernel; - $this->followRedirects = false; - - parent::__construct($server, $history, $cookieJar); - } - - /** - * Sets whether to catch exceptions when the kernel is handling a request. - * - * @param bool $catchExceptions Whether to catch exceptions - */ - public function catchExceptions($catchExceptions) - { - $this->catchExceptions = $catchExceptions; - } - - /** - * Makes a request. - * - * @return Response A Response instance - */ - protected function doRequest($request) - { - $response = $this->kernel->handle($request, HttpKernelInterface::MASTER_REQUEST, $this->catchExceptions); - - if ($this->kernel instanceof TerminableInterface) { - $this->kernel->terminate($request, $response); - } - - return $response; - } - - /** - * Returns the script to execute when the request must be insulated. - * - * @return string - */ - protected function getScript($request) - { - $kernel = var_export(serialize($this->kernel), true); - $request = var_export(serialize($request), true); - - $errorReporting = error_reporting(); - - $requires = ''; - foreach (get_declared_classes() as $class) { - if (0 === strpos($class, 'ComposerAutoloaderInit')) { - $r = new \ReflectionClass($class); - $file = \dirname(\dirname($r->getFileName())).'/autoload.php'; - if (file_exists($file)) { - $requires .= 'require_once '.var_export($file, true).";\n"; - } - } - } - - if (!$requires) { - throw new \RuntimeException('Composer autoloader not found.'); - } - - $code = <<getHandleScript(); - } - - protected function getHandleScript() - { - return <<<'EOF' -$response = $kernel->handle($request); - -if ($kernel instanceof Symfony\Component\HttpKernel\TerminableInterface) { - $kernel->terminate($request, $response); -} - -echo serialize($response); -EOF; - } - - /** - * Converts the BrowserKit request to a HttpKernel request. - * - * @return Request A Request instance - */ - protected function filterRequest(DomRequest $request) - { - $httpRequest = Request::create($request->getUri(), $request->getMethod(), $request->getParameters(), $request->getCookies(), $request->getFiles(), $request->getServer(), $request->getContent()); - - foreach ($this->filterFiles($httpRequest->files->all()) as $key => $value) { - $httpRequest->files->set($key, $value); - } - - return $httpRequest; - } - - /** - * Filters an array of files. - * - * This method created test instances of UploadedFile so that the move() - * method can be called on those instances. - * - * If the size of a file is greater than the allowed size (from php.ini) then - * an invalid UploadedFile is returned with an error set to UPLOAD_ERR_INI_SIZE. - * - * @see UploadedFile - * - * @return array An array with all uploaded files marked as already moved - */ - protected function filterFiles(array $files) - { - $filtered = []; - foreach ($files as $key => $value) { - if (\is_array($value)) { - $filtered[$key] = $this->filterFiles($value); - } elseif ($value instanceof UploadedFile) { - if ($value->isValid() && $value->getSize() > UploadedFile::getMaxFilesize()) { - $filtered[$key] = new UploadedFile( - '', - $value->getClientOriginalName(), - $value->getClientMimeType(), - UPLOAD_ERR_INI_SIZE, - true - ); - } else { - $filtered[$key] = new UploadedFile( - $value->getPathname(), - $value->getClientOriginalName(), - $value->getClientMimeType(), - $value->getError(), - true - ); - } - } - } - - return $filtered; - } - - /** - * Converts the HttpKernel response to a BrowserKit response. - * - * @return DomResponse A DomResponse instance - */ - protected function filterResponse($response) - { - // this is needed to support StreamedResponse - ob_start(); - $response->sendContent(); - $content = ob_get_clean(); - - return new DomResponse($content, $response->getStatusCode(), $response->headers->all()); - } } From 9f244a50ecee4f0721ae9341e8bdd8bd1f906152 Mon Sep 17 00:00:00 2001 From: Yonel Ceruto Date: Wed, 5 Jun 2019 18:09:42 -0400 Subject: [PATCH 06/10] Fix DoctrineBridge upgrade 5.0 --- UPGRADE-5.0.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/UPGRADE-5.0.md b/UPGRADE-5.0.md index c2abf4f8b7..4f94883ae3 100644 --- a/UPGRADE-5.0.md +++ b/UPGRADE-5.0.md @@ -75,7 +75,7 @@ DoctrineBridge * Deprecated injecting `ClassMetadataFactory` in `DoctrineExtractor`, an instance of `EntityManagerInterface` should be injected instead * Passing an `IdReader` to the `DoctrineChoiceLoader` when the query cannot be optimized with single id field will throw an exception, pass `null` instead - * Not passing an `IdReader` to the `DoctrineChoiceLoader` when the query can be optimized with single id field will throw an exception + * Not passing an `IdReader` to the `DoctrineChoiceLoader` when the query can be optimized with single id field will not apply any optimization DomCrawler From d03eb033bb413f310cdbe89005ba1b4ee7a88943 Mon Sep 17 00:00:00 2001 From: Thomas Calvet Date: Wed, 5 Jun 2019 18:16:43 +0200 Subject: [PATCH 07/10] [Cache] Pass arg to get callback everywhere --- .../Component/Cache/Adapter/ArrayAdapter.php | 3 ++- .../Component/Cache/Adapter/NullAdapter.php | 4 +++- .../Component/Cache/Adapter/ProxyAdapter.php | 4 ++-- .../Cache/Adapter/TraceableAdapter.php | 4 ++-- .../Cache/Tests/Adapter/AdapterTestCase.php | 19 +++++++++++++++++++ 5 files changed, 28 insertions(+), 6 deletions(-) diff --git a/src/Symfony/Component/Cache/Adapter/ArrayAdapter.php b/src/Symfony/Component/Cache/Adapter/ArrayAdapter.php index bbb1f846e4..defa48eed9 100644 --- a/src/Symfony/Component/Cache/Adapter/ArrayAdapter.php +++ b/src/Symfony/Component/Cache/Adapter/ArrayAdapter.php @@ -59,7 +59,8 @@ class ArrayAdapter implements AdapterInterface, CacheInterface, LoggerAwareInter // ArrayAdapter works in memory, we don't care about stampede protection if (INF === $beta || !$item->isHit()) { - $this->save($item->set($callback($item))); + $save = true; + $this->save($item->set($callback($item, $save))); } return $item->get(); diff --git a/src/Symfony/Component/Cache/Adapter/NullAdapter.php b/src/Symfony/Component/Cache/Adapter/NullAdapter.php index f1bdd2bf71..54cd453565 100644 --- a/src/Symfony/Component/Cache/Adapter/NullAdapter.php +++ b/src/Symfony/Component/Cache/Adapter/NullAdapter.php @@ -42,7 +42,9 @@ class NullAdapter implements AdapterInterface, CacheInterface */ public function get(string $key, callable $callback, float $beta = null, array &$metadata = null) { - return $callback(($this->createCacheItem)($key)); + $save = true; + + return $callback(($this->createCacheItem)($key), $save); } /** diff --git a/src/Symfony/Component/Cache/Adapter/ProxyAdapter.php b/src/Symfony/Component/Cache/Adapter/ProxyAdapter.php index 8340bdf034..cf51b90d8d 100644 --- a/src/Symfony/Component/Cache/Adapter/ProxyAdapter.php +++ b/src/Symfony/Component/Cache/Adapter/ProxyAdapter.php @@ -103,9 +103,9 @@ class ProxyAdapter implements AdapterInterface, CacheInterface, PruneableInterfa return $this->doGet($this, $key, $callback, $beta, $metadata); } - return $this->pool->get($this->getId($key), function ($innerItem) use ($key, $callback) { + return $this->pool->get($this->getId($key), function ($innerItem, bool &$save) use ($key, $callback) { $item = ($this->createCacheItem)($key, $innerItem); - $item->set($value = $callback($item)); + $item->set($value = $callback($item, $save)); ($this->setInnerItem)($innerItem, (array) $item); return $value; diff --git a/src/Symfony/Component/Cache/Adapter/TraceableAdapter.php b/src/Symfony/Component/Cache/Adapter/TraceableAdapter.php index 5c294d03fd..660acf54d7 100644 --- a/src/Symfony/Component/Cache/Adapter/TraceableAdapter.php +++ b/src/Symfony/Component/Cache/Adapter/TraceableAdapter.php @@ -45,10 +45,10 @@ class TraceableAdapter implements AdapterInterface, CacheInterface, PruneableInt } $isHit = true; - $callback = function (CacheItem $item) use ($callback, &$isHit) { + $callback = function (CacheItem $item, bool &$save) use ($callback, &$isHit) { $isHit = $item->isHit(); - return $callback($item); + return $callback($item, $save); }; $event = $this->start(__FUNCTION__); diff --git a/src/Symfony/Component/Cache/Tests/Adapter/AdapterTestCase.php b/src/Symfony/Component/Cache/Tests/Adapter/AdapterTestCase.php index 498c00ca64..2b4c9e95bf 100644 --- a/src/Symfony/Component/Cache/Tests/Adapter/AdapterTestCase.php +++ b/src/Symfony/Component/Cache/Tests/Adapter/AdapterTestCase.php @@ -12,9 +12,12 @@ namespace Symfony\Component\Cache\Tests\Adapter; use Cache\IntegrationTests\CachePoolTest; +use PHPUnit\Framework\Assert; +use Psr\Cache\CacheItemInterface; use Psr\Cache\CacheItemPoolInterface; use Symfony\Component\Cache\CacheItem; use Symfony\Component\Cache\PruneableInterface; +use Symfony\Contracts\Cache\CallbackInterface; abstract class AdapterTestCase extends CachePoolTest { @@ -57,6 +60,22 @@ abstract class AdapterTestCase extends CachePoolTest $this->assertSame($value, $item->get()); }, INF)); $this->assertFalse($isHit); + + $this->assertSame($value, $cache->get('bar', new class($value) implements CallbackInterface { + private $value; + + public function __construct(int $value) + { + $this->value = $value; + } + + public function __invoke(CacheItemInterface $item, bool &$save) + { + Assert::assertSame('bar', $item->getKey()); + + return $this->value; + } + })); } public function testRecursiveGet() From 625392669a1dfd6c4210b5c506d6d9392e78c21a Mon Sep 17 00:00:00 2001 From: Nicolas Grekas Date: Wed, 5 Jun 2019 18:16:08 +0200 Subject: [PATCH 08/10] [FrameworkBundle] fix BC-breaking property in WebTestAssertionsTrait --- .../Test/WebTestAssertionsTrait.php | 64 ++++++++++--------- .../FrameworkBundle/Test/WebTestCase.php | 8 +-- .../Tests/Test/WebTestCaseTest.php | 4 +- 3 files changed, 38 insertions(+), 38 deletions(-) diff --git a/src/Symfony/Bundle/FrameworkBundle/Test/WebTestAssertionsTrait.php b/src/Symfony/Bundle/FrameworkBundle/Test/WebTestAssertionsTrait.php index ce6c514518..e3e37a5359 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Test/WebTestAssertionsTrait.php +++ b/src/Symfony/Bundle/FrameworkBundle/Test/WebTestAssertionsTrait.php @@ -30,12 +30,12 @@ trait WebTestAssertionsTrait { public static function assertResponseIsSuccessful(string $message = ''): void { - self::assertThat(static::getResponse(), new ResponseConstraint\ResponseIsSuccessful(), $message); + self::assertThat(self::getResponse(), new ResponseConstraint\ResponseIsSuccessful(), $message); } public static function assertResponseStatusCodeSame(int $expectedCode, string $message = ''): void { - self::assertThat(static::getResponse(), new ResponseConstraint\ResponseStatusCodeSame($expectedCode), $message); + self::assertThat(self::getResponse(), new ResponseConstraint\ResponseStatusCodeSame($expectedCode), $message); } public static function assertResponseRedirects(string $expectedLocation = null, int $expectedCode = null, string $message = ''): void @@ -48,42 +48,42 @@ trait WebTestAssertionsTrait $constraint = LogicalAnd::fromConstraints($constraint, new ResponseConstraint\ResponseStatusCodeSame($expectedCode)); } - self::assertThat(static::getResponse(), $constraint, $message); + self::assertThat(self::getResponse(), $constraint, $message); } public static function assertResponseHasHeader(string $headerName, string $message = ''): void { - self::assertThat(static::getResponse(), new ResponseConstraint\ResponseHasHeader($headerName), $message); + self::assertThat(self::getResponse(), new ResponseConstraint\ResponseHasHeader($headerName), $message); } public static function assertResponseNotHasHeader(string $headerName, string $message = ''): void { - self::assertThat(static::getResponse(), new LogicalNot(new ResponseConstraint\ResponseHasHeader($headerName)), $message); + self::assertThat(self::getResponse(), new LogicalNot(new ResponseConstraint\ResponseHasHeader($headerName)), $message); } public static function assertResponseHeaderSame(string $headerName, string $expectedValue, string $message = ''): void { - self::assertThat(static::getResponse(), new ResponseConstraint\ResponseHeaderSame($headerName, $expectedValue), $message); + self::assertThat(self::getResponse(), new ResponseConstraint\ResponseHeaderSame($headerName, $expectedValue), $message); } public static function assertResponseHeaderNotSame(string $headerName, string $expectedValue, string $message = ''): void { - self::assertThat(static::getResponse(), new LogicalNot(new ResponseConstraint\ResponseHeaderSame($headerName, $expectedValue)), $message); + self::assertThat(self::getResponse(), new LogicalNot(new ResponseConstraint\ResponseHeaderSame($headerName, $expectedValue)), $message); } public static function assertResponseHasCookie(string $name, string $path = '/', string $domain = null, string $message = ''): void { - self::assertThat(static::getResponse(), new ResponseConstraint\ResponseHasCookie($name, $path, $domain), $message); + self::assertThat(self::getResponse(), new ResponseConstraint\ResponseHasCookie($name, $path, $domain), $message); } public static function assertResponseNotHasCookie(string $name, string $path = '/', string $domain = null, string $message = ''): void { - self::assertThat(static::getResponse(), new LogicalNot(new ResponseConstraint\ResponseHasCookie($name, $path, $domain)), $message); + self::assertThat(self::getResponse(), new LogicalNot(new ResponseConstraint\ResponseHasCookie($name, $path, $domain)), $message); } public static function assertResponseCookieValueSame(string $name, string $expectedValue, string $path = '/', string $domain = null, string $message = ''): void { - self::assertThat(static::getResponse(), LogicalAnd::fromConstraints( + self::assertThat(self::getResponse(), LogicalAnd::fromConstraints( new ResponseConstraint\ResponseHasCookie($name, $path, $domain), new ResponseConstraint\ResponseCookieValueSame($name, $expectedValue, $path, $domain) ), $message); @@ -91,17 +91,17 @@ trait WebTestAssertionsTrait public static function assertBrowserHasCookie(string $name, string $path = '/', string $domain = null, string $message = ''): void { - self::assertThat(static::getClient(), new BrowserKitConstraint\BrowserHasCookie($name, $path, $domain), $message); + self::assertThat(self::getClient(), new BrowserKitConstraint\BrowserHasCookie($name, $path, $domain), $message); } public static function assertBrowserNotHasCookie(string $name, string $path = '/', string $domain = null, string $message = ''): void { - self::assertThat(static::getClient(), new LogicalNot(new BrowserKitConstraint\BrowserHasCookie($name, $path, $domain)), $message); + self::assertThat(self::getClient(), new LogicalNot(new BrowserKitConstraint\BrowserHasCookie($name, $path, $domain)), $message); } public static function assertBrowserCookieValueSame(string $name, string $expectedValue, bool $raw = false, string $path = '/', string $domain = null, string $message = ''): void { - self::assertThat(static::getClient(), LogicalAnd::fromConstraints( + self::assertThat(self::getClient(), LogicalAnd::fromConstraints( new BrowserKitConstraint\BrowserHasCookie($name, $path, $domain), new BrowserKitConstraint\BrowserCookieValueSame($name, $expectedValue, $raw, $path, $domain) ), $message); @@ -109,17 +109,17 @@ trait WebTestAssertionsTrait public static function assertSelectorExists(string $selector, string $message = ''): void { - self::assertThat(static::getCrawler(), new DomCrawlerConstraint\CrawlerSelectorExists($selector), $message); + self::assertThat(self::getCrawler(), new DomCrawlerConstraint\CrawlerSelectorExists($selector), $message); } public static function assertSelectorNotExists(string $selector, string $message = ''): void { - self::assertThat(static::getCrawler(), new LogicalNot(new DomCrawlerConstraint\CrawlerSelectorExists($selector)), $message); + self::assertThat(self::getCrawler(), new LogicalNot(new DomCrawlerConstraint\CrawlerSelectorExists($selector)), $message); } public static function assertSelectorTextContains(string $selector, string $text, string $message = ''): void { - self::assertThat(static::getCrawler(), LogicalAnd::fromConstraints( + self::assertThat(self::getCrawler(), LogicalAnd::fromConstraints( new DomCrawlerConstraint\CrawlerSelectorExists($selector), new DomCrawlerConstraint\CrawlerSelectorTextContains($selector, $text) ), $message); @@ -127,7 +127,7 @@ trait WebTestAssertionsTrait public static function assertSelectorTextSame(string $selector, string $text, string $message = ''): void { - self::assertThat(static::getCrawler(), LogicalAnd::fromConstraints( + self::assertThat(self::getCrawler(), LogicalAnd::fromConstraints( new DomCrawlerConstraint\CrawlerSelectorExists($selector), new DomCrawlerConstraint\CrawlerSelectorTextSame($selector, $text) ), $message); @@ -135,7 +135,7 @@ trait WebTestAssertionsTrait public static function assertSelectorTextNotContains(string $selector, string $text, string $message = ''): void { - self::assertThat(static::getCrawler(), LogicalAnd::fromConstraints( + self::assertThat(self::getCrawler(), LogicalAnd::fromConstraints( new DomCrawlerConstraint\CrawlerSelectorExists($selector), new LogicalNot(new DomCrawlerConstraint\CrawlerSelectorTextContains($selector, $text)) ), $message); @@ -153,7 +153,7 @@ trait WebTestAssertionsTrait public static function assertInputValueSame(string $fieldName, string $expectedValue, string $message = ''): void { - self::assertThat(static::getCrawler(), LogicalAnd::fromConstraints( + self::assertThat(self::getCrawler(), LogicalAnd::fromConstraints( new DomCrawlerConstraint\CrawlerSelectorExists("input[name=\"$fieldName\"]"), new DomCrawlerConstraint\CrawlerSelectorAttributeValueSame("input[name=\"$fieldName\"]", 'value', $expectedValue) ), $message); @@ -161,7 +161,7 @@ trait WebTestAssertionsTrait public static function assertInputValueNotSame(string $fieldName, string $expectedValue, string $message = ''): void { - self::assertThat(static::getCrawler(), LogicalAnd::fromConstraints( + self::assertThat(self::getCrawler(), LogicalAnd::fromConstraints( new DomCrawlerConstraint\CrawlerSelectorExists("input[name=\"$fieldName\"]"), new LogicalNot(new DomCrawlerConstraint\CrawlerSelectorAttributeValueSame("input[name=\"$fieldName\"]", 'value', $expectedValue)) ), $message); @@ -169,7 +169,7 @@ trait WebTestAssertionsTrait public static function assertRequestAttributeValueSame(string $name, string $expectedValue, string $message = ''): void { - self::assertThat(static::getRequest(), new ResponseConstraint\RequestAttributeValueSame($name, $expectedValue), $message); + self::assertThat(self::getRequest(), new ResponseConstraint\RequestAttributeValueSame($name, $expectedValue), $message); } public static function assertRouteSame($expectedRoute, array $parameters = [], string $message = ''): void @@ -183,21 +183,27 @@ trait WebTestAssertionsTrait $constraint = LogicalAnd::fromConstraints($constraint, ...$constraints); } - self::assertThat(static::getRequest(), $constraint, $message); + self::assertThat(self::getRequest(), $constraint, $message); } - private static function getClient(): KernelBrowser + private static function getClient(KernelBrowser $newClient = null): ?KernelBrowser { - if (!static::$client instanceof KernelBrowser) { - static::fail(\sprintf('A client must be set to make assertions on it. Did you forget to call "%s::createClient"?', __CLASS__)); + static $client; + + if (0 < \func_num_args()) { + return $client = $newClient; } - return static::$client; + if (!$client instanceof KernelBrowser) { + static::fail(\sprintf('A client must be set to make assertions on it. Did you forget to call "%s::createClient()"?', __CLASS__)); + } + + return $client; } private static function getCrawler(): Crawler { - if (!$crawler = static::getClient()->getCrawler()) { + if (!$crawler = self::getClient()->getCrawler()) { static::fail('A client must have a crawler to make assertions. Did you forget to make an HTTP request?'); } @@ -206,7 +212,7 @@ trait WebTestAssertionsTrait private static function getResponse(): Response { - if (!$response = static::getClient()->getResponse()) { + if (!$response = self::getClient()->getResponse()) { static::fail('A client must have an HTTP Response to make assertions. Did you forget to make an HTTP request?'); } @@ -215,7 +221,7 @@ trait WebTestAssertionsTrait private static function getRequest(): Request { - if (!$request = static::getClient()->getRequest()) { + if (!$request = self::getClient()->getRequest()) { static::fail('A client must have an HTTP Request to make assertions. Did you forget to make an HTTP request?'); } diff --git a/src/Symfony/Bundle/FrameworkBundle/Test/WebTestCase.php b/src/Symfony/Bundle/FrameworkBundle/Test/WebTestCase.php index caed6fe8a2..09ab5eeb66 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Test/WebTestCase.php +++ b/src/Symfony/Bundle/FrameworkBundle/Test/WebTestCase.php @@ -23,14 +23,10 @@ abstract class WebTestCase extends KernelTestCase { use WebTestAssertionsTrait; - /** @var KernelBrowser|null */ - protected static $client; - protected function doTearDown(): void { parent::doTearDown(); - - static::$client = null; + self::getClient(null); } /** @@ -56,6 +52,6 @@ abstract class WebTestCase extends KernelTestCase $client->setServerParameters($server); - return static::$client = $client; + return self::getClient($client); } } diff --git a/src/Symfony/Bundle/FrameworkBundle/Tests/Test/WebTestCaseTest.php b/src/Symfony/Bundle/FrameworkBundle/Tests/Test/WebTestCaseTest.php index dc1bef152f..c77e5a6f2d 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Tests/Test/WebTestCaseTest.php +++ b/src/Symfony/Bundle/FrameworkBundle/Tests/Test/WebTestCaseTest.php @@ -277,11 +277,9 @@ class WebTestCaseTest extends TestCase return new class($client) extends WebTestCase { use WebTestAssertionsTrait; - protected static $client; - public function __construct(KernelBrowser $client) { - static::$client = $client; + self::getClient($client); } }; } From 35e6df6bac3bbb35f71c57771ecf1dbbc510af38 Mon Sep 17 00:00:00 2001 From: Franco Traversaro Date: Wed, 5 Jun 2019 16:31:24 +0200 Subject: [PATCH 09/10] [Doctrine Bridge] Check field type before adding Length constraint --- .../Doctrine/Tests/Fixtures/DoctrineLoaderEntity.php | 9 +++++++++ .../Doctrine/Tests/Validator/DoctrineLoaderTest.php | 10 ++++++++++ .../Bridge/Doctrine/Validator/DoctrineLoader.php | 2 +- 3 files changed, 20 insertions(+), 1 deletion(-) diff --git a/src/Symfony/Bridge/Doctrine/Tests/Fixtures/DoctrineLoaderEntity.php b/src/Symfony/Bridge/Doctrine/Tests/Fixtures/DoctrineLoaderEntity.php index b6b6a681bd..dc06d37fa3 100644 --- a/src/Symfony/Bridge/Doctrine/Tests/Fixtures/DoctrineLoaderEntity.php +++ b/src/Symfony/Bridge/Doctrine/Tests/Fixtures/DoctrineLoaderEntity.php @@ -60,4 +60,13 @@ class DoctrineLoaderEntity extends DoctrineLoaderParentEntity * @ORM\Embedded(class=DoctrineLoaderEmbed::class) */ public $embedded; + + /** @ORM\Column(type="text", nullable=true, length=1000) */ + public $textField; + + /** @ORM\Id @ORM\Column(type="guid", length=50) */ + protected $guidField; + + /** @ORM\Column(type="simple_array", length=100) */ + public $simpleArrayField = []; } diff --git a/src/Symfony/Bridge/Doctrine/Tests/Validator/DoctrineLoaderTest.php b/src/Symfony/Bridge/Doctrine/Tests/Validator/DoctrineLoaderTest.php index e673d79210..c4c0d75fa7 100644 --- a/src/Symfony/Bridge/Doctrine/Tests/Validator/DoctrineLoaderTest.php +++ b/src/Symfony/Bridge/Doctrine/Tests/Validator/DoctrineLoaderTest.php @@ -108,6 +108,16 @@ class DoctrineLoaderTest extends TestCase $this->assertCount(1, $embeddedMaxLengthConstraints); $this->assertInstanceOf(Length::class, $embeddedMaxLengthConstraints[0]); $this->assertSame(25, $embeddedMaxLengthConstraints[0]->max); + + $this->assertCount(0, $classMetadata->getPropertyMetadata('guidField')); + $this->assertCount(0, $classMetadata->getPropertyMetadata('simpleArrayField')); + + $textFieldMetadata = $classMetadata->getPropertyMetadata('textField'); + $this->assertCount(1, $textFieldMetadata); + $textFieldConstraints = $textFieldMetadata[0]->getConstraints(); + $this->assertCount(1, $textFieldConstraints); + $this->assertInstanceOf(Length::class, $textFieldConstraints[0]); + $this->assertSame(1000, $textFieldConstraints[0]->max); } public function testFieldMappingsConfiguration() diff --git a/src/Symfony/Bridge/Doctrine/Validator/DoctrineLoader.php b/src/Symfony/Bridge/Doctrine/Validator/DoctrineLoader.php index b3993518dd..53bf606ac3 100644 --- a/src/Symfony/Bridge/Doctrine/Validator/DoctrineLoader.php +++ b/src/Symfony/Bridge/Doctrine/Validator/DoctrineLoader.php @@ -73,7 +73,7 @@ final class DoctrineLoader implements LoaderInterface $metadata->addConstraint(new UniqueEntity(['fields' => $mapping['fieldName']])); } - if (null === ($mapping['length'] ?? null)) { + if (null === ($mapping['length'] ?? null) || !\in_array($mapping['type'], ['string', 'text'], true)) { continue; } From 4a4b62bf4d012f4052a1127ef075a01809bc25be Mon Sep 17 00:00:00 2001 From: Nicolas Grekas Date: Thu, 6 Jun 2019 11:21:46 +0200 Subject: [PATCH 10/10] [HttpKernel] fix link to source generation --- .../Component/HttpKernel/Debug/FileLinkFormatter.php | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/src/Symfony/Component/HttpKernel/Debug/FileLinkFormatter.php b/src/Symfony/Component/HttpKernel/Debug/FileLinkFormatter.php index 54defbf1d1..eb24167529 100644 --- a/src/Symfony/Component/HttpKernel/Debug/FileLinkFormatter.php +++ b/src/Symfony/Component/HttpKernel/Debug/FileLinkFormatter.php @@ -68,7 +68,7 @@ class FileLinkFormatter */ public function __sleep(): array { - $this->getFileLinkFormat(); + $this->fileLinkFormat = $this->getFileLinkFormat(); return ['fileLinkFormat']; } @@ -87,17 +87,19 @@ class FileLinkFormatter private function getFileLinkFormat() { + if ($this->fileLinkFormat) { + return $this->fileLinkFormat; + } + if ($this->requestStack && $this->baseDir && $this->urlFormat) { $request = $this->requestStack->getMasterRequest(); if ($request instanceof Request && (!$this->urlFormat instanceof \Closure || $this->urlFormat = ($this->urlFormat)())) { - $this->fileLinkFormat = [ + return [ $request->getSchemeAndHttpHost().$request->getBasePath().$this->urlFormat, $this->baseDir.\DIRECTORY_SEPARATOR, '', ]; } } - - return $this->fileLinkFormat; } }