mirror of
https://github.com/fruithost/Panel.git
synced 2026-10-26 04:56:41 +09:00
232 lines
5.8 KiB
PHP
232 lines
5.8 KiB
PHP
<?php
|
|
/**
|
|
* fruithost | OpenSource Hosting
|
|
*
|
|
* @author Adrian Preuß
|
|
* @version 1.0.0
|
|
* @license MIT
|
|
*/
|
|
|
|
namespace fruithost\System;
|
|
|
|
use fruithost\Accounting\Auth;
|
|
|
|
class Hooks {
|
|
protected array $filters = [];
|
|
protected array $merged_filters = [];
|
|
protected array $actions = [];
|
|
protected array $current_filter = [];
|
|
|
|
protected function createID(mixed $method) : string | false {
|
|
if(is_string($method)) {
|
|
return $method;
|
|
}
|
|
|
|
if(is_object($method)) {
|
|
$method = [ $method, '' ];
|
|
} else {
|
|
$method = (array) $method;
|
|
}
|
|
|
|
if(is_object($method[0])) {
|
|
return spl_object_hash($method[0]) . $method[1];
|
|
}
|
|
|
|
if(is_string($method[0])) {
|
|
return $method[0] . $method[1];
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
public function callAllHook(array $args) : void {
|
|
reset($this->filters['all']);
|
|
|
|
do {
|
|
foreach(current($this->filters['all']) AS $entry) {
|
|
if(!empty($entry['method']) && (isset($entry['logged_in']) && ($entry['logged_in'] == true && Auth::isLoggedIn() || $entry['logged_in'] == false))) {
|
|
call_user_func_array($entry['method'], $args);
|
|
}
|
|
}
|
|
} while(next($this->filters['all']) !== false);
|
|
}
|
|
|
|
/* Filter */
|
|
public function addFilter(string $name, \Closure | array $method, int $priority = 50, bool $logged_in = true) : bool {
|
|
$this->filters[$name][$priority][$this->createID($method)] = [
|
|
'method' => $method,
|
|
'logged_in' => $logged_in
|
|
];
|
|
|
|
unset($this->merged_filters[$name]);
|
|
return true;
|
|
}
|
|
|
|
public function removeFilter(string $name, \Closure | array $method, int $priority = 50) : bool {
|
|
$method = $this->createID($method);
|
|
|
|
if(!isset($this->filters[$name][$priority][$method])) {
|
|
return false;
|
|
}
|
|
|
|
unset($this->filters[$name][$priority][$method]);
|
|
|
|
if(empty($this->filters[$name][$priority])) {
|
|
unset($this->filters[$name][$priority]);
|
|
}
|
|
|
|
unset($this->merged_filters[$name]);
|
|
return true;
|
|
}
|
|
|
|
public function hasFilter(string $name, mixed $method = false) : bool {
|
|
$exists = isset($this->filters[$name]);
|
|
|
|
if($method === false || !$exists) {
|
|
return $exists;
|
|
}
|
|
|
|
if(!($id = $this->createID($method))) {
|
|
return false;
|
|
}
|
|
|
|
foreach(array_keys($this->filters[$name]) AS $priority) {
|
|
if(isset($this->filters[$name][$priority][$id])) {
|
|
return $priority;
|
|
}
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
public function applyFilter(string $name, mixed $arguments, bool $logged_in = true) : mixed {
|
|
$args = [];
|
|
$value = $arguments;
|
|
|
|
if(isset($this->filters['all'])) {
|
|
$this->current_filter[] = $name;
|
|
$args = func_get_args();
|
|
|
|
$this->callAllHook($args);
|
|
}
|
|
|
|
if(!isset($this->filters[$name])) {
|
|
if(isset($this->filters['all'])) {
|
|
array_pop($this->current_filter);
|
|
}
|
|
|
|
return $value;
|
|
}
|
|
|
|
if(!isset($this->filters['all'])) {
|
|
$this->current_filter[] = $name;
|
|
}
|
|
|
|
if(!isset($this->merged_filters[$name])) {
|
|
ksort($this->filters[$name]);
|
|
$this->merged_filters[$name] = true;
|
|
}
|
|
|
|
reset($this->filters[$name]);
|
|
|
|
if(empty($args)) {
|
|
$args = func_get_args();
|
|
}
|
|
|
|
array_shift($args);
|
|
|
|
do {
|
|
foreach(current($this->filters[$name]) AS $entry) {
|
|
if(!empty($entry['method']) && (!$logged_in || (isset($entry['logged_in']) && $logged_in && ($entry['logged_in'] == true && Auth::isLoggedIn() || $entry['logged_in'] == false)))) {
|
|
if($value instanceof HookParameters) {
|
|
$args = $value->get();
|
|
} else {
|
|
$args[0] = $value;
|
|
}
|
|
|
|
$value = call_user_func_array($entry['method'], $args);
|
|
}
|
|
}
|
|
} while(next($this->filters[$name]) !== false);
|
|
|
|
array_pop($this->current_filter);
|
|
|
|
return $value;
|
|
}
|
|
|
|
/* Actions */
|
|
public function addAction(string $name, \Closure | array $method, int $priority = 50, bool $logged_in = true) : bool {
|
|
return $this->addFilter($name, $method, $priority, $logged_in);
|
|
}
|
|
|
|
public function removeAction(string $name, \Closure | array $method, int $priority = 50) : bool {
|
|
return $this->removeFilter($name, $method, $priority);
|
|
}
|
|
|
|
public function hasAction(string $name, mixed $method = false) : bool {
|
|
return $this->hasFilter($name, $method);
|
|
}
|
|
|
|
public function runAction(string $name, mixed $arguments = null, bool $logged_in = true) : bool {
|
|
if(!is_array($this->actions)) {
|
|
$this->actions = [];
|
|
}
|
|
|
|
if(isset($this->actions[$name])) {
|
|
++$this->actions[$name];
|
|
} else {
|
|
$this->actions[$name] = 1;
|
|
}
|
|
|
|
if(isset($this->filters['all'])) {
|
|
$this->current_filter[] = $name;
|
|
$all_args = func_get_args();
|
|
|
|
$this->callAllHook($all_args);
|
|
}
|
|
|
|
if(!isset($this->filters[$name])) {
|
|
if(isset($this->filters['all'])) {
|
|
array_pop($this->current_filter);
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
if(!isset($this->filters['all'])) {
|
|
$this->current_filter[] = $name;
|
|
}
|
|
|
|
$args = [];
|
|
|
|
if(is_array($arguments) && isset($arguments[0]) && is_object($arguments[0]) && count($arguments) == 1) {
|
|
$args[] = &$arguments[0];
|
|
} else {
|
|
$args[] = $arguments;
|
|
}
|
|
|
|
for($a = 2; $a < func_num_args(); $a++) {
|
|
$args[] = func_get_arg($a);
|
|
}
|
|
|
|
if(!isset($this->merged_filters[$name])) {
|
|
ksort($this->filters[$name]);
|
|
$this->merged_filters[$name] = true;
|
|
}
|
|
|
|
reset($this->filters[$name]);
|
|
|
|
do {
|
|
foreach(current($this->filters[$name]) AS $entry) {
|
|
if(!empty($entry['method']) && (!$logged_in || (isset($entry['logged_in']) && $logged_in && ($entry['logged_in'] == true && Auth::isLoggedIn() || $entry['logged_in'] == false)))) {
|
|
call_user_func_array($entry['method'], $args);
|
|
}
|
|
}
|
|
} while(next($this->filters[$name]) !== false);
|
|
|
|
array_pop($this->current_filter);
|
|
|
|
return true;
|
|
}
|
|
}
|
|
?>
|