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.
300 lines
5.1 KiB
300 lines
5.1 KiB
<?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; |
|
} |
|
|
|
}
|
|
|