first commit
This commit is contained in:
commit
0024080c28
18
.editorconfig
Normal file
18
.editorconfig
Normal file
@ -0,0 +1,18 @@
|
||||
root = true
|
||||
|
||||
[*]
|
||||
charset = utf-8
|
||||
end_of_line = lf
|
||||
indent_size = 4
|
||||
indent_style = space
|
||||
insert_final_newline = true
|
||||
trim_trailing_whitespace = true
|
||||
|
||||
[*.md]
|
||||
trim_trailing_whitespace = false
|
||||
|
||||
[*.{yml,yaml}]
|
||||
indent_size = 2
|
||||
|
||||
[docker-compose.yml]
|
||||
indent_size = 4
|
59
.env.example
Normal file
59
.env.example
Normal file
@ -0,0 +1,59 @@
|
||||
APP_NAME=Laravel
|
||||
APP_ENV=local
|
||||
APP_KEY=
|
||||
APP_DEBUG=true
|
||||
APP_URL=http://localhost
|
||||
|
||||
LOG_CHANNEL=stack
|
||||
LOG_DEPRECATIONS_CHANNEL=null
|
||||
LOG_LEVEL=debug
|
||||
|
||||
DB_CONNECTION=mysql
|
||||
DB_HOST=127.0.0.1
|
||||
DB_PORT=3306
|
||||
DB_DATABASE=laravel
|
||||
DB_USERNAME=root
|
||||
DB_PASSWORD=
|
||||
DB_PREFIX=
|
||||
|
||||
BROADCAST_DRIVER=log
|
||||
CACHE_DRIVER=file
|
||||
FILESYSTEM_DISK=local
|
||||
QUEUE_CONNECTION=sync
|
||||
SESSION_DRIVER=file
|
||||
SESSION_LIFETIME=120
|
||||
|
||||
MEMCACHED_HOST=127.0.0.1
|
||||
|
||||
REDIS_HOST=127.0.0.1
|
||||
REDIS_PASSWORD=null
|
||||
REDIS_PORT=6379
|
||||
|
||||
MAIL_MAILER=smtp
|
||||
MAIL_HOST=mailhog
|
||||
MAIL_PORT=1025
|
||||
MAIL_USERNAME=null
|
||||
MAIL_PASSWORD=null
|
||||
MAIL_ENCRYPTION=null
|
||||
MAIL_FROM_ADDRESS="hello@example.com"
|
||||
MAIL_FROM_NAME="${APP_NAME}"
|
||||
|
||||
AWS_ACCESS_KEY_ID=
|
||||
AWS_SECRET_ACCESS_KEY=
|
||||
AWS_DEFAULT_REGION=us-east-1
|
||||
AWS_BUCKET=
|
||||
AWS_USE_PATH_STYLE_ENDPOINT=false
|
||||
|
||||
PUSHER_APP_ID=
|
||||
PUSHER_APP_KEY=
|
||||
PUSHER_APP_SECRET=
|
||||
PUSHER_HOST=
|
||||
PUSHER_PORT=443
|
||||
PUSHER_SCHEME=https
|
||||
PUSHER_APP_CLUSTER=mt1
|
||||
|
||||
VITE_PUSHER_APP_KEY="${PUSHER_APP_KEY}"
|
||||
VITE_PUSHER_HOST="${PUSHER_HOST}"
|
||||
VITE_PUSHER_PORT="${PUSHER_PORT}"
|
||||
VITE_PUSHER_SCHEME="${PUSHER_SCHEME}"
|
||||
VITE_PUSHER_APP_CLUSTER="${PUSHER_APP_CLUSTER}"
|
11
.gitattributes
vendored
Normal file
11
.gitattributes
vendored
Normal file
@ -0,0 +1,11 @@
|
||||
* text=auto
|
||||
|
||||
*.blade.php diff=html
|
||||
*.css diff=css
|
||||
*.html diff=html
|
||||
*.md diff=markdown
|
||||
*.php diff=php
|
||||
|
||||
/.github export-ignore
|
||||
CHANGELOG.md export-ignore
|
||||
.styleci.yml export-ignore
|
24
.gitee/ISSUE_TEMPLATE.zh-CN.md
Normal file
24
.gitee/ISSUE_TEMPLATE.zh-CN.md
Normal file
@ -0,0 +1,24 @@
|
||||
# 环境
|
||||
- 操作系统:
|
||||
- php 版本:
|
||||
- Laravel 版本:
|
||||
- Mysql 版本:
|
||||
- web 服务器:
|
||||
|
||||
# 问题
|
||||
- 问题描述:
|
||||
- 问题截图:
|
||||
|
||||
# 结果
|
||||
- 实际结果:
|
||||
- 预期结果:
|
||||
|
||||
# 分析
|
||||
- 所做的尝试:
|
||||
-
|
||||
-
|
||||
|
||||
# 方案:
|
||||
- 解决方案:
|
||||
|
||||
> 请在问题解决后关闭 issue
|
25
.github/issue_template.md
vendored
Normal file
25
.github/issue_template.md
vendored
Normal file
@ -0,0 +1,25 @@
|
||||
# 环境
|
||||
- 操作系统:
|
||||
- php 版本:
|
||||
- Laravel 版本:
|
||||
- Mysql 版本:
|
||||
- web 服务器:
|
||||
|
||||
# 问题
|
||||
- 问题描述:
|
||||
|
||||
- 问题截图:
|
||||
|
||||
# 结果
|
||||
- 实际结果:
|
||||
- 预期结果:
|
||||
|
||||
# 分析
|
||||
- 所做的尝试:
|
||||
-
|
||||
-
|
||||
|
||||
# 方案:
|
||||
- 解决方案:
|
||||
|
||||
> 请在问题解决后关闭 issue
|
24
.gitignore
vendored
Normal file
24
.gitignore
vendored
Normal file
@ -0,0 +1,24 @@
|
||||
/node_modules
|
||||
/public/build
|
||||
/public/hot
|
||||
/public/storage
|
||||
/storage/*.key
|
||||
/vendor
|
||||
/fixer
|
||||
.env
|
||||
.env.backup
|
||||
.env.production
|
||||
.phpunit.result.cache
|
||||
.php-cs-fixer.cache
|
||||
Homestead.json
|
||||
Homestead.yaml
|
||||
auth.json
|
||||
npm-debug.log
|
||||
yarn-error.log
|
||||
yarn.lock
|
||||
composer.lock
|
||||
/.fleet
|
||||
/.idea
|
||||
/.vscode
|
||||
components.d.ts
|
||||
auto-imports.d.ts
|
101
.php-cs-fixer.dist.php
Normal file
101
.php-cs-fixer.dist.php
Normal file
@ -0,0 +1,101 @@
|
||||
<?php
|
||||
|
||||
require_once __DIR__.DIRECTORY_SEPARATOR.'fixer'.DIRECTORY_SEPARATOR.'vendor'.DIRECTORY_SEPARATOR.'autoload.php';
|
||||
|
||||
use PhpCsFixer\Finder;
|
||||
use PhpCsFixer\Config;
|
||||
|
||||
$finder = Finder::create()
|
||||
// 排除目录
|
||||
//->exclude('packages')
|
||||
//// ->notPath('./packages/test.php')
|
||||
// in 配置需要规则的目录
|
||||
->in([
|
||||
__DIR__.DIRECTORY_SEPARATOR.'app',
|
||||
|
||||
__DIR__.DIRECTORY_SEPARATOR.'catch',
|
||||
|
||||
__DIR__.DIRECTORY_SEPARATOR.'modules',
|
||||
])
|
||||
// 排除 . 开头的文件
|
||||
->ignoreDotFiles(true)
|
||||
// vcs 文件
|
||||
->ignoreVCS(true);
|
||||
|
||||
$config = new Config();
|
||||
|
||||
return $config->setRules([
|
||||
'@PSR1' => true, // psr1
|
||||
|
||||
'@PSR2' => true, // psr2 规范
|
||||
|
||||
'@PSR12' => true, // psr12 规范
|
||||
|
||||
'binary_operator_spaces' => true, // 二元操作符号空格 $a=1 => $a = 1;
|
||||
|
||||
'array_syntax' => [
|
||||
'syntax' => 'short', // array('1') => ['1']
|
||||
],
|
||||
|
||||
'no_trailing_comma_in_singleline_array' => true, // -$a = array('sample', ); => $a = array('sample');
|
||||
|
||||
'trim_array_spaces' => true, // array( 'a', 'b' ); => array('a', 'b')
|
||||
|
||||
'single_trait_insert_per_statement' => false,
|
||||
|
||||
'standardize_not_equals' => true, // "!=" => "<>"
|
||||
|
||||
'magic_constant_casing' => true, // __dir__ => __DIR__
|
||||
|
||||
'native_function_casing' => true, // STRLEN($str); => strlen($str);
|
||||
|
||||
'cast_spaces' => true, // (int)$b => (int) $b
|
||||
|
||||
'simplified_if_return' => true, // if ($foo) { return true; } return false; => return (bool) ($foo) ;
|
||||
|
||||
'no_unused_imports' => true, // use \DateTime; -use \Exception; => use \DateTime;
|
||||
|
||||
'not_operator_with_successor_space' => true, // if (!$bar) => if (! $bar)
|
||||
|
||||
/**
|
||||
* // function example($b) {
|
||||
if ($b) {
|
||||
return;
|
||||
}
|
||||
- return;
|
||||
*/
|
||||
'no_useless_return' => true,
|
||||
|
||||
/**
|
||||
* function a() {
|
||||
- $a = 1;
|
||||
- return $a;
|
||||
+ return 1;
|
||||
*/
|
||||
'return_assignment' => true,
|
||||
|
||||
/**
|
||||
-<?php return null;
|
||||
+<?php return;
|
||||
*/
|
||||
'simplified_null_return' => true,
|
||||
|
||||
/**
|
||||
* $foo = [
|
||||
- 'bar' => [
|
||||
- 'baz' => true,
|
||||
- ],
|
||||
+ 'bar' => [
|
||||
+ 'baz' => true,
|
||||
+ ],
|
||||
*/
|
||||
'array_indentation' => true,
|
||||
|
||||
/**
|
||||
* -$sample = $b [ 'a' ] [ 'b' ];
|
||||
+$sample = $b['a']['b'];
|
||||
*/
|
||||
'no_spaces_around_offset' => true,
|
||||
|
||||
'concat_space' => true, // $a.$b => $a . $b
|
||||
])->setFinder($finder);
|
10
.prettierrc
Normal file
10
.prettierrc
Normal file
@ -0,0 +1,10 @@
|
||||
{
|
||||
"semi": false,
|
||||
"printWidth": 200,
|
||||
"tabWidth": 2,
|
||||
"useTabs": false,
|
||||
"singleQuote": true,
|
||||
"arrowParens": "avoid",
|
||||
"trailingComma": "all",
|
||||
"bracketSpacing": true
|
||||
}
|
35
README.md
Normal file
35
README.md
Normal file
@ -0,0 +1,35 @@
|
||||
## About CatchAdmin
|
||||
|
||||
|
||||
## 安装
|
||||
```shell
|
||||
yarn install
|
||||
|
||||
yarn dev
|
||||
```
|
||||
|
||||
```
|
||||
composer install
|
||||
|
||||
php artisan serve
|
||||
```
|
||||
## 规范
|
||||
### PHP
|
||||
使用 fixer 进行代码检查, 具体请查看根目录下 `.php-cs-fixer.dist.php` 文件的规范,还需要进行以下两步骤
|
||||
```shell
|
||||
mkdir path && cd path // any path name you set
|
||||
```
|
||||
```shell
|
||||
composer require --working-dir=path friendsofphp/php-cs-fixer
|
||||
```
|
||||
安装完成之后可以使用
|
||||
```shell
|
||||
composer cs
|
||||
```
|
||||
进行代码格式化,这个命令会直接修改文件完成修正,如果只需要查看格式是否正确,那么使用
|
||||
```shell
|
||||
composer cs-diff
|
||||
```
|
||||
会列出不符合的代码格式
|
||||
|
||||
|
32
app/Console/Kernel.php
Normal file
32
app/Console/Kernel.php
Normal file
@ -0,0 +1,32 @@
|
||||
<?php
|
||||
|
||||
namespace App\Console;
|
||||
|
||||
use Illuminate\Console\Scheduling\Schedule;
|
||||
use Illuminate\Foundation\Console\Kernel as ConsoleKernel;
|
||||
|
||||
class Kernel extends ConsoleKernel
|
||||
{
|
||||
/**
|
||||
* Define the application's command schedule.
|
||||
*
|
||||
* @param \Illuminate\Console\Scheduling\Schedule $schedule
|
||||
* @return void
|
||||
*/
|
||||
protected function schedule(Schedule $schedule)
|
||||
{
|
||||
// $schedule->command('inspire')->hourly();
|
||||
}
|
||||
|
||||
/**
|
||||
* Register the commands for the application.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function commands()
|
||||
{
|
||||
$this->load(__DIR__.'/Commands');
|
||||
|
||||
require base_path('routes/console.php');
|
||||
}
|
||||
}
|
33
app/Events/Create.php
Normal file
33
app/Events/Create.php
Normal file
@ -0,0 +1,33 @@
|
||||
<?php
|
||||
|
||||
namespace App\Events;
|
||||
|
||||
use Illuminate\Broadcasting\InteractsWithSockets;
|
||||
use Illuminate\Broadcasting\PrivateChannel;
|
||||
use Illuminate\Foundation\Events\Dispatchable;
|
||||
use Illuminate\Queue\SerializesModels;
|
||||
|
||||
class Create
|
||||
{
|
||||
use Dispatchable, InteractsWithSockets, SerializesModels;
|
||||
|
||||
/**
|
||||
* Create a new event instance.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
//
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the channels the event should broadcast on.
|
||||
*
|
||||
* @return \Illuminate\Broadcasting\Channel|array
|
||||
*/
|
||||
public function broadcastOn()
|
||||
{
|
||||
return new PrivateChannel('channel-name');
|
||||
}
|
||||
}
|
33
app/Events/Test.php
Normal file
33
app/Events/Test.php
Normal file
@ -0,0 +1,33 @@
|
||||
<?php
|
||||
|
||||
namespace App\Events;
|
||||
|
||||
use Illuminate\Broadcasting\InteractsWithSockets;
|
||||
use Illuminate\Broadcasting\PrivateChannel;
|
||||
use Illuminate\Foundation\Events\Dispatchable;
|
||||
use Illuminate\Queue\SerializesModels;
|
||||
|
||||
class Test
|
||||
{
|
||||
use Dispatchable, InteractsWithSockets, SerializesModels;
|
||||
|
||||
/**
|
||||
* Create a new event instance.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
//
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the channels the event should broadcast on.
|
||||
*
|
||||
* @return \Illuminate\Broadcasting\Channel|array
|
||||
*/
|
||||
public function broadcastOn()
|
||||
{
|
||||
return new PrivateChannel('channel-name');
|
||||
}
|
||||
}
|
83
app/Exceptions/Handler.php
Normal file
83
app/Exceptions/Handler.php
Normal file
@ -0,0 +1,83 @@
|
||||
<?php
|
||||
|
||||
namespace App\Exceptions;
|
||||
|
||||
use Catch\Exceptions\FailedException;
|
||||
use Illuminate\Foundation\Exceptions\Handler as ExceptionHandler;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
use Symfony\Component\HttpFoundation\Response;
|
||||
use Throwable;
|
||||
|
||||
class Handler extends ExceptionHandler
|
||||
{
|
||||
/**
|
||||
* A list of exception types with their corresponding custom log levels.
|
||||
*
|
||||
* @var array<class-string<\Throwable>, \Psr\Log\LogLevel::*>
|
||||
*/
|
||||
protected $levels = [
|
||||
//
|
||||
];
|
||||
|
||||
/**
|
||||
* A list of the exception types that are not reported.
|
||||
*
|
||||
* @var array<int, class-string<\Throwable>>
|
||||
*/
|
||||
protected $dontReport = [
|
||||
//
|
||||
];
|
||||
|
||||
/**
|
||||
* A list of the inputs that are never flashed to the session on validation exceptions.
|
||||
*
|
||||
* @var array<int, string>
|
||||
*/
|
||||
protected $dontFlash = [
|
||||
'current_password',
|
||||
'password',
|
||||
'password_confirmation',
|
||||
];
|
||||
|
||||
/**
|
||||
* Register the exception handling callbacks for the application.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function register()
|
||||
{
|
||||
$this->reportable(function (Throwable $e) {
|
||||
//
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* render
|
||||
*
|
||||
* @param $request
|
||||
* @param Throwable $e
|
||||
* @return JsonResponse|Response
|
||||
* @throws Throwable
|
||||
*/
|
||||
public function render($request, Throwable $e): JsonResponse|Response
|
||||
{
|
||||
$message = $e->getMessage();
|
||||
|
||||
if (method_exists($e, 'getStatusCode')) {
|
||||
if ($e->getStatusCode() == Response::HTTP_NOT_FOUND) {
|
||||
$message = '路由未找到或未注册';
|
||||
}
|
||||
}
|
||||
|
||||
$e = new FailedException($message ?: 'Server Error');
|
||||
|
||||
$response = parent::render($request, $e);
|
||||
|
||||
$response->header('Access-Control-Allow-Origin', '*');
|
||||
$response->header('Access-Control-Allow-Methods', '*');
|
||||
$response->header('Access-Control-Allow-Headers', '*');
|
||||
|
||||
return $response;
|
||||
}
|
||||
}
|
13
app/Http/Controllers/Controller.php
Normal file
13
app/Http/Controllers/Controller.php
Normal file
@ -0,0 +1,13 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers;
|
||||
|
||||
use Illuminate\Foundation\Auth\Access\AuthorizesRequests;
|
||||
use Illuminate\Foundation\Bus\DispatchesJobs;
|
||||
use Illuminate\Foundation\Validation\ValidatesRequests;
|
||||
use Illuminate\Routing\Controller as BaseController;
|
||||
|
||||
class Controller extends BaseController
|
||||
{
|
||||
use AuthorizesRequests, DispatchesJobs, ValidatesRequests;
|
||||
}
|
67
app/Http/Kernel.php
Normal file
67
app/Http/Kernel.php
Normal file
@ -0,0 +1,67 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http;
|
||||
|
||||
use Illuminate\Foundation\Http\Kernel as HttpKernel;
|
||||
|
||||
class Kernel extends HttpKernel
|
||||
{
|
||||
/**
|
||||
* The application's global HTTP middleware stack.
|
||||
*
|
||||
* These middleware are run during every request to your application.
|
||||
*
|
||||
* @var array<int, class-string|string>
|
||||
*/
|
||||
protected $middleware = [
|
||||
// \App\Http\Middleware\TrustHosts::class,
|
||||
\App\Http\Middleware\TrustProxies::class,
|
||||
\Illuminate\Http\Middleware\HandleCors::class,
|
||||
\App\Http\Middleware\PreventRequestsDuringMaintenance::class,
|
||||
\Illuminate\Foundation\Http\Middleware\ValidatePostSize::class,
|
||||
\App\Http\Middleware\TrimStrings::class,
|
||||
\Illuminate\Foundation\Http\Middleware\ConvertEmptyStringsToNull::class,
|
||||
];
|
||||
|
||||
/**
|
||||
* The application's route middleware groups.
|
||||
*
|
||||
* @var array<string, array<int, class-string|string>>
|
||||
*/
|
||||
protected $middlewareGroups = [
|
||||
'web' => [
|
||||
\App\Http\Middleware\EncryptCookies::class,
|
||||
\Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse::class,
|
||||
\Illuminate\Session\Middleware\StartSession::class,
|
||||
\Illuminate\View\Middleware\ShareErrorsFromSession::class,
|
||||
\App\Http\Middleware\VerifyCsrfToken::class,
|
||||
\Illuminate\Routing\Middleware\SubstituteBindings::class,
|
||||
],
|
||||
|
||||
'api' => [
|
||||
// \Laravel\Sanctum\Http\Middleware\EnsureFrontendRequestsAreStateful::class,
|
||||
'throttle:api',
|
||||
\Illuminate\Routing\Middleware\SubstituteBindings::class
|
||||
],
|
||||
];
|
||||
|
||||
/**
|
||||
* The application's route middleware.
|
||||
*
|
||||
* These middleware may be assigned to groups or used individually.
|
||||
*
|
||||
* @var array<string, class-string|string>
|
||||
*/
|
||||
protected $routeMiddleware = [
|
||||
'auth' => \App\Http\Middleware\Authenticate::class,
|
||||
'auth.basic' => \Illuminate\Auth\Middleware\AuthenticateWithBasicAuth::class,
|
||||
'auth.session' => \Illuminate\Session\Middleware\AuthenticateSession::class,
|
||||
'cache.headers' => \Illuminate\Http\Middleware\SetCacheHeaders::class,
|
||||
'can' => \Illuminate\Auth\Middleware\Authorize::class,
|
||||
'guest' => \App\Http\Middleware\RedirectIfAuthenticated::class,
|
||||
'password.confirm' => \Illuminate\Auth\Middleware\RequirePassword::class,
|
||||
'signed' => \App\Http\Middleware\ValidateSignature::class,
|
||||
'throttle' => \Illuminate\Routing\Middleware\ThrottleRequests::class,
|
||||
'verified' => \Illuminate\Auth\Middleware\EnsureEmailIsVerified::class,
|
||||
];
|
||||
}
|
21
app/Http/Middleware/Authenticate.php
Normal file
21
app/Http/Middleware/Authenticate.php
Normal file
@ -0,0 +1,21 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Middleware;
|
||||
|
||||
use Illuminate\Auth\Middleware\Authenticate as Middleware;
|
||||
|
||||
class Authenticate extends Middleware
|
||||
{
|
||||
/**
|
||||
* Get the path the user should be redirected to when they are not authenticated.
|
||||
*
|
||||
* @param \Illuminate\Http\Request $request
|
||||
* @return string|null
|
||||
*/
|
||||
protected function redirectTo($request)
|
||||
{
|
||||
if (! $request->expectsJson()) {
|
||||
return route('login');
|
||||
}
|
||||
}
|
||||
}
|
17
app/Http/Middleware/EncryptCookies.php
Normal file
17
app/Http/Middleware/EncryptCookies.php
Normal file
@ -0,0 +1,17 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Middleware;
|
||||
|
||||
use Illuminate\Cookie\Middleware\EncryptCookies as Middleware;
|
||||
|
||||
class EncryptCookies extends Middleware
|
||||
{
|
||||
/**
|
||||
* The names of the cookies that should not be encrypted.
|
||||
*
|
||||
* @var array<int, string>
|
||||
*/
|
||||
protected $except = [
|
||||
//
|
||||
];
|
||||
}
|
17
app/Http/Middleware/PreventRequestsDuringMaintenance.php
Normal file
17
app/Http/Middleware/PreventRequestsDuringMaintenance.php
Normal file
@ -0,0 +1,17 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Middleware;
|
||||
|
||||
use Illuminate\Foundation\Http\Middleware\PreventRequestsDuringMaintenance as Middleware;
|
||||
|
||||
class PreventRequestsDuringMaintenance extends Middleware
|
||||
{
|
||||
/**
|
||||
* The URIs that should be reachable while maintenance mode is enabled.
|
||||
*
|
||||
* @var array<int, string>
|
||||
*/
|
||||
protected $except = [
|
||||
//
|
||||
];
|
||||
}
|
32
app/Http/Middleware/RedirectIfAuthenticated.php
Normal file
32
app/Http/Middleware/RedirectIfAuthenticated.php
Normal file
@ -0,0 +1,32 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Middleware;
|
||||
|
||||
use App\Providers\RouteServiceProvider;
|
||||
use Closure;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\Auth;
|
||||
|
||||
class RedirectIfAuthenticated
|
||||
{
|
||||
/**
|
||||
* Handle an incoming request.
|
||||
*
|
||||
* @param \Illuminate\Http\Request $request
|
||||
* @param \Closure(\Illuminate\Http\Request): (\Illuminate\Http\Response|\Illuminate\Http\RedirectResponse) $next
|
||||
* @param string|null ...$guards
|
||||
* @return \Illuminate\Http\Response|\Illuminate\Http\RedirectResponse
|
||||
*/
|
||||
public function handle(Request $request, Closure $next, ...$guards)
|
||||
{
|
||||
$guards = empty($guards) ? [null] : $guards;
|
||||
|
||||
foreach ($guards as $guard) {
|
||||
if (Auth::guard($guard)->check()) {
|
||||
return redirect(RouteServiceProvider::HOME);
|
||||
}
|
||||
}
|
||||
|
||||
return $next($request);
|
||||
}
|
||||
}
|
19
app/Http/Middleware/TrimStrings.php
Normal file
19
app/Http/Middleware/TrimStrings.php
Normal file
@ -0,0 +1,19 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Middleware;
|
||||
|
||||
use Illuminate\Foundation\Http\Middleware\TrimStrings as Middleware;
|
||||
|
||||
class TrimStrings extends Middleware
|
||||
{
|
||||
/**
|
||||
* The names of the attributes that should not be trimmed.
|
||||
*
|
||||
* @var array<int, string>
|
||||
*/
|
||||
protected $except = [
|
||||
'current_password',
|
||||
'password',
|
||||
'password_confirmation',
|
||||
];
|
||||
}
|
20
app/Http/Middleware/TrustHosts.php
Normal file
20
app/Http/Middleware/TrustHosts.php
Normal file
@ -0,0 +1,20 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Middleware;
|
||||
|
||||
use Illuminate\Http\Middleware\TrustHosts as Middleware;
|
||||
|
||||
class TrustHosts extends Middleware
|
||||
{
|
||||
/**
|
||||
* Get the host patterns that should be trusted.
|
||||
*
|
||||
* @return array<int, string|null>
|
||||
*/
|
||||
public function hosts()
|
||||
{
|
||||
return [
|
||||
$this->allSubdomainsOfApplicationUrl(),
|
||||
];
|
||||
}
|
||||
}
|
28
app/Http/Middleware/TrustProxies.php
Normal file
28
app/Http/Middleware/TrustProxies.php
Normal file
@ -0,0 +1,28 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Middleware;
|
||||
|
||||
use Illuminate\Http\Middleware\TrustProxies as Middleware;
|
||||
use Illuminate\Http\Request;
|
||||
|
||||
class TrustProxies extends Middleware
|
||||
{
|
||||
/**
|
||||
* The trusted proxies for this application.
|
||||
*
|
||||
* @var array<int, string>|string|null
|
||||
*/
|
||||
protected $proxies;
|
||||
|
||||
/**
|
||||
* The headers that should be used to detect proxies.
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
protected $headers =
|
||||
Request::HEADER_X_FORWARDED_FOR |
|
||||
Request::HEADER_X_FORWARDED_HOST |
|
||||
Request::HEADER_X_FORWARDED_PORT |
|
||||
Request::HEADER_X_FORWARDED_PROTO |
|
||||
Request::HEADER_X_FORWARDED_AWS_ELB;
|
||||
}
|
22
app/Http/Middleware/ValidateSignature.php
Normal file
22
app/Http/Middleware/ValidateSignature.php
Normal file
@ -0,0 +1,22 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Middleware;
|
||||
|
||||
use Illuminate\Routing\Middleware\ValidateSignature as Middleware;
|
||||
|
||||
class ValidateSignature extends Middleware
|
||||
{
|
||||
/**
|
||||
* The names of the query string parameters that should be ignored.
|
||||
*
|
||||
* @var array<int, string>
|
||||
*/
|
||||
protected $except = [
|
||||
// 'fbclid',
|
||||
// 'utm_campaign',
|
||||
// 'utm_content',
|
||||
// 'utm_medium',
|
||||
// 'utm_source',
|
||||
// 'utm_term',
|
||||
];
|
||||
}
|
17
app/Http/Middleware/VerifyCsrfToken.php
Normal file
17
app/Http/Middleware/VerifyCsrfToken.php
Normal file
@ -0,0 +1,17 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Middleware;
|
||||
|
||||
use Illuminate\Foundation\Http\Middleware\VerifyCsrfToken as Middleware;
|
||||
|
||||
class VerifyCsrfToken extends Middleware
|
||||
{
|
||||
/**
|
||||
* The URIs that should be excluded from CSRF verification.
|
||||
*
|
||||
* @var array<int, string>
|
||||
*/
|
||||
protected $except = [
|
||||
//
|
||||
];
|
||||
}
|
30
app/Listeners/Command.php
Normal file
30
app/Listeners/Command.php
Normal file
@ -0,0 +1,30 @@
|
||||
<?php
|
||||
|
||||
namespace App\Listeners;
|
||||
|
||||
use Illuminate\Console\Events\CommandFinished;
|
||||
|
||||
class Command
|
||||
{
|
||||
/**
|
||||
* Create the event listener.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
//
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle the event.
|
||||
*
|
||||
* @param CommandFinished $event
|
||||
* @return void
|
||||
*/
|
||||
public function handle(CommandFinished $event)
|
||||
{
|
||||
//
|
||||
// dd($event->command);
|
||||
}
|
||||
}
|
28
app/Listeners/RouteMatched.php
Normal file
28
app/Listeners/RouteMatched.php
Normal file
@ -0,0 +1,28 @@
|
||||
<?php
|
||||
|
||||
namespace App\Listeners;
|
||||
|
||||
class RouteMatched
|
||||
{
|
||||
/**
|
||||
* Create the event listener.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
//
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle the event.
|
||||
*
|
||||
* @param object $event
|
||||
* @return void
|
||||
*/
|
||||
public function handle(\Illuminate\Routing\Events\RouteMatched $event)
|
||||
{
|
||||
//
|
||||
// dd($event->route);
|
||||
}
|
||||
}
|
27
app/Listeners/test.php
Normal file
27
app/Listeners/test.php
Normal file
@ -0,0 +1,27 @@
|
||||
<?php
|
||||
|
||||
namespace App\Listeners;
|
||||
|
||||
class test
|
||||
{
|
||||
/**
|
||||
* Create the event listener.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
//
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle the event.
|
||||
*
|
||||
* @param object $event
|
||||
* @return void
|
||||
*/
|
||||
public function handle($event)
|
||||
{
|
||||
//
|
||||
}
|
||||
}
|
11
app/Models/Modules/Users/Models/CatchController.php
Normal file
11
app/Models/Modules/Users/Models/CatchController.php
Normal file
@ -0,0 +1,11 @@
|
||||
<?php
|
||||
|
||||
namespace App\Models\Modules\Users\Models;
|
||||
|
||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
|
||||
class CatchController extends Model
|
||||
{
|
||||
use HasFactory;
|
||||
}
|
45
app/Models/User.php
Normal file
45
app/Models/User.php
Normal file
@ -0,0 +1,45 @@
|
||||
<?php
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
// use Illuminate\Contracts\Auth\MustVerifyEmail;
|
||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||
use Illuminate\Foundation\Auth\User as Authenticatable;
|
||||
use Illuminate\Notifications\Notifiable;
|
||||
|
||||
class User extends Authenticatable
|
||||
{
|
||||
use HasFactory, Notifiable;
|
||||
|
||||
protected $table = 'users';
|
||||
|
||||
/**
|
||||
* The attributes that are mass assignable.
|
||||
*
|
||||
* @var array<int, string>
|
||||
*/
|
||||
protected $fillable = [
|
||||
'name',
|
||||
'email',
|
||||
'password',
|
||||
];
|
||||
|
||||
/**
|
||||
* The attributes that should be hidden for serialization.
|
||||
*
|
||||
* @var array<int, string>
|
||||
*/
|
||||
protected $hidden = [
|
||||
'password',
|
||||
'remember_token',
|
||||
];
|
||||
|
||||
/**
|
||||
* The attributes that should be cast.
|
||||
*
|
||||
* @var array<string, string>
|
||||
*/
|
||||
protected $casts = [
|
||||
'email_verified_at' => 'datetime',
|
||||
];
|
||||
}
|
28
app/Providers/AppServiceProvider.php
Normal file
28
app/Providers/AppServiceProvider.php
Normal file
@ -0,0 +1,28 @@
|
||||
<?php
|
||||
|
||||
namespace App\Providers;
|
||||
|
||||
use Illuminate\Support\ServiceProvider;
|
||||
|
||||
class AppServiceProvider extends ServiceProvider
|
||||
{
|
||||
/**
|
||||
* Register any application services.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function register()
|
||||
{
|
||||
//
|
||||
}
|
||||
|
||||
/**
|
||||
* Bootstrap any application services.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function boot()
|
||||
{
|
||||
//
|
||||
}
|
||||
}
|
30
app/Providers/AuthServiceProvider.php
Normal file
30
app/Providers/AuthServiceProvider.php
Normal file
@ -0,0 +1,30 @@
|
||||
<?php
|
||||
|
||||
namespace App\Providers;
|
||||
|
||||
// use Illuminate\Support\Facades\Gate;
|
||||
use Illuminate\Foundation\Support\Providers\AuthServiceProvider as ServiceProvider;
|
||||
|
||||
class AuthServiceProvider extends ServiceProvider
|
||||
{
|
||||
/**
|
||||
* The model to policy mappings for the application.
|
||||
*
|
||||
* @var array<class-string, class-string>
|
||||
*/
|
||||
protected $policies = [
|
||||
// 'App\Models\Model' => 'App\Policies\ModelPolicy',
|
||||
];
|
||||
|
||||
/**
|
||||
* Register any authentication / authorization services.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function boot()
|
||||
{
|
||||
$this->registerPolicies();
|
||||
|
||||
//
|
||||
}
|
||||
}
|
21
app/Providers/BroadcastServiceProvider.php
Normal file
21
app/Providers/BroadcastServiceProvider.php
Normal file
@ -0,0 +1,21 @@
|
||||
<?php
|
||||
|
||||
namespace App\Providers;
|
||||
|
||||
use Illuminate\Support\Facades\Broadcast;
|
||||
use Illuminate\Support\ServiceProvider;
|
||||
|
||||
class BroadcastServiceProvider extends ServiceProvider
|
||||
{
|
||||
/**
|
||||
* Bootstrap any application services.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function boot()
|
||||
{
|
||||
Broadcast::routes();
|
||||
|
||||
require base_path('routes/channels.php');
|
||||
}
|
||||
}
|
53
app/Providers/EventServiceProvider.php
Normal file
53
app/Providers/EventServiceProvider.php
Normal file
@ -0,0 +1,53 @@
|
||||
<?php
|
||||
|
||||
namespace App\Providers;
|
||||
|
||||
use App\Listeners\Command;
|
||||
use Illuminate\Auth\Events\Registered;
|
||||
use Illuminate\Auth\Listeners\SendEmailVerificationNotification;
|
||||
use Illuminate\Console\Events\CommandFinished;
|
||||
use Illuminate\Foundation\Support\Providers\EventServiceProvider as ServiceProvider;
|
||||
use Illuminate\Routing\Events\RouteMatched;
|
||||
use Illuminate\Support\Facades\Event;
|
||||
|
||||
class EventServiceProvider extends ServiceProvider
|
||||
{
|
||||
/**
|
||||
* The event to listener mappings for the application.
|
||||
*
|
||||
* @var array<class-string, array<int, class-string>>
|
||||
*/
|
||||
protected $listen = [
|
||||
Registered::class => [
|
||||
SendEmailVerificationNotification::class,
|
||||
],
|
||||
|
||||
RouteMatched::class => [
|
||||
\App\Listeners\RouteMatched::class
|
||||
],
|
||||
|
||||
CommandFinished::class => [
|
||||
Command::class
|
||||
]
|
||||
];
|
||||
|
||||
/**
|
||||
* Register any events for your application.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function boot()
|
||||
{
|
||||
//
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine if events and listeners should be automatically discovered.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function shouldDiscoverEvents()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
52
app/Providers/RouteServiceProvider.php
Normal file
52
app/Providers/RouteServiceProvider.php
Normal file
@ -0,0 +1,52 @@
|
||||
<?php
|
||||
|
||||
namespace App\Providers;
|
||||
|
||||
use Illuminate\Cache\RateLimiting\Limit;
|
||||
use Illuminate\Foundation\Support\Providers\RouteServiceProvider as ServiceProvider;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\RateLimiter;
|
||||
use Illuminate\Support\Facades\Route;
|
||||
|
||||
class RouteServiceProvider extends ServiceProvider
|
||||
{
|
||||
/**
|
||||
* The path to the "home" route for your application.
|
||||
*
|
||||
* Typically, users are redirected here after authentication.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public const HOME = '/home';
|
||||
|
||||
/**
|
||||
* Define your route model bindings, pattern filters, and other route configuration.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function boot()
|
||||
{
|
||||
$this->configureRateLimiting();
|
||||
|
||||
$this->routes(function () {
|
||||
Route::middleware('api')
|
||||
->prefix('api')
|
||||
->group(base_path('routes/api.php'));
|
||||
|
||||
Route::middleware('web')
|
||||
->group(base_path('routes/web.php'));
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Configure the rate limiters for the application.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function configureRateLimiting()
|
||||
{
|
||||
RateLimiter::for('api', function (Request $request) {
|
||||
return Limit::perMinute(60)->by($request->user()?->id ?: $request->ip());
|
||||
});
|
||||
}
|
||||
}
|
53
artisan
Normal file
53
artisan
Normal file
@ -0,0 +1,53 @@
|
||||
#!/usr/bin/env php
|
||||
<?php
|
||||
|
||||
define('LARAVEL_START', microtime(true));
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Register The Auto Loader
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| Composer provides a convenient, automatically generated class loader
|
||||
| for our application. We just need to utilize it! We'll require it
|
||||
| into the script here so that we do not have to worry about the
|
||||
| loading of any of our classes manually. It's great to relax.
|
||||
|
|
||||
*/
|
||||
|
||||
require __DIR__.'/vendor/autoload.php';
|
||||
|
||||
$app = require_once __DIR__.'/bootstrap/app.php';
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Run The Artisan Application
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| When we run the console application, the current CLI command will be
|
||||
| executed in this console and the response sent back to a terminal
|
||||
| or another output device for the developers. Here goes nothing!
|
||||
|
|
||||
*/
|
||||
|
||||
$kernel = $app->make(Illuminate\Contracts\Console\Kernel::class);
|
||||
|
||||
$status = $kernel->handle(
|
||||
$input = new Symfony\Component\Console\Input\ArgvInput,
|
||||
new Symfony\Component\Console\Output\ConsoleOutput
|
||||
);
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Shutdown The Application
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| Once Artisan has finished running, we will fire off the shutdown events
|
||||
| so that any final work may be done by the application before we shut
|
||||
| down the process. This is the last thing to happen to the request.
|
||||
|
|
||||
*/
|
||||
|
||||
$kernel->terminate($input, $status);
|
||||
|
||||
exit($status);
|
278
auto-imports.d.ts
vendored
Normal file
278
auto-imports.d.ts
vendored
Normal file
@ -0,0 +1,278 @@
|
||||
// Generated by 'unplugin-auto-import'
|
||||
export {}
|
||||
declare global {
|
||||
const EffectScope: typeof import('vue')['EffectScope']
|
||||
const acceptHMRUpdate: typeof import('pinia')['acceptHMRUpdate']
|
||||
const asyncComputed: typeof import('@vueuse/core')['asyncComputed']
|
||||
const autoResetRef: typeof import('@vueuse/core')['autoResetRef']
|
||||
const computed: typeof import('vue')['computed']
|
||||
const computedAsync: typeof import('@vueuse/core')['computedAsync']
|
||||
const computedEager: typeof import('@vueuse/core')['computedEager']
|
||||
const computedInject: typeof import('@vueuse/core')['computedInject']
|
||||
const computedWithControl: typeof import('@vueuse/core')['computedWithControl']
|
||||
const controlledComputed: typeof import('@vueuse/core')['controlledComputed']
|
||||
const controlledRef: typeof import('@vueuse/core')['controlledRef']
|
||||
const createApp: typeof import('vue')['createApp']
|
||||
const createEventHook: typeof import('@vueuse/core')['createEventHook']
|
||||
const createGlobalState: typeof import('@vueuse/core')['createGlobalState']
|
||||
const createInjectionState: typeof import('@vueuse/core')['createInjectionState']
|
||||
const createPinia: typeof import('pinia')['createPinia']
|
||||
const createReactiveFn: typeof import('@vueuse/core')['createReactiveFn']
|
||||
const createSharedComposable: typeof import('@vueuse/core')['createSharedComposable']
|
||||
const createUnrefFn: typeof import('@vueuse/core')['createUnrefFn']
|
||||
const customRef: typeof import('vue')['customRef']
|
||||
const debouncedRef: typeof import('@vueuse/core')['debouncedRef']
|
||||
const debouncedWatch: typeof import('@vueuse/core')['debouncedWatch']
|
||||
const defineAsyncComponent: typeof import('vue')['defineAsyncComponent']
|
||||
const defineComponent: typeof import('vue')['defineComponent']
|
||||
const defineStore: typeof import('pinia')['defineStore']
|
||||
const eagerComputed: typeof import('@vueuse/core')['eagerComputed']
|
||||
const effectScope: typeof import('vue')['effectScope']
|
||||
const extendRef: typeof import('@vueuse/core')['extendRef']
|
||||
const getActivePinia: typeof import('pinia')['getActivePinia']
|
||||
const getCurrentInstance: typeof import('vue')['getCurrentInstance']
|
||||
const getCurrentScope: typeof import('vue')['getCurrentScope']
|
||||
const h: typeof import('vue')['h']
|
||||
const ignorableWatch: typeof import('@vueuse/core')['ignorableWatch']
|
||||
const inject: typeof import('vue')['inject']
|
||||
const isDefined: typeof import('@vueuse/core')['isDefined']
|
||||
const isProxy: typeof import('vue')['isProxy']
|
||||
const isReactive: typeof import('vue')['isReactive']
|
||||
const isReadonly: typeof import('vue')['isReadonly']
|
||||
const isRef: typeof import('vue')['isRef']
|
||||
const makeDestructurable: typeof import('@vueuse/core')['makeDestructurable']
|
||||
const mapActions: typeof import('pinia')['mapActions']
|
||||
const mapGetters: typeof import('pinia')['mapGetters']
|
||||
const mapState: typeof import('pinia')['mapState']
|
||||
const mapStores: typeof import('pinia')['mapStores']
|
||||
const mapWritableState: typeof import('pinia')['mapWritableState']
|
||||
const markRaw: typeof import('vue')['markRaw']
|
||||
const nextTick: typeof import('vue')['nextTick']
|
||||
const onActivated: typeof import('vue')['onActivated']
|
||||
const onBeforeMount: typeof import('vue')['onBeforeMount']
|
||||
const onBeforeRouteLeave: typeof import('vue-router')['onBeforeRouteLeave']
|
||||
const onBeforeRouteUpdate: typeof import('vue-router')['onBeforeRouteUpdate']
|
||||
const onBeforeUnmount: typeof import('vue')['onBeforeUnmount']
|
||||
const onBeforeUpdate: typeof import('vue')['onBeforeUpdate']
|
||||
const onClickOutside: typeof import('@vueuse/core')['onClickOutside']
|
||||
const onDeactivated: typeof import('vue')['onDeactivated']
|
||||
const onErrorCaptured: typeof import('vue')['onErrorCaptured']
|
||||
const onKeyStroke: typeof import('@vueuse/core')['onKeyStroke']
|
||||
const onLongPress: typeof import('@vueuse/core')['onLongPress']
|
||||
const onMounted: typeof import('vue')['onMounted']
|
||||
const onRenderTracked: typeof import('vue')['onRenderTracked']
|
||||
const onRenderTriggered: typeof import('vue')['onRenderTriggered']
|
||||
const onScopeDispose: typeof import('vue')['onScopeDispose']
|
||||
const onServerPrefetch: typeof import('vue')['onServerPrefetch']
|
||||
const onStartTyping: typeof import('@vueuse/core')['onStartTyping']
|
||||
const onUnmounted: typeof import('vue')['onUnmounted']
|
||||
const onUpdated: typeof import('vue')['onUpdated']
|
||||
const pausableWatch: typeof import('@vueuse/core')['pausableWatch']
|
||||
const provide: typeof import('vue')['provide']
|
||||
const reactify: typeof import('@vueuse/core')['reactify']
|
||||
const reactifyObject: typeof import('@vueuse/core')['reactifyObject']
|
||||
const reactive: typeof import('vue')['reactive']
|
||||
const reactiveComputed: typeof import('@vueuse/core')['reactiveComputed']
|
||||
const reactiveOmit: typeof import('@vueuse/core')['reactiveOmit']
|
||||
const reactivePick: typeof import('@vueuse/core')['reactivePick']
|
||||
const readonly: typeof import('vue')['readonly']
|
||||
const ref: typeof import('vue')['ref']
|
||||
const refAutoReset: typeof import('@vueuse/core')['refAutoReset']
|
||||
const refDebounced: typeof import('@vueuse/core')['refDebounced']
|
||||
const refDefault: typeof import('@vueuse/core')['refDefault']
|
||||
const refThrottled: typeof import('@vueuse/core')['refThrottled']
|
||||
const refWithControl: typeof import('@vueuse/core')['refWithControl']
|
||||
const resolveComponent: typeof import('vue')['resolveComponent']
|
||||
const resolveDirective: typeof import('vue')['resolveDirective']
|
||||
const resolveRef: typeof import('@vueuse/core')['resolveRef']
|
||||
const resolveUnref: typeof import('@vueuse/core')['resolveUnref']
|
||||
const setActivePinia: typeof import('pinia')['setActivePinia']
|
||||
const setMapStoreSuffix: typeof import('pinia')['setMapStoreSuffix']
|
||||
const shallowReactive: typeof import('vue')['shallowReactive']
|
||||
const shallowReadonly: typeof import('vue')['shallowReadonly']
|
||||
const shallowRef: typeof import('vue')['shallowRef']
|
||||
const storeToRefs: typeof import('pinia')['storeToRefs']
|
||||
const syncRef: typeof import('@vueuse/core')['syncRef']
|
||||
const syncRefs: typeof import('@vueuse/core')['syncRefs']
|
||||
const templateRef: typeof import('@vueuse/core')['templateRef']
|
||||
const throttledRef: typeof import('@vueuse/core')['throttledRef']
|
||||
const throttledWatch: typeof import('@vueuse/core')['throttledWatch']
|
||||
const toRaw: typeof import('vue')['toRaw']
|
||||
const toReactive: typeof import('@vueuse/core')['toReactive']
|
||||
const toRef: typeof import('vue')['toRef']
|
||||
const toRefs: typeof import('vue')['toRefs']
|
||||
const triggerRef: typeof import('vue')['triggerRef']
|
||||
const tryOnBeforeMount: typeof import('@vueuse/core')['tryOnBeforeMount']
|
||||
const tryOnBeforeUnmount: typeof import('@vueuse/core')['tryOnBeforeUnmount']
|
||||
const tryOnMounted: typeof import('@vueuse/core')['tryOnMounted']
|
||||
const tryOnScopeDispose: typeof import('@vueuse/core')['tryOnScopeDispose']
|
||||
const tryOnUnmounted: typeof import('@vueuse/core')['tryOnUnmounted']
|
||||
const unref: typeof import('vue')['unref']
|
||||
const unrefElement: typeof import('@vueuse/core')['unrefElement']
|
||||
const until: typeof import('@vueuse/core')['until']
|
||||
const useActiveElement: typeof import('@vueuse/core')['useActiveElement']
|
||||
const useArrayEvery: typeof import('@vueuse/core')['useArrayEvery']
|
||||
const useArrayFilter: typeof import('@vueuse/core')['useArrayFilter']
|
||||
const useArrayFind: typeof import('@vueuse/core')['useArrayFind']
|
||||
const useArrayFindIndex: typeof import('@vueuse/core')['useArrayFindIndex']
|
||||
const useArrayJoin: typeof import('@vueuse/core')['useArrayJoin']
|
||||
const useArrayMap: typeof import('@vueuse/core')['useArrayMap']
|
||||
const useArrayReduce: typeof import('@vueuse/core')['useArrayReduce']
|
||||
const useArraySome: typeof import('@vueuse/core')['useArraySome']
|
||||
const useAsyncQueue: typeof import('@vueuse/core')['useAsyncQueue']
|
||||
const useAsyncState: typeof import('@vueuse/core')['useAsyncState']
|
||||
const useAttrs: typeof import('vue')['useAttrs']
|
||||
const useBase64: typeof import('@vueuse/core')['useBase64']
|
||||
const useBattery: typeof import('@vueuse/core')['useBattery']
|
||||
const useBluetooth: typeof import('@vueuse/core')['useBluetooth']
|
||||
const useBreakpoints: typeof import('@vueuse/core')['useBreakpoints']
|
||||
const useBroadcastChannel: typeof import('@vueuse/core')['useBroadcastChannel']
|
||||
const useBrowserLocation: typeof import('@vueuse/core')['useBrowserLocation']
|
||||
const useCached: typeof import('@vueuse/core')['useCached']
|
||||
const useClipboard: typeof import('@vueuse/core')['useClipboard']
|
||||
const useCloned: typeof import('@vueuse/core')['useCloned']
|
||||
const useColorMode: typeof import('@vueuse/core')['useColorMode']
|
||||
const useConfirmDialog: typeof import('@vueuse/core')['useConfirmDialog']
|
||||
const useCounter: typeof import('@vueuse/core')['useCounter']
|
||||
const useCssModule: typeof import('vue')['useCssModule']
|
||||
const useCssVar: typeof import('@vueuse/core')['useCssVar']
|
||||
const useCssVars: typeof import('vue')['useCssVars']
|
||||
const useCurrentElement: typeof import('@vueuse/core')['useCurrentElement']
|
||||
const useCycleList: typeof import('@vueuse/core')['useCycleList']
|
||||
const useDark: typeof import('@vueuse/core')['useDark']
|
||||
const useDateFormat: typeof import('@vueuse/core')['useDateFormat']
|
||||
const useDebounce: typeof import('@vueuse/core')['useDebounce']
|
||||
const useDebounceFn: typeof import('@vueuse/core')['useDebounceFn']
|
||||
const useDebouncedRefHistory: typeof import('@vueuse/core')['useDebouncedRefHistory']
|
||||
const useDeviceMotion: typeof import('@vueuse/core')['useDeviceMotion']
|
||||
const useDeviceOrientation: typeof import('@vueuse/core')['useDeviceOrientation']
|
||||
const useDevicePixelRatio: typeof import('@vueuse/core')['useDevicePixelRatio']
|
||||
const useDevicesList: typeof import('@vueuse/core')['useDevicesList']
|
||||
const useDisplayMedia: typeof import('@vueuse/core')['useDisplayMedia']
|
||||
const useDocumentVisibility: typeof import('@vueuse/core')['useDocumentVisibility']
|
||||
const useDraggable: typeof import('@vueuse/core')['useDraggable']
|
||||
const useDropZone: typeof import('@vueuse/core')['useDropZone']
|
||||
const useElementBounding: typeof import('@vueuse/core')['useElementBounding']
|
||||
const useElementByPoint: typeof import('@vueuse/core')['useElementByPoint']
|
||||
const useElementHover: typeof import('@vueuse/core')['useElementHover']
|
||||
const useElementSize: typeof import('@vueuse/core')['useElementSize']
|
||||
const useElementVisibility: typeof import('@vueuse/core')['useElementVisibility']
|
||||
const useEventBus: typeof import('@vueuse/core')['useEventBus']
|
||||
const useEventListener: typeof import('@vueuse/core')['useEventListener']
|
||||
const useEventSource: typeof import('@vueuse/core')['useEventSource']
|
||||
const useEyeDropper: typeof import('@vueuse/core')['useEyeDropper']
|
||||
const useFavicon: typeof import('@vueuse/core')['useFavicon']
|
||||
const useFetch: typeof import('@vueuse/core')['useFetch']
|
||||
const useFileDialog: typeof import('@vueuse/core')['useFileDialog']
|
||||
const useFileSystemAccess: typeof import('@vueuse/core')['useFileSystemAccess']
|
||||
const useFocus: typeof import('@vueuse/core')['useFocus']
|
||||
const useFocusWithin: typeof import('@vueuse/core')['useFocusWithin']
|
||||
const useFps: typeof import('@vueuse/core')['useFps']
|
||||
const useFullscreen: typeof import('@vueuse/core')['useFullscreen']
|
||||
const useGamepad: typeof import('@vueuse/core')['useGamepad']
|
||||
const useGeolocation: typeof import('@vueuse/core')['useGeolocation']
|
||||
const useIdle: typeof import('@vueuse/core')['useIdle']
|
||||
const useImage: typeof import('@vueuse/core')['useImage']
|
||||
const useInfiniteScroll: typeof import('@vueuse/core')['useInfiniteScroll']
|
||||
const useIntersectionObserver: typeof import('@vueuse/core')['useIntersectionObserver']
|
||||
const useInterval: typeof import('@vueuse/core')['useInterval']
|
||||
const useIntervalFn: typeof import('@vueuse/core')['useIntervalFn']
|
||||
const useKeyModifier: typeof import('@vueuse/core')['useKeyModifier']
|
||||
const useLastChanged: typeof import('@vueuse/core')['useLastChanged']
|
||||
const useLink: typeof import('vue-router')['useLink']
|
||||
const useLocalStorage: typeof import('@vueuse/core')['useLocalStorage']
|
||||
const useMagicKeys: typeof import('@vueuse/core')['useMagicKeys']
|
||||
const useManualRefHistory: typeof import('@vueuse/core')['useManualRefHistory']
|
||||
const useMediaControls: typeof import('@vueuse/core')['useMediaControls']
|
||||
const useMediaQuery: typeof import('@vueuse/core')['useMediaQuery']
|
||||
const useMemoize: typeof import('@vueuse/core')['useMemoize']
|
||||
const useMemory: typeof import('@vueuse/core')['useMemory']
|
||||
const useMounted: typeof import('@vueuse/core')['useMounted']
|
||||
const useMouse: typeof import('@vueuse/core')['useMouse']
|
||||
const useMouseInElement: typeof import('@vueuse/core')['useMouseInElement']
|
||||
const useMousePressed: typeof import('@vueuse/core')['useMousePressed']
|
||||
const useMutationObserver: typeof import('@vueuse/core')['useMutationObserver']
|
||||
const useNavigatorLanguage: typeof import('@vueuse/core')['useNavigatorLanguage']
|
||||
const useNetwork: typeof import('@vueuse/core')['useNetwork']
|
||||
const useNow: typeof import('@vueuse/core')['useNow']
|
||||
const useObjectUrl: typeof import('@vueuse/core')['useObjectUrl']
|
||||
const useOffsetPagination: typeof import('@vueuse/core')['useOffsetPagination']
|
||||
const useOnline: typeof import('@vueuse/core')['useOnline']
|
||||
const usePageLeave: typeof import('@vueuse/core')['usePageLeave']
|
||||
const useParallax: typeof import('@vueuse/core')['useParallax']
|
||||
const usePermission: typeof import('@vueuse/core')['usePermission']
|
||||
const usePointer: typeof import('@vueuse/core')['usePointer']
|
||||
const usePointerSwipe: typeof import('@vueuse/core')['usePointerSwipe']
|
||||
const usePreferredColorScheme: typeof import('@vueuse/core')['usePreferredColorScheme']
|
||||
const usePreferredContrast: typeof import('@vueuse/core')['usePreferredContrast']
|
||||
const usePreferredDark: typeof import('@vueuse/core')['usePreferredDark']
|
||||
const usePreferredLanguages: typeof import('@vueuse/core')['usePreferredLanguages']
|
||||
const usePreferredReducedMotion: typeof import('@vueuse/core')['usePreferredReducedMotion']
|
||||
const useRafFn: typeof import('@vueuse/core')['useRafFn']
|
||||
const useRefHistory: typeof import('@vueuse/core')['useRefHistory']
|
||||
const useResizeObserver: typeof import('@vueuse/core')['useResizeObserver']
|
||||
const useRoute: typeof import('vue-router')['useRoute']
|
||||
const useRouter: typeof import('vue-router')['useRouter']
|
||||
const useScreenOrientation: typeof import('@vueuse/core')['useScreenOrientation']
|
||||
const useScreenSafeArea: typeof import('@vueuse/core')['useScreenSafeArea']
|
||||
const useScriptTag: typeof import('@vueuse/core')['useScriptTag']
|
||||
const useScroll: typeof import('@vueuse/core')['useScroll']
|
||||
const useScrollLock: typeof import('@vueuse/core')['useScrollLock']
|
||||
const useSessionStorage: typeof import('@vueuse/core')['useSessionStorage']
|
||||
const useShare: typeof import('@vueuse/core')['useShare']
|
||||
const useSlots: typeof import('vue')['useSlots']
|
||||
const useSorted: typeof import('@vueuse/core')['useSorted']
|
||||
const useSpeechRecognition: typeof import('@vueuse/core')['useSpeechRecognition']
|
||||
const useSpeechSynthesis: typeof import('@vueuse/core')['useSpeechSynthesis']
|
||||
const useStepper: typeof import('@vueuse/core')['useStepper']
|
||||
const useStorage: typeof import('@vueuse/core')['useStorage']
|
||||
const useStorageAsync: typeof import('@vueuse/core')['useStorageAsync']
|
||||
const useStyleTag: typeof import('@vueuse/core')['useStyleTag']
|
||||
const useSupported: typeof import('@vueuse/core')['useSupported']
|
||||
const useSwipe: typeof import('@vueuse/core')['useSwipe']
|
||||
const useTemplateRefsList: typeof import('@vueuse/core')['useTemplateRefsList']
|
||||
const useTextDirection: typeof import('@vueuse/core')['useTextDirection']
|
||||
const useTextSelection: typeof import('@vueuse/core')['useTextSelection']
|
||||
const useTextareaAutosize: typeof import('@vueuse/core')['useTextareaAutosize']
|
||||
const useThrottle: typeof import('@vueuse/core')['useThrottle']
|
||||
const useThrottleFn: typeof import('@vueuse/core')['useThrottleFn']
|
||||
const useThrottledRefHistory: typeof import('@vueuse/core')['useThrottledRefHistory']
|
||||
const useTimeAgo: typeof import('@vueuse/core')['useTimeAgo']
|
||||
const useTimeout: typeof import('@vueuse/core')['useTimeout']
|
||||
const useTimeoutFn: typeof import('@vueuse/core')['useTimeoutFn']
|
||||
const useTimeoutPoll: typeof import('@vueuse/core')['useTimeoutPoll']
|
||||
const useTimestamp: typeof import('@vueuse/core')['useTimestamp']
|
||||
const useTitle: typeof import('@vueuse/core')['useTitle']
|
||||
const useToNumber: typeof import('@vueuse/core')['useToNumber']
|
||||
const useToString: typeof import('@vueuse/core')['useToString']
|
||||
const useToggle: typeof import('@vueuse/core')['useToggle']
|
||||
const useTransition: typeof import('@vueuse/core')['useTransition']
|
||||
const useUrlSearchParams: typeof import('@vueuse/core')['useUrlSearchParams']
|
||||
const useUserMedia: typeof import('@vueuse/core')['useUserMedia']
|
||||
const useVModel: typeof import('@vueuse/core')['useVModel']
|
||||
const useVModels: typeof import('@vueuse/core')['useVModels']
|
||||
const useVibrate: typeof import('@vueuse/core')['useVibrate']
|
||||
const useVirtualList: typeof import('@vueuse/core')['useVirtualList']
|
||||
const useWakeLock: typeof import('@vueuse/core')['useWakeLock']
|
||||
const useWebNotification: typeof import('@vueuse/core')['useWebNotification']
|
||||
const useWebSocket: typeof import('@vueuse/core')['useWebSocket']
|
||||
const useWebWorker: typeof import('@vueuse/core')['useWebWorker']
|
||||
const useWebWorkerFn: typeof import('@vueuse/core')['useWebWorkerFn']
|
||||
const useWindowFocus: typeof import('@vueuse/core')['useWindowFocus']
|
||||
const useWindowScroll: typeof import('@vueuse/core')['useWindowScroll']
|
||||
const useWindowSize: typeof import('@vueuse/core')['useWindowSize']
|
||||
const watch: typeof import('vue')['watch']
|
||||
const watchArray: typeof import('@vueuse/core')['watchArray']
|
||||
const watchAtMost: typeof import('@vueuse/core')['watchAtMost']
|
||||
const watchDebounced: typeof import('@vueuse/core')['watchDebounced']
|
||||
const watchEffect: typeof import('vue')['watchEffect']
|
||||
const watchIgnorable: typeof import('@vueuse/core')['watchIgnorable']
|
||||
const watchOnce: typeof import('@vueuse/core')['watchOnce']
|
||||
const watchPausable: typeof import('@vueuse/core')['watchPausable']
|
||||
const watchPostEffect: typeof import('vue')['watchPostEffect']
|
||||
const watchSyncEffect: typeof import('vue')['watchSyncEffect']
|
||||
const watchThrottled: typeof import('@vueuse/core')['watchThrottled']
|
||||
const watchTriggerable: typeof import('@vueuse/core')['watchTriggerable']
|
||||
const watchWithFilter: typeof import('@vueuse/core')['watchWithFilter']
|
||||
const whenever: typeof import('@vueuse/core')['whenever']
|
||||
}
|
55
bootstrap/app.php
Normal file
55
bootstrap/app.php
Normal file
@ -0,0 +1,55 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Create The Application
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| The first thing we will do is create a new Laravel application instance
|
||||
| which serves as the "glue" for all the components of Laravel, and is
|
||||
| the IoC container for the system binding all of the various parts.
|
||||
|
|
||||
*/
|
||||
|
||||
$app = new Illuminate\Foundation\Application(
|
||||
$_ENV['APP_BASE_PATH'] ?? dirname(__DIR__)
|
||||
);
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Bind Important Interfaces
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| Next, we need to bind some important interfaces into the container so
|
||||
| we will be able to resolve them when needed. The kernels serve the
|
||||
| incoming requests to this application from both the web and CLI.
|
||||
|
|
||||
*/
|
||||
|
||||
$app->singleton(
|
||||
Illuminate\Contracts\Http\Kernel::class,
|
||||
App\Http\Kernel::class
|
||||
);
|
||||
|
||||
$app->singleton(
|
||||
Illuminate\Contracts\Console\Kernel::class,
|
||||
App\Console\Kernel::class
|
||||
);
|
||||
|
||||
$app->singleton(
|
||||
Illuminate\Contracts\Debug\ExceptionHandler::class,
|
||||
App\Exceptions\Handler::class
|
||||
);
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Return The Application
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| This script returns the application instance. The instance is given to
|
||||
| the calling script so we can separate the building of the instances
|
||||
| from the actual running of the application and sending responses.
|
||||
|
|
||||
*/
|
||||
|
||||
return $app;
|
49
bootstrap/cache/packages.php
vendored
Executable file
49
bootstrap/cache/packages.php
vendored
Executable file
@ -0,0 +1,49 @@
|
||||
<?php return array (
|
||||
'laravel/tinker' =>
|
||||
array (
|
||||
'providers' =>
|
||||
array (
|
||||
0 => 'Laravel\\Tinker\\TinkerServiceProvider',
|
||||
),
|
||||
),
|
||||
'nesbot/carbon' =>
|
||||
array (
|
||||
'providers' =>
|
||||
array (
|
||||
0 => 'Carbon\\Laravel\\ServiceProvider',
|
||||
),
|
||||
),
|
||||
'nunomaduro/collision' =>
|
||||
array (
|
||||
'providers' =>
|
||||
array (
|
||||
0 => 'NunoMaduro\\Collision\\Adapters\\Laravel\\CollisionServiceProvider',
|
||||
),
|
||||
),
|
||||
'nunomaduro/termwind' =>
|
||||
array (
|
||||
'providers' =>
|
||||
array (
|
||||
0 => 'Termwind\\Laravel\\TermwindServiceProvider',
|
||||
),
|
||||
),
|
||||
'pestphp/pest' =>
|
||||
array (
|
||||
'providers' =>
|
||||
array (
|
||||
0 => 'Pest\\Laravel\\PestServiceProvider',
|
||||
),
|
||||
),
|
||||
'tymon/jwt-auth' =>
|
||||
array (
|
||||
'aliases' =>
|
||||
array (
|
||||
'JWTAuth' => 'Tymon\\JWTAuth\\Facades\\JWTAuth',
|
||||
'JWTFactory' => 'Tymon\\JWTAuth\\Facades\\JWTFactory',
|
||||
),
|
||||
'providers' =>
|
||||
array (
|
||||
0 => 'Tymon\\JWTAuth\\Providers\\LaravelServiceProvider',
|
||||
),
|
||||
),
|
||||
);
|
237
bootstrap/cache/services.php
vendored
Executable file
237
bootstrap/cache/services.php
vendored
Executable file
@ -0,0 +1,237 @@
|
||||
<?php return array (
|
||||
'providers' =>
|
||||
array (
|
||||
0 => 'Illuminate\\Auth\\AuthServiceProvider',
|
||||
1 => 'Illuminate\\Broadcasting\\BroadcastServiceProvider',
|
||||
2 => 'Illuminate\\Bus\\BusServiceProvider',
|
||||
3 => 'Illuminate\\Cache\\CacheServiceProvider',
|
||||
4 => 'Illuminate\\Foundation\\Providers\\ConsoleSupportServiceProvider',
|
||||
5 => 'Illuminate\\Cookie\\CookieServiceProvider',
|
||||
6 => 'Illuminate\\Database\\DatabaseServiceProvider',
|
||||
7 => 'Illuminate\\Encryption\\EncryptionServiceProvider',
|
||||
8 => 'Illuminate\\Filesystem\\FilesystemServiceProvider',
|
||||
9 => 'Illuminate\\Foundation\\Providers\\FoundationServiceProvider',
|
||||
10 => 'Illuminate\\Hashing\\HashServiceProvider',
|
||||
11 => 'Illuminate\\Mail\\MailServiceProvider',
|
||||
12 => 'Illuminate\\Notifications\\NotificationServiceProvider',
|
||||
13 => 'Illuminate\\Pagination\\PaginationServiceProvider',
|
||||
14 => 'Illuminate\\Pipeline\\PipelineServiceProvider',
|
||||
15 => 'Illuminate\\Queue\\QueueServiceProvider',
|
||||
16 => 'Illuminate\\Redis\\RedisServiceProvider',
|
||||
17 => 'Illuminate\\Auth\\Passwords\\PasswordResetServiceProvider',
|
||||
18 => 'Illuminate\\Session\\SessionServiceProvider',
|
||||
19 => 'Illuminate\\Translation\\TranslationServiceProvider',
|
||||
20 => 'Illuminate\\Validation\\ValidationServiceProvider',
|
||||
21 => 'Illuminate\\View\\ViewServiceProvider',
|
||||
22 => 'Laravel\\Tinker\\TinkerServiceProvider',
|
||||
23 => 'Carbon\\Laravel\\ServiceProvider',
|
||||
24 => 'NunoMaduro\\Collision\\Adapters\\Laravel\\CollisionServiceProvider',
|
||||
25 => 'Termwind\\Laravel\\TermwindServiceProvider',
|
||||
26 => 'Pest\\Laravel\\PestServiceProvider',
|
||||
27 => 'Tymon\\JWTAuth\\Providers\\LaravelServiceProvider',
|
||||
28 => 'Catch\\Providers\\CatchAdminServiceProvider',
|
||||
29 => 'App\\Providers\\AppServiceProvider',
|
||||
30 => 'App\\Providers\\AuthServiceProvider',
|
||||
31 => 'App\\Providers\\EventServiceProvider',
|
||||
32 => 'App\\Providers\\RouteServiceProvider',
|
||||
),
|
||||
'eager' =>
|
||||
array (
|
||||
0 => 'Illuminate\\Auth\\AuthServiceProvider',
|
||||
1 => 'Illuminate\\Cookie\\CookieServiceProvider',
|
||||
2 => 'Illuminate\\Database\\DatabaseServiceProvider',
|
||||
3 => 'Illuminate\\Encryption\\EncryptionServiceProvider',
|
||||
4 => 'Illuminate\\Filesystem\\FilesystemServiceProvider',
|
||||
5 => 'Illuminate\\Foundation\\Providers\\FoundationServiceProvider',
|
||||
6 => 'Illuminate\\Notifications\\NotificationServiceProvider',
|
||||
7 => 'Illuminate\\Pagination\\PaginationServiceProvider',
|
||||
8 => 'Illuminate\\Session\\SessionServiceProvider',
|
||||
9 => 'Illuminate\\View\\ViewServiceProvider',
|
||||
10 => 'Carbon\\Laravel\\ServiceProvider',
|
||||
11 => 'NunoMaduro\\Collision\\Adapters\\Laravel\\CollisionServiceProvider',
|
||||
12 => 'Termwind\\Laravel\\TermwindServiceProvider',
|
||||
13 => 'Pest\\Laravel\\PestServiceProvider',
|
||||
14 => 'Tymon\\JWTAuth\\Providers\\LaravelServiceProvider',
|
||||
15 => 'Catch\\Providers\\CatchAdminServiceProvider',
|
||||
16 => 'App\\Providers\\AppServiceProvider',
|
||||
17 => 'App\\Providers\\AuthServiceProvider',
|
||||
18 => 'App\\Providers\\EventServiceProvider',
|
||||
19 => 'App\\Providers\\RouteServiceProvider',
|
||||
),
|
||||
'deferred' =>
|
||||
array (
|
||||
'Illuminate\\Broadcasting\\BroadcastManager' => 'Illuminate\\Broadcasting\\BroadcastServiceProvider',
|
||||
'Illuminate\\Contracts\\Broadcasting\\Factory' => 'Illuminate\\Broadcasting\\BroadcastServiceProvider',
|
||||
'Illuminate\\Contracts\\Broadcasting\\Broadcaster' => 'Illuminate\\Broadcasting\\BroadcastServiceProvider',
|
||||
'Illuminate\\Bus\\Dispatcher' => 'Illuminate\\Bus\\BusServiceProvider',
|
||||
'Illuminate\\Contracts\\Bus\\Dispatcher' => 'Illuminate\\Bus\\BusServiceProvider',
|
||||
'Illuminate\\Contracts\\Bus\\QueueingDispatcher' => 'Illuminate\\Bus\\BusServiceProvider',
|
||||
'Illuminate\\Bus\\BatchRepository' => 'Illuminate\\Bus\\BusServiceProvider',
|
||||
'Illuminate\\Bus\\DatabaseBatchRepository' => 'Illuminate\\Bus\\BusServiceProvider',
|
||||
'cache' => 'Illuminate\\Cache\\CacheServiceProvider',
|
||||
'cache.store' => 'Illuminate\\Cache\\CacheServiceProvider',
|
||||
'cache.psr6' => 'Illuminate\\Cache\\CacheServiceProvider',
|
||||
'memcached.connector' => 'Illuminate\\Cache\\CacheServiceProvider',
|
||||
'Illuminate\\Cache\\RateLimiter' => 'Illuminate\\Cache\\CacheServiceProvider',
|
||||
'Illuminate\\Foundation\\Console\\AboutCommand' => 'Illuminate\\Foundation\\Providers\\ConsoleSupportServiceProvider',
|
||||
'Illuminate\\Cache\\Console\\ClearCommand' => 'Illuminate\\Foundation\\Providers\\ConsoleSupportServiceProvider',
|
||||
'Illuminate\\Cache\\Console\\ForgetCommand' => 'Illuminate\\Foundation\\Providers\\ConsoleSupportServiceProvider',
|
||||
'Illuminate\\Foundation\\Console\\ClearCompiledCommand' => 'Illuminate\\Foundation\\Providers\\ConsoleSupportServiceProvider',
|
||||
'Illuminate\\Auth\\Console\\ClearResetsCommand' => 'Illuminate\\Foundation\\Providers\\ConsoleSupportServiceProvider',
|
||||
'Illuminate\\Foundation\\Console\\ConfigCacheCommand' => 'Illuminate\\Foundation\\Providers\\ConsoleSupportServiceProvider',
|
||||
'Illuminate\\Foundation\\Console\\ConfigClearCommand' => 'Illuminate\\Foundation\\Providers\\ConsoleSupportServiceProvider',
|
||||
'Illuminate\\Database\\Console\\DbCommand' => 'Illuminate\\Foundation\\Providers\\ConsoleSupportServiceProvider',
|
||||
'Illuminate\\Database\\Console\\MonitorCommand' => 'Illuminate\\Foundation\\Providers\\ConsoleSupportServiceProvider',
|
||||
'Illuminate\\Database\\Console\\PruneCommand' => 'Illuminate\\Foundation\\Providers\\ConsoleSupportServiceProvider',
|
||||
'Illuminate\\Database\\Console\\ShowCommand' => 'Illuminate\\Foundation\\Providers\\ConsoleSupportServiceProvider',
|
||||
'Illuminate\\Database\\Console\\TableCommand' => 'Illuminate\\Foundation\\Providers\\ConsoleSupportServiceProvider',
|
||||
'Illuminate\\Database\\Console\\WipeCommand' => 'Illuminate\\Foundation\\Providers\\ConsoleSupportServiceProvider',
|
||||
'Illuminate\\Foundation\\Console\\DownCommand' => 'Illuminate\\Foundation\\Providers\\ConsoleSupportServiceProvider',
|
||||
'Illuminate\\Foundation\\Console\\EnvironmentCommand' => 'Illuminate\\Foundation\\Providers\\ConsoleSupportServiceProvider',
|
||||
'Illuminate\\Foundation\\Console\\EnvironmentDecryptCommand' => 'Illuminate\\Foundation\\Providers\\ConsoleSupportServiceProvider',
|
||||
'Illuminate\\Foundation\\Console\\EnvironmentEncryptCommand' => 'Illuminate\\Foundation\\Providers\\ConsoleSupportServiceProvider',
|
||||
'Illuminate\\Foundation\\Console\\EventCacheCommand' => 'Illuminate\\Foundation\\Providers\\ConsoleSupportServiceProvider',
|
||||
'Illuminate\\Foundation\\Console\\EventClearCommand' => 'Illuminate\\Foundation\\Providers\\ConsoleSupportServiceProvider',
|
||||
'Illuminate\\Foundation\\Console\\EventListCommand' => 'Illuminate\\Foundation\\Providers\\ConsoleSupportServiceProvider',
|
||||
'Illuminate\\Foundation\\Console\\KeyGenerateCommand' => 'Illuminate\\Foundation\\Providers\\ConsoleSupportServiceProvider',
|
||||
'Illuminate\\Foundation\\Console\\OptimizeCommand' => 'Illuminate\\Foundation\\Providers\\ConsoleSupportServiceProvider',
|
||||
'Illuminate\\Foundation\\Console\\OptimizeClearCommand' => 'Illuminate\\Foundation\\Providers\\ConsoleSupportServiceProvider',
|
||||
'Illuminate\\Foundation\\Console\\PackageDiscoverCommand' => 'Illuminate\\Foundation\\Providers\\ConsoleSupportServiceProvider',
|
||||
'Illuminate\\Queue\\Console\\ClearCommand' => 'Illuminate\\Foundation\\Providers\\ConsoleSupportServiceProvider',
|
||||
'Illuminate\\Queue\\Console\\ListFailedCommand' => 'Illuminate\\Foundation\\Providers\\ConsoleSupportServiceProvider',
|
||||
'Illuminate\\Queue\\Console\\FlushFailedCommand' => 'Illuminate\\Foundation\\Providers\\ConsoleSupportServiceProvider',
|
||||
'Illuminate\\Queue\\Console\\ForgetFailedCommand' => 'Illuminate\\Foundation\\Providers\\ConsoleSupportServiceProvider',
|
||||
'Illuminate\\Queue\\Console\\ListenCommand' => 'Illuminate\\Foundation\\Providers\\ConsoleSupportServiceProvider',
|
||||
'Illuminate\\Queue\\Console\\MonitorCommand' => 'Illuminate\\Foundation\\Providers\\ConsoleSupportServiceProvider',
|
||||
'Illuminate\\Queue\\Console\\PruneBatchesCommand' => 'Illuminate\\Foundation\\Providers\\ConsoleSupportServiceProvider',
|
||||
'Illuminate\\Queue\\Console\\PruneFailedJobsCommand' => 'Illuminate\\Foundation\\Providers\\ConsoleSupportServiceProvider',
|
||||
'Illuminate\\Queue\\Console\\RestartCommand' => 'Illuminate\\Foundation\\Providers\\ConsoleSupportServiceProvider',
|
||||
'Illuminate\\Queue\\Console\\RetryCommand' => 'Illuminate\\Foundation\\Providers\\ConsoleSupportServiceProvider',
|
||||
'Illuminate\\Queue\\Console\\RetryBatchCommand' => 'Illuminate\\Foundation\\Providers\\ConsoleSupportServiceProvider',
|
||||
'Illuminate\\Queue\\Console\\WorkCommand' => 'Illuminate\\Foundation\\Providers\\ConsoleSupportServiceProvider',
|
||||
'Illuminate\\Foundation\\Console\\RouteCacheCommand' => 'Illuminate\\Foundation\\Providers\\ConsoleSupportServiceProvider',
|
||||
'Illuminate\\Foundation\\Console\\RouteClearCommand' => 'Illuminate\\Foundation\\Providers\\ConsoleSupportServiceProvider',
|
||||
'Illuminate\\Foundation\\Console\\RouteListCommand' => 'Illuminate\\Foundation\\Providers\\ConsoleSupportServiceProvider',
|
||||
'Illuminate\\Database\\Console\\DumpCommand' => 'Illuminate\\Foundation\\Providers\\ConsoleSupportServiceProvider',
|
||||
'Illuminate\\Database\\Console\\Seeds\\SeedCommand' => 'Illuminate\\Foundation\\Providers\\ConsoleSupportServiceProvider',
|
||||
'Illuminate\\Console\\Scheduling\\ScheduleFinishCommand' => 'Illuminate\\Foundation\\Providers\\ConsoleSupportServiceProvider',
|
||||
'Illuminate\\Console\\Scheduling\\ScheduleListCommand' => 'Illuminate\\Foundation\\Providers\\ConsoleSupportServiceProvider',
|
||||
'Illuminate\\Console\\Scheduling\\ScheduleRunCommand' => 'Illuminate\\Foundation\\Providers\\ConsoleSupportServiceProvider',
|
||||
'Illuminate\\Console\\Scheduling\\ScheduleClearCacheCommand' => 'Illuminate\\Foundation\\Providers\\ConsoleSupportServiceProvider',
|
||||
'Illuminate\\Console\\Scheduling\\ScheduleTestCommand' => 'Illuminate\\Foundation\\Providers\\ConsoleSupportServiceProvider',
|
||||
'Illuminate\\Console\\Scheduling\\ScheduleWorkCommand' => 'Illuminate\\Foundation\\Providers\\ConsoleSupportServiceProvider',
|
||||
'Illuminate\\Foundation\\Console\\ShowModelCommand' => 'Illuminate\\Foundation\\Providers\\ConsoleSupportServiceProvider',
|
||||
'Illuminate\\Foundation\\Console\\StorageLinkCommand' => 'Illuminate\\Foundation\\Providers\\ConsoleSupportServiceProvider',
|
||||
'Illuminate\\Foundation\\Console\\UpCommand' => 'Illuminate\\Foundation\\Providers\\ConsoleSupportServiceProvider',
|
||||
'Illuminate\\Foundation\\Console\\ViewCacheCommand' => 'Illuminate\\Foundation\\Providers\\ConsoleSupportServiceProvider',
|
||||
'Illuminate\\Foundation\\Console\\ViewClearCommand' => 'Illuminate\\Foundation\\Providers\\ConsoleSupportServiceProvider',
|
||||
'Illuminate\\Cache\\Console\\CacheTableCommand' => 'Illuminate\\Foundation\\Providers\\ConsoleSupportServiceProvider',
|
||||
'Illuminate\\Foundation\\Console\\CastMakeCommand' => 'Illuminate\\Foundation\\Providers\\ConsoleSupportServiceProvider',
|
||||
'Illuminate\\Foundation\\Console\\ChannelMakeCommand' => 'Illuminate\\Foundation\\Providers\\ConsoleSupportServiceProvider',
|
||||
'Illuminate\\Foundation\\Console\\ComponentMakeCommand' => 'Illuminate\\Foundation\\Providers\\ConsoleSupportServiceProvider',
|
||||
'Illuminate\\Foundation\\Console\\ConsoleMakeCommand' => 'Illuminate\\Foundation\\Providers\\ConsoleSupportServiceProvider',
|
||||
'Illuminate\\Routing\\Console\\ControllerMakeCommand' => 'Illuminate\\Foundation\\Providers\\ConsoleSupportServiceProvider',
|
||||
'Illuminate\\Foundation\\Console\\DocsCommand' => 'Illuminate\\Foundation\\Providers\\ConsoleSupportServiceProvider',
|
||||
'Illuminate\\Foundation\\Console\\EventGenerateCommand' => 'Illuminate\\Foundation\\Providers\\ConsoleSupportServiceProvider',
|
||||
'Illuminate\\Foundation\\Console\\EventMakeCommand' => 'Illuminate\\Foundation\\Providers\\ConsoleSupportServiceProvider',
|
||||
'Illuminate\\Foundation\\Console\\ExceptionMakeCommand' => 'Illuminate\\Foundation\\Providers\\ConsoleSupportServiceProvider',
|
||||
'Illuminate\\Database\\Console\\Factories\\FactoryMakeCommand' => 'Illuminate\\Foundation\\Providers\\ConsoleSupportServiceProvider',
|
||||
'Illuminate\\Foundation\\Console\\JobMakeCommand' => 'Illuminate\\Foundation\\Providers\\ConsoleSupportServiceProvider',
|
||||
'Illuminate\\Foundation\\Console\\ListenerMakeCommand' => 'Illuminate\\Foundation\\Providers\\ConsoleSupportServiceProvider',
|
||||
'Illuminate\\Foundation\\Console\\MailMakeCommand' => 'Illuminate\\Foundation\\Providers\\ConsoleSupportServiceProvider',
|
||||
'Illuminate\\Routing\\Console\\MiddlewareMakeCommand' => 'Illuminate\\Foundation\\Providers\\ConsoleSupportServiceProvider',
|
||||
'Illuminate\\Foundation\\Console\\ModelMakeCommand' => 'Illuminate\\Foundation\\Providers\\ConsoleSupportServiceProvider',
|
||||
'Illuminate\\Foundation\\Console\\NotificationMakeCommand' => 'Illuminate\\Foundation\\Providers\\ConsoleSupportServiceProvider',
|
||||
'Illuminate\\Notifications\\Console\\NotificationTableCommand' => 'Illuminate\\Foundation\\Providers\\ConsoleSupportServiceProvider',
|
||||
'Illuminate\\Foundation\\Console\\ObserverMakeCommand' => 'Illuminate\\Foundation\\Providers\\ConsoleSupportServiceProvider',
|
||||
'Illuminate\\Foundation\\Console\\PolicyMakeCommand' => 'Illuminate\\Foundation\\Providers\\ConsoleSupportServiceProvider',
|
||||
'Illuminate\\Foundation\\Console\\ProviderMakeCommand' => 'Illuminate\\Foundation\\Providers\\ConsoleSupportServiceProvider',
|
||||
'Illuminate\\Queue\\Console\\FailedTableCommand' => 'Illuminate\\Foundation\\Providers\\ConsoleSupportServiceProvider',
|
||||
'Illuminate\\Queue\\Console\\TableCommand' => 'Illuminate\\Foundation\\Providers\\ConsoleSupportServiceProvider',
|
||||
'Illuminate\\Queue\\Console\\BatchesTableCommand' => 'Illuminate\\Foundation\\Providers\\ConsoleSupportServiceProvider',
|
||||
'Illuminate\\Foundation\\Console\\RequestMakeCommand' => 'Illuminate\\Foundation\\Providers\\ConsoleSupportServiceProvider',
|
||||
'Illuminate\\Foundation\\Console\\ResourceMakeCommand' => 'Illuminate\\Foundation\\Providers\\ConsoleSupportServiceProvider',
|
||||
'Illuminate\\Foundation\\Console\\RuleMakeCommand' => 'Illuminate\\Foundation\\Providers\\ConsoleSupportServiceProvider',
|
||||
'Illuminate\\Foundation\\Console\\ScopeMakeCommand' => 'Illuminate\\Foundation\\Providers\\ConsoleSupportServiceProvider',
|
||||
'Illuminate\\Database\\Console\\Seeds\\SeederMakeCommand' => 'Illuminate\\Foundation\\Providers\\ConsoleSupportServiceProvider',
|
||||
'Illuminate\\Session\\Console\\SessionTableCommand' => 'Illuminate\\Foundation\\Providers\\ConsoleSupportServiceProvider',
|
||||
'Illuminate\\Foundation\\Console\\ServeCommand' => 'Illuminate\\Foundation\\Providers\\ConsoleSupportServiceProvider',
|
||||
'Illuminate\\Foundation\\Console\\StubPublishCommand' => 'Illuminate\\Foundation\\Providers\\ConsoleSupportServiceProvider',
|
||||
'Illuminate\\Foundation\\Console\\TestMakeCommand' => 'Illuminate\\Foundation\\Providers\\ConsoleSupportServiceProvider',
|
||||
'Illuminate\\Foundation\\Console\\VendorPublishCommand' => 'Illuminate\\Foundation\\Providers\\ConsoleSupportServiceProvider',
|
||||
'migrator' => 'Illuminate\\Foundation\\Providers\\ConsoleSupportServiceProvider',
|
||||
'migration.repository' => 'Illuminate\\Foundation\\Providers\\ConsoleSupportServiceProvider',
|
||||
'migration.creator' => 'Illuminate\\Foundation\\Providers\\ConsoleSupportServiceProvider',
|
||||
'Illuminate\\Database\\Console\\Migrations\\MigrateCommand' => 'Illuminate\\Foundation\\Providers\\ConsoleSupportServiceProvider',
|
||||
'Illuminate\\Database\\Console\\Migrations\\FreshCommand' => 'Illuminate\\Foundation\\Providers\\ConsoleSupportServiceProvider',
|
||||
'Illuminate\\Database\\Console\\Migrations\\InstallCommand' => 'Illuminate\\Foundation\\Providers\\ConsoleSupportServiceProvider',
|
||||
'Illuminate\\Database\\Console\\Migrations\\RefreshCommand' => 'Illuminate\\Foundation\\Providers\\ConsoleSupportServiceProvider',
|
||||
'Illuminate\\Database\\Console\\Migrations\\ResetCommand' => 'Illuminate\\Foundation\\Providers\\ConsoleSupportServiceProvider',
|
||||
'Illuminate\\Database\\Console\\Migrations\\RollbackCommand' => 'Illuminate\\Foundation\\Providers\\ConsoleSupportServiceProvider',
|
||||
'Illuminate\\Database\\Console\\Migrations\\StatusCommand' => 'Illuminate\\Foundation\\Providers\\ConsoleSupportServiceProvider',
|
||||
'Illuminate\\Database\\Console\\Migrations\\MigrateMakeCommand' => 'Illuminate\\Foundation\\Providers\\ConsoleSupportServiceProvider',
|
||||
'composer' => 'Illuminate\\Foundation\\Providers\\ConsoleSupportServiceProvider',
|
||||
'hash' => 'Illuminate\\Hashing\\HashServiceProvider',
|
||||
'hash.driver' => 'Illuminate\\Hashing\\HashServiceProvider',
|
||||
'mail.manager' => 'Illuminate\\Mail\\MailServiceProvider',
|
||||
'mailer' => 'Illuminate\\Mail\\MailServiceProvider',
|
||||
'Illuminate\\Mail\\Markdown' => 'Illuminate\\Mail\\MailServiceProvider',
|
||||
'Illuminate\\Contracts\\Pipeline\\Hub' => 'Illuminate\\Pipeline\\PipelineServiceProvider',
|
||||
'queue' => 'Illuminate\\Queue\\QueueServiceProvider',
|
||||
'queue.connection' => 'Illuminate\\Queue\\QueueServiceProvider',
|
||||
'queue.failer' => 'Illuminate\\Queue\\QueueServiceProvider',
|
||||
'queue.listener' => 'Illuminate\\Queue\\QueueServiceProvider',
|
||||
'queue.worker' => 'Illuminate\\Queue\\QueueServiceProvider',
|
||||
'redis' => 'Illuminate\\Redis\\RedisServiceProvider',
|
||||
'redis.connection' => 'Illuminate\\Redis\\RedisServiceProvider',
|
||||
'auth.password' => 'Illuminate\\Auth\\Passwords\\PasswordResetServiceProvider',
|
||||
'auth.password.broker' => 'Illuminate\\Auth\\Passwords\\PasswordResetServiceProvider',
|
||||
'translator' => 'Illuminate\\Translation\\TranslationServiceProvider',
|
||||
'translation.loader' => 'Illuminate\\Translation\\TranslationServiceProvider',
|
||||
'validator' => 'Illuminate\\Validation\\ValidationServiceProvider',
|
||||
'validation.presence' => 'Illuminate\\Validation\\ValidationServiceProvider',
|
||||
'command.tinker' => 'Laravel\\Tinker\\TinkerServiceProvider',
|
||||
),
|
||||
'when' =>
|
||||
array (
|
||||
'Illuminate\\Broadcasting\\BroadcastServiceProvider' =>
|
||||
array (
|
||||
),
|
||||
'Illuminate\\Bus\\BusServiceProvider' =>
|
||||
array (
|
||||
),
|
||||
'Illuminate\\Cache\\CacheServiceProvider' =>
|
||||
array (
|
||||
),
|
||||
'Illuminate\\Foundation\\Providers\\ConsoleSupportServiceProvider' =>
|
||||
array (
|
||||
),
|
||||
'Illuminate\\Hashing\\HashServiceProvider' =>
|
||||
array (
|
||||
),
|
||||
'Illuminate\\Mail\\MailServiceProvider' =>
|
||||
array (
|
||||
),
|
||||
'Illuminate\\Pipeline\\PipelineServiceProvider' =>
|
||||
array (
|
||||
),
|
||||
'Illuminate\\Queue\\QueueServiceProvider' =>
|
||||
array (
|
||||
),
|
||||
'Illuminate\\Redis\\RedisServiceProvider' =>
|
||||
array (
|
||||
),
|
||||
'Illuminate\\Auth\\Passwords\\PasswordResetServiceProvider' =>
|
||||
array (
|
||||
),
|
||||
'Illuminate\\Translation\\TranslationServiceProvider' =>
|
||||
array (
|
||||
),
|
||||
'Illuminate\\Validation\\ValidationServiceProvider' =>
|
||||
array (
|
||||
),
|
||||
'Laravel\\Tinker\\TinkerServiceProvider' =>
|
||||
array (
|
||||
),
|
||||
),
|
||||
);
|
145
catch/config/catch.php
Normal file
145
catch/config/catch.php
Normal file
@ -0,0 +1,145 @@
|
||||
<?php
|
||||
|
||||
// +----------------------------------------------------------------------
|
||||
// | CatchAdmin
|
||||
// +----------------------------------------------------------------------
|
||||
// | Copyright (c) 2017~2021 https://catchadmin.com All rights reserved.
|
||||
// +----------------------------------------------------------------------
|
||||
// | Licensed ( https://github.com/JaguarJack/catchadmin/blob/master/LICENSE.md )
|
||||
// +----------------------------------------------------------------------
|
||||
// | Author: JaguarJack [ njphper@gmail.com ]
|
||||
// +----------------------------------------------------------------------
|
||||
|
||||
return [
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| catch-admin default middleware
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| where you can set default middlewares
|
||||
|
|
||||
*/
|
||||
'middleware_group' => [
|
||||
|
||||
],
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| catch-admin catch_auth_middleware_alias
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| where you can set default middlewares
|
||||
|
|
||||
*/
|
||||
'catch_auth_middleware_alias' => [
|
||||
|
||||
],
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| catch-admin super admin id
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| where you can set super admin id
|
||||
|
|
||||
*/
|
||||
'super_admin' => 1,
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| catch-admin module setting
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| the root where module generate
|
||||
| the namespace is module root namespace
|
||||
| the default dirs is module generate default dirs
|
||||
*/
|
||||
'module' => [
|
||||
'root' => 'modules',
|
||||
|
||||
'namespace' => 'Modules',
|
||||
|
||||
'default' => ['develop', 'user', 'permission'],
|
||||
|
||||
'default_dirs' => [
|
||||
'Http'.DIRECTORY_SEPARATOR,
|
||||
|
||||
'Http'.DIRECTORY_SEPARATOR.'Requests'.DIRECTORY_SEPARATOR,
|
||||
|
||||
'Http'.DIRECTORY_SEPARATOR.'Controllers'.DIRECTORY_SEPARATOR,
|
||||
|
||||
'Models'.DIRECTORY_SEPARATOR,
|
||||
|
||||
'views'.DIRECTORY_SEPARATOR,
|
||||
],
|
||||
|
||||
// storage module information
|
||||
// which driver should be used?
|
||||
'driver' => [
|
||||
// currently, catchadmin support file and database
|
||||
// the default is driver
|
||||
'default' => 'file',
|
||||
|
||||
// use database driver
|
||||
'table_name' => 'admin_modules'
|
||||
]
|
||||
],
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| catch-admin response
|
||||
|--------------------------------------------------------------------------
|
||||
*/
|
||||
'response' => [
|
||||
// it's a controller middleware, it's set in CatchController
|
||||
// if you not need json response, don't extend CatchController
|
||||
'always_json' => \Catch\Middleware\JsonResponseMiddleware::class,
|
||||
|
||||
// response listener
|
||||
// it listens [RequestHandled] event, if you don't need this
|
||||
// you can change this config
|
||||
'request_handled_listener' => \Catch\Listeners\RequestHandledListener::class
|
||||
],
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| catch-admin auth setting
|
||||
|--------------------------------------------------------------------------
|
||||
*/
|
||||
'auth' => [
|
||||
'guards' => [
|
||||
'admin' => [
|
||||
'driver' => 'jwt',
|
||||
'provider' => 'admin_users',
|
||||
],
|
||||
],
|
||||
|
||||
'providers' => [
|
||||
'admin_users' => [
|
||||
'driver' => 'eloquent',
|
||||
'model' => \Modules\User\Models\Users::class
|
||||
]
|
||||
]
|
||||
],
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| database sql log
|
||||
|--------------------------------------------------------------------------
|
||||
*/
|
||||
'listen_db_log' => true,
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| route config
|
||||
|--------------------------------------------------------------------------
|
||||
*/
|
||||
'route' => [
|
||||
'prefix' => 'api',
|
||||
|
||||
'middlewares' => [
|
||||
\Catch\Middleware\AuthMiddleware::class,
|
||||
\Catch\Middleware\JsonResponseMiddleware::class
|
||||
]
|
||||
],
|
||||
];
|
47
catch/database/migrations/2022_11_14_034127_module.php
Normal file
47
catch/database/migrations/2022_11_14_034127_module.php
Normal file
@ -0,0 +1,47 @@
|
||||
<?php
|
||||
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
return new class () extends Migration {
|
||||
/**
|
||||
* Run the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function up()
|
||||
{
|
||||
//
|
||||
Schema::create(config('catch.module.table_name'), function (Blueprint $table) {
|
||||
$table->increments('id');
|
||||
|
||||
$table->string('name')->comment('模块名称');
|
||||
|
||||
$table->string('path', 20)->comment('模块目录');
|
||||
|
||||
$table->string('description')->comment('模块描述');
|
||||
|
||||
$table->string('keywords')->comment('模块关键字');
|
||||
|
||||
$table->string('version', 20)->comment('模块版本号')->default('1.0.0');
|
||||
|
||||
$table->boolean('status')->comment('模块状态')->default(1);
|
||||
|
||||
$table->unsignedInteger('created_at')->comment('创建时间')->default(0);
|
||||
|
||||
$table->unsignedInteger('updated_at')->comment('更新时间')->default(0);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function down()
|
||||
{
|
||||
//
|
||||
Schema::dropIfExists(config('catch.module.table_name'));
|
||||
}
|
||||
};
|
34
catch/src/Base/CatchController.php
Normal file
34
catch/src/Base/CatchController.php
Normal file
@ -0,0 +1,34 @@
|
||||
<?php
|
||||
|
||||
// +----------------------------------------------------------------------
|
||||
// | CatchAdmin [Just Like ~ ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | Copyright (c) 2017~2021 https://catchadmin.com All rights reserved.
|
||||
// +----------------------------------------------------------------------
|
||||
// | Licensed ( https://github.com/JaguarJack/catchadmin/blob/master/LICENSE.md )
|
||||
// +----------------------------------------------------------------------
|
||||
// | Author: JaguarJack [ njphper@gmail.com ]
|
||||
// +----------------------------------------------------------------------
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Catch\Base;
|
||||
|
||||
use Illuminate\Contracts\Auth\Authenticatable;
|
||||
use Illuminate\Routing\Controller;
|
||||
use Illuminate\Support\Facades\Auth;
|
||||
|
||||
/**
|
||||
* base catch controller
|
||||
*/
|
||||
abstract class CatchController extends Controller
|
||||
{
|
||||
/**
|
||||
* @param $guard
|
||||
* @return Authenticatable
|
||||
*/
|
||||
protected function getLoginUser($guard = null): Authenticatable
|
||||
{
|
||||
return Auth::guard($guard ?: getGuardName())->user();
|
||||
}
|
||||
}
|
89
catch/src/Base/CatchModel.php
Normal file
89
catch/src/Base/CatchModel.php
Normal file
@ -0,0 +1,89 @@
|
||||
<?php
|
||||
|
||||
// +----------------------------------------------------------------------
|
||||
// | CatchAdmin [Just Like ~ ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | Copyright (c) 2017~2021 https://catchadmin.com All rights reserved.
|
||||
// +----------------------------------------------------------------------
|
||||
// | Licensed ( https://github.com/JaguarJack/catchadmin-laravel/blob/master/LICENSE.md )
|
||||
// +----------------------------------------------------------------------
|
||||
// | Author: JaguarJack [ njphper@gmail.com ]
|
||||
// +----------------------------------------------------------------------
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Catch\Base;
|
||||
|
||||
use Catch\Support\DB\SoftDelete;
|
||||
use Catch\Traits\DB\BaseOperate;
|
||||
use Catch\Traits\DB\ScopeTrait;
|
||||
use Catch\Traits\DB\Trans;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Database\Eloquent\SoftDeletes;
|
||||
use Illuminate\Database\Query\Builder;
|
||||
|
||||
/**
|
||||
*
|
||||
* @mixin Builder
|
||||
* @mixin \Illuminate\Database\Eloquent\Builder
|
||||
*/
|
||||
abstract class CatchModel extends Model
|
||||
{
|
||||
use BaseOperate, Trans, SoftDeletes, ScopeTrait;
|
||||
|
||||
|
||||
/**
|
||||
* unix timestamp
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $dateFormat = 'U';
|
||||
|
||||
/**
|
||||
* paginate limit
|
||||
*/
|
||||
protected $perPage = 10;
|
||||
|
||||
/**
|
||||
* @var string[]
|
||||
*/
|
||||
protected $hidden = ['deleted_at'];
|
||||
|
||||
/**
|
||||
* @var string[]
|
||||
*/
|
||||
protected $casts = [
|
||||
'created_at' => 'datetime:Y-m-d H:i:s',
|
||||
|
||||
'updated_at' => 'datetime:Y-m-d H:i:s',
|
||||
|
||||
'deleted_at' => 'datetime:Y-m-d H:i:s'
|
||||
];
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
protected array $fieldsInList = ['*'];
|
||||
|
||||
/**
|
||||
* @var bool
|
||||
*/
|
||||
protected bool $isPaginate = true;
|
||||
|
||||
/**
|
||||
* @var array $searchable
|
||||
*/
|
||||
public array $searchable = [];
|
||||
|
||||
|
||||
/**
|
||||
* soft delete
|
||||
*
|
||||
* @time 2021年08月09日
|
||||
* @return void
|
||||
*/
|
||||
public static function bootSoftDeletes(): void
|
||||
{
|
||||
static::addGlobalScope(new SoftDelete());
|
||||
}
|
||||
}
|
363
catch/src/CatchAdmin.php
Normal file
363
catch/src/CatchAdmin.php
Normal file
@ -0,0 +1,363 @@
|
||||
<?php
|
||||
|
||||
// +----------------------------------------------------------------------
|
||||
// | CatchAdmin [Just Like ~ ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | Copyright (c) 2017 ~ now https://catchadmin.com All rights reserved.
|
||||
// +----------------------------------------------------------------------
|
||||
// | Licensed ( https://github.com/JaguarJack/catchadmin/blob/master/LICENSE.md )
|
||||
// +----------------------------------------------------------------------
|
||||
// | Author: JaguarJack [ njphper@gmail.com ]
|
||||
// +----------------------------------------------------------------------
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Catch;
|
||||
|
||||
use Illuminate\Support\Facades\File;
|
||||
use Illuminate\Support\Str;
|
||||
|
||||
class CatchAdmin
|
||||
{
|
||||
public const VERSION = '0.1.0';
|
||||
|
||||
/**
|
||||
* version
|
||||
*
|
||||
*/
|
||||
public static function version(): string
|
||||
{
|
||||
return static::VERSION;
|
||||
}
|
||||
|
||||
/**
|
||||
* module root path
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public static function moduleRootPath(): string
|
||||
{
|
||||
return self::makeDir(base_path(config('catch.module.root')).DIRECTORY_SEPARATOR);
|
||||
}
|
||||
|
||||
/**
|
||||
* make dir
|
||||
*
|
||||
* @param string $dir
|
||||
* @return string
|
||||
*/
|
||||
public static function makeDir(string $dir): string
|
||||
{
|
||||
if (! File::isDirectory($dir) && ! File::makeDirectory($dir, 0777, true)) {
|
||||
throw new \RuntimeException(sprintf('Directory %s created Failed', $dir));
|
||||
}
|
||||
|
||||
return $dir;
|
||||
}
|
||||
|
||||
/**
|
||||
* module dir
|
||||
*
|
||||
* @param string $module
|
||||
* @param bool $make
|
||||
* @return string
|
||||
*/
|
||||
public static function getModulePath(string $module, bool $make = true): string
|
||||
{
|
||||
if ($make) {
|
||||
return self::makeDir(self::moduleRootPath().ucfirst($module).DIRECTORY_SEPARATOR);
|
||||
}
|
||||
|
||||
return self::moduleRootPath().ucfirst($module).DIRECTORY_SEPARATOR;
|
||||
}
|
||||
|
||||
/**
|
||||
* delete module path
|
||||
*
|
||||
* @param string $module
|
||||
* @return bool
|
||||
*/
|
||||
public static function deleteModulePath(string $module): bool
|
||||
{
|
||||
if (self::isModulePathExist($module)) {
|
||||
File::deleteDirectory(self::getModulePath($module));
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* module path exists
|
||||
*
|
||||
* @param string $module
|
||||
* @return bool
|
||||
*/
|
||||
public static function isModulePathExist(string $module): bool
|
||||
{
|
||||
return File::isDirectory(self::moduleRootPath().ucfirst($module).DIRECTORY_SEPARATOR);
|
||||
}
|
||||
|
||||
/**
|
||||
* module migration dir
|
||||
*
|
||||
* @param string $module
|
||||
* @return string
|
||||
*/
|
||||
public static function getModuleMigrationPath(string $module): string
|
||||
{
|
||||
return self::makeDir(self::getModulePath($module).'database'.DIRECTORY_SEPARATOR.'migrations'.DIRECTORY_SEPARATOR);
|
||||
}
|
||||
|
||||
/**
|
||||
* module seeder dir
|
||||
*
|
||||
* @param string $module
|
||||
* @return string
|
||||
*/
|
||||
public static function getModuleSeederPath(string $module): string
|
||||
{
|
||||
return self::makeDir(self::getModulePath($module).'database'.DIRECTORY_SEPARATOR.'seeder'.DIRECTORY_SEPARATOR);
|
||||
}
|
||||
|
||||
/**
|
||||
* get modules dir
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public static function getModulesPath(): array
|
||||
{
|
||||
return File::directories(self::moduleRootPath());
|
||||
}
|
||||
|
||||
/**
|
||||
* get module root namespace
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public static function getModuleRootNamespace(): string
|
||||
{
|
||||
return config('catch.module.namespace').'\\';
|
||||
}
|
||||
|
||||
/**
|
||||
* get module root namespace
|
||||
*
|
||||
* @param $moduleName
|
||||
* @return string
|
||||
*/
|
||||
public static function getModuleNamespace($moduleName): string
|
||||
{
|
||||
return self::getModuleRootNamespace().ucfirst($moduleName).'\\';
|
||||
}
|
||||
|
||||
/**
|
||||
* model namespace
|
||||
*
|
||||
* @param $moduleName
|
||||
* @return string
|
||||
*/
|
||||
public static function getModuleModelNamespace($moduleName): string
|
||||
{
|
||||
return self::getModuleNamespace($moduleName).'Models\\';
|
||||
}
|
||||
|
||||
/**
|
||||
* getServiceProviders
|
||||
*
|
||||
* @param $moduleName
|
||||
* @return string
|
||||
*/
|
||||
public static function getModuleServiceProviderNamespace($moduleName): string
|
||||
{
|
||||
return self::getModuleNamespace($moduleName).'Providers\\';
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param $moduleName
|
||||
* @return string
|
||||
*/
|
||||
public static function getModuleServiceProvider($moduleName): string
|
||||
{
|
||||
return self::getModuleServiceProviderNamespace($moduleName).ucfirst($moduleName).'ServiceProvider';
|
||||
}
|
||||
|
||||
/**
|
||||
* controller namespace
|
||||
*
|
||||
* @param $moduleName
|
||||
* @return string
|
||||
*/
|
||||
public static function getModuleControllerNamespace($moduleName): string
|
||||
{
|
||||
return self::getModuleNamespace($moduleName).'Http\\Controllers\\';
|
||||
}
|
||||
|
||||
/**
|
||||
* getModuleRequestNamespace
|
||||
*
|
||||
* @param $moduleName
|
||||
* @return string
|
||||
*/
|
||||
public static function getModuleRequestNamespace($moduleName): string
|
||||
{
|
||||
return self::getModuleNamespace($moduleName).'Http\\Requests\\';
|
||||
}
|
||||
|
||||
/**
|
||||
* getModuleRequestNamespace
|
||||
*
|
||||
* @param $moduleName
|
||||
* @return string
|
||||
*/
|
||||
public static function getModuleEventsNamespace($moduleName): string
|
||||
{
|
||||
return self::getModuleNamespace($moduleName).'Events\\';
|
||||
}
|
||||
|
||||
/**
|
||||
* getModuleRequestNamespace
|
||||
*
|
||||
* @param $moduleName
|
||||
* @return string
|
||||
*/
|
||||
public static function getModuleListenersNamespace($moduleName): string
|
||||
{
|
||||
return self::getModuleNamespace($moduleName).'Listeners\\';
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* module provider dir
|
||||
*
|
||||
* @param string $module
|
||||
* @return string
|
||||
*/
|
||||
public static function getModuleProviderPath(string $module): string
|
||||
{
|
||||
return self::makeDir(self::getModulePath($module).'Providers'.DIRECTORY_SEPARATOR);
|
||||
}
|
||||
|
||||
/**
|
||||
* module model dir
|
||||
*
|
||||
* @param string $module
|
||||
* @return string
|
||||
*/
|
||||
public static function getModuleModelPath(string $module): string
|
||||
{
|
||||
return self::makeDir(self::getModulePath($module).'Models'.DIRECTORY_SEPARATOR);
|
||||
}
|
||||
|
||||
/**
|
||||
* module controller dir
|
||||
*
|
||||
* @param string $module
|
||||
* @return string
|
||||
*/
|
||||
public static function getModuleControllerPath(string $module): string
|
||||
{
|
||||
return self::makeDir(self::getModulePath($module).'Http'.DIRECTORY_SEPARATOR.'Controllers'.DIRECTORY_SEPARATOR);
|
||||
}
|
||||
|
||||
/**
|
||||
* module request dir
|
||||
*
|
||||
* @param string $module
|
||||
* @return string
|
||||
*/
|
||||
public static function getModuleRequestPath(string $module): string
|
||||
{
|
||||
return self::makeDir(self::getModulePath($module).'Http'.DIRECTORY_SEPARATOR.'Requests'.DIRECTORY_SEPARATOR);
|
||||
}
|
||||
|
||||
/**
|
||||
* module request dir
|
||||
*
|
||||
* @param string $module
|
||||
* @return string
|
||||
*/
|
||||
public static function getModuleEventPath(string $module): string
|
||||
{
|
||||
return self::makeDir(self::getModulePath($module).'Events'.DIRECTORY_SEPARATOR);
|
||||
}
|
||||
|
||||
/**
|
||||
* module request dir
|
||||
*
|
||||
* @param string $module
|
||||
* @return string
|
||||
*/
|
||||
public static function getModuleListenersPath(string $module): string
|
||||
{
|
||||
return self::makeDir(self::getModulePath($module).'Listeners'.DIRECTORY_SEPARATOR);
|
||||
}
|
||||
|
||||
/**
|
||||
* commands path
|
||||
*
|
||||
* @param string $module
|
||||
* @return string
|
||||
*/
|
||||
public static function getCommandsPath(string $module): string
|
||||
{
|
||||
return self::makeDir(self::getModulePath($module).'Commands'.DIRECTORY_SEPARATOR);
|
||||
}
|
||||
|
||||
/**
|
||||
* commands namespace
|
||||
*
|
||||
* @param string $module
|
||||
* @return string
|
||||
*/
|
||||
public static function getCommandsNamespace(string $module): string
|
||||
{
|
||||
return self::getModuleNamespace($module).'Commands\\';
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* module route
|
||||
*
|
||||
* @param string $module
|
||||
* @param string $routeName
|
||||
* @return string
|
||||
*/
|
||||
public static function getModuleRoutePath(string $module, string $routeName = 'route.php'): string
|
||||
{
|
||||
return self::getModulePath($module).$routeName;
|
||||
}
|
||||
|
||||
/**
|
||||
* module route.php exists
|
||||
*
|
||||
* @param string $module
|
||||
* @return bool
|
||||
*/
|
||||
public static function isModuleRouteExists(string $module): bool
|
||||
{
|
||||
return File::exists(self::getModuleRoutePath($module));
|
||||
}
|
||||
|
||||
/**
|
||||
* module views path
|
||||
*
|
||||
* @param string $module
|
||||
* @return string
|
||||
*/
|
||||
public static function getModuleViewsPath(string $module): string
|
||||
{
|
||||
return self::makeDir(self::getModulePath($module).'views'.DIRECTORY_SEPARATOR);
|
||||
}
|
||||
|
||||
/**
|
||||
* relative path
|
||||
*
|
||||
* @param $path
|
||||
* @return string
|
||||
*/
|
||||
public static function getModuleRelativePath($path): string
|
||||
{
|
||||
return Str::replaceFirst(base_path(), '.', $path);
|
||||
}
|
||||
}
|
141
catch/src/Commands/CatchCommand.php
Normal file
141
catch/src/Commands/CatchCommand.php
Normal file
@ -0,0 +1,141 @@
|
||||
<?php
|
||||
|
||||
// +----------------------------------------------------------------------
|
||||
// | CatchAdmin [Just Like ~ ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | Copyright (c) 2017 ~ now https://catchadmin.com All rights reserved.
|
||||
// +----------------------------------------------------------------------
|
||||
// | Licensed ( https://github.com/JaguarJack/catchadmin/blob/master/LICENSE.md )
|
||||
// +----------------------------------------------------------------------
|
||||
// | Author: JaguarJack [ njphper@gmail.com ]
|
||||
// +----------------------------------------------------------------------
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Catch\Commands;
|
||||
|
||||
use Illuminate\Console\Command;
|
||||
use Illuminate\Support\Collection;
|
||||
use Symfony\Component\Console\Input\InputInterface;
|
||||
use Symfony\Component\Console\Output\OutputInterface;
|
||||
use Catch\Facade\Module;
|
||||
|
||||
use function Termwind\ask;
|
||||
use function Termwind\render;
|
||||
|
||||
abstract class CatchCommand extends Command
|
||||
{
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $name;
|
||||
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct();
|
||||
|
||||
if (! property_exists($this, 'signature')
|
||||
&& property_exists($this, 'name')
|
||||
&& $this->name
|
||||
) {
|
||||
$this->signature = $this->name.' {module}';
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param InputInterface $input
|
||||
* @param OutputInterface $output
|
||||
* @return void
|
||||
*/
|
||||
protected function initialize(InputInterface $input, OutputInterface $output): void
|
||||
{
|
||||
if ($input->hasArgument('module')
|
||||
&& ! Module::all()->pluck('name')->merge(Collection::make(config('catch.module.default')))->contains(lcfirst($input->getArgument('module')))
|
||||
) {
|
||||
$this->error(sprintf('Module [%s] Not Found', $input->getArgument('module')));
|
||||
exit;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
* @param string $question
|
||||
* @param null $default
|
||||
* @param bool $isChoice
|
||||
* @return string|int|null
|
||||
*/
|
||||
public function askFor(string $question, $default = null, bool $isChoice = false): string|null|int
|
||||
{
|
||||
$_default = $default ? "<em class='pl-1 text-rose-600'>[$default]</em>" : '';
|
||||
|
||||
$choice = $isChoice ? '<em class="bg-indigo-600 w-5 pl-1 ml-1 mr-1">Yes</em>OR<em class="bg-rose-600 w-4 pl-1 ml-1">No</em>' : '';
|
||||
|
||||
$answer = ask(
|
||||
<<<HTML
|
||||
<div>
|
||||
<div class="px-1 bg-indigo-700">CatchAdmin</div>
|
||||
<em class="ml-1">
|
||||
<em class="text-green-700">$question</em>
|
||||
$_default
|
||||
$choice
|
||||
<em class="ml-1">:</em><em class="ml-1"></em>
|
||||
</em>
|
||||
</div>
|
||||
HTML
|
||||
);
|
||||
|
||||
|
||||
$this->newLine();
|
||||
|
||||
if ($default && ! $answer) {
|
||||
return $default;
|
||||
}
|
||||
|
||||
return $answer;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* info
|
||||
*
|
||||
* @param $string
|
||||
* @param null $verbosity
|
||||
* @return void
|
||||
*/
|
||||
public function info($string, $verbosity = null): void
|
||||
{
|
||||
render(
|
||||
<<<HTML
|
||||
<div>
|
||||
<div class="px-1 bg-indigo-700">CatchAdmin</div>
|
||||
<em class="ml-1">
|
||||
<em class="text-green-700">$string</em>
|
||||
</em>
|
||||
</div>
|
||||
HTML
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* error
|
||||
*
|
||||
* @param $string
|
||||
* @param null $verbosity
|
||||
* @return void
|
||||
*/
|
||||
public function error($string, $verbosity = null): void
|
||||
{
|
||||
render(
|
||||
<<<HTML
|
||||
<div>
|
||||
<div class="px-1 bg-indigo-700">CatchAdmin</div>
|
||||
<em class="ml-1">
|
||||
<em class="text-rose-700">$string</em>
|
||||
</em>
|
||||
</div>
|
||||
HTML
|
||||
);
|
||||
}
|
||||
}
|
100
catch/src/Commands/Create/Controller.php
Normal file
100
catch/src/Commands/Create/Controller.php
Normal file
@ -0,0 +1,100 @@
|
||||
<?php
|
||||
|
||||
// +----------------------------------------------------------------------
|
||||
// | CatchAdmin [Just Like ~ ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | Copyright (c) 2017~2021 https://catchadmin.com All rights reserved.
|
||||
// +----------------------------------------------------------------------
|
||||
// | Licensed ( https://github.com/JaguarJack/catchadmin-laravel/blob/master/LICENSE.md )
|
||||
// +----------------------------------------------------------------------
|
||||
// | Author: JaguarJack [ njphper@gmail.com ]
|
||||
// +----------------------------------------------------------------------
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Catch\Commands\Create;
|
||||
|
||||
use Catch\CatchAdmin;
|
||||
use Catch\Commands\CatchCommand;
|
||||
use Illuminate\Support\Facades\File;
|
||||
use Illuminate\Support\Str;
|
||||
|
||||
;
|
||||
|
||||
class Controller extends CatchCommand
|
||||
{
|
||||
/**
|
||||
* The name and signature of the console command.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $signature = 'catch:make:controller {module} {name}';
|
||||
|
||||
/**
|
||||
* The console command description.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $description = 'create catch controller';
|
||||
|
||||
|
||||
public function handle()
|
||||
{
|
||||
$controllerPath = CatchAdmin::getModuleControllerPath($this->argument('module'));
|
||||
|
||||
$file = $controllerPath.$this->getControllerFile();
|
||||
|
||||
if (File::exists($file)) {
|
||||
$answer = $this->ask($file.' already exists, Did you want replace it?', 'Y');
|
||||
|
||||
if (! Str::of($answer)->lower()->exactly('y')) {
|
||||
exit;
|
||||
}
|
||||
}
|
||||
|
||||
File::put($file, Str::of($this->getStubContent())->replace([
|
||||
'{namespace}', '{controller}'
|
||||
], [trim(CatchAdmin::getModuleControllerNamespace($this->argument('module')), '\\'), $this->getControllerName()])->toString());
|
||||
|
||||
if (File::exists($file)) {
|
||||
$this->info($file.' has been created');
|
||||
} else {
|
||||
$this->error($file.' create failed');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
protected function getControllerFile(): string
|
||||
{
|
||||
return $this->getControllerName().'.php';
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
protected function getControllerName(): string
|
||||
{
|
||||
return Str::of($this->argument('name'))
|
||||
->whenContains('Controller', function ($str) {
|
||||
return $str;
|
||||
}, function ($str) {
|
||||
return $str->append('Controller');
|
||||
})->ucfirst()->toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* get stub content
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
protected function getStubContent(): string
|
||||
{
|
||||
return File::get(dirname(__DIR__).DIRECTORY_SEPARATOR.'stubs'.DIRECTORY_SEPARATOR.'controller.stub');
|
||||
}
|
||||
}
|
100
catch/src/Commands/Create/Event.php
Normal file
100
catch/src/Commands/Create/Event.php
Normal file
@ -0,0 +1,100 @@
|
||||
<?php
|
||||
|
||||
// +----------------------------------------------------------------------
|
||||
// | CatchAdmin [Just Like ~ ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | Copyright (c) 2017~2021 https://catchadmin.com All rights reserved.
|
||||
// +----------------------------------------------------------------------
|
||||
// | Licensed ( https://github.com/JaguarJack/catchadmin-laravel/blob/master/LICENSE.md )
|
||||
// +----------------------------------------------------------------------
|
||||
// | Author: JaguarJack [ njphper@gmail.com ]
|
||||
// +----------------------------------------------------------------------
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Catch\Commands\Create;
|
||||
|
||||
use Catch\CatchAdmin;
|
||||
use Catch\Commands\CatchCommand;
|
||||
use Illuminate\Support\Facades\File;
|
||||
use Illuminate\Support\Str;
|
||||
|
||||
;
|
||||
|
||||
class Event extends CatchCommand
|
||||
{
|
||||
/**
|
||||
* The name and signature of the console command.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $signature = 'catch:make:event {module} {name}';
|
||||
|
||||
/**
|
||||
* The console command description.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $description = 'create catch module event';
|
||||
|
||||
|
||||
public function handle()
|
||||
{
|
||||
$eventPath = CatchAdmin::getModuleEventPath($this->argument('module'));
|
||||
|
||||
$file = $eventPath.$this->getEventFile();
|
||||
|
||||
if (File::exists($file)) {
|
||||
$answer = $this->ask($file.' already exists, Did you want replace it?', 'Y');
|
||||
|
||||
if (! Str::of($answer)->lower()->exactly('y')) {
|
||||
exit;
|
||||
}
|
||||
}
|
||||
|
||||
File::put($file, Str::of($this->getStubContent())->replace([
|
||||
'{namespace}', '{event}'
|
||||
], [trim(CatchAdmin::getModuleEventsNamespace($this->argument('module')), '\\'), $this->getEventName()])->toString());
|
||||
|
||||
if (File::exists($file)) {
|
||||
$this->info($file.' has been created');
|
||||
} else {
|
||||
$this->error($file.' create failed');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
protected function getEventFile(): string
|
||||
{
|
||||
return $this->getEventName().'.php';
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
protected function getEventName(): string
|
||||
{
|
||||
return Str::of($this->argument('name'))
|
||||
->whenContains('Event', function ($str) {
|
||||
return $str;
|
||||
}, function ($str) {
|
||||
return $str->append('Event');
|
||||
})->ucfirst()->toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* get stub content
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
protected function getStubContent(): string
|
||||
{
|
||||
return File::get(dirname(__DIR__).DIRECTORY_SEPARATOR.'stubs'.DIRECTORY_SEPARATOR.'event.stub');
|
||||
}
|
||||
}
|
103
catch/src/Commands/Create/Listener.php
Normal file
103
catch/src/Commands/Create/Listener.php
Normal file
@ -0,0 +1,103 @@
|
||||
<?php
|
||||
|
||||
// +----------------------------------------------------------------------
|
||||
// | CatchAdmin [Just Like ~ ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | Copyright (c) 2017~2021 https://catchadmin.com All rights reserved.
|
||||
// +----------------------------------------------------------------------
|
||||
// | Licensed ( https://github.com/JaguarJack/catchadmin-laravel/blob/master/LICENSE.md )
|
||||
// +----------------------------------------------------------------------
|
||||
// | Author: JaguarJack [ njphper@gmail.com ]
|
||||
// +----------------------------------------------------------------------
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Catch\Commands\Create;
|
||||
|
||||
use Catch\CatchAdmin;
|
||||
use Catch\Commands\CatchCommand;
|
||||
use Illuminate\Support\Facades\File;
|
||||
use Illuminate\Support\Str;
|
||||
|
||||
;
|
||||
|
||||
class Listener extends CatchCommand
|
||||
{
|
||||
/**
|
||||
* The name and signature of the console command.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $signature = 'catch:make:listener {module} {name}';
|
||||
|
||||
/**
|
||||
* The console command description.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $description = 'create catch module event';
|
||||
|
||||
|
||||
public function handle()
|
||||
{
|
||||
$eventPath = CatchAdmin::getModuleListenersPath($this->argument('module'));
|
||||
|
||||
$file = $eventPath.$this->getListenerFile();
|
||||
|
||||
if (File::exists($file)) {
|
||||
$answer = $this->ask($file.' already exists, Did you want replace it?', 'Y');
|
||||
|
||||
if (! Str::of($answer)->lower()->exactly('y')) {
|
||||
exit;
|
||||
}
|
||||
}
|
||||
|
||||
File::put($file, Str::of($this->getStubContent())->replace([
|
||||
'{namespace}', '{listener}'
|
||||
], [
|
||||
trim(CatchAdmin::getModuleListenersNamespace($this->argument('module')), '\\'),
|
||||
|
||||
$this->getListenerName()])->toString());
|
||||
|
||||
if (File::exists($file)) {
|
||||
$this->info($file.' has been created');
|
||||
} else {
|
||||
$this->error($file.' create failed');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
protected function getListenerFile(): string
|
||||
{
|
||||
return $this->getListenerName().'.php';
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
protected function getListenerName(): string
|
||||
{
|
||||
return Str::of($this->argument('name'))
|
||||
->whenContains('Listener', function ($str) {
|
||||
return $str;
|
||||
}, function ($str) {
|
||||
return $str->append('Listener');
|
||||
})->ucfirst()->toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* get stub content
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
protected function getStubContent(): string
|
||||
{
|
||||
return File::get(dirname(__DIR__).DIRECTORY_SEPARATOR.'stubs'.DIRECTORY_SEPARATOR.'listener.stub');
|
||||
}
|
||||
}
|
174
catch/src/Commands/Create/Model.php
Normal file
174
catch/src/Commands/Create/Model.php
Normal file
@ -0,0 +1,174 @@
|
||||
<?php
|
||||
|
||||
// +----------------------------------------------------------------------
|
||||
// | CatchAdmin [Just Like ~ ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | Copyright (c) 2017~2021 https://catchadmin.com All rights reserved.
|
||||
// +----------------------------------------------------------------------
|
||||
// | Licensed ( https://github.com/JaguarJack/catchadmin-laravel/blob/master/LICENSE.md )
|
||||
// +----------------------------------------------------------------------
|
||||
// | Author: JaguarJack [ njphper@gmail.com ]
|
||||
// +----------------------------------------------------------------------
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Catch\Commands\Create;
|
||||
|
||||
use Catch\CatchAdmin;
|
||||
use Catch\Commands\CatchCommand;
|
||||
use Illuminate\Support\Facades\File;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
use Illuminate\Support\Str;
|
||||
|
||||
class Model extends CatchCommand
|
||||
{
|
||||
/**
|
||||
* The name and signature of the console command.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $signature = 'catch:make:model {module} {model} {--t= : the model of table name}';
|
||||
|
||||
/**
|
||||
* The console command description.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $description = 'create catch module';
|
||||
|
||||
/**
|
||||
* Create a new command instance.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct();
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute the console command.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function handle()
|
||||
{
|
||||
if (! Schema::hasTable($this->getTableName())) {
|
||||
$this->error('Schema ['.$this->getTableName().'] not found');
|
||||
exit;
|
||||
}
|
||||
|
||||
$modelPath = CatchAdmin::getModuleModelPath($this->argument('module'));
|
||||
|
||||
$file = $modelPath.$this->getModelFile();
|
||||
|
||||
if (File::exists($file)) {
|
||||
$answer = $this->ask($file.' already exists, Did you want replace it?', 'Y');
|
||||
|
||||
if (! Str::of($answer)->lower()->exactly('y')) {
|
||||
exit;
|
||||
}
|
||||
}
|
||||
|
||||
File::put($file, $this->getModelContent());
|
||||
|
||||
if (File::exists($file)) {
|
||||
$this->info($file.' has been created');
|
||||
} else {
|
||||
$this->error($file.' create failed');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
protected function getModelFile(): string
|
||||
{
|
||||
return $this->getModelName().'.php';
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
protected function getModelName(): string
|
||||
{
|
||||
return Str::of($this->argument('model'))->ucfirst()->toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* get stub content
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
protected function getStubContent(): string
|
||||
{
|
||||
return File::get(dirname(__DIR__).DIRECTORY_SEPARATOR.'stubs'.DIRECTORY_SEPARATOR.'model.stub');
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* get model content
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
protected function getModelContent(): string
|
||||
{
|
||||
return Str::of($this->getStubContent())
|
||||
|
||||
->replace(
|
||||
[
|
||||
'{namespace}', '{model}', '{table}', '{fillable}'
|
||||
],
|
||||
[
|
||||
|
||||
$this->getModelNamespace(), $this->getModelName(),
|
||||
|
||||
$this->getTableName(), $this->getFillable()
|
||||
]
|
||||
)->toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* get namespace
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
protected function getModelNamespace(): string
|
||||
{
|
||||
return trim(CatchAdmin::getModuleModelNamespace($this->argument('module')), '\\');
|
||||
}
|
||||
|
||||
/**
|
||||
* get table name
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
protected function getTableName(): string
|
||||
{
|
||||
return $this->option('t') ? $this->option('t') :
|
||||
Str::of($this->argument('model'))
|
||||
->snake()->lcfirst()->toString();
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
protected function getFillable(): string
|
||||
{
|
||||
$fillable = Str::of('');
|
||||
|
||||
|
||||
foreach (getTableColumns($this->getTableName()) as $column) {
|
||||
$fillable = $fillable->append("'{$column}', ");
|
||||
}
|
||||
|
||||
|
||||
return $fillable->trim(',')->toString();
|
||||
}
|
||||
}
|
316
catch/src/Commands/InstallCommand.php
Normal file
316
catch/src/Commands/InstallCommand.php
Normal file
@ -0,0 +1,316 @@
|
||||
<?php
|
||||
|
||||
// +----------------------------------------------------------------------
|
||||
// | CatchAdmin [Just Like ~ ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | Copyright (c) 2017 ~ now https://catchadmin.com All rights reserved.
|
||||
// +----------------------------------------------------------------------
|
||||
// | Licensed ( https://github.com/JaguarJack/catchadmin/blob/master/LICENSE.md )
|
||||
// +----------------------------------------------------------------------
|
||||
// | Author: JaguarJack [ njphper@gmail.com ]
|
||||
// +----------------------------------------------------------------------
|
||||
|
||||
namespace Catch\Commands;
|
||||
|
||||
use Catch\CatchAdmin;
|
||||
use Illuminate\Console\Application;
|
||||
use Illuminate\Contracts\Container\BindingResolutionException;
|
||||
use Illuminate\Database\Connectors\ConnectionFactory;
|
||||
use Illuminate\Foundation\Bootstrap\LoadConfiguration;
|
||||
use Illuminate\Foundation\Bootstrap\LoadEnvironmentVariables;
|
||||
use Illuminate\Support\Collection;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use Illuminate\Support\Facades\File;
|
||||
use Illuminate\Support\Str;
|
||||
use Catch\Support\Composer;
|
||||
|
||||
class InstallCommand extends CatchCommand
|
||||
{
|
||||
protected $signature = 'catch:install';
|
||||
|
||||
protected $description = 'install catch admin';
|
||||
|
||||
/**
|
||||
* @var array|string[]
|
||||
*/
|
||||
private array $defaultExtensions = ['BCMath', 'Ctype', 'DOM', 'Fileinfo', 'JSON', 'Mbstring', 'OpenSSL', 'PCRE', 'PDO', 'Tokenizer', 'XML'];
|
||||
|
||||
/**
|
||||
* handle
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function handle(): void
|
||||
{
|
||||
try {
|
||||
$this->detectionEnvironment();
|
||||
|
||||
$this->copyEnvFile();
|
||||
|
||||
$this->askForCreatingDatabase();
|
||||
|
||||
$this->publishConfig();
|
||||
|
||||
$this->installed();
|
||||
} catch (\Throwable $e) {
|
||||
File::delete(app()->environmentFilePath());
|
||||
|
||||
$this->error($e->getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 环境检测
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function detectionEnvironment(): void
|
||||
{
|
||||
$this->checkPHPVersion();
|
||||
|
||||
$this->checkExtensions();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* check needed php extensions
|
||||
*/
|
||||
private function checkExtensions()
|
||||
{
|
||||
/* @var Collection $loadedExtensions */
|
||||
$loadedExtensions = Collection::make(get_loaded_extensions())->map(function ($item) {
|
||||
return strtolower($item);
|
||||
});
|
||||
|
||||
Collection::make($this->defaultExtensions)
|
||||
->each(function ($extension) use ($loadedExtensions, &$continue) {
|
||||
$extension = strtolower($extension);
|
||||
|
||||
if (! $loadedExtensions->contains($extension)) {
|
||||
$this->error("$extension extension 未安装");
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* check php version
|
||||
*/
|
||||
private function checkPHPVersion()
|
||||
{
|
||||
if (version_compare(PHP_VERSION, '8.1.0', '<')) {
|
||||
// $this->error('php version should >= 8.1');
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* create database
|
||||
*
|
||||
* @param string $databaseName
|
||||
* @return void
|
||||
* @throws BindingResolutionException
|
||||
*/
|
||||
private function createDatabase(string $databaseName): void
|
||||
{
|
||||
$databaseConfig = config('database.connections.'.DB::getDefaultConnection());
|
||||
|
||||
$databaseConfig['database'] = null;
|
||||
|
||||
app(ConnectionFactory::class)->make($databaseConfig)->select(sprintf("create database if not exists $databaseName default charset %s collate %s", 'utf8mb4', 'utf8mb4_general_ci'));
|
||||
}
|
||||
|
||||
/**
|
||||
* copy .env
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function copyEnvFile(): void
|
||||
{
|
||||
if (! File::exists(app()->environmentFilePath())) {
|
||||
File::copy(app()->environmentFilePath().'.example', app()->environmentFilePath());
|
||||
}
|
||||
|
||||
if (! File::exists(app()->environmentFilePath())) {
|
||||
$this->error('【.env】创建失败, 请重新尝试或者手动创建!');
|
||||
}
|
||||
|
||||
File::put(app()->environmentFile(), implode("\n", explode("\n", $this->getEnvFileContent())));
|
||||
}
|
||||
|
||||
/**
|
||||
* get env file content
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
protected function getEnvFileContent(): string
|
||||
{
|
||||
return File::get(app()->environmentFile());
|
||||
}
|
||||
|
||||
/**
|
||||
* publish config
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function publishConfig(): void
|
||||
{
|
||||
// can't use Artisan::call, it will block the process, no reason found, just block!!!
|
||||
exec(Application::formatCommandString('key:generate'));
|
||||
|
||||
exec(Application::formatCommandString('vendor:publish --tag=catch-config'));
|
||||
|
||||
exec(Application::formatCommandString('vendor:publish --provider="Tymon\JWTAuth\Providers\LaravelServiceProvider"'));
|
||||
|
||||
exec(Application::formatCommandString('jwt:secret'));
|
||||
}
|
||||
|
||||
/**
|
||||
* create database
|
||||
*/
|
||||
protected function askForCreatingDatabase()
|
||||
{
|
||||
$appUrl = $this->askFor('请配置应用的 URL');
|
||||
|
||||
if ($appUrl && ! Str::contains($appUrl, 'http://') && ! Str::contains($appUrl, 'https://')) {
|
||||
$appUrl = 'http://'.$appUrl;
|
||||
}
|
||||
|
||||
$databaseName = $this->askFor('请输入数据库名称');
|
||||
|
||||
$prefix = $this->askFor('请输入数据库表前缀', '');
|
||||
|
||||
$dbHost = $this->askFor('请输入数据库主机地址', '127.0.0.1');
|
||||
|
||||
$dbPort = $this->askFor('请输入数据的端口号', 3306);
|
||||
|
||||
$dbUsername = $this->askFor('请输入数据的用户名', 'root');
|
||||
|
||||
$dbPassword = $this->askFor('请输入数据库密码');
|
||||
|
||||
if (! $dbPassword) {
|
||||
$dbPassword = $this->askFor('确认数据库密码为空吗?');
|
||||
}
|
||||
|
||||
// set env
|
||||
$env = explode("\n", $this->getEnvFileContent());
|
||||
|
||||
foreach ($env as &$value) {
|
||||
foreach ([
|
||||
'APP_URL' => $appUrl,
|
||||
'DB_HOST' => $dbHost,
|
||||
'DB_PORT' => $dbPort,
|
||||
'DB_DATABASE' => $databaseName,
|
||||
'DB_USERNAME' => $dbUsername,
|
||||
'DB_PASSWORD' => $dbPassword,
|
||||
'DB_PREFIX' => $prefix
|
||||
] as $key => $newValue) {
|
||||
if (Str::contains($value, $key)) {
|
||||
$value = $this->resetEnvValue($value, $newValue);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// add vite config
|
||||
$env[] = 'VITE_BASE_URL=${APP_URL}/api/';
|
||||
|
||||
File::put(app()->environmentFile(), implode("\n", $env));
|
||||
|
||||
app()->bootstrapWith([
|
||||
LoadEnvironmentVariables::class,
|
||||
LoadConfiguration::class
|
||||
]);
|
||||
|
||||
$this->info("正在创建数据库[$databaseName]...");
|
||||
|
||||
$this->createDatabase($databaseName);
|
||||
|
||||
$this->info("创建数据库[$databaseName] 成功");
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $originValue
|
||||
* @param $newValue
|
||||
* @return string
|
||||
*/
|
||||
protected function resetEnvValue($originValue, $newValue): string
|
||||
{
|
||||
if (Str::contains($originValue, '=')) {
|
||||
$originValue = explode('=', $originValue);
|
||||
|
||||
$originValue[1] = $newValue;
|
||||
|
||||
return implode('=', $originValue);
|
||||
}
|
||||
|
||||
return $originValue;
|
||||
}
|
||||
|
||||
/**
|
||||
* add prs4 autoload
|
||||
*/
|
||||
protected function addPsr4Autoload()
|
||||
{
|
||||
$composerFile = base_path().DIRECTORY_SEPARATOR.'composer.json';
|
||||
|
||||
$composerJson = json_decode(File::get(base_path().DIRECTORY_SEPARATOR.'composer.json'), true);
|
||||
|
||||
$composerJson['autoload']['psr-4'][CatchAdmin::getModuleRootNamespace()] = str_replace('\\', '/', config('catch.module.root'));
|
||||
|
||||
File::put($composerFile, json_encode($composerJson, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES));
|
||||
|
||||
$this->info('composer dump autoload..., 请耐心等待');
|
||||
|
||||
app(Composer::class)->dumpAutoloads();
|
||||
}
|
||||
|
||||
/**
|
||||
* admin installed
|
||||
*/
|
||||
public function installed()
|
||||
{
|
||||
$this->addPsr4Autoload();
|
||||
|
||||
$this->info('🎉 CatchAdmin 已安装, 欢迎!');
|
||||
|
||||
$this->output->info(sprintf('
|
||||
/------------------------ welcome ----------------------------\
|
||||
| __ __ ___ __ _ |
|
||||
| _________ _/ /______/ /_ / | ____/ /___ ___ (_)___ |
|
||||
| / ___/ __ `/ __/ ___/ __ \ / /| |/ __ / __ `__ \/ / __ \ |
|
||||
| / /__/ /_/ / /_/ /__/ / / / / ___ / /_/ / / / / / / / / / / |
|
||||
| \___/\__,_/\__/\___/_/ /_/ /_/ |_\__,_/_/ /_/ /_/_/_/ /_/ |
|
||||
| |
|
||||
\ __ __ __ __ _ __ _ __ enjoy it ! _ __ __ __ __ __ __ ___ _ @
|
||||
版本: %s
|
||||
初始账号: catch@admin.com
|
||||
初始密码: catchadmin', CatchAdmin::VERSION));
|
||||
|
||||
$this->support();
|
||||
}
|
||||
|
||||
/**
|
||||
* support
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function support(): void
|
||||
{
|
||||
$answer = $this->askFor('支持我们! 感谢在 Github 上 star 该项目', 'yes', true);
|
||||
|
||||
if (in_array(strtolower($answer), ['yes', 'y'])) {
|
||||
if (PHP_OS_FAMILY == 'Darwin') {
|
||||
exec('open https://github.com/JaguarJack/catch-admin');
|
||||
}
|
||||
if (PHP_OS_FAMILY == 'Windows') {
|
||||
exec('start https://github.com/JaguarJack/catch-admin');
|
||||
}
|
||||
if (PHP_OS_FAMILY == 'Linux') {
|
||||
exec('xdg-open https://github.com/JaguarJack/catch-admin');
|
||||
}
|
||||
}
|
||||
|
||||
$this->info('支 持: https://github.com/jaguarjack/catchadmin');
|
||||
$this->info('文 档: https://catchadmin.com/docs/3.0/intro');
|
||||
$this->info('官 网: https://catchadmin.com');
|
||||
}
|
||||
}
|
55
catch/src/Commands/Migrate/MigrateFresh.php
Normal file
55
catch/src/Commands/Migrate/MigrateFresh.php
Normal file
@ -0,0 +1,55 @@
|
||||
<?php
|
||||
|
||||
namespace Catch\Commands\Migrate;
|
||||
|
||||
use Catch\CatchAdmin;
|
||||
use Catch\Commands\CatchCommand;
|
||||
use Illuminate\Support\Facades\Artisan;
|
||||
use Illuminate\Support\Facades\File;
|
||||
|
||||
class MigrateFresh extends CatchCommand
|
||||
{
|
||||
/**
|
||||
* The name and signature of the console command.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $signature = 'catch:migrate:fresh {module} {--force}';
|
||||
|
||||
/**
|
||||
* The console command description.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $description = 'catch migrate fresh';
|
||||
|
||||
/**
|
||||
* Create a new command instance.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct();
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute the console command.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function handle(): void
|
||||
{
|
||||
$module = $this->argument('module');
|
||||
|
||||
if (! File::isDirectory(CatchAdmin::getModuleMigrationPath($module))) {
|
||||
Artisan::call('migration:fresh', [
|
||||
'--path' => CatchAdmin::getModuleRelativePath(CatchAdmin::getModuleMigrationPath($module)),
|
||||
|
||||
'--force' => $this->option('force')
|
||||
]);
|
||||
} else {
|
||||
$this->error('No migration files in module');
|
||||
}
|
||||
}
|
||||
}
|
91
catch/src/Commands/Migrate/MigrateMake.php
Normal file
91
catch/src/Commands/Migrate/MigrateMake.php
Normal file
@ -0,0 +1,91 @@
|
||||
<?php
|
||||
|
||||
// +----------------------------------------------------------------------
|
||||
// | CatchAdmin [Just Like ~ ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | Copyright (c) 2017~2021 https://catchadmin.com All rights reserved.
|
||||
// +----------------------------------------------------------------------
|
||||
// | Licensed ( https://github.com/JaguarJack/catchadmin-laravel/blob/master/LICENSE.md )
|
||||
// +----------------------------------------------------------------------
|
||||
// | Author: JaguarJack [ njphper@gmail.com ]
|
||||
// +----------------------------------------------------------------------
|
||||
|
||||
namespace Catch\Commands\Migrate;
|
||||
|
||||
use Catch\CatchAdmin;
|
||||
use Catch\Commands\CatchCommand;
|
||||
use Illuminate\Support\Facades\File;
|
||||
use Illuminate\Support\Str;
|
||||
|
||||
class MigrateMake extends CatchCommand
|
||||
{
|
||||
/**
|
||||
* The name and signature of the console command.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $signature = 'catch:make:migration {module : The module of the migration created at}
|
||||
{table : The name of the table to migration}';
|
||||
|
||||
/**
|
||||
* The console command description.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $description = 'create module migration';
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function handle(): void
|
||||
{
|
||||
$migrationPath = CatchAdmin::getModuleMigrationPath($this->argument('module'));
|
||||
|
||||
$file = $migrationPath.$this->getMigrationFile();
|
||||
|
||||
File::put($file, Str::of($this->getStubContent())->replace(
|
||||
'{table}',
|
||||
$this->getTable()
|
||||
)->toString());
|
||||
|
||||
|
||||
if (File::exists($file)) {
|
||||
$this->info($file.' has been created');
|
||||
} else {
|
||||
$this->error($file.' create failed');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
protected function getMigrationFile(): string
|
||||
{
|
||||
return date('Y_m_d_His').'_create_'.$this->getTable().'.php';
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
protected function getTable(): string
|
||||
{
|
||||
return Str::of($this->argument('table'))->ucfirst()->snake()->lower()->toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* get stub content
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
protected function getStubContent(): string
|
||||
{
|
||||
return File::get(dirname(__DIR__).DIRECTORY_SEPARATOR.'stubs'.DIRECTORY_SEPARATOR.'migration.stub');
|
||||
}
|
||||
}
|
74
catch/src/Commands/Migrate/MigrateRun.php
Normal file
74
catch/src/Commands/Migrate/MigrateRun.php
Normal file
@ -0,0 +1,74 @@
|
||||
<?php
|
||||
|
||||
// +----------------------------------------------------------------------
|
||||
// | CatchAdmin [Just Like ~ ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | Copyright (c) 2017~2021 https://catchadmin.com All rights reserved.
|
||||
// +----------------------------------------------------------------------
|
||||
// | Licensed ( https://github.com/JaguarJack/catchadmin-laravel/blob/master/LICENSE.md )
|
||||
// +----------------------------------------------------------------------
|
||||
// | Author: JaguarJack [ njphper@gmail.com ]
|
||||
// +----------------------------------------------------------------------
|
||||
|
||||
namespace Catch\Commands\Migrate;
|
||||
|
||||
use Catch\CatchAdmin;
|
||||
use Catch\Commands\CatchCommand;
|
||||
use Illuminate\Support\Facades\Artisan;
|
||||
use Illuminate\Support\Facades\File;
|
||||
use Illuminate\Support\Str;
|
||||
|
||||
class MigrateRun extends CatchCommand
|
||||
{
|
||||
/**
|
||||
* The name and signature of the console command.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $signature = 'catch:migrate {module} {--force}';
|
||||
|
||||
/**
|
||||
* The console command description.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $description = 'migrate catch module';
|
||||
|
||||
/**
|
||||
* Create a new command instance.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct();
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute the console command.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function handle(): void
|
||||
{
|
||||
$module = $this->argument('module');
|
||||
|
||||
if (File::isDirectory(CatchAdmin::getModuleMigrationPath($module))) {
|
||||
foreach (File::files(CatchAdmin::getModuleMigrationPath($module)) as $file) {
|
||||
$path = Str::of(CatchAdmin::getModuleRelativePath(CatchAdmin::getModuleMigrationPath($module)))
|
||||
|
||||
->remove('.')->append($file->getFilename());
|
||||
|
||||
Artisan::call('migrate', [
|
||||
'--path' => $path,
|
||||
|
||||
'--force' => $this->option('force')
|
||||
]);
|
||||
}
|
||||
|
||||
$this->info("Module [$module] migrate success");
|
||||
} else {
|
||||
$this->error('No migration files in module');
|
||||
}
|
||||
}
|
||||
}
|
65
catch/src/Commands/Migrate/MigrationRollback.php
Normal file
65
catch/src/Commands/Migrate/MigrationRollback.php
Normal file
@ -0,0 +1,65 @@
|
||||
<?php
|
||||
|
||||
// +----------------------------------------------------------------------
|
||||
// | CatchAdmin [Just Like ~ ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | Copyright (c) 2017~2021 https://catchadmin.com All rights reserved.
|
||||
// +----------------------------------------------------------------------
|
||||
// | Licensed ( https://github.com/JaguarJack/catchadmin-laravel/blob/master/LICENSE.md )
|
||||
// +----------------------------------------------------------------------
|
||||
// | Author: JaguarJack [ njphper@gmail.com ]
|
||||
// +----------------------------------------------------------------------
|
||||
|
||||
namespace Catch\Commands\Migrate;
|
||||
|
||||
use Catch\CatchAdmin;
|
||||
use Catch\Commands\CatchCommand;
|
||||
use Illuminate\Support\Facades\Artisan;
|
||||
use Illuminate\Support\Facades\File;
|
||||
|
||||
class MigrationRollback extends CatchCommand
|
||||
{
|
||||
/**
|
||||
* The name and signature of the console command.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $signature = 'catch:migrate:rollback {module} {--force}';
|
||||
|
||||
/**
|
||||
* The console command description.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $description = 'rollback module tables';
|
||||
|
||||
/**
|
||||
* Create a new command instance.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct();
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute the console command.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function handle(): void
|
||||
{
|
||||
$module = $this->argument('module');
|
||||
|
||||
if (! File::isDirectory(CatchAdmin::getModuleMigrationPath($module))) {
|
||||
Artisan::call('migration:rollback', [
|
||||
'--path' => CatchAdmin::getModuleRelativePath(CatchAdmin::getModuleMigrationPath($module)),
|
||||
|
||||
'--force' => $this->option('force')
|
||||
]);
|
||||
} else {
|
||||
$this->error('No migration files in module');
|
||||
}
|
||||
}
|
||||
}
|
88
catch/src/Commands/Migrate/SeedRun.php
Normal file
88
catch/src/Commands/Migrate/SeedRun.php
Normal file
@ -0,0 +1,88 @@
|
||||
<?php
|
||||
|
||||
// +----------------------------------------------------------------------
|
||||
// | CatchAdmin [Just Like ~ ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | Copyright (c) 2017~2021 https://catchadmin.com All rights reserved.
|
||||
// +----------------------------------------------------------------------
|
||||
// | Licensed ( https://github.com/JaguarJack/catchadmin-laravel/blob/master/LICENSE.md )
|
||||
// +----------------------------------------------------------------------
|
||||
// | Author: JaguarJack [ njphper@gmail.com ]
|
||||
// +----------------------------------------------------------------------
|
||||
|
||||
namespace Catch\Commands\Migrate;
|
||||
|
||||
use Catch\CatchAdmin;
|
||||
use Catch\Commands\CatchCommand;
|
||||
use Illuminate\Support\Facades\File;
|
||||
|
||||
class SeedRun extends CatchCommand
|
||||
{
|
||||
/**
|
||||
* The name and signature of the console command.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $signature = 'catch:db:seed {module} {--class=}';
|
||||
|
||||
/**
|
||||
* The console command description.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $description = 'catch db seed';
|
||||
|
||||
/**
|
||||
* Create a new command instance.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct();
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute the console command.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function handle(): void
|
||||
{
|
||||
$classes = $this->loadModuleSeeders();
|
||||
|
||||
if ($class = $this->option('class')) {
|
||||
(new $class())->run();
|
||||
} else {
|
||||
foreach ($classes as $class) {
|
||||
$class = new $class();
|
||||
if (method_exists($class, 'run')) {
|
||||
$class->run();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$this->info('Seed run successfully');
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
* @time 2021年07月31日
|
||||
* @return array
|
||||
*/
|
||||
protected function loadModuleSeeders(): array
|
||||
{
|
||||
$files = File::allFiles(CatchAdmin::getModuleSeederPath($this->argument('module')));
|
||||
|
||||
$fileNames = [];
|
||||
|
||||
foreach ($files as $file) {
|
||||
require_once $file->getRealPath();
|
||||
|
||||
$fileNames[] = pathinfo($file->getBasename(), PATHINFO_FILENAME);
|
||||
}
|
||||
|
||||
return $fileNames;
|
||||
}
|
||||
}
|
88
catch/src/Commands/Migrate/SeederMake.php
Normal file
88
catch/src/Commands/Migrate/SeederMake.php
Normal file
@ -0,0 +1,88 @@
|
||||
<?php
|
||||
|
||||
// +----------------------------------------------------------------------
|
||||
// | CatchAdmin [Just Like ~ ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | Copyright (c) 2017~2021 https://catchadmin.com All rights reserved.
|
||||
// +----------------------------------------------------------------------
|
||||
// | Licensed ( https://github.com/JaguarJack/catchadmin-laravel/blob/master/LICENSE.md )
|
||||
// +----------------------------------------------------------------------
|
||||
// | Author: JaguarJack [ njphper@gmail.com ]
|
||||
// +----------------------------------------------------------------------
|
||||
|
||||
namespace Catch\Commands\Migrate;
|
||||
|
||||
use Catch\CatchAdmin;
|
||||
use Catch\Commands\CatchCommand;
|
||||
use Illuminate\Support\Facades\File;
|
||||
use Illuminate\Support\Str;
|
||||
use PhpParser\Node\Name;
|
||||
|
||||
class SeederMake extends CatchCommand
|
||||
{
|
||||
/**
|
||||
* The name and signature of the console command.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $signature = 'catch:make:seeder {module} {name}';
|
||||
|
||||
/**
|
||||
* The console command description.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $description = 'make module seeder';
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
* @return void
|
||||
* @throws \Exception
|
||||
* @author CatchAdmin
|
||||
* @time 2021年08月01日
|
||||
*/
|
||||
public function handle(): void
|
||||
{
|
||||
$seederPath = CatchAdmin::getModuleSeederPath($this->argument('module'));
|
||||
|
||||
$file = $seederPath.$this->getSeederName().'.php';
|
||||
|
||||
if (File::exists($file)) {
|
||||
$answer = $this->ask($file.' already exists, Did you want replace it?', 'Y');
|
||||
|
||||
if (! Str::of($answer)->lower()->exactly('y')) {
|
||||
exit;
|
||||
}
|
||||
}
|
||||
|
||||
File::put($file, $this->getSeederContent());
|
||||
|
||||
if (File::exists($file)) {
|
||||
$this->info($file.' has been created');
|
||||
} else {
|
||||
$this->error($file.' create failed');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* seeder content
|
||||
*
|
||||
* @return string
|
||||
* @throws \Exception
|
||||
*/
|
||||
protected function getSeederContent(): string
|
||||
{
|
||||
return File::get(dirname(__DIR__).DIRECTORY_SEPARATOR.'stubs'.DIRECTORY_SEPARATOR.'seeder.stub');
|
||||
}
|
||||
|
||||
/**
|
||||
* seeder name
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
protected function getSeederName(): string
|
||||
{
|
||||
return Str::of($this->argument('name'))->ucfirst()->toString();
|
||||
}
|
||||
}
|
35
catch/src/Commands/stubs/controller.stub
Normal file
35
catch/src/Commands/stubs/controller.stub
Normal file
@ -0,0 +1,35 @@
|
||||
<?php
|
||||
|
||||
namespace {namespace};
|
||||
|
||||
use Catch\Base\CatchController;
|
||||
use Illuminate\Http\Request;
|
||||
|
||||
class {controller} extends CatchController
|
||||
{
|
||||
public function index(Request $request)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public function store(Request $request)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public function show($id)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
|
||||
public function update($id, Request $request)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public function destroy($id)
|
||||
{
|
||||
|
||||
}
|
||||
}
|
36
catch/src/Commands/stubs/event.stub
Normal file
36
catch/src/Commands/stubs/event.stub
Normal file
@ -0,0 +1,36 @@
|
||||
<?php
|
||||
|
||||
namespace {namespace};
|
||||
|
||||
use Illuminate\Broadcasting\Channel;
|
||||
use Illuminate\Broadcasting\InteractsWithSockets;
|
||||
use Illuminate\Broadcasting\PresenceChannel;
|
||||
use Illuminate\Broadcasting\PrivateChannel;
|
||||
use Illuminate\Contracts\Broadcasting\ShouldBroadcast;
|
||||
use Illuminate\Foundation\Events\Dispatchable;
|
||||
use Illuminate\Queue\SerializesModels;
|
||||
|
||||
class {event}
|
||||
{
|
||||
use Dispatchable, InteractsWithSockets, SerializesModels;
|
||||
|
||||
/**
|
||||
* Create a new event instance.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function __construct(): void
|
||||
{
|
||||
//
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the channels the event should broadcast on.
|
||||
*
|
||||
* @return \Illuminate\Broadcasting\Channel|array
|
||||
*/
|
||||
public function broadcastOn()
|
||||
{
|
||||
return new PrivateChannel('channel-name');
|
||||
}
|
||||
}
|
30
catch/src/Commands/stubs/listener.stub
Normal file
30
catch/src/Commands/stubs/listener.stub
Normal file
@ -0,0 +1,30 @@
|
||||
<?php
|
||||
|
||||
namespace {namespace};
|
||||
|
||||
use Illuminate\Contracts\Queue\ShouldQueue;
|
||||
use Illuminate\Queue\InteractsWithQueue;
|
||||
|
||||
class {listener}
|
||||
{
|
||||
/**
|
||||
* Create the event listener.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function __construct(): void
|
||||
{
|
||||
//
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle the event.
|
||||
*
|
||||
* @param object $event
|
||||
* @return void
|
||||
*/
|
||||
public function handle($event): void
|
||||
{
|
||||
//
|
||||
}
|
||||
}
|
31
catch/src/Commands/stubs/migration.stub
Normal file
31
catch/src/Commands/stubs/migration.stub
Normal file
@ -0,0 +1,31 @@
|
||||
<?php
|
||||
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
return new class extends Migration
|
||||
{
|
||||
/**
|
||||
* Run the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function up(): void
|
||||
{
|
||||
|
||||
Schema::create('{table}', function (Blueprint $table) {
|
||||
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function down(): void
|
||||
{
|
||||
|
||||
}
|
||||
};
|
16
catch/src/Commands/stubs/model.stub
Normal file
16
catch/src/Commands/stubs/model.stub
Normal file
@ -0,0 +1,16 @@
|
||||
<?php
|
||||
|
||||
namespace {namespace};
|
||||
|
||||
use Catch\Base\CatchModel as Model;
|
||||
|
||||
|
||||
class {model} extends Model
|
||||
{
|
||||
protected $table = '{table}';
|
||||
|
||||
protected $fillable = [
|
||||
{fillable}
|
||||
];
|
||||
|
||||
}
|
18
catch/src/Commands/stubs/seeder.stub
Normal file
18
catch/src/Commands/stubs/seeder.stub
Normal file
@ -0,0 +1,18 @@
|
||||
<?php
|
||||
|
||||
use Illuminate\Database\Console\Seeds\WithoutModelEvents;
|
||||
use Illuminate\Database\Seeder;
|
||||
|
||||
return new class extends Seeder
|
||||
{
|
||||
/**
|
||||
* Run the seeder.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function run(): void
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
};
|
35
catch/src/Contracts/ModuleRepositoryInterface.php
Normal file
35
catch/src/Contracts/ModuleRepositoryInterface.php
Normal file
@ -0,0 +1,35 @@
|
||||
<?php
|
||||
|
||||
// +----------------------------------------------------------------------
|
||||
// | CatchAdmin [Just Like ~ ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | Copyright (c) 2017~2021 https://catchadmin.com All rights reserved.
|
||||
// +----------------------------------------------------------------------
|
||||
// | Licensed ( https://github.com/JaguarJack/catchadmin/blob/master/LICENSE.md )
|
||||
// +----------------------------------------------------------------------
|
||||
// | Author: JaguarJack [ njphper@gmail.com ]
|
||||
// +----------------------------------------------------------------------
|
||||
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Catch\Contracts;
|
||||
|
||||
use Illuminate\Support\Collection;
|
||||
|
||||
interface ModuleRepositoryInterface
|
||||
{
|
||||
public function all(array $search): Collection;
|
||||
|
||||
public function create(array $module): bool|int;
|
||||
|
||||
public function show(string $name): Collection;
|
||||
|
||||
public function update(string $name, array $module): bool|int;
|
||||
|
||||
public function delete(string $name): bool|int;
|
||||
|
||||
public function disOrEnable(string $name): bool|int;
|
||||
|
||||
public function getEnabled(): Collection;
|
||||
}
|
79
catch/src/Enums/Code.php
Normal file
79
catch/src/Enums/Code.php
Normal file
@ -0,0 +1,79 @@
|
||||
<?php
|
||||
|
||||
// +----------------------------------------------------------------------
|
||||
// | CatchAdmin [Just Like ~ ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | Copyright (c) 2017~2021 https://catchadmin.com All rights reserved.
|
||||
// +----------------------------------------------------------------------
|
||||
// | Licensed ( https://github.com/JaguarJack/catchadmin-laravel/blob/master/LICENSE.md )
|
||||
// +----------------------------------------------------------------------
|
||||
// | Author: JaguarJack [ njphper@gmail.com ]
|
||||
// +----------------------------------------------------------------------
|
||||
|
||||
namespace Catch\Enums;
|
||||
|
||||
enum Code: int implements Enum
|
||||
{
|
||||
case SUCCESS = 10000; // 成功
|
||||
case LOST_LOGIN = 10001; // 登录失效
|
||||
case VALIDATE_FAILED = 10002; // 验证错误
|
||||
case PERMISSION_FORBIDDEN = 10003; // 权限禁止
|
||||
case LOGIN_FAILED = 10004; // 登录失败
|
||||
case FAILED = 10005; // 操作失败
|
||||
case LOGIN_EXPIRED = 10006; // 登录失效
|
||||
case LOGIN_BLACKLIST = 10007; // 黑名单
|
||||
case USER_FORBIDDEN = 10008; // 账户被禁
|
||||
case WECHAT_RESPONSE_ERROR = 40000;
|
||||
|
||||
/**
|
||||
* message
|
||||
*
|
||||
*/
|
||||
public function message(): string
|
||||
{
|
||||
return $this->name();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* get value
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function value(): int
|
||||
{
|
||||
return match ($this) {
|
||||
Code::SUCCESS => 10000,
|
||||
Code::LOST_LOGIN => 10001,
|
||||
Code::VALIDATE_FAILED => 10002,
|
||||
Code::PERMISSION_FORBIDDEN => 10003,
|
||||
Code::LOGIN_FAILED => 10004,
|
||||
Code::FAILED => 10005,
|
||||
Code::LOGIN_EXPIRED => 10006,
|
||||
Code::LOGIN_BLACKLIST => 10007,
|
||||
Code::USER_FORBIDDEN => 10008,
|
||||
Code::WECHAT_RESPONSE_ERROR => 40000,
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* name
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function name(): string
|
||||
{
|
||||
return match ($this) {
|
||||
self::SUCCESS => '操作成功',
|
||||
self::LOST_LOGIN => '登陆失效',
|
||||
self::VALIDATE_FAILED => '验证失败',
|
||||
self::PERMISSION_FORBIDDEN => '权限禁止',
|
||||
self::LOGIN_FAILED => '登陆失败',
|
||||
self::FAILED => '操作失败',
|
||||
self::LOGIN_EXPIRED => '登陆过期',
|
||||
self::LOGIN_BLACKLIST => '已被加入黑名单',
|
||||
self::USER_FORBIDDEN => '账户被禁用',
|
||||
self::WECHAT_RESPONSE_ERROR => '微信响应错误'
|
||||
};
|
||||
}
|
||||
}
|
10
catch/src/Enums/Enum.php
Normal file
10
catch/src/Enums/Enum.php
Normal file
@ -0,0 +1,10 @@
|
||||
<?php
|
||||
|
||||
namespace Catch\Enums;
|
||||
|
||||
interface Enum
|
||||
{
|
||||
public function value(): int;
|
||||
|
||||
public function name(): string;
|
||||
}
|
49
catch/src/Enums/Status.php
Normal file
49
catch/src/Enums/Status.php
Normal file
@ -0,0 +1,49 @@
|
||||
<?php
|
||||
|
||||
// +----------------------------------------------------------------------
|
||||
// | CatchAdmin [Just Like ~ ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | Copyright (c) 2017~2021 https://catchadmin.com All rights reserved.
|
||||
// +----------------------------------------------------------------------
|
||||
// | Licensed ( https://github.com/yanwenwu/catch-admin/blob/master/LICENSE.txt )
|
||||
// +----------------------------------------------------------------------
|
||||
// | Author: JaguarJack [ njphper@gmail.com ]
|
||||
// +----------------------------------------------------------------------
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Catch\Enums;
|
||||
|
||||
enum Status: int implements Enum
|
||||
{
|
||||
case Enable = 1;
|
||||
|
||||
case Disable = 2;
|
||||
|
||||
/**
|
||||
* @desc name
|
||||
*
|
||||
*/
|
||||
public function name(): string
|
||||
{
|
||||
return match ($this) {
|
||||
Status::Enable => '启用',
|
||||
|
||||
Status::Disable => '禁用'
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* get value
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function value(): int
|
||||
{
|
||||
return match ($this) {
|
||||
Status::Enable => 1,
|
||||
|
||||
Status::Disable => 2,
|
||||
};
|
||||
}
|
||||
}
|
21
catch/src/Events/Module/Created.php
Normal file
21
catch/src/Events/Module/Created.php
Normal file
@ -0,0 +1,21 @@
|
||||
<?php
|
||||
|
||||
namespace Catch\Events\Module;
|
||||
|
||||
use Illuminate\Broadcasting\InteractsWithSockets;
|
||||
use Illuminate\Foundation\Events\Dispatchable;
|
||||
use Illuminate\Queue\SerializesModels;
|
||||
|
||||
class Created
|
||||
{
|
||||
use Dispatchable, InteractsWithSockets, SerializesModels;
|
||||
|
||||
/**
|
||||
* Create a new event instance.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function __construct(public array $module)
|
||||
{
|
||||
}
|
||||
}
|
21
catch/src/Events/Module/Creating.php
Normal file
21
catch/src/Events/Module/Creating.php
Normal file
@ -0,0 +1,21 @@
|
||||
<?php
|
||||
|
||||
namespace Catch\Events\Module;
|
||||
|
||||
use Illuminate\Broadcasting\InteractsWithSockets;
|
||||
use Illuminate\Foundation\Events\Dispatchable;
|
||||
use Illuminate\Queue\SerializesModels;
|
||||
|
||||
class Creating
|
||||
{
|
||||
use Dispatchable, InteractsWithSockets, SerializesModels;
|
||||
|
||||
/**
|
||||
* Create a new event instance.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function __construct(public array $module)
|
||||
{
|
||||
}
|
||||
}
|
22
catch/src/Events/Module/Deleted.php
Normal file
22
catch/src/Events/Module/Deleted.php
Normal file
@ -0,0 +1,22 @@
|
||||
<?php
|
||||
|
||||
namespace Catch\Events\Module;
|
||||
|
||||
use Illuminate\Broadcasting\InteractsWithSockets;
|
||||
use Illuminate\Foundation\Events\Dispatchable;
|
||||
use Illuminate\Queue\SerializesModels;
|
||||
use Illuminate\Support\Collection;
|
||||
|
||||
class Deleted
|
||||
{
|
||||
use Dispatchable, InteractsWithSockets, SerializesModels;
|
||||
|
||||
/**
|
||||
* Create a new event instance.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function __construct(public Collection $module)
|
||||
{
|
||||
}
|
||||
}
|
21
catch/src/Events/Module/Updated.php
Normal file
21
catch/src/Events/Module/Updated.php
Normal file
@ -0,0 +1,21 @@
|
||||
<?php
|
||||
|
||||
namespace Catch\Events\Module;
|
||||
|
||||
use Illuminate\Broadcasting\InteractsWithSockets;
|
||||
use Illuminate\Foundation\Events\Dispatchable;
|
||||
use Illuminate\Queue\SerializesModels;
|
||||
|
||||
class Updated
|
||||
{
|
||||
use Dispatchable, InteractsWithSockets, SerializesModels;
|
||||
|
||||
/**
|
||||
* Create a new event instance.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function __construct(public string $originName, public array $module)
|
||||
{
|
||||
}
|
||||
}
|
21
catch/src/Events/Module/Updating.php
Normal file
21
catch/src/Events/Module/Updating.php
Normal file
@ -0,0 +1,21 @@
|
||||
<?php
|
||||
|
||||
namespace Catch\Events\Module;
|
||||
|
||||
use Illuminate\Broadcasting\InteractsWithSockets;
|
||||
use Illuminate\Foundation\Events\Dispatchable;
|
||||
use Illuminate\Queue\SerializesModels;
|
||||
|
||||
class Updating
|
||||
{
|
||||
use Dispatchable, InteractsWithSockets, SerializesModels;
|
||||
|
||||
/**
|
||||
* Create a new event instance.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function __construct(public string $originName, public array $module)
|
||||
{
|
||||
}
|
||||
}
|
27
catch/src/Events/User.php
Normal file
27
catch/src/Events/User.php
Normal file
@ -0,0 +1,27 @@
|
||||
<?php
|
||||
|
||||
namespace Catch\Events;
|
||||
|
||||
use Illuminate\Broadcasting\InteractsWithSockets;
|
||||
use Illuminate\Contracts\Auth\Authenticatable;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Foundation\Events\Dispatchable;
|
||||
use Illuminate\Queue\SerializesModels;
|
||||
|
||||
class User
|
||||
{
|
||||
use Dispatchable, InteractsWithSockets, SerializesModels;
|
||||
|
||||
public Authenticatable|Model $user;
|
||||
|
||||
/**
|
||||
* Create a new event instance.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function __construct(Authenticatable|Model $user)
|
||||
{
|
||||
//
|
||||
$this->user = $user;
|
||||
}
|
||||
}
|
65
catch/src/Exceptions/CatchException.php
Normal file
65
catch/src/Exceptions/CatchException.php
Normal file
@ -0,0 +1,65 @@
|
||||
<?php
|
||||
|
||||
// +----------------------------------------------------------------------
|
||||
// | CatchAdmin [Just Like ~ ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | Copyright (c) 2017~2021 https://catchadmin.com All rights reserved.
|
||||
// +----------------------------------------------------------------------
|
||||
// | Licensed ( https://github.com/JaguarJack/catchadmin-laravel/blob/master/LICENSE.md )
|
||||
// +----------------------------------------------------------------------
|
||||
// | Author: JaguarJack [ njphper@gmail.com ]
|
||||
// +----------------------------------------------------------------------
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Catch\Exceptions;
|
||||
|
||||
use Catch\Enums\Enum;
|
||||
use Symfony\Component\HttpKernel\Exception\HttpException;
|
||||
use Catch\Enums\Code;
|
||||
|
||||
abstract class CatchException extends HttpException
|
||||
{
|
||||
protected $code = 0;
|
||||
|
||||
/**
|
||||
* @param string $message
|
||||
* @param int|Code $code
|
||||
*/
|
||||
public function __construct(string $message = '', int|Code $code = 0)
|
||||
{
|
||||
if ($code instanceof Enum) {
|
||||
$code = $code->value();
|
||||
}
|
||||
|
||||
if ($this->code instanceof Enum && ! $code) {
|
||||
$code = $this->code->value();
|
||||
}
|
||||
|
||||
parent::__construct($this->statusCode(), $message ?: $this->message, null, [], $code);
|
||||
}
|
||||
|
||||
/**
|
||||
* status code
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function statusCode(): int
|
||||
{
|
||||
return 500;
|
||||
}
|
||||
|
||||
/**
|
||||
* render
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function render(): array
|
||||
{
|
||||
return [
|
||||
'code' => $this->code,
|
||||
|
||||
'message' => $this->message
|
||||
];
|
||||
}
|
||||
}
|
22
catch/src/Exceptions/FailedException.php
Normal file
22
catch/src/Exceptions/FailedException.php
Normal file
@ -0,0 +1,22 @@
|
||||
<?php
|
||||
|
||||
// +----------------------------------------------------------------------
|
||||
// | CatchAdmin [Just Like ~ ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | Copyright (c) 2017~2021 https://catchadmin.com All rights reserved.
|
||||
// +----------------------------------------------------------------------
|
||||
// | Licensed ( https://github.com/JaguarJack/catchadmin-laravel/blob/master/LICENSE.md )
|
||||
// +----------------------------------------------------------------------
|
||||
// | Author: JaguarJack [ njphper@gmail.com ]
|
||||
// +----------------------------------------------------------------------
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Catch\Exceptions;
|
||||
|
||||
use Catch\Enums\Code;
|
||||
|
||||
class FailedException extends CatchException
|
||||
{
|
||||
protected $code = Code::FAILED;
|
||||
}
|
34
catch/src/Exceptions/Handler.php
Normal file
34
catch/src/Exceptions/Handler.php
Normal file
@ -0,0 +1,34 @@
|
||||
<?php
|
||||
|
||||
// +----------------------------------------------------------------------
|
||||
// | CatchAdmin [Just Like ~ ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | Copyright (c) 2017~2021 https://catchadmin.com All rights reserved.
|
||||
// +----------------------------------------------------------------------
|
||||
// | Licensed ( https://github.com/JaguarJack/catchadmin-laravel/blob/master/LICENSE.md )
|
||||
// +----------------------------------------------------------------------
|
||||
// | Author: JaguarJack [ njphper@gmail.com ]
|
||||
// +----------------------------------------------------------------------
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Catch\Exceptions;
|
||||
|
||||
use Illuminate\Foundation\Exceptions\Handler as ExceptionHandler;
|
||||
|
||||
class Handler extends ExceptionHandler
|
||||
{
|
||||
/**
|
||||
* register
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function register(): void
|
||||
{
|
||||
if (config('catch')) {
|
||||
$this->dontReport = config('catch.exception.dont_report');
|
||||
|
||||
$this->dontFlash = config('catch.exception.dont_flash');
|
||||
}
|
||||
}
|
||||
}
|
22
catch/src/Exceptions/UnMatchedTokenException.php
Normal file
22
catch/src/Exceptions/UnMatchedTokenException.php
Normal file
@ -0,0 +1,22 @@
|
||||
<?php
|
||||
|
||||
// +----------------------------------------------------------------------
|
||||
// | CatchAdmin [Just Like ~ ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | Copyright (c) 2017~2021 https://catchadmin.com All rights reserved.
|
||||
// +----------------------------------------------------------------------
|
||||
// | Licensed ( https://github.com/JaguarJack/catchadmin-laravel/blob/master/LICENSE.md )
|
||||
// +----------------------------------------------------------------------
|
||||
// | Author: JaguarJack [ njphper@gmail.com ]
|
||||
// +----------------------------------------------------------------------
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Catch\Exceptions;
|
||||
|
||||
use Catch\Enums\Code;
|
||||
|
||||
class UnMatchedTokenException extends CatchException
|
||||
{
|
||||
protected $code = Code::FAILED;
|
||||
}
|
25
catch/src/Facade/Module.php
Normal file
25
catch/src/Facade/Module.php
Normal file
@ -0,0 +1,25 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Catch\Facade;
|
||||
|
||||
use Illuminate\Support\Facades\Facade;
|
||||
|
||||
/**
|
||||
* @method static all()
|
||||
* @method static create(array $module)
|
||||
* @method static update(string $name, array $module)
|
||||
* @method static delete(string $name)
|
||||
* @method static disOrEnable(string $name)
|
||||
*
|
||||
* @see ModuleRepository
|
||||
* Class Module
|
||||
*/
|
||||
class Module extends Facade
|
||||
{
|
||||
public static function getFacadeAccessor(): string
|
||||
{
|
||||
return 'module';
|
||||
}
|
||||
}
|
24
catch/src/Facade/Zipper.php
Normal file
24
catch/src/Facade/Zipper.php
Normal file
@ -0,0 +1,24 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Catch\Facade;
|
||||
|
||||
use Illuminate\Support\Facades\Facade;
|
||||
use Catch\Support\Zip\Zipper as Zip;
|
||||
|
||||
/**
|
||||
* @method static Zip make(string $pathToFile)
|
||||
* @method static Zip zip(string $pathToFile)
|
||||
* @method static Zip phar(string $pathToFile)
|
||||
*
|
||||
* @see Zipper
|
||||
* Class Module
|
||||
*/
|
||||
class Zipper extends Facade
|
||||
{
|
||||
public static function getFacadeAccessor(): string
|
||||
{
|
||||
return Zip::class;
|
||||
}
|
||||
}
|
57
catch/src/Listeners/RequestHandledListener.php
Normal file
57
catch/src/Listeners/RequestHandledListener.php
Normal file
@ -0,0 +1,57 @@
|
||||
<?php
|
||||
|
||||
namespace Catch\Listeners;
|
||||
|
||||
use Catch\Enums\Code;
|
||||
use Illuminate\Foundation\Http\Events\RequestHandled;
|
||||
use Symfony\Component\HttpFoundation\Response as SymfonyResponse;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
|
||||
class RequestHandledListener
|
||||
{
|
||||
/**
|
||||
* Handle the event.
|
||||
*
|
||||
* @param RequestHandled $event
|
||||
* @return void
|
||||
*/
|
||||
public function handle(RequestHandled $event): void
|
||||
{
|
||||
$response = $event->response;
|
||||
|
||||
if ($response instanceof JsonResponse) {
|
||||
$exception = $response->exception;
|
||||
|
||||
if ($response->getStatusCode() == SymfonyResponse::HTTP_OK && ! $exception) {
|
||||
$response->setData($this->formatData($response->getData()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param mixed $data
|
||||
* @return array
|
||||
*/
|
||||
protected function formatData(mixed $data): array
|
||||
{
|
||||
$responseData = [
|
||||
'code' => Code::SUCCESS->value(),
|
||||
'message' => Code::SUCCESS->message(),
|
||||
];
|
||||
|
||||
if (is_object($data) && property_exists($data, 'per_page')
|
||||
&& property_exists($data, 'total')
|
||||
&& property_exists($data, 'current_page')) {
|
||||
$responseData['data'] = $data->data;
|
||||
$responseData['total'] = $data->total;
|
||||
$responseData['limit'] = $data->per_page;
|
||||
$responseData['page'] = $data->current_page;
|
||||
|
||||
return $responseData;
|
||||
}
|
||||
|
||||
$responseData['data'] = $data;
|
||||
|
||||
return $responseData;
|
||||
}
|
||||
}
|
42
catch/src/Middleware/AuthMiddleware.php
Normal file
42
catch/src/Middleware/AuthMiddleware.php
Normal file
@ -0,0 +1,42 @@
|
||||
<?php
|
||||
|
||||
namespace Catch\Middleware;
|
||||
|
||||
use Catch\Enums\Code;
|
||||
use Catch\Events\User as UserEvent;
|
||||
use Catch\Exceptions\FailedException;
|
||||
use Exception;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\Auth;
|
||||
use Illuminate\Support\Facades\Event;
|
||||
use Throwable;
|
||||
use Tymon\JWTAuth\Exceptions\TokenBlacklistedException;
|
||||
use Tymon\JWTAuth\Exceptions\TokenExpiredException;
|
||||
|
||||
class AuthMiddleware
|
||||
{
|
||||
public function handle(Request $request, \Closure $next)
|
||||
{
|
||||
try {
|
||||
$guardName = getGuardName();
|
||||
|
||||
if (Auth::guard($guardName)->check()) {
|
||||
$user = Auth::guard($guardName)->user();
|
||||
|
||||
Event::dispatch(new UserEvent($user));
|
||||
}
|
||||
} catch (Exception|Throwable $e) {
|
||||
if ($e instanceof TokenExpiredException) {
|
||||
throw new FailedException(Code::LOGIN_EXPIRED->message(), Code::LOGIN_EXPIRED);
|
||||
}
|
||||
|
||||
if ($e instanceof TokenBlacklistedException) {
|
||||
throw new FailedException(Code::LOGIN_BLACKLIST->message(), Code::LOGIN_BLACKLIST);
|
||||
}
|
||||
|
||||
throw new FailedException(Code::LOST_LOGIN->message().":{$e->getMessage()}", Code::LOST_LOGIN);
|
||||
} finally {
|
||||
return $next($request);
|
||||
}
|
||||
}
|
||||
}
|
21
catch/src/Middleware/JsonResponseMiddleware.php
Normal file
21
catch/src/Middleware/JsonResponseMiddleware.php
Normal file
@ -0,0 +1,21 @@
|
||||
<?php
|
||||
|
||||
namespace Catch\Middleware;
|
||||
|
||||
use Illuminate\Http\JsonResponse;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Http\Response;
|
||||
|
||||
class JsonResponseMiddleware
|
||||
{
|
||||
public function handle(Request $request, \Closure $next)
|
||||
{
|
||||
$response = $next($request);
|
||||
|
||||
if ($response instanceof Response) {
|
||||
return new JsonResponse($response->getContent());
|
||||
}
|
||||
|
||||
return $response;
|
||||
}
|
||||
}
|
229
catch/src/Providers/CatchAdminServiceProvider.php
Normal file
229
catch/src/Providers/CatchAdminServiceProvider.php
Normal file
@ -0,0 +1,229 @@
|
||||
<?php
|
||||
|
||||
// +----------------------------------------------------------------------
|
||||
// | CatchAdmin [Just Like ~ ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | Copyright (c) 2017 ~ now https://catchadmin.com All rights reserved.
|
||||
// +----------------------------------------------------------------------
|
||||
// | Licensed ( https://github.com/JaguarJack/catchadmin/blob/master/LICENSE.md )
|
||||
// +----------------------------------------------------------------------
|
||||
// | Author: JaguarJack [ njphper@gmail.com ]
|
||||
// +----------------------------------------------------------------------
|
||||
|
||||
namespace Catch\Providers;
|
||||
|
||||
use Catch\CatchAdmin;
|
||||
use Catch\Contracts\ModuleRepositoryInterface;
|
||||
use Catch\Exceptions\Handler;
|
||||
use Catch\Support\DB\Query;
|
||||
use Catch\Support\Module\ModuleManager;
|
||||
use Illuminate\Container\Container;
|
||||
use Illuminate\Contracts\Container\BindingResolutionException;
|
||||
use Illuminate\Contracts\Debug\ExceptionHandler;
|
||||
use Illuminate\Foundation\Http\Events\RequestHandled;
|
||||
use Illuminate\Support\Facades\Event;
|
||||
use Illuminate\Support\ServiceProvider;
|
||||
use Psr\Container\ContainerExceptionInterface;
|
||||
use Psr\Container\NotFoundExceptionInterface;
|
||||
use ReflectionException;
|
||||
use Catch\Support\Macros\Register as MacrosRegister;
|
||||
|
||||
/**
|
||||
* CatchAmin Service Provider
|
||||
*/
|
||||
class CatchAdminServiceProvider extends ServiceProvider
|
||||
{
|
||||
/**
|
||||
* boot
|
||||
*
|
||||
* @return void
|
||||
* @throws NotFoundExceptionInterface
|
||||
* @throws ContainerExceptionInterface
|
||||
*/
|
||||
public function boot(): void
|
||||
{
|
||||
$this->bootDefaultModuleProviders();
|
||||
$this->bootModuleProviders();
|
||||
|
||||
$this->registerEvents();
|
||||
|
||||
$this->listenDBLog();
|
||||
|
||||
$this->mergeAuthConfig();
|
||||
|
||||
// $this->registerExceptionHandler();
|
||||
|
||||
MacrosRegister::boot();
|
||||
}
|
||||
|
||||
/**
|
||||
* register
|
||||
*
|
||||
* @return void
|
||||
* @throws ReflectionException
|
||||
*/
|
||||
public function register(): void
|
||||
{
|
||||
$this->registerCommands();
|
||||
|
||||
$this->registerModuleRepository();
|
||||
|
||||
$this->publishConfig();
|
||||
|
||||
$this->publishModuleMigration();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* register commands
|
||||
*
|
||||
* @return void
|
||||
* @throws ReflectionException
|
||||
*/
|
||||
protected function registerCommands(): void
|
||||
{
|
||||
loadCommands(dirname(__DIR__).DIRECTORY_SEPARATOR.'Commands', 'Catch\\');
|
||||
}
|
||||
|
||||
/**
|
||||
* register exception handler
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function registerExceptionHandler(): void
|
||||
{
|
||||
$this->app->singleton(
|
||||
ExceptionHandler::class,
|
||||
Handler::class
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* bind module repository
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function registerModuleRepository(): void
|
||||
{
|
||||
// register module manager
|
||||
$this->app->singleton(ModuleManager::class, function () {
|
||||
return new ModuleManager(fn () => Container::getInstance());
|
||||
});
|
||||
|
||||
// register module repository
|
||||
$this->app->singleton(ModuleRepositoryInterface::class, function () {
|
||||
return $this->app->make(ModuleManager::class)->driver();
|
||||
});
|
||||
|
||||
$this->app->alias(ModuleRepositoryInterface::class, 'module');
|
||||
}
|
||||
|
||||
/**
|
||||
* register events
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function registerEvents(): void
|
||||
{
|
||||
Event::listen(RequestHandled::class, config('catch.response.request_handled_listener'));
|
||||
}
|
||||
|
||||
/**
|
||||
* publish config
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function publishConfig(): void
|
||||
{
|
||||
if ($this->app->runningInConsole()) {
|
||||
$from = dirname(__DIR__, 2).DIRECTORY_SEPARATOR.'config'.DIRECTORY_SEPARATOR.'catch.php';
|
||||
|
||||
$to = config_path('catch.php');
|
||||
|
||||
$this->publishes([$from => $to], 'catch-config');
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* publish module migration
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function publishModuleMigration(): void
|
||||
{
|
||||
if ($this->app->runningInConsole()) {
|
||||
$form = dirname(__DIR__, 2).DIRECTORY_SEPARATOR.'database'.DIRECTORY_SEPARATOR.'migrations'.DIRECTORY_SEPARATOR.'2022_11_14_034127_module.php';
|
||||
|
||||
$to = database_path('migrations').DIRECTORY_SEPARATOR.'2022_11_14_034127_module.php';
|
||||
|
||||
$this->publishes([$form => $to], 'catch-module');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @return void
|
||||
* @throws NotFoundExceptionInterface
|
||||
* @throws ContainerExceptionInterface
|
||||
*/
|
||||
protected function bootDefaultModuleProviders(): void
|
||||
{
|
||||
foreach ($this->app['config']->get('catch.module.default') as $module) {
|
||||
$provider = CatchAdmin::getModuleServiceProvider($module);
|
||||
if (class_exists($provider)) {
|
||||
$this->app->register($provider);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* boot module
|
||||
*
|
||||
* @throws BindingResolutionException
|
||||
*/
|
||||
protected function bootModuleProviders()
|
||||
{
|
||||
foreach ($this->app->make(ModuleRepositoryInterface::class)->getEnabled() as $module) {
|
||||
if (class_exists($module['service'])) {
|
||||
$this->app->register($module['service']);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* listen db log
|
||||
*
|
||||
* @throws ContainerExceptionInterface
|
||||
* @throws NotFoundExceptionInterface
|
||||
* @return void
|
||||
*/
|
||||
protected function listenDBLog(): void
|
||||
{
|
||||
if ($this->app['config']->get('catch.listen_db_log')) {
|
||||
Query::listen();
|
||||
|
||||
$this->app->terminating(function () {
|
||||
Query::log();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* merge auth config
|
||||
*
|
||||
* @throws BindingResolutionException
|
||||
* @return void
|
||||
*/
|
||||
protected function mergeAuthConfig(): void
|
||||
{
|
||||
if (! $this->app->configurationIsCached()) {
|
||||
$config = $this->app->make('config');
|
||||
|
||||
$config->set('auth', array_merge_recursive(
|
||||
$config->get('catch.auth', []),
|
||||
$config->get('auth', [])
|
||||
));
|
||||
}
|
||||
}
|
||||
}
|
63
catch/src/Providers/CatchModuleServiceProvider.php
Normal file
63
catch/src/Providers/CatchModuleServiceProvider.php
Normal file
@ -0,0 +1,63 @@
|
||||
<?php
|
||||
|
||||
// +----------------------------------------------------------------------
|
||||
// | CatchAdmin [Just Like ~ ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | Copyright (c) 2017 ~ now https://catchadmin.com All rights reserved.
|
||||
// +----------------------------------------------------------------------
|
||||
// | Licensed ( https://github.com/JaguarJack/catchadmin/blob/master/LICENSE.md )
|
||||
// +----------------------------------------------------------------------
|
||||
// | Author: JaguarJack [ njphper@gmail.com ]
|
||||
// +----------------------------------------------------------------------
|
||||
|
||||
namespace Catch\Providers;
|
||||
|
||||
use Illuminate\Support\Facades\Event;
|
||||
use Illuminate\Support\Facades\Route;
|
||||
use Illuminate\Support\ServiceProvider;
|
||||
use Psr\Container\ContainerExceptionInterface;
|
||||
use Psr\Container\NotFoundExceptionInterface;
|
||||
|
||||
abstract class CatchModuleServiceProvider extends ServiceProvider
|
||||
{
|
||||
protected array $events = [];
|
||||
|
||||
/**
|
||||
* register
|
||||
*
|
||||
* @return void
|
||||
* @throws NotFoundExceptionInterface
|
||||
* @throws ContainerExceptionInterface
|
||||
*/
|
||||
public function boot(): void
|
||||
{
|
||||
$this->registerModuleRoute();
|
||||
|
||||
foreach ($this->events as $event => $listener) {
|
||||
Event::listen($event, $listener);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* load module router
|
||||
*
|
||||
* @return void
|
||||
* @throws NotFoundExceptionInterface
|
||||
* @throws ContainerExceptionInterface
|
||||
*/
|
||||
protected function registerModuleRoute(): void
|
||||
{
|
||||
$route = $this->app['config']->get('catch.route');
|
||||
|
||||
Route::prefix($route['prefix'])
|
||||
->middleware($route['middlewares'])
|
||||
->group($this->routePath());
|
||||
}
|
||||
|
||||
/**
|
||||
* route path
|
||||
*
|
||||
* @return string|array
|
||||
*/
|
||||
abstract protected function routePath(): string | array;
|
||||
}
|
108
catch/src/Support/Composer.php
Normal file
108
catch/src/Support/Composer.php
Normal file
@ -0,0 +1,108 @@
|
||||
<?php
|
||||
|
||||
namespace Catch\Support;
|
||||
|
||||
use Illuminate\Support\Composer as LaravelComposer;
|
||||
use Illuminate\Support\Str;
|
||||
use Illuminate\Support\Facades\File;
|
||||
use Laravel\SerializableClosure\Exceptions\PhpVersionNotSupportedException;
|
||||
|
||||
class Composer extends LaravelComposer
|
||||
{
|
||||
protected bool $ignorePlatformReqs = false;
|
||||
|
||||
|
||||
/**
|
||||
* require package
|
||||
* @param string $package
|
||||
* @return string
|
||||
* @throws PhpVersionNotSupportedException
|
||||
*/
|
||||
public function require(string $package): string
|
||||
{
|
||||
$this->checkPHPVersion();
|
||||
|
||||
$command = ['require', $package];
|
||||
|
||||
return $this->runCommand($command);
|
||||
}
|
||||
|
||||
/**
|
||||
* require dev-package
|
||||
*
|
||||
* @param string $package
|
||||
* @return string
|
||||
* @throws PhpVersionNotSupportedException
|
||||
*/
|
||||
public function requireDev(string $package): string
|
||||
{
|
||||
$this->checkPHPVersion();
|
||||
|
||||
$command = ['require', '--dev', $package];
|
||||
|
||||
return $this->runCommand($command);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* remove
|
||||
*
|
||||
* @param string $package
|
||||
*/
|
||||
public function remove(string $package)
|
||||
{
|
||||
$this->runCommand([
|
||||
'remove', $package
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param array $command
|
||||
* @return string
|
||||
*/
|
||||
protected function runCommand(array $command): string
|
||||
{
|
||||
$command = array_merge($this->findComposer(), $command);
|
||||
|
||||
if ($this->ignorePlatformReqs) {
|
||||
$command[] = '--ignore-platform-reqs';
|
||||
}
|
||||
|
||||
$process = $this->getProcess($command);
|
||||
|
||||
$process->run();
|
||||
|
||||
return $process->getOutput();
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @throws PhpVersionNotSupportedException
|
||||
* @return void
|
||||
*/
|
||||
protected function checkPHPVersion(): void
|
||||
{
|
||||
$composerJson = json_decode(File::get(base_path().DIRECTORY_SEPARATOR.'composer.json'), true);
|
||||
|
||||
$phpVersion = PHP_VERSION;
|
||||
|
||||
$needPHPVersion = Str::of($composerJson['require']['php'])->remove('^');
|
||||
|
||||
if (version_compare($phpVersion, $needPHPVersion, '<') && ! $this->ignorePlatformReqs) {
|
||||
throw new PhpVersionNotSupportedException("PHP $phpVersion 版本太低, 需要 PHP {$needPHPVersion}!如果想忽略版本要求, s可使用 {ignorePlatFormReqs} 方法然后安装");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function ignorePlatFormReqs(): static
|
||||
{
|
||||
$this->ignorePlatformReqs = true;
|
||||
|
||||
return $this;
|
||||
}
|
||||
}
|
55
catch/src/Support/DB/Query.php
Normal file
55
catch/src/Support/DB/Query.php
Normal file
@ -0,0 +1,55 @@
|
||||
<?php
|
||||
|
||||
namespace Catch\Support\DB;
|
||||
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use Illuminate\Support\Facades\File;
|
||||
|
||||
class Query
|
||||
{
|
||||
/**
|
||||
* @var string|null
|
||||
*/
|
||||
protected static string|null $log = null;
|
||||
|
||||
/**
|
||||
* @return void
|
||||
*/
|
||||
public static function listen(): void
|
||||
{
|
||||
DB::listen(function ($query) {
|
||||
$sql = str_replace(
|
||||
'?',
|
||||
'%s',
|
||||
sprintf('[%s] '.$query->sql.' | %s ms'.PHP_EOL, date('Y-m-d H:i'), $query->time)
|
||||
);
|
||||
|
||||
static::$log .= vsprintf($sql, $query->bindings);
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @return void
|
||||
*/
|
||||
public static function log(): void
|
||||
{
|
||||
if (static::$log) {
|
||||
$sqlLogPath = storage_path('logs'.DIRECTORY_SEPARATOR.'query'.DIRECTORY_SEPARATOR);
|
||||
|
||||
if (! File::isDirectory($sqlLogPath)) {
|
||||
File::makeDirectory($sqlLogPath, 0777, true);
|
||||
}
|
||||
|
||||
$logFile = $sqlLogPath.date('Ymd').'.log';
|
||||
|
||||
if (! File::exists($logFile)) {
|
||||
File::put($logFile, '', true);
|
||||
}
|
||||
|
||||
file_put_contents($logFile, static::$log.PHP_EOL, LOCK_EX | FILE_APPEND);
|
||||
|
||||
static::$log = null;
|
||||
}
|
||||
}
|
||||
}
|
19
catch/src/Support/DB/SoftDelete.php
Normal file
19
catch/src/Support/DB/SoftDelete.php
Normal file
@ -0,0 +1,19 @@
|
||||
<?php
|
||||
|
||||
namespace Catch\Support\DB;
|
||||
|
||||
use Illuminate\Database\Eloquent\Builder;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Database\Eloquent\SoftDeletingScope;
|
||||
|
||||
class SoftDelete extends SoftDeletingScope
|
||||
{
|
||||
/**
|
||||
* @param Builder $builder
|
||||
* @param Model $model
|
||||
*/
|
||||
public function apply(Builder $builder, Model $model)
|
||||
{
|
||||
$builder->where($model->getQualifiedDeletedAtColumn(), '=', 0);
|
||||
}
|
||||
}
|
140
catch/src/Support/Macros/Blueprint.php
Normal file
140
catch/src/Support/Macros/Blueprint.php
Normal file
@ -0,0 +1,140 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Catch\Support\Macros;
|
||||
|
||||
use Illuminate\Database\Schema\Blueprint as LaravelBlueprint;
|
||||
|
||||
class Blueprint
|
||||
{
|
||||
/**
|
||||
* boot;
|
||||
*/
|
||||
public static function boot(): void
|
||||
{
|
||||
$bluePrint = new static();
|
||||
|
||||
$bluePrint->createdAt();
|
||||
|
||||
$bluePrint->updatedAt();
|
||||
|
||||
$bluePrint->deletedAt();
|
||||
|
||||
$bluePrint->status();
|
||||
|
||||
$bluePrint->creatorId();
|
||||
|
||||
$bluePrint->unixTimestamp();
|
||||
|
||||
$bluePrint->parentId();
|
||||
|
||||
$bluePrint->sort();
|
||||
}
|
||||
|
||||
/**
|
||||
* created unix timestamp
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function createdAt(): void
|
||||
{
|
||||
LaravelBlueprint::macro(__FUNCTION__, function () {
|
||||
$this->unsignedInteger('created_at')->default(0)->comment('created time');
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* update unix timestamp
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function updatedAt(): void
|
||||
{
|
||||
LaravelBlueprint::macro(__FUNCTION__, function () {
|
||||
$this->unsignedInteger('updated_at')->default(0)->comment('updated time');
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* soft delete
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function deletedAt(): void
|
||||
{
|
||||
LaravelBlueprint::macro(__FUNCTION__, function () {
|
||||
$this->unsignedInteger('deleted_at')->default(0)->comment('delete time');
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* unix timestamp
|
||||
*
|
||||
* @param bool $softDeleted
|
||||
* @return void
|
||||
*/
|
||||
public function unixTimestamp(bool $softDeleted = true): void
|
||||
{
|
||||
LaravelBlueprint::macro(__FUNCTION__, function () use ($softDeleted) {
|
||||
$this->createdAt();
|
||||
$this->updatedAt();
|
||||
|
||||
if ($softDeleted) {
|
||||
$this->deletedAt();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* creator id
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function creatorId(): void
|
||||
{
|
||||
LaravelBlueprint::macro(__FUNCTION__, function () {
|
||||
$this->unsignedInteger('creator_id')->default(0)->comment('creator id');
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* parent ID
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function parentId(): void
|
||||
{
|
||||
LaravelBlueprint::macro(__FUNCTION__, function () {
|
||||
$this->unsignedInteger('parent_id')->default(0)->comment('parent id');
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* status
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function status(): void
|
||||
{
|
||||
LaravelBlueprint::macro(__FUNCTION__, function ($default = 1) {
|
||||
$this->tinyInteger('status')->default($default)->comment('1:normal 2: forbidden');
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* sort
|
||||
*
|
||||
* @param int $default
|
||||
* @return void
|
||||
*/
|
||||
public function sort(int $default = 1): void
|
||||
{
|
||||
LaravelBlueprint::macro(__FUNCTION__, function () use ($default) {
|
||||
$this->integer('sort')->comment('sort')->default($default);
|
||||
});
|
||||
}
|
||||
}
|
107
catch/src/Support/Macros/Builder.php
Normal file
107
catch/src/Support/Macros/Builder.php
Normal file
@ -0,0 +1,107 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Catch\Support\Macros;
|
||||
|
||||
use Illuminate\Support\Str;
|
||||
use Illuminate\Database\Eloquent\Builder as LaravelBuilder;
|
||||
|
||||
class Builder
|
||||
{
|
||||
/**
|
||||
* boot
|
||||
*/
|
||||
public static function boot(): void
|
||||
{
|
||||
$builder = new static();
|
||||
|
||||
$builder->whereLike();
|
||||
|
||||
$builder->quickSearch();
|
||||
|
||||
$builder->tree();
|
||||
}
|
||||
|
||||
/**
|
||||
* where like
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function whereLike(): void
|
||||
{
|
||||
LaravelBuilder::macro(__FUNCTION__, function ($filed, $value) {
|
||||
return $this->where($filed, 'like', "%$value%");
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* quick search
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function quickSearch(): void
|
||||
{
|
||||
LaravelBuilder::macro(__FUNCTION__, function (array $params = []) {
|
||||
$params = array_merge(request()->all(), $params);
|
||||
|
||||
if (! property_exists($this->model, 'searchable')) {
|
||||
return $this;
|
||||
}
|
||||
|
||||
// filter null & empty string
|
||||
$params = array_filter($params, function ($value) {
|
||||
return (is_string($value) && strlen($value)) || is_numeric($value);
|
||||
});
|
||||
|
||||
$wheres = [];
|
||||
|
||||
if (! empty($this->model->searchable)) {
|
||||
foreach ($this->model->searchable as $field => $op) {
|
||||
// 临时变量
|
||||
$_field = $field;
|
||||
// contains alias
|
||||
if (str_contains($field, '.')) {
|
||||
[, $_field] = explode('.', $field);
|
||||
}
|
||||
|
||||
if (isset($params[$_field])) {
|
||||
$opString = Str::of($op)->lower();
|
||||
if ($opString->exactly('op')) {
|
||||
$value = implode(',', $params[$_field]);
|
||||
} elseif ($opString->exactly('like')) {
|
||||
$value = "%{$params[$_field]}%";
|
||||
} elseif ($opString->exactly('rlike')) {
|
||||
$value = "{$params[$_field]}%";
|
||||
} elseif ($opString->exactly('llike')) {
|
||||
$value = "%{$params[$_field]}";
|
||||
} else {
|
||||
$value = $params[$_field];
|
||||
}
|
||||
$wheres[] = [$field, $op, $value];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$this->where($wheres);
|
||||
|
||||
return $this;
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* where like
|
||||
*
|
||||
* @time 2021年08月06日
|
||||
* @return void
|
||||
*/
|
||||
public function tree(): void
|
||||
{
|
||||
LaravelBuilder::macro(__FUNCTION__, function (string $id, string $parentId, ...$fields) {
|
||||
$fields = array_merge([$id, $parentId], $fields);
|
||||
|
||||
return $this->get($fields)->toTree(0, $parentId);
|
||||
});
|
||||
}
|
||||
}
|
65
catch/src/Support/Macros/Collection.php
Normal file
65
catch/src/Support/Macros/Collection.php
Normal file
@ -0,0 +1,65 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Catch\Support\Macros;
|
||||
|
||||
use Catch\Support\Tree;
|
||||
use Illuminate\Contracts\Support\Arrayable;
|
||||
use Illuminate\Support\Collection as LaravelCollection;
|
||||
|
||||
class Collection
|
||||
{
|
||||
/**
|
||||
* boot
|
||||
*/
|
||||
public static function boot(): void
|
||||
{
|
||||
$collection = new static();
|
||||
|
||||
$collection->toOptions();
|
||||
|
||||
$collection->toTree();
|
||||
}
|
||||
|
||||
/**
|
||||
* collection to tree
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function toTree(): void
|
||||
{
|
||||
LaravelCollection::macro(__FUNCTION__, function (int $pid = 0, string $pidField = 'parent_id', string $child = 'children') {
|
||||
return Tree::done($this->all(), $pid, $pidField, $child);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* toOptions
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function toOptions(): void
|
||||
{
|
||||
LaravelCollection::macro(__FUNCTION__, function () {
|
||||
return $this->transform(function ($item, $key) use (&$options) {
|
||||
if ($item instanceof Arrayable) {
|
||||
$item = $item->toArray();
|
||||
}
|
||||
|
||||
if (is_array($item)) {
|
||||
$item = array_values($item);
|
||||
return [
|
||||
'value' => $item[0],
|
||||
'label' => $item[1]
|
||||
];
|
||||
} else {
|
||||
return [
|
||||
'value' => $key,
|
||||
'label' => $item
|
||||
];
|
||||
}
|
||||
})->values();
|
||||
});
|
||||
}
|
||||
}
|
23
catch/src/Support/Macros/Register.php
Normal file
23
catch/src/Support/Macros/Register.php
Normal file
@ -0,0 +1,23 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Catch\Support\Macros;
|
||||
|
||||
/**
|
||||
* boot
|
||||
*/
|
||||
class Register
|
||||
{
|
||||
/**
|
||||
* macros boot
|
||||
*/
|
||||
public static function boot(): void
|
||||
{
|
||||
Blueprint::boot();
|
||||
|
||||
Collection::boot();
|
||||
|
||||
Builder::boot();
|
||||
}
|
||||
}
|
171
catch/src/Support/Module/Driver/DatabaseDriver.php
Normal file
171
catch/src/Support/Module/Driver/DatabaseDriver.php
Normal file
@ -0,0 +1,171 @@
|
||||
<?php
|
||||
|
||||
// +----------------------------------------------------------------------
|
||||
// | CatchAdmin [Just Like ~ ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | Copyright (c) 2017~2021 https://catchadmin.com All rights reserved.
|
||||
// +----------------------------------------------------------------------
|
||||
// | Licensed ( https://github.com/JaguarJack/catchadmin-laravel/blob/master/LICENSE.md )
|
||||
// +----------------------------------------------------------------------
|
||||
// | Author: JaguarJack [ njphper@gmail.com ]
|
||||
// +----------------------------------------------------------------------
|
||||
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Catch\Support\Module\Driver;
|
||||
|
||||
use Catch\CatchAdmin;
|
||||
use Catch\Contracts\ModuleRepositoryInterface;
|
||||
use Catch\Enums\Status;
|
||||
use Catch\Exceptions\FailedException;
|
||||
use Illuminate\Container\Container;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Support\Collection;
|
||||
|
||||
/**
|
||||
* DatabaseDriver
|
||||
*/
|
||||
class DatabaseDriver implements ModuleRepositoryInterface
|
||||
{
|
||||
protected Model $model;
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
$this->model = $this->createModuleModel();
|
||||
}
|
||||
|
||||
/**
|
||||
* all
|
||||
*
|
||||
* @param array $search
|
||||
* @return Collection
|
||||
*/
|
||||
public function all(array $search): Collection
|
||||
{
|
||||
return $this->model::query()
|
||||
->when($search['name'] ?? false, function ($query) use ($search) {
|
||||
$query->where('name', 'like', '%'.$search['name'].'%');
|
||||
})->get();
|
||||
}
|
||||
|
||||
/**
|
||||
* create module json
|
||||
*
|
||||
* @param array $module
|
||||
* @return bool|int
|
||||
*/
|
||||
public function create(array $module): bool|int
|
||||
{
|
||||
$this->hasSameModule($module);
|
||||
|
||||
return $this->model->save([
|
||||
'name' => $module['name'],
|
||||
'path' => $module['path'],
|
||||
'description' => $module['desc'],
|
||||
'keywords' => $module['keywords'],
|
||||
'service' => sprintf('\\%s%s', CatchAdmin::getModuleNamespace($module['name']), ucfirst($module['name']).'ServiceProvider'),
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* module info
|
||||
*
|
||||
* @param string $name
|
||||
* @return Collection
|
||||
*/
|
||||
public function show(string $name): Collection
|
||||
{
|
||||
return $this->model->where('name', $name)->first();
|
||||
}
|
||||
|
||||
/**
|
||||
* update module json
|
||||
*
|
||||
* @param string $name
|
||||
* @param array $module
|
||||
* @return bool|int
|
||||
*/
|
||||
public function update(string $name, array $module): bool|int
|
||||
{
|
||||
return $this->model->where('name', $name)
|
||||
|
||||
->update([
|
||||
'name' => $module['name'],
|
||||
'alias' => $module['alias'],
|
||||
'description' => $module['desc'],
|
||||
'keywords' => $module['keywords'],
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* delete module json
|
||||
*
|
||||
* @param string $name
|
||||
* @return bool|int
|
||||
*/
|
||||
public function delete(string $name): bool|int
|
||||
{
|
||||
return $this->model->where('name', $name)->delete();
|
||||
}
|
||||
|
||||
/**
|
||||
* disable or enable
|
||||
*
|
||||
* @param $name
|
||||
* @return bool|int
|
||||
*/
|
||||
public function disOrEnable($name): bool|int
|
||||
{
|
||||
$module = $this->show($name);
|
||||
|
||||
$module->status = (int) $module->status;
|
||||
|
||||
return $module->save();
|
||||
}
|
||||
|
||||
/**
|
||||
* get enabled
|
||||
*
|
||||
* @return Collection
|
||||
*/
|
||||
public function getEnabled(): Collection
|
||||
{
|
||||
// TODO: Implement getEnabled() method.
|
||||
return $this->model->where('status', Status::Enable->value())->get();
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param array $module
|
||||
* @return void
|
||||
*/
|
||||
protected function hasSameModule(array $module): void
|
||||
{
|
||||
if ($this->model->where('name', $module['name'])->first()) {
|
||||
throw new FailedException(sprintf('Module [%s] has been created', $module['name']));
|
||||
}
|
||||
|
||||
if ($this->model->where('alias', $module['alias'])->first()) {
|
||||
throw new FailedException(sprintf('Module Alias [%s] has been exised', $module['alias']));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* create model
|
||||
* @return Model
|
||||
*/
|
||||
protected function createModuleModel(): Model
|
||||
{
|
||||
return new class () extends Model {
|
||||
protected $table;
|
||||
|
||||
public function __construct(array $attributes = [])
|
||||
{
|
||||
parent::__construct($attributes);
|
||||
|
||||
$this->table = Container::getInstance()->make('config')->get('catch.module.driver.table_name');
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
193
catch/src/Support/Module/Driver/FileDriver.php
Normal file
193
catch/src/Support/Module/Driver/FileDriver.php
Normal file
@ -0,0 +1,193 @@
|
||||
<?php
|
||||
|
||||
// +----------------------------------------------------------------------
|
||||
// | CatchAdmin [Just Like ~ ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | Copyright (c) 2017~2021 https://catchadmin.com All rights reserved.
|
||||
// +----------------------------------------------------------------------
|
||||
// | Licensed ( https://github.com/JaguarJack/catchadmin-laravel/blob/master/LICENSE.md )
|
||||
// +----------------------------------------------------------------------
|
||||
// | Author: JaguarJack [ njphper@gmail.com ]
|
||||
// +----------------------------------------------------------------------
|
||||
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Catch\Support\Module\Driver;
|
||||
|
||||
use Catch\CatchAdmin;
|
||||
use Catch\Contracts\ModuleRepositoryInterface;
|
||||
use Catch\Exceptions\FailedException;
|
||||
use Illuminate\Support\Collection;
|
||||
use Illuminate\Support\Facades\File;
|
||||
use Illuminate\Support\Str;
|
||||
|
||||
/**
|
||||
* FileDriver
|
||||
*/
|
||||
class FileDriver implements ModuleRepositoryInterface
|
||||
{
|
||||
protected string $moduleJson;
|
||||
|
||||
/**
|
||||
* construct
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
$this->moduleJson = storage_path('app').DIRECTORY_SEPARATOR.'modules.json';
|
||||
}
|
||||
|
||||
/**
|
||||
* all
|
||||
*
|
||||
* @param array $search
|
||||
* @return Collection
|
||||
*/
|
||||
public function all(array $search = []): Collection
|
||||
{
|
||||
if (! File::exists($this->moduleJson)) {
|
||||
return Collection::make([]);
|
||||
}
|
||||
|
||||
if (! Str::length(File::get($this->moduleJson))) {
|
||||
return Collection::make([]);
|
||||
}
|
||||
|
||||
$modules = Collection::make(\json_decode(File::get($this->moduleJson), true))->values();
|
||||
|
||||
$name = $search['name'] ?? '';
|
||||
|
||||
if (! $name) {
|
||||
return $modules;
|
||||
}
|
||||
|
||||
return $modules->filter(function ($module) use ($name) {
|
||||
return Str::of($module['name'])->contains($name);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* create module json
|
||||
*
|
||||
* @param array $module
|
||||
* @return bool
|
||||
*/
|
||||
public function create(array $module): bool
|
||||
{
|
||||
$modules = $this->all();
|
||||
|
||||
$this->hasSameModule($module, $modules);
|
||||
|
||||
$module['service'] = sprintf('\\%s', CatchAdmin::getModuleServiceProvider($module['path']));
|
||||
$module['version'] = '1.0.0';
|
||||
$module['enable'] = true;
|
||||
|
||||
File::put($this->moduleJson, $modules->push($module)->toJson(JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* module info
|
||||
*
|
||||
* @param string $name
|
||||
* @return Collection
|
||||
*/
|
||||
public function show(string $name): Collection
|
||||
{
|
||||
foreach ($this->all() as $module) {
|
||||
if (Str::of($module['name'])->exactly($name)) {
|
||||
return Collection::make($module);
|
||||
}
|
||||
}
|
||||
|
||||
throw new FailedException("Module [$name] not Found");
|
||||
}
|
||||
|
||||
/**
|
||||
* update module json
|
||||
*
|
||||
* @param string $name
|
||||
* @param array $module
|
||||
* @return bool
|
||||
*/
|
||||
public function update(string $name, array $module): bool
|
||||
{
|
||||
File::put($this->moduleJson, $this->all()->map(function ($m) use ($module, $name) {
|
||||
if (Str::of($name)->exactly($m['name'])) {
|
||||
$m['path'] = $module['path'];
|
||||
$m['name'] = $module['name'];
|
||||
$m['description'] = $module['description'] ?? '';
|
||||
$m['keywords'] = $module['keywords'] ?? '';
|
||||
$m['enable'] = $module['enable'];
|
||||
}
|
||||
return $m;
|
||||
})->toJson(JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* delete module json
|
||||
*
|
||||
* @param string $name
|
||||
* @return bool
|
||||
*/
|
||||
public function delete(string $name): bool
|
||||
{
|
||||
File::put($this->moduleJson, $this->all()->filter(function ($module) use ($name) {
|
||||
if (! Str::of($name)->exactly($module['name'])) {
|
||||
return $module;
|
||||
}
|
||||
})->toJson(JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE));
|
||||
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* disable or enable
|
||||
*
|
||||
* @param $name
|
||||
* @return bool|int
|
||||
*/
|
||||
public function disOrEnable($name): bool|int
|
||||
{
|
||||
return File::put($this->moduleJson, $this->all()->map(function ($module) use ($name) {
|
||||
if (Str::of($module['name'])->exactly($name)) {
|
||||
$module['enable'] = ! $module['enable'];
|
||||
}
|
||||
return $module;
|
||||
})->toJson(JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE));
|
||||
}
|
||||
|
||||
/**
|
||||
* get enabled
|
||||
*
|
||||
* @return Collection
|
||||
*/
|
||||
public function getEnabled(): Collection
|
||||
{
|
||||
// TODO: Implement getEnabled() method.
|
||||
return $this->all()->where('enable', true)->values();
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param array $module
|
||||
* @param Collection $modules
|
||||
* @return void
|
||||
*/
|
||||
protected function hasSameModule(array $module, Collection $modules): void
|
||||
{
|
||||
if ($modules->count()) {
|
||||
if ($modules->pluck('name')->contains($module['name'])) {
|
||||
throw new FailedException(sprintf('Module [%s] has been created', $module['name']));
|
||||
}
|
||||
|
||||
if ($modules->pluck('path')->contains($module['path'])) {
|
||||
throw new FailedException(sprintf('Module path [%s] has been existed', $module['path']));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
97
catch/src/Support/Module/Installer.php
Normal file
97
catch/src/Support/Module/Installer.php
Normal file
@ -0,0 +1,97 @@
|
||||
<?php
|
||||
|
||||
namespace Catch\Support\Module;
|
||||
|
||||
use Catch\Contracts\ModuleRepositoryInterface;
|
||||
use Catch\Support\Composer;
|
||||
|
||||
/**
|
||||
* installer
|
||||
*/
|
||||
abstract class Installer
|
||||
{
|
||||
/**
|
||||
* construct
|
||||
*
|
||||
* @param ModuleRepositoryInterface $moduleRepository
|
||||
*/
|
||||
public function __construct(protected ModuleRepositoryInterface $moduleRepository)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* module info
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
abstract protected function info(): array;
|
||||
|
||||
/**
|
||||
* migration
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
abstract protected function migration(): string;
|
||||
|
||||
/**
|
||||
* seed
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
abstract protected function seeder(): string;
|
||||
|
||||
/**
|
||||
* require packages
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
abstract protected function requirePackages(): void;
|
||||
|
||||
|
||||
/**
|
||||
* remove packages
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
abstract protected function removePackages(): void;
|
||||
|
||||
/**
|
||||
* uninstall
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function uninstall(): void
|
||||
{
|
||||
$this->moduleRepository->delete($this->info()['name']);
|
||||
|
||||
|
||||
$this->removePackages();
|
||||
}
|
||||
|
||||
/**
|
||||
* invoke
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function __invoke(): void
|
||||
{
|
||||
// TODO: Implement __invoke() method.
|
||||
$this->moduleRepository->create($this->info());
|
||||
|
||||
// migration
|
||||
|
||||
// seed
|
||||
|
||||
$this->requirePackages();
|
||||
}
|
||||
|
||||
/**
|
||||
* composer installer
|
||||
*
|
||||
* @return Composer
|
||||
*/
|
||||
protected function composer(): Composer
|
||||
{
|
||||
return app(Composer::class);
|
||||
}
|
||||
}
|
63
catch/src/Support/Module/ModuleManager.php
Normal file
63
catch/src/Support/Module/ModuleManager.php
Normal file
@ -0,0 +1,63 @@
|
||||
<?php
|
||||
|
||||
// +----------------------------------------------------------------------
|
||||
// | CatchAdmin [Just Like ~ ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | Copyright (c) 2017~2021 https://catchadmin.com All rights reserved.
|
||||
// +----------------------------------------------------------------------
|
||||
// | Licensed ( https://github.com/JaguarJack/catchadmin-laravel/blob/master/LICENSE.md )
|
||||
// +----------------------------------------------------------------------
|
||||
// | Author: JaguarJack [ njphper@gmail.com ]
|
||||
// +----------------------------------------------------------------------
|
||||
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Catch\Support\Module;
|
||||
|
||||
use Catch\Support\Module\Driver\DatabaseDriver;
|
||||
use Catch\Support\Module\Driver\FileDriver;
|
||||
use Illuminate\Contracts\Container\Container;
|
||||
use Illuminate\Support\Facades\File;
|
||||
use Illuminate\Support\Manager;
|
||||
|
||||
class ModuleManager extends Manager
|
||||
{
|
||||
public function __construct(Container|\Closure $container)
|
||||
{
|
||||
if ($container instanceof \Closure) {
|
||||
$container = $container();
|
||||
}
|
||||
|
||||
parent::__construct($container);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getDefaultDriver(): string
|
||||
{
|
||||
// TODO: Implement getDefaultDriver() method.
|
||||
return $this->config->get('catch.module.driver.default');
|
||||
}
|
||||
|
||||
/**
|
||||
* create file driver
|
||||
*
|
||||
* @return FileDriver
|
||||
*/
|
||||
public function createFileDriver(): FileDriver
|
||||
{
|
||||
return new FileDriver();
|
||||
}
|
||||
|
||||
/**
|
||||
* create database driver
|
||||
*
|
||||
* @return DatabaseDriver
|
||||
*/
|
||||
public function createDatabaseDriver(): DatabaseDriver
|
||||
{
|
||||
return new DatabaseDriver();
|
||||
}
|
||||
}
|
144
catch/src/Support/Module/ModuleRepository.php
Normal file
144
catch/src/Support/Module/ModuleRepository.php
Normal file
@ -0,0 +1,144 @@
|
||||
<?php
|
||||
|
||||
// +----------------------------------------------------------------------
|
||||
// | CatchAdmin [Just Like ~ ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | Copyright (c) 2017~2021 https://catchadmin.com All rights reserved.
|
||||
// +----------------------------------------------------------------------
|
||||
// | Licensed ( https://github.com/JaguarJack/catchadmin-laravel/blob/master/LICENSE.md )
|
||||
// +----------------------------------------------------------------------
|
||||
// | Author: JaguarJack [ njphper@gmail.com ]
|
||||
// +----------------------------------------------------------------------
|
||||
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Catch\Support\Module;
|
||||
|
||||
use Catch\Contracts\ModuleRepositoryInterface;
|
||||
use Catch\Events\Module\Created;
|
||||
use Catch\Events\Module\Creating;
|
||||
use Catch\Events\Module\Deleted;
|
||||
use Catch\Events\Module\Updated;
|
||||
use Catch\Events\Module\Updating;
|
||||
use Exception;
|
||||
use Illuminate\Support\Collection;
|
||||
use Illuminate\Support\Facades\Event;
|
||||
|
||||
/**
|
||||
* FileDriver
|
||||
*/
|
||||
class ModuleRepository
|
||||
{
|
||||
protected ModuleRepositoryInterface $moduleRepository;
|
||||
|
||||
/**
|
||||
* construct
|
||||
*/
|
||||
public function __construct(ModuleRepositoryInterface $moduleRepository)
|
||||
{
|
||||
$this->moduleRepository = $moduleRepository;
|
||||
}
|
||||
|
||||
/**
|
||||
* all
|
||||
*
|
||||
* @param array $search
|
||||
* @return Collection
|
||||
*/
|
||||
public function all(array $search): Collection
|
||||
{
|
||||
return $this->moduleRepository->all($search);
|
||||
}
|
||||
|
||||
/**
|
||||
* create module json
|
||||
*
|
||||
* @param array $module
|
||||
* @return bool
|
||||
*/
|
||||
public function create(array $module): bool
|
||||
{
|
||||
Event::dispatch(new Creating($module));
|
||||
|
||||
$this->moduleRepository->create($module);
|
||||
|
||||
Event::dispatch(new Created($module));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* module info
|
||||
*
|
||||
* @param string $name
|
||||
* @return Collection
|
||||
* @throws Exception
|
||||
*/
|
||||
public function show(string $name): Collection
|
||||
{
|
||||
try {
|
||||
return $this->moduleRepository->show($name);
|
||||
} catch (Exception $e) {
|
||||
throw new $e();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* update module json
|
||||
*
|
||||
* @param string $name
|
||||
* @param array $module
|
||||
* @return bool
|
||||
*/
|
||||
public function update(string $name, array $module): bool
|
||||
{
|
||||
Event::dispatch(new Updating($name, $module));
|
||||
|
||||
$this->moduleRepository->update($name, $module);
|
||||
|
||||
Event::dispatch(new Updated($name, $module));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* delete module json
|
||||
*
|
||||
* @param string $name
|
||||
* @return bool
|
||||
* @throws Exception
|
||||
*/
|
||||
public function delete(string $name): bool
|
||||
{
|
||||
$module = $this->show($name);
|
||||
|
||||
$this->moduleRepository->delete($name);
|
||||
|
||||
Event::dispatch(new Deleted($module));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* disable or enable
|
||||
*
|
||||
* @param string $name
|
||||
* @return bool|int
|
||||
*/
|
||||
public function disOrEnable(string $name): bool|int
|
||||
{
|
||||
return $this->moduleRepository->disOrEnable($name);
|
||||
}
|
||||
|
||||
/**
|
||||
* get enabled
|
||||
*
|
||||
* @return Collection
|
||||
*/
|
||||
public function getEnabled(): Collection
|
||||
{
|
||||
// TODO: Implement getEnabled() method.
|
||||
return $this->moduleRepository->getEnabled();
|
||||
}
|
||||
}
|
61
catch/src/Support/Tree.php
Normal file
61
catch/src/Support/Tree.php
Normal file
@ -0,0 +1,61 @@
|
||||
<?php
|
||||
|
||||
// +----------------------------------------------------------------------
|
||||
// | CatchAdmin [Just Like ~ ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | Copyright (c) 2017~2021 https://catchadmin.com All rights reserved.
|
||||
// +----------------------------------------------------------------------
|
||||
// | Licensed ( https://github.com/JaguarJack/catchadmin-laravel/blob/master/LICENSE.md )
|
||||
// +----------------------------------------------------------------------
|
||||
// | Author: JaguarJack [ njphper@gmail.com ]
|
||||
// +----------------------------------------------------------------------
|
||||
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Catch\Support;
|
||||
|
||||
class Tree
|
||||
{
|
||||
protected static string $pk = 'id';
|
||||
|
||||
/**
|
||||
*
|
||||
* @param string $pk
|
||||
* @return Tree
|
||||
*/
|
||||
public static function setPk(string $pk): Tree
|
||||
{
|
||||
self::$pk = $pk;
|
||||
|
||||
return new self();
|
||||
}
|
||||
|
||||
/**
|
||||
* return done
|
||||
*
|
||||
* @param array $items
|
||||
* @param int $pid
|
||||
* @param string $pidField
|
||||
* @param string $child
|
||||
* @return array
|
||||
*/
|
||||
public static function done(array $items, int $pid = 0, string $pidField = 'parent_id', string $child = 'children'): array
|
||||
{
|
||||
$tree = [];
|
||||
|
||||
foreach ($items as $item) {
|
||||
if ($item[$pidField] == $pid) {
|
||||
$children = self::done($items, $item[self::$pk], $pidField, $child);
|
||||
|
||||
if (count($children)) {
|
||||
$item[$child] = $children;
|
||||
}
|
||||
|
||||
$tree[] = $item;
|
||||
}
|
||||
}
|
||||
|
||||
return $tree;
|
||||
}
|
||||
}
|
200
catch/src/Support/Zip/ZipRepository.php
Normal file
200
catch/src/Support/Zip/ZipRepository.php
Normal file
@ -0,0 +1,200 @@
|
||||
<?php
|
||||
|
||||
// +----------------------------------------------------------------------
|
||||
// | CatchAdmin [Just Like ~ ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | Copyright (c) 2017~2021 https://catchadmin.com All rights reserved.
|
||||
// +----------------------------------------------------------------------
|
||||
// | Licensed ( https://github.com/JaguarJack/catchadmin-laravel/blob/master/LICENSE.md )
|
||||
// +----------------------------------------------------------------------
|
||||
// | Author: JaguarJack [ njphper@gmail.com ]
|
||||
// +----------------------------------------------------------------------
|
||||
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Catch\Support\Zip;
|
||||
|
||||
use Exception;
|
||||
use ZipArchive;
|
||||
|
||||
class ZipRepository
|
||||
{
|
||||
private mixed $archive;
|
||||
|
||||
/**
|
||||
* Construct with a given path
|
||||
*
|
||||
* @param $filePath
|
||||
* @param bool $create
|
||||
* @param $archive
|
||||
*
|
||||
* @return void
|
||||
* @throws Exception
|
||||
*
|
||||
*/
|
||||
public function __construct($filePath, bool $create, $archive = null)
|
||||
{
|
||||
//Check if ZipArchive is available
|
||||
if (! class_exists('ZipArchive')) {
|
||||
throw new Exception('Error: Your PHP version is not compiled with zip support');
|
||||
}
|
||||
$this->archive = $archive ? $archive : new ZipArchive();
|
||||
|
||||
$res = $this->archive->open($filePath, ($create ? ZipArchive::CREATE : 0));
|
||||
if ($res !== true) {
|
||||
throw new Exception("Error: Failed to open $filePath! Error: ".$this->getErrorMessage($res));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a file to the opened Archive
|
||||
*
|
||||
* @param $pathToFile
|
||||
* @param $pathInArchive
|
||||
*/
|
||||
public function addFile($pathToFile, $pathInArchive): void
|
||||
{
|
||||
$this->archive->addFile($pathToFile, $pathInArchive);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add an empty directory
|
||||
*
|
||||
* @param $dirName
|
||||
*/
|
||||
public function addEmptyDir($dirName): void
|
||||
{
|
||||
$this->archive->addEmptyDir($dirName);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a file to the opened Archive using its contents
|
||||
*
|
||||
* @param string $name
|
||||
* @param $content
|
||||
*/
|
||||
public function addFromString(string $name, $content): void
|
||||
{
|
||||
$this->archive->addFromString($name, $content);
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove a file permanently from the Archive
|
||||
*
|
||||
* @param string $pathInArchive
|
||||
*/
|
||||
public function removeFile(string $pathInArchive): void
|
||||
{
|
||||
$this->archive->deleteName($pathInArchive);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the content of a file
|
||||
*
|
||||
* @param string $pathInArchive
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getFileContent(string $pathInArchive): string
|
||||
{
|
||||
return $this->archive->getFromName($pathInArchive);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the stream of a file
|
||||
*
|
||||
* @param string $pathInArchive
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function getFileStream(string $pathInArchive): bool
|
||||
{
|
||||
return $this->archive->getStream($pathInArchive);
|
||||
}
|
||||
|
||||
/**
|
||||
* Will loop over every item in the archive and will execute the callback on them
|
||||
* Will provide the filename for every item
|
||||
*
|
||||
* @param $callback
|
||||
*/
|
||||
public function each($callback): void
|
||||
{
|
||||
for ($i = 0; $i < $this->archive->numFiles; ++$i) {
|
||||
//skip if folder
|
||||
$stats = $this->archive->statIndex($i);
|
||||
if ($stats['size'] === 0 && $stats['crc'] === 0) {
|
||||
continue;
|
||||
}
|
||||
call_user_func_array($callback, [
|
||||
'file' => $this->archive->getNameIndex($i),
|
||||
'stats' => $this->archive->statIndex($i)
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks whether the file is in the archive
|
||||
*
|
||||
* @param $fileInArchive
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function fileExists($fileInArchive): bool
|
||||
{
|
||||
return $this->archive->locateName($fileInArchive) !== false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the password to be used for decompressing
|
||||
* function named usePassword for clarity
|
||||
*
|
||||
* @param $password
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function usePassword($password): bool
|
||||
{
|
||||
return $this->archive->setPassword($password);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the status of the archive as a string
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getStatus(): string
|
||||
{
|
||||
return $this->archive->getStatusString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Closes the archive and saves it
|
||||
*/
|
||||
public function close(): void
|
||||
{
|
||||
@$this->archive->close();
|
||||
}
|
||||
|
||||
/**
|
||||
* get error message
|
||||
*
|
||||
* @param $resultCode
|
||||
* @return string
|
||||
*/
|
||||
private function getErrorMessage($resultCode): string
|
||||
{
|
||||
return match ($resultCode) {
|
||||
ZipArchive::ER_EXISTS => 'ZipArchive::ER_EXISTS - File already exists.',
|
||||
ZipArchive::ER_INCONS => 'ZipArchive::ER_INCONS - Zip archive inconsistent.',
|
||||
ZipArchive::ER_MEMORY => 'ZipArchive::ER_MEMORY - Malloc failure.',
|
||||
ZipArchive::ER_NOENT => 'ZipArchive::ER_NOENT - No such file.',
|
||||
ZipArchive::ER_NOZIP => 'ZipArchive::ER_NOZIP - Not a zip archive.',
|
||||
ZipArchive::ER_OPEN => 'ZipArchive::ER_OPEN - Can\'t open file.',
|
||||
ZipArchive::ER_READ => 'ZipArchive::ER_READ - Read error.',
|
||||
ZipArchive::ER_SEEK => 'ZipArchive::ER_SEEK - Seek error.',
|
||||
default => "An unknown error [$resultCode] has occurred.",
|
||||
};
|
||||
}
|
||||
}
|
626
catch/src/Support/Zip/Zipper.php
Normal file
626
catch/src/Support/Zip/Zipper.php
Normal file
@ -0,0 +1,626 @@
|
||||
<?php
|
||||
|
||||
// +----------------------------------------------------------------------
|
||||
// | CatchAdmin [Just Like ~ ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | Copyright (c) 2017~2021 https://catchadmin.com All rights reserved.
|
||||
// +----------------------------------------------------------------------
|
||||
// | Licensed ( https://github.com/JaguarJack/catchadmin-laravel/blob/master/LICENSE.md )
|
||||
// +----------------------------------------------------------------------
|
||||
// | Author: JaguarJack [ njphper@gmail.com ]
|
||||
// +----------------------------------------------------------------------
|
||||
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Catch\Support\Zip;
|
||||
|
||||
use Exception;
|
||||
use Illuminate\Filesystem\Filesystem;
|
||||
use Illuminate\Support\Str;
|
||||
use InvalidArgumentException;
|
||||
use RuntimeException;
|
||||
|
||||
/**
|
||||
* This Zipper class is a wrapper around the ZipArchive methods with some handy functions
|
||||
*
|
||||
* Class Zipper
|
||||
*
|
||||
*/
|
||||
class Zipper
|
||||
{
|
||||
/**
|
||||
* Constant for extracting
|
||||
*/
|
||||
public const WHITELIST = 1;
|
||||
|
||||
/**
|
||||
* Constant for extracting
|
||||
*/
|
||||
public const BLACKLIST = 2;
|
||||
|
||||
/**
|
||||
* Constant for matching only strictly equal file names
|
||||
*/
|
||||
public const EXACT_MATCH = 4;
|
||||
|
||||
/**
|
||||
* @var string Represents the current location in the archive
|
||||
*/
|
||||
private string $currentFolder = '';
|
||||
|
||||
/**
|
||||
* @var Filesystem Handler to the file system
|
||||
*/
|
||||
private Filesystem $file;
|
||||
|
||||
/**
|
||||
* @var ZipRepository|null Handler to the archive
|
||||
*/
|
||||
private ?ZipRepository $repository;
|
||||
|
||||
/**
|
||||
* @var string The path to the current zip file
|
||||
*/
|
||||
private string $filePath;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param Filesystem|null $fs
|
||||
*/
|
||||
public function __construct(Filesystem $fs = null)
|
||||
{
|
||||
$this->file = $fs ? $fs : new Filesystem();
|
||||
}
|
||||
|
||||
/**
|
||||
* Destructor
|
||||
*/
|
||||
public function __destruct()
|
||||
{
|
||||
if (is_object($this->repository)) {
|
||||
$this->repository->close();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new zip Archive if the file does not exists
|
||||
* opens a zip archive if the file exists
|
||||
*
|
||||
* @param $pathToFile string The file to open
|
||||
* @return $this Zipper instance
|
||||
* @throws Exception
|
||||
*/
|
||||
public function make(string $pathToFile): Zipper
|
||||
{
|
||||
$new = $this->createArchiveFile($pathToFile);
|
||||
|
||||
$this->repository = new ZipRepository($pathToFile, $new);
|
||||
|
||||
$this->filePath = $pathToFile;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new zip archive or open an existing one
|
||||
*
|
||||
* @param $pathToFile
|
||||
*
|
||||
* @return $this
|
||||
* @throws Exception
|
||||
*
|
||||
*/
|
||||
public function zip($pathToFile): Zipper
|
||||
{
|
||||
$this->make($pathToFile);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new phar file or open one
|
||||
*
|
||||
* @param $pathToFile
|
||||
*
|
||||
* @return $this
|
||||
* @throws Exception
|
||||
*
|
||||
*/
|
||||
public function phar($pathToFile): Zipper
|
||||
{
|
||||
$this->make($pathToFile, 'phar');
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new rar file or open one
|
||||
*
|
||||
* @param $pathToFile
|
||||
*
|
||||
* @return $this
|
||||
* @throws Exception
|
||||
*
|
||||
*/
|
||||
public function rar($pathToFile): Zipper
|
||||
{
|
||||
$this->make($pathToFile, 'rar');
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Extracts the opened zip archive to the specified location <br/>
|
||||
* you can provide an array of files and folders and define if they should be a white list
|
||||
* or a black list to extract. By default this method compares file names using "string starts with" logic
|
||||
*
|
||||
* @param $path string The path to extract to
|
||||
* @param array $files An array of files
|
||||
* @param int $methodFlags The Method the files should be treated
|
||||
*
|
||||
* @throws Exception
|
||||
*/
|
||||
public function extractTo(string $path, array $files = [], int $methodFlags = self::BLACKLIST): void
|
||||
{
|
||||
if (! $this->file->exists($path) && ! $this->file->makeDirectory($path, 0755, true)) {
|
||||
throw new RuntimeException('Failed to create folder');
|
||||
}
|
||||
|
||||
if ($methodFlags & self::EXACT_MATCH) {
|
||||
$matchingMethod = function ($haystack) use ($files) {
|
||||
return in_array($haystack, $files, true);
|
||||
};
|
||||
} else {
|
||||
$matchingMethod = function ($haystack) use ($files) {
|
||||
return Str::startsWith($haystack, $files);
|
||||
};
|
||||
}
|
||||
|
||||
if ($methodFlags & self::WHITELIST) {
|
||||
$this->extractFilesInternal($path, $matchingMethod);
|
||||
} else {
|
||||
// blacklist - extract files that do not match with $matchingMethod
|
||||
$this->extractFilesInternal($path, function ($filename) use ($matchingMethod) {
|
||||
return ! $matchingMethod($filename);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Extracts matching files/folders from the opened zip archive to the specified location.
|
||||
*
|
||||
* @param string $extractToPath The path to extract to
|
||||
* @param string $regex regular expression used to match files. See @link http://php.net/manual/en/reference.pcre.pattern.syntax.php
|
||||
*
|
||||
* @throws InvalidArgumentException
|
||||
* @throws RuntimeException
|
||||
*/
|
||||
public function extractMatchingRegex(string $extractToPath, string $regex): void
|
||||
{
|
||||
if (empty($regex)) {
|
||||
throw new InvalidArgumentException('Missing pass valid regex parameter');
|
||||
}
|
||||
|
||||
$this->extractFilesInternal($extractToPath, function ($filename) use ($regex) {
|
||||
$match = preg_match($regex, $filename);
|
||||
if ($match === 1) {
|
||||
return true;
|
||||
} elseif ($match === false) {
|
||||
//invalid pattern for preg_match raises E_WARNING and returns FALSE
|
||||
//so if you have custom error_handler set to catch and throw E_WARNINGs you never end up here
|
||||
//but if you have not - this will throw exception
|
||||
throw new RuntimeException("regular expression match on '$filename' failed with error. Please check if pattern is valid regular expression.");
|
||||
}
|
||||
|
||||
return false;
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the content of a single file if available
|
||||
*
|
||||
* @param $filePath string The full path (including all folders) of the file in the zip
|
||||
*
|
||||
* @return string returns the content or throws an exception
|
||||
* @throws Exception
|
||||
*
|
||||
*/
|
||||
public function getFileContent(string $filePath): string
|
||||
{
|
||||
if ($this->repository->fileExists($filePath) === false) {
|
||||
throw new Exception(sprintf('The file "%s" cannot be found', $filePath));
|
||||
}
|
||||
return $this->repository->getFileContent($filePath);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add one or multiple files to the zip.
|
||||
*
|
||||
* @param $pathToAdd array|string An array or string of files and folders to add
|
||||
* @param mixed|null $fileName
|
||||
*
|
||||
* @return $this Zipper instance
|
||||
*/
|
||||
public function add(array|string $pathToAdd, mixed $fileName = null): Zipper
|
||||
{
|
||||
if (is_array($pathToAdd)) {
|
||||
foreach ($pathToAdd as $key => $dir) {
|
||||
if (! is_int($key)) {
|
||||
$this->add($dir, $key);
|
||||
} else {
|
||||
$this->add($dir);
|
||||
}
|
||||
}
|
||||
} elseif ($this->file->isFile($pathToAdd)) {
|
||||
if ($fileName) {
|
||||
$this->addFile($pathToAdd, $fileName);
|
||||
} else {
|
||||
$this->addFile($pathToAdd);
|
||||
}
|
||||
} else {
|
||||
$this->addDir($pathToAdd);
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add an empty directory
|
||||
*
|
||||
* @param $dirName
|
||||
*
|
||||
* @return Zipper
|
||||
*/
|
||||
public function addEmptyDir($dirName): Zipper
|
||||
{
|
||||
$this->repository->addEmptyDir($dirName);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a file to the zip using its contents
|
||||
*
|
||||
* @param $filename string The name of the file to create
|
||||
* @param $content string The file contents
|
||||
*
|
||||
* @return $this Zipper instance
|
||||
*/
|
||||
public function addString(string $filename, string $content): Zipper
|
||||
{
|
||||
$this->addFromString($filename, $content);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the status of the zip.
|
||||
*
|
||||
* @return string The status of the internal zip file
|
||||
*/
|
||||
public function getStatus(): string
|
||||
{
|
||||
return $this->repository->getStatus();
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove a file or array of files and folders from the zip archive
|
||||
*
|
||||
* @param $fileToRemove array|string The path/array to the files in the zip
|
||||
*
|
||||
* @return $this Zipper instance
|
||||
*/
|
||||
public function remove(array|string $fileToRemove): Zipper
|
||||
{
|
||||
if (is_array($fileToRemove)) {
|
||||
$self = $this;
|
||||
$this->repository->each(function ($file) use ($fileToRemove, $self) {
|
||||
if (Str::startsWith($file, $fileToRemove)) {
|
||||
$self->getRepository()->removeFile($file);
|
||||
}
|
||||
});
|
||||
} else {
|
||||
$this->repository->removeFile($fileToRemove);
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the path of the current zip file if there is one.
|
||||
*
|
||||
* @return string The path to the file
|
||||
*/
|
||||
public function getFilePath(): string
|
||||
{
|
||||
return $this->filePath;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the password to be used for decompressing
|
||||
*
|
||||
* @param $password
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function usePassword($password): bool
|
||||
{
|
||||
return $this->repository->usePassword($password);
|
||||
}
|
||||
|
||||
/**
|
||||
* Closes the zip file and frees all handles
|
||||
*/
|
||||
public function close(): void
|
||||
{
|
||||
if (null !== $this->repository) {
|
||||
$this->repository->close();
|
||||
}
|
||||
$this->filePath = '';
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the internal folder to the given path.<br/>
|
||||
* Useful for extracting only a segment of a zip file.
|
||||
*
|
||||
* @param string $path
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function folder(string $path): Zipper
|
||||
{
|
||||
$this->currentFolder = $path;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Resets the internal folder to the root of the zip file.
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function home(): Zipper
|
||||
{
|
||||
$this->currentFolder = '';
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Deletes the archive file
|
||||
*/
|
||||
public function delete(): void
|
||||
{
|
||||
if (null !== $this->repository) {
|
||||
$this->repository->close();
|
||||
}
|
||||
|
||||
$this->file->delete($this->filePath);
|
||||
$this->filePath = '';
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the type of the Archive
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getArchiveType(): string
|
||||
{
|
||||
return get_class($this->repository);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the current internal folder pointer
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getCurrentFolderPath(): string
|
||||
{
|
||||
return $this->currentFolder;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if a file is present in the archive
|
||||
*
|
||||
* @param $fileInArchive
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function contains($fileInArchive): bool
|
||||
{
|
||||
return $this->repository->fileExists($fileInArchive);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return ZipRepository
|
||||
*/
|
||||
public function getRepository(): ZipRepository
|
||||
{
|
||||
return $this->repository;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Filesystem
|
||||
*/
|
||||
public function getFileHandler(): Filesystem
|
||||
{
|
||||
return $this->file;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the path to the internal folder
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getInternalPath(): string
|
||||
{
|
||||
return empty($this->currentFolder) ? '' : $this->currentFolder.'/';
|
||||
}
|
||||
|
||||
/**
|
||||
* List all files that are within the archive
|
||||
*
|
||||
* @param string|null $regexFilter regular expression to filter returned files/folders. See @link http://php.net/manual/en/reference.pcre.pattern.syntax.php
|
||||
*
|
||||
* @throws RuntimeException
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function listFiles(string $regexFilter = null): array
|
||||
{
|
||||
$filesList = [];
|
||||
if ($regexFilter) {
|
||||
$filter = function ($file) use (&$filesList, $regexFilter) {
|
||||
// push/pop an error handler here to to make sure no error/exception thrown if $expected is not a regex
|
||||
set_error_handler(function () {
|
||||
});
|
||||
$match = preg_match($regexFilter, $file);
|
||||
restore_error_handler();
|
||||
|
||||
if ($match === 1) {
|
||||
$filesList[] = $file;
|
||||
} elseif ($match === false) {
|
||||
throw new RuntimeException("regular expression match on '$file' failed with error. Please check if pattern is valid regular expression.");
|
||||
}
|
||||
};
|
||||
} else {
|
||||
$filter = function ($file) use (&$filesList) {
|
||||
$filesList[] = $file;
|
||||
};
|
||||
}
|
||||
$this->repository->each($filter);
|
||||
|
||||
return $filesList;
|
||||
}
|
||||
|
||||
private function getCurrentFolderWithTrailingSlash(): string
|
||||
{
|
||||
if (empty($this->currentFolder)) {
|
||||
return '';
|
||||
}
|
||||
|
||||
$lastChar = mb_substr($this->currentFolder, -1);
|
||||
if ($lastChar !== '/' || $lastChar !== '\\') {
|
||||
return $this->currentFolder.'/';
|
||||
}
|
||||
|
||||
return $this->currentFolder;
|
||||
}
|
||||
|
||||
//---------------------PRIVATE FUNCTIONS-------------
|
||||
|
||||
/**
|
||||
* @param $pathToZip
|
||||
*
|
||||
* @return bool
|
||||
* @throws Exception
|
||||
*
|
||||
*/
|
||||
private function createArchiveFile($pathToZip): bool
|
||||
{
|
||||
if (! $this->file->exists($pathToZip)) {
|
||||
$dirname = dirname($pathToZip);
|
||||
if (! $this->file->exists($dirname) && ! $this->file->makeDirectory($dirname, 0755, true)) {
|
||||
throw new RuntimeException('Failed to create folder');
|
||||
} elseif (! $this->file->isWritable($dirname)) {
|
||||
throw new Exception(sprintf('The path "%s" is not writeable', $pathToZip));
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $pathToDir
|
||||
*/
|
||||
private function addDir($pathToDir): void
|
||||
{
|
||||
// First go over the files in this directory and add them to the repository.
|
||||
foreach ($this->file->files($pathToDir) as $file) {
|
||||
$this->addFile($pathToDir.'/'.basename($file));
|
||||
}
|
||||
|
||||
// Now let's visit the subdirectories and add them, too.
|
||||
foreach ($this->file->directories($pathToDir) as $dir) {
|
||||
$old_folder = $this->currentFolder;
|
||||
$this->currentFolder = empty($this->currentFolder) ? basename($dir) : $this->currentFolder.'/'.basename($dir);
|
||||
$this->addDir($pathToDir.'/'.basename($dir));
|
||||
$this->currentFolder = $old_folder;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Add the file to the zip
|
||||
*
|
||||
* @param string $pathToAdd
|
||||
* @param string|null $fileName
|
||||
*/
|
||||
private function addFile(string $pathToAdd, string $fileName = null): void
|
||||
{
|
||||
if (! $fileName) {
|
||||
$info = pathinfo($pathToAdd);
|
||||
$fileName = isset($info['extension']) ?
|
||||
$info['filename'].'.'.$info['extension'] :
|
||||
$info['filename'];
|
||||
}
|
||||
|
||||
$this->repository->addFile($pathToAdd, $this->getInternalPath().$fileName);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add the file to the zip from content
|
||||
*
|
||||
* @param $filename
|
||||
* @param $content
|
||||
*/
|
||||
private function addFromString($filename, $content): void
|
||||
{
|
||||
$this->repository->addFromString($this->getInternalPath().$filename, $content);
|
||||
}
|
||||
|
||||
private function extractFilesInternal($path, callable $matchingMethod): void
|
||||
{
|
||||
$self = $this;
|
||||
$this->repository->each(function ($fileName) use ($path, $matchingMethod, $self) {
|
||||
$currentPath = $self->getCurrentFolderWithTrailingSlash();
|
||||
if (! empty($currentPath) && ! Str::startsWith($fileName, $currentPath)) {
|
||||
return;
|
||||
}
|
||||
|
||||
$filename = str_replace($self->getInternalPath(), '', $fileName);
|
||||
if ($matchingMethod($filename)) {
|
||||
$self->extractOneFileInternal($fileName, $path);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $fileName
|
||||
* @param $path
|
||||
*
|
||||
* @throws RuntimeException
|
||||
*/
|
||||
private function extractOneFileInternal($fileName, $path): void
|
||||
{
|
||||
$tmpPath = str_replace($this->getInternalPath(), '', $fileName);
|
||||
|
||||
//Prevent Zip traversal attacks
|
||||
if (str_contains($fileName, '../') || str_contains($fileName, '..\\')) {
|
||||
throw new RuntimeException('Special characters found within filenames');
|
||||
}
|
||||
|
||||
// We need to create the directory first in case it doesn't exist
|
||||
$dir = pathinfo($path.DIRECTORY_SEPARATOR.$tmpPath, PATHINFO_DIRNAME);
|
||||
if (! $this->file->exists($dir) && ! $this->file->makeDirectory($dir, 0755, true, true)) {
|
||||
throw new RuntimeException('Failed to create folders');
|
||||
}
|
||||
|
||||
$toPath = $path.DIRECTORY_SEPARATOR.$tmpPath;
|
||||
$fileStream = $this->getRepository()->getFileStream($fileName);
|
||||
$this->getFileHandler()->put($toPath, $fileStream);
|
||||
}
|
||||
}
|
122
catch/src/Support/helpers.php
Normal file
122
catch/src/Support/helpers.php
Normal file
@ -0,0 +1,122 @@
|
||||
<?php
|
||||
|
||||
// +----------------------------------------------------------------------
|
||||
// | CatchAdmin [Just Like ~ ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | Copyright (c) 2017~2021 https://catchadmin.com All rights reserved.
|
||||
// +----------------------------------------------------------------------
|
||||
// | Licensed ( https://github.com/JaguarJack/catchadmin-laravel/blob/master/LICENSE.md )
|
||||
// +----------------------------------------------------------------------
|
||||
// | Author: JaguarJack [ njphper@gmail.com ]
|
||||
// +----------------------------------------------------------------------
|
||||
declare(strict_types=1);
|
||||
|
||||
use Illuminate\Console\Application as Artisan;
|
||||
use Illuminate\Console\Command;
|
||||
use Illuminate\Support\Arr;
|
||||
use Illuminate\Support\Collection;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use Illuminate\Support\Str;
|
||||
use Symfony\Component\Finder\Finder;
|
||||
use Symfony\Component\VarDumper\VarDumper;
|
||||
|
||||
/**
|
||||
* load commands
|
||||
*/
|
||||
if (! function_exists('loadCommands')) {
|
||||
/**
|
||||
* @throws ReflectionException
|
||||
*/
|
||||
function loadCommands($paths, $namespace, $searchPath = null): void
|
||||
{
|
||||
if (! $searchPath) {
|
||||
$searchPath = dirname($paths).DIRECTORY_SEPARATOR;
|
||||
}
|
||||
|
||||
$paths = Collection::make(Arr::wrap($paths))->unique()->filter(function ($path) {
|
||||
return is_dir($path);
|
||||
});
|
||||
|
||||
if ($paths->isEmpty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
foreach ((new Finder())->in($paths->toArray())->files() as $command) {
|
||||
$command = $namespace.str_replace(['/', '.php'], ['\\', ''], Str::after($command->getRealPath(), $searchPath));
|
||||
|
||||
if (is_subclass_of($command, Command::class) &&
|
||||
! (new ReflectionClass($command))->isAbstract()) {
|
||||
Artisan::starting(function ($artisan) use ($command) {
|
||||
$artisan->resolve($command);
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* table prefix
|
||||
*/
|
||||
if (! function_exists('withTablePrefix')) {
|
||||
function withTablePrefix(string $table): string
|
||||
{
|
||||
return DB::connection()->getTablePrefix().$table;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* get guard name
|
||||
*/
|
||||
if (! function_exists('getGuardName')) {
|
||||
function getGuardName(): string
|
||||
{
|
||||
$guardKeys = array_keys(config('catch.auth.guards'));
|
||||
|
||||
if (count($guardKeys)) {
|
||||
return $guardKeys[0];
|
||||
}
|
||||
|
||||
return 'admin';
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* get table columns
|
||||
*/
|
||||
if (! function_exists('getTableColumns')) {
|
||||
function getTableColumns(string $table): array
|
||||
{
|
||||
$SQL = 'desc '.withTablePrefix($table);
|
||||
|
||||
$columns = [];
|
||||
|
||||
foreach (DB::select($SQL) as $column) {
|
||||
$columns[] = $column->Field;
|
||||
}
|
||||
|
||||
return $columns;
|
||||
}
|
||||
}
|
||||
|
||||
if (! function_exists('dd_')) {
|
||||
/**
|
||||
* @param mixed ...$vars
|
||||
* @return never
|
||||
*/
|
||||
function dd_(...$vars): never
|
||||
{
|
||||
if (! in_array(\PHP_SAPI, ['cli', 'phpdbg'], true) && ! headers_sent()) {
|
||||
header('HTTP/1.1 500 Internal Server Error');
|
||||
}
|
||||
|
||||
header('Access-Control-Allow-Origin: *');
|
||||
header('Access-Control-Allow-Methods: *');
|
||||
header('Access-Control-Allow-Headers: *');
|
||||
|
||||
foreach ($vars as $v) {
|
||||
VarDumper::dump($v);
|
||||
}
|
||||
|
||||
exit(1);
|
||||
}
|
||||
}
|
239
catch/src/Traits/DB/BaseOperate.php
Normal file
239
catch/src/Traits/DB/BaseOperate.php
Normal file
@ -0,0 +1,239 @@
|
||||
<?php
|
||||
|
||||
// +----------------------------------------------------------------------
|
||||
// | CatchAdmin [Just Like ~ ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | Copyright (c) 2017~2021 https://catchadmin.com All rights reserved.
|
||||
// +----------------------------------------------------------------------
|
||||
// | Licensed ( https://github.com/JaguarJack/catchadmin-laravel/blob/master/LICENSE.md )
|
||||
// +----------------------------------------------------------------------
|
||||
// | Author: JaguarJack [ njphper@gmail.com ]
|
||||
// +----------------------------------------------------------------------
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Catch\Traits\DB;
|
||||
|
||||
use Catch\Enums\Status;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Support\Facades\Request;
|
||||
|
||||
/**
|
||||
* base operate
|
||||
*/
|
||||
trait BaseOperate
|
||||
{
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function initializeBaseOperate(): void
|
||||
{
|
||||
if (property_exists($this, 'mergeCasts')) {
|
||||
$this->mergeCasts($this->mergeCasts);
|
||||
}
|
||||
|
||||
if (property_exists($this, 'mergeHidden')) {
|
||||
$this->makeHidden($this->mergeHidden);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
public function getList(): mixed
|
||||
{
|
||||
$queryBuilder = self::query()->select($this->fieldsInList)->quickSearch();
|
||||
|
||||
if ($this->isPaginate) {
|
||||
return $queryBuilder->paginate(Request::get('limit', $this->perPage));
|
||||
}
|
||||
|
||||
return $queryBuilder->get();
|
||||
}
|
||||
|
||||
/**
|
||||
* save
|
||||
*
|
||||
* @param array $data
|
||||
* @return false|mixed
|
||||
*/
|
||||
public function storeBy(array $data): mixed
|
||||
{
|
||||
if ($this->fill($this->filterData($data))->save()) {
|
||||
return $this->getKey();
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* create
|
||||
*
|
||||
* @param array $data
|
||||
* @return false|mixed
|
||||
*/
|
||||
public function createBy(array $data): mixed
|
||||
{
|
||||
$model = $this->newInstance();
|
||||
|
||||
if ($model->fill($this->filterData($data))->save()) {
|
||||
return $model->getKey();
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* update
|
||||
*
|
||||
* @param $id
|
||||
* @param array $data
|
||||
* @return mixed
|
||||
*/
|
||||
public function updateBy($id, array $data): mixed
|
||||
{
|
||||
return $this->where($this->getKeyName(), $id)->update($this->filterData($data));
|
||||
}
|
||||
|
||||
/**
|
||||
* filter data/ remove null && empty string
|
||||
*
|
||||
* @param array $data
|
||||
* @return array
|
||||
*/
|
||||
protected function filterData(array $data): array
|
||||
{
|
||||
// 表单保存的数据集合
|
||||
$form = property_exists($this, 'form') ? $this->form : [];
|
||||
|
||||
foreach ($data as $k => $val) {
|
||||
if (is_null($val) || (is_string($val) && ! $val)) {
|
||||
unset($data[$k]);
|
||||
}
|
||||
|
||||
if (! empty($form) && ! in_array($k, $form)) {
|
||||
unset($data[$k]);
|
||||
}
|
||||
}
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* get first by ID
|
||||
*
|
||||
* @param $id
|
||||
* @param string[] $columns
|
||||
* @return ?Model
|
||||
*/
|
||||
public function firstBy($id, array $columns = ['*']): ?Model
|
||||
{
|
||||
return static::where($this->getKeyName(), $id)->first($columns);
|
||||
}
|
||||
|
||||
/**
|
||||
* delete model
|
||||
*
|
||||
* @param $id
|
||||
* @param bool $force
|
||||
* @return bool|null
|
||||
*/
|
||||
public function deleteBy($id, bool $force = false): ?bool
|
||||
{
|
||||
/* @var Model $model */
|
||||
$model = self::find($id);
|
||||
|
||||
if ($force) {
|
||||
return $model->forceDelete();
|
||||
}
|
||||
|
||||
return $model->delete();
|
||||
}
|
||||
|
||||
/**
|
||||
* disable or enable
|
||||
*
|
||||
* @param $id
|
||||
* @param string $field
|
||||
* @return bool
|
||||
*/
|
||||
public function disOrEnable($id, string $field = 'status'): bool
|
||||
{
|
||||
$model = self::firstBy($id);
|
||||
|
||||
$model->{$field} = $model->{$field} == Status::Enable->value() ? Status::Disable->value() : Status::Enable->value();
|
||||
|
||||
return $model->save();
|
||||
}
|
||||
|
||||
/**
|
||||
* alias field
|
||||
*
|
||||
* @param string|array $fields
|
||||
* @return string|array
|
||||
*/
|
||||
public function aliasField(string|array $fields): string|array
|
||||
{
|
||||
$table = $this->getTable();
|
||||
|
||||
if (is_string($fields)) {
|
||||
return "{$table}.{$fields}";
|
||||
}
|
||||
|
||||
foreach ($fields as &$field) {
|
||||
$field = "{$table}.{$field}";
|
||||
}
|
||||
|
||||
return $fields;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* get updated at column
|
||||
*
|
||||
* @return string|null
|
||||
*/
|
||||
public function getUpdatedAtColumn(): ?string
|
||||
{
|
||||
$updatedAtColumn = parent::getUpdatedAtColumn();
|
||||
|
||||
if (! in_array(parent::getUpdatedAtColumn(), $this->getFillable())) {
|
||||
$updatedAtColumn = null;
|
||||
}
|
||||
|
||||
return $updatedAtColumn;
|
||||
}
|
||||
|
||||
/**
|
||||
* get created at column
|
||||
*
|
||||
* @return string|null
|
||||
*/
|
||||
public function getCreatedAtColumn(): ?string
|
||||
{
|
||||
$createdAtColumn = parent::getCreatedAtColumn();
|
||||
|
||||
if (! in_array(parent::getUpdatedAtColumn(), $this->getFillable())) {
|
||||
$createdAtColumn = null;
|
||||
}
|
||||
|
||||
return $createdAtColumn;
|
||||
}
|
||||
|
||||
/**
|
||||
* whit form data
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function withoutForm(): static
|
||||
{
|
||||
if (property_exists($this, 'form') && ! empty($this->form)) {
|
||||
$this->form = [];
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user