*/
interface AdapterInterface extends CacheItemPoolInterface
{
+ /**
+ * {@inheritdoc}
+ *
+ * @return CacheItem
+ */
+ public function getItem($key);
+
+ /**
+ * {@inheritdoc}
+ *
+ * return \Traversable|CacheItem[]
+ */
+ public function getItems(array $keys = array());
}
diff --git a/src/Symfony/Component/Cache/Adapter/FilesystemAdapter.php b/src/Symfony/Component/Cache/Adapter/FilesystemAdapter.php
index 5fd1d31a45e66..1c62641cf6d67 100644
--- a/src/Symfony/Component/Cache/Adapter/FilesystemAdapter.php
+++ b/src/Symfony/Component/Cache/Adapter/FilesystemAdapter.php
@@ -11,6 +11,8 @@
namespace Symfony\Component\Cache\Adapter;
+use Symfony\Component\Cache\Exception\CacheException;
+
/**
* @author Nicolas Grekas
*/
diff --git a/src/Symfony/Component/Cache/Adapter/FilesystemAdapterTrait.php b/src/Symfony/Component/Cache/Adapter/FilesystemAdapterTrait.php
index 34ed20e6d2660..156fc5c1fb63a 100644
--- a/src/Symfony/Component/Cache/Adapter/FilesystemAdapterTrait.php
+++ b/src/Symfony/Component/Cache/Adapter/FilesystemAdapterTrait.php
@@ -11,7 +11,6 @@
namespace Symfony\Component\Cache\Adapter;
-use Symfony\Component\Cache\Exception\CacheException;
use Symfony\Component\Cache\Exception\InvalidArgumentException;
/**
diff --git a/src/Symfony/Component/Cache/Adapter/PdoAdapter.php b/src/Symfony/Component/Cache/Adapter/PdoAdapter.php
index 24245fcf27d10..3fa3a40533d9e 100644
--- a/src/Symfony/Component/Cache/Adapter/PdoAdapter.php
+++ b/src/Symfony/Component/Cache/Adapter/PdoAdapter.php
@@ -108,9 +108,20 @@ public function createTable()
$conn = $this->getConnection();
if ($conn instanceof Connection) {
+ $types = array(
+ 'mysql' => 'binary',
+ 'sqlite' => 'text',
+ 'pgsql' => 'string',
+ 'oci' => 'string',
+ 'sqlsrv' => 'string',
+ );
+ if (!isset($types[$this->driver])) {
+ throw new \DomainException(sprintf('Creating the cache table is currently not implemented for PDO driver "%s".', $this->driver));
+ }
+
$schema = new Schema();
$table = $schema->createTable($this->table);
- $table->addColumn($this->idCol, 'blob', array('length' => 255));
+ $table->addColumn($this->idCol, $types[$this->driver], array('length' => 255));
$table->addColumn($this->dataCol, 'blob', array('length' => 16777215));
$table->addColumn($this->lifetimeCol, 'integer', array('unsigned' => true, 'notnull' => false));
$table->addColumn($this->timeCol, 'integer', array('unsigned' => true, 'foo' => 'bar'));
diff --git a/src/Symfony/Component/Cache/Adapter/PhpArrayAdapter.php b/src/Symfony/Component/Cache/Adapter/PhpArrayAdapter.php
index e4d8ad5eea318..c272ad0a4ae5f 100644
--- a/src/Symfony/Component/Cache/Adapter/PhpArrayAdapter.php
+++ b/src/Symfony/Component/Cache/Adapter/PhpArrayAdapter.php
@@ -373,15 +373,15 @@ private function generateItems(array $keys)
*/
public static function throwOnRequiredClass($class)
{
- $e = new \ReflectionException(sprintf('Class %s does not exist', $class));
+ $e = new \ReflectionException("Class $class does not exist");
$trace = $e->getTrace();
$autoloadFrame = array(
'function' => 'spl_autoload_call',
'args' => array($class),
);
- $i = array_search($autoloadFrame, $trace);
+ $i = 1 + array_search($autoloadFrame, $trace, true);
- if (false !== $i++ && isset($trace[$i]['function']) && !isset($trace[$i]['class'])) {
+ if (isset($trace[$i]['function']) && !isset($trace[$i]['class'])) {
switch ($trace[$i]['function']) {
case 'get_class_methods':
case 'get_class_vars':
diff --git a/src/Symfony/Component/Cache/Adapter/TagAwareAdapter.php b/src/Symfony/Component/Cache/Adapter/TagAwareAdapter.php
index 802c30fa92d9e..b8c4a08021b70 100644
--- a/src/Symfony/Component/Cache/Adapter/TagAwareAdapter.php
+++ b/src/Symfony/Component/Cache/Adapter/TagAwareAdapter.php
@@ -26,6 +26,7 @@ class TagAwareAdapter implements TagAwareAdapterInterface
private $deferred = array();
private $createCacheItem;
private $getTagsByKey;
+ private $invalidateTags;
private $tagsAdapter;
public function __construct(AdapterInterface $itemsAdapter, AdapterInterface $tagsAdapter = null)
@@ -33,17 +34,15 @@ public function __construct(AdapterInterface $itemsAdapter, AdapterInterface $ta
$this->itemsAdapter = $itemsAdapter;
$this->tagsAdapter = $tagsAdapter ?: $itemsAdapter;
$this->createCacheItem = \Closure::bind(
- function ($key, $value = null, CacheItem $protoItem = null) {
+ function ($key, $value, CacheItem $protoItem) {
$item = new CacheItem();
$item->key = $key;
$item->value = $value;
$item->isHit = false;
-
- if (null !== $protoItem) {
- $item->defaultLifetime = $protoItem->defaultLifetime;
- $item->innerItem = $protoItem->innerItem;
- $item->poolHash = $protoItem->poolHash;
- }
+ $item->defaultLifetime = $protoItem->defaultLifetime;
+ $item->expiry = $protoItem->expiry;
+ $item->innerItem = $protoItem->innerItem;
+ $item->poolHash = $protoItem->poolHash;
return $item;
},
@@ -62,6 +61,20 @@ function ($deferred) {
null,
CacheItem::class
);
+ $this->invalidateTags = \Closure::bind(
+ function (AdapterInterface $tagsAdapter, array $tags) {
+ foreach ($tagsAdapter->getItems($tags) as $v) {
+ $v->set(1 + (int) $v->get());
+ $v->defaultLifetime = 0;
+ $v->expiry = null;
+ $tagsAdapter->saveDeferred($v);
+ }
+
+ return $tagsAdapter->commit();
+ },
+ null,
+ CacheItem::class
+ );
}
/**
@@ -74,13 +87,9 @@ public function invalidateTags(array $tags)
$tags[$k] = $tag.static::TAGS_PREFIX;
}
}
+ $f = $this->invalidateTags;
- foreach ($this->tagsAdapter->getItems($tags) as $v) {
- $v->set(1 + (int) $v->get());
- $this->tagsAdapter->saveDeferred($v);
- }
-
- return $this->tagsAdapter->commit();
+ return $f($this->tagsAdapter, $tags);
}
/**
@@ -211,7 +220,8 @@ public function commit()
$ok = true;
if ($this->deferred) {
- foreach ($this->deferred as $key => $item) {
+ $items = $this->deferred;
+ foreach ($items as $key => $item) {
if (!$this->itemsAdapter->saveDeferred($item)) {
unset($this->deferred[$key]);
$ok = false;
@@ -219,14 +229,14 @@ public function commit()
}
$f = $this->getTagsByKey;
- $tagsByKey = $f($this->deferred);
+ $tagsByKey = $f($items);
$deletedTags = $this->deferred = array();
$tagVersions = $this->getTagVersions($tagsByKey);
$f = $this->createCacheItem;
foreach ($tagsByKey as $key => $tags) {
if ($tags) {
- $this->itemsAdapter->saveDeferred($f(static::TAGS_PREFIX.$key, array_intersect_key($tagVersions, $tags)));
+ $this->itemsAdapter->saveDeferred($f(static::TAGS_PREFIX.$key, array_intersect_key($tagVersions, $tags), $items[$key]));
} else {
$deletedTags[] = static::TAGS_PREFIX.$key;
}
diff --git a/src/Symfony/Component/Cache/CacheItem.php b/src/Symfony/Component/Cache/CacheItem.php
index f3d8b83812672..941d0bc6cd5e9 100644
--- a/src/Symfony/Component/Cache/CacheItem.php
+++ b/src/Symfony/Component/Cache/CacheItem.php
@@ -104,7 +104,7 @@ public function expiresAfter($time)
*
* @return static
*
- * @throws InvalidArgumentException When $tag is not valid.
+ * @throws InvalidArgumentException When $tag is not valid
*/
public function tag($tags)
{
@@ -121,7 +121,7 @@ public function tag($tags)
if (!isset($tag[0])) {
throw new InvalidArgumentException('Cache tag length must be greater than zero');
}
- if (isset($tag[strcspn($tag, '{}()/\@:')])) {
+ if (false !== strpbrk($tag, '{}()/\@:')) {
throw new InvalidArgumentException(sprintf('Cache tag "%s" contains reserved characters {}()/\@:', $tag));
}
$this->tags[$tag] = $tag;
@@ -135,7 +135,7 @@ public function tag($tags)
*
* @param string $key The key to validate
*
- * @throws InvalidArgumentException When $key is not valid.
+ * @throws InvalidArgumentException When $key is not valid
*/
public static function validateKey($key)
{
@@ -145,7 +145,7 @@ public static function validateKey($key)
if (!isset($key[0])) {
throw new InvalidArgumentException('Cache key length must be greater than zero');
}
- if (isset($key[strcspn($key, '{}()/\@:')])) {
+ if (false !== strpbrk($key, '{}()/\@:')) {
throw new InvalidArgumentException(sprintf('Cache key "%s" contains reserved characters {}()/\@:', $key));
}
}
diff --git a/src/Symfony/Component/Cache/Tests/Adapter/TagAwareAdapterTest.php b/src/Symfony/Component/Cache/Tests/Adapter/TagAwareAdapterTest.php
index 20b1fd7a07fe2..24586c0ca9aae 100644
--- a/src/Symfony/Component/Cache/Tests/Adapter/TagAwareAdapterTest.php
+++ b/src/Symfony/Component/Cache/Tests/Adapter/TagAwareAdapterTest.php
@@ -97,4 +97,21 @@ public function testTagsAreCleanedOnDelete()
$this->assertTrue($pool->getItem('k')->isHit());
}
+
+ public function testTagItemExpiry()
+ {
+ $pool = $this->createCachePool(10);
+
+ $item = $pool->getItem('foo');
+ $item->tag(array('baz'));
+ $item->expiresAfter(100);
+
+ $pool->save($item);
+ $pool->invalidateTags(array('baz'));
+ $this->assertFalse($pool->getItem('foo')->isHit());
+
+ sleep(20);
+
+ $this->assertFalse($pool->getItem('foo')->isHit());
+ }
}
diff --git a/src/Symfony/Component/ClassLoader/Tests/Fixtures/Namespaced/WithStrictTypes.php b/src/Symfony/Component/ClassLoader/Tests/Fixtures/Namespaced/WithStrictTypes.php
index 3c7870592b3cb..846611e38bbc4 100644
--- a/src/Symfony/Component/ClassLoader/Tests/Fixtures/Namespaced/WithStrictTypes.php
+++ b/src/Symfony/Component/ClassLoader/Tests/Fixtures/Namespaced/WithStrictTypes.php
@@ -4,7 +4,7 @@
* foo
*/
-declare (strict_types = 1);
+declare(strict_types=1);
namespace Namespaced;
diff --git a/src/Symfony/Component/Config/ResourceCheckerConfigCache.php b/src/Symfony/Component/Config/ResourceCheckerConfigCache.php
index ba7d600c7737b..0e3a411b07552 100644
--- a/src/Symfony/Component/Config/ResourceCheckerConfigCache.php
+++ b/src/Symfony/Component/Config/ResourceCheckerConfigCache.php
@@ -72,11 +72,6 @@ public function isFresh()
return true; // shortcut - if we don't have any checkers we don't need to bother with the meta file at all
}
- $metadata = $this->getMetaFile();
- if (!is_file($metadata)) {
- return true;
- }
-
$metadata = $this->getMetaFile();
if (!is_file($metadata)) {
return false;
diff --git a/src/Symfony/Component/Config/Tests/ResourceCheckerConfigCacheTest.php b/src/Symfony/Component/Config/Tests/ResourceCheckerConfigCacheTest.php
index d66c2e89d95b8..6c12c28a5b363 100644
--- a/src/Symfony/Component/Config/Tests/ResourceCheckerConfigCacheTest.php
+++ b/src/Symfony/Component/Config/Tests/ResourceCheckerConfigCacheTest.php
@@ -128,4 +128,16 @@ public function testCacheKeepsContent()
$this->assertSame('FOOBAR', file_get_contents($cache->getPath()));
}
+
+ public function testCacheIsNotFreshIfNotExistsMetaFile()
+ {
+ $checker = $this->getMockBuilder('\Symfony\Component\Config\ResourceCheckerInterface')->getMock();
+ $cache = new ResourceCheckerConfigCache($this->cacheFile, array($checker));
+ $cache->write('foo', array(new FileResource(__FILE__)));
+
+ $metaFile = "{$this->cacheFile}.meta";
+ unlink($metaFile);
+
+ $this->assertFalse($cache->isFresh());
+ }
}
diff --git a/src/Symfony/Component/Console/Helper/Table.php b/src/Symfony/Component/Console/Helper/Table.php
index 37ba3f53238ee..6f784ae78df64 100644
--- a/src/Symfony/Component/Console/Helper/Table.php
+++ b/src/Symfony/Component/Console/Helper/Table.php
@@ -599,7 +599,7 @@ private function calculateColumnsWidth($rows)
foreach ($row as $i => $cell) {
if ($cell instanceof TableCell) {
- $textLength = strlen($cell);
+ $textLength = Helper::strlenWithoutDecoration($this->output->getFormatter(), $cell);
if ($textLength > 0) {
$contentColumns = str_split($cell, ceil($textLength / $cell->getColspan()));
foreach ($contentColumns as $position => $content) {
diff --git a/src/Symfony/Component/Console/Helper/TableCell.php b/src/Symfony/Component/Console/Helper/TableCell.php
index 69442d4249c66..a3064fc0981f6 100644
--- a/src/Symfony/Component/Console/Helper/TableCell.php
+++ b/src/Symfony/Component/Console/Helper/TableCell.php
@@ -37,6 +37,10 @@ class TableCell
*/
public function __construct($value = '', array $options = array())
{
+ if (is_numeric($value) && !is_string($value)) {
+ $value = (string) $value;
+ }
+
$this->value = $value;
// check option names
diff --git a/src/Symfony/Component/Console/Tester/CommandTester.php b/src/Symfony/Component/Console/Tester/CommandTester.php
index 2c547a8f667ea..080ace5c95911 100644
--- a/src/Symfony/Component/Console/Tester/CommandTester.php
+++ b/src/Symfony/Component/Console/Tester/CommandTester.php
@@ -155,7 +155,7 @@ private static function createStream(array $inputs)
{
$stream = fopen('php://memory', 'r+', false);
- fputs($stream, implode(PHP_EOL, $inputs));
+ fwrite($stream, implode(PHP_EOL, $inputs));
rewind($stream);
return $stream;
diff --git a/src/Symfony/Component/Console/Tests/Fixtures/Style/SymfonyStyle/command/interactive_command_1.php b/src/Symfony/Component/Console/Tests/Fixtures/Style/SymfonyStyle/command/interactive_command_1.php
index c370c00106b25..3c9c744050185 100644
--- a/src/Symfony/Component/Console/Tests/Fixtures/Style/SymfonyStyle/command/interactive_command_1.php
+++ b/src/Symfony/Component/Console/Tests/Fixtures/Style/SymfonyStyle/command/interactive_command_1.php
@@ -9,7 +9,7 @@
$output = new SymfonyStyle($input, $output);
$stream = fopen('php://memory', 'r+', false);
- fputs($stream, "Foo\nBar\nBaz");
+ fwrite($stream, "Foo\nBar\nBaz");
rewind($stream);
$input->setStream($stream);
diff --git a/src/Symfony/Component/Console/Tests/Helper/ProcessHelperTest.php b/src/Symfony/Component/Console/Tests/Helper/ProcessHelperTest.php
index 1dcddf8badd49..b0d7f9c2f6f4c 100644
--- a/src/Symfony/Component/Console/Tests/Helper/ProcessHelperTest.php
+++ b/src/Symfony/Component/Console/Tests/Helper/ProcessHelperTest.php
@@ -16,6 +16,7 @@
use Symfony\Component\Console\Output\StreamOutput;
use Symfony\Component\Console\Helper\ProcessHelper;
use Symfony\Component\Process\Process;
+use Symfony\Component\Process\ProcessBuilder;
class ProcessHelperTest extends \PHPUnit_Framework_TestCase
{
@@ -83,9 +84,9 @@ public function provideCommandsAndOutput()
EOT;
$errorMessage = 'An error occurred';
- if ('\\' === DIRECTORY_SEPARATOR) {
- $successOutputProcessDebug = str_replace("'", '"', $successOutputProcessDebug);
- }
+ $args = new ProcessBuilder(array('php', '-r', 'echo 42;'));
+ $args = $args->getProcess()->getCommandLine();
+ $successOutputProcessDebug = str_replace("'php' '-r' 'echo 42;'", $args, $successOutputProcessDebug);
return array(
array('', 'php -r "echo 42;"', StreamOutput::VERBOSITY_VERBOSE, null),
diff --git a/src/Symfony/Component/Console/Tests/Helper/TableTest.php b/src/Symfony/Component/Console/Tests/Helper/TableTest.php
index 1ea7b11f646f6..f70d84b591449 100644
--- a/src/Symfony/Component/Console/Tests/Helper/TableTest.php
+++ b/src/Symfony/Component/Console/Tests/Helper/TableTest.php
@@ -35,9 +35,9 @@ protected function tearDown()
/**
* @dataProvider testRenderProvider
*/
- public function testRender($headers, $rows, $style, $expected)
+ public function testRender($headers, $rows, $style, $expected, $decorated = false)
{
- $table = new Table($output = $this->getOutputStream());
+ $table = new Table($output = $this->getOutputStream($decorated));
$table
->setHeaders($headers)
->setRows($rows)
@@ -51,9 +51,9 @@ public function testRender($headers, $rows, $style, $expected)
/**
* @dataProvider testRenderProvider
*/
- public function testRenderAddRows($headers, $rows, $style, $expected)
+ public function testRenderAddRows($headers, $rows, $style, $expected, $decorated = false)
{
- $table = new Table($output = $this->getOutputStream());
+ $table = new Table($output = $this->getOutputStream($decorated));
$table
->setHeaders($headers)
->addRows($rows)
@@ -67,9 +67,9 @@ public function testRenderAddRows($headers, $rows, $style, $expected)
/**
* @dataProvider testRenderProvider
*/
- public function testRenderAddRowsOneByOne($headers, $rows, $style, $expected)
+ public function testRenderAddRowsOneByOne($headers, $rows, $style, $expected, $decorated = false)
{
- $table = new Table($output = $this->getOutputStream());
+ $table = new Table($output = $this->getOutputStream($decorated));
$table
->setHeaders($headers)
->setStyle($style)
@@ -485,6 +485,35 @@ public function testRenderProvider()
TABLE
),
+ 'Coslpan and table cells with comment style' => array(
+ array(
+ new TableCell('Long Title', array('colspan' => 3)),
+ ),
+ array(
+ array(
+ new TableCell('9971-5-0210-0', array('colspan' => 3)),
+ ),
+ new TableSeparator(),
+ array(
+ 'Dante Alighieri',
+ 'J. R. R. Tolkien',
+ 'J. R. R',
+ ),
+ ),
+ 'default',
+ <<
assertEquals($expected, $this->getOutputContent($output));
+ }
+
+ public function testTableCellWithNumericIntValue()
+ {
+ $table = new Table($output = $this->getOutputStream());
+
+ $table->setRows(array(array(new TableCell(12345))));
+ $table->render();
+
+ $expected =
+<<<'TABLE'
++-------+
+| 12345 |
++-------+
+
+TABLE;
+
+ $this->assertEquals($expected, $this->getOutputContent($output));
+ }
+
+ public function testTableCellWithNumericFloatValue()
+ {
+ $table = new Table($output = $this->getOutputStream());
+
+ $table->setRows(array(array(new TableCell(12345.01))));
+ $table->render();
+
+ $expected =
+<<<'TABLE'
++----------+
+| 12345.01 |
++----------+
+
TABLE;
$this->assertEquals($expected, $this->getOutputContent($output));
@@ -713,9 +778,9 @@ public function testGetStyleDefinition()
Table::getStyleDefinition('absent');
}
- protected function getOutputStream()
+ protected function getOutputStream($decorated = false)
{
- return new StreamOutput($this->stream, StreamOutput::VERBOSITY_NORMAL, false);
+ return new StreamOutput($this->stream, StreamOutput::VERBOSITY_NORMAL, $decorated);
}
protected function getOutputContent(StreamOutput $output)
diff --git a/src/Symfony/Component/Console/Tests/Style/SymfonyStyleTest.php b/src/Symfony/Component/Console/Tests/Style/SymfonyStyleTest.php
index 3338f4b055cc4..92d9d92c7a089 100644
--- a/src/Symfony/Component/Console/Tests/Style/SymfonyStyleTest.php
+++ b/src/Symfony/Component/Console/Tests/Style/SymfonyStyleTest.php
@@ -31,6 +31,7 @@ protected function setUp()
protected function tearDown()
{
+ putenv('COLUMNS');
$this->command = null;
$this->tester = null;
}
diff --git a/src/Symfony/Component/Debug/ErrorHandler.php b/src/Symfony/Component/Debug/ErrorHandler.php
index f03a93d6826db..6805ef156aa02 100644
--- a/src/Symfony/Component/Debug/ErrorHandler.php
+++ b/src/Symfony/Component/Debug/ErrorHandler.php
@@ -225,7 +225,7 @@ public function setLoggers(array $loggers)
if ($flush) {
foreach ($this->bootstrappingLogger->cleanLogs() as $log) {
- $type = $log[2]['exception']->getSeverity();
+ $type = $log[2]['exception'] instanceof \ErrorException ? $log[2]['exception']->getSeverity() : E_ERROR;
if (!isset($flush[$type])) {
$this->bootstrappingLogger->log($log[0], $log[1], $log[2]);
} elseif ($this->loggers[$type][0]) {
@@ -352,12 +352,10 @@ private function reRegister($prev)
/**
* Handles errors by filtering then logging them according to the configured bit fields.
*
- * @param int $type One of the E_* constants
+ * @param int $type One of the E_* constants
* @param string $message
* @param string $file
* @param int $line
- * @param array $context
- * @param array $backtrace
*
* @return bool Returns false when no handling happens so that the PHP engine can handle the error itself
*
@@ -365,7 +363,7 @@ private function reRegister($prev)
*
* @internal
*/
- public function handleError($type, $message, $file, $line, array $context, array $backtrace = null)
+ public function handleError($type, $message, $file, $line)
{
// Level is the current error reporting level to manage silent error.
// Strong errors are not authorized to be silenced.
@@ -377,9 +375,20 @@ public function handleError($type, $message, $file, $line, array $context, array
if (!$type || (!$log && !$throw)) {
return $type && $log;
}
+ $scope = $this->scopedErrors & $type;
- if (isset($context['GLOBALS']) && ($this->scopedErrors & $type)) {
- unset($context['GLOBALS']);
+ if (4 < $numArgs = func_num_args()) {
+ $context = $scope ? (func_get_arg(4) ?: array()) : array();
+ $backtrace = 5 < $numArgs ? func_get_arg(5) : null; // defined on HHVM
+ } else {
+ $context = array();
+ $backtrace = null;
+ }
+
+ if (isset($context['GLOBALS']) && $scope) {
+ $e = $context; // Whatever the signature of the method,
+ unset($e['GLOBALS'], $context); // $context is always a reference in 5.3
+ $context = $e;
}
if (null !== $backtrace && $type & E_ERROR) {
@@ -399,7 +408,7 @@ public function handleError($type, $message, $file, $line, array $context, array
} elseif (!$throw && !($type & $level)) {
$errorAsException = new SilencedErrorContext($type, $file, $line);
} else {
- if ($this->scopedErrors & $type) {
+ if ($scope) {
$errorAsException = new ContextErrorException($logMessage, 0, $type, $file, $line, $context);
} else {
$errorAsException = new \ErrorException($logMessage, 0, $type, $file, $line);
diff --git a/src/Symfony/Component/Debug/Exception/FlattenException.php b/src/Symfony/Component/Debug/Exception/FlattenException.php
index 51baeb9be8b75..286a71ec143c6 100644
--- a/src/Symfony/Component/Debug/Exception/FlattenException.php
+++ b/src/Symfony/Component/Debug/Exception/FlattenException.php
@@ -237,7 +237,7 @@ private function flattenArgs($args, $level = 0, &$count = 0)
$result[$key] = array('null', null);
} elseif (is_bool($value)) {
$result[$key] = array('boolean', $value);
- } elseif (is_integer($value)) {
+ } elseif (is_int($value)) {
$result[$key] = array('integer', $value);
} elseif (is_float($value)) {
$result[$key] = array('float', $value);
diff --git a/src/Symfony/Component/Debug/FatalErrorHandler/ClassNotFoundFatalErrorHandler.php b/src/Symfony/Component/Debug/FatalErrorHandler/ClassNotFoundFatalErrorHandler.php
index c48d0d3fa5ae2..32ba9a09c5777 100644
--- a/src/Symfony/Component/Debug/FatalErrorHandler/ClassNotFoundFatalErrorHandler.php
+++ b/src/Symfony/Component/Debug/FatalErrorHandler/ClassNotFoundFatalErrorHandler.php
@@ -173,7 +173,7 @@ private function convertFileToClass($path, $file, $prefix)
);
if ($prefix) {
- $candidates = array_filter($candidates, function ($candidate) use ($prefix) {return 0 === strpos($candidate, $prefix);});
+ $candidates = array_filter($candidates, function ($candidate) use ($prefix) { return 0 === strpos($candidate, $prefix); });
}
// We cannot use the autoloader here as most of them use require; but if the class
diff --git a/src/Symfony/Component/Debug/Tests/ErrorHandlerTest.php b/src/Symfony/Component/Debug/Tests/ErrorHandlerTest.php
index bc568fa3fa23b..3a5da7f4e26cf 100644
--- a/src/Symfony/Component/Debug/Tests/ErrorHandlerTest.php
+++ b/src/Symfony/Component/Debug/Tests/ErrorHandlerTest.php
@@ -417,6 +417,25 @@ public function testBootstrappingLogger()
$handler->setLoggers(array(E_DEPRECATED => array($mockLogger, LogLevel::WARNING)));
}
+ public function testSettingLoggerWhenExceptionIsBuffered()
+ {
+ $bootLogger = new BufferingLogger();
+ $handler = new ErrorHandler($bootLogger);
+
+ $exception = new \Exception('Foo message');
+
+ $mockLogger = $this->getMockBuilder('Psr\Log\LoggerInterface')->getMock();
+ $mockLogger->expects($this->once())
+ ->method('log')
+ ->with(LogLevel::CRITICAL, 'Uncaught Exception: Foo message', array('exception' => $exception));
+
+ $handler->setExceptionHandler(function () use ($handler, $mockLogger) {
+ $handler->setDefaultLogger($mockLogger);
+ });
+
+ $handler->handleException($exception);
+ }
+
public function testHandleFatalError()
{
try {
diff --git a/src/Symfony/Component/DependencyInjection/Compiler/AutowirePass.php b/src/Symfony/Component/DependencyInjection/Compiler/AutowirePass.php
index d1b1fd292cf06..fcb986383c3de 100644
--- a/src/Symfony/Component/DependencyInjection/Compiler/AutowirePass.php
+++ b/src/Symfony/Component/DependencyInjection/Compiler/AutowirePass.php
@@ -114,8 +114,10 @@ private function completeDefinition($id, Definition $definition)
throw new RuntimeException(sprintf('Unable to autowire argument index %d ($%s) for the service "%s". If this is an object, give it a type-hint. Otherwise, specify this argument\'s value explicitly.', $index, $parameter->name, $id));
}
- // specifically pass the default value
- $arguments[$index] = $parameter->getDefaultValue();
+ if (!array_key_exists($index, $arguments)) {
+ // specifically pass the default value
+ $arguments[$index] = $parameter->getDefaultValue();
+ }
continue;
}
@@ -345,10 +347,11 @@ private static function getResourceMetadataForMethod(\ReflectionMethod $method)
$class = false;
}
+ $isVariadic = method_exists($parameter, 'isVariadic') && $parameter->isVariadic();
$methodArgumentsMetadata[] = array(
'class' => $class,
'isOptional' => $parameter->isOptional(),
- 'defaultValue' => $parameter->isOptional() ? $parameter->getDefaultValue() : null,
+ 'defaultValue' => ($parameter->isOptional() && !$isVariadic) ? $parameter->getDefaultValue() : null,
);
}
diff --git a/src/Symfony/Component/DependencyInjection/Compiler/CheckCircularReferencesPass.php b/src/Symfony/Component/DependencyInjection/Compiler/CheckCircularReferencesPass.php
index 156bcc0c3ab7b..f39a89af2be71 100644
--- a/src/Symfony/Component/DependencyInjection/Compiler/CheckCircularReferencesPass.php
+++ b/src/Symfony/Component/DependencyInjection/Compiler/CheckCircularReferencesPass.php
@@ -60,7 +60,6 @@ private function checkOutEdges(array $edges)
$id = $node->getId();
if (empty($this->checkedNodes[$id])) {
-
// don't check circular dependencies for lazy services
if (!$node->getValue() || !$node->getValue()->isLazy()) {
$searchKey = array_search($id, $this->currentPath);
diff --git a/src/Symfony/Component/DependencyInjection/Definition.php b/src/Symfony/Component/DependencyInjection/Definition.php
index 96928142264d8..d8e954329fa71 100644
--- a/src/Symfony/Component/DependencyInjection/Definition.php
+++ b/src/Symfony/Component/DependencyInjection/Definition.php
@@ -106,7 +106,7 @@ public function setDecoratedService($id, $renamedId = null, $priority = 0)
}
/**
- * Gets the service that decorates this service.
+ * Gets the service that this service is decorating.
*
* @return null|array An array composed of the decorated service id, the new id for it and the priority of decoration, null if no service is decorated
*/
@@ -198,6 +198,10 @@ public function addArgument($argument)
*/
public function replaceArgument($index, $argument)
{
+ if (0 === count($this->arguments)) {
+ throw new OutOfBoundsException('Cannot replace arguments if none have been configured yet.');
+ }
+
if ($index < 0 || $index > count($this->arguments) - 1) {
throw new OutOfBoundsException(sprintf('The index "%d" is not in the range [0, %d].', $index, count($this->arguments) - 1));
}
diff --git a/src/Symfony/Component/DependencyInjection/Loader/YamlFileLoader.php b/src/Symfony/Component/DependencyInjection/Loader/YamlFileLoader.php
index 06cc506e670c9..a8f00986f7b18 100644
--- a/src/Symfony/Component/DependencyInjection/Loader/YamlFileLoader.php
+++ b/src/Symfony/Component/DependencyInjection/Loader/YamlFileLoader.php
@@ -110,7 +110,7 @@ public function supports($resource, $type = null)
* @param array $content
* @param string $file
*/
- private function parseImports($content, $file)
+ private function parseImports(array $content, $file)
{
if (!isset($content['imports'])) {
return;
@@ -137,7 +137,7 @@ private function parseImports($content, $file)
* @param array $content
* @param string $file
*/
- private function parseDefinitions($content, $file)
+ private function parseDefinitions(array $content, $file)
{
if (!isset($content['services'])) {
return;
@@ -155,9 +155,9 @@ private function parseDefinitions($content, $file)
/**
* Parses a definition.
*
- * @param string $id
- * @param array $service
- * @param string $file
+ * @param string $id
+ * @param array|string $service
+ * @param string $file
*
* @throws InvalidArgumentException When tags are invalid
*/
@@ -486,7 +486,7 @@ private function resolveServices($value)
*
* @param array $content
*/
- private function loadFromExtensions($content)
+ private function loadFromExtensions(array $content)
{
foreach ($content as $namespace => $values) {
if (in_array($namespace, array('imports', 'parameters', 'services'))) {
diff --git a/src/Symfony/Component/DependencyInjection/Tests/Compiler/AutowirePassTest.php b/src/Symfony/Component/DependencyInjection/Tests/Compiler/AutowirePassTest.php
index 16c8130cd5cad..212b93d9724f3 100644
--- a/src/Symfony/Component/DependencyInjection/Tests/Compiler/AutowirePassTest.php
+++ b/src/Symfony/Component/DependencyInjection/Tests/Compiler/AutowirePassTest.php
@@ -14,6 +14,7 @@
use Symfony\Component\DependencyInjection\Compiler\AutowirePass;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\Reference;
+use Symfony\Component\DependencyInjection\Tests\Fixtures\includes\FooVariadic;
/**
* @author Kévin Dunglas
@@ -35,6 +36,23 @@ public function testProcess()
$this->assertEquals('foo', (string) $container->getDefinition('bar')->getArgument(0));
}
+ /**
+ * @requires PHP 5.6
+ */
+ public function testProcessVariadic()
+ {
+ $container = new ContainerBuilder();
+ $container->register('foo', Foo::class);
+ $definition = $container->register('fooVariadic', FooVariadic::class);
+ $definition->setAutowired(true);
+
+ $pass = new AutowirePass();
+ $pass->process($container);
+
+ $this->assertCount(1, $container->getDefinition('fooVariadic')->getArguments());
+ $this->assertEquals('foo', (string) $container->getDefinition('fooVariadic')->getArgument(0));
+ }
+
public function testProcessAutowireParent()
{
$container = new ContainerBuilder();
@@ -476,6 +494,22 @@ public function testIgnoreServiceWithClassNotExisting()
$this->assertTrue($container->hasDefinition('bar'));
}
+
+ public function testEmptyStringIsKept()
+ {
+ $container = new ContainerBuilder();
+
+ $container->register('a', __NAMESPACE__.'\A');
+ $container->register('lille', __NAMESPACE__.'\Lille');
+ $container->register('foo', __NAMESPACE__.'\MultipleArgumentsOptionalScalar')
+ ->setAutowired(true)
+ ->setArguments(array('', ''));
+
+ $pass = new AutowirePass();
+ $pass->process($container);
+
+ $this->assertEquals(array(new Reference('a'), '', new Reference('lille')), $container->getDefinition('foo')->getArguments());
+ }
}
class Foo
diff --git a/src/Symfony/Component/DependencyInjection/Tests/DefinitionTest.php b/src/Symfony/Component/DependencyInjection/Tests/DefinitionTest.php
index 6a85f8044bde6..9b89b339412fb 100644
--- a/src/Symfony/Component/DependencyInjection/Tests/DefinitionTest.php
+++ b/src/Symfony/Component/DependencyInjection/Tests/DefinitionTest.php
@@ -257,6 +257,7 @@ public function testGetArgumentShouldCheckBounds()
/**
* @expectedException \OutOfBoundsException
+ * @expectedExceptionMessage The index "1" is not in the range [0, 0].
*/
public function testReplaceArgumentShouldCheckBounds()
{
@@ -266,6 +267,16 @@ public function testReplaceArgumentShouldCheckBounds()
$def->replaceArgument(1, 'bar');
}
+ /**
+ * @expectedException \OutOfBoundsException
+ * @expectedExceptionMessage Cannot replace arguments if none have been configured yet.
+ */
+ public function testReplaceArgumentWithoutExistingArgumentsShouldCheckBounds()
+ {
+ $def = new Definition('stdClass');
+ $def->replaceArgument(0, 'bar');
+ }
+
public function testSetGetProperties()
{
$def = new Definition('stdClass');
diff --git a/src/Symfony/Component/DependencyInjection/Tests/Fixtures/includes/FooVariadic.php b/src/Symfony/Component/DependencyInjection/Tests/Fixtures/includes/FooVariadic.php
new file mode 100644
index 0000000000000..12861c5611735
--- /dev/null
+++ b/src/Symfony/Component/DependencyInjection/Tests/Fixtures/includes/FooVariadic.php
@@ -0,0 +1,16 @@
+validateOnParse = true;
- set_error_handler(function () {throw new \Exception();});
+ set_error_handler(function () { throw new \Exception(); });
try {
// Convert charset to HTML-entities to work around bugs in DOMDocument::loadHTML()
diff --git a/src/Symfony/Component/DomCrawler/Tests/CrawlerTest.php b/src/Symfony/Component/DomCrawler/Tests/CrawlerTest.php
index 90c060665bb5f..0d655a32d8e26 100755
--- a/src/Symfony/Component/DomCrawler/Tests/CrawlerTest.php
+++ b/src/Symfony/Component/DomCrawler/Tests/CrawlerTest.php
@@ -30,14 +30,14 @@ public function testConstructor()
public function testGetUri()
{
$uri = 'http://symfony.com';
- $crawler = new Crawler(null, $uri);
+ $crawler = new Crawler(null, $uri);
$this->assertEquals($uri, $crawler->getUri());
}
public function testGetBaseHref()
{
$baseHref = 'http://symfony.com';
- $crawler = new Crawler(null, null, $baseHref);
+ $crawler = new Crawler(null, null, $baseHref);
$this->assertEquals($baseHref, $crawler->getBaseHref());
}
diff --git a/src/Symfony/Component/Form/Extension/Core/Type/DateType.php b/src/Symfony/Component/Form/Extension/Core/Type/DateType.php
index ca26ae572e363..af90793282948 100644
--- a/src/Symfony/Component/Form/Extension/Core/Type/DateType.php
+++ b/src/Symfony/Component/Form/Extension/Core/Type/DateType.php
@@ -56,11 +56,11 @@ public function buildForm(FormBuilderInterface $builder, array $options)
throw new InvalidOptionsException('The "format" option must be one of the IntlDateFormatter constants (FULL, LONG, MEDIUM, SHORT) or a string representing a custom format.');
}
- if (null !== $pattern && (false === strpos($pattern, 'y') || false === strpos($pattern, 'M') || false === strpos($pattern, 'd'))) {
- throw new InvalidOptionsException(sprintf('The "format" option should contain the letters "y", "M" and "d". Its current value is "%s".', $pattern));
- }
-
if ('single_text' === $options['widget']) {
+ if (null !== $pattern && false === strpos($pattern, 'y') && false === strpos($pattern, 'M') && false === strpos($pattern, 'd')) {
+ throw new InvalidOptionsException(sprintf('The "format" option should contain the letters "y", "M" or "d". Its current value is "%s".', $pattern));
+ }
+
$builder->addViewTransformer(new DateTimeToLocalizedStringTransformer(
$options['model_timezone'],
$options['view_timezone'],
@@ -70,6 +70,10 @@ public function buildForm(FormBuilderInterface $builder, array $options)
$pattern
));
} else {
+ if (null !== $pattern && (false === strpos($pattern, 'y') || false === strpos($pattern, 'M') || false === strpos($pattern, 'd'))) {
+ throw new InvalidOptionsException(sprintf('The "format" option should contain the letters "y", "M" and "d". Its current value is "%s".', $pattern));
+ }
+
$yearOptions = $monthOptions = $dayOptions = array(
'error_bubbling' => true,
);
@@ -212,7 +216,7 @@ public function configureOptions(OptionsResolver $resolver)
array('year' => $default, 'month' => $default, 'day' => $default),
$choiceTranslationDomain
);
- };
+ }
return array(
'year' => $choiceTranslationDomain,
diff --git a/src/Symfony/Component/Form/Extension/Core/Type/TimeType.php b/src/Symfony/Component/Form/Extension/Core/Type/TimeType.php
index 4ba23a8c8b2e5..d1c04f73d9278 100644
--- a/src/Symfony/Component/Form/Extension/Core/Type/TimeType.php
+++ b/src/Symfony/Component/Form/Extension/Core/Type/TimeType.php
@@ -213,7 +213,7 @@ public function configureOptions(OptionsResolver $resolver)
array('hour' => $default, 'minute' => $default, 'second' => $default),
$choiceTranslationDomain
);
- };
+ }
return array(
'hour' => $choiceTranslationDomain,
diff --git a/src/Symfony/Component/Form/Tests/Extension/Core/Type/DateTypeTest.php b/src/Symfony/Component/Form/Tests/Extension/Core/Type/DateTypeTest.php
index 9b33db2a654ac..628a71f14c895 100644
--- a/src/Symfony/Component/Form/Tests/Extension/Core/Type/DateTypeTest.php
+++ b/src/Symfony/Component/Form/Tests/Extension/Core/Type/DateTypeTest.php
@@ -67,12 +67,28 @@ public function testSubmitFromSingleTextDateTimeWithDefaultFormat()
$this->assertEquals('2010-06-02', $form->getViewData());
}
+ public function testSubmitFromSingleTextDateTimeWithCustomFormat()
+ {
+ $form = $this->factory->create('Symfony\Component\Form\Extension\Core\Type\DateType', null, array(
+ 'model_timezone' => 'UTC',
+ 'view_timezone' => 'UTC',
+ 'widget' => 'single_text',
+ 'input' => 'datetime',
+ 'format' => 'yyyy',
+ ));
+
+ $form->submit('2010');
+
+ $this->assertDateTimeEquals(new \DateTime('2010-01-01 UTC'), $form->getData());
+ $this->assertEquals('2010', $form->getViewData());
+ }
+
public function testSubmitFromSingleTextDateTime()
{
- // we test against "de_AT", so we need the full implementation
+ // we test against "de_DE", so we need the full implementation
IntlTestHelper::requireFullIntl($this, false);
- \Locale::setDefault('de_AT');
+ \Locale::setDefault('de_DE');
$form = $this->factory->create('Symfony\Component\Form\Extension\Core\Type\DateType', null, array(
'format' => \IntlDateFormatter::MEDIUM,
@@ -90,10 +106,10 @@ public function testSubmitFromSingleTextDateTime()
public function testSubmitFromSingleTextString()
{
- // we test against "de_AT", so we need the full implementation
+ // we test against "de_DE", so we need the full implementation
IntlTestHelper::requireFullIntl($this, false);
- \Locale::setDefault('de_AT');
+ \Locale::setDefault('de_DE');
$form = $this->factory->create('Symfony\Component\Form\Extension\Core\Type\DateType', null, array(
'format' => \IntlDateFormatter::MEDIUM,
@@ -111,10 +127,10 @@ public function testSubmitFromSingleTextString()
public function testSubmitFromSingleTextTimestamp()
{
- // we test against "de_AT", so we need the full implementation
+ // we test against "de_DE", so we need the full implementation
IntlTestHelper::requireFullIntl($this, false);
- \Locale::setDefault('de_AT');
+ \Locale::setDefault('de_DE');
$form = $this->factory->create('Symfony\Component\Form\Extension\Core\Type\DateType', null, array(
'format' => \IntlDateFormatter::MEDIUM,
@@ -134,10 +150,10 @@ public function testSubmitFromSingleTextTimestamp()
public function testSubmitFromSingleTextRaw()
{
- // we test against "de_AT", so we need the full implementation
+ // we test against "de_DE", so we need the full implementation
IntlTestHelper::requireFullIntl($this, false);
- \Locale::setDefault('de_AT');
+ \Locale::setDefault('de_DE');
$form = $this->factory->create('Symfony\Component\Form\Extension\Core\Type\DateType', null, array(
'format' => \IntlDateFormatter::MEDIUM,
@@ -337,6 +353,7 @@ public function testThrowExceptionIfFormatIsNoPattern()
/**
* @expectedException \Symfony\Component\OptionsResolver\Exception\InvalidOptionsException
+ * @expectedExceptionMessage The "format" option should contain the letters "y", "M" and "d". Its current value is "yy".
*/
public function testThrowExceptionIfFormatDoesNotContainYearMonthAndDay()
{
@@ -346,6 +363,18 @@ public function testThrowExceptionIfFormatDoesNotContainYearMonthAndDay()
));
}
+ /**
+ * @expectedException \Symfony\Component\OptionsResolver\Exception\InvalidOptionsException
+ * @expectedExceptionMessage The "format" option should contain the letters "y", "M" or "d". Its current value is "wrong".
+ */
+ public function testThrowExceptionIfFormatMissesYearMonthAndDayWithSingleTextWidget()
+ {
+ $this->factory->create('Symfony\Component\Form\Extension\Core\Type\DateType', null, array(
+ 'widget' => 'single_text',
+ 'format' => 'wrong',
+ ));
+ }
+
/**
* @expectedException \Symfony\Component\OptionsResolver\Exception\InvalidOptionsException
*/
@@ -398,10 +427,10 @@ public function testThrowExceptionIfDaysIsInvalid()
public function testSetDataWithNegativeTimezoneOffsetStringInput()
{
- // we test against "de_AT", so we need the full implementation
+ // we test against "de_DE", so we need the full implementation
IntlTestHelper::requireFullIntl($this, false);
- \Locale::setDefault('de_AT');
+ \Locale::setDefault('de_DE');
$form = $this->factory->create('Symfony\Component\Form\Extension\Core\Type\DateType', null, array(
'format' => \IntlDateFormatter::MEDIUM,
@@ -420,10 +449,10 @@ public function testSetDataWithNegativeTimezoneOffsetStringInput()
public function testSetDataWithNegativeTimezoneOffsetDateTimeInput()
{
- // we test against "de_AT", so we need the full implementation
+ // we test against "de_DE", so we need the full implementation
IntlTestHelper::requireFullIntl($this, false);
- \Locale::setDefault('de_AT');
+ \Locale::setDefault('de_DE');
$form = $this->factory->create('Symfony\Component\Form\Extension\Core\Type\DateType', null, array(
'format' => \IntlDateFormatter::MEDIUM,
diff --git a/src/Symfony/Component/HttpFoundation/Request.php b/src/Symfony/Component/HttpFoundation/Request.php
index 54cc5f4de38eb..dc23d2ca1a1d7 100644
--- a/src/Symfony/Component/HttpFoundation/Request.php
+++ b/src/Symfony/Component/HttpFoundation/Request.php
@@ -596,6 +596,7 @@ public static function getTrustedHosts()
* * Request::HEADER_CLIENT_HOST: defaults to X-Forwarded-Host (see getHost())
* * Request::HEADER_CLIENT_PORT: defaults to X-Forwarded-Port (see getPort())
* * Request::HEADER_CLIENT_PROTO: defaults to X-Forwarded-Proto (see getScheme() and isSecure())
+ * * Request::HEADER_FORWARDED: defaults to Forwarded (see RFC 7239)
*
* Setting an empty value allows to disable the trusted header for the given key.
*
diff --git a/src/Symfony/Component/HttpKernel/Bundle/Bundle.php b/src/Symfony/Component/HttpKernel/Bundle/Bundle.php
index 68e1157e4510b..8505bbbddd3f0 100644
--- a/src/Symfony/Component/HttpKernel/Bundle/Bundle.php
+++ b/src/Symfony/Component/HttpKernel/Bundle/Bundle.php
@@ -223,6 +223,8 @@ private function parseClassName()
{
$pos = strrpos(static::class, '\\');
$this->namespace = false === $pos ? '' : substr(static::class, 0, $pos);
- $this->name = false === $pos ? static::class : substr(static::class, $pos + 1);
+ if (null === $this->name) {
+ $this->name = false === $pos ? static::class : substr(static::class, $pos + 1);
+ }
}
}
diff --git a/src/Symfony/Component/HttpKernel/DataCollector/DumpDataCollector.php b/src/Symfony/Component/HttpKernel/DataCollector/DumpDataCollector.php
index e1ab2cc473b98..b638ba79059bd 100644
--- a/src/Symfony/Component/HttpKernel/DataCollector/DumpDataCollector.php
+++ b/src/Symfony/Component/HttpKernel/DataCollector/DumpDataCollector.php
@@ -290,7 +290,7 @@ private function htmlEncode($s)
{
$html = '';
- $dumper = new HtmlDumper(function ($line) use (&$html) {$html .= $line;}, $this->charset);
+ $dumper = new HtmlDumper(function ($line) use (&$html) { $html .= $line; }, $this->charset);
$dumper->setDumpHeader('');
$dumper->setDumpBoundaries('', '');
diff --git a/src/Symfony/Component/HttpKernel/EventListener/AddRequestFormatsListener.php b/src/Symfony/Component/HttpKernel/EventListener/AddRequestFormatsListener.php
index 14a5d435115d7..280844c18313e 100644
--- a/src/Symfony/Component/HttpKernel/EventListener/AddRequestFormatsListener.php
+++ b/src/Symfony/Component/HttpKernel/EventListener/AddRequestFormatsListener.php
@@ -52,6 +52,6 @@ public function onKernelRequest(GetResponseEvent $event)
*/
public static function getSubscribedEvents()
{
- return array(KernelEvents::REQUEST => 'onKernelRequest');
+ return array(KernelEvents::REQUEST => array('onKernelRequest', 1));
}
}
diff --git a/src/Symfony/Component/HttpKernel/EventListener/DebugHandlersListener.php b/src/Symfony/Component/HttpKernel/EventListener/DebugHandlersListener.php
index ef2b17ff63ec1..29e1725adc672 100644
--- a/src/Symfony/Component/HttpKernel/EventListener/DebugHandlersListener.php
+++ b/src/Symfony/Component/HttpKernel/EventListener/DebugHandlersListener.php
@@ -137,7 +137,7 @@ public static function getSubscribedEvents()
{
$events = array(KernelEvents::REQUEST => array('configure', 2048));
- if ('cli' === php_sapi_name() && defined('Symfony\Component\Console\ConsoleEvents::COMMAND')) {
+ if ('cli' === PHP_SAPI && defined('Symfony\Component\Console\ConsoleEvents::COMMAND')) {
$events[ConsoleEvents::COMMAND] = array('configure', 2048);
}
diff --git a/src/Symfony/Component/HttpKernel/Kernel.php b/src/Symfony/Component/HttpKernel/Kernel.php
index 0f8d13868d28e..6bc132aa2d3c7 100644
--- a/src/Symfony/Component/HttpKernel/Kernel.php
+++ b/src/Symfony/Component/HttpKernel/Kernel.php
@@ -58,11 +58,11 @@ abstract class Kernel implements KernelInterface, TerminableInterface
protected $startTime;
protected $loadClassCache;
- const VERSION = '3.2.2';
- const VERSION_ID = 30202;
+ const VERSION = '3.2.3';
+ const VERSION_ID = 30203;
const MAJOR_VERSION = 3;
const MINOR_VERSION = 2;
- const RELEASE_VERSION = 2;
+ const RELEASE_VERSION = 3;
const EXTRA_VERSION = '';
const END_OF_MAINTENANCE = '07/2017';
diff --git a/src/Symfony/Component/HttpKernel/Tests/Bundle/BundleTest.php b/src/Symfony/Component/HttpKernel/Tests/Bundle/BundleTest.php
index 0b11f8253c8b6..a8b91453c672e 100644
--- a/src/Symfony/Component/HttpKernel/Tests/Bundle/BundleTest.php
+++ b/src/Symfony/Component/HttpKernel/Tests/Bundle/BundleTest.php
@@ -12,6 +12,7 @@
namespace Symfony\Component\HttpKernel\Tests\Bundle;
use Symfony\Component\DependencyInjection\ContainerBuilder;
+use Symfony\Component\HttpKernel\Bundle\Bundle;
use Symfony\Component\HttpKernel\Tests\Fixtures\ExtensionNotValidBundle\ExtensionNotValidBundle;
use Symfony\Component\HttpKernel\Tests\Fixtures\ExtensionPresentBundle\ExtensionPresentBundle;
use Symfony\Component\HttpKernel\Tests\Fixtures\ExtensionAbsentBundle\ExtensionAbsentBundle;
@@ -66,4 +67,33 @@ public function testHttpKernelRegisterCommandsIgnoresCommandsThatAreRegisteredAs
$bundle->setContainer($container);
$bundle->registerCommands($application);
}
+
+ public function testBundleNameIsGuessedFromClass()
+ {
+ $bundle = new GuessedNameBundle();
+
+ $this->assertSame('Symfony\Component\HttpKernel\Tests\Bundle', $bundle->getNamespace());
+ $this->assertSame('GuessedNameBundle', $bundle->getName());
+ }
+
+ public function testBundleNameCanBeExplicitlyProvided()
+ {
+ $bundle = new NamedBundle();
+
+ $this->assertSame('ExplicitlyNamedBundle', $bundle->getName());
+ $this->assertSame('Symfony\Component\HttpKernel\Tests\Bundle', $bundle->getNamespace());
+ $this->assertSame('ExplicitlyNamedBundle', $bundle->getName());
+ }
+}
+
+class NamedBundle extends Bundle
+{
+ public function __construct()
+ {
+ $this->name = 'ExplicitlyNamedBundle';
+ }
+}
+
+class GuessedNameBundle extends Bundle
+{
}
diff --git a/src/Symfony/Component/HttpKernel/Tests/EventListener/AddRequestFormatsListenerTest.php b/src/Symfony/Component/HttpKernel/Tests/EventListener/AddRequestFormatsListenerTest.php
index 0f3577cbdb14b..c5b2c51e40ecb 100644
--- a/src/Symfony/Component/HttpKernel/Tests/EventListener/AddRequestFormatsListenerTest.php
+++ b/src/Symfony/Component/HttpKernel/Tests/EventListener/AddRequestFormatsListenerTest.php
@@ -45,7 +45,7 @@ public function testIsAnEventSubscriber()
public function testRegisteredEvent()
{
$this->assertEquals(
- array(KernelEvents::REQUEST => 'onKernelRequest'),
+ array(KernelEvents::REQUEST => array('onKernelRequest', 1)),
AddRequestFormatsListener::getSubscribedEvents()
);
}
diff --git a/src/Symfony/Component/Intl/Data/Generator/AbstractDataGenerator.php b/src/Symfony/Component/Intl/Data/Generator/AbstractDataGenerator.php
index 84b7f74373992..6b7cf5a0caf1d 100644
--- a/src/Symfony/Component/Intl/Data/Generator/AbstractDataGenerator.php
+++ b/src/Symfony/Component/Intl/Data/Generator/AbstractDataGenerator.php
@@ -42,9 +42,6 @@ public function __construct(GenrbCompiler $compiler, $dirName)
$this->dirName = $dirName;
}
- /**
- * {@inheritdoc}
- */
public function generateData(GeneratorConfig $config)
{
$filesystem = new Filesystem();
diff --git a/src/Symfony/Component/Intl/Data/Generator/LocaleDataGenerator.php b/src/Symfony/Component/Intl/Data/Generator/LocaleDataGenerator.php
index 5f4f95102fd85..e89e5e8757b67 100644
--- a/src/Symfony/Component/Intl/Data/Generator/LocaleDataGenerator.php
+++ b/src/Symfony/Component/Intl/Data/Generator/LocaleDataGenerator.php
@@ -57,9 +57,6 @@ public function __construct($dirName, LanguageDataProvider $languageDataProvider
$this->regionDataProvider = $regionDataProvider;
}
- /**
- * {@inheritdoc}
- */
public function generateData(GeneratorConfig $config)
{
$filesystem = new Filesystem();
diff --git a/src/Symfony/Component/Intl/Util/IntlTestHelper.php b/src/Symfony/Component/Intl/Util/IntlTestHelper.php
index 71fb4acdd72fa..c1e37a72ec8a4 100644
--- a/src/Symfony/Component/Intl/Util/IntlTestHelper.php
+++ b/src/Symfony/Component/Intl/Util/IntlTestHelper.php
@@ -41,7 +41,7 @@ public static function requireIntl(\PHPUnit_Framework_TestCase $testCase, $minim
// * the intl extension is loaded with version Intl::getIcuStubVersion()
// * the intl extension is not loaded
- if (($minimumIcuVersion || defined('HHVM_VERSION_ID')) && IcuVersion::compare(Intl::getIcuVersion(), $minimumIcuVersion, '!=', 1)) {
+ if (($minimumIcuVersion || defined('HHVM_VERSION_ID')) && IcuVersion::compare(Intl::getIcuVersion(), $minimumIcuVersion, '<', 1)) {
$testCase->markTestSkipped('ICU version '.$minimumIcuVersion.' is required.');
}
diff --git a/src/Symfony/Component/Process/ProcessUtils.php b/src/Symfony/Component/Process/ProcessUtils.php
index 500202e5844cd..cbc95708ed4a6 100644
--- a/src/Symfony/Component/Process/ProcessUtils.php
+++ b/src/Symfony/Component/Process/ProcessUtils.php
@@ -71,7 +71,7 @@ public static function escapeArgument($argument)
return $escapedArgument;
}
- return escapeshellarg($argument);
+ return "'".str_replace("'", "'\\''", $argument)."'";
}
/**
diff --git a/src/Symfony/Component/Process/Tests/ProcessTest.php b/src/Symfony/Component/Process/Tests/ProcessTest.php
index 811c98f15e7d8..c19206117e9fc 100644
--- a/src/Symfony/Component/Process/Tests/ProcessTest.php
+++ b/src/Symfony/Component/Process/Tests/ProcessTest.php
@@ -1281,7 +1281,7 @@ public function testInputStreamOnEmpty()
{
$i = 0;
$input = new InputStream();
- $input->onEmpty(function () use (&$i) {++$i;});
+ $input->onEmpty(function () use (&$i) { ++$i; });
$process = $this->getProcess(self::$phpBin.' -r '.escapeshellarg('echo 123; echo fread(STDIN, 1); echo 456;'));
$process->setInput($input);
diff --git a/src/Symfony/Component/Process/Tests/ProcessUtilsTest.php b/src/Symfony/Component/Process/Tests/ProcessUtilsTest.php
index e6564cde5ba6d..0f554b6151801 100644
--- a/src/Symfony/Component/Process/Tests/ProcessUtilsTest.php
+++ b/src/Symfony/Component/Process/Tests/ProcessUtilsTest.php
@@ -43,6 +43,7 @@ public function dataArguments()
array("'<|>\" \"'\\''f'", '<|>" "\'f'),
array("''", ''),
array("'with\\trailingbs\\'", 'with\trailingbs\\'),
+ array("'withNonAsciiAccentLikeéÉèÈàÀöä'", 'withNonAsciiAccentLikeéÉèÈàÀöä'),
);
}
}
diff --git a/src/Symfony/Component/Process/Tests/SignalListener.php b/src/Symfony/Component/Process/Tests/SignalListener.php
index 03536577c40f2..9e30ce3bbbbc6 100644
--- a/src/Symfony/Component/Process/Tests/SignalListener.php
+++ b/src/Symfony/Component/Process/Tests/SignalListener.php
@@ -9,7 +9,7 @@
* file that was distributed with this source code.
*/
-pcntl_signal(SIGUSR1, function () {echo 'SIGUSR1'; exit;});
+pcntl_signal(SIGUSR1, function () { echo 'SIGUSR1'; exit; });
echo 'Caught ';
diff --git a/src/Symfony/Component/PropertyAccess/PropertyAccess.php b/src/Symfony/Component/PropertyAccess/PropertyAccess.php
index 66a7e3a43fdf5..3c8dc1c56cc18 100644
--- a/src/Symfony/Component/PropertyAccess/PropertyAccess.php
+++ b/src/Symfony/Component/PropertyAccess/PropertyAccess.php
@@ -31,7 +31,7 @@ public static function createPropertyAccessor()
/**
* Creates a property accessor builder.
*
- * @return PropertyAccessor
+ * @return PropertyAccessorBuilder
*/
public static function createPropertyAccessorBuilder()
{
diff --git a/src/Symfony/Component/PropertyAccess/PropertyAccessor.php b/src/Symfony/Component/PropertyAccess/PropertyAccessor.php
index 618007ef59980..6019544a19e8c 100644
--- a/src/Symfony/Component/PropertyAccess/PropertyAccessor.php
+++ b/src/Symfony/Component/PropertyAccess/PropertyAccessor.php
@@ -267,7 +267,7 @@ public static function handleError($type, $message, $file, $line, $context)
private static function throwInvalidArgumentException($message, $trace, $i)
{
if (isset($trace[$i]['file']) && __FILE__ === $trace[$i]['file']) {
- $pos = strpos($message, $delim = 'must be of the type ') ?: strpos($message, $delim = 'must be an instance of ');
+ $pos = strpos($message, $delim = 'must be of the type ') ?: (strpos($message, $delim = 'must be an instance of ') ?: strpos($message, $delim = 'must implement interface '));
$pos += strlen($delim);
$type = $trace[$i]['args'][0];
$type = is_object($type) ? get_class($type) : gettype($type);
diff --git a/src/Symfony/Component/PropertyAccess/Tests/Fixtures/TypeHinted.php b/src/Symfony/Component/PropertyAccess/Tests/Fixtures/TypeHinted.php
index ca4c5745ae06c..ce0f3d89aaa30 100644
--- a/src/Symfony/Component/PropertyAccess/Tests/Fixtures/TypeHinted.php
+++ b/src/Symfony/Component/PropertyAccess/Tests/Fixtures/TypeHinted.php
@@ -18,6 +18,11 @@ class TypeHinted
{
private $date;
+ /**
+ * @var \Countable
+ */
+ private $countable;
+
public function setDate(\DateTime $date)
{
$this->date = $date;
@@ -27,4 +32,20 @@ public function getDate()
{
return $this->date;
}
+
+ /**
+ * @return \Countable
+ */
+ public function getCountable()
+ {
+ return $this->countable;
+ }
+
+ /**
+ * @param \Countable $countable
+ */
+ public function setCountable(\Countable $countable)
+ {
+ $this->countable = $countable;
+ }
}
diff --git a/src/Symfony/Component/PropertyAccess/Tests/PropertyAccessorTest.php b/src/Symfony/Component/PropertyAccess/Tests/PropertyAccessorTest.php
index a3a82b0b63cba..33d4085b07969 100644
--- a/src/Symfony/Component/PropertyAccess/Tests/PropertyAccessorTest.php
+++ b/src/Symfony/Component/PropertyAccess/Tests/PropertyAccessorTest.php
@@ -566,4 +566,15 @@ public function testCacheReadAccess()
$propertyAccessor->setValue($obj, 'publicGetSetter', 'baz');
$this->assertEquals('baz', $propertyAccessor->getValue($obj, 'publicGetSetter'));
}
+
+ /**
+ * @expectedException \Symfony\Component\PropertyAccess\Exception\InvalidArgumentException
+ * @expectedExceptionMessage Expected argument of type "Countable", "string" given
+ */
+ public function testThrowTypeErrorWithInterface()
+ {
+ $object = new TypeHinted();
+
+ $this->propertyAccessor->setValue($object, 'countable', 'This is a string, \Countable expected.');
+ }
}
diff --git a/src/Symfony/Component/PropertyInfo/Extractor/PhpDocExtractor.php b/src/Symfony/Component/PropertyInfo/Extractor/PhpDocExtractor.php
index 5e459f4b038d0..f7e4aa871e3cf 100644
--- a/src/Symfony/Component/PropertyInfo/Extractor/PhpDocExtractor.php
+++ b/src/Symfony/Component/PropertyInfo/Extractor/PhpDocExtractor.php
@@ -223,6 +223,9 @@ private function getDocBlockFromMethod($class, $ucFirstProperty, $type)
try {
$reflectionMethod = new \ReflectionMethod($class, $methodName);
+ if ($reflectionMethod->isStatic()) {
+ continue;
+ }
if (
(self::ACCESSOR === $type && 0 === $reflectionMethod->getNumberOfRequiredParameters()) ||
diff --git a/src/Symfony/Component/PropertyInfo/Extractor/ReflectionExtractor.php b/src/Symfony/Component/PropertyInfo/Extractor/ReflectionExtractor.php
index e92da1fcd0088..96c2e9b48ef5f 100644
--- a/src/Symfony/Component/PropertyInfo/Extractor/ReflectionExtractor.php
+++ b/src/Symfony/Component/PropertyInfo/Extractor/ReflectionExtractor.php
@@ -73,6 +73,10 @@ public function getProperties($class, array $context = array())
}
foreach ($reflectionClass->getMethods(\ReflectionMethod::IS_PUBLIC) as $reflectionMethod) {
+ if ($reflectionMethod->isStatic()) {
+ continue;
+ }
+
$propertyName = $this->getPropertyName($reflectionMethod->name, $reflectionProperties);
if (!$propertyName || isset($properties[$propertyName])) {
continue;
@@ -263,6 +267,9 @@ private function getAccessorMethod($class, $property)
foreach (self::$accessorPrefixes as $prefix) {
try {
$reflectionMethod = new \ReflectionMethod($class, $prefix.$ucProperty);
+ if ($reflectionMethod->isStatic()) {
+ continue;
+ }
if (0 === $reflectionMethod->getNumberOfRequiredParameters()) {
return array($reflectionMethod, $prefix);
@@ -298,6 +305,9 @@ private function getMutatorMethod($class, $property)
foreach ($names as $name) {
try {
$reflectionMethod = new \ReflectionMethod($class, $prefix.$name);
+ if ($reflectionMethod->isStatic()) {
+ continue;
+ }
// Parameter can be optional to allow things like: method(array $foo = null)
if ($reflectionMethod->getNumberOfParameters() >= 1) {
diff --git a/src/Symfony/Component/PropertyInfo/PropertyInfoExtractor.php b/src/Symfony/Component/PropertyInfo/PropertyInfoExtractor.php
index 942318af605d8..031c8ac05e26a 100644
--- a/src/Symfony/Component/PropertyInfo/PropertyInfoExtractor.php
+++ b/src/Symfony/Component/PropertyInfo/PropertyInfoExtractor.php
@@ -44,7 +44,7 @@ class PropertyInfoExtractor implements PropertyInfoExtractorInterface
* @param PropertyDescriptionExtractorInterface[] $descriptionExtractors
* @param PropertyAccessExtractorInterface[] $accessExtractors
*/
- public function __construct(array $listExtractors = array(), array $typeExtractors = array(), array $descriptionExtractors = array(), array $accessExtractors = array())
+ public function __construct(array $listExtractors = array(), array $typeExtractors = array(), array $descriptionExtractors = array(), array $accessExtractors = array())
{
$this->listExtractors = $listExtractors;
$this->typeExtractors = $typeExtractors;
diff --git a/src/Symfony/Component/PropertyInfo/Tests/Extractors/PhpDocExtractorTest.php b/src/Symfony/Component/PropertyInfo/Tests/Extractors/PhpDocExtractorTest.php
index a8cc99ece0d08..942dd74c9cd3b 100644
--- a/src/Symfony/Component/PropertyInfo/Tests/Extractors/PhpDocExtractorTest.php
+++ b/src/Symfony/Component/PropertyInfo/Tests/Extractors/PhpDocExtractorTest.php
@@ -68,6 +68,8 @@ public function typesProvider()
array('e', array(new Type(Type::BUILTIN_TYPE_ARRAY, false, null, true, new Type(Type::BUILTIN_TYPE_INT), new Type(Type::BUILTIN_TYPE_RESOURCE))), null, null),
array('f', array(new Type(Type::BUILTIN_TYPE_ARRAY, false, null, true, new Type(Type::BUILTIN_TYPE_INT), new Type(Type::BUILTIN_TYPE_OBJECT, false, 'DateTime'))), null, null),
array('donotexist', null, null, null),
+ array('staticGetter', null, null, null),
+ array('staticSetter', null, null, null),
);
}
diff --git a/src/Symfony/Component/PropertyInfo/Tests/Extractors/ReflectionExtractorTest.php b/src/Symfony/Component/PropertyInfo/Tests/Extractors/ReflectionExtractorTest.php
index 70050f94e6559..91974d689db2b 100644
--- a/src/Symfony/Component/PropertyInfo/Tests/Extractors/ReflectionExtractorTest.php
+++ b/src/Symfony/Component/PropertyInfo/Tests/Extractors/ReflectionExtractorTest.php
@@ -73,6 +73,8 @@ public function typesProvider()
array('e', null),
array('f', array(new Type(Type::BUILTIN_TYPE_ARRAY, false, null, true, new Type(Type::BUILTIN_TYPE_INT), new Type(Type::BUILTIN_TYPE_OBJECT, false, 'DateTime')))),
array('donotexist', null),
+ array('staticGetter', null),
+ array('staticSetter', null),
);
}
diff --git a/src/Symfony/Component/PropertyInfo/Tests/Fixtures/Dummy.php b/src/Symfony/Component/PropertyInfo/Tests/Fixtures/Dummy.php
index 41a513ac362e1..96cb87db4a8fa 100644
--- a/src/Symfony/Component/PropertyInfo/Tests/Fixtures/Dummy.php
+++ b/src/Symfony/Component/PropertyInfo/Tests/Fixtures/Dummy.php
@@ -51,6 +51,21 @@ class Dummy extends ParentDummy
*/
public $B;
+ public static function getStatic()
+ {
+ }
+
+ /**
+ * @return string
+ */
+ public static function staticGetter()
+ {
+ }
+
+ public static function staticSetter(\DateTime $d)
+ {
+ }
+
/**
* A.
*
diff --git a/src/Symfony/Component/Routing/Loader/AnnotationClassLoader.php b/src/Symfony/Component/Routing/Loader/AnnotationClassLoader.php
index 565698e808007..8463673e2d1ac 100644
--- a/src/Symfony/Component/Routing/Loader/AnnotationClassLoader.php
+++ b/src/Symfony/Component/Routing/Loader/AnnotationClassLoader.php
@@ -139,7 +139,7 @@ protected function addRoute(RouteCollection $collection, $annot, $globals, \Refl
$defaults = array_replace($globals['defaults'], $annot->getDefaults());
foreach ($method->getParameters() as $param) {
- if (!isset($defaults[$param->getName()]) && $param->isDefaultValueAvailable()) {
+ if (false !== strpos($globals['path'].$annot->getPath(), sprintf('{%s}', $param->getName())) && !isset($defaults[$param->getName()]) && $param->isDefaultValueAvailable()) {
$defaults[$param->getName()] = $param->getDefaultValue();
}
}
diff --git a/src/Symfony/Component/Routing/Tests/Loader/AnnotationClassLoaderTest.php b/src/Symfony/Component/Routing/Tests/Loader/AnnotationClassLoaderTest.php
index 83bf7108fb28b..44229633b5cbc 100644
--- a/src/Symfony/Component/Routing/Tests/Loader/AnnotationClassLoaderTest.php
+++ b/src/Symfony/Component/Routing/Tests/Loader/AnnotationClassLoaderTest.php
@@ -136,11 +136,10 @@ public function testLoad($className, $routeData = array(), $methodArgs = array()
array_intersect_assoc($routeData['options'], $route->getOptions()),
'->load preserves options annotation'
);
- $defaults = array_replace($methodArgs, $routeData['defaults']);
$this->assertCount(
- count($defaults),
- array_intersect_assoc($defaults, $route->getDefaults()),
- '->load preserves defaults annotation and merges them with default arguments in method signature'
+ count($routeData['defaults']),
+ $route->getDefaults(),
+ '->load preserves defaults annotation'
);
$this->assertEquals($routeData['schemes'], $route->getSchemes(), '->load preserves schemes annotation');
$this->assertEquals($routeData['methods'], $route->getMethods(), '->load preserves methods annotation');
diff --git a/src/Symfony/Component/Security/Core/Tests/User/LdapUserProviderTest.php b/src/Symfony/Component/Security/Core/Tests/User/LdapUserProviderTest.php
index a1ef0bbf19e8e..06baeae7d118f 100644
--- a/src/Symfony/Component/Security/Core/Tests/User/LdapUserProviderTest.php
+++ b/src/Symfony/Component/Security/Core/Tests/User/LdapUserProviderTest.php
@@ -151,6 +151,48 @@ public function testLoadUserByUsernameFailsIfMoreThanOneLdapPasswordsInEntry()
);
}
+ /**
+ * @expectedException \Symfony\Component\Security\Core\Exception\InvalidArgumentException
+ */
+ public function testLoadUserByUsernameFailsIfEntryHasNoUidKeyAttribute()
+ {
+ $result = $this->getMockBuilder(CollectionInterface::class)->getMock();
+ $query = $this->getMockBuilder(QueryInterface::class)->getMock();
+ $query
+ ->expects($this->once())
+ ->method('execute')
+ ->will($this->returnValue($result))
+ ;
+ $ldap = $this->getMockBuilder(LdapInterface::class)->getMock();
+ $result
+ ->expects($this->once())
+ ->method('offsetGet')
+ ->with(0)
+ ->will($this->returnValue(new Entry('foo', array())))
+ ;
+ $result
+ ->expects($this->once())
+ ->method('count')
+ ->will($this->returnValue(1))
+ ;
+ $ldap
+ ->expects($this->once())
+ ->method('escape')
+ ->will($this->returnValue('foo'))
+ ;
+ $ldap
+ ->expects($this->once())
+ ->method('query')
+ ->will($this->returnValue($query))
+ ;
+
+ $provider = new LdapUserProvider($ldap, 'ou=MyBusiness,dc=symfony,dc=com', null, null, array(), 'sAMAccountName', '({uid_key}={username})');
+ $this->assertInstanceOf(
+ 'Symfony\Component\Security\Core\User\User',
+ $provider->loadUserByUsername('foo')
+ );
+ }
+
/**
* @expectedException \Symfony\Component\Security\Core\Exception\InvalidArgumentException
*/
@@ -238,6 +280,45 @@ public function testLoadUserByUsernameIsSuccessfulWithoutPasswordAttribute()
);
}
+ public function testLoadUserByUsernameIsSuccessfulWithoutPasswordAttributeAndWrongCase()
+ {
+ $result = $this->getMockBuilder(CollectionInterface::class)->getMock();
+ $query = $this->getMockBuilder(QueryInterface::class)->getMock();
+ $query
+ ->expects($this->once())
+ ->method('execute')
+ ->will($this->returnValue($result))
+ ;
+ $ldap = $this->getMockBuilder(LdapInterface::class)->getMock();
+ $result
+ ->expects($this->once())
+ ->method('offsetGet')
+ ->with(0)
+ ->will($this->returnValue(new Entry('foo', array(
+ 'sAMAccountName' => array('foo'),
+ )
+ )))
+ ;
+ $result
+ ->expects($this->once())
+ ->method('count')
+ ->will($this->returnValue(1))
+ ;
+ $ldap
+ ->expects($this->once())
+ ->method('escape')
+ ->will($this->returnValue('Foo'))
+ ;
+ $ldap
+ ->expects($this->once())
+ ->method('query')
+ ->will($this->returnValue($query))
+ ;
+
+ $provider = new LdapUserProvider($ldap, 'ou=MyBusiness,dc=symfony,dc=com');
+ $this->assertSame('foo', $provider->loadUserByUsername('Foo')->getUsername());
+ }
+
public function testLoadUserByUsernameIsSuccessfulWithPasswordAttribute()
{
$result = $this->getMockBuilder(CollectionInterface::class)->getMock();
diff --git a/src/Symfony/Component/Security/Core/User/LdapUserProvider.php b/src/Symfony/Component/Security/Core/User/LdapUserProvider.php
index fc42419a6d1ab..1edf3f764ef04 100644
--- a/src/Symfony/Component/Security/Core/User/LdapUserProvider.php
+++ b/src/Symfony/Component/Security/Core/User/LdapUserProvider.php
@@ -31,6 +31,7 @@ class LdapUserProvider implements UserProviderInterface
private $searchDn;
private $searchPassword;
private $defaultRoles;
+ private $uidKey;
private $defaultSearch;
private $passwordAttribute;
@@ -46,11 +47,16 @@ class LdapUserProvider implements UserProviderInterface
*/
public function __construct(LdapInterface $ldap, $baseDn, $searchDn = null, $searchPassword = null, array $defaultRoles = array(), $uidKey = 'sAMAccountName', $filter = '({uid_key}={username})', $passwordAttribute = null)
{
+ if (null === $uidKey) {
+ $uidKey = 'uid';
+ }
+
$this->ldap = $ldap;
$this->baseDn = $baseDn;
$this->searchDn = $searchDn;
$this->searchPassword = $searchPassword;
$this->defaultRoles = $defaultRoles;
+ $this->uidKey = $uidKey;
$this->defaultSearch = str_replace('{uid_key}', $uidKey, $filter);
$this->passwordAttribute = $passwordAttribute;
}
@@ -80,7 +86,10 @@ public function loadUserByUsername($username)
throw new UsernameNotFoundException('More than one user found');
}
- return $this->loadUser($username, $entries[0]);
+ $entry = $entries[0];
+ $username = $this->getAttributeValue($entry, $this->uidKey);
+
+ return $this->loadUser($username, $entry);
}
/**
@@ -113,30 +122,30 @@ public function supportsClass($class)
*/
protected function loadUser($username, Entry $entry)
{
- $password = $this->getPassword($entry);
+ $password = null;
+ if (null !== $this->passwordAttribute) {
+ $password = $this->getAttributeValue($entry, $this->passwordAttribute);
+ }
return new User($username, $password, $this->defaultRoles);
}
/**
- * Fetches the password from an LDAP entry.
+ * Fetches a required unique attribute value from an LDAP entry.
*
* @param null|Entry $entry
+ * @param string $attribute
*/
- private function getPassword(Entry $entry)
+ private function getAttributeValue(Entry $entry, $attribute)
{
- if (null === $this->passwordAttribute) {
- return;
- }
-
- if (!$entry->hasAttribute($this->passwordAttribute)) {
- throw new InvalidArgumentException(sprintf('Missing attribute "%s" for user "%s".', $this->passwordAttribute, $entry->getDn()));
+ if (!$entry->hasAttribute($attribute)) {
+ throw new InvalidArgumentException(sprintf('Missing attribute "%s" for user "%s".', $attribute, $entry->getDn()));
}
- $values = $entry->getAttribute($this->passwordAttribute);
+ $values = $entry->getAttribute($attribute);
if (1 !== count($values)) {
- throw new InvalidArgumentException(sprintf('Attribute "%s" has multiple values.', $this->passwordAttribute));
+ throw new InvalidArgumentException(sprintf('Attribute "%s" has multiple values.', $attribute));
}
return $values[0];
diff --git a/src/Symfony/Component/Serializer/Tests/Encoder/JsonDecodeTest.php b/src/Symfony/Component/Serializer/Tests/Encoder/JsonDecodeTest.php
index c87ab21b510a2..7818aeaf55df8 100644
--- a/src/Symfony/Component/Serializer/Tests/Encoder/JsonDecodeTest.php
+++ b/src/Symfony/Component/Serializer/Tests/Encoder/JsonDecodeTest.php
@@ -61,7 +61,7 @@ public function decodeProvider()
*/
public function testDecodeWithException($value)
{
- $this->decode->decode($value, JsonEncoder::FORMAT);
+ $this->decode->decode($value, JsonEncoder::FORMAT);
}
public function decodeProviderException()
diff --git a/src/Symfony/Component/Serializer/Tests/Encoder/JsonEncodeTest.php b/src/Symfony/Component/Serializer/Tests/Encoder/JsonEncodeTest.php
index d255b21d22e7f..291c0f0965c80 100644
--- a/src/Symfony/Component/Serializer/Tests/Encoder/JsonEncodeTest.php
+++ b/src/Symfony/Component/Serializer/Tests/Encoder/JsonEncodeTest.php
@@ -54,6 +54,6 @@ public function encodeProvider()
*/
public function testEncodeWithError()
{
- $this->encode->encode("\xB1\x31", JsonEncoder::FORMAT);
+ $this->encode->encode("\xB1\x31", JsonEncoder::FORMAT);
}
}
diff --git a/src/Symfony/Component/Serializer/composer.json b/src/Symfony/Component/Serializer/composer.json
index 8bbb2b18937b0..d7dbfc6509c09 100644
--- a/src/Symfony/Component/Serializer/composer.json
+++ b/src/Symfony/Component/Serializer/composer.json
@@ -31,6 +31,7 @@
},
"conflict": {
"symfony/property-access": ">=3.0,<3.0.4|>=2.8,<2.8.4",
+ "symfony/property-info": "<3.1",
"symfony/yaml": "<3.1"
},
"suggest": {
diff --git a/src/Symfony/Component/Translation/Tests/Dumper/FileDumperTest.php b/src/Symfony/Component/Translation/Tests/Dumper/FileDumperTest.php
index 2b4b163a758f0..4fcabaf2c985a 100644
--- a/src/Symfony/Component/Translation/Tests/Dumper/FileDumperTest.php
+++ b/src/Symfony/Component/Translation/Tests/Dumper/FileDumperTest.php
@@ -26,7 +26,7 @@ public function testDump()
$dumper = new ConcreteFileDumper();
$dumper->dump($catalogue, array('path' => $tempDir));
- $this->assertTrue(file_exists($tempDir.'/messages.en.concrete'));
+ $this->assertFileExists($tempDir.'/messages.en.concrete');
}
/**
diff --git a/src/Symfony/Component/Translation/Util/ArrayConverter.php b/src/Symfony/Component/Translation/Util/ArrayConverter.php
index 60a55e9d3709c..9c0a420a8592f 100644
--- a/src/Symfony/Component/Translation/Util/ArrayConverter.php
+++ b/src/Symfony/Component/Translation/Util/ArrayConverter.php
@@ -62,7 +62,7 @@ private static function &getElementByPath(array &$tree, array $parts)
* $tree['foo'] was string before we found array {bar: test2}.
* Treat new element as string too, e.g. add $tree['foo.bar'] = 'test2';
*/
- $elem = &$elem[ implode('.', array_slice($parts, $i)) ];
+ $elem = &$elem[implode('.', array_slice($parts, $i))];
break;
}
$parentOfElem = &$elem;
diff --git a/src/Symfony/Component/Validator/Constraints/BicValidator.php b/src/Symfony/Component/Validator/Constraints/BicValidator.php
index f476713c74d14..d2188071fabf1 100644
--- a/src/Symfony/Component/Validator/Constraints/BicValidator.php
+++ b/src/Symfony/Component/Validator/Constraints/BicValidator.php
@@ -17,7 +17,7 @@
/**
* @author Michael Hirschler
*
- * @link https://en.wikipedia.org/wiki/ISO_9362#Structure
+ * @see https://en.wikipedia.org/wiki/ISO_9362#Structure
*/
class BicValidator extends ConstraintValidator
{
diff --git a/src/Symfony/Component/Validator/Resources/translations/validators.de.xlf b/src/Symfony/Component/Validator/Resources/translations/validators.de.xlf
index 541ebaa0a8f85..192b992f8f3ba 100644
--- a/src/Symfony/Component/Validator/Resources/translations/validators.de.xlf
+++ b/src/Symfony/Component/Validator/Resources/translations/validators.de.xlf
@@ -192,7 +192,7 @@
No temporary folder was configured in php.ini.
- Es wurde kein temporärer Ordner in der php.ini konfiguriert.
+ Es wurde kein temporärer Ordner in der php.ini konfiguriert oder der temporäre Ordner existiert nicht.
Cannot write temporary file to disk.
diff --git a/src/Symfony/Component/Validator/Resources/translations/validators.en.xlf b/src/Symfony/Component/Validator/Resources/translations/validators.en.xlf
index ec072eb716dfc..2a5c97d8cf2d0 100644
--- a/src/Symfony/Component/Validator/Resources/translations/validators.en.xlf
+++ b/src/Symfony/Component/Validator/Resources/translations/validators.en.xlf
@@ -192,7 +192,7 @@
No temporary folder was configured in php.ini.
- No temporary folder was configured in php.ini.
+ No temporary folder was configured in php.ini, or the configured folder does not exist.
Cannot write temporary file to disk.
diff --git a/src/Symfony/Component/Validator/Resources/translations/validators.hr.xlf b/src/Symfony/Component/Validator/Resources/translations/validators.hr.xlf
index a11e825ccadad..8c62d899fdaec 100644
--- a/src/Symfony/Component/Validator/Resources/translations/validators.hr.xlf
+++ b/src/Symfony/Component/Validator/Resources/translations/validators.hr.xlf
@@ -278,6 +278,42 @@
This value should not be identical to {{ compared_value_type }} {{ compared_value }}.
Ova vrijednost ne bi trebala biti {{ compared_value_type }} {{ compared_value }}.
+
+ The image ratio is too big ({{ ratio }}). Allowed maximum ratio is {{ max_ratio }}.
+ Omjer slike je prevelik ({{ ratio }}). Dozvoljeni maksimalni omjer je {{ max_ratio }}.
+
+
+ The image ratio is too small ({{ ratio }}). Minimum ratio expected is {{ min_ratio }}.
+ Omjer slike je premali ({{ ratio }}). Minimalni očekivani omjer je {{ min_ratio }}.
+
+
+ The image is square ({{ width }}x{{ height }}px). Square images are not allowed.
+ Slika je kvadratnog oblika ({{ width }}x{{ height }}px). Kvadratne slike nisu dozvoljene.
+
+
+ The image is landscape oriented ({{ width }}x{{ height }}px). Landscape oriented images are not allowed.
+ Slika je orijentirana horizontalno ({{ width }}x{{ height }}px). Horizontalno orijentirane slike nisu dozvoljene.
+
+
+ The image is portrait oriented ({{ width }}x{{ height }}px). Portrait oriented images are not allowed.
+ Slika je orijentirana vertikalno ({{ width }}x{{ height }}px). Vertikalno orijentirane slike nisu dozvoljene.
+
+
+ An empty file is not allowed.
+ Prazna datoteka nije dozvoljena.
+
+
+ The host could not be resolved.
+ Poslužitelj nije mogao biti razriješen.
+
+
+ This value does not match the expected {{ charset }} charset.
+ Znakovne oznake vrijednosti ne odgovaraju očekivanom {{ charset }} skupu.
+
+
+ This is not a valid Business Identifier Code (BIC).
+ Ovo nije validan poslovni identifikacijski broj (BIC).
+