Merge branch '2.8' into 3.1
* 2.8: [FrameworkBundle] Fix Incorrect line break in exception message (500 debug page) [Security] Added note inside phpdoc. Minor cleanups and improvements [form] lazy trans `post_max_size_message`. [DI] Fix setting synthetic services on ContainerBuilder [ClassLoader] Fix ClassCollectionLoader inlining with declare(strict_types=1)
This commit is contained in:
commit
86f8d74ba1
@ -39,7 +39,7 @@ build: 56
|
||||
font-family: Georgia, "Times New Roman", Times, serif;
|
||||
font-size: 20px;
|
||||
color: #313131;
|
||||
word-break: break-all;
|
||||
word-wrap: break-word;
|
||||
}
|
||||
.sf-reset li {
|
||||
padding-bottom: 10px;
|
||||
|
@ -55,7 +55,12 @@ class ClassCollectionLoader
|
||||
|
||||
$classes = array_unique($classes);
|
||||
|
||||
$cache = $cacheDir.'/'.$name.$extension;
|
||||
// cache the core classes
|
||||
if (!is_dir($cacheDir) && !@mkdir($cacheDir, 0777, true) && !is_dir($cacheDir)) {
|
||||
throw new \RuntimeException(sprintf('Class Collection Loader was not able to create directory "%s"', $cacheDir));
|
||||
}
|
||||
$cacheDir = rtrim(realpath($cacheDir), '/'.DIRECTORY_SEPARATOR);
|
||||
$cache = $cacheDir.DIRECTORY_SEPARATOR.$name.$extension;
|
||||
|
||||
// auto-reload
|
||||
$reload = false;
|
||||
@ -93,6 +98,10 @@ class ClassCollectionLoader
|
||||
$declared = array_merge(get_declared_classes(), get_declared_interfaces(), get_declared_traits());
|
||||
}
|
||||
|
||||
$c = '(?:\s*+(?:(?:#|//)[^\n]*+\n|/\*(?:(?<!\*/).)++)?+)*+';
|
||||
$strictTypesRegex = str_replace('.', $c, "'^<\?php\s.declare.\(.strict_types.=.1.\).;'is");
|
||||
|
||||
$cacheDir = explode(DIRECTORY_SEPARATOR, $cacheDir);
|
||||
$files = array();
|
||||
$content = '';
|
||||
foreach (self::getOrderedClasses($classes) as $class) {
|
||||
@ -100,25 +109,40 @@ class ClassCollectionLoader
|
||||
continue;
|
||||
}
|
||||
|
||||
$files[] = $class->getFileName();
|
||||
$files[] = $file = $class->getFileName();
|
||||
$c = file_get_contents($file);
|
||||
|
||||
$c = preg_replace(array('/^\s*<\?php/', '/\?>\s*$/'), '', file_get_contents($class->getFileName()));
|
||||
if (preg_match($strictTypesRegex, $c)) {
|
||||
$file = explode(DIRECTORY_SEPARATOR, $file);
|
||||
|
||||
// fakes namespace declaration for global code
|
||||
if (!$class->inNamespace()) {
|
||||
$c = "\nnamespace\n{\n".$c."\n}\n";
|
||||
for ($i = 0; isset($file[$i], $cacheDir[$i]); ++$i) {
|
||||
if ($file[$i] !== $cacheDir[$i]) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (1 >= $i) {
|
||||
$file = var_export(implode(DIRECTORY_SEPARATOR, $file), true);
|
||||
} else {
|
||||
$file = array_slice($file, $i);
|
||||
$file = str_repeat('..'.DIRECTORY_SEPARATOR, count($cacheDir) - $i).implode(DIRECTORY_SEPARATOR, $file);
|
||||
$file = '__DIR__.'.var_export(DIRECTORY_SEPARATOR.$file, true);
|
||||
}
|
||||
|
||||
$c = "\nnamespace {require $file;}";
|
||||
} else {
|
||||
$c = preg_replace(array('/^\s*<\?php/', '/\?>\s*$/'), '', $c);
|
||||
|
||||
// fakes namespace declaration for global code
|
||||
if (!$class->inNamespace()) {
|
||||
$c = "\nnamespace\n{\n".$c."\n}\n";
|
||||
}
|
||||
|
||||
$c = self::fixNamespaceDeclarations('<?php '.$c);
|
||||
$c = preg_replace('/^\s*<\?php/', '', $c);
|
||||
}
|
||||
|
||||
$c = self::fixNamespaceDeclarations('<?php '.$c);
|
||||
$c = preg_replace('/^\s*<\?php/', '', $c);
|
||||
|
||||
$content .= $c;
|
||||
}
|
||||
|
||||
// cache the core classes
|
||||
if (!is_dir($cacheDir) && !@mkdir($cacheDir, 0777, true) && !is_dir($cacheDir)) {
|
||||
throw new \RuntimeException(sprintf('Class Collection Loader was not able to create directory "%s"', $cacheDir));
|
||||
}
|
||||
self::writeCacheFile($cache, '<?php '.$content);
|
||||
|
||||
if ($autoReload) {
|
||||
|
@ -216,18 +216,20 @@ class ClassCollectionLoaderTest extends \PHPUnit_Framework_TestCase
|
||||
|
||||
public function testCommentStripping()
|
||||
{
|
||||
if (is_file($file = sys_get_temp_dir().'/bar.php')) {
|
||||
if (is_file($file = __DIR__.'/bar.php')) {
|
||||
unlink($file);
|
||||
}
|
||||
spl_autoload_register($r = function ($class) {
|
||||
if (0 === strpos($class, 'Namespaced') || 0 === strpos($class, 'Pearlike_')) {
|
||||
require_once __DIR__.'/Fixtures/'.str_replace(array('\\', '_'), '/', $class).'.php';
|
||||
@require_once __DIR__.'/Fixtures/'.str_replace(array('\\', '_'), '/', $class).'.php';
|
||||
}
|
||||
});
|
||||
|
||||
$strictTypes = defined('HHVM_VERSION') ? '' : "\nnamespace {require __DIR__.'/Fixtures/Namespaced/WithStrictTypes.php';}";
|
||||
|
||||
ClassCollectionLoader::load(
|
||||
array('Namespaced\\WithComments', 'Pearlike_WithComments'),
|
||||
sys_get_temp_dir(),
|
||||
array('Namespaced\\WithComments', 'Pearlike_WithComments', $strictTypes ? 'Namespaced\\WithStrictTypes' : 'Namespaced\\WithComments'),
|
||||
__DIR__,
|
||||
'bar',
|
||||
false
|
||||
);
|
||||
@ -267,7 +269,9 @@ public static $loaded = true;
|
||||
}
|
||||
}
|
||||
EOF
|
||||
, str_replace("<?php \n", '', file_get_contents($file)));
|
||||
.$strictTypes,
|
||||
str_replace(array("<?php \n", '\\\\'), array('', '/'), file_get_contents($file))
|
||||
);
|
||||
|
||||
unlink($file);
|
||||
}
|
||||
|
@ -76,6 +76,7 @@ class ClassMapGeneratorTest extends \PHPUnit_Framework_TestCase
|
||||
'Namespaced\\Foo' => realpath(__DIR__).'/Fixtures/Namespaced/Foo.php',
|
||||
'Namespaced\\Baz' => realpath(__DIR__).'/Fixtures/Namespaced/Baz.php',
|
||||
'Namespaced\\WithComments' => realpath(__DIR__).'/Fixtures/Namespaced/WithComments.php',
|
||||
'Namespaced\WithStrictTypes' => realpath(__DIR__).'/Fixtures/Namespaced/WithStrictTypes.php',
|
||||
),
|
||||
),
|
||||
array(__DIR__.'/Fixtures/beta/NamespaceCollision', array(
|
||||
|
@ -0,0 +1,13 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* foo
|
||||
*/
|
||||
|
||||
declare (strict_types = 1);
|
||||
|
||||
namespace Namespaced;
|
||||
|
||||
class WithStrictTypes
|
||||
{
|
||||
}
|
@ -56,14 +56,12 @@ class RepeatedPass implements CompilerPassInterface
|
||||
*/
|
||||
public function process(ContainerBuilder $container)
|
||||
{
|
||||
$this->repeat = false;
|
||||
foreach ($this->passes as $pass) {
|
||||
$pass->process($container);
|
||||
}
|
||||
|
||||
if ($this->repeat) {
|
||||
$this->process($container);
|
||||
}
|
||||
do {
|
||||
$this->repeat = false;
|
||||
foreach ($this->passes as $pass) {
|
||||
$pass->process($container);
|
||||
}
|
||||
} while ($this->repeat);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -341,7 +341,8 @@ class ContainerBuilder extends Container implements TaggedContainerInterface
|
||||
{
|
||||
$id = strtolower($id);
|
||||
|
||||
if ($this->isFrozen() && (!isset($this->definitions[$id]) || !$this->definitions[$id]->isSynthetic())) {
|
||||
if ($this->isFrozen() && (isset($this->definitions[$id]) && !$this->definitions[$id]->isSynthetic())) {
|
||||
// setting a synthetic service on a frozen container is alright
|
||||
throw new BadMethodCallException(sprintf('Setting service "%s" for an unknown or non-synthetic service definition on a frozen container is not allowed.', $id));
|
||||
}
|
||||
|
||||
|
@ -128,7 +128,7 @@ class GraphvizDumper extends Dumper
|
||||
*
|
||||
* @return array An array of edges
|
||||
*/
|
||||
private function findEdges($id, $arguments, $required, $name)
|
||||
private function findEdges($id, array $arguments, $required, $name)
|
||||
{
|
||||
$edges = array();
|
||||
foreach ($arguments as $argument) {
|
||||
@ -241,7 +241,7 @@ class GraphvizDumper extends Dumper
|
||||
*
|
||||
* @return string A comma separated list of attributes
|
||||
*/
|
||||
private function addAttributes($attributes)
|
||||
private function addAttributes(array $attributes)
|
||||
{
|
||||
$code = array();
|
||||
foreach ($attributes as $k => $v) {
|
||||
@ -258,7 +258,7 @@ class GraphvizDumper extends Dumper
|
||||
*
|
||||
* @return string A space separated list of options
|
||||
*/
|
||||
private function addOptions($options)
|
||||
private function addOptions(array $options)
|
||||
{
|
||||
$code = array();
|
||||
foreach ($options as $k => $v) {
|
||||
|
@ -374,7 +374,7 @@ class PhpDumper extends Dumper
|
||||
* @throws InvalidArgumentException
|
||||
* @throws RuntimeException
|
||||
*/
|
||||
private function addServiceInstance($id, $definition)
|
||||
private function addServiceInstance($id, Definition $definition)
|
||||
{
|
||||
$class = $definition->getClass();
|
||||
|
||||
@ -422,7 +422,7 @@ class PhpDumper extends Dumper
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
private function isSimpleInstance($id, $definition)
|
||||
private function isSimpleInstance($id, Definition $definition)
|
||||
{
|
||||
foreach (array_merge(array($definition), $this->getInlinedDefinitions($definition)) as $sDefinition) {
|
||||
if ($definition !== $sDefinition && !$this->hasReference($id, $sDefinition->getMethodCalls())) {
|
||||
@ -446,7 +446,7 @@ class PhpDumper extends Dumper
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
private function addServiceMethodCalls($id, $definition, $variableName = 'instance')
|
||||
private function addServiceMethodCalls($id, Definition $definition, $variableName = 'instance')
|
||||
{
|
||||
$calls = '';
|
||||
foreach ($definition->getMethodCalls() as $call) {
|
||||
@ -461,7 +461,7 @@ class PhpDumper extends Dumper
|
||||
return $calls;
|
||||
}
|
||||
|
||||
private function addServiceProperties($id, $definition, $variableName = 'instance')
|
||||
private function addServiceProperties($id, Definition $definition, $variableName = 'instance')
|
||||
{
|
||||
$code = '';
|
||||
foreach ($definition->getProperties() as $name => $value) {
|
||||
@ -481,7 +481,7 @@ class PhpDumper extends Dumper
|
||||
*
|
||||
* @throws ServiceCircularReferenceException when the container contains a circular reference
|
||||
*/
|
||||
private function addServiceInlinedDefinitionsSetup($id, $definition)
|
||||
private function addServiceInlinedDefinitionsSetup($id, Definition $definition)
|
||||
{
|
||||
$this->referenceVariables[$id] = new Variable('instance');
|
||||
|
||||
@ -525,7 +525,7 @@ class PhpDumper extends Dumper
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
private function addServiceConfigurator($id, $definition, $variableName = 'instance')
|
||||
private function addServiceConfigurator($id, Definition $definition, $variableName = 'instance')
|
||||
{
|
||||
if (!$callable = $definition->getConfigurator()) {
|
||||
return '';
|
||||
@ -561,7 +561,7 @@ class PhpDumper extends Dumper
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
private function addService($id, $definition)
|
||||
private function addService($id, Definition $definition)
|
||||
{
|
||||
$this->definitionVariables = new \SplObjectStorage();
|
||||
$this->referenceVariables = array();
|
||||
@ -1032,7 +1032,7 @@ EOF;
|
||||
*
|
||||
* @throws InvalidArgumentException
|
||||
*/
|
||||
private function exportParameters($parameters, $path = '', $indent = 12)
|
||||
private function exportParameters(array $parameters, $path = '', $indent = 12)
|
||||
{
|
||||
$php = array();
|
||||
foreach ($parameters as $key => $value) {
|
||||
|
@ -271,7 +271,7 @@ class XmlDumper extends Dumper
|
||||
* @param \DOMElement $parent
|
||||
* @param string $keyAttribute
|
||||
*/
|
||||
private function convertParameters($parameters, $type, \DOMElement $parent, $keyAttribute = 'key')
|
||||
private function convertParameters(array $parameters, $type, \DOMElement $parent, $keyAttribute = 'key')
|
||||
{
|
||||
$withKeys = array_keys($parameters) !== range(0, count($parameters) - 1);
|
||||
foreach ($parameters as $key => $value) {
|
||||
@ -317,7 +317,7 @@ class XmlDumper extends Dumper
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
private function escape($arguments)
|
||||
private function escape(array $arguments)
|
||||
{
|
||||
$args = array();
|
||||
foreach ($arguments as $k => $v) {
|
||||
|
@ -307,7 +307,7 @@ class YamlDumper extends Dumper
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
private function prepareParameters($parameters, $escape = true)
|
||||
private function prepareParameters(array $parameters, $escape = true)
|
||||
{
|
||||
$filtered = array();
|
||||
foreach ($parameters as $key => $value) {
|
||||
@ -330,7 +330,7 @@ class YamlDumper extends Dumper
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
private function escape($arguments)
|
||||
private function escape(array $arguments)
|
||||
{
|
||||
$args = array();
|
||||
foreach ($arguments as $k => $v) {
|
||||
|
@ -425,9 +425,9 @@ class YamlFileLoader extends FileLoader
|
||||
{
|
||||
if (is_array($value)) {
|
||||
$value = array_map(array($this, 'resolveServices'), $value);
|
||||
} elseif (is_string($value) && 0 === strpos($value, '@=')) {
|
||||
} elseif (is_string($value) && 0 === strpos($value, '@=')) {
|
||||
return new Expression(substr($value, 2));
|
||||
} elseif (is_string($value) && 0 === strpos($value, '@')) {
|
||||
} elseif (is_string($value) && 0 === strpos($value, '@')) {
|
||||
if (0 === strpos($value, '@@')) {
|
||||
$value = substr($value, 1);
|
||||
$invalidBehavior = null;
|
||||
|
@ -626,14 +626,12 @@ class ContainerBuilderTest extends \PHPUnit_Framework_TestCase
|
||||
$container->set('a', new \stdClass());
|
||||
}
|
||||
|
||||
/**
|
||||
* @expectedException \BadMethodCallException
|
||||
*/
|
||||
public function testThrowsExceptionWhenAddServiceOnAFrozenContainer()
|
||||
{
|
||||
$container = new ContainerBuilder();
|
||||
$container->compile();
|
||||
$container->set('a', new \stdClass());
|
||||
$container->set('a', $foo = new \stdClass());
|
||||
$this->assertSame($foo, $container->get('a'));
|
||||
}
|
||||
|
||||
public function testNoExceptionWhenSetSyntheticServiceOnAFrozenContainer()
|
||||
|
@ -210,7 +210,7 @@ class ContainerTest extends \PHPUnit_Framework_TestCase
|
||||
|
||||
/**
|
||||
* @expectedException \Symfony\Component\DependencyInjection\Exception\RuntimeException
|
||||
* @expectedExcepionMessage You have requested a synthetic service ("request"). The DIC does not know how to construct this service.
|
||||
* @expectedExceptionMessage You have requested a synthetic service ("request"). The DIC does not know how to construct this service.
|
||||
*/
|
||||
public function testGetSyntheticServiceAlwaysThrows()
|
||||
{
|
||||
|
@ -142,6 +142,13 @@ class FormType extends BaseType
|
||||
};
|
||||
};
|
||||
|
||||
// Wrap "post_max_size_message" in a closure to translate it lazily
|
||||
$uploadMaxSizeMessage = function (Options $options) {
|
||||
return function () use ($options) {
|
||||
return $options['post_max_size_message'];
|
||||
};
|
||||
};
|
||||
|
||||
// For any form that is not represented by a single HTML control,
|
||||
// errors should bubble up by default
|
||||
$errorBubbling = function (Options $options) {
|
||||
@ -172,9 +179,11 @@ class FormType extends BaseType
|
||||
'action' => '',
|
||||
'attr' => array(),
|
||||
'post_max_size_message' => 'The uploaded file was too large. Please try to upload a smaller file.',
|
||||
'upload_max_size_message' => $uploadMaxSizeMessage, // internal
|
||||
));
|
||||
|
||||
$resolver->setAllowedTypes('label_attr', 'array');
|
||||
$resolver->setAllowedTypes('upload_max_size_message', array('callable'));
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -78,7 +78,7 @@ class HttpFoundationRequestHandler implements RequestHandlerInterface
|
||||
$form->submit(null, false);
|
||||
|
||||
$form->addError(new FormError(
|
||||
$form->getConfig()->getOption('post_max_size_message'),
|
||||
call_user_func($form->getConfig()->getOption('upload_max_size_message')),
|
||||
null,
|
||||
array('{{ max }}' => $this->serverParams->getNormalizedIniPostMaxSize())
|
||||
));
|
||||
|
@ -42,9 +42,10 @@ class UploadValidatorExtension extends AbstractTypeExtension
|
||||
{
|
||||
$translator = $this->translator;
|
||||
$translationDomain = $this->translationDomain;
|
||||
|
||||
$resolver->setNormalizer('post_max_size_message', function (Options $options, $errorMessage) use ($translator, $translationDomain) {
|
||||
return $translator->trans($errorMessage, array(), $translationDomain);
|
||||
$resolver->setNormalizer('upload_max_size_message', function (Options $options, $message) use ($translator, $translationDomain) {
|
||||
return function () use ($translator, $translationDomain, $message) {
|
||||
return $translator->trans(call_user_func($message), array(), $translationDomain);
|
||||
};
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -86,7 +86,7 @@ class NativeRequestHandler implements RequestHandlerInterface
|
||||
$form->submit(null, false);
|
||||
|
||||
$form->addError(new FormError(
|
||||
$form->getConfig()->getOption('post_max_size_message'),
|
||||
call_user_func($form->getConfig()->getOption('upload_max_size_message')),
|
||||
null,
|
||||
array('{{ max }}' => $this->serverParams->getNormalizedIniPostMaxSize())
|
||||
));
|
||||
|
@ -13,6 +13,7 @@ namespace Symfony\Component\Form\Tests\Extension\Validator\Type;
|
||||
|
||||
use Symfony\Component\Form\Extension\Validator\Type\UploadValidatorExtension;
|
||||
use Symfony\Component\OptionsResolver\OptionsResolver;
|
||||
use Symfony\Component\OptionsResolver\Options;
|
||||
|
||||
class UploadValidatorExtensionTest extends TypeTestCase
|
||||
{
|
||||
@ -29,10 +30,15 @@ class UploadValidatorExtensionTest extends TypeTestCase
|
||||
|
||||
$resolver = new OptionsResolver();
|
||||
$resolver->setDefault('post_max_size_message', 'old max {{ max }}!');
|
||||
$resolver->setDefault('upload_max_size_message', function (Options $options, $message) {
|
||||
return function () use ($options) {
|
||||
return $options['post_max_size_message'];
|
||||
};
|
||||
});
|
||||
|
||||
$extension->configureOptions($resolver);
|
||||
$options = $resolver->resolve();
|
||||
|
||||
$this->assertEquals('translated max {{ max }}!', $options['post_max_size_message']);
|
||||
$this->assertEquals('translated max {{ max }}!', call_user_func($options['upload_max_size_message']));
|
||||
}
|
||||
}
|
||||
|
@ -58,6 +58,7 @@ abstract class Voter implements VoterInterface
|
||||
|
||||
/**
|
||||
* Perform a single access check operation on a given attribute, subject and token.
|
||||
* It is safe to assume that $attribute and $subject already passed the "supports()" method check.
|
||||
*
|
||||
* @param string $attribute
|
||||
* @param mixed $subject
|
||||
|
Reference in New Issue
Block a user