Framework Update

This commit is contained in:
2024-01-31 22:15:08 +08:00
parent b5ff5e8b5f
commit 20678a6a0c
1459 changed files with 25954 additions and 16153 deletions
+159 -108
View File
@@ -16,8 +16,24 @@ namespace Webman;
use FastRoute\Dispatcher\GroupCountBased;
use FastRoute\RouteCollector;
use FilesystemIterator;
use RecursiveDirectoryIterator;
use RecursiveIteratorIterator;
use Webman\Route\Route as RouteObject;
use function array_diff;
use function array_values;
use function class_exists;
use function explode;
use function FastRoute\simpleDispatcher;
use function in_array;
use function is_array;
use function is_callable;
use function is_file;
use function is_scalar;
use function is_string;
use function json_encode;
use function method_exists;
use function strpos;
/**
* Class Route
@@ -28,124 +44,129 @@ class Route
/**
* @var Route
*/
protected static $_instance = null;
protected static $instance = null;
/**
* @var GroupCountBased
*/
protected static $_dispatcher = null;
protected static $dispatcher = null;
/**
* @var RouteCollector
*/
protected static $_collector = null;
protected static $collector = null;
/**
* @var null|callable
*/
protected static $_fallback = [];
protected static $fallback = [];
/**
* @var array
*/
protected static $_nameList = [];
protected static $nameList = [];
/**
* @var string
*/
protected static $_groupPrefix = '';
protected static $groupPrefix = '';
/**
* @var bool
*/
protected static $_disableDefaultRoute = [];
protected static $disableDefaultRoute = [];
/**
* @var RouteObject[]
*/
protected static $_allRoutes = [];
protected static $allRoutes = [];
/**
* @var RouteObject[]
*/
protected $_routes = [];
protected $routes = [];
/**
* @var Route[]
*/
protected $children = [];
/**
* @param string $path
* @param callable $callback
* @param callable|mixed $callback
* @return RouteObject
*/
public static function get(string $path, $callback)
public static function get(string $path, $callback): RouteObject
{
return static::addRoute('GET', $path, $callback);
}
/**
* @param string $path
* @param callable $callback
* @param callable|mixed $callback
* @return RouteObject
*/
public static function post(string $path, $callback)
public static function post(string $path, $callback): RouteObject
{
return static::addRoute('POST', $path, $callback);
}
/**
* @param string $path
* @param callable $callback
* @param callable|mixed $callback
* @return RouteObject
*/
public static function put(string $path, $callback)
public static function put(string $path, $callback): RouteObject
{
return static::addRoute('PUT', $path, $callback);
}
/**
* @param string $path
* @param callable $callback
* @param callable|mixed $callback
* @return RouteObject
*/
public static function patch(string $path, $callback)
public static function patch(string $path, $callback): RouteObject
{
return static::addRoute('PATCH', $path, $callback);
}
/**
* @param string $path
* @param callable $callback
* @param callable|mixed $callback
* @return RouteObject
*/
public static function delete(string $path, $callback)
public static function delete(string $path, $callback): RouteObject
{
return static::addRoute('DELETE', $path, $callback);
}
/**
* @param string $path
* @param callable $callback
* @param callable|mixed $callback
* @return RouteObject
*/
public static function head(string $path, $callback)
public static function head(string $path, $callback): RouteObject
{
return static::addRoute('HEAD', $path, $callback);
}
/**
* @param string $path
* @param callable $callback
* @param callable|mixed $callback
* @return RouteObject
*/
public static function options(string $path, $callback)
public static function options(string $path, $callback): RouteObject
{
return static::addRoute('OPTIONS', $path, $callback);
}
/**
* @param string $path
* @param callable $callback
* @param callable|mixed $callback
* @return RouteObject
*/
public static function any(string $path, $callback)
public static function any(string $path, $callback): RouteObject
{
return static::addRoute(['GET', 'POST', 'PUT', 'DELETE', 'PATCH', 'HEAD', 'OPTIONS'], $path, $callback);
}
@@ -153,10 +174,10 @@ class Route
/**
* @param $method
* @param string $path
* @param callable $callback
* @param callable|mixed $callback
* @return RouteObject
*/
public static function add($method, string $path, $callback)
public static function add($method, string $path, $callback): RouteObject
{
return static::addRoute($method, $path, $callback);
}
@@ -166,18 +187,22 @@ class Route
* @param callable|null $callback
* @return static
*/
public static function group($path, callable $callback = null)
public static function group($path, callable $callback = null): Route
{
if ($callback === null) {
$callback = $path;
$path = '';
}
$previous_group_prefix = static::$_groupPrefix;
static::$_groupPrefix = $previous_group_prefix . $path;
$instance = static::$_instance = new static;
static::$_collector->addGroup($path, $callback);
static::$_instance = null;
static::$_groupPrefix = $previous_group_prefix;
$previousGroupPrefix = static::$groupPrefix;
static::$groupPrefix = $previousGroupPrefix . $path;
$previousInstance = static::$instance;
$instance = static::$instance = new static;
static::$collector->addGroup($path, $callback);
static::$groupPrefix = $previousGroupPrefix;
static::$instance = $previousInstance;
if ($previousInstance) {
$previousInstance->addChild($instance);
}
return $instance;
}
@@ -190,41 +215,41 @@ class Route
public static function resource(string $name, string $controller, array $options = [])
{
$name = trim($name, '/');
if (\is_array($options) && !empty($options)) {
$diff_options = \array_diff($options, ['index', 'create', 'store', 'update', 'show', 'edit', 'destroy', 'recovery']);
if (!empty($diff_options)) {
foreach ($diff_options as $action) {
static::any("/{$name}/{$action}[/{id}]", [$controller, $action])->name("{$name}.{$action}");
if (is_array($options) && !empty($options)) {
$diffOptions = array_diff($options, ['index', 'create', 'store', 'update', 'show', 'edit', 'destroy', 'recovery']);
if (!empty($diffOptions)) {
foreach ($diffOptions as $action) {
static::any("/$name/{$action}[/{id}]", [$controller, $action])->name("$name.{$action}");
}
}
// 注册路由 由于顺序不同会导致路由无效 因此不适用循环注册
if (\in_array('index', $options)) static::get("/{$name}", [$controller, 'index'])->name("{$name}.index");
if (\in_array('create', $options)) static::get("/{$name}/create", [$controller, 'create'])->name("{$name}.create");
if (\in_array('store', $options)) static::post("/{$name}", [$controller, 'store'])->name("{$name}.store");
if (\in_array('update', $options)) static::put("/{$name}/{id}", [$controller, 'update'])->name("{$name}.update");
if (\in_array('show', $options)) static::get("/{$name}/{id}", [$controller, 'show'])->name("{$name}.show");
if (\in_array('edit', $options)) static::get("/{$name}/{id}/edit", [$controller, 'edit'])->name("{$name}.edit");
if (\in_array('destroy', $options)) static::delete("/{$name}/{id}", [$controller, 'destroy'])->name("{$name}.destroy");
if (\in_array('recovery', $options)) static::put("/{$name}/{id}/recovery", [$controller, 'recovery'])->name("{$name}.recovery");
if (in_array('index', $options)) static::get("/$name", [$controller, 'index'])->name("$name.index");
if (in_array('create', $options)) static::get("/$name/create", [$controller, 'create'])->name("$name.create");
if (in_array('store', $options)) static::post("/$name", [$controller, 'store'])->name("$name.store");
if (in_array('update', $options)) static::put("/$name/{id}", [$controller, 'update'])->name("$name.update");
if (in_array('show', $options)) static::get("/$name/{id}", [$controller, 'show'])->name("$name.show");
if (in_array('edit', $options)) static::get("/$name/{id}/edit", [$controller, 'edit'])->name("$name.edit");
if (in_array('destroy', $options)) static::delete("/$name/{id}", [$controller, 'destroy'])->name("$name.destroy");
if (in_array('recovery', $options)) static::put("/$name/{id}/recovery", [$controller, 'recovery'])->name("$name.recovery");
} else {
//为空时自动注册所有常用路由
if (\method_exists($controller, 'index')) static::get("/{$name}", [$controller, 'index'])->name("{$name}.index");
if (\method_exists($controller, 'create')) static::get("/{$name}/create", [$controller, 'create'])->name("{$name}.create");
if (\method_exists($controller, 'store')) static::post("/{$name}", [$controller, 'store'])->name("{$name}.store");
if (\method_exists($controller, 'update')) static::put("/{$name}/{id}", [$controller, 'update'])->name("{$name}.update");
if (\method_exists($controller, 'show')) static::get("/{$name}/{id}", [$controller, 'show'])->name("{$name}.show");
if (\method_exists($controller, 'edit')) static::get("/{$name}/{id}/edit", [$controller, 'edit'])->name("{$name}.edit");
if (\method_exists($controller, 'destroy')) static::delete("/{$name}/{id}", [$controller, 'destroy'])->name("{$name}.destroy");
if (\method_exists($controller, 'recovery')) static::put("/{$name}/{id}/recovery", [$controller, 'recovery'])->name("{$name}.recovery");
if (method_exists($controller, 'index')) static::get("/$name", [$controller, 'index'])->name("$name.index");
if (method_exists($controller, 'create')) static::get("/$name/create", [$controller, 'create'])->name("$name.create");
if (method_exists($controller, 'store')) static::post("/$name", [$controller, 'store'])->name("$name.store");
if (method_exists($controller, 'update')) static::put("/$name/{id}", [$controller, 'update'])->name("$name.update");
if (method_exists($controller, 'show')) static::get("/$name/{id}", [$controller, 'show'])->name("$name.show");
if (method_exists($controller, 'edit')) static::get("/$name/{id}/edit", [$controller, 'edit'])->name("$name.edit");
if (method_exists($controller, 'destroy')) static::delete("/$name/{id}", [$controller, 'destroy'])->name("$name.destroy");
if (method_exists($controller, 'recovery')) static::put("/$name/{id}/recovery", [$controller, 'recovery'])->name("$name.recovery");
}
}
/**
* @return RouteObject[]
*/
public static function getRoutes()
public static function getRoutes(): array
{
return static::$_allRoutes;
return static::$allRoutes;
}
/**
@@ -234,26 +259,31 @@ class Route
*/
public static function disableDefaultRoute($plugin = '')
{
static::$_disableDefaultRoute[$plugin] = true;
static::$disableDefaultRoute[$plugin] = true;
}
/**
* @param string $plugin
* @return bool
*/
public static function hasDisableDefaultRoute($plugin = '')
public static function hasDisableDefaultRoute(string $plugin = ''): bool
{
return static::$_disableDefaultRoute[$plugin] ?? false;
return static::$disableDefaultRoute[$plugin] ?? false;
}
/**
* @param $middleware
* @return $this
*/
public function middleware($middleware)
public function middleware($middleware): Route
{
foreach ($this->_routes as $route) {
foreach ($this->routes as $route) {
$route->middleware($middleware);
}
foreach ($this->getChildren() as $child) {
$child->middleware($middleware);
}
return $this;
}
/**
@@ -261,59 +291,75 @@ class Route
*/
public function collect(RouteObject $route)
{
$this->_routes[] = $route;
$this->routes[] = $route;
}
/**
* @param $name
* @param string $name
* @param RouteObject $instance
*/
public static function setByName(string $name, RouteObject $instance)
{
static::$_nameList[$name] = $instance;
static::$nameList[$name] = $instance;
}
/**
* @param $name
* @param string $name
* @return null|RouteObject
*/
public static function getByName(string $name)
public static function getByName(string $name): ?RouteObject
{
return static::$_nameList[$name] ?? null;
return static::$nameList[$name] ?? null;
}
/**
* @param Route $route
* @return void
*/
public function addChild(Route $route)
{
$this->children[] = $route;
}
/**
* @return Route[]
*/
public function getChildren()
{
return $this->children;
}
/**
* @param string $method
* @param string $path
* @return array
*/
public static function dispatch($method, string $path)
public static function dispatch(string $method, string $path): array
{
return static::$_dispatcher->dispatch($method, $path);
return static::$dispatcher->dispatch($method, $path);
}
/**
* @param string $path
* @param callable $callback
* @param callable|mixed $callback
* @return callable|false|string[]
*/
public static function convertToCallable(string $path, $callback)
{
if (\is_string($callback) && \strpos($callback, '@')) {
$callback = \explode('@', $callback, 2);
if (is_string($callback) && strpos($callback, '@')) {
$callback = explode('@', $callback, 2);
}
if (!\is_array($callback)) {
if (!\is_callable($callback)) {
$call_str = \is_scalar($callback) ? $callback : 'Closure';
echo "Route $path $call_str is not callable\n";
if (!is_array($callback)) {
if (!is_callable($callback)) {
$callStr = is_scalar($callback) ? $callback : 'Closure';
echo "Route $path $callStr is not callable\n";
return false;
}
} else {
$callback = \array_values($callback);
if (!isset($callback[1]) || !\class_exists($callback[0]) || !\method_exists($callback[0], $callback[1])) {
echo "Route $path " . \json_encode($callback) . " is not callable\n";
$callback = array_values($callback);
if (!isset($callback[1]) || !class_exists($callback[0]) || !method_exists($callback[0], $callback[1])) {
echo "Route $path " . json_encode($callback) . " is not callable\n";
return false;
}
}
@@ -322,56 +368,57 @@ class Route
}
/**
* @param array $methods
* @param array|string $methods
* @param string $path
* @param callable $callback
* @param callable|mixed $callback
* @return RouteObject
*/
protected static function addRoute($methods, string $path, $callback)
protected static function addRoute($methods, string $path, $callback): RouteObject
{
$route = new RouteObject($methods, static::$_groupPrefix . $path, $callback);
static::$_allRoutes[] = $route;
$route = new RouteObject($methods, static::$groupPrefix . $path, $callback);
static::$allRoutes[] = $route;
if ($callback = static::convertToCallable($path, $callback)) {
static::$_collector->addRoute($methods, $path, ['callback' => $callback, 'route' => $route]);
static::$collector->addRoute($methods, $path, ['callback' => $callback, 'route' => $route]);
}
if (static::$_instance) {
static::$_instance->collect($route);
if (static::$instance) {
static::$instance->collect($route);
}
return $route;
}
/**
* @param array $paths
* Load.
* @param mixed $paths
* @return void
*/
public static function load($paths)
{
if (!\is_array($paths)) {
if (!is_array($paths)) {
return;
}
static::$_dispatcher = simpleDispatcher(function (RouteCollector $route) use ($paths) {
static::$dispatcher = simpleDispatcher(function (RouteCollector $route) use ($paths) {
Route::setCollector($route);
foreach ($paths as $config_path) {
$route_config_file = $config_path . '/route.php';
if (\is_file($route_config_file)) {
require_once $route_config_file;
foreach ($paths as $configPath) {
$routeConfigFile = $configPath . '/route.php';
if (is_file($routeConfigFile)) {
require_once $routeConfigFile;
}
if (!is_dir($plugin_config_path = $config_path . '/plugin')) {
if (!is_dir($pluginConfigPath = $configPath . '/plugin')) {
continue;
}
$dir_iterator = new \RecursiveDirectoryIterator($plugin_config_path, \FilesystemIterator::FOLLOW_SYMLINKS);
$iterator = new \RecursiveIteratorIterator($dir_iterator);
$dirIterator = new RecursiveDirectoryIterator($pluginConfigPath, FilesystemIterator::FOLLOW_SYMLINKS);
$iterator = new RecursiveIteratorIterator($dirIterator);
foreach ($iterator as $file) {
if ($file->getBaseName('.php') !== 'route') {
continue;
}
$app_config_file = pathinfo($file, PATHINFO_DIRNAME) . '/app.php';
if (!is_file($app_config_file)) {
$appConfigFile = pathinfo($file, PATHINFO_DIRNAME) . '/app.php';
if (!is_file($appConfigFile)) {
continue;
}
$app_config = include $app_config_file;
if (empty($app_config['enable'])) {
$appConfig = include $appConfigFile;
if (empty($appConfig['enable'])) {
continue;
}
require_once $file;
@@ -381,35 +428,39 @@ class Route
}
/**
* SetCollector.
* @param RouteCollector $route
* @return void
*/
public static function setCollector(RouteCollector $route)
{
static::$_collector = $route;
static::$collector = $route;
}
/**
* @param callable $callback
* Fallback.
* @param callable|mixed $callback
* @param string $plugin
* @return void
*/
public static function fallback(callable $callback, string $plugin = '')
{
static::$_fallback[$plugin] = $callback;
static::$fallback[$plugin] = $callback;
}
/**
* GetFallBack.
* @param string $plugin
* @return callable|null
*/
public static function getFallback(string $plugin = '')
public static function getFallback(string $plugin = ''): ?callable
{
return static::$_fallback[$plugin] ?? null;
return static::$fallback[$plugin] ?? null;
}
/**
* @deprecated
* @return void
* @deprecated
*/
public static function container()
{