From 6852a46423970a0fbad0a97d782a5c20c874ce0e Mon Sep 17 00:00:00 2001 From: Possum Date: Thu, 14 Jan 2016 11:04:11 +0100 Subject: [PATCH 01/28] Normalize params only when used. --- src/Symfony/Bridge/Doctrine/Logger/DbalLogger.php | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/src/Symfony/Bridge/Doctrine/Logger/DbalLogger.php b/src/Symfony/Bridge/Doctrine/Logger/DbalLogger.php index 2d834d7d40..acd8cc0fcd 100644 --- a/src/Symfony/Bridge/Doctrine/Logger/DbalLogger.php +++ b/src/Symfony/Bridge/Doctrine/Logger/DbalLogger.php @@ -49,12 +49,8 @@ class DbalLogger implements SQLLogger $this->stopwatch->start('doctrine', 'doctrine'); } - if (is_array($params)) { - $params = $this->normalizeParams($params); - } - if (null !== $this->logger) { - $this->log($sql, null === $params ? array() : $params); + $this->log($sql, null === $params ? array() : $this->normalizeParams($params)); } } From 50d55f68552a0fd41745a94528f89b9d23c9d6a3 Mon Sep 17 00:00:00 2001 From: Tobias Schultze Date: Thu, 14 Jan 2016 14:17:14 +0100 Subject: [PATCH 02/28] [SecurityBundle] fix SecureRandom service constructor args --- .../Bundle/SecurityBundle/Resources/config/security.xml | 6 +----- src/Symfony/Bundle/SecurityBundle/composer.json | 2 +- 2 files changed, 2 insertions(+), 6 deletions(-) diff --git a/src/Symfony/Bundle/SecurityBundle/Resources/config/security.xml b/src/Symfony/Bundle/SecurityBundle/Resources/config/security.xml index 0e65fcfe15..956bf89aa4 100644 --- a/src/Symfony/Bundle/SecurityBundle/Resources/config/security.xml +++ b/src/Symfony/Bundle/SecurityBundle/Resources/config/security.xml @@ -141,10 +141,6 @@ - - - %kernel.cache_dir%/secure_random.seed - - + diff --git a/src/Symfony/Bundle/SecurityBundle/composer.json b/src/Symfony/Bundle/SecurityBundle/composer.json index 98f4fd0fff..2c18a26bc5 100644 --- a/src/Symfony/Bundle/SecurityBundle/composer.json +++ b/src/Symfony/Bundle/SecurityBundle/composer.json @@ -17,7 +17,7 @@ ], "require": { "php": ">=5.3.3", - "symfony/security": "~2.2", + "symfony/security": "~2.3.37|~2.6.13|~2.7.9|~2.8", "symfony/security-acl": "~2.2", "symfony/http-kernel": "~2.2" }, From d1f72d8ef4e1b2b4bc20c6c8736858004fcb7005 Mon Sep 17 00:00:00 2001 From: Nicolas Grekas Date: Thu, 14 Jan 2016 14:08:57 +0100 Subject: [PATCH 03/28] Fix perf and mem issue when using token_get_all --- .../Translation/PhpExtractor.php | 6 +++--- .../ClassLoader/ClassCollectionLoader.php | 17 +++++++++-------- .../Component/ClassLoader/ClassMapGenerator.php | 17 +++++++++-------- src/Symfony/Component/HttpKernel/Kernel.php | 9 +++++---- .../Component/HttpKernel/Tests/KernelTest.php | 4 ++-- .../Routing/Loader/AnnotationFileLoader.php | 14 +++++++------- 6 files changed, 35 insertions(+), 32 deletions(-) diff --git a/src/Symfony/Bundle/FrameworkBundle/Translation/PhpExtractor.php b/src/Symfony/Bundle/FrameworkBundle/Translation/PhpExtractor.php index e8479eb5cf..8bfa99da62 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Translation/PhpExtractor.php +++ b/src/Symfony/Bundle/FrameworkBundle/Translation/PhpExtractor.php @@ -81,7 +81,7 @@ class PhpExtractor implements ExtractorInterface */ protected function normalizeToken($token) { - if (is_array($token)) { + if (isset($token[1]) && 'b"' !== $token) { return $token[1]; } @@ -95,7 +95,7 @@ class PhpExtractor implements ExtractorInterface { for (; $tokenIterator->valid(); $tokenIterator->next()) { $t = $tokenIterator->current(); - if (!is_array($t) || ($t[0] !== T_WHITESPACE)) { + if (T_WHITESPACE !== $t[0]) { break; } } @@ -112,7 +112,7 @@ class PhpExtractor implements ExtractorInterface for (; $tokenIterator->valid(); $tokenIterator->next()) { $t = $tokenIterator->current(); - if (!is_array($t)) { + if (!isset($t[1])) { break; } diff --git a/src/Symfony/Component/ClassLoader/ClassCollectionLoader.php b/src/Symfony/Component/ClassLoader/ClassCollectionLoader.php index f811cd0a71..a137a3cf5c 100644 --- a/src/Symfony/Component/ClassLoader/ClassCollectionLoader.php +++ b/src/Symfony/Component/ClassLoader/ClassCollectionLoader.php @@ -149,8 +149,9 @@ class ClassCollectionLoader $inNamespace = false; $tokens = token_get_all($source); - for (reset($tokens); false !== $token = current($tokens); next($tokens)) { - if (is_string($token)) { + for ($i = 0; isset($tokens[$i]); ++$i) { + $token = $tokens[$i]; + if (!isset($token[1]) || 'b"' === $token) { $rawChunk .= $token; } elseif (in_array($token[0], array(T_COMMENT, T_DOC_COMMENT))) { // strip comments @@ -162,12 +163,12 @@ class ClassCollectionLoader $rawChunk .= $token[1]; // namespace name and whitespaces - while (($t = next($tokens)) && is_array($t) && in_array($t[0], array(T_WHITESPACE, T_NS_SEPARATOR, T_STRING))) { - $rawChunk .= $t[1]; + while (isset($tokens[++$i][1]) && in_array($tokens[$i][0], array(T_WHITESPACE, T_NS_SEPARATOR, T_STRING))) { + $rawChunk .= $tokens[$i][1]; } - if ('{' === $t) { + if ('{' === $tokens[$i]) { $inNamespace = false; - prev($tokens); + --$i; } else { $rawChunk = rtrim($rawChunk)."\n{"; $inNamespace = true; @@ -175,8 +176,8 @@ class ClassCollectionLoader } elseif (T_START_HEREDOC === $token[0]) { $output .= self::compressCode($rawChunk).$token[1]; do { - $token = next($tokens); - $output .= is_string($token) ? $token : $token[1]; + $token = $tokens[++$i]; + $output .= isset($token[1]) && 'b"' !== $token ? $token[1] : $token; } while ($token[0] !== T_END_HEREDOC); $output .= "\n"; $rawChunk = ''; diff --git a/src/Symfony/Component/ClassLoader/ClassMapGenerator.php b/src/Symfony/Component/ClassLoader/ClassMapGenerator.php index a4ddce5115..2f88df12e3 100644 --- a/src/Symfony/Component/ClassLoader/ClassMapGenerator.php +++ b/src/Symfony/Component/ClassLoader/ClassMapGenerator.php @@ -95,10 +95,10 @@ class ClassMapGenerator $classes = array(); $namespace = ''; - for ($i = 0, $max = count($tokens); $i < $max; ++$i) { + for ($i = 0; isset($tokens[$i]); ++$i) { $token = $tokens[$i]; - if (is_string($token)) { + if (!isset($token[1])) { continue; } @@ -108,9 +108,9 @@ class ClassMapGenerator case T_NAMESPACE: $namespace = ''; // If there is a namespace, extract it - while (($t = $tokens[++$i]) && is_array($t)) { - if (in_array($t[0], array(T_STRING, T_NS_SEPARATOR))) { - $namespace .= $t[1]; + while (isset($tokens[++$i][1])) { + if (in_array($tokens[$i][0], array(T_STRING, T_NS_SEPARATOR))) { + $namespace .= $tokens[$i][1]; } } $namespace .= '\\'; @@ -121,7 +121,7 @@ class ClassMapGenerator // Skip usage of ::class constant $isClassConstant = false; for ($j = $i - 1; $j > 0; --$j) { - if (is_string($tokens[$j])) { + if (!isset($tokens[$j][1])) { break; } @@ -138,10 +138,11 @@ class ClassMapGenerator } // Find the classname - while (($t = $tokens[++$i]) && is_array($t)) { + while (isset($tokens[++$i][1])) { + $t = $tokens[$i]; if (T_STRING === $t[0]) { $class .= $t[1]; - } elseif ($class !== '' && T_WHITESPACE == $t[0]) { + } elseif ('' !== $class && T_WHITESPACE === $t[0]) { break; } } diff --git a/src/Symfony/Component/HttpKernel/Kernel.php b/src/Symfony/Component/HttpKernel/Kernel.php index 04ec2c240b..6df51ae12d 100644 --- a/src/Symfony/Component/HttpKernel/Kernel.php +++ b/src/Symfony/Component/HttpKernel/Kernel.php @@ -699,14 +699,15 @@ abstract class Kernel implements KernelInterface, TerminableInterface $output = ''; $tokens = token_get_all($source); $ignoreSpace = false; - for (reset($tokens); false !== $token = current($tokens); next($tokens)) { - if (is_string($token)) { + for ($i = 0; isset($tokens[$i]); ++$i) { + $token = $tokens[$i]; + if (!isset($token[1]) || 'b"' === $token) { $rawChunk .= $token; } elseif (T_START_HEREDOC === $token[0]) { $output .= $rawChunk.$token[1]; do { - $token = next($tokens); - $output .= $token[1]; + $token = $tokens[++$i]; + $output .= isset($token[1]) && 'b"' !== $token ? $token[1] : $token; } while ($token[0] !== T_END_HEREDOC); $rawChunk = ''; } elseif (T_WHITESPACE === $token[0]) { diff --git a/src/Symfony/Component/HttpKernel/Tests/KernelTest.php b/src/Symfony/Component/HttpKernel/Tests/KernelTest.php index 6bf5c25884..fa1294e806 100644 --- a/src/Symfony/Component/HttpKernel/Tests/KernelTest.php +++ b/src/Symfony/Component/HttpKernel/Tests/KernelTest.php @@ -307,7 +307,7 @@ modified'; $heredoc = << Date: Thu, 14 Jan 2016 20:10:56 +0100 Subject: [PATCH 04/28] [TwigBridge] Use label_format option for checkbox and radio labels --- .../Resources/views/Form/bootstrap_3_layout.html.twig | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/src/Symfony/Bridge/Twig/Resources/views/Form/bootstrap_3_layout.html.twig b/src/Symfony/Bridge/Twig/Resources/views/Form/bootstrap_3_layout.html.twig index 165236ef61..5affc7a6a1 100644 --- a/src/Symfony/Bridge/Twig/Resources/views/Form/bootstrap_3_layout.html.twig +++ b/src/Symfony/Bridge/Twig/Resources/views/Form/bootstrap_3_layout.html.twig @@ -167,7 +167,14 @@ {% set label_attr = label_attr|merge({class: (label_attr.class|default('') ~ ' ' ~ parent_label_class)|trim}) %} {% endif %} {% if label is not same as(false) and label is empty %} - {% set label = name|humanize %} + {%- if label_format is not empty -%} + {% set label = label_format|replace({ + '%name%': name, + '%id%': id, + }) %} + {%- else -%} + {% set label = name|humanize %} + {%- endif -%} {% endif %} {{- widget|raw }} {{ label is not same as(false) ? (translation_domain is same as(false) ? label : label|trans({}, translation_domain)) -}} From 2bb5f45aea15df6824eadf9bf9c10b9145a3ec11 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=B4me=20Vasseur?= Date: Wed, 6 Jan 2016 22:10:50 +0100 Subject: [PATCH 05/28] Refactor serializer normalize method --- .../Component/Serializer/Serializer.php | 42 ++++--------------- 1 file changed, 7 insertions(+), 35 deletions(-) diff --git a/src/Symfony/Component/Serializer/Serializer.php b/src/Symfony/Component/Serializer/Serializer.php index eb83544b42..00e8b2b8ce 100644 --- a/src/Symfony/Component/Serializer/Serializer.php +++ b/src/Symfony/Component/Serializer/Serializer.php @@ -127,10 +127,8 @@ class Serializer implements SerializerInterface, NormalizerInterface, Denormaliz if (null === $data || is_scalar($data)) { return $data; } - if (is_object($data) && $this->supportsNormalization($data, $format)) { - return $this->normalizeObject($data, $format, $context); - } - if ($data instanceof \Traversable) { + + if (is_array($data) || $data instanceof \Traversable) { $normalized = array(); foreach ($data as $key => $val) { $normalized[$key] = $this->normalize($val, $format, $context); @@ -138,16 +136,15 @@ class Serializer implements SerializerInterface, NormalizerInterface, Denormaliz return $normalized; } + if (is_object($data)) { - return $this->normalizeObject($data, $format, $context); - } - if (is_array($data)) { - foreach ($data as $key => $val) { - $data[$key] = $this->normalize($val, $format, $context); + if (!$this->normalizers) { + throw new LogicException('You must register at least one normalizer to be able to normalize objects.'); } - return $data; + throw new UnexpectedValueException(sprintf('Could not normalize object of type %s, no supporting normalizer found.', get_class($data))); } + throw new UnexpectedValueException(sprintf('An unexpected value could not be normalized: %s', var_export($data, true))); } @@ -230,31 +227,6 @@ class Serializer implements SerializerInterface, NormalizerInterface, Denormaliz return $this->decoder->decode($data, $format, $context); } - /** - * Normalizes an object into a set of arrays/scalars. - * - * @param object $object object to normalize - * @param string $format format name, present to give the option to normalizers to act differently based on formats - * @param array $context The context data for this particular normalization - * - * @return array|string|bool|int|float|null - * - * @throws LogicException - * @throws UnexpectedValueException - */ - private function normalizeObject($object, $format, array $context = array()) - { - if (!$this->normalizers) { - throw new LogicException('You must register at least one normalizer to be able to normalize objects.'); - } - - if ($normalizer = $this->getNormalizer($object, $format)) { - return $normalizer->normalize($object, $format, $context); - } - - throw new UnexpectedValueException(sprintf('Could not normalize object of type %s, no supporting normalizer found.', get_class($object))); - } - /** * Denormalizes data back into an object of the given class. * From 197413168c43e4366e8500abc01193924d669e6e Mon Sep 17 00:00:00 2001 From: Javier Eguiluz Date: Fri, 15 Jan 2016 09:07:14 +0100 Subject: [PATCH 06/28] Removed a duplicated test in CardSchemeValidatorTest --- .../Validator/Tests/Constraints/CardSchemeValidatorTest.php | 1 - 1 file changed, 1 deletion(-) diff --git a/src/Symfony/Component/Validator/Tests/Constraints/CardSchemeValidatorTest.php b/src/Symfony/Component/Validator/Tests/Constraints/CardSchemeValidatorTest.php index 11418ac707..93cd84d4b1 100644 --- a/src/Symfony/Component/Validator/Tests/Constraints/CardSchemeValidatorTest.php +++ b/src/Symfony/Component/Validator/Tests/Constraints/CardSchemeValidatorTest.php @@ -92,7 +92,6 @@ class CardSchemeValidatorTest extends AbstractConstraintValidatorTest array('MAESTRO', '5020507657408074712'), array('MAESTRO', '5612559223580173965'), array('MAESTRO', '6759744069209'), - array('MAESTRO', '6759744069209'), array('MAESTRO', '6594371785970435599'), array('MASTERCARD', '5555555555554444'), array('MASTERCARD', '5105105105105100'), From e555aade120b0950ee63ed10e792dd602e749214 Mon Sep 17 00:00:00 2001 From: Peter Ward Date: Fri, 15 Jan 2016 08:12:11 +0000 Subject: [PATCH 07/28] Add gc_mem_caches() call for PHP7 after itoken_get_all() as new memory manager will not release small buckets to OS automatically --- .../FrameworkBundle/Translation/PhpExtractor.php | 5 +++++ .../Component/ClassLoader/ClassCollectionLoader.php | 10 +++++++++- .../Component/ClassLoader/ClassMapGenerator.php | 5 +++++ src/Symfony/Component/HttpKernel/Kernel.php | 6 ++++++ .../Component/Routing/Loader/AnnotationFileLoader.php | 4 ++++ 5 files changed, 29 insertions(+), 1 deletion(-) diff --git a/src/Symfony/Bundle/FrameworkBundle/Translation/PhpExtractor.php b/src/Symfony/Bundle/FrameworkBundle/Translation/PhpExtractor.php index 8bfa99da62..f68f8a7979 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Translation/PhpExtractor.php +++ b/src/Symfony/Bundle/FrameworkBundle/Translation/PhpExtractor.php @@ -61,6 +61,11 @@ class PhpExtractor implements ExtractorInterface $files = $finder->files()->name('*.php')->in($directory); foreach ($files as $file) { $this->parseTokens(token_get_all(file_get_contents($file)), $catalog); + + if (PHP_VERSION_ID >= 70000) { + // PHP 7 memory manager will not release after token_get_all(), see https://bugs.php.net/70098 + gc_mem_caches(); + } } } diff --git a/src/Symfony/Component/ClassLoader/ClassCollectionLoader.php b/src/Symfony/Component/ClassLoader/ClassCollectionLoader.php index a137a3cf5c..ba0b2e032a 100644 --- a/src/Symfony/Component/ClassLoader/ClassCollectionLoader.php +++ b/src/Symfony/Component/ClassLoader/ClassCollectionLoader.php @@ -193,7 +193,15 @@ class ClassCollectionLoader $rawChunk .= "}\n"; } - return $output.self::compressCode($rawChunk); + $output .= self::compressCode($rawChunk); + + if (PHP_VERSION_ID >= 70000) { + // PHP 7 memory manager will not release after token_get_all(), see https://bugs.php.net/70098 + unset($tokens, $rawChunk); + gc_mem_caches(); + } + + return $output; } /** diff --git a/src/Symfony/Component/ClassLoader/ClassMapGenerator.php b/src/Symfony/Component/ClassLoader/ClassMapGenerator.php index 2f88df12e3..07c974f428 100644 --- a/src/Symfony/Component/ClassLoader/ClassMapGenerator.php +++ b/src/Symfony/Component/ClassLoader/ClassMapGenerator.php @@ -72,6 +72,11 @@ class ClassMapGenerator $classes = self::findClasses($path); + if (PHP_VERSION_ID >= 70000) { + // PHP 7 memory manager will not release after token_get_all(), see https://bugs.php.net/70098 + gc_mem_caches(); + } + foreach ($classes as $class) { $map[$class] = $path; } diff --git a/src/Symfony/Component/HttpKernel/Kernel.php b/src/Symfony/Component/HttpKernel/Kernel.php index 6df51ae12d..fa849e02a1 100644 --- a/src/Symfony/Component/HttpKernel/Kernel.php +++ b/src/Symfony/Component/HttpKernel/Kernel.php @@ -733,6 +733,12 @@ abstract class Kernel implements KernelInterface, TerminableInterface $output .= $rawChunk; + if (PHP_VERSION_ID >= 70000) { + // PHP 7 memory manager will not release after token_get_all(), see https://bugs.php.net/70098 + unset($tokens, $rawChunk); + gc_mem_caches(); + } + return $output; } diff --git a/src/Symfony/Component/Routing/Loader/AnnotationFileLoader.php b/src/Symfony/Component/Routing/Loader/AnnotationFileLoader.php index 51ead25e79..a3a7e0e5ae 100644 --- a/src/Symfony/Component/Routing/Loader/AnnotationFileLoader.php +++ b/src/Symfony/Component/Routing/Loader/AnnotationFileLoader.php @@ -64,6 +64,10 @@ class AnnotationFileLoader extends FileLoader $collection->addResource(new FileResource($path)); $collection->addCollection($this->loader->load($class, $type)); } + if (PHP_VERSION_ID >= 70000) { + // PHP 7 memory manager will not release after token_get_all(), see https://bugs.php.net/70098 + gc_mem_caches(); + } return $collection; } From c847feb5f3fbe6509e3cda29de77e7afb44f0f26 Mon Sep 17 00:00:00 2001 From: Robin van der Vleuten Date: Fri, 15 Jan 2016 15:32:28 +0100 Subject: [PATCH 08/28] Fixed correct class name in thrown exception --- src/Symfony/Component/Routing/Loader/AnnotationClassLoader.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Symfony/Component/Routing/Loader/AnnotationClassLoader.php b/src/Symfony/Component/Routing/Loader/AnnotationClassLoader.php index 11d8f34d5a..24505add17 100644 --- a/src/Symfony/Component/Routing/Loader/AnnotationClassLoader.php +++ b/src/Symfony/Component/Routing/Loader/AnnotationClassLoader.php @@ -120,7 +120,7 @@ abstract class AnnotationClassLoader implements LoaderInterface $class = new \ReflectionClass($class); if ($class->isAbstract()) { - throw new \InvalidArgumentException(sprintf('Annotations from class "%s" cannot be read as it is abstract.', $class)); + throw new \InvalidArgumentException(sprintf('Annotations from class "%s" cannot be read as it is abstract.', $class->getName())); } if ($annot = $this->reader->getClassAnnotation($class, $this->routeAnnotationClass)) { From 51e3652aeb33587e163d39547938a2afea92cb07 Mon Sep 17 00:00:00 2001 From: Ener-Getick Date: Sat, 16 Jan 2016 14:42:15 +0100 Subject: [PATCH 09/28] Use is_subclass_of instead of Reflection when possible --- .../Component/Serializer/Normalizer/CustomNormalizer.php | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/Symfony/Component/Serializer/Normalizer/CustomNormalizer.php b/src/Symfony/Component/Serializer/Normalizer/CustomNormalizer.php index 83c3c14384..e3f09a9436 100644 --- a/src/Symfony/Component/Serializer/Normalizer/CustomNormalizer.php +++ b/src/Symfony/Component/Serializer/Normalizer/CustomNormalizer.php @@ -59,8 +59,6 @@ class CustomNormalizer extends SerializerAwareNormalizer implements NormalizerIn */ public function supportsDenormalization($data, $type, $format = null) { - $class = new \ReflectionClass($type); - - return $class->isSubclassOf('Symfony\Component\Serializer\Normalizer\DenormalizableInterface'); + return is_subclass_of($type, 'Symfony\Component\Serializer\Normalizer\DenormalizableInterface'); } } From 5af5d06f2e5ad11021365251c253f0b2c8d22e17 Mon Sep 17 00:00:00 2001 From: Ener-Getick Date: Sat, 16 Jan 2016 14:49:05 +0100 Subject: [PATCH 10/28] Use is_subclass_of instead of reflection --- .../DependencyInjection/Compiler/AddConsoleCommandPass.php | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Compiler/AddConsoleCommandPass.php b/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Compiler/AddConsoleCommandPass.php index 3c96761ba3..4ab0d82ed1 100644 --- a/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Compiler/AddConsoleCommandPass.php +++ b/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Compiler/AddConsoleCommandPass.php @@ -37,8 +37,7 @@ class AddConsoleCommandPass implements CompilerPassInterface } $class = $container->getParameterBag()->resolveValue($definition->getClass()); - $r = new \ReflectionClass($class); - if (!$r->isSubclassOf('Symfony\\Component\\Console\\Command\\Command')) { + if (!is_subclass_of($class, 'Symfony\\Component\\Console\\Command\\Command')) { throw new \InvalidArgumentException(sprintf('The service "%s" tagged "console.command" must be a subclass of "Symfony\\Component\\Console\\Command\\Command".', $id)); } $container->setAlias('console.command.'.strtolower(str_replace('\\', '_', $class)), $id); From aedeebb4f1c5108f40a8551f3eb7e02a92807c6a Mon Sep 17 00:00:00 2001 From: Tobias Schultze Date: Sat, 16 Jan 2016 18:29:47 +0100 Subject: [PATCH 11/28] fix merge 2.3 into 2.7 for SecureRandom dependency --- src/Symfony/Bundle/FrameworkBundle/composer.json | 2 +- src/Symfony/Bundle/SecurityBundle/composer.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Symfony/Bundle/FrameworkBundle/composer.json b/src/Symfony/Bundle/FrameworkBundle/composer.json index 045d19c354..bcfce7b707 100644 --- a/src/Symfony/Bundle/FrameworkBundle/composer.json +++ b/src/Symfony/Bundle/FrameworkBundle/composer.json @@ -26,7 +26,7 @@ "symfony/http-kernel": "~2.7", "symfony/filesystem": "~2.3", "symfony/routing": "~2.6,>2.6.4", - "symfony/security-core": "~2.6", + "symfony/security-core": "~2.6.13|~2.7.9|~2.8", "symfony/security-csrf": "~2.6", "symfony/stopwatch": "~2.3", "symfony/templating": "~2.1", diff --git a/src/Symfony/Bundle/SecurityBundle/composer.json b/src/Symfony/Bundle/SecurityBundle/composer.json index e702a90990..f00e09ca3c 100644 --- a/src/Symfony/Bundle/SecurityBundle/composer.json +++ b/src/Symfony/Bundle/SecurityBundle/composer.json @@ -17,7 +17,7 @@ ], "require": { "php": ">=5.3.9", - "symfony/security": "~2.7.9|~2.8", + "symfony/security": "~2.7", "symfony/security-acl": "~2.7", "symfony/http-kernel": "~2.2" }, From 8d5b9d572a96faf57914f181d2eb14ee071e60f2 Mon Sep 17 00:00:00 2001 From: Christian Flothmann Date: Sat, 16 Jan 2016 19:17:20 +0100 Subject: [PATCH 12/28] synchronize 2.7 and 3.0 upgrade files --- UPGRADE-3.0.md | 63 +++++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 57 insertions(+), 6 deletions(-) diff --git a/UPGRADE-3.0.md b/UPGRADE-3.0.md index 5f045f7c51..c572a20a15 100644 --- a/UPGRADE-3.0.md +++ b/UPGRADE-3.0.md @@ -19,6 +19,12 @@ UPGRADE FROM 2.x to 3.0 * The `DebugUniversalClassLoader` class has been removed in favor of `DebugClassLoader`. The difference is that the constructor now takes a loader to wrap. + ``` + +### Config + + * The `__toString()` method of the `\Symfony\Component\Config\ConfigCache` class + was removed in favor of the new `getPath()` method. ### Console @@ -99,6 +105,26 @@ UPGRADE FROM 2.x to 3.0 removed: `ContainerBuilder::synchronize()`, `Definition::isSynchronized()`, and `Definition::setSynchronized()`. +### DoctrineBridge + + * The `property` option of `DoctrineType` was removed in favor of the `choice_label` option. + + * The `loader` option of `DoctrineType` was removed. You now have to override the `getLoader()` + method in your custom type. + + * The `Symfony\Bridge\Doctrine\Form\ChoiceList\EntityChoiceList` was removed in favor + of `Symfony\Bridge\Doctrine\Form\ChoiceList\DoctrineChoiceLoader`. + + * Passing a query builder closure to `ORMQueryBuilderLoader` is not supported anymore. + You should pass resolved query builders only. + + Consequently, the arguments `$manager` and `$class` of `ORMQueryBuilderLoader` + have been removed as well. + + Note that the `query_builder` option of `DoctrineType` *does* support + closures, but the closure is now resolved in the type instead of in the + loader. + ### EventDispatcher * The interface `Symfony\Component\EventDispatcher\Debug\TraceableEventDispatcherInterface` @@ -106,6 +132,11 @@ UPGRADE FROM 2.x to 3.0 ### Form + * The `ChoiceToBooleanArrayTransformer`, `ChoicesToBooleanArrayTransformer`, + `FixRadioInputListener`, and `FixCheckboxInputListener` classes were removed. + + * The `choice_list` option of `ChoiceType` was removed. + * The option "precision" was renamed to "scale". Before: @@ -271,11 +302,11 @@ UPGRADE FROM 2.x to 3.0 `NumberToLocalizedStringTransformer` were renamed to `ROUND_HALF_EVEN`, `ROUND_HALF_UP` and `ROUND_HALF_DOWN`. - * The methods `ChoiceListInterface::getIndicesForChoices()` and - `ChoiceListInterface::getIndicesForValues()` were removed. No direct - replacement exists, although in most cases - `ChoiceListInterface::getChoicesForValues()` and - `ChoiceListInterface::getValuesForChoices()` should be sufficient. + * The `Symfony\Component\Form\Extension\Core\ChoiceList\ChoiceListInterface` was + removed in favor of `Symfony\Component\Form\ChoiceList\ChoiceListInterface`. + + * `Symfony\Component\Form\Extension\Core\View\ChoiceView` was removed in favor of + `Symfony\Component\Form\ChoiceList\View\ChoiceView`. * The interface `Symfony\Component\Form\Extension\Csrf\CsrfProvider\CsrfProviderInterface` and all of its implementations were removed. Use the new interface @@ -544,7 +575,7 @@ UPGRADE FROM 2.x to 3.0 * Some route settings have been renamed: - * The `pattern` setting for a route has been deprecated in favor of `path` + * The `pattern` setting has been removed in favor of `path` * The `_scheme` and `_method` requirements have been moved to the `schemes` and `methods` settings Before: @@ -597,10 +628,23 @@ UPGRADE FROM 2.x to 3.0 the performance gains were minimal and it's hard to replicate the behaviour of PHP implementation. + * The `getMatcherDumperInstance()` and `getGeneratorDumperInstance()` methods in the + `Symfony\Component\Routing\Router` have been changed from `public` to `protected`. + ### Security * The `Resources/` directory was moved to `Core/Resources/` +### Serializer + + * The `setCamelizedAttributes()` method of the + `Symfony\Component\Serializer\Normalizer\GetSetMethodNormalizer` and + `Symfony\Component\Serializer\Normalizer\PropertyNormalizer` classes + was removed. + + * The `Symfony\Component\Serializer\Exception\Exception` interface was removed + in favor of the new `Symfony\Component\Serializer\Exception\ExceptionInterface`. + ### Translator * The `Translator::setFallbackLocale()` method has been removed in favor of @@ -665,11 +709,18 @@ UPGRADE FROM 2.x to 3.0 ### TwigBundle + * The `Symfony\Bundle\TwigBundle\TwigDefaultEscapingStrategy` was removed + in favor of `Twig_FileExtensionEscapingStrategy`. + * The `twig:debug` command has been deprecated since Symfony 2.7 and will be removed in Symfony 3.0. Use the `debug:twig` command instead. ### Validator + * The PHP7-incompatible constraints (`Null`, `True`, `False`) and their related + validators (`NullValidator`, `TrueValidator`, `FalseValidator`) have been + removed in favor of their `Is`-prefixed equivalent. + * The class `Symfony\Component\Validator\Mapping\Cache\ApcCache` has been removed in favor of `Symfony\Component\Validator\Mapping\Cache\DoctrineCache`. From f6a078b96cd61556a6500c67735ba032eb94ab8b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Par=C3=A1da=20J=C3=B3zsef?= Date: Sat, 16 Jan 2016 13:37:00 +0100 Subject: [PATCH 13/28] [FrameworkBundle] Optimize framework extension tests --- .../Tests/DependencyInjection/FrameworkExtensionTest.php | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/FrameworkExtensionTest.php b/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/FrameworkExtensionTest.php index 33b5fa7f34..5b64b4e524 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/FrameworkExtensionTest.php +++ b/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/FrameworkExtensionTest.php @@ -18,6 +18,8 @@ use Symfony\Component\DependencyInjection\ParameterBag\ParameterBag; abstract class FrameworkExtensionTest extends TestCase { + private static $containerCache = array(); + abstract protected function loadFromFile(ContainerBuilder $container, $file); public function testCsrfProtection() @@ -307,6 +309,10 @@ abstract class FrameworkExtensionTest extends TestCase protected function createContainerFromFile($file, $data = array()) { + $cacheKey = md5($file.serialize($data)); + if (isset(self::$containerCache[$cacheKey])) { + return self::$containerCache[$cacheKey]; + } $container = $this->createContainer($data); $container->registerExtension(new FrameworkExtension()); $this->loadFromFile($container, $file); @@ -315,6 +321,6 @@ abstract class FrameworkExtensionTest extends TestCase $container->getCompilerPassConfig()->setRemovingPasses(array()); $container->compile(); - return $container; + return self::$containerCache[$cacheKey] = $container; } } From deab1276635890417ddddb8f02bc408155c3bdf6 Mon Sep 17 00:00:00 2001 From: Wouter J Date: Mon, 18 Jan 2016 10:52:44 +0100 Subject: [PATCH 14/28] Remove useless duplicated tests --- src/Symfony/Component/HttpFoundation/Tests/RequestTest.php | 5 ----- 1 file changed, 5 deletions(-) diff --git a/src/Symfony/Component/HttpFoundation/Tests/RequestTest.php b/src/Symfony/Component/HttpFoundation/Tests/RequestTest.php index cbc1b74fc9..e17953819b 100644 --- a/src/Symfony/Component/HttpFoundation/Tests/RequestTest.php +++ b/src/Symfony/Component/HttpFoundation/Tests/RequestTest.php @@ -17,11 +17,6 @@ use Symfony\Component\HttpFoundation\Request; class RequestTest extends \PHPUnit_Framework_TestCase { - public function testConstructor() - { - $this->testInitialize(); - } - public function testInitialize() { $request = new Request(); From 67c7f05d961ee7212633d4ec4aeadc56fbc6de22 Mon Sep 17 00:00:00 2001 From: Javier Eguiluz Date: Mon, 18 Jan 2016 17:01:35 +0100 Subject: [PATCH 15/28] Fixed Bootstrap form theme form "reset" buttons --- .../Form/bootstrap_3_horizontal_layout.html.twig | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/src/Symfony/Bridge/Twig/Resources/views/Form/bootstrap_3_horizontal_layout.html.twig b/src/Symfony/Bridge/Twig/Resources/views/Form/bootstrap_3_horizontal_layout.html.twig index e997615d11..5de20b1b8f 100644 --- a/src/Symfony/Bridge/Twig/Resources/views/Form/bootstrap_3_horizontal_layout.html.twig +++ b/src/Symfony/Bridge/Twig/Resources/views/Form/bootstrap_3_horizontal_layout.html.twig @@ -65,6 +65,17 @@ col-sm-2 {% endspaceless %} {% endblock submit_row %} +{% block reset_row -%} +{% spaceless %} +
+
+
+ {{ form_widget(form) }} +
+
+{% endspaceless %} +{% endblock reset_row %} + {% block form_group_class -%} col-sm-10 {%- endblock form_group_class %} From d662c2ae8fca7034e5f60401d4b1191426417d25 Mon Sep 17 00:00:00 2001 From: Javier Eguiluz Date: Mon, 18 Jan 2016 17:25:45 +0100 Subject: [PATCH 16/28] Fixed the documentation of VoterInterface::supportsAttribute --- .../Security/Core/Authorization/Voter/VoterInterface.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Symfony/Component/Security/Core/Authorization/Voter/VoterInterface.php b/src/Symfony/Component/Security/Core/Authorization/Voter/VoterInterface.php index d00ff1cfae..1032cb200d 100644 --- a/src/Symfony/Component/Security/Core/Authorization/Voter/VoterInterface.php +++ b/src/Symfony/Component/Security/Core/Authorization/Voter/VoterInterface.php @@ -27,7 +27,7 @@ interface VoterInterface /** * Checks if the voter supports the given attribute. * - * @param string $attribute An attribute + * @param mixed $attribute An attribute (usually the attribute name string) * * @return bool true if this Voter supports the attribute, false otherwise */ From c56c7bf869d952ba44ed48ab566fbca8361bd97b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?K=C3=A9vin=20Dunglas?= Date: Mon, 18 Jan 2016 17:42:55 +0100 Subject: [PATCH 17/28] [Serializer] Introduce constants for context keys --- .../Normalizer/AbstractNormalizer.php | 28 +++++++++++-------- .../Normalizer/AbstractNormalizerTest.php | 11 ++++---- .../Normalizer/GetSetMethodNormalizerTest.php | 14 +++++----- .../Tests/Normalizer/ObjectNormalizerTest.php | 12 ++++---- .../Normalizer/PropertyNormalizerTest.php | 12 ++++---- 5 files changed, 41 insertions(+), 36 deletions(-) diff --git a/src/Symfony/Component/Serializer/Normalizer/AbstractNormalizer.php b/src/Symfony/Component/Serializer/Normalizer/AbstractNormalizer.php index ae184bbeb6..f12d3d2263 100644 --- a/src/Symfony/Component/Serializer/Normalizer/AbstractNormalizer.php +++ b/src/Symfony/Component/Serializer/Normalizer/AbstractNormalizer.php @@ -27,6 +27,10 @@ use Symfony\Component\Serializer\NameConverter\NameConverterInterface; */ abstract class AbstractNormalizer extends SerializerAwareNormalizer implements NormalizerInterface, DenormalizerInterface { + const CIRCULAR_REFERENCE_LIMIT = 'circular_reference_limit'; + const OBJECT_TO_POPULATE = 'object_to_populate'; + const GROUPS = 'groups'; + /** * @var int */ @@ -185,16 +189,16 @@ abstract class AbstractNormalizer extends SerializerAwareNormalizer implements N { $objectHash = spl_object_hash($object); - if (isset($context['circular_reference_limit'][$objectHash])) { - if ($context['circular_reference_limit'][$objectHash] >= $this->circularReferenceLimit) { - unset($context['circular_reference_limit'][$objectHash]); + if (isset($context[static::CIRCULAR_REFERENCE_LIMIT][$objectHash])) { + if ($context[static::CIRCULAR_REFERENCE_LIMIT][$objectHash] >= $this->circularReferenceLimit) { + unset($context[static::CIRCULAR_REFERENCE_LIMIT][$objectHash]); return true; } - ++$context['circular_reference_limit'][$objectHash]; + ++$context[static::CIRCULAR_REFERENCE_LIMIT][$objectHash]; } else { - $context['circular_reference_limit'][$objectHash] = 1; + $context[static::CIRCULAR_REFERENCE_LIMIT][$objectHash] = 1; } return false; @@ -248,13 +252,13 @@ abstract class AbstractNormalizer extends SerializerAwareNormalizer implements N */ protected function getAllowedAttributes($classOrObject, array $context, $attributesAsString = false) { - if (!$this->classMetadataFactory || !isset($context['groups']) || !is_array($context['groups'])) { + if (!$this->classMetadataFactory || !isset($context[static::GROUPS]) || !is_array($context[static::GROUPS])) { return false; } $allowedAttributes = array(); foreach ($this->classMetadataFactory->getMetadataFor($classOrObject)->getAttributesMetadata() as $attributeMetadata) { - if (count(array_intersect($attributeMetadata->getGroups(), $context['groups']))) { + if (count(array_intersect($attributeMetadata->getGroups(), $context[static::GROUPS]))) { $allowedAttributes[] = $attributesAsString ? $attributeMetadata->getName() : $attributeMetadata; } } @@ -296,12 +300,12 @@ abstract class AbstractNormalizer extends SerializerAwareNormalizer implements N protected function instantiateObject(array &$data, $class, array &$context, \ReflectionClass $reflectionClass, $allowedAttributes) { if ( - isset($context['object_to_populate']) && - is_object($context['object_to_populate']) && - $context['object_to_populate'] instanceof $class + isset($context[static::OBJECT_TO_POPULATE]) && + is_object($context[static::OBJECT_TO_POPULATE]) && + $context[static::OBJECT_TO_POPULATE] instanceof $class ) { - $object = $context['object_to_populate']; - unset($context['object_to_populate']); + $object = $context[static::OBJECT_TO_POPULATE]; + unset($context[static::OBJECT_TO_POPULATE]); return $object; } diff --git a/src/Symfony/Component/Serializer/Tests/Normalizer/AbstractNormalizerTest.php b/src/Symfony/Component/Serializer/Tests/Normalizer/AbstractNormalizerTest.php index b317ec276f..66ac992350 100644 --- a/src/Symfony/Component/Serializer/Tests/Normalizer/AbstractNormalizerTest.php +++ b/src/Symfony/Component/Serializer/Tests/Normalizer/AbstractNormalizerTest.php @@ -5,6 +5,7 @@ namespace Symfony\Component\Serializer\Tests\Normalizer; use Symfony\Component\Serializer\Mapping\AttributeMetadata; use Symfony\Component\Serializer\Mapping\ClassMetadata; use Symfony\Component\Serializer\Mapping\Factory\ClassMetadataFactoryInterface; +use Symfony\Component\Serializer\Normalizer\AbstractNormalizer; use Symfony\Component\Serializer\Normalizer\ObjectNormalizer; use Symfony\Component\Serializer\Tests\Fixtures\AbstractNormalizerDummy; use Symfony\Component\Serializer\Tests\Fixtures\ProxyDummy; @@ -55,10 +56,10 @@ class AbstractNormalizerTest extends \PHPUnit_Framework_TestCase $this->classMetadata->method('getMetadataFor')->willReturn($classMetadata); - $result = $this->normalizer->getAllowedAttributes('c', array('groups' => array('test')), true); + $result = $this->normalizer->getAllowedAttributes('c', array(AbstractNormalizer::GROUPS => array('test')), true); $this->assertEquals(array('a2', 'a4'), $result); - $result = $this->normalizer->getAllowedAttributes('c', array('groups' => array('other')), true); + $result = $this->normalizer->getAllowedAttributes('c', array(AbstractNormalizer::GROUPS => array('other')), true); $this->assertEquals(array('a3', 'a4'), $result); } @@ -84,10 +85,10 @@ class AbstractNormalizerTest extends \PHPUnit_Framework_TestCase $this->classMetadata->method('getMetadataFor')->willReturn($classMetadata); - $result = $this->normalizer->getAllowedAttributes('c', array('groups' => array('test')), false); + $result = $this->normalizer->getAllowedAttributes('c', array(AbstractNormalizer::GROUPS => array('test')), false); $this->assertEquals(array($a2, $a4), $result); - $result = $this->normalizer->getAllowedAttributes('c', array('groups' => array('other')), false); + $result = $this->normalizer->getAllowedAttributes('c', array(AbstractNormalizer::GROUPS => array('other')), false); $this->assertEquals(array($a3, $a4), $result); } @@ -95,7 +96,7 @@ class AbstractNormalizerTest extends \PHPUnit_Framework_TestCase { $proxyDummy = new ProxyDummy(); - $context = array('object_to_populate' => $proxyDummy); + $context = array(AbstractNormalizer::OBJECT_TO_POPULATE => $proxyDummy); $normalizer = new ObjectNormalizer(); $normalizer->denormalize(array('foo' => 'bar'), 'Symfony\Component\Serializer\Tests\Fixtures\ToBeProxyfiedDummy', null, $context); diff --git a/src/Symfony/Component/Serializer/Tests/Normalizer/GetSetMethodNormalizerTest.php b/src/Symfony/Component/Serializer/Tests/Normalizer/GetSetMethodNormalizerTest.php index 1d487c2fdd..9027bfa7ec 100644 --- a/src/Symfony/Component/Serializer/Tests/Normalizer/GetSetMethodNormalizerTest.php +++ b/src/Symfony/Component/Serializer/Tests/Normalizer/GetSetMethodNormalizerTest.php @@ -277,7 +277,7 @@ class GetSetMethodNormalizerTest extends \PHPUnit_Framework_TestCase $this->assertEquals(array( 'bar' => 'bar', - ), $this->normalizer->normalize($obj, null, array('groups' => array('c')))); + ), $this->normalizer->normalize($obj, null, array(GetSetMethodNormalizer::GROUPS => array('c')))); $this->assertEquals(array( 'symfony' => 'symfony', @@ -286,7 +286,7 @@ class GetSetMethodNormalizerTest extends \PHPUnit_Framework_TestCase 'bar' => 'bar', 'kevin' => 'kevin', 'coopTilleuls' => 'coopTilleuls', - ), $this->normalizer->normalize($obj, null, array('groups' => array('a', 'c')))); + ), $this->normalizer->normalize($obj, null, array(GetSetMethodNormalizer::GROUPS => array('a', 'c')))); } public function testGroupsDenormalize() @@ -304,7 +304,7 @@ class GetSetMethodNormalizerTest extends \PHPUnit_Framework_TestCase $toNormalize, 'Symfony\Component\Serializer\Tests\Fixtures\GroupDummy', null, - array('groups' => array('a')) + array(GetSetMethodNormalizer::GROUPS => array('a')) ); $this->assertEquals($obj, $normalized); @@ -314,7 +314,7 @@ class GetSetMethodNormalizerTest extends \PHPUnit_Framework_TestCase $toNormalize, 'Symfony\Component\Serializer\Tests\Fixtures\GroupDummy', null, - array('groups' => array('a', 'b')) + array(GetSetMethodNormalizer::GROUPS => array('a', 'b')) ); $this->assertEquals($obj, $normalized); } @@ -336,7 +336,7 @@ class GetSetMethodNormalizerTest extends \PHPUnit_Framework_TestCase 'foo_bar' => '@dunglas', 'symfony' => '@coopTilleuls', ), - $this->normalizer->normalize($obj, null, array('groups' => array('name_converter'))) + $this->normalizer->normalize($obj, null, array(GetSetMethodNormalizer::GROUPS => array('name_converter'))) ); } @@ -357,7 +357,7 @@ class GetSetMethodNormalizerTest extends \PHPUnit_Framework_TestCase 'foo_bar' => '@dunglas', 'symfony' => '@coopTilleuls', 'coop_tilleuls' => 'les-tilleuls.coop', - ), 'Symfony\Component\Serializer\Tests\Fixtures\GroupDummy', null, array('groups' => array('name_converter'))) + ), 'Symfony\Component\Serializer\Tests\Fixtures\GroupDummy', null, array(GetSetMethodNormalizer::GROUPS => array('name_converter'))) ); } @@ -533,7 +533,7 @@ class GetSetMethodNormalizerTest extends \PHPUnit_Framework_TestCase array('bar' => 'bar'), __NAMESPACE__.'\GetSetDummy', null, - array('object_to_populate' => $dummy) + array(GetSetMethodNormalizer::OBJECT_TO_POPULATE => $dummy) ); $this->assertEquals($dummy, $obj); diff --git a/src/Symfony/Component/Serializer/Tests/Normalizer/ObjectNormalizerTest.php b/src/Symfony/Component/Serializer/Tests/Normalizer/ObjectNormalizerTest.php index 80a021d08f..c0602d7fa6 100644 --- a/src/Symfony/Component/Serializer/Tests/Normalizer/ObjectNormalizerTest.php +++ b/src/Symfony/Component/Serializer/Tests/Normalizer/ObjectNormalizerTest.php @@ -197,7 +197,7 @@ class ObjectNormalizerTest extends \PHPUnit_Framework_TestCase $this->assertEquals(array( 'bar' => 'bar', - ), $this->normalizer->normalize($obj, null, array('groups' => array('c')))); + ), $this->normalizer->normalize($obj, null, array(ObjectNormalizer::GROUPS => array('c')))); $this->assertEquals(array( 'symfony' => 'symfony', @@ -206,7 +206,7 @@ class ObjectNormalizerTest extends \PHPUnit_Framework_TestCase 'bar' => 'bar', 'kevin' => 'kevin', 'coopTilleuls' => 'coopTilleuls', - ), $this->normalizer->normalize($obj, null, array('groups' => array('a', 'c')))); + ), $this->normalizer->normalize($obj, null, array(ObjectNormalizer::GROUPS => array('a', 'c')))); } public function testGroupsDenormalize() @@ -224,7 +224,7 @@ class ObjectNormalizerTest extends \PHPUnit_Framework_TestCase $toNormalize, 'Symfony\Component\Serializer\Tests\Fixtures\GroupDummy', null, - array('groups' => array('a')) + array(ObjectNormalizer::GROUPS => array('a')) ); $this->assertEquals($obj, $normalized); @@ -234,7 +234,7 @@ class ObjectNormalizerTest extends \PHPUnit_Framework_TestCase $toNormalize, 'Symfony\Component\Serializer\Tests\Fixtures\GroupDummy', null, - array('groups' => array('a', 'b')) + array(ObjectNormalizer::GROUPS => array('a', 'b')) ); $this->assertEquals($obj, $normalized); } @@ -256,7 +256,7 @@ class ObjectNormalizerTest extends \PHPUnit_Framework_TestCase 'foo_bar' => '@dunglas', 'symfony' => '@coopTilleuls', ), - $this->normalizer->normalize($obj, null, array('groups' => array('name_converter'))) + $this->normalizer->normalize($obj, null, array(ObjectNormalizer::GROUPS => array('name_converter'))) ); } @@ -277,7 +277,7 @@ class ObjectNormalizerTest extends \PHPUnit_Framework_TestCase 'foo_bar' => '@dunglas', 'symfony' => '@coopTilleuls', 'coop_tilleuls' => 'les-tilleuls.coop', - ), 'Symfony\Component\Serializer\Tests\Fixtures\GroupDummy', null, array('groups' => array('name_converter'))) + ), 'Symfony\Component\Serializer\Tests\Fixtures\GroupDummy', null, array(ObjectNormalizer::GROUPS => array('name_converter'))) ); } diff --git a/src/Symfony/Component/Serializer/Tests/Normalizer/PropertyNormalizerTest.php b/src/Symfony/Component/Serializer/Tests/Normalizer/PropertyNormalizerTest.php index fd30381800..381936ad00 100644 --- a/src/Symfony/Component/Serializer/Tests/Normalizer/PropertyNormalizerTest.php +++ b/src/Symfony/Component/Serializer/Tests/Normalizer/PropertyNormalizerTest.php @@ -214,7 +214,7 @@ class PropertyNormalizerTest extends \PHPUnit_Framework_TestCase $this->assertEquals(array( 'bar' => 'bar', - ), $this->normalizer->normalize($obj, null, array('groups' => array('c')))); + ), $this->normalizer->normalize($obj, null, array(PropertyNormalizer::GROUPS => array('c')))); // The PropertyNormalizer is not able to hydrate properties from parent classes $this->assertEquals(array( @@ -222,7 +222,7 @@ class PropertyNormalizerTest extends \PHPUnit_Framework_TestCase 'foo' => 'foo', 'fooBar' => 'fooBar', 'bar' => 'bar', - ), $this->normalizer->normalize($obj, null, array('groups' => array('a', 'c')))); + ), $this->normalizer->normalize($obj, null, array(PropertyNormalizer::GROUPS => array('a', 'c')))); } public function testGroupsDenormalize() @@ -240,7 +240,7 @@ class PropertyNormalizerTest extends \PHPUnit_Framework_TestCase $toNormalize, 'Symfony\Component\Serializer\Tests\Fixtures\GroupDummy', null, - array('groups' => array('a')) + array(PropertyNormalizer::GROUPS => array('a')) ); $this->assertEquals($obj, $normalized); @@ -250,7 +250,7 @@ class PropertyNormalizerTest extends \PHPUnit_Framework_TestCase $toNormalize, 'Symfony\Component\Serializer\Tests\Fixtures\GroupDummy', null, - array('groups' => array('a', 'b')) + array(PropertyNormalizer::GROUPS => array('a', 'b')) ); $this->assertEquals($obj, $normalized); } @@ -272,7 +272,7 @@ class PropertyNormalizerTest extends \PHPUnit_Framework_TestCase 'foo_bar' => '@dunglas', 'symfony' => '@coopTilleuls', ), - $this->normalizer->normalize($obj, null, array('groups' => array('name_converter'))) + $this->normalizer->normalize($obj, null, array(PropertyNormalizer::GROUPS => array('name_converter'))) ); } @@ -293,7 +293,7 @@ class PropertyNormalizerTest extends \PHPUnit_Framework_TestCase 'foo_bar' => '@dunglas', 'symfony' => '@coopTilleuls', 'coop_tilleuls' => 'les-tilleuls.coop', - ), 'Symfony\Component\Serializer\Tests\Fixtures\GroupDummy', null, array('groups' => array('name_converter'))) + ), 'Symfony\Component\Serializer\Tests\Fixtures\GroupDummy', null, array(PropertyNormalizer::GROUPS => array('name_converter'))) ); } From 7f89158a0d488828f511150391b038bb6ecc4bbe Mon Sep 17 00:00:00 2001 From: Romain Neutron Date: Mon, 18 Jan 2016 18:32:04 +0100 Subject: [PATCH 18/28] [Process] Fix typo, no arguments needed anymore --- src/Symfony/Component/Process/Process.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Symfony/Component/Process/Process.php b/src/Symfony/Component/Process/Process.php index df36fd581d..6660950b7a 100644 --- a/src/Symfony/Component/Process/Process.php +++ b/src/Symfony/Component/Process/Process.php @@ -1232,7 +1232,7 @@ class Process $this->processPipes = UnixPipes::create($this, $this->input); } - return $this->processPipes->getDescriptors($this->outputDisabled); + return $this->processPipes->getDescriptors(); } /** From f6fd5e47eda8c82d86c361083d56f2bd41cbe8f7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Par=C3=A1da=20J=C3=B3zsef?= Date: Mon, 18 Jan 2016 23:07:25 +0100 Subject: [PATCH 19/28] Remove useless is_object condition --- src/Symfony/Component/Serializer/Serializer.php | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/Symfony/Component/Serializer/Serializer.php b/src/Symfony/Component/Serializer/Serializer.php index eb83544b42..cb9fe14394 100644 --- a/src/Symfony/Component/Serializer/Serializer.php +++ b/src/Symfony/Component/Serializer/Serializer.php @@ -185,10 +185,6 @@ class Serializer implements SerializerInterface, NormalizerInterface, Denormaliz */ private function getNormalizer($data, $format) { - if ($isObject = is_object($data)) { - $class = get_class($data); - } - foreach ($this->normalizers as $normalizer) { if ($normalizer instanceof NormalizerInterface && $normalizer->supportsNormalization($data, $format)) { return $normalizer; From 90d493ea9712f4684220d041f9fda14b5a09af71 Mon Sep 17 00:00:00 2001 From: Nicolas Grekas Date: Thu, 31 Dec 2015 17:39:50 +0100 Subject: [PATCH 20/28] [FrameworkBundle] Don't log twice with the error handler --- .../DependencyInjection/FrameworkExtension.php | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/FrameworkExtension.php b/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/FrameworkExtension.php index da54b51dea..462a802a20 100644 --- a/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/FrameworkExtension.php +++ b/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/FrameworkExtension.php @@ -139,6 +139,8 @@ class FrameworkExtension extends Extension } if ($container->getParameter('kernel.debug')) { + $definition->replaceArgument(2, -1 & ~(E_COMPILE_ERROR | E_PARSE | E_ERROR | E_CORE_ERROR | E_RECOVERABLE_ERROR)); + $loader->load('debug.xml'); $definition = $container->findDefinition('http_kernel'); @@ -150,7 +152,7 @@ class FrameworkExtension extends Extension $container->setDefinition('debug.event_dispatcher.parent', $definition); $container->setAlias('event_dispatcher', 'debug.event_dispatcher'); } else { - $definition->replaceArgument(2, E_COMPILE_ERROR | E_PARSE | E_ERROR | E_CORE_ERROR); + $definition->replaceArgument(1, null); } $this->addClassesToCompile(array( From da73125a9cfc0f9a908ce31ad0f2166134b5df75 Mon Sep 17 00:00:00 2001 From: Romain Neutron Date: Mon, 18 Jan 2016 17:23:05 +0100 Subject: [PATCH 21/28] [Process] Use stream based storage to avoid memory issues --- src/Symfony/Component/Process/Process.php | 42 ++++++++++++++--------- 1 file changed, 26 insertions(+), 16 deletions(-) diff --git a/src/Symfony/Component/Process/Process.php b/src/Symfony/Component/Process/Process.php index e0f49a7e3b..157499d10f 100644 --- a/src/Symfony/Component/Process/Process.php +++ b/src/Symfony/Component/Process/Process.php @@ -378,7 +378,11 @@ class Process $this->readPipes(false, '\\' === DIRECTORY_SEPARATOR ? !$this->processInformation['running'] : true); - return $this->stdout; + if (false === $ret = stream_get_contents($this->stdout, -1, 0)) { + return ''; + } + + return $ret; } /** @@ -395,16 +399,13 @@ class Process { $this->requireProcessIsStarted(__FUNCTION__); - $data = $this->getOutput(); - - $latest = substr($data, $this->incrementalOutputOffset); + $latest = stream_get_contents($this->stdout, -1, $this->incrementalOutputOffset); + $this->incrementalOutputOffset = ftell($this->stdout); if (false === $latest) { return ''; } - $this->incrementalOutputOffset = strlen($data); - return $latest; } @@ -421,7 +422,11 @@ class Process $this->readPipes(false, '\\' === DIRECTORY_SEPARATOR ? !$this->processInformation['running'] : true); - return $this->stderr; + if (false === $ret = stream_get_contents($this->stderr, -1, 0)) { + return ''; + } + + return $ret; } /** @@ -439,16 +444,13 @@ class Process { $this->requireProcessIsStarted(__FUNCTION__); - $data = $this->getErrorOutput(); - - $latest = substr($data, $this->incrementalErrorOutputOffset); + $latest = stream_get_contents($this->stderr, -1, $this->incrementalErrorOutputOffset); + $this->incrementalErrorOutputOffset = ftell($this->stderr); if (false === $latest) { return ''; } - $this->incrementalErrorOutputOffset = strlen($data); - return $latest; } @@ -666,21 +668,29 @@ class Process /** * Adds a line to the STDOUT stream. * + * @internal + * * @param string $line The line to append */ public function addOutput($line) { - $this->stdout .= $line; + fseek($this->stdout, 0, SEEK_END); + fwrite($this->stdout, $line); + fseek($this->stdout, $this->incrementalOutputOffset); } /** * Adds a line to the STDERR stream. * + * @internal + * * @param string $line The line to append */ public function addErrorOutput($line) { - $this->stderr .= $line; + fseek($this->stderr, 0, SEEK_END); + fwrite($this->stderr, $line); + fseek($this->stderr, $this->incrementalErrorOutputOffset); } /** @@ -1126,8 +1136,8 @@ class Process $this->exitcode = null; $this->fallbackStatus = array(); $this->processInformation = null; - $this->stdout = null; - $this->stderr = null; + $this->stdout = fopen('php://temp/maxmemory:'.(1024 * 1024), 'wb+'); + $this->stderr = fopen('php://temp/maxmemory:'.(1024 * 1024), 'wb+'); $this->process = null; $this->latestSignal = null; $this->status = self::STATUS_READY; From 1b170d7a851879d08a109d722392db2b1f1d7f6c Mon Sep 17 00:00:00 2001 From: Matthieu Napoli Date: Tue, 19 Jan 2016 11:31:11 +0100 Subject: [PATCH 22/28] Improve the phpdoc of SplFileInfo methods --- src/Symfony/Component/Finder/SplFileInfo.php | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/Symfony/Component/Finder/SplFileInfo.php b/src/Symfony/Component/Finder/SplFileInfo.php index c7fbe02191..31a3f86a67 100644 --- a/src/Symfony/Component/Finder/SplFileInfo.php +++ b/src/Symfony/Component/Finder/SplFileInfo.php @@ -38,6 +38,8 @@ class SplFileInfo extends \SplFileInfo /** * Returns the relative path. * + * This path does not contain the file name. + * * @return string the relative path */ public function getRelativePath() @@ -48,6 +50,8 @@ class SplFileInfo extends \SplFileInfo /** * Returns the relative path name. * + * This path contains the file name. + * * @return string the relative path name */ public function getRelativePathname() From be056fd0bf1a15a87a73f33fba8a9d5d645a427c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Par=C3=A1da=20J=C3=B3zsef?= Date: Sun, 17 Jan 2016 01:29:59 +0100 Subject: [PATCH 23/28] [Form] ChoiceType: Fix a notice when 'choices' normalizer is replaced --- .../Form/Extension/Core/Type/ChoiceType.php | 4 ++ .../Extension/Core/Type/ChoiceTypeTest.php | 27 ++++++++++ .../Form/Tests/Fixtures/ChoiceSubType.php | 51 +++++++++++++++++++ 3 files changed, 82 insertions(+) create mode 100644 src/Symfony/Component/Form/Tests/Fixtures/ChoiceSubType.php diff --git a/src/Symfony/Component/Form/Extension/Core/Type/ChoiceType.php b/src/Symfony/Component/Form/Extension/Core/Type/ChoiceType.php index ef9a4b5bae..515f104af6 100644 --- a/src/Symfony/Component/Form/Extension/Core/Type/ChoiceType.php +++ b/src/Symfony/Component/Form/Extension/Core/Type/ChoiceType.php @@ -291,6 +291,10 @@ class ChoiceType extends AbstractType // forms) $labels = $choiceLabels->labels; + // The $choiceLabels object is shared with the 'choices' closure. + // Since that normalizer can be replaced, labels have to be cleared here. + $choiceLabels->labels = array(); + return function ($choice, $key) use ($labels) { return $labels[$key]; }; 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 d7536f7640..cf74fec212 100644 --- a/src/Symfony/Component/Form/Tests/Extension/Core/Type/ChoiceTypeTest.php +++ b/src/Symfony/Component/Form/Tests/Extension/Core/Type/ChoiceTypeTest.php @@ -14,6 +14,7 @@ namespace Symfony\Component\Form\Tests\Extension\Core\Type; use Symfony\Component\Form\ChoiceList\View\ChoiceGroupView; use Symfony\Component\Form\ChoiceList\View\ChoiceView; use Symfony\Component\Form\Extension\Core\ChoiceList\ObjectChoiceList; +use Symfony\Component\Form\Tests\Fixtures\ChoiceSubType; class ChoiceTypeTest extends \Symfony\Component\Form\Test\TypeTestCase { @@ -1887,4 +1888,30 @@ class ChoiceTypeTest extends \Symfony\Component\Form\Test\TypeTestCase // Trigger data initialization $form->getViewData(); } + + /** + * This covers the case when: + * - Custom choice type added after a choice type. + * - Custom type is expanded. + * - Custom type replaces 'choices' normalizer with a custom one. + * In this case, custom type should not inherit labels from the first added choice type. + */ + public function testCustomChoiceTypeDoesNotInheritChoiceLabels() + { + $builder = $this->factory->createBuilder(); + $builder->add('choice', 'choice', array( + 'choices' => array( + '1' => '1', + '2' => '2', + ), + ) + ); + $builder->add('subChoice', new ChoiceSubType()); + $form = $builder->getForm(); + + // The default 'choices' normalizer would fill the $choiceLabels, but it has been replaced + // in the custom choice type, so $choiceLabels->labels remains empty array. + // In this case the 'choice_label' closure returns null and not the closure from the first choice type. + $this->assertNull($form->get('subChoice')->getConfig()->getOption('choice_label')); + } } diff --git a/src/Symfony/Component/Form/Tests/Fixtures/ChoiceSubType.php b/src/Symfony/Component/Form/Tests/Fixtures/ChoiceSubType.php new file mode 100644 index 0000000000..857dd5d5a7 --- /dev/null +++ b/src/Symfony/Component/Form/Tests/Fixtures/ChoiceSubType.php @@ -0,0 +1,51 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Form\Tests\Fixtures; + +use Symfony\Component\Form\AbstractType; +use Symfony\Component\OptionsResolver\OptionsResolver; + +/** + * @author Paráda József + */ +class ChoiceSubType extends AbstractType +{ + /** + * {@inheritdoc} + */ + public function configureOptions(OptionsResolver $resolver) + { + $resolver->setDefaults(array('expanded' => true)); + $resolver->setNormalizer('choices', function () { + return array( + 'attr1' => 'Attribute 1', + 'attr2' => 'Attribute 2', + ); + }); + } + + /** + * {@inheritdoc} + */ + public function getName() + { + return 'sub_choice'; + } + + /** + * {@inheritdoc} + */ + public function getParent() + { + return 'choice'; + } +} From 0d041c3f8a352fefa7eda54cfe7a427185fd5a86 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Beno=C3=AEt=20Burnichon?= Date: Thu, 14 Jan 2016 14:25:27 +0100 Subject: [PATCH 24/28] ChooseBaseUrl should return an index Enforce chooseBaseUrl to return an integer index to the baseUrls member. --- src/Symfony/Component/Asset/UrlPackage.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/Symfony/Component/Asset/UrlPackage.php b/src/Symfony/Component/Asset/UrlPackage.php index 3626ec843c..de9c1f07d5 100644 --- a/src/Symfony/Component/Asset/UrlPackage.php +++ b/src/Symfony/Component/Asset/UrlPackage.php @@ -108,15 +108,15 @@ class UrlPackage extends Package * Determines which base URL to use for the given path. * * Override this method to change the default distribution strategy. - * This method should always return the same base URL for a given path. + * This method should always return the same base URL index for a given path. * * @param string $path * - * @return string The base URL for the given path + * @return int The base URL index for the given path */ protected function chooseBaseUrl($path) { - return fmod(hexdec(substr(hash('sha256', $path), 0, 10)), count($this->baseUrls)); + return (int) fmod(hexdec(substr(hash('sha256', $path), 0, 10)), count($this->baseUrls)); } private function getSslUrls($urls) From bd70f2443d804e4fa2ef4b4d5acb8a6f26fbc11e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mathieu=20Santo=20Stefano--F=C3=A9ron?= Date: Tue, 19 Jan 2016 14:59:47 +0100 Subject: [PATCH 25/28] Fix markdown typo --- UPGRADE-3.0.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/UPGRADE-3.0.md b/UPGRADE-3.0.md index 3e5d3817d2..5776b14eff 100644 --- a/UPGRADE-3.0.md +++ b/UPGRADE-3.0.md @@ -19,7 +19,7 @@ UPGRADE FROM 2.x to 3.0 * The `DebugUniversalClassLoader` class has been removed in favor of `DebugClassLoader`. The difference is that the constructor now takes a loader to wrap. - ``` + ### Config From 71f4a3200e36376ef5709cec7fe310f380f3fd56 Mon Sep 17 00:00:00 2001 From: Jakub Zalas Date: Tue, 19 Jan 2016 16:31:40 +0000 Subject: [PATCH 26/28] [Process] Remove a misleading comment The described behaviour was never implemented. --- src/Symfony/Component/Process/Process.php | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/Symfony/Component/Process/Process.php b/src/Symfony/Component/Process/Process.php index e0f49a7e3b..734c692795 100644 --- a/src/Symfony/Component/Process/Process.php +++ b/src/Symfony/Component/Process/Process.php @@ -201,9 +201,6 @@ class Process * The callback receives the type of output (out or err) and some bytes from * the output in real-time while writing the standard input to the process. * It allows to have feedback from the independent process during execution. - * If there is no callback passed, the wait() method can be called - * with true as a second parameter then the callback will get all data occurred - * in (and since) the start call. * * @param callback|null $callback A PHP callback to run whenever there is some * output available on STDOUT or STDERR From 5abac565d3aa86559691b1c5eb1799e50232aca9 Mon Sep 17 00:00:00 2001 From: Paulo Rodrigues Pinto Date: Tue, 19 Jan 2016 17:38:30 +0000 Subject: [PATCH 27/28] Fix upgrade guides concerning erroneous removal of assets helper --- UPGRADE-2.7.md | 4 ++-- UPGRADE-3.0.md | 45 --------------------------------------------- 2 files changed, 2 insertions(+), 47 deletions(-) diff --git a/UPGRADE-2.7.md b/UPGRADE-2.7.md index f52220fadc..5de67ebede 100644 --- a/UPGRADE-2.7.md +++ b/UPGRADE-2.7.md @@ -596,11 +596,11 @@ TwigBundle FrameworkBundle --------------- - * The `templating.helper.assets` was refactored and returns now an object of the type + * The `templating.helper.assets` service was refactored and now returns an object of type `Symfony\Bundle\FrameworkBundle\Templating\Helper\AssetsHelper` instead of `Symfony\Component\Templating\Helper\CoreAssetsHelper`. You can update your class definition or use the `assets.packages` service instead. Using the `assets.packages` service is the recommended - way. The `templating.helper.assets` service will be removed in Symfony 3.0. + way. Before: diff --git a/UPGRADE-3.0.md b/UPGRADE-3.0.md index 3e5d3817d2..e6f0e01182 100644 --- a/UPGRADE-3.0.md +++ b/UPGRADE-3.0.md @@ -388,51 +388,6 @@ UPGRADE FROM 2.x to 3.0 * The `request` service was removed. You must inject the `request_stack` service instead. - * The `templating.helper.assets` was removed in Symfony 3.0. You should - use the `assets.package` service instead. - - Before: - - ```php - use Symfony\Component\Templating\Helper\CoreAssetsHelper; - - class DemoService - { - private $assetsHelper; - - public function __construct(CoreAssetsHelper $assetsHelper) - { - $this->assetsHelper = $assetsHelper; - } - - public function testMethod() - { - return $this->assetsHelper->getUrl('thumbnail.png', null, $this->assetsHelper->getVersion()); - } - } - ``` - - After: - - ```php - use Symfony\Component\Asset\Packages; - - class DemoService - { - private $assetPackages; - - public function __construct(Packages $assetPackages) - { - $this->assetPackages = $assetPackages; - } - - public function testMethod() - { - return $this->assetPackages->getUrl('thumbnail.png').$this->assetPackages->getVersion(); - } - } - ``` - * The `enctype` method of the `form` helper was removed. You should use the new method `start` instead. From 2d931f43e07435c6d3eb3e145749d800e6cb36db Mon Sep 17 00:00:00 2001 From: Romain Neutron Date: Mon, 18 Jan 2016 17:23:05 +0100 Subject: [PATCH 28/28] [Process] Use stream based storage to avoid memory issues --- src/Symfony/Component/Process/Process.php | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/src/Symfony/Component/Process/Process.php b/src/Symfony/Component/Process/Process.php index 98fa66a940..32704df3f1 100644 --- a/src/Symfony/Component/Process/Process.php +++ b/src/Symfony/Component/Process/Process.php @@ -491,6 +491,10 @@ class Process */ public function getIncrementalOutput() { + if ($this->outputDisabled) { + throw new LogicException('Output has been disabled.'); + } + $this->requireProcessIsStarted(__FUNCTION__); $latest = stream_get_contents($this->stdout, -1, $this->incrementalOutputOffset); @@ -510,7 +514,8 @@ class Process */ public function clearOutput() { - $this->stdout = ''; + ftruncate($this->stdout, 0); + fseek($this->stdout, 0); $this->incrementalOutputOffset = 0; return $this; @@ -555,6 +560,10 @@ class Process */ public function getIncrementalErrorOutput() { + if ($this->outputDisabled) { + throw new LogicException('Output has been disabled.'); + } + $this->requireProcessIsStarted(__FUNCTION__); $latest = stream_get_contents($this->stderr, -1, $this->incrementalErrorOutputOffset); @@ -574,7 +583,8 @@ class Process */ public function clearErrorOutput() { - $this->stderr = ''; + ftruncate($this->stderr, 0); + fseek($this->stderr, 0); $this->incrementalErrorOutputOffset = 0; return $this;