$flash->set('notice', "Successfully created") * before redirecting to a display action that can then expose the flash to its * template. * * @package trails * * @author mlunzena * @copyright (c) Authors * @version $Id: trails.php 7001 2008-04-04 11:20:27Z mlunzena $ */ final class Flash implements \ArrayAccess { private array $flash = []; private array $used = []; /** * @return self * @throws SessionRequiredException */ public static function instance() { if (!isset($_SESSION)) { throw new Exceptions\SessionRequiredException(); } if (!isset($_SESSION[self::class])) { $_SESSION[self::class] = new self(); } return $_SESSION[self::class]; } public function offsetExists($offset): bool { return isset($this->flash[$offset]); } public function offsetGet($offset): mixed { return $this->get($offset); } public function offsetSet($offset, $value): void { $this->set($offset, $value); } public function offsetUnset($offset): void { unset($this->flash[$offset], $this->used[$offset]); } /** * Used internally by the keep and discard methods * use() # marks the entire flash as used * use('msg') # marks the "msg" entry as used * use(null, false) # marks the entire flash as unused * # (keeps it around for one more action) * use('msg', false) # marks the "msg" entry as unused * # (keeps it around for one more action) * */ private function use(?string $key = null, bool $isUsed = true): void { if ($key) { $this->used[$key] = $isUsed; } else { foreach (array_keys($this->used) as $key) { $this->use($key, $isUsed); } } } /** * Marks the entire flash or a single flash entry to be discarded by the end * of the current action. * * $flash->discard() # discards entire flash * # (it'll still be available for the * # current action) * $flash->discard('warning') # discard the "warning" entry * # (it'll still be available for the * # current action) */ public function discard(?string $key = null): void { $this->use($key); } /** * Returns the value to the specified key. * * @return mixed the key's value. */ public function &get(string $key): mixed { $return = null; if (isset($this->flash[$key])) { $return =& $this->flash[$key]; } return $return; } /** * Keeps either the entire current flash or a specific flash entry available * for the next action: * * $flash->keep() # keeps the entire flash * $flash->keep('notice') # keeps only the "notice" entry, the rest of * # the flash is discarded */ public function keep(?string $key = null): void { $this->use($key, false); } /** * Sets a key's value. */ public function set(string $key, mixed $value): void { $this->keep($key); $this->flash[$key] = $value; } /** * Sets a key's value by reference. */ public function set_ref(string $key, mixed &$value): void { $this->keep($key); $this->flash[$key] =& $valze; } /** * Removes all used values */ public function sweep(): void { foreach (array_keys($this->flash) as $k) { if ($this->used[$k]) { unset($this->flash[$k], $this->used[$k]); } else { $this->use($k); } } } public function __toString() { $values = []; foreach ($this->flash as $key => $value) { $values[] = sprintf( "'%s': [%s, '%s']", $key, var_export($value, true), !empty($this->used[$key]) ? 'used' : 'unused' ); } return '{' . implode(', ', $values) . '}'. "\n"; } public function __sleep(): array { $this->sweep(); return ['flash', 'used']; } public function __wakeUp() { $this->discard(); } }