diff --git a/composer.json b/composer.json index 6767026eb3..d5df1392b8 100644 --- a/composer.json +++ b/composer.json @@ -75,7 +75,7 @@ "monolog/monolog": "~1.11", "propel/propel1": "~1.6", "ircmaxell/password-compat": "~1.0", - "ocramius/proxy-manager": ">=0.3.1,<0.6-dev", + "ocramius/proxy-manager": "~0.3.1", "egulias/email-validator": "~1.2" }, "autoload": { diff --git a/src/Symfony/Bridge/ProxyManager/composer.json b/src/Symfony/Bridge/ProxyManager/composer.json index d7e7139093..bdce61ee87 100644 --- a/src/Symfony/Bridge/ProxyManager/composer.json +++ b/src/Symfony/Bridge/ProxyManager/composer.json @@ -18,7 +18,7 @@ "require": { "php": ">=5.3.3", "symfony/dependency-injection": "~2.3", - "ocramius/proxy-manager": ">=0.3.1,<0.6-dev" + "ocramius/proxy-manager": "~0.3.1" }, "require-dev": { "symfony/config": "~2.3" diff --git a/src/Symfony/Bundle/FrameworkBundle/Templating/TemplateNameParser.php b/src/Symfony/Bundle/FrameworkBundle/Templating/TemplateNameParser.php index 8481dc78e7..5730807fac 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Templating/TemplateNameParser.php +++ b/src/Symfony/Bundle/FrameworkBundle/Templating/TemplateNameParser.php @@ -11,9 +11,9 @@ namespace Symfony\Bundle\FrameworkBundle\Templating; -use Symfony\Component\Templating\TemplateNameParserInterface; use Symfony\Component\Templating\TemplateReferenceInterface; use Symfony\Component\HttpKernel\KernelInterface; +use Symfony\Component\Templating\TemplateNameParser as BaseTemplateNameParser; /** * TemplateNameParser converts template names from the short notation @@ -22,7 +22,7 @@ use Symfony\Component\HttpKernel\KernelInterface; * * @author Fabien Potencier */ -class TemplateNameParser implements TemplateNameParserInterface +class TemplateNameParser extends BaseTemplateNameParser { protected $kernel; protected $cache = array(); @@ -56,7 +56,7 @@ class TemplateNameParser implements TemplateNameParserInterface } if (!preg_match('/^([^:]*):([^:]*):(.+)\.([^\.]+)\.([^\.]+)$/', $name, $matches)) { - throw new \InvalidArgumentException(sprintf('Template name "%s" is not valid (format is "bundle:section:template.format.engine").', $name)); + return parent::parse($name); } $template = new TemplateReference($matches[1], $matches[2], $matches[3], $matches[4], $matches[5]); diff --git a/src/Symfony/Bundle/FrameworkBundle/Test/KernelTestCase.php b/src/Symfony/Bundle/FrameworkBundle/Test/KernelTestCase.php index ba83a547e1..90255f85fa 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Test/KernelTestCase.php +++ b/src/Symfony/Bundle/FrameworkBundle/Test/KernelTestCase.php @@ -141,7 +141,7 @@ abstract class KernelTestCase extends \PHPUnit_Framework_TestCase static::$kernel->boot(); } - /** + /** * Creates a Kernel. * * Available options: diff --git a/src/Symfony/Bundle/FrameworkBundle/Tests/Functional/app/AppKernel.php b/src/Symfony/Bundle/FrameworkBundle/Tests/Functional/app/AppKernel.php index 12747e6dc2..30bfc56a11 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Tests/Functional/app/AppKernel.php +++ b/src/Symfony/Bundle/FrameworkBundle/Tests/Functional/app/AppKernel.php @@ -105,7 +105,8 @@ class AppKernel extends Kernel public function unserialize($str) { - call_user_func_array(array($this, '__construct'), unserialize($str)); + $a = unserialize($str); + $this->__construct($a[0], $a[1], $a[2], $a[3]); } protected function getKernelParameters() diff --git a/src/Symfony/Bundle/FrameworkBundle/Tests/Templating/TemplateNameParserTest.php b/src/Symfony/Bundle/FrameworkBundle/Tests/Templating/TemplateNameParserTest.php index 2a1544c91b..ca10c3a8fe 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Tests/Templating/TemplateNameParserTest.php +++ b/src/Symfony/Bundle/FrameworkBundle/Tests/Templating/TemplateNameParserTest.php @@ -14,6 +14,7 @@ namespace Symfony\Bundle\FrameworkBundle\Tests\Templating; use Symfony\Bundle\FrameworkBundle\Tests\TestCase; use Symfony\Bundle\FrameworkBundle\Templating\TemplateNameParser; use Symfony\Bundle\FrameworkBundle\Templating\TemplateReference; +use Symfony\Component\Templating\TemplateReference as BaseTemplateReference; class TemplateNameParserTest extends TestCase { @@ -63,25 +64,17 @@ class TemplateNameParserTest extends TestCase array(':Post:index.html.php', new TemplateReference('', 'Post', 'index', 'html', 'php')), array('::index.html.php', new TemplateReference('', '', 'index', 'html', 'php')), array('FooBundle:Post:foo.bar.index.html.php', new TemplateReference('FooBundle', 'Post', 'foo.bar.index', 'html', 'php')), + array('/path/to/section/name.php', new BaseTemplateReference('/path/to/section/name.php', 'php')), + array('name.twig', new BaseTemplateReference('name.twig', 'twig')), + array('name', new BaseTemplateReference('name')), ); } /** - * @dataProvider getInvalidLogicalNameProvider * @expectedException \InvalidArgumentException */ - public function testParseInvalidName($name) + public function testParseValidNameWithNotFoundBundle() { - $this->parser->parse($name); - } - - public function getInvalidLogicalNameProvider() - { - return array( - array('BarBundle:Post:index.html.php'), - array('FooBundle:Post:index'), - array('FooBundle:Post'), - array('FooBundle:Post:foo:bar'), - ); + $this->parser->parse('BarBundle:Post:index.html.php'); } } diff --git a/src/Symfony/Bundle/SecurityBundle/DependencyInjection/SecurityExtension.php b/src/Symfony/Bundle/SecurityBundle/DependencyInjection/SecurityExtension.php index bf64d93342..f3e1430ce9 100644 --- a/src/Symfony/Bundle/SecurityBundle/DependencyInjection/SecurityExtension.php +++ b/src/Symfony/Bundle/SecurityBundle/DependencyInjection/SecurityExtension.php @@ -513,6 +513,7 @@ class SecurityExtension extends Extension { $name = $this->getUserProviderId(strtolower($name)); + // Doctrine Entity and In-memory DAO provider are managed by factories foreach ($this->userProviderFactories as $factory) { $key = str_replace('-', '_', $factory->getKey()); @@ -539,37 +540,12 @@ class SecurityExtension extends Extension $container ->setDefinition($name, new DefinitionDecorator('security.user.provider.chain')) - ->addArgument($providers) - ; + ->addArgument($providers); return $name; } - // Doctrine Entity DAO provider - if (isset($provider['entity'])) { - $container - ->setDefinition($name, new DefinitionDecorator('security.user.provider.entity')) - ->addArgument($provider['entity']['class']) - ->addArgument($provider['entity']['property']) - ; - - return $name; - } - - // In-memory DAO provider - $definition = $container->setDefinition($name, new DefinitionDecorator('security.user.provider.in_memory')); - foreach ($provider['users'] as $username => $user) { - $userId = $name.'_'.$username; - - $container - ->setDefinition($userId, new DefinitionDecorator('security.user.provider.in_memory.user')) - ->setArguments(array($username, (string) $user['password'], $user['roles'])) - ; - - $definition->addMethodCall('createUser', array(new Reference($userId))); - } - - return $name; + throw new InvalidConfigurationException(sprintf('Unable to create definition for "%s" user provider', $name)); } private function getUserProviderId($name) diff --git a/src/Symfony/Bundle/SecurityBundle/Tests/DependencyInjection/Fixtures/UserProvider/DummyProvider.php b/src/Symfony/Bundle/SecurityBundle/Tests/DependencyInjection/Fixtures/UserProvider/DummyProvider.php new file mode 100644 index 0000000000..f40f11c3cc --- /dev/null +++ b/src/Symfony/Bundle/SecurityBundle/Tests/DependencyInjection/Fixtures/UserProvider/DummyProvider.php @@ -0,0 +1,25 @@ +compile(); } + /** + * @expectedException \Symfony\Component\Config\Definition\Exception\InvalidConfigurationException + * @expectedExceptionMessage Unable to create definition for "security.user.provider.concrete.my_foo" user provider + */ + public function testFirewallWithInvalidUserProvider() + { + $container = $this->getRawContainer(); + + $extension = $container->getExtension('security'); + $extension->addUserProviderFactory(new DummyProvider()); + + $container->loadFromExtension('security', array( + 'providers' => array( + 'my_foo' => array('foo' => []), + ), + + 'firewalls' => array( + 'some_firewall' => array( + 'pattern' => '/.*', + 'http_basic' => [], + ), + ), + )); + + $container->compile(); + } + protected function getRawContainer() { $container = new ContainerBuilder(); diff --git a/src/Symfony/Bundle/SecurityBundle/Tests/Functional/app/AppKernel.php b/src/Symfony/Bundle/SecurityBundle/Tests/Functional/app/AppKernel.php index 57816ccef9..dfce6e4a6c 100644 --- a/src/Symfony/Bundle/SecurityBundle/Tests/Functional/app/AppKernel.php +++ b/src/Symfony/Bundle/SecurityBundle/Tests/Functional/app/AppKernel.php @@ -105,7 +105,8 @@ class AppKernel extends Kernel public function unserialize($str) { - call_user_func_array(array($this, '__construct'), unserialize($str)); + $a = unserialize($str); + $this->__construct($a[0], $a[1], $a[2], $a[3]); } protected function getKernelParameters() diff --git a/src/Symfony/Bundle/WebProfilerBundle/Resources/config/routing/profiler.xml b/src/Symfony/Bundle/WebProfilerBundle/Resources/config/routing/profiler.xml index 69f934e53f..d9708f9c50 100644 --- a/src/Symfony/Bundle/WebProfilerBundle/Resources/config/routing/profiler.xml +++ b/src/Symfony/Bundle/WebProfilerBundle/Resources/config/routing/profiler.xml @@ -4,47 +4,47 @@ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://symfony.com/schema/routing http://symfony.com/schema/routing/routing-1.0.xsd"> - + web_profiler.controller.profiler:homeAction - + web_profiler.controller.profiler:searchAction - + web_profiler.controller.profiler:searchBarAction - + web_profiler.controller.profiler:purgeAction - + web_profiler.controller.profiler:infoAction - + web_profiler.controller.profiler:phpinfoAction - + web_profiler.controller.profiler:searchResultsAction - + web_profiler.controller.profiler:panelAction - + web_profiler.controller.router:panelAction - + web_profiler.controller.exception:showAction - + web_profiler.controller.exception:cssAction diff --git a/src/Symfony/Bundle/WebProfilerBundle/Resources/config/routing/wdt.xml b/src/Symfony/Bundle/WebProfilerBundle/Resources/config/routing/wdt.xml index 5f6851c9ff..1027ce42f6 100644 --- a/src/Symfony/Bundle/WebProfilerBundle/Resources/config/routing/wdt.xml +++ b/src/Symfony/Bundle/WebProfilerBundle/Resources/config/routing/wdt.xml @@ -4,7 +4,7 @@ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://symfony.com/schema/routing http://symfony.com/schema/routing/routing-1.0.xsd"> - + web_profiler.controller.profiler:toolbarAction diff --git a/src/Symfony/Component/Config/Definition/Builder/ExprBuilder.php b/src/Symfony/Component/Config/Definition/Builder/ExprBuilder.php index 7cbddc6cf3..885863bbb6 100644 --- a/src/Symfony/Component/Config/Definition/Builder/ExprBuilder.php +++ b/src/Symfony/Component/Config/Definition/Builder/ExprBuilder.php @@ -225,8 +225,10 @@ class ExprBuilder { foreach ($expressions as $k => $expr) { if ($expr instanceof ExprBuilder) { - $expressions[$k] = function ($v) use ($expr) { - return call_user_func($expr->ifPart, $v) ? call_user_func($expr->thenPart, $v) : $v; + $if = $expr->ifPart; + $then = $expr->thenPart; + $expressions[$k] = function ($v) use ($if, $then) { + return $if($v) ? $then($v) : $v; }; } } diff --git a/src/Symfony/Component/Config/Definition/VariableNode.php b/src/Symfony/Component/Config/Definition/VariableNode.php index 4f42dda3a6..2ab7a45b6b 100644 --- a/src/Symfony/Component/Config/Definition/VariableNode.php +++ b/src/Symfony/Component/Config/Definition/VariableNode.php @@ -49,7 +49,9 @@ class VariableNode extends BaseNode implements PrototypeNodeInterface */ public function getDefaultValue() { - return $this->defaultValue instanceof \Closure ? call_user_func($this->defaultValue) : $this->defaultValue; + $v = $this->defaultValue; + + return $v instanceof \Closure ? $v() : $v; } /** diff --git a/src/Symfony/Component/Config/Exception/FileLoaderImportCircularReferenceException.php b/src/Symfony/Component/Config/Exception/FileLoaderImportCircularReferenceException.php index b1ad4420dc..6a3b01cfbe 100644 --- a/src/Symfony/Component/Config/Exception/FileLoaderImportCircularReferenceException.php +++ b/src/Symfony/Component/Config/Exception/FileLoaderImportCircularReferenceException.php @@ -22,6 +22,6 @@ class FileLoaderImportCircularReferenceException extends FileLoaderLoadException { $message = sprintf('Circular reference detected in "%s" ("%s" > "%s").', $this->varToString($resources[0]), implode('" > "', $resources), $resources[0]); - call_user_func('Exception::__construct', $message, $code, $previous); + \Exception::__construct($message, $code, $previous); } } diff --git a/src/Symfony/Component/Console/Tests/ApplicationTest.php b/src/Symfony/Component/Console/Tests/ApplicationTest.php index 49d94e2b28..27cf58775e 100644 --- a/src/Symfony/Component/Console/Tests/ApplicationTest.php +++ b/src/Symfony/Component/Console/Tests/ApplicationTest.php @@ -994,7 +994,6 @@ class ApplicationTest extends \PHPUnit_Framework_TestCase $tester = new ApplicationTester($application); $tester->run(array('command' => 'help')); - $this->assertTrue($tester->getInput()->isInteractive()); $this->assertFalse($tester->getInput()->hasParameterOption(array('--no-interaction', '-n'))); $inputStream = $application->getHelperSet()->get('question')->getInputStream(); diff --git a/src/Symfony/Component/Debug/FatalErrorHandler/ClassNotFoundFatalErrorHandler.php b/src/Symfony/Component/Debug/FatalErrorHandler/ClassNotFoundFatalErrorHandler.php index 2b37ee9994..0ba0bd4483 100644 --- a/src/Symfony/Component/Debug/FatalErrorHandler/ClassNotFoundFatalErrorHandler.php +++ b/src/Symfony/Component/Debug/FatalErrorHandler/ClassNotFoundFatalErrorHandler.php @@ -119,7 +119,7 @@ class ClassNotFoundFatalErrorHandler implements FatalErrorHandlerInterface } } - return $classes; + return array_unique($classes); } /** diff --git a/src/Symfony/Component/DependencyInjection/Dumper/PhpDumper.php b/src/Symfony/Component/DependencyInjection/Dumper/PhpDumper.php index 11cae7a97a..3c318a656b 100644 --- a/src/Symfony/Component/DependencyInjection/Dumper/PhpDumper.php +++ b/src/Symfony/Component/DependencyInjection/Dumper/PhpDumper.php @@ -115,17 +115,19 @@ class PhpDumper extends Dumper ), $options); if (!empty($options['file']) && is_dir($dir = dirname($options['file']))) { - // Build a regexp where the first two root dirs are mandatory, + // Build a regexp where the first root dirs are mandatory, // but every other sub-dir is optional up to the full path in $dir + // Mandate at least 2 root dirs and not more that 5 optional dirs. $dir = explode(DIRECTORY_SEPARATOR, realpath($dir)); $i = count($dir); if (3 <= $i) { $regex = ''; - $this->targetDirMaxMatches = $i - 3; + $lastOptionalDir = $i > 8 ? $i - 5 : 3; + $this->targetDirMaxMatches = $i - $lastOptionalDir; - while (2 < --$i) { + while (--$i >= $lastOptionalDir) { $regex = sprintf('(%s%s)?', preg_quote(DIRECTORY_SEPARATOR.$dir[$i], '#'), $regex); } @@ -824,6 +826,7 @@ $bagClass class $class extends $baseClass { private \$parameters; + private \$targetDirs = array(); EOF; } @@ -835,7 +838,8 @@ EOF; */ private function addConstructor() { - $parameters = $this->exportParameters($this->container->getParameterBag()->all()); + $targetDirs = $this->exportTargetDirs(); + $arguments = $this->container->getParameterBag()->all() ? 'new ParameterBag($this->getDefaultParameters())' : null; $code = <<parameters = $parameters; - - parent::__construct(new ParameterBag(\$this->parameters)); + {{$targetDirs} + parent::__construct($arguments); EOF; @@ -874,7 +876,7 @@ EOF; */ private function addFrozenConstructor() { - $parameters = $this->exportParameters($this->container->getParameterBag()->all()); + $targetDirs = $this->exportTargetDirs(); $code = <<container->getParameterBag()->all()) { + $code .= "\n \$this->parameters = \$this->getDefaultParameters();\n"; + } + + $code .= <<services = \$this->scopedServices = \$this->scopeStacks = array(); - \$this->parameters = $parameters; \$this->set('service_container', \$this); @@ -991,6 +1000,8 @@ EOF; return ''; } + $parameters = $this->exportParameters($this->container->getParameterBag()->all()); + $code = ''; if ($this->container->isFrozen()) { $code .= <<expressionLanguage; } + private function exportTargetDirs() + { + return null === $this->targetDirRegex ? '' : <<targetDirMaxMatches}; ++\$i) { + \$this->targetDirs[\$i] = \$dir = dirname(\$dir); + } +EOF; + } + private function export($value) { if (null !== $this->targetDirRegex && is_string($value) && preg_match($this->targetDirRegex, $value, $matches, PREG_OFFSET_CAPTURE)) { @@ -1482,8 +1518,8 @@ EOF; $suffix = isset($value[$suffix]) ? '.'.var_export(substr($value, $suffix), true) : ''; $dirname = '__DIR__'; - for ($i = $this->targetDirMaxMatches - count($matches); 0 <= $i; --$i) { - $dirname = sprintf('dirname(%s)', $dirname); + if (0 < $offset = 1 + $this->targetDirMaxMatches - count($matches)) { + $dirname = sprintf('$this->targetDirs[%d]', $offset); } if ($prefix || $suffix) { diff --git a/src/Symfony/Component/DependencyInjection/Tests/Dumper/PhpDumperTest.php b/src/Symfony/Component/DependencyInjection/Tests/Dumper/PhpDumperTest.php index 4223a19f80..882c5d8a12 100644 --- a/src/Symfony/Component/DependencyInjection/Tests/Dumper/PhpDumperTest.php +++ b/src/Symfony/Component/DependencyInjection/Tests/Dumper/PhpDumperTest.php @@ -70,13 +70,14 @@ class PhpDumperTest extends \PHPUnit_Framework_TestCase $definition = new Definition(); $definition->setClass('stdClass'); $definition->addArgument('%foo%'); - $definition->addArgument(array('%foo%' => '%foo%')); + $definition->addArgument(array('%foo%' => '%buz%/')); $container = new ContainerBuilder(); $container->setDefinition('test', $definition); $container->setParameter('foo', 'wiz'.dirname(dirname(__FILE__))); $container->setParameter('bar', dirname(__FILE__)); $container->setParameter('baz', '%bar%/PhpDumperTest.php'); + $container->setParameter('buz', dirname(dirname(__DIR__))); $container->compile(); $dumper = new PhpDumper($container); diff --git a/src/Symfony/Component/DependencyInjection/Tests/Fixtures/php/services1-1.php b/src/Symfony/Component/DependencyInjection/Tests/Fixtures/php/services1-1.php index c2b50948a4..116d7dfe70 100644 --- a/src/Symfony/Component/DependencyInjection/Tests/Fixtures/php/services1-1.php +++ b/src/Symfony/Component/DependencyInjection/Tests/Fixtures/php/services1-1.php @@ -18,16 +18,13 @@ use Symfony\Component\DependencyInjection\ParameterBag\ParameterBag; class Container extends AbstractContainer { private $parameters; + private $targetDirs = array(); /** * Constructor. */ public function __construct() { - $this->parameters = array( - - ); - - parent::__construct(new ParameterBag($this->parameters)); + parent::__construct(); } } diff --git a/src/Symfony/Component/DependencyInjection/Tests/Fixtures/php/services1.php b/src/Symfony/Component/DependencyInjection/Tests/Fixtures/php/services1.php index 23d367f1f9..90b59ff4eb 100644 --- a/src/Symfony/Component/DependencyInjection/Tests/Fixtures/php/services1.php +++ b/src/Symfony/Component/DependencyInjection/Tests/Fixtures/php/services1.php @@ -17,16 +17,13 @@ use Symfony\Component\DependencyInjection\ParameterBag\ParameterBag; class ProjectServiceContainer extends Container { private $parameters; + private $targetDirs = array(); /** * Constructor. */ public function __construct() { - $this->parameters = array( - - ); - - parent::__construct(new ParameterBag($this->parameters)); + parent::__construct(); } } diff --git a/src/Symfony/Component/DependencyInjection/Tests/Fixtures/php/services10.php b/src/Symfony/Component/DependencyInjection/Tests/Fixtures/php/services10.php index 3b504c9dd5..2079bee130 100644 --- a/src/Symfony/Component/DependencyInjection/Tests/Fixtures/php/services10.php +++ b/src/Symfony/Component/DependencyInjection/Tests/Fixtures/php/services10.php @@ -17,19 +17,18 @@ use Symfony\Component\DependencyInjection\ParameterBag\FrozenParameterBag; class ProjectServiceContainer extends Container { private $parameters; + private $targetDirs = array(); /** * Constructor. */ public function __construct() { + $this->parameters = $this->getDefaultParameters(); + $this->services = $this->scopedServices = $this->scopeStacks = array(); - $this->parameters = array( - 'empty_value' => '', - 'some_string' => '-', - ); $this->set('service_container', $this); @@ -106,4 +105,17 @@ class ProjectServiceContainer extends Container return $this->parameterBag; } + + /** + * Gets the default parameters. + * + * @return array An array of the default parameters + */ + protected function getDefaultParameters() + { + return array( + 'empty_value' => '', + 'some_string' => '-', + ); + } } diff --git a/src/Symfony/Component/DependencyInjection/Tests/Fixtures/php/services12.php b/src/Symfony/Component/DependencyInjection/Tests/Fixtures/php/services12.php index 1d7ac85d7b..5a371a048a 100644 --- a/src/Symfony/Component/DependencyInjection/Tests/Fixtures/php/services12.php +++ b/src/Symfony/Component/DependencyInjection/Tests/Fixtures/php/services12.php @@ -17,20 +17,22 @@ use Symfony\Component\DependencyInjection\ParameterBag\FrozenParameterBag; class ProjectServiceContainer extends Container { private $parameters; + private $targetDirs = array(); /** * Constructor. */ public function __construct() { + $dir = __DIR__; + for ($i = 1; $i <= 5; ++$i) { + $this->targetDirs[$i] = $dir = dirname($dir); + } + $this->parameters = $this->getDefaultParameters(); + $this->services = $this->scopedServices = $this->scopeStacks = array(); - $this->parameters = array( - 'foo' => ('wiz'.dirname(__DIR__)), - 'bar' => __DIR__, - 'baz' => (__DIR__.'/PhpDumperTest.php'), - ); $this->set('service_container', $this); @@ -61,7 +63,7 @@ class ProjectServiceContainer extends Container */ protected function getTestService() { - return $this->services['test'] = new \stdClass(('wiz'.dirname(__DIR__)), array(('wiz'.dirname(__DIR__)) => ('wiz'.dirname(__DIR__)))); + return $this->services['test'] = new \stdClass(('wiz'.$this->targetDirs[1]), array(('wiz'.$this->targetDirs[1]) => ($this->targetDirs[2].'/'))); } /** @@ -107,4 +109,19 @@ class ProjectServiceContainer extends Container return $this->parameterBag; } + + /** + * Gets the default parameters. + * + * @return array An array of the default parameters + */ + protected function getDefaultParameters() + { + return array( + 'foo' => ('wiz'.$this->targetDirs[1]), + 'bar' => __DIR__, + 'baz' => (__DIR__.'/PhpDumperTest.php'), + 'buz' => $this->targetDirs[2], + ); + } } diff --git a/src/Symfony/Component/DependencyInjection/Tests/Fixtures/php/services19.php b/src/Symfony/Component/DependencyInjection/Tests/Fixtures/php/services19.php index fdafa6e406..ecf30a6558 100644 --- a/src/Symfony/Component/DependencyInjection/Tests/Fixtures/php/services19.php +++ b/src/Symfony/Component/DependencyInjection/Tests/Fixtures/php/services19.php @@ -17,17 +17,14 @@ use Symfony\Component\DependencyInjection\ParameterBag\ParameterBag; class ProjectServiceContainer extends Container { private $parameters; + private $targetDirs = array(); /** * Constructor. */ public function __construct() { - $this->parameters = array( - - ); - - parent::__construct(new ParameterBag($this->parameters)); + parent::__construct(); $this->methodMap = array( 'service_from_anonymous_factory' => 'getServiceFromAnonymousFactoryService', 'service_with_method_call_and_factory' => 'getServiceWithMethodCallAndFactoryService', diff --git a/src/Symfony/Component/DependencyInjection/Tests/Fixtures/php/services8.php b/src/Symfony/Component/DependencyInjection/Tests/Fixtures/php/services8.php index a6de38e381..1b86dfc3f8 100644 --- a/src/Symfony/Component/DependencyInjection/Tests/Fixtures/php/services8.php +++ b/src/Symfony/Component/DependencyInjection/Tests/Fixtures/php/services8.php @@ -17,13 +17,24 @@ use Symfony\Component\DependencyInjection\ParameterBag\ParameterBag; class ProjectServiceContainer extends Container { private $parameters; + private $targetDirs = array(); /** * Constructor. */ public function __construct() { - $this->parameters = array( + parent::__construct(new ParameterBag($this->getDefaultParameters())); + } + + /** + * Gets the default parameters. + * + * @return array An array of the default parameters + */ + protected function getDefaultParameters() + { + return array( 'foo' => '%baz%', 'baz' => 'bar', 'bar' => 'foo is %%foo bar', @@ -39,7 +50,5 @@ class ProjectServiceContainer extends Container 7 => 'null', ), ); - - parent::__construct(new ParameterBag($this->parameters)); } } diff --git a/src/Symfony/Component/DependencyInjection/Tests/Fixtures/php/services9.php b/src/Symfony/Component/DependencyInjection/Tests/Fixtures/php/services9.php index 60110570c4..33cbe2f8be 100644 --- a/src/Symfony/Component/DependencyInjection/Tests/Fixtures/php/services9.php +++ b/src/Symfony/Component/DependencyInjection/Tests/Fixtures/php/services9.php @@ -17,19 +17,14 @@ use Symfony\Component\DependencyInjection\ParameterBag\ParameterBag; class ProjectServiceContainer extends Container { private $parameters; + private $targetDirs = array(); /** * Constructor. */ public function __construct() { - $this->parameters = array( - 'baz_class' => 'BazClass', - 'foo_class' => 'Bar\\FooClass', - 'foo' => 'bar', - ); - - parent::__construct(new ParameterBag($this->parameters)); + parent::__construct(new ParameterBag($this->getDefaultParameters())); $this->methodMap = array( 'bar' => 'getBarService', 'baz' => 'getBazService', @@ -392,4 +387,18 @@ class ProjectServiceContainer extends Container return $instance; } + + /** + * Gets the default parameters. + * + * @return array An array of the default parameters + */ + protected function getDefaultParameters() + { + return array( + 'baz_class' => 'BazClass', + 'foo_class' => 'Bar\\FooClass', + 'foo' => 'bar', + ); + } } diff --git a/src/Symfony/Component/DependencyInjection/Tests/Fixtures/php/services9_compiled.php b/src/Symfony/Component/DependencyInjection/Tests/Fixtures/php/services9_compiled.php index 7d03bd5b8b..71a47dc135 100644 --- a/src/Symfony/Component/DependencyInjection/Tests/Fixtures/php/services9_compiled.php +++ b/src/Symfony/Component/DependencyInjection/Tests/Fixtures/php/services9_compiled.php @@ -17,20 +17,18 @@ use Symfony\Component\DependencyInjection\ParameterBag\FrozenParameterBag; class ProjectServiceContainer extends Container { private $parameters; + private $targetDirs = array(); /** * Constructor. */ public function __construct() { + $this->parameters = $this->getDefaultParameters(); + $this->services = $this->scopedServices = $this->scopeStacks = array(); - $this->parameters = array( - 'baz_class' => 'BazClass', - 'foo_class' => 'Bar\\FooClass', - 'foo' => 'bar', - ); $this->set('service_container', $this); @@ -373,4 +371,18 @@ class ProjectServiceContainer extends Container return $this->parameterBag; } + + /** + * Gets the default parameters. + * + * @return array An array of the default parameters + */ + protected function getDefaultParameters() + { + return array( + 'baz_class' => 'BazClass', + 'foo_class' => 'Bar\\FooClass', + 'foo' => 'bar', + ); + } } diff --git a/src/Symfony/Component/EventDispatcher/Debug/TraceableEventDispatcher.php b/src/Symfony/Component/EventDispatcher/Debug/TraceableEventDispatcher.php index 347c7d0739..b796a8125a 100644 --- a/src/Symfony/Component/EventDispatcher/Debug/TraceableEventDispatcher.php +++ b/src/Symfony/Component/EventDispatcher/Debug/TraceableEventDispatcher.php @@ -224,6 +224,9 @@ class TraceableEventDispatcher implements TraceableEventDispatcherInterface { $skipped = false; foreach ($this->dispatcher->getListeners($eventName) as $listener) { + if (!$listener instanceof WrappedListener) { // #12845: a new listener was added during dispatch. + continue; + } // Unwrap listener $this->dispatcher->removeListener($eventName, $listener); $this->dispatcher->addListener($eventName, $listener->getWrappedListener()); diff --git a/src/Symfony/Component/ExpressionLanguage/Node/BinaryNode.php b/src/Symfony/Component/ExpressionLanguage/Node/BinaryNode.php index cbbee60ccf..597cc8918d 100644 --- a/src/Symfony/Component/ExpressionLanguage/Node/BinaryNode.php +++ b/src/Symfony/Component/ExpressionLanguage/Node/BinaryNode.php @@ -87,11 +87,12 @@ class BinaryNode extends Node if (isset(self::$functions[$operator])) { $right = $this->nodes['right']->evaluate($functions, $values); - if ('not in' == $operator) { - return !call_user_func('in_array', $left, $right); + if ('not in' === $operator) { + return !in_array($left, $right); } + $f = self::$functions[$operator]; - return call_user_func(self::$functions[$operator], $left, $right); + return $f($left, $right); } switch ($operator) { diff --git a/src/Symfony/Component/Filesystem/Filesystem.php b/src/Symfony/Component/Filesystem/Filesystem.php index 34f257aed8..c6e842fbc9 100644 --- a/src/Symfony/Component/Filesystem/Filesystem.php +++ b/src/Symfony/Component/Filesystem/Filesystem.php @@ -423,7 +423,7 @@ class Filesystem } } else { if (is_link($file)) { - $this->symlink($file->getLinkTarget(), $target); + $this->symlink($file->getRealPath(), $target); } elseif (is_dir($file)) { $this->mkdir($target); } elseif (is_file($file)) { diff --git a/src/Symfony/Component/Filesystem/Tests/FilesystemTest.php b/src/Symfony/Component/Filesystem/Tests/FilesystemTest.php index 2790e5e4e3..947c636311 100644 --- a/src/Symfony/Component/Filesystem/Tests/FilesystemTest.php +++ b/src/Symfony/Component/Filesystem/Tests/FilesystemTest.php @@ -901,6 +901,31 @@ class FilesystemTest extends FilesystemTestCase $this->assertTrue(is_link($targetPath.DIRECTORY_SEPARATOR.'link1')); } + public function testMirrorCopiesRelativeLinkedContents() + { + $this->markAsSkippedIfSymlinkIsMissing(); + + $sourcePath = $this->workspace.DIRECTORY_SEPARATOR.'source'.DIRECTORY_SEPARATOR; + $oldPath = getcwd(); + + mkdir($sourcePath.'nested/', 0777, true); + file_put_contents($sourcePath.'/nested/file1.txt', 'FILE1'); + // Note: Create relative symlink + chdir($sourcePath); + symlink('nested', 'link1'); + + chdir($oldPath); + + $targetPath = $this->workspace.DIRECTORY_SEPARATOR.'target'.DIRECTORY_SEPARATOR; + + $this->filesystem->mirror($sourcePath, $targetPath); + + $this->assertTrue(is_dir($targetPath)); + $this->assertFileEquals($sourcePath.'/nested/file1.txt', $targetPath.DIRECTORY_SEPARATOR.'link1/file1.txt'); + $this->assertTrue(is_link($targetPath.DIRECTORY_SEPARATOR.'link1')); + $this->assertEquals($sourcePath.'nested', readlink($targetPath.DIRECTORY_SEPARATOR.'link1')); + } + /** * @dataProvider providePathsForIsAbsolutePath */ diff --git a/src/Symfony/Component/Finder/Shell/Command.php b/src/Symfony/Component/Finder/Shell/Command.php index 78824d0df4..1f69afb2c7 100644 --- a/src/Symfony/Component/Finder/Shell/Command.php +++ b/src/Symfony/Component/Finder/Shell/Command.php @@ -246,14 +246,14 @@ class Command */ public function execute() { - if (null === $this->errorHandler) { + if (null === $errorHandler = $this->errorHandler) { exec($this->join(), $output); } else { $process = proc_open($this->join(), array(0 => array('pipe', 'r'), 1 => array('pipe', 'w'), 2 => array('pipe', 'w')), $pipes); $output = preg_split('~(\r\n|\r|\n)~', stream_get_contents($pipes[1]), -1, PREG_SPLIT_NO_EMPTY); if ($error = stream_get_contents($pipes[2])) { - call_user_func($this->errorHandler, $error); + $errorHandler($error); } proc_close($process); diff --git a/src/Symfony/Component/Form/FormFactory.php b/src/Symfony/Component/Form/FormFactory.php index 8a7b1cab05..cfca4588bd 100644 --- a/src/Symfony/Component/Form/FormFactory.php +++ b/src/Symfony/Component/Form/FormFactory.php @@ -113,11 +113,11 @@ class FormFactory implements FormFactoryInterface $pattern = $patternGuess ? $patternGuess->getValue() : null; if (null !== $pattern) { - $options = array_merge(array('attr' => array('pattern' => $pattern)), $options); + $options = array_replace_recursive(array('attr' => array('pattern' => $pattern)), $options); } if (null !== $maxLength) { - $options = array_merge(array('attr' => array('maxlength' => $maxLength)), $options); + $options = array_replace_recursive(array('attr' => array('maxlength' => $maxLength)), $options); } if ($requiredGuess) { diff --git a/src/Symfony/Component/Form/Tests/FormFactoryTest.php b/src/Symfony/Component/Form/Tests/FormFactoryTest.php index a06b49876e..59e9e8085c 100644 --- a/src/Symfony/Component/Form/Tests/FormFactoryTest.php +++ b/src/Symfony/Component/Form/Tests/FormFactoryTest.php @@ -504,6 +504,41 @@ class FormFactoryTest extends \PHPUnit_Framework_TestCase $this->assertEquals('builderInstance', $this->builder); } + public function testCreateBuilderUsesMaxLengthAndPattern() + { + $this->guesser1->expects($this->once()) + ->method('guessMaxLength') + ->with('Application\Author', 'firstName') + ->will($this->returnValue(new ValueGuess( + 20, + Guess::HIGH_CONFIDENCE + ))); + + $this->guesser2->expects($this->once()) + ->method('guessPattern') + ->with('Application\Author', 'firstName') + ->will($this->returnValue(new ValueGuess( + '.{5,}', + Guess::HIGH_CONFIDENCE + ))); + + $factory = $this->getMockFactory(array('createNamedBuilder')); + + $factory->expects($this->once()) + ->method('createNamedBuilder') + ->with('firstName', 'text', null, array('attr' => array('maxlength' => 20, 'pattern' => '.{5,}', 'class' => 'tinymce'))) + ->will($this->returnValue('builderInstance')); + + $this->builder = $factory->createBuilderForProperty( + 'Application\Author', + 'firstName', + null, + array('attr' => array('class' => 'tinymce')) + ); + + $this->assertEquals('builderInstance', $this->builder); + } + public function testCreateBuilderUsesRequiredSettingWithHighestConfidence() { $this->guesser1->expects($this->once()) diff --git a/src/Symfony/Component/HttpKernel/Tests/Debug/TraceableEventDispatcherTest.php b/src/Symfony/Component/HttpKernel/Tests/Debug/TraceableEventDispatcherTest.php index 399f1a7889..c2cafc37b8 100644 --- a/src/Symfony/Component/HttpKernel/Tests/Debug/TraceableEventDispatcherTest.php +++ b/src/Symfony/Component/HttpKernel/Tests/Debug/TraceableEventDispatcherTest.php @@ -75,6 +75,24 @@ class TraceableEventDispatcherTest extends \PHPUnit_Framework_TestCase $kernel->handle($request); } + public function testAddListenerNested() + { + $called1 = false; + $called2 = false; + $dispatcher = new TraceableEventDispatcher(new EventDispatcher(), new Stopwatch()); + $dispatcher->addListener('my-event', function () use ($dispatcher, &$called1, &$called2) { + $called1 = true; + $dispatcher->addListener('my-event', function () use (&$called2) { + $called2 = true; + }); + }); + $dispatcher->dispatch('my-event'); + $this->assertTrue($called1); + $this->assertFalse($called2); + $dispatcher->dispatch('my-event'); + $this->assertTrue($called2); + } + protected function getHttpKernel($dispatcher, $controller) { $resolver = $this->getMock('Symfony\Component\HttpKernel\Controller\ControllerResolverInterface'); diff --git a/src/Symfony/Component/HttpKernel/Tests/HttpCache/TestHttpKernel.php b/src/Symfony/Component/HttpKernel/Tests/HttpCache/TestHttpKernel.php index da8c34c177..5546ba2ed8 100644 --- a/src/Symfony/Component/HttpKernel/Tests/HttpCache/TestHttpKernel.php +++ b/src/Symfony/Component/HttpKernel/Tests/HttpCache/TestHttpKernel.php @@ -72,8 +72,8 @@ class TestHttpKernel extends HttpKernel implements ControllerResolverInterface $response = new Response($this->body, $this->status, $this->headers); - if (null !== $this->customizer) { - call_user_func($this->customizer, $request, $response); + if (null !== $customizer = $this->customizer) { + $customizer($request, $response); } return $response; diff --git a/src/Symfony/Component/Process/Process.php b/src/Symfony/Component/Process/Process.php index e4420f564a..52dc80e6b6 100644 --- a/src/Symfony/Component/Process/Process.php +++ b/src/Symfony/Component/Process/Process.php @@ -1370,11 +1370,12 @@ class Process { $result = $this->processPipes->readAndWrite($blocking, $close); + $callback = $this->callback; foreach ($result as $type => $data) { if (3 == $type) { $this->fallbackExitcode = (int) $data; } else { - call_user_func($this->callback, $type === self::STDOUT ? self::OUT : self::ERR, $data); + $callback($type === self::STDOUT ? self::OUT : self::ERR, $data); } } } diff --git a/src/Symfony/Component/Process/Tests/AbstractProcessTest.php b/src/Symfony/Component/Process/Tests/AbstractProcessTest.php index d48698a7cf..575de4d278 100644 --- a/src/Symfony/Component/Process/Tests/AbstractProcessTest.php +++ b/src/Symfony/Component/Process/Tests/AbstractProcessTest.php @@ -865,7 +865,7 @@ abstract class AbstractProcessTest extends \PHPUnit_Framework_TestCase { $process = $this->getProcess('php -m'); $this->setExpectedException('Symfony\Component\Process\Exception\LogicException', sprintf('Process must be started before calling %s.', $method)); - call_user_func(array($process, $method)); + $process->{$method}(); } public function provideMethodsThatNeedARunningProcess() @@ -887,7 +887,7 @@ abstract class AbstractProcessTest extends \PHPUnit_Framework_TestCase $process = $this->getProcess('php -r "sleep(1);"'); $process->start(); try { - call_user_func(array($process, $method)); + $process->{$method}(); $process->stop(0); $this->fail('A LogicException must have been thrown'); } catch (\Exception $e) { @@ -1013,7 +1013,7 @@ abstract class AbstractProcessTest extends \PHPUnit_Framework_TestCase $p = $this->getProcess('php -r "usleep(500000);"'); $p->disableOutput(); $this->setExpectedException($exception, $exceptionMessage); - call_user_func(array($p, $startMethod), function () {}); + $p->{$startMethod}(function () {}); } public function provideStartMethods() @@ -1034,7 +1034,7 @@ abstract class AbstractProcessTest extends \PHPUnit_Framework_TestCase $p->disableOutput(); $p->start(); $this->setExpectedException('Symfony\Component\Process\Exception\LogicException', 'Output has been disabled.'); - call_user_func(array($p, $fetchMethod)); + $p->{$fetchMethod}(); } public function provideOutputFetchingMethods() diff --git a/src/Symfony/Component/PropertyAccess/PropertyAccessor.php b/src/Symfony/Component/PropertyAccess/PropertyAccessor.php index 6173784370..872f32b208 100644 --- a/src/Symfony/Component/PropertyAccess/PropertyAccessor.php +++ b/src/Symfony/Component/PropertyAccess/PropertyAccessor.php @@ -505,11 +505,11 @@ class PropertyAccessor implements PropertyAccessorInterface } foreach ($itemToRemove as $item) { - call_user_func(array($object, $removeMethod), $item); + $object->{$removeMethod}($item); } foreach ($itemsToAdd as $item) { - call_user_func(array($object, $addMethod), $item); + $object->{$addMethod}($item); } } diff --git a/src/Symfony/Component/Routing/Loader/ClosureLoader.php b/src/Symfony/Component/Routing/Loader/ClosureLoader.php index 8212c2916d..9edab1e9e3 100644 --- a/src/Symfony/Component/Routing/Loader/ClosureLoader.php +++ b/src/Symfony/Component/Routing/Loader/ClosureLoader.php @@ -37,7 +37,7 @@ class ClosureLoader extends Loader */ public function load($closure, $type = null) { - return call_user_func($closure); + return $closure(); } /** diff --git a/src/Symfony/Component/Security/Core/Authentication/Provider/AuthenticationProviderInterface.php b/src/Symfony/Component/Security/Core/Authentication/Provider/AuthenticationProviderInterface.php index 8007234175..adad258ee0 100644 --- a/src/Symfony/Component/Security/Core/Authentication/Provider/AuthenticationProviderInterface.php +++ b/src/Symfony/Component/Security/Core/Authentication/Provider/AuthenticationProviderInterface.php @@ -24,12 +24,12 @@ use Symfony\Component\Security\Core\Authentication\AuthenticationManagerInterfac */ interface AuthenticationProviderInterface extends AuthenticationManagerInterface { - /** - * Checks whether this provider supports the given token. - * - * @param TokenInterface $token A TokenInterface instance - * - * @return bool true if the implementation supports the Token, false otherwise - */ - public function supports(TokenInterface $token); + /** + * Checks whether this provider supports the given token. + * + * @param TokenInterface $token A TokenInterface instance + * + * @return bool true if the implementation supports the Token, false otherwise + */ + public function supports(TokenInterface $token); } diff --git a/src/Symfony/Component/Serializer/Encoder/XmlEncoder.php b/src/Symfony/Component/Serializer/Encoder/XmlEncoder.php index 44e4a1c36d..c531c7309b 100644 --- a/src/Symfony/Component/Serializer/Encoder/XmlEncoder.php +++ b/src/Symfony/Component/Serializer/Encoder/XmlEncoder.php @@ -129,21 +129,21 @@ class XmlEncoder extends SerializerAwareEncoder implements EncoderInterface, Dec return $data; } - /** - * {@inheritdoc} - */ - public function supportsEncoding($format) - { - return 'xml' === $format; - } + /** + * {@inheritdoc} + */ + public function supportsEncoding($format) + { + return 'xml' === $format; + } - /** - * {@inheritdoc} - */ - public function supportsDecoding($format) - { - return 'xml' === $format; - } + /** + * {@inheritdoc} + */ + public function supportsDecoding($format) + { + return 'xml' === $format; + } /** * Sets the root node name. diff --git a/src/Symfony/Component/Validator/Constraints/CallbackValidator.php b/src/Symfony/Component/Validator/Constraints/CallbackValidator.php index a6a29e7e6e..6f073c7d87 100644 --- a/src/Symfony/Component/Validator/Constraints/CallbackValidator.php +++ b/src/Symfony/Component/Validator/Constraints/CallbackValidator.php @@ -50,7 +50,9 @@ class CallbackValidator extends ConstraintValidator $methods = $constraint->methods ?: array($constraint->callback); foreach ($methods as $method) { - if (is_array($method) || $method instanceof \Closure) { + if ($method instanceof \Closure) { + $method($object, $this->context); + } elseif (is_array($method)) { if (!is_callable($method)) { throw new ConstraintDefinitionException(sprintf('"%s::%s" targeted by Callback constraint is not a valid callable', $method[0], $method[1])); } diff --git a/src/Symfony/Component/Validator/Constraints/ChoiceValidator.php b/src/Symfony/Component/Validator/Constraints/ChoiceValidator.php index 1566c318c3..cf5774c63d 100644 --- a/src/Symfony/Component/Validator/Constraints/ChoiceValidator.php +++ b/src/Symfony/Component/Validator/Constraints/ChoiceValidator.php @@ -49,13 +49,12 @@ class ChoiceValidator extends ConstraintValidator } if ($constraint->callback) { - if (is_callable(array($this->context->getClassName(), $constraint->callback))) { - $choices = call_user_func(array($this->context->getClassName(), $constraint->callback)); - } elseif (is_callable($constraint->callback)) { - $choices = call_user_func($constraint->callback); - } else { + if (!is_callable($choices = array($this->context->getClassName(), $constraint->callback)) + && !is_callable($choices = $constraint->callback) + ) { throw new ConstraintDefinitionException('The Choice constraint expects a valid callback'); } + $choices = call_user_func($choices); } else { $choices = $constraint->choices; } diff --git a/src/Symfony/Component/Validator/Constraints/TypeValidator.php b/src/Symfony/Component/Validator/Constraints/TypeValidator.php index ca6e5aa7ca..66217d0c39 100644 --- a/src/Symfony/Component/Validator/Constraints/TypeValidator.php +++ b/src/Symfony/Component/Validator/Constraints/TypeValidator.php @@ -40,9 +40,9 @@ class TypeValidator extends ConstraintValidator $isFunction = 'is_'.$type; $ctypeFunction = 'ctype_'.$type; - if (function_exists($isFunction) && call_user_func($isFunction, $value)) { + if (function_exists($isFunction) && $isFunction($value)) { return; - } elseif (function_exists($ctypeFunction) && call_user_func($ctypeFunction, $value)) { + } elseif (function_exists($ctypeFunction) && $ctypeFunction($value)) { return; } elseif ($value instanceof $constraint->type) { return;