升级插件系统,修复上传组件

This commit is contained in:
taoser 2023-03-16 22:25:27 +08:00
parent a420104b03
commit eac02b95d3
69 changed files with 2620 additions and 1273 deletions

View File

@ -148,6 +148,22 @@ class Forum extends AdminController
View::assign(['template'=>$template]);
return View::fetch();
}
// 应用下article/view模板
public function getAppNameView()
{
$appName = input('appname') ?: 'index';
$sys = $this->getSystem();
if(is_dir(root_path() . 'app' . DS . $appName . DS . 'view' . DS)){
$viewPath = root_path() . 'app' . DS . $appName . DS . 'view' . DS . 'article' . DS;
} elseif(is_dir(root_path() . 'view' . DS . $sys['template'] . DS)) {
$viewPath = root_path() . 'view' . DS . $sys['template'] . DS . 'index' . DS . 'article' . DS;
} else {
$viewPath = '';
}
$template = Files::getDirName($viewPath);
return json(['data' => $template]);
}
//添加和编辑帖子分类
public function tagsform()
@ -169,21 +185,18 @@ class Forum extends AdminController
$sys = $this->getSystem();
$template = Files::getDirName('../view/'.$sys['template'].'/index/article/');
// 如果是新增pid=0,detpl默认第一个子模块如果是编辑查询出cate
$cate = $addOrEdit ? Db::name('cate')->field('detpl,pid')->find((int) input('id')) : ['pid'=>0,'detpl'=>$template[0]];
View::assign(['template'=>$template,'cate'=>$cate]);
$cate = $addOrEdit ? Db::name('cate')->field('detpl,pid,appname')->where(['delete_time' =>0])->find((int) input('id')) : ['pid'=>0,'detpl'=>$template[0],'appname'=>'index'];
// app下前台带模板的应用
$appArr = [];
if(is_dir(root_path() . 'app' . DS . 'home')) {
$appArr = ['index','home'];
} else {
$appArr = ['index'];
}
View::assign(['template'=>$template,'cate'=>$cate, 'appname' => $appArr]);
return View::fetch();
}
//详情页模板设置
public function tplSet()
{
if(Request::isPost()){
$data = Request::only(['id','detpl']);
Db::name('cate')->cache('catename')->update($data);
}
}
//删除帖子分类
public function tagsdelete()
{

View File

@ -95,9 +95,10 @@ overflow: visible;
[
{type: 'numbers'},
{type: 'checkbox'}
,{field: 'catename', title: '分类名', minWidth: 200}
,{field: 'catename', title: '分类名', width: 150}
,{field: 'appname', title: '所属应用', width: 90}
,{field: 'ename', title: 'EN别名', width: 100}
,{field: 'detpl',title: '模板', align: 'center',width: 100,templet: '#inputSel'}
,{field: 'detpl',title: '模板', align: 'center',width: 100}
,{title: '图标', align: 'center',width: 50,templet: '<p><i class="layui-icon {{d.icon}}"></i></p>'}
,{field: 'is_hot', title: '热门', align: 'center',width: 50, templet: '#buttonHot'}
,{field: 'desc', title: '描述', minWidth: 200}
@ -189,15 +190,13 @@ overflow: visible;
}
});
var active = {
add: function(){
layer.open({
type: 2
,title: '添加分类'
,content: 'tagsform.html'
,area: ['400px', '550px']
,area: ['450px', '550px']
,btn: ['确定', '取消']
,yes: function(index, layero){
var othis = layero.find('iframe').contents().find("#layuiadmin-app-form-tags")
@ -230,17 +229,6 @@ overflow: visible;
});
}
}
//详情页模板选择控制
form.on('select(detpl)', function(data){
var detpl = data.value;
$.post("{:url('Forum/tplSet')}",{"id":data.elem.id,"detpl":detpl});
//执行重载
table.reload('LAY-app-content-tags', {
where: detpl
});
});
//分类热点控制
form.on('checkbox(menu-show)', function(data){

View File

@ -9,34 +9,42 @@
<div id="menuSelectBox" class="ew-xmselect-tree"></div>
</div>
</div>
<label class="layui-form-label">所属应用</label>
<div class="layui-input-block">
<select name="appname" lay-filter="appname" lay-verify="required">
{volist name="appname" id="vo"}
<option value="{$vo}" {if($vo == $cate.appname)} selected {/if}>{$vo}</option>
{/volist}
</select>
</div>
<div class="layui-form-item">
<label class="layui-form-label">分类名</label>
<div class="layui-input-inline">
<div class="layui-input-block">
<input type="text" name="catename" lay-verify="required" placeholder="分类名*" autocomplete="off" class="layui-input">
</div>
<label class="layui-form-label">EN别名</label>
<div class="layui-input-inline">
<div class="layui-input-block">
<input type="text" name="ename" lay-verify="required" placeholder="英文名*" autocomplete="off" class="layui-input">
</div>
<label class="layui-form-label">详情页模板</label>
<div class="layui-input-inline">
<select name="detpl" lay-filter="detpl">
{volist name="template" id="vo"}
<option value="{$vo}" {if($vo == $cate.detpl)} selected {/if} >{$vo}</option>
{/volist}
<div class="layui-input-block">
<select name="detpl" id="tpl" lay-verify="required">
{volist name="template" id="vo"}
<option value="{$vo}" {if($vo == $cate.detpl)} selected {/if} >{$vo}</option>
{/volist}
</select>
</div>
<label class="layui-form-label">图标</label>
<div class="layui-input-inline">
<div class="layui-input-block">
<input type="text" name="icon" placeholder="图标*" id="iconPicker" lay-filter="iconPicker" style="display:none;" class="layui-input">
</div>
<label class="layui-form-label">描述</label>
<div class="layui-input-inline">
<div class="layui-input-block">
<input type="text" name="desc" lay-verify="required" placeholder="描述*" autocomplete="off" class="layui-input">
</div>
<label class="layui-form-label">排序</label>
<div class="layui-input-inline">
<input type="text" name="sort" lay-verify="required" placeholder="请填数字" autocomplete="off" class="layui-input">
<div class="layui-input-block">
<input type="text" name="sort" lay-verify="number|required" placeholder="请填数字" autocomplete="off" class="layui-input">
</div>
</div>
</div>
@ -69,6 +77,22 @@
}
});
form.on('select(appname)', function(data){
var appName = data.value;
$("#tpl").children('option').remove();
$.post("{:url('Forum/getAppNameView')}", {appname:appName},function (res){
var str = '<option value="" >请选择</option>';
for(var i=0; i < res.data.length; i++ ) {
str += '<option value="'+ res.data[i] +'" >' + res.data[i] + '</option>';
// $("select[name='detpl']").append('<option value="'+ arr[i] +'" >' + arr[i] + '</option>');
}
$("#tpl").append(str);
// 动态select重新渲染
form.render('select');
})
});
//分类菜单结构
admin.req({
type: "post",

View File

@ -66,8 +66,9 @@ class BaseController extends BaseCtrl
// 显示导航nav
protected function showNav()
{
$appname = app('http')->getName();
//1.查询分类表获取所有分类
$cateList = Db::name('cate')->where(['status'=>1,'delete_time'=>0])->cache('catename',3600)->select()->toArray();
$cateList = Db::name('cate')->where(['status'=>1,'delete_time'=>0, 'appname' => $appname])->cache('catename' . $appname,3600)->select()->toArray();
return getTree($cateList);
}

View File

@ -110,8 +110,10 @@ class Article extends Model
public function getArtTop(int $num)
{
$artTop = Cache::get('arttop');
// 区分应用分类
$appCateIdArr = Cate::where(['appname' => app('http')->getName()])->column('id');
if (!$artTop) {
$artTop = $this::field('id,title,title_color,cate_id,user_id,create_time,is_top,pv,jie,upzip,has_img,has_video,has_audio')->where(['is_top' => 1, 'status' => 1])
$artTop = $this::field('id,title,title_color,cate_id,user_id,create_time,is_top,pv,jie,upzip,has_img,has_video,has_audio')->where([['is_top', '=', 1], ['status', '=', 1], ['cate_id', 'in', $appCateIdArr]])
->with([
'cate' => function ($query) {
$query->where('delete_time', 0)->field('id,catename,ename');
@ -142,6 +144,8 @@ class Article extends Model
public function getArtList(int $num)
{
$artList = Cache::get('artlist');
// 区分应用分类
$appCateIdArr = Cate::where(['appname' => app('http')->getName()])->column('id');
if(!$artList){
$artList = $this::field('id,title,title_color,cate_id,user_id,create_time,is_hot,pv,jie,upzip,has_img,has_video,has_audio')
->with([
@ -152,7 +156,7 @@ class Article extends Model
$query->field('id,name,nickname,user_img,area_id,vip');
} ])
->withCount(['comments'])
->where(['status'=>1,'is_top'=>0])
->where([['status', '=', 1], ['is_top', '=', 0],['cate_id', 'in', $appCateIdArr]])
->order('create_time','desc')
->limit($num)
->append(['url'])
@ -237,14 +241,17 @@ class Article extends Model
public function getCateList(string $ename, string $type, int $page = 1)
{
$where = [];
// 区分应用分类
$appCateIdArr = Cate::where(['appname' => app('http')->getName()])->column('id');
$cateId = Cate::where('ename',$ename)->value('id');
if($cateId){
$where = ['cate_id' => $cateId];
$where[] = ['cate_id' ,'=', $cateId];
} else {
if($ename != 'all'){
// 抛出 HTTP 异常
throw new \think\exception\HttpException(404, '异常消息');
}
$where[] = ['cate_id' ,'in',$appCateIdArr];
}
$artList = Cache::get('arts'.$ename.$type.$page);
@ -252,25 +259,23 @@ class Article extends Model
switch ($type) {
//查询文章,15个分1页
case 'jie':
$where['jie'] = 1;
$where[] = ['jie','=', 1];
break;
case 'hot':
$where['is_hot'] = 1;
$where[] = ['is_hot','=', 1];
break;
case 'top':
$where['is_top'] = 1;
$where[] = ['is_top' ,'=', 1];
break;
case 'wait':
$where['jie'] = 0;
break;
default:
$where = $where;
$where[] = ['jie','=', 0];
break;
}
$artList = $this::field('id,title,content,title_color,cate_id,user_id,create_time,is_top,is_hot,pv,jie,upzip,has_img,has_video,has_audio')
->with([
'cate' => function($query){
$query->where('delete_time',0)->field('id,catename,ename');
'cate' => function($query) {
$query->where('delete_time',0)->field('id,catename,ename,appname');
},
'user' => function($query){
$query->field('id,name,nickname,user_img,area_id,vip');

View File

@ -53,7 +53,7 @@ class Cate extends Model
// 分类表
public function getList()
{
$data = $this->field('sort,id,pid,catename,ename,detpl,icon,is_hot,desc')->where(['status'=>1])->select()->toArray();
$data = $this->field('sort,id,pid,catename,ename,detpl,icon,appname,is_hot,desc')->where(['status'=>1])->select()->toArray();
// 排序
$cmf_arr = array_column($data, 'sort');
array_multisort($cmf_arr, SORT_ASC, $data);

View File

@ -17,6 +17,4 @@ class Article extends Facade
return 'app\common\model\Article';
}
}

21
app/facade/Cate.php Normal file
View File

@ -0,0 +1,21 @@
<?php
namespace app\facade;
use think\Facade;
/**
* Class Article
* @package app\facade
* @method static array getArtTop(int $num) 获取置顶文章
* @method static array getArtList(int $num) 获取文章列表
* @method static array getArtHot(int $num) 获取精华文章
*/
class Cate extends Facade
{
protected static function getFacadeClass()
{
return 'app\common\model\Cate';
}
}

View File

@ -11,12 +11,15 @@
namespace app\index\controller;
use app\common\controller\BaseController;
use app\common\lib\facade\HttpHelper;
use think\facade\View;
use think\facade\Request;
use think\facade\Db;
use app\facade\Article;
use app\common\model\Slider;
use app\common\lib\Msgres;
use yzh52521\EasyHttp\Http;
use QL\QueryList;
class Index extends BaseController
{

View File

@ -40,7 +40,7 @@
"jaeger/querylist": "^4.2",
"symfony/var-exporter": "^5.4",
"yzh52521/easyhttp": "^1.0",
"topthink/think-filesystem": "^2.0"
"topthink/think-filesystem": "1.0.1"
},
"require-dev": {
"symfony/var-dumper": "^4.2",

743
composer.lock generated

File diff suppressed because it is too large Load Diff

View File

@ -16,7 +16,7 @@ return [
// 应用名,此项不可更改
'appname' => 'TaoLer',
// 版本配置
'version' => '2.0.9',
'version' => '2.0.10',
// 加盐
'salt' => 'taoler',
// 数据库备份目录

2
public/static/home/.gitignore vendored Normal file
View File

@ -0,0 +1,2 @@
*
!.gitignore

View File

@ -1,2 +1 @@
ALTER TABLE `tao_auth_rule` CHANGE `sort` `sort` int NOT NULL DEFAULT 50 COMMENT '排序';
ALTER TABLE `tao_auth_rule` CHANGE `ishidden` `ismenu` enum('1','2','3','0','-1') NOT NULL DEFAULT '1' COMMENT '1菜单,2按钮3目录';
ALTER TABLE `tao_cate` ADD `appname` varchar(20) NOT NULL DEFAULT 'index' COMMENT '所属应用' AFTER `status`;

View File

@ -14,7 +14,7 @@ return array(
'think\\composer\\' => array($vendorDir . '/topthink/think-installer/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', $vendorDir . '/topthink/think-filesystem/src'),
'think\\' => array($vendorDir . '/topthink/framework/src/think', $vendorDir . '/topthink/think-filesystem/src', $vendorDir . '/topthink/think-helper/src', $vendorDir . '/topthink/think-orm/src', $vendorDir . '/topthink/think-template/src'),
'taoser\\think\\' => array($vendorDir . '/taoser/think-auth/src'),
'taoser\\' => array($vendorDir . '/taoser/think-addons/src', $vendorDir . '/taoser/think-setarr/src'),
'phpspirit\\databackup\\' => array($vendorDir . '/lotofbadcode/phpspirit_databackup/src'),
@ -42,6 +42,7 @@ return array(
'PHPSocketIO\\' => array($vendorDir . '/workerman/phpsocket.io/src'),
'PHPMailer\\PHPMailer\\' => array($vendorDir . '/phpmailer/phpmailer/src'),
'League\\MimeTypeDetection\\' => array($vendorDir . '/league/mime-type-detection/src'),
'League\\Flysystem\\Cached\\' => array($vendorDir . '/league/flysystem-cached-adapter/src'),
'League\\Flysystem\\' => array($vendorDir . '/league/flysystem/src'),
'Laravel\\SerializableClosure\\' => array($vendorDir . '/laravel/serializable-closure/src'),
'Jaeger\\' => array($vendorDir . '/jaeger/g-http/src'),

View File

@ -102,6 +102,7 @@ class ComposerStaticInit1b32198725235c8d6500c87262ef30c2
'L' =>
array (
'League\\MimeTypeDetection\\' => 25,
'League\\Flysystem\\Cached\\' => 24,
'League\\Flysystem\\' => 17,
'Laravel\\SerializableClosure\\' => 28,
),
@ -181,10 +182,10 @@ class ComposerStaticInit1b32198725235c8d6500c87262ef30c2
'think\\' =>
array (
0 => __DIR__ . '/..' . '/topthink/framework/src/think',
1 => __DIR__ . '/..' . '/topthink/think-helper/src',
2 => __DIR__ . '/..' . '/topthink/think-orm/src',
3 => __DIR__ . '/..' . '/topthink/think-template/src',
4 => __DIR__ . '/..' . '/topthink/think-filesystem/src',
1 => __DIR__ . '/..' . '/topthink/think-filesystem/src',
2 => __DIR__ . '/..' . '/topthink/think-helper/src',
3 => __DIR__ . '/..' . '/topthink/think-orm/src',
4 => __DIR__ . '/..' . '/topthink/think-template/src',
),
'taoser\\think\\' =>
array (
@ -295,6 +296,10 @@ class ComposerStaticInit1b32198725235c8d6500c87262ef30c2
array (
0 => __DIR__ . '/..' . '/league/mime-type-detection/src',
),
'League\\Flysystem\\Cached\\' =>
array (
0 => __DIR__ . '/..' . '/league/flysystem-cached-adapter/src',
),
'League\\Flysystem\\' =>
array (
0 => __DIR__ . '/..' . '/league/flysystem/src',

View File

@ -962,47 +962,63 @@
},
{
"name": "league/flysystem",
"version": "2.5.0",
"version_normalized": "2.5.0.0",
"version": "1.1.10",
"version_normalized": "1.1.10.0",
"source": {
"type": "git",
"url": "https://github.com/thephpleague/flysystem.git",
"reference": "8aaffb653c5777781b0f7f69a5d937baf7ab6cdb"
"reference": "3239285c825c152bcc315fe0e87d6b55f5972ed1"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/thephpleague/flysystem/zipball/8aaffb653c5777781b0f7f69a5d937baf7ab6cdb",
"reference": "8aaffb653c5777781b0f7f69a5d937baf7ab6cdb",
"shasum": ""
"url": "https://api.github.com/repos/thephpleague/flysystem/zipball/3239285c825c152bcc315fe0e87d6b55f5972ed1",
"reference": "3239285c825c152bcc315fe0e87d6b55f5972ed1",
"shasum": "",
"mirrors": [
{
"url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%",
"preferred": true
}
]
},
"require": {
"ext-json": "*",
"league/mime-type-detection": "^1.0.0",
"php": "^7.2 || ^8.0"
"ext-fileinfo": "*",
"league/mime-type-detection": "^1.3",
"php": "^7.2.5 || ^8.0"
},
"conflict": {
"guzzlehttp/ringphp": "<1.1.1"
"league/flysystem-sftp": "<1.0.6"
},
"require-dev": {
"async-aws/s3": "^1.5",
"async-aws/simple-s3": "^1.0",
"aws/aws-sdk-php": "^3.132.4",
"composer/semver": "^3.0",
"ext-fileinfo": "*",
"ext-ftp": "*",
"friendsofphp/php-cs-fixer": "^3.2",
"google/cloud-storage": "^1.23",
"phpseclib/phpseclib": "^2.0",
"phpstan/phpstan": "^0.12.26",
"phpunit/phpunit": "^8.5 || ^9.4",
"sabre/dav": "^4.1"
"phpspec/prophecy": "^1.11.1",
"phpunit/phpunit": "^8.5.8"
},
"time": "2022-09-17T21:02:32+00:00",
"suggest": {
"ext-ftp": "Allows you to use FTP server storage",
"ext-openssl": "Allows you to use FTPS server storage",
"league/flysystem-aws-s3-v2": "Allows you to use S3 storage with AWS SDK v2",
"league/flysystem-aws-s3-v3": "Allows you to use S3 storage with AWS SDK v3",
"league/flysystem-azure": "Allows you to use Windows Azure Blob storage",
"league/flysystem-cached-adapter": "Flysystem adapter decorator for metadata caching",
"league/flysystem-eventable-filesystem": "Allows you to use EventableFilesystem",
"league/flysystem-rackspace": "Allows you to use Rackspace Cloud Files",
"league/flysystem-sftp": "Allows you to use SFTP server storage via phpseclib",
"league/flysystem-webdav": "Allows you to use WebDAV storage",
"league/flysystem-ziparchive": "Allows you to use ZipArchive adapter",
"spatie/flysystem-dropbox": "Allows you to use Dropbox storage",
"srmklive/flysystem-dropbox-v2": "Allows you to use Dropbox storage for PHP 5 applications"
},
"time": "2022-10-04T09:16:37+00:00",
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "1.1-dev"
}
},
"installation-source": "dist",
"autoload": {
"psr-4": {
"League\\Flysystem\\": "src"
"League\\Flysystem\\": "src/"
}
},
"notification-url": "https://packagist.org/downloads/",
@ -1012,43 +1028,101 @@
"authors": [
{
"name": "Frank de Jonge",
"email": "info@frankdejonge.nl"
"email": "info@frenky.net"
}
],
"description": "File storage abstraction for PHP",
"description": "Filesystem abstraction: Many filesystems, one API.",
"keywords": [
"Cloud Files",
"WebDAV",
"abstraction",
"aws",
"cloud",
"file",
"copy.com",
"dropbox",
"file systems",
"files",
"filesystem",
"filesystems",
"ftp",
"rackspace",
"remote",
"s3",
"sftp",
"storage"
],
"support": {
"issues": "https://github.com/thephpleague/flysystem/issues",
"source": "https://github.com/thephpleague/flysystem/tree/2.5.0"
"source": "https://github.com/thephpleague/flysystem/tree/1.1.10"
},
"funding": [
{
"url": "https://ecologi.com/frankdejonge",
"type": "custom"
},
{
"url": "https://github.com/frankdejonge",
"type": "github"
},
{
"url": "https://tidelift.com/funding/github/packagist/league/flysystem",
"type": "tidelift"
"url": "https://offset.earth/frankdejonge",
"type": "other"
}
],
"install-path": "../league/flysystem"
},
{
"name": "league/flysystem-cached-adapter",
"version": "1.1.0",
"version_normalized": "1.1.0.0",
"source": {
"type": "git",
"url": "https://github.com/thephpleague/flysystem-cached-adapter.git",
"reference": "d1925efb2207ac4be3ad0c40b8277175f99ffaff"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/thephpleague/flysystem-cached-adapter/zipball/d1925efb2207ac4be3ad0c40b8277175f99ffaff",
"reference": "d1925efb2207ac4be3ad0c40b8277175f99ffaff",
"shasum": "",
"mirrors": [
{
"url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%",
"preferred": true
}
]
},
"require": {
"league/flysystem": "~1.0",
"psr/cache": "^1.0.0"
},
"require-dev": {
"mockery/mockery": "~0.9",
"phpspec/phpspec": "^3.4",
"phpunit/phpunit": "^5.7",
"predis/predis": "~1.0",
"tedivm/stash": "~0.12"
},
"suggest": {
"ext-phpredis": "Pure C implemented extension for PHP"
},
"time": "2020-07-25T15:56:04+00:00",
"type": "library",
"installation-source": "dist",
"autoload": {
"psr-4": {
"League\\Flysystem\\Cached\\": "src/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "frankdejonge",
"email": "info@frenky.net"
}
],
"description": "An adapter decorator to enable meta-data caching.",
"support": {
"issues": "https://github.com/thephpleague/flysystem-cached-adapter/issues",
"source": "https://github.com/thephpleague/flysystem-cached-adapter/tree/master"
},
"install-path": "../league/flysystem-cached-adapter"
},
{
"name": "league/mime-type-detection",
"version": "1.11.0",
@ -1423,18 +1497,24 @@
},
{
"name": "phpmailer/phpmailer",
"version": "v6.6.5",
"version_normalized": "6.6.5.0",
"version": "v6.6.4",
"version_normalized": "6.6.4.0",
"source": {
"type": "git",
"url": "https://github.com/PHPMailer/PHPMailer.git",
"reference": "8b6386d7417526d1ea4da9edb70b8352f7543627"
"reference": "a94fdebaea6bd17f51be0c2373ab80d3d681269b"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/PHPMailer/PHPMailer/zipball/8b6386d7417526d1ea4da9edb70b8352f7543627",
"reference": "8b6386d7417526d1ea4da9edb70b8352f7543627",
"shasum": ""
"url": "https://api.github.com/repos/PHPMailer/PHPMailer/zipball/a94fdebaea6bd17f51be0c2373ab80d3d681269b",
"reference": "a94fdebaea6bd17f51be0c2373ab80d3d681269b",
"shasum": "",
"mirrors": [
{
"url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%",
"preferred": true
}
]
},
"require": {
"ext-ctype": "*",
@ -1457,10 +1537,10 @@
"hayageek/oauth2-yahoo": "Needed for Yahoo XOAUTH2 authentication",
"league/oauth2-google": "Needed for Google XOAUTH2 authentication",
"psr/log": "For optional PSR-3 debug logging",
"symfony/polyfill-mbstring": "To support UTF-8 if the Mbstring PHP extension is not enabled (^1.2)",
"thenetworg/oauth2-azure": "Needed for Microsoft XOAUTH2 authentication"
"stevenmaguire/oauth2-microsoft": "Needed for Microsoft XOAUTH2 authentication",
"symfony/polyfill-mbstring": "To support UTF-8 if the Mbstring PHP extension is not enabled (^1.2)"
},
"time": "2022-10-07T12:23:10+00:00",
"time": "2022-08-22T09:22:00+00:00",
"type": "library",
"installation-source": "dist",
"autoload": {
@ -1492,7 +1572,7 @@
"description": "PHPMailer is a full-featured email creation and transfer class for PHP",
"support": {
"issues": "https://github.com/PHPMailer/PHPMailer/issues",
"source": "https://github.com/PHPMailer/PHPMailer/tree/v6.6.5"
"source": "https://github.com/PHPMailer/PHPMailer/tree/v6.6.4"
},
"funding": [
{
@ -1949,18 +2029,24 @@
},
{
"name": "symfony/polyfill-mbstring",
"version": "v1.26.0",
"version_normalized": "1.26.0.0",
"version": "v1.27.0",
"version_normalized": "1.27.0.0",
"source": {
"type": "git",
"url": "https://github.com/symfony/polyfill-mbstring.git",
"reference": "9344f9cb97f3b19424af1a21a3b0e75b0a7d8d7e"
"reference": "8ad114f6b39e2c98a8b0e3bd907732c207c2b534"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/9344f9cb97f3b19424af1a21a3b0e75b0a7d8d7e",
"reference": "9344f9cb97f3b19424af1a21a3b0e75b0a7d8d7e",
"shasum": ""
"url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/8ad114f6b39e2c98a8b0e3bd907732c207c2b534",
"reference": "8ad114f6b39e2c98a8b0e3bd907732c207c2b534",
"shasum": "",
"mirrors": [
{
"url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%",
"preferred": true
}
]
},
"require": {
"php": ">=7.1"
@ -1971,11 +2057,11 @@
"suggest": {
"ext-mbstring": "For best performance"
},
"time": "2022-05-24T11:49:31+00:00",
"time": "2022-11-03T14:55:06+00:00",
"type": "library",
"extra": {
"branch-alias": {
"dev-main": "1.26-dev"
"dev-main": "1.27-dev"
},
"thanks": {
"name": "symfony/polyfill",
@ -2015,7 +2101,7 @@
"shim"
],
"support": {
"source": "https://github.com/symfony/polyfill-mbstring/tree/v1.26.0"
"source": "https://github.com/symfony/polyfill-mbstring/tree/v1.27.0"
},
"funding": [
{
@ -2035,27 +2121,33 @@
},
{
"name": "symfony/polyfill-php72",
"version": "v1.26.0",
"version_normalized": "1.26.0.0",
"version": "v1.27.0",
"version_normalized": "1.27.0.0",
"source": {
"type": "git",
"url": "https://github.com/symfony/polyfill-php72.git",
"reference": "bf44a9fd41feaac72b074de600314a93e2ae78e2"
"reference": "869329b1e9894268a8a61dabb69153029b7a8c97"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/polyfill-php72/zipball/bf44a9fd41feaac72b074de600314a93e2ae78e2",
"reference": "bf44a9fd41feaac72b074de600314a93e2ae78e2",
"shasum": ""
"url": "https://api.github.com/repos/symfony/polyfill-php72/zipball/869329b1e9894268a8a61dabb69153029b7a8c97",
"reference": "869329b1e9894268a8a61dabb69153029b7a8c97",
"shasum": "",
"mirrors": [
{
"url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%",
"preferred": true
}
]
},
"require": {
"php": ">=7.1"
},
"time": "2022-05-24T11:49:31+00:00",
"time": "2022-11-03T14:55:06+00:00",
"type": "library",
"extra": {
"branch-alias": {
"dev-main": "1.26-dev"
"dev-main": "1.27-dev"
},
"thanks": {
"name": "symfony/polyfill",
@ -2094,7 +2186,7 @@
"shim"
],
"support": {
"source": "https://github.com/symfony/polyfill-php72/tree/v1.26.0"
"source": "https://github.com/symfony/polyfill-php72/tree/v1.27.0"
},
"funding": [
{
@ -2114,27 +2206,33 @@
},
{
"name": "symfony/polyfill-php80",
"version": "v1.26.0",
"version_normalized": "1.26.0.0",
"version": "v1.27.0",
"version_normalized": "1.27.0.0",
"source": {
"type": "git",
"url": "https://github.com/symfony/polyfill-php80.git",
"reference": "cfa0ae98841b9e461207c13ab093d76b0fa7bace"
"reference": "7a6ff3f1959bb01aefccb463a0f2cd3d3d2fd936"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/polyfill-php80/zipball/cfa0ae98841b9e461207c13ab093d76b0fa7bace",
"reference": "cfa0ae98841b9e461207c13ab093d76b0fa7bace",
"shasum": ""
"url": "https://api.github.com/repos/symfony/polyfill-php80/zipball/7a6ff3f1959bb01aefccb463a0f2cd3d3d2fd936",
"reference": "7a6ff3f1959bb01aefccb463a0f2cd3d3d2fd936",
"shasum": "",
"mirrors": [
{
"url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%",
"preferred": true
}
]
},
"require": {
"php": ">=7.1"
},
"time": "2022-05-10T07:21:04+00:00",
"time": "2022-11-03T14:55:06+00:00",
"type": "library",
"extra": {
"branch-alias": {
"dev-main": "1.26-dev"
"dev-main": "1.27-dev"
},
"thanks": {
"name": "symfony/polyfill",
@ -2180,7 +2278,7 @@
"shim"
],
"support": {
"source": "https://github.com/symfony/polyfill-php80/tree/v1.26.0"
"source": "https://github.com/symfony/polyfill-php80/tree/v1.27.0"
},
"funding": [
{
@ -2200,18 +2298,24 @@
},
{
"name": "symfony/var-dumper",
"version": "v4.4.47",
"version_normalized": "4.4.47.0",
"version": "v4.4.46",
"version_normalized": "4.4.46.0",
"source": {
"type": "git",
"url": "https://github.com/symfony/var-dumper.git",
"reference": "1069c7a3fca74578022fab6f81643248d02f8e63"
"reference": "90425fd98d1ecad98e4b2dca9f54f62069193b15"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/var-dumper/zipball/1069c7a3fca74578022fab6f81643248d02f8e63",
"reference": "1069c7a3fca74578022fab6f81643248d02f8e63",
"shasum": ""
"url": "https://api.github.com/repos/symfony/var-dumper/zipball/90425fd98d1ecad98e4b2dca9f54f62069193b15",
"reference": "90425fd98d1ecad98e4b2dca9f54f62069193b15",
"shasum": "",
"mirrors": [
{
"url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%",
"preferred": true
}
]
},
"require": {
"php": ">=7.1.3",
@ -2234,7 +2338,7 @@
"ext-intl": "To show region name in time zone dump",
"symfony/console": "To use the ServerDumpCommand and/or the bin/var-dump-server script"
},
"time": "2022-10-03T15:15:11+00:00",
"time": "2022-09-03T23:07:25+00:00",
"bin": [
"Resources/bin/var-dump-server"
],
@ -2272,7 +2376,7 @@
"dump"
],
"support": {
"source": "https://github.com/symfony/var-dumper/tree/v4.4.47"
"source": "https://github.com/symfony/var-dumper/tree/v4.4.46"
},
"funding": [
{
@ -2368,18 +2472,24 @@
},
{
"name": "taoser/think-addons",
"version": "v1.0.8",
"version_normalized": "1.0.8.0",
"version": "v1.0.6",
"version_normalized": "1.0.6.0",
"source": {
"type": "git",
"url": "https://github.com/taoser/think-addons.git",
"reference": "570367e8d4904842625427f132d23c93f5edfc68"
"reference": "e6e35bfd8b93dc469ebb5c5530ba350131bd7541"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/taoser/think-addons/zipball/570367e8d4904842625427f132d23c93f5edfc68",
"reference": "570367e8d4904842625427f132d23c93f5edfc68",
"shasum": ""
"url": "https://api.github.com/repos/taoser/think-addons/zipball/e6e35bfd8b93dc469ebb5c5530ba350131bd7541",
"reference": "e6e35bfd8b93dc469ebb5c5530ba350131bd7541",
"shasum": "",
"mirrors": [
{
"url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%",
"preferred": true
}
]
},
"require": {
"php": ">=7.1.0",
@ -2388,7 +2498,7 @@
"topthink/think-helper": "^3.0.0",
"topthink/think-view": "^1.0"
},
"time": "2022-10-15T06:21:17+00:00",
"time": "2022-10-06T13:11:38+00:00",
"type": "library",
"extra": {
"think": {
@ -2422,7 +2532,7 @@
"description": "The ThinkPHP6 Addons Package",
"support": {
"issues": "https://github.com/taoser/think-addons/issues",
"source": "https://github.com/taoser/think-addons/tree/v1.0.8"
"source": "https://github.com/taoser/think-addons/tree/v1.0.6"
},
"install-path": "../taoser/think-addons"
},
@ -2710,21 +2820,29 @@
},
{
"name": "topthink/think-filesystem",
"version": "v2.0.0",
"version_normalized": "2.0.0.0",
"version": "v1.0.1",
"version_normalized": "1.0.1.0",
"source": {
"type": "git",
"url": "https://github.com/top-think/think-filesystem.git",
"reference": "63e525fd74f451b2df1df060c3194e9b6e724730"
"reference": "cfc510520db9bcd22d8d80f51d7e415a2f470af6"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/top-think/think-filesystem/zipball/63e525fd74f451b2df1df060c3194e9b6e724730",
"reference": "63e525fd74f451b2df1df060c3194e9b6e724730",
"shasum": ""
"url": "https://api.github.com/repos/top-think/think-filesystem/zipball/cfc510520db9bcd22d8d80f51d7e415a2f470af6",
"reference": "cfc510520db9bcd22d8d80f51d7e415a2f470af6",
"shasum": "",
"mirrors": [
{
"url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%",
"preferred": true
}
]
},
"require": {
"league/flysystem": "^2.0",
"league/flysystem": "^1.1.4",
"league/flysystem-cached-adapter": "^1.0",
"php": ">=7.2.5",
"topthink/framework": "^6.1"
},
"require-dev": {
@ -2732,7 +2850,7 @@
"mockery/mockery": "^1.2",
"phpunit/phpunit": "^8.0"
},
"time": "2022-10-26T04:51:41+00:00",
"time": "2022-10-26T03:50:24+00:00",
"type": "library",
"installation-source": "dist",
"autoload": {
@ -2753,7 +2871,7 @@
"description": "The ThinkPHP6.1 Filesystem Package",
"support": {
"issues": "https://github.com/top-think/think-filesystem/issues",
"source": "https://github.com/top-think/think-filesystem/tree/v2.0.0"
"source": "https://github.com/top-think/think-filesystem/tree/v1.0.1"
},
"install-path": "../topthink/think-filesystem"
},
@ -2868,21 +2986,27 @@
},
{
"name": "topthink/think-migration",
"version": "v3.0.4",
"version_normalized": "3.0.4.0",
"version": "v3.0.3",
"version_normalized": "3.0.3.0",
"source": {
"type": "git",
"url": "https://github.com/top-think/think-migration.git",
"reference": "c5880669b277762d5ff935e551bc0d5c71de6811"
"reference": "5717d9e5f3ea745f6dbfd1e30b4402aaadff9a79"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/top-think/think-migration/zipball/c5880669b277762d5ff935e551bc0d5c71de6811",
"reference": "c5880669b277762d5ff935e551bc0d5c71de6811",
"shasum": ""
"url": "https://api.github.com/repos/top-think/think-migration/zipball/5717d9e5f3ea745f6dbfd1e30b4402aaadff9a79",
"reference": "5717d9e5f3ea745f6dbfd1e30b4402aaadff9a79",
"shasum": "",
"mirrors": [
{
"url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%",
"preferred": true
}
]
},
"require": {
"topthink/framework": "^6.0",
"topthink/framework": "^6.0.0",
"topthink/think-helper": "^3.0.3"
},
"require-dev": {
@ -2891,7 +3015,7 @@
"suggest": {
"fzaninotto/faker": "Required to use the factory builder (^1.8)."
},
"time": "2022-10-26T07:57:54+00:00",
"time": "2020-12-07T05:54:22+00:00",
"type": "library",
"extra": {
"think": {
@ -2919,7 +3043,7 @@
],
"support": {
"issues": "https://github.com/top-think/think-migration/issues",
"source": "https://github.com/top-think/think-migration/tree/v3.0.4"
"source": "https://github.com/top-think/think-migration/tree/v3.0.3"
},
"install-path": "../topthink/think-migration"
},
@ -2976,18 +3100,24 @@
},
{
"name": "topthink/think-orm",
"version": "v2.0.55",
"version_normalized": "2.0.55.0",
"version": "v2.0.54",
"version_normalized": "2.0.54.0",
"source": {
"type": "git",
"url": "https://github.com/top-think/think-orm.git",
"reference": "e1974a4c3b1b4c5b808fcc0863fc254e711dee13"
"reference": "97b061b47616301ff29fbd4c35ed9184e1162e4e"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/top-think/think-orm/zipball/e1974a4c3b1b4c5b808fcc0863fc254e711dee13",
"reference": "e1974a4c3b1b4c5b808fcc0863fc254e711dee13",
"shasum": ""
"url": "https://api.github.com/repos/top-think/think-orm/zipball/97b061b47616301ff29fbd4c35ed9184e1162e4e",
"reference": "97b061b47616301ff29fbd4c35ed9184e1162e4e",
"shasum": "",
"mirrors": [
{
"url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%",
"preferred": true
}
]
},
"require": {
"ext-json": "*",
@ -3000,7 +3130,7 @@
"require-dev": {
"phpunit/phpunit": "^7|^8|^9.5"
},
"time": "2022-09-27T14:18:43+00:00",
"time": "2022-07-05T05:25:51+00:00",
"type": "library",
"installation-source": "dist",
"autoload": {
@ -3028,7 +3158,7 @@
],
"support": {
"issues": "https://github.com/top-think/think-orm/issues",
"source": "https://github.com/top-think/think-orm/tree/v2.0.55"
"source": "https://github.com/top-think/think-orm/tree/v2.0.54"
},
"install-path": "../topthink/think-orm"
},
@ -3326,18 +3456,24 @@
},
{
"name": "workerman/workerman",
"version": "v4.1.4",
"version_normalized": "4.1.4.0",
"version": "v4.1.3",
"version_normalized": "4.1.3.0",
"source": {
"type": "git",
"url": "https://github.com/walkor/workerman.git",
"reference": "83e007acf936e2233ac92d7368b87716f2bae338"
"reference": "01028d8008c5691ec38c5f675fc13d76496a6db9"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/walkor/workerman/zipball/83e007acf936e2233ac92d7368b87716f2bae338",
"reference": "83e007acf936e2233ac92d7368b87716f2bae338",
"shasum": ""
"url": "https://api.github.com/repos/walkor/workerman/zipball/01028d8008c5691ec38c5f675fc13d76496a6db9",
"reference": "01028d8008c5691ec38c5f675fc13d76496a6db9",
"shasum": "",
"mirrors": [
{
"url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%",
"preferred": true
}
]
},
"require": {
"php": ">=7.0"
@ -3345,7 +3481,7 @@
"suggest": {
"ext-event": "For better performance. "
},
"time": "2022-10-09T11:33:14+00:00",
"time": "2022-09-23T14:05:12+00:00",
"type": "library",
"installation-source": "dist",
"autoload": {
@ -3536,25 +3672,31 @@
},
{
"name": "yzh52521/easyhttp",
"version": "v1.0.3",
"version_normalized": "1.0.3.0",
"version": "v1.0.4",
"version_normalized": "1.0.4.0",
"source": {
"type": "git",
"url": "https://github.com/yzh52521/easyhttp.git",
"reference": "aa7f805cfed6ce613f10045aff564b05e62e944c"
"reference": "e34628f8f90295cf0a19e5cd2bcc4dd19000373b"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/yzh52521/easyhttp/zipball/aa7f805cfed6ce613f10045aff564b05e62e944c",
"reference": "aa7f805cfed6ce613f10045aff564b05e62e944c",
"shasum": ""
"url": "https://api.github.com/repos/yzh52521/easyhttp/zipball/e34628f8f90295cf0a19e5cd2bcc4dd19000373b",
"reference": "e34628f8f90295cf0a19e5cd2bcc4dd19000373b",
"shasum": "",
"mirrors": [
{
"url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%",
"preferred": true
}
]
},
"require": {
"guzzlehttp/guzzle": "^6.0|^7.0",
"php": "^7.2.5|^8.0",
"psr/log": "^1.0|^2.0|^3.0"
},
"time": "2022-10-13T06:56:42+00:00",
"time": "2022-11-10T01:24:11+00:00",
"type": "library",
"installation-source": "dist",
"autoload": {
@ -3585,7 +3727,7 @@
],
"support": {
"issues": "https://github.com/yzh52521/easyhttp/issues",
"source": "https://github.com/yzh52521/easyhttp/tree/v1.0.3"
"source": "https://github.com/yzh52521/easyhttp/tree/v1.0.4"
},
"install-path": "../yzh52521/easyhttp"
}

View File

@ -3,7 +3,7 @@
'name' => 'taoser/taoler',
'pretty_version' => 'dev-master',
'version' => 'dev-master',
'reference' => '6bb4a77619f0244cc914b917f5a95ade44c7500f',
'reference' => '24134372d0bdc16ddb7f8b3582608efc1319b59b',
'type' => 'project',
'install_path' => __DIR__ . '/../../',
'aliases' => array(),
@ -137,14 +137,23 @@
'dev_requirement' => false,
),
'league/flysystem' => array(
'pretty_version' => '2.5.0',
'version' => '2.5.0.0',
'reference' => '8aaffb653c5777781b0f7f69a5d937baf7ab6cdb',
'pretty_version' => '1.1.10',
'version' => '1.1.10.0',
'reference' => '3239285c825c152bcc315fe0e87d6b55f5972ed1',
'type' => 'library',
'install_path' => __DIR__ . '/../league/flysystem',
'aliases' => array(),
'dev_requirement' => false,
),
'league/flysystem-cached-adapter' => array(
'pretty_version' => '1.1.0',
'version' => '1.1.0.0',
'reference' => 'd1925efb2207ac4be3ad0c40b8277175f99ffaff',
'type' => 'library',
'install_path' => __DIR__ . '/../league/flysystem-cached-adapter',
'aliases' => array(),
'dev_requirement' => false,
),
'league/mime-type-detection' => array(
'pretty_version' => '1.11.0',
'version' => '1.11.0.0',
@ -200,9 +209,9 @@
'dev_requirement' => false,
),
'phpmailer/phpmailer' => array(
'pretty_version' => 'v6.6.5',
'version' => '6.6.5.0',
'reference' => '8b6386d7417526d1ea4da9edb70b8352f7543627',
'pretty_version' => 'v6.6.4',
'version' => '6.6.4.0',
'reference' => 'a94fdebaea6bd17f51be0c2373ab80d3d681269b',
'type' => 'library',
'install_path' => __DIR__ . '/../phpmailer/phpmailer',
'aliases' => array(),
@ -311,36 +320,36 @@
'dev_requirement' => false,
),
'symfony/polyfill-mbstring' => array(
'pretty_version' => 'v1.26.0',
'version' => '1.26.0.0',
'reference' => '9344f9cb97f3b19424af1a21a3b0e75b0a7d8d7e',
'pretty_version' => 'v1.27.0',
'version' => '1.27.0.0',
'reference' => '8ad114f6b39e2c98a8b0e3bd907732c207c2b534',
'type' => 'library',
'install_path' => __DIR__ . '/../symfony/polyfill-mbstring',
'aliases' => array(),
'dev_requirement' => false,
),
'symfony/polyfill-php72' => array(
'pretty_version' => 'v1.26.0',
'version' => '1.26.0.0',
'reference' => 'bf44a9fd41feaac72b074de600314a93e2ae78e2',
'pretty_version' => 'v1.27.0',
'version' => '1.27.0.0',
'reference' => '869329b1e9894268a8a61dabb69153029b7a8c97',
'type' => 'library',
'install_path' => __DIR__ . '/../symfony/polyfill-php72',
'aliases' => array(),
'dev_requirement' => false,
),
'symfony/polyfill-php80' => array(
'pretty_version' => 'v1.26.0',
'version' => '1.26.0.0',
'reference' => 'cfa0ae98841b9e461207c13ab093d76b0fa7bace',
'pretty_version' => 'v1.27.0',
'version' => '1.27.0.0',
'reference' => '7a6ff3f1959bb01aefccb463a0f2cd3d3d2fd936',
'type' => 'library',
'install_path' => __DIR__ . '/../symfony/polyfill-php80',
'aliases' => array(),
'dev_requirement' => false,
),
'symfony/var-dumper' => array(
'pretty_version' => 'v4.4.47',
'version' => '4.4.47.0',
'reference' => '1069c7a3fca74578022fab6f81643248d02f8e63',
'pretty_version' => 'v4.4.46',
'version' => '4.4.46.0',
'reference' => '90425fd98d1ecad98e4b2dca9f54f62069193b15',
'type' => 'library',
'install_path' => __DIR__ . '/../symfony/var-dumper',
'aliases' => array(),
@ -358,16 +367,16 @@
'taoser/taoler' => array(
'pretty_version' => 'dev-master',
'version' => 'dev-master',
'reference' => '6bb4a77619f0244cc914b917f5a95ade44c7500f',
'reference' => '24134372d0bdc16ddb7f8b3582608efc1319b59b',
'type' => 'project',
'install_path' => __DIR__ . '/../../',
'aliases' => array(),
'dev_requirement' => false,
),
'taoser/think-addons' => array(
'pretty_version' => 'v1.0.8',
'version' => '1.0.8.0',
'reference' => '570367e8d4904842625427f132d23c93f5edfc68',
'pretty_version' => 'v1.0.6',
'version' => '1.0.6.0',
'reference' => 'e6e35bfd8b93dc469ebb5c5530ba350131bd7541',
'type' => 'library',
'install_path' => __DIR__ . '/../taoser/think-addons',
'aliases' => array(),
@ -419,9 +428,9 @@
'dev_requirement' => false,
),
'topthink/think-filesystem' => array(
'pretty_version' => 'v2.0.0',
'version' => '2.0.0.0',
'reference' => '63e525fd74f451b2df1df060c3194e9b6e724730',
'pretty_version' => 'v1.0.1',
'version' => '1.0.1.0',
'reference' => 'cfc510520db9bcd22d8d80f51d7e415a2f470af6',
'type' => 'library',
'install_path' => __DIR__ . '/../topthink/think-filesystem',
'aliases' => array(),
@ -446,9 +455,9 @@
'dev_requirement' => false,
),
'topthink/think-migration' => array(
'pretty_version' => 'v3.0.4',
'version' => '3.0.4.0',
'reference' => 'c5880669b277762d5ff935e551bc0d5c71de6811',
'pretty_version' => 'v3.0.3',
'version' => '3.0.3.0',
'reference' => '5717d9e5f3ea745f6dbfd1e30b4402aaadff9a79',
'type' => 'library',
'install_path' => __DIR__ . '/../topthink/think-migration',
'aliases' => array(),
@ -464,9 +473,9 @@
'dev_requirement' => false,
),
'topthink/think-orm' => array(
'pretty_version' => 'v2.0.55',
'version' => '2.0.55.0',
'reference' => 'e1974a4c3b1b4c5b808fcc0863fc254e711dee13',
'pretty_version' => 'v2.0.54',
'version' => '2.0.54.0',
'reference' => '97b061b47616301ff29fbd4c35ed9184e1162e4e',
'type' => 'library',
'install_path' => __DIR__ . '/../topthink/think-orm',
'aliases' => array(),
@ -527,9 +536,9 @@
'dev_requirement' => false,
),
'workerman/workerman' => array(
'pretty_version' => 'v4.1.4',
'version' => '4.1.4.0',
'reference' => '83e007acf936e2233ac92d7368b87716f2bae338',
'pretty_version' => 'v4.1.3',
'version' => '4.1.3.0',
'reference' => '01028d8008c5691ec38c5f675fc13d76496a6db9',
'type' => 'library',
'install_path' => __DIR__ . '/../workerman/workerman',
'aliases' => array(),
@ -554,9 +563,9 @@
'dev_requirement' => false,
),
'yzh52521/easyhttp' => array(
'pretty_version' => 'v1.0.3',
'version' => '1.0.3.0',
'reference' => 'aa7f805cfed6ce613f10045aff564b05e62e944c',
'pretty_version' => 'v1.0.4',
'version' => '1.0.4.0',
'reference' => 'e34628f8f90295cf0a19e5cd2bcc4dd19000373b',
'type' => 'library',
'install_path' => __DIR__ . '/../yzh52521/easyhttp',
'aliases' => array(),

View File

@ -1,4 +1,4 @@
Copyright (c) 2013-2022 Frank de Jonge
Copyright (c) 2013-2019 Frank de Jonge
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal

View File

@ -1,48 +1,68 @@
{
"name": "league/flysystem",
"description": "File storage abstraction for PHP",
"keywords": [
"filesystem", "filesystems", "files", "storage", "aws",
"s3", "ftp", "sftp", "webdav", "file", "cloud"
],
"scripts": {
"phpstan": "vendor/bin/phpstan analyse -l 6 src"
},
"type": "library",
"minimum-stability": "dev",
"prefer-stable": true,
"autoload": {
"psr-4": {
"League\\Flysystem\\": "src"
"description": "Filesystem abstraction: Many filesystems, one API.",
"keywords": [
"filesystem", "filesystems", "files", "storage", "dropbox", "aws",
"abstraction", "s3", "ftp", "sftp", "remote", "webdav",
"file systems", "cloud", "cloud files", "rackspace", "copy.com"
],
"funding": [
{
"type": "other",
"url": "https://offset.earth/frankdejonge"
}
},
"require": {
"php": "^7.2 || ^8.0",
"ext-json": "*",
"league/mime-type-detection": "^1.0.0"
},
"require-dev": {
"ext-fileinfo": "*",
"ext-ftp": "*",
"phpunit/phpunit": "^8.5 || ^9.4",
"phpstan/phpstan": "^0.12.26",
"phpseclib/phpseclib": "^2.0",
"aws/aws-sdk-php": "^3.132.4",
"composer/semver": "^3.0",
"friendsofphp/php-cs-fixer": "^3.2",
"google/cloud-storage": "^1.23",
"async-aws/s3": "^1.5",
"async-aws/simple-s3": "^1.0",
"sabre/dav": "^4.1"
},
"conflict": {
"guzzlehttp/ringphp": "<1.1.1"
},
],
"license": "MIT",
"authors": [
{
"name": "Frank de Jonge",
"email": "info@frankdejonge.nl"
"email": "info@frenky.net"
}
]
],
"require": {
"php": "^7.2.5 || ^8.0",
"ext-fileinfo": "*",
"league/mime-type-detection": "^1.3"
},
"require-dev": {
"phpspec/prophecy": "^1.11.1",
"phpunit/phpunit": "^8.5.8"
},
"autoload": {
"psr-4": {
"League\\Flysystem\\": "src/"
}
},
"autoload-dev": {
"psr-4": {
"League\\Flysystem\\Stub\\": "stub/"
}
},
"suggest": {
"league/flysystem-eventable-filesystem": "Allows you to use EventableFilesystem",
"league/flysystem-rackspace": "Allows you to use Rackspace Cloud Files",
"league/flysystem-azure": "Allows you to use Windows Azure Blob storage",
"league/flysystem-webdav": "Allows you to use WebDAV storage",
"league/flysystem-aws-s3-v2": "Allows you to use S3 storage with AWS SDK v2",
"league/flysystem-aws-s3-v3": "Allows you to use S3 storage with AWS SDK v3",
"spatie/flysystem-dropbox": "Allows you to use Dropbox storage",
"srmklive/flysystem-dropbox-v2": "Allows you to use Dropbox storage for PHP 5 applications",
"league/flysystem-cached-adapter": "Flysystem adapter decorator for metadata caching",
"ext-ftp": "Allows you to use FTP server storage",
"ext-openssl": "Allows you to use FTPS server storage",
"league/flysystem-sftp": "Allows you to use SFTP server storage via phpseclib",
"league/flysystem-ziparchive": "Allows you to use ZipArchive adapter"
},
"conflict": {
"league/flysystem-sftp": "<1.0.6"
},
"extra": {
"branch-alias": {
"dev-master": "1.1-dev"
}
},
"scripts": {
"phpstan": "php phpstan.php"
}
}

View File

@ -1,43 +1,107 @@
<?php
declare(strict_types=1);
namespace League\Flysystem;
use function array_merge;
class Config
{
public const OPTION_VISIBILITY = 'visibility';
public const OPTION_DIRECTORY_VISIBILITY = 'directory_visibility';
/**
* @var array
*/
private $options;
protected $settings = [];
public function __construct(array $options = [])
/**
* @var Config|null
*/
protected $fallback;
/**
* Constructor.
*
* @param array $settings
*/
public function __construct(array $settings = [])
{
$this->options = $options;
$this->settings = $settings;
}
/**
* @param mixed $default
* Get a setting.
*
* @return mixed
* @param string $key
* @param mixed $default
*
* @return mixed config setting or default when not found
*/
public function get(string $property, $default = null)
public function get($key, $default = null)
{
return $this->options[$property] ?? $default;
if ( ! array_key_exists($key, $this->settings)) {
return $this->getDefault($key, $default);
}
return $this->settings[$key];
}
public function extend(array $options): Config
/**
* Check if an item exists by key.
*
* @param string $key
*
* @return bool
*/
public function has($key)
{
return new Config(array_merge($this->options, $options));
if (array_key_exists($key, $this->settings)) {
return true;
}
return $this->fallback instanceof Config
? $this->fallback->has($key)
: false;
}
public function withDefaults(array $defaults): Config
/**
* Try to retrieve a default setting from a config fallback.
*
* @param string $key
* @param mixed $default
*
* @return mixed config setting or default when not found
*/
protected function getDefault($key, $default)
{
return new Config($this->options + $defaults);
if ( ! $this->fallback) {
return $default;
}
return $this->fallback->get($key, $default);
}
/**
* Set a setting.
*
* @param string $key
* @param mixed $value
*
* @return $this
*/
public function set($key, $value)
{
$this->settings[$key] = $value;
return $this;
}
/**
* Set the fallback.
*
* @param Config $fallback
*
* @return $this
*/
public function setFallback(Config $fallback)
{
$this->fallback = $fallback;
return $this;
}
}

View File

@ -2,11 +2,15 @@
namespace League\Flysystem;
use RuntimeException;
use LogicException;
final class CorruptedPathDetected extends RuntimeException implements FilesystemException
class CorruptedPathDetected extends LogicException implements FilesystemException
{
public static function forPath(string $path): CorruptedPathDetected
/**
* @param string $path
* @return CorruptedPathDetected
*/
public static function forPath($path)
{
return new CorruptedPathDetected("Corrupted path detected: " . $path);
}

View File

@ -1,163 +1,409 @@
<?php
declare(strict_types=1);
namespace League\Flysystem;
class Filesystem implements FilesystemOperator
use InvalidArgumentException;
use League\Flysystem\Adapter\CanOverwriteFiles;
use League\Flysystem\Plugin\PluggableTrait;
use League\Flysystem\Util\ContentListingFormatter;
/**
* @method void emptyDir(string $dirname)
* @method array|false getWithMetadata(string $path, string[] $metadata)
* @method bool forceCopy(string $path, string $newpath)
* @method bool forceRename(string $path, string $newpath)
* @method array listFiles(string $path = '', boolean $recursive = false)
* @method string[] listPaths(string $path = '', boolean $recursive = false)
* @method array listWith(string[] $keys = [], $directory = '', $recursive = false)
*/
class Filesystem implements FilesystemInterface
{
/**
* @var FilesystemAdapter
*/
private $adapter;
use PluggableTrait;
use ConfigAwareTrait;
/**
* @var Config
* @var AdapterInterface
*/
private $config;
protected $adapter;
/**
* @var PathNormalizer
* Constructor.
*
* @param AdapterInterface $adapter
* @param Config|array $config
*/
private $pathNormalizer;
public function __construct(
FilesystemAdapter $adapter,
array $config = [],
PathNormalizer $pathNormalizer = null
) {
public function __construct(AdapterInterface $adapter, $config = null)
{
$this->adapter = $adapter;
$this->config = new Config($config);
$this->pathNormalizer = $pathNormalizer ?: new WhitespacePathNormalizer();
}
public function fileExists(string $location): bool
{
return $this->adapter->fileExists($this->pathNormalizer->normalizePath($location));
}
public function write(string $location, string $contents, array $config = []): void
{
$this->adapter->write(
$this->pathNormalizer->normalizePath($location),
$contents,
$this->config->extend($config)
);
}
public function writeStream(string $location, $contents, array $config = []): void
{
/* @var resource $contents */
$this->assertIsResource($contents);
$this->rewindStream($contents);
$this->adapter->writeStream(
$this->pathNormalizer->normalizePath($location),
$contents,
$this->config->extend($config)
);
}
public function read(string $location): string
{
return $this->adapter->read($this->pathNormalizer->normalizePath($location));
}
public function readStream(string $location)
{
return $this->adapter->readStream($this->pathNormalizer->normalizePath($location));
}
public function delete(string $location): void
{
$this->adapter->delete($this->pathNormalizer->normalizePath($location));
}
public function deleteDirectory(string $location): void
{
$this->adapter->deleteDirectory($this->pathNormalizer->normalizePath($location));
}
public function createDirectory(string $location, array $config = []): void
{
$this->adapter->createDirectory(
$this->pathNormalizer->normalizePath($location),
$this->config->extend($config)
);
}
public function listContents(string $location, bool $deep = self::LIST_SHALLOW): DirectoryListing
{
$path = $this->pathNormalizer->normalizePath($location);
return new DirectoryListing($this->adapter->listContents($path, $deep));
}
public function move(string $source, string $destination, array $config = []): void
{
$this->adapter->move(
$this->pathNormalizer->normalizePath($source),
$this->pathNormalizer->normalizePath($destination),
$this->config->extend($config)
);
}
public function copy(string $source, string $destination, array $config = []): void
{
$this->adapter->copy(
$this->pathNormalizer->normalizePath($source),
$this->pathNormalizer->normalizePath($destination),
$this->config->extend($config)
);
}
public function lastModified(string $path): int
{
return $this->adapter->lastModified($this->pathNormalizer->normalizePath($path))->lastModified();
}
public function fileSize(string $path): int
{
return $this->adapter->fileSize($this->pathNormalizer->normalizePath($path))->fileSize();
}
public function mimeType(string $path): string
{
return $this->adapter->mimeType($this->pathNormalizer->normalizePath($path))->mimeType();
}
public function setVisibility(string $path, string $visibility): void
{
$this->adapter->setVisibility($this->pathNormalizer->normalizePath($path), $visibility);
}
public function visibility(string $path): string
{
return $this->adapter->visibility($this->pathNormalizer->normalizePath($path))->visibility();
$this->setConfig($config);
}
/**
* @param mixed $contents
* Get the Adapter.
*
* @return AdapterInterface adapter
*/
private function assertIsResource($contents): void
public function getAdapter()
{
if (is_resource($contents) === false) {
throw new InvalidStreamProvided(
"Invalid stream provided, expected stream resource, received " . gettype($contents)
);
} elseif ($type = get_resource_type($contents) !== 'stream') {
throw new InvalidStreamProvided(
"Invalid stream provided, expected stream resource, received resource of type " . $type
);
return $this->adapter;
}
/**
* @inheritdoc
*/
public function has($path)
{
$path = Util::normalizePath($path);
return strlen($path) === 0 ? false : (bool) $this->getAdapter()->has($path);
}
/**
* @inheritdoc
*/
public function write($path, $contents, array $config = [])
{
$path = Util::normalizePath($path);
$this->assertAbsent($path);
$config = $this->prepareConfig($config);
return (bool) $this->getAdapter()->write($path, $contents, $config);
}
/**
* @inheritdoc
*/
public function writeStream($path, $resource, array $config = [])
{
if ( ! is_resource($resource) || get_resource_type($resource) !== 'stream') {
throw new InvalidArgumentException(__METHOD__ . ' expects argument #2 to be a valid resource.');
}
$path = Util::normalizePath($path);
$this->assertAbsent($path);
$config = $this->prepareConfig($config);
Util::rewindStream($resource);
return (bool) $this->getAdapter()->writeStream($path, $resource, $config);
}
/**
* @inheritdoc
*/
public function put($path, $contents, array $config = [])
{
$path = Util::normalizePath($path);
$config = $this->prepareConfig($config);
if ( ! $this->getAdapter() instanceof CanOverwriteFiles && $this->has($path)) {
return (bool) $this->getAdapter()->update($path, $contents, $config);
}
return (bool) $this->getAdapter()->write($path, $contents, $config);
}
/**
* @inheritdoc
*/
public function putStream($path, $resource, array $config = [])
{
if ( ! is_resource($resource) || get_resource_type($resource) !== 'stream') {
throw new InvalidArgumentException(__METHOD__ . ' expects argument #2 to be a valid resource.');
}
$path = Util::normalizePath($path);
$config = $this->prepareConfig($config);
Util::rewindStream($resource);
if ( ! $this->getAdapter() instanceof CanOverwriteFiles && $this->has($path)) {
return (bool) $this->getAdapter()->updateStream($path, $resource, $config);
}
return (bool) $this->getAdapter()->writeStream($path, $resource, $config);
}
/**
* @inheritdoc
*/
public function readAndDelete($path)
{
$path = Util::normalizePath($path);
$this->assertPresent($path);
$contents = $this->read($path);
if ($contents === false) {
return false;
}
$this->delete($path);
return $contents;
}
/**
* @inheritdoc
*/
public function update($path, $contents, array $config = [])
{
$path = Util::normalizePath($path);
$config = $this->prepareConfig($config);
$this->assertPresent($path);
return (bool) $this->getAdapter()->update($path, $contents, $config);
}
/**
* @inheritdoc
*/
public function updateStream($path, $resource, array $config = [])
{
if ( ! is_resource($resource) || get_resource_type($resource) !== 'stream') {
throw new InvalidArgumentException(__METHOD__ . ' expects argument #2 to be a valid resource.');
}
$path = Util::normalizePath($path);
$config = $this->prepareConfig($config);
$this->assertPresent($path);
Util::rewindStream($resource);
return (bool) $this->getAdapter()->updateStream($path, $resource, $config);
}
/**
* @inheritdoc
*/
public function read($path)
{
$path = Util::normalizePath($path);
$this->assertPresent($path);
if ( ! ($object = $this->getAdapter()->read($path))) {
return false;
}
return $object['contents'];
}
/**
* @inheritdoc
*/
public function readStream($path)
{
$path = Util::normalizePath($path);
$this->assertPresent($path);
if ( ! $object = $this->getAdapter()->readStream($path)) {
return false;
}
return $object['stream'];
}
/**
* @inheritdoc
*/
public function rename($path, $newpath)
{
$path = Util::normalizePath($path);
$newpath = Util::normalizePath($newpath);
$this->assertPresent($path);
$this->assertAbsent($newpath);
return (bool) $this->getAdapter()->rename($path, $newpath);
}
/**
* @inheritdoc
*/
public function copy($path, $newpath)
{
$path = Util::normalizePath($path);
$newpath = Util::normalizePath($newpath);
$this->assertPresent($path);
$this->assertAbsent($newpath);
return $this->getAdapter()->copy($path, $newpath);
}
/**
* @inheritdoc
*/
public function delete($path)
{
$path = Util::normalizePath($path);
$this->assertPresent($path);
return $this->getAdapter()->delete($path);
}
/**
* @inheritdoc
*/
public function deleteDir($dirname)
{
$dirname = Util::normalizePath($dirname);
if ($dirname === '') {
throw new RootViolationException('Root directories can not be deleted.');
}
return (bool) $this->getAdapter()->deleteDir($dirname);
}
/**
* @inheritdoc
*/
public function createDir($dirname, array $config = [])
{
$dirname = Util::normalizePath($dirname);
$config = $this->prepareConfig($config);
return (bool) $this->getAdapter()->createDir($dirname, $config);
}
/**
* @inheritdoc
*/
public function listContents($directory = '', $recursive = false)
{
$directory = Util::normalizePath($directory);
$contents = $this->getAdapter()->listContents($directory, $recursive);
return (new ContentListingFormatter($directory, $recursive, $this->config->get('case_sensitive', true)))
->formatListing($contents);
}
/**
* @inheritdoc
*/
public function getMimetype($path)
{
$path = Util::normalizePath($path);
$this->assertPresent($path);
if (( ! $object = $this->getAdapter()->getMimetype($path)) || ! array_key_exists('mimetype', $object)) {
return false;
}
return $object['mimetype'];
}
/**
* @inheritdoc
*/
public function getTimestamp($path)
{
$path = Util::normalizePath($path);
$this->assertPresent($path);
if (( ! $object = $this->getAdapter()->getTimestamp($path)) || ! array_key_exists('timestamp', $object)) {
return false;
}
return (int) $object['timestamp'];
}
/**
* @inheritdoc
*/
public function getVisibility($path)
{
$path = Util::normalizePath($path);
$this->assertPresent($path);
if (( ! $object = $this->getAdapter()->getVisibility($path)) || ! array_key_exists('visibility', $object)) {
return false;
}
return $object['visibility'];
}
/**
* @inheritdoc
*/
public function getSize($path)
{
$path = Util::normalizePath($path);
$this->assertPresent($path);
if (( ! $object = $this->getAdapter()->getSize($path)) || ! array_key_exists('size', $object)) {
return false;
}
return (int) $object['size'];
}
/**
* @inheritdoc
*/
public function setVisibility($path, $visibility)
{
$path = Util::normalizePath($path);
$this->assertPresent($path);
return (bool) $this->getAdapter()->setVisibility($path, $visibility);
}
/**
* @inheritdoc
*/
public function getMetadata($path)
{
$path = Util::normalizePath($path);
$this->assertPresent($path);
return $this->getAdapter()->getMetadata($path);
}
/**
* @inheritdoc
*/
public function get($path, Handler $handler = null)
{
$path = Util::normalizePath($path);
if ( ! $handler) {
$metadata = $this->getMetadata($path);
$handler = ($metadata && $metadata['type'] === 'file') ? new File($this, $path) : new Directory($this, $path);
}
$handler->setPath($path);
$handler->setFilesystem($this);
return $handler;
}
/**
* Assert a file is present.
*
* @param string $path path to file
*
* @throws FileNotFoundException
*
* @return void
*/
public function assertPresent($path)
{
if ($this->config->get('disable_asserts', false) === false && ! $this->has($path)) {
throw new FileNotFoundException($path);
}
}
/**
* @param resource $resource
* Assert a file is absent.
*
* @param string $path path to file
*
* @throws FileExistsException
*
* @return void
*/
private function rewindStream($resource): void
public function assertAbsent($path)
{
if (ftell($resource) !== 0 && stream_get_meta_data($resource)['seekable']) {
rewind($resource);
if ($this->config->get('disable_asserts', false) === false && $this->has($path)) {
throw new FileExistsException($path);
}
}
}

View File

@ -1,11 +1,7 @@
<?php
declare(strict_types=1);
namespace League\Flysystem;
use Throwable;
interface FilesystemException extends Throwable
interface FilesystemException
{
}

View File

@ -1,334 +1,648 @@
<?php
declare(strict_types=1);
namespace League\Flysystem;
use function sprintf;
use InvalidArgumentException;
use League\Flysystem\Plugin\PluggableTrait;
use League\Flysystem\Plugin\PluginNotFoundException;
class MountManager implements FilesystemOperator
/**
* Class MountManager.
*
* Proxies methods to Filesystem (@see __call):
*
* @method AdapterInterface getAdapter($prefix)
* @method Config getConfig($prefix)
* @method array listFiles($directory = '', $recursive = false)
* @method array listPaths($directory = '', $recursive = false)
* @method array getWithMetadata($path, array $metadata)
* @method Filesystem flushCache()
* @method void assertPresent($path)
* @method void assertAbsent($path)
* @method Filesystem addPlugin(PluginInterface $plugin)
*/
class MountManager implements FilesystemInterface
{
/**
* @var array<string, FilesystemOperator>
*/
private $filesystems = [];
use PluggableTrait;
/**
* MountManager constructor.
* @var FilesystemInterface[]
*/
protected $filesystems = [];
/**
* Constructor.
*
* @param array<string,FilesystemOperator> $filesystems
* @param FilesystemInterface[] $filesystems [:prefix => Filesystem,]
*
* @throws InvalidArgumentException
*/
public function __construct(array $filesystems = [])
{
$this->mountFilesystems($filesystems);
}
public function fileExists(string $location): bool
/**
* Mount filesystems.
*
* @param FilesystemInterface[] $filesystems [:prefix => Filesystem,]
*
* @throws InvalidArgumentException
*
* @return $this
*/
public function mountFilesystems(array $filesystems)
{
/** @var FilesystemOperator $filesystem */
[$filesystem, $path] = $this->determineFilesystemAndPath($location);
try {
return $filesystem->fileExists($path);
} catch (UnableToCheckFileExistence $exception) {
throw UnableToCheckFileExistence::forLocation($location, $exception);
foreach ($filesystems as $prefix => $filesystem) {
$this->mountFilesystem($prefix, $filesystem);
}
}
public function read(string $location): string
{
/** @var FilesystemOperator $filesystem */
[$filesystem, $path] = $this->determineFilesystemAndPath($location);
try {
return $filesystem->read($path);
} catch (UnableToReadFile $exception) {
throw UnableToReadFile::fromLocation($location, $exception->reason(), $exception);
}
}
public function readStream(string $location)
{
/** @var FilesystemOperator $filesystem */
[$filesystem, $path] = $this->determineFilesystemAndPath($location);
try {
return $filesystem->readStream($path);
} catch (UnableToReadFile $exception) {
throw UnableToReadFile::fromLocation($location, $exception->reason(), $exception);
}
}
public function listContents(string $location, bool $deep = self::LIST_SHALLOW): DirectoryListing
{
/** @var FilesystemOperator $filesystem */
[$filesystem, $path, $mountIdentifier] = $this->determineFilesystemAndPath($location);
return
$filesystem
->listContents($path, $deep)
->map(
function (StorageAttributes $attributes) use ($mountIdentifier) {
return $attributes->withPath(sprintf('%s://%s', $mountIdentifier, $attributes->path()));
}
);
}
public function lastModified(string $location): int
{
/** @var FilesystemOperator $filesystem */
[$filesystem, $path] = $this->determineFilesystemAndPath($location);
try {
return $filesystem->lastModified($path);
} catch (UnableToRetrieveMetadata $exception) {
throw UnableToRetrieveMetadata::lastModified($location, $exception->reason(), $exception);
}
}
public function fileSize(string $location): int
{
/** @var FilesystemOperator $filesystem */
[$filesystem, $path] = $this->determineFilesystemAndPath($location);
try {
return $filesystem->fileSize($path);
} catch (UnableToRetrieveMetadata $exception) {
throw UnableToRetrieveMetadata::fileSize($location, $exception->reason(), $exception);
}
}
public function mimeType(string $location): string
{
/** @var FilesystemOperator $filesystem */
[$filesystem, $path] = $this->determineFilesystemAndPath($location);
try {
return $filesystem->mimeType($path);
} catch (UnableToRetrieveMetadata $exception) {
throw UnableToRetrieveMetadata::mimeType($location, $exception->reason(), $exception);
}
}
public function visibility(string $location): string
{
/** @var FilesystemOperator $filesystem */
[$filesystem, $path] = $this->determineFilesystemAndPath($location);
try {
return $filesystem->visibility($path);
} catch (UnableToRetrieveMetadata $exception) {
throw UnableToRetrieveMetadata::visibility($location, $exception->reason(), $exception);
}
}
public function write(string $location, string $contents, array $config = []): void
{
/** @var FilesystemOperator $filesystem */
[$filesystem, $path] = $this->determineFilesystemAndPath($location);
try {
$filesystem->write($path, $contents, $config);
} catch (UnableToWriteFile $exception) {
throw UnableToWriteFile::atLocation($location, $exception->reason(), $exception);
}
}
public function writeStream(string $location, $contents, array $config = []): void
{
/** @var FilesystemOperator $filesystem */
[$filesystem, $path] = $this->determineFilesystemAndPath($location);
$filesystem->writeStream($path, $contents, $config);
}
public function setVisibility(string $path, string $visibility): void
{
/** @var FilesystemOperator $filesystem */
[$filesystem, $path] = $this->determineFilesystemAndPath($path);
$filesystem->setVisibility($path, $visibility);
}
public function delete(string $location): void
{
/** @var FilesystemOperator $filesystem */
[$filesystem, $path] = $this->determineFilesystemAndPath($location);
try {
$filesystem->delete($path);
} catch (UnableToDeleteFile $exception) {
throw UnableToDeleteFile::atLocation($location, '', $exception);
}
}
public function deleteDirectory(string $location): void
{
/** @var FilesystemOperator $filesystem */
[$filesystem, $path] = $this->determineFilesystemAndPath($location);
try {
$filesystem->deleteDirectory($path);
} catch (UnableToDeleteDirectory $exception) {
throw UnableToDeleteDirectory::atLocation($location, '', $exception);
}
}
public function createDirectory(string $location, array $config = []): void
{
/** @var FilesystemOperator $filesystem */
[$filesystem, $path] = $this->determineFilesystemAndPath($location);
try {
$filesystem->createDirectory($path, $config);
} catch (UnableToCreateDirectory $exception) {
throw UnableToCreateDirectory::dueToFailure($location, $exception);
}
}
public function move(string $source, string $destination, array $config = []): void
{
/** @var FilesystemOperator $sourceFilesystem */
/* @var FilesystemOperator $destinationFilesystem */
[$sourceFilesystem, $sourcePath] = $this->determineFilesystemAndPath($source);
[$destinationFilesystem, $destinationPath] = $this->determineFilesystemAndPath($destination);
$sourceFilesystem === $destinationFilesystem ? $this->moveInTheSameFilesystem(
$sourceFilesystem,
$sourcePath,
$destinationPath,
$source,
$destination
) : $this->moveAcrossFilesystems($source, $destination);
}
public function copy(string $source, string $destination, array $config = []): void
{
/** @var FilesystemOperator $sourceFilesystem */
/* @var FilesystemOperator $destinationFilesystem */
[$sourceFilesystem, $sourcePath] = $this->determineFilesystemAndPath($source);
[$destinationFilesystem, $destinationPath] = $this->determineFilesystemAndPath($destination);
$sourceFilesystem === $destinationFilesystem ? $this->copyInSameFilesystem(
$sourceFilesystem,
$sourcePath,
$destinationPath,
$source,
$destination
) : $this->copyAcrossFilesystem(
$config['visibility'] ?? null,
$sourceFilesystem,
$sourcePath,
$destinationFilesystem,
$destinationPath,
$source,
$destination
);
}
private function mountFilesystems(array $filesystems): void
{
foreach ($filesystems as $key => $filesystem) {
$this->guardAgainstInvalidMount($key, $filesystem);
/* @var string $key */
/* @var FilesystemOperator $filesystem */
$this->mountFilesystem($key, $filesystem);
}
return $this;
}
/**
* @param mixed $key
* @param mixed $filesystem
* Mount filesystems.
*
* @param string $prefix
* @param FilesystemInterface $filesystem
*
* @throws InvalidArgumentException
*
* @return $this
*/
private function guardAgainstInvalidMount($key, $filesystem): void
public function mountFilesystem($prefix, FilesystemInterface $filesystem)
{
if ( ! is_string($key)) {
throw UnableToMountFilesystem::becauseTheKeyIsNotValid($key);
if ( ! is_string($prefix)) {
throw new InvalidArgumentException(__METHOD__ . ' expects argument #1 to be a string.');
}
if ( ! $filesystem instanceof FilesystemOperator) {
throw UnableToMountFilesystem::becauseTheFilesystemWasNotValid($filesystem);
}
$this->filesystems[$prefix] = $filesystem;
return $this;
}
private function mountFilesystem(string $key, FilesystemOperator $filesystem): void
/**
* Get the filesystem with the corresponding prefix.
*
* @param string $prefix
*
* @throws FilesystemNotFoundException
*
* @return FilesystemInterface
*/
public function getFilesystem($prefix)
{
$this->filesystems[$key] = $filesystem;
if ( ! isset($this->filesystems[$prefix])) {
throw new FilesystemNotFoundException('No filesystem mounted with prefix ' . $prefix);
}
return $this->filesystems[$prefix];
}
/**
* Retrieve the prefix from an arguments array.
*
* @param array $arguments
*
* @throws InvalidArgumentException
*
* @return array [:prefix, :arguments]
*/
public function filterPrefix(array $arguments)
{
if (empty($arguments)) {
throw new InvalidArgumentException('At least one argument needed');
}
$path = array_shift($arguments);
if ( ! is_string($path)) {
throw new InvalidArgumentException('First argument should be a string');
}
list($prefix, $path) = $this->getPrefixAndPath($path);
array_unshift($arguments, $path);
return [$prefix, $arguments];
}
/**
* @param string $directory
* @param bool $recursive
*
* @throws InvalidArgumentException
* @throws FilesystemNotFoundException
*
* @return array
*/
public function listContents($directory = '', $recursive = false)
{
list($prefix, $directory) = $this->getPrefixAndPath($directory);
$filesystem = $this->getFilesystem($prefix);
$result = $filesystem->listContents($directory, $recursive);
foreach ($result as &$file) {
$file['filesystem'] = $prefix;
}
return $result;
}
/**
* Call forwarder.
*
* @param string $method
* @param array $arguments
*
* @throws InvalidArgumentException
* @throws FilesystemNotFoundException
*
* @return mixed
*/
public function __call($method, $arguments)
{
list($prefix, $arguments) = $this->filterPrefix($arguments);
return $this->invokePluginOnFilesystem($method, $arguments, $prefix);
}
/**
* @param string $from
* @param string $to
* @param array $config
*
* @throws InvalidArgumentException
* @throws FilesystemNotFoundException
* @throws FileExistsException
*
* @return bool
*/
public function copy($from, $to, array $config = [])
{
list($prefixFrom, $from) = $this->getPrefixAndPath($from);
$buffer = $this->getFilesystem($prefixFrom)->readStream($from);
if ($buffer === false) {
return false;
}
list($prefixTo, $to) = $this->getPrefixAndPath($to);
$result = $this->getFilesystem($prefixTo)->writeStream($to, $buffer, $config);
if (is_resource($buffer)) {
fclose($buffer);
}
return $result;
}
/**
* List with plugin adapter.
*
* @param array $keys
* @param string $directory
* @param bool $recursive
*
* @throws InvalidArgumentException
* @throws FilesystemNotFoundException
*
* @return array
*/
public function listWith(array $keys = [], $directory = '', $recursive = false)
{
list($prefix, $directory) = $this->getPrefixAndPath($directory);
$arguments = [$keys, $directory, $recursive];
return $this->invokePluginOnFilesystem('listWith', $arguments, $prefix);
}
/**
* Move a file.
*
* @param string $from
* @param string $to
* @param array $config
*
* @throws InvalidArgumentException
* @throws FilesystemNotFoundException
*
* @return bool
*/
public function move($from, $to, array $config = [])
{
list($prefixFrom, $pathFrom) = $this->getPrefixAndPath($from);
list($prefixTo, $pathTo) = $this->getPrefixAndPath($to);
if ($prefixFrom === $prefixTo) {
$filesystem = $this->getFilesystem($prefixFrom);
$renamed = $filesystem->rename($pathFrom, $pathTo);
if ($renamed && isset($config['visibility'])) {
return $filesystem->setVisibility($pathTo, $config['visibility']);
}
return $renamed;
}
$copied = $this->copy($from, $to, $config);
if ($copied) {
return $this->delete($from);
}
return false;
}
/**
* Invoke a plugin on a filesystem mounted on a given prefix.
*
* @param string $method
* @param array $arguments
* @param string $prefix
*
* @throws FilesystemNotFoundException
*
* @return mixed
*/
public function invokePluginOnFilesystem($method, $arguments, $prefix)
{
$filesystem = $this->getFilesystem($prefix);
try {
return $this->invokePlugin($method, $arguments, $filesystem);
} catch (PluginNotFoundException $e) {
// Let it pass, it's ok, don't panic.
}
$callback = [$filesystem, $method];
return call_user_func_array($callback, $arguments);
}
/**
* @param string $path
*
* @return array{0:FilesystemOperator, 1:string}
* @throws InvalidArgumentException
*
* @return string[] [:prefix, :path]
*/
private function determineFilesystemAndPath(string $path): array
protected function getPrefixAndPath($path)
{
if (strpos($path, '://') < 1) {
throw UnableToResolveFilesystemMount::becauseTheSeparatorIsMissing($path);
throw new InvalidArgumentException('No prefix detected in path: ' . $path);
}
/** @var string $mountIdentifier */
/** @var string $mountPath */
[$mountIdentifier, $mountPath] = explode('://', $path, 2);
if ( ! array_key_exists($mountIdentifier, $this->filesystems)) {
throw UnableToResolveFilesystemMount::becauseTheMountWasNotRegistered($mountIdentifier);
}
return [$this->filesystems[$mountIdentifier], $mountPath, $mountIdentifier];
return explode('://', $path, 2);
}
private function copyInSameFilesystem(
FilesystemOperator $sourceFilesystem,
string $sourcePath,
string $destinationPath,
string $source,
string $destination
): void {
try {
$sourceFilesystem->copy($sourcePath, $destinationPath);
} catch (UnableToCopyFile $exception) {
throw UnableToCopyFile::fromLocationTo($source, $destination, $exception);
}
}
private function copyAcrossFilesystem(
?string $visibility,
FilesystemOperator $sourceFilesystem,
string $sourcePath,
FilesystemOperator $destinationFilesystem,
string $destinationPath,
string $source,
string $destination
): void {
try {
$visibility = $visibility ?? $sourceFilesystem->visibility($sourcePath);
$stream = $sourceFilesystem->readStream($sourcePath);
$destinationFilesystem->writeStream($destinationPath, $stream, compact('visibility'));
} catch (UnableToRetrieveMetadata | UnableToReadFile | UnableToWriteFile $exception) {
throw UnableToCopyFile::fromLocationTo($source, $destination, $exception);
}
}
private function moveInTheSameFilesystem(
FilesystemOperator $sourceFilesystem,
string $sourcePath,
string $destinationPath,
string $source,
string $destination
): void {
try {
$sourceFilesystem->move($sourcePath, $destinationPath);
} catch (UnableToMoveFile $exception) {
throw UnableToMoveFile::fromLocationTo($source, $destination, $exception);
}
}
private function moveAcrossFilesystems(string $source, string $destination): void
/**
* Check whether a file exists.
*
* @param string $path
*
* @return bool
*/
public function has($path)
{
try {
$this->copy($source, $destination);
$this->delete($source);
} catch (UnableToCopyFile | UnableToDeleteFile $exception) {
throw UnableToMoveFile::fromLocationTo($source, $destination, $exception);
}
list($prefix, $path) = $this->getPrefixAndPath($path);
return $this->getFilesystem($prefix)->has($path);
}
/**
* Read a file.
*
* @param string $path The path to the file.
*
* @throws FileNotFoundException
*
* @return string|false The file contents or false on failure.
*/
public function read($path)
{
list($prefix, $path) = $this->getPrefixAndPath($path);
return $this->getFilesystem($prefix)->read($path);
}
/**
* Retrieves a read-stream for a path.
*
* @param string $path The path to the file.
*
* @throws FileNotFoundException
*
* @return resource|false The path resource or false on failure.
*/
public function readStream($path)
{
list($prefix, $path) = $this->getPrefixAndPath($path);
return $this->getFilesystem($prefix)->readStream($path);
}
/**
* Get a file's metadata.
*
* @param string $path The path to the file.
*
* @throws FileNotFoundException
*
* @return array|false The file metadata or false on failure.
*/
public function getMetadata($path)
{
list($prefix, $path) = $this->getPrefixAndPath($path);
return $this->getFilesystem($prefix)->getMetadata($path);
}
/**
* Get a file's size.
*
* @param string $path The path to the file.
*
* @throws FileNotFoundException
*
* @return int|false The file size or false on failure.
*/
public function getSize($path)
{
list($prefix, $path) = $this->getPrefixAndPath($path);
return $this->getFilesystem($prefix)->getSize($path);
}
/**
* Get a file's mime-type.
*
* @param string $path The path to the file.
*
* @throws FileNotFoundException
*
* @return string|false The file mime-type or false on failure.
*/
public function getMimetype($path)
{
list($prefix, $path) = $this->getPrefixAndPath($path);
return $this->getFilesystem($prefix)->getMimetype($path);
}
/**
* Get a file's timestamp.
*
* @param string $path The path to the file.
*
* @throws FileNotFoundException
*
* @return string|false The timestamp or false on failure.
*/
public function getTimestamp($path)
{
list($prefix, $path) = $this->getPrefixAndPath($path);
return $this->getFilesystem($prefix)->getTimestamp($path);
}
/**
* Get a file's visibility.
*
* @param string $path The path to the file.
*
* @throws FileNotFoundException
*
* @return string|false The visibility (public|private) or false on failure.
*/
public function getVisibility($path)
{
list($prefix, $path) = $this->getPrefixAndPath($path);
return $this->getFilesystem($prefix)->getVisibility($path);
}
/**
* Write a new file.
*
* @param string $path The path of the new file.
* @param string $contents The file contents.
* @param array $config An optional configuration array.
*
* @throws FileExistsException
*
* @return bool True on success, false on failure.
*/
public function write($path, $contents, array $config = [])
{
list($prefix, $path) = $this->getPrefixAndPath($path);
return $this->getFilesystem($prefix)->write($path, $contents, $config);
}
/**
* Write a new file using a stream.
*
* @param string $path The path of the new file.
* @param resource $resource The file handle.
* @param array $config An optional configuration array.
*
* @throws InvalidArgumentException If $resource is not a file handle.
* @throws FileExistsException
*
* @return bool True on success, false on failure.
*/
public function writeStream($path, $resource, array $config = [])
{
list($prefix, $path) = $this->getPrefixAndPath($path);
return $this->getFilesystem($prefix)->writeStream($path, $resource, $config);
}
/**
* Update an existing file.
*
* @param string $path The path of the existing file.
* @param string $contents The file contents.
* @param array $config An optional configuration array.
*
* @throws FileNotFoundException
*
* @return bool True on success, false on failure.
*/
public function update($path, $contents, array $config = [])
{
list($prefix, $path) = $this->getPrefixAndPath($path);
return $this->getFilesystem($prefix)->update($path, $contents, $config);
}
/**
* Update an existing file using a stream.
*
* @param string $path The path of the existing file.
* @param resource $resource The file handle.
* @param array $config An optional configuration array.
*
* @throws InvalidArgumentException If $resource is not a file handle.
* @throws FileNotFoundException
*
* @return bool True on success, false on failure.
*/
public function updateStream($path, $resource, array $config = [])
{
list($prefix, $path) = $this->getPrefixAndPath($path);
return $this->getFilesystem($prefix)->updateStream($path, $resource, $config);
}
/**
* Rename a file.
*
* @param string $path Path to the existing file.
* @param string $newpath The new path of the file.
*
* @throws FileExistsException Thrown if $newpath exists.
* @throws FileNotFoundException Thrown if $path does not exist.
*
* @return bool True on success, false on failure.
*/
public function rename($path, $newpath)
{
list($prefix, $path) = $this->getPrefixAndPath($path);
return $this->getFilesystem($prefix)->rename($path, $newpath);
}
/**
* Delete a file.
*
* @param string $path
*
* @throws FileNotFoundException
*
* @return bool True on success, false on failure.
*/
public function delete($path)
{
list($prefix, $path) = $this->getPrefixAndPath($path);
return $this->getFilesystem($prefix)->delete($path);
}
/**
* Delete a directory.
*
* @param string $dirname
*
* @throws RootViolationException Thrown if $dirname is empty.
*
* @return bool True on success, false on failure.
*/
public function deleteDir($dirname)
{
list($prefix, $dirname) = $this->getPrefixAndPath($dirname);
return $this->getFilesystem($prefix)->deleteDir($dirname);
}
/**
* Create a directory.
*
* @param string $dirname The name of the new directory.
* @param array $config An optional configuration array.
*
* @return bool True on success, false on failure.
*/
public function createDir($dirname, array $config = [])
{
list($prefix, $dirname) = $this->getPrefixAndPath($dirname);
return $this->getFilesystem($prefix)->createDir($dirname);
}
/**
* Set the visibility for a file.
*
* @param string $path The path to the file.
* @param string $visibility One of 'public' or 'private'.
*
* @throws FileNotFoundException
*
* @return bool True on success, false on failure.
*/
public function setVisibility($path, $visibility)
{
list($prefix, $path) = $this->getPrefixAndPath($path);
return $this->getFilesystem($prefix)->setVisibility($path, $visibility);
}
/**
* Create a file or update if exists.
*
* @param string $path The path to the file.
* @param string $contents The file contents.
* @param array $config An optional configuration array.
*
* @return bool True on success, false on failure.
*/
public function put($path, $contents, array $config = [])
{
list($prefix, $path) = $this->getPrefixAndPath($path);
return $this->getFilesystem($prefix)->put($path, $contents, $config);
}
/**
* Create a file or update if exists.
*
* @param string $path The path to the file.
* @param resource $resource The file handle.
* @param array $config An optional configuration array.
*
* @throws InvalidArgumentException Thrown if $resource is not a resource.
*
* @return bool True on success, false on failure.
*/
public function putStream($path, $resource, array $config = [])
{
list($prefix, $path) = $this->getPrefixAndPath($path);
return $this->getFilesystem($prefix)->putStream($path, $resource, $config);
}
/**
* Read and delete a file.
*
* @param string $path The path to the file.
*
* @throws FileNotFoundException
*
* @return string|false The file contents, or false on failure.
*/
public function readAndDelete($path)
{
list($prefix, $path) = $this->getPrefixAndPath($path);
return $this->getFilesystem($prefix)->readAndDelete($path);
}
/**
* Get a file/directory handler.
*
* @deprecated
*
* @param string $path The path to the file.
* @param Handler $handler An optional existing handler to populate.
*
* @return Handler Either a file or directory handler.
*/
public function get($path, Handler $handler = null)
{
list($prefix, $path) = $this->getPrefixAndPath($path);
return $this->getFilesystem($prefix)->get($path);
}
}

View File

@ -1 +1 @@
6.6.5
6.6.4

View File

@ -51,7 +51,7 @@
"hayageek/oauth2-yahoo": "Needed for Yahoo XOAUTH2 authentication",
"league/oauth2-google": "Needed for Google XOAUTH2 authentication",
"psr/log": "For optional PSR-3 debug logging",
"thenetworg/oauth2-azure": "Needed for Microsoft XOAUTH2 authentication",
"stevenmaguire/oauth2-microsoft": "Needed for Microsoft XOAUTH2 authentication",
"symfony/polyfill-mbstring": "To support UTF-8 if the Mbstring PHP extension is not enabled (^1.2)"
},
"autoload": {

View File

@ -14,22 +14,16 @@ $PHPMAILER_LANG['data_not_accepted'] = 'SMTP fejl: Data blev ikke accepteret.
$PHPMAILER_LANG['empty_message'] = 'Meddelelsen er uden indhold';
$PHPMAILER_LANG['encoding'] = 'Ukendt encode-format: ';
$PHPMAILER_LANG['execute'] = 'Kunne ikke afvikle: ';
$PHPMAILER_LANG['extension_missing'] = 'Udvidelse mangler: ';
$PHPMAILER_LANG['file_access'] = 'Kunne ikke tilgå filen: ';
$PHPMAILER_LANG['file_open'] = 'Fil fejl: Kunne ikke åbne filen: ';
$PHPMAILER_LANG['from_failed'] = 'Følgende afsenderadresse er forkert: ';
$PHPMAILER_LANG['instantiate'] = 'Email funktionen kunne ikke initialiseres.';
$PHPMAILER_LANG['invalid_address'] = 'Udgyldig adresse: ';
$PHPMAILER_LANG['invalid_header'] = 'Ugyldig header navn eller værdi';
$PHPMAILER_LANG['invalid_hostentry'] = 'Ugyldig hostentry: ';
$PHPMAILER_LANG['invalid_host'] = 'Ugyldig vært: ';
$PHPMAILER_LANG['mailer_not_supported'] = ' mailer understøttes ikke.';
$PHPMAILER_LANG['provide_address'] = 'Indtast mindst en modtagers email adresse.';
$PHPMAILER_LANG['recipients_failed'] = 'SMTP fejl: Følgende modtagere fejlede: ';
$PHPMAILER_LANG['recipients_failed'] = 'SMTP fejl: Følgende modtagere er forkerte: ';
$PHPMAILER_LANG['signing'] = 'Signeringsfejl: ';
$PHPMAILER_LANG['smtp_code'] = 'SMTP kode: ';
$PHPMAILER_LANG['smtp_code_ex'] = 'Yderligere SMTP info: ';
$PHPMAILER_LANG['smtp_connect_failed'] = 'SMTP Connect() fejlede.';
$PHPMAILER_LANG['smtp_detail'] = 'Detalje: ';
$PHPMAILER_LANG['smtp_error'] = 'SMTP server fejl: ';
$PHPMAILER_LANG['variable_set'] = 'Kunne ikke definere eller nulstille variablen: ';
$PHPMAILER_LANG['extension_missing'] = 'Udvidelse mangler: ';

View File

@ -9,18 +9,19 @@ $PHPMAILER_LANG['authenticate'] = 'Błąd SMTP: Nie można przeprowadzi
$PHPMAILER_LANG['connect_host'] = 'Błąd SMTP: Nie można połączyć się z wybranym hostem.';
$PHPMAILER_LANG['data_not_accepted'] = 'Błąd SMTP: Dane nie zostały przyjęte.';
$PHPMAILER_LANG['empty_message'] = 'Wiadomość jest pusta.';
$PHPMAILER_LANG['encoding'] = 'Błędny sposób kodowania znaków: ';
$PHPMAILER_LANG['encoding'] = 'Nieznany sposób kodowania znaków: ';
$PHPMAILER_LANG['execute'] = 'Nie można uruchomić: ';
$PHPMAILER_LANG['file_access'] = 'Brak dostępu do pliku: ';
$PHPMAILER_LANG['file_open'] = 'Nie można otworzyć pliku: ';
$PHPMAILER_LANG['from_failed'] = 'Następujący adres nadawcy jest nieprawidłowy lub nie istnieje: ';
$PHPMAILER_LANG['from_failed'] = 'Następujący adres Nadawcy jest nieprawidłowy: ';
$PHPMAILER_LANG['instantiate'] = 'Nie można wywołać funkcji mail(). Sprawdź konfigurację serwera.';
$PHPMAILER_LANG['invalid_address'] = 'Nie można wysłać wiadomości, ' . 'następujący adres odbiorcy jest nieprawidłowy lub nie istnieje: ';
$PHPMAILER_LANG['provide_address'] = 'Należy podać prawidłowy adres email odbiorcy.';
$PHPMAILER_LANG['invalid_address'] = 'Nie można wysłać wiadomości, ' .
'następujący adres Odbiorcy jest nieprawidłowy: ';
$PHPMAILER_LANG['provide_address'] = 'Należy podać prawidłowy adres email Odbiorcy.';
$PHPMAILER_LANG['mailer_not_supported'] = 'Wybrana metoda wysyłki wiadomości nie jest obsługiwana.';
$PHPMAILER_LANG['recipients_failed'] = 'Błąd SMTP: Następujący odbiorcy są nieprawidłowi lub nie istnieją: ';
$PHPMAILER_LANG['recipients_failed'] = 'Błąd SMTP: Następujący odbiorcy są nieprawidłowi: ';
$PHPMAILER_LANG['signing'] = 'Błąd podpisywania wiadomości: ';
$PHPMAILER_LANG['smtp_connect_failed'] = 'Wywołanie funkcji SMTP Connect() zostało zakończone niepowodzeniem.';
$PHPMAILER_LANG['smtp_connect_failed'] = 'SMTP Connect() zakończone niepowodzeniem.';
$PHPMAILER_LANG['smtp_error'] = 'Błąd SMTP: ';
$PHPMAILER_LANG['variable_set'] = 'Nie można ustawić lub zmodyfikować zmiennej: ';
$PHPMAILER_LANG['extension_missing'] = 'Brakujące rozszerzenie: ';

View File

@ -750,7 +750,7 @@ class PHPMailer
*
* @var string
*/
const VERSION = '6.6.5';
const VERSION = '6.6.4';
/**
* Error severity: message only, continue processing.
@ -1671,7 +1671,7 @@ class PHPMailer
return $this->mailSend($this->MIMEHeader, $this->MIMEBody);
}
} catch (Exception $exc) {
if ($this->Mailer === 'smtp' && $this->SMTPKeepAlive == true && $this->smtp->connected()) {
if ($this->Mailer === 'smtp' && $this->SMTPKeepAlive == true) {
$this->smtp->reset();
}
$this->setError($exc->getMessage());
@ -1863,7 +1863,7 @@ class PHPMailer
if (!static::isPermittedPath($path)) {
return false;
}
$readable = is_file($path);
$readable = file_exists($path);
//If not a UNC path (expected to start with \\), check read permission, see #2069
if (strpos($path, '\\\\') !== 0) {
$readable = $readable && is_readable($path);
@ -2101,9 +2101,6 @@ class PHPMailer
$this->smtp->setDebugLevel($this->SMTPDebug);
$this->smtp->setDebugOutput($this->Debugoutput);
$this->smtp->setVerp($this->do_verp);
if ($this->Host === null) {
$this->Host = 'localhost';
}
$hosts = explode(';', $this->Host);
$lastexception = null;

View File

@ -46,7 +46,7 @@ class POP3
*
* @var string
*/
const VERSION = '6.6.5';
const VERSION = '6.6.4';
/**
* Default POP3 port number.

View File

@ -35,7 +35,7 @@ class SMTP
*
* @var string
*/
const VERSION = '6.6.5';
const VERSION = '6.6.4';
/**
* SMTP line break constant.
@ -682,6 +682,7 @@ class SMTP
*/
public function close()
{
$this->setError('');
$this->server_caps = null;
$this->helo_rply = null;
if (is_resource($this->smtp_conn)) {

2
vendor/services.php vendored
View File

@ -1,5 +1,5 @@
<?php
// This file is automatically generated at:2022-11-07 13:45:48
// This file is automatically generated at:2022-11-15 15:58:49
declare (strict_types = 1);
return array (
0 => 'taoser\\addons\\Service',

View File

@ -80,7 +80,7 @@ final class Mbstring
public static function mb_convert_encoding($s, $toEncoding, $fromEncoding = null)
{
if (\is_array($fromEncoding) || ($fromEncoding !== null && false !== strpos($fromEncoding, ','))) {
if (\is_array($fromEncoding) || (null !== $fromEncoding && false !== strpos($fromEncoding, ','))) {
$fromEncoding = self::mb_detect_encoding($s, $fromEncoding);
} else {
$fromEncoding = self::getEncoding($fromEncoding);
@ -102,7 +102,7 @@ final class Mbstring
$fromEncoding = 'Windows-1252';
}
if ('UTF-8' !== $fromEncoding) {
$s = \iconv($fromEncoding, 'UTF-8//IGNORE', $s);
$s = iconv($fromEncoding, 'UTF-8//IGNORE', $s);
}
return preg_replace_callback('/[\x80-\xFF]+/', [__CLASS__, 'html_encoding_callback'], $s);
@ -113,7 +113,7 @@ final class Mbstring
$fromEncoding = 'UTF-8';
}
return \iconv($fromEncoding, $toEncoding.'//IGNORE', $s);
return iconv($fromEncoding, $toEncoding.'//IGNORE', $s);
}
public static function mb_convert_variables($toEncoding, $fromEncoding, &...$vars)
@ -130,7 +130,7 @@ final class Mbstring
public static function mb_decode_mimeheader($s)
{
return \iconv_mime_decode($s, 2, self::$internalEncoding);
return iconv_mime_decode($s, 2, self::$internalEncoding);
}
public static function mb_encode_mimeheader($s, $charset = null, $transferEncoding = null, $linefeed = null, $indent = null)
@ -140,7 +140,7 @@ final class Mbstring
public static function mb_decode_numericentity($s, $convmap, $encoding = null)
{
if (null !== $s && !is_scalar($s) && !(\is_object($s) && method_exists($s, '__toString'))) {
if (null !== $s && !\is_scalar($s) && !(\is_object($s) && method_exists($s, '__toString'))) {
trigger_error('mb_decode_numericentity() expects parameter 1 to be string, '.\gettype($s).' given', \E_USER_WARNING);
return null;
@ -150,7 +150,7 @@ final class Mbstring
return false;
}
if (null !== $encoding && !is_scalar($encoding)) {
if (null !== $encoding && !\is_scalar($encoding)) {
trigger_error('mb_decode_numericentity() expects parameter 3 to be string, '.\gettype($s).' given', \E_USER_WARNING);
return ''; // Instead of null (cf. mb_encode_numericentity).
@ -166,10 +166,10 @@ final class Mbstring
if ('UTF-8' === $encoding) {
$encoding = null;
if (!preg_match('//u', $s)) {
$s = @\iconv('UTF-8', 'UTF-8//IGNORE', $s);
$s = @iconv('UTF-8', 'UTF-8//IGNORE', $s);
}
} else {
$s = \iconv($encoding, 'UTF-8//IGNORE', $s);
$s = iconv($encoding, 'UTF-8//IGNORE', $s);
}
$cnt = floor(\count($convmap) / 4) * 4;
@ -195,12 +195,12 @@ final class Mbstring
return $s;
}
return \iconv('UTF-8', $encoding.'//IGNORE', $s);
return iconv('UTF-8', $encoding.'//IGNORE', $s);
}
public static function mb_encode_numericentity($s, $convmap, $encoding = null, $is_hex = false)
{
if (null !== $s && !is_scalar($s) && !(\is_object($s) && method_exists($s, '__toString'))) {
if (null !== $s && !\is_scalar($s) && !(\is_object($s) && method_exists($s, '__toString'))) {
trigger_error('mb_encode_numericentity() expects parameter 1 to be string, '.\gettype($s).' given', \E_USER_WARNING);
return null;
@ -210,13 +210,13 @@ final class Mbstring
return false;
}
if (null !== $encoding && !is_scalar($encoding)) {
if (null !== $encoding && !\is_scalar($encoding)) {
trigger_error('mb_encode_numericentity() expects parameter 3 to be string, '.\gettype($s).' given', \E_USER_WARNING);
return null; // Instead of '' (cf. mb_decode_numericentity).
}
if (null !== $is_hex && !is_scalar($is_hex)) {
if (null !== $is_hex && !\is_scalar($is_hex)) {
trigger_error('mb_encode_numericentity() expects parameter 4 to be boolean, '.\gettype($s).' given', \E_USER_WARNING);
return null;
@ -232,10 +232,10 @@ final class Mbstring
if ('UTF-8' === $encoding) {
$encoding = null;
if (!preg_match('//u', $s)) {
$s = @\iconv('UTF-8', 'UTF-8//IGNORE', $s);
$s = @iconv('UTF-8', 'UTF-8//IGNORE', $s);
}
} else {
$s = \iconv($encoding, 'UTF-8//IGNORE', $s);
$s = iconv($encoding, 'UTF-8//IGNORE', $s);
}
static $ulenMask = ["\xC0" => 2, "\xD0" => 2, "\xE0" => 3, "\xF0" => 4];
@ -265,7 +265,7 @@ final class Mbstring
return $result;
}
return \iconv('UTF-8', $encoding.'//IGNORE', $result);
return iconv('UTF-8', $encoding.'//IGNORE', $result);
}
public static function mb_convert_case($s, $mode, $encoding = null)
@ -280,10 +280,10 @@ final class Mbstring
if ('UTF-8' === $encoding) {
$encoding = null;
if (!preg_match('//u', $s)) {
$s = @\iconv('UTF-8', 'UTF-8//IGNORE', $s);
$s = @iconv('UTF-8', 'UTF-8//IGNORE', $s);
}
} else {
$s = \iconv($encoding, 'UTF-8//IGNORE', $s);
$s = iconv($encoding, 'UTF-8//IGNORE', $s);
}
if (\MB_CASE_TITLE == $mode) {
@ -343,7 +343,7 @@ final class Mbstring
return $s;
}
return \iconv('UTF-8', $encoding.'//IGNORE', $s);
return iconv('UTF-8', $encoding.'//IGNORE', $s);
}
public static function mb_internal_encoding($encoding = null)
@ -354,7 +354,7 @@ final class Mbstring
$normalizedEncoding = self::getEncoding($encoding);
if ('UTF-8' === $normalizedEncoding || false !== @\iconv($normalizedEncoding, $normalizedEncoding, ' ')) {
if ('UTF-8' === $normalizedEncoding || false !== @iconv($normalizedEncoding, $normalizedEncoding, ' ')) {
self::$internalEncoding = $normalizedEncoding;
return true;
@ -413,7 +413,7 @@ final class Mbstring
$encoding = self::$internalEncoding;
}
return self::mb_detect_encoding($var, [$encoding]) || false !== @\iconv($encoding, $encoding, $var);
return self::mb_detect_encoding($var, [$encoding]) || false !== @iconv($encoding, $encoding, $var);
}
public static function mb_detect_encoding($str, $encodingList = null, $strict = false)
@ -488,7 +488,7 @@ final class Mbstring
return \strlen($s);
}
return @\iconv_strlen($s, $encoding);
return @iconv_strlen($s, $encoding);
}
public static function mb_strpos($haystack, $needle, $offset = 0, $encoding = null)
@ -509,7 +509,7 @@ final class Mbstring
return 0;
}
return \iconv_strpos($haystack, $needle, $offset, $encoding);
return iconv_strpos($haystack, $needle, $offset, $encoding);
}
public static function mb_strrpos($haystack, $needle, $offset = 0, $encoding = null)
@ -533,7 +533,7 @@ final class Mbstring
}
$pos = '' !== $needle || 80000 > \PHP_VERSION_ID
? \iconv_strrpos($haystack, $needle, $encoding)
? iconv_strrpos($haystack, $needle, $encoding)
: self::mb_strlen($haystack, $encoding);
return false !== $pos ? $offset + $pos : false;
@ -541,7 +541,7 @@ final class Mbstring
public static function mb_str_split($string, $split_length = 1, $encoding = null)
{
if (null !== $string && !is_scalar($string) && !(\is_object($string) && method_exists($string, '__toString'))) {
if (null !== $string && !\is_scalar($string) && !(\is_object($string) && method_exists($string, '__toString'))) {
trigger_error('mb_str_split() expects parameter 1 to be string, '.\gettype($string).' given', \E_USER_WARNING);
return null;
@ -550,6 +550,7 @@ final class Mbstring
if (1 > $split_length = (int) $split_length) {
if (80000 > \PHP_VERSION_ID) {
trigger_error('The length of each segment must be greater than zero', \E_USER_WARNING);
return false;
}
@ -617,7 +618,7 @@ final class Mbstring
}
if ($start < 0) {
$start = \iconv_strlen($s, $encoding) + $start;
$start = iconv_strlen($s, $encoding) + $start;
if ($start < 0) {
$start = 0;
}
@ -626,13 +627,13 @@ final class Mbstring
if (null === $length) {
$length = 2147483647;
} elseif ($length < 0) {
$length = \iconv_strlen($s, $encoding) + $length - $start;
$length = iconv_strlen($s, $encoding) + $length - $start;
if ($length < 0) {
return '';
}
}
return (string) \iconv_substr($s, $start, $length, $encoding);
return (string) iconv_substr($s, $start, $length, $encoding);
}
public static function mb_stripos($haystack, $needle, $offset = 0, $encoding = null)
@ -657,7 +658,7 @@ final class Mbstring
$pos = strrpos($haystack, $needle);
} else {
$needle = self::mb_substr($needle, 0, 1, $encoding);
$pos = \iconv_strrpos($haystack, $needle, $encoding);
$pos = iconv_strrpos($haystack, $needle, $encoding);
}
return self::getSubpart($pos, $part, $haystack, $encoding);
@ -736,12 +737,12 @@ final class Mbstring
$encoding = self::getEncoding($encoding);
if ('UTF-8' !== $encoding) {
$s = \iconv($encoding, 'UTF-8//IGNORE', $s);
$s = iconv($encoding, 'UTF-8//IGNORE', $s);
}
$s = preg_replace('/[\x{1100}-\x{115F}\x{2329}\x{232A}\x{2E80}-\x{303E}\x{3040}-\x{A4CF}\x{AC00}-\x{D7A3}\x{F900}-\x{FAFF}\x{FE10}-\x{FE19}\x{FE30}-\x{FE6F}\x{FF00}-\x{FF60}\x{FFE0}-\x{FFE6}\x{20000}-\x{2FFFD}\x{30000}-\x{3FFFD}]/u', '', $s, -1, $wide);
return ($wide << 1) + \iconv_strlen($s, 'UTF-8');
return ($wide << 1) + iconv_strlen($s, 'UTF-8');
}
public static function mb_substr_count($haystack, $needle, $encoding = null)

View File

@ -31,7 +31,7 @@
"minimum-stability": "dev",
"extra": {
"branch-alias": {
"dev-main": "1.26-dev"
"dev-main": "1.27-dev"
},
"thanks": {
"name": "symfony/polyfill",

View File

@ -83,7 +83,7 @@ final class Php72
'SunOS' => 'Solaris',
];
return isset($map[\PHP_OS]) ? $map[\PHP_OS] : 'Unknown';
return $map[\PHP_OS] ?? 'Unknown';
}
public static function spl_object_id($object)
@ -96,7 +96,7 @@ final class Php72
}
// On 32-bit systems, PHP_INT_SIZE is 4,
return self::$hashMask ^ hexdec(substr($hash, 16 - (\PHP_INT_SIZE * 2 - 1), (\PHP_INT_SIZE * 2 - 1)));
return self::$hashMask ^ hexdec(substr($hash, 16 - (\PHP_INT_SIZE * 2 - 1), \PHP_INT_SIZE * 2 - 1));
}
public static function sapi_windows_vt100_support($stream, $enable = null)
@ -167,7 +167,7 @@ final class Php72
self::$hashMask = (int) substr(ob_get_clean(), 17);
}
self::$hashMask ^= hexdec(substr(spl_object_hash($obj), 16 - (\PHP_INT_SIZE * 2 - 1), (\PHP_INT_SIZE * 2 - 1)));
self::$hashMask ^= hexdec(substr(spl_object_hash($obj), 16 - (\PHP_INT_SIZE * 2 - 1), \PHP_INT_SIZE * 2 - 1));
}
public static function mb_chr($code, $encoding = null)

View File

@ -25,7 +25,7 @@
"minimum-stability": "dev",
"extra": {
"branch-alias": {
"dev-main": "1.26-dev"
"dev-main": "1.27-dev"
},
"thanks": {
"name": "symfony/polyfill",

View File

@ -1,5 +1,14 @@
<?php
/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
#[Attribute(Attribute::TARGET_CLASS)]
final class Attribute
{

View File

@ -1,6 +1,15 @@
<?php
if (\PHP_VERSION_ID < 80000 && \extension_loaded('tokenizer')) {
/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
if (\PHP_VERSION_ID < 80000 && extension_loaded('tokenizer')) {
class PhpToken extends Symfony\Polyfill\Php80\PhpToken
{
}

View File

@ -1,5 +1,14 @@
<?php
/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
if (\PHP_VERSION_ID < 80000) {
interface Stringable
{

View File

@ -1,5 +1,14 @@
<?php
/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
if (\PHP_VERSION_ID < 80000) {
class UnhandledMatchError extends Error
{

View File

@ -1,5 +1,14 @@
<?php
/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
if (\PHP_VERSION_ID < 80000) {
class ValueError extends Error
{

View File

@ -30,7 +30,7 @@
"minimum-stability": "dev",
"extra": {
"branch-alias": {
"dev-main": "1.26-dev"
"dev-main": "1.27-dev"
},
"thanks": {
"name": "symfony/polyfill",

View File

@ -10,10 +10,6 @@
* file that was distributed with this source code.
*/
if ('cli' !== PHP_SAPI) {
throw new Exception('This script must be run from the command line.');
}
/**
* Starts a dump server to collect and output dumps on a single place with multiple formats support.
*

View File

@ -15,37 +15,15 @@ class Controller extends BaseController
{
// app 容器
protected $app;
// 当前插件操作
protected $addon = null;
// 请求对象
protected $request;
// 当前插件标识
protected $name;
// 插件路径
protected $addon_path;
protected $controller = null;
protected $action = null;
// 视图模型
protected $view;
/**
* 无需登录的方法,同时也就不需要鉴权了
* @var array
*/
protected $noNeedLogin = ['*'];
/**
* 无需鉴权的方法,但需要登录
* @var array
*/
protected $noNeedRight = ['*'];
/**
* 权限Auth
* @var Auth
*/
protected $auth = null;
/**
* 插件构造函数
@ -57,8 +35,6 @@ class Controller extends BaseController
$this->app = $app;
$this->request = $app->request;
$this->name = $this->getName();
$this->controller = $this->request->controller();
$this->action = $this->request->action();
$this->addon_path = $app->addons->getAddonsPath() . $this->name . DIRECTORY_SEPARATOR;
$this->addon_config = "addon_{$this->name}_config";
$this->addon_info = "addon_{$this->name}_info";
@ -68,17 +44,12 @@ class Controller extends BaseController
]);
// 控制器初始化
$this->_initialize();
parent::__construct($app);
$this->initialize();
}
// 初始化
protected function _initialize()
{
$controller = $this->controller;
$action = $this->action;
}
protected function initialize()
{}
/**
* 获取插件标识

View File

@ -284,37 +284,3 @@ if (!function_exists('get_addons_menu')) {
}
}
if (!function_exists('get_addons_list')) {
/**
* 获得插件列表
* @return array
*/
function get_addons_list()
{
$list = Cache::get('addonslist');
if (empty($list)) {
$addonsPath = app()->getRootPath().'addons'.DS; // 插件列表
$results = scandir($addonsPath);
$list = [];
foreach ($results as $name) {
if ($name === '.' or $name === '..')
continue;
if (is_file($addonsPath . $name))
continue;
$addonDir = $addonsPath . $name . DS;
if (!is_dir($addonDir))
continue;
if (!is_file($addonDir . 'Plugin' . '.php'))
continue;
$info = get_addons_info($name);
if (!isset($info['name']))
continue;
$info['url'] =isset($info['url']) && $info['url'] ?(string)addons_url($info['url']):'';
$list[$name] = $info;
}
Cache::set('addonslist', $list);
}
return $list;
}
}

View File

@ -20,8 +20,10 @@
}
},
"require": {
"php": ">=7.2.5",
"topthink/framework": "^6.1",
"league/flysystem": "^2.0"
"league/flysystem": "^1.1.4",
"league/flysystem-cached-adapter": "^1.0"
},
"require-dev": {
"mikey179/vfsstream": "^1.6",

View File

@ -0,0 +1,54 @@
<?php
// +----------------------------------------------------------------------
// | ThinkPHP [ WE CAN DO IT JUST THINK ]
// +----------------------------------------------------------------------
// | Copyright (c) 2006~2021 http://thinkphp.cn All rights reserved.
// +----------------------------------------------------------------------
// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
// +----------------------------------------------------------------------
// | Author: yunwuxin <448901948@qq.com>
// +----------------------------------------------------------------------
declare (strict_types = 1);
namespace think\filesystem;
use League\Flysystem\Cached\Storage\AbstractCache;
use Psr\SimpleCache\CacheInterface;
class CacheStore extends AbstractCache
{
protected $store;
protected $key;
protected $expire;
public function __construct(CacheInterface $store, $key = 'flysystem', $expire = null)
{
$this->key = $key;
$this->store = $store;
$this->expire = $expire;
}
/**
* Store the cache.
*/
public function save()
{
$contents = $this->getForStorage();
$this->store->set($this->key, $contents, $this->expire);
}
/**
* Load the cache.
*/
public function load()
{
$contents = $this->store->get($this->key);
if (!is_null($contents)) {
$this->setFromStorage($contents);
}
}
}

View File

@ -12,10 +12,11 @@ declare (strict_types = 1);
namespace think\filesystem;
use League\Flysystem\AdapterInterface;
use League\Flysystem\Adapter\AbstractAdapter;
use League\Flysystem\Cached\CachedAdapter;
use League\Flysystem\Cached\Storage\Memory as MemoryStore;
use League\Flysystem\Filesystem;
use League\Flysystem\FilesystemAdapter;
use League\Flysystem\UnableToSetVisibility;
use League\Flysystem\UnableToWriteFile;
use RuntimeException;
use think\Cache;
use think\File;
@ -49,13 +50,30 @@ abstract class Driver
$this->filesystem = $this->createFilesystem($adapter);
}
abstract protected function createAdapter(): FilesystemAdapter;
protected function createFilesystem(FilesystemAdapter $adapter): Filesystem
protected function createCacheStore($config)
{
if (true === $config) {
return new MemoryStore;
}
return new CacheStore(
$this->cache->store($config['store']),
$config['prefix'] ?? 'flysystem',
$config['expire'] ?? null
);
}
abstract protected function createAdapter(): AdapterInterface;
protected function createFilesystem(AdapterInterface $adapter): Filesystem
{
if (!empty($this->config['cache'])) {
$adapter = new CachedAdapter($adapter, $this->createCacheStore($this->config['cache']));
}
$config = array_intersect_key($this->config, array_flip(['visibility', 'disable_asserts', 'url']));
return new Filesystem($adapter, count($config) > 0 ? $config : null);
return new Filesystem($adapter, count($config) > 0 ? $config : []);
}
/**
@ -65,6 +83,12 @@ abstract class Driver
*/
public function path(string $path): string
{
$adapter = $this->filesystem->getAdapter();
if ($adapter instanceof AbstractAdapter) {
return $adapter->applyPathPrefix($path);
}
return $path;
}
@ -80,10 +104,10 @@ abstract class Driver
/**
* 保存文件
* @param string $path 路径
* @param File $file 文件
* @param null|string|\Closure $rule 文件名规则
* @param array $options 参数
* @param string $path 路径
* @param File $file 文件
* @param null|string|\Closure $rule 文件名规则
* @param array $options 参数
* @return bool|string
*/
public function putFile(string $path, File $file, $rule = null, array $options = [])
@ -93,10 +117,10 @@ abstract class Driver
/**
* 指定文件名保存文件
* @param string $path 路径
* @param File $file 文件
* @param string $name 文件名
* @param array $options 参数
* @param string $path 路径
* @param File $file 文件
* @param string $name 文件名
* @param array $options 参数
* @return bool|string
*/
public function putFileAs(string $path, File $file, string $name, array $options = [])
@ -104,7 +128,7 @@ abstract class Driver
$stream = fopen($file->getRealPath(), 'r');
$path = trim($path . '/' . $name, '/');
$result = $this->put($path, $stream, $options);
$result = $this->putStream($path, $stream, $options);
if (is_resource($stream)) {
fclose($stream);
@ -113,16 +137,6 @@ abstract class Driver
return $result ? $path : false;
}
protected function put(string $path, $contents, array $options = [])
{
try {
$this->writeStream($path, $contents, $options);
} catch (UnableToWriteFile|UnableToSetVisibility $e) {
return false;
}
return true;
}
public function __call($method, $parameters)
{
return $this->filesystem->$method(...$parameters);

View File

@ -12,13 +12,8 @@ declare (strict_types = 1);
namespace think\filesystem\driver;
use League\Flysystem\FilesystemAdapter;
use League\Flysystem\Local\LocalFilesystemAdapter;
use League\Flysystem\PathNormalizer;
use League\Flysystem\PathPrefixer;
use League\Flysystem\UnixVisibility\PortableVisibilityConverter;
use League\Flysystem\Visibility;
use League\Flysystem\WhitespacePathNormalizer;
use League\Flysystem\AdapterInterface;
use League\Flysystem\Adapter\Local as LocalAdapter;
use think\filesystem\Driver;
class Local extends Driver
@ -31,51 +26,22 @@ class Local extends Driver
'root' => '',
];
/**
* @var PathPrefixer
*/
protected $prefixer;
/**
* @var PathNormalizer
*/
protected $normalizer;
protected function createAdapter(): FilesystemAdapter
protected function createAdapter(): AdapterInterface
{
$visibility = PortableVisibilityConverter::fromArray(
$this->config['permissions'] ?? [],
$this->config['visibility'] ?? Visibility::PRIVATE
);
$permissions = $this->config['permissions'] ?? [];
$links = ($this->config['links'] ?? null) === 'skip'
? LocalFilesystemAdapter::SKIP_LINKS
: LocalFilesystemAdapter::DISALLOW_LINKS;
? LocalAdapter::SKIP_LINKS
: LocalAdapter::DISALLOW_LINKS;
return new LocalFilesystemAdapter(
return new LocalAdapter(
$this->config['root'],
$visibility,
$this->config['lock'] ?? LOCK_EX,
$links
LOCK_EX,
$links,
$permissions
);
}
protected function prefixer()
{
if (!$this->prefixer) {
$this->prefixer = new PathPrefixer($this->config['root'], DIRECTORY_SEPARATOR);
}
return $this->prefixer;
}
protected function normalizer()
{
if (!$this->normalizer) {
$this->normalizer = new WhitespacePathNormalizer();
}
return $this->normalizer;
}
/**
* 获取文件访问地址
* @param string $path 文件路径
@ -83,16 +49,11 @@ class Local extends Driver
*/
public function url(string $path): string
{
$path = $this->normalizer()->normalizePath($path);
$path = str_replace('\\', '/', $path);
if (isset($this->config['url'])) {
return $this->concatPathToUrl($this->config['url'], $path);
}
return parent::url($path);
}
public function path(string $path): string
{
return $this->prefixer()->prefixPath($path);
}
}

View File

@ -2,15 +2,20 @@
namespace think\tests;
use League\Flysystem\Adapter\NullAdapter;
use League\Flysystem\AdapterInterface;
use Mockery as m;
use Mockery\MockInterface;
use org\bovigo\vfs\vfsStream;
use org\bovigo\vfs\vfsStreamDirectory;
use PHPUnit\Framework\TestCase;
use think\App;
use think\Cache;
use think\cache\driver\File;
use think\Config;
use think\Container;
use think\Filesystem;
use think\filesystem\Driver;
use think\filesystem\driver\Local;
class FilesystemTest extends TestCase
@ -62,5 +67,65 @@ class FilesystemTest extends TestCase
$this->assertInstanceOf(Local::class, $this->filesystem->disk('foo'));
}
public function testCache()
{
$this->config->shouldReceive('get')->with('filesystem.disks.local', null)->andReturn([
'type' => 'local',
'root' => $this->root->url(),
'cache' => true,
]);
$this->assertInstanceOf(Local::class, $this->filesystem->disk());
$this->config->shouldReceive('get')->with('filesystem.disks.cache', null)->andReturn([
'type' => NullDriver::class,
'root' => $this->root->url(),
'cache' => [
'store' => 'flysystem',
],
]);
$cache = m::mock(Cache::class);
$cacheDriver = m::mock(File::class);
$cache->shouldReceive('store')->once()->with('flysystem')->andReturn($cacheDriver);
$this->app->shouldReceive('make')->with(Cache::class)->andReturn($cache);
$cacheDriver->shouldReceive('get')->with('flysystem')->once()->andReturn(null);
$cacheDriver->shouldReceive('set')->withAnyArgs();
$this->filesystem->disk('cache')->put('test.txt', 'aa');
}
public function testPutFile()
{
$root = vfsStream::setup('rootDir', null, [
'foo.jpg' => 'hello',
]);
$this->config->shouldReceive('get')->with('filesystem.disks.local', null)->andReturn([
'type' => NullDriver::class,
'root' => $root->url(),
'cache' => true,
]);
$file = m::mock(\think\File::class);
$file->shouldReceive('hashName')->with(null)->once()->andReturn('foo.jpg');
$file->shouldReceive('getRealPath')->once()->andReturn($root->getChild('foo.jpg')->url());
$this->filesystem->putFile('test', $file);
}
}
class NullDriver extends Driver
{
protected function createAdapter(): AdapterInterface
{
return new NullAdapter();
}
}

View File

@ -21,7 +21,7 @@
}
},
"require": {
"topthink/framework": "^6.0",
"topthink/framework": "^6.0.0",
"topthink/think-helper": "^3.0.3"
},
"minimum-stability": "dev",

View File

@ -85,11 +85,11 @@ class FactoryBuilder
*
* @param string $class
* @param string $name
* @param array $definitions
* @param array $states
* @param array $afterMaking
* @param array $afterCreating
* @param Faker $faker
* @param array $definitions
* @param array $states
* @param array $afterMaking
* @param array $afterCreating
* @param Faker $faker
* @return void
*/
public function __construct($class, $name, array $definitions, array $states,
@ -283,12 +283,9 @@ class FactoryBuilder
*/
protected function makeInstance(array $attributes = [])
{
/** @var Model $model */
$model = new $this->class;
$model->setAttrs($this->getRawAttributes($attributes));
return $model;
return new $this->class(
$this->getRawAttributes($attributes)
);
}
/**
@ -322,7 +319,7 @@ class FactoryBuilder
* Get the state attributes.
*
* @param string $state
* @param array $attributes
* @param array $attributes
* @return array
*/
protected function stateAttributes($state, array $attributes)
@ -389,7 +386,7 @@ class FactoryBuilder
/**
* Call after callbacks for each model and state.
*
* @param array $afterCallbacks
* @param array $afterCallbacks
* @param Collection $models
* @return void
*/
@ -407,8 +404,8 @@ class FactoryBuilder
/**
* Call after callbacks for each model and state.
*
* @param array $afterCallbacks
* @param Model $model
* @param array $afterCallbacks
* @param Model $model
* @param string $state
* @return void
*/

View File

@ -14,11 +14,5 @@ use Phinx\Seed\AbstractSeed;
class Seeder extends AbstractSeed
{
/**
* @return Factory
*/
public function factory()
{
return app(Factory::class);
}
}

View File

@ -26,7 +26,7 @@ class Create extends Command
->addArgument('name', InputArgument::REQUIRED, 'What is the name of the model?');
}
public function handle()
protected function handle()
{
$path = $this->getPath();

View File

@ -74,8 +74,6 @@ EOT
$status = ' <info>up</info> ';
} else {
$status = ' <error>down</error> ';
$version = [];
$version['start_time'] = $version['end_time'] = $version['breakpoint'] = '';
}
$maxNameLength = max($maxNameLength, strlen($migration->getName()));

View File

@ -559,4 +559,23 @@ trait ModelRelationQuery
$result->refreshOrigin();
}
/**
* 查询软删除数据
* @access public
* @return Query
*/
public function withTrashed()
{
return $this->model ? $this->model->queryWithTrashed() : $this;
}
/**
* 只查询软删除数据
* @access public
* @return Query
*/
public function onlyTrashed()
{
return $this->model ? $this->model->queryOnlyTrashed() : $this;
}
}

View File

@ -383,7 +383,7 @@ trait Attribute
} elseif (isset($this->type[$name])) {
// 类型转换
$value = $this->writeTransform($value, $this->type[$name]);
} elseif ((array_key_exists($name, $this->origin) || empty($this->origin)) && is_object($value) && method_exists($value, '__toString')) {
} elseif (array_key_exists($name, $this->origin) && is_object($value) && method_exists($value, '__toString')) {
// 对象类型
$value = $value->__toString();
}

View File

@ -18,18 +18,14 @@ use think\Model;
/**
* 数据软删除
* @mixin Model
* @method $this withTrashed()
* @method $this onlyTrashed()
*/
trait SoftDelete
{
public function db($scope = []): Query
{
$query = parent::db($scope);
$this->withNoTrashed($query);
return $query;
}
/**
* 是否包含软删除数据
* @var bool
*/
protected $withTrashed = false;
/**
* 判断当前实例是否被软删除
@ -47,18 +43,74 @@ trait SoftDelete
return false;
}
public function scopeWithTrashed(Query $query)
/**
* 查询软删除数据
* @access public
* @return Query
*/
public static function withTrashed(): Query
{
$query->removeOption('soft_delete');
$model = new static();
return $model->withTrashedData(true)->db();
}
public function scopeOnlyTrashed(Query $query)
/**
* 查询软删除数据
* @access public
* @return Query
*/
public function queryWithTrashed(): Query
{
return $this->withTrashedData(true)->db();
}
/**
* 是否包含软删除数据
* @access protected
* @param bool $withTrashed 是否包含软删除数据
* @return $this
*/
protected function withTrashedData(bool $withTrashed)
{
$this->withTrashed = $withTrashed;
return $this;
}
/**
* 只查询软删除数据
* @access public
* @return Query
*/
public static function onlyTrashed(): Query
{
$model = new static();
$field = $model->getDeleteTimeField(true);
if ($field) {
return $model
->db()
->useSoftDelete($field, $model->getWithTrashedExp());
}
return $model->db();
}
/**
* 只查询软删除数据
* @access public
* @return Query
*/
public function queryOnlyTrashed(): Query
{
$field = $this->getDeleteTimeField(true);
if ($field) {
$query->useSoftDelete($field, $this->getWithTrashedExp());
return $this->db()
->useSoftDelete($field, $this->getWithTrashedExp());
}
return $this->db();
}
/**
@ -87,9 +139,9 @@ trait SoftDelete
if ($name && !$force) {
// 软删除
$this->set($name, $this->autoWriteTimestamp());
$this->set($name, $this->autoWriteTimestamp($name));
$this->exists()->withEvent(false)->save();
$result = $this->exists()->withEvent(false)->save();
$this->withEvent(true);
} else {
@ -97,7 +149,7 @@ trait SoftDelete
$where = $this->getWhere();
// 删除当前模型数据
$this->db()
$result = $this->db()
->where($where)
->removeOption('soft_delete')
->delete();
@ -120,8 +172,8 @@ trait SoftDelete
/**
* 删除记录
* @access public
* @param mixed $data 主键列表 支持闭包查询条件
* @param bool $force 是否强制删除
* @param mixed $data 主键列表 支持闭包查询条件
* @param bool $force 是否强制删除
* @return bool
*/
public static function destroy($data, bool $force = false): bool
@ -130,20 +182,18 @@ trait SoftDelete
if (empty($data) && 0 !== $data) {
return false;
}
$model = (new static());
$query = $model->db(false);
// 仅当强制删除时包含软删除数据
$model = (new static());
if ($force) {
$query->removeOption('soft_delete');
$model->withTrashedData(true);
}
$query = $model->db(false);
if (is_array($data) && key($data) !== 0) {
$query->where($data);
$data = null;
} elseif ($data instanceof \Closure) {
call_user_func_array($data, [&$query]);
call_user_func_array($data, [ & $query]);
$data = null;
} elseif (is_null($data)) {
return false;
@ -152,7 +202,6 @@ trait SoftDelete
$resultSet = $query->select($data);
foreach ($resultSet as $result) {
/** @var Model $result */
$result->force($force)->delete();
}
@ -162,7 +211,7 @@ trait SoftDelete
/**
* 恢复被软删除的记录
* @access public
* @param array $where 更新条件
* @param array $where 更新条件
* @return bool
*/
public function restore($where = []): bool
@ -194,7 +243,7 @@ trait SoftDelete
/**
* 获取软删除字段
* @access protected
* @param bool $read 是否查询操作 写操作的时候会自动去掉表别名
* @param bool $read 是否查询操作 写操作的时候会自动去掉表别名
* @return string|false
*/
protected function getDeleteTimeField(bool $read = false)
@ -220,7 +269,7 @@ trait SoftDelete
/**
* 查询的时候默认排除软删除数据
* @access protected
* @param Query $query
* @param Query $query
* @return void
*/
protected function withNoTrashed(Query $query): void

View File

@ -241,7 +241,7 @@ class BelongsTo extends OneToOne
if (!empty($this->bindAttr)) {
// 绑定关联属性
$this->bindAttr($result, $relationModel);
$result->hidden([$relation], true);
$result->hidden([$relation]);
}
}
}
@ -283,7 +283,7 @@ class BelongsTo extends OneToOne
if (!empty($this->bindAttr)) {
// 绑定关联属性
$this->bindAttr($result, $relationModel);
$result->hidden([$relation], true);
$result->hidden([$relation]);
}
}

View File

@ -240,7 +240,7 @@ class HasOne extends OneToOne
if (!empty($this->bindAttr)) {
// 绑定关联属性
$this->bindAttr($result, $relationModel);
$result->hidden([$relation], true);
$result->hidden([$relation]);
}
}
}
@ -282,7 +282,7 @@ class HasOne extends OneToOne
if (!empty($this->bindAttr)) {
// 绑定关联属性
$this->bindAttr($result, $relationModel);
$result->hidden([$relation], true);
$result->hidden([$relation]);
}
}

View File

@ -13,7 +13,6 @@ namespace think\model\relation;
use Closure;
use think\db\exception\DbException as Exception;
use think\db\Query;
use think\helper\Str;
use think\Model;
use think\model\Relation;
@ -47,16 +46,14 @@ class MorphTo extends Relation
*/
protected $relation;
protected $queryCaller = [];
/**
* 架构函数
* @access public
* @param Model $parent 上级模型对象
* @param string $morphType 多态字段名
* @param string $morphKey 外键名
* @param array $alias 多态别名定义
* @param ?string $relation 关联名
* @param Model $parent 上级模型对象
* @param string $morphType 多态字段名
* @param string $morphKey 外键名
* @param array $alias 多态别名定义
* @param string $relation 关联名
*/
public function __construct(Model $parent, string $morphType, string $morphKey, array $alias = [], string $relation = null)
{
@ -83,8 +80,8 @@ class MorphTo extends Relation
/**
* 延迟获取关联数据
* @access public
* @param array $subRelation 子关联名
* @param ?Closure $closure 闭包查询条件
* @param array $subRelation 子关联名
* @param Closure $closure 闭包查询条件
* @return Model
*/
public function getRelation(array $subRelation = [], Closure $closure = null)
@ -98,7 +95,7 @@ class MorphTo extends Relation
// 主键数据
$pk = $this->parent->$morphKey;
$relationModel = $this->buildQuery((new $model)->relation($subRelation))->find($pk);
$relationModel = (new $model)->relation($subRelation)->find($pk);
if ($relationModel) {
$relationModel->setParent(clone $this->parent);
@ -110,11 +107,11 @@ class MorphTo extends Relation
/**
* 根据关联条件查询当前模型
* @access public
* @param string $operator 比较操作符
* @param integer $count 个数
* @param string $id 关联表的统计字段
* @param string $joinType JOIN类型
* @param Query $query Query对象
* @param string $operator 比较操作符
* @param integer $count 个数
* @param string $id 关联表的统计字段
* @param string $joinType JOIN类型
* @param Query $query Query对象
* @return Query
*/
public function has(string $operator = '>=', int $count = 1, string $id = '*', string $joinType = '', Query $query = null)
@ -125,45 +122,22 @@ class MorphTo extends Relation
/**
* 根据关联条件查询当前模型
* @access public
* @param mixed $where 查询条件(数组或者闭包)
* @param mixed $fields 字段
* @param string $joinType JOIN类型
* @param ?Query $query Query对象
* @param mixed $where 查询条件(数组或者闭包)
* @param mixed $fields 字段
* @param string $joinType JOIN类型
* @param Query $query Query对象
* @return Query
*/
public function hasWhere($where = [], $fields = null, string $joinType = '', Query $query = null)
{
$alias = class_basename($this->parent);
$types = $this->parent->distinct()->column($this->morphType);
$query = $query ?: $this->parent->db();
return $query->alias($alias)
->where(function (Query $query) use ($types, $where, $alias) {
foreach ($types as $type) {
if ($type) {
$query->whereExists(function (Query $query) use ($type, $where, $alias) {
/** @var Model $model */
$model = new ($this->parseModel($type));
$table = $model->getTable();
$query
->table($table)
->where($alias . '.' . $this->morphType, $type)
->whereRaw("`{$alias}`.`{$this->morphKey}`=`{$table}`.`{$model->getPk()}`")
->where($where);
}, 'OR');
}
}
});
throw new Exception('relation not support: hasWhere');
}
/**
* 解析模型的完整命名空间
* @access protected
* @param string $model 模型名(或者完整类名)
* @return Model
* @param string $model 模型名(或者完整类名)
* @return string
*/
protected function parseModel(string $model): string
{
@ -184,7 +158,7 @@ class MorphTo extends Relation
/**
* 设置多态别名
* @access public
* @param array $alias 别名定义
* @param array $alias 别名定义
* @return $this
*/
public function setAlias(array $alias)
@ -199,7 +173,7 @@ class MorphTo extends Relation
* @access public
* @return $this
*/
public function removeOption(string $option = '')
public function removeOption()
{
return $this;
}
@ -207,11 +181,11 @@ class MorphTo extends Relation
/**
* 预载入关联查询
* @access public
* @param array $resultSet 数据集
* @param string $relation 当前关联名
* @param array $subRelation 子关联名
* @param ?Closure $closure 闭包
* @param array $cache 关联缓存
* @param array $resultSet 数据集
* @param string $relation 当前关联名
* @param array $subRelation 子关联名
* @param Closure $closure 闭包
* @param array $cache 关联缓存
* @return void
* @throws Exception
*/
@ -237,8 +211,8 @@ class MorphTo extends Relation
if (!\is_null($closure)) {
$obj = $closure($obj);
}
$pk = $obj->getPk();
$list = $obj->with($subRelation)
$pk = $obj->getPk();
$list = $obj->with($subRelation)
->cache($cache[0] ?? false, $cache[1] ?? null, $cache[2] ?? null)
->select($val);
$data = [];
@ -268,11 +242,11 @@ class MorphTo extends Relation
/**
* 预载入关联查询
* @access public
* @param Model $result 数据对象
* @param string $relation 当前关联名
* @param array $subRelation 子关联名
* @param ?Closure $closure 闭包
* @param array $cache 关联缓存
* @param Model $result 数据对象
* @param string $relation 当前关联名
* @param array $subRelation 子关联名
* @param Closure $closure 闭包
* @param array $cache 关联缓存
* @return void
*/
public function eagerlyResult(Model $result, string $relation, array $subRelation = [], Closure $closure = null, array $cache = []): void
@ -286,42 +260,36 @@ class MorphTo extends Relation
/**
* 关联统计
* @access public
* @param Model $result 数据对象
* @param ?Closure $closure 闭包
* @param string $aggregate 聚合查询方法
* @param string $field 字段
* @param Model $result 数据对象
* @param Closure $closure 闭包
* @param string $aggregate 聚合查询方法
* @param string $field 字段
* @return integer
*/
public function relationCount(Model $result, Closure $closure = null, string $aggregate = 'count', string $field = '*')
{
}
{}
/**
* 多态MorphTo 关联模型预查询
* @access protected
* @param string $model 关联模型对象
* @param string $relation 关联名
* @param Model $result
* @param array $subRelation 子关联
* @param array $cache 关联缓存
* @param string $model 关联模型对象
* @param string $relation 关联名
* @param Model $result
* @param array $subRelation 子关联
* @param array $cache 关联缓存
* @return void
*/
protected function eagerlyMorphToOne(string $model, string $relation, Model $result, array $subRelation = [], array $cache = []): void
{
// 预载入关联查询 支持嵌套预载入
$pk = $this->parent->{$this->morphKey};
$data = (new $model)->with($subRelation)
->cache($cache[0] ?? false, $cache[1] ?? null, $cache[2] ?? null)
->find($pk);
$data = null;
if(\class_exists($model)){
$data = (new $model)->with($subRelation)
->cache($cache[0] ?? false, $cache[1] ?? null, $cache[2] ?? null)
->find($pk);
if ($data) {
$data->setParent(clone $result);
$data->exists(true);
}
if ($data) {
$data->setParent(clone $result);
$data->exists(true);
}
$result->setRelation($relation, $data ?: null);
@ -330,8 +298,8 @@ class MorphTo extends Relation
/**
* 添加关联数据
* @access public
* @param Model $model 关联模型对象
* @param string $type 多态类型
* @param Model $model 关联模型对象
* @param string $type 多态类型
* @return Model
*/
public function associate(Model $model, string $type = ''): Model
@ -364,18 +332,4 @@ class MorphTo extends Relation
return $this->parent->setRelation($this->relation, null);
}
protected function buildQuery(Query $query)
{
foreach ($this->queryCaller as $caller) {
call_user_func_array([$query, $caller[0]], $caller[1]);
}
return $query;
}
public function __call($method, $args)
{
$this->queryCaller[] = [$method, $args];
return $this;
}
}

View File

@ -16,7 +16,6 @@ namespace Workerman\Connection;
/**
* ConnectionInterface.
*/
#[\AllowDynamicProperties]
abstract class ConnectionInterface
{
/**

View File

@ -26,7 +26,6 @@ use \Exception;
* Worker class
* A container for listening ports
*/
#[\AllowDynamicProperties]
class Worker
{
/**
@ -34,7 +33,7 @@ class Worker
*
* @var string
*/
const VERSION = '4.1.4';
const VERSION = '4.1.3';
/**
* Status starting.
@ -638,18 +637,9 @@ class Worker
if (\DIRECTORY_SEPARATOR !== '/') {
return;
}
$lock_file = static::$pidFile . '.lock';
$fd = $fd ?: \fopen($lock_file, 'a+');
$fd = $fd ?: \fopen(static::$pidFile . '.lock', 'a+');
if ($fd) {
flock($fd, $flag);
if ($flag === \LOCK_UN) {
fclose($fd);
$fd = null;
clearstatcache();
if (\is_file($lock_file)) {
unlink($lock_file);
}
}
}
}

View File

@ -47,6 +47,7 @@ namespace yzh52521\EasyHttp;
* @method static \yzh52521\EasyHttp\Request headAsync(string $url, array|null $data = null, callable $success = null, callable $fail = null)
* @method static \yzh52521\EasyHttp\Request optionsAsync(string $url, array|null $data = null, callable $success = null, callable $fail = null)
* @method static \yzh52521\EasyHttp\Request multiAsync(array $promises, callable $success = null, callable $fail = null)
* @method static \yzh52521\EasyHttp\Request wait()
*/
class Http extends Facade

View File

@ -594,6 +594,14 @@ class Request
}
}
public function wait()
{
if (!empty($this->promises)) {
Promise\settle($this->promises)->wait();
}
$this->promises = [];
}
protected function response($response)
{
return new Response( $response );

View File

@ -0,0 +1,2 @@
*
!.gitignore

View File

@ -0,0 +1,2 @@
*
!.gitignore

2
view/wcompany/.gitignore vendored Normal file
View File

@ -0,0 +1,2 @@
*
!.gitignore