install addons
This commit is contained in:
parent
a9f5deaf52
commit
f68a930812
274
addons/README.md
Normal file
274
addons/README.md
Normal file
@ -0,0 +1,274 @@
|
||||
# think-addons
|
||||
The ThinkPHP 6 Addons Package
|
||||
|
||||
## 安装
|
||||
> composer require zzstudio/think-addons
|
||||
|
||||
## 配置
|
||||
|
||||
### 生成配置
|
||||
|
||||
系统安装后会自动在 config 目录中生成 addons.php 的配置文件,
|
||||
如果系统未生成可在命令行执行
|
||||
|
||||
```php
|
||||
php think addons:config
|
||||
```
|
||||
|
||||
快速生成配置文件
|
||||
|
||||
### 公共配置
|
||||
```php
|
||||
'addons' => [
|
||||
// 是否自动读取取插件钩子配置信息(默认是开启)
|
||||
'autoload' => true,
|
||||
// 当关闭自动获取配置时需要手动配置hooks信息
|
||||
'hooks' => [
|
||||
// 可以定义多个钩子
|
||||
'testhook'=>'test' // 键为钩子名称,用于在业务中自定义钩子处理,值为实现该钩子的插件,
|
||||
// 多个插件可以用数组也可以用逗号分割
|
||||
],
|
||||
'route' => [],
|
||||
'service' => [],
|
||||
];
|
||||
```
|
||||
或者在\config目录中新建`addons.php`,内容为:
|
||||
```php
|
||||
<?php
|
||||
return [
|
||||
// 是否自动读取取插件钩子配置信息
|
||||
'autoload' => false,
|
||||
// 当关闭自动获取配置时需要手动配置hooks信息
|
||||
'hooks' => [
|
||||
// 可以定义多个钩子
|
||||
'testhook'=>'test' // 键为钩子名称,用于在业务中自定义钩子处理,值为实现该钩子的插件,
|
||||
// 多个插件可以用数组也可以用逗号分割
|
||||
],
|
||||
'route' => [],
|
||||
'service' => [],
|
||||
];
|
||||
```
|
||||
|
||||
## 创建插件
|
||||
> 创建的插件可以在view视图中使用,也可以在php业务中使用
|
||||
|
||||
安装完成后访问系统时会在项目根目录生成名为`addons`的目录,在该目录中创建需要的插件。
|
||||
|
||||
下面写一个例子:
|
||||
|
||||
### 创建test插件
|
||||
> 在addons目录中创建test目录
|
||||
|
||||
### 创建钩子实现类
|
||||
> 在test目录中创建 Plugin.php 类文件。注意:类文件首字母需大写
|
||||
|
||||
```php
|
||||
<?php
|
||||
namespace addons\test; // 注意命名空间规范
|
||||
|
||||
use think\Addons;
|
||||
|
||||
/**
|
||||
* 插件测试
|
||||
* @author byron sampson
|
||||
*/
|
||||
class Plugin extends Addons // 需继承think\Addons类
|
||||
{
|
||||
// 该插件的基础信息
|
||||
public $info = [
|
||||
'name' => 'test', // 插件标识
|
||||
'title' => '插件测试', // 插件名称
|
||||
'description' => 'thinkph6插件测试', // 插件简介
|
||||
'status' => 0, // 状态
|
||||
'author' => 'byron sampson',
|
||||
'version' => '0.1'
|
||||
];
|
||||
|
||||
/**
|
||||
* 插件安装方法
|
||||
* @return bool
|
||||
*/
|
||||
public function install()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* 插件卸载方法
|
||||
* @return bool
|
||||
*/
|
||||
public function uninstall()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* 实现的testhook钩子方法
|
||||
* @return mixed
|
||||
*/
|
||||
public function testhook($param)
|
||||
{
|
||||
// 调用钩子时候的参数信息
|
||||
print_r($param);
|
||||
// 当前插件的配置信息,配置信息存在当前目录的config.php文件中,见下方
|
||||
print_r($this->getConfig());
|
||||
// 可以返回模板,模板文件默认读取的为插件目录中的文件。模板名不能为空!
|
||||
return $this->fetch('info');
|
||||
}
|
||||
|
||||
}
|
||||
```
|
||||
|
||||
### 创建插件配置文件
|
||||
> 在test目录中创建config.php类文件,插件配置文件可以省略。
|
||||
|
||||
```php
|
||||
<?php
|
||||
return [
|
||||
'display' => [
|
||||
'title' => '是否显示:',
|
||||
'type' => 'radio',
|
||||
'options' => [
|
||||
'1' => '显示',
|
||||
'0' => '不显示'
|
||||
],
|
||||
'value' => '1'
|
||||
]
|
||||
];
|
||||
```
|
||||
|
||||
### 创建钩子模板文件
|
||||
> 在test->view目录中创建info.html模板文件,钩子在使用fetch方法时对应的模板文件。
|
||||
|
||||
```html
|
||||
<h1>hello tpl</h1>
|
||||
|
||||
如果插件中需要有链接或提交数据的业务,可以在插件中创建controller业务文件,
|
||||
要访问插件中的controller时使用addon_url生成url链接。
|
||||
如下:
|
||||
<a href="{:addons_url('Action/link')}">link test</a>
|
||||
或
|
||||
<a href="{:addons_url('test://Action/link')}">link test</a>
|
||||
格式为:
|
||||
test为插件名,Action为controller中的类名[多级控制器可以用.分割],link为controller中的方法
|
||||
```
|
||||
|
||||
### 创建插件的controller文件
|
||||
> 在test目录中创建controller目录,在controller目录中创建Index.php文件
|
||||
> controller类的用法与tp6中的controller一致
|
||||
|
||||
```php
|
||||
<?php
|
||||
namespace addons\test\controller;
|
||||
|
||||
class Index
|
||||
{
|
||||
public function link()
|
||||
{
|
||||
echo 'hello link';
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## 使用钩子
|
||||
> 创建好插件后就可以在正常业务中使用该插件中的钩子了
|
||||
> 使用钩子的时候第二个参数可以省略
|
||||
|
||||
### 模板中使用钩子
|
||||
|
||||
```html
|
||||
<div>{:hook('testhook', ['id'=>1])}</div>
|
||||
```
|
||||
|
||||
### php业务中使用
|
||||
> 只要是thinkphp6正常流程中的任意位置均可以使用
|
||||
|
||||
```php
|
||||
hook('testhook', ['id'=>1])
|
||||
```
|
||||
|
||||
### 插件公共方法
|
||||
```php
|
||||
/**
|
||||
* 处理插件钩子
|
||||
* @param string $event 钩子名称
|
||||
* @param array|null $params 传入参数
|
||||
* @param bool $once 是否只返回一个结果
|
||||
* @return mixed
|
||||
*/
|
||||
function hook($event, $params = null, bool $once = false);
|
||||
|
||||
/**
|
||||
* 读取插件的基础信息
|
||||
* @param string $name 插件名
|
||||
* @return array
|
||||
*/
|
||||
function get_addons_info($name);
|
||||
|
||||
/**
|
||||
* 获取插件Plugin的单例
|
||||
* @param string $name 插件名
|
||||
* @return mixed|null
|
||||
*/
|
||||
function get_addons_instance($name);
|
||||
|
||||
/**
|
||||
* 插件显示内容里生成访问插件的url
|
||||
* @param $url 在插件控制器中可忽略插件名,在非插件中生成时需指定插件名。例:插件名://控制器/方法
|
||||
* @param array $param
|
||||
* @param bool|string $suffix 生成的URL后缀
|
||||
* @param bool|string $domain 域名
|
||||
* @return bool|string
|
||||
*/
|
||||
function addons_url($url = '', $param = [], $suffix = true, $domain = false);
|
||||
|
||||
```
|
||||
|
||||
## 插件目录结构
|
||||
### 最终生成的目录结构为
|
||||
|
||||
```html
|
||||
www WEB部署目录(或者子目录)
|
||||
├─addons 插件目录
|
||||
├─app 应用目录
|
||||
│ ├─controller 控制器目录
|
||||
│ ├─model 模型目录
|
||||
│ ├─ ... 更多类库目录
|
||||
│ │
|
||||
│ ├─common.php 公共函数文件
|
||||
│ └─event.php 事件定义文件
|
||||
│
|
||||
├─config 配置目录
|
||||
│ ├─app.php 应用配置
|
||||
│ ├─cache.php 缓存配置
|
||||
│ ├─console.php 控制台配置
|
||||
│ ├─cookie.php Cookie配置
|
||||
│ ├─database.php 数据库配置
|
||||
│ ├─filesystem.php 文件磁盘配置
|
||||
│ ├─lang.php 多语言配置
|
||||
│ ├─log.php 日志配置
|
||||
│ ├─middleware.php 中间件配置
|
||||
│ ├─route.php URL和路由配置
|
||||
│ ├─session.php Session配置
|
||||
│ ├─trace.php Trace配置
|
||||
│ └─view.php 视图配置
|
||||
│
|
||||
├─view 视图目录
|
||||
├─route 路由定义目录
|
||||
│ ├─route.php 路由定义文件
|
||||
│ └─ ...
|
||||
│
|
||||
├─public WEB目录(对外访问目录)
|
||||
│ ├─index.php 入口文件
|
||||
│ ├─router.php 快速测试文件
|
||||
│ └─.htaccess 用于apache的重写
|
||||
│
|
||||
├─extend 扩展类库目录
|
||||
├─runtime 应用的运行时目录(可写,可定制)
|
||||
├─vendor Composer类库目录
|
||||
├─.example.env 环境变量示例文件
|
||||
├─composer.json composer 定义文件
|
||||
├─LICENSE.txt 授权说明文件
|
||||
├─README.md README 文件
|
||||
├─think 命令行入口文件
|
||||
```
|
@ -27,7 +27,8 @@
|
||||
"taoser/think-auth": "^1.0",
|
||||
"topthink/think-multi-app": "^1.0",
|
||||
"topthink/think-captcha": "^3.0",
|
||||
"topthink/think-view": "^1.0"
|
||||
"topthink/think-view": "^1.0",
|
||||
"zzstudio/think-addons": "^2.0"
|
||||
},
|
||||
"require-dev": {
|
||||
"symfony/var-dumper": "^4.2",
|
||||
|
60
composer.lock
generated
60
composer.lock
generated
@ -4,7 +4,7 @@
|
||||
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
|
||||
"This file is @generated automatically"
|
||||
],
|
||||
"content-hash": "6ebd3a4578a0960080346336d4970bfd",
|
||||
"content-hash": "6228bf65a800388ad9f6b06b8ac6ba72",
|
||||
"packages": [
|
||||
{
|
||||
"name": "league/flysystem",
|
||||
@ -907,6 +907,64 @@
|
||||
],
|
||||
"description": "thinkphp template driver",
|
||||
"time": "2019-11-06T11:40:13+00:00"
|
||||
},
|
||||
{
|
||||
"name": "zzstudio/think-addons",
|
||||
"version": "2.0.5",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/zz-studio/think-addons.git",
|
||||
"reference": "7eb740cb219a111d593a05ad88248a74f640fe5c"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/zz-studio/think-addons/zipball/7eb740cb219a111d593a05ad88248a74f640fe5c",
|
||||
"reference": "7eb740cb219a111d593a05ad88248a74f640fe5c",
|
||||
"shasum": "",
|
||||
"mirrors": [
|
||||
{
|
||||
"url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%",
|
||||
"preferred": true
|
||||
}
|
||||
]
|
||||
},
|
||||
"require": {
|
||||
"php": ">=7.1.0",
|
||||
"topthink/framework": "^6.0",
|
||||
"topthink/think-helper": "^3.0.0",
|
||||
"topthink/think-view": "^1.0"
|
||||
},
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"think": {
|
||||
"services": [
|
||||
"think\\addons\\Service"
|
||||
],
|
||||
"config": {
|
||||
"addons": "src/config.php"
|
||||
}
|
||||
}
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"think\\": "src/"
|
||||
},
|
||||
"files": [
|
||||
"src/helper.php"
|
||||
]
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"Apache-2.0"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "byron",
|
||||
"email": "xiaobo.sun@qq.com"
|
||||
}
|
||||
],
|
||||
"description": "The ThinkPHP6 Addons Package",
|
||||
"time": "2020-01-06T06:42:39+00:00"
|
||||
}
|
||||
],
|
||||
"packages-dev": [
|
||||
|
17
config/addons.php
Normal file
17
config/addons.php
Normal file
@ -0,0 +1,17 @@
|
||||
<?php
|
||||
// +----------------------------------------------------------------------
|
||||
// | thinkphp5 Addons [ WE CAN DO IT JUST THINK IT ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | Copyright (c) 2016 http://www.zzstudio.net All rights reserved.
|
||||
// +----------------------------------------------------------------------
|
||||
// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
|
||||
// +----------------------------------------------------------------------
|
||||
// | Author: Byron Sampson <xiaobo.sun@qq.com>
|
||||
// +----------------------------------------------------------------------
|
||||
|
||||
return [
|
||||
'autoload' => true,
|
||||
'hooks' => [],
|
||||
'route' => [],
|
||||
'service' => [],
|
||||
];
|
1
vendor/composer/autoload_files.php
vendored
1
vendor/composer/autoload_files.php
vendored
@ -12,4 +12,5 @@ return array(
|
||||
'25072dd6e2470089de65ae7bf11d3109' => $vendorDir . '/symfony/polyfill-php72/bootstrap.php',
|
||||
'667aeda72477189d0494fecd327c3641' => $vendorDir . '/symfony/var-dumper/Resources/functions/dump.php',
|
||||
'1cfd2761b63b0a29ed23657ea394cb2d' => $vendorDir . '/topthink/think-captcha/src/helper.php',
|
||||
'39594db8502267d6df2fe2dca5f3914d' => $vendorDir . '/zzstudio/think-addons/src/helper.php',
|
||||
);
|
||||
|
2
vendor/composer/autoload_psr4.php
vendored
2
vendor/composer/autoload_psr4.php
vendored
@ -10,7 +10,7 @@ return array(
|
||||
'think\\trace\\' => array($vendorDir . '/topthink/think-trace/src'),
|
||||
'think\\captcha\\' => array($vendorDir . '/topthink/think-captcha/src'),
|
||||
'think\\app\\' => array($vendorDir . '/topthink/think-multi-app/src'),
|
||||
'think\\' => array($vendorDir . '/topthink/framework/src/think', $vendorDir . '/topthink/think-helper/src', $vendorDir . '/topthink/think-orm/src', $vendorDir . '/topthink/think-template/src'),
|
||||
'think\\' => array($vendorDir . '/topthink/framework/src/think', $vendorDir . '/topthink/think-helper/src', $vendorDir . '/topthink/think-orm/src', $vendorDir . '/topthink/think-template/src', $vendorDir . '/zzstudio/think-addons/src'),
|
||||
'taoser\\think\\' => array($vendorDir . '/taoser/think-auth/src'),
|
||||
'app\\' => array($baseDir . '/app'),
|
||||
'Symfony\\Polyfill\\Php72\\' => array($vendorDir . '/symfony/polyfill-php72'),
|
||||
|
2
vendor/composer/autoload_static.php
vendored
2
vendor/composer/autoload_static.php
vendored
@ -13,6 +13,7 @@ class ComposerStaticInit9b80d9a7bd440d07cac42880e0942921
|
||||
'25072dd6e2470089de65ae7bf11d3109' => __DIR__ . '/..' . '/symfony/polyfill-php72/bootstrap.php',
|
||||
'667aeda72477189d0494fecd327c3641' => __DIR__ . '/..' . '/symfony/var-dumper/Resources/functions/dump.php',
|
||||
'1cfd2761b63b0a29ed23657ea394cb2d' => __DIR__ . '/..' . '/topthink/think-captcha/src/helper.php',
|
||||
'39594db8502267d6df2fe2dca5f3914d' => __DIR__ . '/..' . '/zzstudio/think-addons/src/helper.php',
|
||||
);
|
||||
|
||||
public static $prefixLengthsPsr4 = array (
|
||||
@ -77,6 +78,7 @@ class ComposerStaticInit9b80d9a7bd440d07cac42880e0942921
|
||||
1 => __DIR__ . '/..' . '/topthink/think-helper/src',
|
||||
2 => __DIR__ . '/..' . '/topthink/think-orm/src',
|
||||
3 => __DIR__ . '/..' . '/topthink/think-template/src',
|
||||
4 => __DIR__ . '/..' . '/zzstudio/think-addons/src',
|
||||
),
|
||||
'taoser\\think\\' =>
|
||||
array (
|
||||
|
60
vendor/composer/installed.json
vendored
60
vendor/composer/installed.json
vendored
@ -1201,5 +1201,65 @@
|
||||
}
|
||||
],
|
||||
"description": "thinkphp template driver"
|
||||
},
|
||||
{
|
||||
"name": "zzstudio/think-addons",
|
||||
"version": "2.0.5",
|
||||
"version_normalized": "2.0.5.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/zz-studio/think-addons.git",
|
||||
"reference": "7eb740cb219a111d593a05ad88248a74f640fe5c"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/zz-studio/think-addons/zipball/7eb740cb219a111d593a05ad88248a74f640fe5c",
|
||||
"reference": "7eb740cb219a111d593a05ad88248a74f640fe5c",
|
||||
"shasum": "",
|
||||
"mirrors": [
|
||||
{
|
||||
"url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%",
|
||||
"preferred": true
|
||||
}
|
||||
]
|
||||
},
|
||||
"require": {
|
||||
"php": ">=7.1.0",
|
||||
"topthink/framework": "^6.0",
|
||||
"topthink/think-helper": "^3.0.0",
|
||||
"topthink/think-view": "^1.0"
|
||||
},
|
||||
"time": "2020-01-06T06:42:39+00:00",
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"think": {
|
||||
"services": [
|
||||
"think\\addons\\Service"
|
||||
],
|
||||
"config": {
|
||||
"addons": "src/config.php"
|
||||
}
|
||||
}
|
||||
},
|
||||
"installation-source": "dist",
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"think\\": "src/"
|
||||
},
|
||||
"files": [
|
||||
"src/helper.php"
|
||||
]
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"Apache-2.0"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "byron",
|
||||
"email": "xiaobo.sun@qq.com"
|
||||
}
|
||||
],
|
||||
"description": "The ThinkPHP6 Addons Package"
|
||||
}
|
||||
]
|
||||
|
3
vendor/services.php
vendored
3
vendor/services.php
vendored
@ -1,8 +1,9 @@
|
||||
<?php
|
||||
// This file is automatically generated at:2020-02-12 16:42:46
|
||||
// This file is automatically generated at:2020-02-18 19:24:39
|
||||
declare (strict_types = 1);
|
||||
return array (
|
||||
0 => 'think\\captcha\\CaptchaService',
|
||||
1 => 'think\\app\\Service',
|
||||
2 => 'think\\trace\\Service',
|
||||
3 => 'think\\addons\\Service',
|
||||
);
|
274
vendor/zzstudio/think-addons/README.md
vendored
Normal file
274
vendor/zzstudio/think-addons/README.md
vendored
Normal file
@ -0,0 +1,274 @@
|
||||
# think-addons
|
||||
The ThinkPHP 6 Addons Package
|
||||
|
||||
## 安装
|
||||
> composer require zzstudio/think-addons
|
||||
|
||||
## 配置
|
||||
|
||||
### 生成配置
|
||||
|
||||
系统安装后会自动在 config 目录中生成 addons.php 的配置文件,
|
||||
如果系统未生成可在命令行执行
|
||||
|
||||
```php
|
||||
php think addons:config
|
||||
```
|
||||
|
||||
快速生成配置文件
|
||||
|
||||
### 公共配置
|
||||
```php
|
||||
'addons' => [
|
||||
// 是否自动读取取插件钩子配置信息(默认是开启)
|
||||
'autoload' => true,
|
||||
// 当关闭自动获取配置时需要手动配置hooks信息
|
||||
'hooks' => [
|
||||
// 可以定义多个钩子
|
||||
'testhook'=>'test' // 键为钩子名称,用于在业务中自定义钩子处理,值为实现该钩子的插件,
|
||||
// 多个插件可以用数组也可以用逗号分割
|
||||
],
|
||||
'route' => [],
|
||||
'service' => [],
|
||||
];
|
||||
```
|
||||
或者在\config目录中新建`addons.php`,内容为:
|
||||
```php
|
||||
<?php
|
||||
return [
|
||||
// 是否自动读取取插件钩子配置信息
|
||||
'autoload' => false,
|
||||
// 当关闭自动获取配置时需要手动配置hooks信息
|
||||
'hooks' => [
|
||||
// 可以定义多个钩子
|
||||
'testhook'=>'test' // 键为钩子名称,用于在业务中自定义钩子处理,值为实现该钩子的插件,
|
||||
// 多个插件可以用数组也可以用逗号分割
|
||||
],
|
||||
'route' => [],
|
||||
'service' => [],
|
||||
];
|
||||
```
|
||||
|
||||
## 创建插件
|
||||
> 创建的插件可以在view视图中使用,也可以在php业务中使用
|
||||
|
||||
安装完成后访问系统时会在项目根目录生成名为`addons`的目录,在该目录中创建需要的插件。
|
||||
|
||||
下面写一个例子:
|
||||
|
||||
### 创建test插件
|
||||
> 在addons目录中创建test目录
|
||||
|
||||
### 创建钩子实现类
|
||||
> 在test目录中创建 Plugin.php 类文件。注意:类文件首字母需大写
|
||||
|
||||
```php
|
||||
<?php
|
||||
namespace addons\test; // 注意命名空间规范
|
||||
|
||||
use think\Addons;
|
||||
|
||||
/**
|
||||
* 插件测试
|
||||
* @author byron sampson
|
||||
*/
|
||||
class Plugin extends Addons // 需继承think\Addons类
|
||||
{
|
||||
// 该插件的基础信息
|
||||
public $info = [
|
||||
'name' => 'test', // 插件标识
|
||||
'title' => '插件测试', // 插件名称
|
||||
'description' => 'thinkph6插件测试', // 插件简介
|
||||
'status' => 0, // 状态
|
||||
'author' => 'byron sampson',
|
||||
'version' => '0.1'
|
||||
];
|
||||
|
||||
/**
|
||||
* 插件安装方法
|
||||
* @return bool
|
||||
*/
|
||||
public function install()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* 插件卸载方法
|
||||
* @return bool
|
||||
*/
|
||||
public function uninstall()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* 实现的testhook钩子方法
|
||||
* @return mixed
|
||||
*/
|
||||
public function testhook($param)
|
||||
{
|
||||
// 调用钩子时候的参数信息
|
||||
print_r($param);
|
||||
// 当前插件的配置信息,配置信息存在当前目录的config.php文件中,见下方
|
||||
print_r($this->getConfig());
|
||||
// 可以返回模板,模板文件默认读取的为插件目录中的文件。模板名不能为空!
|
||||
return $this->fetch('info');
|
||||
}
|
||||
|
||||
}
|
||||
```
|
||||
|
||||
### 创建插件配置文件
|
||||
> 在test目录中创建config.php类文件,插件配置文件可以省略。
|
||||
|
||||
```php
|
||||
<?php
|
||||
return [
|
||||
'display' => [
|
||||
'title' => '是否显示:',
|
||||
'type' => 'radio',
|
||||
'options' => [
|
||||
'1' => '显示',
|
||||
'0' => '不显示'
|
||||
],
|
||||
'value' => '1'
|
||||
]
|
||||
];
|
||||
```
|
||||
|
||||
### 创建钩子模板文件
|
||||
> 在test->view目录中创建info.html模板文件,钩子在使用fetch方法时对应的模板文件。
|
||||
|
||||
```html
|
||||
<h1>hello tpl</h1>
|
||||
|
||||
如果插件中需要有链接或提交数据的业务,可以在插件中创建controller业务文件,
|
||||
要访问插件中的controller时使用addon_url生成url链接。
|
||||
如下:
|
||||
<a href="{:addons_url('Action/link')}">link test</a>
|
||||
或
|
||||
<a href="{:addons_url('test://Action/link')}">link test</a>
|
||||
格式为:
|
||||
test为插件名,Action为controller中的类名[多级控制器可以用.分割],link为controller中的方法
|
||||
```
|
||||
|
||||
### 创建插件的controller文件
|
||||
> 在test目录中创建controller目录,在controller目录中创建Index.php文件
|
||||
> controller类的用法与tp6中的controller一致
|
||||
|
||||
```php
|
||||
<?php
|
||||
namespace addons\test\controller;
|
||||
|
||||
class Index
|
||||
{
|
||||
public function link()
|
||||
{
|
||||
echo 'hello link';
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## 使用钩子
|
||||
> 创建好插件后就可以在正常业务中使用该插件中的钩子了
|
||||
> 使用钩子的时候第二个参数可以省略
|
||||
|
||||
### 模板中使用钩子
|
||||
|
||||
```html
|
||||
<div>{:hook('testhook', ['id'=>1])}</div>
|
||||
```
|
||||
|
||||
### php业务中使用
|
||||
> 只要是thinkphp6正常流程中的任意位置均可以使用
|
||||
|
||||
```php
|
||||
hook('testhook', ['id'=>1])
|
||||
```
|
||||
|
||||
### 插件公共方法
|
||||
```php
|
||||
/**
|
||||
* 处理插件钩子
|
||||
* @param string $event 钩子名称
|
||||
* @param array|null $params 传入参数
|
||||
* @param bool $once 是否只返回一个结果
|
||||
* @return mixed
|
||||
*/
|
||||
function hook($event, $params = null, bool $once = false);
|
||||
|
||||
/**
|
||||
* 读取插件的基础信息
|
||||
* @param string $name 插件名
|
||||
* @return array
|
||||
*/
|
||||
function get_addons_info($name);
|
||||
|
||||
/**
|
||||
* 获取插件Plugin的单例
|
||||
* @param string $name 插件名
|
||||
* @return mixed|null
|
||||
*/
|
||||
function get_addons_instance($name);
|
||||
|
||||
/**
|
||||
* 插件显示内容里生成访问插件的url
|
||||
* @param $url 在插件控制器中可忽略插件名,在非插件中生成时需指定插件名。例:插件名://控制器/方法
|
||||
* @param array $param
|
||||
* @param bool|string $suffix 生成的URL后缀
|
||||
* @param bool|string $domain 域名
|
||||
* @return bool|string
|
||||
*/
|
||||
function addons_url($url = '', $param = [], $suffix = true, $domain = false);
|
||||
|
||||
```
|
||||
|
||||
## 插件目录结构
|
||||
### 最终生成的目录结构为
|
||||
|
||||
```html
|
||||
www WEB部署目录(或者子目录)
|
||||
├─addons 插件目录
|
||||
├─app 应用目录
|
||||
│ ├─controller 控制器目录
|
||||
│ ├─model 模型目录
|
||||
│ ├─ ... 更多类库目录
|
||||
│ │
|
||||
│ ├─common.php 公共函数文件
|
||||
│ └─event.php 事件定义文件
|
||||
│
|
||||
├─config 配置目录
|
||||
│ ├─app.php 应用配置
|
||||
│ ├─cache.php 缓存配置
|
||||
│ ├─console.php 控制台配置
|
||||
│ ├─cookie.php Cookie配置
|
||||
│ ├─database.php 数据库配置
|
||||
│ ├─filesystem.php 文件磁盘配置
|
||||
│ ├─lang.php 多语言配置
|
||||
│ ├─log.php 日志配置
|
||||
│ ├─middleware.php 中间件配置
|
||||
│ ├─route.php URL和路由配置
|
||||
│ ├─session.php Session配置
|
||||
│ ├─trace.php Trace配置
|
||||
│ └─view.php 视图配置
|
||||
│
|
||||
├─view 视图目录
|
||||
├─route 路由定义目录
|
||||
│ ├─route.php 路由定义文件
|
||||
│ └─ ...
|
||||
│
|
||||
├─public WEB目录(对外访问目录)
|
||||
│ ├─index.php 入口文件
|
||||
│ ├─router.php 快速测试文件
|
||||
│ └─.htaccess 用于apache的重写
|
||||
│
|
||||
├─extend 扩展类库目录
|
||||
├─runtime 应用的运行时目录(可写,可定制)
|
||||
├─vendor Composer类库目录
|
||||
├─.example.env 环境变量示例文件
|
||||
├─composer.json composer 定义文件
|
||||
├─LICENSE.txt 授权说明文件
|
||||
├─README.md README 文件
|
||||
├─think 命令行入口文件
|
||||
```
|
40
vendor/zzstudio/think-addons/composer.json
vendored
Normal file
40
vendor/zzstudio/think-addons/composer.json
vendored
Normal file
@ -0,0 +1,40 @@
|
||||
{
|
||||
"name": "zz-studio/think-addons",
|
||||
"description": "The ThinkPHP6 Addons Package",
|
||||
"license": "Apache-2.0",
|
||||
"authors": [
|
||||
{
|
||||
"name": "byron",
|
||||
"email": "xiaobo.sun@qq.com"
|
||||
}
|
||||
],
|
||||
"require": {
|
||||
"php": ">=7.1.0",
|
||||
"topthink/framework": "^6.0",
|
||||
"topthink/think-view": "^1.0",
|
||||
"topthink/think-helper": "^3.0.0"
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"think\\": "src/"
|
||||
},
|
||||
"files": [
|
||||
"src/helper.php"
|
||||
]
|
||||
},
|
||||
"extra": {
|
||||
"think": {
|
||||
"services": [
|
||||
"think\\addons\\Service"
|
||||
],
|
||||
"config":{
|
||||
"addons": "src/config.php"
|
||||
}
|
||||
}
|
||||
},
|
||||
"scripts" : {
|
||||
"post-install-cmd": [
|
||||
"php think addons:config"
|
||||
]
|
||||
}
|
||||
}
|
194
vendor/zzstudio/think-addons/src/Addons.php
vendored
Normal file
194
vendor/zzstudio/think-addons/src/Addons.php
vendored
Normal file
@ -0,0 +1,194 @@
|
||||
<?php
|
||||
/**
|
||||
* +----------------------------------------------------------------------
|
||||
* | think-addons [thinkphp6]
|
||||
* +----------------------------------------------------------------------
|
||||
* .--, .--, | FILE: Addons.php
|
||||
* ( ( \.---./ ) ) | AUTHOR: byron
|
||||
* '.__/o o\__.' | EMAIL: xiaobo.sun@qq.com
|
||||
* {= ^ =} | QQ: 150093589
|
||||
* / \ | DATETIME: 2019/11/5 14:47
|
||||
* // \\ |
|
||||
* //| . |\\ |
|
||||
* "'\ /'"_.-~^`'-. |
|
||||
* \ _ /--' ` |
|
||||
* ___)( )(___ |-----------------------------------------
|
||||
* (((__) (__))) | 高山仰止,景行行止.虽不能至,心向往之。
|
||||
* +----------------------------------------------------------------------
|
||||
* | Copyright (c) 2019 http://www.zzstudio.net All rights reserved.
|
||||
* +----------------------------------------------------------------------
|
||||
*/
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace think;
|
||||
|
||||
use think\App;
|
||||
use think\helper\Str;
|
||||
use think\facade\Config;
|
||||
use think\facade\View;
|
||||
|
||||
abstract class Addons
|
||||
{
|
||||
// app 容器
|
||||
protected $app;
|
||||
// 请求对象
|
||||
protected $request;
|
||||
// 当前插件标识
|
||||
protected $name;
|
||||
// 插件路径
|
||||
protected $addon_path;
|
||||
// 视图模型
|
||||
protected $view;
|
||||
// 插件配置
|
||||
protected $addon_config;
|
||||
// 插件信息
|
||||
protected $addon_info;
|
||||
|
||||
/**
|
||||
* 插件构造函数
|
||||
* Addons constructor.
|
||||
* @param \think\App $app
|
||||
*/
|
||||
public function __construct(App $app)
|
||||
{
|
||||
$this->app = $app;
|
||||
$this->request = $app->request;
|
||||
$this->name = $this->getName();
|
||||
$this->addon_path = $app->addons->getAddonsPath() . $this->name . DIRECTORY_SEPARATOR;
|
||||
$this->addon_config = "addon_{$this->name}_config";
|
||||
$this->addon_info = "addon_{$this->name}_info";
|
||||
$this->view = clone View::engine('Think');
|
||||
$this->view->config([
|
||||
'view_path' => $this->addon_path . 'view' . DIRECTORY_SEPARATOR
|
||||
]);
|
||||
|
||||
// 控制器初始化
|
||||
$this->initialize();
|
||||
}
|
||||
|
||||
// 初始化
|
||||
protected function initialize()
|
||||
{}
|
||||
|
||||
/**
|
||||
* 获取插件标识
|
||||
* @return mixed|null
|
||||
*/
|
||||
final protected function getName()
|
||||
{
|
||||
$class = get_class($this);
|
||||
list(, $name, ) = explode('\\', $class);
|
||||
$this->request->addon = $name;
|
||||
|
||||
return $name;
|
||||
}
|
||||
|
||||
/**
|
||||
* 加载模板输出
|
||||
* @param string $template
|
||||
* @param array $vars 模板文件名
|
||||
* @return false|mixed|string 模板输出变量
|
||||
* @throws \think\Exception
|
||||
*/
|
||||
protected function fetch($template = '', $vars = [])
|
||||
{
|
||||
return $this->view->fetch($template, $vars);
|
||||
}
|
||||
|
||||
/**
|
||||
* 渲染内容输出
|
||||
* @access protected
|
||||
* @param string $content 模板内容
|
||||
* @param array $vars 模板输出变量
|
||||
* @return mixed
|
||||
*/
|
||||
protected function display($content = '', $vars = [])
|
||||
{
|
||||
return $this->view->display($content, $vars);
|
||||
}
|
||||
|
||||
/**
|
||||
* 模板变量赋值
|
||||
* @access protected
|
||||
* @param mixed $name 要显示的模板变量
|
||||
* @param mixed $value 变量的值
|
||||
* @return $this
|
||||
*/
|
||||
protected function assign($name, $value = '')
|
||||
{
|
||||
$this->view->assign([$name => $value]);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 初始化模板引擎
|
||||
* @access protected
|
||||
* @param array|string $engine 引擎参数
|
||||
* @return $this
|
||||
*/
|
||||
protected function engine($engine)
|
||||
{
|
||||
$this->view->engine($engine);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 插件基础信息
|
||||
* @return array
|
||||
*/
|
||||
final public function getInfo()
|
||||
{
|
||||
$info = Config::get($this->addon_info, []);
|
||||
if ($info) {
|
||||
return $info;
|
||||
}
|
||||
|
||||
// 文件属性
|
||||
$info = $this->info ?? [];
|
||||
// 文件配置
|
||||
$info_file = $this->addon_path . 'info.ini';
|
||||
if (is_file($info_file)) {
|
||||
$_info = parse_ini_file($info_file, true, INI_SCANNER_TYPED) ?: [];
|
||||
$_info['url'] = addons_url();
|
||||
$info = array_merge($_info, $info);
|
||||
}
|
||||
Config::set($info, $this->addon_info);
|
||||
|
||||
return isset($info) ? $info : [];
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取配置信息
|
||||
* @param bool $type 是否获取完整配置
|
||||
* @return array|mixed
|
||||
*/
|
||||
final public function getConfig($type = false)
|
||||
{
|
||||
$config = Config::get($this->addon_config, []);
|
||||
if ($config) {
|
||||
return $config;
|
||||
}
|
||||
$config_file = $this->addon_path . 'config.php';
|
||||
if (is_file($config_file)) {
|
||||
$temp_arr = (array)include $config_file;
|
||||
if ($type) {
|
||||
return $temp_arr;
|
||||
}
|
||||
foreach ($temp_arr as $key => $value) {
|
||||
$config[$key] = $value['value'];
|
||||
}
|
||||
unset($temp_arr);
|
||||
}
|
||||
Config::set($config, $this->addon_config);
|
||||
|
||||
return $config;
|
||||
}
|
||||
|
||||
//必须实现安装
|
||||
abstract public function install();
|
||||
|
||||
//必须卸载插件方法
|
||||
abstract public function uninstall();
|
||||
}
|
93
vendor/zzstudio/think-addons/src/addons/Route.php
vendored
Normal file
93
vendor/zzstudio/think-addons/src/addons/Route.php
vendored
Normal file
@ -0,0 +1,93 @@
|
||||
<?php
|
||||
/**
|
||||
* +----------------------------------------------------------------------
|
||||
* | think-addons [thinkphp6]
|
||||
* +----------------------------------------------------------------------
|
||||
* .--, .--, | FILE: Route.php
|
||||
* ( ( \.---./ ) ) | AUTHOR: byron
|
||||
* '.__/o o\__.' | EMAIL: xiaobo.sun@qq.com
|
||||
* {= ^ =} | QQ: 150093589
|
||||
* / \ | DATETIME: 2019/11/5 09:57
|
||||
* // \\ |
|
||||
* //| . |\\ |
|
||||
* "'\ /'"_.-~^`'-. |
|
||||
* \ _ /--' ` |
|
||||
* ___)( )(___ |-----------------------------------------
|
||||
* (((__) (__))) | 高山仰止,景行行止.虽不能至,心向往之。
|
||||
* +----------------------------------------------------------------------
|
||||
* | Copyright (c) 2019 http://www.zzstudio.net All rights reserved.
|
||||
* +----------------------------------------------------------------------
|
||||
*/
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace think\addons;
|
||||
|
||||
use think\helper\Str;
|
||||
use think\facade\Event;
|
||||
use think\facade\Config;
|
||||
use think\exception\HttpException;
|
||||
|
||||
class Route
|
||||
{
|
||||
/**
|
||||
* 插件路由请求
|
||||
* @param null $addon
|
||||
* @param null $controller
|
||||
* @param null $action
|
||||
* @return mixed
|
||||
*/
|
||||
public static function execute($addon = null, $controller = null, $action = null)
|
||||
{
|
||||
$app = app();
|
||||
$request = $app->request;
|
||||
|
||||
Event::trigger('addons_begin', $request);
|
||||
|
||||
if (empty($addon) || empty($controller) || empty($action)) {
|
||||
throw new HttpException(500, lang('addon can not be empty'));
|
||||
}
|
||||
|
||||
$request->addon = $addon;
|
||||
// 设置当前请求的控制器、操作
|
||||
$request->setController($controller)->setAction($action);
|
||||
|
||||
// 获取插件基础信息
|
||||
$info = get_addons_info($addon);
|
||||
if (!$info) {
|
||||
throw new HttpException(404, lang('addon %s not found', [$addon]));
|
||||
}
|
||||
if (!$info['status']) {
|
||||
throw new HttpException(500, lang('addon %s is disabled', [$addon]));
|
||||
}
|
||||
|
||||
// 监听addon_module_init
|
||||
Event::trigger('addon_module_init', $request);
|
||||
$class = get_addons_class($addon, 'controller', $controller);
|
||||
if (!$class) {
|
||||
throw new HttpException(404, lang('addon controller %s not found', [Str::studly($controller)]));
|
||||
}
|
||||
|
||||
// 重写视图基础路径
|
||||
$config = Config::get('view');
|
||||
$config['view_path'] = $app->addons->getAddonsPath() . $addon . DIRECTORY_SEPARATOR . 'view' . DIRECTORY_SEPARATOR;
|
||||
Config::set($config, 'view');
|
||||
|
||||
// 生成控制器对象
|
||||
$instance = new $class($app);
|
||||
$vars = [];
|
||||
if (is_callable([$instance, $action])) {
|
||||
// 执行操作方法
|
||||
$call = [$instance, $action];
|
||||
} elseif (is_callable([$instance, '_empty'])) {
|
||||
// 空操作
|
||||
$call = [$instance, '_empty'];
|
||||
$vars = [$action];
|
||||
} else {
|
||||
// 操作不存在
|
||||
throw new HttpException(404, lang('addon action %s not found', [get_class($instance).'->'.$action.'()']));
|
||||
}
|
||||
Event::trigger('addons_action_begin', $call);
|
||||
|
||||
return call_user_func_array($call, $vars);
|
||||
}
|
||||
}
|
232
vendor/zzstudio/think-addons/src/addons/Service.php
vendored
Normal file
232
vendor/zzstudio/think-addons/src/addons/Service.php
vendored
Normal file
@ -0,0 +1,232 @@
|
||||
<?php
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace think\addons;
|
||||
|
||||
use think\Route;
|
||||
use think\helper\Str;
|
||||
use think\facade\Config;
|
||||
use think\facade\Lang;
|
||||
use think\facade\Cache;
|
||||
use think\facade\Event;
|
||||
use think\addons\middleware\Addons;
|
||||
|
||||
/**
|
||||
* 插件服务
|
||||
* Class Service
|
||||
* @package think\addons
|
||||
*/
|
||||
class Service extends \think\Service
|
||||
{
|
||||
protected $addons_path;
|
||||
|
||||
public function register()
|
||||
{
|
||||
$this->addons_path = $this->getAddonsPath();
|
||||
// 加载系统语言包
|
||||
Lang::load([
|
||||
$this->app->getRootPath() . '/vendor/zzstudio/think-addons/src/lang/zh-cn.php'
|
||||
]);
|
||||
// 自动载入插件
|
||||
$this->autoload();
|
||||
// 加载插件事件
|
||||
$this->loadEvent();
|
||||
// 加载插件系统服务
|
||||
$this->loadService();
|
||||
// 绑定插件容器
|
||||
$this->app->bind('addons', Service::class);
|
||||
}
|
||||
|
||||
public function boot()
|
||||
{
|
||||
$this->registerRoutes(function (Route $route) {
|
||||
// 路由脚本
|
||||
$execute = '\\think\\addons\\Route::execute';
|
||||
|
||||
// 注册插件公共中间件
|
||||
if (is_file($this->app->addons->getAddonsPath() . 'middleware.php')) {
|
||||
$this->app->middleware->import(include $this->app->addons->getAddonsPath() . 'middleware.php', 'route');
|
||||
}
|
||||
|
||||
// 注册控制器路由
|
||||
$route->rule("addons/:addon/[:controller]/[:action]", $execute)->middleware(Addons::class);
|
||||
// 自定义路由
|
||||
$routes = (array) Config::get('addons.route', []);
|
||||
foreach ($routes as $key => $val) {
|
||||
if (!$val) {
|
||||
continue;
|
||||
}
|
||||
if (is_array($val)) {
|
||||
$domain = $val['domain'];
|
||||
$rules = [];
|
||||
foreach ($val['rule'] as $k => $rule) {
|
||||
[$addon, $controller, $action] = explode('/', $rule);
|
||||
$rules[$k] = [
|
||||
'addons' => $addon,
|
||||
'controller' => $controller,
|
||||
'action' => $action,
|
||||
'indomain' => 1,
|
||||
];
|
||||
}
|
||||
$route->domain($domain, function () use ($rules, $route, $execute) {
|
||||
// 动态注册域名的路由规则
|
||||
foreach ($rules as $k => $rule) {
|
||||
$route->rule($k, $execute)
|
||||
->name($k)
|
||||
->completeMatch(true)
|
||||
->append($rule);
|
||||
}
|
||||
});
|
||||
} else {
|
||||
list($addon, $controller, $action) = explode('/', $val);
|
||||
$route->rule($key, $execute)
|
||||
->name($key)
|
||||
->completeMatch(true)
|
||||
->append([
|
||||
'addons' => $addon,
|
||||
'controller' => $controller,
|
||||
'action' => $action
|
||||
]);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 插件事件
|
||||
*/
|
||||
private function loadEvent()
|
||||
{
|
||||
$hooks = $this->app->isDebug() ? [] : Cache::get('hooks', []);
|
||||
if (empty($hooks)) {
|
||||
$hooks = (array) Config::get('addons.hooks', []);
|
||||
// 初始化钩子
|
||||
foreach ($hooks as $key => $values) {
|
||||
if (is_string($values)) {
|
||||
$values = explode(',', $values);
|
||||
} else {
|
||||
$values = (array) $values;
|
||||
}
|
||||
$hooks[$key] = array_filter(array_map(function ($v) use ($key) {
|
||||
return [get_addons_class($v), $key];
|
||||
}, $values));
|
||||
}
|
||||
Cache::set('hooks', $hooks);
|
||||
}
|
||||
//如果在插件中有定义 AddonsInit,则直接执行
|
||||
if (isset($hooks['AddonsInit'])) {
|
||||
foreach ($hooks['AddonsInit'] as $k => $v) {
|
||||
Event::trigger('AddonsInit', $v);
|
||||
}
|
||||
}
|
||||
Event::listenEvents($hooks);
|
||||
}
|
||||
|
||||
/**
|
||||
* 挂载插件服务
|
||||
*/
|
||||
private function loadService()
|
||||
{
|
||||
$results = scandir($this->addons_path);
|
||||
$bind = [];
|
||||
foreach ($results as $name) {
|
||||
if ($name === '.' or $name === '..') {
|
||||
continue;
|
||||
}
|
||||
if (is_file($this->addons_path . $name)) {
|
||||
continue;
|
||||
}
|
||||
$addonDir = $this->addons_path . $name . DIRECTORY_SEPARATOR;
|
||||
if (!is_dir($addonDir)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!is_file($addonDir . ucfirst($name) . '.php')) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$service_file = $addonDir . 'service.ini';
|
||||
if (!is_file($service_file)) {
|
||||
continue;
|
||||
}
|
||||
$info = parse_ini_file($service_file, true, INI_SCANNER_TYPED) ?: [];
|
||||
$bind = array_merge($bind, $info);
|
||||
}
|
||||
$this->app->bind($bind);
|
||||
}
|
||||
|
||||
/**
|
||||
* 自动载入插件
|
||||
* @return bool
|
||||
*/
|
||||
private function autoload()
|
||||
{
|
||||
// 是否处理自动载入
|
||||
if (!Config::get('addons.autoload', true)) {
|
||||
return true;
|
||||
}
|
||||
$config = Config::get('addons');
|
||||
// 读取插件目录及钩子列表
|
||||
$base = get_class_methods("\\think\\Addons");
|
||||
// 读取插件目录中的php文件
|
||||
foreach (glob($this->getAddonsPath() . '*/*.php') as $addons_file) {
|
||||
// 格式化路径信息
|
||||
$info = pathinfo($addons_file);
|
||||
// 获取插件目录名
|
||||
$name = pathinfo($info['dirname'], PATHINFO_FILENAME);
|
||||
// 找到插件入口文件
|
||||
if (strtolower($info['filename']) === 'plugin') {
|
||||
// 读取出所有公共方法
|
||||
$methods = (array)get_class_methods("\\addons\\" . $name . "\\" . $info['filename']);
|
||||
// 跟插件基类方法做比对,得到差异结果
|
||||
$hooks = array_diff($methods, $base);
|
||||
// 循环将钩子方法写入配置中
|
||||
foreach ($hooks as $hook) {
|
||||
if (!isset($config['hooks'][$hook])) {
|
||||
$config['hooks'][$hook] = [];
|
||||
}
|
||||
// 兼容手动配置项
|
||||
if (is_string($config['hooks'][$hook])) {
|
||||
$config['hooks'][$hook] = explode(',', $config['hooks'][$hook]);
|
||||
}
|
||||
if (!in_array($name, $config['hooks'][$hook])) {
|
||||
$config['hooks'][$hook][] = $name;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Config::set($config, 'addons');
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取 addons 路径
|
||||
* @return string
|
||||
*/
|
||||
public function getAddonsPath()
|
||||
{
|
||||
// 初始化插件目录
|
||||
$addons_path = $this->app->getRootPath() . 'addons' . DIRECTORY_SEPARATOR;
|
||||
// 如果插件目录不存在则创建
|
||||
if (!is_dir($addons_path)) {
|
||||
@mkdir($addons_path, 0755, true);
|
||||
}
|
||||
|
||||
return $addons_path;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取插件的配置信息
|
||||
* @param string $name
|
||||
* @return array
|
||||
*/
|
||||
public function getAddonsConfig()
|
||||
{
|
||||
$name = $this->app->request->addon;
|
||||
$addon = get_addons_instance($name);
|
||||
if (!$addon) {
|
||||
return [];
|
||||
}
|
||||
|
||||
return $addon->getConfig();
|
||||
}
|
||||
}
|
67
vendor/zzstudio/think-addons/src/addons/command/SendConfig.php
vendored
Normal file
67
vendor/zzstudio/think-addons/src/addons/command/SendConfig.php
vendored
Normal file
@ -0,0 +1,67 @@
|
||||
<?php
|
||||
/**
|
||||
* +----------------------------------------------------------------------
|
||||
* | think-addons [基于 thinkphp6]
|
||||
* +----------------------------------------------------------------------
|
||||
* .--, .--, | FILE: config.php
|
||||
* ( ( \.---./ ) ) | AUTHOR: byron sampson
|
||||
* '.__/o o\__.' | EMAIL: xiaobo.sun@qq.com
|
||||
* {= ^ =} | QQ: 150093589
|
||||
* > - < | WECHAT: wx5ini99
|
||||
* / \ | DATETIME: 2019/10/29
|
||||
* // \\ |
|
||||
* //| . |\\ |
|
||||
* "'\ /'"_.-~^`'-. |
|
||||
* \ _ /--' ` |
|
||||
* ___)( )(___ |-----------------------------------------
|
||||
* (((__) (__))) | 高山仰止,景行行止.虽不能至,心向往之。
|
||||
* +----------------------------------------------------------------------
|
||||
* | Copyright (c) 2019 http://www.zzstudio.net All rights reserved.
|
||||
* +----------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
namespace think\addons\command;
|
||||
|
||||
use think\console\Command;
|
||||
use think\console\Input;
|
||||
use think\console\input\Argument;
|
||||
use think\console\input\Option;
|
||||
use think\console\Output;
|
||||
use think\facade\Env;
|
||||
|
||||
class SendConfig extends Command
|
||||
{
|
||||
|
||||
public function configure()
|
||||
{
|
||||
$this->setName('addons:config')
|
||||
->setDescription('send config to config folder');
|
||||
}
|
||||
|
||||
public function execute(Input $input, Output $output)
|
||||
{
|
||||
//获取默认配置文件
|
||||
$content = file_get_contents(root_path() . 'vendor/zzstudio/think-addons/src/config.php');
|
||||
|
||||
$configPath = config_path() . '/';
|
||||
$configFile = $configPath . 'addons.php';
|
||||
|
||||
|
||||
//判断目录是否存在
|
||||
if (!file_exists($configPath)) {
|
||||
mkdir($configPath, 0755, true);
|
||||
}
|
||||
|
||||
//判断文件是否存在
|
||||
if (is_file($configFile)) {
|
||||
throw new \InvalidArgumentException(sprintf('The config file "%s" already exists', $configFile));
|
||||
}
|
||||
|
||||
if (false === file_put_contents($configFile, $content)) {
|
||||
throw new \RuntimeException(sprintf('The config file "%s" could not be written to "%s"', $configFile,$configPath));
|
||||
}
|
||||
|
||||
$output->writeln('create addons config ok');
|
||||
}
|
||||
|
||||
}
|
48
vendor/zzstudio/think-addons/src/addons/middleware/Addons.php
vendored
Normal file
48
vendor/zzstudio/think-addons/src/addons/middleware/Addons.php
vendored
Normal file
@ -0,0 +1,48 @@
|
||||
<?php
|
||||
/**
|
||||
* +----------------------------------------------------------------------
|
||||
* | think-addons [thinkphp6]
|
||||
* +----------------------------------------------------------------------
|
||||
* .--, .--, | FILE: Addons.php
|
||||
* ( ( \.---./ ) ) | AUTHOR: byron
|
||||
* '.__/o o\__.' | EMAIL: xiaobo.sun@qq.com
|
||||
* {= ^ =} | QQ: 150093589
|
||||
* / \ | DATETIME: 2019/11/5 09:55
|
||||
* // \\ |
|
||||
* //| . |\\ |
|
||||
* "'\ /'"_.-~^`'-. |
|
||||
* \ _ /--' ` |
|
||||
* ___)( )(___ |-----------------------------------------
|
||||
* (((__) (__))) | 高山仰止,景行行止.虽不能至,心向往之。
|
||||
* +----------------------------------------------------------------------
|
||||
* | Copyright (c) 2019 http://www.zzstudio.net All rights reserved.
|
||||
* +----------------------------------------------------------------------
|
||||
*/
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace think\addons\middleware;
|
||||
|
||||
use think\App;
|
||||
|
||||
class Addons
|
||||
{
|
||||
protected $app;
|
||||
|
||||
public function __construct(App $app)
|
||||
{
|
||||
$this->app = $app;
|
||||
}
|
||||
|
||||
/**
|
||||
* 插件中间件
|
||||
* @param $request
|
||||
* @param \Closure $next
|
||||
* @return mixed
|
||||
*/
|
||||
public function handle($request, \Closure $next)
|
||||
{
|
||||
hook('addon_middleware', $request);
|
||||
|
||||
return $next($request);
|
||||
}
|
||||
}
|
17
vendor/zzstudio/think-addons/src/config.php
vendored
Normal file
17
vendor/zzstudio/think-addons/src/config.php
vendored
Normal file
@ -0,0 +1,17 @@
|
||||
<?php
|
||||
// +----------------------------------------------------------------------
|
||||
// | thinkphp5 Addons [ WE CAN DO IT JUST THINK IT ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | Copyright (c) 2016 http://www.zzstudio.net All rights reserved.
|
||||
// +----------------------------------------------------------------------
|
||||
// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
|
||||
// +----------------------------------------------------------------------
|
||||
// | Author: Byron Sampson <xiaobo.sun@qq.com>
|
||||
// +----------------------------------------------------------------------
|
||||
|
||||
return [
|
||||
'autoload' => true,
|
||||
'hooks' => [],
|
||||
'route' => [],
|
||||
'service' => [],
|
||||
];
|
177
vendor/zzstudio/think-addons/src/helper.php
vendored
Normal file
177
vendor/zzstudio/think-addons/src/helper.php
vendored
Normal file
@ -0,0 +1,177 @@
|
||||
<?php
|
||||
declare(strict_types=1);
|
||||
|
||||
use think\facade\Event;
|
||||
use think\facade\Route;
|
||||
use think\helper\{
|
||||
Str, Arr
|
||||
};
|
||||
|
||||
\think\Console::starting(function (\think\Console $console) {
|
||||
$console->addCommands([
|
||||
'addons:config' => '\\think\\addons\\command\\SendConfig'
|
||||
]);
|
||||
});
|
||||
|
||||
// 插件类库自动载入
|
||||
spl_autoload_register(function ($class) {
|
||||
|
||||
$class = ltrim($class, '\\');
|
||||
|
||||
$dir = app()->getRootPath();
|
||||
$namespace = 'addons';
|
||||
|
||||
if (strpos($class, $namespace) === 0) {
|
||||
$class = substr($class, strlen($namespace));
|
||||
$path = '';
|
||||
if (($pos = strripos($class, '\\')) !== false) {
|
||||
$path = str_replace('\\', '/', substr($class, 0, $pos)) . '/';
|
||||
$class = substr($class, $pos + 1);
|
||||
}
|
||||
$path .= str_replace('_', '/', $class) . '.php';
|
||||
$dir .= $namespace . $path;
|
||||
|
||||
if (file_exists($dir)) {
|
||||
include $dir;
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
return false;
|
||||
|
||||
});
|
||||
|
||||
if (!function_exists('hook')) {
|
||||
/**
|
||||
* 处理插件钩子
|
||||
* @param string $event 钩子名称
|
||||
* @param array|null $params 传入参数
|
||||
* @param bool $once 是否只返回一个结果
|
||||
* @return mixed
|
||||
*/
|
||||
function hook($event, $params = null, bool $once = false)
|
||||
{
|
||||
$result = Event::trigger($event, $params, $once);
|
||||
|
||||
return join('', $result);
|
||||
}
|
||||
}
|
||||
|
||||
if (!function_exists('get_addons_info')) {
|
||||
/**
|
||||
* 读取插件的基础信息
|
||||
* @param string $name 插件名
|
||||
* @return array
|
||||
*/
|
||||
function get_addons_info($name)
|
||||
{
|
||||
$addon = get_addons_instance($name);
|
||||
if (!$addon) {
|
||||
return [];
|
||||
}
|
||||
|
||||
return $addon->getInfo();
|
||||
}
|
||||
}
|
||||
|
||||
if (!function_exists('get_addons_instance')) {
|
||||
/**
|
||||
* 获取插件的单例
|
||||
* @param string $name 插件名
|
||||
* @return mixed|null
|
||||
*/
|
||||
function get_addons_instance($name)
|
||||
{
|
||||
static $_addons = [];
|
||||
if (isset($_addons[$name])) {
|
||||
return $_addons[$name];
|
||||
}
|
||||
$class = get_addons_class($name);
|
||||
if (class_exists($class)) {
|
||||
$_addons[$name] = new $class(app());
|
||||
|
||||
return $_addons[$name];
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!function_exists('get_addons_class')) {
|
||||
/**
|
||||
* 获取插件类的类名
|
||||
* @param string $name 插件名
|
||||
* @param string $type 返回命名空间类型
|
||||
* @param string $class 当前类名
|
||||
* @return string
|
||||
*/
|
||||
function get_addons_class($name, $type = 'hook', $class = null)
|
||||
{
|
||||
$name = trim($name);
|
||||
// 处理多级控制器情况
|
||||
if (!is_null($class) && strpos($class, '.')) {
|
||||
$class = explode('.', $class);
|
||||
|
||||
$class[count($class) - 1] = Str::studly(end($class));
|
||||
$class = implode('\\', $class);
|
||||
} else {
|
||||
$class = Str::studly(is_null($class) ? $name : $class);
|
||||
}
|
||||
switch ($type) {
|
||||
case 'controller':
|
||||
$namespace = '\\addons\\' . $name . '\\controller\\' . $class;
|
||||
break;
|
||||
default:
|
||||
$namespace = '\\addons\\' . $name . '\\Plugin';
|
||||
}
|
||||
|
||||
return class_exists($namespace) ? $namespace : '';
|
||||
}
|
||||
}
|
||||
|
||||
if (!function_exists('addons_url')) {
|
||||
/**
|
||||
* 插件显示内容里生成访问插件的url
|
||||
* @param $url
|
||||
* @param array $param
|
||||
* @param bool|string $suffix 生成的URL后缀
|
||||
* @param bool|string $domain 域名
|
||||
* @return bool|string
|
||||
*/
|
||||
function addons_url($url = '', $param = [], $suffix = true, $domain = false)
|
||||
{
|
||||
$request = app('request');
|
||||
if (empty($url)) {
|
||||
// 生成 url 模板变量
|
||||
$addons = $request->addon;
|
||||
$controller = $request->controller();
|
||||
$controller = str_replace('/', '.', $controller);
|
||||
$action = $request->action();
|
||||
} else {
|
||||
$url = Str::studly($url);
|
||||
$url = parse_url($url);
|
||||
if (isset($url['scheme'])) {
|
||||
$addons = strtolower($url['scheme']);
|
||||
$controller = $url['host'];
|
||||
$action = trim($url['path'], '/');
|
||||
} else {
|
||||
$route = explode('/', $url['path']);
|
||||
$addons = $request->addon;
|
||||
$action = array_pop($route);
|
||||
$controller = array_pop($route) ?: $request->controller();
|
||||
}
|
||||
$controller = Str::snake((string)$controller);
|
||||
|
||||
/* 解析URL带的参数 */
|
||||
if (isset($url['query'])) {
|
||||
parse_str($url['query'], $query);
|
||||
$param = array_merge($query, $param);
|
||||
}
|
||||
}
|
||||
|
||||
return Route::buildUrl("@addons/{$addons}/{$controller}/{$action}", $param)->suffix($suffix)->domain($domain);
|
||||
}
|
||||
}
|
||||
|
97
vendor/zzstudio/think-addons/src/lang/zh-cn.php
vendored
Normal file
97
vendor/zzstudio/think-addons/src/lang/zh-cn.php
vendored
Normal file
@ -0,0 +1,97 @@
|
||||
<?php
|
||||
// 插件中文语言包
|
||||
return [
|
||||
'addon %s not found' => '插件 %s 未找到',
|
||||
'addon %s is disabled' => '插件 %s 已禁用',
|
||||
'addon controller %s not found' => '插件控制器 %s 未找到',
|
||||
'addon action %s not found' => '插件控制器方法 %s 未找到',
|
||||
'addon can not be empty' => '插件不能为空',
|
||||
'Keep login' => '保持会话',
|
||||
'Forgot password' => '忘记密码?',
|
||||
'Username' => '用户名',
|
||||
'User id' => '会员ID',
|
||||
'Nickname' => '昵称',
|
||||
'Password' => '密码',
|
||||
'Sign up' => '注 册',
|
||||
'Sign in' => '登 录',
|
||||
'Sign out' => '注 销',
|
||||
'Guest' => '游客',
|
||||
'Welcome' => '%s,你好!',
|
||||
'Add' => '添加',
|
||||
'Edit' => '编辑',
|
||||
'Delete' => '删除',
|
||||
'Move' => '移动',
|
||||
'Name' => '名称',
|
||||
'Status' => '状态',
|
||||
'Weigh' => '权重',
|
||||
'Operate' => '操作',
|
||||
'Warning' => '温馨提示',
|
||||
'Default' => '默认',
|
||||
'Article' => '文章',
|
||||
'Page' => '单页',
|
||||
'OK' => '确定',
|
||||
'Cancel' => '取消',
|
||||
'Loading' => '加载中',
|
||||
'More' => '更多',
|
||||
'Normal' => '正常',
|
||||
'Hidden' => '隐藏',
|
||||
'Submit' => '提交',
|
||||
'Reset' => '重置',
|
||||
'Execute' => '执行',
|
||||
'Close' => '关闭',
|
||||
'Search' => '搜索',
|
||||
'Refresh' => '刷新',
|
||||
'First' => '首页',
|
||||
'Previous' => '上一页',
|
||||
'Next' => '下一页',
|
||||
'Last' => '末页',
|
||||
'None' => '无',
|
||||
'Online' => '在线',
|
||||
'Logout' => '注销',
|
||||
'Profile' => '个人资料',
|
||||
'Index' => '首页',
|
||||
'Hot' => '热门',
|
||||
'Recommend' => '推荐',
|
||||
'Dashboard' => '控制台',
|
||||
'Code' => '编号',
|
||||
'Message' => '内容',
|
||||
'Line' => '行号',
|
||||
'File' => '文件',
|
||||
'Menu' => '菜单',
|
||||
'Type' => '类型',
|
||||
'Title' => '标题',
|
||||
'Content' => '内容',
|
||||
'Append' => '追加',
|
||||
'Memo' => '备注',
|
||||
'Parent' => '父级',
|
||||
'Params' => '参数',
|
||||
'Permission' => '权限',
|
||||
'Begin time' => '开始时间',
|
||||
'End time' => '结束时间',
|
||||
'Create time' => '创建时间',
|
||||
'Flag' => '标志',
|
||||
'Home' => '首页',
|
||||
'Store' => '插件市场',
|
||||
'Services' => '服务',
|
||||
'Download' => '下载',
|
||||
'Demo' => '演示',
|
||||
'Donation' => '捐赠',
|
||||
'Forum' => '社区',
|
||||
'Docs' => '文档',
|
||||
'Go back' => '返回首页',
|
||||
'Jump now' => '立即跳转',
|
||||
'Please login first' => '请登录后再操作',
|
||||
'Send verification code' => '发送验证码',
|
||||
'Redirect now' => '立即跳转',
|
||||
'Operation completed' => '操作成功!',
|
||||
'Operation failed' => '操作失败!',
|
||||
'Unknown data format' => '未知的数据格式!',
|
||||
'Network error' => '网络错误!',
|
||||
'Advanced search' => '高级搜索',
|
||||
'Invalid parameters' => '未知参数',
|
||||
'No results were found' => '记录未找到',
|
||||
'Parameter %s can not be empty' => '参数 %s 不能为空',
|
||||
'You have no permission' => '你没有权限访问',
|
||||
'An unexpected error occurred' => '发生了一个意外错误,程序猿正在紧急处理中',
|
||||
'This page will be re-directed in %s seconds' => '页面将在 %s 秒后自动跳转',
|
||||
];
|
Loading…
Reference in New Issue
Block a user