2 Commits
v0.5.1 ... main

Author SHA1 Message Date
李东云
4484fb1eea chore(deps): 升级 hyperf 框架依赖至 3.0 版本
- 将所有 hyperf 组件版本从 2.2.x 升级到 3.0.x
- 更新 singularity/hdk-core 依赖从0.1.6 到 1.0.0
- 移除 minimum-stability 配置项
- 添加 runtime 目录到 .gitignore
- 更新 RedisArray 类型提示和返回值
- 为监听器方法添加 void 返回类型
- 更新 ColorLineFormatter 的 LogRecord 类型提示
- 添加 hyperf.php 入口文件
2025-09-28 09:41:31 +08:00
李东云
606672b1d6 refactor(admin): 迁移到 php8.2
- 将多个匿名函数改为箭头函数以提高可读性
- 修复部分变量类型不匹配的问题,增加类型转换
- 删除冗余的代码和注释,简化逻辑
- 更新数据库操作相关代码,提高安全性
- 优化数组处理和字符串操作方法
- 统一代码风格,提升整体代码质量
2025-09-26 18:10:31 +08:00
81 changed files with 5782 additions and 2034 deletions

1
.gitignore vendored
View File

@@ -1,4 +1,5 @@
.idea/ .idea/
vendor/ vendor/
runtime/
.phpunit.result.cache .phpunit.result.cache
.php-cs-fixer.cache .php-cs-fixer.cache

32
bin/hyperf.php Normal file
View File

@@ -0,0 +1,32 @@
#!/usr/bin/env php
<?php
declare(strict_types=1);
use Hyperf\Di\ClassLoader;
use Hyperf\Di\Container;
use Hyperf\Di\Definition\DefinitionSource;
use Hyperf\Utils\ApplicationContext;
use Psr\Container\ContainerInterface;
use Swoole\Runtime;
ini_set('display_errors', 'on');
ini_set('display_startup_errors', 'on');
error_reporting(E_ALL);
date_default_timezone_set('Asia/Shanghai');
!defined('BASE_PATH') && define('BASE_PATH', dirname(__DIR__, 1));
!defined('SWOOLE_HOOK_FLAGS') && define('SWOOLE_HOOK_FLAGS', SWOOLE_HOOK_ALL);
Runtime::enableCoroutine();
require BASE_PATH . '/vendor/autoload.php';
ClassLoader::init();
$container = new Container(new DefinitionSource([]));
if (!$container instanceof ContainerInterface) {
throw new RuntimeException('The dependency injection container is invalid.');
}
$container = ApplicationContext::setContainer($container);

View File

@@ -1,133 +1,136 @@
{ {
"name": "singularity/hyperf-admin", "name": "singularity/hyperf-admin",
"description": "hyperf-admin", "description": "hyperf-admin",
"authors": [ "authors": [
{ {
"name": "ch4o5", "name": "ch4o5",
"email": "dongyun.li@luxcreo.ai" "email": "dongyun.li@luxcreo.ai"
}, },
{ {
"name": "daodao97", "name": "daodao97",
"email": "daodao97@foxmail.com" "email": "daodao97@foxmail.com"
} }
],
"require": {
"php": ">=8.2",
"ext-json": "*",
"ext-pdo": "*",
"ext-swoole": ">=4.4",
"aliyuncs/oss-sdk-php": "^2.3",
"box/spout": "^3.1",
"hyperf/amqp": "3.0.*",
"hyperf/async-queue": "3.0.*",
"hyperf/cache": "3.0.*",
"hyperf/code-generator": "^0.3.3",
"hyperf/command": "3.0.*",
"hyperf/config": "3.0.*",
"hyperf/constants": "3.0.*",
"hyperf/crontab": "3.0.*",
"hyperf/database": "3.0.*",
"hyperf/db-connection": "3.0.*",
"hyperf/filesystem": "3.0.*",
"hyperf/framework": "3.0.*",
"hyperf/guzzle": "3.0.*",
"hyperf/http-server": "3.0.*",
"hyperf/logger": "3.0.*",
"hyperf/memory": "3.0.*",
"hyperf/metric": "3.0.*",
"hyperf/nsq": "3.0.*",
"hyperf/process": "3.0.*",
"hyperf/redis": "3.0.*",
"hyperf/snowflake": "3.0.*",
"hyperf/validation": "3.0.*",
"nette/php-generator": "^3.4",
"singularity/hdk-core": "^1.0.0",
"xxtime/flysystem-aliyun-oss": "~1.5.0",
"yadakhov/insert-on-duplicate-key": "^1.2",
"zoujingli/ip2region": "^1.0"
},
"replace": {
"hyperf-admin/base-utils": "self.version",
"hyperf-admin/admin": "self.version",
"hyperf-admin/alert-manager": "self.version",
"hyperf-admin/cron-center": "self.version",
"hyperf-admin/event-bus": "self.version",
"hyperf-admin/process-manager": "self.version",
"hyperf-admin/rule-engine": "self.version",
"hyperf-admin/validation": "self.version",
"hyperf-admin/workflow": "self.version",
"hyperf-admin/data-focus": "self.version",
"hyperf-admin/dev-tools": "self.version"
},
"autoload": {
"psr-4": {
"HyperfAdmin\\BaseUtils\\": "src/base-utils/src",
"HyperfAdmin\\Admin\\": "src/admin/src",
"HyperfAdmin\\AlertManager\\": "src/alert-manager/src",
"HyperfAdmin\\CronCenter\\": "src/cron-center/src",
"HyperfAdmin\\DataFocus\\": "src/data-focus/src",
"HyperfAdmin\\DevTools\\": "src/dev-tools/src",
"HyperfAdmin\\EventBus\\": "src/event-bus/src",
"HyperfAdmin\\ProcessManager\\": "src/process-manager/src",
"HyperfAdmin\\RuleEngine\\": "src/rule-engine/src",
"HyperfAdmin\\Validation\\": "src/validation/src",
"HyperfAdmin\\ConfigCenter\\": "src/config-center/src"
},
"files": [
"src/base-utils/src/Helper/array.php",
"src/base-utils/src/Helper/common.php",
"src/base-utils/src/Helper/constants.php",
"src/base-utils/src/Helper/system.php",
"src/data-focus/src/Util/func.php",
"src/event-bus/src/funcs.php",
"src/admin/src/funcs/common.php",
"src/data-focus/src/Util/SimpleHtmlDom.php"
], ],
"require": { "classmap": [
"php": ">=7.4", "src/base-utils/src/classmap"
"ext-json": "*", ]
"ext-pdo": "*", },
"ext-swoole": ">=4.4", "extra": {
"aliyuncs/oss-sdk-php": "^2.3", "hyperf": {
"box/spout": "^3.1", "config": [
"hyperf/amqp": "~2.2.0", "HyperfAdmin\\Admin\\ConfigProvider",
"hyperf/async-queue": "~2.2.0", "HyperfAdmin\\BaseUtils\\ConfigProvider@99",
"hyperf/cache": "~2.2.0", "HyperfAdmin\\AlertManager\\ConfigProvider",
"hyperf/command": "~2.2.0", "HyperfAdmin\\CronCenter\\ConfigProvider",
"hyperf/config": "~2.2.0", "HyperfAdmin\\DataFocus\\ConfigProvider",
"hyperf/constants": "~2.2.0", "HyperfAdmin\\DevTools\\ConfigProvider",
"hyperf/crontab": "~2.2.0", "HyperfAdmin\\EventBus\\ConfigProvider",
"hyperf/database": "~2.2.0", "HyperfAdmin\\ProcessManager\\ConfigProvider",
"hyperf/db-connection": "~2.2.0", "HyperfAdmin\\ConfigCenter\\ConfigProvider"
"hyperf/filesystem": "^2.0", ]
"hyperf/framework": "~2.2.0", }
"hyperf/guzzle": "~2.2.0", },
"hyperf/http-server": "~2.2.0", "prefer-stable": true,
"hyperf/logger": "~2.2.0", "config": {
"hyperf/memory": "~2.2.0", "sort-packages": true,
"hyperf/metric": "~2.2.0", "secure-http": false
"hyperf/nsq": "~2.2.0", },
"hyperf/process": "~2.2.0", "scripts": {
"hyperf/redis": "~2.2.0", "post-root-package-install": [],
"hyperf/snowflake": "~2.2.0", "test": "vendor/bin/pest $1",
"hyperf/validation": "~2.2.0", "cs-fix": "vendor/bin/php-cs-fixer fix $1 --rules=@PSR12 --allow-risky=yes",
"nette/php-generator": "^3.4", "analyse": "vendor/bin/phpstan analyse $1",
"singularity/hdk-core": "^0.1.6", "ci": [
"xxtime/flysystem-aliyun-oss": "~1.5.0", "@analyse publish/ src/ tests/",
"yadakhov/insert-on-duplicate-key": "^1.2", "@cs-fix",
"zoujingli/ip2region": "^1.0" "@test --ci",
"echo CI Success"
]
},
"repositories": {
"nest": {
"type": "composer",
"url": "https://nest.doylee.cn/api/packages/HDK/composer"
}, },
"replace": { "packagist": {
"hyperf-admin/base-utils": "self.version", "type": "composer",
"hyperf-admin/admin": "self.version", "url": "https://mirrors.aliyun.com/composer/"
"hyperf-admin/alert-manager": "self.version", }
"hyperf-admin/cron-center": "self.version", },
"hyperf-admin/event-bus": "self.version", "version": "0.5.1",
"hyperf-admin/process-manager": "self.version", "require-dev": {
"hyperf-admin/rule-engine": "self.version", "rector/rector": "^2.0"
"hyperf-admin/validation": "self.version", }
"hyperf-admin/workflow": "self.version",
"hyperf-admin/data-focus": "self.version",
"hyperf-admin/dev-tools": "self.version"
},
"autoload": {
"psr-4": {
"HyperfAdmin\\BaseUtils\\": "src/base-utils/src",
"HyperfAdmin\\Admin\\": "src/admin/src",
"HyperfAdmin\\AlertManager\\": "src/alert-manager/src",
"HyperfAdmin\\CronCenter\\": "src/cron-center/src",
"HyperfAdmin\\DataFocus\\": "src/data-focus/src",
"HyperfAdmin\\DevTools\\": "src/dev-tools/src",
"HyperfAdmin\\EventBus\\": "src/event-bus/src",
"HyperfAdmin\\ProcessManager\\": "src/process-manager/src",
"HyperfAdmin\\RuleEngine\\": "src/rule-engine/src",
"HyperfAdmin\\Validation\\": "src/validation/src",
"HyperfAdmin\\ConfigCenter\\": "src/config-center/src"
},
"files": [
"src/base-utils/src/Helper/array.php",
"src/base-utils/src/Helper/common.php",
"src/base-utils/src/Helper/constants.php",
"src/base-utils/src/Helper/system.php",
"src/data-focus/src/Util/func.php",
"src/event-bus/src/funcs.php",
"src/admin/src/funcs/common.php",
"src/data-focus/src/Util/SimpleHtmlDom.php"
],
"classmap": [
"src/base-utils/src/classmap"
]
},
"extra": {
"hyperf": {
"config": [
"HyperfAdmin\\Admin\\ConfigProvider",
"HyperfAdmin\\BaseUtils\\ConfigProvider@99",
"HyperfAdmin\\AlertManager\\ConfigProvider",
"HyperfAdmin\\CronCenter\\ConfigProvider",
"HyperfAdmin\\DataFocus\\ConfigProvider",
"HyperfAdmin\\DevTools\\ConfigProvider",
"HyperfAdmin\\EventBus\\ConfigProvider",
"HyperfAdmin\\ProcessManager\\ConfigProvider",
"HyperfAdmin\\ConfigCenter\\ConfigProvider"
]
}
},
"minimum-stability": "dev",
"prefer-stable": true,
"config": {
"sort-packages": true,
"secure-http": false
},
"scripts": {
"post-root-package-install": [],
"test": "vendor/bin/pest $1",
"cs-fix": "vendor/bin/php-cs-fixer fix $1 --rules=@PSR12 --allow-risky=yes",
"analyse": "vendor/bin/phpstan analyse $1",
"ci": [
"@analyse publish/ src/ tests/",
"@cs-fix",
"@test --ci",
"echo CI Success"
]
},
"repositories": {
"lux-map": {
"type": "composer",
"url": "https://satis.luxcreo.cn/"
},
"packagist": {
"type": "composer",
"url": "https://mirrors.cloud.tencent.com/composer/"
}
},
"version": "0.5.1"
} }

6369
composer.lock generated

File diff suppressed because it is too large Load Diff

30
rector.php Normal file
View File

@@ -0,0 +1,30 @@
<?php
declare(strict_types=1);
// rector.php
use Rector\Config\RectorConfig;
use Rector\Set\ValueObject\LevelSetList;
use Rector\Set\ValueObject\SetList;
return static function (RectorConfig $rectorConfig): void {
// 1. 定义需要扫描的文件/目录
$rectorConfig->paths([
__DIR__ . '/src', // 替换为你项目代码的路径,例如:/app, /backend 等
// __DIR__ . '/tests', // 如果你想升级测试代码,也加入
]);
// 2. 一次性应用所有规则到 PHP 8.2 (推荐用于大型升级)
$rectorConfig->sets([
// 这将包含从 7.4 到 8.1 的所有升级规则,以及 8.2 的所有新规则
LevelSetList::UP_TO_PHP_82,
// 建议同时加入一些代码质量改进的规则
SetList::DEAD_CODE, // 移除无用代码
]);
// 可选:跳过某些文件或规则
// $rectorConfig->skip([
// // 例如:跳过特定文件
// // __DIR__ . '/src/Legacy/old_file.php',
// ]);
};

View File

@@ -7,4 +7,4 @@ docker run \
-v "$(pwd)":/srv/www \ -v "$(pwd)":/srv/www \
-v ~/.ssh:/root/.ssh \ -v ~/.ssh:/root/.ssh \
-v ~/.gitconfig:/root/.gitconfig \ -v ~/.gitconfig:/root/.gitconfig \
harbor.luxcreo.cn/library/hyperf:7.4-swoole /bin/ash harbor.luxcreo.cn/library/hyperf:8.2-swoole /bin/ash

View File

@@ -36,7 +36,7 @@ abstract class AdminAbstractController extends AbstractController
public function getRecordHistory() public function getRecordHistory()
{ {
$history_versions = $this->getEntity()->lastVersion($this->previous_version_number); $history_versions = $this->getEntity()->lastVersion($this->previous_version_number);
$history_versions = array_node_append($history_versions, 'user_id', 'username', function ($uids) { return array_node_append($history_versions, 'user_id', 'username', function ($uids) {
$ret = User::query()->select(['id', 'username'])->whereIn('id', $uids)->get(); $ret = User::query()->select(['id', 'username'])->whereIn('id', $uids)->get();
if (!$ret) { if (!$ret) {
return []; return [];
@@ -49,14 +49,11 @@ abstract class AdminAbstractController extends AbstractController
} }
return $ret; return $ret;
}); });
return $history_versions;
} }
/** /**
* 新版本检查 * 新版本检查
* *
* @param int $id
* @param int $last_ver_id
* *
* @return array * @return array
*/ */

View File

@@ -94,7 +94,7 @@ class LogController extends AdminAbstractController
'width' => '480px', 'width' => '480px',
'render' => function ($field, $row) { 'render' => function ($field, $row) {
if (!is_array($row['detail_json'])) { if (!is_array($row['detail_json'])) {
$row['detail_json'] = json_decode($row['detail_json'], true); $row['detail_json'] = json_decode((string) $row['detail_json'], true);
} }
return $row['detail_json']['description'] ?? ''; return $row['detail_json']['description'] ?? '';
@@ -112,7 +112,7 @@ class LogController extends AdminAbstractController
'width' => '200px', 'width' => '200px',
'render' => function ($field, $row) { 'render' => function ($field, $row) {
if (!is_array($row['detail_json'])) { if (!is_array($row['detail_json'])) {
$row['detail_json'] = json_decode($row['detail_json'], true); $row['detail_json'] = json_decode((string) $row['detail_json'], true);
} }
return $row['detail_json']['remark'] ?? ''; return $row['detail_json']['remark'] ?? '';

View File

@@ -252,13 +252,11 @@ class MenuController extends AdminAbstractController
'tabs' => function() { 'tabs' => function() {
$conf = \HyperfAdmin\Admin\Service\CommonConfig::getValByName('website_config'); $conf = \HyperfAdmin\Admin\Service\CommonConfig::getValByName('website_config');
$system_module = $conf['system_module'] ?? []; $system_module = $conf['system_module'] ?? [];
return array_map(function ($item) { return array_map(fn($item) => [
return [ 'label' => $item['label'],
'label' => $item['label'], 'value' => $item['name'],
'value' => $item['name'], 'icon' => $item['icon']
'icon' => $item['icon'] ], $system_module);
];
}, $system_module);
}, },
'rowActions' => [ 'rowActions' => [
[ [
@@ -382,9 +380,9 @@ class MenuController extends AdminAbstractController
} }
return $item; return $item;
}, array_filter(explode(',', $record['permission']))); }, array_filter(explode(',', (string) $record['permission'])));
} }
$scaffold_action = json_decode($record['scaffold_action'], true); $scaffold_action = json_decode((string) $record['scaffold_action'], true);
$record['scaffold_action'] = $scaffold_action ? array_keys($scaffold_action) : []; $record['scaffold_action'] = $scaffold_action ? array_keys($scaffold_action) : [];
$record['pid'] = (new Menu())->getPathNodeIds($id); $record['pid'] = (new Menu())->getPathNodeIds($id);
} }
@@ -395,7 +393,7 @@ class MenuController extends AdminAbstractController
if ($data['path'] == '#' || $data['path'] == '') { if ($data['path'] == '#' || $data['path'] == '') {
$this->exception('菜单路由地址不能为空或"#"', ErrorCode::CODE_ERR_PARAM); $this->exception('菜单路由地址不能为空或"#"', ErrorCode::CODE_ERR_PARAM);
} }
$paths = array_filter(explode('/', $data['path'])); $paths = array_filter(explode('/', (string) $data['path']));
if (count($paths) > 5) { if (count($paths) > 5) {
$this->exception('路由地址层级过深>5请设置精简一些', ErrorCode::CODE_ERR_PARAM); $this->exception('路由地址层级过深>5请设置精简一些', ErrorCode::CODE_ERR_PARAM);
} }
@@ -423,14 +421,14 @@ class MenuController extends AdminAbstractController
protected function afterSave($pk_val, $data, $entity) protected function afterSave($pk_val, $data, $entity)
{ {
// 更新预置的脚手架权限 // 更新预置的脚手架权限
$scaffold_action = json_decode($entity->scaffold_action, true); $scaffold_action = json_decode((string) $entity->scaffold_action, true);
$action_keys = $scaffold_action ? array_keys($scaffold_action) : []; $action_keys = $scaffold_action ? array_keys($scaffold_action) : [];
$need_del_ids = $scaffold_action ? array_values($scaffold_action) : []; $need_del_ids = $scaffold_action ? array_values($scaffold_action) : [];
$router_ids = []; $router_ids = [];
if (!empty($data['scaffold_action'])) { if (!empty($data['scaffold_action'])) {
$need_del_ids = collect($scaffold_action)->except($data['scaffold_action'])->values()->toArray(); $need_del_ids = collect($scaffold_action)->except($data['scaffold_action'])->values()->toArray();
$scaffold_action = collect($scaffold_action)->only($data['scaffold_action'])->toArray(); $scaffold_action = collect($scaffold_action)->only($data['scaffold_action'])->toArray();
$paths = array_filter(explode('/', $data['path'])); $paths = array_filter(explode('/', (string) $data['path']));
array_pop($paths); array_pop($paths);
$prefix = implode('/', $paths); $prefix = implode('/', $paths);
foreach ($data['scaffold_action'] as $k => $action) { foreach ($data['scaffold_action'] as $k => $action) {
@@ -530,7 +528,7 @@ class MenuController extends AdminAbstractController
$route_list = $routes; $route_list = $routes;
} }
foreach ($route_list as $route => $v) { foreach ($route_list as $route => $v) {
$route = is_string($route) ? rtrim($route) : rtrim($v[0]->route); $route = is_string($route) ? rtrim($route) : rtrim((string) $v[0]->route);
$route_key = "$http_method::{$route}"; $route_key = "$http_method::{$route}";
if (in_array($route_key, $conf)) { if (in_array($route_key, $conf)) {
continue; continue;
@@ -555,7 +553,7 @@ class MenuController extends AdminAbstractController
} }
$right_options = []; $right_options = [];
foreach ($conf as $route) { foreach ($conf as $route) {
[$http_method, $uri] = explode("::", $route, 2); [$http_method, $uri] = explode("::", (string) $route, 2);
$dispatcher = container(DispatcherFactory::class)->getDispatcher('http'); $dispatcher = container(DispatcherFactory::class)->getDispatcher('http');
$route_info = $dispatcher->dispatch($http_method, $uri); $route_info = $dispatcher->dispatch($http_method, $uri);
if (!empty($route_info[1]->callback[0])) { if (!empty($route_info[1]->callback[0])) {

View File

@@ -132,7 +132,7 @@ class RoleController extends AdminAbstractController
protected function afterSave($pk_val, $data) protected function afterSave($pk_val, $data)
{ {
$data['permissions'] = json_decode($data['permissions'], true); $data['permissions'] = json_decode((string) $data['permissions'], true);
if (empty($data['permissions'])) { if (empty($data['permissions'])) {
return true; return true;
} }

View File

@@ -29,9 +29,7 @@ class SystemController extends AdminAbstractController
if (isset($config['system_module']) && !$this->auth_service->isSupperAdmin()) { if (isset($config['system_module']) && !$this->auth_service->isSupperAdmin()) {
$user_id = $this->auth_service->get('id'); $user_id = $this->auth_service->get('id');
$modules = $this->permission_service->getModules($user_id); $modules = $this->permission_service->getModules($user_id);
$config['system_module'] = array_filter($config['system_module'], function ($item) use ($modules) { $config['system_module'] = array_filter($config['system_module'], fn($item) => in_array($item['name'], $modules));
return in_array($item['name'], $modules);
});
} }
return $this->success($config); return $this->success($config);
@@ -46,9 +44,7 @@ class SystemController extends AdminAbstractController
$kw = $this->request->input('kw', ''); $kw = $this->request->input('kw', '');
$routes = $this->permission_service->getSystemRouteOptions(); $routes = $this->permission_service->getSystemRouteOptions();
$routes = array_filter($routes, function ($item) use ($kw) { $routes = array_filter($routes, fn($item) => Str::contains($item['value'], $kw));
return Str::contains($item['value'], $kw);
});
return $this->success(array_values($routes)); return $this->success(array_values($routes));
} }

View File

@@ -90,9 +90,7 @@ class UserController extends AdminAbstractController
'type' => 'date_range', 'type' => 'date_range',
], ],
], ],
'hasOne' => function ($field, $row) { 'hasOne' => fn($field, $row) => 'hyperf_admin.'.env('HYPERF_ADMIN_DB_NAME').'.user_role:user_id,role_id',
return 'hyperf_admin.'.env('HYPERF_ADMIN_DB_NAME').'.user_role:user_id,role_id';
},
'table' => [ 'table' => [
'columns' => [ 'columns' => [
'id', 'id',
@@ -100,9 +98,7 @@ class UserController extends AdminAbstractController
'username', 'username',
[ [
'field' => 'mobile', 'field' => 'mobile',
'render' => function ($field, $row) { 'render' => fn($field, $row) => data_desensitization($field, 3, 4),
return data_desensitization($field, 3, 4);
},
], ],
['field' => 'avatar', 'render' => 'avatarRender'], ['field' => 'avatar', 'render' => 'avatarRender'],
'email', 'email',
@@ -235,12 +231,12 @@ class UserController extends AdminAbstractController
public function passwordHash($password) public function passwordHash($password)
{ {
return sha1(md5($password) . md5(config('password.salt'))); return sha1(md5((string) $password) . md5((string) config('password.salt')));
} }
public function logout() public function logout()
{ {
$user = $this->auth_service->logout(); $this->auth_service->logout();
return $this->success(); return $this->success();
} }
@@ -259,9 +255,7 @@ class UserController extends AdminAbstractController
$task = new ExportTasks(); $task = new ExportTasks();
$task->name = $this->request->input('name'); $task->name = $this->request->input('name');
$task->list_api = $url; $task->list_api = $url;
$task->filters = array_filter($this->request->input('filters'), function ($item) { $task->filters = array_filter($this->request->input('filters'), fn($item) => $item !== '');
return $item !== '';
});
$task->operator_id = $this->userId() ?? 0; $task->operator_id = $this->userId() ?? 0;
if ((new ExportService())->getFirstSameTask($task->list_api, $task->filters, $task->operator_id)) { // 如果当天已经有相同过滤条件且还未成功生成文件的任务 if ((new ExportService())->getFirstSameTask($task->list_api, $task->filters, $task->operator_id)) { // 如果当天已经有相同过滤条件且还未成功生成文件的任务
return $this->success([], '已经有相同的任务,请勿重复导出'); return $this->success([], '已经有相同的任务,请勿重复导出');

View File

@@ -22,7 +22,7 @@ class InstallCommand extends HyperfCommand
$sql = file_get_contents(__DIR__ . '/install.sql'); $sql = file_get_contents(__DIR__ . '/install.sql');
$re = Db::connection('hyperf_admin')->getPdo()->exec($sql); Db::connection('hyperf_admin')->getPdo()->exec($sql);
$this->output->success('hyperf-admin db install success'); $this->output->success('hyperf-admin db install success');
} }

View File

@@ -36,7 +36,7 @@ class UpdateCommand extends HyperfCommand
$sql = file_get_contents($update_sql_file); $sql = file_get_contents($update_sql_file);
$re = Db::connection('hyperf_admin')->getPdo()->exec($sql); Db::connection('hyperf_admin')->getPdo()->exec($sql);
$this->output->success('hyperf-admin db update success'); $this->output->success('hyperf-admin db update success');

View File

@@ -116,8 +116,6 @@ class PermissionMiddleware extends CoreMiddleware
} }
/** /**
* @param int $code
* @param string|null $message
* *
* @return \Psr\Http\Message\ResponseInterface * @return \Psr\Http\Message\ResponseInterface
*/ */
@@ -152,7 +150,7 @@ class PermissionMiddleware extends CoreMiddleware
} else { } else {
$body = ''; $body = '';
} }
$ak = str_replace('ha ', '', explode(':', $client_token)[0] ?? ''); $ak = str_replace('ha ', '', explode(':', (string) $client_token)[0] ?? '');
$sk = config('client_user')[$ak] ?? ''; $sk = config('client_user')[$ak] ?? '';
$auth = new AKSK($ak, $sk); $auth = new AKSK($ak, $sk);
$token = $auth->token($method, $path, $host, $query, $content_type, $body); $token = $auth->token($method, $path, $host, $query, $content_type, $body);

View File

@@ -57,7 +57,7 @@ class GlobalConfig extends BaseModel
if(empty($item)) { if(empty($item)) {
return $default; return $default;
} }
$config = json_decode($item[0]['value'], true); $config = json_decode((string) $item[0]['value'], true);
if(is_null($config)) { if(is_null($config)) {
return $default; return $default;
} }
@@ -76,8 +76,8 @@ class GlobalConfig extends BaseModel
public static function setConfig($name, $value, $ext = [], $raw = true) public static function setConfig($name, $value, $ext = [], $raw = true)
{ {
$namespace = ''; $namespace = '';
if(($pos = strpos($name, '.')) !== false) { if(($pos = strpos((string) $name, '.')) !== false) {
$namespace = substr($name, 0, $pos); $namespace = substr((string) $name, 0, $pos);
} }
if($raw) { if($raw) {
$value = json_encode($value); $value = json_encode($value);

View File

@@ -70,7 +70,7 @@ class User extends BaseModel
public function getRolesAttribute($value) public function getRolesAttribute($value)
{ {
return explode(',', $value); return explode(',', (string) $value);
} }
public function setRolesAttribute($value) public function setRolesAttribute($value)

View File

@@ -53,7 +53,7 @@ trait Versionable
public function getMorphClass() public function getMorphClass()
{ {
if (strpos($this->getTable(), '.') !== false) { if (str_contains($this->getTable(), '.')) {
return $this->getTable(); return $this->getTable();
} }
return $this->getConnectionName() . '.' . $this->getTable(); return $this->getConnectionName() . '.' . $this->getTable();
@@ -89,8 +89,6 @@ trait Versionable
/** /**
* 监听saved事件保存表更数据 * 监听saved事件保存表更数据
*
* @param Saved $event
*/ */
public function saved(Saved $event) public function saved(Saved $event)
{ {
@@ -119,8 +117,6 @@ trait Versionable
/** /**
* 记录数据版本前先记录请求 * 记录数据版本前先记录请求
*
* @return RequestLog
*/ */
private function processRequest(): RequestLog private function processRequest(): RequestLog
{ {
@@ -152,7 +148,7 @@ trait Versionable
{ {
$keep = $this->keep_version_count ?? 100; $keep = $this->keep_version_count ?? 100;
$count = $this->versions()->count(); $count = $this->versions()->count();
if ($keep > 0 && $count > $keep) { if ($count > $keep) {
$this->versions()->limit($count - $keep)->delete(); $this->versions()->limit($count - $keep)->delete();
} }
} }
@@ -170,7 +166,6 @@ trait Versionable
/** /**
* 前几个版本 * 前几个版本
* *
* @param int $previous
* *
* @return mixed * @return mixed
*/ */

View File

@@ -80,7 +80,7 @@ class ExportService
} }
$task->fill(['status' => ExportTasks::STATUS_PROCESSING])->save(); $task->fill(['status' => ExportTasks::STATUS_PROCESSING])->save();
$list_api = 'http://127.0.0.1:' . config('server.servers.0.port') . $task->list_api; $list_api = 'http://127.0.0.1:' . config('server.servers.0.port') . $task->list_api;
$query['_page'] = ($query['_page'] ?? 1); $query['_page'] ??= 1;
$size = 100; $size = 100;
$query['_size'] = $size; $query['_size'] = $size;
$query = array_merge($query, $task->filters); $query = array_merge($query, $task->filters);
@@ -95,9 +95,7 @@ class ExportService
$info_api = 'http://127.0.0.1:' . config('server.servers.0.port') . '/' . $subject . '/info'; $info_api = 'http://127.0.0.1:' . config('server.servers.0.port') . '/' . $subject . '/info';
} }
$info = Guzzle::get($info_api, [], $headers); $info = Guzzle::get($info_api, [], $headers);
$table_headers = array_filter($info['payload']['tableHeader'], function ($item) { $table_headers = array_filter($info['payload']['tableHeader'], fn($item) => $item['hidden'] ?? true);
return $item['hidden'] ?? true;
});
$table_headers_str = []; $table_headers_str = [];
foreach($table_headers as $item) { foreach($table_headers as $item) {
$table_headers_str[] = $item['title']; $table_headers_str[] = $item['title'];
@@ -166,9 +164,8 @@ class ExportService
} }
$arr = array_map(function ($item) { $arr = array_map(function ($item) {
$item = csv_big_num($item); $item = csv_big_num($item);
$item = preg_replace('/\\n/', ' ', $item);
return $item; return preg_replace('/\\n/', ' ', (string) $item);
}, $arr); }, $arr);
return implode(',', array_map(function ($item) { return implode(',', array_map(function ($item) {

View File

@@ -9,8 +9,8 @@ class GlobalConfig
public static function setConfig($name, $value, $ext = [], $raw = true) public static function setConfig($name, $value, $ext = [], $raw = true)
{ {
$namespace = ''; $namespace = '';
if(($pos = strpos($name, '.')) !== false) { if(($pos = strpos((string) $name, '.')) !== false) {
$namespace = substr($name, 0, $pos); $namespace = substr((string) $name, 0, $pos);
} }
if($raw) { if($raw) {
$value = json_encode($value); $value = json_encode($value);

View File

@@ -14,11 +14,7 @@ class Menu
{ {
$query = $this->query(); $query = $this->query();
if (!empty($menu_ids)) { if (!empty($menu_ids)) {
$query->where(function ($query) use ($menu_ids) { $query->where(fn($query) => $query->whereIn('id', $menu_ids)->orWhere(fn($query) => $query->where('is_menu', 0)->whereIn('pid', $menu_ids)));
return $query->whereIn('id', $menu_ids)->orWhere(function ($query) use ($menu_ids) {
return $query->where('is_menu', 0)->whereIn('pid', $menu_ids);
});
});
} }
$query = $query->select([ $query = $query->select([
'id', 'id',

View File

@@ -31,11 +31,11 @@ class OperatorLogService
try { try {
// 页面url和名称 // 页面url和名称
$page_url = request()->header('page-url'); $page_url = request()->header('page-url');
$parse_url = parse_url($page_url); $parse_url = parse_url((string) $page_url);
$fragment = $parse_url['fragment'] ?? '/'; // 抽出#后面的部分 $fragment = $parse_url['fragment'] ?? '/'; // 抽出#后面的部分
$fragments = explode('?', $fragment); // 去掉querystring $fragments = explode('?', $fragment); // 去掉querystring
$page_url = array_shift($fragments); $page_url = array_shift($fragments);
$page_name = urldecode(request()->header('page-name', '')); // 页面名称 $page_name = urldecode((string) request()->header('page-name', '')); // 页面名称
$relation_ids = json_encode($ids, JSON_UNESCAPED_UNICODE); // 如果没有版本启用则只记录操作的id $relation_ids = json_encode($ids, JSON_UNESCAPED_UNICODE); // 如果没有版本启用则只记录操作的id
// 关联id-版本id记录 // 关联id-版本id记录
if(is_string($model) && $model) { if(is_string($model) && $model) {

View File

@@ -53,7 +53,7 @@ class PermissionService
if (!is_array($callback)) { if (!is_array($callback)) {
continue; continue;
} }
$route = is_string($route) ? rtrim($route) : rtrim($v[0]->route); $route = is_string($route) ? rtrim($route) : rtrim((string) $v[0]->route);
$route_key = "$http_method::{$route}"; $route_key = "$http_method::{$route}";
$options[] = [ $options[] = [
'value' => $route_key, 'value' => $route_key,
@@ -127,7 +127,7 @@ class PermissionService
if (empty($role_ids)) { if (empty($role_ids)) {
return []; return [];
} }
$routes = RoleMenu::query()->distinct(true)->select(['router_id'])->whereIn('role_id', $role_ids)->get()->toArray(); $routes = RoleMenu::query()->distinct()->select(['router_id'])->whereIn('role_id', $role_ids)->get()->toArray();
return $routes ? array_column($routes, 'router_id') : []; return $routes ? array_column($routes, 'router_id') : [];
} }
@@ -193,7 +193,7 @@ class PermissionService
$resources = []; $resources = [];
foreach ($list as $route) { foreach ($list as $route) {
if (Str::contains($route['permission'], '::')) { if (Str::contains($route['permission'], '::')) {
$permissions = array_filter(explode(',', $route['permission'])); $permissions = array_filter(explode(',', (string) $route['permission']));
foreach ($permissions as $permission) { foreach ($permissions as $permission) {
[ [
$http_method, $http_method,
@@ -206,7 +206,7 @@ class PermissionService
} }
} else { } else {
// 这段代码为兼容老的数据 // 这段代码为兼容老的数据
$paths = array_filter(explode('/', $route['path'])); $paths = array_filter(explode('/', (string) $route['path']));
$suffix = array_pop($paths); $suffix = array_pop($paths);
$prefix = implode('/', $paths); $prefix = implode('/', $paths);
if ($suffix == 'list') { if ($suffix == 'list') {
@@ -245,7 +245,7 @@ class PermissionService
])->value('value')[$field] ?? []; ])->value('value')[$field] ?? [];
$data = []; $data = [];
foreach ($open_apis as $route) { foreach ($open_apis as $route) {
[$http_method, $uri] = explode("::", $route, 2); [$http_method, $uri] = explode("::", (string) $route, 2);
$data[] = compact('http_method', 'uri'); $data[] = compact('http_method', 'uri');
} }
@@ -256,13 +256,12 @@ class PermissionService
{ {
$cache_key = $this->getPermissionCacheKey($user_id); $cache_key = $this->getPermissionCacheKey($user_id);
$options = [ $options = [
'routeParser' => 'FastRoute\\RouteParser\\Std', 'routeParser' => \FastRoute\RouteParser\Std::class,
'dataGenerator' => 'FastRoute\\DataGenerator\\GroupCountBased', 'dataGenerator' => \FastRoute\DataGenerator\GroupCountBased::class,
'dispatcher' => 'FastRoute\\Dispatcher\\GroupCountBased', 'dispatcher' => \FastRoute\Dispatcher\GroupCountBased::class,
'routeCollector' => 'FastRoute\\RouteCollector', 'routeCollector' => \FastRoute\RouteCollector::class,
]; ];
if (!$dispatch_data = json_decode(Redis::get($cache_key), true)) { if (!$dispatch_data = json_decode(Redis::get($cache_key), true)) {
/** @var RouteCollector $routeCollector */
$route_collector = new $options['routeCollector'](new $options['routeParser'], new $options['dataGenerator']); $route_collector = new $options['routeCollector'](new $options['routeParser'], new $options['dataGenerator']);
$this->processUserResource($route_collector, $user_id, $auth_type); $this->processUserResource($route_collector, $user_id, $auth_type);
$dispatch_data = $route_collector->getData(); $dispatch_data = $route_collector->getData();
@@ -359,7 +358,7 @@ class PermissionService
protected function prepareHandler($handler): array protected function prepareHandler($handler): array
{ {
if (is_string($handler)) { if (is_string($handler)) {
if (strpos($handler, '@') !== false) { if (str_contains($handler, '@')) {
return explode('@', $handler); return explode('@', $handler);
} }

View File

@@ -10,12 +10,8 @@ use HyperfAdmin\RuleEngine\Context\TimeContext;
class AlertJob extends Job class AlertJob extends Job
{ {
public $params; public function __construct(public $params)
public function __construct($params)
{ {
// 这里最好是普通数据,不要使用携带 IO 的对象,比如 PDO 对象
$this->params = $params;
} }
public function handle() public function handle()

View File

@@ -22,8 +22,6 @@ class AlertService
* *
* @param $params 数据 * @param $params 数据
* @param int $delay 延时时间 单位秒 * @param int $delay 延时时间 单位秒
*
* @return bool
*/ */
public function push($params, int $delay = 0): bool public function push($params, int $delay = 0): bool
{ {

View File

@@ -6,14 +6,8 @@ namespace HyperfAdmin\BaseUtils;
*/ */
class AKSK class AKSK
{ {
private $access_key; public function __construct(private $access_key, private $secret_key)
private $secret_key;
public function __construct($access_key, $secret_key)
{ {
$this->access_key = $access_key;
$this->secret_key = $secret_key;
} }
public function token($method, $path, $host, $query, $content_type, $body) public function token($method, $path, $host, $query, $content_type, $body)
@@ -40,7 +34,7 @@ class AKSK
private function digest($secret, $data) private function digest($secret, $data)
{ {
return hash_hmac('sha1', $data, $secret, true); return hash_hmac('sha1', (string) $data, (string) $secret, true);
} }
private function sign($secret, $data) private function sign($secret, $data)

View File

@@ -128,14 +128,14 @@ class AliyunOSS
$conditions[] = [ $conditions[] = [
'starts-with', 'starts-with',
'$key', '$key',
rtrim($dir, '/') . '/', rtrim((string) $dir, '/') . '/',
]; ];
} }
$base64_policy = base64_encode(json_encode([ $base64_policy = base64_encode(json_encode([
'expiration' => $expiration, 'expiration' => $expiration,
'conditions' => $conditions, 'conditions' => $conditions,
])); ]));
$signature = base64_encode(hash_hmac('sha1', $base64_policy, $this->access_key_secret, true)); $signature = base64_encode(hash_hmac('sha1', $base64_policy, (string) $this->access_key_secret, true));
return [ return [
'OSSAccessKeyId' => $this->access_key, 'OSSAccessKeyId' => $this->access_key,
@@ -144,7 +144,7 @@ class AliyunOSS
'Signature' => $signature, 'Signature' => $signature,
'expire' => $end, 'expire' => $end,
'dir' => $dir, //这个参数是设置用户上传指定的前缀 'dir' => $dir, //这个参数是设置用户上传指定的前缀
'cdn' => $this->cdn ? rtrim($this->cdn, '/') : '', 'cdn' => $this->cdn ? rtrim((string) $this->cdn, '/') : '',
]; ];
} }
} }

View File

@@ -2,6 +2,7 @@
namespace HyperfAdmin\BaseUtils; namespace HyperfAdmin\BaseUtils;
use Monolog\Formatter\LineFormatter; use Monolog\Formatter\LineFormatter;
use Monolog\LogRecord;
class ColorLineFormatter extends LineFormatter class ColorLineFormatter extends LineFormatter
{ {
@@ -11,7 +12,7 @@ class ColorLineFormatter extends LineFormatter
'WARNING' => "\e[0;33m{log_str}\e[0m", 'WARNING' => "\e[0;33m{log_str}\e[0m",
]; ];
public function format(array $record): string public function format(LogRecord $record): string
{ {
$log = parent::format($record); $log = parent::format($record);

View File

@@ -9,8 +9,6 @@ use GuzzleHttp\Cookie\CookieJar;
class Guzzle class Guzzle
{ {
/** /**
* @param array $config
*
* @return Client * @return Client
*/ */
public static function create(array $config = []) public static function create(array $config = [])
@@ -39,9 +37,9 @@ class Guzzle
$client = self::create([ $client = self::create([
'timeout' => $headers['timeout'] ?? 10.0, 'timeout' => $headers['timeout'] ?? 10.0,
]); ]);
$method = strtoupper($method); $method = strtoupper((string) $method);
$options = []; $options = [];
$headers['charset'] = $headers['charset'] ?? 'UTF-8'; $headers['charset'] ??= 'UTF-8';
$options['headers'] = $headers; $options['headers'] = $headers;
if($method == 'GET' && $params) { if($method == 'GET' && $params) {
$options['query'] = $params; $options['query'] = $params;
@@ -49,7 +47,7 @@ class Guzzle
if($method == 'POST') { if($method == 'POST') {
$options['headers']['Content-Type'] = $headers['Content-Type'] ?? 'application/json'; $options['headers']['Content-Type'] = $headers['Content-Type'] ?? 'application/json';
if($options['headers']['Content-Type'] == 'application/json' && $params) { if($options['headers']['Content-Type'] == 'application/json' && $params) {
$options['body'] = \GuzzleHttp\json_encode($params ? $params : (object)[]); $options['body'] = \GuzzleHttp\json_encode($params ?: (object)[]);
} }
if($options['headers']['Content-Type'] == 'application/x-www-form-urlencoded' && $params) { if($options['headers']['Content-Type'] == 'application/x-www-form-urlencoded' && $params) {
$options['form_params'] = $params; $options['form_params'] = $params;
@@ -92,9 +90,7 @@ class Guzzle
try { try {
$options['headers']['X-No-Proxy'] = true; $options['headers']['X-No-Proxy'] = true;
$options['headers'] = array_merge($options['headers'], array_map(function ($item) { $options['headers'] = array_merge($options['headers'], array_map(fn($item) => $item[0], request_header()));
return $item[0];
}, request_header()));
foreach ($options['headers'] as $key => $val) { foreach ($options['headers'] as $key => $val) {
$new_key = implode('-', array_map('ucfirst', explode('-', $key))); $new_key = implode('-', array_map('ucfirst', explode('-', $key)));
@@ -102,7 +98,7 @@ class Guzzle
unset($options['headers'][$key]); unset($options['headers'][$key]);
} }
$parse =parse_url($url); $parse =parse_url((string) $url);
$domain = isset($parse['port']) ? $parse['host'] . ':' . $parse['port'] : $parse['host']; $domain = isset($parse['port']) ? $parse['host'] . ':' . $parse['port'] : $parse['host'];
$options['cookies'] = CookieJar::fromArray(cookie(), $domain); $options['cookies'] = CookieJar::fromArray(cookie(), $domain);
@@ -116,16 +112,11 @@ class Guzzle
$options['form_params'] = $form_data; $options['form_params'] = $form_data;
} }
$request = retry(3, function () use ($client, $request, $url, $options) { $request = retry(3, fn() => $client->request($request->getMethod(), $url, $options), 50);
return $client->request($request->getMethod(), $url, $options);
}, 50);
$content = $request->getBody()->getContents(); $content = $request->getBody()->getContents();
$logger->info('proxy_success', compact('url', 'options')); $logger->info('proxy_success', compact('url', 'options'));
return my_json_decode($content); return my_json_decode($content);
} catch (\GuzzleHttp\Exception\GuzzleException $e) { } catch (\GuzzleHttp\Exception\GuzzleException|\Throwable $e) {
$logger->error('proxy_fail', compact('url', 'options', 'e'));
throw new \Exception("proxy exception {$e}", 500);
} catch (\Throwable $e) {
$logger->error('proxy_fail', compact('url', 'options', 'e')); $logger->error('proxy_fail', compact('url', 'options', 'e'));
throw new \Exception("proxy exception {$e}", 500); throw new \Exception("proxy exception {$e}", 500);
} }

View File

@@ -268,7 +268,7 @@ if(!function_exists('array_remove')) {
if(!function_exists('array_get_node')) { if(!function_exists('array_get_node')) {
function array_get_node($key, $arr = []) function array_get_node($key, $arr = [])
{ {
$path = explode('.', $key); $path = explode('.', (string) $key);
foreach($path as $key) { foreach($path as $key) {
$key = trim($key); $key = trim($key);
if(empty($arr) || !isset($arr[$key])) { if(empty($arr) || !isset($arr[$key])) {

View File

@@ -183,11 +183,11 @@ if (!function_exists('encrypt')) {
{ {
$chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-=+"; $chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-=+";
//$nh = rand(0,64); //$nh = rand(0,64);
$nh = strlen($txt) % 65; $nh = strlen((string) $txt) % 65;
$ch = $chars[$nh]; $ch = $chars[$nh];
$mdKey = md5($key . $ch); $mdKey = md5($key . $ch);
$mdKey = substr($mdKey, $nh % 8, $nh % 8 + 7); $mdKey = substr($mdKey, $nh % 8, $nh % 8 + 7);
$txt = base64_encode($txt); $txt = base64_encode((string) $txt);
$tmp = ''; $tmp = '';
$i = 0; $i = 0;
$j = 0; $j = 0;
@@ -239,7 +239,7 @@ if (!function_exists('is_valid_date')) {
if (!function_exists('str_var_replace')) { if (!function_exists('str_var_replace')) {
function str_var_replace($str, $data) function str_var_replace($str, $data)
{ {
preg_match_all('/{([\s\S]*?)}/', $str, $match); preg_match_all('/{([\s\S]*?)}/', (string) $str, $match);
$values = []; $values = [];
$vars = []; $vars = [];
foreach (($match && $match[1] ? $match[1] : []) as $item) { foreach (($match && $match[1] ? $match[1] : []) as $item) {
@@ -256,7 +256,7 @@ if (!function_exists('convert_memory')) {
{ {
$unit = ['b', 'kb', 'mb', 'gb', 'tb', 'pb']; $unit = ['b', 'kb', 'mb', 'gb', 'tb', 'pb'];
return @round($size / pow(1024, ($i = floor(log($size, 1024)))), 2) . ' ' . $unit[$i]; return @round($size / 1024 ** $i = floor(log($size, 1024)), 2) . ' ' . $unit[$i];
} }
} }
@@ -277,7 +277,7 @@ if (!function_exists('read_file')) {
if (!function_exists('get_extension')) { if (!function_exists('get_extension')) {
function get_extension($file) function get_extension($file)
{ {
return substr(strrchr($file, '.'), 1); return substr(strrchr((string) $file, '.'), 1);
} }
} }
@@ -363,7 +363,7 @@ if (!function_exists('http_build_url')) {
if (!function_exists('replace_url_query')) { if (!function_exists('replace_url_query')) {
function replace_url_query($url, array $query) function replace_url_query($url, array $query)
{ {
$parse = parse_url($url); $parse = parse_url((string) $url);
parse_str($parse['query'], $p); parse_str($parse['query'], $p);
$parse['query'] = urldecode(http_build_query(array_merge($p, $query))); $parse['query'] = urldecode(http_build_query(array_merge($p, $query)));
@@ -425,7 +425,7 @@ if (!function_exists('my_json_decode')) {
if (!$json) { if (!$json) {
return $default; return $default;
} }
$json = preg_replace('@//[^"]+?$@mui', '', $json); $json = preg_replace('@//[^"]+?$@mui', '', (string) $json);
$json = preg_replace('@^\s*//.*?$@mui', '', $json); $json = preg_replace('@^\s*//.*?$@mui', '', $json);
$json = $json ? @json_decode($json, true) : $default; $json = $json ? @json_decode($json, true) : $default;
if (is_null($json)) { if (is_null($json)) {
@@ -524,10 +524,10 @@ if (!function_exists('generate_random_str')) {
$characters = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'; $characters = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';
$random_str = ''; $random_str = '';
for ($i = 0; $i < $length; $i++) { for ($i = 0; $i < $length; $i++) {
$random_str .= $characters[rand(0, strlen($characters) - 1)]; $random_str .= $characters[random_int(0, strlen($characters) - 1)];
} }
return trim($prefix) . $random_str; return trim((string) $prefix) . $random_str;
} }
} }
@@ -537,7 +537,7 @@ if (!function_exists('get_dir_filename')) {
$handler = opendir($dir); $handler = opendir($dir);
$files = []; $files = [];
while (($filename = readdir($handler)) !== false) { while (($filename = readdir($handler)) !== false) {
$filter_extension = $extension === '' ? true : strpos($filename, $extension); $filter_extension = $extension === '' ? true : strpos($filename, (string) $extension);
if (!($filename !== "." && $filename !== ".." && $filter_extension)) { if (!($filename !== "." && $filename !== ".." && $filter_extension)) {
continue; continue;
} }
@@ -556,34 +556,33 @@ if (!function_exists('get_dir_filename')) {
if (!function_exists('sp_encrypt')) { if (!function_exists('sp_encrypt')) {
function sp_encrypt($plaintext, $key) function sp_encrypt($plaintext, $key)
{ {
$key = substr(sha1($key, true), 0, 16); $key = substr(sha1((string) $key, true), 0, 16);
$iv = openssl_random_pseudo_bytes(16); $iv = openssl_random_pseudo_bytes(16);
$ciphertext = openssl_encrypt($plaintext, 'AES-128-CBC', $key, OPENSSL_RAW_DATA, $iv); $ciphertext = openssl_encrypt($plaintext, 'AES-128-CBC', $key, OPENSSL_RAW_DATA, $iv);
$ciphertext_base64 = urlsafe_b64encode($iv . $ciphertext);
return $ciphertext_base64; return urlsafe_b64encode($iv . $ciphertext);
} }
} }
if (!function_exists('sp_decrypt')) { if (!function_exists('sp_decrypt')) {
function sp_decrypt($ciphertext_base64, $key) function sp_decrypt($ciphertext_base64, $key)
{ {
$key = substr(sha1($key, true), 0, 16); $key = substr(sha1((string) $key, true), 0, 16);
$ciphertext_dec = urlsafe_b64decode($ciphertext_base64); $ciphertext_dec = urlsafe_b64decode($ciphertext_base64);
$iv_size = 16; $iv_size = 16;
$iv_dec = substr($ciphertext_dec, 0, $iv_size); $iv_dec = substr((string) $ciphertext_dec, 0, $iv_size);
$ciphertext_dec = substr($ciphertext_dec, $iv_size); $ciphertext_dec = substr((string) $ciphertext_dec, $iv_size);
$plaintext_dec = openssl_decrypt($ciphertext_dec, 'AES-128-CBC', $key, OPENSSL_RAW_DATA, $iv_dec);
return $plaintext_dec; return openssl_decrypt($ciphertext_dec, 'AES-128-CBC', $key, OPENSSL_RAW_DATA, $iv_dec);
} }
} }
if (!function_exists('urlsafe_b64encode')) { if (!function_exists('urlsafe_b64encode')) {
function urlsafe_b64encode($string) function urlsafe_b64encode($string)
{ {
$data = base64_encode($string); $data = base64_encode((string) $string);
$data = str_replace([
return str_replace([
'+', '+',
'/', '/',
// '=', // '=',
@@ -592,8 +591,6 @@ if (!function_exists('urlsafe_b64encode')) {
'_', '_',
// '', // '',
], $data); ], $data);
return $data;
} }
} }
@@ -662,7 +659,6 @@ if (!function_exists('cookie')) {
/** /**
* 快捷方式,返回 request 相关 cookie * 快捷方式,返回 request 相关 cookie
* *
* @param string $key
* *
* @return mixed * @return mixed
*/ */
@@ -684,7 +680,6 @@ if (!function_exists('request_header')) {
/** /**
* 快捷方式,返回 request 相关 header * 快捷方式,返回 request 相关 header
* *
* @param string $key
* *
* @return mixed * @return mixed
*/ */
@@ -754,10 +749,10 @@ if (!function_exists('is_cli')) {
if (!function_exists('xml2array')) { if (!function_exists('xml2array')) {
function xml2array($xml_string, $key = '') function xml2array($xml_string, $key = '')
{ {
if (strpos($xml_string, '<') === false) { if (!str_contains((string) $xml_string, '<')) {
return []; return [];
} }
$array = (array)@simplexml_load_string($xml_string, 'SimpleXMLElement', LIBXML_NOCDATA); $array = (array)@simplexml_load_string((string) $xml_string, 'SimpleXMLElement', LIBXML_NOCDATA);
if (!$key) { if (!$key) {
return $array; return $array;
} }
@@ -804,7 +799,7 @@ if (!function_exists('now')) {
if (!function_exists('is_json_str')) { if (!function_exists('is_json_str')) {
function is_json_str($string) function is_json_str($string)
{ {
json_decode($string); json_decode((string) $string);
return (json_last_error() == JSON_ERROR_NONE); return (json_last_error() == JSON_ERROR_NONE);
} }
} }

View File

@@ -123,17 +123,16 @@ if (!function_exists('filesystem_private_url')) {
} }
$filesystem = make(FilesystemFactory::class)->get($bucket); $filesystem = make(FilesystemFactory::class)->get($bucket);
if (Str::startsWith($save_file_path, 'http')) { if (Str::startsWith($save_file_path, 'http')) {
$save_file_path = parse_url($save_file_path)['path']; $save_file_path = parse_url((string) $save_file_path)['path'];
$parts = explode('/', $save_file_path); $parts = explode('/', $save_file_path);
unset($parts[0]); unset($parts[0]);
$save_file_path = implode('/', $parts); $save_file_path = implode('/', $parts);
} }
$save_file_path = preg_replace('@^oss/@', '', $save_file_path); $save_file_path = preg_replace('@^oss/@', '', (string) $save_file_path);
try { try {
switch (config("file.storage.{$bucket}.driver")) { switch (config("file.storage.{$bucket}.driver")) {
case \Hyperf\Filesystem\Adapter\LocalAdapterFactory::class: case \Hyperf\Filesystem\Adapter\LocalAdapterFactory::class:
return config("file.storage.{$bucket}.cdn") . $save_file_path; return config("file.storage.{$bucket}.cdn") . $save_file_path;
break;
case \Hyperf\Filesystem\Adapter\AliyunOssAdapterFactory::class; case \Hyperf\Filesystem\Adapter\AliyunOssAdapterFactory::class;
$adapter = $filesystem->getAdapter(); $adapter = $filesystem->getAdapter();
if (method_exists($adapter, 'signUrl')) { if (method_exists($adapter, 'signUrl')) {
@@ -188,11 +187,7 @@ if (!function_exists('process_list_filter')) {
$processes = []; $processes = [];
} }
if (is_array($ignore)) { if (is_array($ignore)) {
$processes = array_filter($processes, function ($item) use ($ignore) { $processes = array_filter($processes, fn($item) => !Str::startsWith($item, array_map(fn($each) => Str::replaceLast('*', '', $each), $ignore)));
return !Str::startsWith($item, array_map(function ($each) {
return Str::replaceLast('*', '', $each);
}, $ignore));
});
} }
} }
if ($active = $rule['active'] ?? []) { if ($active = $rule['active'] ?? []) {

View File

@@ -37,9 +37,8 @@ class JWT
} }
$base64_header = self::base64UrlEncode(json_encode(self::$header, JSON_UNESCAPED_UNICODE)); $base64_header = self::base64UrlEncode(json_encode(self::$header, JSON_UNESCAPED_UNICODE));
$base64_payload = self::base64UrlEncode(json_encode($payload, JSON_UNESCAPED_UNICODE)); $base64_payload = self::base64UrlEncode(json_encode($payload, JSON_UNESCAPED_UNICODE));
$token = $base64_header . '.' . $base64_payload . '.' . self::signature($base64_header . '.' . $base64_payload, self::$key, self::$header['alg']);
return $token; return $base64_header . '.' . $base64_payload . '.' . self::signature($base64_header . '.' . $base64_payload, self::$key, self::$header['alg']);
} }
/** /**
@@ -116,9 +115,7 @@ class JWT
* HMACSHA256签名 https://jwt.io/ 中HMACSHA256签名实现 * HMACSHA256签名 https://jwt.io/ 中HMACSHA256签名实现
* *
* @param string $input 为base64UrlEncode(header).".".base64UrlEncode(payload) * @param string $input 为base64UrlEncode(header).".".base64UrlEncode(payload)
* @param string $key
* @param string $alg 算法方式 * @param string $alg 算法方式
*
* @return mixed * @return mixed
*/ */
private static function signature(string $input, string $key, string $alg = 'HS256') private static function signature(string $input, string $key, string $alg = 'HS256')

View File

@@ -15,7 +15,7 @@ class BootAppConfListener implements ListenerInterface
]; ];
} }
public function process(object $event) public function process(object $event): void
{ {
Builder::macro('getAsArray', function () { Builder::macro('getAsArray', function () {
/** @var \Hyperf\Database\Query\Builder $this */ /** @var \Hyperf\Database\Query\Builder $this */

View File

@@ -15,10 +15,7 @@ class DbQueryExecutedListener implements ListenerInterface
]; ];
} }
/** public function process(object $event): void
* @param object $event
*/
public function process(object $event)
{ {
if($event instanceof QueryExecuted) { if($event instanceof QueryExecuted) {
if(is_production()) { if(is_production()) {
@@ -73,9 +70,7 @@ class DbQueryExecutedListener implements ListenerInterface
/** /**
* 获取sql类型 * 获取sql类型
* *
* @param string $sql
* *
* @return string
*/ */
protected function getSqlType(string $sql): string protected function getSqlType(string $sql): string
{ {

View File

@@ -15,7 +15,7 @@ class FetchModeListener implements ListenerInterface
]; ];
} }
public function process(object $event) public function process(object $event): void
{ {
if($event instanceof StatementPrepared) { if($event instanceof StatementPrepared) {
$event->statement->setFetchMode(PDO::FETCH_ASSOC); $event->statement->setFetchMode(PDO::FETCH_ASSOC);

View File

@@ -35,7 +35,7 @@ class BaseModel extends Model
*/ */
public function where2query($where, $query = null) public function where2query($where, $query = null)
{ {
$query = $query ?? $this->newQuery(); $query ??= $this->newQuery();
if (!$where) { if (!$where) {
return $query; return $query;
} }
@@ -43,9 +43,7 @@ class BaseModel extends Model
unset($where['__logic']); unset($where['__logic']);
foreach ($where as $key => $item) { foreach ($where as $key => $item) {
if (is_numeric($key) && is_array($item)) { if (is_numeric($key) && is_array($item)) {
$query->where(function ($query) use ($item) { $query->where(fn($query) => $this->where2query($item, $query), null, null, $boolean);
return $this->where2query($item, $query);
}, null, null, $boolean);
continue; continue;
} }
if (!is_array($item)) { if (!is_array($item)) {
@@ -105,20 +103,20 @@ class BaseModel extends Model
$where = []; $where = [];
$kw = request()->input('kw'); $kw = request()->input('kw');
if ($kw) { if ($kw) {
if (preg_match_all('/^\d+$/', $kw)) { if (preg_match_all('/^\d+$/', (string) $kw)) {
$where[$id_key] = $kw; $where[$id_key] = $kw;
} elseif (preg_match_all('/^\d+?,/', $kw)) { } elseif (preg_match_all('/^\d+?,/', (string) $kw)) {
$where[$id_key] = explode(',', $kw); $where[$id_key] = explode(',', (string) $kw);
} else { } else {
$where[$name_key] = ['like' => "%{$kw}%"]; $where[$name_key] = ['like' => "%{$kw}%"];
} }
} }
$id = request()->input('id'); $id = request()->input('id');
if ($id) { if ($id) {
if (preg_match_all('/^\d+$/', $id)) { if (preg_match_all('/^\d+$/', (string) $id)) {
$where[$id_key] = $id; $where[$id_key] = $id;
} elseif (preg_match_all('/^\d+?,/', $id)) { } elseif (preg_match_all('/^\d+?,/', (string) $id)) {
$where[$id_key] = explode(',', $id); $where[$id_key] = explode(',', (string) $id);
} }
} }
if (!$default_query && !$where) { if (!$default_query && !$where) {
@@ -126,7 +124,7 @@ class BaseModel extends Model
} }
$where['__logic'] = $logic; $where['__logic'] = $logic;
$where = array_merge($where, $extra_where); $where = array_merge($where, $extra_where);
$attr['limit'] = $attr['limit'] ?? 100; $attr['limit'] ??= 100;
return $this->list($where, $attr)->toArray(); return $this->list($where, $attr)->toArray();
} }

View File

@@ -276,7 +276,7 @@ class EsBaseModel
]; ];
try { try {
return $this->client->get($params); return $this->client->get($params);
} catch (\Exception $e) { } catch (\Exception) {
return false; return false;
} }
} }
@@ -491,7 +491,7 @@ class EsBaseModel
foreach ($val_tile as $operator => $each) { foreach ($val_tile as $operator => $each) {
if (isset($this->operator_map[$operator])) { if (isset($this->operator_map[$operator])) {
$mapping_date_format = $this->mapping['properties'][$key]['format'] ?? null; $mapping_date_format = $this->mapping['properties'][$key]['format'] ?? null;
$query['bool']['filter']['bool']['must'][$index]['range'][$key][$this->operator_map[$operator]] = $is_time_field ? date($mapping_date_format ? $this->transDateFormat($mapping_date_format) : "Y-m-d\TH:i:s", strtotime($each)) : $each; $query['bool']['filter']['bool']['must'][$index]['range'][$key][$this->operator_map[$operator]] = $is_time_field ? date($mapping_date_format ? $this->transDateFormat($mapping_date_format) : "Y-m-d\TH:i:s", strtotime((string) $each)) : $each;
} }
} }
continue; continue;
@@ -500,9 +500,7 @@ class EsBaseModel
if (is_array($val)) { if (is_array($val)) {
$query['bool']['filter']['bool']['must'][] = [ $query['bool']['filter']['bool']['must'][] = [
'terms' => [ 'terms' => [
$key => array_map(function ($each) { $key => array_map(fn($each) => is_numeric($each) ? $each * 1 : $each, $val),
return is_numeric($each) ? $each * 1 : $each;
}, $val),
], ],
]; ];
continue; continue;

View File

@@ -12,17 +12,14 @@ use HyperfAdmin\BaseUtils\Log;
*/ */
class Redis class Redis
{ {
private $pool;
/** /**
* @var \Redis * @var \Redis
*/ */
private $redis; private $redis;
public function __construct($pool = 'default') public function __construct(private $pool = 'default')
{ {
$this->pool = $pool; $this->redis = container(RedisFactory::class)->get($this->pool);
$this->redis = container(RedisFactory::class)->get($pool);
} }
public static function conn($pool = 'default') public static function conn($pool = 'default')
@@ -73,8 +70,6 @@ class Redis
} }
/** /**
* @param string $name
* @param int $expired
* @param mixed $callable * @param mixed $callable
* *
* @return array|null * @return array|null
@@ -84,7 +79,7 @@ class Redis
if ($this->redis->exists($name)) { if ($this->redis->exists($name)) {
Log::get('redis')->info(sprintf('get %s from cache', $name)); Log::get('redis')->info(sprintf('get %s from cache', $name));
return json_decode($this->redis->get($name), true); return json_decode((string) $this->redis->get($name), true);
} }
$data = call($callable); $data = call($callable);
if ($data) { if ($data) {

View File

@@ -16,29 +16,29 @@ class RedisArray implements \ArrayAccess
$this->redis = container(RedisFactory::class)->get($cluster); $this->redis = container(RedisFactory::class)->get($cluster);
} }
public function offsetExists($offset) public function offsetExists($offset): bool
{ {
return $this->redis->hExists($this->name, (string)$offset); return $this->redis->hExists($this->name, (string)$offset);
} }
public function offsetGet($offset) public function offsetGet($offset): mixed
{ {
$val = $this->redis->hGet($this->name, (string)$offset); $val = $this->redis->hGet($this->name, (string)$offset);
if(is_json_str($val)) { if(is_json_str($val)) {
return json_decode($val, true); return json_decode((string) $val, true);
} }
return $val; return $val;
} }
public function offsetSet($offset, $value) public function offsetSet($offset, $value): void
{ {
return $this->redis->hSet($this->name, (string)$offset, is_array($value) ? json_encode($value) : $value); $this->redis->hSet($this->name, (string)$offset, is_array($value) ? json_encode($value) : $value);
} }
public function offsetUnset($offset) public function offsetUnset($offset): void
{ {
return $this->redis->hDel($this->name, (string)$offset); $this->redis->hDel($this->name, (string)$offset);
} }
public function __destruct() public function __destruct()

View File

@@ -5,10 +5,6 @@ use Hyperf\Redis\RedisFactory;
class RedisQueue class RedisQueue
{ {
protected $cluster = 'default';
protected $queue_name = 'redis_queue_default';
protected $queue_wait_ack_suffix = 'wait_ack'; protected $queue_wait_ack_suffix = 'wait_ack';
protected $wait_timeout = 10; protected $wait_timeout = 10;
@@ -20,11 +16,9 @@ class RedisQueue
*/ */
protected $redis; protected $redis;
public function __construct($queue_name, $cluster = 'default') public function __construct(protected $queue_name, protected $cluster = 'default')
{ {
$this->queue_name = $queue_name; $this->redis = container(RedisFactory::class)->get($this->cluster);
$this->cluster = $cluster;
$this->redis = container(RedisFactory::class)->get($cluster);
} }
public function length($name = '') public function length($name = '')
@@ -65,8 +59,8 @@ class RedisQueue
} }
$msg = $this->getOne($this->queue_name, $filter); $msg = $this->getOne($this->queue_name, $filter);
if($msg) { if($msg) {
$msg_id = md5($msg); $msg_id = md5((string) $msg);
$data = json_decode($msg, true); $data = json_decode((string) $msg, true);
$ret = array_merge($data, ['_queue_msg_id' => $msg_id]); $ret = array_merge($data, ['_queue_msg_id' => $msg_id]);
$this->redis->rPush($this->getAckQueueName(), json_encode(array_merge($ret, ['_time' => time()]))); $this->redis->rPush($this->getAckQueueName(), json_encode(array_merge($ret, ['_time' => time()])));
@@ -87,7 +81,7 @@ class RedisQueue
} }
foreach(range(0, $len - 1) as $index) { foreach(range(0, $len - 1) as $index) {
$ele = $this->redis->lIndex($queue_name, $index); $ele = $this->redis->lIndex($queue_name, $index);
$ele_array = json_decode($ele, true); $ele_array = json_decode((string) $ele, true);
if(array_intersect($ele_array, $filter)) { if(array_intersect($ele_array, $filter)) {
$this->redis->lRem($queue_name, $ele, 1); $this->redis->lRem($queue_name, $ele, 1);
@@ -132,7 +126,7 @@ class RedisQueue
{ {
$list = $this->redis->lRange($this->getAckQueueName(), 0, -1); $list = $this->redis->lRange($this->getAckQueueName(), 0, -1);
foreach($list as &$item) { foreach($list as &$item) {
$item = json_decode($item, true); $item = json_decode((string) $item, true);
} }
unset($item); unset($item);

View File

@@ -77,9 +77,7 @@ abstract class AbstractController extends Controller
*/ */
public function info() public function info()
{ {
$tableHeader = array_values(array_filter($this->getListHeader(), function ($item) { $tableHeader = array_values(array_filter($this->getListHeader(), fn($item) => !($item['hidden'] ?? false)));
return !($item['hidden'] ?? false);
}));
$filter = $this->getListFilters(); $filter = $this->getListFilters();
$actions = $this->options['table']['rowActions'] ?? []; $actions = $this->options['table']['rowActions'] ?? [];
$actions = $this->buttonConfigConvert($actions); $actions = $this->buttonConfigConvert($actions);
@@ -125,7 +123,7 @@ abstract class AbstractController extends Controller
foreach ($config as $key => $item) { foreach ($config as $key => $item) {
$buttons[$key]['text'] = $item['text'] ?? ''; $buttons[$key]['text'] = $item['text'] ?? '';
$buttons[$key]['type'] = isset($item['target']) ? $item['type'] ?? 'jump' : (isset($item['rules']) ? 'form' : (isset($item['api']) ? 'api' : 'jump')); $buttons[$key]['type'] = isset($item['target']) ? $item['type'] ?? 'jump' : (isset($item['rules']) ? 'form' : (isset($item['api']) ? 'api' : 'jump'));
$buttons[$key]['target'] = isset($item['target']) ? $item['target'] : (isset($item['api']) ? $item['api'] : ($item['action'] ?? '')); $buttons[$key]['target'] = $item['target'] ?? $item['api'] ?? $item['action'] ?? '';
$buttons[$key]['props'] = isset($item['target']) ? $item['props'] ?? [] : [ $buttons[$key]['props'] = isset($item['target']) ? $item['props'] ?? [] : [
'icon' => $item['icon'] ?? '', 'icon' => $item['icon'] ?? '',
'circle' => $item['circle'] ?? false, 'circle' => $item['circle'] ?? false,
@@ -160,11 +158,7 @@ abstract class AbstractController extends Controller
$page = $this->request->input('_page', 1); $page = $this->request->input('_page', 1);
$size = $this->request->input('_size', 20); $size = $this->request->input('_size', 20);
$table_options = $this->getListHeader(); $table_options = $this->getListHeader();
$columns = array_unique(array_values(array_map(function ($item) { $columns = array_unique(array_values(array_map(fn($item) => explode('.', (string) $item)[0], array_column(array_filter($table_options, fn($each) => isset($each['virtual_field']) ? !$each['virtual_field'] : true), 'field'))));
return explode('.', $item)[0];
}, array_column(array_filter($table_options, function ($each) {
return isset($each['virtual_field']) ? !$each['virtual_field'] : true;
}), 'field'))));
$filter_options = $this->getListFilters(); $filter_options = $this->getListFilters();
$filters = []; $filters = [];
if (!empty($filter_options)) { if (!empty($filter_options)) {
@@ -184,23 +178,13 @@ abstract class AbstractController extends Controller
} }
$conditions = $this->options['where'] ?? []; $conditions = $this->options['where'] ?? [];
foreach ($filters as $field => $value) { foreach ($filters as $field => $value) {
switch ($filter_options[$field]['search_type'] ?? '') { $conditions[$field] = match ($filter_options[$field]['search_type'] ?? '') {
case 'between': 'between' => ['between' => $value],
$conditions[$field] = ['between' => $value]; 'full_like' => ['like' => "%{$value}%"],
break; 'suffix_like' => ['like' => "{$value}%"],
case 'full_like': 'prefix_like' => ['like' => "%{$value}"],
$conditions[$field] = ['like' => "%{$value}%"]; default => $value,
break; };
case 'suffix_like':
$conditions[$field] = ['like' => "{$value}%"];
break;
case 'prefix_like':
$conditions[$field] = ['like' => "%{$value}"];
break;
default:
$conditions[$field] = $value;
break;
}
} }
$order_by = $this->options['order_by'] ?? ''; $order_by = $this->options['order_by'] ?? '';
$group_by = $this->options['group_by'] ?? ''; $group_by = $this->options['group_by'] ?? '';
@@ -322,7 +306,7 @@ abstract class AbstractController extends Controller
$ret = Db::connection($pool)->table("{$db}.{$table}")->whereIn($foreign_key, $where)->get($columns)->toArray(); $ret = Db::connection($pool)->table("{$db}.{$table}")->whereIn($foreign_key, $where)->get($columns)->toArray();
array_change_v2k($ret, $foreign_key); array_change_v2k($ret, $foreign_key);
foreach ($list as &$item) { foreach ($list as &$item) {
$append = isset($ret[$item[$local_key]]) ? $ret[$item[$local_key]] : $default; $append = $ret[$item[$local_key]] ?? $default;
unset($append[$foreign_key]); unset($append[$foreign_key]);
$item = array_merge($item, $append); $item = array_merge($item, $append);
} }
@@ -352,7 +336,7 @@ abstract class AbstractController extends Controller
$ret = Db::connection($pool)->table("{$db}.{$table}")->whereIn($foreign_key, $where)->get($columns)->toArray(); $ret = Db::connection($pool)->table("{$db}.{$table}")->whereIn($foreign_key, $where)->get($columns)->toArray();
$ret = array_group_by($ret, $foreign_key); $ret = array_group_by($ret, $foreign_key);
foreach ($list as &$item) { foreach ($list as &$item) {
$group = isset($ret[$item[$local_key]]) ? $ret[$item[$local_key]] : $default; $group = $ret[$item[$local_key]] ?? $default;
$append = []; $append = [];
foreach (array_keys($default) as $field) { foreach (array_keys($default) as $field) {
$append[$field] = array_values(array_unique(array_filter(array_column($group, $field)))); $append[$field] = array_values(array_unique(array_filter(array_column($group, $field))));
@@ -366,7 +350,7 @@ abstract class AbstractController extends Controller
public function explodeHasStr($has_str) public function explodeHasStr($has_str)
{ {
$check = preg_match('/([a-zA-Z_0-9]+\.)?([a-zA-Z_0-9]+)\.([a-zA-Z_0-9]+):([a-zA-Z_0-9]+->)?([a-zA-Z_,0-9 ]+)/', $has_str, $match); $check = preg_match('/([a-zA-Z_0-9]+\.)?([a-zA-Z_0-9]+)\.([a-zA-Z_0-9]+):([a-zA-Z_0-9]+->)?([a-zA-Z_,0-9 ]+)/', (string) $has_str, $match);
if ($check === 0) { if ($check === 0) {
return false; return false;
} }
@@ -377,11 +361,9 @@ abstract class AbstractController extends Controller
$table, $table,
$local_key, $local_key,
$foreign_key, $foreign_key,
] = array_map(function ($item) { ] = array_map(fn($item) => str_replace(['.', '->'], '', $item), $match);
return str_replace(['.', '->'], '', $item); $pool = $pool ?: 'default';
}, $match); $local_key = $local_key ?: 'id';
$pool = $pool ? $pool : 'default';
$local_key = $local_key ? $local_key : 'id';
$columns = explode(',', $foreign_key); $columns = explode(',', $foreign_key);
if (!$columns) { if (!$columns) {
return false; return false;
@@ -389,7 +371,7 @@ abstract class AbstractController extends Controller
$foreign_key = $columns[0]; $foreign_key = $columns[0];
$default = []; $default = [];
foreach ($columns as $each) { foreach ($columns as $each) {
$default[trim(preg_replace('/[\w ]+as +/i', '', trim($each)))] = null; $default[trim((string) preg_replace('/[\w ]+as +/i', '', trim($each)))] = null;
} }
return array_values(compact('pool', 'db', 'table', 'local_key', 'foreign_key', 'columns', 'default')); return array_values(compact('pool', 'db', 'table', 'local_key', 'foreign_key', 'columns', 'default'));
} }
@@ -397,11 +379,7 @@ abstract class AbstractController extends Controller
public function getTreeNodeChilds($id) public function getTreeNodeChilds($id)
{ {
$tableOptions = $this->getListHeader(); $tableOptions = $this->getListHeader();
$columns = array_unique(array_values(array_map(function ($item) { $columns = array_unique(array_values(array_map(fn($item) => explode('.', (string) $item)[0], array_column(array_filter($tableOptions, fn($each) => isset($each['virtual_field']) ? !$each['virtual_field'] : true), 'field'))));
return explode('.', $item)[0];
}, array_column(array_filter($tableOptions, function ($each) {
return isset($each['virtual_field']) ? !$each['virtual_field'] : true;
}), 'field'))));
$order_by = $this->options['order_by'] ?? ''; $order_by = $this->options['order_by'] ?? '';
$attr['select'] = $columns; $attr['select'] = $columns;
$order_by && $attr['order_by'] = $order_by; $order_by && $attr['order_by'] = $order_by;
@@ -677,13 +655,9 @@ abstract class AbstractController extends Controller
public function getFields() public function getFields()
{ {
$form = $this->formOptionsConvert(); $form = $this->formOptionsConvert();
$form = array_filter($form, function ($item) { $form = array_filter($form, fn($item) => !($item['virtual_field'] ?? false));
return !($item['virtual_field'] ?? false);
});
$fields = array_column($form, 'field'); $fields = array_column($form, 'field');
$fields = array_map(function ($item) { $fields = array_map(fn($item) => explode('.', (string) $item)[0], $fields);
return explode('.', $item)[0];
}, $fields);
return array_unique($fields); return array_unique($fields);
} }
@@ -700,7 +674,7 @@ abstract class AbstractController extends Controller
$filter_options = []; $filter_options = [];
foreach ($this->options['filter'] as $key => $item) { foreach ($this->options['filter'] as $key => $item) {
$filter_option_key = is_array($item) ? $key : str_replace('%', '', $item); $filter_option_key = is_array($item) ? $key : str_replace('%', '', $item);
$field_extra = explode('|', $filter_option_key); $field_extra = explode('|', (string) $filter_option_key);
$field = $field_extra[0]; $field = $field_extra[0];
$form_option = []; $form_option = [];
if (isset($form_fields[$field]) && isset($form_options[$form_fields[$field]])) { if (isset($form_fields[$field]) && isset($form_options[$form_fields[$field]])) {
@@ -726,7 +700,7 @@ abstract class AbstractController extends Controller
if (Str::startsWith($item, '%') !== false && Str::endsWith($item, '%') !== false) { if (Str::startsWith($item, '%') !== false && Str::endsWith($item, '%') !== false) {
$search_type = 'full_like'; $search_type = 'full_like';
} }
if (strpos(($filter_options[$filter_option_key]['type'] ?? ''), 'range') !== false) { if (str_contains(($filter_options[$filter_option_key]['type'] ?? ''), 'range')) {
$search_type = 'between'; $search_type = 'between';
} }
$filter_options[$filter_option_key]['search_type'] = $search_type; $filter_options[$filter_option_key]['search_type'] = $search_type;
@@ -803,7 +777,7 @@ abstract class AbstractController extends Controller
} }
$form = []; $form = [];
foreach ($formOption as $key => $val) { foreach ($formOption as $key => $val) {
$field_extra = explode('|', $key); $field_extra = explode('|', (string) $key);
$field = $field_extra[0]; $field = $field_extra[0];
$title = $field_extra[1] ?? $field_extra[0]; $title = $field_extra[1] ?? $field_extra[0];
$biz = []; $biz = [];
@@ -817,7 +791,7 @@ abstract class AbstractController extends Controller
continue; continue;
} }
$rule = $biz['rule'] ?? ''; $rule = $biz['rule'] ?? '';
$rules = is_array($rule) ? $rule : explode('|', $rule); $rules = is_array($rule) ? $rule : explode('|', (string) $rule);
$_form = [ $_form = [
'title' => $title, 'title' => $title,
'field' => $field, 'field' => $field,
@@ -831,15 +805,15 @@ abstract class AbstractController extends Controller
$_form['value'] = (array)$_form['value']; $_form['value'] = (array)$_form['value'];
break; break;
case 'image': case 'image':
$biz['props']['limit'] = $biz['props']['limit'] ?? 1; $biz['props']['limit'] ??= 1;
break; break;
case 'select': case 'select':
if (isset($biz['props']['selectApi']) && $_form['value']) { if (isset($biz['props']['selectApi']) && $_form['value']) {
$biz['options'] = select_options($biz['props']['selectApi'], is_array($_form['value']) ? $_form['value'] : explode(',', $_form['value'])); $biz['options'] = select_options($biz['props']['selectApi'], is_array($_form['value']) ? $_form['value'] : explode(',', (string) $_form['value']));
} }
// fixme sub-form value 不好取, 先默认查一次 // fixme sub-form value 不好取, 先默认查一次
if (isset($biz['props']['selectApi']) && $depth) { if (isset($biz['props']['selectApi']) && $depth) {
$biz['options'] = select_options($biz['props']['selectApi'], is_array($_form['value']) ? $_form['value'] : explode(',', $_form['value'])); $biz['options'] = select_options($biz['props']['selectApi'], is_array($_form['value']) ? $_form['value'] : explode(',', (string) $_form['value']));
} }
break; break;
default: default:
@@ -943,7 +917,7 @@ abstract class AbstractController extends Controller
*/ */
public function getFormRules($options = null) public function getFormRules($options = null)
{ {
$formOptions = $options ? $options : ($this->options['form'] ?? []); $formOptions = $options ?: $this->options['form'] ?? [];
$rules = []; $rules = [];
foreach ($formOptions as $key => $val) { foreach ($formOptions as $key => $val) {
if (is_array($val) && ($val['form'] ?? true) === false) { if (is_array($val) && ($val['form'] ?? true) === false) {
@@ -978,7 +952,7 @@ abstract class AbstractController extends Controller
$data_source = $this->request->all(); $data_source = $this->request->all();
$pk_val = $data_source[$pk] ?? null; $pk_val = $data_source[$pk] ?? null;
foreach ($rules as &$val) { foreach ($rules as &$val) {
$rule_parts = is_array($val) ? $val : explode('|', $val); $rule_parts = is_array($val) ? $val : explode('|', (string) $val);
foreach ($rule_parts as &$rule) { foreach ($rule_parts as &$rule) {
if ($pk_val && is_string($rule) && Str::startsWith($rule, 'unique')) { if ($pk_val && is_string($rule) && Str::startsWith($rule, 'unique')) {
// unique rule without itself in update // unique rule without itself in update
@@ -1088,7 +1062,7 @@ abstract class AbstractController extends Controller
$up = $this->request->all(); $up = $this->request->all();
$up_fields = array_keys($up); $up_fields = array_keys($up);
foreach ($rules as $key => $val) { foreach ($rules as $key => $val) {
$field_extra = explode('|', $key); $field_extra = explode('|', (string) $key);
$field = $field_extra[0]; $field = $field_extra[0];
if (!in_array($field, $up_fields)) { if (!in_array($field, $up_fields)) {
unset($rules[$key]); unset($rules[$key]);
@@ -1117,7 +1091,6 @@ abstract class AbstractController extends Controller
* *
* @param string $message * @param string $message
* @param int $code * @param int $code
* @param \Throwable $previous
* *
* @return void * @return void
* @throws \Exception * @throws \Exception
@@ -1141,7 +1114,7 @@ abstract class AbstractController extends Controller
{ {
$validates = []; $validates = [];
foreach ($rules as $item) { foreach ($rules as $item) {
$parts = explode(':', $item); $parts = explode(':', (string) $item);
$rule = array_shift($parts); $rule = array_shift($parts);
switch ($rule) { switch ($rule) {
case 'required': case 'required':
@@ -1232,9 +1205,7 @@ abstract class AbstractController extends Controller
$filters = []; $filters = [];
if ($filter_options = $this->getListFilters()) { if ($filter_options = $this->getListFilters()) {
array_change_v2k($filter_options, 'field'); array_change_v2k($filter_options, 'field');
$filters = array_filter($this->request->inputs(array_keys($filter_options)), function ($item) { $filters = array_filter($this->request->inputs(array_keys($filter_options)), fn($item) => !in_array($item, [null, '']));
return !in_array($item, [null, '']);
});
} }
$list = []; $list = [];
if (is_array($notices)) { if (is_array($notices)) {
@@ -1289,7 +1260,7 @@ abstract class AbstractController extends Controller
{ {
$const = []; $const = [];
if ($model = $this->model_class ?? '') { if ($model = $this->model_class ?? '') {
$const = constant($model . '::' . strtoupper($field)) ?? []; $const = constant($model . '::' . strtoupper((string) $field)) ?? [];
} }
$options = []; $options = [];
foreach ($const as $k => $v) { foreach ($const as $k => $v) {
@@ -1305,8 +1276,6 @@ abstract class AbstractController extends Controller
/** /**
* 新版本检查 * 新版本检查
* *
* @param int $id
* @param int $last_ver_id
* *
* @return array * @return array
*/ */

View File

@@ -82,7 +82,7 @@ abstract class Controller
protected function getCalledSource($get_arr = false) protected function getCalledSource($get_arr = false)
{ {
$uri = $this->getRequestUri(); $uri = $this->getRequestUri();
$parts = array_filter(explode('/', $uri)); $parts = array_filter(explode('/', (string) $uri));
if ($get_arr) { if ($get_arr) {
return array_values($parts); return array_values($parts);
} }
@@ -98,9 +98,7 @@ abstract class Controller
/** /**
* 返回成功的请求 * 返回成功的请求
* *
* @param array $data
* @param string $message * @param string $message
*
* @return array * @return array
*/ */
public function success(array $data = [], $message = '操作成功') public function success(array $data = [], $message = '操作成功')
@@ -115,8 +113,6 @@ abstract class Controller
} }
/** /**
* @param int $code
* @param string|null $message
* *
* @return array * @return array
*/ */

View File

@@ -47,26 +47,21 @@ class OssAdapter extends AbstractAdapter
$isCName = false; $isCName = false;
$token = null; $token = null;
$this->supports = new Supports(); $this->supports = new Supports();
try { $this->bucket = $config['bucket'];
$this->bucket = $config['bucket']; empty($config['endpoint']) ? null : $this->endpoint = $config['endpoint'];
empty($config['endpoint']) ? null : $this->endpoint = $config['endpoint']; empty($config['timeout']) ? $config['timeout'] = 3600 : null;
empty($config['timeout']) ? $config['timeout'] = 3600 : null; empty($config['connectTimeout']) ? $config['connectTimeout'] = 10 : null;
empty($config['connectTimeout']) ? $config['connectTimeout'] = 10 : null; if (!empty($config['isCName'])) {
$isCName = true;
if (!empty($config['isCName'])) {
$isCName = true;
}
if (!empty($config['token'])) {
$token = $config['token'];
}
$this->oss = new OssClient(
$config['accessId'], $config['accessSecret'], $this->endpoint, $isCName, $token
);
$this->oss->setTimeout($config['timeout']);
$this->oss->setConnectTimeout($config['connectTimeout']);
} catch (Exception $e) {
throw $e;
} }
if (!empty($config['token'])) {
$token = $config['token'];
}
$this->oss = new OssClient(
$config['accessId'], $config['accessSecret'], $this->endpoint, $isCName, $token
);
$this->oss->setTimeout($config['timeout']);
$this->oss->setConnectTimeout($config['connectTimeout']);
} }
/** /**
@@ -214,7 +209,6 @@ class OssAdapter extends AbstractAdapter
* Create a directory. * Create a directory.
* *
* @param string $dirname directory name * @param string $dirname directory name
* @param Config $config
* *
* @return array|false * @return array|false
*/ */
@@ -422,7 +416,6 @@ class OssAdapter extends AbstractAdapter
/** /**
* Get OSS Options * Get OSS Options
* @param Config $config
* @return array * @return array
*/ */
private function getOssOptions(Config $config) private function getOssOptions(Config $config)

View File

@@ -22,15 +22,13 @@ class ProviderConfig
{ {
if (!static::$providerConfigs) { if (!static::$providerConfigs) {
$providers = Composer::getMergedExtra('hyperf')['config'] ?? []; $providers = Composer::getMergedExtra('hyperf')['config'] ?? [];
$handel = function ($arr) { $handel = (fn($arr) => array_map(function ($item) {
return array_map(function ($item) { $explode = explode('@', $item);
$explode = explode('@', $item); return [
return [ 'provider' => $explode[0],
'provider' => $explode[0], 'weight' => $explode[1] ?? 0,
'weight' => $explode[1] ?? 0, ];
]; }, $arr));
}, $arr);
};
$package = $handel($providers); $package = $handel($providers);
array_change_v2k($package, 'provider'); array_change_v2k($package, 'provider');
@@ -43,9 +41,7 @@ class ProviderConfig
} }
$providers = array_values($package); $providers = array_values($package);
usort($providers, function ($a, $b) { usort($providers, fn($a, $b) => intval($a['weight'] > $b['weight']));
return intval($a['weight'] > $b['weight']);
});
$providers = array_column($providers, 'provider'); $providers = array_column($providers, 'provider');
static::$providerConfigs = static::loadProviders($providers); static::$providerConfigs = static::loadProviders($providers);
} }

View File

@@ -3,9 +3,7 @@
use Hyperf\HttpServer\Router\Router; use Hyperf\HttpServer\Router\Router;
// 健康检查 // 健康检查
Router::get('/ping', function () { Router::get('/ping', fn() => [
return [ 'code' => 200,
'code' => 200, 'message' => 'ok',
'message' => 'ok', ]);
];
});

View File

@@ -94,7 +94,7 @@ class ConfigCenterController extends AdminAbstractController
public function beforeFormResponse($id, &$data) public function beforeFormResponse($id, &$data)
{ {
$data['owner_uids'] = array_filter(array_map('intval', explode(',', $data['owner_uids']))); $data['owner_uids'] = array_filter(array_map('intval', explode(',', (string) $data['owner_uids'])));
} }
public function beforeSave($id, &$data) public function beforeSave($id, &$data)

View File

@@ -22,7 +22,7 @@ class InstallCommand extends HyperfCommand
$sql = file_get_contents(__DIR__ . '/install.sql'); $sql = file_get_contents(__DIR__ . '/install.sql');
$re = Db::connection('config_center')->getPdo()->exec($sql); Db::connection('config_center')->getPdo()->exec($sql);
$this->output->success('config_center db install success'); $this->output->success('config_center db install success');
} }

View File

@@ -55,7 +55,7 @@ class CommandJobAbstract extends HyperfCommand
$callback = function () { $callback = function () {
try { try {
$this->beforeRun(); $this->beforeRun();
call([$this, 'handle']); call($this->handle(...));
$this->afterRun(); $this->afterRun();
} catch (\Throwable $throwable) { } catch (\Throwable $throwable) {
$this->onError($throwable); $this->onError($throwable);

View File

@@ -51,7 +51,7 @@ class CronNodeController extends AbstractController
CronNodes::STATUS_LOSS => 'danger', CronNodes::STATUS_LOSS => 'danger',
], ],
'render' => function ($status, $row) { 'render' => function ($status, $row) {
if ((time() - strtotime($row['updated_at'])) > 60) { if ((time() - strtotime((string) $row['updated_at'])) > 60) {
return CronNodes::STATUS_LOSS; return CronNodes::STATUS_LOSS;
} }

View File

@@ -168,9 +168,7 @@ class CrontabController extends AbstractController
'运行次数: {state.counter}', '运行次数: {state.counter}',
], ],
], ],
'render' => function () { 'render' => fn() => '悬浮查看',
return '悬浮查看';
},
], ],
], ],
'rowActions' => [ 'rowActions' => [
@@ -207,7 +205,7 @@ class CrontabController extends AbstractController
public function beforeFormResponse($id, &$record) public function beforeFormResponse($id, &$record)
{ {
$record['bind_nodes'] = array_map('intval', explode(',', $record['bind_nodes'])); $record['bind_nodes'] = array_map('intval', explode(',', (string) $record['bind_nodes']));
} }
public function trigger($id) public function trigger($id)

View File

@@ -13,13 +13,10 @@ class CronManager
*/ */
private $config; private $config;
private $db;
public function __construct() public function __construct()
{ {
$container = ApplicationContext::getContainer(); $container = ApplicationContext::getContainer();
$this->config = $container->get(ConfigInterface::class); $this->config = $container->get(ConfigInterface::class);
$this->db = $this->getConn();
} }
public function addConfig() public function addConfig()
@@ -71,9 +68,9 @@ class CronManager
} }
$list = $query->where('status', 1)->where('is_deleted', 0)->get()->toArray(); $list = $query->where('status', 1)->where('is_deleted', 0)->get()->toArray();
foreach ($list as &$item) { foreach ($list as &$item) {
$item['config'] = json_decode($item['config'], true); $item['config'] = json_decode((string) $item['config'], true);
$item['state'] = json_decode($item['state'], true); $item['state'] = json_decode((string) $item['state'], true);
$item['alert_rule'] = json_decode($item['alert_rule'], true); $item['alert_rule'] = json_decode((string) $item['alert_rule'], true);
unset($item); unset($item);
} }
@@ -106,7 +103,7 @@ class CronManager
if (!$job) { if (!$job) {
return false; return false;
} }
$job['config'] = json_decode($job['config'], true); $job['config'] = json_decode((string) $job['config'], true);
return $this->convertCrontab($job); return $this->convertCrontab($job);
} }
@@ -127,9 +124,8 @@ class CronManager
->setSingleton($item['singleton'] ?? true) ->setSingleton($item['singleton'] ?? true)
->setOnOneServer($item['on_one_server'] ?? true) ->setOnOneServer($item['on_one_server'] ?? true)
->setCallback($callback); ->setCallback($callback);
break;
case 'class': case 'class':
$class = explode('::', $config['execute']); $class = explode('::', (string) $config['execute']);
$callback = [$class[0], 'run', $config['params']]; $callback = [$class[0], 'run', $config['params']];
return (new Crontab)->setId($item['id']) return (new Crontab)->setId($item['id'])
@@ -138,7 +134,6 @@ class CronManager
->setSingleton($item['singleton'] ?? true) ->setSingleton($item['singleton'] ?? true)
->setOnOneServer($item['on_one_server'] ?? false) ->setOnOneServer($item['on_one_server'] ?? false)
->setCallback($callback); ->setCallback($callback);
break;
case 'gateway': case 'gateway':
$callback = [ $callback = [
'api' => $config['api'], 'api' => $config['api'],
@@ -154,7 +149,6 @@ class CronManager
->setSingleton($item['singleton'] ?? true) ->setSingleton($item['singleton'] ?? true)
->setOnOneServer($item['on_one_server'] ?? false) ->setOnOneServer($item['on_one_server'] ?? false)
->setCallback($callback); ->setCallback($callback);
break;
default: default:
return false; return false;
} }
@@ -214,7 +208,7 @@ class CronManager
{ {
$state = $this->getConn()->table('cron_jobs')->find($id)['state']; $state = $this->getConn()->table('cron_jobs')->find($id)['state'];
return $state ? json_decode($state, true) : []; return $state ? json_decode((string) $state, true) : [];
} }
public function setJobState($id, $data) public function setJobState($id, $data)

View File

@@ -58,7 +58,7 @@ class CrontabDispatcherProcess extends ProcessCrontabDispatcherProcess
$crontabs = $this->getCrontabs(); $crontabs = $this->getCrontabs();
$this->logger->info(sprintf('Crontab dispatcher the %s time, jobs total %s', $this->counter, count($crontabs))); $this->logger->info(sprintf('Crontab dispatcher the %s time, jobs total %s', $this->counter, count($crontabs)));
$last = time(); $last = time();
foreach ($crontabs ?? [] as $key => $crontab) { foreach ($crontabs ?? [] as $crontab) {
$time = $this->parser->parse($crontab->getRule(), $last); $time = $this->parser->parse($crontab->getRule(), $last);
if ($time) { if ($time) {
foreach ($time as $t) { foreach ($time as $t) {

View File

@@ -14,17 +14,14 @@ use Symfony\Component\Console\Output\NullOutput;
class Executor extends StrategyExecutor class Executor extends StrategyExecutor
{ {
private $manager;
public function __construct(ContainerInterface $container) public function __construct(ContainerInterface $container)
{ {
parent::__construct($container); parent::__construct($container);
$this->manager = new CronManager();
} }
public function execute(Crontab $crontab) public function execute(Crontab $crontab)
{ {
if (!($crontab instanceof Crontab) || !$crontab->getCallback()) { if (!$crontab->getCallback()) {
return false; return false;
} }
$handle = $crontab->getType() . 'Handle'; $handle = $crontab->getType() . 'Handle';
@@ -90,9 +87,7 @@ class Executor extends StrategyExecutor
public function evalHandle(Crontab $crontab) public function evalHandle(Crontab $crontab)
{ {
return function () use ($crontab) { return fn() => eval($crontab->getCallback());
return eval($crontab->getCallback());
};
} }
protected function runInSingleton(Crontab $crontab, Closure $runnable): Closure protected function runInSingleton(Crontab $crontab, Closure $runnable): Closure

View File

@@ -22,7 +22,7 @@ class InstallCommand extends HyperfCommand
$sql = file_get_contents(__DIR__ . '/install.sql'); $sql = file_get_contents(__DIR__ . '/install.sql');
$re = Db::connection('cron_center')->getPdo()->exec($sql); Db::connection('cron_center')->getPdo()->exec($sql);
$this->output->success('cron_center db install success'); $this->output->success('cron_center db install success');
} }

View File

@@ -48,9 +48,7 @@ class DsnController extends AbstractController
[ [
'field' => 'create_uid', 'field' => 'create_uid',
'title' => '创建者', 'title' => '创建者',
'render' => function ($val, $row) { 'render' => fn($val, $row) => $row['realname'],
return $row['realname'];
},
], ],
], ],
'rowActions' => [ 'rowActions' => [

View File

@@ -22,7 +22,7 @@ class InstallCommand extends HyperfCommand
$sql = file_get_contents(__DIR__ . '/install.sql'); $sql = file_get_contents(__DIR__ . '/install.sql');
$re = Db::connection('cron_center')->getPdo()->exec($sql); Db::connection('cron_center')->getPdo()->exec($sql);
$this->output->success('data_focus db install success'); $this->output->success('data_focus db install success');
} }

View File

@@ -7,11 +7,8 @@ use HyperfAdmin\BaseUtils\Redis\Redis;
class Dsn class Dsn
{ {
private $config; public function __construct(private readonly ConfigInterface $config)
public function __construct(ConfigInterface $config)
{ {
$this->config = $config;
} }
public function initAll() public function initAll()
@@ -24,7 +21,7 @@ class Dsn
// todo decrypt // todo decrypt
//$dsn_list = $this->config->decryptOne($dsn_list); //$dsn_list = $this->config->decryptOne($dsn_list);
foreach($dsn_list as $dsn) { foreach($dsn_list as $dsn) {
$method = 'add' . strtolower(DsnModel::$types[$dsn['type']]); $method = 'add' . strtolower((string) DsnModel::$types[$dsn['type']]);
if(method_exists($this, $method)) { if(method_exists($this, $method)) {
$this->{$method}($dsn['name'], $dsn['config']); $this->{$method}($dsn['name'], $dsn['config']);
} }
@@ -51,7 +48,7 @@ class Dsn
if(!$dsn) { if(!$dsn) {
return false; return false;
} }
$method = $type . strtolower(DsnModel::$types[$dsn['type']]); $method = $type . strtolower((string) DsnModel::$types[$dsn['type']]);
$this->{$method}($dsn['name'], $dsn['config']); $this->{$method}($dsn['name'], $dsn['config']);
} }

View File

@@ -27,10 +27,10 @@ class CodeRunner
$result = []; $result = [];
$errors = []; $errors = [];
$startTime = microtime(true); $startTime = microtime(true);
$namespace = sprintf("PHPSandbox_%s_%s", md5($code), (int)(microtime(true) * 1000)); $namespace = sprintf("PHPSandbox_%s_%s", md5((string) $code), (int)(microtime(true) * 1000));
$this->namespace = $namespace; $this->namespace = $namespace;
$this->runner->setNamespace($namespace); $this->runner->setNamespace($namespace);
if(preg_match_all('/df_\w+/', $code, $m)) { if(preg_match_all('/df_\w+/', (string) $code, $m)) {
$plugins = PluginFunction::query() $plugins = PluginFunction::query()
->where('status', PluginFunction::STATUS_YES) ->where('status', PluginFunction::STATUS_YES)
->whereIn('func_name', array_unique($m[0])) ->whereIn('func_name', array_unique($m[0]))
@@ -43,7 +43,7 @@ class CodeRunner
$code = implode("\n", $plugin_str) . $code; $code = implode("\n", $plugin_str) . $code;
} }
try { try {
if(preg_match_all('/<\?(?:php|=).*?\?>/msui', $code, $match)) { if(preg_match_all('/<\?(?:php|=).*?\?>/msui', (string) $code, $match)) {
foreach($match[0] ?? [] as $part) { foreach($match[0] ?? [] as $part) {
$ret = $this->executePHPCode($part); $ret = $this->executePHPCode($part);
$wrap = null; $wrap = null;
@@ -60,7 +60,7 @@ class CodeRunner
$code = str_replace($part, $replace, $code); $code = str_replace($part, $replace, $code);
} }
} }
if(preg_match_all('/\{{([^}]+)\}}/i', $code, $m)) { if(preg_match_all('/\{{([^}]+)\}}/i', (string) $code, $m)) {
foreach($m[1] as $each) { foreach($m[1] as $each) {
$ret = $this->pipFilter($each); $ret = $this->pipFilter($each);
$code = Str::replaceArray('{{' . $each . '}}', [$ret], $code); $code = Str::replaceArray('{{' . $each . '}}', [$ret], $code);
@@ -80,7 +80,7 @@ class CodeRunner
continue; continue;
} }
$type = $node->tag; $type = $node->tag;
$text = trim($node->innertext()); $text = trim((string) $node->innertext());
if($node->hasChildNodes()) { if($node->hasChildNodes()) {
throw new \Exception('一级标签不允许嵌套'); throw new \Exception('一级标签不允许嵌套');
} }
@@ -139,7 +139,7 @@ class CodeRunner
'type' => $part_type, 'type' => $part_type,
'chart' => (object)$this->getChartOptions($node->getAttribute('chart'), $data), 'chart' => (object)$this->getChartOptions($node->getAttribute('chart'), $data),
'col' => $this->getColOption($node->getAttribute('span') ?: $node->getAttribute('col')), 'col' => $this->getColOption($node->getAttribute('span') ?: $node->getAttribute('col')),
'show_table' => $node->hasAttribute('show_table') ? $node->getAttribute('show_table') == 'true' : false, 'show_table' => $node->hasAttribute('show_table') && $node->getAttribute('show_table') == 'true',
'data' => (array)$data, 'data' => (array)$data,
'tips' => $node->getAttribute('tips') ?: '', 'tips' => $node->getAttribute('tips') ?: '',
'runtime' => [ 'runtime' => [
@@ -159,9 +159,7 @@ class CodeRunner
return [ return [
'result' => $result, 'result' => $result,
'errors' => array_map(function ($item) use ($namespace) { 'errors' => array_map(fn($item) => Str::replaceArray($namespace . '\\', [''], $item), $errors),
return Str::replaceArray($namespace . '\\', [''], $item);
}, $errors),
'info' => [ 'info' => [
'use_ms' => (int)(($endTime - $startTime) * 1000), 'use_ms' => (int)(($endTime - $startTime) * 1000),
], ],
@@ -174,7 +172,7 @@ class CodeRunner
if(!$str) { if(!$str) {
return []; return [];
} }
$parts = explode('|', $str); $parts = explode('|', (string) $str);
return array_map(function ($item) { return array_map(function ($item) {
$tokens = preg_split('/[:,]/', $item); $tokens = preg_split('/[:,]/', $item);
@@ -258,9 +256,9 @@ class CodeRunner
]; ];
} }
if(Str::startsWith($conf, 'LineChart')) { if(Str::startsWith($conf, 'LineChart')) {
$token = explode('|', $conf); $token = explode('|', (string) $conf);
array_shift($token); array_shift($token);
$field = explode(',', array_shift($token)); $field = explode(',', (string) array_shift($token));
$x = array_shift($field); $x = array_shift($field);
$y = $field; $y = $field;
@@ -293,9 +291,9 @@ class CodeRunner
]; ];
} }
if(Str::startsWith($conf, 'ColumnChart')) { if(Str::startsWith($conf, 'ColumnChart')) {
$token = explode('|', $conf); $token = explode('|', (string) $conf);
array_shift($token); array_shift($token);
$field = explode(',', array_shift($token)); $field = explode(',', (string) array_shift($token));
$x = array_shift($field); $x = array_shift($field);
$y = $field; $y = $field;
@@ -326,7 +324,7 @@ class CodeRunner
public function pipFilter($str) public function pipFilter($str)
{ {
$parts = explode('|', trim($str)); $parts = explode('|', trim((string) $str));
$first = array_shift($parts); $first = array_shift($parts);
$code = "<?php\n\$ret = $first;"; $code = "<?php\n\$ret = $first;";
$raw = false; $raw = false;

View File

@@ -73,7 +73,7 @@ class PHPSandbox
public function execute($code) public function execute($code)
{ {
if(preg_match('/<\?(?:php|=)(.*)?\?>/msui', $code, $match)) { if(preg_match('/<\?(?:php|=)(.*)?\?>/msui', (string) $code, $match)) {
$code = trim($match[1]); $code = trim($match[1]);
} }
if($this->namespace) { if($this->namespace) {
@@ -142,7 +142,7 @@ class PHPSandbox
$this->validatorFunc($call); $this->validatorFunc($call);
} }
public function filterClass(Class_ $parserClass) public function filterClass(Class_ $parserClass): never
{ {
$class = $parserClass->name->toString(); $class = $parserClass->name->toString();
throw new SandboxException(sprintf('define class [%s] not allowed!', $class)); throw new SandboxException(sprintf('define class [%s] not allowed!', $class));

View File

@@ -74,7 +74,7 @@ function file_get_html($url, $use_include_path = false, $context = null, $offset
if($context !== null) { if($context !== null) {
// Test if "Accept-Encoding: gzip" has been set in $context // Test if "Accept-Encoding: gzip" has been set in $context
$params = stream_context_get_params($context); $params = stream_context_get_params($context);
if(isset($params['options']['http']['header']) && preg_match('/gzip/', $params['options']['http']['header']) !== false) { if(isset($params['options']['http']['header']) && preg_match('/gzip/', (string) $params['options']['http']['header']) !== false) {
$contents = file_get_contents('compress.zlib://' . $url, $use_include_path, $context, $offset); $contents = file_get_contents('compress.zlib://' . $url, $use_include_path, $context, $offset);
} else { } else {
$contents = file_get_contents($url, $use_include_path, $context, $offset); $contents = file_get_contents($url, $use_include_path, $context, $offset);
@@ -83,11 +83,11 @@ function file_get_html($url, $use_include_path = false, $context = null, $offset
$contents = file_get_contents($url, $use_include_path, null, $offset); $contents = file_get_contents($url, $use_include_path, null, $offset);
} }
// test if the URL doesn't return a 200 status // test if the URL doesn't return a 200 status
if(isset($http_response_header) && strpos($http_response_header[0], '200') === false) { if(!str_contains($http_response_header[0], '200')) {
// has a 301 redirect header been sent? // has a 301 redirect header been sent?
$pattern = "/^Location:\s*(.*)$/i"; $pattern = "/^Location:\s*(.*)$/i";
$location_headers = preg_grep($pattern, $http_response_header); $location_headers = preg_grep($pattern, $http_response_header);
if(!empty($location_headers) && preg_match($pattern, array_values($location_headers)[0], $matches)) { if(!empty($location_headers) && preg_match($pattern, (string) array_values($location_headers)[0], $matches)) {
// set the URL to that returned via the redirect header and repeat this loop // set the URL to that returned via the redirect header and repeat this loop
$url = $matches[1]; $url = $matches[1];
$repeat = true; $repeat = true;
@@ -95,7 +95,7 @@ function file_get_html($url, $use_include_path = false, $context = null, $offset
} }
} while($repeat); } while($repeat);
// stop processing if the header isn't a good responce // stop processing if the header isn't a good responce
if(isset($http_response_header) && strpos($http_response_header[0], '200') === false) { if(!str_contains($http_response_header[0], '200')) {
return false; return false;
} }
// stop processing if the contents are too big // stop processing if the contents are too big
@@ -112,7 +112,7 @@ function file_get_html($url, $use_include_path = false, $context = null, $offset
function str_get_html($str, $lowercase = true, $forceTagsClosed = true, $target_charset = DEFAULT_TARGET_CHARSET, $stripRN = true, $defaultBRText = DEFAULT_BR_TEXT, $defaultSpanText = DEFAULT_SPAN_TEXT) function str_get_html($str, $lowercase = true, $forceTagsClosed = true, $target_charset = DEFAULT_TARGET_CHARSET, $stripRN = true, $defaultBRText = DEFAULT_BR_TEXT, $defaultSpanText = DEFAULT_SPAN_TEXT)
{ {
$dom = new simple_html_dom(null, $lowercase, $forceTagsClosed, $target_charset, $stripRN, $defaultBRText, $defaultSpanText); $dom = new simple_html_dom(null, $lowercase, $forceTagsClosed, $target_charset, $stripRN, $defaultBRText, $defaultSpanText);
if(empty($str) || strlen($str) > MAX_FILE_SIZE) { if(empty($str) || strlen((string) $str) > MAX_FILE_SIZE) {
$dom->clear(); $dom->clear();
return false; return false;
@@ -135,7 +135,7 @@ function dump_html_tree($node, $show_attr = true, $deep = 0)
* *
* @package PlaceLocalInclude * @package PlaceLocalInclude
*/ */
class simple_html_dom_node class simple_html_dom_node implements \Stringable
{ {
public $nodetype = HDOM_TYPE_TEXT; public $nodetype = HDOM_TYPE_TEXT;
@@ -147,19 +147,16 @@ class simple_html_dom_node
public $nodes = []; public $nodes = [];
public $parent = null; public $parent;
// The "info" array - see HDOM_INFO_... for what each element contains. // The "info" array - see HDOM_INFO_... for what each element contains.
public $_ = []; public $_ = [];
public $tag_start = 0; public $tag_start = 0;
private $dom = null; function __construct(private $dom)
function __construct($dom)
{ {
$this->dom = $dom; $this->dom->nodes[] = $this;
$dom->nodes[] = $this;
} }
function __destruct() function __destruct()
@@ -167,9 +164,9 @@ class simple_html_dom_node
$this->clear(); $this->clear();
} }
function __toString() function __toString(): string
{ {
return $this->outertext(); return (string) $this->outertext();
} }
// clean up memory due to php5 circular references memory leak... // clean up memory due to php5 circular references memory leak...
@@ -276,11 +273,8 @@ class simple_html_dom_node
if($idx === -1) { if($idx === -1) {
return $this->children; return $this->children;
} }
if(isset($this->children[$idx])) {
return $this->children[$idx];
}
return null; return $this->children[$idx] ?? null;
} }
// returns the first child of node // returns the first child of node
@@ -441,14 +435,13 @@ class simple_html_dom_node
case HDOM_TYPE_TEXT: case HDOM_TYPE_TEXT:
return $this->dom->restore_noise($this->_[HDOM_INFO_TEXT]); return $this->dom->restore_noise($this->_[HDOM_INFO_TEXT]);
case HDOM_TYPE_COMMENT: case HDOM_TYPE_COMMENT:
return '';
case HDOM_TYPE_UNKNOWN: case HDOM_TYPE_UNKNOWN:
return ''; return '';
} }
if(strcasecmp($this->tag, 'script') === 0) { if(strcasecmp((string) $this->tag, 'script') === 0) {
return ''; return '';
} }
if(strcasecmp($this->tag, 'style') === 0) { if(strcasecmp((string) $this->tag, 'style') === 0) {
return ''; return '';
} }
$ret = ''; $ret = '';
@@ -472,9 +465,8 @@ class simple_html_dom_node
{ {
$ret = $this->innertext(); $ret = $this->innertext();
$ret = str_ireplace('<![CDATA[', '', $ret); $ret = str_ireplace('<![CDATA[', '', $ret);
$ret = str_replace(']]>', '', $ret);
return $ret; return str_replace(']]>', '', $ret);
} }
// build node's text with tag // build node's text with tag
@@ -497,16 +489,11 @@ class simple_html_dom_node
if($val === true) { if($val === true) {
$ret .= $key; $ret .= $key;
} else { } else {
switch($this->_[HDOM_INFO_QUOTE][$i]) { $quote = match ($this->_[HDOM_INFO_QUOTE][$i]) {
case HDOM_QUOTE_DOUBLE: HDOM_QUOTE_DOUBLE => '"',
$quote = '"'; HDOM_QUOTE_SINGLE => '\'',
break; default => '',
case HDOM_QUOTE_SINGLE: };
$quote = '\'';
break;
default:
$quote = '';
}
$ret .= $key . $this->_[HDOM_INFO_SPACE][$i][1] . '=' . $this->_[HDOM_INFO_SPACE][$i][2] . $quote . $val . $quote; $ret .= $key . $this->_[HDOM_INFO_SPACE][$i][1] . '=' . $this->_[HDOM_INFO_SPACE][$i][2] . $quote . $val . $quote;
} }
} }
@@ -564,7 +551,7 @@ class simple_html_dom_node
$idx = count($found) + $idx; $idx = count($found) + $idx;
} }
return (isset($found[$idx])) ? $found[$idx] : null; return $found[$idx] ?? null;
} }
// seek for given conditions // seek for given conditions
@@ -640,7 +627,7 @@ class simple_html_dom_node
} }
//PaperG - If lowercase is set, do a case insensitive test of the value of the selector. //PaperG - If lowercase is set, do a case insensitive test of the value of the selector.
if($lowercase) { if($lowercase) {
$check = $this->match($exp, strtolower($val), strtolower($nodeKeyValue)); $check = $this->match($exp, strtolower((string) $val), strtolower((string) $nodeKeyValue));
} else { } else {
$check = $this->match($exp, $val, $nodeKeyValue); $check = $this->match($exp, $val, $nodeKeyValue);
} }
@@ -648,12 +635,12 @@ class simple_html_dom_node
$debugObject->debugLog(2, "after match: " . ($check ? "true" : "false")); $debugObject->debugLog(2, "after match: " . ($check ? "true" : "false"));
} }
// handle multiple class // handle multiple class
if(!$check && strcasecmp($key, 'class') === 0) { if(!$check && strcasecmp((string) $key, 'class') === 0) {
foreach(explode(' ', $node->attr[$key]) as $k) { foreach(explode(' ', (string) $node->attr[$key]) as $k) {
// Without this, there were cases where leading, trailing, or double spaces lead to our comparing blanks - bad form. // Without this, there were cases where leading, trailing, or double spaces lead to our comparing blanks - bad form.
if(!empty($k)) { if(!empty($k)) {
if($lowercase) { if($lowercase) {
$check = $this->match($exp, strtolower($val), strtolower($k)); $check = $this->match($exp, strtolower((string) $val), strtolower($k));
} else { } else {
$check = $this->match($exp, $val, $k); $check = $this->match($exp, $val, $k);
} }
@@ -690,15 +677,15 @@ class simple_html_dom_node
case '!=': case '!=':
return ($value !== $pattern); return ($value !== $pattern);
case '^=': case '^=':
return preg_match("/^" . preg_quote($pattern, '/') . "/", $value); return preg_match("/^" . preg_quote((string) $pattern, '/') . "/", (string) $value);
case '$=': case '$=':
return preg_match("/" . preg_quote($pattern, '/') . "$/", $value); return preg_match("/" . preg_quote((string) $pattern, '/') . "$/", (string) $value);
case '*=': case '*=':
if($pattern[0] == '/') { if($pattern[0] == '/') {
return preg_match($pattern, $value); return preg_match($pattern, (string) $value);
} }
return preg_match("/" . $pattern . "/i", $value); return preg_match("/" . $pattern . "/i", (string) $value);
} }
return false; return false;
@@ -718,7 +705,7 @@ class simple_html_dom_node
// farther study is required to determine of this should be documented or removed. // farther study is required to determine of this should be documented or removed.
// $pattern = "/([\w-:\*]*)(?:\#([\w-]+)|\.([\w-]+))?(?:\[@?(!?[\w-]+)(?:([!*^$]?=)[\"']?(.*?)[\"']?)?\])?([\/, ]+)/is"; // $pattern = "/([\w-:\*]*)(?:\#([\w-]+)|\.([\w-]+))?(?:\[@?(!?[\w-]+)(?:([!*^$]?=)[\"']?(.*?)[\"']?)?\])?([\/, ]+)/is";
$pattern = "/([\w\-:\*]*)(?:\#([\w\-]+)|\.([\w\-]+))?(?:\[@?(!?[\w\-:]+)(?:([!*^$]?=)[\"']?(.*?)[\"']?)?\])?([\/, ]+)/is"; $pattern = "/([\w\-:\*]*)(?:\#([\w\-]+)|\.([\w\-]+))?(?:\[@?(!?[\w\-:]+)(?:([!*^$]?=)[\"']?(.*?)[\"']?)?\])?([\/, ]+)/is";
preg_match_all($pattern, trim($selector_string) . ' ', $matches, PREG_SET_ORDER); preg_match_all($pattern, trim((string) $selector_string) . ' ', $matches, PREG_SET_ORDER);
if(is_object($debugObject)) { if(is_object($debugObject)) {
$debugObject->debugLog(2, "Matches Array: ", $matches); $debugObject->debugLog(2, "Matches Array: ", $matches);
} }
@@ -755,7 +742,7 @@ class simple_html_dom_node
// convert to lowercase // convert to lowercase
if($this->dom->lowercase) { if($this->dom->lowercase) {
$tag = strtolower($tag); $tag = strtolower($tag);
$key = strtolower($key); $key = strtolower((string) $key);
} }
//elements that do NOT have the specified attribute //elements that do NOT have the specified attribute
if(isset($key[0]) && $key[0] === '!') { if(isset($key[0]) && $key[0] === '!') {
@@ -780,18 +767,13 @@ class simple_html_dom_node
if(isset($this->attr[$name])) { if(isset($this->attr[$name])) {
return $this->convert_text($this->attr[$name]); return $this->convert_text($this->attr[$name]);
} }
switch($name) { return match ($name) {
case 'outertext': 'outertext' => $this->outertext(),
return $this->outertext(); 'innertext' => $this->innertext(),
case 'innertext': 'plaintext' => $this->text(),
return $this->innertext(); 'xmltext' => $this->xmltext(),
case 'plaintext': default => array_key_exists($name, $this->attr),
return $this->text(); };
case 'xmltext':
return $this->xmltext();
default:
return array_key_exists($name, $this->attr);
}
} }
function __set($name, $value) function __set($name, $value)
@@ -815,17 +797,13 @@ class simple_html_dom_node
function __isset($name) function __isset($name)
{ {
switch($name) { return match ($name) {
case 'outertext': 'outertext' => true,
return true; 'innertext' => true,
case 'innertext': 'plaintext' => true,
return true; //no value attr: nowrap, checked selected...
case 'plaintext': default => (array_key_exists($name, $this->attr)) ? true : isset($this->attr[$name]),
return true; };
}
//no value attr: nowrap, checked selected...
return (array_key_exists($name, $this->attr)) ? true : isset($this->attr[$name]);
} }
function __unset($name) function __unset($name)
@@ -846,27 +824,27 @@ class simple_html_dom_node
$sourceCharset = ""; $sourceCharset = "";
$targetCharset = ""; $targetCharset = "";
if($this->dom) { if($this->dom) {
$sourceCharset = strtoupper($this->dom->_charset); $sourceCharset = strtoupper((string) $this->dom->_charset);
$targetCharset = strtoupper($this->dom->_target_charset); $targetCharset = strtoupper((string) $this->dom->_target_charset);
} }
if(is_object($debugObject)) { if(is_object($debugObject)) {
$debugObject->debugLog(3, "source charset: " . $sourceCharset . " target charaset: " . $targetCharset); $debugObject->debugLog(3, "source charset: " . $sourceCharset . " target charaset: " . $targetCharset);
} }
if(!empty($sourceCharset) && !empty($targetCharset) && (strcasecmp($sourceCharset, $targetCharset) != 0)) { if(!empty($sourceCharset) && !empty($targetCharset) && (strcasecmp($sourceCharset, $targetCharset) != 0)) {
// Check if the reported encoding could have been incorrect and the text is actually already UTF-8 // Check if the reported encoding could have been incorrect and the text is actually already UTF-8
if((strcasecmp($targetCharset, 'UTF-8') == 0) && ($this->is_utf8($text))) { if((strcasecmp($targetCharset, 'UTF-8') == 0) && (static::is_utf8($text))) {
$converted_text = $text; $converted_text = $text;
} else { } else {
$converted_text = iconv($sourceCharset, $targetCharset, $text); $converted_text = iconv($sourceCharset, $targetCharset, (string) $text);
} }
} }
// Lets make sure that we don't have that silly BOM issue with any of the utf-8 text we output. // Lets make sure that we don't have that silly BOM issue with any of the utf-8 text we output.
if($targetCharset == 'UTF-8') { if($targetCharset == 'UTF-8') {
if(substr($converted_text, 0, 3) == "\xef\xbb\xbf") { if(str_starts_with((string) $converted_text, "\xef\xbb\xbf")) {
$converted_text = substr($converted_text, 3); $converted_text = substr((string) $converted_text, 3);
} }
if(substr($converted_text, -3) == "\xef\xbb\xbf") { if(str_ends_with((string) $converted_text, "\xef\xbb\xbf")) {
$converted_text = substr($converted_text, 0, -3); $converted_text = substr((string) $converted_text, 0, -3);
} }
} }
@@ -885,7 +863,7 @@ class simple_html_dom_node
$c = 0; $c = 0;
$b = 0; $b = 0;
$bits = 0; $bits = 0;
$len = strlen($str); $len = strlen((string) $str);
for($i = 0; $i < $len; $i++) { for($i = 0; $i < $len; $i++) {
$c = ord($str[$i]); $c = ord($str[$i]);
if($c > 128) { if($c > 128) {
@@ -1098,13 +1076,13 @@ class simple_html_dom_node
* *
* @package PlaceLocalInclude * @package PlaceLocalInclude
*/ */
class simple_html_dom class simple_html_dom implements \Stringable
{ {
public $root = null; public $root;
public $nodes = []; public $nodes = [];
public $callback = null; public $callback;
public $lowercase = false; public $lowercase = false;
@@ -1136,8 +1114,6 @@ class simple_html_dom
// Note that this is referenced by a child node, and so it needs to be public for that node to see this information. // Note that this is referenced by a child node, and so it needs to be public for that node to see this information.
public $_charset = ''; public $_charset = '';
public $_target_charset = '';
protected $default_br_text = ""; protected $default_br_text = "";
public $default_span_text = ""; public $default_span_text = "";
@@ -1180,10 +1156,10 @@ class simple_html_dom
'option' => ['option' => 1], 'option' => ['option' => 1],
]; ];
function __construct($str = null, $lowercase = true, $forceTagsClosed = true, $target_charset = DEFAULT_TARGET_CHARSET, $stripRN = true, $defaultBRText = DEFAULT_BR_TEXT, $defaultSpanText = DEFAULT_SPAN_TEXT) function __construct($str = null, $lowercase = true, $forceTagsClosed = true, public $_target_charset = DEFAULT_TARGET_CHARSET, $stripRN = true, $defaultBRText = DEFAULT_BR_TEXT, $defaultSpanText = DEFAULT_SPAN_TEXT)
{ {
if($str) { if($str) {
if(preg_match("/^http:\/\//i", $str) || is_file($str)) { if(preg_match("/^http:\/\//i", (string) $str) || is_file($str)) {
$this->load_file($str); $this->load_file($str);
} else { } else {
$this->load($str, $lowercase, $stripRN, $defaultBRText, $defaultSpanText); $this->load($str, $lowercase, $stripRN, $defaultBRText, $defaultSpanText);
@@ -1193,7 +1169,6 @@ class simple_html_dom
if(!$forceTagsClosed) { if(!$forceTagsClosed) {
$this->optional_closing_array = []; $this->optional_closing_array = [];
} }
$this->_target_charset = $target_charset;
} }
function __destruct() function __destruct()
@@ -1316,7 +1291,7 @@ class simple_html_dom
{ {
$this->clear(); $this->clear();
// set the length of content before we do anything to it. // set the length of content before we do anything to it.
$this->size = strlen($str); $this->size = strlen((string) $str);
// Save the original size of the html that we got in. It might be useful to someone. // Save the original size of the html that we got in. It might be useful to someone.
$this->original_size = $this->size; $this->original_size = $this->size;
//before we save the string as the doc... strip out the \r \n's if we are told to. //before we save the string as the doc... strip out the \r \n's if we are told to.
@@ -1384,7 +1359,7 @@ class simple_html_dom
$debugObject->debugLog(2, 'meta content-type tag found' . $fullvalue); $debugObject->debugLog(2, 'meta content-type tag found' . $fullvalue);
} }
if(!empty($fullvalue)) { if(!empty($fullvalue)) {
$success = preg_match('/charset=(.+)/', $fullvalue, $matches); $success = preg_match('/charset=(.+)/', (string) $fullvalue, $matches);
if($success) { if($success) {
$charset = $matches[1]; $charset = $matches[1];
} else { } else {
@@ -1447,19 +1422,19 @@ class simple_html_dom
$this->skip($this->token_blank); $this->skip($this->token_blank);
$tag = $this->copy_until_char('>'); $tag = $this->copy_until_char('>');
// skip attributes in end tag // skip attributes in end tag
if(($pos = strpos($tag, ' ')) !== false) { if(($pos = strpos((string) $tag, ' ')) !== false) {
$tag = substr($tag, 0, $pos); $tag = substr((string) $tag, 0, $pos);
} }
$parent_lower = strtolower($this->parent->tag); $parent_lower = strtolower((string) $this->parent->tag);
$tag_lower = strtolower($tag); $tag_lower = strtolower((string) $tag);
if($parent_lower !== $tag_lower) { if($parent_lower !== $tag_lower) {
if(isset($this->optional_closing_tags[$parent_lower]) && isset($this->block_tags[$tag_lower])) { if(isset($this->optional_closing_tags[$parent_lower]) && isset($this->block_tags[$tag_lower])) {
$this->parent->_[HDOM_INFO_END] = 0; $this->parent->_[HDOM_INFO_END] = 0;
$org_parent = $this->parent; $org_parent = $this->parent;
while(($this->parent->parent) && strtolower($this->parent->tag) !== $tag_lower) { while(($this->parent->parent) && strtolower((string) $this->parent->tag) !== $tag_lower) {
$this->parent = $this->parent->parent; $this->parent = $this->parent->parent;
} }
if(strtolower($this->parent->tag) !== $tag_lower) { if(strtolower((string) $this->parent->tag) !== $tag_lower) {
$this->parent = $org_parent; // restore origonal parent $this->parent = $org_parent; // restore origonal parent
if($this->parent->parent) { if($this->parent->parent) {
$this->parent = $this->parent->parent; $this->parent = $this->parent->parent;
@@ -1471,16 +1446,16 @@ class simple_html_dom
} elseif(($this->parent->parent) && isset($this->block_tags[$tag_lower])) { } elseif(($this->parent->parent) && isset($this->block_tags[$tag_lower])) {
$this->parent->_[HDOM_INFO_END] = 0; $this->parent->_[HDOM_INFO_END] = 0;
$org_parent = $this->parent; $org_parent = $this->parent;
while(($this->parent->parent) && strtolower($this->parent->tag) !== $tag_lower) { while(($this->parent->parent) && strtolower((string) $this->parent->tag) !== $tag_lower) {
$this->parent = $this->parent->parent; $this->parent = $this->parent->parent;
} }
if(strtolower($this->parent->tag) !== $tag_lower) { if(strtolower((string) $this->parent->tag) !== $tag_lower) {
$this->parent = $org_parent; // restore origonal parent $this->parent = $org_parent; // restore origonal parent
$this->parent->_[HDOM_INFO_END] = $this->cursor; $this->parent->_[HDOM_INFO_END] = $this->cursor;
return $this->as_text_node($tag); return $this->as_text_node($tag);
} }
} elseif(($this->parent->parent) && strtolower($this->parent->parent->tag) === $tag_lower) { } elseif(($this->parent->parent) && strtolower((string) $this->parent->parent->tag) === $tag_lower) {
$this->parent->_[HDOM_INFO_END] = 0; $this->parent->_[HDOM_INFO_END] = 0;
$this->parent = $this->parent->parent; $this->parent = $this->parent->parent;
} else { } else {
@@ -1519,15 +1494,15 @@ class simple_html_dom
return true; return true;
} }
// text // text
if($pos = strpos($tag, '<') !== false) { if($pos = str_contains((string) $tag, '<')) {
$tag = '<' . substr($tag, 0, -1); $tag = '<' . substr((string) $tag, 0, -1);
$node->_[HDOM_INFO_TEXT] = $tag; $node->_[HDOM_INFO_TEXT] = $tag;
$this->link_nodes($node, false); $this->link_nodes($node, false);
$this->char = $this->doc[--$this->pos]; // prev $this->char = $this->doc[--$this->pos]; // prev
return true; return true;
} }
if(!preg_match("/^[\w\-:]+$/", $tag)) { if(!preg_match("/^[\w\-:]+$/", (string) $tag)) {
$node->_[HDOM_INFO_TEXT] = '<' . $tag . $this->copy_until('<>'); $node->_[HDOM_INFO_TEXT] = '<' . $tag . $this->copy_until('<>');
if($this->char === '<') { if($this->char === '<') {
$this->link_nodes($node, false); $this->link_nodes($node, false);
@@ -1544,11 +1519,11 @@ class simple_html_dom
} }
// begin tag // begin tag
$node->nodetype = HDOM_TYPE_ELEMENT; $node->nodetype = HDOM_TYPE_ELEMENT;
$tag_lower = strtolower($tag); $tag_lower = strtolower((string) $tag);
$node->tag = ($this->lowercase) ? $tag_lower : $tag; $node->tag = ($this->lowercase) ? $tag_lower : $tag;
// handle optional closing tags // handle optional closing tags
if(isset($this->optional_closing_tags[$tag_lower])) { if(isset($this->optional_closing_tags[$tag_lower])) {
while(isset($this->optional_closing_tags[$tag_lower][strtolower($this->parent->tag)])) { while(isset($this->optional_closing_tags[$tag_lower][strtolower((string) $this->parent->tag)])) {
$this->parent->_[HDOM_INFO_END] = 0; $this->parent->_[HDOM_INFO_END] = 0;
$this->parent = $this->parent->parent; $this->parent = $this->parent->parent;
} }
@@ -1583,7 +1558,7 @@ class simple_html_dom
$node->tag = 'text'; $node->tag = 'text';
$node->attr = []; $node->attr = [];
$node->_[HDOM_INFO_END] = 0; $node->_[HDOM_INFO_END] = 0;
$node->_[HDOM_INFO_TEXT] = substr($this->doc, $begin_tag_pos, $this->pos - $begin_tag_pos - 1); $node->_[HDOM_INFO_TEXT] = substr((string) $this->doc, $begin_tag_pos, $this->pos - $begin_tag_pos - 1);
$this->pos -= 2; $this->pos -= 2;
$this->char = (++$this->pos < $this->size) ? $this->doc[$this->pos] : null; // next $this->char = (++$this->pos < $this->size) ? $this->doc[$this->pos] : null; // next
$this->link_nodes($node, false); $this->link_nodes($node, false);
@@ -1594,7 +1569,7 @@ class simple_html_dom
$space[1] = $this->copy_skip($this->token_blank); $space[1] = $this->copy_skip($this->token_blank);
$name = $this->restore_noise($name); $name = $this->restore_noise($name);
if($this->lowercase) { if($this->lowercase) {
$name = strtolower($name); $name = strtolower((string) $name);
} }
if($this->char === '=') { if($this->char === '=') {
$this->char = (++$this->pos < $this->size) ? $this->doc[$this->pos] : null; // next $this->char = (++$this->pos < $this->size) ? $this->doc[$this->pos] : null; // next
@@ -1621,7 +1596,7 @@ class simple_html_dom
$node->_[HDOM_INFO_END] = 0; $node->_[HDOM_INFO_END] = 0;
} else { } else {
// reset parent // reset parent
if(!isset($this->self_closing_tags[strtolower($node->tag)])) { if(!isset($this->self_closing_tags[strtolower((string) $node->tag)])) {
$this->parent = $node; $this->parent = $node;
} }
} }
@@ -1695,31 +1670,31 @@ class simple_html_dom
protected function skip($chars) protected function skip($chars)
{ {
$this->pos += strspn($this->doc, $chars, $this->pos); $this->pos += strspn((string) $this->doc, (string) $chars, $this->pos);
$this->char = ($this->pos < $this->size) ? $this->doc[$this->pos] : null; // next $this->char = ($this->pos < $this->size) ? $this->doc[$this->pos] : null; // next
} }
protected function copy_skip($chars) protected function copy_skip($chars)
{ {
$pos = $this->pos; $pos = $this->pos;
$len = strspn($this->doc, $chars, $pos); $len = strspn((string) $this->doc, (string) $chars, $pos);
$this->pos += $len; $this->pos += $len;
$this->char = ($this->pos < $this->size) ? $this->doc[$this->pos] : null; // next $this->char = ($this->pos < $this->size) ? $this->doc[$this->pos] : null; // next
if($len === 0) { if($len === 0) {
return ''; return '';
} }
return substr($this->doc, $pos, $len); return substr((string) $this->doc, $pos, $len);
} }
protected function copy_until($chars) protected function copy_until($chars)
{ {
$pos = $this->pos; $pos = $this->pos;
$len = strcspn($this->doc, $chars, $pos); $len = strcspn((string) $this->doc, (string) $chars, $pos);
$this->pos += $len; $this->pos += $len;
$this->char = ($this->pos < $this->size) ? $this->doc[$this->pos] : null; // next $this->char = ($this->pos < $this->size) ? $this->doc[$this->pos] : null; // next
return substr($this->doc, $pos, $len); return substr((string) $this->doc, $pos, $len);
} }
protected function copy_until_char($char) protected function copy_until_char($char)
@@ -1727,8 +1702,8 @@ class simple_html_dom
if($this->char === null) { if($this->char === null) {
return ''; return '';
} }
if(($pos = strpos($this->doc, $char, $this->pos)) === false) { if(($pos = strpos((string) $this->doc, (string) $char, $this->pos)) === false) {
$ret = substr($this->doc, $this->pos, $this->size - $this->pos); $ret = substr((string) $this->doc, $this->pos, $this->size - $this->pos);
$this->char = null; $this->char = null;
$this->pos = $this->size; $this->pos = $this->size;
@@ -1741,7 +1716,7 @@ class simple_html_dom
$this->char = $this->doc[$pos]; $this->char = $this->doc[$pos];
$this->pos = $pos; $this->pos = $pos;
return substr($this->doc, $pos_old, $pos - $pos_old); return substr((string) $this->doc, $pos_old, $pos - $pos_old);
} }
protected function copy_until_char_escape($char) protected function copy_until_char_escape($char)
@@ -1751,8 +1726,8 @@ class simple_html_dom
} }
$start = $this->pos; $start = $this->pos;
while(1) { while(1) {
if(($pos = strpos($this->doc, $char, $start)) === false) { if(($pos = strpos((string) $this->doc, (string) $char, $start)) === false) {
$ret = substr($this->doc, $this->pos, $this->size - $this->pos); $ret = substr((string) $this->doc, $this->pos, $this->size - $this->pos);
$this->char = null; $this->char = null;
$this->pos = $this->size; $this->pos = $this->size;
@@ -1769,7 +1744,7 @@ class simple_html_dom
$this->char = $this->doc[$pos]; $this->char = $this->doc[$pos];
$this->pos = $pos; $this->pos = $pos;
return substr($this->doc, $pos_old, $pos - $pos_old); return substr((string) $this->doc, $pos_old, $pos - $pos_old);
} }
} }
@@ -1781,7 +1756,7 @@ class simple_html_dom
if(is_object($debugObject)) { if(is_object($debugObject)) {
$debugObject->debugLogEntry(1); $debugObject->debugLogEntry(1);
} }
$count = preg_match_all($pattern, $this->doc, $matches, PREG_SET_ORDER | PREG_OFFSET_CAPTURE); $count = preg_match_all($pattern, (string) $this->doc, $matches, PREG_SET_ORDER | PREG_OFFSET_CAPTURE);
for($i = $count - 1; $i > -1; --$i) { for($i = $count - 1; $i > -1; --$i) {
$key = '___noise___' . sprintf('% 5d', count($this->noise) + 1000); $key = '___noise___' . sprintf('% 5d', count($this->noise) + 1000);
if(is_object($debugObject)) { if(is_object($debugObject)) {
@@ -1792,7 +1767,7 @@ class simple_html_dom
$this->doc = substr_replace($this->doc, $key, $matches[$i][$idx][1], strlen($matches[$i][$idx][0])); $this->doc = substr_replace($this->doc, $key, $matches[$i][$idx][1], strlen($matches[$i][$idx][0]));
} }
// reset the length of content // reset the length of content
$this->size = strlen($this->doc); $this->size = strlen((string) $this->doc);
if($this->size > 0) { if($this->size > 0) {
$this->char = $this->doc[0]; $this->char = $this->doc[0];
} }
@@ -1805,22 +1780,22 @@ class simple_html_dom
if(is_object($debugObject)) { if(is_object($debugObject)) {
$debugObject->debugLogEntry(1); $debugObject->debugLogEntry(1);
} }
while(($pos = strpos($text, '___noise___')) !== false) { while(($pos = strpos((string) $text, '___noise___')) !== false) {
// Sometimes there is a broken piece of markup, and we don't GET the pos+11 etc... token which indicates a problem outside of us... // Sometimes there is a broken piece of markup, and we don't GET the pos+11 etc... token which indicates a problem outside of us...
if(strlen($text) > $pos + 15) { if(strlen((string) $text) > $pos + 15) {
$key = '___noise___' . $text[$pos + 11] . $text[$pos + 12] . $text[$pos + 13] . $text[$pos + 14] . $text[$pos + 15]; $key = '___noise___' . $text[$pos + 11] . $text[$pos + 12] . $text[$pos + 13] . $text[$pos + 14] . $text[$pos + 15];
if(is_object($debugObject)) { if(is_object($debugObject)) {
$debugObject->debugLog(2, 'located key of: ' . $key); $debugObject->debugLog(2, 'located key of: ' . $key);
} }
if(isset($this->noise[$key])) { if(isset($this->noise[$key])) {
$text = substr($text, 0, $pos) . $this->noise[$key] . substr($text, $pos + 16); $text = substr((string) $text, 0, $pos) . $this->noise[$key] . substr((string) $text, $pos + 16);
} else { } else {
// do this to prevent an infinite loop. // do this to prevent an infinite loop.
$text = substr($text, 0, $pos) . 'UNDEFINED NOISE FOR KEY: ' . $key . substr($text, $pos + 16); $text = substr((string) $text, 0, $pos) . 'UNDEFINED NOISE FOR KEY: ' . $key . substr((string) $text, $pos + 16);
} }
} else { } else {
// There is no valid key being given back to us... We must get rid of the ___noise___ or we will have a problem. // There is no valid key being given back to us... We must get rid of the ___noise___ or we will have a problem.
$text = substr($text, 0, $pos) . 'NO NUMERIC NOISE KEY' . substr($text, $pos + 11); $text = substr((string) $text, 0, $pos) . 'NO NUMERIC NOISE KEY' . substr((string) $text, $pos + 11);
} }
} }
@@ -1835,22 +1810,21 @@ class simple_html_dom
$debugObject->debugLogEntry(1); $debugObject->debugLogEntry(1);
} }
foreach($this->noise as $noiseElement) { foreach($this->noise as $noiseElement) {
if(strpos($noiseElement, $text) !== false) { if(str_contains((string) $noiseElement, (string) $text)) {
return $noiseElement; return $noiseElement;
} }
} }
} }
function __toString() function __toString(): string
{ {
return $this->root->innertext(); return (string) $this->root->innertext();
} }
function __get($name) function __get($name)
{ {
switch($name) { switch($name) {
case 'outertext': case 'outertext':
return $this->root->innertext();
case 'innertext': case 'innertext':
return $this->root->innertext(); return $this->root->innertext();
case 'plaintext': case 'plaintext':

View File

@@ -36,9 +36,7 @@ function df_db_query($sql, $pool)
df_set_context('last_sql', $sql); df_set_context('last_sql', $sql);
df_collect('sql_logs', $sql); df_collect('sql_logs', $sql);
if (is_array($ret)) { if (is_array($ret)) {
$ret = array_map(function ($item) { $ret = array_map(fn($item) => (array)$item, $ret);
return (array)$item;
}, $ret);
} }
return $ret; return $ret;
@@ -89,7 +87,7 @@ function df_json_decode($json, $default = [])
if (!$json) { if (!$json) {
return $default; return $default;
} }
$json = preg_replace('@//[^"]+?$@mui', '', $json); $json = preg_replace('@//[^"]+?$@mui', '', (string) $json);
$json = preg_replace('@^\s*//.*?$@mui', '', $json); $json = preg_replace('@^\s*//.*?$@mui', '', $json);
$json = $json ? @json_decode($json, true) : $default; $json = $json ? @json_decode($json, true) : $default;
if (is_null($json)) { if (is_null($json)) {
@@ -129,7 +127,7 @@ function df_collected_clear($key)
function df_dump(...$arg) function df_dump(...$arg)
{ {
foreach ($arg as $index => $value) { foreach ($arg as $value) {
$dump = highlight_string("<?php\n" . var_export($value, true) . "; \n?>", true); $dump = highlight_string("<?php\n" . var_export($value, true) . "; \n?>", true);
$dump = Str::replaceArray('<span style="color: #0000BB">&lt;?php<br /></span>', [''], $dump); $dump = Str::replaceArray('<span style="color: #0000BB">&lt;?php<br /></span>', [''], $dump);
$dump = Str::replaceArray('<span style="color: #0000BB">?&gt;</span>', [''], $dump); $dump = Str::replaceArray('<span style="color: #0000BB">?&gt;</span>', [''], $dump);

View File

@@ -25,10 +25,7 @@ abstract class AbstractMaker
$body = Str::replaceLast('}', '', $body); $body = Str::replaceLast('}', '', $body);
$body = str::replaceArray(' ', [''], $body); $body = str::replaceArray(' ', [''], $body);
$method = new Method($from->getName()); $method = new Method($from->getName());
$method->setParameters(array_map([ $method->setParameters(array_map($this->fromParameterReflection(...), $from->getParameters()));
$this,
'fromParameterReflection',
], $from->getParameters()));
$method->setStatic($from->isStatic()); $method->setStatic($from->isStatic());
$isInterface = $from->getDeclaringClass()->isInterface(); $isInterface = $from->getDeclaringClass()->isInterface();
$method->setVisibility($from->isPrivate() ? ClassType::VISIBILITY_PRIVATE : ($from->isProtected() ? ClassType::VISIBILITY_PROTECTED : ($isInterface ? null : ClassType::VISIBILITY_PUBLIC))); $method->setVisibility($from->isPrivate() ? ClassType::VISIBILITY_PRIVATE : ($from->isProtected() ? ClassType::VISIBILITY_PROTECTED : ($isInterface ? null : ClassType::VISIBILITY_PUBLIC)));
@@ -63,9 +60,7 @@ abstract class AbstractMaker
protected function pathToNamespace(string $path): string protected function pathToNamespace(string $path): string
{ {
return implode('\\', array_map(function ($item) { return implode('\\', array_map(fn($item) => ucfirst((string) $item), explode('/', $path)));
return ucfirst($item);
}, explode('/', $path)));
} }
public function getBaseClass($save_path, $class_namespace, $class_name, $extend_class = null) public function getBaseClass($save_path, $class_namespace, $class_name, $extend_class = null)
@@ -73,7 +68,7 @@ abstract class AbstractMaker
$namespace = new PhpNamespace($class_namespace); $namespace = new PhpNamespace($class_namespace);
$extend_class && $namespace->addUse($extend_class); $extend_class && $namespace->addUse($extend_class);
if(!file_exists($save_path)) { if(!file_exists($save_path)) {
$dir = dirname($save_path); $dir = dirname((string) $save_path);
if(!is_dir($dir)) { if(!is_dir($dir)) {
@mkdir($dir, 0755, true); @mkdir($dir, 0755, true);
} }
@@ -126,8 +121,7 @@ abstract class AbstractMaker
$str .= str_repeat(' ', $deep * 4) . "{$k}{$val},\n"; $str .= str_repeat(' ', $deep * 4) . "{$k}{$val},\n";
} }
} }
$str .= str_repeat(' ', ($deep - 1) * 4) . "]";
return $str; return $str . (str_repeat(' ', ($deep - 1) * 4) . "]");
} }
} }

View File

@@ -311,17 +311,12 @@ class DevController extends AbstractController
public function transType($type) public function transType($type)
{ {
switch ($type) { return match ($type) {
case 'datetime': 'datetime' => 'datetime',
return 'datetime'; 'bigint' => 'number',
case 'bigint': 'text' => 'html',
return 'number'; 'enum' => 'radio',
case 'text': default => 'input',
return 'html'; };
case 'enum':
return 'radio';
default:
return 'input';
}
} }
} }

View File

@@ -10,7 +10,7 @@ class ControllerMaker extends AbstractMaker
{ {
public function make($model_class, $path, $config) public function make($model_class, $path, $config)
{ {
$model_name = array_last(explode('\\', $model_class)); $model_name = array_last(explode('\\', (string) $model_class));
$controller_name = $model_name . 'Controller'; $controller_name = $model_name . 'Controller';
$class_namespace = $this->pathToNamespace($path); $class_namespace = $this->pathToNamespace($path);
$save_path = BASE_PATH . '/' . $path . '/' . $controller_name . '.php'; $save_path = BASE_PATH . '/' . $path . '/' . $controller_name . '.php';
@@ -41,7 +41,7 @@ class ControllerMaker extends AbstractMaker
} }
public function splitToRouteName($greatHumpStr){ public function splitToRouteName($greatHumpStr){
$arr = preg_split('/(?<=[a-z0-9])(?=[A-Z])/x', $greatHumpStr); $arr = preg_split('/(?<=[a-z0-9])(?=[A-Z])/x', (string) $greatHumpStr);
return strtolower(implode("_", $arr)); return strtolower(implode("_", $arr));
} }

View File

@@ -76,31 +76,13 @@ class ModelMaker extends AbstractMaker
protected function formatDatabaseType(string $type): ?string protected function formatDatabaseType(string $type): ?string
{ {
switch($type) { return match ($type) {
case 'tinyint': 'tinyint', 'smallint', 'mediumint', 'int', 'bigint' => 'integer',
case 'smallint': 'decimal', 'float', 'double', 'real' => 'float',
case 'mediumint': 'bool', 'boolean' => 'boolean',
case 'int': 'varchar', 'text', 'char', 'tinytext', 'longtext', 'enum' => 'string',
case 'bigint': default => $type,
return 'integer'; };
case 'decimal':
case 'float':
case 'double':
case 'real':
return 'float';
case 'bool':
case 'boolean':
return 'boolean';
case 'varchar':
case 'text':
case 'char':
case 'tinytext':
case 'longtext':
case 'enum':
return 'string';
default:
return $type;
}
} }
protected function formatPropertyType(string $type, ?string $cast): ?string protected function formatPropertyType(string $type, ?string $cast): ?string
@@ -108,23 +90,16 @@ class ModelMaker extends AbstractMaker
if(!isset($cast)) { if(!isset($cast)) {
$cast = $this->formatDatabaseType($type) ?? 'string'; $cast = $this->formatDatabaseType($type) ?? 'string';
} }
switch($cast) { return match ($cast) {
case 'integer': 'integer' => 'int',
return 'int'; 'date', 'datetime' => \Carbon\Carbon::class,
case 'date': 'json' => 'array',
case 'datetime': default => $cast,
return '\Carbon\Carbon'; };
case 'json':
return 'array';
}
return $cast;
} }
protected function formatColumns(array $columns): array protected function formatColumns(array $columns): array
{ {
return array_map(function ($item) { return array_map(fn($item) => array_change_key_case($item, CASE_LOWER), $columns);
return array_change_key_case($item, CASE_LOWER);
}, $columns);
} }
} }

View File

@@ -12,20 +12,8 @@ use Psr\Container\ContainerInterface;
class BootProcessListener implements ListenerInterface class BootProcessListener implements ListenerInterface
{ {
/** public function __construct(private readonly ConfigInterface $config)
* @var ContainerInterface
*/
private $container;
/**
* @var ConfigInterface
*/
private $config;
public function __construct(ContainerInterface $container, ConfigInterface $config)
{ {
$this->container = $container;
$this->config = $config;
} }
/** /**

View File

@@ -32,7 +32,6 @@ class PushController extends AbstractController
break; break;
default: default:
return $this->fail(ErrorCode::CODE_ERR_SYSTEM, 'not support queue type'); return $this->fail(ErrorCode::CODE_ERR_SYSTEM, 'not support queue type');
break;
} }
return $ret ? $this->success() : $this->fail(ErrorCode::CODE_ERR_SYSTEM, 'push message faile'); return $ret ? $this->success() : $this->fail(ErrorCode::CODE_ERR_SYSTEM, 'push message faile');

View File

@@ -18,18 +18,11 @@ class Kafka
// Set a rebalance callback to log partition assignments (optional) // Set a rebalance callback to log partition assignments (optional)
$conf->setRebalanceCb(function (KafkaConsumer $kafka, $err, array $partitions = null) { $conf->setRebalanceCb(function (KafkaConsumer $kafka, $err, array $partitions = null) {
switch($err) { match ($err) {
case RD_KAFKA_RESP_ERR__ASSIGN_PARTITIONS: RD_KAFKA_RESP_ERR__ASSIGN_PARTITIONS => $kafka->assign($partitions),
$kafka->assign($partitions); RD_KAFKA_RESP_ERR__REVOKE_PARTITIONS => $kafka->assign(null),
break; default => throw new \Exception($err),
};
case RD_KAFKA_RESP_ERR__REVOKE_PARTITIONS:
$kafka->assign(null);
break;
default:
throw new \Exception($err);
}
}); });
// Configure the group.id. All consumer with the same group.id will consume // Configure the group.id. All consumer with the same group.id will consume
@@ -64,14 +57,11 @@ class Kafka
$handler($message->payload); $handler($message->payload);
break; break;
case RD_KAFKA_RESP_ERR__PARTITION_EOF: case RD_KAFKA_RESP_ERR__PARTITION_EOF:
// "No more messages; will wait for more\n";
break;
case RD_KAFKA_RESP_ERR__TIMED_OUT: case RD_KAFKA_RESP_ERR__TIMED_OUT:
// "Timed out\n"; // "Timed out\n";
break; break;
default: default:
throw new \Exception($message->errstr(), $message->err); throw new \Exception($message->errstr(), $message->err);
break;
} }
} }
} }

View File

@@ -31,7 +31,7 @@ class OnPipeMessageListener implements ListenerInterface
if(Str::startsWith($msg['callback'], ['http://', 'https://'])) { if(Str::startsWith($msg['callback'], ['http://', 'https://'])) {
$guzzle = $container->get(ClientFactory::class)->create(); $guzzle = $container->get(ClientFactory::class)->create();
$response = $guzzle->request('GET', $msg['callback']); $response = $guzzle->request('GET', $msg['callback']);
$ret = json_decode($response->getBody()->getContents()); $ret = json_decode((string) $response->getBody()->getContents());
} elseif(preg_match('/([\w+\\\\]+)@(\w+)/', $msg['callback'], $m)) { } elseif(preg_match('/([\w+\\\\]+)@(\w+)/', $msg['callback'], $m)) {
$ret = call([make($m[1]), $m[2]], [$msg['arg']]); $ret = call([make($m[1]), $m[2]], [$msg['arg']]);
} elseif(preg_match('/([\w+\\\\]+)::(\w+)/', $msg['callback'], $m)) { } elseif(preg_match('/([\w+\\\\]+)::(\w+)/', $msg['callback'], $m)) {

View File

@@ -22,16 +22,11 @@ class ProcessFactory
$this->serve = $serve; $this->serve = $serve;
$this->deliver_type = $params['deliver_type'] ?? 'single'; $this->deliver_type = $params['deliver_type'] ?? 'single';
$this->callback = $params['callback']; $this->callback = $params['callback'];
switch($params['type']) { return match ($params['type']) {
case 'amqp': 'amqp' => $this->makeAmqpProcess($params['options']),
return $this->makeAmqpProcess($params['options']); 'kafka' => $this->makeKafkaProcess($params['options']),
break; default => false,
case 'kafka': };
return $this->makeKafkaProcess($params['options']);
break;
default:
return false;
}
} }
public function makeAmqpProcess($options) public function makeAmqpProcess($options)
@@ -39,16 +34,13 @@ class ProcessFactory
$factory = $this; $factory = $this;
$nums = $options['nums'] ?? 1; $nums = $options['nums'] ?? 1;
$message = new class ($options, $factory) extends ConsumerMessage { $message = new class ($options, $factory) extends ConsumerMessage {
public $factory; public function __construct($options, public $factory)
public function __construct($options, $factory)
{ {
foreach($options as $key => $val) { foreach($options as $key => $val) {
if(property_exists($this, $key)) { if(property_exists($this, $key)) {
$this->$key = $val; $this->$key = $val;
} }
} }
$this->factory = $factory;
} }
public function consume($data): string public function consume($data): string
@@ -101,16 +93,13 @@ class ProcessFactory
public $instance; public $instance;
public $factory; public function __construct($options, public $factory)
public function __construct($options, $factory)
{ {
$container = ApplicationContext::getContainer(); $container = ApplicationContext::getContainer();
$this->instance = $options['instance']; $this->instance = $options['instance'];
$this->topic = $options['topic']; $this->topic = $options['topic'];
$this->group = $options['group']; $this->group = $options['group'];
$this->name = 'event_bus:kafka_' . $this->group . '_' . $this->topic; $this->name = 'event_bus:kafka_' . $this->group . '_' . $this->topic;
$this->factory = $factory;
$this->nums = $options['nums'] ?? 1; $this->nums = $options['nums'] ?? 1;
parent::__construct($container); parent::__construct($container);
} }

View File

@@ -12,24 +12,14 @@ use Psr\Container\ContainerInterface;
class AmqpConsumerManager class AmqpConsumerManager
{ {
/** public function __construct(private readonly ContainerInterface $container)
* @var ContainerInterface
*/
private $container;
public function __construct(ContainerInterface $container)
{ {
$this->container = $container;
} }
public function run() public function run()
{ {
$classes = AnnotationCollector::getClassByAnnotation(ConsumerAnnotation::class); $classes = AnnotationCollector::getClassByAnnotation(ConsumerAnnotation::class);
$consumer_names = process_list_filter(array_keys($classes), config('process_manager.amqp_consumer', [])); $consumer_names = process_list_filter(array_keys($classes), config('process_manager.amqp_consumer', []));
/**
* @var string
* @var ConsumerAnnotation $annotation
*/
foreach($classes as $class => $annotation) { foreach($classes as $class => $annotation) {
if(!in_array($class, $consumer_names)) { if(!in_array($class, $consumer_names)) {
continue; continue;
@@ -59,16 +49,10 @@ class AmqpConsumerManager
*/ */
private $consumer; private $consumer;
/** public function __construct(ContainerInterface $container, private readonly ConsumerMessageInterface $consumerMessage)
* @var ConsumerMessageInterface
*/
private $consumerMessage;
public function __construct(ContainerInterface $container, ConsumerMessageInterface $consumerMessage)
{ {
parent::__construct($container); parent::__construct($container);
$this->consumer = $container->get(Consumer::class); $this->consumer = $container->get(Consumer::class);
$this->consumerMessage = $consumerMessage;
} }
public function handle(): void public function handle(): void

View File

@@ -13,20 +13,8 @@ use Psr\Container\ContainerInterface;
class BootProcessListener implements ListenerInterface class BootProcessListener implements ListenerInterface
{ {
/** public function __construct(private readonly ContainerInterface $container, private readonly ConfigInterface $config)
* @var ContainerInterface
*/
private $container;
/**
* @var ConfigInterface
*/
private $config;
public function __construct(ContainerInterface $container, ConfigInterface $config)
{ {
$this->container = $container;
$this->config = $config;
} }
/** /**

View File

@@ -20,24 +20,14 @@ use Psr\EventDispatcher\EventDispatcherInterface;
class NsqConsumerManager class NsqConsumerManager
{ {
/** public function __construct(private readonly ContainerInterface $container)
* @var ContainerInterface
*/
private $container;
public function __construct(ContainerInterface $container)
{ {
$this->container = $container;
} }
public function run() public function run()
{ {
$classes = AnnotationCollector::getClassByAnnotation(ConsumerAnnotation::class); $classes = AnnotationCollector::getClassByAnnotation(ConsumerAnnotation::class);
$consumer_names = process_list_filter(array_keys($classes), config('process_manager.nsq_consumer', [])); $consumer_names = process_list_filter(array_keys($classes), config('process_manager.nsq_consumer', []));
/**
* @var string
* @var ConsumerAnnotation $annotation
*/
foreach($classes as $class => $annotation) { foreach($classes as $class => $annotation) {
if(!in_array($class, $consumer_names)) { if(!in_array($class, $consumer_names)) {
continue; continue;
@@ -61,11 +51,6 @@ class NsqConsumerManager
private function createProcess(AbstractConsumer $consumer): AbstractProcess private function createProcess(AbstractConsumer $consumer): AbstractProcess
{ {
return new class($this->container, $consumer) extends AbstractProcess { return new class($this->container, $consumer) extends AbstractProcess {
/**
* @var AbstractConsumer
*/
private $consumer;
/** /**
* @var \Hyperf\Nsq\Nsq * @var \Hyperf\Nsq\Nsq
*/ */
@@ -81,14 +66,13 @@ class NsqConsumerManager
*/ */
private $config; private $config;
public function __construct(ContainerInterface $container, AbstractConsumer $consumer) public function __construct(ContainerInterface $container, private readonly AbstractConsumer $consumer)
{ {
parent::__construct($container); parent::__construct($container);
$this->consumer = $consumer;
$this->config = $container->get(ConfigInterface::class); $this->config = $container->get(ConfigInterface::class);
$this->subscriber = make(Nsq::class, [ $this->subscriber = make(Nsq::class, [
'container' => $container, 'container' => $container,
'pool' => $consumer->getPool(), 'pool' => $this->consumer->getPool(),
]); ]);
if($container->has(EventDispatcherInterface::class)) { if($container->has(EventDispatcherInterface::class)) {
$this->dispatcher = $container->get(EventDispatcherInterface::class); $this->dispatcher = $container->get(EventDispatcherInterface::class);

View File

@@ -61,7 +61,7 @@ class ArrayHelper
if($current === null) { if($current === null) {
return false; return false;
} }
$keys = explode('.', $key); $keys = explode('.', (string) $key);
$target = &$arr; $target = &$arr;
$unset_key = array_pop($keys); $unset_key = array_pop($keys);
while($item = array_shift($keys)) { while($item = array_shift($keys)) {

View File

@@ -3,15 +3,12 @@ namespace HyperfAdmin\RuleEngine;
class BooleanOperation class BooleanOperation
{ {
protected $data = [];
protected $sets = []; protected $sets = [];
protected $info = []; protected $info = [];
public function __construct($data = []) public function __construct(protected $data = [])
{ {
$this->data = $data;
} }
public function setContext($data) public function setContext($data)
@@ -122,8 +119,8 @@ class BooleanOperation
case 'between': case 'between':
$rule = $this->toArr($rule_val); $rule = $this->toArr($rule_val);
if($this->isDateStr($rule[0])) { if($this->isDateStr($rule[0])) {
$rule[0] = strtotime($rule[0]); $rule[0] = strtotime((string) $rule[0]);
$rule[1] = strtotime($rule[1]); $rule[1] = strtotime((string) $rule[1]);
} }
return $current_val > $rule[0] && $current_val < $rule[1]; return $current_val > $rule[0] && $current_val < $rule[1];
@@ -136,7 +133,7 @@ class BooleanOperation
case 'elapse between': case 'elapse between':
$rule = $this->toArr($rule_val); $rule = $this->toArr($rule_val);
if($this->isDateStr($rule[0])) { if($this->isDateStr($rule[0])) {
return (time() - $rule_val) > strtotime($rule[0]) && (time() - $rule_val) < strtotime($rule[1]); return (time() - $rule_val) > strtotime((string) $rule[0]) && (time() - $rule_val) < strtotime((string) $rule[1]);
} }
return (time() - $rule_val) > $rule[0] && (time() - $rule_val) < $rule[1]; return (time() - $rule_val) > $rule[0] && (time() - $rule_val) < $rule[1];
@@ -154,11 +151,11 @@ class BooleanOperation
if(is_array($val)) { if(is_array($val)) {
return $val; return $val;
} }
if(strpos($val, ',')) { if(strpos((string) $val, ',')) {
return explode(',', $val); return explode(',', (string) $val);
} }
if(strpos($val, '...')) { if(strpos((string) $val, '...')) {
$parts = explode('...', $val); $parts = explode('...', (string) $val);
return range($parts[0], $parts[1]); return range($parts[0], $parts[1]);
} }
@@ -168,7 +165,7 @@ class BooleanOperation
protected function isDateStr($var) protected function isDateStr($var)
{ {
return preg_match('/[0-9]{4}-(0[1-9]|1[0-2])-(0[1-9]|[1-2][0-9]|3[0-1]) (2[0-3]|[01][0-9]):[0-5][0-9]:[0-5][0-9]/', $var); return preg_match('/[0-9]{4}-(0[1-9]|1[0-2])-(0[1-9]|[1-2][0-9]|3[0-1]) (2[0-3]|[01][0-9]):[0-5][0-9]:[0-5][0-9]/', (string) $var);
} }
protected function assignment($key, $operator, $right) protected function assignment($key, $operator, $right)

View File

@@ -34,7 +34,7 @@ class Context implements \ArrayAccess
if(isset($this->custom_data[$offset])) { if(isset($this->custom_data[$offset])) {
return $this->custom_data[$offset]; return $this->custom_data[$offset];
} }
preg_match('/^([a-zA-Z._0-9]+)\((.*)\)$/', $offset, $m); preg_match('/^([a-zA-Z._0-9]+)\((.*)\)$/', (string) $offset, $m);
$param = ''; $param = '';
if($m) { if($m) {
$offset = $m[1]; $offset = $m[1];
@@ -53,12 +53,12 @@ class Context implements \ArrayAccess
} }
$param = str_replace('.', "\001", $param); $param = str_replace('.', "\001", $param);
if(isset($this->key_map[$offset])) { if(isset($this->key_map[$offset])) {
[$plugin_name, $key] = explode('.', $offset, 2); [$plugin_name, $key] = explode('.', (string) $offset, 2);
return ArrayHelper::array_get($param ? "{$key}({$param})" : $key, $this->plugins[$plugin_name]); return ArrayHelper::array_get($param ? "{$key}({$param})" : $key, $this->plugins[$plugin_name]);
} }
foreach($this->plugins as $plugin) { foreach($this->plugins as $plugin) {
$key = explode('.', $offset, 2)[0]; $key = explode('.', (string) $offset, 2)[0];
if(in_array($key, $plugin->keys())) { if(in_array($key, $plugin->keys())) {
return ArrayHelper::array_get($param ? "{$offset}($param)" : $offset, $plugin); return ArrayHelper::array_get($param ? "{$offset}($param)" : $offset, $plugin);
} }
@@ -72,7 +72,7 @@ class Context implements \ArrayAccess
if(isset($this->custom_data[$offset])) { if(isset($this->custom_data[$offset])) {
return true; return true;
} }
preg_match('/^([a-zA-Z._0-9]+)\((.*)\)$/', $offset, $m); preg_match('/^([a-zA-Z._0-9]+)\((.*)\)$/', (string) $offset, $m);
if($m) { if($m) {
$offset = $m[1]; $offset = $m[1];
} }
@@ -80,7 +80,7 @@ class Context implements \ArrayAccess
return true; return true;
} }
foreach($this->plugins as $plugin) { foreach($this->plugins as $plugin) {
$key = explode('.', $offset, 2)[0]; $key = explode('.', (string) $offset, 2)[0];
if(in_array($key, $plugin->keys())) { if(in_array($key, $plugin->keys())) {
return true; return true;
} }

View File

@@ -14,13 +14,13 @@ abstract class ContextPluginAbstract implements ContextPluginInterface, \ArrayAc
$methods = $ref->getMethods(); $methods = $ref->getMethods();
$keys = []; $keys = [];
foreach($methods as $method) { foreach($methods as $method) {
if(strpos($method->name, 'get') === 0) { if(str_starts_with($method->name, 'get')) {
$keys[] = $this->camel2snake(str_replace('get', '', $method->name)); $keys[] = $this->camel2snake(str_replace('get', '', $method->name));
} }
} }
return $keys; return $keys;
} catch (\ReflectionException $e) { } catch (\ReflectionException) {
return []; return [];
} }
} }
@@ -37,7 +37,7 @@ abstract class ContextPluginAbstract implements ContextPluginInterface, \ArrayAc
public function camel2snake($str) public function camel2snake($str)
{ {
preg_match_all('!([A-Z][A-Z0-9]*(?=$|[A-Z][a-z0-9])|[A-Za-z][a-z0-9]+)!', $str, $matches); preg_match_all('!([A-Z][A-Z0-9]*(?=$|[A-Z][a-z0-9])|[A-Za-z][a-z0-9]+)!', (string) $str, $matches);
$ret = $matches[0]; $ret = $matches[0];
foreach($ret as &$match) { foreach($ret as &$match) {
$match = $match == strtoupper($match) ? strtolower($match) : lcfirst($match); $match = $match == strtoupper($match) ? strtolower($match) : lcfirst($match);

View File

@@ -23,7 +23,7 @@ class IpContext extends ContextPluginAbstract
try { try {
$region = $this->ip2Region->memorySearch($ip); $region = $this->ip2Region->memorySearch($ip);
// 国家|区域|省份|城市|ISP // 国家|区域|省份|城市|ISP
$region = explode('|', $region['region']); $region = explode('|', (string) $region['region']);
return [ return [
'country' => $region[0], 'country' => $region[0],
@@ -32,7 +32,7 @@ class IpContext extends ContextPluginAbstract
'city' => $region[3], 'city' => $region[3],
'isp' => $region[4], 'isp' => $region[4],
]; ];
} catch (\Exception $exception) { } catch (\Exception) {
return false; return false;
} }
} }

View File

@@ -22,7 +22,7 @@ class Validation
public function check($rules, $data, $obj = null, $options = []) public function check($rules, $data, $obj = null, $options = [])
{ {
foreach($data as $key => $val) { foreach($data as $key => $val) {
if(strpos($key, '.') !== false) { if(str_contains((string) $key, '.')) {
Arr::set($data, $key, $val); Arr::set($data, $key, $val);
unset($data[$key]); unset($data[$key]);
} }
@@ -32,14 +32,14 @@ class Validation
$white_data = []; $white_data = [];
foreach($rules as $key => $rule) { foreach($rules as $key => $rule) {
$field_extra = explode('|', $key); $field_extra = explode('|', (string) $key);
$field = $field_extra[0]; $field = $field_extra[0];
if(!$rule && Arr::get($data, $field)) { if(!$rule && Arr::get($data, $field)) {
$white_data[$field] = Arr::get($data, $field); $white_data[$field] = Arr::get($data, $field);
continue; continue;
} }
$title = $field_extra[1] ?? $field_extra[0]; $title = $field_extra[1] ?? $field_extra[0];
$rules = is_array($rule) ? $rule : explode('|', $rule); $rules = is_array($rule) ? $rule : explode('|', (string) $rule);
foreach($rules as $index => &$item) { foreach($rules as $index => &$item) {
if($index === 'children') { if($index === 'children') {
$request_sub_data = Arr::get($data, $field); $request_sub_data = Arr::get($data, $field);
@@ -101,17 +101,17 @@ class Validation
} }
$map = array_sort_by_key_length($map); $map = array_sort_by_key_length($map);
$filed_keys = array_map(function ($key) { $filed_keys = array_map(function ($key) {
if(strpos($key, '.') === false) { if(!str_contains((string) $key, '.')) {
return str_replace('_', ' ', $key); return str_replace('_', ' ', $key);
} }
return $key; return $key;
}, $filed_keys); }, $filed_keys);
if(preg_match('/.*当 (.*) 是 (.*)/', $item, $m)) { if(preg_match('/.*当 (.*) 是 (.*)/', (string) $item, $m)) {
if(isset($m[1]) && isset($m[2])) { if(isset($m[1]) && isset($m[2])) {
$field = str_replace(' ', '_', $m[1]); $field = str_replace(' ', '_', $m[1]);
$option = $options[$field][$m[2]]; $option = $options[$field][$m[2]];
$item = preg_replace('/是 .*/', '是 ' . $option, $item); $item = preg_replace('/是 .*/', '是 ' . $option, (string) $item);
} }
} }
@@ -133,9 +133,7 @@ class Validation
Arr::set($real_data, $key, $val); Arr::set($real_data, $key, $val);
} }
$real_data = array_map_recursive(function ($item) { $real_data = array_map_recursive(fn($item) => is_string($item) ? trim($item) : $item, $real_data);
return is_string($item) ? trim($item) : $item;
}, $real_data);
return [ return [
$fails ? null : $real_data, $fails ? null : $real_data,
@@ -146,26 +144,20 @@ class Validation
public function makeCustomRule($custom_rule) public function makeCustomRule($custom_rule)
{ {
return new class ($custom_rule, $this) implements Rule { return new class ($custom_rule, $this) implements Rule {
public $custom_rule;
public $validation;
public $error = "%s "; public $error = "%s ";
public $attribute; public $attribute;
public function __construct($custom_rule, $validation) public function __construct(public $custom_rule, public $validation)
{ {
$this->custom_rule = $custom_rule;
$this->validation = $validation;
} }
public function passes($attribute, $value): bool public function passes($attribute, $value): bool
{ {
$this->attribute = $attribute; $this->attribute = $attribute;
$rule = $this->custom_rule; $rule = $this->custom_rule;
if(strpos($rule, ':') !== false) { if(str_contains((string) $rule, ':')) {
$rule = explode(':', $rule)[0]; $rule = explode(':', (string) $rule)[0];
$extra = explode(',', explode(':', $rule)[1]); $extra = explode(',', explode(':', $rule)[1]);
$ret = $this->validation->$rule($attribute, $value, $extra); $ret = $this->validation->$rule($attribute, $value, $extra);
if(is_string($ret)) { if(is_string($ret)) {
@@ -196,29 +188,20 @@ class Validation
public function makeObjectCallback($method, $object) public function makeObjectCallback($method, $object)
{ {
return new class ($method, $this, $object) implements Rule { return new class ($method, $this, $object) implements Rule {
public $custom_rule;
public $validation;
public $object;
public $error = "%s "; public $error = "%s ";
public $attribute; public $attribute;
public function __construct($custom_rule, $validation, $object) public function __construct(public $custom_rule, public $validation, public $object)
{ {
$this->custom_rule = $custom_rule;
$this->validation = $validation;
$this->object = $object;
} }
public function passes($attribute, $value): bool public function passes($attribute, $value): bool
{ {
$this->attribute = $attribute; $this->attribute = $attribute;
$rule = $this->custom_rule; $rule = $this->custom_rule;
if(strpos($rule, ':') !== false) { if(str_contains((string) $rule, ':')) {
$rule = explode(':', $rule)[0]; $rule = explode(':', (string) $rule)[0];
$extra = explode(',', explode(':', $rule)[1]); $extra = explode(',', explode(':', $rule)[1]);
$ret = $this->object->$rule($attribute, $value, $extra); $ret = $this->object->$rule($attribute, $value, $extra);
if(is_string($ret)) { if(is_string($ret)) {

View File

@@ -16,8 +16,8 @@ trait ValidationCustomRule
public function crontab($attribute, $value) public function crontab($attribute, $value)
{ {
if(!preg_match('/^((\*(\/[0-9]+)?)|[0-9\-\,\/]+)\s+((\*(\/[0-9]+)?)|[0-9\-\,\/]+)\s+((\*(\/[0-9]+)?)|[0-9\-\,\/]+)\s+((\*(\/[0-9]+)?)|[0-9\-\,\/]+)\s+((\*(\/[0-9]+)?)|[0-9\-\,\/]+)\s+((\*(\/[0-9]+)?)|[0-9\-\,\/]+)$/i', trim($value))) { if(!preg_match('/^((\*(\/[0-9]+)?)|[0-9\-\,\/]+)\s+((\*(\/[0-9]+)?)|[0-9\-\,\/]+)\s+((\*(\/[0-9]+)?)|[0-9\-\,\/]+)\s+((\*(\/[0-9]+)?)|[0-9\-\,\/]+)\s+((\*(\/[0-9]+)?)|[0-9\-\,\/]+)\s+((\*(\/[0-9]+)?)|[0-9\-\,\/]+)$/i', trim((string) $value))) {
if(!preg_match('/^((\*(\/[0-9]+)?)|[0-9\-\,\/]+)\s+((\*(\/[0-9]+)?)|[0-9\-\,\/]+)\s+((\*(\/[0-9]+)?)|[0-9\-\,\/]+)\s+((\*(\/[0-9]+)?)|[0-9\-\,\/]+)\s+((\*(\/[0-9]+)?)|[0-9\-\,\/]+)$/i', trim($value))) { if(!preg_match('/^((\*(\/[0-9]+)?)|[0-9\-\,\/]+)\s+((\*(\/[0-9]+)?)|[0-9\-\,\/]+)\s+((\*(\/[0-9]+)?)|[0-9\-\,\/]+)\s+((\*(\/[0-9]+)?)|[0-9\-\,\/]+)\s+((\*(\/[0-9]+)?)|[0-9\-\,\/]+)$/i', trim((string) $value))) {
return '不是合法的crontab配置'; return '不是合法的crontab配置';
} }
} }
@@ -36,7 +36,7 @@ trait ValidationCustomRule
public function number_concat_ws_comma($attribute, $value) public function number_concat_ws_comma($attribute, $value)
{ {
if(!preg_match("/^\d+(,\d+)*$/", $value)) { if(!preg_match("/^\d+(,\d+)*$/", (string) $value)) {
return "不是英文逗号分隔的字符串"; return "不是英文逗号分隔的字符串";
} }