Commit 209dd7e6 by Qiang Xue

Fixes #3956: Flash messages set via `Yii::$app->session->setFlash()` will be…

Fixes #3956: Flash messages set via `Yii::$app->session->setFlash()` will be removed only if they are accessed
parent 46041d0c
...@@ -125,6 +125,7 @@ Yii Framework 2 Change Log ...@@ -125,6 +125,7 @@ Yii Framework 2 Change Log
- Chg #3804: Added `fileinfo` PHP extension to the basic requirement of Yii (Ragazzo) - Chg #3804: Added `fileinfo` PHP extension to the basic requirement of Yii (Ragazzo)
- Chg #3866: The `FileValidator::types` property is renamed to `FileValidator::extensions` (Ragazzo) - Chg #3866: The `FileValidator::types` property is renamed to `FileValidator::extensions` (Ragazzo)
- Chg #3897: Raised visibility of `yii\web\View::registerAssetFiles()` to protected (samdark) - Chg #3897: Raised visibility of `yii\web\View::registerAssetFiles()` to protected (samdark)
- Chg #3956: Flash messages set via `Yii::$app->session->setFlash()` will be removed only if they are accessed (qiangxue)
- Chg: Replaced `clearAll()` and `clearAllAssignments()` in `yii\rbac\ManagerInterface` with `removeAll()`, `removeAllRoles()`, `removeAllPermissions()`, `removeAllRules()` and `removeAllAssignments()` (qiangxue) - Chg: Replaced `clearAll()` and `clearAllAssignments()` in `yii\rbac\ManagerInterface` with `removeAll()`, `removeAllRoles()`, `removeAllPermissions()`, `removeAllRules()` and `removeAllAssignments()` (qiangxue)
- Chg: Added `$user` as the first parameter of `yii\rbac\Rule::execute()` (qiangxue) - Chg: Added `$user` as the first parameter of `yii\rbac\Rule::execute()` (qiangxue)
- Chg: `yii\grid\DataColumn::getDataCellValue()` visibility is now `public` to allow accessing the value from a GridView directly (cebe) - Chg: `yii\grid\DataColumn::getDataCellValue()` visibility is now `public` to allow accessing the value from a GridView directly (cebe)
......
...@@ -603,9 +603,9 @@ class Session extends Component implements \IteratorAggregate, \ArrayAccess, \Co ...@@ -603,9 +603,9 @@ class Session extends Component implements \IteratorAggregate, \ArrayAccess, \Co
$counters = $this->get($this->flashParam, []); $counters = $this->get($this->flashParam, []);
if (is_array($counters)) { if (is_array($counters)) {
foreach ($counters as $key => $count) { foreach ($counters as $key => $count) {
if ($count) { if ($count > 0) {
unset($counters[$key], $_SESSION[$key]); unset($counters[$key], $_SESSION[$key]);
} else { } elseif ($count == 0) {
$counters[$key]++; $counters[$key]++;
} }
} }
...@@ -618,11 +618,10 @@ class Session extends Component implements \IteratorAggregate, \ArrayAccess, \Co ...@@ -618,11 +618,10 @@ class Session extends Component implements \IteratorAggregate, \ArrayAccess, \Co
/** /**
* Returns a flash message. * Returns a flash message.
* A flash message is available only in the current request and the next request.
* @param string $key the key identifying the flash message * @param string $key the key identifying the flash message
* @param mixed $defaultValue value to be returned if the flash message does not exist. * @param mixed $defaultValue value to be returned if the flash message does not exist.
* @param boolean $delete whether to delete this flash message right after this method is called. * @param boolean $delete whether to delete this flash message right after this method is called.
* If false, the flash message will be automatically deleted after the next request. * If false, the flash message will be automatically deleted in the next request.
* @return mixed the flash message * @return mixed the flash message
* @see setFlash() * @see setFlash()
* @see hasFlash() * @see hasFlash()
...@@ -636,6 +635,10 @@ class Session extends Component implements \IteratorAggregate, \ArrayAccess, \Co ...@@ -636,6 +635,10 @@ class Session extends Component implements \IteratorAggregate, \ArrayAccess, \Co
$value = $this->get($key, $defaultValue); $value = $this->get($key, $defaultValue);
if ($delete) { if ($delete) {
$this->removeFlash($key); $this->removeFlash($key);
} elseif ($counters[$key] < 0) {
// mark for deletion in the next request
$counters[$key] = 1;
$_SESSION[$this->flashParam] = $counters;
} }
return $value; return $value;
...@@ -661,46 +664,62 @@ class Session extends Component implements \IteratorAggregate, \ArrayAccess, \Co ...@@ -661,46 +664,62 @@ class Session extends Component implements \IteratorAggregate, \ArrayAccess, \Co
* *
* [bootstrap alert]: http://getbootstrap.com/components/#alerts * [bootstrap alert]: http://getbootstrap.com/components/#alerts
* *
* @param boolean $delete whether to delete the flash messages right after this method is called.
* If false, the flash messages will be automatically deleted in the next request.
* @return array flash messages (key => message). * @return array flash messages (key => message).
* @see setFlash() * @see setFlash()
* @see getFlash() * @see getFlash()
* @see hasFlash() * @see hasFlash()
* @see removeFlash() * @see removeFlash()
*/ */
public function getAllFlashes() public function getAllFlashes($delete = false)
{ {
$counters = $this->get($this->flashParam, []); $counters = $this->get($this->flashParam, []);
$flashes = []; $flashes = [];
foreach (array_keys($counters) as $key) { foreach (array_keys($counters) as $key) {
if (isset($_SESSION[$key])) { if (array_key_exists($key, $_SESSION)) {
$flashes[$key] = $_SESSION[$key]; $flashes[$key] = $_SESSION[$key];
if ($delete) {
unset($counters[$key], $_SESSION[$key]);
} elseif ($counters[$key] < 0) {
// mark for deletion in the next request
$counters[$key] = 1;
}
} else {
unset($counters[$key]);
} }
} }
$_SESSION[$this->flashParam] = $counters;
return $flashes; return $flashes;
} }
/** /**
* Stores a flash message. * Stores a flash message.
* A flash message is available only in the current request and the next request. * A flash message will be automatically deleted after it is accessed in a request and the deletion will happen
* in the next request.
* @param string $key the key identifying the flash message. Note that flash messages * @param string $key the key identifying the flash message. Note that flash messages
* and normal session variables share the same name space. If you have a normal * and normal session variables share the same name space. If you have a normal
* session variable using the same name, its value will be overwritten by this method. * session variable using the same name, its value will be overwritten by this method.
* @param mixed $value flash message * @param mixed $value flash message
* @param boolean $removeAfterAccess whether the flash message should be automatically removed only if
* it is accessed. If false, the flash message will be automatically removed after the next request,
* regardless if it is accessed or not. If true (default value), the flash message will remain until after
* it is accessed.
* @see getFlash() * @see getFlash()
* @see removeFlash() * @see removeFlash()
*/ */
public function setFlash($key, $value = true) public function setFlash($key, $value = true, $removeAfterAccess = true)
{ {
$counters = $this->get($this->flashParam, []); $counters = $this->get($this->flashParam, []);
$counters[$key] = 0; $counters[$key] = $removeAfterAccess ? -1 : 0;
$_SESSION[$key] = $value; $_SESSION[$key] = $value;
$_SESSION[$this->flashParam] = $counters; $_SESSION[$this->flashParam] = $counters;
} }
/** /**
* Removes a flash message. * Removes a flash message.
* Note that flash messages will be automatically removed after the next request.
* @param string $key the key identifying the flash message. Note that flash messages * @param string $key the key identifying the flash message. Note that flash messages
* and normal session variables share the same name space. If you have a normal * and normal session variables share the same name space. If you have a normal
* session variable using the same name, it will be removed by this method. * session variable using the same name, it will be removed by this method.
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment