Merge branch '3.0' into 3.1

* 3.0:
  fixed CS
  fixed CS
  fixed CS
  tweaked default CS fixer config
  [HttpKernel] Dont close the output stream in debug
  move HttpKernel component to require section
  Fixed oci and sqlsrv merge queries when emulation is disabled - fixes #17284
  [Session] fix PDO transaction aborted under PostgreSQL
  [Console] Use InputInterface inherited doc as possible
  Mention generating absolute urls in UPGRADE files and CHANGELOG
  add docblock type elements to support newly added IteratorAggregate::getIterator PhpStorm support
  FormBuilderInterface: fix getForm() return type.
  Fixed typo in PHPDoc
This commit is contained in:
Fabien Potencier 2016-06-21 07:59:09 +02:00
commit 9cbec2c4fa
32 changed files with 218 additions and 205 deletions

View File

@ -3,6 +3,10 @@
return Symfony\CS\Config\Config::create() return Symfony\CS\Config\Config::create()
->setUsingLinter(false) ->setUsingLinter(false)
->setUsingCache(true) ->setUsingCache(true)
->fixers(array(
'long_array_syntax',
'php_unit_construct',
))
->finder( ->finder(
Symfony\CS\Finder\DefaultFinder::create() Symfony\CS\Finder\DefaultFinder::create()
->in(__DIR__) ->in(__DIR__)
@ -12,6 +16,9 @@ return Symfony\CS\Config\Config::create()
'src/Symfony/Component/Routing/Tests/Fixtures/dumper', 'src/Symfony/Component/Routing/Tests/Fixtures/dumper',
// fixture templates // fixture templates
'src/Symfony/Component/Templating/Tests/Fixtures/templates', 'src/Symfony/Component/Templating/Tests/Fixtures/templates',
'src/Symfony/Bundle/FrameworkBundle/Tests/Templating/Helper/Resources/Custom',
// generated fixtures
'src/Symfony/Component/VarDumper/Tests/Fixtures',
// resource templates // resource templates
'src/Symfony/Bundle/FrameworkBundle/Resources/views/Form', 'src/Symfony/Bundle/FrameworkBundle/Resources/views/Form',
)) ))

View File

@ -939,6 +939,30 @@ UPGRADE FROM 2.x to 3.0
* The `getMatcherDumperInstance()` and `getGeneratorDumperInstance()` methods in the * The `getMatcherDumperInstance()` and `getGeneratorDumperInstance()` methods in the
`Symfony\Component\Routing\Router` have been changed from `public` to `protected`. `Symfony\Component\Routing\Router` have been changed from `public` to `protected`.
* Use the constants defined in the UrlGeneratorInterface for the $referenceType argument of the UrlGeneratorInterface::generate method.
Before:
```php
// url generated in controller
$this->generateUrl('blog_show', array('slug' => 'my-blog-post'), true);
// url generated in @router service
$router->generate('blog_show', array('slug' => 'my-blog-post'), true);
```
After:
```php
use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
// url generated in controller
$this->generateUrl('blog_show', array('slug' => 'my-blog-post'), UrlGeneratorInterface::ABSOLUTE_URL);
// url generated in @router service
$router->generate('blog_show', array('slug' => 'my-blog-post'), UrlGeneratorInterface::ABSOLUTE_URL);
```
### Security ### Security
* The `vote()` method from the `VoterInterface` was changed to now accept arbitrary * The `vote()` method from the `VoterInterface` was changed to now accept arbitrary

View File

@ -17,10 +17,10 @@
], ],
"require": { "require": {
"php": ">=5.5.9", "php": ">=5.5.9",
"monolog/monolog": "~1.11" "monolog/monolog": "~1.11",
"symfony/http-kernel": "~2.8|~3.0"
}, },
"require-dev": { "require-dev": {
"symfony/http-kernel": "~2.8|~3.0",
"symfony/console": "~2.8|~3.0", "symfony/console": "~2.8|~3.0",
"symfony/event-dispatcher": "~2.8|~3.0" "symfony/event-dispatcher": "~2.8|~3.0"
}, },

View File

@ -32,7 +32,7 @@ abstract class AbstractConfigCommand extends ContainerDebugCommand
$rows = array(); $rows = array();
$bundles = $this->getContainer()->get('kernel')->getBundles(); $bundles = $this->getContainer()->get('kernel')->getBundles();
usort($bundles, function($bundleA, $bundleB) { usort($bundles, function ($bundleA, $bundleB) {
return strcmp($bundleA->getName(), $bundleB->getName()); return strcmp($bundleA->getName(), $bundleB->getName());
}); });

View File

@ -25,7 +25,7 @@ class AssetsHelperTest extends \PHPUnit_Framework_TestCase
$fooPackage = new Package(new StaticVersionStrategy('42', '%s?v=%s')); $fooPackage = new Package(new StaticVersionStrategy('42', '%s?v=%s'));
$barPackage = new Package(new StaticVersionStrategy('22', '%s?%s')); $barPackage = new Package(new StaticVersionStrategy('22', '%s?%s'));
$packages = new Packages($fooPackage, ['bar' => $barPackage]); $packages = new Packages($fooPackage, array('bar' => $barPackage));
$this->helper = new AssetsHelper($packages); $this->helper = new AssetsHelper($packages);
} }

View File

@ -21,6 +21,9 @@ use Symfony\Component\Console\Exception\InvalidArgumentException;
*/ */
class HelperSet implements \IteratorAggregate class HelperSet implements \IteratorAggregate
{ {
/**
* @var Helper[]
*/
private $helpers = array(); private $helpers = array();
private $command; private $command;
@ -102,6 +105,9 @@ class HelperSet implements \IteratorAggregate
return $this->command; return $this->command;
} }
/**
* @return Helper[]
*/
public function getIterator() public function getIterator()
{ {
return new \ArrayIterator($this->helpers); return new \ArrayIterator($this->helpers);

View File

@ -46,8 +46,8 @@ class ArgvInput extends Input
/** /**
* Constructor. * Constructor.
* *
* @param array $argv An array of parameters from the CLI (in the argv format) * @param array|null $argv An array of parameters from the CLI (in the argv format)
* @param InputDefinition $definition A InputDefinition instance * @param InputDefinition|null $definition A InputDefinition instance
*/ */
public function __construct(array $argv = null, InputDefinition $definition = null) public function __construct(array $argv = null, InputDefinition $definition = null)
{ {
@ -69,7 +69,7 @@ class ArgvInput extends Input
} }
/** /**
* Processes command line arguments. * {@inheritdoc}
*/ */
protected function parse() protected function parse()
{ {
@ -253,9 +253,7 @@ class ArgvInput extends Input
} }
/** /**
* Returns the first argument from the raw parameters (not parsed). * {@inheritdoc}
*
* @return string The value of the first argument or null otherwise
*/ */
public function getFirstArgument() public function getFirstArgument()
{ {
@ -269,15 +267,7 @@ class ArgvInput extends Input
} }
/** /**
* Returns true if the raw parameters (not parsed) contain a value. * {@inheritdoc}
*
* This method is to be used to introspect the input parameters
* before they have been validated. It must be used carefully.
*
* @param string|array $values The value(s) to look for in the raw parameters (can be an array)
* @param bool $onlyParams Only check real parameters, skip those following an end of options (--) signal
*
* @return bool true if the value is contained in the raw parameters
*/ */
public function hasParameterOption($values, $onlyParams = false) public function hasParameterOption($values, $onlyParams = false)
{ {
@ -298,16 +288,7 @@ class ArgvInput extends Input
} }
/** /**
* Returns the value of a raw option (not parsed). * {@inheritdoc}
*
* This method is to be used to introspect the input parameters
* before they have been validated. It must be used carefully.
*
* @param string|array $values The value(s) to look for in the raw parameters (can be an array)
* @param mixed $default The default value to return if no result is found
* @param bool $onlyParams Only check real parameters, skip those following an end of options (--) signal
*
* @return mixed The option value
*/ */
public function getParameterOption($values, $default = false, $onlyParams = false) public function getParameterOption($values, $default = false, $onlyParams = false)
{ {

View File

@ -31,7 +31,7 @@ class ArrayInput extends Input
* Constructor. * Constructor.
* *
* @param array $parameters An array of parameters * @param array $parameters An array of parameters
* @param InputDefinition $definition A InputDefinition instance * @param InputDefinition|null $definition A InputDefinition instance
*/ */
public function __construct(array $parameters, InputDefinition $definition = null) public function __construct(array $parameters, InputDefinition $definition = null)
{ {
@ -41,9 +41,7 @@ class ArrayInput extends Input
} }
/** /**
* Returns the first argument from the raw parameters (not parsed). * {@inheritdoc}
*
* @return string The value of the first argument or null otherwise
*/ */
public function getFirstArgument() public function getFirstArgument()
{ {
@ -57,15 +55,7 @@ class ArrayInput extends Input
} }
/** /**
* Returns true if the raw parameters (not parsed) contain a value. * {@inheritdoc}
*
* This method is to be used to introspect the input parameters
* before they have been validated. It must be used carefully.
*
* @param string|array $values The values to look for in the raw parameters (can be an array)
* @param bool $onlyParams Only check real parameters, skip those following an end of options (--) signal
*
* @return bool true if the value is contained in the raw parameters
*/ */
public function hasParameterOption($values, $onlyParams = false) public function hasParameterOption($values, $onlyParams = false)
{ {
@ -89,16 +79,7 @@ class ArrayInput extends Input
} }
/** /**
* Returns the value of a raw option (not parsed). * {@inheritdoc}
*
* This method is to be used to introspect the input parameters
* before they have been validated. It must be used carefully.
*
* @param string|array $values The value(s) to look for in the raw parameters (can be an array)
* @param mixed $default The default value to return if no result is found
* @param bool $onlyParams Only check real parameters, skip those following an end of options (--) signal
*
* @return mixed The option value
*/ */
public function getParameterOption($values, $default = false, $onlyParams = false) public function getParameterOption($values, $default = false, $onlyParams = false)
{ {
@ -141,7 +122,7 @@ class ArrayInput extends Input
} }
/** /**
* Processes command line arguments. * {@inheritdoc}
*/ */
protected function parse() protected function parse()
{ {

View File

@ -38,7 +38,7 @@ abstract class Input implements InputInterface
/** /**
* Constructor. * Constructor.
* *
* @param InputDefinition $definition A InputDefinition instance * @param InputDefinition|null $definition A InputDefinition instance
*/ */
public function __construct(InputDefinition $definition = null) public function __construct(InputDefinition $definition = null)
{ {
@ -51,9 +51,7 @@ abstract class Input implements InputInterface
} }
/** /**
* Binds the current Input instance with the given arguments and options. * {@inheritdoc}
*
* @param InputDefinition $definition A InputDefinition instance
*/ */
public function bind(InputDefinition $definition) public function bind(InputDefinition $definition)
{ {
@ -70,9 +68,7 @@ abstract class Input implements InputInterface
abstract protected function parse(); abstract protected function parse();
/** /**
* Validates the input. * {@inheritdoc}
*
* @throws RuntimeException When not enough arguments are given
*/ */
public function validate() public function validate()
{ {
@ -89,9 +85,7 @@ abstract class Input implements InputInterface
} }
/** /**
* Checks if the input is interactive. * {@inheritdoc}
*
* @return bool Returns true if the input is interactive
*/ */
public function isInteractive() public function isInteractive()
{ {
@ -99,9 +93,7 @@ abstract class Input implements InputInterface
} }
/** /**
* Sets the input interactivity. * {@inheritdoc}
*
* @param bool $interactive If the input should be interactive
*/ */
public function setInteractive($interactive) public function setInteractive($interactive)
{ {
@ -109,9 +101,7 @@ abstract class Input implements InputInterface
} }
/** /**
* Returns the argument values. * {@inheritdoc}
*
* @return array An array of argument values
*/ */
public function getArguments() public function getArguments()
{ {
@ -119,13 +109,7 @@ abstract class Input implements InputInterface
} }
/** /**
* Returns the argument value for a given argument name. * {@inheritdoc}
*
* @param string $name The argument name
*
* @return mixed The argument value
*
* @throws InvalidArgumentException When argument given doesn't exist
*/ */
public function getArgument($name) public function getArgument($name)
{ {
@ -137,12 +121,7 @@ abstract class Input implements InputInterface
} }
/** /**
* Sets an argument value by name. * {@inheritdoc}
*
* @param string $name The argument name
* @param string $value The argument value
*
* @throws InvalidArgumentException When argument given doesn't exist
*/ */
public function setArgument($name, $value) public function setArgument($name, $value)
{ {
@ -154,11 +133,7 @@ abstract class Input implements InputInterface
} }
/** /**
* Returns true if an InputArgument object exists by name or position. * {@inheritdoc}
*
* @param string|int $name The InputArgument name or position
*
* @return bool true if the InputArgument object exists, false otherwise
*/ */
public function hasArgument($name) public function hasArgument($name)
{ {
@ -166,9 +141,7 @@ abstract class Input implements InputInterface
} }
/** /**
* Returns the options values. * {@inheritdoc}
*
* @return array An array of option values
*/ */
public function getOptions() public function getOptions()
{ {
@ -176,13 +149,7 @@ abstract class Input implements InputInterface
} }
/** /**
* Returns the option value for a given option name. * {@inheritdoc}
*
* @param string $name The option name
*
* @return mixed The option value
*
* @throws InvalidArgumentException When option given doesn't exist
*/ */
public function getOption($name) public function getOption($name)
{ {
@ -194,12 +161,7 @@ abstract class Input implements InputInterface
} }
/** /**
* Sets an option value by name. * {@inheritdoc}
*
* @param string $name The option name
* @param string|bool $value The option value
*
* @throws InvalidArgumentException When option given doesn't exist
*/ */
public function setOption($name, $value) public function setOption($name, $value)
{ {
@ -211,11 +173,7 @@ abstract class Input implements InputInterface
} }
/** /**
* Returns true if an InputOption object exists by name. * {@inheritdoc}
*
* @param string $name The InputOption name
*
* @return bool true if the InputOption object exists, false otherwise
*/ */
public function hasOption($name) public function hasOption($name)
{ {

View File

@ -11,6 +11,9 @@
namespace Symfony\Component\Console\Input; namespace Symfony\Component\Console\Input;
use Symfony\Component\Console\Exception\InvalidArgumentException;
use Symfony\Component\Console\Exception\RuntimeException;
/** /**
* InputInterface is the interface implemented by all input classes. * InputInterface is the interface implemented by all input classes.
* *
@ -60,11 +63,9 @@ interface InputInterface
public function bind(InputDefinition $definition); public function bind(InputDefinition $definition);
/** /**
* Validates if arguments given are correct. * Validates the input.
* *
* Throws an exception when not enough arguments are given. * @throws RuntimeException When not enough arguments are given
*
* @throws \RuntimeException
*/ */
public function validate(); public function validate();
@ -76,11 +77,13 @@ interface InputInterface
public function getArguments(); public function getArguments();
/** /**
* Gets argument by name. * Returns the argument value for a given argument name.
* *
* @param string $name The name of the argument * @param string $name The argument name
* *
* @return mixed * @return mixed The argument value
*
* @throws InvalidArgumentException When argument given doesn't exist
*/ */
public function getArgument($name); public function getArgument($name);
@ -111,11 +114,13 @@ interface InputInterface
public function getOptions(); public function getOptions();
/** /**
* Gets an option by name. * Returns the option value for a given option name.
* *
* @param string $name The name of the option * @param string $name The option name
* *
* @return mixed * @return mixed The option value
*
* @throws InvalidArgumentException When option given doesn't exist
*/ */
public function getOption($name); public function getOption($name);

View File

@ -557,7 +557,7 @@ class Finder implements \IteratorAggregate, \Countable
* *
* This method implements the IteratorAggregate interface. * This method implements the IteratorAggregate interface.
* *
* @return \Iterator An iterator * @return \Iterator|SplFileInfo[] An iterator
* *
* @throws \LogicException if the in() method has not been called * @throws \LogicException if the in() method has not been called
*/ */

View File

@ -47,6 +47,8 @@ class ChoiceGroupView implements \IteratorAggregate
/** /**
* {@inheritdoc} * {@inheritdoc}
*
* @return ChoiceGroupView[]|ChoiceView[]
*/ */
public function getIterator() public function getIterator()
{ {

View File

@ -968,7 +968,7 @@ class Form implements \IteratorAggregate, FormInterface
/** /**
* Returns the iterator for this group. * Returns the iterator for this group.
* *
* @return \Traversable * @return \Traversable|FormInterface[]
*/ */
public function getIterator() public function getIterator()
{ {

View File

@ -231,6 +231,8 @@ class FormBuilder extends FormConfigBuilder implements \IteratorAggregate, FormB
/** /**
* {@inheritdoc} * {@inheritdoc}
*
* @return FormBuilderInterface[]
*/ */
public function getIterator() public function getIterator()
{ {

View File

@ -81,7 +81,7 @@ interface FormBuilderInterface extends \Traversable, \Countable, FormConfigBuild
/** /**
* Creates the form. * Creates the form.
* *
* @return Form The form * @return FormInterface The form
*/ */
public function getForm(); public function getForm();
} }

View File

@ -143,7 +143,7 @@ class FormView implements \ArrayAccess, \IteratorAggregate, \Countable
/** /**
* Returns an iterator to iterate over children (implements \IteratorAggregate). * Returns an iterator to iterate over children (implements \IteratorAggregate).
* *
* @return \ArrayIterator The iterator * @return \ArrayIterator|FormView[] The iterator
*/ */
public function getIterator() public function getIterator()
{ {

View File

@ -68,7 +68,7 @@ class ChoicesToValuesTransformerTest extends \PHPUnit_Framework_TestCase
$this->assertSame($out, $this->transformer->reverseTransform($in)); $this->assertSame($out, $this->transformer->reverseTransform($in));
// values are expected to be valid choices and stay the same // values are expected to be valid choices and stay the same
$inWithNull = array('0','1','2','3'); $inWithNull = array('0', '1', '2', '3');
$out[] = null; $out[] = null;
$this->assertSame($out, $this->transformerWithNull->reverseTransform($inWithNull)); $this->assertSame($out, $this->transformerWithNull->reverseTransform($inWithNull));

View File

@ -21,7 +21,6 @@ use Symfony\Component\Form\SubmitButtonBuilder;
use Symfony\Component\Validator\Constraints\NotNull; use Symfony\Component\Validator\Constraints\NotNull;
use Symfony\Component\Validator\Constraints\NotBlank; use Symfony\Component\Validator\Constraints\NotBlank;
use Symfony\Component\Validator\Constraints\Valid; use Symfony\Component\Validator\Constraints\Valid;
use Symfony\Component\Validator\ExecutionContextInterface;
use Symfony\Component\Validator\Tests\Constraints\AbstractConstraintValidatorTest; use Symfony\Component\Validator\Tests\Constraints\AbstractConstraintValidatorTest;
/** /**

View File

@ -12,7 +12,6 @@
namespace Symfony\Component\Form\Tests\Extension\Validator; namespace Symfony\Component\Form\Tests\Extension\Validator;
use Symfony\Component\Form\Extension\Validator\ValidatorExtension; use Symfony\Component\Form\Extension\Validator\ValidatorExtension;
use Symfony\Component\Validator\ValidatorInterface;
class ValidatorExtensionTest extends \PHPUnit_Framework_TestCase class ValidatorExtensionTest extends \PHPUnit_Framework_TestCase
{ {

View File

@ -68,7 +68,7 @@ class File extends \SplFileInfo
* mime_content_type() and the system binary "file" (in this order), depending on * mime_content_type() and the system binary "file" (in this order), depending on
* which of those are available. * which of those are available.
* *
* @return string|null The guessed mime type (i.e. "application/pdf") * @return string|null The guessed mime type (e.g. "application/pdf")
* *
* @see MimeTypeGuesser * @see MimeTypeGuesser
*/ */

View File

@ -377,12 +377,6 @@ class Response
$this->sendHeaders(); $this->sendHeaders();
$this->sendContent(); $this->sendContent();
if (function_exists('fastcgi_finish_request')) {
fastcgi_finish_request();
} elseif ('cli' !== PHP_SAPI) {
static::closeOutputBuffers(0, true);
}
return $this; return $this;
} }

View File

@ -325,14 +325,8 @@ class PdoSessionHandler implements \SessionHandlerInterface
try { try {
// We use a single MERGE SQL query when supported by the database. // We use a single MERGE SQL query when supported by the database.
$mergeSql = $this->getMergeSql(); $mergeStmt = $this->getMergeStatement($sessionId, $data, $maxlifetime);
if (null !== $mergeStmt) {
if (null !== $mergeSql) {
$mergeStmt = $this->pdo->prepare($mergeSql);
$mergeStmt->bindParam(':id', $sessionId, \PDO::PARAM_STR);
$mergeStmt->bindParam(':data', $data, \PDO::PARAM_LOB);
$mergeStmt->bindParam(':lifetime', $maxlifetime, \PDO::PARAM_INT);
$mergeStmt->bindValue(':time', time(), \PDO::PARAM_INT);
$mergeStmt->execute(); $mergeStmt->execute();
return true; return true;
@ -510,8 +504,9 @@ class PdoSessionHandler implements \SessionHandlerInterface
$selectSql = $this->getSelectSql(); $selectSql = $this->getSelectSql();
$selectStmt = $this->pdo->prepare($selectSql); $selectStmt = $this->pdo->prepare($selectSql);
$selectStmt->bindParam(':id', $sessionId, \PDO::PARAM_STR); $selectStmt->bindParam(':id', $sessionId, \PDO::PARAM_STR);
$selectStmt->execute();
do {
$selectStmt->execute();
$sessionRows = $selectStmt->fetchAll(\PDO::FETCH_NUM); $sessionRows = $selectStmt->fetchAll(\PDO::FETCH_NUM);
if ($sessionRows) { if ($sessionRows) {
@ -540,17 +535,12 @@ class PdoSessionHandler implements \SessionHandlerInterface
// Catch duplicate key error because other connection created the session already. // Catch duplicate key error because other connection created the session already.
// It would only not be the case when the other connection destroyed the session. // It would only not be the case when the other connection destroyed the session.
if (0 === strpos($e->getCode(), '23')) { if (0 === strpos($e->getCode(), '23')) {
// Retrieve finished session data written by concurrent connection. SELECT // Retrieve finished session data written by concurrent connection by restarting the loop.
// FOR UPDATE is necessary to avoid deadlock of connection that starts reading // We have to start a new transaction as a failed query will mark the current transaction as
// before we write (transform intention to real lock). // aborted in PostgreSQL and disallow further queries within it.
$selectStmt->execute(); $this->rollback();
$sessionRows = $selectStmt->fetchAll(\PDO::FETCH_NUM); $this->beginTransaction();
continue;
if ($sessionRows) {
return is_resource($sessionRows[0][0]) ? stream_get_contents($sessionRows[0][0]) : $sessionRows[0][0];
}
return '';
} }
throw $e; throw $e;
@ -558,6 +548,7 @@ class PdoSessionHandler implements \SessionHandlerInterface
} }
return ''; return '';
} while (true);
} }
/** /**
@ -653,32 +644,64 @@ class PdoSessionHandler implements \SessionHandlerInterface
} }
/** /**
* Returns a merge/upsert (i.e. insert or update) SQL query when supported by the database for writing session data. * Returns a merge/upsert (i.e. insert or update) statement when supported by the database for writing session data.
* *
* @return string|null The SQL string or null when not supported * @param string $sessionId Session ID
* @param string $data Encoded session data
* @param int $maxlifetime session.gc_maxlifetime
*
* @return \PDOStatement|null The merge statement or null when not supported
*/ */
private function getMergeSql() private function getMergeStatement($sessionId, $data, $maxlifetime)
{ {
$mergeSql = null;
switch (true) { switch (true) {
case 'mysql' === $this->driver: case 'mysql' === $this->driver:
return "INSERT INTO $this->table ($this->idCol, $this->dataCol, $this->lifetimeCol, $this->timeCol) VALUES (:id, :data, :lifetime, :time) ". $mergeSql = "INSERT INTO $this->table ($this->idCol, $this->dataCol, $this->lifetimeCol, $this->timeCol) VALUES (:id, :data, :lifetime, :time) ".
"ON DUPLICATE KEY UPDATE $this->dataCol = VALUES($this->dataCol), $this->lifetimeCol = VALUES($this->lifetimeCol), $this->timeCol = VALUES($this->timeCol)"; "ON DUPLICATE KEY UPDATE $this->dataCol = VALUES($this->dataCol), $this->lifetimeCol = VALUES($this->lifetimeCol), $this->timeCol = VALUES($this->timeCol)";
break;
case 'oci' === $this->driver: case 'oci' === $this->driver:
// DUAL is Oracle specific dummy table // DUAL is Oracle specific dummy table
return "MERGE INTO $this->table USING DUAL ON ($this->idCol = :id) ". $mergeSql = "MERGE INTO $this->table USING DUAL ON ($this->idCol = ?) ".
"WHEN NOT MATCHED THEN INSERT ($this->idCol, $this->dataCol, $this->lifetimeCol, $this->timeCol) VALUES (:id, :data, :lifetime, :time) ". "WHEN NOT MATCHED THEN INSERT ($this->idCol, $this->dataCol, $this->lifetimeCol, $this->timeCol) VALUES (?, ?, ?, ?) ".
"WHEN MATCHED THEN UPDATE SET $this->dataCol = :data, $this->lifetimeCol = :lifetime, $this->timeCol = :time"; "WHEN MATCHED THEN UPDATE SET $this->dataCol = ?, $this->lifetimeCol = ?, $this->timeCol = ?";
break;
case 'sqlsrv' === $this->driver && version_compare($this->pdo->getAttribute(\PDO::ATTR_SERVER_VERSION), '10', '>='): case 'sqlsrv' === $this->driver && version_compare($this->pdo->getAttribute(\PDO::ATTR_SERVER_VERSION), '10', '>='):
// MERGE is only available since SQL Server 2008 and must be terminated by semicolon // MERGE is only available since SQL Server 2008 and must be terminated by semicolon
// It also requires HOLDLOCK according to http://weblogs.sqlteam.com/dang/archive/2009/01/31/UPSERT-Race-Condition-With-MERGE.aspx // It also requires HOLDLOCK according to http://weblogs.sqlteam.com/dang/archive/2009/01/31/UPSERT-Race-Condition-With-MERGE.aspx
return "MERGE INTO $this->table WITH (HOLDLOCK) USING (SELECT 1 AS dummy) AS src ON ($this->idCol = :id) ". $mergeSql = "MERGE INTO $this->table WITH (HOLDLOCK) USING (SELECT 1 AS dummy) AS src ON ($this->idCol = ?) ".
"WHEN NOT MATCHED THEN INSERT ($this->idCol, $this->dataCol, $this->lifetimeCol, $this->timeCol) VALUES (:id, :data, :lifetime, :time) ". "WHEN NOT MATCHED THEN INSERT ($this->idCol, $this->dataCol, $this->lifetimeCol, $this->timeCol) VALUES (?, ?, ?, ?) ".
"WHEN MATCHED THEN UPDATE SET $this->dataCol = :data, $this->lifetimeCol = :lifetime, $this->timeCol = :time;"; "WHEN MATCHED THEN UPDATE SET $this->dataCol = ?, $this->lifetimeCol = ?, $this->timeCol = ?;";
break;
case 'sqlite' === $this->driver: case 'sqlite' === $this->driver:
return "INSERT OR REPLACE INTO $this->table ($this->idCol, $this->dataCol, $this->lifetimeCol, $this->timeCol) VALUES (:id, :data, :lifetime, :time)"; $mergeSql = "INSERT OR REPLACE INTO $this->table ($this->idCol, $this->dataCol, $this->lifetimeCol, $this->timeCol) VALUES (:id, :data, :lifetime, :time)";
break;
case 'pgsql' === $this->driver && version_compare($this->pdo->getAttribute(\PDO::ATTR_SERVER_VERSION), '9.5', '>='): case 'pgsql' === $this->driver && version_compare($this->pdo->getAttribute(\PDO::ATTR_SERVER_VERSION), '9.5', '>='):
return "INSERT INTO $this->table ($this->idCol, $this->dataCol, $this->lifetimeCol, $this->timeCol) VALUES (:id, :data, :lifetime, :time) ". $mergeSql = "INSERT INTO $this->table ($this->idCol, $this->dataCol, $this->lifetimeCol, $this->timeCol) VALUES (:id, :data, :lifetime, :time) ".
"ON CONFLICT ($this->idCol) DO UPDATE SET ($this->dataCol, $this->lifetimeCol, $this->timeCol) = (EXCLUDED.$this->dataCol, EXCLUDED.$this->lifetimeCol, EXCLUDED.$this->timeCol)"; "ON CONFLICT ($this->idCol) DO UPDATE SET ($this->dataCol, $this->lifetimeCol, $this->timeCol) = (EXCLUDED.$this->dataCol, EXCLUDED.$this->lifetimeCol, EXCLUDED.$this->timeCol)";
break;
}
if (null !== $mergeSql) {
$mergeStmt = $this->pdo->prepare($mergeSql);
if ('sqlsrv' === $this->driver || 'oci' === $this->driver) {
$mergeStmt->bindParam(1, $sessionId, \PDO::PARAM_STR);
$mergeStmt->bindParam(2, $sessionId, \PDO::PARAM_STR);
$mergeStmt->bindParam(3, $data, \PDO::PARAM_LOB);
$mergeStmt->bindParam(4, $maxlifetime, \PDO::PARAM_INT);
$mergeStmt->bindValue(5, time(), \PDO::PARAM_INT);
$mergeStmt->bindParam(6, $data, \PDO::PARAM_LOB);
$mergeStmt->bindParam(7, $maxlifetime, \PDO::PARAM_INT);
$mergeStmt->bindValue(8, time(), \PDO::PARAM_INT);
} else {
$mergeStmt->bindParam(':id', $sessionId, \PDO::PARAM_STR);
$mergeStmt->bindParam(':data', $data, \PDO::PARAM_LOB);
$mergeStmt->bindParam(':lifetime', $maxlifetime, \PDO::PARAM_INT);
$mergeStmt->bindValue(':time', time(), \PDO::PARAM_INT);
}
return $mergeStmt;
} }
} }

View File

@ -362,4 +362,8 @@ class MockPdo extends \PDO
public function beginTransaction() public function beginTransaction()
{ {
} }
public function rollBack()
{
}
} }

View File

@ -134,6 +134,14 @@ abstract class Kernel implements KernelInterface, TerminableInterface
} }
if ($this->getHttpKernel() instanceof TerminableInterface) { if ($this->getHttpKernel() instanceof TerminableInterface) {
if (!$this->debug) {
if (function_exists('fastcgi_finish_request')) {
fastcgi_finish_request();
} elseif ('cli' !== PHP_SAPI) {
Response::closeOutputBuffers(0, true);
}
}
$this->getHttpKernel()->terminate($request, $response); $this->getHttpKernel()->terminate($request, $response);
} }
} }

View File

@ -1153,7 +1153,8 @@ class ProcessTest extends \PHPUnit_Framework_TestCase
/** /**
* @dataProvider provideVariousIncrementals * @dataProvider provideVariousIncrementals
*/ */
public function testIncrementalOutputDoesNotRequireAnotherCall($stream, $method) { public function testIncrementalOutputDoesNotRequireAnotherCall($stream, $method)
{
$process = $this->getProcess(self::$phpBin.' -r '.escapeshellarg('$n = 0; while ($n < 3) { file_put_contents(\''.$stream.'\', $n, 1); $n++; usleep(1000); }'), null, null, null, null); $process = $this->getProcess(self::$phpBin.' -r '.escapeshellarg('$n = 0; while ($n < 3) { file_put_contents(\''.$stream.'\', $n, 1); $n++; usleep(1000); }'), null, null, null, null);
$process->start(); $process->start();
$result = ''; $result = '';
@ -1168,7 +1169,8 @@ class ProcessTest extends \PHPUnit_Framework_TestCase
$process->stop(); $process->stop();
} }
public function provideVariousIncrementals() { public function provideVariousIncrementals()
{
return array( return array(
array('php://stdout', 'getIncrementalOutput'), array('php://stdout', 'getIncrementalOutput'),
array('php://stderr', 'getIncrementalErrorOutput'), array('php://stderr', 'getIncrementalErrorOutput'),

View File

@ -7,6 +7,22 @@ CHANGELOG
* allowed specifying a directory to recursively load all routing configuration files it contains * allowed specifying a directory to recursively load all routing configuration files it contains
* Added ObjectRouteLoader and ServiceRouteLoader that allow routes to be loaded * Added ObjectRouteLoader and ServiceRouteLoader that allow routes to be loaded
by calling a method on an object/service. by calling a method on an object/service.
* [DEPRECATION] Deprecated the hardcoded value for the `$referenceType` argument of the `UrlGeneratorInterface::generate` method.
Use the constants defined in the `UrlGeneratorInterface` instead.
Before:
```php
$router->generate('blog_show', array('slug' => 'my-blog-post'), true);
```
After:
```php
use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
$router->generate('blog_show', array('slug' => 'my-blog-post'), UrlGeneratorInterface::ABSOLUTE_URL);
```
2.5.0 2.5.0
----- -----

View File

@ -26,7 +26,7 @@ class DumperCollection implements \IteratorAggregate
private $parent; private $parent;
/** /**
* @var (DumperCollection|DumperRoute)[] * @var DumperCollection[]|DumperRoute[]
*/ */
private $children = array(); private $children = array();
@ -38,7 +38,7 @@ class DumperCollection implements \IteratorAggregate
/** /**
* Returns the children routes and collections. * Returns the children routes and collections.
* *
* @return (DumperCollection|DumperRoute)[] Array of DumperCollection|DumperRoute * @return DumperCollection[]|DumperRoute[] Array of DumperCollection|DumperRoute
*/ */
public function all() public function all()
{ {
@ -76,7 +76,7 @@ class DumperCollection implements \IteratorAggregate
/** /**
* Returns an iterator over the children. * Returns an iterator over the children.
* *
* @return \Iterator The iterator * @return \Iterator|DumperCollection[]|DumperRoute[] The iterator
*/ */
public function getIterator() public function getIterator()
{ {

View File

@ -49,7 +49,7 @@ class RouteCollection implements \IteratorAggregate, \Countable
* *
* @see all() * @see all()
* *
* @return \ArrayIterator An \ArrayIterator object for iterating over routes * @return \ArrayIterator|Route[] An \ArrayIterator object for iterating over routes
*/ */
public function getIterator() public function getIterator()
{ {

View File

@ -249,7 +249,8 @@ XML;
$this->assertEquals($expected, $serializer->serialize($array, 'xml', $options)); $this->assertEquals($expected, $serializer->serialize($array, 'xml', $options));
} }
public function testEncodeTraversableWhenNormalizable() { public function testEncodeTraversableWhenNormalizable()
{
$this->encoder = new XmlEncoder(); $this->encoder = new XmlEncoder();
$serializer = new Serializer(array(new CustomNormalizer()), array('xml' => new XmlEncoder())); $serializer = new Serializer(array(new CustomNormalizer()), array('xml' => new XmlEncoder()));
$this->encoder->setSerializer($serializer); $this->encoder->setSerializer($serializer);
@ -261,7 +262,6 @@ XML;
XML; XML;
$this->assertEquals($expected, $serializer->serialize(new NormalizableTraversableDummy(), 'xml')); $this->assertEquals($expected, $serializer->serialize(new NormalizableTraversableDummy(), 'xml'));
} }
public function testDecode() public function testDecode()

View File

@ -285,12 +285,12 @@ class TranslatorTest extends \PHPUnit_Framework_TestCase
$resources = $translator->getCatalogue('en')->getResources(); $resources = $translator->getCatalogue('en')->getResources();
$this->assertCount(1, $resources); $this->assertCount(1, $resources);
$this->assertContains( __DIR__.DIRECTORY_SEPARATOR.'fixtures'.DIRECTORY_SEPARATOR.'resources.yml', $resources); $this->assertContains(__DIR__.DIRECTORY_SEPARATOR.'fixtures'.DIRECTORY_SEPARATOR.'resources.yml', $resources);
$resources = $translator->getCatalogue('en_GB')->getResources(); $resources = $translator->getCatalogue('en_GB')->getResources();
$this->assertCount(2, $resources); $this->assertCount(2, $resources);
$this->assertContains( __DIR__.DIRECTORY_SEPARATOR.'fixtures'.DIRECTORY_SEPARATOR.'empty.yml', $resources); $this->assertContains(__DIR__.DIRECTORY_SEPARATOR.'fixtures'.DIRECTORY_SEPARATOR.'empty.yml', $resources);
$this->assertContains( __DIR__.DIRECTORY_SEPARATOR.'fixtures'.DIRECTORY_SEPARATOR.'resources.yml', $resources); $this->assertContains(__DIR__.DIRECTORY_SEPARATOR.'fixtures'.DIRECTORY_SEPARATOR.'resources.yml', $resources);
} }
/** /**

View File

@ -107,6 +107,8 @@ class ConstraintViolationList implements \IteratorAggregate, ConstraintViolation
/** /**
* {@inheritdoc} * {@inheritdoc}
*
* @return \ArrayIterator|ConstraintViolationInterface[]
*/ */
public function getIterator() public function getIterator()
{ {