You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
301 lines
5.1 KiB
301 lines
5.1 KiB
4 years ago
|
<?php
|
||
|
|
||
|
namespace App\Classes;
|
||
|
|
||
|
use stdClass;
|
||
|
|
||
|
class Session {
|
||
|
|
||
|
/**
|
||
|
* The session attributes.
|
||
|
*
|
||
|
* @var array
|
||
|
*/
|
||
|
private static $attributes;
|
||
|
|
||
|
/**
|
||
|
* Session store started status.
|
||
|
*
|
||
|
* @var bool
|
||
|
*/
|
||
|
protected static $started = false;
|
||
|
|
||
|
//-------------------------------------//
|
||
|
|
||
|
/**
|
||
|
* Start the PHP session
|
||
|
*
|
||
|
* @return void
|
||
|
*/
|
||
|
public static function start(): void
|
||
|
{
|
||
|
if (self::$started) {
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
session_set_cookie_params(['secure' => true, 'httponly' => true, 'samesite' => 'Strict']);
|
||
|
session_start();
|
||
|
|
||
|
self::$attributes = &$_SESSION;
|
||
|
|
||
|
if (!self::exists('_token')) {
|
||
|
self::regenerateToken();
|
||
|
}
|
||
|
|
||
|
self::$started = true;
|
||
|
}
|
||
|
|
||
|
//-------------------------------------//
|
||
|
|
||
|
/**
|
||
|
* Get all of the session data.
|
||
|
*
|
||
|
* @return array
|
||
|
*/
|
||
|
public static function all(): array
|
||
|
{
|
||
|
return self::$attributes;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Checks if a key exists.
|
||
|
*
|
||
|
* @param string|array $key
|
||
|
*
|
||
|
* @return bool
|
||
|
*/
|
||
|
public static function isset($key): bool
|
||
|
{
|
||
|
$placeholder = new stdClass;
|
||
|
return self::get($key, $placeholder) !== $placeholder;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Check if a key is present and not null.
|
||
|
*
|
||
|
* @param string|array $key
|
||
|
*
|
||
|
* @return bool
|
||
|
*/
|
||
|
public static function exists($key): bool
|
||
|
{
|
||
|
return !is_null(self::get($key));
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Get an item from the session.
|
||
|
*
|
||
|
* @param string $key
|
||
|
* @param mixed $default
|
||
|
*
|
||
|
* @return mixed
|
||
|
*/
|
||
|
public static function get(string $key, $default = null)
|
||
|
{
|
||
|
if (array_key_exists($key, self::$attributes)) {
|
||
|
return self::$attributes[$key];
|
||
|
}
|
||
|
|
||
|
if (strpos($key, '.') === false) {
|
||
|
return $default;
|
||
|
}
|
||
|
|
||
|
// Get item using the "dot" notation
|
||
|
$array = self::$attributes;
|
||
|
foreach (explode('.', $key) as $segment) {
|
||
|
if (is_array($array) && array_key_exists($segment, $array)) {
|
||
|
$array = $array[$segment];
|
||
|
}
|
||
|
else {
|
||
|
return $default;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return $array;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Put a key / value pair or array of key / value pairs in the session.
|
||
|
*
|
||
|
* @param string|array $key
|
||
|
* @param mixed $value
|
||
|
* @return void
|
||
|
*/
|
||
|
public static function put($key, $value = null)
|
||
|
{
|
||
|
if (!is_array($key)) {
|
||
|
$key = [$key => $value];
|
||
|
}
|
||
|
|
||
|
foreach ($key as $arrayKey => $arrayValue) {
|
||
|
|
||
|
// Set array item to a given value using the "dot" notation
|
||
|
|
||
|
$keys = explode('.', $arrayKey);
|
||
|
|
||
|
$array = &self::$attributes;
|
||
|
foreach ($keys as $i => $key) {
|
||
|
if (count($keys) === 1) {
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
unset($keys[$i]);
|
||
|
|
||
|
// If key doesnt exist at this depth, create empty array holder
|
||
|
if (!isset($array[$key]) || !is_array($array[$key])) {
|
||
|
$array[$key] = [];
|
||
|
}
|
||
|
|
||
|
$array = &$array[$key];
|
||
|
}
|
||
|
|
||
|
$array[array_shift($keys)] = $arrayValue;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Get an item from the session, or store the default value.
|
||
|
*
|
||
|
* @param string $key
|
||
|
*
|
||
|
* @return mixed
|
||
|
*/
|
||
|
public static function emplace(string $key)
|
||
|
{
|
||
|
$value = self::get($key);
|
||
|
if (!is_null($value)) {
|
||
|
return $value;
|
||
|
}
|
||
|
|
||
|
self::put($key, $value);
|
||
|
return $value;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Push a value onto a session array.
|
||
|
*
|
||
|
* @param string $key
|
||
|
* @param mixed $value
|
||
|
*
|
||
|
* @return void
|
||
|
*/
|
||
|
public static function push(string $key, $value): void
|
||
|
{
|
||
|
$array = self::get($key, []);
|
||
|
$array[] = $value;
|
||
|
self::put($key, $array);
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Get the value of a given key and then remove it.
|
||
|
*
|
||
|
* @param string $keys
|
||
|
*
|
||
|
* @return mixed
|
||
|
*/
|
||
|
public static function pull(string $key, $default = null)
|
||
|
{
|
||
|
$result = self::get($key, $default);
|
||
|
self::delete($key);
|
||
|
|
||
|
return $result;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Delete one or many items from the session.
|
||
|
*
|
||
|
* @param string|array $keys
|
||
|
*
|
||
|
* @return void
|
||
|
*/
|
||
|
public static function delete($keys): void
|
||
|
{
|
||
|
$start = &self::$attributes;
|
||
|
|
||
|
$keys = (array)$keys;
|
||
|
|
||
|
if (count($keys) === 0) {
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
foreach ($keys as $key) {
|
||
|
// Delete top-level if non-"dot" notation key
|
||
|
if (self::exists($key)) {
|
||
|
unset(self::$attributes[$key]);
|
||
|
|
||
|
continue;
|
||
|
}
|
||
|
|
||
|
// Delete using "dot" notation key
|
||
|
|
||
|
$parts = explode('.', $key);
|
||
|
|
||
|
// Move to the start of the array each pass
|
||
|
$array = &$start;
|
||
|
|
||
|
// Traverse into the associative array
|
||
|
while (count($parts) > 1) {
|
||
|
$part = array_shift($parts);
|
||
|
|
||
|
if (isset($array[$part]) && is_array($array[$part])) {
|
||
|
$array = &$array[$part];
|
||
|
}
|
||
|
else {
|
||
|
continue 2;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
unset($array[array_shift($parts)]);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Remove all of the items from the session.
|
||
|
*
|
||
|
* @return void
|
||
|
*/
|
||
|
public static function flush(): void
|
||
|
{
|
||
|
self::$attributes = [];
|
||
|
}
|
||
|
|
||
|
//-------------------------------------//
|
||
|
|
||
|
/**
|
||
|
* Get the CSRF token value.
|
||
|
*
|
||
|
* @return string
|
||
|
*/
|
||
|
public static function token()
|
||
|
{
|
||
|
return self::get('_token');
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Regenerate the CSRF token value.
|
||
|
*
|
||
|
* @return void
|
||
|
*/
|
||
|
public static function regenerateToken()
|
||
|
{
|
||
|
self::put('_token', _randomStr(40));
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Validate the CSRF token value to the given value.
|
||
|
*
|
||
|
* @param array $array
|
||
|
*
|
||
|
* @return bool
|
||
|
*/
|
||
|
public static function validateToken(array $array = null): bool
|
||
|
{
|
||
|
if (is_array($array) && array_key_exists('_token', $array) && $array['_token'] == self::token()) {
|
||
|
return true;
|
||
|
}
|
||
|
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
}
|