diff --git a/CHANGELOG-3.1.md b/CHANGELOG-3.1.md
new file mode 100644
index 0000000000..9b183cb3a8
--- /dev/null
+++ b/CHANGELOG-3.1.md
@@ -0,0 +1,136 @@
+CHANGELOG for 3.1.x
+===================
+
+This changelog references the relevant changes (bug and security fixes) done
+in 3.1 minor versions.
+
+To get the diff for a specific change, go to https://github.com/symfony/symfony/commit/XXX where XXX is the change hash
+To get the diff between two versions, go to https://github.com/symfony/symfony/compare/v3.1.0...v3.1.1
+
+* 3.1.0-BETA1 (2016-05-13)
+
+ * feature #18725 [Ldap] Added the possibility to configure all available Ldap options for connection (csarrazi)
+ * feature #18715 [FrameworkBundle] Default to Apcu+Filesystem cache chain (nicolas-grekas)
+ * feature #18184 [DomCrawler] Expose getter for uri (hason)
+ * feature #18654 [Bridge/Doctrine] Use better exception in the register mapping pass (dantleech)
+ * feature #18676 [HttpKernel] Add request method to logger messages (gnat42)
+ * feature #18716 [Cache] Add nonce based cache invalidation to ApcuAdapter (nicolas-grekas)
+ * feature #18762 [Translation] XLIFF Add `id` to meta data. (SpacePossum)
+ * feature #18689 [Cache] Add support for Predis, RedisArray and RedisCluster (nicolas-grekas)
+ * feature #18667 [FrameworkBundle] Semantic config for app/system/pool caches (tgalopin, nicolas-grekas)
+ * feature #18685 move event listener method type hint docs to @Event annotations defau… (Haehnchen)
+ * feature #18681 [Cache] Add DSN based Redis connection factory (nicolas-grekas)
+ * feature #18656 Updating the error message of an AuthenticationEntryPointInterface (weaverryan)
+ * feature #18069 [DoctrineBridge] deprecate `MergeDoctrineCollectionListener::onBind()` (HeahDude)
+ * feature #18492 [LDAP] Check whether an entry attribute exists (hiddewie)
+ * feature #18359 [Form] [DoctrineBridge] optimized LazyChoiceList and DoctrineChoiceLoader (HeahDude)
+ * feature #18357 [Form] Let `TextType` implement `DataTransformerInterface` (HeahDude)
+ * feature #18631 [FrameworkBundle] Add optional logger to cache pools (nicolas-grekas)
+ * feature #18597 [Cache] Add CacheItem::validateKey utility method (nicolas-grekas)
+ * feature #17660 [Serializer] Integrate the PropertyInfo Component (recursive denormalization and hardening) (mihai-stancu, dunglas)
+ * feature #18561 [FrameworkBundle] Fallback to default cache system in production for serializer (tgalopin)
+ * feature #18567 [FrameworkBundle][Serializer] Fix APC cache service name (tgalopin)
+ * feature #17959 [Serializer] Harden the ObjectNormalizer (dunglas)
+ * feature #18547 DX: better error message if factory class is empty (dbu)
+ * feature #18020 fix #17993 - Deprecated callable strings (hamza)
+ * feature #18487 [Cache] Add DoctrineProvider, for using PSR-6 pools in Doctrine Cache (nicolas-grekas)
+ * feature #18544 [FrameworkBundle] Fallback to default cache system in production for validation (tgalopin)
+ * feature #18416 [FrameworkBundle] Calls support for debug:container (JhonnyL)
+ * feature #18513 [Process] Turn getIterator() args to flags & add ITER_SKIP_OUT/ERR modes (nicolas-grekas)
+ * feature #18371 [FrameworkBundle] integrate the Cache component (xabbuh, nicolas-grekas)
+ * feature #18440 Add the kernel.controller_arguments event (stof)
+ * feature #18308 Added an ArgumentResolver with clean extension point (iltar, HeahDude)
+ * feature #18414 [Process] Implement IteratorAggregate to stream output (nicolas-grekas)
+ * feature #18144 [DI] Only rebuild autowiring cache when actually needed (weaverryan)
+ * feature #18386 [Process] Add InputStream to seamlessly feed running processes (nicolas-grekas)
+ * feature #18167 [DependencyInjection] Fix a limitation of the PhpDumper (Ener-Getick)
+ * feature #18387 [DX] [LDAP] Added default service name for the Security component's Ldap providers (csarrazi)
+ * feature #18290 [Translation] deprecate the backup feature (xabbuh)
+ * feature #18036 [Serializer] XmlEncoder: Make load flags configurable (dunglas)
+ * feature #17589 [WebProfilerBundle] [DX] Feature allow forward and redirection detection in wdt (HeahDude)
+ * feature #18260 Add Inflector component (from StringUtil of PropertyAccess) (teohhanhui)
+ * feature #18356 [FrameworkBundle] Deprecated form types as services (HeahDude)
+ * feature #17458 Add strict image validation (Koc)
+ * feature #18350 [Process] Accept Traversable input (nicolas-grekas)
+ * feature #18135 [Security] Deprecate onAuthenticationSuccess() (weaverryan)
+ * feature #18294 [Yaml] dump non UTF-8 encoded strings as binary data (xabbuh)
+ * feature #18215 [Cache] Add a Chain adapter (dunglas, nicolas-grekas)
+ * feature #18242 [FrameworkBundle][TwigBundle] Make EngineInterface autowirable (dunglas)
+ * feature #18197 Make Request::isFromTrustedProxy() public. (Peter Bex)
+ * feature #18211 [Security] Use auth trust resolver to determine anonymous in ContextListener (WouterJ)
+ * feature #18232 [Bridge\PhpUnit] Add "disabled" mode to SYMFONY_DEPRECATIONS_HELPER (nicolas-grekas)
+ * feature #18181 [PhpUnitBridge] Mock DNS functions (nicolas-grekas)
+ * feature #18176 [Cache] Restrict flushes to namespace scopes (nicolas-grekas)
+ * feature #18172 [Cache] Redis adapter (gcds, nicolas-grekas)
+ * feature #18101 [Console] Allow to register commands privately (Ener-Getick)
+ * feature #18143 [DomCrawler] Exposed getter for baseHref (AAstakhov)
+ * feature #18034 [FrameworkBundle] Deprecate absolute template paths (jakzal)
+ * feature #18105 [HttpFoundation] Add support for sending raw cookies in the response (jakzal)
+ * feature #17255 [Console] ApplicationTester - test stdout and stderr (SpacePossum)
+ * feature #18024 [Cache] Add namespace handling to all adapters (nicolas-grekas)
+ * feature #17734 [Cache] Count cache hits/misses in ProxyAdapter (nicolas-grekas)
+ * feature #17887 Show more information in the security profiler (javiereguiluz)
+ * feature #17642 [FrameworkBundle] [DX] Add `Controller::json` method to make it easy to send json (mcfedr)
+ * feature #17484 [FrameworkBundle][DX] Add Levenshtein suggesters to AbstractConfigCommand (kix)
+ * feature #17690 [FrameworkBundle] Use canBeEnabled() instead of canBeUnset() for consistency (Ener-Getick)
+ * feature #17714 Adding new TargetPathTrait to get/set the authentication "target_path" (weaverryan)
+ * feature #17852 Improved the logger panel when the log context is very long (javiereguiluz)
+ * feature #17761 [Console] Add non-auto column width functionality (akeeman)
+ * feature #17943 [Yaml] option to dump multi line strings as scalar blocks (xabbuh)
+ * feature #17553 [Validator] Added a format option to the DateTime constraint. (dosten)
+ * feature #17728 [Yaml] add option to dump objects as maps (xabbuh)
+ * feature #17863 [Yaml] add support for parsing the !!binary tag (xabbuh)
+ * feature #17738 [PropertyAccess] Throw an InvalidArgumentException when the type do not match (dunglas)
+ * feature #17531 [PropertyInfo] Use last version of reflection docblock (joelwurtz)
+ * feature #17782 Support autowiring for Doctrine\Common\Annotations\Reader (maryo)
+ * feature #17603 [Serializer] Add a normalizer that support JsonSerializable objects (mcfedr)
+ * feature #17630 [FrameworkBundle] Register the DateTimeNormalizer (dunglas)
+ * feature #17631 [FrameworkBundle] Register the DataUriNormalizer (dunglas)
+ * feature #17545 [Serializer] Add normalizer / denormalizer awarness (joelwurtz)
+ * feature #17877 [DependencyInjection] Improving autowiring error messages (weaverryan)
+ * feature #17732 [DEPRECATION] : deprecated support for Traversable in method ResizeFormListener::PreSubmit (ybensacq)
+ * feature #17721 [Cache] Add FilesystemAdapter (nicolas-grekas)
+ * feature #17836 [Yaml] support to parse and dump DateTime objects (xabbuh)
+ * feature #17809 [Yaml] deprecate starting plain scalars with characters (xabbuh)
+ * feature #17817 [Ldap] Add write support for the Ldap component (csarrazi)
+ * feature #17560 [Ldap] Improving the LDAP component (csarrazi)
+ * feature #17726 [FrameworkBundle] Improve debug:container command (voronkovich)
+ * feature #17743 [Yaml] dumper flag for enabling exceptions on invalid type (xabbuh)
+ * feature #17746 [Yaml] deprecate the Dumper::setIndentation() method (xabbuh)
+ * feature #17730 [Yaml] introduce flags to customize the parser behavior (xabbuh)
+ * feature #17125 Webprofiler add status code to search form (oktapodia)
+ * feature #17705 [TwigBridge] deprecate the boolean object support trigger (xabbuh)
+ * feature #17578 [Yaml] dump customization option with dumper flags (xabbuh)
+ * feature #17585 [DomCrawler] Abstract URI logic and crawl images (valeriangalliat)
+ * feature #17654 [Cache] Don't clone, serialize (nicolas-grekas)
+ * feature #16947 [FrameworkBundle] PropertyInfo: register the SerializerExtractor (dunglas)
+ * feature #17611 [HttpKernel] Deprecate passing objects as URI attributes to the ESI and SSI renderers (jakzal)
+ * feature #14288 [Console] Add getters for Application::$autoExit and $catchExceptions (VasekPurchart)
+ * feature #17504 [Console] Show code when an exception is thrown (maidmaid)
+ * feature #17540 [WebProfilerBundle] Add HTTP return code in the Ajax request list table (kucharovic)
+ * feature #17446 [Serializer] Add PSR-6 adapter (dunglas)
+ * feature #16917 [PropertyInfo] Cache support (dunglas)
+ * feature #17532 [Asset] Version as service (ewgRa)
+ * feature #17440 [Validator] Add a PSR-6 adapter (dunglas)
+ * feature #17113 [Serializer] Add a MaxDepth option (dunglas)
+ * feature #17530 [Cache] Handle and log errors properly (nicolas-grekas)
+ * feature #17522 [Cache] Use generator in ArrayAdapter (gcds)
+ * feature #16164 [Serializer] Add a data: URI normalizer (dunglas)
+ * feature #15279 Added {{ value }} message placeholder to UniqueEntityValidator (jperovic)
+ * feature #16652 [console] Add truncate method to FormatterHelper (mheki)
+ * feature #17438 [Cache] Allow and use generators in AbstractAdapter (nicolas-grekas)
+ * feature #17111 [HttpKernel] added a setter for the headers property in the HttpException (smatyas)
+ * feature #17132 [DependencyInjection] Properly ignore invalid reference arguments in collection arguments (ogizanagi)
+ * feature #17427 [Process] Allow a callback whenever the output is disabled (romainneutron)
+ * feature #17327 Added support links to exception and toolbar (peterrehm)
+ * feature #16909 Allows access to payload in callback validator (conradkleinespel)
+ * feature #17402 [Profiler] make it possible to omit the link var (xabbuh)
+ * feature #17411 [Serializer] Add a new DateTime normalizer (dunglas)
+ * feature #17462 [Yaml] deprecate parsing the !!php/object tag (xabbuh)
+ * feature #17408 [Cache] Symfony PSR-6 implementation (nicolas-grekas)
+ * feature #17323 [DependencyInjection] Deprecate unsupported attributes/elements for alias (Ener-Getick)
+ * feature #17305 [VarDumper] Add flags to allow fine tuning dumps representation (nicolas-grekas)
+ * feature #17318 [HttpFoundation] Allow to get all the mime types associated to a format in the Request (Ener-Getick)
+ * feature #17133 [DependencyInjection] Make YamlFileLoader raise a deprecation notice if a service definition contains unsupported keywords. (hhamon)
+ * feature #17191 [Serializer] Move the normalization logic in an abstract class (dunglas)
+ * feature #16994 [Form] Deprecate the "choices_as_values" option of ChoiceType (nicolas-grekas)
diff --git a/UPGRADE-3.0.md b/UPGRADE-3.0.md
index 8925b91189..8c509b36f0 100644
--- a/UPGRADE-3.0.md
+++ b/UPGRADE-3.0.md
@@ -398,8 +398,11 @@ UPGRADE FROM 2.x to 3.0
```
- * The `ChoiceToBooleanArrayTransformer`, `ChoicesToBooleanArrayTransformer`,
- `FixRadioInputListener`, and `FixCheckboxInputListener` classes were removed.
+ * The `max_length` option was removed. Use the `attr` option instead by setting it to
+ an `array` with a `maxlength` key.
+
+ * The `ChoiceToBooleanArrayTransformer`, `ChoicesToBooleanArrayTransformer`,
+ `FixRadioInputListener`, and `FixCheckboxInputListener` classes were removed.
* The `choice_list` option of `ChoiceType` was removed.
@@ -636,6 +639,11 @@ UPGRADE FROM 2.x to 3.0
be removed in Symfony 3.0. Use the `debug:config`, `debug:container`,
`debug:router`, `debug:translation` and `lint:yaml` commands instead.
+ * The base `Controller`class is now abstract.
+
+ * The visibility of all methods of the base `Controller` class has been changed from
+ `public` to `protected`.
+
* The `getRequest` method of the base `Controller` class has been deprecated
since Symfony 2.4 and must be therefore removed in 3.0. The only reliable
way to get the `Request` object is to inject it in the action method.
@@ -1737,8 +1745,7 @@ UPGRADE FROM 2.x to 3.0
### WebProfiler
- * The `profiler:import` and `profiler:export` commands have been deprecated and
- will be removed in 3.0.
+ * The `profiler:import` and `profiler:export` commands have been removed.
* All the profiler storages different than `FileProfilerStorage` have been
removed. The removed classes are:
diff --git a/UPGRADE-3.1.md b/UPGRADE-3.1.md
index fffb06bad9..134dfa4e5d 100644
--- a/UPGRADE-3.1.md
+++ b/UPGRADE-3.1.md
@@ -202,7 +202,7 @@ Yaml
After:
```php
- Yaml::dump(array('foo' => new A(), 'bar' => 1), 0, 0, false, Yaml::DUMP_OBJECT);
+ Yaml::dump(array('foo' => new A(), 'bar' => 1), 0, 0, Yaml::DUMP_OBJECT);
```
* The `!!php/object` tag to indicate dumped PHP objects has been deprecated
diff --git a/src/Symfony/Bundle/FrameworkBundle/Command/ServerStatusCommand.php b/src/Symfony/Bundle/FrameworkBundle/Command/ServerStatusCommand.php
index b6ec558701..d7cb9e7d08 100644
--- a/src/Symfony/Bundle/FrameworkBundle/Command/ServerStatusCommand.php
+++ b/src/Symfony/Bundle/FrameworkBundle/Command/ServerStatusCommand.php
@@ -13,6 +13,7 @@ namespace Symfony\Bundle\FrameworkBundle\Command;
use Symfony\Component\Console\Input\InputArgument;
use Symfony\Component\Console\Input\InputInterface;
+use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\Console\Style\SymfonyStyle;
@@ -32,6 +33,7 @@ class ServerStatusCommand extends ServerCommand
$this
->setDefinition(array(
new InputArgument('address', InputArgument::OPTIONAL, 'Address:port', '127.0.0.1:8000'),
+ new InputOption('port', 'p', InputOption::VALUE_REQUIRED, 'Address port number', '8000'),
))
->setName('server:status')
->setDescription('Outputs the status of the built-in web server for the given address')
@@ -46,6 +48,10 @@ class ServerStatusCommand extends ServerCommand
$io = new SymfonyStyle($input, $output);
$address = $input->getArgument('address');
+ if (false === strpos($address, ':')) {
+ $address = $address.':'.$input->getOption('port');
+ }
+
// remove an orphaned lock file
if (file_exists($this->getLockFile($address)) && !$this->isServerRunning($address)) {
unlink($this->getLockFile($address));
diff --git a/src/Symfony/Bundle/FrameworkBundle/Controller/ControllerNameParser.php b/src/Symfony/Bundle/FrameworkBundle/Controller/ControllerNameParser.php
index 873c736841..374d0eba10 100644
--- a/src/Symfony/Bundle/FrameworkBundle/Controller/ControllerNameParser.php
+++ b/src/Symfony/Bundle/FrameworkBundle/Controller/ControllerNameParser.php
@@ -142,6 +142,7 @@ class ControllerNameParser
$lev = levenshtein($nonExistentBundleName, $bundleName);
if ($lev <= strlen($nonExistentBundleName) / 3 && ($alternative === null || $lev < $shortest)) {
$alternative = $bundleName;
+ $shortest = $lev;
}
}
diff --git a/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/FrameworkExtension.php b/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/FrameworkExtension.php
index 84a5e3d094..c434cac057 100644
--- a/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/FrameworkExtension.php
+++ b/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/FrameworkExtension.php
@@ -1037,9 +1037,9 @@ class FrameworkExtension extends Extension
private function registerCacheConfiguration(array $config, ContainerBuilder $container, XmlFileLoader $loader)
{
- $nonce = substr(str_replace('/', '-', base64_encode(md5(uniqid(mt_rand(), true), true))), 0, -2);
- $container->getDefinition('cache.adapter.apcu')->replaceArgument(2, $nonce);
- $container->getDefinition('cache.adapter.system')->replaceArgument(2, $nonce);
+ $version = substr(str_replace('/', '-', base64_encode(md5(uniqid(mt_rand(), true), true))), 0, -2);
+ $container->getDefinition('cache.adapter.apcu')->replaceArgument(2, $version);
+ $container->getDefinition('cache.adapter.system')->replaceArgument(2, $version);
$container->getDefinition('cache.adapter.filesystem')->replaceArgument(2, $config['directory']);
foreach (array('doctrine', 'psr6', 'redis') as $name) {
diff --git a/src/Symfony/Bundle/FrameworkBundle/Resources/config/cache.xml b/src/Symfony/Bundle/FrameworkBundle/Resources/config/cache.xml
index 931b74a58d..c438a1a66f 100644
--- a/src/Symfony/Bundle/FrameworkBundle/Resources/config/cache.xml
+++ b/src/Symfony/Bundle/FrameworkBundle/Resources/config/cache.xml
@@ -28,7 +28,7 @@
-
+
%kernel.cache_dir%/pools
@@ -38,7 +38,7 @@
-
+
diff --git a/src/Symfony/Bundle/FrameworkBundle/Tests/Controller/ControllerNameParserTest.php b/src/Symfony/Bundle/FrameworkBundle/Tests/Controller/ControllerNameParserTest.php
index 4718c1eb0b..0fe47b0908 100644
--- a/src/Symfony/Bundle/FrameworkBundle/Tests/Controller/ControllerNameParserTest.php
+++ b/src/Symfony/Bundle/FrameworkBundle/Tests/Controller/ControllerNameParserTest.php
@@ -59,8 +59,8 @@ class ControllerNameParserTest extends TestCase
{
$parser = $this->createParser();
- $this->assertEquals('FooBundle:Default:index', $parser->build('TestBundle\FooBundle\Controller\DefaultController::indexAction'), '->parse() converts a class::method string to a short a:b:c notation string');
- $this->assertEquals('FooBundle:Sub\Default:index', $parser->build('TestBundle\FooBundle\Controller\Sub\DefaultController::indexAction'), '->parse() converts a class::method string to a short a:b:c notation string');
+ $this->assertEquals('FoooooBundle:Default:index', $parser->build('TestBundle\FooBundle\Controller\DefaultController::indexAction'), '->parse() converts a class::method string to a short a:b:c notation string');
+ $this->assertEquals('FoooooBundle:Sub\Default:index', $parser->build('TestBundle\FooBundle\Controller\Sub\DefaultController::indexAction'), '->parse() converts a class::method string to a short a:b:c notation string');
try {
$parser->build('TestBundle\FooBundle\Controller\DefaultController::index');
@@ -132,8 +132,9 @@ class ControllerNameParserTest extends TestCase
public function getInvalidBundleNameTests()
{
return array(
- array('FoodBundle:Default:index', 'FooBundle:Default:index'),
- array('CrazyBundle:Default:index', false),
+ 'Alternative will be found using levenshtein' => array('FoodBundle:Default:index', 'FooBundle:Default:index'),
+ 'Alternative will be found using partial match' => array('FabpotFooBund:Default:index', 'FabpotFooBundle:Default:index'),
+ 'Bundle does not exist at all' => array('CrazyBundle:Default:index', false),
);
}
@@ -162,6 +163,7 @@ class ControllerNameParserTest extends TestCase
$bundles = array(
'SensioFooBundle' => $this->getBundle('TestBundle\Fabpot\FooBundle', 'FabpotFooBundle'),
'SensioCmsFooBundle' => $this->getBundle('TestBundle\Sensio\Cms\FooBundle', 'SensioCmsFooBundle'),
+ 'FoooooBundle' => $this->getBundle('TestBundle\FooBundle', 'FoooooBundle'),
'FooBundle' => $this->getBundle('TestBundle\FooBundle', 'FooBundle'),
'FabpotFooBundle' => $this->getBundle('TestBundle\Fabpot\FooBundle', 'FabpotFooBundle'),
);
diff --git a/src/Symfony/Bundle/WebProfilerBundle/Resources/views/Profiler/base_js.html.twig b/src/Symfony/Bundle/WebProfilerBundle/Resources/views/Profiler/base_js.html.twig
index c9103ae419..bd8213721e 100644
--- a/src/Symfony/Bundle/WebProfilerBundle/Resources/views/Profiler/base_js.html.twig
+++ b/src/Symfony/Bundle/WebProfilerBundle/Resources/views/Profiler/base_js.html.twig
@@ -82,6 +82,20 @@
requestStack = [],
+ extractHeaders = function(xhr, stackElement) {
+ // Here we avoid to call xhr.getResponseHeader in order to
+ // prevent polluting the console with CORS security errors
+ var allHeaders = xhr.getAllResponseHeaders();
+ var ret;
+
+ if (ret = allHeaders.match(/^x-debug-token:\s+(.*)$/im)) {
+ stackElement.profile = ret[1];
+ }
+ if (ret = allHeaders.match(/^x-debug-token-link:\s+(.*)$/im)) {
+ stackElement.profilerUrl = ret[1];
+ }
+ },
+
renderAjaxRequests = function() {
var requestCounter = document.querySelectorAll('.sf-toolbar-ajax-requests');
if (!requestCounter.length) {
@@ -255,8 +269,7 @@
stackElement.loading = false;
stackElement.error = self.status < 200 || self.status >= 400;
stackElement.statusCode = self.status;
- stackElement.profile = self.getResponseHeader("X-Debug-Token");
- stackElement.profilerUrl = self.getResponseHeader("X-Debug-Token-Link");
+ extractHeaders(self, stackElement);
Sfjs.renderAjaxRequests();
}
diff --git a/src/Symfony/Component/Cache/Adapter/AbstractAdapter.php b/src/Symfony/Component/Cache/Adapter/AbstractAdapter.php
index 8c753fb814..01207f54e6 100644
--- a/src/Symfony/Component/Cache/Adapter/AbstractAdapter.php
+++ b/src/Symfony/Component/Cache/Adapter/AbstractAdapter.php
@@ -68,7 +68,7 @@ abstract class AbstractAdapter implements AdapterInterface, LoggerAwareInterface
);
}
- public static function createSystemCache($namespace, $defaultLifetime, $nonce, $directory, LoggerInterface $logger = null)
+ public static function createSystemCache($namespace, $defaultLifetime, $version, $directory, LoggerInterface $logger = null)
{
$fs = new FilesystemAdapter($namespace, $defaultLifetime, $directory);
if (null !== $logger) {
@@ -78,7 +78,7 @@ abstract class AbstractAdapter implements AdapterInterface, LoggerAwareInterface
return $fs;
}
- $apcu = new ApcuAdapter($namespace, $defaultLifetime / 5, $nonce);
+ $apcu = new ApcuAdapter($namespace, $defaultLifetime / 5, $version);
if (null !== $logger) {
$apcu->setLogger($logger);
}
diff --git a/src/Symfony/Component/Cache/Adapter/ApcuAdapter.php b/src/Symfony/Component/Cache/Adapter/ApcuAdapter.php
index 35a4d987e3..a1c24a6350 100644
--- a/src/Symfony/Component/Cache/Adapter/ApcuAdapter.php
+++ b/src/Symfony/Component/Cache/Adapter/ApcuAdapter.php
@@ -24,7 +24,7 @@ class ApcuAdapter extends AbstractAdapter
return function_exists('apcu_fetch') && ini_get('apc.enabled') && !('cli' === PHP_SAPI && !ini_get('apc.enable_cli'));
}
- public function __construct($namespace = '', $defaultLifetime = 0, $nonce = null)
+ public function __construct($namespace = '', $defaultLifetime = 0, $version = null)
{
if (!static::isSupported()) {
throw new CacheException('APCu is not enabled');
@@ -34,12 +34,12 @@ class ApcuAdapter extends AbstractAdapter
}
parent::__construct($namespace, $defaultLifetime);
- if (null !== $nonce) {
- CacheItem::validateKey($nonce);
+ if (null !== $version) {
+ CacheItem::validateKey($version);
- if (!apcu_exists($nonce.':nonce'.$namespace)) {
+ if (!apcu_exists($version.':'.$namespace)) {
$this->clear($namespace);
- apcu_add($nonce.':nonce'.$namespace, null);
+ apcu_add($version.':'.$namespace, null);
}
}
}
diff --git a/src/Symfony/Component/Cache/Tests/Adapter/ApcuAdapterTest.php b/src/Symfony/Component/Cache/Tests/Adapter/ApcuAdapterTest.php
index 9dcbb5ba9d..1cd4269b45 100644
--- a/src/Symfony/Component/Cache/Tests/Adapter/ApcuAdapterTest.php
+++ b/src/Symfony/Component/Cache/Tests/Adapter/ApcuAdapterTest.php
@@ -44,7 +44,7 @@ class ApcuAdapterTest extends CachePoolTest
$this->assertFalse($item->isHit());
}
- public function testNonce()
+ public function testVersion()
{
$namespace = str_replace('\\', '.', __CLASS__);
diff --git a/src/Symfony/Component/Config/Resource/FileResource.php b/src/Symfony/Component/Config/Resource/FileResource.php
index f94640fffc..65a195f5d2 100644
--- a/src/Symfony/Component/Config/Resource/FileResource.php
+++ b/src/Symfony/Component/Config/Resource/FileResource.php
@@ -36,6 +36,10 @@ class FileResource implements SelfCheckingResourceInterface, \Serializable
{
$this->resource = realpath($resource);
+ if (false === $this->resource && file_exists($resource)) {
+ $this->resource = $resource;
+ }
+
if (false === $this->resource) {
throw new \InvalidArgumentException(sprintf('The file "%s" does not exist.', $resource));
}
diff --git a/src/Symfony/Component/Config/Tests/Resource/FileResourceTest.php b/src/Symfony/Component/Config/Tests/Resource/FileResourceTest.php
index 4151f66bc5..6a168e6351 100644
--- a/src/Symfony/Component/Config/Tests/Resource/FileResourceTest.php
+++ b/src/Symfony/Component/Config/Tests/Resource/FileResourceTest.php
@@ -21,7 +21,7 @@ class FileResourceTest extends \PHPUnit_Framework_TestCase
protected function setUp()
{
- $this->file = realpath(sys_get_temp_dir()).'/tmp.xml';
+ $this->file = sys_get_temp_dir().'/tmp.xml';
$this->time = time();
touch($this->file, $this->time);
$this->resource = new FileResource($this->file);
@@ -41,6 +41,12 @@ class FileResourceTest extends \PHPUnit_Framework_TestCase
$this->assertSame(realpath($this->file), $this->resource->getResource(), '->getResource() returns the path to the resource');
}
+ public function testGetResourceWithScheme()
+ {
+ $resource = new FileResource('file://'.$this->file);
+ $this->assertSame('file://'.$this->file, $resource->getResource(), '->getResource() returns the path to the schemed resource');
+ }
+
public function testToString()
{
$this->assertSame(realpath($this->file), (string) $this->resource);
diff --git a/src/Symfony/Component/Console/Helper/ProgressIndicator.php b/src/Symfony/Component/Console/Helper/ProgressIndicator.php
index ccf9771bcf..f90a85c291 100644
--- a/src/Symfony/Component/Console/Helper/ProgressIndicator.php
+++ b/src/Symfony/Component/Console/Helper/ProgressIndicator.php
@@ -76,42 +76,6 @@ class ProgressIndicator
$this->display();
}
- /**
- * Gets the current indicator message.
- *
- * @return string|null
- *
- * @internal for PHP 5.3 compatibility
- */
- public function getMessage()
- {
- return $this->message;
- }
-
- /**
- * Gets the progress bar start time.
- *
- * @return int The progress bar start time
- *
- * @internal for PHP 5.3 compatibility
- */
- public function getStartTime()
- {
- return $this->startTime;
- }
-
- /**
- * Gets the current animated indicator character.
- *
- * @return string
- *
- * @internal for PHP 5.3 compatibility
- */
- public function getCurrentValue()
- {
- return $this->indicatorValues[$this->indicatorCurrent % count($this->indicatorValues)];
- }
-
/**
* Starts the indicator output.
*
@@ -294,13 +258,13 @@ class ProgressIndicator
{
return array(
'indicator' => function (ProgressIndicator $indicator) {
- return $indicator->getCurrentValue();
+ return $indicator->indicatorValues[$indicator->indicatorCurrent % count($indicator->indicatorValues)];
},
'message' => function (ProgressIndicator $indicator) {
- return $indicator->getMessage();
+ return $indicator->message;
},
'elapsed' => function (ProgressIndicator $indicator) {
- return Helper::formatTime(time() - $indicator->getStartTime());
+ return Helper::formatTime(time() - $indicator->startTime);
},
'memory' => function () {
return Helper::formatMemory(memory_get_usage(true));
diff --git a/src/Symfony/Component/Debug/ErrorHandler.php b/src/Symfony/Component/Debug/ErrorHandler.php
index 5fdcd5cdb4..f4932fc82c 100644
--- a/src/Symfony/Component/Debug/ErrorHandler.php
+++ b/src/Symfony/Component/Debug/ErrorHandler.php
@@ -580,6 +580,8 @@ class ErrorHandler
}
} catch (\Exception $exception) {
// Handled below
+ } catch (\Throwable $exception) {
+ // Handled below
}
if ($error && $error['type'] &= E_PARSE | E_ERROR | E_CORE_ERROR | E_COMPILE_ERROR) {
diff --git a/src/Symfony/Component/DependencyInjection/Compiler/AutowirePass.php b/src/Symfony/Component/DependencyInjection/Compiler/AutowirePass.php
index 8e1b06e0ff..fdf0edcfb4 100644
--- a/src/Symfony/Component/DependencyInjection/Compiler/AutowirePass.php
+++ b/src/Symfony/Component/DependencyInjection/Compiler/AutowirePass.php
@@ -45,8 +45,8 @@ class AutowirePass implements CompilerPassInterface
$this->completeDefinition($id, $definition);
}
}
- } catch (\Error $e) {
} catch (\Exception $e) {
+ } catch (\Throwable $e) {
}
spl_autoload_unregister($throwingAutoloader);
@@ -283,7 +283,7 @@ class AutowirePass implements CompilerPassInterface
try {
$this->completeDefinition($argumentId, $argumentDefinition);
- } catch (\RuntimeException $e) {
+ } catch (RuntimeException $e) {
$classOrInterface = $typeHint->isInterface() ? 'interface' : 'class';
$message = sprintf('Unable to autowire argument of type "%s" for the service "%s". No services were found matching this %s and it cannot be auto-registered.', $typeHint->name, $id, $classOrInterface);
throw new RuntimeException($message, 0, $e);
diff --git a/src/Symfony/Component/DependencyInjection/Dumper/PhpDumper.php b/src/Symfony/Component/DependencyInjection/Dumper/PhpDumper.php
index 57b0f086c0..ce0336b3e4 100644
--- a/src/Symfony/Component/DependencyInjection/Dumper/PhpDumper.php
+++ b/src/Symfony/Component/DependencyInjection/Dumper/PhpDumper.php
@@ -542,6 +542,10 @@ class PhpDumper extends Dumper
return sprintf(" %s::%s(\$%s);\n", $this->dumpLiteralClass($class), $callable[1], $variableName);
}
+ if (0 === strpos($class, 'new ')) {
+ return sprintf(" (%s)->%s(\$%s);\n", $this->dumpValue($callable[0]), $callable[1], $variableName);
+ }
+
return sprintf(" call_user_func(array(%s, '%s'), \$%s);\n", $this->dumpValue($callable[0]), $callable[1], $variableName);
}
@@ -723,6 +727,10 @@ EOF;
return sprintf(" $return{$instantiation}%s::%s(%s);\n", $this->dumpLiteralClass($class), $callable[1], $arguments ? implode(', ', $arguments) : '');
}
+ if (0 === strpos($class, 'new ')) {
+ return sprintf(" $return{$instantiation}(%s)->%s(%s);\n", $this->dumpValue($callable[0]), $callable[1], $arguments ? implode(', ', $arguments) : '');
+ }
+
return sprintf(" $return{$instantiation}call_user_func(array(%s, '%s')%s);\n", $this->dumpValue($callable[0]), $callable[1], $arguments ? ', '.implode(', ', $arguments) : '');
}
diff --git a/src/Symfony/Component/DependencyInjection/Tests/Fixtures/containers/container9.php b/src/Symfony/Component/DependencyInjection/Tests/Fixtures/containers/container9.php
index 96f334fdd1..f499635604 100644
--- a/src/Symfony/Component/DependencyInjection/Tests/Fixtures/containers/container9.php
+++ b/src/Symfony/Component/DependencyInjection/Tests/Fixtures/containers/container9.php
@@ -78,6 +78,15 @@ $container
->register('configured_service', 'stdClass')
->setConfigurator(array(new Reference('configurator_service'), 'configureStdClass'))
;
+$container
+ ->register('configurator_service_simple', 'ConfClass')
+ ->addArgument('bar')
+ ->setPublic(false)
+;
+$container
+ ->register('configured_service_simple', 'stdClass')
+ ->setConfigurator(array(new Reference('configurator_service_simple'), 'configureStdClass'))
+;
$container
->register('decorated', 'stdClass')
;
@@ -111,5 +120,14 @@ $container
->register('service_from_static_method', 'Bar\FooClass')
->setFactory(array('Bar\FooClass', 'getInstance'))
;
+$container
+ ->register('factory_simple', 'SimpleFactoryClass')
+ ->addArgument('foo')
+ ->setPublic(false)
+;
+$container
+ ->register('factory_service_simple', 'Bar')
+ ->setFactory(array(new Reference('factory_simple'), 'getInstance'))
+;
return $container;
diff --git a/src/Symfony/Component/DependencyInjection/Tests/Fixtures/graphviz/services9.dot b/src/Symfony/Component/DependencyInjection/Tests/Fixtures/graphviz/services9.dot
index f6536980aa..3b24ef8ffb 100644
--- a/src/Symfony/Component/DependencyInjection/Tests/Fixtures/graphviz/services9.dot
+++ b/src/Symfony/Component/DependencyInjection/Tests/Fixtures/graphviz/services9.dot
@@ -14,6 +14,8 @@ digraph sc {
node_request [label="request\nRequest\n", shape=record, fillcolor="#eeeeee", style="filled"];
node_configurator_service [label="configurator_service\nConfClass\n", shape=record, fillcolor="#eeeeee", style="filled"];
node_configured_service [label="configured_service\nstdClass\n", shape=record, fillcolor="#eeeeee", style="filled"];
+ node_configurator_service_simple [label="configurator_service_simple\nConfClass\n", shape=record, fillcolor="#eeeeee", style="filled"];
+ node_configured_service_simple [label="configured_service_simple\nstdClass\n", shape=record, fillcolor="#eeeeee", style="filled"];
node_decorated [label="decorated\nstdClass\n", shape=record, fillcolor="#eeeeee", style="filled"];
node_decorator_service [label="decorator_service\nstdClass\n", shape=record, fillcolor="#eeeeee", style="filled"];
node_decorator_service_with_name [label="decorator_service_with_name\nstdClass\n", shape=record, fillcolor="#eeeeee", style="filled"];
@@ -22,6 +24,8 @@ digraph sc {
node_factory_service [label="factory_service\nBar\n", shape=record, fillcolor="#eeeeee", style="filled"];
node_new_factory_service [label="new_factory_service\nFooBarBaz\n", shape=record, fillcolor="#eeeeee", style="filled"];
node_service_from_static_method [label="service_from_static_method\nBar\\FooClass\n", shape=record, fillcolor="#eeeeee", style="filled"];
+ node_factory_simple [label="factory_simple\nSimpleFactoryClass\n", shape=record, fillcolor="#eeeeee", style="filled"];
+ node_factory_service_simple [label="factory_service_simple\nBar\n", shape=record, fillcolor="#eeeeee", style="filled"];
node_service_container [label="service_container\nSymfony\\Component\\DependencyInjection\\ContainerBuilder\n", shape=record, fillcolor="#9999ff", style="filled"];
node_foo2 [label="foo2\n\n", shape=record, fillcolor="#ff9999", style="filled"];
node_foo3 [label="foo3\n\n", shape=record, fillcolor="#ff9999", style="filled"];
diff --git a/src/Symfony/Component/DependencyInjection/Tests/Fixtures/php/services19.php b/src/Symfony/Component/DependencyInjection/Tests/Fixtures/php/services19.php
index cc2a18dcd1..6c56cfcebf 100644
--- a/src/Symfony/Component/DependencyInjection/Tests/Fixtures/php/services19.php
+++ b/src/Symfony/Component/DependencyInjection/Tests/Fixtures/php/services19.php
@@ -40,7 +40,7 @@ class ProjectServiceContainer extends Container
*/
protected function getServiceFromAnonymousFactoryService()
{
- return $this->services['service_from_anonymous_factory'] = call_user_func(array(new \Bar\FooClass(), 'getInstance'));
+ return $this->services['service_from_anonymous_factory'] = (new \Bar\FooClass())->getInstance();
}
/**
diff --git a/src/Symfony/Component/DependencyInjection/Tests/Fixtures/php/services9.php b/src/Symfony/Component/DependencyInjection/Tests/Fixtures/php/services9.php
index a29f7dd768..cb84452bca 100644
--- a/src/Symfony/Component/DependencyInjection/Tests/Fixtures/php/services9.php
+++ b/src/Symfony/Component/DependencyInjection/Tests/Fixtures/php/services9.php
@@ -28,12 +28,16 @@ class ProjectServiceContainer extends Container
'bar' => 'getBarService',
'baz' => 'getBazService',
'configurator_service' => 'getConfiguratorServiceService',
+ 'configurator_service_simple' => 'getConfiguratorServiceSimpleService',
'configured_service' => 'getConfiguredServiceService',
+ 'configured_service_simple' => 'getConfiguredServiceSimpleService',
'decorated' => 'getDecoratedService',
'decorator_service' => 'getDecoratorServiceService',
'decorator_service_with_name' => 'getDecoratorServiceWithNameService',
'deprecated_service' => 'getDeprecatedServiceService',
'factory_service' => 'getFactoryServiceService',
+ 'factory_service_simple' => 'getFactoryServiceSimpleService',
+ 'factory_simple' => 'getFactorySimpleService',
'foo' => 'getFooService',
'foo.baz' => 'getFoo_BazService',
'foo_bar' => 'getFooBarService',
@@ -104,6 +108,23 @@ class ProjectServiceContainer extends Container
return $instance;
}
+ /**
+ * Gets the 'configured_service_simple' service.
+ *
+ * This service is shared.
+ * This method always returns the same instance of the service.
+ *
+ * @return \stdClass A stdClass instance.
+ */
+ protected function getConfiguredServiceSimpleService()
+ {
+ $this->services['configured_service_simple'] = $instance = new \stdClass();
+
+ $this->get('configurator_service_simple')->configureStdClass($instance);
+
+ return $instance;
+ }
+
/**
* Gets the 'decorated' service.
*
@@ -173,6 +194,19 @@ class ProjectServiceContainer extends Container
return $this->services['factory_service'] = $this->get('foo.baz')->getInstance();
}
+ /**
+ * Gets the 'factory_service_simple' service.
+ *
+ * This service is shared.
+ * This method always returns the same instance of the service.
+ *
+ * @return \Bar A Bar instance.
+ */
+ protected function getFactoryServiceSimpleService()
+ {
+ return $this->services['factory_service_simple'] = $this->get('factory_simple')->getInstance();
+ }
+
/**
* Gets the 'foo' service.
*
@@ -334,6 +368,40 @@ class ProjectServiceContainer extends Container
return $instance;
}
+ /**
+ * Gets the 'configurator_service_simple' service.
+ *
+ * This service is shared.
+ * This method always returns the same instance of the service.
+ *
+ * This service is private.
+ * If you want to be able to request this service from the container directly,
+ * make it public, otherwise you might end up with broken code.
+ *
+ * @return \ConfClass A ConfClass instance.
+ */
+ protected function getConfiguratorServiceSimpleService()
+ {
+ return $this->services['configurator_service_simple'] = new \ConfClass('bar');
+ }
+
+ /**
+ * Gets the 'factory_simple' service.
+ *
+ * This service is shared.
+ * This method always returns the same instance of the service.
+ *
+ * This service is private.
+ * If you want to be able to request this service from the container directly,
+ * make it public, otherwise you might end up with broken code.
+ *
+ * @return \SimpleFactoryClass A SimpleFactoryClass instance.
+ */
+ protected function getFactorySimpleService()
+ {
+ return $this->services['factory_simple'] = new \SimpleFactoryClass('foo');
+ }
+
/**
* Gets the 'inlined' service.
*
diff --git a/src/Symfony/Component/DependencyInjection/Tests/Fixtures/php/services9_compiled.php b/src/Symfony/Component/DependencyInjection/Tests/Fixtures/php/services9_compiled.php
index 5386b12a99..4fd1ac90f3 100644
--- a/src/Symfony/Component/DependencyInjection/Tests/Fixtures/php/services9_compiled.php
+++ b/src/Symfony/Component/DependencyInjection/Tests/Fixtures/php/services9_compiled.php
@@ -30,10 +30,12 @@ class ProjectServiceContainer extends Container
'bar' => 'getBarService',
'baz' => 'getBazService',
'configured_service' => 'getConfiguredServiceService',
+ 'configured_service_simple' => 'getConfiguredServiceSimpleService',
'decorator_service' => 'getDecoratorServiceService',
'decorator_service_with_name' => 'getDecoratorServiceWithNameService',
'deprecated_service' => 'getDeprecatedServiceService',
'factory_service' => 'getFactoryServiceService',
+ 'factory_service_simple' => 'getFactoryServiceSimpleService',
'foo' => 'getFooService',
'foo.baz' => 'getFoo_BazService',
'foo_bar' => 'getFooBarService',
@@ -114,6 +116,23 @@ class ProjectServiceContainer extends Container
return $instance;
}
+ /**
+ * Gets the 'configured_service_simple' service.
+ *
+ * This service is shared.
+ * This method always returns the same instance of the service.
+ *
+ * @return \stdClass A stdClass instance.
+ */
+ protected function getConfiguredServiceSimpleService()
+ {
+ $this->services['configured_service_simple'] = $instance = new \stdClass();
+
+ (new \ConfClass('bar'))->configureStdClass($instance);
+
+ return $instance;
+ }
+
/**
* Gets the 'decorator_service' service.
*
@@ -170,6 +189,19 @@ class ProjectServiceContainer extends Container
return $this->services['factory_service'] = $this->get('foo.baz')->getInstance();
}
+ /**
+ * Gets the 'factory_service_simple' service.
+ *
+ * This service is shared.
+ * This method always returns the same instance of the service.
+ *
+ * @return \Bar A Bar instance.
+ */
+ protected function getFactoryServiceSimpleService()
+ {
+ return $this->services['factory_service_simple'] = (new \SimpleFactoryClass('foo'))->getInstance();
+ }
+
/**
* Gets the 'foo' service.
*
diff --git a/src/Symfony/Component/DependencyInjection/Tests/Fixtures/xml/services9.xml b/src/Symfony/Component/DependencyInjection/Tests/Fixtures/xml/services9.xml
index 4ddb8655c5..d3974c07b0 100644
--- a/src/Symfony/Component/DependencyInjection/Tests/Fixtures/xml/services9.xml
+++ b/src/Symfony/Component/DependencyInjection/Tests/Fixtures/xml/services9.xml
@@ -84,6 +84,12 @@
+
+ bar
+
+
+
+
@@ -103,6 +109,12 @@
+
+ foo
+
+
+
+
diff --git a/src/Symfony/Component/DependencyInjection/Tests/Fixtures/yaml/services9.yml b/src/Symfony/Component/DependencyInjection/Tests/Fixtures/yaml/services9.yml
index 6efeb37e74..4a97dcadff 100644
--- a/src/Symfony/Component/DependencyInjection/Tests/Fixtures/yaml/services9.yml
+++ b/src/Symfony/Component/DependencyInjection/Tests/Fixtures/yaml/services9.yml
@@ -67,6 +67,13 @@ services:
configured_service:
class: stdClass
configurator: ['@configurator_service', configureStdClass]
+ configurator_service_simple:
+ class: ConfClass
+ public: false
+ arguments: ['bar']
+ configured_service_simple:
+ class: stdClass
+ configurator: ['@configurator_service_simple', configureStdClass]
decorated:
class: stdClass
decorator_service:
@@ -93,5 +100,12 @@ services:
service_from_static_method:
class: Bar\FooClass
factory: [Bar\FooClass, getInstance]
+ factory_simple:
+ class: SimpleFactoryClass
+ public: false
+ arguments: ['foo']
+ factory_service_simple:
+ class: Bar
+ factory: ['@factory_simple', getInstance]
alias_for_foo: '@foo'
alias_for_alias: '@foo'
diff --git a/src/Symfony/Component/Serializer/Tests/Normalizer/ObjectNormalizerTest.php b/src/Symfony/Component/Serializer/Tests/Normalizer/ObjectNormalizerTest.php
index b04d09bf1f..5d91a9fd1e 100644
--- a/src/Symfony/Component/Serializer/Tests/Normalizer/ObjectNormalizerTest.php
+++ b/src/Symfony/Component/Serializer/Tests/Normalizer/ObjectNormalizerTest.php
@@ -312,6 +312,19 @@ class ObjectNormalizerTest extends \PHPUnit_Framework_TestCase
);
}
+ public function testIgnoredAttributesDenormalize()
+ {
+ $this->normalizer->setIgnoredAttributes(array('fooBar', 'bar', 'baz'));
+
+ $obj = new ObjectDummy();
+ $obj->setFoo('foo');
+
+ $this->assertEquals(
+ $obj,
+ $this->normalizer->denormalize(array('fooBar' => 'fooBar', 'foo' => 'foo', 'baz' => 'baz'), __NAMESPACE__.'\ObjectDummy')
+ );
+ }
+
public function provideCallbacks()
{
return array(
diff --git a/src/Symfony/Component/Validator/Constraints/DateTimeValidator.php b/src/Symfony/Component/Validator/Constraints/DateTimeValidator.php
index 681b7bdbee..af956ee06b 100644
--- a/src/Symfony/Component/Validator/Constraints/DateTimeValidator.php
+++ b/src/Symfony/Component/Validator/Constraints/DateTimeValidator.php
@@ -34,7 +34,7 @@ class DateTimeValidator extends DateValidator
throw new UnexpectedTypeException($constraint, __NAMESPACE__.'\DateTime');
}
- if (null === $value || '' === $value || $value instanceof \DateTime) {
+ if (null === $value || '' === $value || $value instanceof \DateTimeInterface) {
return;
}
diff --git a/src/Symfony/Component/Validator/Constraints/DateValidator.php b/src/Symfony/Component/Validator/Constraints/DateValidator.php
index bfeb5fca30..ed836de9ac 100644
--- a/src/Symfony/Component/Validator/Constraints/DateValidator.php
+++ b/src/Symfony/Component/Validator/Constraints/DateValidator.php
@@ -47,7 +47,7 @@ class DateValidator extends ConstraintValidator
throw new UnexpectedTypeException($constraint, __NAMESPACE__.'\Date');
}
- if (null === $value || '' === $value || $value instanceof \DateTime) {
+ if (null === $value || '' === $value || $value instanceof \DateTimeInterface) {
return;
}
diff --git a/src/Symfony/Component/Validator/Tests/Constraints/DateTimeValidatorTest.php b/src/Symfony/Component/Validator/Tests/Constraints/DateTimeValidatorTest.php
index 28206025d5..8fb2024dd5 100644
--- a/src/Symfony/Component/Validator/Tests/Constraints/DateTimeValidatorTest.php
+++ b/src/Symfony/Component/Validator/Tests/Constraints/DateTimeValidatorTest.php
@@ -42,6 +42,13 @@ class DateTimeValidatorTest extends AbstractConstraintValidatorTest
$this->assertNoViolation();
}
+ public function testDateTimeImmutableClassIsValid()
+ {
+ $this->validator->validate(new \DateTimeImmutable(), new DateTime());
+
+ $this->assertNoViolation();
+ }
+
/**
* @expectedException \Symfony\Component\Validator\Exception\UnexpectedTypeException
*/
diff --git a/src/Symfony/Component/Validator/Tests/Constraints/DateValidatorTest.php b/src/Symfony/Component/Validator/Tests/Constraints/DateValidatorTest.php
index 67bb2340c3..ec62de6281 100644
--- a/src/Symfony/Component/Validator/Tests/Constraints/DateValidatorTest.php
+++ b/src/Symfony/Component/Validator/Tests/Constraints/DateValidatorTest.php
@@ -42,6 +42,13 @@ class DateValidatorTest extends AbstractConstraintValidatorTest
$this->assertNoViolation();
}
+ public function testDateTimeImmutableClassIsValid()
+ {
+ $this->validator->validate(new \DateTimeImmutable(), new Date());
+
+ $this->assertNoViolation();
+ }
+
/**
* @expectedException \Symfony\Component\Validator\Exception\UnexpectedTypeException
*/
diff --git a/src/Symfony/Component/VarDumper/Dumper/AbstractDumper.php b/src/Symfony/Component/VarDumper/Dumper/AbstractDumper.php
index da6e51d6b4..ee70b9d0c7 100644
--- a/src/Symfony/Component/VarDumper/Dumper/AbstractDumper.php
+++ b/src/Symfony/Component/VarDumper/Dumper/AbstractDumper.php
@@ -128,6 +128,8 @@ abstract class AbstractDumper implements DataDumperInterface, DumperInterface
$this->dumpLine(-1);
} catch (\Exception $exception) {
// Re-thrown below
+ } catch (\Throwable $exception) {
+ // Re-thrown below
}
if ($output) {
$this->setOutput($prevOutput);
diff --git a/src/Symfony/Component/Yaml/Parser.php b/src/Symfony/Component/Yaml/Parser.php
index c45ba46b87..de1101f009 100644
--- a/src/Symfony/Component/Yaml/Parser.php
+++ b/src/Symfony/Component/Yaml/Parser.php
@@ -24,6 +24,7 @@ class Parser
const BLOCK_SCALAR_HEADER_PATTERN = '(?P\||>)(?P\+|\-|\d+|\+\d+|\-\d+|\d+\+|\d+\-)?(?P +#.*)?';
private $offset = 0;
+ private $totalNumberOfLines;
private $lines = array();
private $currentLineNb = -1;
private $currentLine = '';
@@ -32,11 +33,13 @@ class Parser
/**
* Constructor.
*
- * @param int $offset The offset of YAML document (used for line numbers in error messages)
+ * @param int $offset The offset of YAML document (used for line numbers in error messages)
+ * @param int|null $totalNumberOfLines The overall number of lines being parsed
*/
- public function __construct($offset = 0)
+ public function __construct($offset = 0, $totalNumberOfLines = null)
{
$this->offset = $offset;
+ $this->totalNumberOfLines = $totalNumberOfLines;
}
/**
@@ -85,6 +88,10 @@ class Parser
$value = $this->cleanup($value);
$this->lines = explode("\n", $value);
+ if (null === $this->totalNumberOfLines) {
+ $this->totalNumberOfLines = count($this->lines);
+ }
+
if (2 /* MB_OVERLOAD_STRING */ & (int) ini_get('mbstring.func_overload')) {
$mbEncoding = mb_internal_encoding();
mb_internal_encoding('UTF-8');
@@ -106,7 +113,7 @@ class Parser
$isRef = $mergeNode = false;
if (preg_match('#^\-((?P\s+)(?P.+?))?\s*$#u', $this->currentLine, $values)) {
if ($context && 'mapping' == $context) {
- throw new ParseException('You cannot define a sequence item when in a mapping');
+ throw new ParseException('You cannot define a sequence item when in a mapping', $this->getRealCurrentLineNb() + 1, $this->currentLine);
}
$context = 'sequence';
@@ -118,7 +125,7 @@ class Parser
// array
if (!isset($values['value']) || '' == trim($values['value'], ' ') || 0 === strpos(ltrim($values['value'], ' '), '#')) {
$c = $this->getRealCurrentLineNb() + 1;
- $parser = new self($c);
+ $parser = new self($c, $this->totalNumberOfLines);
$parser->refs = &$this->refs;
$data[] = $parser->parse($this->getNextEmbedBlock(null, true), $flags);
} else {
@@ -127,7 +134,7 @@ class Parser
) {
// this is a compact notation element, add to next block and parse
$c = $this->getRealCurrentLineNb();
- $parser = new self($c);
+ $parser = new self($c, $this->totalNumberOfLines);
$parser->refs = &$this->refs;
$block = $values['value'];
@@ -145,7 +152,7 @@ class Parser
}
} elseif (preg_match('#^(?P'.Inline::REGEX_QUOTED_STRING.'|[^ \'"\[\{].*?) *\:(\s+(?P.+?))?\s*$#u', $this->currentLine, $values) && (false === strpos($values['key'], ' #') || in_array($values['key'][0], array('"', "'")))) {
if ($context && 'sequence' == $context) {
- throw new ParseException('You cannot define a mapping item when in a sequence');
+ throw new ParseException('You cannot define a mapping item when in a sequence', $this->currentLineNb + 1, $this->currentLine);
}
$context = 'mapping';
@@ -192,7 +199,7 @@ class Parser
$value = $this->getNextEmbedBlock();
}
$c = $this->getRealCurrentLineNb() + 1;
- $parser = new self($c);
+ $parser = new self($c, $this->totalNumberOfLines);
$parser->refs = &$this->refs;
$parsed = $parser->parse($value, $flags);
@@ -243,7 +250,7 @@ class Parser
}
} else {
$c = $this->getRealCurrentLineNb() + 1;
- $parser = new self($c);
+ $parser = new self($c, $this->totalNumberOfLines);
$parser->refs = &$this->refs;
$value = $parser->parse($this->getNextEmbedBlock(), $flags);
// Spec: Keys MUST be unique; first one wins.
@@ -266,7 +273,7 @@ class Parser
} else {
// multiple documents are not supported
if ('---' === $this->currentLine) {
- throw new ParseException('Multiple documents are not supported.');
+ throw new ParseException('Multiple documents are not supported.', $this->currentLineNb + 1, $this->currentLine);
}
// 1-liner optionally followed by newline(s)
@@ -511,7 +518,7 @@ class Parser
}
if (!array_key_exists($value, $this->refs)) {
- throw new ParseException(sprintf('Reference "%s" does not exist.', $value), $this->currentLine);
+ throw new ParseException(sprintf('Reference "%s" does not exist.', $value), $this->currentLineNb + 1, $this->currentLine);
}
return $this->refs[$value];
@@ -609,6 +616,8 @@ class Parser
if ($notEOF) {
$blockLines[] = '';
$this->moveToPreviousLine();
+ } elseif (!$notEOF && !$this->isCurrentLineLastLineInDocument()) {
+ $blockLines[] = '';
}
// folded style
@@ -715,6 +724,11 @@ class Parser
return '' !== $ltrimmedLine && $ltrimmedLine[0] === '#';
}
+ private function isCurrentLineLastLineInDocument()
+ {
+ return ($this->offset + $this->currentLineNb) >= ($this->totalNumberOfLines - 1);
+ }
+
/**
* Cleanups a YAML string to be parsed.
*
@@ -792,7 +806,7 @@ class Parser
*/
private function isStringUnIndentedCollectionItem()
{
- return 0 === strpos($this->currentLine, '- ');
+ return '-' === rtrim($this->currentLine) || 0 === strpos($this->currentLine, '- ');
}
/**
diff --git a/src/Symfony/Component/Yaml/Tests/ParserTest.php b/src/Symfony/Component/Yaml/Tests/ParserTest.php
index 69a1bab2f3..bb70c3a9a8 100644
--- a/src/Symfony/Component/Yaml/Tests/ParserTest.php
+++ b/src/Symfony/Component/Yaml/Tests/ParserTest.php
@@ -654,7 +654,7 @@ EOF;
/**
* @expectedException \Symfony\Component\Yaml\Exception\ParseException
- * @expectedExceptionMessage Multiple documents are not supported.
+ * @expectedExceptionMessageRegExp /^Multiple documents are not supported.+/
*/
public function testMultipleDocumentsNotSupportedException()
{
@@ -686,6 +686,34 @@ EOF
);
}
+ public function testSequenceInMappingStartedBySingleDashLine()
+ {
+ $yaml = << array(
+ array(
+ 'b' => array(
+ array(
+ 'bar' => 'baz',
+ ),
+ ),
+ ),
+ 'foo',
+ ),
+ 'd' => 'e',
+ );
+
+ $this->assertSame($expected, $this->parser->parse($yaml));
+ }
+
/**
* @expectedException \Symfony\Component\Yaml\Exception\ParseException
*/
@@ -1035,6 +1063,7 @@ EOT
foo
# bar
baz
+
EOT
,
),
@@ -1063,7 +1092,7 @@ EOT;
$expected = array(
'foo' => array(
'bar' => array(
- 'scalar-block' => 'line1 line2>',
+ 'scalar-block' => "line1 line2>\n",
),
'baz' => array(
'foobar' => null,