From 67b91e562bbed909ea13b916b5797d1a4c366697 Mon Sep 17 00:00:00 2001 From: Fabien Potencier Date: Fri, 13 Jul 2012 15:39:54 +0200 Subject: [PATCH 001/975] [HttpKernel] added a way to enable a disable Profiler --- src/Symfony/Component/HttpKernel/Profiler/Profiler.php | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/Symfony/Component/HttpKernel/Profiler/Profiler.php b/src/Symfony/Component/HttpKernel/Profiler/Profiler.php index f2fc8a937a595..a4d27c2269651 100644 --- a/src/Symfony/Component/HttpKernel/Profiler/Profiler.php +++ b/src/Symfony/Component/HttpKernel/Profiler/Profiler.php @@ -51,6 +51,14 @@ public function disable() $this->enabled = false; } + /** + * Enables the profiler. + */ + public function enable() + { + $this->enabled = true; + } + /** * Loads the Profile for the given Response. * From f41872b9078fcfdc53dbe77ed3b66f317be775a1 Mon Sep 17 00:00:00 2001 From: Fabien Potencier Date: Fri, 13 Jul 2012 15:40:24 +0200 Subject: [PATCH 002/975] [FrameworkBundle] added a way to enable the profiler for the very next request in functional tests (closes #4307) --- src/Symfony/Bundle/FrameworkBundle/Client.php | 40 +++++++++++++++ .../DependencyInjection/Configuration.php | 1 + .../FrameworkExtension.php | 4 ++ .../Resources/config/schema/symfony-1.0.xsd | 1 + .../DependencyInjection/Fixtures/php/full.php | 1 + .../DependencyInjection/Fixtures/xml/full.xml | 2 +- .../DependencyInjection/Fixtures/yml/full.yml | 1 + .../FrameworkExtensionTest.php | 3 ++ .../Controller/ProfilerController.php | 23 +++++++++ .../TestBundle/Resources/config/routing.yml | 4 ++ .../Tests/Functional/ProfilerTest.php | 49 +++++++++++++++++++ .../Tests/Functional/app/Profiler/bundles.php | 9 ++++ .../Tests/Functional/app/Profiler/config.yml | 6 +++ .../Tests/Functional/app/Profiler/routing.yml | 2 + 14 files changed, 145 insertions(+), 1 deletion(-) create mode 100644 src/Symfony/Bundle/FrameworkBundle/Tests/Functional/Bundle/TestBundle/Controller/ProfilerController.php create mode 100644 src/Symfony/Bundle/FrameworkBundle/Tests/Functional/ProfilerTest.php create mode 100644 src/Symfony/Bundle/FrameworkBundle/Tests/Functional/app/Profiler/bundles.php create mode 100644 src/Symfony/Bundle/FrameworkBundle/Tests/Functional/app/Profiler/config.yml create mode 100644 src/Symfony/Bundle/FrameworkBundle/Tests/Functional/app/Profiler/routing.yml diff --git a/src/Symfony/Bundle/FrameworkBundle/Client.php b/src/Symfony/Bundle/FrameworkBundle/Client.php index cd6309b0bc1ed..3874573f90d74 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Client.php +++ b/src/Symfony/Bundle/FrameworkBundle/Client.php @@ -26,6 +26,7 @@ class Client extends BaseClient { private $hasPerformedRequest = false; + private $profiler = false; /** * Returns the container. @@ -61,6 +62,20 @@ public function getProfile() return $this->kernel->getContainer()->get('profiler')->loadProfileFromResponse($this->response); } + /** + * Enables the profiler for the very next request. + * + * @throws \LogicException if the profiler is not configured in the service container + */ + public function enableProfiler() + { + if (!$this->kernel->getContainer()->has('profiler')) { + throw new \LogicException('You cannot enable the profiler as it is not configured in the service container.'); + } + + $this->profiler = true; + } + /** * Makes a request. * @@ -78,9 +93,28 @@ protected function doRequest($request) $this->hasPerformedRequest = true; } + if ($this->profiler) { + $this->profiler = false; + + $this->kernel->boot(); + $this->kernel->getContainer()->get('profiler')->enable(); + } + return $this->kernel->handle($request); } + /** + * {@inheritdoc} + */ + protected function doRequestInProcess($request) + { + $response = parent::doRequestInProcess($request); + + $this->profiler = false; + + return $response; + } + /** * Returns the script to execute when the request must be insulated. * @@ -109,6 +143,11 @@ protected function getScript($request) $path = str_replace("'", "\\'", $r->getFileName()); + $profilerCode = ''; + if ($this->profiler) { + $profilerCode = '$kernel->getContainer()->get(\'profiler\')->enable();'; + } + return <<boot(); +$profilerCode echo serialize(\$kernel->handle(unserialize('$request'))); EOF; } diff --git a/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Configuration.php b/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Configuration.php index f2941c62254ec..bbda8f9fe1ffd 100644 --- a/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Configuration.php +++ b/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Configuration.php @@ -135,6 +135,7 @@ private function addProfilerSection(ArrayNodeDefinition $rootNode) ->children() ->booleanNode('only_exceptions')->defaultFalse()->end() ->booleanNode('only_master_requests')->defaultFalse()->end() + ->booleanNode('enabled')->defaultTrue()->end() ->scalarNode('dsn')->defaultValue('file:%kernel.cache_dir%/profiler')->end() ->scalarNode('username')->defaultValue('')->end() ->scalarNode('password')->defaultValue('')->end() diff --git a/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/FrameworkExtension.php b/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/FrameworkExtension.php index 938be74f43898..95ab24fa8dba3 100644 --- a/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/FrameworkExtension.php +++ b/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/FrameworkExtension.php @@ -229,6 +229,10 @@ private function registerProfilerConfiguration(array $config, ContainerBuilder $ } } } + + if (!$config['enabled']) { + $container->getDefinition('profiler')->addMethodCall('disable', array()); + } } /** diff --git a/src/Symfony/Bundle/FrameworkBundle/Resources/config/schema/symfony-1.0.xsd b/src/Symfony/Bundle/FrameworkBundle/Resources/config/schema/symfony-1.0.xsd index 5a97023d0766d..ddad0d1db6464 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Resources/config/schema/symfony-1.0.xsd +++ b/src/Symfony/Bundle/FrameworkBundle/Resources/config/schema/symfony-1.0.xsd @@ -50,6 +50,7 @@ + diff --git a/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/php/full.php b/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/php/full.php index b4c1acc52e098..8b25687e7ad45 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/php/full.php +++ b/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/php/full.php @@ -13,6 +13,7 @@ ), 'profiler' => array( 'only_exceptions' => true, + 'enabled' => false, ), 'router' => array( 'resource' => '%kernel.root_dir%/config/routing.xml', diff --git a/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/xml/full.xml b/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/xml/full.xml index 3e75d66e690f4..703e2355fa0c5 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/xml/full.xml +++ b/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/xml/full.xml @@ -10,7 +10,7 @@ - + diff --git a/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/yml/full.yml b/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/yml/full.yml index f10bb5ccfec4c..2a4fda9191aa4 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/yml/full.yml +++ b/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/yml/full.yml @@ -9,6 +9,7 @@ framework: enabled: true profiler: only_exceptions: true + enabled: false router: resource: %kernel.root_dir%/config/routing.xml type: xml diff --git a/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/FrameworkExtensionTest.php b/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/FrameworkExtensionTest.php index 385ece0c8cba5..4b6629ec8ee59 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/FrameworkExtensionTest.php +++ b/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/FrameworkExtensionTest.php @@ -48,6 +48,9 @@ public function testProfiler() $this->assertTrue($container->hasDefinition('data_collector.config'), '->registerProfilerConfiguration() loads collectors.xml'); $this->assertTrue($container->getParameter('profiler_listener.only_exceptions')); $this->assertEquals('%profiler_listener.only_exceptions%', $container->getDefinition('profiler_listener')->getArgument(2)); + + $calls = $container->getDefinition('profiler')->getMethodCalls(); + $this->assertEquals('disable', $calls[0][0]); } public function testRouter() diff --git a/src/Symfony/Bundle/FrameworkBundle/Tests/Functional/Bundle/TestBundle/Controller/ProfilerController.php b/src/Symfony/Bundle/FrameworkBundle/Tests/Functional/Bundle/TestBundle/Controller/ProfilerController.php new file mode 100644 index 0000000000000..0452e255eafe4 --- /dev/null +++ b/src/Symfony/Bundle/FrameworkBundle/Tests/Functional/Bundle/TestBundle/Controller/ProfilerController.php @@ -0,0 +1,23 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Bundle\FrameworkBundle\Tests\Functional\Bundle\TestBundle\Controller; + +use Symfony\Component\HttpFoundation\Response; +use Symfony\Component\DependencyInjection\ContainerAware; + +class ProfilerController extends ContainerAware +{ + public function indexAction() + { + return new Response('Hello'); + } +} diff --git a/src/Symfony/Bundle/FrameworkBundle/Tests/Functional/Bundle/TestBundle/Resources/config/routing.yml b/src/Symfony/Bundle/FrameworkBundle/Tests/Functional/Bundle/TestBundle/Resources/config/routing.yml index 69a8e6d45a2dd..2a077856f6bcf 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Tests/Functional/Bundle/TestBundle/Resources/config/routing.yml +++ b/src/Symfony/Bundle/FrameworkBundle/Tests/Functional/Bundle/TestBundle/Resources/config/routing.yml @@ -17,3 +17,7 @@ session_setflash: session_showflash: pattern: /session_showflash defaults: { _controller: TestBundle:Session:showFlash} + +profiler: + pattern: /profiler + defaults: { _controller: TestBundle:Profiler:index } diff --git a/src/Symfony/Bundle/FrameworkBundle/Tests/Functional/ProfilerTest.php b/src/Symfony/Bundle/FrameworkBundle/Tests/Functional/ProfilerTest.php new file mode 100644 index 0000000000000..d4eb927ff8213 --- /dev/null +++ b/src/Symfony/Bundle/FrameworkBundle/Tests/Functional/ProfilerTest.php @@ -0,0 +1,49 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Bundle\FrameworkBundle\Tests\Functional; + +/** + * @group functional + */ +class ProfilerTest extends WebTestCase +{ + /** + * @dataProvider getConfigs + */ + public function testProfilerIsDisabled($insulate) + { + $client = $this->createClient(array('test_case' => 'Profiler', 'root_config' => 'config.yml')); + if ($insulate) { + $client->insulate(); + } + + $client->request('GET', '/profiler'); + $this->assertFalse($client->getProfile()); + + // enable the profiler for the next request + $client->enableProfiler(); + $crawler = $client->request('GET', '/profiler'); + $profile = $client->getProfile(); + $this->assertTrue(is_object($profile)); + + $client->request('GET', '/profiler'); + $this->assertFalse($client->getProfile()); + } + + public function getConfigs() + { + return array( + array(false), + array(true), + ); + } +} diff --git a/src/Symfony/Bundle/FrameworkBundle/Tests/Functional/app/Profiler/bundles.php b/src/Symfony/Bundle/FrameworkBundle/Tests/Functional/app/Profiler/bundles.php new file mode 100644 index 0000000000000..351cf79d43231 --- /dev/null +++ b/src/Symfony/Bundle/FrameworkBundle/Tests/Functional/app/Profiler/bundles.php @@ -0,0 +1,9 @@ + Date: Fri, 20 Jul 2012 14:59:54 +0200 Subject: [PATCH 003/975] [FrameworkBundle] recursively resolve container parameter placeholders for arrays in router _defaults --- src/Symfony/Bundle/FrameworkBundle/Routing/Router.php | 8 ++++++++ .../FrameworkBundle/Tests/Routing/RouterTest.php | 10 ++++++++++ 2 files changed, 18 insertions(+) diff --git a/src/Symfony/Bundle/FrameworkBundle/Routing/Router.php b/src/Symfony/Bundle/FrameworkBundle/Routing/Router.php index 49c3dda9f8ff1..c4c348c25f3c3 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Routing/Router.php +++ b/src/Symfony/Bundle/FrameworkBundle/Routing/Router.php @@ -114,6 +114,14 @@ private function resolveString($value) { $container = $this->container; + if (is_array($value)) { + foreach ($value as $key => $val) { + $value[$key] = $this->resolveString($val); + } + + return $value; + } + if (null === $value || false === $value || true === $value || is_object($value)) { return $value; } diff --git a/src/Symfony/Bundle/FrameworkBundle/Tests/Routing/RouterTest.php b/src/Symfony/Bundle/FrameworkBundle/Tests/Routing/RouterTest.php index 2c6a031b69d14..0c8a5d3e0a5a8 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Tests/Routing/RouterTest.php +++ b/src/Symfony/Bundle/FrameworkBundle/Tests/Routing/RouterTest.php @@ -27,6 +27,8 @@ public function testDefaultsPlaceholders() 'foo' => 'before_%parameter.foo%', 'bar' => '%parameter.bar%_after', 'baz' => '%%unescaped%%', + 'boo' => array('%parameter%', '%%escaped_parameter%%', array('%bee_parameter%', 'bee')), + 'bee' => array('bee', 'bee'), ), array( ) @@ -39,6 +41,12 @@ public function testDefaultsPlaceholders() $sc->expects($this->at(3))->method('hasParameter')->will($this->returnValue(true)); $sc->expects($this->at(4))->method('getParameter')->will($this->returnValue('bar')); + $sc->expects($this->at(5))->method('hasParameter')->will($this->returnValue(true)); + $sc->expects($this->at(6))->method('getParameter')->will($this->returnValue('boo')); + + $sc->expects($this->at(7))->method('hasParameter')->will($this->returnValue(true)); + $sc->expects($this->at(8))->method('getParameter')->will($this->returnValue('foo_bee')); + $router = new Router($sc, 'foo'); $route = $router->getRouteCollection()->get('foo'); @@ -47,6 +55,8 @@ public function testDefaultsPlaceholders() 'foo' => 'before_foo', 'bar' => 'bar_after', 'baz' => '%unescaped%', + 'boo' => array('boo', '%escaped_parameter%', array('foo_bee', 'bee')), + 'bee' => array('bee', 'bee'), ), $route->getDefaults() ); From e2aa79b88542c1b26a5e904fd1672b741319738e Mon Sep 17 00:00:00 2001 From: Tim Nagel Date: Fri, 27 Jul 2012 09:25:56 +1000 Subject: [PATCH 004/975] Added CardScheme validator --- .../Validator/Constraints/CardScheme.php | 35 +++++++ .../Constraints/CardSchemeValidator.php | 92 +++++++++++++++++++ .../Constraints/CardSchemeValidatorTest.php | 81 ++++++++++++++++ 3 files changed, 208 insertions(+) create mode 100644 src/Symfony/Component/Validator/Constraints/CardScheme.php create mode 100644 src/Symfony/Component/Validator/Constraints/CardSchemeValidator.php create mode 100644 src/Symfony/Component/Validator/Tests/Constraints/CardSchemeValidatorTest.php diff --git a/src/Symfony/Component/Validator/Constraints/CardScheme.php b/src/Symfony/Component/Validator/Constraints/CardScheme.php new file mode 100644 index 0000000000000..356cad930c5b3 --- /dev/null +++ b/src/Symfony/Component/Validator/Constraints/CardScheme.php @@ -0,0 +1,35 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Validator\Constraints; + +use Symfony\Component\Validator\Constraint; + +/** + * Metadata for the CardSchemeValidator. + * + * @Annotation + */ +class CardScheme extends Constraint +{ + public $message = 'Unsupported card type or invalid card number'; + public $schemes; + + public function getDefaultOption() + { + return 'schemes'; + } + + public function getRequiredOptions() + { + return array('schemes'); + } +} diff --git a/src/Symfony/Component/Validator/Constraints/CardSchemeValidator.php b/src/Symfony/Component/Validator/Constraints/CardSchemeValidator.php new file mode 100644 index 0000000000000..97b4567491551 --- /dev/null +++ b/src/Symfony/Component/Validator/Constraints/CardSchemeValidator.php @@ -0,0 +1,92 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Validator\Constraints; + +use Symfony\Component\Validator\Constraint; +use Symfony\Component\Validator\ConstraintValidator; + +/** + * Validates that a card number belongs to a specified scheme. + * + * @see http://en.wikipedia.org/wiki/Bank_card_number + * @author Tim Nagel + */ +class CardSchemeValidator extends ConstraintValidator +{ + protected $schemes = array( + 'AMEX' => array( + '/^(3[47])([0-9]{13})/' + ), + 'CHINA_UNIONPAY' => array( + '/^(62)([0-9]{16,19}/' + ), + 'DINERS' => array( + '/^(36)([0-9]{12})/', + '/^(30[0-5])([0-9]{11})/', + '/^(5[45])([0-9]{14})/' + ), + 'DISCOVER' => array( + '/^(6011)([0-9]{12})/', + '/^(64[4-9])([0-9]{13})/', + '/^(65)([0-9]{14})/', + '/^(622)(12[6-9]|1[3-9][0-9]|[2-8][0-9][0-9]|91[0-9]|92[0-5])([0-9]{10})/' + ), + 'INSTAPAYMENT' => array( + '/^(63[7-9])([0-9]{13})/' + ), + 'JCB' => array( + '/^(352[8-9]|35[3-8][0-9])([0-9]{12})/' + ), + 'LASER' => array( + '/^(6304|670[69]|6771)([0-9]{12, 15})/' + ), + 'MAESTRO' => array( + '/^(5018|5020|5038|6304|6759|6761|676[23]|0604)([0-9]{8, 15})/' + ), + 'MASTERCARD' => array( + '/^(5[1-5])([0-9]{14})/' + ), + 'VISA' => array( + '/^(4)([0-9]{12})/' + ), + ); + + /** + * Validates a creditcard belongs to a specified scheme. + * + * @param mixed $value + * @param Constraint $constraint + */ + public function validate($value, Constraint $constraint) + { + if (null === $value || '' === $value) { + return; + } + + if (!is_numeric($value)) { + $this->context->addViolation($constraint->message); + } + + $schemes = array_flip($constraint->schemes); + $schemeRegexes = array_intersect_key($this->schemes, $schemes); + + foreach ($schemeRegexes as $regexes) { + foreach ($regexes as $regex) { + if (preg_match($regex, $value)) { + return; + } + } + } + + $this->context->addViolation($constraint->message); + } +} diff --git a/src/Symfony/Component/Validator/Tests/Constraints/CardSchemeValidatorTest.php b/src/Symfony/Component/Validator/Tests/Constraints/CardSchemeValidatorTest.php new file mode 100644 index 0000000000000..3fa3092dca2fd --- /dev/null +++ b/src/Symfony/Component/Validator/Tests/Constraints/CardSchemeValidatorTest.php @@ -0,0 +1,81 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Validator\Tests\Constraints; + +use Symfony\Component\Validator\Constraints\CardScheme; +use Symfony\Component\Validator\Constraints\CardSchemeValidator; + +class CardSchemeValidatorTest extends \PHPUnit_Framework_TestCase +{ + protected $context; + protected $validator; + + protected function setUp() + { + $this->context = $this->getMock('Symfony\Component\Validator\ExecutionContext', array(), array(), '', false); + $this->validator = new CardSchemeValidator(); + $this->validator->initialize($this->context); + } + + protected function tearDown() + { + $this->context = null; + $this->validator = null; + } + + public function testNullIsValid() + { + $this->context->expects($this->never()) + ->method('addViolation'); + + $this->validator->validate(null, new CardScheme(array('schemes' => array()))); + } + + public function testEmptyStringIsValid() + { + $this->context->expects($this->never()) + ->method('addViolation'); + + $this->validator->validate('', new CardScheme(array('schemes' => array()))); + } + + /** + * @dataProvider getValidNumbers + */ + public function testValidNumbers($scheme, $number) + { + $this->context->expects($this->never()) + ->method('addViolation'); + + $this->validator->validate($number, new CardScheme(array('schemes' => array($scheme)))); + } + + public function getValidNumbers() + { + return array( + array('VISA', '42424242424242424242'), + array('AMEX', '378282246310005'), + array('AMEX', '371449635398431'), + array('AMEX', '378734493671000'), + array('DINERS', '30569309025904'), + array('DISCOVER', '6011111111111117'), + array('DISCOVER', '6011000990139424'), + array('JCB', '3530111333300000'), + array('JCB', '3566002020360505'), + array('MASTERCARD', '5555555555554444'), + array('MASTERCARD', '5105105105105100'), + array('VISA', '4111111111111111'), + array('VISA', '4012888888881881'), + array('VISA', '4222222222222'), + ); + } +} From 6ff9b045c299a4c2499c02efa11bb414fdc668bb Mon Sep 17 00:00:00 2001 From: Tim Nagel Date: Wed, 4 Jul 2012 08:45:52 +1000 Subject: [PATCH 005/975] Add Luhn validator --- .../Component/Validator/Constraints/Luhn.php | 24 ++++ .../Validator/Constraints/LuhnValidator.php | 58 ++++++++++ .../Tests/Constraints/LuhnValidatorTest.php | 107 ++++++++++++++++++ 3 files changed, 189 insertions(+) create mode 100644 src/Symfony/Component/Validator/Constraints/Luhn.php create mode 100644 src/Symfony/Component/Validator/Constraints/LuhnValidator.php create mode 100644 src/Symfony/Component/Validator/Tests/Constraints/LuhnValidatorTest.php diff --git a/src/Symfony/Component/Validator/Constraints/Luhn.php b/src/Symfony/Component/Validator/Constraints/Luhn.php new file mode 100644 index 0000000000000..f376045fc7de8 --- /dev/null +++ b/src/Symfony/Component/Validator/Constraints/Luhn.php @@ -0,0 +1,24 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Validator\Constraints; + +use Symfony\Component\Validator\Constraint; + +/** + * Metadata for the LuhnValidator. + * + * @Annotation + */ +class Luhn extends Constraint +{ + public $message = 'Invalid card number'; +} diff --git a/src/Symfony/Component/Validator/Constraints/LuhnValidator.php b/src/Symfony/Component/Validator/Constraints/LuhnValidator.php new file mode 100644 index 0000000000000..1ae8b399483ab --- /dev/null +++ b/src/Symfony/Component/Validator/Constraints/LuhnValidator.php @@ -0,0 +1,58 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Validator\Constraints; + +use Symfony\Component\Validator\Constraint; +use Symfony\Component\Validator\ConstraintValidator; + +/** + * Validates a PAN using the LUHN Algorithm + * + * For a list of example card numbers that are used to test this + * class, please see the LuhnValidatorTest class. + * + * @see http://en.wikipedia.org/wiki/Luhn_algorithm + * @author Tim Nagel + * @author Greg Knapp http://gregk.me/2011/php-implementation-of-bank-card-luhn-algorithm/ + */ +class LuhnValidator extends ConstraintValidator +{ + /** + * Validates a creditcard number with the Luhn algorithm. + * + * @param mixed $value + * @param Constraint $constraint + */ + public function validate($value, Constraint $constraint) + { + if (null === $value || '' === $value) { + return; + } + + if (!is_numeric($value)) { + $this->context->addViolation($constraint->message); + + return; + } + + $length = strlen($value); + $oddLength = $length % 2; + for ($sum = 0, $i = $length - 1; $i >= 0; $i--) { + $digit = (int) $value[$i]; + $sum += (($i % 2) === $oddLength) ? array_sum(str_split($digit * 2)) : $digit; + } + + if (($sum % 10) !== 0) { + $this->context->addViolation($constraint->message); + } + } +} diff --git a/src/Symfony/Component/Validator/Tests/Constraints/LuhnValidatorTest.php b/src/Symfony/Component/Validator/Tests/Constraints/LuhnValidatorTest.php new file mode 100644 index 0000000000000..3c057786391fa --- /dev/null +++ b/src/Symfony/Component/Validator/Tests/Constraints/LuhnValidatorTest.php @@ -0,0 +1,107 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Validator\Tests\Constraints; + +use Symfony\Component\Validator\Constraints\Luhn; +use Symfony\Component\Validator\Constraints\LuhnValidator; + +class LuhnValidatorTest extends \PHPUnit_Framework_TestCase +{ + protected $context; + protected $validator; + + protected function setUp() + { + $this->context = $this->getMock('Symfony\Component\Validator\ExecutionContext', array(), array(), '', false); + $this->validator = new LuhnValidator(); + $this->validator->initialize($this->context); + } + + protected function tearDown() + { + $this->context = null; + $this->validator = null; + } + + public function testNullIsValid() + { + $this->context->expects($this->never()) + ->method('addViolation'); + + $this->validator->validate(null, new Luhn()); + } + + public function testEmptyStringIsValid() + { + $this->context->expects($this->never()) + ->method('addViolation'); + + $this->validator->validate('', new Luhn()); + } + + /** + * @dataProvider getValidNumbers + */ + public function testValidNumbers($number) + { + $this->context->expects($this->never()) + ->method('addViolation'); + + $this->validator->validate($number, new Luhn()); + } + + public function getValidNumbers() + { + return array( + array('42424242424242424242'), + array('378282246310005'), + array('371449635398431'), + array('378734493671000'), + array('5610591081018250'), + array('30569309025904'), + array('38520000023237'), + array('6011111111111117'), + array('6011000990139424'), + array('3530111333300000'), + array('3566002020360505'), + array('5555555555554444'), + array('5105105105105100'), + array('4111111111111111'), + array('4012888888881881'), + array('4222222222222'), + array('5019717010103742'), + array('6331101999990016'), + ); + } + + /** + * @dataProvider getInvalidNumbers + */ + public function testInvalidNumbers($number) + { + $constraint = new Luhn(); + + $this->context->expects($this->once()) + ->method('addViolation') + ->with($constraint->message); + + $this->validator->validate($number, $constraint); + } + + public function getInvalidNumbers() + { + return array( + array('1234567812345678'), + array('4222222222222222'), + ); + } +} From 2f7bbbfec15222097d4632bf05344d9f4d09a198 Mon Sep 17 00:00:00 2001 From: Niklas Fiekas Date: Sun, 10 Jun 2012 17:37:24 +0200 Subject: [PATCH 006/975] [HttpFoundation] Added BinaryFileResponse. --- .../HttpFoundation/BinaryFileResponse.php | 259 ++++++++++++++++++ .../Tests/BinaryFileResponseTest.php | 124 +++++++++ 2 files changed, 383 insertions(+) create mode 100644 src/Symfony/Component/HttpFoundation/BinaryFileResponse.php create mode 100644 src/Symfony/Component/HttpFoundation/Tests/BinaryFileResponseTest.php diff --git a/src/Symfony/Component/HttpFoundation/BinaryFileResponse.php b/src/Symfony/Component/HttpFoundation/BinaryFileResponse.php new file mode 100644 index 0000000000000..080a4408552e4 --- /dev/null +++ b/src/Symfony/Component/HttpFoundation/BinaryFileResponse.php @@ -0,0 +1,259 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\HttpFoundation; + +use Symfony\Component\HttpFoundation\File\File; +use Symfony\Component\HttpFoundation\File\Exception\FileException; + +/** + * BinaryFileResponse represents an HTTP response delivering a file. + * + * @author Niklas Fiekas + * @author stealth35 + * @author Igor Wiedler + * @author Jordan Alliot + * @author Sergey Linnik + */ +class BinaryFileResponse extends Response +{ + protected static $trustXSendfileTypeHeader = false; + + protected $file; + protected $offset; + protected $maxlen; + + /** + * Constructor. + * + * @param SplFileInfo|string $file The file to stream + * @param integer $status The response status code + * @param array $headers An array of response headers + * @param boolean $public Files are public by default + * @param null|string $contentDisposition The type of Content-Disposition to set automatically with the filename + * @param boolean $autoEtag Whether the ETag header should be automatically set + * @param boolean $autoLastModified Whether the Last-Modified header should be automatically set + */ + public function __construct($file, $status = 200, $headers = array(), $public = true, $contentDisposition = null, $autoEtag = false, $autoLastModified = true) + { + parent::__construct(null, $status, $headers); + + $this->setFile($file, $contentDisposition, $autoEtag, $autoLastModified); + + if ($public) { + $this->setPublic(); + } + } + + /** + * {@inheritdoc} + */ + public static function create($file = null, $status = 200, $headers = array(), $public = true, $contentDisposition = null, $autoEtag = false, $autoLastModified = true) + { + return new static($file, $status, $headers, $public, $contentDisposition, $autoEtag, $autoLastModified); + } + + /** + * Sets the file to stream. + * + * @param SplFileInfo|string $file The file to stream + */ + public function setFile($file, $contentDisposition = null, $autoEtag = false, $autoLastModified = true) + { + $file = new File((string) $file); + + if (!$file->isReadable()) { + throw new FileException('File must be readable.'); + } + + $this->file = $file; + + if ($autoEtag) { + $this->setAutoEtag(); + } + + if ($autoLastModified) { + $this->setAutoLastModified(); + } + + if ($contentDisposition) { + $this->setContentDisposition($contentDisposition); + } + + return $this; + } + + /** + * Gets the file. + * + * @return File The file to stream + */ + public function getFile() + { + return $this->file; + } + + /** + * Automatically sets the Last-Modified header according the file modification date. + */ + public function setAutoLastModified() + { + $this->setLastModified(\DateTime::createFromFormat('U', $this->file->getMTime())); + + return $this; + } + + /** + * Automatically sets the ETag header according to the checksum of the file. + */ + public function setAutoEtag() + { + $this->setEtag(sha1_file($this->file->getPathname())); + + return $this; + } + + /** + * Sets the Content-Disposition header with the given filename. + * + * @param string $disposition ResponseHeaderBag::DISPOSITION_INLINE or ResponseHeaderBag::DISPOSITION_ATTACHMENT + * @param string $filename Optionally use this filename instead of the real name of the file + * @param string $filenameFallback A fallback filename, containing only ASCII characters. Defaults to an automatically encoded filename + */ + public function setContentDisposition($disposition, $filename = '', $filenameFallback = '') + { + if ($filename === '') { + $filename = $this->file->getFilename(); + } + + $dispositionHeader = $this->headers->makeDisposition($disposition, $filename, $filenameFallback); + $this->headers->set('Content-Disposition', $dispositionHeader); + + return $this; + } + + /** + * {@inheritdoc} + */ + public function prepare(Request $request) + { + $this->headers->set('Content-Length', $this->file->getSize()); + $this->headers->set('Accept-Ranges', 'bytes'); + $this->headers->set('Content-Transfer-Encoding', 'binary'); + + if (!$this->headers->has('Content-Type')) { + $this->headers->set('Content-Type', $this->file->getMimeType() ?: 'application/octet-stream'); + } + + if ('HTTP/1.0' != $request->server->get('SERVER_PROTOCOL')) { + $this->setProtocolVersion('1.1'); + } + + $this->offset = 0; + $this->maxlen = -1; + + if (self::$trustXSendfileTypeHeader && $request->headers->has('X-Sendfile-Type')) { + // Use X-Sendfile, do not send any content. + $type = $request->headers->get('X-Sendfile-Type'); + $path = $this->file->getRealPath(); + if (strtolower($type) == 'x-accel-redirect') { + // Do X-Accel-Mapping substitutions. + foreach (explode(',', $request->headers->get('X-Accel-Mapping', '')) as $mapping) { + $mapping = explode('=', $mapping, 2); + + if (2 == count($mapping)) { + $location = trim($mapping[0]); + $pathPrefix = trim($mapping[1]); + + if (substr($path, 0, strlen($pathPrefix)) == $pathPrefix) { + $path = $location . substr($path, strlen($pathPrefix)); + break; + } + } + } + } + $this->headers->set($type, $path); + $this->maxlen = 0; + } elseif ($request->headers->has('Range')) { + // Process the range headers. + if (!$request->headers->has('If-Range') || $this->getEtag() == $request->headers->get('If-Range')) { + $range = $request->headers->get('Range'); + + list($start, $end) = array_map('intval', explode('-', substr($range, 6), 2)) + array(0); + + if ('' !== $end) { + $this->maxlen = $end - $start; + } else { + $end = $this->file->getSize() - 1; + } + + $this->offset = $start; + + $this->setStatusCode(206); + $this->headers->set('Content-Range', sprintf('bytes %s-%s/%s', $start, $end, $this->file->getSize())); + } + } + } + + /** + * Sends the file. + */ + public function sendContent() + { + if (!$this->isSuccessful()) { + parent::sendContent(); + + return; + } + + if (0 === $this->maxlen) { + return; + } + + $out = fopen('php://output', 'wb'); + $file = fopen($this->file->getPathname(), 'rb'); + + stream_copy_to_stream($file, $out, $this->maxlen, $this->offset); + + fclose($out); + fclose($file); + } + + /** + * {@inheritdoc} + * + * @throws \LogicException when the content is not null + */ + public function setContent($content) + { + if (null !== $content) { + throw new \LogicException('The content cannot be set on a BinaryFileResponse instance.'); + } + } + + /** + * {@inheritdoc} + * + * @return false + */ + public function getContent() + { + return false; + } + + /** + * Trust X-Sendfile-Type header. + */ + public static function trustXSendfileTypeHeader() + { + self::$trustXSendfileTypeHeader = true; + } +} diff --git a/src/Symfony/Component/HttpFoundation/Tests/BinaryFileResponseTest.php b/src/Symfony/Component/HttpFoundation/Tests/BinaryFileResponseTest.php new file mode 100644 index 0000000000000..4a8fe5489fffa --- /dev/null +++ b/src/Symfony/Component/HttpFoundation/Tests/BinaryFileResponseTest.php @@ -0,0 +1,124 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\HttpFoundation\Tests; + +use Symfony\Component\HttpFoundation\BinaryFileResponse; +use Symfony\Component\HttpFoundation\Request; +use Symfony\Component\HttpFoundation\ResponseHeaderBag; + +class BinaryFileResponseTest extends \PHPUnit_Framework_TestCase +{ + public function testConstruction() + { + $response = new BinaryFileResponse('README.md', 404, array('X-Header' => 'Foo'), true, null, true, true); + $this->assertEquals(404, $response->getStatusCode()); + $this->assertEquals('Foo', $response->headers->get('X-Header')); + $this->assertTrue($response->headers->has('ETag')); + $this->assertTrue($response->headers->has('Last-Modified')); + $this->assertFalse($response->headers->has('Content-Disposition')); + + $response = BinaryFileResponse::create('README.md', 404, array(), true, ResponseHeaderBag::DISPOSITION_INLINE); + $this->assertEquals(404, $response->getStatusCode()); + $this->assertFalse($response->headers->has('ETag')); + $this->assertEquals('inline; filename="README.md"', $response->headers->get('Content-Disposition')); + } + + /** + * @expectedException \LogicException + */ + public function testSetContent() + { + $response = new BinaryFileResponse('README.md'); + $response->setContent('foo'); + } + + public function testGetContent() + { + $response = new BinaryFileResponse('README.md'); + $this->assertFalse($response->getContent()); + } + + public function testRequests() + { + $response = BinaryFileResponse::create('src/Symfony/Component/HttpFoundation/Tests/File/Fixtures/test.gif')->setAutoEtag(); + + // do a request to get the ETag + $request = Request::create('/'); + $response->prepare($request); + $etag = $response->headers->get('ETag'); + + // prepare a request for a range of the testing file + $request = Request::create('/'); + $request->headers->set('If-Range', $etag); + $request->headers->set('Range', 'bytes=1-4'); + + $this->expectOutputString('IF8'); + $response = clone $response; + $response->prepare($request); + $response->sendContent(); + + $this->assertEquals('binary', $response->headers->get('Content-Transfer-Encoding')); + } + + public function testXSendfile() + { + $request = Request::create('/'); + $request->headers->set('X-Sendfile-Type', 'X-Sendfile'); + + BinaryFileResponse::trustXSendfileTypeHeader(); + $response = BinaryFileResponse::create('README.md'); + $response->prepare($request); + + $this->expectOutputString(''); + $response->sendContent(); + + $this->assertContains('README.md', $response->headers->get('X-Sendfile')); + } + + /** + * @dataProvider getSampleXAccelMappings + */ + public function testXAccelMapping($realpath, $mapping, $virtual) + { + $request = Request::create('/'); + $request->headers->set('X-Sendfile-Type', 'X-Accel-Redirect'); + $request->headers->set('X-Accel-Mapping', $mapping); + + $file = $this->getMockBuilder('Symfony\Component\HttpFoundation\File\File') + ->disableOriginalConstructor() + ->getMock(); + $file->expects($this->any()) + ->method('getRealPath') + ->will($this->returnValue($realpath)); + $file->expects($this->any()) + ->method('isReadable') + ->will($this->returnValue(true)); + + BinaryFileResponse::trustXSendFileTypeHeader(); + $response = new BinaryFileResponse('README.md'); + $reflection = new \ReflectionObject($response); + $property = $reflection->getProperty('file'); + $property->setAccessible(true); + $property->setValue($response, $file); + + $response->prepare($request); + $this->assertEquals($virtual, $response->headers->get('X-Accel-Redirect')); + } + + public function getSampleXAccelMappings() + { + return array( + array('/var/www/var/www/files/foo.txt', '/files/=/var/www/', '/files/var/www/files/foo.txt'), + array('/home/foo/bar.txt', '/files/=/var/www/,/baz/=/home/foo/', '/baz/bar.txt'), + ); + } +} From 92e10a87aca412df67a0e1dfa9bd1e397667c5a7 Mon Sep 17 00:00:00 2001 From: Jordan Alliot Date: Wed, 8 Aug 2012 00:06:54 +0200 Subject: [PATCH 007/975] Updated HttpFoundation and Locale for proper Composer autoloading --- composer.json | 9 +++++---- src/Symfony/Component/HttpFoundation/README.md | 2 +- src/Symfony/Component/HttpFoundation/composer.json | 6 ++---- src/Symfony/Component/Locale/README.md | 5 ++++- src/Symfony/Component/Locale/composer.json | 3 ++- 5 files changed, 14 insertions(+), 11 deletions(-) diff --git a/composer.json b/composer.json index 045d434556b20..5e021fc66234f 100644 --- a/composer.json +++ b/composer.json @@ -62,10 +62,11 @@ "monolog/monolog": "dev-master" }, "autoload": { - "psr-0": { - "Symfony": "src/", - "SessionHandlerInterface": "src/Symfony/Component/HttpFoundation/Resources/stubs" - } + "psr-0": { "Symfony": "src/" }, + "classmap": [ + "src/Symfony/Component/HttpFoundation/Resources/stubs", + "src/Symfony/Component/Locale/Resources/stubs" + ] }, "minimum-stability": "dev", "extra": { diff --git a/src/Symfony/Component/HttpFoundation/README.md b/src/Symfony/Component/HttpFoundation/README.md index bb6f02c443c55..0c4a4a9dc3a61 100644 --- a/src/Symfony/Component/HttpFoundation/README.md +++ b/src/Symfony/Component/HttpFoundation/README.md @@ -31,7 +31,7 @@ the HTTP specification. Loading ------- -If you are using PHP 5.3.x you must add the following to your autoloader: +If you are not using Composer but are using PHP 5.3.x, you must add the following to your autoloader: // SessionHandlerInterface if (!interface_exists('SessionHandlerInterface')) { diff --git a/src/Symfony/Component/HttpFoundation/composer.json b/src/Symfony/Component/HttpFoundation/composer.json index 4e4f90779fc64..95c9d70d56c41 100644 --- a/src/Symfony/Component/HttpFoundation/composer.json +++ b/src/Symfony/Component/HttpFoundation/composer.json @@ -19,10 +19,8 @@ "php": ">=5.3.3" }, "autoload": { - "psr-0": { - "Symfony\\Component\\HttpFoundation": "", - "SessionHandlerInterface": "Symfony/Component/HttpFoundation/Resources/stubs" - } + "psr-0": { "Symfony\\Component\\HttpFoundation": "" }, + "classmap": [ "Resources/stubs" ] }, "target-dir": "Symfony/Component/HttpFoundation", "extra": { diff --git a/src/Symfony/Component/Locale/README.md b/src/Symfony/Component/Locale/README.md index 7db3d6bf01a52..431a65a1fb03a 100644 --- a/src/Symfony/Component/Locale/README.md +++ b/src/Symfony/Component/Locale/README.md @@ -14,6 +14,9 @@ requires adding the following lines to your autoloader: $loader->registerPrefixFallback(__DIR__.'/../vendor/symfony/src/Symfony/Component/Locale/Resources/stubs'); } +If you are using Composer for autoloading, then you can even simplify it by +removing the ``$loader->registerPrefixFallback`` line. + Resources --------- @@ -33,4 +36,4 @@ This way the tests will use the ICU data files with the same version of your ``intl`` extension. Read the file ``Resources/data/UPDATE.txt`` for more info about building or -updating the ICU data files. \ No newline at end of file +updating the ICU data files. diff --git a/src/Symfony/Component/Locale/composer.json b/src/Symfony/Component/Locale/composer.json index 0c96cdefcdf5e..99a850c885c7c 100644 --- a/src/Symfony/Component/Locale/composer.json +++ b/src/Symfony/Component/Locale/composer.json @@ -22,7 +22,8 @@ "ext-intl": ">=5.3.3" }, "autoload": { - "psr-0": { "Symfony\\Component\\Locale": "" } + "psr-0": { "Symfony\\Component\\Locale": "" }, + "classmap": [ "Resources/stubs" ] }, "target-dir": "Symfony/Component/Locale", "extra": { From 5a53821ca34ea3f71c74be9985a24467bcdc77a6 Mon Sep 17 00:00:00 2001 From: Tobias Schultze Date: Sun, 29 Jul 2012 18:01:50 +0300 Subject: [PATCH 008/975] [OptionsResolver] fix removing normalizers --- .../Component/OptionsResolver/Options.php | 1 + .../OptionsResolver/Tests/OptionsTest.php | 45 +++++++++++++++++++ 2 files changed, 46 insertions(+) diff --git a/src/Symfony/Component/OptionsResolver/Options.php b/src/Symfony/Component/OptionsResolver/Options.php index ef10a19427630..5a2b0f7f381f3 100644 --- a/src/Symfony/Component/OptionsResolver/Options.php +++ b/src/Symfony/Component/OptionsResolver/Options.php @@ -143,6 +143,7 @@ public function replace(array $options) $this->options = array(); $this->lazy = array(); + $this->normalizers = array(); foreach ($options as $option => $value) { $this->overload($option, $value); diff --git a/src/Symfony/Component/OptionsResolver/Tests/OptionsTest.php b/src/Symfony/Component/OptionsResolver/Tests/OptionsTest.php index e1510516116c2..66f9e399a435a 100644 --- a/src/Symfony/Component/OptionsResolver/Tests/OptionsTest.php +++ b/src/Symfony/Component/OptionsResolver/Tests/OptionsTest.php @@ -469,4 +469,49 @@ public function testHasWithNullValue() $this->assertTrue($this->options->has('foo')); } + + public function testRemoveOptionAndNormalizer() + { + $this->options->set('foo1', 'bar'); + $this->options->setNormalizer('foo1', function (Options $options) { + return ''; + }); + $this->options->set('foo2', 'bar'); + $this->options->setNormalizer('foo2', function (Options $options) { + return ''; + }); + + $this->options->remove('foo2'); + $this->assertEquals(array('foo1' => ''), $this->options->all()); + } + + public function testReplaceOptionAndNormalizer() + { + $this->options->set('foo1', 'bar'); + $this->options->setNormalizer('foo1', function (Options $options) { + return ''; + }); + $this->options->set('foo2', 'bar'); + $this->options->setNormalizer('foo2', function (Options $options) { + return ''; + }); + + $this->options->replace(array('foo1' => 'new')); + $this->assertEquals(array('foo1' => 'new'), $this->options->all()); + } + + public function testClearOptionAndNormalizer() + { + $this->options->set('foo1', 'bar'); + $this->options->setNormalizer('foo1', function (Options $options) { + return ''; + }); + $this->options->set('foo2', 'bar'); + $this->options->setNormalizer('foo2', function (Options $options) { + return ''; + }); + + $this->options->clear(); + $this->assertEmpty($this->options->all()); + } } From e2a50ef4bc05c0c719d00d1cbbf680a3e8c1bb4a Mon Sep 17 00:00:00 2001 From: Tobias Schultze Date: Mon, 30 Jul 2012 23:35:43 +0200 Subject: [PATCH 009/975] [OptionsResolver] fix normalizer without corresponding option --- src/Symfony/Component/OptionsResolver/Options.php | 2 +- .../Component/OptionsResolver/Tests/OptionsTest.php | 11 +++++++++++ 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/src/Symfony/Component/OptionsResolver/Options.php b/src/Symfony/Component/OptionsResolver/Options.php index 5a2b0f7f381f3..3c1129c9217a9 100644 --- a/src/Symfony/Component/OptionsResolver/Options.php +++ b/src/Symfony/Component/OptionsResolver/Options.php @@ -504,7 +504,7 @@ private function normalize($option) $normalizer = $this->normalizers[$option]; $this->lock[$option] = true; - $this->options[$option] = $normalizer($this, $this->options[$option]); + $this->options[$option] = $normalizer($this, array_key_exists($option, $this->options) ? $this->options[$option] : null); unset($this->lock[$option]); // The option is now normalized diff --git a/src/Symfony/Component/OptionsResolver/Tests/OptionsTest.php b/src/Symfony/Component/OptionsResolver/Tests/OptionsTest.php index 66f9e399a435a..f739c911a1dc6 100644 --- a/src/Symfony/Component/OptionsResolver/Tests/OptionsTest.php +++ b/src/Symfony/Component/OptionsResolver/Tests/OptionsTest.php @@ -514,4 +514,15 @@ public function testClearOptionAndNormalizer() $this->options->clear(); $this->assertEmpty($this->options->all()); } + + public function testNormalizerWithoutCorrespondingOption() + { + $test = $this; + + $this->options->setNormalizer('foo', function (Options $options, $previousValue) use ($test) { + $test->assertNull($previousValue); + return ''; + }); + $this->assertEquals(array('foo' => ''), $this->options->all()); + } } From e271b176b84c314ffd2b09a0b2eac32a25836f58 Mon Sep 17 00:00:00 2001 From: Marcel Beerta Date: Sat, 25 Aug 2012 17:46:58 +0200 Subject: [PATCH 010/975] Remove the string optimization since it causes no real performance gain but increases generation time of the dumped PHP Container --- src/Symfony/Component/DependencyInjection/Dumper/PhpDumper.php | 3 --- .../DependencyInjection/Tests/Fixtures/php/services9.php | 2 +- 2 files changed, 1 insertion(+), 4 deletions(-) diff --git a/src/Symfony/Component/DependencyInjection/Dumper/PhpDumper.php b/src/Symfony/Component/DependencyInjection/Dumper/PhpDumper.php index 4a29d234484c3..639503cc7b513 100644 --- a/src/Symfony/Component/DependencyInjection/Dumper/PhpDumper.php +++ b/src/Symfony/Component/DependencyInjection/Dumper/PhpDumper.php @@ -1049,9 +1049,6 @@ private function dumpValue($value, $interpolate = true) $code = str_replace('%%', '%', preg_replace_callback('/(?get('foo.baz'); - $instance = call_user_func(array('FooClass', 'getInstance'), 'foo', $a, array($this->getParameter('foo') => 'foo is '.$this->getParameter('foo'), 'bar' => $this->getParameter('foo')), true, $this); + $instance = call_user_func(array('FooClass', 'getInstance'), 'foo', $a, array($this->getParameter('foo') => 'foo is '.$this->getParameter('foo').'', 'bar' => $this->getParameter('foo')), true, $this); $instance->setBar($this->get('bar')); $instance->initialize(); From c5e77930043a1e07ec08af6352bfa64e9afced35 Mon Sep 17 00:00:00 2001 From: Romain Neutron Date: Thu, 30 Aug 2012 21:25:16 +0200 Subject: [PATCH 011/975] [Process] Normalize exceptions --- .../Exception/InvalidArgumentException.php | 21 +++++++++++++ .../Process/Exception/LogicException.php | 21 +++++++++++++ .../Exception/ProcessFailedException.php | 2 +- src/Symfony/Component/Process/PhpProcess.php | 4 ++- src/Symfony/Component/Process/Process.php | 31 ++++++++++--------- .../Component/Process/ProcessBuilder.php | 7 +++-- .../Process/Tests/ProcessBuilderTest.php | 2 +- .../Tests/ProcessFailedExceptionTest.php | 3 +- .../Component/Process/Tests/ProcessTest.php | 4 +-- 9 files changed, 72 insertions(+), 23 deletions(-) create mode 100644 src/Symfony/Component/Process/Exception/InvalidArgumentException.php create mode 100644 src/Symfony/Component/Process/Exception/LogicException.php diff --git a/src/Symfony/Component/Process/Exception/InvalidArgumentException.php b/src/Symfony/Component/Process/Exception/InvalidArgumentException.php new file mode 100644 index 0000000000000..926ee2118b037 --- /dev/null +++ b/src/Symfony/Component/Process/Exception/InvalidArgumentException.php @@ -0,0 +1,21 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Process\Exception; + +/** + * InvalidArgumentException for the Process Component. + * + * @author Romain Neutron + */ +class InvalidArgumentException extends \InvalidArgumentException implements ExceptionInterface +{ +} diff --git a/src/Symfony/Component/Process/Exception/LogicException.php b/src/Symfony/Component/Process/Exception/LogicException.php new file mode 100644 index 0000000000000..be3d490dde8cd --- /dev/null +++ b/src/Symfony/Component/Process/Exception/LogicException.php @@ -0,0 +1,21 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Process\Exception; + +/** + * LogicException for the Process Component. + * + * @author Romain Neutron + */ +class LogicException extends \LogicException implements ExceptionInterface +{ +} diff --git a/src/Symfony/Component/Process/Exception/ProcessFailedException.php b/src/Symfony/Component/Process/Exception/ProcessFailedException.php index a4540c065710c..010789ddac41a 100755 --- a/src/Symfony/Component/Process/Exception/ProcessFailedException.php +++ b/src/Symfony/Component/Process/Exception/ProcessFailedException.php @@ -25,7 +25,7 @@ class ProcessFailedException extends RuntimeException public function __construct(Process $process) { if ($process->isSuccessful()) { - throw new \InvalidArgumentException('Expected a failed process, but the given process was successful.'); + throw new InvalidArgumentException('Expected a failed process, but the given process was successful.'); } parent::__construct( diff --git a/src/Symfony/Component/Process/PhpProcess.php b/src/Symfony/Component/Process/PhpProcess.php index 2bd5600451567..956052d421aac 100644 --- a/src/Symfony/Component/Process/PhpProcess.php +++ b/src/Symfony/Component/Process/PhpProcess.php @@ -11,6 +11,8 @@ namespace Symfony\Component\Process; +use Symfony\Component\Process\Exception\RuntimeException; + /** * PhpProcess runs a PHP script in an independent process. * @@ -68,7 +70,7 @@ public function run($callback = null) { if (null === $this->getCommandLine()) { if (false === $php = $this->executableFinder->find()) { - throw new \RuntimeException('Unable to find the PHP executable.'); + throw new RuntimeException('Unable to find the PHP executable.'); } $this->setCommandLine($php); } diff --git a/src/Symfony/Component/Process/Process.php b/src/Symfony/Component/Process/Process.php index cd1e8b42155a2..14d304708541a 100644 --- a/src/Symfony/Component/Process/Process.php +++ b/src/Symfony/Component/Process/Process.php @@ -11,6 +11,9 @@ namespace Symfony\Component\Process; +use Symfony\Component\Process\Exception\InvalidArgumentException; +use Symfony\Component\Process\Exception\RuntimeException; + /** * Process is a thin wrapper around proc_* functions to ease * start independent PHP processes. @@ -111,14 +114,14 @@ class Process * @param integer $timeout The timeout in seconds * @param array $options An array of options for proc_open * - * @throws \RuntimeException When proc_open is not installed + * @throws RuntimeException When proc_open is not installed * * @api */ public function __construct($commandline, $cwd = null, array $env = null, $stdin = null, $timeout = 60, array $options = array()) { if (!function_exists('proc_open')) { - throw new \RuntimeException('The Process class relies on proc_open, which is not available on your PHP installation.'); + throw new RuntimeException('The Process class relies on proc_open, which is not available on your PHP installation.'); } $this->commandline = $commandline; @@ -158,7 +161,7 @@ public function __destruct() * * @return integer The exit status code * - * @throws \RuntimeException When process can't be launch or is stopped + * @throws RuntimeException When process can't be launch or is stopped * * @api */ @@ -187,13 +190,13 @@ public function run($callback = null) * @param Closure|string|array $callback A PHP callback to run whenever there is some * output available on STDOUT or STDERR * - * @throws \RuntimeException When process can't be launch or is stopped - * @throws \RuntimeException When process is already running + * @throws RuntimeException When process can't be launch or is stopped + * @throws RuntimeException When process is already running */ public function start($callback = null) { if ($this->isRunning()) { - throw new \RuntimeException('Process is already running'); + throw new RuntimeException('Process is already running'); } $this->stdout = ''; @@ -233,7 +236,7 @@ public function start($callback = null) $this->process = proc_open($commandline, $descriptors, $this->pipes, $this->cwd, $this->env, $this->options); if (!is_resource($this->process)) { - throw new \RuntimeException('Unable to launch a new process.'); + throw new RuntimeException('Unable to launch a new process.'); } $this->status = self::STATUS_STARTED; @@ -270,7 +273,7 @@ public function start($callback = null) if ($n === 0) { proc_terminate($this->process); - throw new \RuntimeException('The process timed out.'); + throw new RuntimeException('The process timed out.'); } if ($w) { @@ -311,7 +314,7 @@ public function start($callback = null) * * @return int The exitcode of the process * - * @throws \RuntimeException + * @throws RuntimeException */ public function wait($callback = null) { @@ -337,7 +340,7 @@ public function wait($callback = null) if (0 === $n) { proc_terminate($this->process); - throw new \RuntimeException('The process timed out.'); + throw new RuntimeException('The process timed out.'); } foreach ($r as $pipe) { @@ -361,7 +364,7 @@ public function wait($callback = null) } $this->updateStatus(); if ($this->processInformation['signaled']) { - throw new \RuntimeException(sprintf('The process stopped because of a "%s" signal.', $this->processInformation['stopsig'])); + throw new RuntimeException(sprintf('The process stopped because of a "%s" signal.', $this->processInformation['stopsig'])); } $time = 0; @@ -373,7 +376,7 @@ public function wait($callback = null) $exitcode = proc_close($this->process); if ($this->processInformation['signaled']) { - throw new \RuntimeException(sprintf('The process stopped because of a "%s" signal.', $this->processInformation['stopsig'])); + throw new RuntimeException(sprintf('The process stopped because of a "%s" signal.', $this->processInformation['stopsig'])); } $this->exitcode = $this->processInformation['running'] ? $exitcode : $this->processInformation['exitcode']; @@ -546,7 +549,7 @@ public function isRunning() * * @return integer The exitcode of the process * - * @throws \RuntimeException if the process got signaled + * @throws RuntimeException if the process got signaled */ public function stop($timeout=10) { @@ -622,7 +625,7 @@ public function setTimeout($timeout) $timeout = (integer) $timeout; if ($timeout < 0) { - throw new \InvalidArgumentException('The timeout value must be a valid positive integer.'); + throw new InvalidArgumentException('The timeout value must be a valid positive integer.'); } $this->timeout = $timeout; diff --git a/src/Symfony/Component/Process/ProcessBuilder.php b/src/Symfony/Component/Process/ProcessBuilder.php index 2ffb3af5ffb98..2a88ea00d4bab 100644 --- a/src/Symfony/Component/Process/ProcessBuilder.php +++ b/src/Symfony/Component/Process/ProcessBuilder.php @@ -11,6 +11,9 @@ namespace Symfony\Component\Process; +use Symfony\Component\Process\Exception\InvalidArgumentException; +use Symfony\Component\Process\Exception\LogicException; + /** * Process builder. * @@ -99,7 +102,7 @@ public function setTimeout($timeout) $timeout = (integer) $timeout; if ($timeout < 0) { - throw new \InvalidArgumentException('The timeout value must be a valid positive integer.'); + throw new InvalidArgumentException('The timeout value must be a valid positive integer.'); } $this->timeout = $timeout; @@ -117,7 +120,7 @@ public function setOption($name, $value) public function getProcess() { if (!count($this->arguments)) { - throw new \LogicException('You must add() command arguments before calling getProcess().'); + throw new LogicException('You must add() command arguments before calling getProcess().'); } $options = $this->options; diff --git a/src/Symfony/Component/Process/Tests/ProcessBuilderTest.php b/src/Symfony/Component/Process/Tests/ProcessBuilderTest.php index 9ca45a80a7905..4f6157e46e7ff 100644 --- a/src/Symfony/Component/Process/Tests/ProcessBuilderTest.php +++ b/src/Symfony/Component/Process/Tests/ProcessBuilderTest.php @@ -85,7 +85,7 @@ public function shouldNotReplaceExplicitlySetVars() } /** - * @expectedException \InvalidArgumentException + * @expectedException Symfony\Component\Process\Exception\InvalidArgumentException */ public function testNegativeTimeoutFromSetter() { diff --git a/src/Symfony/Component/Process/Tests/ProcessFailedExceptionTest.php b/src/Symfony/Component/Process/Tests/ProcessFailedExceptionTest.php index 356c7debaa02b..9bc2fdf30fa58 100644 --- a/src/Symfony/Component/Process/Tests/ProcessFailedExceptionTest.php +++ b/src/Symfony/Component/Process/Tests/ProcessFailedExceptionTest.php @@ -11,8 +11,7 @@ namespace Symfony\Component\Process\Tests; -use Symfony\Component\Process\Process, - Symfony\Component\Process\Exception\ProcessFailedException; +use Symfony\Component\Process\Exception\ProcessFailedException; /** * @author Sebastian Marek diff --git a/src/Symfony/Component/Process/Tests/ProcessTest.php b/src/Symfony/Component/Process/Tests/ProcessTest.php index 64f929cc20d61..da04712f84190 100644 --- a/src/Symfony/Component/Process/Tests/ProcessTest.php +++ b/src/Symfony/Component/Process/Tests/ProcessTest.php @@ -19,7 +19,7 @@ class ProcessTest extends \PHPUnit_Framework_TestCase { /** - * @expectedException \InvalidArgumentException + * @expectedException Symfony\Component\Process\Exception\InvalidArgumentException */ public function testNegativeTimeoutFromConstructor() { @@ -27,7 +27,7 @@ public function testNegativeTimeoutFromConstructor() } /** - * @expectedException \InvalidArgumentException + * @expectedException Symfony\Component\Process\Exception\InvalidArgumentException */ public function testNegativeTimeoutFromSetter() { From bcd8db2a344f279ce80700901249aa858c0de79e Mon Sep 17 00:00:00 2001 From: Romain Neutron Date: Thu, 30 Aug 2012 21:32:42 +0200 Subject: [PATCH 012/975] [DependencyInjection] Normalize exceptions --- .../Component/DependencyInjection/Loader/XmlFileLoader.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/Symfony/Component/DependencyInjection/Loader/XmlFileLoader.php b/src/Symfony/Component/DependencyInjection/Loader/XmlFileLoader.php index 5329195cdb8a2..e32e787dd1807 100644 --- a/src/Symfony/Component/DependencyInjection/Loader/XmlFileLoader.php +++ b/src/Symfony/Component/DependencyInjection/Loader/XmlFileLoader.php @@ -11,13 +11,13 @@ namespace Symfony\Component\DependencyInjection\Loader; +use Symfony\Component\Config\Resource\FileResource; use Symfony\Component\DependencyInjection\DefinitionDecorator; use Symfony\Component\DependencyInjection\ContainerInterface; use Symfony\Component\DependencyInjection\Alias; use Symfony\Component\DependencyInjection\Definition; use Symfony\Component\DependencyInjection\Reference; use Symfony\Component\DependencyInjection\SimpleXMLElement; -use Symfony\Component\Config\Resource\FileResource; use Symfony\Component\DependencyInjection\Exception\InvalidArgumentException; use Symfony\Component\DependencyInjection\Exception\RuntimeException; @@ -213,7 +213,7 @@ private function parseFile($file) if (!$dom->loadXML(file_get_contents($file), LIBXML_NONET | (defined('LIBXML_COMPACT') ? LIBXML_COMPACT : 0))) { libxml_disable_entity_loader($disableEntities); - throw new \InvalidArgumentException(implode("\n", $this->getXmlErrors($internalErrors))); + throw new InvalidArgumentException(implode("\n", $this->getXmlErrors($internalErrors))); } $dom->normalizeDocument(); @@ -222,7 +222,7 @@ private function parseFile($file) foreach ($dom->childNodes as $child) { if ($child->nodeType === XML_DOCUMENT_TYPE_NODE) { - throw new \InvalidArgumentException('Document types are not allowed.'); + throw new InvalidArgumentException('Document types are not allowed.'); } } From b0f5f2e7f27b1e71ec9393e32079a87df6ac0ac7 Mon Sep 17 00:00:00 2001 From: Romain Neutron Date: Thu, 30 Aug 2012 21:37:05 +0200 Subject: [PATCH 013/975] [Serializer] Normalize exceptions --- .../Serializer/Normalizer/GetSetMethodNormalizer.php | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/Symfony/Component/Serializer/Normalizer/GetSetMethodNormalizer.php b/src/Symfony/Component/Serializer/Normalizer/GetSetMethodNormalizer.php index 4dfe1770e5787..dab97fe658a76 100644 --- a/src/Symfony/Component/Serializer/Normalizer/GetSetMethodNormalizer.php +++ b/src/Symfony/Component/Serializer/Normalizer/GetSetMethodNormalizer.php @@ -11,6 +11,7 @@ namespace Symfony\Component\Serializer\Normalizer; +use Symfony\Component\Serializer\Exception\InvalidArgumentException; use Symfony\Component\Serializer\Exception\RuntimeException; /** @@ -42,12 +43,14 @@ class GetSetMethodNormalizer extends SerializerAwareNormalizer implements Normal * Set normalization callbacks * * @param array $callbacks help normalize the result + * + * @throws InvalidArgumentException if a non-callable callback is set */ public function setCallbacks(array $callbacks) { foreach ($callbacks as $attribute => $callback) { if (!is_callable($callback)) { - throw new \InvalidArgumentException(sprintf('The given callback for attribute "%s" is not callable.', $attribute)); + throw new InvalidArgumentException(sprintf('The given callback for attribute "%s" is not callable.', $attribute)); } } $this->callbacks = $callbacks; From f2e4802565ba03558a02b898bb4520bce4845c54 Mon Sep 17 00:00:00 2001 From: Romain Neutron Date: Thu, 30 Aug 2012 21:54:08 +0200 Subject: [PATCH 014/975] [Yaml] Normalize exceptions --- .../Yaml/Exception/DumpException.php | 2 +- .../Yaml/Exception/ParseException.php | 2 +- .../Yaml/Exception/RuntimeException.php | 23 +++++++++++++++++++ src/Symfony/Component/Yaml/Unescaper.php | 4 ++-- 4 files changed, 27 insertions(+), 4 deletions(-) create mode 100644 src/Symfony/Component/Yaml/Exception/RuntimeException.php diff --git a/src/Symfony/Component/Yaml/Exception/DumpException.php b/src/Symfony/Component/Yaml/Exception/DumpException.php index 53952ce1adfd1..9b3e6de079588 100644 --- a/src/Symfony/Component/Yaml/Exception/DumpException.php +++ b/src/Symfony/Component/Yaml/Exception/DumpException.php @@ -18,6 +18,6 @@ * * @api */ -class DumpException extends \RuntimeException implements ExceptionInterface +class DumpException extends RuntimeException { } diff --git a/src/Symfony/Component/Yaml/Exception/ParseException.php b/src/Symfony/Component/Yaml/Exception/ParseException.php index 975fe6d46eb7d..a27a005e6f551 100644 --- a/src/Symfony/Component/Yaml/Exception/ParseException.php +++ b/src/Symfony/Component/Yaml/Exception/ParseException.php @@ -18,7 +18,7 @@ * * @api */ -class ParseException extends \RuntimeException implements ExceptionInterface +class ParseException extends RuntimeException { private $parsedFile; private $parsedLine; diff --git a/src/Symfony/Component/Yaml/Exception/RuntimeException.php b/src/Symfony/Component/Yaml/Exception/RuntimeException.php new file mode 100644 index 0000000000000..3573bf15abb81 --- /dev/null +++ b/src/Symfony/Component/Yaml/Exception/RuntimeException.php @@ -0,0 +1,23 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Yaml\Exception; + +/** + * Exception class thrown when an error occurs during parsing. + * + * @author Romain Neutron + * + * @api + */ +class RuntimeException extends \RuntimeException implements ExceptionInterface +{ +} diff --git a/src/Symfony/Component/Yaml/Unescaper.php b/src/Symfony/Component/Yaml/Unescaper.php index ac3a576b677bc..708f2a18f2851 100644 --- a/src/Symfony/Component/Yaml/Unescaper.php +++ b/src/Symfony/Component/Yaml/Unescaper.php @@ -130,7 +130,7 @@ public function unescapeCharacter($value) * * @return string The string with the new encoding * - * @throws \RuntimeException if no suitable encoding function is found (iconv or mbstring) + * @throws RuntimeException if no suitable encoding function is found (iconv or mbstring) */ private function convertEncoding($value, $to, $from) { @@ -140,6 +140,6 @@ private function convertEncoding($value, $to, $from) return iconv($from, $to, $value); } - throw new \RuntimeException('No suitable convert encoding function (install the iconv or mbstring extension).'); + throw new RuntimeException('No suitable convert encoding function (install the iconv or mbstring extension).'); } } From 4efb9fec500247a7aab5860bd04bd912926a67c8 Mon Sep 17 00:00:00 2001 From: Tobias Schultze Date: Sat, 18 Aug 2012 14:43:48 +0300 Subject: [PATCH 015/975] [Form] Remove unneeded FormUtil constants MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit They are part of the public API (as const are always public) but cannot be used at all from outside the class as the$pluralMap is private. The meaning of the indices is already documented in the array. --- src/Symfony/Component/Form/Util/FormUtil.php | 22 +++++++------------- 1 file changed, 7 insertions(+), 15 deletions(-) diff --git a/src/Symfony/Component/Form/Util/FormUtil.php b/src/Symfony/Component/Form/Util/FormUtil.php index 614361c49b369..b4048f76a6ca7 100644 --- a/src/Symfony/Component/Form/Util/FormUtil.php +++ b/src/Symfony/Component/Form/Util/FormUtil.php @@ -16,16 +16,6 @@ */ abstract class FormUtil { - const PLURAL_SUFFIX = 0; - - const PLURAL_SUFFIX_LENGTH = 1; - - const PLURAL_SUFFIX_AFTER_VOCAL = 2; - - const PLURAL_SUFFIX_AFTER_CONS = 3; - - const SINGULAR_SUFFIX = 4; - /** * Map english plural to singular suffixes * @@ -128,8 +118,8 @@ public static function singularify($plural) // in the plural table to compare them with the characters of the actual // given plural suffix for ($i = 0, $numPlurals = count(self::$pluralMap); $i < $numPlurals; ++$i) { - $suffix = self::$pluralMap[$i][self::PLURAL_SUFFIX]; - $suffixLength = self::$pluralMap[$i][self::PLURAL_SUFFIX_LENGTH]; + $suffix = self::$pluralMap[$i][0]; + $suffixLength = self::$pluralMap[$i][1]; $j = 0; // Compare characters in the plural table and of the suffix of the @@ -145,17 +135,19 @@ public static function singularify($plural) if ($j < $pluralLength) { $nextIsVocal = false !== strpos('aeiou', $lowerPluralRev[$j]); - if (!self::$pluralMap[$i][self::PLURAL_SUFFIX_AFTER_VOCAL] && $nextIsVocal) { + if (!self::$pluralMap[$i][2] && $nextIsVocal) { + // suffix may not succeed a vocal but next char is one break; } - if (!self::$pluralMap[$i][self::PLURAL_SUFFIX_AFTER_CONS] && !$nextIsVocal) { + if (!self::$pluralMap[$i][3] && !$nextIsVocal) { + // suffix may not succeed a consonant but next char is one break; } } $newBase = substr($plural, 0, $pluralLength - $suffixLength); - $newSuffix = self::$pluralMap[$i][self::SINGULAR_SUFFIX]; + $newSuffix = self::$pluralMap[$i][4]; // Check whether the first character in the plural suffix // is uppercased. If yes, uppercase the first character in From 0f86a33b610c8fd97c468ba11ecca131476ff395 Mon Sep 17 00:00:00 2001 From: Tobias Schultze Date: Sat, 18 Aug 2012 17:12:41 +0200 Subject: [PATCH 016/975] micro-optim: replace for with foreach --- src/Symfony/Component/Form/Util/FormUtil.php | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/Symfony/Component/Form/Util/FormUtil.php b/src/Symfony/Component/Form/Util/FormUtil.php index b4048f76a6ca7..5e8d461698ff1 100644 --- a/src/Symfony/Component/Form/Util/FormUtil.php +++ b/src/Symfony/Component/Form/Util/FormUtil.php @@ -113,13 +113,13 @@ public static function singularify($plural) $lowerPluralRev = strtolower($pluralRev); $pluralLength = strlen($lowerPluralRev); - // The outer loop $i iterates over the entries of the plural table + // The outer loop iterates over the entries of the plural table // The inner loop $j iterates over the characters of the plural suffix // in the plural table to compare them with the characters of the actual // given plural suffix - for ($i = 0, $numPlurals = count(self::$pluralMap); $i < $numPlurals; ++$i) { - $suffix = self::$pluralMap[$i][0]; - $suffixLength = self::$pluralMap[$i][1]; + foreach (self::$pluralMap as $map) { + $suffix = $map[0]; + $suffixLength = $map[1]; $j = 0; // Compare characters in the plural table and of the suffix of the @@ -135,19 +135,19 @@ public static function singularify($plural) if ($j < $pluralLength) { $nextIsVocal = false !== strpos('aeiou', $lowerPluralRev[$j]); - if (!self::$pluralMap[$i][2] && $nextIsVocal) { + if (!$map[2] && $nextIsVocal) { // suffix may not succeed a vocal but next char is one break; } - if (!self::$pluralMap[$i][3] && !$nextIsVocal) { + if (!$map[3] && !$nextIsVocal) { // suffix may not succeed a consonant but next char is one break; } } $newBase = substr($plural, 0, $pluralLength - $suffixLength); - $newSuffix = self::$pluralMap[$i][4]; + $newSuffix = $map[4]; // Check whether the first character in the plural suffix // is uppercased. If yes, uppercase the first character in From 1f5b7930c03b899e322383b14bb87b95333603bd Mon Sep 17 00:00:00 2001 From: Tobias Schultze Date: Tue, 4 Sep 2012 06:31:46 +0200 Subject: [PATCH 017/975] [Routing] fix setting empty requirement in Route --- src/Symfony/Component/Routing/Route.php | 22 ++++++++++--------- .../Component/Routing/Tests/RouteTest.php | 5 ++++- 2 files changed, 16 insertions(+), 11 deletions(-) diff --git a/src/Symfony/Component/Routing/Route.php b/src/Symfony/Component/Routing/Route.php index 318426a0db09c..fd9d90dc95444 100644 --- a/src/Symfony/Component/Routing/Route.php +++ b/src/Symfony/Component/Routing/Route.php @@ -179,7 +179,7 @@ public function setOption($name, $value) * * @param string $name An option name * - * @return mixed The option value + * @return mixed The option value or null when not given */ public function getOption($name) { @@ -236,7 +236,7 @@ public function addDefaults(array $defaults) * * @param string $name A variable name * - * @return mixed The default value + * @return mixed The default value or null when not given */ public function getDefault($name) { @@ -323,7 +323,7 @@ public function addRequirements(array $requirements) * * @param string $key The key * - * @return string The regex + * @return string|null The regex or null when not given */ public function getRequirement($key) { @@ -352,6 +352,8 @@ public function setRequirement($key, $regex) * Compiles the route. * * @return CompiledRoute A CompiledRoute instance + * + * @see RouteCompiler which is responsible for the compilation process */ public function compile() { @@ -371,21 +373,21 @@ public function compile() private function sanitizeRequirement($key, $regex) { if (!is_string($regex)) { - throw new \InvalidArgumentException(sprintf('Routing requirement for "%s" must be a string', $key)); - } - - if ('' === $regex) { - throw new \InvalidArgumentException(sprintf('Routing requirement for "%s" cannot be empty', $key)); + throw new \InvalidArgumentException(sprintf('Routing requirement for "%s" must be a string.', $key)); } - if ('^' === $regex[0]) { - $regex = substr($regex, 1); + if ('' !== $regex && '^' === $regex[0]) { + $regex = (string) substr($regex, 1); // returns false for a single character } if ('$' === substr($regex, -1)) { $regex = substr($regex, 0, -1); } + if ('' === $regex) { + throw new \InvalidArgumentException(sprintf('Routing requirement for "%s" cannot be empty.', $key)); + } + return $regex; } } diff --git a/src/Symfony/Component/Routing/Tests/RouteTest.php b/src/Symfony/Component/Routing/Tests/RouteTest.php index 8e466826dae35..8a42b724f8898 100644 --- a/src/Symfony/Component/Routing/Tests/RouteTest.php +++ b/src/Symfony/Component/Routing/Tests/RouteTest.php @@ -112,7 +112,10 @@ public function getInvalidRequirements() { return array( array(''), - array(array()) + array(array()), + array('^$'), + array('^'), + array('$') ); } From be28e56f4e1646675d07af8163b069f29ce00f06 Mon Sep 17 00:00:00 2001 From: Tobias Schultze Date: Tue, 4 Sep 2012 07:10:18 +0200 Subject: [PATCH 018/975] [Routing] disallow numeric named variables in pattern because PHP raises an error for such subpatterns in PCRE and thus would break matching, e.g. '(?<123>.+)'. --- .../Component/Routing/RouteCompiler.php | 9 +++++++-- .../Routing/Tests/RouteCompilerTest.php | 19 +++++++++++++++++++ 2 files changed, 26 insertions(+), 2 deletions(-) diff --git a/src/Symfony/Component/Routing/RouteCompiler.php b/src/Symfony/Component/Routing/RouteCompiler.php index e19f8d50d566b..76877bc14b85d 100644 --- a/src/Symfony/Component/Routing/RouteCompiler.php +++ b/src/Symfony/Component/Routing/RouteCompiler.php @@ -23,8 +23,10 @@ class RouteCompiler implements RouteCompilerInterface /** * {@inheritDoc} * - * @throws \LogicException If a variable is referenced more than once or if a required variable - * has a default value that doesn't meet its own requirement. + * @throws \LogicException If a variable is referenced more than once or if a required variable + * has a default value that doesn't meet its own requirement. + * @throws \DomainException If a variable name is numeric because PHP raises an error for such + * subpatterns in PCRE and thus would break matching, e.g. "(?<123>.+)". */ public function compile(Route $route) { @@ -57,6 +59,9 @@ public function compile(Route $route) $tokens[] = array('variable', $match[0][0][0], $regexp, $var); + if (is_numeric($var)) { + throw new \DomainException(sprintf('Variable name "%s" cannot be numeric in route pattern "%s". Please use a different name.', $var, $route->getPattern())); + } if (in_array($var, $variables)) { throw new \LogicException(sprintf('Route pattern "%s" cannot reference variable name "%s" more than once.', $route->getPattern(), $var)); } diff --git a/src/Symfony/Component/Routing/Tests/RouteCompilerTest.php b/src/Symfony/Component/Routing/Tests/RouteCompilerTest.php index 4a32387fd0eb0..fee2ae1304888 100644 --- a/src/Symfony/Component/Routing/Tests/RouteCompilerTest.php +++ b/src/Symfony/Component/Routing/Tests/RouteCompilerTest.php @@ -144,4 +144,23 @@ public function testRouteWithRequiredVariableAndBadDefault() // irrelevant for both matching and generating URLs. $route->compile(); } + + /** + * @dataProvider getNumericVariableNames + * @expectedException \DomainException + */ + public function testRouteWithNumericVariableName($name) + { + $route = new Route('/{'. $name . '}'); + $route->compile(); + } + + public function getNumericVariableNames() + { + return array( + array('09'), + array('123'), + array('1e2') + ); + } } From 02516de6521b3806b3708d6f0d1c8fe8be05f3a2 Mon Sep 17 00:00:00 2001 From: Tobias Schultze Date: Tue, 4 Sep 2012 07:18:13 +0200 Subject: [PATCH 019/975] [Routing] fix variable with a requirement of '0' --- src/Symfony/Component/Routing/RouteCompiler.php | 2 +- src/Symfony/Component/Routing/Tests/RouteCompilerTest.php | 7 +++++++ 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/src/Symfony/Component/Routing/RouteCompiler.php b/src/Symfony/Component/Routing/RouteCompiler.php index e19f8d50d566b..7dcae85f10d8f 100644 --- a/src/Symfony/Component/Routing/RouteCompiler.php +++ b/src/Symfony/Component/Routing/RouteCompiler.php @@ -42,7 +42,7 @@ public function compile(Route $route) $pos = $match[0][1] + strlen($match[0][0]); $var = $match[1][0]; - if ($req = $route->getRequirement($var)) { + if (null !== $req = $route->getRequirement($var)) { $regexp = $req; } else { // Use the character preceding the variable as a separator diff --git a/src/Symfony/Component/Routing/Tests/RouteCompilerTest.php b/src/Symfony/Component/Routing/Tests/RouteCompilerTest.php index 4a32387fd0eb0..d871a05bd9ba4 100644 --- a/src/Symfony/Component/Routing/Tests/RouteCompilerTest.php +++ b/src/Symfony/Component/Routing/Tests/RouteCompilerTest.php @@ -90,6 +90,13 @@ public function provideCompileData() array('variable', '/', '[^/]+', 'bar'), )), + array( + 'Route with a requirement of 0', + array('/{bar}', array('bar' => null), array('bar' => '0')), + '', '#^/(?0)?$#s', array('bar'), array( + array('variable', '/', '0', 'bar'), + )), + array( 'Route with an optional variable as the first segment with requirements', array('/{bar}', array('bar' => 'bar'), array('bar' => '(foo|bar)')), From 9bc8f659bd4509ed70e7062805a0bc0a5cbe5ff0 Mon Sep 17 00:00:00 2001 From: Michal Piotrowski Date: Tue, 4 Sep 2012 18:27:42 +0200 Subject: [PATCH 020/975] Cookie tests --- .../HttpFoundation/Tests/CookieTest.php | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/src/Symfony/Component/HttpFoundation/Tests/CookieTest.php b/src/Symfony/Component/HttpFoundation/Tests/CookieTest.php index 6a9948d62ab2d..721cc3cd9e77f 100644 --- a/src/Symfony/Component/HttpFoundation/Tests/CookieTest.php +++ b/src/Symfony/Component/HttpFoundation/Tests/CookieTest.php @@ -79,6 +79,23 @@ public function testGetExpiresTime() $this->assertEquals(3600, $cookie->getExpiresTime(), '->getExpiresTime() returns the expire date'); } + public function testConstructorWithDateTime() + { + $expire = new \DateTime(); + $cookie = new Cookie('foo', 'bar', $expire); + + $this->assertEquals($expire->format('U'), $cookie->getExpiresTime(), '->getExpiresTime() returns the expire date'); + } + + public function testGetExpiresTimeWithStringValue() + { + $value = "+1 day"; + $cookie = new Cookie('foo', 'bar', $value); + $expire = strtotime($value); + + $this->assertEquals($expire, $cookie->getExpiresTime(), '->getExpiresTime() returns the expire date'); + } + public function testGetDomain() { $cookie = new Cookie('foo', 'bar', 3600, '/', '.myfoodomain.com'); From 8f467956c86df5363cbc67acfdcb96a2191e789a Mon Sep 17 00:00:00 2001 From: Michal Piotrowski Date: Tue, 4 Sep 2012 20:36:25 +0200 Subject: [PATCH 021/975] tests for HeaderBag --- .../HttpFoundation/Tests/HeaderBagTest.php | 43 +++++++++++++++++++ 1 file changed, 43 insertions(+) diff --git a/src/Symfony/Component/HttpFoundation/Tests/HeaderBagTest.php b/src/Symfony/Component/HttpFoundation/Tests/HeaderBagTest.php index bafccb2eba253..20d3603038cad 100644 --- a/src/Symfony/Component/HttpFoundation/Tests/HeaderBagTest.php +++ b/src/Symfony/Component/HttpFoundation/Tests/HeaderBagTest.php @@ -24,6 +24,49 @@ public function testConstructor() $this->assertTrue($bag->has('foo')); } + public function testToStringNull() + { + $bag = new HeaderBag(); + $this->assertEquals('', $bag->__toString()); + } + + public function testToStringNotNull() + { + $bag = new HeaderBag(array('foo' => 'bar')); + $this->assertEquals("Foo: bar\r\n", $bag->__toString()); + } + + public function testKeys() + { + $bag = new HeaderBag(array('foo' => 'bar')); + $keys = $bag->keys(); + $this->assertEquals("foo", $keys[0]); + } + + public function testGetDate() + { + $bag = new HeaderBag(array('foo' => 'Tue, 4 Sep 2012 20:00:00 +0200')); + $headerDate = $bag->getDate('foo'); + $this->assertInstanceOf('DateTime', $headerDate); + } + + /** + * @expectedException \RuntimeException + */ + public function testGetDateException() + { + $bag = new HeaderBag(array('foo' => 'Tue')); + $headerDate = $bag->getDate('foo'); + } + + public function testGetCacheControlHeader() + { + $bag = new HeaderBag(); + $bag->addCacheControlDirective('public', '#a'); + $this->assertTrue($bag->hasCacheControlDirective('public')); + $this->assertEquals('#a', $bag->getCacheControlDirective('public')); + } + /** * @covers Symfony\Component\HttpFoundation\HeaderBag::all */ From 7c5cfeb77603f56c0ae529e9d1430808979c8183 Mon Sep 17 00:00:00 2001 From: Tobias Schultze Date: Wed, 5 Sep 2012 06:36:05 +0200 Subject: [PATCH 022/975] [Routing] added test why #5238 is not that easy --- .../Component/Routing/Tests/Matcher/UrlMatcherTest.php | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/Symfony/Component/Routing/Tests/Matcher/UrlMatcherTest.php b/src/Symfony/Component/Routing/Tests/Matcher/UrlMatcherTest.php index 31069b2af7f11..eb18e5068dfeb 100644 --- a/src/Symfony/Component/Routing/Tests/Matcher/UrlMatcherTest.php +++ b/src/Symfony/Component/Routing/Tests/Matcher/UrlMatcherTest.php @@ -214,6 +214,15 @@ public function testMatchRegression() } } + public function testDefaultRequirementForOptionalVariables() + { + $coll = new RouteCollection(); + $coll->add('test', new Route('/{page}.{_format}', array('page' => 'index', '_format' => 'html'))); + + $matcher = new UrlMatcher($coll, new RequestContext()); + $this->assertEquals(array('page' => 'my-page', '_format' => 'xml', '_route' => 'test'), $matcher->match('/my-page.xml')); + } + public function testMatchingIsEager() { $coll = new RouteCollection(); From cba2a31e3631ab9043389f8f7df873da0e6c8f47 Mon Sep 17 00:00:00 2001 From: Fabien Potencier Date: Thu, 6 Sep 2012 12:12:45 +0200 Subject: [PATCH 023/975] bumped Symfony version to 2.2.0-DEV --- src/Symfony/Component/HttpKernel/Kernel.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/Symfony/Component/HttpKernel/Kernel.php b/src/Symfony/Component/HttpKernel/Kernel.php index 366d216d4a665..6a695c5f487b4 100644 --- a/src/Symfony/Component/HttpKernel/Kernel.php +++ b/src/Symfony/Component/HttpKernel/Kernel.php @@ -58,12 +58,12 @@ abstract class Kernel implements KernelInterface, TerminableInterface protected $classes; protected $errorReportingLevel; - const VERSION = '2.1.0'; + const VERSION = '2.2.0-DEV'; const VERSION_ID = '20100'; const MAJOR_VERSION = '2'; - const MINOR_VERSION = '1'; + const MINOR_VERSION = '2'; const RELEASE_VERSION = '0'; - const EXTRA_VERSION = ''; + const EXTRA_VERSION = 'DEV'; /** * Constructor. From 16c1b015318b36cd5ee37355895acbd77f847068 Mon Sep 17 00:00:00 2001 From: Tobias Schultze Date: Sun, 5 Aug 2012 05:35:48 +0200 Subject: [PATCH 024/975] [Routing] fixed 4 bugs in the UrlGenerator --- .../Routing/Generator/UrlGenerator.php | 42 ++++++++---------- .../Tests/Generator/UrlGeneratorTest.php | 43 +++++++++++++++++-- 2 files changed, 58 insertions(+), 27 deletions(-) diff --git a/src/Symfony/Component/Routing/Generator/UrlGenerator.php b/src/Symfony/Component/Routing/Generator/UrlGenerator.php index 18edd160dd597..307b5a588f842 100644 --- a/src/Symfony/Component/Routing/Generator/UrlGenerator.php +++ b/src/Symfony/Component/Routing/Generator/UrlGenerator.php @@ -23,6 +23,7 @@ * UrlGenerator generates a URL based on a set of routes. * * @author Fabien Potencier + * @author Tobias Schultze * * @api */ @@ -132,13 +133,10 @@ public function generate($name, $parameters = array(), $absolute = false) protected function doGenerate($variables, $defaults, $requirements, $tokens, $parameters, $name, $absolute) { $variables = array_flip($variables); - - $originParameters = $parameters; - $parameters = array_replace($this->context->getParameters(), $parameters); - $tparams = array_replace($defaults, $parameters); + $mergedParams = array_replace($this->context->getParameters(), $defaults, $parameters); // all params must be given - if ($diff = array_diff_key($variables, $tparams)) { + if ($diff = array_diff_key($variables, $mergedParams)) { throw new MissingMandatoryParametersException(sprintf('The "%s" route has some missing mandatory parameters ("%s").', $name, implode('", "', array_keys($diff)))); } @@ -146,30 +144,26 @@ protected function doGenerate($variables, $defaults, $requirements, $tokens, $pa $optional = true; foreach ($tokens as $token) { if ('variable' === $token[0]) { - if (false === $optional || !array_key_exists($token[3], $defaults) || (isset($parameters[$token[3]]) && (string) $parameters[$token[3]] != (string) $defaults[$token[3]])) { - if (!$isEmpty = in_array($tparams[$token[3]], array(null, '', false), true)) { - // check requirement - if ($tparams[$token[3]] && !preg_match('#^'.$token[2].'$#', $tparams[$token[3]])) { - $message = sprintf('Parameter "%s" for route "%s" must match "%s" ("%s" given).', $token[3], $name, $token[2], $tparams[$token[3]]); - if ($this->strictRequirements) { - throw new InvalidParameterException($message); - } - - if ($this->logger) { - $this->logger->err($message); - } - - return null; + if (!$optional || !array_key_exists($token[3], $defaults) || (string) $mergedParams[$token[3]] !== (string) $defaults[$token[3]]) { + // check requirement + if (!preg_match('#^'.$token[2].'$#', $mergedParams[$token[3]])) { + $message = sprintf('Parameter "%s" for route "%s" must match "%s" ("%s" given).', $token[3], $name, $token[2], $mergedParams[$token[3]]); + if ($this->strictRequirements) { + throw new InvalidParameterException($message); + } + + if ($this->logger) { + $this->logger->err($message); } - } - if (!$isEmpty || !$optional) { - $url = $token[1].$tparams[$token[3]].$url; + return null; } + $url = $token[1].$mergedParams[$token[3]].$url; $optional = false; } - } elseif ('text' === $token[0]) { + } else { + // static text $url = $token[1].$url; $optional = false; } @@ -193,7 +187,7 @@ protected function doGenerate($variables, $defaults, $requirements, $tokens, $pa } // add a query string if needed - $extra = array_diff_key($originParameters, $variables, $defaults); + $extra = array_diff_key($parameters, $variables); if ($extra && $query = http_build_query($extra, '', '&')) { $url .= '?'.$query; } diff --git a/src/Symfony/Component/Routing/Tests/Generator/UrlGeneratorTest.php b/src/Symfony/Component/Routing/Tests/Generator/UrlGeneratorTest.php index f001067a5392f..236015f976c57 100644 --- a/src/Symfony/Component/Routing/Tests/Generator/UrlGeneratorTest.php +++ b/src/Symfony/Component/Routing/Tests/Generator/UrlGeneratorTest.php @@ -74,12 +74,15 @@ public function testRelativeUrlWithNullParameter() $this->assertEquals('/app.php/testing', $url); } + /** + * @expectedException Symfony\Component\Routing\Exception\InvalidParameterException + */ public function testRelativeUrlWithNullParameterButNotOptional() { $routes = $this->getRoutes('test', new Route('/testing/{foo}/bar', array('foo' => null))); - $url = $this->getGenerator($routes)->generate('test', array(), false); - - $this->assertEquals('/app.php/testing//bar', $url); + // This must raise an exception because the default requirement for "foo" is "[^/]+" which is not met with these params. + // Generating path "/testing//bar" would be wrong as matching this route would fail. + $this->getGenerator($routes)->generate('test', array(), false); } public function testRelativeUrlWithOptionalZeroParameter() @@ -90,6 +93,13 @@ public function testRelativeUrlWithOptionalZeroParameter() $this->assertEquals('/app.php/testing/0', $url); } + public function testNotPassedOptionalParameterInBetween() + { + $routes = $this->getRoutes('test', new Route('/{slug}/{page}', array('slug' => 'index', 'page' => 0))); + $this->assertSame('/app.php/index/1', $this->getGenerator($routes)->generate('test', array('page' => 1))); + $this->assertSame('/app.php/', $this->getGenerator($routes)->generate('test')); + } + public function testRelativeUrlWithExtraParameters() { $routes = $this->getRoutes('test', new Route('/testing')); @@ -165,6 +175,15 @@ public function testGenerateForRouteWithInvalidOptionalParameter() $this->getGenerator($routes)->generate('test', array('foo' => 'bar'), true); } + /** + * @expectedException Symfony\Component\Routing\Exception\InvalidParameterException + */ + public function testGenerateForRouteWithInvalidParameter() + { + $routes = $this->getRoutes('test', new Route('/testing/{foo}', array(), array('foo' => '1|2'))); + $this->getGenerator($routes)->generate('test', array('foo' => '0'), true); + } + public function testGenerateForRouteWithInvalidOptionalParameterNonStrict() { $routes = $this->getRoutes('test', new Route('/testing/{foo}', array('foo' => '1'), array('foo' => 'd+'))); @@ -196,6 +215,15 @@ public function testGenerateForRouteWithInvalidMandatoryParameter() $routes = $this->getRoutes('test', new Route('/testing/{foo}', array(), array('foo' => 'd+'))); $this->getGenerator($routes)->generate('test', array('foo' => 'bar'), true); } + + /** + * @expectedException Symfony\Component\Routing\Exception\InvalidParameterException + */ + public function testRequiredParamAndEmptyPassed() + { + $routes = $this->getRoutes('test', new Route('/{slug}', array(), array('slug' => '.+'))); + $this->getGenerator($routes)->generate('test', array('slug' => '')); + } public function testSchemeRequirementDoesNothingIfSameCurrentScheme() { @@ -229,6 +257,15 @@ public function testWithAnIntegerAsADefaultValue() $this->assertEquals('/app.php/foo', $this->getGenerator($routes)->generate('test', array('default' => 'foo'))); } + public function testQueryParamSameAsDefault() + { + $routes = $this->getRoutes('test', new Route('/test', array('default' => 'value'))); + + $this->assertSame('/app.php/test?default=foo', $this->getGenerator($routes)->generate('test', array('default' => 'foo'))); + $this->assertSame('/app.php/test?default=value', $this->getGenerator($routes)->generate('test', array('default' => 'value'))); + $this->assertSame('/app.php/test', $this->getGenerator($routes)->generate('test')); + } + public function testUrlEncoding() { // This tests the encoding of reserved characters that are used for delimiting of URI components (defined in RFC 3986) From 4dc197c3e1ea227e36cab7ea93877fa44ecc569b Mon Sep 17 00:00:00 2001 From: Fabien Potencier Date: Thu, 6 Sep 2012 20:45:30 +0200 Subject: [PATCH 025/975] udpated composer.json to 2.2 --- composer.json | 2 +- src/Symfony/Bridge/Doctrine/composer.json | 2 +- src/Symfony/Bridge/Monolog/composer.json | 2 +- src/Symfony/Bridge/Propel1/composer.json | 2 +- src/Symfony/Bridge/Swiftmailer/composer.json | 2 +- src/Symfony/Bridge/Twig/composer.json | 14 ++++++------ .../Bundle/FrameworkBundle/composer.json | 2 +- .../Bundle/SecurityBundle/composer.json | 2 +- src/Symfony/Bundle/TwigBundle/composer.json | 2 +- .../Bundle/WebProfilerBundle/composer.json | 2 +- .../Component/BrowserKit/composer.json | 8 +++---- .../Component/ClassLoader/composer.json | 4 ++-- src/Symfony/Component/Config/composer.json | 2 +- src/Symfony/Component/Console/composer.json | 2 +- .../Component/CssSelector/composer.json | 2 +- .../DependencyInjection/composer.json | 6 ++--- .../Component/DomCrawler/composer.json | 4 ++-- .../Component/EventDispatcher/composer.json | 4 ++-- .../Component/Filesystem/composer.json | 2 +- src/Symfony/Component/Finder/composer.json | 2 +- src/Symfony/Component/Form/composer.json | 12 +++++----- .../Component/HttpFoundation/composer.json | 2 +- .../Component/HttpKernel/composer.json | 22 +++++++++---------- src/Symfony/Component/Locale/composer.json | 2 +- .../Component/OptionsResolver/composer.json | 2 +- src/Symfony/Component/Process/composer.json | 2 +- src/Symfony/Component/Routing/composer.json | 8 +++---- src/Symfony/Component/Security/composer.json | 14 ++++++------ .../Component/Serializer/composer.json | 2 +- .../Component/Templating/composer.json | 2 +- .../Component/Translation/composer.json | 6 ++--- src/Symfony/Component/Validator/composer.json | 8 +++---- src/Symfony/Component/Yaml/composer.json | 2 +- 33 files changed, 76 insertions(+), 76 deletions(-) diff --git a/composer.json b/composer.json index 045d434556b20..37d1b3341d9a9 100644 --- a/composer.json +++ b/composer.json @@ -70,7 +70,7 @@ "minimum-stability": "dev", "extra": { "branch-alias": { - "dev-master": "2.1-dev" + "dev-master": "2.2-dev" } } } diff --git a/src/Symfony/Bridge/Doctrine/composer.json b/src/Symfony/Bridge/Doctrine/composer.json index 33c6956320cbe..83533de1b9230 100644 --- a/src/Symfony/Bridge/Doctrine/composer.json +++ b/src/Symfony/Bridge/Doctrine/composer.json @@ -33,7 +33,7 @@ "minimum-stability": "dev", "extra": { "branch-alias": { - "dev-master": "2.1-dev" + "dev-master": "2.2-dev" } } } diff --git a/src/Symfony/Bridge/Monolog/composer.json b/src/Symfony/Bridge/Monolog/composer.json index d0e36b525eda0..e5d959ed4edac 100644 --- a/src/Symfony/Bridge/Monolog/composer.json +++ b/src/Symfony/Bridge/Monolog/composer.json @@ -27,7 +27,7 @@ "minimum-stability": "dev", "extra": { "branch-alias": { - "dev-master": "2.1-dev" + "dev-master": "2.2-dev" } } } diff --git a/src/Symfony/Bridge/Propel1/composer.json b/src/Symfony/Bridge/Propel1/composer.json index b3955bf85ccfd..c312d98e68da4 100644 --- a/src/Symfony/Bridge/Propel1/composer.json +++ b/src/Symfony/Bridge/Propel1/composer.json @@ -29,7 +29,7 @@ "minimum-stability": "dev", "extra": { "branch-alias": { - "dev-master": "2.1-dev" + "dev-master": "2.2-dev" } } } diff --git a/src/Symfony/Bridge/Swiftmailer/composer.json b/src/Symfony/Bridge/Swiftmailer/composer.json index f3c8b55061e9b..560f1fe035ee1 100644 --- a/src/Symfony/Bridge/Swiftmailer/composer.json +++ b/src/Symfony/Bridge/Swiftmailer/composer.json @@ -29,7 +29,7 @@ "minimum-stability": "dev", "extra": { "branch-alias": { - "dev-master": "2.1-dev" + "dev-master": "2.2-dev" } } } diff --git a/src/Symfony/Bridge/Twig/composer.json b/src/Symfony/Bridge/Twig/composer.json index c7f42595a5b12..9e19140005921 100644 --- a/src/Symfony/Bridge/Twig/composer.json +++ b/src/Symfony/Bridge/Twig/composer.json @@ -20,12 +20,12 @@ "twig/twig": ">=1.9.1,<2.0-dev" }, "require-dev": { - "symfony/form": "2.1.*", - "symfony/routing": "2.1.*", - "symfony/templating": "2.1.*", - "symfony/translation": "2.1.*", - "symfony/yaml": "2.1.*", - "symfony/security": "2.1.*" + "symfony/form": "2.2.*", + "symfony/routing": "2.2.*", + "symfony/templating": "2.2.*", + "symfony/translation": "2.2.*", + "symfony/yaml": "2.2.*", + "symfony/security": "2.2.*" }, "suggest": { "symfony/form": "self.version", @@ -42,7 +42,7 @@ "minimum-stability": "dev", "extra": { "branch-alias": { - "dev-master": "2.1-dev" + "dev-master": "2.2-dev" } } } diff --git a/src/Symfony/Bundle/FrameworkBundle/composer.json b/src/Symfony/Bundle/FrameworkBundle/composer.json index 4b48a97b8c299..d06ccc27ad054 100644 --- a/src/Symfony/Bundle/FrameworkBundle/composer.json +++ b/src/Symfony/Bundle/FrameworkBundle/composer.json @@ -43,7 +43,7 @@ "minimum-stability": "dev", "extra": { "branch-alias": { - "dev-master": "2.1-dev" + "dev-master": "2.2-dev" } } } diff --git a/src/Symfony/Bundle/SecurityBundle/composer.json b/src/Symfony/Bundle/SecurityBundle/composer.json index fb4c79b7b9e34..c7f32ec856740 100644 --- a/src/Symfony/Bundle/SecurityBundle/composer.json +++ b/src/Symfony/Bundle/SecurityBundle/composer.json @@ -26,7 +26,7 @@ "minimum-stability": "dev", "extra": { "branch-alias": { - "dev-master": "2.1-dev" + "dev-master": "2.2-dev" } } } diff --git a/src/Symfony/Bundle/TwigBundle/composer.json b/src/Symfony/Bundle/TwigBundle/composer.json index 4403206686a45..9dc49d2a22979 100644 --- a/src/Symfony/Bundle/TwigBundle/composer.json +++ b/src/Symfony/Bundle/TwigBundle/composer.json @@ -26,7 +26,7 @@ "minimum-stability": "dev", "extra": { "branch-alias": { - "dev-master": "2.1-dev" + "dev-master": "2.2-dev" } } } diff --git a/src/Symfony/Bundle/WebProfilerBundle/composer.json b/src/Symfony/Bundle/WebProfilerBundle/composer.json index edc5c8d708ec4..67ab2b048dc28 100644 --- a/src/Symfony/Bundle/WebProfilerBundle/composer.json +++ b/src/Symfony/Bundle/WebProfilerBundle/composer.json @@ -26,7 +26,7 @@ "minimum-stability": "dev", "extra": { "branch-alias": { - "dev-master": "2.1-dev" + "dev-master": "2.2-dev" } } } diff --git a/src/Symfony/Component/BrowserKit/composer.json b/src/Symfony/Component/BrowserKit/composer.json index f40ddfae25a25..8088fbb7b932d 100644 --- a/src/Symfony/Component/BrowserKit/composer.json +++ b/src/Symfony/Component/BrowserKit/composer.json @@ -17,11 +17,11 @@ ], "require": { "php": ">=5.3.3", - "symfony/dom-crawler": "2.1.*" + "symfony/dom-crawler": "2.2.*" }, "require-dev": { - "symfony/process": "2.1.*", - "symfony/css-selector": "2.1.*" + "symfony/process": "2.2.*", + "symfony/css-selector": "2.2.*" }, "suggest": { "symfony/process": "self.version" @@ -33,7 +33,7 @@ "minimum-stability": "dev", "extra": { "branch-alias": { - "dev-master": "2.1-dev" + "dev-master": "2.2-dev" } } } diff --git a/src/Symfony/Component/ClassLoader/composer.json b/src/Symfony/Component/ClassLoader/composer.json index ccd9ba9bc7007..5a68c85e67dcf 100644 --- a/src/Symfony/Component/ClassLoader/composer.json +++ b/src/Symfony/Component/ClassLoader/composer.json @@ -20,7 +20,7 @@ "php": ">=5.3.3" }, "require-dev": { - "symfony/finder": "2.1.*" + "symfony/finder": "2.2.*" }, "autoload": { "psr-0": { "Symfony\\Component\\ClassLoader": "" } @@ -29,7 +29,7 @@ "minimum-stability": "dev", "extra": { "branch-alias": { - "dev-master": "2.1-dev" + "dev-master": "2.2-dev" } } } diff --git a/src/Symfony/Component/Config/composer.json b/src/Symfony/Component/Config/composer.json index 7d809454abb14..cf7074b7ef382 100644 --- a/src/Symfony/Component/Config/composer.json +++ b/src/Symfony/Component/Config/composer.json @@ -25,7 +25,7 @@ "minimum-stability": "dev", "extra": { "branch-alias": { - "dev-master": "2.1-dev" + "dev-master": "2.2-dev" } } } diff --git a/src/Symfony/Component/Console/composer.json b/src/Symfony/Component/Console/composer.json index 4488bf6092dd1..a0f2b1e0943a1 100644 --- a/src/Symfony/Component/Console/composer.json +++ b/src/Symfony/Component/Console/composer.json @@ -25,7 +25,7 @@ "minimum-stability": "dev", "extra": { "branch-alias": { - "dev-master": "2.1-dev" + "dev-master": "2.2-dev" } } } diff --git a/src/Symfony/Component/CssSelector/composer.json b/src/Symfony/Component/CssSelector/composer.json index 285fade6f3b9d..f893e74d2772f 100644 --- a/src/Symfony/Component/CssSelector/composer.json +++ b/src/Symfony/Component/CssSelector/composer.json @@ -25,7 +25,7 @@ "minimum-stability": "dev", "extra": { "branch-alias": { - "dev-master": "2.1-dev" + "dev-master": "2.2-dev" } } } diff --git a/src/Symfony/Component/DependencyInjection/composer.json b/src/Symfony/Component/DependencyInjection/composer.json index 81811c39a25b1..ae900cbd44357 100644 --- a/src/Symfony/Component/DependencyInjection/composer.json +++ b/src/Symfony/Component/DependencyInjection/composer.json @@ -19,8 +19,8 @@ "php": ">=5.3.3" }, "require-dev": { - "symfony/yaml": "2.1.*", - "symfony/config": "2.1.*" + "symfony/yaml": "2.2.*", + "symfony/config": "2.2.*" }, "suggest": { "symfony/yaml": "self.version", @@ -33,7 +33,7 @@ "minimum-stability": "dev", "extra": { "branch-alias": { - "dev-master": "2.1-dev" + "dev-master": "2.2-dev" } } } diff --git a/src/Symfony/Component/DomCrawler/composer.json b/src/Symfony/Component/DomCrawler/composer.json index 2dfd795dcde16..9f5ef9ca46d21 100644 --- a/src/Symfony/Component/DomCrawler/composer.json +++ b/src/Symfony/Component/DomCrawler/composer.json @@ -19,7 +19,7 @@ "php": ">=5.3.3" }, "require-dev": { - "symfony/css-selector": "2.1.*" + "symfony/css-selector": "2.2.*" }, "suggest": { "symfony/css-selector": "self.version" @@ -31,7 +31,7 @@ "minimum-stability": "dev", "extra": { "branch-alias": { - "dev-master": "2.1-dev" + "dev-master": "2.2-dev" } } } diff --git a/src/Symfony/Component/EventDispatcher/composer.json b/src/Symfony/Component/EventDispatcher/composer.json index 93abadeaca771..9cca69216bd50 100644 --- a/src/Symfony/Component/EventDispatcher/composer.json +++ b/src/Symfony/Component/EventDispatcher/composer.json @@ -19,7 +19,7 @@ "php": ">=5.3.3" }, "require-dev": { - "symfony/dependency-injection": "2.1.*" + "symfony/dependency-injection": "2.2.*" }, "suggest": { "symfony/dependency-injection": "self.version", @@ -32,7 +32,7 @@ "minimum-stability": "dev", "extra": { "branch-alias": { - "dev-master": "2.1-dev" + "dev-master": "2.2-dev" } } } diff --git a/src/Symfony/Component/Filesystem/composer.json b/src/Symfony/Component/Filesystem/composer.json index 82325ce29c93c..168cefb3e0677 100644 --- a/src/Symfony/Component/Filesystem/composer.json +++ b/src/Symfony/Component/Filesystem/composer.json @@ -25,7 +25,7 @@ "minimum-stability": "dev", "extra": { "branch-alias": { - "dev-master": "2.1-dev" + "dev-master": "2.2-dev" } } } diff --git a/src/Symfony/Component/Finder/composer.json b/src/Symfony/Component/Finder/composer.json index aeac80eaf5a51..690fd427e3000 100644 --- a/src/Symfony/Component/Finder/composer.json +++ b/src/Symfony/Component/Finder/composer.json @@ -25,7 +25,7 @@ "minimum-stability": "dev", "extra": { "branch-alias": { - "dev-master": "2.1-dev" + "dev-master": "2.2-dev" } } } diff --git a/src/Symfony/Component/Form/composer.json b/src/Symfony/Component/Form/composer.json index b0446c608c569..9b6797377f1c7 100644 --- a/src/Symfony/Component/Form/composer.json +++ b/src/Symfony/Component/Form/composer.json @@ -17,13 +17,13 @@ ], "require": { "php": ">=5.3.3", - "symfony/event-dispatcher": "2.1.*", - "symfony/locale": "2.1.*", - "symfony/options-resolver": "2.1.*" + "symfony/event-dispatcher": "2.2.*", + "symfony/locale": "2.2.*", + "symfony/options-resolver": "2.2.*" }, "require-dev": { - "symfony/validator": "2.1.*", - "symfony/http-foundation": "2.1.*" + "symfony/validator": "2.2.*", + "symfony/http-foundation": "2.2.*" }, "suggest": { "symfony/validator": "self.version", @@ -36,7 +36,7 @@ "minimum-stability": "dev", "extra": { "branch-alias": { - "dev-master": "2.1-dev" + "dev-master": "2.2-dev" } } } diff --git a/src/Symfony/Component/HttpFoundation/composer.json b/src/Symfony/Component/HttpFoundation/composer.json index 91c23c24870f1..d10ef3180357e 100644 --- a/src/Symfony/Component/HttpFoundation/composer.json +++ b/src/Symfony/Component/HttpFoundation/composer.json @@ -28,7 +28,7 @@ "minimum-stability": "dev", "extra": { "branch-alias": { - "dev-master": "2.1-dev" + "dev-master": "2.2-dev" } } } diff --git a/src/Symfony/Component/HttpKernel/composer.json b/src/Symfony/Component/HttpKernel/composer.json index 12ea499dfd658..b1d1c2c4d0176 100644 --- a/src/Symfony/Component/HttpKernel/composer.json +++ b/src/Symfony/Component/HttpKernel/composer.json @@ -17,18 +17,18 @@ ], "require": { "php": ">=5.3.3", - "symfony/event-dispatcher": "2.1.*", - "symfony/http-foundation": "2.1.*" + "symfony/event-dispatcher": "2.2.*", + "symfony/http-foundation": "2.2.*" }, "require-dev": { - "symfony/browser-kit": "2.1.*", - "symfony/class-loader": "2.1.*", - "symfony/config": "2.1.*", - "symfony/console": "2.1.*", - "symfony/dependency-injection": "2.1.*", - "symfony/finder": "2.1.*", - "symfony/process": "2.1.*", - "symfony/routing": "2.1.*" + "symfony/browser-kit": "2.2.*", + "symfony/class-loader": "2.2.*", + "symfony/config": "2.2.*", + "symfony/console": "2.2.*", + "symfony/dependency-injection": "2.2.*", + "symfony/finder": "2.2.*", + "symfony/process": "2.2.*", + "symfony/routing": "2.2.*" }, "suggest": { "symfony/browser-kit": "self.version", @@ -45,7 +45,7 @@ "minimum-stability": "dev", "extra": { "branch-alias": { - "dev-master": "2.1-dev" + "dev-master": "2.2-dev" } } } diff --git a/src/Symfony/Component/Locale/composer.json b/src/Symfony/Component/Locale/composer.json index ff051d656194b..c450797b1774a 100644 --- a/src/Symfony/Component/Locale/composer.json +++ b/src/Symfony/Component/Locale/composer.json @@ -28,7 +28,7 @@ "minimum-stability": "dev", "extra": { "branch-alias": { - "dev-master": "2.1-dev" + "dev-master": "2.2-dev" } } } diff --git a/src/Symfony/Component/OptionsResolver/composer.json b/src/Symfony/Component/OptionsResolver/composer.json index 22a39a23e2d39..39ad60a68e15e 100644 --- a/src/Symfony/Component/OptionsResolver/composer.json +++ b/src/Symfony/Component/OptionsResolver/composer.json @@ -25,7 +25,7 @@ "minimum-stability": "dev", "extra": { "branch-alias": { - "dev-master": "2.1-dev" + "dev-master": "2.2-dev" } } } diff --git a/src/Symfony/Component/Process/composer.json b/src/Symfony/Component/Process/composer.json index a9f85f1af895b..ea53b3c459abe 100644 --- a/src/Symfony/Component/Process/composer.json +++ b/src/Symfony/Component/Process/composer.json @@ -25,7 +25,7 @@ "minimum-stability": "dev", "extra": { "branch-alias": { - "dev-master": "2.1-dev" + "dev-master": "2.2-dev" } } } diff --git a/src/Symfony/Component/Routing/composer.json b/src/Symfony/Component/Routing/composer.json index 09706a6ff3a53..88a2b1952e55b 100644 --- a/src/Symfony/Component/Routing/composer.json +++ b/src/Symfony/Component/Routing/composer.json @@ -19,9 +19,9 @@ "php": ">=5.3.3" }, "require-dev": { - "symfony/config": "2.1.*", - "symfony/yaml": "2.1.*", - "symfony/http-kernel": "2.1.*", + "symfony/config": "2.2.*", + "symfony/yaml": "2.2.*", + "symfony/http-kernel": "2.2.*", "doctrine/common": ">=2.2,<2.4-dev" }, "suggest": { @@ -36,7 +36,7 @@ "minimum-stability": "dev", "extra": { "branch-alias": { - "dev-master": "2.1-dev" + "dev-master": "2.2-dev" } } } diff --git a/src/Symfony/Component/Security/composer.json b/src/Symfony/Component/Security/composer.json index 0be7fd2a215e7..ce5d22878b5a7 100644 --- a/src/Symfony/Component/Security/composer.json +++ b/src/Symfony/Component/Security/composer.json @@ -17,14 +17,14 @@ ], "require": { "php": ">=5.3.3", - "symfony/event-dispatcher": "2.1.*", - "symfony/http-foundation": "2.1.*", - "symfony/http-kernel": "2.1.*" + "symfony/event-dispatcher": "2.2.*", + "symfony/http-foundation": "2.2.*", + "symfony/http-kernel": "2.2.*" }, "require-dev": { - "symfony/form": "2.1.*", - "symfony/routing": "2.1.*", - "symfony/validator": "2.1.*", + "symfony/form": "2.2.*", + "symfony/routing": "2.2.*", + "symfony/validator": "2.2.*", "doctrine/common": ">=2.2,<2.4-dev", "doctrine/dbal": ">=2.2,<2.4-dev" }, @@ -43,7 +43,7 @@ "minimum-stability": "dev", "extra": { "branch-alias": { - "dev-master": "2.1-dev" + "dev-master": "2.2-dev" } } } diff --git a/src/Symfony/Component/Serializer/composer.json b/src/Symfony/Component/Serializer/composer.json index 1c8feb3050e6d..aa23f3839f773 100644 --- a/src/Symfony/Component/Serializer/composer.json +++ b/src/Symfony/Component/Serializer/composer.json @@ -25,7 +25,7 @@ "minimum-stability": "dev", "extra": { "branch-alias": { - "dev-master": "2.1-dev" + "dev-master": "2.2-dev" } } } diff --git a/src/Symfony/Component/Templating/composer.json b/src/Symfony/Component/Templating/composer.json index 43b701b824b63..dcf589a2f75ec 100644 --- a/src/Symfony/Component/Templating/composer.json +++ b/src/Symfony/Component/Templating/composer.json @@ -25,7 +25,7 @@ "minimum-stability": "dev", "extra": { "branch-alias": { - "dev-master": "2.1-dev" + "dev-master": "2.2-dev" } } } diff --git a/src/Symfony/Component/Translation/composer.json b/src/Symfony/Component/Translation/composer.json index 6bcf291611153..caa44e0b0e349 100644 --- a/src/Symfony/Component/Translation/composer.json +++ b/src/Symfony/Component/Translation/composer.json @@ -19,8 +19,8 @@ "php": ">=5.3.3" }, "require-dev": { - "symfony/config": "2.1.*", - "symfony/yaml": "2.1.*" + "symfony/config": "2.2.*", + "symfony/yaml": "2.2.*" }, "suggest": { "symfony/config": "self.version", @@ -33,7 +33,7 @@ "minimum-stability": "dev", "extra": { "branch-alias": { - "dev-master": "2.1-dev" + "dev-master": "2.2-dev" } } } diff --git a/src/Symfony/Component/Validator/composer.json b/src/Symfony/Component/Validator/composer.json index 5fa51ed77673f..c016c07fede2f 100644 --- a/src/Symfony/Component/Validator/composer.json +++ b/src/Symfony/Component/Validator/composer.json @@ -19,9 +19,9 @@ "php": ">=5.3.3" }, "require-dev": { - "symfony/http-foundation": "2.1.*", - "symfony/locale": "2.1.*", - "symfony/yaml": "2.1.*" + "symfony/http-foundation": "2.2.*", + "symfony/locale": "2.2.*", + "symfony/yaml": "2.2.*" }, "suggest": { "doctrine/common": ">=2.1,<2.4-dev", @@ -35,7 +35,7 @@ "minimum-stability": "dev", "extra": { "branch-alias": { - "dev-master": "2.1-dev" + "dev-master": "2.2-dev" } } } diff --git a/src/Symfony/Component/Yaml/composer.json b/src/Symfony/Component/Yaml/composer.json index 88460ce34b70d..13a9e23603e0d 100644 --- a/src/Symfony/Component/Yaml/composer.json +++ b/src/Symfony/Component/Yaml/composer.json @@ -25,7 +25,7 @@ "minimum-stability": "dev", "extra": { "branch-alias": { - "dev-master": "2.1-dev" + "dev-master": "2.2-dev" } } } From e22823bb7d6c0a4cd5fb9d5315144d35ecc1a0b2 Mon Sep 17 00:00:00 2001 From: Tobias Schultze Date: Fri, 7 Sep 2012 03:30:48 +0200 Subject: [PATCH 026/975] [Routing] context params should have higher priority than defaults fixes #5437 --- .../Component/Routing/Generator/UrlGenerator.php | 2 +- .../Routing/Tests/Generator/UrlGeneratorTest.php | 12 ++++++++++++ 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/src/Symfony/Component/Routing/Generator/UrlGenerator.php b/src/Symfony/Component/Routing/Generator/UrlGenerator.php index 307b5a588f842..23ac3d7904062 100644 --- a/src/Symfony/Component/Routing/Generator/UrlGenerator.php +++ b/src/Symfony/Component/Routing/Generator/UrlGenerator.php @@ -133,7 +133,7 @@ public function generate($name, $parameters = array(), $absolute = false) protected function doGenerate($variables, $defaults, $requirements, $tokens, $parameters, $name, $absolute) { $variables = array_flip($variables); - $mergedParams = array_replace($this->context->getParameters(), $defaults, $parameters); + $mergedParams = array_replace($defaults, $this->context->getParameters(), $parameters); // all params must be given if ($diff = array_diff_key($variables, $mergedParams)) { diff --git a/src/Symfony/Component/Routing/Tests/Generator/UrlGeneratorTest.php b/src/Symfony/Component/Routing/Tests/Generator/UrlGeneratorTest.php index 236015f976c57..3e039c520d643 100644 --- a/src/Symfony/Component/Routing/Tests/Generator/UrlGeneratorTest.php +++ b/src/Symfony/Component/Routing/Tests/Generator/UrlGeneratorTest.php @@ -148,6 +148,18 @@ public function testUrlWithGlobalParameter() $this->assertEquals('/app.php/testing/bar', $url); } + public function testGlobalParameterHasHigherPriorityThanDefault() + { + $routes = $this->getRoutes('test', new Route('/{_locale}', array('_locale' => 'en'))); + $generator = $this->getGenerator($routes); + $context = new RequestContext('/app.php'); + $context->setParameter('_locale', 'de'); + $generator->setContext($context); + $url = $generator->generate('test', array()); + + $this->assertSame('/app.php/de', $url); + } + /** * @expectedException Symfony\Component\Routing\Exception\RouteNotFoundException */ From 622102e2e99cf6a87432669eaabc678137ac3120 Mon Sep 17 00:00:00 2001 From: boombatower Date: Fri, 7 Sep 2012 14:36:28 -0700 Subject: [PATCH 027/975] [Process] change all documentation type to callable --- src/Symfony/Component/Process/Process.php | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/Symfony/Component/Process/Process.php b/src/Symfony/Component/Process/Process.php index cd1e8b42155a2..19fdb78823029 100644 --- a/src/Symfony/Component/Process/Process.php +++ b/src/Symfony/Component/Process/Process.php @@ -153,8 +153,8 @@ public function __destruct() * The STDOUT and STDERR are also available after the process is finished * via the getOutput() and getErrorOutput() methods. * - * @param Closure|string|array $callback A PHP callback to run whenever there is some - * output available on STDOUT or STDERR + * @param callable $callback A PHP callback to run whenever there is some + * output available on STDOUT or STDERR * * @return integer The exit status code * @@ -184,8 +184,8 @@ public function run($callback = null) * with true as a second parameter then the callback will get all data occurred * in (and since) the start call. * - * @param Closure|string|array $callback A PHP callback to run whenever there is some - * output available on STDOUT or STDERR + * @param callable $callback A PHP callback to run whenever there is some + * output available on STDOUT or STDERR * * @throws \RuntimeException When process can't be launch or is stopped * @throws \RuntimeException When process is already running @@ -307,7 +307,7 @@ public function start($callback = null) * 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. * - * @param mixed $callback A valid PHP callback + * @param callable $callback A valid PHP callback * * @return int The exitcode of the process * @@ -684,7 +684,7 @@ public function setEnhanceWindowsCompatibility($enhance) * The callbacks adds all occurred output to the specific buffer and calls * the user callback (if present) with the received output. * - * @param mixed $callback The user defined PHP callback + * @param callable $callback The user defined PHP callback * * @return mixed A PHP callable */ @@ -746,7 +746,7 @@ protected function updateOutput() /** * Handles the windows file handles fallbacks * - * @param mixed $callback A valid PHP callback + * @param callable $callback A valid PHP callback * @param Boolean $closeEmptyHandles if true, handles that are empty will be assumed closed */ private function processFileHandles($callback, $closeEmptyHandles = false) From 13937de2c8b82ea37f2eb75c0b3b22d7d5d5bf7d Mon Sep 17 00:00:00 2001 From: Fabien Potencier Date: Mon, 10 Sep 2012 12:59:37 +0200 Subject: [PATCH 028/975] replaced self.version/2.1.* by 2.2.* in composer.json files --- src/Symfony/Bridge/Doctrine/composer.json | 4 +-- src/Symfony/Bridge/Monolog/composer.json | 2 +- src/Symfony/Bridge/Propel1/composer.json | 6 ++--- src/Symfony/Bridge/Swiftmailer/composer.json | 2 +- src/Symfony/Bridge/Twig/composer.json | 12 ++++----- .../Bundle/FrameworkBundle/composer.json | 26 +++++++++---------- .../Bundle/SecurityBundle/composer.json | 2 +- src/Symfony/Bundle/TwigBundle/composer.json | 2 +- .../Bundle/WebProfilerBundle/composer.json | 2 +- .../Component/BrowserKit/composer.json | 2 +- .../DependencyInjection/composer.json | 4 +-- .../Component/DomCrawler/composer.json | 2 +- .../Component/EventDispatcher/composer.json | 4 +-- src/Symfony/Component/Form/composer.json | 4 +-- .../Component/HttpKernel/composer.json | 12 ++++----- src/Symfony/Component/Routing/composer.json | 4 +-- src/Symfony/Component/Security/composer.json | 10 +++---- .../Component/Translation/composer.json | 4 +-- src/Symfony/Component/Validator/composer.json | 4 +-- 19 files changed, 54 insertions(+), 54 deletions(-) diff --git a/src/Symfony/Bridge/Doctrine/composer.json b/src/Symfony/Bridge/Doctrine/composer.json index d1e0248fb0350..adc825d463070 100644 --- a/src/Symfony/Bridge/Doctrine/composer.json +++ b/src/Symfony/Bridge/Doctrine/composer.json @@ -20,8 +20,8 @@ "doctrine/common": ">=2.2,<2.4-dev" }, "suggest": { - "symfony/form": "2.1.*", - "symfony/validator": "2.1.*", + "symfony/form": "2.2.*", + "symfony/validator": "2.2.*", "doctrine/data-fixtures": "1.0.*", "doctrine/dbal": ">=2.2,<2.4-dev", "doctrine/orm": ">=2.2.3,<2.4-dev" diff --git a/src/Symfony/Bridge/Monolog/composer.json b/src/Symfony/Bridge/Monolog/composer.json index 9c39ec2e1d59a..2b60a451ee941 100644 --- a/src/Symfony/Bridge/Monolog/composer.json +++ b/src/Symfony/Bridge/Monolog/composer.json @@ -17,7 +17,7 @@ ], "require": { "php": ">=5.3.3", - "symfony/http-kernel": "2.1.*", + "symfony/http-kernel": "2.2.*", "monolog/monolog": "1.*" }, "autoload": { diff --git a/src/Symfony/Bridge/Propel1/composer.json b/src/Symfony/Bridge/Propel1/composer.json index 9219b32388c3f..7827d5e3874f6 100644 --- a/src/Symfony/Bridge/Propel1/composer.json +++ b/src/Symfony/Bridge/Propel1/composer.json @@ -17,9 +17,9 @@ ], "require": { "php": ">=5.3.3", - "symfony/http-foundation": "2.1.*", - "symfony/http-kernel": "2.1.*", - "symfony/form": "2.1.*", + "symfony/http-foundation": "2.2.*", + "symfony/http-kernel": "2.2.*", + "symfony/form": "2.2.*", "propel/propel1": "1.6.*" }, "autoload": { diff --git a/src/Symfony/Bridge/Swiftmailer/composer.json b/src/Symfony/Bridge/Swiftmailer/composer.json index 5995b79c0777f..c4dbd47793015 100644 --- a/src/Symfony/Bridge/Swiftmailer/composer.json +++ b/src/Symfony/Bridge/Swiftmailer/composer.json @@ -20,7 +20,7 @@ "swiftmailer/swiftmailer": ">=4.2.0,<4.3-dev" }, "suggest": { - "symfony/http-kernel": "2.1.*" + "symfony/http-kernel": "2.2.*" }, "autoload": { "psr-0": { "Symfony\\Bridge\\Swiftmailer": "" } diff --git a/src/Symfony/Bridge/Twig/composer.json b/src/Symfony/Bridge/Twig/composer.json index fcb4d946bf75b..8c9f13df4bb2e 100644 --- a/src/Symfony/Bridge/Twig/composer.json +++ b/src/Symfony/Bridge/Twig/composer.json @@ -28,12 +28,12 @@ "symfony/security": "2.2.*" }, "suggest": { - "symfony/form": "2.1.*", - "symfony/routing": "2.1.*", - "symfony/templating": "2.1.*", - "symfony/translation": "2.1.*", - "symfony/yaml": "2.1.*", - "symfony/security": "2.1.*" + "symfony/form": "2.2.*", + "symfony/routing": "2.2.*", + "symfony/templating": "2.2.*", + "symfony/translation": "2.2.*", + "symfony/yaml": "2.2.*", + "symfony/security": "2.2.*" }, "autoload": { "psr-0": { "Symfony\\Bridge\\Twig": "" } diff --git a/src/Symfony/Bundle/FrameworkBundle/composer.json b/src/Symfony/Bundle/FrameworkBundle/composer.json index e41d0005d1cf2..869dc5d153501 100644 --- a/src/Symfony/Bundle/FrameworkBundle/composer.json +++ b/src/Symfony/Bundle/FrameworkBundle/composer.json @@ -17,24 +17,24 @@ ], "require": { "php": ">=5.3.3", - "symfony/dependency-injection" : "2.1.*", - "symfony/config" : "2.1.*", - "symfony/event-dispatcher": "2.1.*", - "symfony/http-kernel": "2.1.*", - "symfony/filesystem": "2.1.*", - "symfony/routing": "2.1.*", - "symfony/templating": "2.1.*", - "symfony/translation": "2.1.*", + "symfony/dependency-injection" : "2.2.*", + "symfony/config" : "2.2.*", + "symfony/event-dispatcher": "2.2.*", + "symfony/http-kernel": "2.2.*", + "symfony/filesystem": "2.2.*", + "symfony/routing": "2.2.*", + "symfony/templating": "2.2.*", + "symfony/translation": "2.2.*", "doctrine/common": ">=2.2,<2.4-dev" }, "require-dev": { - "symfony/finder": "2.1.*" + "symfony/finder": "2.2.*" }, "suggest": { - "symfony/console": "2.1.*", - "symfony/finder": "2.1.*", - "symfony/form": "2.1.*", - "symfony/validator": "2.1.*" + "symfony/console": "2.2.*", + "symfony/finder": "2.2.*", + "symfony/form": "2.2.*", + "symfony/validator": "2.2.*" }, "autoload": { "psr-0": { "Symfony\\Bundle\\FrameworkBundle": "" } diff --git a/src/Symfony/Bundle/SecurityBundle/composer.json b/src/Symfony/Bundle/SecurityBundle/composer.json index 70e6a486580bb..e369a94813f7c 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.1.*" + "symfony/security": "2.2.*" }, "autoload": { "psr-0": { "Symfony\\Bundle\\SecurityBundle": "" } diff --git a/src/Symfony/Bundle/TwigBundle/composer.json b/src/Symfony/Bundle/TwigBundle/composer.json index 62978d302247a..c263b0a165cb3 100644 --- a/src/Symfony/Bundle/TwigBundle/composer.json +++ b/src/Symfony/Bundle/TwigBundle/composer.json @@ -17,7 +17,7 @@ ], "require": { "php": ">=5.3.3", - "symfony/twig-bridge": "2.1.*" + "symfony/twig-bridge": "2.2.*" }, "autoload": { "psr-0": { "Symfony\\Bundle\\TwigBundle": "" } diff --git a/src/Symfony/Bundle/WebProfilerBundle/composer.json b/src/Symfony/Bundle/WebProfilerBundle/composer.json index 900880e275175..3c14ba5eebe7b 100644 --- a/src/Symfony/Bundle/WebProfilerBundle/composer.json +++ b/src/Symfony/Bundle/WebProfilerBundle/composer.json @@ -17,7 +17,7 @@ ], "require": { "php": ">=5.3.3", - "symfony/twig-bundle": "2.1.*" + "symfony/twig-bundle": "2.2.*" }, "autoload": { "psr-0": { "Symfony\\Bundle\\WebProfilerBundle": "" } diff --git a/src/Symfony/Component/BrowserKit/composer.json b/src/Symfony/Component/BrowserKit/composer.json index 47c657f934771..12ff0e041d5b9 100644 --- a/src/Symfony/Component/BrowserKit/composer.json +++ b/src/Symfony/Component/BrowserKit/composer.json @@ -24,7 +24,7 @@ "symfony/css-selector": "2.2.*" }, "suggest": { - "symfony/process": "2.1.*" + "symfony/process": "2.2.*" }, "autoload": { "psr-0": { "Symfony\\Component\\BrowserKit": "" } diff --git a/src/Symfony/Component/DependencyInjection/composer.json b/src/Symfony/Component/DependencyInjection/composer.json index f108829d3b469..b50f49b2a93cd 100644 --- a/src/Symfony/Component/DependencyInjection/composer.json +++ b/src/Symfony/Component/DependencyInjection/composer.json @@ -23,8 +23,8 @@ "symfony/config": "2.2.*" }, "suggest": { - "symfony/yaml": "2.1.*", - "symfony/config": "2.1.*" + "symfony/yaml": "2.2.*", + "symfony/config": "2.2.*" }, "autoload": { "psr-0": { "Symfony\\Component\\DependencyInjection": "" } diff --git a/src/Symfony/Component/DomCrawler/composer.json b/src/Symfony/Component/DomCrawler/composer.json index b220622561230..80b1792b1aacc 100644 --- a/src/Symfony/Component/DomCrawler/composer.json +++ b/src/Symfony/Component/DomCrawler/composer.json @@ -22,7 +22,7 @@ "symfony/css-selector": "2.2.*" }, "suggest": { - "symfony/css-selector": "2.1.*" + "symfony/css-selector": "2.2.*" }, "autoload": { "psr-0": { "Symfony\\Component\\DomCrawler": "" } diff --git a/src/Symfony/Component/EventDispatcher/composer.json b/src/Symfony/Component/EventDispatcher/composer.json index a706847e980e9..c31dd481e2d93 100644 --- a/src/Symfony/Component/EventDispatcher/composer.json +++ b/src/Symfony/Component/EventDispatcher/composer.json @@ -22,8 +22,8 @@ "symfony/dependency-injection": "2.2.*" }, "suggest": { - "symfony/dependency-injection": "2.1.*", - "symfony/http-kernel": "2.1.*" + "symfony/dependency-injection": "2.2.*", + "symfony/http-kernel": "2.2.*" }, "autoload": { "psr-0": { "Symfony\\Component\\EventDispatcher": "" } diff --git a/src/Symfony/Component/Form/composer.json b/src/Symfony/Component/Form/composer.json index bd5d58393b66a..e861e3b1d2b47 100644 --- a/src/Symfony/Component/Form/composer.json +++ b/src/Symfony/Component/Form/composer.json @@ -26,8 +26,8 @@ "symfony/http-foundation": "2.2.*" }, "suggest": { - "symfony/validator": "2.1.*", - "symfony/http-foundation": "2.1.*" + "symfony/validator": "2.2.*", + "symfony/http-foundation": "2.2.*" }, "autoload": { "psr-0": { "Symfony\\Component\\Form": "" } diff --git a/src/Symfony/Component/HttpKernel/composer.json b/src/Symfony/Component/HttpKernel/composer.json index 6393185961816..7c9fe7dc308fa 100644 --- a/src/Symfony/Component/HttpKernel/composer.json +++ b/src/Symfony/Component/HttpKernel/composer.json @@ -31,12 +31,12 @@ "symfony/routing": "2.2.*" }, "suggest": { - "symfony/browser-kit": "2.1.*", - "symfony/class-loader": "2.1.*", - "symfony/config": "2.1.*", - "symfony/console": "2.1.*", - "symfony/dependency-injection": "2.1.*", - "symfony/finder": "2.1.*" + "symfony/browser-kit": "2.2.*", + "symfony/class-loader": "2.2.*", + "symfony/config": "2.2.*", + "symfony/console": "2.2.*", + "symfony/dependency-injection": "2.2.*", + "symfony/finder": "2.2.*" }, "autoload": { "psr-0": { "Symfony\\Component\\HttpKernel": "" } diff --git a/src/Symfony/Component/Routing/composer.json b/src/Symfony/Component/Routing/composer.json index d8f0e95e0ce4d..2cee345e274ec 100644 --- a/src/Symfony/Component/Routing/composer.json +++ b/src/Symfony/Component/Routing/composer.json @@ -25,8 +25,8 @@ "doctrine/common": ">=2.2,<2.4-dev" }, "suggest": { - "symfony/config": "2.1.*", - "symfony/yaml": "2.1.*", + "symfony/config": "2.2.*", + "symfony/yaml": "2.2.*", "doctrine/common": ">=2.2,<2.4-dev" }, "autoload": { diff --git a/src/Symfony/Component/Security/composer.json b/src/Symfony/Component/Security/composer.json index 26fea16f0b9fd..ceaf28036cae5 100644 --- a/src/Symfony/Component/Security/composer.json +++ b/src/Symfony/Component/Security/composer.json @@ -29,11 +29,11 @@ "doctrine/dbal": ">=2.2,<2.4-dev" }, "suggest": { - "symfony/class-loader": "2.1.*", - "symfony/finder": "2.1.*", - "symfony/form": "2.1.*", - "symfony/validator": "2.1.*", - "symfony/routing": "2.1.*", + "symfony/class-loader": "2.2.*", + "symfony/finder": "2.2.*", + "symfony/form": "2.2.*", + "symfony/validator": "2.2.*", + "symfony/routing": "2.2.*", "doctrine/dbal": "to use the built-in ACL implementation" }, "autoload": { diff --git a/src/Symfony/Component/Translation/composer.json b/src/Symfony/Component/Translation/composer.json index 41183c2a5de9b..dcc3c0e1a04e3 100644 --- a/src/Symfony/Component/Translation/composer.json +++ b/src/Symfony/Component/Translation/composer.json @@ -23,8 +23,8 @@ "symfony/yaml": "2.2.*" }, "suggest": { - "symfony/config": "2.1.*", - "symfony/yaml": "2.1.*" + "symfony/config": "2.2.*", + "symfony/yaml": "2.2.*" }, "autoload": { "psr-0": { "Symfony\\Component\\Translation": "" } diff --git a/src/Symfony/Component/Validator/composer.json b/src/Symfony/Component/Validator/composer.json index a4702c970f259..de1279e0a921f 100644 --- a/src/Symfony/Component/Validator/composer.json +++ b/src/Symfony/Component/Validator/composer.json @@ -25,8 +25,8 @@ }, "suggest": { "doctrine/common": ">=2.1,<2.4-dev", - "symfony/http-foundation": "2.1.*", - "symfony/yaml": "2.1.*" + "symfony/http-foundation": "2.2.*", + "symfony/yaml": "2.2.*" }, "autoload": { "psr-0": { "Symfony\\Component\\Validator": "" } From 005a9a3c5bd137acdec7f222a0e0dc101e513f41 Mon Sep 17 00:00:00 2001 From: Tobias Schultze Date: Tue, 8 May 2012 10:14:10 +0200 Subject: [PATCH 029/975] [Routing] fixed RouteCompiler for adjacent and nested placeholders --- .../Component/Routing/RouteCompiler.php | 77 ++++++++++++------- .../Tests/Generator/UrlGeneratorTest.php | 13 ++++ .../Routing/Tests/Matcher/UrlMatcherTest.php | 20 +++++ .../Routing/Tests/RouteCompilerTest.php | 20 +++++ 4 files changed, 104 insertions(+), 26 deletions(-) diff --git a/src/Symfony/Component/Routing/RouteCompiler.php b/src/Symfony/Component/Routing/RouteCompiler.php index 5c16813943534..76cd4f2df9c1b 100644 --- a/src/Symfony/Component/Routing/RouteCompiler.php +++ b/src/Symfony/Component/Routing/RouteCompiler.php @@ -15,6 +15,7 @@ * RouteCompiler compiles Route instances to CompiledRoute instances. * * @author Fabien Potencier + * @author Tobias Schultze */ class RouteCompiler implements RouteCompilerInterface { @@ -30,45 +31,50 @@ class RouteCompiler implements RouteCompilerInterface public function compile(Route $route) { $pattern = $route->getPattern(); - $len = strlen($pattern); $tokens = array(); $variables = array(); + $matches = array(); $pos = 0; - preg_match_all('#.\{(\w+)\}#', $pattern, $matches, PREG_OFFSET_CAPTURE | PREG_SET_ORDER); - foreach ($matches as $match) { - if ($text = substr($pattern, $pos, $match[0][1] - $pos)) { - $tokens[] = array('text', $text); - } + $lastSeparator = ''; + // Match all variables enclosed in "{}" and iterate over them. But we only want to match the innermost variable + // in case of nested "{}", e.g. {foo{bar}}. This in ensured because \w does not match "{" or "}" itself. + preg_match_all('#\{\w+\}#', $pattern, $matches, PREG_OFFSET_CAPTURE | PREG_SET_ORDER); + foreach ($matches as $match) { + $varName = substr($match[0][0], 1, -1); + // get all static text preceding the current variable + $precedingText = substr($pattern, $pos, $match[0][1] - $pos); $pos = $match[0][1] + strlen($match[0][0]); - $var = $match[1][0]; - - if (null !== $req = $route->getRequirement($var)) { - $regexp = $req; - } else { - // Use the character preceding the variable as a separator - $separators = array($match[0][0][0]); + $precedingChar = strlen($precedingText) > 0 ? substr($precedingText, -1) : ''; - if ($pos !== $len) { - // Use the character following the variable as the separator when available - $separators[] = $pattern[$pos]; - } - $regexp = sprintf('[^%s]+', preg_quote(implode('', array_unique($separators)), self::REGEX_DELIMITER)); + if (is_numeric($varName)) { + throw new \DomainException(sprintf('Variable name "%s" cannot be numeric in route pattern "%s". Please use a different name.', $varName, $pattern)); + } + if (in_array($varName, $variables)) { + throw new \LogicException(sprintf('Route pattern "%s" cannot reference variable name "%s" more than once.', $pattern, $varName)); } - $tokens[] = array('variable', $match[0][0][0], $regexp, $var); - - if (is_numeric($var)) { - throw new \DomainException(sprintf('Variable name "%s" cannot be numeric in route pattern "%s". Please use a different name.', $var, $route->getPattern())); + if (strlen($precedingText) > 1) { + $tokens[] = array('text', substr($precedingText, 0, -1)); } - if (in_array($var, $variables)) { - throw new \LogicException(sprintf('Route pattern "%s" cannot reference variable name "%s" more than once.', $route->getPattern(), $var)); + // use the character preceding the variable as a separator + // save it for later use as default separator for variables that follow directly without having a preceding char e.g. "/{x}{y}" + if ('' !== $precedingChar) { + $lastSeparator = $precedingChar; + } + + $regexp = $route->getRequirement($varName); + if (null === $regexp) { + // use the character following the variable (ignoring other placeholders) as a separator when it's not the same as the preceding separator + $nextSeparator = $this->findNextSeparator(substr($pattern, $pos)); + $regexp = sprintf('[^%s]+', preg_quote($lastSeparator !== $nextSeparator ? $lastSeparator.$nextSeparator : $lastSeparator, self::REGEX_DELIMITER)); } - $variables[] = $var; + $tokens[] = array('variable', $precedingChar, $regexp, $varName); + $variables[] = $varName; } - if ($pos < $len) { + if ($pos < strlen($pattern)) { $tokens[] = array('text', substr($pattern, $pos)); } @@ -97,6 +103,25 @@ public function compile(Route $route) ); } + /** + * Returns the next static character in the Route pattern that will serve as a separator. + * + * @param string $pattern The route pattern + * + * @return string The next static character (or empty string when none available) + */ + private function findNextSeparator($pattern) + { + if ('' == $pattern) { + // return empty string if pattern is empty or false (false which can be returned by substr) + return ''; + } + // first remove all placeholders from the pattern so we can find the next real static character + $pattern = preg_replace('#\{\w+\}#', '', $pattern); + + return isset($pattern[0]) ? $pattern[0] : ''; + } + /** * Computes the regexp used to match a specific token. It can be static text or a subpattern. * diff --git a/src/Symfony/Component/Routing/Tests/Generator/UrlGeneratorTest.php b/src/Symfony/Component/Routing/Tests/Generator/UrlGeneratorTest.php index f001067a5392f..e40285defe944 100644 --- a/src/Symfony/Component/Routing/Tests/Generator/UrlGeneratorTest.php +++ b/src/Symfony/Component/Routing/Tests/Generator/UrlGeneratorTest.php @@ -255,6 +255,19 @@ public function testEncodingOfRelativePathSegments() $this->assertSame('/app.php/a./.a/a../..a/...', $this->getGenerator($routes)->generate('test')); } + public function testAdjacentVariables() + { + $routes = $this->getRoutes('test', new Route('/{x}{y}{z}.{_format}', array('z' => 'default-z', '_format' => 'html'), array('y' => '\d+'))); + $generator = $this->getGenerator($routes); + $this->assertSame('/app.php/foo123', $generator->generate('test', array('x' => 'foo', 'y' => '123'))); + $this->assertSame('/app.php/foo123bar.xml', $generator->generate('test', array('x' => 'foo', 'y' => '123', 'z' => 'bar', '_format' => 'xml'))); + + // The default requirement for 'x' should not allow the separator '.' in this case because it would otherwise match everything + // and following optional variables like _format could never match. + $this->setExpectedException('Symfony\Component\Routing\Exception\InvalidParameterException'); + $generator->generate('test', array('x' => 'do.t', 'y' => '123', 'z' => 'bar', '_format' => 'xml')); + } + protected function getGenerator(RouteCollection $routes, array $parameters = array(), $logger = null) { $context = new RequestContext('/app.php'); diff --git a/src/Symfony/Component/Routing/Tests/Matcher/UrlMatcherTest.php b/src/Symfony/Component/Routing/Tests/Matcher/UrlMatcherTest.php index eb18e5068dfeb..2fde2d8864bff 100644 --- a/src/Symfony/Component/Routing/Tests/Matcher/UrlMatcherTest.php +++ b/src/Symfony/Component/Routing/Tests/Matcher/UrlMatcherTest.php @@ -232,6 +232,26 @@ public function testMatchingIsEager() $this->assertEquals(array('foo' => 'text1-text2-text3', 'bar' => 'text4', '_route' => 'test'), $matcher->match('/text1-text2-text3-text4-')); } + public function testAdjacentVariables() + { + $coll = new RouteCollection(); + $coll->add('test', new Route('/{w}{x}{y}{z}.{_format}', array('z' => 'default-z', '_format' => 'html'), array('y' => 'y|Y'))); + + $matcher = new UrlMatcher($coll, new RequestContext()); + // 'w' eagerly matches as much as possible and the other variables match the remaining chars. + // This also shows that the variables w-z must all exclude the separating char (the dot '.' in this case) by default requirement. + // Otherwise they would also comsume '.xml' and _format would never match as it's an optional variable. + $this->assertEquals(array('w' => 'wwwww', 'x' => 'x', 'y' => 'Y', 'z' => 'Z','_format' => 'xml', '_route' => 'test'), $matcher->match('/wwwwwxYZ.xml')); + // As 'y' has custom requirement and can only be of value 'y|Y', it will leave 'ZZZ' to variable z. + // So with carefully chosen requirements adjacent variables, can be useful. + $this->assertEquals(array('w' => 'wwwww', 'x' => 'x', 'y' => 'y', 'z' => 'ZZZ','_format' => 'html', '_route' => 'test'), $matcher->match('/wwwwwxyZZZ')); + // z and _format are optional. + $this->assertEquals(array('w' => 'wwwww', 'x' => 'x', 'y' => 'y', 'z' => 'default-z','_format' => 'html', '_route' => 'test'), $matcher->match('/wwwwwxy')); + + $this->setExpectedException('Symfony\Component\Routing\Exception\ResourceNotFoundException'); + $matcher->match('/wxy.html'); + } + /** * @expectedException Symfony\Component\Routing\Exception\ResourceNotFoundException */ diff --git a/src/Symfony/Component/Routing/Tests/RouteCompilerTest.php b/src/Symfony/Component/Routing/Tests/RouteCompilerTest.php index a71b4993ad267..284739c10a8d6 100644 --- a/src/Symfony/Component/Routing/Tests/RouteCompilerTest.php +++ b/src/Symfony/Component/Routing/Tests/RouteCompilerTest.php @@ -120,6 +120,26 @@ public function provideCompileData() array('text', '/foo'), )), + array( + 'Route with nested placeholders', + array('/{static{var}static}'), + '/{stati', '#^/\{static(?[^cs]+)static\}$#s', array('var'), array( + array('text', 'static}'), + array('variable', 'c', '[^cs]+', 'var'), + array('text', '/{stati'), + )), + + array( + 'Route without separator between variables', + array('/{w}{x}{y}{z}.{_format}', array('z' => 'default-z', '_format' => 'html'), array('y' => '(y|Y)')), + '', '#^/(?[^/\.]+)(?[^/\.]+)(?(y|Y))(?:(?[^/\.]+)(?:\.(?<_format>[^\.]+))?)?$#s', array('w', 'x', 'y', 'z', '_format'), array( + array('variable', '.', '[^\.]+', '_format'), + array('variable', '', '[^/\.]+', 'z'), + array('variable', '', '(y|Y)', 'y'), + array('variable', '', '[^/\.]+', 'x'), + array('variable', '/', '[^/\.]+', 'w'), + )), + array( 'Route with a format', array('/foo/{bar}.{_format}'), From 2a35941bab64b692104402c81fa5cd21283ad425 Mon Sep 17 00:00:00 2001 From: Michal Piotrowski Date: Tue, 11 Sep 2012 16:34:01 +0200 Subject: [PATCH 030/975] ParameterBag tests --- .../HttpFoundation/Tests/ParameterBagTest.php | 22 +++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/src/Symfony/Component/HttpFoundation/Tests/ParameterBagTest.php b/src/Symfony/Component/HttpFoundation/Tests/ParameterBagTest.php index c3c0b16bfd5a6..6cd42bf91dd0f 100644 --- a/src/Symfony/Component/HttpFoundation/Tests/ParameterBagTest.php +++ b/src/Symfony/Component/HttpFoundation/Tests/ParameterBagTest.php @@ -32,6 +32,28 @@ public function testAll() $this->assertEquals(array('foo' => 'bar'), $bag->all(), '->all() gets all the input'); } + public function testKeys() + { + $bag = new ParameterBag(array('foo' => 'bar')); + $this->assertEquals(array('foo'), $bag->keys()); + } + + public function testAdd() + { + $bag = new ParameterBag(array('foo' => 'bar')); + $bag->add(array('bar' => 'bas')); + $this->assertEquals(array('foo' => 'bar', 'bar' => 'bas'), $bag->all()); + } + + public function testRemove() + { + $bag = new ParameterBag(array('foo' => 'bar')); + $bag->add(array('bar' => 'bas')); + $this->assertEquals(array('foo' => 'bar', 'bar' => 'bas'), $bag->all()); + $bag->remove('bar'); + $this->assertEquals(array('foo' => 'bar'), $bag->all()); + } + /** * @covers Symfony\Component\HttpFoundation\ParameterBag::replace */ From cc58b3092d62d14f2333f80f3e6ed68296688fea Mon Sep 17 00:00:00 2001 From: Arnaud Kleinpeter Date: Sat, 15 Sep 2012 18:15:43 +0200 Subject: [PATCH 031/975] [Console] Misuse of str_pad instead of str_repeat --- src/Symfony/Component/Console/Input/InputDefinition.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Symfony/Component/Console/Input/InputDefinition.php b/src/Symfony/Component/Console/Input/InputDefinition.php index 2db9222f1e4fe..d93e8e3a0be3a 100644 --- a/src/Symfony/Component/Console/Input/InputDefinition.php +++ b/src/Symfony/Component/Console/Input/InputDefinition.php @@ -433,7 +433,7 @@ public function asText() $default = ''; } - $description = str_replace("\n", "\n".str_pad('', $max + 2, ' '), $argument->getDescription()); + $description = str_replace("\n", "\n".str_repeat(' ', $max + 2), $argument->getDescription()); $text[] = sprintf(" %-${max}s %s%s", $argument->getName(), $description, $default); } @@ -452,7 +452,7 @@ public function asText() } $multiple = $option->isArray() ? ' (multiple values allowed)' : ''; - $description = str_replace("\n", "\n".str_pad('', $max + 2, ' '), $option->getDescription()); + $description = str_replace("\n", "\n".str_repeat(' ', $max + 2), $option->getDescription()); $optionMax = $max - strlen($option->getName()) - 2; $text[] = sprintf(" %s %-${optionMax}s%s%s%s", From baf2c46a076ba2e62b880204c1eb19fcc00a8803 Mon Sep 17 00:00:00 2001 From: Pascal Borreli Date: Sun, 16 Sep 2012 00:50:00 +0000 Subject: [PATCH 032/975] [Config] Little tweak --- src/Symfony/Component/Config/ConfigCache.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Symfony/Component/Config/ConfigCache.php b/src/Symfony/Component/Config/ConfigCache.php index 1a96bddd3c67d..780e8a0228b32 100644 --- a/src/Symfony/Component/Config/ConfigCache.php +++ b/src/Symfony/Component/Config/ConfigCache.php @@ -99,7 +99,7 @@ public function write($content, array $metadata = null) throw new \RuntimeException(sprintf('Unable to write in the %s directory', $dir)); } - $tmpFile = tempnam(dirname($this->file), basename($this->file)); + $tmpFile = tempnam($dir, basename($this->file)); if (false !== @file_put_contents($tmpFile, $content) && @rename($tmpFile, $this->file)) { @chmod($this->file, 0666 & ~umask()); } else { @@ -108,7 +108,7 @@ public function write($content, array $metadata = null) if (null !== $metadata && true === $this->debug) { $file = $this->file.'.meta'; - $tmpFile = tempnam(dirname($file), basename($file)); + $tmpFile = tempnam($dir, basename($file)); if (false !== @file_put_contents($tmpFile, serialize($metadata)) && @rename($tmpFile, $file)) { @chmod($file, 0666 & ~umask()); } From bb2566c17dfd98cb1d6e7ec3d6a09dcac7d245f2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Haso=C5=88?= Date: Wed, 12 Sep 2012 11:29:58 +0200 Subject: [PATCH 033/975] [Console] Console colorization is also provided by ConEmu on Windows --- src/Symfony/Component/Console/CHANGELOG.md | 5 +++++ src/Symfony/Component/Console/Output/StreamOutput.php | 4 ++-- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/src/Symfony/Component/Console/CHANGELOG.md b/src/Symfony/Component/Console/CHANGELOG.md index 79449d8237a6d..1a0457fc3dd81 100644 --- a/src/Symfony/Component/Console/CHANGELOG.md +++ b/src/Symfony/Component/Console/CHANGELOG.md @@ -1,6 +1,11 @@ CHANGELOG ========= +2.1.2 +----- + + * added support for colorization on Windows via ConEmu + 2.1.0 ----- diff --git a/src/Symfony/Component/Console/Output/StreamOutput.php b/src/Symfony/Component/Console/Output/StreamOutput.php index e00d0655cdddb..bf869fa19f315 100644 --- a/src/Symfony/Component/Console/Output/StreamOutput.php +++ b/src/Symfony/Component/Console/Output/StreamOutput.php @@ -95,7 +95,7 @@ protected function doWrite($message, $newline) * * Colorization is disabled if not supported by the stream: * - * - windows without ansicon + * - windows without ansicon and ConEmu * - non tty consoles * * @return Boolean true if the stream supports colorization, false otherwise @@ -104,7 +104,7 @@ protected function hasColorSupport() { // @codeCoverageIgnoreStart if (DIRECTORY_SEPARATOR == '\\') { - return false !== getenv('ANSICON'); + return false !== getenv('ANSICON') || 'ON' === getenv('ConEmuANSI'); } return function_exists('posix_isatty') && @posix_isatty($this->stream); From 91354311f0bd04dcc87736021fa2e0c203c832cd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Haso=C5=88?= Date: Wed, 5 Sep 2012 10:02:54 +0200 Subject: [PATCH 034/975] [HttpKernel] Added support for WinCache in ConfigDataCollector --- src/Symfony/Component/HttpKernel/CHANGELOG.md | 5 +++ .../DataCollector/ConfigDataCollector.php | 35 ++++++++++++------- .../DataCollector/ConfigDataCollectorTest.php | 4 ++- 3 files changed, 31 insertions(+), 13 deletions(-) diff --git a/src/Symfony/Component/HttpKernel/CHANGELOG.md b/src/Symfony/Component/HttpKernel/CHANGELOG.md index c27de87eca5d9..9863fe25ca677 100644 --- a/src/Symfony/Component/HttpKernel/CHANGELOG.md +++ b/src/Symfony/Component/HttpKernel/CHANGELOG.md @@ -1,6 +1,11 @@ CHANGELOG ========= +2.1.2 +----- + + * added support for WinCache opcode cache in ConfigDataCollector + 2.1.0 ----- diff --git a/src/Symfony/Component/HttpKernel/DataCollector/ConfigDataCollector.php b/src/Symfony/Component/HttpKernel/DataCollector/ConfigDataCollector.php index 81ede39ced0ea..97797a48f23b8 100644 --- a/src/Symfony/Component/HttpKernel/DataCollector/ConfigDataCollector.php +++ b/src/Symfony/Component/HttpKernel/DataCollector/ConfigDataCollector.php @@ -42,17 +42,18 @@ public function setKernel(KernelInterface $kernel) public function collect(Request $request, Response $response, \Exception $exception = null) { $this->data = array( - 'token' => $response->headers->get('X-Debug-Token'), - 'symfony_version' => Kernel::VERSION, - 'name' => isset($this->kernel) ? $this->kernel->getName() : 'n/a', - 'env' => isset($this->kernel) ? $this->kernel->getEnvironment() : 'n/a', - 'debug' => isset($this->kernel) ? $this->kernel->isDebug() : 'n/a', - 'php_version' => PHP_VERSION, - 'xdebug_enabled' => extension_loaded('xdebug'), - 'eaccel_enabled' => extension_loaded('eaccelerator') && ini_get('eaccelerator.enable'), - 'apc_enabled' => extension_loaded('apc') && ini_get('apc.enabled'), - 'xcache_enabled' => extension_loaded('xcache') && ini_get('xcache.cacher'), - 'bundles' => array(), + 'token' => $response->headers->get('X-Debug-Token'), + 'symfony_version' => Kernel::VERSION, + 'name' => isset($this->kernel) ? $this->kernel->getName() : 'n/a', + 'env' => isset($this->kernel) ? $this->kernel->getEnvironment() : 'n/a', + 'debug' => isset($this->kernel) ? $this->kernel->isDebug() : 'n/a', + 'php_version' => PHP_VERSION, + 'xdebug_enabled' => extension_loaded('xdebug'), + 'eaccel_enabled' => extension_loaded('eaccelerator') && ini_get('eaccelerator.enable'), + 'apc_enabled' => extension_loaded('apc') && ini_get('apc.enabled'), + 'xcache_enabled' => extension_loaded('xcache') && ini_get('xcache.cacher'), + 'wincache_enabled' => extension_loaded('wincache') && ini_get('wincache.ocenabled'), + 'bundles' => array(), ); if (isset($this->kernel)) { @@ -162,6 +163,16 @@ public function hasXCache() return $this->data['xcache_enabled']; } + /** + * Returns true if WinCache is enabled. + * + * @return Boolean true if WinCache is enabled, false otherwise + */ + public function hasWinCache() + { + return $this->data['wincache_enabled']; + } + /** * Returns true if any accelerator is enabled. * @@ -169,7 +180,7 @@ public function hasXCache() */ public function hasAccelerator() { - return $this->hasApc() || $this->hasEAccelerator() || $this->hasXCache(); + return $this->hasApc() || $this->hasEAccelerator() || $this->hasXCache() || $this->hasWinCache(); } public function getBundles() diff --git a/src/Symfony/Component/HttpKernel/Tests/DataCollector/ConfigDataCollectorTest.php b/src/Symfony/Component/HttpKernel/Tests/DataCollector/ConfigDataCollectorTest.php index f517c12b2f92a..5a0166d39ec0a 100644 --- a/src/Symfony/Component/HttpKernel/Tests/DataCollector/ConfigDataCollectorTest.php +++ b/src/Symfony/Component/HttpKernel/Tests/DataCollector/ConfigDataCollectorTest.php @@ -53,7 +53,9 @@ public function testCollect() || (extension_loaded('apc') && ini_get('apc.enabled')) || - (extension_loaded('xcache') && ini_get('xcache.cacher')))) { + (extension_loaded('xcache') && ini_get('xcache.cacher')) + || + (extension_loaded('wincache') && ini_get('wincache.ocenabled')))) { $this->assertTrue($c->hasAccelerator()); } else { $this->assertFalse($c->hasAccelerator()); From f6857d4075ba2d48df6860ab196074272ea78e96 Mon Sep 17 00:00:00 2001 From: Fabien Potencier Date: Tue, 18 Sep 2012 15:46:10 +0200 Subject: [PATCH 035/975] updated CHANGELOG --- src/Symfony/Component/Validator/CHANGELOG.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/Symfony/Component/Validator/CHANGELOG.md b/src/Symfony/Component/Validator/CHANGELOG.md index 47687ba91a393..208325ac13a19 100644 --- a/src/Symfony/Component/Validator/CHANGELOG.md +++ b/src/Symfony/Component/Validator/CHANGELOG.md @@ -1,6 +1,11 @@ CHANGELOG ========= +2.2.0 +----- + + * added a Luhn validator + 2.1.0 ----- From 71db836e1f27c5b2039a7c5c4346179f83ca783c Mon Sep 17 00:00:00 2001 From: Jeanmonod David Date: Tue, 12 Jun 2012 17:47:41 +0200 Subject: [PATCH 036/975] Better config validation handling for numerical values: * New node type Integer and Float * New expressions: min() and max() --- .../Builder/FloatNodeDefinition.php | 32 +++++++ .../Builder/IntegerNodeDefinition.php | 32 +++++++ .../Config/Definition/Builder/NodeBuilder.php | 26 ++++++ .../Builder/NumericNodeDefinition.php | 58 +++++++++++++ .../Component/Config/Definition/FloatNode.php | 44 ++++++++++ .../Config/Definition/IntegerNode.php | 39 +++++++++ .../Config/Definition/NumericNode.php | 56 +++++++++++++ .../Definition/Builder/ExprBuilderTest.php | 13 +-- .../Definition/Builder/NodeBuilderTest.php | 11 +++ .../Builder/NumericNodeDefinitionTest.php | 84 +++++++++++++++++++ .../Config/Tests/Definition/FloatNodeTest.php | 64 ++++++++++++++ .../Tests/Definition/IntegerNodeTest.php | 61 ++++++++++++++ 12 files changed, 514 insertions(+), 6 deletions(-) create mode 100644 src/Symfony/Component/Config/Definition/Builder/FloatNodeDefinition.php create mode 100644 src/Symfony/Component/Config/Definition/Builder/IntegerNodeDefinition.php create mode 100644 src/Symfony/Component/Config/Definition/Builder/NumericNodeDefinition.php create mode 100644 src/Symfony/Component/Config/Definition/FloatNode.php create mode 100644 src/Symfony/Component/Config/Definition/IntegerNode.php create mode 100644 src/Symfony/Component/Config/Definition/NumericNode.php create mode 100755 src/Symfony/Component/Config/Tests/Definition/Builder/NumericNodeDefinitionTest.php create mode 100644 src/Symfony/Component/Config/Tests/Definition/FloatNodeTest.php create mode 100644 src/Symfony/Component/Config/Tests/Definition/IntegerNodeTest.php diff --git a/src/Symfony/Component/Config/Definition/Builder/FloatNodeDefinition.php b/src/Symfony/Component/Config/Definition/Builder/FloatNodeDefinition.php new file mode 100644 index 0000000000000..b8fc34d0ead41 --- /dev/null +++ b/src/Symfony/Component/Config/Definition/Builder/FloatNodeDefinition.php @@ -0,0 +1,32 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Config\Definition\Builder; + +use Symfony\Component\Config\Definition\FloatNode; + +/** + * This class provides a fluent interface for defining a float node. + * + * @author Jeanmonod David + */ +class FloatNodeDefinition extends NumericNodeDefinition +{ + /** + * Instantiate a Node + * + * @return FloatNode The node + */ + protected function instantiateNode() + { + return new FloatNode($this->name, $this->parent, $this->min, $this->max); + } +} diff --git a/src/Symfony/Component/Config/Definition/Builder/IntegerNodeDefinition.php b/src/Symfony/Component/Config/Definition/Builder/IntegerNodeDefinition.php new file mode 100644 index 0000000000000..d3d6179276edf --- /dev/null +++ b/src/Symfony/Component/Config/Definition/Builder/IntegerNodeDefinition.php @@ -0,0 +1,32 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Config\Definition\Builder; + +use Symfony\Component\Config\Definition\IntegerNode; + +/** + * This class provides a fluent interface for defining an integer node. + * + * @author Jeanmonod David + */ +class IntegerNodeDefinition extends NumericNodeDefinition +{ + /** + * Instantiate a Node + * + * @return IntegerNode The node + */ + protected function instantiateNode() + { + return new IntegerNode($this->name, $this->parent, $this->min, $this->max); + } +} diff --git a/src/Symfony/Component/Config/Definition/Builder/NodeBuilder.php b/src/Symfony/Component/Config/Definition/Builder/NodeBuilder.php index c960ac43a6c12..a53685a22e57c 100644 --- a/src/Symfony/Component/Config/Definition/Builder/NodeBuilder.php +++ b/src/Symfony/Component/Config/Definition/Builder/NodeBuilder.php @@ -31,6 +31,8 @@ public function __construct() 'variable' => __NAMESPACE__.'\\VariableNodeDefinition', 'scalar' => __NAMESPACE__.'\\ScalarNodeDefinition', 'boolean' => __NAMESPACE__.'\\BooleanNodeDefinition', + 'integer' => __NAMESPACE__.'\\IntegerNodeDefinition', + 'float' => __NAMESPACE__.'\\FloatNodeDefinition', 'array' => __NAMESPACE__.'\\ArrayNodeDefinition', 'enum' => __NAMESPACE__.'\\EnumNodeDefinition', ); @@ -86,6 +88,30 @@ public function booleanNode($name) return $this->node($name, 'boolean'); } + /** + * Creates a child integer node. + * + * @param string $name the name of the node + * + * @return IntegerNodeDefinition The child node + */ + public function integerNode($name) + { + return $this->node($name, 'integer'); + } + + /** + * Creates a child float node. + * + * @param string $name the name of the node + * + * @return FloatNodeDefinition The child node + */ + public function floatNode($name) + { + return $this->node($name, 'float'); + } + /** * Creates a child EnumNode. * diff --git a/src/Symfony/Component/Config/Definition/Builder/NumericNodeDefinition.php b/src/Symfony/Component/Config/Definition/Builder/NumericNodeDefinition.php new file mode 100644 index 0000000000000..54f6d86f6d910 --- /dev/null +++ b/src/Symfony/Component/Config/Definition/Builder/NumericNodeDefinition.php @@ -0,0 +1,58 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Config\Definition\Builder; + +/** + * Abstract class that contain common code of integer and float node definition. + * + * @author David Jeanmonod + */ +abstract class NumericNodeDefinition extends ScalarNodeDefinition +{ + + protected $min; + protected $max; + + /** + * Ensure the value is smaller than the given reference + * + * @param mixed $max + * + * @return NumericNodeDefinition + */ + public function max($max) + { + if (isset($this->min) && $this->min > $max) { + throw new \InvalidArgumentException(sprintf('You cannot define a max(%s) as you already have a min(%s)', $max, $this->min)); + } + $this->max = $max; + + return $this; + } + + /** + * Ensure the value is bigger than the given reference + * + * @param mixed $min + * + * @return NumericNodeDefinition + */ + public function min($min) + { + if (isset($this->max) && $this->max < $min) { + throw new \InvalidArgumentException(sprintf('You cannot define a min(%s) as you already have a max(%s)', $min, $this->max)); + } + $this->min = $min; + + return $this; + } +} diff --git a/src/Symfony/Component/Config/Definition/FloatNode.php b/src/Symfony/Component/Config/Definition/FloatNode.php new file mode 100644 index 0000000000000..782bd8b708d90 --- /dev/null +++ b/src/Symfony/Component/Config/Definition/FloatNode.php @@ -0,0 +1,44 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Config\Definition; + +use Symfony\Component\Config\Definition\Exception\InvalidTypeException; + +/** + * This node represents a float value in the config tree. + * + * @author Jeanmonod David + */ +class FloatNode extends NumericNode +{ + /** + * {@inheritDoc} + */ + protected function validateType($value) + { + // Integers are also accepted, we just cast them + if (is_int($value)) { + $value = (float) $value; + } + + if (!is_float($value)) { + $ex = new InvalidTypeException(sprintf( + 'Invalid type for path "%s". Expected float, but got %s.', + $this->getPath(), + gettype($value) + )); + $ex->setPath($this->getPath()); + + throw $ex; + } + } +} diff --git a/src/Symfony/Component/Config/Definition/IntegerNode.php b/src/Symfony/Component/Config/Definition/IntegerNode.php new file mode 100644 index 0000000000000..7a5c394513e81 --- /dev/null +++ b/src/Symfony/Component/Config/Definition/IntegerNode.php @@ -0,0 +1,39 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Config\Definition; + +use Symfony\Component\Config\Definition\Exception\InvalidTypeException; + +/** + * This node represents an integer value in the config tree. + * + * @author Jeanmonod David + */ +class IntegerNode extends NumericNode +{ + /** + * {@inheritDoc} + */ + protected function validateType($value) + { + if (!is_int($value)) { + $ex = new InvalidTypeException(sprintf( + 'Invalid type for path "%s". Expected int, but got %s.', + $this->getPath(), + gettype($value) + )); + $ex->setPath($this->getPath()); + + throw $ex; + } + } +} diff --git a/src/Symfony/Component/Config/Definition/NumericNode.php b/src/Symfony/Component/Config/Definition/NumericNode.php new file mode 100644 index 0000000000000..88c0caa628d76 --- /dev/null +++ b/src/Symfony/Component/Config/Definition/NumericNode.php @@ -0,0 +1,56 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Config\Definition; + +use Symfony\Component\Config\Definition\Exception\InvalidConfigurationException; + +/** + * This node represents a numeric value in the config tree + * + * @author David Jeanmonod + */ +class NumericNode extends ScalarNode +{ + protected $min; + protected $max; + + public function __construct($name, NodeInterface $parent = null, $min = null, $max = null) + { + parent::__construct($name, $parent); + $this->min = $min; + $this->max = $max; + } + + /** + * {@inheritDoc} + */ + protected function finalizeValue($value) + { + $value = parent::finalizeValue($value); + + $errorMsg = null; + if (isset($this->min) && $value < $this->min) { + $errorMsg = sprintf('The value %s is too small for path "%s". Should be greater than: %s', $value, $this->getPath(), $this->min); + } + if (isset($this->max) && $value > $this->max) { + $errorMsg = sprintf('The value %s is too big for path "%s". Should be less than: %s', $value, $this->getPath(), $this->max); + } + if (isset($errorMsg)) { + $ex = new InvalidConfigurationException($errorMsg); + $ex->setPath($this->getPath()); + throw $ex; + } + + return $value; + } + +} diff --git a/src/Symfony/Component/Config/Tests/Definition/Builder/ExprBuilderTest.php b/src/Symfony/Component/Config/Tests/Definition/Builder/ExprBuilderTest.php index 7d4c72bb26b66..9c7b71902e11c 100644 --- a/src/Symfony/Component/Config/Tests/Definition/Builder/ExprBuilderTest.php +++ b/src/Symfony/Component/Config/Tests/Definition/Builder/ExprBuilderTest.php @@ -13,7 +13,6 @@ use Symfony\Component\Config\Definition\Builder\TreeBuilder; - class ExprBuilderTest extends \PHPUnit_Framework_TestCase { @@ -160,6 +159,7 @@ public function testThenUnsetExpression() protected function getTestBuilder() { $builder = new TreeBuilder(); + return $builder ->root('test') ->children() @@ -171,7 +171,7 @@ protected function getTestBuilder() /** * Close the validation process and finalize with the given config * @param TreeBuilder $testBuilder The tree builder to finalize - * @param array $config The config you want to use for the finalization, if nothing provided + * @param array $config The config you want to use for the finalization, if nothing provided * a simple array('key'=>'value') will be used * @return array The finalized config values */ @@ -191,7 +191,8 @@ protected function finalizeTestBuilder($testBuilder, $config=null) * @param $val The value that the closure must return * @return Closure */ - protected function returnClosure($val) { + protected function returnClosure($val) + { return function($v) use ($val) { return $val; }; @@ -199,9 +200,9 @@ protected function returnClosure($val) { /** * Assert that the given test builder, will return the given value - * @param mixed $value The value to test - * @param TreeBuilder $test The tree builder to finalize - * @param mixed $config The config values that new to be finalized + * @param mixed $value The value to test + * @param TreeBuilder $test The tree builder to finalize + * @param mixed $config The config values that new to be finalized */ protected function assertFinalizedValueIs($value, $treeBuilder, $config=null) { diff --git a/src/Symfony/Component/Config/Tests/Definition/Builder/NodeBuilderTest.php b/src/Symfony/Component/Config/Tests/Definition/Builder/NodeBuilderTest.php index c8295916908a3..8d0a845309947 100644 --- a/src/Symfony/Component/Config/Tests/Definition/Builder/NodeBuilderTest.php +++ b/src/Symfony/Component/Config/Tests/Definition/Builder/NodeBuilderTest.php @@ -76,6 +76,17 @@ public function testNodeTypesAreNotCaseSensitive() $this->assertEquals(get_class($node1), get_class($node2)); } + + public function testNumericNodeCreation() + { + $builder = new NodeBuilder(); + + $node = $builder->integerNode('foo')->min(3)->max(5); + $this->assertEquals('Symfony\Component\Config\Definition\Builder\IntegerNodeDefinition', get_class($node)); + + $node = $builder->floatNode('bar')->min(3.0)->max(5.0); + $this->assertEquals('Symfony\Component\Config\Definition\Builder\FloatNodeDefinition', get_class($node)); + } } class SomeNodeDefinition extends BaseVariableNodeDefinition diff --git a/src/Symfony/Component/Config/Tests/Definition/Builder/NumericNodeDefinitionTest.php b/src/Symfony/Component/Config/Tests/Definition/Builder/NumericNodeDefinitionTest.php new file mode 100755 index 0000000000000..0add0db5682cb --- /dev/null +++ b/src/Symfony/Component/Config/Tests/Definition/Builder/NumericNodeDefinitionTest.php @@ -0,0 +1,84 @@ +max(3)->min(4); + } + + /** + * @expectedException \InvalidArgumentException + * @expectedExceptionMessage You cannot define a max(2) as you already have a min(3) + */ + public function testIncoherentMaxAssertion() + { + $node = new NumericNodeDefinition('foo'); + $node->min(3)->max(2); + } + + /** + * @expectedException Symfony\Component\Config\Definition\Exception\InvalidConfigurationException + * @expectedExceptionMessage The value 4 is too small for path "foo". Should be greater than: 5 + */ + public function testIntegerMinAssertion() + { + $def = new IntegerNodeDefinition('foo'); + $def->min(5)->getNode()->finalize(4); + } + + /** + * @expectedException Symfony\Component\Config\Definition\Exception\InvalidConfigurationException + * @expectedExceptionMessage The value 4 is too big for path "foo". Should be less than: 3 + */ + public function testIntegerMaxAssertion() + { + $def = new IntegerNodeDefinition('foo'); + $def->max(3)->getNode()->finalize(4); + } + + public function testIntegerValidMinMaxAssertion() + { + $def = new IntegerNodeDefinition('foo'); + $node = $def->min(3)->max(7)->getNode(); + $this->assertEquals(4, $node->finalize(4)); + } + + /** + * @expectedException Symfony\Component\Config\Definition\Exception\InvalidConfigurationException + * @expectedExceptionMessage The value 400 is too small for path "foo". Should be greater than: 500 + */ + public function testFloatMinAssertion() + { + $def = new FloatNodeDefinition('foo'); + $def->min(5E2)->getNode()->finalize(4e2); + } + + /** + * @expectedException Symfony\Component\Config\Definition\Exception\InvalidConfigurationException + * @expectedExceptionMessage The value 4.3 is too big for path "foo". Should be less than: 0.3 + */ + public function testFloatMaxAssertion() + { + $def = new FloatNodeDefinition('foo'); + $def->max(0.3)->getNode()->finalize(4.3); + } + + public function testFloatValidMinMaxAssertion() + { + $def = new FloatNodeDefinition('foo'); + $node = $def->min(3.0)->max(7e2)->getNode(); + $this->assertEquals(4.5, $node->finalize(4.5)); + } +} diff --git a/src/Symfony/Component/Config/Tests/Definition/FloatNodeTest.php b/src/Symfony/Component/Config/Tests/Definition/FloatNodeTest.php new file mode 100644 index 0000000000000..b91446e1c8c9c --- /dev/null +++ b/src/Symfony/Component/Config/Tests/Definition/FloatNodeTest.php @@ -0,0 +1,64 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Config\Tests\Definition; + +use Symfony\Component\Config\Definition\FloatNode; + +class FloatNodeTest extends \PHPUnit_Framework_TestCase +{ + /** + * @dataProvider getValidValues + */ + public function testNormalize($value) + { + $node = new FloatNode('test'); + $this->assertSame($value, $node->normalize($value)); + } + + public function getValidValues() + { + return array( + array(1798.0), + array(-678.987), + array(12.56E45), + array(0.0), + // Integer are accepted too, they will be cast + array(17), + array(-10), + array(0) + ); + } + + /** + * @dataProvider getInvalidValues + * @expectedException Symfony\Component\Config\Definition\Exception\InvalidTypeException + */ + public function testNormalizeThrowsExceptionOnInvalidValues($value) + { + $node = new FloatNode('test'); + $node->normalize($value); + } + + public function getInvalidValues() + { + return array( + array(null), + array(''), + array('foo'), + array(true), + array(false), + array(array()), + array(array('foo' => 'bar')), + array(new \stdClass()), + ); + } +} diff --git a/src/Symfony/Component/Config/Tests/Definition/IntegerNodeTest.php b/src/Symfony/Component/Config/Tests/Definition/IntegerNodeTest.php new file mode 100644 index 0000000000000..11d53153069fc --- /dev/null +++ b/src/Symfony/Component/Config/Tests/Definition/IntegerNodeTest.php @@ -0,0 +1,61 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Config\Tests\Definition; + +use Symfony\Component\Config\Definition\IntegerNode; + +class IntegerNodeTest extends \PHPUnit_Framework_TestCase +{ + /** + * @dataProvider getValidValues + */ + public function testNormalize($value) + { + $node = new IntegerNode('test'); + $this->assertSame($value, $node->normalize($value)); + } + + public function getValidValues() + { + return array( + array(1798), + array(-678), + array(0), + ); + } + + /** + * @dataProvider getInvalidValues + * @expectedException Symfony\Component\Config\Definition\Exception\InvalidTypeException + */ + public function testNormalizeThrowsExceptionOnInvalidValues($value) + { + $node = new IntegerNode('test'); + $node->normalize($value); + } + + public function getInvalidValues() + { + return array( + array(null), + array(''), + array('foo'), + array(true), + array(false), + array(0.0), + array(0.1), + array(array()), + array(array('foo' => 'bar')), + array(new \stdClass()), + ); + } +} From bafe89047fbad1dc12cde5e3b0a62de651cf6bfb Mon Sep 17 00:00:00 2001 From: Fabien Potencier Date: Tue, 18 Sep 2012 16:33:46 +0200 Subject: [PATCH 037/975] [FrameworkBundle] changed Client::enableProfiler() behavior to fail silently when the profiler is not available (it makes it easier to write functional tests) --- src/Symfony/Bundle/FrameworkBundle/Client.php | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/src/Symfony/Bundle/FrameworkBundle/Client.php b/src/Symfony/Bundle/FrameworkBundle/Client.php index 3874573f90d74..ec4e4aa64789e 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Client.php +++ b/src/Symfony/Bundle/FrameworkBundle/Client.php @@ -65,15 +65,13 @@ public function getProfile() /** * Enables the profiler for the very next request. * - * @throws \LogicException if the profiler is not configured in the service container + * If the profiler is not enabled, the call to this method does nothing. */ public function enableProfiler() { - if (!$this->kernel->getContainer()->has('profiler')) { - throw new \LogicException('You cannot enable the profiler as it is not configured in the service container.'); + if ($this->kernel->getContainer()->has('profiler')) { + $this->profiler = true; } - - $this->profiler = true; } /** From 22e9036f8ce7c08b38ef222e5e967e0da0c8b460 Mon Sep 17 00:00:00 2001 From: Fabien Potencier Date: Tue, 18 Sep 2012 16:34:09 +0200 Subject: [PATCH 038/975] updated CHANGELOG --- src/Symfony/Bundle/FrameworkBundle/CHANGELOG.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/Symfony/Bundle/FrameworkBundle/CHANGELOG.md b/src/Symfony/Bundle/FrameworkBundle/CHANGELOG.md index da9db7ca3ecc0..bcb3a0adc85f8 100644 --- a/src/Symfony/Bundle/FrameworkBundle/CHANGELOG.md +++ b/src/Symfony/Bundle/FrameworkBundle/CHANGELOG.md @@ -1,6 +1,11 @@ CHANGELOG ========= +2.2.0 +----- + + * added Client::enableProfiler() + 2.1.0 ----- From f9467128ad321fca450c62acaff0c0d78fd8b91a Mon Sep 17 00:00:00 2001 From: Fabien Potencier Date: Tue, 18 Sep 2012 19:22:28 +0200 Subject: [PATCH 039/975] fixed CHANGELOG --- src/Symfony/Component/HttpKernel/CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Symfony/Component/HttpKernel/CHANGELOG.md b/src/Symfony/Component/HttpKernel/CHANGELOG.md index 9863fe25ca677..ae2e0f5bee548 100644 --- a/src/Symfony/Component/HttpKernel/CHANGELOG.md +++ b/src/Symfony/Component/HttpKernel/CHANGELOG.md @@ -1,7 +1,7 @@ CHANGELOG ========= -2.1.2 +2.2.0 ----- * added support for WinCache opcode cache in ConfigDataCollector From 3ae0b4731fa3a4433faa9e749546316b84211033 Mon Sep 17 00:00:00 2001 From: Fabien Potencier Date: Tue, 18 Sep 2012 19:29:43 +0200 Subject: [PATCH 040/975] fixed CHANGELOG --- src/Symfony/Component/Console/CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Symfony/Component/Console/CHANGELOG.md b/src/Symfony/Component/Console/CHANGELOG.md index 1a0457fc3dd81..9d3466d70967e 100644 --- a/src/Symfony/Component/Console/CHANGELOG.md +++ b/src/Symfony/Component/Console/CHANGELOG.md @@ -1,7 +1,7 @@ CHANGELOG ========= -2.1.2 +2.2.0 ----- * added support for colorization on Windows via ConEmu From 05d8c4288cd174d82ea07105e2dfd523fa3a162e Mon Sep 17 00:00:00 2001 From: Fabien Potencier Date: Wed, 19 Sep 2012 05:59:05 +0200 Subject: [PATCH 041/975] [FrameworkBundle] fixed the typehint for Kernel on the Client class (refs #4897) --- src/Symfony/Bundle/FrameworkBundle/Client.php | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/src/Symfony/Bundle/FrameworkBundle/Client.php b/src/Symfony/Bundle/FrameworkBundle/Client.php index ec4e4aa64789e..46928d2f12415 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Client.php +++ b/src/Symfony/Bundle/FrameworkBundle/Client.php @@ -12,11 +12,13 @@ namespace Symfony\Bundle\FrameworkBundle; use Symfony\Component\DependencyInjection\ContainerInterface; -use Symfony\Component\HttpKernel\HttpKernelInterface; +use Symfony\Component\HttpKernel\KernelInterface; use Symfony\Component\HttpKernel\Client as BaseClient; use Symfony\Component\HttpKernel\Profiler\Profile as HttpProfile; use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\Response; +use Symfony\Component\BrowserKit\History; +use Symfony\Component\BrowserKit\CookieJar; /** * Client simulates a browser and makes requests to a Kernel object. @@ -28,6 +30,14 @@ class Client extends BaseClient private $hasPerformedRequest = false; private $profiler = false; + /** + * @inheritdoc + */ + public function __construct(KernelInterface $kernel, array $server = array(), History $history = null, CookieJar $cookieJar = null) + { + parent::__construct($kernel, $server, $history, $cookieJar); + } + /** * Returns the container. * @@ -41,7 +51,7 @@ public function getContainer() /** * Returns the kernel. * - * @return HttpKernelInterface + * @return KernelInterface */ public function getKernel() { From be331ca7f2bab213e5997151bcdc89347bc356dc Mon Sep 17 00:00:00 2001 From: Fabien Potencier Date: Wed, 19 Sep 2012 06:19:30 +0200 Subject: [PATCH 042/975] [FrameworkBundle] fixed functional tests --- .../Bundle/FrameworkBundle/Tests/Functional/WebTestCase.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Symfony/Bundle/FrameworkBundle/Tests/Functional/WebTestCase.php b/src/Symfony/Bundle/FrameworkBundle/Tests/Functional/WebTestCase.php index affbeb93d3f6c..8cf0dfead75dc 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Tests/Functional/WebTestCase.php +++ b/src/Symfony/Bundle/FrameworkBundle/Tests/Functional/WebTestCase.php @@ -60,7 +60,7 @@ protected static function createKernel(array $options = array()) return new $class( $options['test_case'], isset($options['root_config']) ? $options['root_config'] : 'config.yml', - isset($options['environment']) ? $options['environment'] : 'frameworkbundletest', + isset($options['environment']) ? $options['environment'] : 'frameworkbundletest'.strtolower($options['test_case']), isset($options['debug']) ? $options['debug'] : true ); } From b89e413a93682a6ce8f6cb3e5d533c7e945172a0 Mon Sep 17 00:00:00 2001 From: Romain Neutron Date: Wed, 19 Sep 2012 02:35:24 +0200 Subject: [PATCH 043/975] [Process] Add output / error output incremental getters --- src/Symfony/Component/Process/Process.php | 41 +++++++++++++++++++ .../Process/Tests/AbstractProcessTest.php | 38 +++++++++++++++++ 2 files changed, 79 insertions(+) diff --git a/src/Symfony/Component/Process/Process.php b/src/Symfony/Component/Process/Process.php index 699e2647c86b5..83155d80b1085 100644 --- a/src/Symfony/Component/Process/Process.php +++ b/src/Symfony/Component/Process/Process.php @@ -51,6 +51,8 @@ class Process private $pipes; private $process; private $status = self::STATUS_READY; + private $incrementalOutputOffset; + private $incrementalErrorOutputOffset; private $fileHandles; private $readBytes; @@ -205,6 +207,8 @@ public function start($callback = null) $this->stdout = ''; $this->stderr = ''; + $this->incrementalOutputOffset = 0; + $this->incrementalErrorOutputOffset = 0; $callback = $this->buildCallback($callback); //Fix for PHP bug #51800: reading from STDOUT pipe hangs forever on Windows if the output is too big. @@ -413,6 +417,24 @@ public function getOutput() return $this->stdout; } + /** + * Returns the output incrementally. + * + * In comparison with the getOutput method which always return the whole + * output, this one returns the new output since the last call. + * + * @return string The process output since the last call + */ + public function getIncrementalOutput() + { + $data = $this->getOutput(); + + $latest = substr($data, $this->incrementalOutputOffset); + $this->incrementalOutputOffset = strlen($data); + + return $latest; + } + /** * Returns the current error output of the process (STDERR). * @@ -427,6 +449,25 @@ public function getErrorOutput() return $this->stderr; } + /** + * Returns the errorOutput incrementally. + * + * In comparison with the getErrorOutput method which always return the + * whole error output, this one returns the new error output since the last + * call. + * + * @return string The process error output since the last call + */ + public function getIncrementalErrorOutput() + { + $data = $this->getErrorOutput(); + + $latest = substr($data, $this->incrementalErrorOutputOffset); + $this->incrementalErrorOutputOffset = strlen($data); + + return $latest; + } + /** * Returns the exit code returned by the process. * diff --git a/src/Symfony/Component/Process/Tests/AbstractProcessTest.php b/src/Symfony/Component/Process/Tests/AbstractProcessTest.php index 1b443502bd0f3..a9b5009dd6e6c 100644 --- a/src/Symfony/Component/Process/Tests/AbstractProcessTest.php +++ b/src/Symfony/Component/Process/Tests/AbstractProcessTest.php @@ -88,6 +88,44 @@ public function testCallbackIsExecutedForOutput() $this->assertTrue($called, 'The callback should be executed with the output'); } + public function testGetErrorOutput() + { + $p = new Process(sprintf('php -r %s', escapeshellarg('ini_set(\'display_errors\',\'on\');$n=0;while($n<3){echo $a;$n++;}'))); + + $p->run(); + $this->assertEquals(3, preg_match_all('/PHP Notice/', $p->getErrorOutput(), $matches)); + } + + public function testGetIncrementalErrorOutput() + { + $p = new Process(sprintf('php -r %s', escapeshellarg('ini_set(\'display_errors\',\'on\');usleep(50000);$n=0;while($n<3){echo $a;$n++;}'))); + + $p->start(); + while($p->isRunning()) { + $this->assertLessThanOrEqual(1, preg_match_all('/PHP Notice/', $p->getIncrementalOutput(), $matches)); + usleep(20000); + } + } + + public function testGetOutput() + { + $p = new Process(sprintf('php -r %s', escapeshellarg('$n=0;while($n<3){echo \' foo \';$n++;}'))); + + $p->run(); + $this->assertEquals(3, preg_match_all('/foo/', $p->getOutput(), $matches)); + } + + public function testGetIncrementalOutput() + { + $p = new Process(sprintf('php -r %s', escapeshellarg('$n=0;while($n<3){echo \' foo \';usleep(50000);$n++;}'))); + + $p->start(); + while($p->isRunning()) { + $this->assertLessThanOrEqual(1, preg_match_all('/foo/', $p->getIncrementalOutput(), $matches)); + usleep(20000); + } + } + public function testExitCodeCommandFailed() { if (defined('PHP_WINDOWS_VERSION_BUILD')) { From c9029664ad3c307f81efa9d3322170a96fca9398 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Haso=C5=88?= Date: Fri, 31 Aug 2012 15:38:13 +0200 Subject: [PATCH 044/975] [DomCrawler] Added ability to set file as raw path to file field --- src/Symfony/Component/DomCrawler/CHANGELOG.md | 6 ++++++ .../Component/DomCrawler/Field/FileFormField.php | 10 ++++++++++ .../DomCrawler/Tests/Field/FileFormFieldTest.php | 10 ++++++++++ 3 files changed, 26 insertions(+) diff --git a/src/Symfony/Component/DomCrawler/CHANGELOG.md b/src/Symfony/Component/DomCrawler/CHANGELOG.md index 50edf20d8a4ad..815162c146dd8 100644 --- a/src/Symfony/Component/DomCrawler/CHANGELOG.md +++ b/src/Symfony/Component/DomCrawler/CHANGELOG.md @@ -1,6 +1,12 @@ CHANGELOG ========= +2.2.0 +----- + + * added a way to set raw path to the file in FileFormField - necessary for + simulating HTTP requests + 2.1.0 ----- diff --git a/src/Symfony/Component/DomCrawler/Field/FileFormField.php b/src/Symfony/Component/DomCrawler/Field/FileFormField.php index 1bb08afde9300..a00e65613af95 100644 --- a/src/Symfony/Component/DomCrawler/Field/FileFormField.php +++ b/src/Symfony/Component/DomCrawler/Field/FileFormField.php @@ -76,6 +76,16 @@ public function setValue($value) $this->value = array('name' => $name, 'type' => '', 'tmp_name' => $value, 'error' => $error, 'size' => $size); } + /** + * Sets path to the file as string for simulating HTTP request + * + * @param string $path The path to the file + */ + public function setFilePath($path) + { + parent::setValue($path); + } + /** * Initializes the form field. * diff --git a/src/Symfony/Component/DomCrawler/Tests/Field/FileFormFieldTest.php b/src/Symfony/Component/DomCrawler/Tests/Field/FileFormFieldTest.php index 95937ca01cccb..ea3840a18dddb 100644 --- a/src/Symfony/Component/DomCrawler/Tests/Field/FileFormFieldTest.php +++ b/src/Symfony/Component/DomCrawler/Tests/Field/FileFormFieldTest.php @@ -84,4 +84,14 @@ public function testSetErrorCode() $this->assertTrue(true, '->setErrorCode() throws a \InvalidArgumentException if the error code is not valid'); } } + + public function testSetRawFilePath() + { + $node = $this->createNode('input', '', array('type' => 'file')); + $field = new FileFormField($node); + $field->setFilePath(__FILE__); + + $this->assertEquals(__FILE__, $field->getValue()); + } + } From 46d90ce845fd8165d5f57e16cc6ea9f059a161aa Mon Sep 17 00:00:00 2001 From: Fabien Potencier Date: Thu, 20 Sep 2012 07:46:50 +0200 Subject: [PATCH 045/975] [Config] fixed CS --- .../Config/Definition/Builder/FloatNodeDefinition.php | 2 +- .../Config/Definition/Builder/IntegerNodeDefinition.php | 2 +- .../Config/Definition/Builder/NumericNodeDefinition.php | 9 ++++++--- src/Symfony/Component/Config/Definition/FloatNode.php | 6 +----- src/Symfony/Component/Config/Definition/IntegerNode.php | 6 +----- src/Symfony/Component/Config/Definition/NumericNode.php | 1 - .../Config/Tests/Definition/Builder/ExprBuilderTest.php | 4 ++-- .../Definition/Builder/NumericNodeDefinitionTest.php | 9 +++++++++ 8 files changed, 21 insertions(+), 18 deletions(-) diff --git a/src/Symfony/Component/Config/Definition/Builder/FloatNodeDefinition.php b/src/Symfony/Component/Config/Definition/Builder/FloatNodeDefinition.php index b8fc34d0ead41..c0bed462bf385 100644 --- a/src/Symfony/Component/Config/Definition/Builder/FloatNodeDefinition.php +++ b/src/Symfony/Component/Config/Definition/Builder/FloatNodeDefinition.php @@ -21,7 +21,7 @@ class FloatNodeDefinition extends NumericNodeDefinition { /** - * Instantiate a Node + * Instantiates a Node. * * @return FloatNode The node */ diff --git a/src/Symfony/Component/Config/Definition/Builder/IntegerNodeDefinition.php b/src/Symfony/Component/Config/Definition/Builder/IntegerNodeDefinition.php index d3d6179276edf..f6c3c147f3e6a 100644 --- a/src/Symfony/Component/Config/Definition/Builder/IntegerNodeDefinition.php +++ b/src/Symfony/Component/Config/Definition/Builder/IntegerNodeDefinition.php @@ -21,7 +21,7 @@ class IntegerNodeDefinition extends NumericNodeDefinition { /** - * Instantiate a Node + * Instantiates a Node. * * @return IntegerNode The node */ diff --git a/src/Symfony/Component/Config/Definition/Builder/NumericNodeDefinition.php b/src/Symfony/Component/Config/Definition/Builder/NumericNodeDefinition.php index 54f6d86f6d910..5b6e9550bf3cd 100644 --- a/src/Symfony/Component/Config/Definition/Builder/NumericNodeDefinition.php +++ b/src/Symfony/Component/Config/Definition/Builder/NumericNodeDefinition.php @@ -18,16 +18,17 @@ */ abstract class NumericNodeDefinition extends ScalarNodeDefinition { - protected $min; protected $max; /** - * Ensure the value is smaller than the given reference + * Ensures that the value is smaller than the given reference. * * @param mixed $max * * @return NumericNodeDefinition + * + * @throws \InvalidArgumentException when the constraint is inconsistent */ public function max($max) { @@ -40,11 +41,13 @@ public function max($max) } /** - * Ensure the value is bigger than the given reference + * Ensures that the value is bigger than the given reference. * * @param mixed $min * * @return NumericNodeDefinition + * + * @throws \InvalidArgumentException when the constraint is inconsistent */ public function min($min) { diff --git a/src/Symfony/Component/Config/Definition/FloatNode.php b/src/Symfony/Component/Config/Definition/FloatNode.php index 782bd8b708d90..17c570acaa795 100644 --- a/src/Symfony/Component/Config/Definition/FloatNode.php +++ b/src/Symfony/Component/Config/Definition/FloatNode.php @@ -31,11 +31,7 @@ protected function validateType($value) } if (!is_float($value)) { - $ex = new InvalidTypeException(sprintf( - 'Invalid type for path "%s". Expected float, but got %s.', - $this->getPath(), - gettype($value) - )); + $ex = new InvalidTypeException(sprintf('Invalid type for path "%s". Expected float, but got %s.', $this->getPath(), gettype($value))); $ex->setPath($this->getPath()); throw $ex; diff --git a/src/Symfony/Component/Config/Definition/IntegerNode.php b/src/Symfony/Component/Config/Definition/IntegerNode.php index 7a5c394513e81..dbc04122fadf0 100644 --- a/src/Symfony/Component/Config/Definition/IntegerNode.php +++ b/src/Symfony/Component/Config/Definition/IntegerNode.php @@ -26,11 +26,7 @@ class IntegerNode extends NumericNode protected function validateType($value) { if (!is_int($value)) { - $ex = new InvalidTypeException(sprintf( - 'Invalid type for path "%s". Expected int, but got %s.', - $this->getPath(), - gettype($value) - )); + $ex = new InvalidTypeException(sprintf('Invalid type for path "%s". Expected int, but got %s.', $this->getPath(), gettype($value))); $ex->setPath($this->getPath()); throw $ex; diff --git a/src/Symfony/Component/Config/Definition/NumericNode.php b/src/Symfony/Component/Config/Definition/NumericNode.php index 88c0caa628d76..df45f2ebefd46 100644 --- a/src/Symfony/Component/Config/Definition/NumericNode.php +++ b/src/Symfony/Component/Config/Definition/NumericNode.php @@ -52,5 +52,4 @@ protected function finalizeValue($value) return $value; } - } diff --git a/src/Symfony/Component/Config/Tests/Definition/Builder/ExprBuilderTest.php b/src/Symfony/Component/Config/Tests/Definition/Builder/ExprBuilderTest.php index bea34dca4b46e..d30f3f3ff7d42 100644 --- a/src/Symfony/Component/Config/Tests/Definition/Builder/ExprBuilderTest.php +++ b/src/Symfony/Component/Config/Tests/Definition/Builder/ExprBuilderTest.php @@ -175,7 +175,7 @@ protected function getTestBuilder() * a simple array('key'=>'value') will be used * @return array The finalized config values */ - protected function finalizeTestBuilder($testBuilder, $config=null) + protected function finalizeTestBuilder($testBuilder, $config = null) { return $testBuilder ->end() @@ -205,7 +205,7 @@ protected function returnClosure($val) * @param TreeBuilder $treeBuilder The tree builder to finalize * @param mixed $config The config values that new to be finalized */ - protected function assertFinalizedValueIs($value, $treeBuilder, $config=null) + protected function assertFinalizedValueIs($value, $treeBuilder, $config = null) { $this->assertEquals(array('key'=>$value), $this->finalizeTestBuilder($treeBuilder, $config)); } diff --git a/src/Symfony/Component/Config/Tests/Definition/Builder/NumericNodeDefinitionTest.php b/src/Symfony/Component/Config/Tests/Definition/Builder/NumericNodeDefinitionTest.php index 0add0db5682cb..51af2d71a247c 100755 --- a/src/Symfony/Component/Config/Tests/Definition/Builder/NumericNodeDefinitionTest.php +++ b/src/Symfony/Component/Config/Tests/Definition/Builder/NumericNodeDefinitionTest.php @@ -1,5 +1,14 @@ + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + namespace Symfony\Component\Config\Tests\Definition\Builder; use Symfony\Component\Config\Definition\Builder\IntegerNodeDefinition as NumericNodeDefinition; From 496ed135e87d48f2b14fbe403f007c5186201bf3 Mon Sep 17 00:00:00 2001 From: Fabien Potencier Date: Thu, 20 Sep 2012 07:48:14 +0200 Subject: [PATCH 046/975] updated CHANGELOG --- src/Symfony/Component/Config/CHANGELOG.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/Symfony/Component/Config/CHANGELOG.md b/src/Symfony/Component/Config/CHANGELOG.md index 27dd93111e56d..f6c219b1923fe 100644 --- a/src/Symfony/Component/Config/CHANGELOG.md +++ b/src/Symfony/Component/Config/CHANGELOG.md @@ -1,6 +1,11 @@ CHANGELOG ========= +2.2.0 +----- + + * added numerical type handling for config definitions + 2.1.0 ----- From 6cbeff0ea9b1337b04b833ac46a95eb51d2ebdca Mon Sep 17 00:00:00 2001 From: Gunther Konig Date: Thu, 20 Sep 2012 11:09:17 +0300 Subject: [PATCH 047/975] use ->find instead of ->get in the help command to allow command aliases to be used (e.g. "./app/console help do:sc:ge") --- src/Symfony/Component/Console/Command/HelpCommand.php | 2 +- .../Component/Console/Tests/Command/HelpCommandTest.php | 8 ++++++++ 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/src/Symfony/Component/Console/Command/HelpCommand.php b/src/Symfony/Component/Console/Command/HelpCommand.php index 93c81045c704a..71e2e15df76a0 100644 --- a/src/Symfony/Component/Console/Command/HelpCommand.php +++ b/src/Symfony/Component/Console/Command/HelpCommand.php @@ -70,7 +70,7 @@ public function setCommand(Command $command) protected function execute(InputInterface $input, OutputInterface $output) { if (null === $this->command) { - $this->command = $this->getApplication()->get($input->getArgument('command_name')); + $this->command = $this->getApplication()->find($input->getArgument('command_name')); } if ($input->getOption('xml')) { diff --git a/src/Symfony/Component/Console/Tests/Command/HelpCommandTest.php b/src/Symfony/Component/Console/Tests/Command/HelpCommandTest.php index 417eea1af9548..b62973d9d637e 100644 --- a/src/Symfony/Component/Console/Tests/Command/HelpCommandTest.php +++ b/src/Symfony/Component/Console/Tests/Command/HelpCommandTest.php @@ -22,6 +22,14 @@ public function testExecute() { $command = new HelpCommand(); + $application = new Application(); + $command->setApplication($application); + $commandTester = new CommandTester($command); + $commandTester->execute(array('command_name' => 'li')); + $this->assertRegExp('/list \[--xml\] \[--raw\] \[namespace\]/', $commandTester->getDisplay(), '->execute() returns a text help for the given command alias'); + + $command = new HelpCommand(); + $commandTester = new CommandTester($command); $command->setCommand(new ListCommand()); $commandTester->execute(array()); From 6bafe5a635ff9970c50309d285e53016d938d2be Mon Sep 17 00:00:00 2001 From: "Johannes M. Schmitt" Date: Thu, 20 Sep 2012 13:28:43 +0200 Subject: [PATCH 048/975] moved some code to the component --- .../Command/ConfigDumpReferenceCommand.php | 157 +--------------- .../Config/Definition/ReferenceDumper.php | 175 ++++++++++++++++++ 2 files changed, 178 insertions(+), 154 deletions(-) create mode 100644 src/Symfony/Component/Config/Definition/ReferenceDumper.php diff --git a/src/Symfony/Bundle/FrameworkBundle/Command/ConfigDumpReferenceCommand.php b/src/Symfony/Bundle/FrameworkBundle/Command/ConfigDumpReferenceCommand.php index 36c0593a84ed6..3036bdbc04416 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Command/ConfigDumpReferenceCommand.php +++ b/src/Symfony/Bundle/FrameworkBundle/Command/ConfigDumpReferenceCommand.php @@ -11,6 +11,7 @@ namespace Symfony\Bundle\FrameworkBundle\Command; +use Symfony\Component\Config\Definition\ReferenceDumper; use Symfony\Component\Console\Input\InputArgument; use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Output\OutputInterface; @@ -26,8 +27,6 @@ */ class ConfigDumpReferenceCommand extends ContainerDebugCommand { - protected $output; - /** * @see Command */ @@ -61,7 +60,6 @@ protected function configure() */ protected function execute(InputInterface $input, OutputInterface $output) { - $this->output = $output; $bundles = $this->getContainer()->get('kernel')->getBundles(); $containerBuilder = $this->getContainerBuilder(); @@ -112,158 +110,9 @@ protected function execute(InputInterface $input, OutputInterface $output) '" should implement ConfigurationInterface in order to be dumpable'); } - $rootNode = $configuration->getConfigTreeBuilder()->buildTree(); - $output->writeln($message); - // root node - $this->outputNode($rootNode); - } - - /** - * Outputs a single config reference line - * - * @param string $text - * @param int $indent - */ - private function outputLine($text, $indent = 0) - { - $indent = strlen($text) + $indent; - - $format = '%'.$indent.'s'; - - $this->output->writeln(sprintf($format, $text)); - } - - private function outputArray(array $array, $depth) - { - $isIndexed = array_values($array) === $array; - - foreach ($array as $key => $value) { - if (is_array($value)) { - $val = ''; - } else { - $val = $value; - } - - if ($isIndexed) { - $this->outputLine('- '.$val, $depth * 4); - } else { - $this->outputLine(sprintf('%-20s %s', $key.':', $val), $depth * 4); - } - - if (is_array($value)) { - $this->outputArray($value, $depth + 1); - } - } - } - - /** - * @param NodeInterface $node - * @param int $depth - */ - private function outputNode(NodeInterface $node, $depth = 0) - { - $comments = array(); - $default = ''; - $defaultArray = null; - $children = null; - $example = $node->getExample(); - - // defaults - if ($node instanceof ArrayNode) { - $children = $node->getChildren(); - - if ($node instanceof PrototypedArrayNode) { - $prototype = $node->getPrototype(); - - if ($prototype instanceof ArrayNode) { - $children = $prototype->getChildren(); - } - - // check for attribute as key - if ($key = $node->getKeyAttribute()) { - $keyNode = new ArrayNode($key, $node); - $keyNode->setInfo('Prototype'); - - // add children - foreach ($children as $childNode) { - $keyNode->addChild($childNode); - } - $children = array($key => $keyNode); - } - } - - if (!$children) { - if ($node->hasDefaultValue() && count($defaultArray = $node->getDefaultValue())) { - $default = ''; - } elseif (!is_array($example)) { - $default = '[]'; - } - } - } else { - $default = '~'; - - if ($node->hasDefaultValue()) { - $default = $node->getDefaultValue(); - - if (true === $default) { - $default = 'true'; - } elseif (false === $default) { - $default = 'false'; - } elseif (null === $default) { - $default = '~'; - } - } - } - - // required? - if ($node->isRequired()) { - $comments[] = 'Required'; - } - - // example - if ($example && !is_array($example)) { - $comments[] = 'Example: '.$example; - } - - $default = (string) $default != '' ? ' '.$default : ''; - $comments = count($comments) ? '# '.implode(', ', $comments) : ''; - - $text = sprintf('%-20s %s %s', $node->getName().':', $default, $comments); - - if ($info = $node->getInfo()) { - $this->outputLine(''); - $this->outputLine('# '.$info, $depth * 4); - } - - $this->outputLine($text, $depth * 4); - - // output defaults - if ($defaultArray) { - $this->outputLine(''); - - $message = count($defaultArray) > 1 ? 'Defaults' : 'Default'; - - $this->outputLine('# '.$message.':', $depth * 4 + 4); - - $this->outputArray($defaultArray, $depth + 1); - } - - if (is_array($example)) { - $this->outputLine(''); - - $message = count($example) > 1 ? 'Examples' : 'Example'; - - $this->outputLine('# '.$message.':', $depth * 4 + 4); - - $this->outputArray($example, $depth + 1); - } - - if ($children) { - foreach ($children as $childNode) { - $this->outputNode($childNode, $depth + 1); - } - } + $dumper = new ReferenceDumper(); + $output->writeln($dumper->dump($configuration)); } } diff --git a/src/Symfony/Component/Config/Definition/ReferenceDumper.php b/src/Symfony/Component/Config/Definition/ReferenceDumper.php new file mode 100644 index 0000000000000..6c4312db109a1 --- /dev/null +++ b/src/Symfony/Component/Config/Definition/ReferenceDumper.php @@ -0,0 +1,175 @@ + + */ +class ReferenceDumper +{ + private $reference; + + public function dump(ConfigurationInterface $configuration) + { + return $this->dumpNode($configuration->getConfigTreeBuilder()->buildTree()); + } + + public function dumpNode(NodeInterface $node) + { + $this->reference = ''; + $this->writeNode($node); + $ref = $this->reference; + $this->reference = null; + + return $ref; + } + + /** + * @param int $depth + */ + private function writeNode(NodeInterface $node, $depth = 0) + { + $comments = array(); + $default = ''; + $defaultArray = null; + $children = null; + $example = $node->getExample(); + + // defaults + if ($node instanceof ArrayNode) { + $children = $node->getChildren(); + + if ($node instanceof PrototypedArrayNode) { + $prototype = $node->getPrototype(); + + if ($prototype instanceof ArrayNode) { + $children = $prototype->getChildren(); + } + + // check for attribute as key + if ($key = $node->getKeyAttribute()) { + $keyNode = new ArrayNode($key, $node); + $keyNode->setInfo('Prototype'); + + // add children + foreach ($children as $childNode) { + $keyNode->addChild($childNode); + } + $children = array($key => $keyNode); + } + } + + if (!$children) { + if ($node->hasDefaultValue() && count($defaultArray = $node->getDefaultValue())) { + $default = ''; + } elseif (!is_array($example)) { + $default = '[]'; + } + } + } else { + $default = '~'; + + if ($node->hasDefaultValue()) { + $default = $node->getDefaultValue(); + + if (true === $default) { + $default = 'true'; + } elseif (false === $default) { + $default = 'false'; + } elseif (null === $default) { + $default = '~'; + } + } + } + + // required? + if ($node->isRequired()) { + $comments[] = 'Required'; + } + + // example + if ($example && !is_array($example)) { + $comments[] = 'Example: '.$example; + } + + $default = (string) $default != '' ? ' '.$default : ''; + $comments = count($comments) ? '# '.implode(', ', $comments) : ''; + + $text = sprintf('%-20s %s %s', $node->getName().':', $default, $comments); + + if ($info = $node->getInfo()) { + $this->writeLine(''); + $this->writeLine('# '.$info, $depth * 4); + } + + $this->writeLine($text, $depth * 4); + + // output defaults + if ($defaultArray) { + $this->writeLine(''); + + $message = count($defaultArray) > 1 ? 'Defaults' : 'Default'; + + $this->writeLine('# '.$message.':', $depth * 4 + 4); + + $this->writeArray($defaultArray, $depth + 1); + } + + if (is_array($example)) { + $this->writeLine(''); + + $message = count($example) > 1 ? 'Examples' : 'Example'; + + $this->writeLine('# '.$message.':', $depth * 4 + 4); + + $this->writeArray($example, $depth + 1); + } + + if ($children) { + foreach ($children as $childNode) { + $this->writeNode($childNode, $depth + 1); + } + } + } + + /** + * Outputs a single config reference line + * + * @param string $text + * @param int $indent + */ + private function writeLine($text, $indent = 0) + { + $indent = strlen($text) + $indent; + $format = '%'.$indent.'s'; + + $this->reference .= sprintf($format, $text)."\n"; + } + + private function writeArray(array $array, $depth) + { + $isIndexed = array_values($array) === $array; + + foreach ($array as $key => $value) { + if (is_array($value)) { + $val = ''; + } else { + $val = $value; + } + + if ($isIndexed) { + $this->writeLine('- '.$val, $depth * 4); + } else { + $this->writeLine(sprintf('%-20s %s', $key.':', $val), $depth * 4); + } + + if (is_array($value)) { + $this->writeArray($value, $depth + 1); + } + } + } +} \ No newline at end of file From 3680cec3e88ca26c0b6dfb1d7aa0c65f19e7bc79 Mon Sep 17 00:00:00 2001 From: Christian Jul Jensen Date: Thu, 20 Sep 2012 17:53:59 +0200 Subject: [PATCH 049/975] Fix PSR-0 incompatibilty Having 2 classes in the same file breaks PSR-0 compability --- src/Symfony/Component/DomCrawler/Form.php | 201 +---------------- .../DomCrawler/FormFieldRegistry.php | 213 ++++++++++++++++++ 2 files changed, 214 insertions(+), 200 deletions(-) create mode 100644 src/Symfony/Component/DomCrawler/FormFieldRegistry.php diff --git a/src/Symfony/Component/DomCrawler/Form.php b/src/Symfony/Component/DomCrawler/Form.php index 9106a232e9068..9730e3eb5984e 100644 --- a/src/Symfony/Component/DomCrawler/Form.php +++ b/src/Symfony/Component/DomCrawler/Form.php @@ -384,203 +384,4 @@ private function initialize() } } } -} - -class FormFieldRegistry -{ - private $fields = array(); - - private $base; - - /** - * Adds a field to the registry. - * - * @param FormField $field The field - * - * @throws \InvalidArgumentException when the name is malformed - */ - public function add(FormField $field) - { - $segments = $this->getSegments($field->getName()); - - $target =& $this->fields; - while ($segments) { - if (!is_array($target)) { - $target = array(); - } - $path = array_shift($segments); - if ('' === $path) { - $target =& $target[]; - } else { - $target =& $target[$path]; - } - } - $target = $field; - } - - /** - * Removes a field and its children from the registry. - * - * @param string $name The fully qualified name of the base field - * - * @throws \InvalidArgumentException when the name is malformed - */ - public function remove($name) - { - $segments = $this->getSegments($name); - $target =& $this->fields; - while (count($segments) > 1) { - $path = array_shift($segments); - if (!array_key_exists($path, $target)) { - return; - } - $target =& $target[$path]; - } - unset($target[array_shift($segments)]); - } - - /** - * Returns the value of the field and its children. - * - * @param string $name The fully qualified name of the field - * - * @return mixed The value of the field - * - * @throws \InvalidArgumentException when the name is malformed - * @throws \InvalidArgumentException if the field does not exist - */ - public function &get($name) - { - $segments = $this->getSegments($name); - $target =& $this->fields; - while ($segments) { - $path = array_shift($segments); - if (!array_key_exists($path, $target)) { - throw new \InvalidArgumentException(sprintf('Unreachable field "%s"', $path)); - } - $target =& $target[$path]; - } - - return $target; - } - - /** - * Tests whether the form has the given field. - * - * @param string $name The fully qualified name of the field - * - * @return Boolean Whether the form has the given field - */ - public function has($name) - { - try { - $this->get($name); - - return true; - } catch (\InvalidArgumentException $e) { - return false; - } - } - - /** - * Set the value of a field and its children. - * - * @param string $name The fully qualified name of the field - * @param mixed $value The value - * - * @throws \InvalidArgumentException when the name is malformed - * @throws \InvalidArgumentException if the field does not exist - */ - public function set($name, $value) - { - $target =& $this->get($name); - if (is_array($value)) { - $fields = self::create($name, $value); - foreach ($fields->all() as $k => $v) { - $this->set($k, $v); - } - } else { - $target->setValue($value); - } - } - - /** - * Returns the list of field with their value. - * - * @return array The list of fields as array((string) Fully qualified name => (mixed) value) - */ - public function all() - { - return $this->walk($this->fields, $this->base); - } - - /** - * Creates an instance of the class. - * - * This function is made private because it allows overriding the $base and - * the $values properties without any type checking. - * - * @param string $base The fully qualified name of the base field - * @param array $values The values of the fields - * - * @return FormFieldRegistry - */ - private static function create($base, array $values) - { - $registry = new static(); - $registry->base = $base; - $registry->fields = $values; - - return $registry; - } - - /** - * Transforms a PHP array in a list of fully qualified name / value. - * - * @param array $array The PHP array - * @param string $base The name of the base field - * @param array $output The initial values - * - * @return array The list of fields as array((string) Fully qualified name => (mixed) value) - */ - private function walk(array $array, $base = '', array &$output = array()) - { - foreach ($array as $k => $v) { - $path = empty($base) ? $k : sprintf("%s[%s]", $base, $k); - if (is_array($v)) { - $this->walk($v, $path, $output); - } else { - $output[$path] = $v; - } - } - - return $output; - } - - /** - * Splits a field name into segments as a web browser would do. - * - * - * getSegments('base[foo][3][]') = array('base', 'foo, '3', ''); - * - * - * @param string $name The name of the field - * - * @return array The list of segments - * - * @throws \InvalidArgumentException when the name is malformed - */ - private function getSegments($name) - { - if (preg_match('/^(?P[^[]+)(?P(\[.*)|$)/', $name, $m)) { - $segments = array($m['base']); - while (preg_match('/^\[(?P.*?)\](?P.*)$/', $m['extra'], $m)) { - $segments[] = $m['segment']; - } - - return $segments; - } - - throw new \InvalidArgumentException(sprintf('Malformed field path "%s"', $name)); - } -} +} \ No newline at end of file diff --git a/src/Symfony/Component/DomCrawler/FormFieldRegistry.php b/src/Symfony/Component/DomCrawler/FormFieldRegistry.php new file mode 100644 index 0000000000000..967e36c2d3469 --- /dev/null +++ b/src/Symfony/Component/DomCrawler/FormFieldRegistry.php @@ -0,0 +1,213 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\DomCrawler; + +use Symfony\Component\DomCrawler\Field\FormField; + +class FormFieldRegistry +{ + private $fields = array(); + + private $base; + + /** + * Adds a field to the registry. + * + * @param FormField $field The field + * + * @throws \InvalidArgumentException when the name is malformed + */ + public function add(FormField $field) + { + $segments = $this->getSegments($field->getName()); + + $target =& $this->fields; + while ($segments) { + if (!is_array($target)) { + $target = array(); + } + $path = array_shift($segments); + if ('' === $path) { + $target =& $target[]; + } else { + $target =& $target[$path]; + } + } + $target = $field; + } + + /** + * Removes a field and its children from the registry. + * + * @param string $name The fully qualified name of the base field + * + * @throws \InvalidArgumentException when the name is malformed + */ + public function remove($name) + { + $segments = $this->getSegments($name); + $target =& $this->fields; + while (count($segments) > 1) { + $path = array_shift($segments); + if (!array_key_exists($path, $target)) { + return; + } + $target =& $target[$path]; + } + unset($target[array_shift($segments)]); + } + + /** + * Returns the value of the field and its children. + * + * @param string $name The fully qualified name of the field + * + * @return mixed The value of the field + * + * @throws \InvalidArgumentException when the name is malformed + * @throws \InvalidArgumentException if the field does not exist + */ + public function &get($name) + { + $segments = $this->getSegments($name); + $target =& $this->fields; + while ($segments) { + $path = array_shift($segments); + if (!array_key_exists($path, $target)) { + throw new \InvalidArgumentException(sprintf('Unreachable field "%s"', $path)); + } + $target =& $target[$path]; + } + + return $target; + } + + /** + * Tests whether the form has the given field. + * + * @param string $name The fully qualified name of the field + * + * @return Boolean Whether the form has the given field + */ + public function has($name) + { + try { + $this->get($name); + + return true; + } catch (\InvalidArgumentException $e) { + return false; + } + } + + /** + * Set the value of a field and its children. + * + * @param string $name The fully qualified name of the field + * @param mixed $value The value + * + * @throws \InvalidArgumentException when the name is malformed + * @throws \InvalidArgumentException if the field does not exist + */ + public function set($name, $value) + { + $target =& $this->get($name); + if (is_array($value)) { + $fields = self::create($name, $value); + foreach ($fields->all() as $k => $v) { + $this->set($k, $v); + } + } else { + $target->setValue($value); + } + } + + /** + * Returns the list of field with their value. + * + * @return array The list of fields as array((string) Fully qualified name => (mixed) value) + */ + public function all() + { + return $this->walk($this->fields, $this->base); + } + + /** + * Creates an instance of the class. + * + * This function is made private because it allows overriding the $base and + * the $values properties without any type checking. + * + * @param string $base The fully qualified name of the base field + * @param array $values The values of the fields + * + * @return FormFieldRegistry + */ + private static function create($base, array $values) + { + $registry = new static(); + $registry->base = $base; + $registry->fields = $values; + + return $registry; + } + + /** + * Transforms a PHP array in a list of fully qualified name / value. + * + * @param array $array The PHP array + * @param string $base The name of the base field + * @param array $output The initial values + * + * @return array The list of fields as array((string) Fully qualified name => (mixed) value) + */ + private function walk(array $array, $base = '', array &$output = array()) + { + foreach ($array as $k => $v) { + $path = empty($base) ? $k : sprintf("%s[%s]", $base, $k); + if (is_array($v)) { + $this->walk($v, $path, $output); + } else { + $output[$path] = $v; + } + } + + return $output; + } + + /** + * Splits a field name into segments as a web browser would do. + * + * + * getSegments('base[foo][3][]') = array('base', 'foo, '3', ''); + * + * + * @param string $name The name of the field + * + * @return array The list of segments + * + * @throws \InvalidArgumentException when the name is malformed + */ + private function getSegments($name) + { + if (preg_match('/^(?P[^[]+)(?P(\[.*)|$)/', $name, $m)) { + $segments = array($m['base']); + while (preg_match('/^\[(?P.*?)\](?P.*)$/', $m['extra'], $m)) { + $segments[] = $m['segment']; + } + + return $segments; + } + + throw new \InvalidArgumentException(sprintf('Malformed field path "%s"', $name)); + } +} From 0d9d7bd4449af57e47c407b9843e5c35f0f170a1 Mon Sep 17 00:00:00 2001 From: Fabien Potencier Date: Thu, 20 Sep 2012 21:58:11 +0200 Subject: [PATCH 050/975] added a comment --- src/Symfony/Component/DomCrawler/FormFieldRegistry.php | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/Symfony/Component/DomCrawler/FormFieldRegistry.php b/src/Symfony/Component/DomCrawler/FormFieldRegistry.php index 967e36c2d3469..43b45c6712a63 100644 --- a/src/Symfony/Component/DomCrawler/FormFieldRegistry.php +++ b/src/Symfony/Component/DomCrawler/FormFieldRegistry.php @@ -13,6 +13,9 @@ use Symfony\Component\DomCrawler\Field\FormField; +/** + * This is an internal class that must not be used directly. + */ class FormFieldRegistry { private $fields = array(); From 958c9768ea86011e5f080d53109611c7e6b7a409 Mon Sep 17 00:00:00 2001 From: Fabien Potencier Date: Fri, 21 Sep 2012 08:09:07 +0200 Subject: [PATCH 051/975] fixed CS --- .../Config/Definition/ReferenceDumper.php | 217 +++++++++--------- 1 file changed, 113 insertions(+), 104 deletions(-) diff --git a/src/Symfony/Component/Config/Definition/ReferenceDumper.php b/src/Symfony/Component/Config/Definition/ReferenceDumper.php index 6c4312db109a1..835307eeae1cf 100644 --- a/src/Symfony/Component/Config/Definition/ReferenceDumper.php +++ b/src/Symfony/Component/Config/Definition/ReferenceDumper.php @@ -1,5 +1,14 @@ + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + namespace Symfony\Component\Config\Definition; /** @@ -18,7 +27,7 @@ public function dump(ConfigurationInterface $configuration) return $this->dumpNode($configuration->getConfigTreeBuilder()->buildTree()); } - public function dumpNode(NodeInterface $node) + public function dumpNode(NodeInterface $node) { $this->reference = ''; $this->writeNode($node); @@ -32,108 +41,108 @@ public function dumpNode(NodeInterface $node) * @param int $depth */ private function writeNode(NodeInterface $node, $depth = 0) - { - $comments = array(); - $default = ''; - $defaultArray = null; - $children = null; - $example = $node->getExample(); - - // defaults - if ($node instanceof ArrayNode) { - $children = $node->getChildren(); - - if ($node instanceof PrototypedArrayNode) { - $prototype = $node->getPrototype(); - - if ($prototype instanceof ArrayNode) { - $children = $prototype->getChildren(); - } - - // check for attribute as key - if ($key = $node->getKeyAttribute()) { - $keyNode = new ArrayNode($key, $node); - $keyNode->setInfo('Prototype'); - - // add children - foreach ($children as $childNode) { - $keyNode->addChild($childNode); - } - $children = array($key => $keyNode); - } - } - - if (!$children) { - if ($node->hasDefaultValue() && count($defaultArray = $node->getDefaultValue())) { - $default = ''; - } elseif (!is_array($example)) { - $default = '[]'; - } - } - } else { - $default = '~'; - - if ($node->hasDefaultValue()) { - $default = $node->getDefaultValue(); - - if (true === $default) { - $default = 'true'; - } elseif (false === $default) { - $default = 'false'; - } elseif (null === $default) { - $default = '~'; - } - } - } - - // required? - if ($node->isRequired()) { - $comments[] = 'Required'; - } - - // example - if ($example && !is_array($example)) { - $comments[] = 'Example: '.$example; - } - - $default = (string) $default != '' ? ' '.$default : ''; - $comments = count($comments) ? '# '.implode(', ', $comments) : ''; - - $text = sprintf('%-20s %s %s', $node->getName().':', $default, $comments); - - if ($info = $node->getInfo()) { - $this->writeLine(''); - $this->writeLine('# '.$info, $depth * 4); - } - - $this->writeLine($text, $depth * 4); - - // output defaults - if ($defaultArray) { - $this->writeLine(''); - - $message = count($defaultArray) > 1 ? 'Defaults' : 'Default'; - - $this->writeLine('# '.$message.':', $depth * 4 + 4); - - $this->writeArray($defaultArray, $depth + 1); - } - - if (is_array($example)) { - $this->writeLine(''); - - $message = count($example) > 1 ? 'Examples' : 'Example'; - - $this->writeLine('# '.$message.':', $depth * 4 + 4); - - $this->writeArray($example, $depth + 1); - } - - if ($children) { - foreach ($children as $childNode) { - $this->writeNode($childNode, $depth + 1); - } - } + { + $comments = array(); + $default = ''; + $defaultArray = null; + $children = null; + $example = $node->getExample(); + + // defaults + if ($node instanceof ArrayNode) { + $children = $node->getChildren(); + + if ($node instanceof PrototypedArrayNode) { + $prototype = $node->getPrototype(); + + if ($prototype instanceof ArrayNode) { + $children = $prototype->getChildren(); + } + + // check for attribute as key + if ($key = $node->getKeyAttribute()) { + $keyNode = new ArrayNode($key, $node); + $keyNode->setInfo('Prototype'); + + // add children + foreach ($children as $childNode) { + $keyNode->addChild($childNode); + } + $children = array($key => $keyNode); + } + } + + if (!$children) { + if ($node->hasDefaultValue() && count($defaultArray = $node->getDefaultValue())) { + $default = ''; + } elseif (!is_array($example)) { + $default = '[]'; + } + } + } else { + $default = '~'; + + if ($node->hasDefaultValue()) { + $default = $node->getDefaultValue(); + + if (true === $default) { + $default = 'true'; + } elseif (false === $default) { + $default = 'false'; + } elseif (null === $default) { + $default = '~'; + } + } + } + + // required? + if ($node->isRequired()) { + $comments[] = 'Required'; + } + + // example + if ($example && !is_array($example)) { + $comments[] = 'Example: '.$example; + } + + $default = (string) $default != '' ? ' '.$default : ''; + $comments = count($comments) ? '# '.implode(', ', $comments) : ''; + + $text = sprintf('%-20s %s %s', $node->getName().':', $default, $comments); + + if ($info = $node->getInfo()) { + $this->writeLine(''); + $this->writeLine('# '.$info, $depth * 4); + } + + $this->writeLine($text, $depth * 4); + + // output defaults + if ($defaultArray) { + $this->writeLine(''); + + $message = count($defaultArray) > 1 ? 'Defaults' : 'Default'; + + $this->writeLine('# '.$message.':', $depth * 4 + 4); + + $this->writeArray($defaultArray, $depth + 1); + } + + if (is_array($example)) { + $this->writeLine(''); + + $message = count($example) > 1 ? 'Examples' : 'Example'; + + $this->writeLine('# '.$message.':', $depth * 4 + 4); + + $this->writeArray($example, $depth + 1); + } + + if ($children) { + foreach ($children as $childNode) { + $this->writeNode($childNode, $depth + 1); + } + } } /** @@ -172,4 +181,4 @@ private function writeArray(array $array, $depth) } } } -} \ No newline at end of file +} From e0c001b772dd30b80bee6829e0686a4b7dca8116 Mon Sep 17 00:00:00 2001 From: nervo Date: Sun, 23 Sep 2012 10:54:29 +0300 Subject: [PATCH 052/975] Update src/Symfony/Component/Security/Http/Firewall/UsernamePasswordFormAuthenticationListener.php Better consistency in request method checking (See L.58) --- .../Firewall/UsernamePasswordFormAuthenticationListener.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Symfony/Component/Security/Http/Firewall/UsernamePasswordFormAuthenticationListener.php b/src/Symfony/Component/Security/Http/Firewall/UsernamePasswordFormAuthenticationListener.php index 22330a8c43cac..057ff7141ab20 100644 --- a/src/Symfony/Component/Security/Http/Firewall/UsernamePasswordFormAuthenticationListener.php +++ b/src/Symfony/Component/Security/Http/Firewall/UsernamePasswordFormAuthenticationListener.php @@ -67,7 +67,7 @@ protected function requiresAuthentication(Request $request) */ protected function attemptAuthentication(Request $request) { - if ($this->options['post_only'] && 'post' !== strtolower($request->getMethod())) { + if ($this->options['post_only'] && !$request->isMethod('post')) { if (null !== $this->logger) { $this->logger->debug(sprintf('Authentication method not supported: %s.', $request->getMethod())); } From 58cb6f55ccb3332595b46764d12482bfb0507781 Mon Sep 17 00:00:00 2001 From: Fabien Potencier Date: Sun, 23 Sep 2012 15:11:53 +0200 Subject: [PATCH 053/975] changed comparison on the request method to use the isMethod() method --- src/Symfony/Component/HttpFoundation/Response.php | 2 +- src/Symfony/Component/HttpKernel/HttpCache/HttpCache.php | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Symfony/Component/HttpFoundation/Response.php b/src/Symfony/Component/HttpFoundation/Response.php index dbc82d1b61bc0..6c9d715416e2c 100644 --- a/src/Symfony/Component/HttpFoundation/Response.php +++ b/src/Symfony/Component/HttpFoundation/Response.php @@ -231,7 +231,7 @@ public function prepare(Request $request) $headers->remove('Content-Length'); } - if ('HEAD' === $request->getMethod()) { + if ($request->isMethod('HEAD')) { // cf. RFC2616 14.13 $length = $headers->get('Content-Length'); $this->setContent(null); diff --git a/src/Symfony/Component/HttpKernel/HttpCache/HttpCache.php b/src/Symfony/Component/HttpKernel/HttpCache/HttpCache.php index ec66dcd5fcbee..d5d6f3a4d93dc 100644 --- a/src/Symfony/Component/HttpKernel/HttpCache/HttpCache.php +++ b/src/Symfony/Component/HttpKernel/HttpCache/HttpCache.php @@ -580,7 +580,7 @@ protected function store(Request $request, Response $response) */ private function restoreResponseBody(Request $request, Response $response) { - if ('HEAD' === $request->getMethod() || 304 === $response->getStatusCode()) { + if ($request->isMethod('HEAD') || 304 === $response->getStatusCode()) { $response->setContent(null); $response->headers->remove('X-Body-Eval'); $response->headers->remove('X-Body-File'); From 45bf52358e8708f3e666d03d39bddd7fe3caf8e8 Mon Sep 17 00:00:00 2001 From: Filippo Tessarotto Date: Fri, 28 Sep 2012 09:34:16 +0200 Subject: [PATCH 054/975] Optimize autoload prefix in composer.json By having more specific autoload prefixes it is possible to reduce the number of stat calls made. Also it prevents conflicts with similar namespaces. --- composer.json | 2 +- src/Symfony/Bridge/Doctrine/composer.json | 2 +- src/Symfony/Bridge/Monolog/composer.json | 2 +- src/Symfony/Bridge/Propel1/composer.json | 2 +- src/Symfony/Bridge/Swiftmailer/composer.json | 2 +- src/Symfony/Bridge/Twig/composer.json | 2 +- src/Symfony/Bundle/FrameworkBundle/composer.json | 2 +- src/Symfony/Bundle/SecurityBundle/composer.json | 2 +- src/Symfony/Bundle/TwigBundle/composer.json | 2 +- src/Symfony/Bundle/WebProfilerBundle/composer.json | 2 +- src/Symfony/Component/BrowserKit/composer.json | 2 +- src/Symfony/Component/ClassLoader/composer.json | 2 +- src/Symfony/Component/Config/composer.json | 2 +- src/Symfony/Component/Console/composer.json | 2 +- src/Symfony/Component/CssSelector/composer.json | 2 +- src/Symfony/Component/DependencyInjection/composer.json | 2 +- src/Symfony/Component/DomCrawler/composer.json | 2 +- src/Symfony/Component/EventDispatcher/composer.json | 2 +- src/Symfony/Component/Filesystem/composer.json | 2 +- src/Symfony/Component/Finder/composer.json | 2 +- src/Symfony/Component/Form/composer.json | 2 +- src/Symfony/Component/HttpFoundation/composer.json | 2 +- src/Symfony/Component/HttpKernel/composer.json | 2 +- src/Symfony/Component/Locale/composer.json | 2 +- src/Symfony/Component/OptionsResolver/composer.json | 2 +- src/Symfony/Component/Process/composer.json | 2 +- src/Symfony/Component/Routing/composer.json | 2 +- src/Symfony/Component/Security/composer.json | 2 +- src/Symfony/Component/Serializer/composer.json | 2 +- src/Symfony/Component/Templating/composer.json | 2 +- src/Symfony/Component/Translation/composer.json | 2 +- src/Symfony/Component/Validator/composer.json | 2 +- src/Symfony/Component/Yaml/composer.json | 2 +- 33 files changed, 33 insertions(+), 33 deletions(-) diff --git a/composer.json b/composer.json index 37d1b3341d9a9..f1cb8feab4067 100644 --- a/composer.json +++ b/composer.json @@ -63,7 +63,7 @@ }, "autoload": { "psr-0": { - "Symfony": "src/", + "Symfony\\": "src/", "SessionHandlerInterface": "src/Symfony/Component/HttpFoundation/Resources/stubs" } }, diff --git a/src/Symfony/Bridge/Doctrine/composer.json b/src/Symfony/Bridge/Doctrine/composer.json index adc825d463070..325c335e3e4df 100644 --- a/src/Symfony/Bridge/Doctrine/composer.json +++ b/src/Symfony/Bridge/Doctrine/composer.json @@ -27,7 +27,7 @@ "doctrine/orm": ">=2.2.3,<2.4-dev" }, "autoload": { - "psr-0": { "Symfony\\Bridge\\Doctrine": "" } + "psr-0": { "Symfony\\Bridge\\Doctrine\\": "" } }, "target-dir": "Symfony/Bridge/Doctrine", "minimum-stability": "dev", diff --git a/src/Symfony/Bridge/Monolog/composer.json b/src/Symfony/Bridge/Monolog/composer.json index 2b60a451ee941..b41701a305e69 100644 --- a/src/Symfony/Bridge/Monolog/composer.json +++ b/src/Symfony/Bridge/Monolog/composer.json @@ -21,7 +21,7 @@ "monolog/monolog": "1.*" }, "autoload": { - "psr-0": { "Symfony\\Bridge\\Monolog": "" } + "psr-0": { "Symfony\\Bridge\\Monolog\\": "" } }, "target-dir": "Symfony/Bridge/Monolog", "minimum-stability": "dev", diff --git a/src/Symfony/Bridge/Propel1/composer.json b/src/Symfony/Bridge/Propel1/composer.json index 7827d5e3874f6..b4fb61284aedb 100644 --- a/src/Symfony/Bridge/Propel1/composer.json +++ b/src/Symfony/Bridge/Propel1/composer.json @@ -23,7 +23,7 @@ "propel/propel1": "1.6.*" }, "autoload": { - "psr-0": { "Symfony\\Bridge\\Propel1": "" } + "psr-0": { "Symfony\\Bridge\\Propel1\\": "" } }, "target-dir": "Symfony/Bridge/Propel1", "minimum-stability": "dev", diff --git a/src/Symfony/Bridge/Swiftmailer/composer.json b/src/Symfony/Bridge/Swiftmailer/composer.json index c4dbd47793015..28fb63fd4d6b2 100644 --- a/src/Symfony/Bridge/Swiftmailer/composer.json +++ b/src/Symfony/Bridge/Swiftmailer/composer.json @@ -23,7 +23,7 @@ "symfony/http-kernel": "2.2.*" }, "autoload": { - "psr-0": { "Symfony\\Bridge\\Swiftmailer": "" } + "psr-0": { "Symfony\\Bridge\\Swiftmailer\\": "" } }, "target-dir": "Symfony/Bridge/Swiftmailer", "minimum-stability": "dev", diff --git a/src/Symfony/Bridge/Twig/composer.json b/src/Symfony/Bridge/Twig/composer.json index 8c9f13df4bb2e..4a3e09e018616 100644 --- a/src/Symfony/Bridge/Twig/composer.json +++ b/src/Symfony/Bridge/Twig/composer.json @@ -36,7 +36,7 @@ "symfony/security": "2.2.*" }, "autoload": { - "psr-0": { "Symfony\\Bridge\\Twig": "" } + "psr-0": { "Symfony\\Bridge\\Twig\\": "" } }, "target-dir": "Symfony/Bridge/Twig", "minimum-stability": "dev", diff --git a/src/Symfony/Bundle/FrameworkBundle/composer.json b/src/Symfony/Bundle/FrameworkBundle/composer.json index 869dc5d153501..d61031eb58fea 100644 --- a/src/Symfony/Bundle/FrameworkBundle/composer.json +++ b/src/Symfony/Bundle/FrameworkBundle/composer.json @@ -37,7 +37,7 @@ "symfony/validator": "2.2.*" }, "autoload": { - "psr-0": { "Symfony\\Bundle\\FrameworkBundle": "" } + "psr-0": { "Symfony\\Bundle\\FrameworkBundle\\": "" } }, "target-dir": "Symfony/Bundle/FrameworkBundle", "minimum-stability": "dev", diff --git a/src/Symfony/Bundle/SecurityBundle/composer.json b/src/Symfony/Bundle/SecurityBundle/composer.json index e369a94813f7c..f7be085bb7cc1 100644 --- a/src/Symfony/Bundle/SecurityBundle/composer.json +++ b/src/Symfony/Bundle/SecurityBundle/composer.json @@ -20,7 +20,7 @@ "symfony/security": "2.2.*" }, "autoload": { - "psr-0": { "Symfony\\Bundle\\SecurityBundle": "" } + "psr-0": { "Symfony\\Bundle\\SecurityBundle\\": "" } }, "target-dir": "Symfony/Bundle/SecurityBundle", "minimum-stability": "dev", diff --git a/src/Symfony/Bundle/TwigBundle/composer.json b/src/Symfony/Bundle/TwigBundle/composer.json index c263b0a165cb3..3e05e854dfb41 100644 --- a/src/Symfony/Bundle/TwigBundle/composer.json +++ b/src/Symfony/Bundle/TwigBundle/composer.json @@ -20,7 +20,7 @@ "symfony/twig-bridge": "2.2.*" }, "autoload": { - "psr-0": { "Symfony\\Bundle\\TwigBundle": "" } + "psr-0": { "Symfony\\Bundle\\TwigBundle\\": "" } }, "target-dir": "Symfony/Bundle/TwigBundle", "minimum-stability": "dev", diff --git a/src/Symfony/Bundle/WebProfilerBundle/composer.json b/src/Symfony/Bundle/WebProfilerBundle/composer.json index 3c14ba5eebe7b..62d1aae314e2b 100644 --- a/src/Symfony/Bundle/WebProfilerBundle/composer.json +++ b/src/Symfony/Bundle/WebProfilerBundle/composer.json @@ -20,7 +20,7 @@ "symfony/twig-bundle": "2.2.*" }, "autoload": { - "psr-0": { "Symfony\\Bundle\\WebProfilerBundle": "" } + "psr-0": { "Symfony\\Bundle\\WebProfilerBundle\\": "" } }, "target-dir": "Symfony/Bundle/WebProfilerBundle", "minimum-stability": "dev", diff --git a/src/Symfony/Component/BrowserKit/composer.json b/src/Symfony/Component/BrowserKit/composer.json index 12ff0e041d5b9..e1921435106fc 100644 --- a/src/Symfony/Component/BrowserKit/composer.json +++ b/src/Symfony/Component/BrowserKit/composer.json @@ -27,7 +27,7 @@ "symfony/process": "2.2.*" }, "autoload": { - "psr-0": { "Symfony\\Component\\BrowserKit": "" } + "psr-0": { "Symfony\\Component\\BrowserKit\\": "" } }, "target-dir": "Symfony/Component/BrowserKit", "minimum-stability": "dev", diff --git a/src/Symfony/Component/ClassLoader/composer.json b/src/Symfony/Component/ClassLoader/composer.json index 5a68c85e67dcf..effcb83308f84 100644 --- a/src/Symfony/Component/ClassLoader/composer.json +++ b/src/Symfony/Component/ClassLoader/composer.json @@ -23,7 +23,7 @@ "symfony/finder": "2.2.*" }, "autoload": { - "psr-0": { "Symfony\\Component\\ClassLoader": "" } + "psr-0": { "Symfony\\Component\\ClassLoader\\": "" } }, "target-dir": "Symfony/Component/ClassLoader", "minimum-stability": "dev", diff --git a/src/Symfony/Component/Config/composer.json b/src/Symfony/Component/Config/composer.json index cf7074b7ef382..e148c27c09085 100644 --- a/src/Symfony/Component/Config/composer.json +++ b/src/Symfony/Component/Config/composer.json @@ -19,7 +19,7 @@ "php": ">=5.3.3" }, "autoload": { - "psr-0": { "Symfony\\Component\\Config": "" } + "psr-0": { "Symfony\\Component\\Config\\": "" } }, "target-dir": "Symfony/Component/Config", "minimum-stability": "dev", diff --git a/src/Symfony/Component/Console/composer.json b/src/Symfony/Component/Console/composer.json index a0f2b1e0943a1..3369681580e30 100644 --- a/src/Symfony/Component/Console/composer.json +++ b/src/Symfony/Component/Console/composer.json @@ -19,7 +19,7 @@ "php": ">=5.3.3" }, "autoload": { - "psr-0": { "Symfony\\Component\\Console": "" } + "psr-0": { "Symfony\\Component\\Console\\": "" } }, "target-dir": "Symfony/Component/Console", "minimum-stability": "dev", diff --git a/src/Symfony/Component/CssSelector/composer.json b/src/Symfony/Component/CssSelector/composer.json index f893e74d2772f..54661fb87ba55 100644 --- a/src/Symfony/Component/CssSelector/composer.json +++ b/src/Symfony/Component/CssSelector/composer.json @@ -19,7 +19,7 @@ "php": ">=5.3.3" }, "autoload": { - "psr-0": { "Symfony\\Component\\CssSelector": "" } + "psr-0": { "Symfony\\Component\\CssSelector\\": "" } }, "target-dir": "Symfony/Component/CssSelector", "minimum-stability": "dev", diff --git a/src/Symfony/Component/DependencyInjection/composer.json b/src/Symfony/Component/DependencyInjection/composer.json index b50f49b2a93cd..d951f3041d29d 100644 --- a/src/Symfony/Component/DependencyInjection/composer.json +++ b/src/Symfony/Component/DependencyInjection/composer.json @@ -27,7 +27,7 @@ "symfony/config": "2.2.*" }, "autoload": { - "psr-0": { "Symfony\\Component\\DependencyInjection": "" } + "psr-0": { "Symfony\\Component\\DependencyInjection\\": "" } }, "target-dir": "Symfony/Component/DependencyInjection", "minimum-stability": "dev", diff --git a/src/Symfony/Component/DomCrawler/composer.json b/src/Symfony/Component/DomCrawler/composer.json index 80b1792b1aacc..5696a86893435 100644 --- a/src/Symfony/Component/DomCrawler/composer.json +++ b/src/Symfony/Component/DomCrawler/composer.json @@ -25,7 +25,7 @@ "symfony/css-selector": "2.2.*" }, "autoload": { - "psr-0": { "Symfony\\Component\\DomCrawler": "" } + "psr-0": { "Symfony\\Component\\DomCrawler\\": "" } }, "target-dir": "Symfony/Component/DomCrawler", "minimum-stability": "dev", diff --git a/src/Symfony/Component/EventDispatcher/composer.json b/src/Symfony/Component/EventDispatcher/composer.json index c31dd481e2d93..1a90992fd1867 100644 --- a/src/Symfony/Component/EventDispatcher/composer.json +++ b/src/Symfony/Component/EventDispatcher/composer.json @@ -26,7 +26,7 @@ "symfony/http-kernel": "2.2.*" }, "autoload": { - "psr-0": { "Symfony\\Component\\EventDispatcher": "" } + "psr-0": { "Symfony\\Component\\EventDispatcher\\": "" } }, "target-dir": "Symfony/Component/EventDispatcher", "minimum-stability": "dev", diff --git a/src/Symfony/Component/Filesystem/composer.json b/src/Symfony/Component/Filesystem/composer.json index 168cefb3e0677..d1f97cf8d42d2 100644 --- a/src/Symfony/Component/Filesystem/composer.json +++ b/src/Symfony/Component/Filesystem/composer.json @@ -19,7 +19,7 @@ "php": ">=5.3.3" }, "autoload": { - "psr-0": { "Symfony\\Component\\Filesystem": "" } + "psr-0": { "Symfony\\Component\\Filesystem\\": "" } }, "target-dir": "Symfony/Component/Filesystem", "minimum-stability": "dev", diff --git a/src/Symfony/Component/Finder/composer.json b/src/Symfony/Component/Finder/composer.json index 690fd427e3000..2ad5b34ccb4a6 100644 --- a/src/Symfony/Component/Finder/composer.json +++ b/src/Symfony/Component/Finder/composer.json @@ -19,7 +19,7 @@ "php": ">=5.3.3" }, "autoload": { - "psr-0": { "Symfony\\Component\\Finder": "" } + "psr-0": { "Symfony\\Component\\Finder\\": "" } }, "target-dir": "Symfony/Component/Finder", "minimum-stability": "dev", diff --git a/src/Symfony/Component/Form/composer.json b/src/Symfony/Component/Form/composer.json index e861e3b1d2b47..1e69cb140d615 100644 --- a/src/Symfony/Component/Form/composer.json +++ b/src/Symfony/Component/Form/composer.json @@ -30,7 +30,7 @@ "symfony/http-foundation": "2.2.*" }, "autoload": { - "psr-0": { "Symfony\\Component\\Form": "" } + "psr-0": { "Symfony\\Component\\Form\\": "" } }, "target-dir": "Symfony/Component/Form", "minimum-stability": "dev", diff --git a/src/Symfony/Component/HttpFoundation/composer.json b/src/Symfony/Component/HttpFoundation/composer.json index d10ef3180357e..d486e545ea0e6 100644 --- a/src/Symfony/Component/HttpFoundation/composer.json +++ b/src/Symfony/Component/HttpFoundation/composer.json @@ -20,7 +20,7 @@ }, "autoload": { "psr-0": { - "Symfony\\Component\\HttpFoundation": "", + "Symfony\\Component\\HttpFoundation\\": "", "SessionHandlerInterface": "Symfony/Component/HttpFoundation/Resources/stubs" } }, diff --git a/src/Symfony/Component/HttpKernel/composer.json b/src/Symfony/Component/HttpKernel/composer.json index 7c9fe7dc308fa..40f10b333bb9b 100644 --- a/src/Symfony/Component/HttpKernel/composer.json +++ b/src/Symfony/Component/HttpKernel/composer.json @@ -39,7 +39,7 @@ "symfony/finder": "2.2.*" }, "autoload": { - "psr-0": { "Symfony\\Component\\HttpKernel": "" } + "psr-0": { "Symfony\\Component\\HttpKernel\\": "" } }, "target-dir": "Symfony/Component/HttpKernel", "minimum-stability": "dev", diff --git a/src/Symfony/Component/Locale/composer.json b/src/Symfony/Component/Locale/composer.json index c450797b1774a..771b5cda59e82 100644 --- a/src/Symfony/Component/Locale/composer.json +++ b/src/Symfony/Component/Locale/composer.json @@ -22,7 +22,7 @@ "ext-intl": ">=5.3.3" }, "autoload": { - "psr-0": { "Symfony\\Component\\Locale": "" } + "psr-0": { "Symfony\\Component\\Locale\\": "" } }, "target-dir": "Symfony/Component/Locale", "minimum-stability": "dev", diff --git a/src/Symfony/Component/OptionsResolver/composer.json b/src/Symfony/Component/OptionsResolver/composer.json index 39ad60a68e15e..4812585a5277f 100644 --- a/src/Symfony/Component/OptionsResolver/composer.json +++ b/src/Symfony/Component/OptionsResolver/composer.json @@ -19,7 +19,7 @@ "php": ">=5.3.3" }, "autoload": { - "psr-0": { "Symfony\\Component\\OptionsResolver": "" } + "psr-0": { "Symfony\\Component\\OptionsResolver\\": "" } }, "target-dir": "Symfony/Component/OptionsResolver", "minimum-stability": "dev", diff --git a/src/Symfony/Component/Process/composer.json b/src/Symfony/Component/Process/composer.json index ea53b3c459abe..1681ef6c1f97b 100644 --- a/src/Symfony/Component/Process/composer.json +++ b/src/Symfony/Component/Process/composer.json @@ -19,7 +19,7 @@ "php": ">=5.3.3" }, "autoload": { - "psr-0": { "Symfony\\Component\\Process": "" } + "psr-0": { "Symfony\\Component\\Process\\": "" } }, "target-dir": "Symfony/Component/Process", "minimum-stability": "dev", diff --git a/src/Symfony/Component/Routing/composer.json b/src/Symfony/Component/Routing/composer.json index 2cee345e274ec..d3f653b761c84 100644 --- a/src/Symfony/Component/Routing/composer.json +++ b/src/Symfony/Component/Routing/composer.json @@ -30,7 +30,7 @@ "doctrine/common": ">=2.2,<2.4-dev" }, "autoload": { - "psr-0": { "Symfony\\Component\\Routing": "" } + "psr-0": { "Symfony\\Component\\Routing\\": "" } }, "target-dir": "Symfony/Component/Routing", "minimum-stability": "dev", diff --git a/src/Symfony/Component/Security/composer.json b/src/Symfony/Component/Security/composer.json index ceaf28036cae5..73e07b513eaba 100644 --- a/src/Symfony/Component/Security/composer.json +++ b/src/Symfony/Component/Security/composer.json @@ -37,7 +37,7 @@ "doctrine/dbal": "to use the built-in ACL implementation" }, "autoload": { - "psr-0": { "Symfony\\Component\\Security": "" } + "psr-0": { "Symfony\\Component\\Security\\": "" } }, "target-dir": "Symfony/Component/Security", "minimum-stability": "dev", diff --git a/src/Symfony/Component/Serializer/composer.json b/src/Symfony/Component/Serializer/composer.json index aa23f3839f773..cff1e49cfa4fe 100644 --- a/src/Symfony/Component/Serializer/composer.json +++ b/src/Symfony/Component/Serializer/composer.json @@ -19,7 +19,7 @@ "php": ">=5.3.3" }, "autoload": { - "psr-0": { "Symfony\\Component\\Serializer": "" } + "psr-0": { "Symfony\\Component\\Serializer\\": "" } }, "target-dir": "Symfony/Component/Serializer", "minimum-stability": "dev", diff --git a/src/Symfony/Component/Templating/composer.json b/src/Symfony/Component/Templating/composer.json index dcf589a2f75ec..234e28d63bdc7 100644 --- a/src/Symfony/Component/Templating/composer.json +++ b/src/Symfony/Component/Templating/composer.json @@ -19,7 +19,7 @@ "php": ">=5.3.3" }, "autoload": { - "psr-0": { "Symfony\\Component\\Templating": "" } + "psr-0": { "Symfony\\Component\\Templating\\": "" } }, "target-dir": "Symfony/Component/Templating", "minimum-stability": "dev", diff --git a/src/Symfony/Component/Translation/composer.json b/src/Symfony/Component/Translation/composer.json index dcc3c0e1a04e3..52e4c43b403bf 100644 --- a/src/Symfony/Component/Translation/composer.json +++ b/src/Symfony/Component/Translation/composer.json @@ -27,7 +27,7 @@ "symfony/yaml": "2.2.*" }, "autoload": { - "psr-0": { "Symfony\\Component\\Translation": "" } + "psr-0": { "Symfony\\Component\\Translation\\": "" } }, "target-dir": "Symfony/Component/Translation", "minimum-stability": "dev", diff --git a/src/Symfony/Component/Validator/composer.json b/src/Symfony/Component/Validator/composer.json index de1279e0a921f..a52d33bb21153 100644 --- a/src/Symfony/Component/Validator/composer.json +++ b/src/Symfony/Component/Validator/composer.json @@ -29,7 +29,7 @@ "symfony/yaml": "2.2.*" }, "autoload": { - "psr-0": { "Symfony\\Component\\Validator": "" } + "psr-0": { "Symfony\\Component\\Validator\\": "" } }, "target-dir": "Symfony/Component/Validator", "minimum-stability": "dev", diff --git a/src/Symfony/Component/Yaml/composer.json b/src/Symfony/Component/Yaml/composer.json index 13a9e23603e0d..e04dabf3fc22c 100644 --- a/src/Symfony/Component/Yaml/composer.json +++ b/src/Symfony/Component/Yaml/composer.json @@ -19,7 +19,7 @@ "php": ">=5.3.3" }, "autoload": { - "psr-0": { "Symfony\\Component\\Yaml": "" } + "psr-0": { "Symfony\\Component\\Yaml\\": "" } }, "target-dir": "Symfony/Component/Yaml", "minimum-stability": "dev", From ef18e00283622b0fea82d4fa08ed032ca3f8c60f Mon Sep 17 00:00:00 2001 From: Ray Date: Tue, 18 Sep 2012 10:26:12 -0500 Subject: [PATCH 055/975] [HttpKernel] Added a bit to convert incomplete objects in the error message --- .../HttpKernel/Exception/FlattenException.php | 10 +++++ .../Tests/Exception/FlattenExceptionTest.php | 43 ++++++++++++++++++- 2 files changed, 52 insertions(+), 1 deletion(-) diff --git a/src/Symfony/Component/HttpKernel/Exception/FlattenException.php b/src/Symfony/Component/HttpKernel/Exception/FlattenException.php index b2ffb9fcfbb21..eb5e5715fa80b 100644 --- a/src/Symfony/Component/HttpKernel/Exception/FlattenException.php +++ b/src/Symfony/Component/HttpKernel/Exception/FlattenException.php @@ -221,6 +221,9 @@ private function flattenArgs($args, $level = 0) $result[$key] = array('boolean', $value); } elseif (is_resource($value)) { $result[$key] = array('resource', get_resource_type($value)); + } elseif ($value instanceof \__PHP_Incomplete_Class) { + // Special case of object, is_object will return false + $result[$key] = array('incomplete-object', $this->getClassNameFromIncomplete($value)); } else { $result[$key] = array('string', (string) $value); } @@ -228,4 +231,11 @@ private function flattenArgs($args, $level = 0) return $result; } + + private function getClassNameFromIncomplete(\__PHP_Incomplete_Class $value) + { + $array = new \ArrayObject($value); + + return $array['__PHP_Incomplete_Class_Name']; + } } diff --git a/src/Symfony/Component/HttpKernel/Tests/Exception/FlattenExceptionTest.php b/src/Symfony/Component/HttpKernel/Tests/Exception/FlattenExceptionTest.php index 65975aa96fc83..cd76c3a637b80 100644 --- a/src/Symfony/Component/HttpKernel/Tests/Exception/FlattenExceptionTest.php +++ b/src/Symfony/Component/HttpKernel/Tests/Exception/FlattenExceptionTest.php @@ -101,7 +101,7 @@ public function testToArray(\Exception $exception, $statusCode) 'args' => array() )), ) - ),$flattened->toArray()); + ), $flattened->toArray()); } public function flattenDataProvider() @@ -125,4 +125,45 @@ private function createException($foo) { return new \Exception(); } + + public function testSetTraceIncompleteClass() + { + $flattened = FlattenException::create(new \Exception('test', 123)); + $flattened->setTrace( + array( + array( + 'file' => __FILE__, + 'line' => 123, + 'function' => 'test', + 'args' => array( + unserialize('O:14:"BogusTestClass":0:{}') + ), + ), + ), + 'foo.php', 123 + ); + + $this->assertEquals(array( + array( + 'message'=> 'test', + 'class'=>'Exception', + 'trace'=>array( + array( + 'namespace' => '', 'short_class' => '', 'class' => '','type' => '','function' => '', + 'file' => 'foo.php', 'line' => 123, + 'args' => array(), + ), + array( + 'namespace' => '', 'short_class' => '', 'class' => '','type' => '','function' => 'test', + 'file' => __FILE__, 'line' => 123, + 'args' => array( + array( + 'incomplete-object', 'BogusTestClass' + ), + ), + ) + ), + ) + ), $flattened->toArray()); + } } From 310c2f98a9e520d82a8ea1a2b4c04c521743c304 Mon Sep 17 00:00:00 2001 From: Florin Patan Date: Sat, 15 Sep 2012 16:31:44 +0300 Subject: [PATCH 056/975] [2.2][WebProfilerBundle] Added minimize option to Web Profiler panels --- .../Controller/ProfilerController.php | 1 + .../Resources/public/css/profiler.css | 40 +++++++-- .../public/images/profiler/left-arrow.png | Bin 0 -> 1001 bytes .../public/images/profiler/right-arrow.png | Bin 0 -> 1001 bytes .../Resources/views/Collector/time.html.twig | 11 ++- .../Resources/views/Profiler/admin.html.twig | 2 +- .../views/Profiler/base_js.html.twig | 32 ++++++- .../Resources/views/Profiler/header.html.twig | 2 +- .../Resources/views/Profiler/layout.html.twig | 78 ++++++++++++++++++ .../Resources/views/Profiler/search.html.twig | 2 +- .../views/Profiler/toolbar.html.twig | 24 +++++- .../views/Profiler/toolbar_js.html.twig | 14 ++++ .../views/Profiler/toolbar_style.html.twig | 62 ++++++++++++-- 13 files changed, 243 insertions(+), 25 deletions(-) create mode 100644 src/Symfony/Bundle/WebProfilerBundle/Resources/public/images/profiler/left-arrow.png create mode 100644 src/Symfony/Bundle/WebProfilerBundle/Resources/public/images/profiler/right-arrow.png diff --git a/src/Symfony/Bundle/WebProfilerBundle/Controller/ProfilerController.php b/src/Symfony/Bundle/WebProfilerBundle/Controller/ProfilerController.php index 3eebc77914750..b67e1fbe63cb6 100644 --- a/src/Symfony/Bundle/WebProfilerBundle/Controller/ProfilerController.php +++ b/src/Symfony/Bundle/WebProfilerBundle/Controller/ProfilerController.php @@ -186,6 +186,7 @@ public function toolbarAction(Request $request, $token, $position = null) 'profile' => $profile, 'templates' => $this->getTemplateManager()->getTemplates($profile), 'profiler_url' => $url, + 'token' => $token, )); } diff --git a/src/Symfony/Bundle/WebProfilerBundle/Resources/public/css/profiler.css b/src/Symfony/Bundle/WebProfilerBundle/Resources/public/css/profiler.css index 8381a9a7b1cab..734826baa65fb 100644 --- a/src/Symfony/Bundle/WebProfilerBundle/Resources/public/css/profiler.css +++ b/src/Symfony/Bundle/WebProfilerBundle/Resources/public/css/profiler.css @@ -104,13 +104,14 @@ abbr { #content { padding: 0 50px; - margin: 0 auto; + margin: 0 auto 20px; font-family: Arial, Helvetica, sans-serif; min-width: 970px; + } #header { - padding: 30px 30px 20px; + padding: 20px 30px 20px; } #header h1 { @@ -131,6 +132,7 @@ abbr { padding-bottom: 0; display: block; background-color: #f6f6f6; + z-index: 10000; } #menu_profiler li a { @@ -144,9 +146,9 @@ abbr { #menu_profiler li a span.label { display: block; - padding: 20px 20px 16px 65px; - min-height: 24px; - _height: 24px; + padding: 20px 0px 16px 65px; + min-height: 16px; + overflow: hidden; } #menu_profiler li a span.icon { @@ -186,7 +188,7 @@ abbr { #collector_content { margin-left: 250px; - padding: 40px 50px; + padding: 30px 40px 40px; } #navigation { @@ -235,8 +237,9 @@ li { #resume { background-color: #f6f6f6; border-bottom: 1px solid #dfdfdf; - padding: 10px 50px; - margin-left: 210px; + padding: 18px 10px 0px; + margin-left: 250px; + height: 34px; color: #313131; font-size: 12px; -moz-border-radius-topright: 16px; @@ -284,7 +287,9 @@ table th.value { } .sf-exceptionreset .block_exception_detected .text_exception { - width: 520px; + left: 10px; + right: 10px; + width: 95%; } .sf-exceptionreset .block_exception_detected .illustration_exception { @@ -488,3 +493,20 @@ td.main, td.menu { border: 1px solid #999; border-width: 1px 0; } + +.collapsed-menu-parents #resume, +.collapsed-menu-parents #collector_content { + margin-left: 60px !important; +} + +.collapsed-menu { + width: 60px !important; +} + +.collapsed-menu span :not(.icon) { + display: none !important; +} + +.collapsed-menu span.icon img { + display: inline !important; +} diff --git a/src/Symfony/Bundle/WebProfilerBundle/Resources/public/images/profiler/left-arrow.png b/src/Symfony/Bundle/WebProfilerBundle/Resources/public/images/profiler/left-arrow.png new file mode 100644 index 0000000000000000000000000000000000000000..1c63f0919bd228b3a5f91330cd46a2f8774ceabd GIT binary patch literal 1001 zcmVI3MnFyh>-ewR#sL}C=@;y ziA4QYtMxX%3TF!D8w`e%Ua$A!!otE9CNs&&$r+c)Waljw%RRb3up)SHa4_F&Huv~^ zz9Z?Zp;Rh0n@py2Wo2a{#^9l$p$#1!9ghQnz}`#}NGulH1_lN+xctr}t8=@$x~^vm zC2e+gR*9v$hRe07!2Fh$mPU`qbCAXT2kCxvxm+Q9&-2h^GXy-&6<-Jt2|>D>q$p&9Cod3L+KBpeR& zQ$P=;10~Jx_vgFa?gFxfso?BjFepng)&l4Q3Um{~T_(_Y!&1uP%s4m;R+pV(oDr}C z6#w=j)Iq# z_!+iviA3@vFE4K{-Y*U&K!0gzsh8nXyOIRnO*f#pxY&b04vYvDOg?;5C=_p4xYl1d zq5+|it~2_)BKDokKztgF<`IswMV9beh&SjuVQoV-H8oGk9I)c>;;N93)VZB zDHM-)rm3mPj7tYe-c%I`aiTrY;m*#^(|vt?61G6{c#THmSDj9GGiIqyXn{%1C4fpH z^~lJG78T|$oYjm|Ao00000NkvXXu0mjfq3p}1 literal 0 HcmV?d00001 diff --git a/src/Symfony/Bundle/WebProfilerBundle/Resources/public/images/profiler/right-arrow.png b/src/Symfony/Bundle/WebProfilerBundle/Resources/public/images/profiler/right-arrow.png new file mode 100644 index 0000000000000000000000000000000000000000..bc6166272eb952cfeabe589d5a6e7ba69c10b1bd GIT binary patch literal 1001 zcmV z&dwe|r&?D#*aRH~oFVohgdWj)krH21|~ zaUfMNO{G#bI-SlNfj~e+M8I^VQaNa~T3dD^dWAyaQ@vh) z9)=rR;sSGBdQVT!1p?5QM8OarCt=rZC|;6*b4(`FHJr6BO-xKk!CoN>pP!$qOy@f;@HfwL_Z%Nd+C~?#u+wI;*;N}y-?}9m%Y*H{7q)kpv zmc*DbFclt!kVKXs_#=Sxk}Hh)`8SxsV9-c_L!cIbEyaF-n>Y?emGo{I z3+1WN9Dc>fNX&1M$PI(kquQK_%Sjv(n+Jy9>eK3?2dh)kFBk(uOP_q)@mk^ z0ci?_Vj7?yVCYFyxzMw>R##V#%Ve@IJJr-dBd{cuN*}<`9N&>(w}zZ==;-Ls*45Rm zr3wYVdb_&1P*Irzt>HETpo1XU=;-K0olch*4u?rYo0^)wwzs$6fg$qidr*K#>yrs8 z2Awb(jg4BZ_AuBCBEX`eqD|;DP37g~<8b-{#SLhkOqaPA6&uh|Q0>gj%rS$(uph*7 zI2=?=dlRmxs93M8taN}-O1?%e1EE;?zMb|K)m1j=0H`D?)aG)b;4`7WPUCPm8_^W` zjG7J5Cy*t+SftX>r-M*#=S1_J6@4P;_=&0>DnQWy@+AYN`t3x)lv~n^?Ak}$F98Ms X>*aOuJKrDw00000NkvXXu0mjfh)3Nk literal 0 HcmV?d00001 diff --git a/src/Symfony/Bundle/WebProfilerBundle/Resources/views/Collector/time.html.twig b/src/Symfony/Bundle/WebProfilerBundle/Resources/views/Collector/time.html.twig index d283182720f18..f4179792ffba4 100644 --- a/src/Symfony/Bundle/WebProfilerBundle/Resources/views/Collector/time.html.twig +++ b/src/Symfony/Bundle/WebProfilerBundle/Resources/views/Collector/time.html.twig @@ -134,7 +134,7 @@ "use strict"; var _drawingColors = {{ colors|json_encode|raw }}, - _storagePrefix = 'sf2/profiler/timeline', + _storagePrefix = 'timeline/', _threshold = 1, _requests = requests, _maxRequestTime = maxRequestTime; @@ -353,7 +353,7 @@ }; this.getThreshold = function() { - var threshold = localStorage.getItem(_storagePrefix + '/threshold'); + var threshold = Sfjs.getPreference(_storagePrefix + 'threshold'); if (threshold === null) { return _threshold; @@ -368,7 +368,7 @@ { _threshold = threshold; - localStorage.setItem(_storagePrefix + '/threshold', threshold); + Sfjs.setPreference(_storagePrefix + 'threshold', threshold); return this; }; @@ -423,6 +423,11 @@ elementThresholdControl.onclick = canvasAutoUpdateOnThresholdChange; elementThresholdControl.onchange = canvasAutoUpdateOnThresholdChange; elementThresholdControl.onkeyup = canvasAutoUpdateOnThresholdChange; + + window.setTimeout(function() { + canvasAutoUpdateOnThresholdChange(null); + }, 50); + //]]> {% endblock %} diff --git a/src/Symfony/Bundle/WebProfilerBundle/Resources/views/Profiler/admin.html.twig b/src/Symfony/Bundle/WebProfilerBundle/Resources/views/Profiler/admin.html.twig index 2488af4157221..8989115b2b499 100644 --- a/src/Symfony/Bundle/WebProfilerBundle/Resources/views/Profiler/admin.html.twig +++ b/src/Symfony/Bundle/WebProfilerBundle/Resources/views/Profiler/admin.html.twig @@ -1,4 +1,4 @@ -