Personal Website
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

<?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;
}
}