Merge branch '2.2'

* 2.2:
  Fix default value handling for multi-value options
  [HttpKernel] truncate profiler token to 6 chars (see #7665)
  Disabled APC on Travis for PHP 5.5+ as it is not available
  [HttpFoundation] do not use server variable PATH_INFO because it is already decoded and thus symfony is fragile to double encoding of the path
  Fix download over SSL using IE < 8 and binary file response
  [Console] Fix merging of application definition, fixes #7068, replaces #7158
  [HttpKernel] fixed the Kernel when the ClassLoader component is not available (closes #7406)
  fixed output of bag values
  [Yaml] improved boolean naming ($notEOF -> !$EOF)
  [Yaml] fixed handling an empty value
  [Routing][XML Loader] Add a possibility to set a default value to null
  [Console] fixed handling of "0" input on ask
  The /e modifier for preg_replace() is deprecated in PHP 5.5; replace with preg_replace_callback()
  fixed handling of "0" input on ask
  [HttpFoundation] Fixed bug in key searching for NamespacedAttributeBag
  [Form] DateTimeToRfc3339Transformer use proper transformation exteption in reverse transformation
  Update PhpEngine.php
  [PropertyAccess] Add objectives to pluralMap
  [Security] Removed unused var
  [HttpFoundation] getClientIp is fixed.

Conflicts:
	src/Symfony/Component/Console/Tests/Command/CommandTest.php
	src/Symfony/Component/Console/Tests/Input/ArgvInputTest.php
	src/Symfony/Component/HttpFoundation/Request.php
	src/Symfony/Component/HttpKernel/Kernel.php
This commit is contained in:
Fabien Potencier 2013-04-17 07:31:37 +02:00
commit 1b2619078d
33 changed files with 245 additions and 122 deletions

View File

@ -12,7 +12,7 @@ matrix:
before_script:
- echo '' > ~/.phpenv/versions/$(phpenv version-name)/etc/conf.d/xdebug.ini
- echo "extension = apc.so" >> ~/.phpenv/versions/$(phpenv version-name)/etc/php.ini
- sh -c 'if [ $(php -r "echo PHP_MINOR_VERSION;") -le 4 ]; then echo "extension = apc.so" >> ~/.phpenv/versions/$(phpenv version-name)/etc/php.ini; fi;'
- COMPOSER_ROOT_VERSION=dev-master composer --prefer-source --dev install
- php src/Symfony/Component/Locale/Resources/data/build-data.php
- export USE_INTL_ICU_DATA_VERSION=1

View File

@ -33,10 +33,11 @@ class RegisterKernelListenersPass implements CompilerPassInterface
}
if (!isset($event['method'])) {
$event['method'] = 'on'.preg_replace(array(
'/(?<=\b)[a-z]/ie',
'/[^a-z0-9]/i'
), array('strtoupper("\\0")', ''), $event['event']);
$event['method'] = 'on'.preg_replace_callback(array(
'/(?<=\b)[a-z]/i',
'/[^a-z0-9]/i',
), function ($matches) { return strtoupper($matches[0]); }, $event['event']);
$event['method'] = preg_replace('/[^a-z0-9]/i', '', $event['method']);
}
$definition->addMethodCall('addListenerService', array($event['event'], array($id, $event['method']), $priority));

View File

@ -7,10 +7,11 @@
</thead>
<tbody>
{% for key in bag.keys|sort %}
<tr>
<th>{{ key }}</th>
<td>{{ bag.get(key)|json_encode }}</td>
</tr>
<tr>
<th>{{ key }}</th>
{# JSON_UNESCAPED_SLASHES = 64, JSON_UNESCAPED_UNICODE = 256 #}
<td>{{ bag.get(key)|json_encode(64 b-or 256) }}</td>
</tr>
{% endfor %}
</tbody>
</table>

View File

@ -9,7 +9,8 @@
{% for key in data|keys|sort %}
<tr>
<th>{{ key }}</th>
<td>{{ data[key]|json_encode }}</td>
{# JSON_UNESCAPED_SLASHES = 64, JSON_UNESCAPED_UNICODE = 256 #}
<td>{{ data[key]|json_encode(64 b-or 256) }}</td>
</tr>
{% endfor %}
</tbody>

View File

@ -36,6 +36,7 @@ class Command
private $description;
private $ignoreValidationErrors;
private $applicationDefinitionMerged;
private $applicationDefinitionMergedWithArgs;
private $code;
private $synopsis;
private $helperSet;
@ -54,6 +55,7 @@ class Command
$this->definition = new InputDefinition();
$this->ignoreValidationErrors = false;
$this->applicationDefinitionMerged = false;
$this->applicationDefinitionMergedWithArgs = false;
$this->aliases = array();
if (null !== $name) {
@ -277,7 +279,7 @@ class Command
*/
private function mergeApplicationDefinition($mergeArgs = true)
{
if (null === $this->application || true === $this->applicationDefinitionMerged) {
if (null === $this->application || (true === $this->applicationDefinitionMerged && ($this->applicationDefinitionMergedWithArgs || !$mergeArgs))) {
return;
}
@ -290,6 +292,9 @@ class Command
$this->definition->addOptions($this->application->getDefinition()->getOptions());
$this->applicationDefinitionMerged = true;
if ($mergeArgs) {
$this->applicationDefinitionMergedWithArgs = true;
}
}
/**

View File

@ -102,7 +102,9 @@ class DialogHelper extends Helper
$output->getFormatter()->setStyle('hl', new OutputFormatterStyle('black', 'white'));
// Read a keypress
while ($c = fread($inputStream, 1)) {
while (!feof($inputStream)) {
$c = fread($inputStream, 1);
// Backspace Character
if ("\177" === $c) {
if (0 === $numMatches && 0 !== $i) {

View File

@ -215,6 +215,11 @@ class ArgvInput extends Input
$option = $this->definition->getOption($name);
// Convert false values (from a previous call to substr()) to null
if (false === $value) {
$value = null;
}
if (null === $value && $option->acceptValue() && count($this->parsed)) {
// if option accepts an optional or mandatory argument
// let's see if there is one provided
@ -233,7 +238,9 @@ class ArgvInput extends Input
throw new \RuntimeException(sprintf('The "--%s" option requires a value.', $name));
}
$value = $option->isValueOptional() ? $option->getDefault() : true;
if (!$option->isArray()) {
$value = $option->isValueOptional() ? $option->getDefault() : true;
}
}
if ($option->isArray()) {

View File

@ -198,6 +198,29 @@ class CommandTest extends \PHPUnit_Framework_TestCase
$this->assertEquals(3, $command->getDefinition()->getArgumentCount(), '->mergeApplicationDefinition() does not try to merge twice the application arguments and options');
}
public function testMergeApplicationDefinitionWithoutArgsThenWithArgsAddsArgs()
{
$application1 = new Application();
$application1->getDefinition()->addArguments(array(new InputArgument('foo')));
$application1->getDefinition()->addOptions(array(new InputOption('bar')));
$command = new \TestCommand();
$command->setApplication($application1);
$command->setDefinition($definition = new InputDefinition(array()));
$r = new \ReflectionObject($command);
$m = $r->getMethod('mergeApplicationDefinition');
$m->setAccessible(true);
$m->invoke($command, false);
$this->assertTrue($command->getDefinition()->hasOption('bar'), '->mergeApplicationDefinition(false) merges the application and the commmand options');
$this->assertFalse($command->getDefinition()->hasArgument('foo'), '->mergeApplicationDefinition(false) does not merge the application arguments');
$m->invoke($command, true);
$this->assertTrue($command->getDefinition()->hasArgument('foo'), '->mergeApplicationDefinition(true) merges the application arguments and the command arguments');
$m->invoke($command);
$this->assertEquals(2, $command->getDefinition()->getArgumentCount(), '->mergeApplicationDefinition() does not try to merge twice the application arguments');
}
public function testRunInteractive()
{
$tester = new CommandTester(new \TestCommand());

View File

@ -69,7 +69,8 @@ class DialogHelperTest extends \PHPUnit_Framework_TestCase
// <UP ARROW><UP ARROW><UP ARROW><UP ARROW><UP ARROW><TAB>Test<NEWLINE>
// <DOWN ARROW><NEWLINE>
// S<BACKSPACE><BACKSPACE><DOWN ARROW><DOWN ARROW><NEWLINE>
$inputStream = $this->getInputStream("Acm\nAc\177\177s\tTest\n\n\033[A\033[A\n\033[A\033[A\033[A\033[A\033[A\tTest\n\033[B\nS\177\177\033[B\033[B\n");
// F00<BACKSPACE><BACKSPACE>oo<TAB><NEWLINE>
$inputStream = $this->getInputStream("Acm\nAc\177\177s\tTest\n\n\033[A\033[A\n\033[A\033[A\033[A\033[A\033[A\tTest\n\033[B\nS\177\177\033[B\033[B\nF00\177\177oo\t\n");
$dialog = new DialogHelper();
$dialog->setInputStream($inputStream);
@ -83,6 +84,7 @@ class DialogHelperTest extends \PHPUnit_Framework_TestCase
$this->assertEquals('FooBundleTest', $dialog->ask($this->getOutputStream(), 'Please select a bundle', 'FrameworkBundle', $bundles));
$this->assertEquals('AcmeDemoBundle', $dialog->ask($this->getOutputStream(), 'Please select a bundle', 'FrameworkBundle', $bundles));
$this->assertEquals('AsseticBundle', $dialog->ask($this->getOutputStream(), 'Please select a bundle', 'FrameworkBundle', $bundles));
$this->assertEquals('FooBundle', $dialog->ask($this->getOutputStream(), 'Please select a bundle', 'FrameworkBundle', $bundles));
}
public function testAskHiddenResponse()

View File

@ -211,6 +211,23 @@ class ArgvInputTest extends \PHPUnit_Framework_TestCase
$input = new ArgvInput(array('cli.php', '--name=foo', '--name=bar', '--name=baz'));
$input->bind(new InputDefinition(array(new InputOption('name', null, InputOption::VALUE_OPTIONAL | InputOption::VALUE_IS_ARRAY))));
$this->assertEquals(array('name' => array('foo', 'bar', 'baz')), $input->getOptions(), '->parse() parses array options ("--option=value" syntax)');
$input = new ArgvInput(array('cli.php', '--name', 'foo', '--name', 'bar', '--name', 'baz'));
$input->bind(new InputDefinition(array(new InputOption('name', null, InputOption::VALUE_OPTIONAL | InputOption::VALUE_IS_ARRAY))));
$this->assertEquals(array('name' => array('foo', 'bar', 'baz')), $input->getOptions(), '->parse() parses array options ("--option value" syntax)');
$input = new ArgvInput(array('cli.php', '--name=foo', '--name=bar', '--name='));
$input->bind(new InputDefinition(array(new InputOption('name', null, InputOption::VALUE_OPTIONAL | InputOption::VALUE_IS_ARRAY))));
$this->assertSame(array('name' => array('foo', 'bar', null)), $input->getOptions(), '->parse() parses empty array options as null ("--option=value" syntax)');
$input = new ArgvInput(array('cli.php', '--name', 'foo', '--name', 'bar', '--name', '--anotherOption'));
$input->bind(new InputDefinition(array(
new InputOption('name', null, InputOption::VALUE_OPTIONAL | InputOption::VALUE_IS_ARRAY),
new InputOption('anotherOption', null, InputOption::VALUE_NONE),
)));
$this->assertSame(array('name' => array('foo', 'bar', null), 'anotherOption' => true), $input->getOptions(), '->parse() parses empty array options as null ("--option value" syntax)');
$this->assertEquals(array('name' => array('foo', 'bar', 'baz')), $input->getOptions());
}

View File

@ -53,7 +53,11 @@ class DateTimeToRfc3339Transformer extends BaseDateTimeTransformer
return null;
}
$dateTime = new \DateTime($rfc3339);
try {
$dateTime = new \DateTime($rfc3339);
} catch (\Exception $e) {
throw new TransformationFailedException($e->getMessage(), $e->getCode(), $e);
}
if ($this->outputTimezone !== $this->inputTimezone) {
try {

View File

@ -119,4 +119,14 @@ class DateTimeToRfc3339TransformerTest extends DateTimeTestCase
$transformer->reverseTransform('2010-04-31T04:05Z');
}
/**
* @expectedException Symfony\Component\Form\Exception\TransformationFailedException
*/
public function testReverseTransformExpectsValidDateString()
{
$transformer = new DateTimeToRfc3339Transformer('UTC', 'UTC');
$transformer->reverseTransform('2010-2010-2010');
}
}

View File

@ -40,12 +40,4 @@ class ApacheRequest extends Request
return $baseUrl;
}
/**
* {@inheritdoc}
*/
protected function preparePathInfo()
{
return $this->server->get('PATH_INFO') ?: substr($this->prepareRequestUri(), strlen($this->prepareBaseUrl())) ?: '/';
}
}

View File

@ -166,6 +166,8 @@ class BinaryFileResponse extends Response
$this->setProtocolVersion('1.1');
}
$this->ensureIEOverSSLCompatibility($request);
$this->offset = 0;
$this->maxlen = -1;

View File

@ -684,9 +684,10 @@ class Request
$clientIps[] = $ip;
$trustedProxies = self::$trustProxy && !self::$trustedProxies ? array($ip) : self::$trustedProxies;
$ip = $clientIps[0];
$clientIps = array_diff($clientIps, $trustedProxies);
return $clientIps;
return $clientIps ? $clientIps : array($ip);
}
/**

View File

@ -253,15 +253,7 @@ class Response
$this->headers->set('expires', -1);
}
/**
* Check if we need to remove Cache-Control for ssl encrypted downloads when using IE < 9
* @link http://support.microsoft.com/kb/323308
*/
if (false !== stripos($this->headers->get('Content-Disposition'), 'attachment') && preg_match('/MSIE (.*?);/i', $request->server->get('HTTP_USER_AGENT'), $match) == 1 && true === $request->isSecure()) {
if (intval(preg_replace("/(MSIE )(.*?);/", "$2", $match[0])) < 9) {
$this->headers->remove('Cache-Control');
}
}
$this->ensureIEOverSSLCompatibility($request);
return $this;
}
@ -1179,4 +1171,18 @@ class Response
{
return in_array($this->statusCode, array(201, 204, 304));
}
/**
* Check if we need to remove Cache-Control for ssl encrypted downloads when using IE < 9
*
* @link http://support.microsoft.com/kb/323308
*/
protected function ensureIEOverSSLCompatibility(Request $request)
{
if (false !== stripos($this->headers->get('Content-Disposition'), 'attachment') && preg_match('/MSIE (.*?);/i', $request->server->get('HTTP_USER_AGENT'), $match) == 1 && true === $request->isSecure()) {
if (intval(preg_replace("/(MSIE )(.*?);/", "$2", $match[0])) < 9) {
$this->headers->remove('Cache-Control');
}
}
}
}

View File

@ -46,6 +46,10 @@ class NamespacedAttributeBag extends AttributeBag
$attributes = $this->resolveAttributePath($name);
$name = $this->resolveKey($name);
if (null === $attributes) {
return false;
}
return array_key_exists($name, $attributes);
}
@ -57,6 +61,10 @@ class NamespacedAttributeBag extends AttributeBag
$attributes = $this->resolveAttributePath($name);
$name = $this->resolveKey($name);
if (null === $attributes) {
return $default;
}
return array_key_exists($name, $attributes) ? $attributes[$name] : $default;
}
@ -120,12 +128,8 @@ class NamespacedAttributeBag extends AttributeBag
unset($parts[count($parts)-1]);
foreach ($parts as $part) {
if (!array_key_exists($part, $array)) {
if (!$writeContext) {
return $array;
}
$array[$part] = array();
if (null !== $array && !array_key_exists($part, $array)) {
$array[$part] = $writeContext ? array() : null;
}
$array = & $array[$part];

View File

@ -15,7 +15,7 @@ use Symfony\Component\HttpFoundation\BinaryFileResponse;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\ResponseHeaderBag;
class BinaryFileResponseTest extends \PHPUnit_Framework_TestCase
class BinaryFileResponseTest extends ResponseTestCase
{
public function testConstruction()
{
@ -145,4 +145,9 @@ class BinaryFileResponseTest extends \PHPUnit_Framework_TestCase
array('/home/foo/bar.txt', '/files/=/var/www/,/baz/=/home/foo/', '/baz/bar.txt'),
);
}
protected function provideResponse()
{
return new BinaryFileResponse('README.md');
}
}

View File

@ -754,6 +754,7 @@ class RequestTest extends \PHPUnit_Framework_TestCase
{
return array(
array('88.88.88.88', false, '88.88.88.88', null, null),
array('88.88.88.88', true, '88.88.88.88', null, null),
array('127.0.0.1', false, '127.0.0.1', null, null),
array('::1', false, '::1', null, null),
array('127.0.0.1', false, '127.0.0.1', '88.88.88.88', null),
@ -762,6 +763,8 @@ class RequestTest extends \PHPUnit_Framework_TestCase
array('88.88.88.88', true, '123.45.67.89', '127.0.0.1, 87.65.43.21, 88.88.88.88', null),
array('87.65.43.21', true, '123.45.67.89', '127.0.0.1, 87.65.43.21, 88.88.88.88', array('123.45.67.89', '88.88.88.88')),
array('87.65.43.21', false, '123.45.67.89', '127.0.0.1, 87.65.43.21, 88.88.88.88', array('123.45.67.89', '88.88.88.88')),
array('88.88.88.88', true, '123.45.67.89', '88.88.88.88', array('123.45.67.89', '88.88.88.88')),
array('88.88.88.88', false, '123.45.67.89', '88.88.88.88', array('123.45.67.89', '88.88.88.88')),
);
}

View File

@ -14,7 +14,7 @@ namespace Symfony\Component\HttpFoundation\Tests;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
class ResponseTest extends \PHPUnit_Framework_TestCase
class ResponseTest extends ResponseTestCase
{
public function testCreate()
{
@ -326,75 +326,6 @@ class ResponseTest extends \PHPUnit_Framework_TestCase
$this->assertEquals('text/css; charset=UTF-8', $response->headers->get('Content-Type'));
}
public function testNoCacheControlHeaderOnAttachmentUsingHTTPSAndMSIE()
{
// Check for HTTPS and IE 8
$request = new Request();
$request->server->set('HTTPS', true);
$request->server->set('HTTP_USER_AGENT', 'Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.0; Trident/4.0)');
$response = new Response();
$response->headers->set('Content-Disposition', 'attachment; filename="fname.ext"');
$response->prepare($request);
$this->assertFalse($response->headers->has('Cache-Control'));
// Check for IE 10 and HTTPS
$request->server->set('HTTP_USER_AGENT', 'Mozilla/5.0 (compatible; MSIE 10.0; Windows NT 6.1; WOW64; Trident/6.0)');
$response = new Response();
$response->headers->set('Content-Disposition', 'attachment; filename="fname.ext"');
$response->prepare($request);
$this->assertTrue($response->headers->has('Cache-Control'));
// Check for IE 9 and HTTPS
$request->server->set('HTTP_USER_AGENT', 'Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 7.1; Trident/5.0)');
$response = new Response();
$response->headers->set('Content-Disposition', 'attachment; filename="fname.ext"');
$response->prepare($request);
$this->assertTrue($response->headers->has('Cache-Control'));
// Check for IE 9 and HTTP
$request->server->set('HTTPS', false);
$response = new Response();
$response->headers->set('Content-Disposition', 'attachment; filename="fname.ext"');
$response->prepare($request);
$this->assertTrue($response->headers->has('Cache-Control'));
// Check for IE 8 and HTTP
$request->server->set('HTTP_USER_AGENT', 'Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.0; Trident/4.0)');
$response = new Response();
$response->headers->set('Content-Disposition', 'attachment; filename="fname.ext"');
$response->prepare($request);
$this->assertTrue($response->headers->has('Cache-Control'));
// Check for non-IE and HTTPS
$request->server->set('HTTPS', true);
$request->server->set('HTTP_USER_AGENT', 'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.17 (KHTML, like Gecko) Chrome/24.0.1312.60 Safari/537.17');
$response = new Response();
$response->headers->set('Content-Disposition', 'attachment; filename="fname.ext"');
$response->prepare($request);
$this->assertTrue($response->headers->has('Cache-Control'));
// Check for non-IE and HTTP
$request->server->set('HTTPS', false);
$response = new Response();
$response->headers->set('Content-Disposition', 'attachment; filename="fname.ext"');
$response->prepare($request);
$this->assertTrue($response->headers->has('Cache-Control'));
}
public function testPrepareDoesNothingIfContentTypeIsSet()
{
$response = new Response('foo');
@ -770,6 +701,11 @@ class ResponseTest extends \PHPUnit_Framework_TestCase
{
return new \DateTime();
}
protected function provideResponse()
{
return new Response();
}
}
class StringableObject

View File

@ -0,0 +1,79 @@
<?php
namespace Symfony\Component\HttpFoundation\Tests;
use Symfony\Component\HttpFoundation\Request;
abstract class ResponseTestCase extends \PHPUnit_Framework_TestCase
{
public function testNoCacheControlHeaderOnAttachmentUsingHTTPSAndMSIE()
{
// Check for HTTPS and IE 8
$request = new Request();
$request->server->set('HTTPS', true);
$request->server->set('HTTP_USER_AGENT', 'Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.0; Trident/4.0)');
$response = $this->provideResponse();
$response->headers->set('Content-Disposition', 'attachment; filename="fname.ext"');
$response->prepare($request);
$this->assertFalse($response->headers->has('Cache-Control'));
// Check for IE 10 and HTTPS
$request->server->set('HTTP_USER_AGENT', 'Mozilla/5.0 (compatible; MSIE 10.0; Windows NT 6.1; WOW64; Trident/6.0)');
$response = $this->provideResponse();
$response->headers->set('Content-Disposition', 'attachment; filename="fname.ext"');
$response->prepare($request);
$this->assertTrue($response->headers->has('Cache-Control'));
// Check for IE 9 and HTTPS
$request->server->set('HTTP_USER_AGENT', 'Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 7.1; Trident/5.0)');
$response = $this->provideResponse();
$response->headers->set('Content-Disposition', 'attachment; filename="fname.ext"');
$response->prepare($request);
$this->assertTrue($response->headers->has('Cache-Control'));
// Check for IE 9 and HTTP
$request->server->set('HTTPS', false);
$response = $this->provideResponse();
$response->headers->set('Content-Disposition', 'attachment; filename="fname.ext"');
$response->prepare($request);
$this->assertTrue($response->headers->has('Cache-Control'));
// Check for IE 8 and HTTP
$request->server->set('HTTP_USER_AGENT', 'Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.0; Trident/4.0)');
$response = $this->provideResponse();
$response->headers->set('Content-Disposition', 'attachment; filename="fname.ext"');
$response->prepare($request);
$this->assertTrue($response->headers->has('Cache-Control'));
// Check for non-IE and HTTPS
$request->server->set('HTTPS', true);
$request->server->set('HTTP_USER_AGENT', 'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.17 (KHTML, like Gecko) Chrome/24.0.1312.60 Safari/537.17');
$response = $this->provideResponse();
$response->headers->set('Content-Disposition', 'attachment; filename="fname.ext"');
$response->prepare($request);
$this->assertTrue($response->headers->has('Cache-Control'));
// Check for non-IE and HTTP
$request->server->set('HTTPS', false);
$response = $this->provideResponse();
$response->headers->set('Content-Disposition', 'attachment; filename="fname.ext"');
$response->prepare($request);
$this->assertTrue($response->headers->has('Cache-Control'));
}
abstract protected function provideResponse();
}

View File

@ -160,8 +160,10 @@ class NamespacedAttributeBagTest extends \PHPUnit_Framework_TestCase
array('csrf.token/b', '4321', true),
array('category', array('fishing' => array('first' => 'cod', 'second' => 'sole')), true),
array('category/fishing', array('first' => 'cod', 'second' => 'sole'), true),
array('category/fishing/missing/first', null, false),
array('category/fishing/first', 'cod', true),
array('category/fishing/second', 'sole', true),
array('category/fishing/missing/second', null, false),
array('user2.login', null, false),
array('never', null, false),
array('bye', null, false),

View File

@ -204,7 +204,7 @@ class Profiler
return;
}
$profile = new Profile(sha1(uniqid(mt_rand(), true)));
$profile = new Profile(substr(sha1(uniqid(mt_rand(), true)), 0, 6));
$profile->setTime(time());
$profile->setUrl($request->getUri());
$profile->setIp($request->getClientIp());

View File

@ -69,6 +69,9 @@ class StringUtil
// atlases (atlas), kisses (kiss)
array('ses', 3, true, true, array('s', 'se', 'sis')),
// objectives (objective), alternative (alternatives)
array('sevit', 5, true, true, 'tive'),
// lives (life), wives (wife)
array('sevi', 4, false, true, 'ife'),

View File

@ -117,6 +117,7 @@ class StringUtilTest extends \PHPUnit_Framework_TestCase
array('bees', array('be', 'bee')),
array('cheeses', array('chees', 'cheese', 'cheesis')),
array('radii', 'radius'),
array('objectives', 'objective'),
// test casing: if the first letter was uppercase, it should remain so
array('Men', 'Man'),

View File

@ -215,7 +215,12 @@ class XmlFileLoader extends FileLoader
foreach ($node->getElementsByTagNameNS(self::NAMESPACE_URI, '*') as $n) {
switch ($n->localName) {
case 'default':
$defaults[$n->getAttribute('key')] = trim($n->textContent);
if ($n->hasAttribute('xsi:nil') && 'true' == $n->getAttribute('xsi:nil')) {
$defaults[$n->getAttribute('key')] = null;
} else {
$defaults[$n->getAttribute('key')] = trim($n->textContent);
}
break;
case 'requirement':
$requirements[$n->getAttribute('key')] = trim($n->textContent);

View File

@ -26,7 +26,7 @@
<xsd:group name="configs">
<xsd:choice>
<xsd:element name="default" type="element" />
<xsd:element name="default" nillable="true" type="element" />
<xsd:element name="requirement" type="element" />
<xsd:element name="option" type="element" />
</xsd:choice>

View File

@ -12,6 +12,7 @@
<route id="blog_show_legacy" pattern="/blog/{slug}" host="{locale}.example.com">
<default key="_controller">MyBundle:Blog:show</default>
<default key="slug" xsi:nil="true" />
<requirement key="_method">GET|POST|put|OpTiOnS</requirement>
<requirement key="_scheme">hTTps</requirement>
<requirement key="locale">\w+</requirement>

View File

@ -68,6 +68,7 @@ class XmlFileLoaderTest extends \PHPUnit_Framework_TestCase
$this->assertSame('MyBundle:Blog:show', $route->getDefault('_controller'));
$this->assertSame('\w+', $route->getRequirement('slug'));
$this->assertSame('en|fr|de', $route->getRequirement('_locale'));
$this->assertSame(null, $route->getDefault('slug'));
$this->assertSame('RouteCompiler', $route->getOption('compiler_class'));
}

View File

@ -63,7 +63,7 @@ class Firewall implements EventSubscriberInterface
// initiate the listener chain
foreach ($listeners as $listener) {
$response = $listener->handle($event);
$listener->handle($event);
if ($event->hasResponse()) {
break;

View File

@ -186,7 +186,7 @@ class PhpEngine implements EngineInterface, \ArrayAccess
*
* @param string $name The helper name
*
* @return mixed The helper value
* @return HelperInterface The helper value
*
* @throws \InvalidArgumentException if the helper is not defined
*

View File

@ -102,7 +102,7 @@ class Parser
$parser->refs =& $this->refs;
$block = $values['value'];
if (!$this->isNextLineIndented()) {
if ($this->isNextLineIndented()) {
$block .= "\n".$this->getNextEmbedBlock($this->getCurrentLineIndentation() + 2);
}
@ -174,7 +174,7 @@ class Parser
// hash
} elseif (!isset($values['value']) || '' == trim($values['value'], ' ') || 0 === strpos(ltrim($values['value'], ' '), '#')) {
// if next line is less indented or equal, then it means that the current value is null
if ($this->isNextLineIndented() && !$this->isNextLineUnIndentedCollection()) {
if (!$this->isNextLineIndented() && !$this->isNextLineUnIndentedCollection()) {
$data[$key] = null;
} else {
$c = $this->getRealCurrentLineNb() + 1;
@ -482,18 +482,18 @@ class Parser
private function isNextLineIndented()
{
$currentIndentation = $this->getCurrentLineIndentation();
$notEOF = $this->moveToNextLine();
$EOF = !$this->moveToNextLine();
while ($notEOF && $this->isCurrentLineEmpty()) {
$notEOF = $this->moveToNextLine();
while (!$EOF && $this->isCurrentLineEmpty()) {
$EOF = !$this->moveToNextLine();
}
if (false === $notEOF) {
if ($EOF) {
return false;
}
$ret = false;
if ($this->getCurrentLineIndentation() <= $currentIndentation) {
if ($this->getCurrentLineIndentation() > $currentIndentation) {
$ret = true;
}

View File

@ -492,6 +492,15 @@ yaml:
EOF
);
}
public function testEmptyValue()
{
$input = <<<EOF
hash:
EOF;
$this->assertEquals(array('hash' => null), Yaml::parse($input));
}
}
class B