diff --git a/CHANGELOG-2.1.md b/CHANGELOG-2.1.md
index 35cbb4f96e..ae87cee725 100644
--- a/CHANGELOG-2.1.md
+++ b/CHANGELOG-2.1.md
@@ -40,6 +40,11 @@ To get the diff between two versions, go to https://github.com/symfony/symfony/c
* changed the default profiler storage to use the filesystem instead of SQLite
* added support for placeholders in route defaults and requirements (replaced by the value set in the service container)
* added Filesystem component as a dependency
+ * [BC BREAK] changed `session.xml` service name `session.storage.native` to `session.storage.native_file`
+ * added new session storage drivers to session.xml: `session.storage.native_memcache`, `session.storage.native_memcached`,
+ `session.storage.native_sqlite`, `session.storage.null`, `session.storage.memcache`,
+ and `session.storage.memcached`. Added `session.storage.mock_file` service for functional session testing.
+ * removed `session.storage.filesystem` service.
### MonologBundle
@@ -224,6 +229,32 @@ To get the diff between two versions, go to https://github.com/symfony/symfony/c
* removed the ContentTypeMimeTypeGuesser class as it is deprecated and never used on PHP 5.3
* added ResponseHeaderBag::makeDisposition() (implements RFC 6266)
* made mimetype to extension conversion configurable
+ * Flashes are now stored as a bucket of messages per `$type` so there can be multiple messages per type.
+ There are four interface constants for type, `FlashBagInterface::INFO`, `FlashBagInterface::NOTICE`,
+ `FlashBagInterface::WARNING` and `FlashBagInterface::ERROR`.
+ * Added `FlashBag` (default). Flashes expire when retrieved by `popFlashes()`.
+ This makes the implementation ESI compatible.
+ * Added `AutoExpireFlashBag` to replicate Symfony 2.0.x auto expire behaviour of messages auto expiring
+ after one page page load. Messages must be retrived by `popFlashes()` but will expire regardless of
+ being retrieved or not, which retains th old behaviour.
+ * [BC BREAK] Removed the following methods from the Session class: `close()`, `setFlash()`, `hasFlash()`,
+ and `removeFlash()` and added new methods. Use `addFlashes()` to add new flash messages.
+ `getFlashes()` now returns and array of flash messages.
+ * `Session->clear()` now only clears session attributes as before it cleared flash messages and
+ attributes. `Session->clearAllFlashes()` clears flashes now.
+ * Added `AbstractSessionStorage` base class for session storage drivers.
+ * Added `SessionSaveHandler` interface which storage drivers should implement after inheriting from
+ `AbstractSessionStorage` when writing custom session save handlers.
+ * [BC BREAK] `SessionStorageInterface` methods removed: `write()`, `read()` and `remove()`. Added
+ `getAttributes()`, `getFlashes()`.
+ * Moved attribute storage to `AttributeBagInterface`.
+ * Added `AttributeBag` to replicate attributes storage behaviour from 2.0.x (default).
+ * Added `NamespacedAttributeBag` for namespace session attributes.
+ * Session now implements `SessionInterface` making implementation customizable and portable.
+ * [BC BREAK] Removed `NativeSessionStorage` and replaced with `NativeFileSessionStorage`.
+ * Added session storage drivers for PHP native Memcache, Memcached and SQLite session save handlers.
+ * Added session storage drivers for custom Memcache, Memcached and Null session save handlers.
+ * Removed `FilesystemSessionStorage`, use `MockFileSessionStorage` for functional testing instead.
### HttpKernel
diff --git a/UPGRADE-2.1.md b/UPGRADE-2.1.md
index b94b511d79..0e7e631efe 100644
--- a/UPGRADE-2.1.md
+++ b/UPGRADE-2.1.md
@@ -1,6 +1,8 @@
UPGRADE FROM 2.0 to 2.1
=======================
+### General
+
* assets_base_urls and base_urls merging strategy has changed
Unlike most configuration blocks, successive values for
@@ -11,6 +13,8 @@ UPGRADE FROM 2.0 to 2.1
and/or share a common base configuration (i.e. ``config.yml``), merging
could yield a set of base URL's for multiple environments.
+### [HttpFoundation]
+
* moved management of the locale from the Session class to the Request class
Configuring the default locale:
@@ -73,8 +77,8 @@ UPGRADE FROM 2.0 to 2.1
explicitely need to set the `Valid` constraint in your model if you want to
validate associated objects.
- If you don't want to set the `Valid` constraint, or if there is no reference
- from the data of the parent form to the data of the child form, you can
+ If you don't want to set the `Valid` constraint, or if there is no reference
+ from the data of the parent form to the data of the child form, you can
enable BC behaviour by setting the option "cascade_validation" to `true` on
the parent form.
@@ -229,22 +233,98 @@ UPGRADE FROM 2.0 to 2.1
return false;
}
}
+ the parent form.
-* The options passed to `getParent` of the form types don't contain default
- options anymore
+ Before: $session->getLocale()
+ After: $request->getLocale()
- You should check with `isset` if options exist before checking their value.
+ * Flash Messages now returns and array based on type
- Before:
+ Before (PHP):
- public function getParent(array $options)
- {
- return 'single_text' === $options['widget'] ? 'text' : 'choice';
- }
+ hasFlash('notice')): ?>
+
+ getFlash('notice') ?>
+
+
- After:
+ After (PHP):
+
+ popFlashes('notice') as $notice): ?>
+
+
+
+
+
+ If You wanted to process all flash types you could also make use of the `popAllFlashes()` API:
+
+ popAllFlashes() as $type => $flashes): ?>
+
+
+
+
+
+
+
+.. note::
+
+ The Flash Message API provides constants which you can optionally use. For example
+ `Symfony\Component\HttpFoundation\FlashBag::NOTICE`, which can also be abbreviated to
+ `FlashBag::NOTICE` providing you declare ``
+ at the beginning of the PHP template.
+
+ Before (Twig):
+
+ {% if app.session.hasFlash('notice') %}
+
+ {{ app.session.flash('notice') }}
+
+ {% endif %}
+
+ After (Twig):
+
+ {% for flashMessage in app.session.popFlashes('notice') %}
+
+ {{ flashMessage }}
+
+ {% endforeach %}
+
+ Again you can process all flash messages in one go with
+
+ {% for type, flashMessages in app.session.popAllFlashes() %}
+ {% for flashMessage in flashMessages) %}
+
+ {{ flashMessage }}
+
+ {% endforeach %}
+ {% endforeach %}
+
+.. note::
+
+ You can access optionally use constants in Twig templates using `constant()` e.g.
+ `constant('Symfony\Component\HttpFoundation\FlashBag::NOTICE')`.
+
+* Session object
+
+ The methods, `setFlash()`, `hasFlash()`, and `removeFlash()` have been removed from the `Session`
+ object. You may use `addFlash()` to add flashes. `getFlashes()`, now returns an array. Use
+ `popFlashes()` to get flashes for display, or `popAllFlashes()` to process all flashes in on go.
+
+* Session storage drivers
+
+ Session storage drivers should inherit from
+ `Symfony\Component\HttpFoundation\SessionStorage\AbstractSessionStorage`
+ and no longer should implement `read()`, `write()`, `remove()` which were removed from the
+ `SessionStorageInterface`.
+
+ Any session storage drive that wants to use custom save handlers should
+ implement `Symfony\Component\HttpFoundation\SessionStorage\SessionSaveHandlerInterface`
+
+### [FrameworkBundle]
+
+ The service `session.storage.native` is now called `session.storage.native_file`
+
+ The service `session.storage.filesystem` is now called `session.storage.mock_file`
+ and is used for functional unit testing. You will need to update any references
+ in functional tests.
- public function getParent(array $options)
- {
- return isset($options['widget']) && 'single_text' === $options['widget'] ? 'text' : 'choice';
- }
diff --git a/src/Symfony/Component/HttpFoundation/SessionStorage/AbstractSessionStorage.php b/src/Symfony/Component/HttpFoundation/SessionStorage/AbstractSessionStorage.php
index db0ecca327..cf1df726c7 100644
--- a/src/Symfony/Component/HttpFoundation/SessionStorage/AbstractSessionStorage.php
+++ b/src/Symfony/Component/HttpFoundation/SessionStorage/AbstractSessionStorage.php
@@ -92,8 +92,8 @@ abstract class AbstractSessionStorage implements SessionStorageInterface
*/
public function __construct(AttributeBagInterface $attributes = null, FlashBagInterface $flashes = null, array $options = array())
{
- $this->attributeBag = $attributes ? $attributes : new AttributeBag();
- $this->flashBag = $flashes ? $flashes : new FlashBag();
+ $this->attributeBag = $attributes ?: new AttributeBag();
+ $this->flashBag = $flashes ?: new FlashBag();
$this->setOptions($options);
$this->registerSaveHandlers();
$this->registerShutdownFunction();
@@ -224,7 +224,7 @@ abstract class AbstractSessionStorage implements SessionStorageInterface
// Unless session.cache_limiter has been set explicitly, disable it
// because this is managed by HeaderBag directly (if used).
- if (!array_key_exists('cache_limiter', $this->options)) {
+ if (!isset($this->options['cache_limiter'])) {
$this->options['cache_limiter'] = 0;
}
diff --git a/src/Symfony/Component/HttpFoundation/SessionStorage/MemcacheSessionStorage.php b/src/Symfony/Component/HttpFoundation/SessionStorage/MemcacheSessionStorage.php
index e3d8d4c42b..6176cb8560 100644
--- a/src/Symfony/Component/HttpFoundation/SessionStorage/MemcacheSessionStorage.php
+++ b/src/Symfony/Component/HttpFoundation/SessionStorage/MemcacheSessionStorage.php
@@ -111,7 +111,7 @@ class MemcacheSessionStorage extends AbstractSessionStorage implements SessionSa
*/
public function sessionRead($sessionId)
{
- $result = $this->memcache->get($this->prefix.$sessionId);
+ return $this->memcache->get($this->prefix.$sessionId) ?: '';
return ($result) ? $result : '';
}
diff --git a/src/Symfony/Component/HttpFoundation/SessionStorage/MemcachedSessionStorage.php b/src/Symfony/Component/HttpFoundation/SessionStorage/MemcachedSessionStorage.php
index f91c7da6d5..85bb358e9e 100644
--- a/src/Symfony/Component/HttpFoundation/SessionStorage/MemcachedSessionStorage.php
+++ b/src/Symfony/Component/HttpFoundation/SessionStorage/MemcachedSessionStorage.php
@@ -96,9 +96,7 @@ class MemcachedSessionStorage extends AbstractSessionStorage implements SessionS
*/
public function sessionRead($sessionId)
{
- $result = $this->memcached->get($this->prefix.$sessionId);
-
- return $result ? $result : '';
+ return $this->memcached->get($this->prefix.$sessionId) ?: '';
}
/**
diff --git a/src/Symfony/Component/HttpFoundation/SessionStorage/MockFileSessionStorage.php b/src/Symfony/Component/HttpFoundation/SessionStorage/MockFileSessionStorage.php
index f5f0999e83..a785ce9f6f 100644
--- a/src/Symfony/Component/HttpFoundation/SessionStorage/MockFileSessionStorage.php
+++ b/src/Symfony/Component/HttpFoundation/SessionStorage/MockFileSessionStorage.php
@@ -47,7 +47,7 @@ class MockFileSessionStorage extends ArraySessionStorage
*/
public function __construct($savePath = null, array $options = array(), AttributeBagInterface $attributes = null, FlashBagInterface $flashes = null)
{
- if (is_null($savePath)) {
+ if (null === $savePath) {
$savePath = sys_get_temp_dir();
}
@@ -133,7 +133,7 @@ class MockFileSessionStorage extends ArraySessionStorage
*/
public function getFilePath()
{
- return $this->savePath . '/' . $this->sessionId . '.sess';
+ return $this->savePath.'/'.$this->sessionId.'.sess';
}
private function read()
diff --git a/src/Symfony/Component/HttpFoundation/SessionStorage/NativeFileSessionStorage.php b/src/Symfony/Component/HttpFoundation/SessionStorage/NativeFileSessionStorage.php
index 9297e4b718..8797e4ab27 100644
--- a/src/Symfony/Component/HttpFoundation/SessionStorage/NativeFileSessionStorage.php
+++ b/src/Symfony/Component/HttpFoundation/SessionStorage/NativeFileSessionStorage.php
@@ -40,7 +40,7 @@ class NativeFileSessionStorage extends AbstractSessionStorage
*/
public function __construct($savePath = null, array $options = array(), AttributeBagInterface $attributes = null, FlashBagInterface $flashes = null)
{
- if (is_null($savePath)) {
+ if (null === $savePath) {
$savePath = sys_get_temp_dir();
}