support plugin

This commit is contained in:
xiaomlove
2022-06-03 03:42:53 +08:00
parent 29d414ce0a
commit 44c750234a
21 changed files with 333 additions and 68 deletions
+27
View File
@@ -0,0 +1,27 @@
<?php
namespace Nexus\Plugin;
use Illuminate\Support\Arr;
use Illuminate\Support\Facades\Artisan;
abstract class BasePlugin
{
abstract function install();
abstract function boot();
public function runMigrations($dir, $rollback = false)
{
$command = "migrate";
if ($rollback) {
$command .= ":rollback";
}
$command .= " --realpath --force";
foreach (glob("$dir/*.php") as $file) {
$file = str_replace('\\', '/', $file);
$toExecute = "$command --path=$file";
do_log("command: $toExecute");
Artisan::call($toExecute);
}
}
}
+71
View File
@@ -0,0 +1,71 @@
<?php
namespace Nexus\Plugin;
class Hook
{
private static array $callbacks = [];
public function addFilter($name, $function, $priority, $argc)
{
$id = $this->buildUniqueId($function);
$isPriorityExists = isset(self::$callbacks[$priority]);
self::$callbacks[$name][$priority][$id] = ['function' => $function, 'argc' => $argc];
if (!$isPriorityExists && count(self::$callbacks) > 1) {
krsort(self::$callbacks, SORT_NUMERIC);
}
}
private function buildUniqueId($function): string
{
if (is_string($function)) {
return $function;
} elseif (is_object($function) && ($function instanceof \Closure)) {
//Closure
return spl_object_hash($function);
} elseif (is_array($function)) {
if (is_object($function[0])) {
return spl_object_hash($function[0]).$function[1];
} elseif (is_string($function[0])) {
return $function[0].'::'.$function[1];
}
}
throw new \InvalidArgumentException("Invalid function, type: " . gettype($function));
}
public function applyFilter($name, $value = '')
{
if (!isset(self::$callbacks[$name])) {
do_log("No this hook: $name");
return null;
}
$args = func_get_args();
reset(self::$callbacks[$name]);
do_log("name: $name, args: " . json_encode($args));
do {
foreach ((array)current(self::$callbacks[$name]) as $callback) {
$args[1] = $value;
$value = call_user_func_array($callback['function'], array_slice($args, 1, $callback['argc']));
}
}
while (next(self::$callbacks[$name]) !== false);
return $value;
}
public function addAction($name, $function, $priority, $argc)
{
return $this->addFilter($name, $function, $priority, $argc);
}
public function doAction($name, ...$args)
{
$this->applyFilter(...func_get_args());
}
public function dump()
{
echo '<pre>';
var_dump(self::$callbacks);
echo '</pre>';
}
}
+57
View File
@@ -0,0 +1,57 @@
<?php
namespace Nexus\Plugin;
class Plugin
{
private static mixed $providers = null;
public function __construct()
{
$this->loadProviders();
if (!isRunningInConsole()) {
$this->bootPlugins();
}
}
public function enabled($name): bool
{
return !empty(self::$providers[$name]['providers']);
}
public function getMainClass($name)
{
if (isset(self::$providers[$name]['providers'][0])) {
$className = self::$providers[$name]['providers'][0];
$className = str_replace('ServiceProvider', '', $className);
if (class_exists($className)) {
return new $className;
}
}
}
private function bootPlugins()
{
foreach (self::$providers as $name => $providers) {
$provider = $providers['providers'][0];
$parts = explode('\\', $provider);
if ($parts[0] == 'NexusPlugin') {
$className = str_replace('ServiceProvider', '', $provider);
call_user_func([new $className, 'boot']);
}
}
}
private function loadProviders()
{
if (is_null(self::$providers)) {
$path = ROOT_PATH . 'bootstrap/cache/packages.php';
if (file_exists($path)) {
self::$providers = require $path;
} else {
self::$providers = [];
}
}
}
}