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.
228 lines
5.4 KiB
228 lines
5.4 KiB
<?php
|
|
|
|
namespace authkit2;
|
|
|
|
/**
|
|
* Internal class for providing a single interface integrating with native PHP,
|
|
* Laravel, and any other environment we need to support.
|
|
*
|
|
* @method static mixed cache(string $key, callable $generator)
|
|
* @method static mixed cache_get(string $key, mixed $default = null)
|
|
* @method static void cache_set(string $key, mixed $value)
|
|
* @method static mixed session_get(string $key)
|
|
* @method static void session_set(string $key, mixed $value)
|
|
*/
|
|
class Authkit2
|
|
{
|
|
/**
|
|
* All data we shove into the session/cache will have its key prefixed
|
|
* with this value.
|
|
* @var string
|
|
*/
|
|
private const LIB_PREFIX = 'authkit2.';
|
|
|
|
/**
|
|
* Functions this class provides
|
|
*
|
|
* @array<string,callable>
|
|
*/
|
|
protected $callbacks = [];
|
|
|
|
/**
|
|
* Try and detect if we recognize the environment the library is running
|
|
* in and adjust our implementations accordingly.
|
|
*
|
|
* Basically, if we see the LARAVEL_START constant we assume Laravel and
|
|
* use Laravel facades, otherwise we use native php implementations.
|
|
*
|
|
*/
|
|
protected function __construct()
|
|
{
|
|
if (defined('LARAVEL_START'))
|
|
{
|
|
$this->initializeLaravel();
|
|
}
|
|
else
|
|
{
|
|
$this->initializeNative();
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Retrieve the instance of Authkit2 class
|
|
*
|
|
* @return Authkit2
|
|
*/
|
|
public static function get(): Authkit2
|
|
{
|
|
static $authkit2;
|
|
if (!isset($authkit2))
|
|
{
|
|
$authkit2 = new Authkit2();
|
|
}
|
|
return $authkit2;
|
|
}
|
|
|
|
/**
|
|
* Override any of the function implementations
|
|
*
|
|
* Name is the same as the callable function name, e.g.,
|
|
* Authkit2::cache_set() can be overriden with Authkit2->cache_set = function(...) {}
|
|
*
|
|
* @param string $name
|
|
* @param callable $value
|
|
* @return void
|
|
*/
|
|
public function __set(string $name, $value): void
|
|
{
|
|
if (!array_key_exists($name, $this->callbacks))
|
|
{
|
|
trigger_error('Undefined property: '.__CLASS__.'::$'.$name, E_USER_WARNING);
|
|
return;
|
|
}
|
|
|
|
if (!is_callable($value))
|
|
{
|
|
throw new \Exception('Authkit2::'.$name.' value must be callable');
|
|
}
|
|
|
|
$this->callbacks[$name] = $value;
|
|
}
|
|
|
|
/**
|
|
* Call any of the provided methods
|
|
*
|
|
* @param string $name
|
|
* @param mixed[] $arguments
|
|
* @return mixed
|
|
*/
|
|
public static function __callStatic(string $name, array $arguments)
|
|
{
|
|
$authkit2 = static::get();
|
|
if (!isset($authkit2->callbacks[$name]))
|
|
{
|
|
trigger_error('Call to undefined method '.__CLASS__.'::'.$name.'()', E_USER_ERROR);
|
|
}
|
|
|
|
return call_user_func_array($authkit2->callbacks[$name], $arguments);
|
|
}
|
|
|
|
/**
|
|
* Helper method for getting cache values, and generating and setting if
|
|
* they do not exist.
|
|
*
|
|
* @param string $key cache key
|
|
* @param callable $generator method that returns the value if we do not have it cached
|
|
* @return mixed
|
|
*/
|
|
protected function cache_helper(string $key, callable $generator)
|
|
{
|
|
$value = static::cache_get($key, null);
|
|
if (!isset($value))
|
|
{
|
|
$value = $generator();
|
|
static::cache_set($key, $value);
|
|
}
|
|
return $value;
|
|
}
|
|
|
|
/**
|
|
* Initialize the class by binding all the PHP native implementations of
|
|
* functions
|
|
*
|
|
* @return void
|
|
*/
|
|
protected function initializeNative(): void
|
|
{
|
|
$this->callbacks = [
|
|
'session_get' => [$this, 'native_session_get'],
|
|
'session_set' => [$this, 'native_session_set'],
|
|
'cache_get' => [$this, 'native_cache_get'],
|
|
'cache_set' => [$this, 'native_cache_set'],
|
|
'cache' => [$this, 'cache_helper']
|
|
];
|
|
}
|
|
|
|
/**
|
|
* Initialize the class by binding Laravel adapters as the implementation
|
|
* of all functions
|
|
*
|
|
* @return void
|
|
*/
|
|
protected function initializeLaravel(): void
|
|
{
|
|
$this->callbacks = [
|
|
'session_get' => function(string $key) { return \Session::get($key); },
|
|
'session_set' => function(string $key, $value) { \Session::put($key, $value); },
|
|
'cache_get' => function(string $key) { return \Cache::get($key); },
|
|
'cache_set' => function(string $key, $value) { \Cache::set($key, $value); },
|
|
'cache' => [$this, 'cache_helper']
|
|
];
|
|
}
|
|
|
|
/**
|
|
* Retrieve a property out of the $_SESSION variable; null if the
|
|
* property doesn't exist.
|
|
*
|
|
* @param string $key
|
|
* @return mixed
|
|
*/
|
|
protected function native_session_get(string $key)
|
|
{
|
|
$this->native_session_check();
|
|
return $_SESSION[static::LIB_PREFIX.$key] ?? null;
|
|
}
|
|
|
|
/**
|
|
* Set a value in the $_SESSION variable
|
|
*
|
|
* @param string $key
|
|
* @param mixed $value
|
|
* @return void
|
|
*/
|
|
protected function native_session_set(string $key, $value): void
|
|
{
|
|
$this->native_session_check();
|
|
$_SESSION[static::LIB_PREFIX.$key] = $value;
|
|
}
|
|
|
|
/**
|
|
* Check whether a PHP session exists, and if not try and start one
|
|
*
|
|
* @internal
|
|
* @return void
|
|
*/
|
|
protected function native_session_check(): void
|
|
{
|
|
if (session_status() == \PHP_SESSION_NONE)
|
|
session_start();
|
|
else if (session_status() == \PHP_SESSION_DISABLED)
|
|
throw new \Exception("Authkit2 requires PHP sessions are enabled");
|
|
}
|
|
|
|
/**
|
|
* Dummy cache implementation to avoid errors; always returns default
|
|
*
|
|
* @todo Check if apcu is available and use if so? Fall back to temp files?
|
|
* @param string $key cache key to retrieve
|
|
* @param mixed $default value to return if the specified key is not found
|
|
* @return mixed
|
|
*/
|
|
protected function native_cache_get(string $key, $default = null)
|
|
{
|
|
return $default;
|
|
}
|
|
|
|
/**
|
|
* Dummy cache implementation
|
|
*
|
|
* @param string $key cache key to set
|
|
* @param mixed $value value to cache
|
|
* @return void
|
|
*/
|
|
protected function native_cache_set(string $key, $value): void
|
|
{
|
|
}
|
|
|
|
|
|
}
|
|
|