Initial xentral_oss_20.3.c9ffacf
This commit is contained in:
@@ -0,0 +1,114 @@
|
||||
<?php
|
||||
|
||||
namespace Xentral\Components\Http\Session;
|
||||
|
||||
use Xentral\Components\Http\Exception\CsrfTokenException;
|
||||
use Xentral\Components\Http\Exception\InvalidArgumentException;
|
||||
use Xentral\Components\Util\StringUtil;
|
||||
|
||||
final class CsrfTokenManager
|
||||
{
|
||||
/** @var int CSRF_TOKEN_LENGTH */
|
||||
const CSRF_TOKEN_LENGTH = 32;
|
||||
/** @var array $tokenData */
|
||||
private $tokenData;
|
||||
|
||||
/**
|
||||
* @param array $tokenData
|
||||
*/
|
||||
public function __construct($tokenData = [])
|
||||
{
|
||||
$this->tokenData = $tokenData;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $key
|
||||
* @param string $value
|
||||
* @param bool $remove
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function isTokenValid($key, $value, $remove = true)
|
||||
{
|
||||
$this->ensureTokenKeyFormat($key);
|
||||
$valid = false;
|
||||
if (array_key_exists($key, $this->tokenData) && $this->tokenData[$key] === $value) {
|
||||
$valid = true;
|
||||
}
|
||||
if ($valid === true && $remove === true) {
|
||||
$this->removeToken($key);
|
||||
}
|
||||
|
||||
return $valid;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $key
|
||||
*
|
||||
* @throws CsrfTokenException
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function createToken($key)
|
||||
{
|
||||
$this->ensureTokenKeyFormat($key);
|
||||
$token = StringUtil::random(self::CSRF_TOKEN_LENGTH, true);
|
||||
$this->tokenData[$key] = $token;
|
||||
|
||||
if (strlen($token) < self::CSRF_TOKEN_LENGTH) {
|
||||
throw new CsrfTokenException('Could not create CSRF token.');
|
||||
}
|
||||
|
||||
return $token;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $key
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function removeToken($key)
|
||||
{
|
||||
$this->ensureTokenKeyFormat($key);
|
||||
unset($this->tokenData[$key]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $key
|
||||
*
|
||||
* @throws InvalidArgumentException
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function refreshToken($key)
|
||||
{
|
||||
$this->ensureTokenKeyFormat($key);
|
||||
$this->removeToken($key);
|
||||
|
||||
return $this->createToken($key);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $target
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function dumpTokens(&$target)
|
||||
{
|
||||
$target = $this->tokenData;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $key
|
||||
*
|
||||
* @throws InvalidArgumentException
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
private function ensureTokenKeyFormat($key)
|
||||
{
|
||||
if (!preg_match('/^[a-z][a-z0-9_]*$/', $key)) {
|
||||
throw new InvalidArgumentException('Invalid token key format.');
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,145 @@
|
||||
<?php
|
||||
|
||||
namespace Xentral\Components\Http\Session;
|
||||
|
||||
final class FlashMessageCollection
|
||||
{
|
||||
/** @var FlashMessageData[] $data */
|
||||
public $data;
|
||||
|
||||
/**
|
||||
* FlashMessageCollection constructor.
|
||||
*
|
||||
* @param array $flashMessageData array structure from session
|
||||
*/
|
||||
public function __construct($flashMessageData = [])
|
||||
{
|
||||
$data = $this->fromSessionArray($flashMessageData);
|
||||
$this->data = $this->sortByPriority($data);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets and removes all flash messages from previous session
|
||||
*
|
||||
* @return FlashMessageData[]
|
||||
*/
|
||||
public function getAll()
|
||||
{
|
||||
$result = $this->data;
|
||||
$this->data = [];
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets and removes flash messages filtered
|
||||
*
|
||||
* @param string|null $segment filter for segment (null=deactivated)
|
||||
* @param string|null $type filter for type (null=deactivated)
|
||||
*
|
||||
* @return FlashMessageData[] sorted by priority
|
||||
*/
|
||||
public function getMessages($segment = null, $type = null)
|
||||
{
|
||||
$result = [];
|
||||
foreach ($this->data as $key => $item) {
|
||||
if (
|
||||
($segment === null || $segment === $item->getSegmentName())
|
||||
&& ($type === null || $type === $item->getType())
|
||||
) {
|
||||
$result[] = $item;
|
||||
unset($this->data[$key]);
|
||||
}
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets and removes flash messages filtered
|
||||
*
|
||||
* @param string $type
|
||||
*
|
||||
* @return FlashMessageData[] sorted by priority
|
||||
*/
|
||||
public function getMessagesByType($type)
|
||||
{
|
||||
return $this->getMessages(null, $type);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets and removes flash messages filtered
|
||||
*
|
||||
* @param string $segment
|
||||
*
|
||||
* @return FlashMessageData[] sorted by priority
|
||||
*/
|
||||
public function getMessagesBySegment($segment)
|
||||
{
|
||||
return $this->getMessages($segment, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns array to be stored in session
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function toSessionArray()
|
||||
{
|
||||
$result = [];
|
||||
foreach ($this->data as $item) {
|
||||
$result[] = $item->toSessionArray();
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sorts flash messages by priority (descending)
|
||||
*
|
||||
* @param FlashMessageData[] $messages
|
||||
*
|
||||
* @return FlashMessageData[]
|
||||
*/
|
||||
public function sortByPriority($messages)
|
||||
{
|
||||
usort($messages, [$this, 'comparePriorityCallback']);
|
||||
|
||||
return $messages;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $data
|
||||
*
|
||||
* @return FlashMessageData[]
|
||||
*/
|
||||
private function fromSessionArray($data)
|
||||
{
|
||||
$result = [];
|
||||
foreach ($data as $item) {
|
||||
$result[] = FlashMessageData::createFromArray($item);
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Callable compare function for sorting.
|
||||
*
|
||||
* @param FlashMessageData $insert
|
||||
* @param FlashMessageData $exist
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
private function comparePriorityCallback($insert, $exist)
|
||||
{
|
||||
if ($insert->getPriority() === $exist->getPriority()) {
|
||||
return 0;
|
||||
}
|
||||
if ($insert->getPriority() > $exist->getPriority()) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,155 @@
|
||||
<?php
|
||||
|
||||
namespace Xentral\Components\Http\Session;
|
||||
|
||||
use Xentral\Components\Http\Exception\InvalidArgumentException;
|
||||
|
||||
final class FlashMessageData
|
||||
{
|
||||
/** @var string FLASHTYPE_DEFAULT */
|
||||
const FLASHTYPE_DEFAULT = 'default';
|
||||
|
||||
/** @var string FLASHTYPE_NOTICE */
|
||||
const FLASHTYPE_NOTICE = 'notice';
|
||||
|
||||
/** @var string FLASHTYPE_SUCCESS */
|
||||
const FLASHTYPE_SUCCESS = 'success';
|
||||
|
||||
/** @var string FLASHTYPE_WARNING */
|
||||
const FLASHTYPE_WARNING = 'warning';
|
||||
|
||||
/** @var string FLASHTYPE_ERROR */
|
||||
const FLASHTYPE_ERROR = 'error';
|
||||
|
||||
/** @var array $flashTypes */
|
||||
public static $flashTypes = [
|
||||
self::FLASHTYPE_DEFAULT,
|
||||
self::FLASHTYPE_NOTICE,
|
||||
self::FLASHTYPE_SUCCESS,
|
||||
self::FLASHTYPE_WARNING,
|
||||
self::FLASHTYPE_ERROR,
|
||||
];
|
||||
|
||||
/**@var string $type */
|
||||
private $type;
|
||||
|
||||
/** @var string $message */
|
||||
private $message;
|
||||
|
||||
/** @var int $priority */
|
||||
private $priority;
|
||||
|
||||
/** @var string $segmentName */
|
||||
private $segmentName;
|
||||
|
||||
/**
|
||||
* @param string $message
|
||||
* @param string $type
|
||||
* @param string $segmentName
|
||||
* @param int $priority
|
||||
*/
|
||||
public function __construct($message, $type, $segmentName = '', $priority = 0)
|
||||
{
|
||||
$this->setType($type);
|
||||
$this->message = $message;
|
||||
$this->setSegmentName($segmentName);
|
||||
$this->priority = (int)$priority;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create FlashMessageData object from session array entry
|
||||
*
|
||||
* @param array $data required keys: 'priority', 'segment, 'type', 'message'
|
||||
*
|
||||
* @throws InvalidArgumentException
|
||||
*
|
||||
* @return FlashMessageData
|
||||
*/
|
||||
public static function createFromArray($data)
|
||||
{
|
||||
if (
|
||||
!array_key_exists('priority', $data)
|
||||
|| !array_key_exists('segment', $data)
|
||||
|| !array_key_exists('type', $data)
|
||||
|| !array_key_exists('message', $data)
|
||||
) {
|
||||
throw new InvalidArgumentException('Invalid array data for FlashMessageData.');
|
||||
}
|
||||
|
||||
return new self($data['message'], $data['type'], $data['segment'], $data['priority']);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getType()
|
||||
{
|
||||
return $this->type;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getMessage()
|
||||
{
|
||||
return $this->message;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return int
|
||||
*/
|
||||
public function getPriority()
|
||||
{
|
||||
return $this->priority;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public function getSegmentName()
|
||||
{
|
||||
return $this->segmentName;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns array to store in the session
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function toSessionArray()
|
||||
{
|
||||
return [
|
||||
'priority' => $this->getPriority(),
|
||||
'segment' => $this->getSegmentName(),
|
||||
'type' => $this->getType(),
|
||||
'message' => $this->getMessage(),
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $type
|
||||
*
|
||||
* @throws InvalidArgumentException
|
||||
*/
|
||||
private function setType($type)
|
||||
{
|
||||
if (!in_array($type, self::$flashTypes, true)) {
|
||||
throw new InvalidArgumentException(sprintf('Unknown message type "%s".', $type));
|
||||
}
|
||||
$this->type = $type;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $name
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
private function setSegmentName($name)
|
||||
{
|
||||
if (!preg_match('/^[a-z0-9_]*$/', $name)) {
|
||||
throw new InvalidArgumentException(sprintf('Invalid Segment Name "%s".', $name));
|
||||
}
|
||||
|
||||
$this->segmentName = $name;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,130 @@
|
||||
<?php
|
||||
|
||||
namespace Xentral\Components\Http\Session;
|
||||
|
||||
use Xentral\Components\Http\Exception\InvalidArgumentException;
|
||||
|
||||
final class Segment
|
||||
{
|
||||
/** @var Session $session */
|
||||
private $session;
|
||||
|
||||
/** @var string $name */
|
||||
private $name;
|
||||
|
||||
/** @var array $data */
|
||||
private $data;
|
||||
|
||||
/**
|
||||
* @param Session $session
|
||||
* @param string $name
|
||||
* @param array $data
|
||||
*/
|
||||
public function __construct(Session $session, $name, $data = [])
|
||||
{
|
||||
$this->session = $session;
|
||||
$this->name = $name;
|
||||
$this->data = $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Makes an entry to the segment
|
||||
*
|
||||
* @param string $key
|
||||
* @param int|float|string|array $value
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function setValue($key, $value)
|
||||
{
|
||||
$this->ensureSegmentKeyFormat($key);
|
||||
$this->data[$key] = $value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a value with a specific key
|
||||
*
|
||||
* @param string $key
|
||||
* @param mixed|null $default
|
||||
* @param bool $clear true=remove entry from the session
|
||||
*
|
||||
* @return mixed|null
|
||||
*/
|
||||
public function getValue($key, $default = null, $clear = false)
|
||||
{
|
||||
$this->ensureSegmentKeyFormat($key);
|
||||
$value = $default;
|
||||
if (isset($this->data[$key])) {
|
||||
$value = $this->data[$key];
|
||||
}
|
||||
if ($clear === true) {
|
||||
$this->removeValue($key);
|
||||
}
|
||||
|
||||
return $value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds new flash message to the segment
|
||||
*
|
||||
* @internal The actual segment which holds the flashes is 'flash_messages'.
|
||||
*
|
||||
* @param string $message
|
||||
* @param string $type
|
||||
* @param int $priority sorted highest to lowest
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function addFlashMessage($message, $type = FlashMessageData::FLASHTYPE_DEFAULT, $priority = 0)
|
||||
{
|
||||
$this->session->addFlashMessage($this->name, $message, $type, $priority);
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes single entry
|
||||
*
|
||||
* @param string $key
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function removeValue($key)
|
||||
{
|
||||
$this->ensureSegmentKeyFormat($key);
|
||||
unset($this->data[$key]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes all entries and flashes of this segment
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function clearAll()
|
||||
{
|
||||
$this->data = [];
|
||||
$this->session->getFlashMessages($this->name);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets all entries
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getAll()
|
||||
{
|
||||
return $this->data;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $key
|
||||
*
|
||||
* @throws InvalidArgumentException
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
private function ensureSegmentKeyFormat($key)
|
||||
{
|
||||
if (!preg_match('/^[a-z][a-z0-9_]*$/', $key)) {
|
||||
throw new InvalidArgumentException('Invalid segment key format.');
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,315 @@
|
||||
<?php
|
||||
|
||||
namespace Xentral\Components\Http\Session;
|
||||
|
||||
use Xentral\Components\Http\Exception\InvalidArgumentException;
|
||||
use Xentral\Components\Http\Exception\SessionSegmentException;
|
||||
|
||||
class Session
|
||||
{
|
||||
/** @var string FLASH_SEGMENTKEY */
|
||||
const FLASH_SEGMENTKEY = 'flash_messages';
|
||||
|
||||
/** @var string CSRF_SEGMENTKEY */
|
||||
const CSRF_SEGMENTKEY = 'csrf_tokens';
|
||||
|
||||
/** @var array $data */
|
||||
protected $data;
|
||||
|
||||
/** @var Segment[] $segments */
|
||||
protected $segments;
|
||||
|
||||
/** @var FlashMessageCollection $flashData */
|
||||
protected $flashMessages;
|
||||
|
||||
/** @var CsrfTokenManager $csrfTokens */
|
||||
protected $csrfTokens;
|
||||
|
||||
/**
|
||||
* @param array $data
|
||||
*/
|
||||
public function __construct($data = [])
|
||||
{
|
||||
$this->data = (array)$data;
|
||||
$this->segments = [];
|
||||
$this->flashMessages = $this->createFlashMessageCollection();
|
||||
$this->csrfTokens = $this->createCsrfTokenManager();
|
||||
}
|
||||
|
||||
/**
|
||||
* Clears all Session data and flash messages
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function clearAll()
|
||||
{
|
||||
$this->data = [];
|
||||
$this->segments = [];
|
||||
$this->flashMessages = new FlashMessageCollection();
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a value with a specific key from the current Segment
|
||||
*
|
||||
* @param string $segment
|
||||
* @param string $key
|
||||
* @param null $default
|
||||
* @param bool $clear true=remove entry from the session
|
||||
*
|
||||
* @return mixed|null
|
||||
*/
|
||||
public function getValue($segment, $key, $default = null, $clear = false)
|
||||
{
|
||||
|
||||
return $this->getSegment($segment)->getValue($key, $default, $clear);
|
||||
}
|
||||
|
||||
/**
|
||||
* Makes an entry to the current Segment
|
||||
*
|
||||
* @param string $segment
|
||||
* @param string $key
|
||||
* @param string|int|float|array $value
|
||||
*
|
||||
* @throws InvalidArgumentException
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function setValue($segment, $key, $value)
|
||||
{
|
||||
$this->getSegment($segment)->setValue($key, $value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes a single Entry from the current segment
|
||||
*
|
||||
* @param string $segment
|
||||
* @param string $key
|
||||
*
|
||||
* @throws InvalidArgumentException
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function removeValue($segment, $key)
|
||||
{
|
||||
$this->getSegment($segment)->removeValue($key);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a segment object by it's name
|
||||
*
|
||||
* @param string $name
|
||||
*
|
||||
* @throws InvalidArgumentException
|
||||
*
|
||||
* @return Segment
|
||||
*/
|
||||
public function getSegment($name = '')
|
||||
{
|
||||
if ($name === self::FLASH_SEGMENTKEY || $name === self::CSRF_SEGMENTKEY) {
|
||||
throw new SessionSegmentException(
|
||||
sprintf('"%s" is a reserved segment name.', self::FLASH_SEGMENTKEY)
|
||||
);
|
||||
}
|
||||
$segmentId = $this->getSegmentKey($name);
|
||||
if (array_key_exists($segmentId, $this->segments)) {
|
||||
return $this->segments[$segmentId];
|
||||
}
|
||||
$data = [];
|
||||
if (array_key_exists($segmentId, $this->data)) {
|
||||
$data = $this->data[$segmentId];
|
||||
}
|
||||
$segment = new Segment($this, $name, $data);
|
||||
$this->segments[$segmentId] = $segment;
|
||||
|
||||
return $segment;
|
||||
}
|
||||
|
||||
/**
|
||||
* Dumps the whole session into specific target variable.
|
||||
*
|
||||
* @param mixed $targetVariable
|
||||
*/
|
||||
public function dumpSession(&$targetVariable)
|
||||
{
|
||||
$this->mergeSession();
|
||||
$targetVariable = $this->data;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function __debugInfo()
|
||||
{
|
||||
$this->dumpSession($dump);
|
||||
$this->csrfTokens->dumpTokens($tokendump);
|
||||
$tokendump = array_keys($tokendump);
|
||||
|
||||
return [
|
||||
'data' => $dump,
|
||||
'tokens' => $tokendump
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds new flash message to specific segment.
|
||||
*
|
||||
* @param string $segment if empty: default segment will be used
|
||||
* @param string $message
|
||||
* @param string $type
|
||||
* @param int $priority
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function addFlashMessage($segment, $message, $type = FlashMessageData::FLASHTYPE_DEFAULT, $priority = 0)
|
||||
{
|
||||
$flash = new FlashMessageData($message, $type, $segment, $priority);
|
||||
$flashData = $flash->toSessionArray();
|
||||
$key = (string)$this->getSegmentKey(self::FLASH_SEGMENTKEY);
|
||||
$this->data[$key][] = $flashData;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets flash message(s) by specific filter conditions.
|
||||
*
|
||||
* The flash message will be cleared from the session after retrieving
|
||||
*
|
||||
* @param string|null $segment filter for segment name
|
||||
* @param string|null $type filter for message type
|
||||
*
|
||||
* @return FlashMessageData[] flash messages sorted by priority
|
||||
*/
|
||||
public function getFlashMessages($segment = null, $type = null)
|
||||
{
|
||||
return $this->flashMessages->getMessages($segment, $type);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a CSRF Token and stores it in the Session
|
||||
*
|
||||
* @param string $tokenKey
|
||||
*
|
||||
* @throws InvalidArgumentException
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function createCsrfToken($tokenKey)
|
||||
{
|
||||
return $this->csrfTokens->createToken($tokenKey);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if specified Token is valid
|
||||
*
|
||||
* @param string $tokenKey
|
||||
* @param string $tokenValue
|
||||
* @param bool $remove true=remove token from session to mitigate second use
|
||||
*
|
||||
* @throws InvalidArgumentException
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function isCsrfTokenValid($tokenKey, $tokenValue, $remove = false)
|
||||
{
|
||||
return $this->csrfTokens->isTokenValid($tokenKey, $tokenValue, $remove);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $segmentName
|
||||
*
|
||||
* @throws InvalidArgumentException
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
private function getSegmentKey($segmentName)
|
||||
{
|
||||
$this->ensureSegmentNameFormat($segmentName);
|
||||
|
||||
return sprintf('segment_%s', $segmentName);
|
||||
}
|
||||
|
||||
/**
|
||||
* Merge all Segments and Flashmessages and CsrfTokens into the session array.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
private function mergeSession()
|
||||
{
|
||||
foreach ($this->segments as $key => $segment) {
|
||||
$segmentData = $segment->getAll();
|
||||
if (count($segmentData) > 0) {
|
||||
$this->data[$key] = $segmentData;
|
||||
}
|
||||
}
|
||||
|
||||
$flashKey = $this->getSegmentKey(self::FLASH_SEGMENTKEY);
|
||||
$newFlashes = [];
|
||||
if (array_key_exists($flashKey, $this->data)) {
|
||||
$newFlashes = $this->data[$flashKey];
|
||||
}
|
||||
$oldFlashes = $this->flashMessages->toSessionArray();
|
||||
$this->flashMessages = new FlashMessageCollection();
|
||||
$allFlashes = array_merge($oldFlashes, $newFlashes);
|
||||
if (count($allFlashes) > 0) {
|
||||
$this->data[$flashKey] = $allFlashes;
|
||||
} else {
|
||||
unset($this->data[$flashKey]);
|
||||
}
|
||||
|
||||
$this->csrfTokens->dumpTokens($tokens);
|
||||
$tokenSegmentKey = $this->getSegmentKey(self::CSRF_SEGMENTKEY);
|
||||
if (is_array($tokens) && count($tokens) > 0) {
|
||||
$this->data[$tokenSegmentKey] = $tokens;
|
||||
} else {
|
||||
unset($this->data[$tokenSegmentKey]);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return FlashMessageCollection
|
||||
*/
|
||||
private function createFlashMessageCollection()
|
||||
{
|
||||
$key = $this->getSegmentKey(self::FLASH_SEGMENTKEY);
|
||||
if (!array_key_exists($key, $this->data)) {
|
||||
return new FlashMessageCollection();
|
||||
}
|
||||
$messages = $this->data[$key];
|
||||
$result = new FlashMessageCollection($messages);
|
||||
unset($this->data[$key]);
|
||||
$this->data[$key] = [];
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return CsrfTokenManager
|
||||
*/
|
||||
private function createCsrfTokenManager()
|
||||
{
|
||||
$key = $this->getSegmentKey(self::CSRF_SEGMENTKEY);
|
||||
if (!array_key_exists($key, $this->data)) {
|
||||
return new CsrfTokenManager();
|
||||
}
|
||||
$tokens = $this->data[$key];
|
||||
$result = new CsrfTokenManager($tokens);
|
||||
unset($this->data[$key]);
|
||||
$this->data[$key] = [];
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $name
|
||||
*
|
||||
* @throws InvalidArgumentException
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
private function ensureSegmentNameFormat($name)
|
||||
{
|
||||
if (!preg_match('/^[a-z][a-z0-9_]*$/', $name)) {
|
||||
throw new InvalidArgumentException('Invalid segment name format.');
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,63 @@
|
||||
<?php
|
||||
|
||||
namespace Xentral\Components\Http\Session;
|
||||
|
||||
use Xentral\Components\Http\Exception\SessionException;
|
||||
|
||||
class SessionHandler
|
||||
{
|
||||
/**
|
||||
* Create a session object with actual session data
|
||||
*
|
||||
* @throws SessionException
|
||||
*
|
||||
* @return Session Session object
|
||||
*/
|
||||
public static function createSession()
|
||||
{
|
||||
if (!extension_loaded('session')) {
|
||||
throw new SessionException('PHP extension "session" is missing.');
|
||||
}
|
||||
|
||||
if (self::isSessionStarted()) {
|
||||
throw new SessionException('Failed to create session. Session can be started only once.');
|
||||
}
|
||||
if (session_status() === PHP_SESSION_DISABLED) {
|
||||
throw new SessionException('Failed to create session. Sessions are disabled.');
|
||||
}
|
||||
|
||||
$isStarted = session_start();
|
||||
if ($isStarted === false) {
|
||||
throw new SessionException('Failed to create session. Initialization failed.');
|
||||
}
|
||||
|
||||
if (session_status() === PHP_SESSION_NONE) {
|
||||
throw new SessionException('Failed to create session. Unexpected status: PHP_SESSION_NONE');
|
||||
}
|
||||
|
||||
return new Session($_SESSION);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public static function isSessionStarted()
|
||||
{
|
||||
$status = session_status();
|
||||
|
||||
return $status === PHP_SESSION_ACTIVE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Save and close the session
|
||||
*
|
||||
* @param Session $session
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public static function commitSession(Session $session)
|
||||
{
|
||||
$session->dumpSession($_SESSION);
|
||||
session_write_close();
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user