国庆版
This commit is contained in:
parent
ac251681e2
commit
e81de0d307
@ -5,6 +5,7 @@ namespace app;
|
||||
|
||||
use think\App;
|
||||
use think\exception\ValidateException;
|
||||
use think\response\Json;
|
||||
use think\Validate;
|
||||
use think\Response;
|
||||
use think\exception\HttpResponseException;
|
||||
@ -410,7 +411,7 @@ abstract class BaseController
|
||||
/**
|
||||
* 标题调用百度关键词词条
|
||||
*
|
||||
* @return void
|
||||
* @return Json
|
||||
*/
|
||||
public function getBdiduSearchWordList($words)
|
||||
{
|
||||
|
@ -18,6 +18,6 @@ class Request extends \think\Request
|
||||
//protected $filter = ['trim','htmlspecialchars'];
|
||||
//protected $filter = ['trim','strip_tags'];
|
||||
//protected $filter = ['htmlspecialchars'];
|
||||
//protected $filter = ['trim'];
|
||||
protected $filter = ['trim'];
|
||||
|
||||
}
|
||||
|
@ -2,14 +2,16 @@
|
||||
namespace app\admin\controller;
|
||||
|
||||
use app\common\controller\AdminController;
|
||||
use app\common\lib\SqlFile;
|
||||
use think\facade\View;
|
||||
use think\facade\Db;
|
||||
use think\facade\Request;
|
||||
use think\facade\Config;
|
||||
use app\admin\model\Addons as AddonsModel;
|
||||
use taoler\com\Files;
|
||||
use taoler\com\Api;
|
||||
use app\common\lib\Zip;
|
||||
use think\response\Json;
|
||||
use app\admin\model\AuthRule;
|
||||
|
||||
class Addons extends AdminController
|
||||
{
|
||||
@ -20,8 +22,12 @@ class Addons extends AdminController
|
||||
{
|
||||
return View::fetch();
|
||||
}
|
||||
|
||||
public function addonsList()
|
||||
|
||||
/**
|
||||
* 插件列表
|
||||
* @return Json
|
||||
*/
|
||||
public function addonsList() :Json
|
||||
{
|
||||
|
||||
$type = input('type');
|
||||
@ -59,24 +65,21 @@ class Addons extends AdminController
|
||||
//在线
|
||||
case 'onlineAddons':
|
||||
$url = $this->getSystem()['api_url'].'/v1/addons';
|
||||
$addons = Api::urlGet($url,[]);
|
||||
$addons = Api::urlGet($url);
|
||||
if( $addons->code !== -1){
|
||||
$res['code'] = 0;
|
||||
$res['msg'] = '';
|
||||
$res['data'] = $addons->data;
|
||||
$res['col'] = [
|
||||
['type' => 'numbers'],
|
||||
['field' => 'name','title'=> '插件', 'width'=> 150],
|
||||
['field'=> 'title','title'=> '标题', 'width'=> 100],
|
||||
['field'=> 'version','title'=> '版本', 'width'=> 100],
|
||||
['field' => 'title','title'=> '插件', 'width'=> 200],
|
||||
['field' => 'description','title'=> '简介', 'minWidth'=> 200],
|
||||
['field' => 'author','title'=> '作者', 'width'=> 100],
|
||||
['field' => 'description','title'=> '简介', 'minWidth'=> 200],
|
||||
['field' => 'price','title'=> '价格(元)'],
|
||||
['field' => 'status','title'=> '状态', 'width'=> 100],
|
||||
['field' => 'install','title'=> '安装', 'width'=> 100],
|
||||
['field' => 'vers','title'=> '版本选择','exportTemplet' => "function(d, obj){console.log(obj) var td = obj.td(this.field); return td.find('select').val();}"],
|
||||
['field' => 'ctime','title'=> '时间', 'width'=> 150],
|
||||
['title' => '操作', 'width'=> 300, 'align'=>'center', 'toolbar'=> '#addons-tool']
|
||||
['field' => 'price','title'=> '价格(元)','width'=> 80],
|
||||
['field' => 'downloads','title'=> '下载', 'width'=> 70],
|
||||
['field' => 'version','title'=> '版本', 'width'=> 70],
|
||||
['field' => 'status','title'=> '状态', 'width'=> 70],
|
||||
['title' => '操作', 'width'=> 180, 'align'=>'center', 'toolbar'=> '#addons-tool']
|
||||
];
|
||||
} else {
|
||||
$res = ['code'=>-1,'msg'=>'未获取到服务器信息'];
|
||||
@ -112,9 +115,11 @@ class Addons extends AdminController
|
||||
|
||||
/**
|
||||
* 编辑版本
|
||||
*
|
||||
* @param int $id
|
||||
* @return \think\Response
|
||||
* @param $id
|
||||
* @return string|Json
|
||||
* @throws \think\db\exception\DataNotFoundException
|
||||
* @throws \think\db\exception\DbException
|
||||
* @throws \think\db\exception\ModelNotFoundException
|
||||
*/
|
||||
public function edit($id)
|
||||
{
|
||||
@ -135,11 +140,8 @@ class Addons extends AdminController
|
||||
}
|
||||
|
||||
/**
|
||||
* 上传版本的zip资源
|
||||
*
|
||||
* @param
|
||||
* @param int $id
|
||||
* @return \think\Response
|
||||
* 上传插件文件zip
|
||||
* @return Json
|
||||
*/
|
||||
public function uploadZip()
|
||||
{
|
||||
@ -148,88 +150,113 @@ class Addons extends AdminController
|
||||
try {
|
||||
validate(['file'=>'filesize:2048|fileExt:zip,rar,7z'])
|
||||
->check(array($file));
|
||||
$savename = \think\facade\Filesystem::disk('public')->putFile('addons',$file);
|
||||
$saveName = \think\facade\Filesystem::disk('public')->putFile('addons',$file);
|
||||
} catch (\think\exception\ValidateException $e) {
|
||||
echo $e->getMessage();
|
||||
return json(['code' => -1,'msg' => $e->getMessage()]);
|
||||
}
|
||||
$upload = Config::get('filesystem.disks.public.url');
|
||||
|
||||
if($savename){
|
||||
$name_path =str_replace('\\',"/",$upload.'/'.$savename);
|
||||
$res = ['code'=>0,'msg'=>'插件上传成功','src'=>$name_path];
|
||||
} else {
|
||||
$res = ['code'=>-1,'msg'=>'上传错误'];
|
||||
}
|
||||
if($saveName){
|
||||
$name_path =str_replace('\\',"/",$upload.'/'.$saveName);
|
||||
$res = ['code'=>0,'msg'=>'插件上传成功','src'=>$name_path];
|
||||
} else {
|
||||
$res = ['code'=>-1,'msg'=>'上传错误'];
|
||||
}
|
||||
return json($res);
|
||||
}
|
||||
|
||||
//安装插件
|
||||
public function install()
|
||||
{
|
||||
$data = Request::param();
|
||||
$data = Request::param();
|
||||
|
||||
$url = $this->getSystem()['api_url'].'/v1/getaddons';
|
||||
$addons = Api::urlPost($url,['name'=>$data['name'],'version'=>$data['version']]);
|
||||
if( $addons->code == -1) {
|
||||
return json(['code'=>$addons->code,'msg'=>$addons->msg]);
|
||||
}
|
||||
//是否安装?
|
||||
$addInstalledVersion = get_addons_info($data['name']);
|
||||
if(!empty($addInstalledVersion)){
|
||||
$verRes = version_compare($data['version'],$addInstalledVersion['version'],'>');
|
||||
if(!$verRes){
|
||||
return json(['code'=>-1,'msg'=>'不能降级,请选择正确版本']);
|
||||
}
|
||||
//$tpl_ver_res = version_compare($addInstalledVersion['template_version'], config('taoler.template_version'),'<');
|
||||
}
|
||||
$addons = Api::urlPost($url,['name'=>$data['name'],'version'=>$data['version']]);
|
||||
if( $addons->code == -1) {
|
||||
return json(['code'=>$addons->code,'msg'=>$addons->msg]);
|
||||
}
|
||||
//是否安装?
|
||||
$addInstalledVersion = get_addons_info($data['name']);
|
||||
// if(!empty($addInstalledVersion)){
|
||||
// $verRes = version_compare($data['version'],$addInstalledVersion['version'],'>');
|
||||
// if(!$verRes){
|
||||
// return json(['code'=>-1,'msg'=>'不能降级,请选择正确版本']);
|
||||
// }
|
||||
// //$tpl_ver_res = version_compare($addInstalledVersion['template_version'], config('taoler.template_version'),'<');
|
||||
// }
|
||||
|
||||
$file_url = $addons->addons_src;
|
||||
//判断远程文件是否可用存在
|
||||
$header = get_headers($file_url, true);
|
||||
if(!isset($header[0]) && (strpos($header[0], '200') || strpos($header[0], '304'))){
|
||||
return json(['code'=>-1,'msg'=>'获取远程文件失败']);
|
||||
$file_url = $addons->addons_src;
|
||||
//判断远程文件是否可用存在
|
||||
$header = get_headers($file_url, true);
|
||||
if(!isset($header[0]) && (strpos($header[0], '200') || strpos($header[0], '304'))){
|
||||
return json(['code'=>-1,'msg'=>'获取远程文件失败']);
|
||||
}
|
||||
|
||||
//把远程文件放入本地
|
||||
|
||||
//拼接路径
|
||||
$addons_dir = Files::getDirPath('../runtime/addons/');
|
||||
Files::mkdirs($addons_dir);
|
||||
|
||||
$package_file = $addons_dir . $data['name'] .'.zip'; //升级的压缩包文件
|
||||
$cpfile = copy($file_url,$package_file);
|
||||
if(!$cpfile) return json(['code'=>-1,'msg'=>'下载升级文件失败']);
|
||||
|
||||
$uzip = new Zip();
|
||||
$zipDir = strstr($package_file, '.zip',true); //返回文件名后缀前的字符串
|
||||
$zipPath = Files::getDirPath($zipDir); //转换为带/的路径 压缩文件解压到的路径
|
||||
$unzip_res = $uzip->unzip($package_file,$zipPath,true);
|
||||
if(!$unzip_res) return json(['code'=>-1,'msg'=>'解压失败']);
|
||||
|
||||
//升级插件
|
||||
|
||||
//升级前的写入文件权限检查
|
||||
$allUpdateFiles = Files::getAllFile($zipPath);
|
||||
|
||||
if (empty($allUpdateFiles)) return json(['code' => -1, 'msg' => '无可更新文件。']);
|
||||
$checkString = '';
|
||||
foreach ($allUpdateFiles as $updateFile) {
|
||||
$coverFile = ltrim(str_replace($zipPath, '', $updateFile), DIRECTORY_SEPARATOR);
|
||||
$dirPath = dirname('../'.$coverFile);
|
||||
if (file_exists('../'.$coverFile)) {
|
||||
if (!is_writable('../'.$coverFile)) $checkString .= $coverFile . ' [<span class="text-red">' . '无写入权限' . '</span>]<br>';
|
||||
} else {
|
||||
if (!is_dir($dirPath)) @mkdir($dirPath, 0777, true);
|
||||
if (!is_writable($dirPath)) $checkString .= $dirPath . ' [<span class="text-red">' . '无写入权限' . '</span>]<br>';
|
||||
}
|
||||
}
|
||||
|
||||
if (!empty($checkString)) return json(['code' => -1, 'msg' => $checkString]);
|
||||
$addonsPath = '../';
|
||||
$cpRes = Files::copyDirs($zipPath,$addonsPath);
|
||||
$cpData = $cpRes->getData();
|
||||
//更新失败
|
||||
if($cpData['code'] == -1) return json(['code'=>-1,'msg'=>$cpData['msg']]);
|
||||
|
||||
//添加数据库
|
||||
$sqlInstallFile = root_path().'addons/'.$data['name'].'/install.sql';
|
||||
if(file_exists($sqlInstallFile)) {
|
||||
SqlFile::dbExecute($sqlInstallFile);
|
||||
}
|
||||
//安装菜单
|
||||
$menuFile = root_path().'addons/'.$data['name'].'/menu.php';
|
||||
if(file_exists($menuFile)) {
|
||||
include_once $menuFile;
|
||||
$menu = Config::get('menu');
|
||||
|
||||
if(!empty($menu)){
|
||||
if(isset($menu['is_nav']) && $menu['is_nav']==1){
|
||||
$pid = 0;
|
||||
}else{
|
||||
$pid = AuthRule::where('name','addons')->value('id');
|
||||
}
|
||||
$menu_arr[] = $menu['menu'];
|
||||
$this->addAddonMenu($menu_arr, (int)$pid,1);
|
||||
}
|
||||
}
|
||||
|
||||
//把远程文件放入本地
|
||||
|
||||
//拼接路径
|
||||
$addons_dir = Files::getDirPath('../runtime/addons/');
|
||||
Files::mkdirs($addons_dir);
|
||||
|
||||
$package_file = $addons_dir . $data['name'] .'.zip'; //升级的压缩包文件
|
||||
$cpfile = copy($file_url,$package_file);
|
||||
if(!$cpfile) return json(['code'=>-1,'msg'=>'下载升级文件失败']);
|
||||
|
||||
$uzip = new Zip();
|
||||
$zipDir = strstr($package_file, '.zip',true); //返回文件名后缀前的字符串
|
||||
$zipPath = Files::getDirPath($zipDir); //转换为带/的路径 压缩文件解压到的路径
|
||||
$unzip_res = $uzip->unzip($package_file,$zipPath,true);
|
||||
if(!$unzip_res) return json(['code'=>-1,'msg'=>'解压失败']);
|
||||
|
||||
|
||||
//升级插件
|
||||
|
||||
//升级前的写入文件权限检查
|
||||
$allUpdateFiles = Files::getAllFile($zipPath);
|
||||
|
||||
if (empty($allUpdateFiles)) return json(['code' => -1, 'msg' => '无可更新文件。']);
|
||||
$checkString = '';
|
||||
foreach ($allUpdateFiles as $updateFile) {
|
||||
$coverFile = ltrim(str_replace($zipPath, '', $updateFile), DIRECTORY_SEPARATOR);
|
||||
$dirPath = dirname('../'.$coverFile);
|
||||
if (file_exists('../'.$coverFile)) {
|
||||
if (!is_writable('../'.$coverFile)) $checkString .= $coverFile . ' [<span class="text-red">' . '无写入权限' . '</span>]<br>';
|
||||
} else {
|
||||
if (!is_dir($dirPath)) @mkdir($dirPath, 0777, true);
|
||||
if (!is_writable($dirPath)) $checkString .= $dirPath . ' [<span class="text-red">' . '无写入权限' . '</span>]<br>';
|
||||
}
|
||||
}
|
||||
|
||||
if (!empty($checkString)) return json(['code' => -1, 'msg' => $checkString]);
|
||||
$addonsPath = '../';
|
||||
$cpRes = Files::copyDirs($zipPath,$addonsPath);
|
||||
$cpData = $cpRes->getData();
|
||||
//更新失败
|
||||
if($cpData['code'] == -1) return json(['code'=>-1,'msg'=>$cpData['msg']]);
|
||||
Files::delDirAndFile('../runtime/addons/');
|
||||
|
||||
return json(['code'=>0,'msg'=>'插件安装成功!']);
|
||||
@ -244,6 +271,23 @@ class Addons extends AdminController
|
||||
$addonsPath = '../addons/'.$name;
|
||||
$staticPath = 'addons/'.$name;
|
||||
|
||||
//卸载菜单
|
||||
$menuFile = root_path().'addons/'.$name.'/menu.php';
|
||||
if(file_exists($menuFile)) {
|
||||
include_once $menuFile;
|
||||
$menu = Config::get('menu');
|
||||
if(!empty($menu)){
|
||||
$menu_arr[] = $menu['menu'];
|
||||
$this->delAddonMenu($menu_arr);
|
||||
}
|
||||
}
|
||||
|
||||
//卸载插件数据库
|
||||
$sqlUninstallFile = root_path().'addons/'.$name.'/uninstall.sql';
|
||||
if(file_exists($sqlUninstallFile)) {
|
||||
SqlFile::dbExecute($sqlUninstallFile);
|
||||
}
|
||||
|
||||
if (is_dir($staticPath)) {
|
||||
Files::delDir($staticPath);
|
||||
}
|
||||
@ -253,6 +297,7 @@ class Addons extends AdminController
|
||||
} else {
|
||||
return json(['code'=>-1,'msg'=>'卸载失败']);
|
||||
}
|
||||
return json(['code'=>0,'msg'=>'卸载成功']);
|
||||
}
|
||||
|
||||
//启用插件
|
||||
@ -317,4 +362,52 @@ class Addons extends AdminController
|
||||
return View::fetch();
|
||||
|
||||
}
|
||||
|
||||
public function addAddonMenu(array $menu,int $pid = 0, int $type = 1)
|
||||
{
|
||||
foreach ($menu as $v){
|
||||
$hasChild = isset($v['sublist']) && $v['sublist'] ? true : false;
|
||||
try {
|
||||
$v['pid'] = $pid;
|
||||
$v['name'] = trim($v['name'],'/');
|
||||
$v['type'] = $type;
|
||||
$menu = AuthRule::withTrashed()->where('name',$v['name'])->find();
|
||||
if($menu){
|
||||
$menu->restore();
|
||||
} else {
|
||||
$menu = AuthRule::create($v);
|
||||
}
|
||||
|
||||
if ($hasChild) {
|
||||
$this->addAddonMenu($v['sublist'], $menu->id,$type);
|
||||
}
|
||||
} catch (\Exception $e) {
|
||||
throw new \Exception($e->getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
//循环删除菜单
|
||||
public function delAddonMenu(array $menu,string $module = 'addon')
|
||||
{
|
||||
foreach ($menu as $k=>$v){
|
||||
$hasChild = isset($v['sublist']) && $v['sublist'] ? true : false;
|
||||
try {
|
||||
$v['name'] = trim($v['name'],'/');
|
||||
$menu_rule = AuthRule::withTrashed()->where('name',$v['name'])->find();
|
||||
if($menu_rule){
|
||||
$menu_rule->delete(true);
|
||||
if ($hasChild) {
|
||||
$this->delAddonMenu($v['sublist']);
|
||||
}
|
||||
}
|
||||
|
||||
} catch (\Exception $e) {
|
||||
throw new \Exception($e->getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -2,6 +2,7 @@
|
||||
namespace app\admin\controller;
|
||||
|
||||
use app\common\controller\AdminController;
|
||||
use think\App;
|
||||
use think\facade\Request;
|
||||
use think\facade\Db;
|
||||
use think\facade\View;
|
||||
@ -9,27 +10,20 @@ use app\admin\model\AuthRule as AuthRuleModel;
|
||||
|
||||
class AuthRule extends AdminController
|
||||
{
|
||||
//
|
||||
public function __construct(App $app)
|
||||
{
|
||||
parent::__construct($app);
|
||||
$this->model = new AuthRuleModel();
|
||||
}
|
||||
|
||||
/**
|
||||
* 菜单列表
|
||||
*/
|
||||
public function index()
|
||||
{
|
||||
if(Request::isAjax()){
|
||||
|
||||
$rule = new AuthRuleModel();
|
||||
$auth_rules = $rule->authRuleTree();
|
||||
$count = count($auth_rules);
|
||||
$res = [];
|
||||
if($auth_rules){
|
||||
$res = ['code'=>0,'msg'=>'ok','count'=>$count];
|
||||
|
||||
foreach($auth_rules as $k => $v){
|
||||
//$data = $v->getData();
|
||||
$data = ['id'=>$v['id'],'pid'=>$v['pid'],'title'=>$v['title'],'url'=>$v['name'],'icon'=>$v['icon'],'status'=>$v['status'],'isMenu'=>$v['ishidden'],'sort'=>$v['sort'],'ctime'=>$v['create_time']];
|
||||
$res['data'][] = $data;
|
||||
}
|
||||
}
|
||||
return json($res);
|
||||
return $this->model->getAuthRuleTree();
|
||||
}
|
||||
return View::fetch();
|
||||
|
||||
@ -88,24 +82,19 @@ class AuthRule extends AdminController
|
||||
{
|
||||
if(Request::isAjax()){
|
||||
$data = Request::param();
|
||||
$plevel = Db::name('auth_rule')->field('level')->find($data['pid']);
|
||||
|
||||
//层级level
|
||||
$plevel = Db::name('auth_rule')->field('level')->find($data['pid']);
|
||||
if($plevel){
|
||||
$data['level'] = $plevel['level']+1;
|
||||
} else {
|
||||
$data['level'] = 0;
|
||||
}
|
||||
$data['create_time'] = time();
|
||||
$list = Db::name('auth_rule')->save($data);
|
||||
|
||||
if($list){
|
||||
return json(['code'=>0,'msg'=>'添加权限成功']);
|
||||
}else{
|
||||
return json(['code'=>-1,'msg'=>'添加权限失败']);
|
||||
}
|
||||
|
||||
return $this->model->saveRule($data);
|
||||
}
|
||||
|
||||
$rule = new AuthRuleModel();
|
||||
$auth_rules = $rule->authRuleTree();
|
||||
|
||||
$auth_rules = $this->model->getAuthRuleTree();
|
||||
View::assign('AuthRule',$auth_rules);
|
||||
return View::fetch();
|
||||
}
|
||||
@ -116,33 +105,27 @@ class AuthRule extends AdminController
|
||||
$rule = new AuthRuleModel();
|
||||
|
||||
if(Request::isAjax()){
|
||||
$data = Request::param(['id','pid','title','name','icon','sort','ishidden']);
|
||||
$ruId = $rule->find($data['pid']); //查询出上级ID
|
||||
$data = Request::param(['id','pid','title','name','icon','sort','ismenu']);
|
||||
//层级level
|
||||
$ruId = $rule->find($data['pid']); //查询出上级ID
|
||||
if($ruId){
|
||||
$plevel = $ruId->level; //上级level等级
|
||||
$data['level'] = $plevel+1;
|
||||
} else {
|
||||
$data['level'] = 0;
|
||||
}
|
||||
|
||||
$zi = $rule->where('pid',$data['id'])->select();//查询出下级
|
||||
$zi = $this->model->where('pid',$data['id'])->select();//查询出下级
|
||||
if(!empty($zi)){
|
||||
$zi->update(['level'=>$data['level']+1]);
|
||||
}
|
||||
|
||||
if($zi){
|
||||
$zi->update(['level'=>$data['level']+1]);
|
||||
}
|
||||
|
||||
$save = AuthRuleModel::update($data);
|
||||
|
||||
if($save){
|
||||
$res = ['code'=>0,'msg'=>'修改成功'];
|
||||
} else {
|
||||
$res = ['code'=>-1,'msg'=>'修改失败'];
|
||||
}
|
||||
return json($res);
|
||||
$rule = $this->model->find($data['id']);
|
||||
return $rule->saveRule($data);
|
||||
}
|
||||
|
||||
$auth_rules = $rule->authRuleTree();
|
||||
$rules = $rule->find(input('id'));
|
||||
$auth_rules = $this->model->getAuthRuleTree();
|
||||
$rules = $this->model->find(input('id'));
|
||||
|
||||
View::assign(['AuthRule'=>$auth_rules,'rules'=>$rules]);
|
||||
return View::fetch();
|
||||
}
|
||||
@ -174,7 +157,7 @@ class AuthRule extends AdminController
|
||||
$data = Request::param();
|
||||
$rules = Db::name('auth_rule')->save($data);
|
||||
if($rules){
|
||||
if($data['ishidden'] == 1){
|
||||
if($data['ismenu'] == 1){
|
||||
return json(['code'=>0,'msg'=>'设置菜单显示','icon'=>6]);
|
||||
} else {
|
||||
return json(['code'=>0,'msg'=>'取消菜单显示','icon'=>5]);
|
||||
|
@ -12,6 +12,7 @@ use think\facade\Db;
|
||||
use think\facade\Cache;
|
||||
use taoler\com\Files;
|
||||
use app\common\lib\Msgres;
|
||||
use think\response\Json;
|
||||
|
||||
class Forum extends AdminController
|
||||
{
|
||||
@ -103,7 +104,7 @@ class Forum extends AdminController
|
||||
if(Request::isAjax()){
|
||||
$arr = explode(",",$id);
|
||||
foreach($arr as $v){
|
||||
$article =Article::find($v);
|
||||
$article = Article::find($v);
|
||||
$result = $article->together(['comments'])->delete();
|
||||
}
|
||||
|
||||
@ -118,7 +119,7 @@ class Forum extends AdminController
|
||||
/**
|
||||
* 置顶、加精、评论开关,审核等状态管理
|
||||
*
|
||||
* @return void
|
||||
* @return Json
|
||||
*/
|
||||
public function check()
|
||||
{
|
||||
@ -137,18 +138,9 @@ class Forum extends AdminController
|
||||
//帖子分类
|
||||
public function tags()
|
||||
{
|
||||
$cate = new Cate();
|
||||
if(Request::isAjax()){
|
||||
$list = Cate::select();
|
||||
if($list){
|
||||
$res['code'] = 0;
|
||||
$res['msg'] = '';
|
||||
$res['count']= count($list);
|
||||
$res['data'] = [];
|
||||
foreach($list as $k=>$v){
|
||||
$res['data'][] = ['sort'=>$v['sort'],'id' => $v['id'],'pid'=>$v['pid'],'tags'=>$v['catename'],'ename'=>$v['ename'],'detpl'=>$v['detpl'],'icon'=>$v['icon'],'is_hot'=>$v['is_hot'],'desc'=>$v['desc']];
|
||||
}
|
||||
}
|
||||
return json($res);
|
||||
return $cate->getList();
|
||||
}
|
||||
//详情模板
|
||||
$sys = $this->getSystem();
|
||||
@ -482,20 +474,19 @@ class Forum extends AdminController
|
||||
/**
|
||||
* 调用百度关键词
|
||||
*
|
||||
* @return void
|
||||
* @return json
|
||||
*/
|
||||
public function getKeywords()
|
||||
{
|
||||
$data = Request::only(['tags','flag']);
|
||||
$data = Request::only(['flag','keywords','content']);
|
||||
return $this->setKeywords($data);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* 标题调用百度关键词词条
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
/**
|
||||
* 标题调用百度关键词词条
|
||||
* @return Json
|
||||
*/
|
||||
public function getWordList()
|
||||
{
|
||||
$title = input('title');
|
||||
@ -507,7 +498,8 @@ class Forum extends AdminController
|
||||
* 内容中是否有图片视频音频插入
|
||||
*
|
||||
* @param [type] $content
|
||||
* @return boolean
|
||||
* @return array
|
||||
*
|
||||
*/
|
||||
public function hasIva($content)
|
||||
{
|
||||
|
@ -44,7 +44,7 @@ class Slider extends AdminController
|
||||
}
|
||||
|
||||
if(count($datas)) {
|
||||
$list = ['code'=>0,'msg'=>'获取数据成功'];
|
||||
$list = ['code'=>0, 'count'=> count($datas), 'msg'=>'获取数据成功'];
|
||||
foreach($datas as $k=>$v) {
|
||||
$list['data'][] = [
|
||||
'id'=>$v['id'],
|
||||
|
@ -168,9 +168,7 @@ class Upgrade extends AdminController
|
||||
|
||||
$package_file = $upload_dir.'taoler_'.$version_num.'.zip'; //升级的压缩包文件
|
||||
$cpfile = copy($file_url,$package_file);
|
||||
|
||||
if(!$cpfile)
|
||||
{
|
||||
if(!$cpfile) {
|
||||
return json(['code'=>-1,'msg'=>'下载升级文件失败']);
|
||||
}
|
||||
//记录下日志
|
||||
@ -236,15 +234,12 @@ class Upgrade extends AdminController
|
||||
private function execute_update(string $package_file)
|
||||
{
|
||||
//解压 zip文件有密码的话需要解密
|
||||
//$uzip = new ZipFile();
|
||||
$zip = new Zip;
|
||||
$zipDir = strstr($package_file, '.zip',true); //返回文件名后缀前的字符串
|
||||
$zipPath = Files::getDirPath($zipDir); //转换为带/的路径 压缩文件解压到的路径
|
||||
//$unzip_res = $uzip->unzip($package_file,$zipPath,true);
|
||||
$unzip_res = $zip->unzip($package_file,$zipPath);
|
||||
|
||||
if(!$unzip_res)
|
||||
{
|
||||
if(!$unzip_res) {
|
||||
return json(['code'=>-1,'msg'=>'解压失败']);
|
||||
}
|
||||
//解压成功,得到文件夹
|
||||
@ -253,8 +248,7 @@ class Upgrade extends AdminController
|
||||
Log::channel('update')->info('update:{type} {progress} {msg}',['type'=>'success','progress'=>'50%','msg'=>'升级文件解压成功!']);
|
||||
|
||||
//升级PHP
|
||||
if(is_dir($zipPath))
|
||||
{
|
||||
if(is_dir($zipPath)) {
|
||||
//升级前的写入文件权限检查
|
||||
$allUpdateFiles = Files::getAllFile($zipPath);
|
||||
|
||||
@ -276,8 +270,7 @@ class Upgrade extends AdminController
|
||||
$cpRes = Files::copyDirs($zipPath,$this->root_dir);
|
||||
$cpData = $cpRes->getData();
|
||||
//更新失败
|
||||
if($cpData['code'] == -1)
|
||||
{
|
||||
if($cpData['code'] == -1) {
|
||||
//数据库回滚
|
||||
/*
|
||||
if(file_exists($this->upload_dir.'/'.$package_file.'/mysql/mysql_rockback.sql'))
|
||||
@ -297,13 +290,8 @@ class Upgrade extends AdminController
|
||||
|
||||
//升级sql操作
|
||||
$upSql = $zipPath.'runtime/update.sql';
|
||||
if(file_exists($upSql))
|
||||
{
|
||||
$sqlRes = $this->db_update($upSql);
|
||||
$upDate = $sqlRes->getData();
|
||||
if($upDate['code'] == -1){
|
||||
return json(['code'=>-1,'msg'=>$upDate['msg']]);
|
||||
}
|
||||
if(file_exists($upSql)) {
|
||||
SqlFile::dbExecute($upSql);
|
||||
//删除sql语句
|
||||
unlink($upSql);
|
||||
}
|
||||
@ -317,7 +305,7 @@ class Upgrade extends AdminController
|
||||
}
|
||||
|
||||
/**
|
||||
* 处理升级包上传
|
||||
* 手动处理升级包上传
|
||||
*/
|
||||
public function uploadZip()
|
||||
{
|
||||
@ -373,36 +361,4 @@ class Upgrade extends AdminController
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 数据库操作
|
||||
*/
|
||||
public function database_operation($file)
|
||||
{
|
||||
$mysqli = new \mysqli('localhost','root','root','test');
|
||||
if($mysqli->connect_errno)
|
||||
{
|
||||
return json(['code'=>0,'msg'=>'Connect failed:'.$mysqli->connect_error]);
|
||||
}
|
||||
$sql = file_get_contents($file);
|
||||
$a = $mysqli->multi_query($sql);
|
||||
return ['code'=>1,'msg'=>'数据库操作OK'];
|
||||
}
|
||||
|
||||
/**
|
||||
* 执行数据库操作
|
||||
*/
|
||||
public function db_update($file)
|
||||
{
|
||||
$sqlf = new SqlFile();
|
||||
$sql_array = $sqlf->load_sql_file($file);
|
||||
foreach($sql_array as $v){
|
||||
$sqlRes = Db::execute($v);
|
||||
if ($sqlRes === false) {
|
||||
return json(['code'=>-1,'msg'=>'数据库升级失败']);
|
||||
}
|
||||
}
|
||||
return json(['code'=>0,'msg'=>'数据库升级成功']);
|
||||
}
|
||||
|
||||
|
||||
}
|
@ -16,29 +16,36 @@ class AuthRule extends Model
|
||||
{
|
||||
$query->where('id', $value );
|
||||
}
|
||||
/**
|
||||
* 权限树
|
||||
*/
|
||||
public function authRuleTree()
|
||||
|
||||
/**
|
||||
* 获取权限列表
|
||||
* @return \think\response\Json
|
||||
* @throws \think\db\exception\DataNotFoundException
|
||||
* @throws \think\db\exception\DbException
|
||||
* @throws \think\db\exception\ModelNotFoundException
|
||||
*/
|
||||
public function getAuthRuleTree()
|
||||
{
|
||||
$authRules = $this->order('sort asc')->select();
|
||||
//return $this->sort($authRules);
|
||||
return $authRules;
|
||||
}
|
||||
/**
|
||||
* id,pid,菜单排序
|
||||
* @var $data 数据
|
||||
* @var $pid 父级id
|
||||
*/
|
||||
public function sort($data,$pid=0)
|
||||
{
|
||||
static $arr = array();
|
||||
foreach($data as $k=> $v){
|
||||
if($v['pid']==$pid){
|
||||
$arr[] = $v;
|
||||
$this->sort($data,$v['id']);
|
||||
}
|
||||
}
|
||||
return $arr;
|
||||
}
|
||||
$authRules = $this->field('id,pid,title,name,icon,status,ismenu,sort,create_time')->select()->toArray();
|
||||
//数组排序
|
||||
$cmf_arr = array_column($authRules, 'sort');
|
||||
array_multisort($cmf_arr, SORT_ASC, $authRules);
|
||||
|
||||
if(count($authRules)) {
|
||||
return json(['code'=>0,'msg'=>'ok','data'=>$authRules]);
|
||||
} else {
|
||||
return json(['code'=>0,'msg'=>'no data','data'=>'']);
|
||||
}
|
||||
}
|
||||
|
||||
public function saveRule($data)
|
||||
{
|
||||
$res = $this->save($data);
|
||||
if($res){
|
||||
return json(['code'=>0,'msg'=>'添加权限成功']);
|
||||
}else{
|
||||
return json(['code'=>-1,'msg'=>'添加权限失败']);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -38,9 +38,9 @@
|
||||
<div class="layui-form-item">
|
||||
<label class="layui-form-label">类型</label>
|
||||
<div class="layui-input-block">
|
||||
<input type="radio" name="ishidden" lay-skin="primary" title="目录" value="-1">
|
||||
<input type="radio" name="ishidden" lay-skin="primary" title="菜单" value="1" checked>
|
||||
<input type="radio" name="ishidden" lay-skin="primary" title="按钮" value="0">
|
||||
<input type="radio" name="ismenu" lay-skin="primary" title="目录" value="0">
|
||||
<input type="radio" name="ismenu" lay-skin="primary" title="菜单" value="1" checked>
|
||||
<input type="radio" name="ismenu" lay-skin="primary" title="按钮" value="2">
|
||||
</div>
|
||||
</div>
|
||||
<div class="layui-form-item layui-hide">
|
||||
|
@ -39,9 +39,9 @@
|
||||
<div class="layui-form-item">
|
||||
<label class="layui-form-label">类型</label>
|
||||
<div class="layui-input-block">
|
||||
<input type="radio" name="ishidden" lay-skin="primary" title="目录" value="-1" {if condition="$rules.ishidden == -1"} checked {/if}>
|
||||
<input type="radio" name="ishidden" lay-skin="primary" title="菜单" value="1" {if condition="$rules.ishidden == 1"} checked {/if}>
|
||||
<input type="radio" name="ishidden" lay-skin="primary" title="按钮" value="0" {if condition="$rules.ishidden == 0"} checked {/if}>
|
||||
<input type="radio" name="ismenu" lay-skin="primary" title="目录" value="0" {if condition="$rules.ismenu == 0"} checked {/if}>
|
||||
<input type="radio" name="ismenu" lay-skin="primary" title="菜单" value="1" {if condition="$rules.ismenu == 1"} checked {/if}>
|
||||
<input type="radio" name="ismenu" lay-skin="primary" title="按钮" value="2" {if condition="$rules.ismenu == 2"} checked {/if}>
|
||||
</div>
|
||||
</div>
|
||||
<div class="layui-form-item layui-hide">
|
||||
|
@ -51,8 +51,8 @@
|
||||
defaultToolbar: ['filter', 'print', 'exports'],
|
||||
cols: [
|
||||
[
|
||||
{type: 'numbers'},
|
||||
{type: 'checkbox'},
|
||||
{field: 'id', title: 'ID',width: 40},
|
||||
{field: 'title', title: '菜单名称', minWidth: 165},
|
||||
{field: 'url', title: '菜单地址', rowspan: 2},
|
||||
{
|
||||
@ -60,10 +60,10 @@
|
||||
templet: '<p><i class="layui-icon {{d.icon}}"></i></p>'
|
||||
},
|
||||
{field: 'authority', title: '权限标识'},
|
||||
{field: 'isMenu', title: '类型', templet: type, align: 'center', width: 60},
|
||||
//{title: '类型', templet: '<p>{{d.isMenu ? "菜单" : "按钮"}}</p>', align: 'center', width: 60},
|
||||
{field: 'ismenu', title: '类型', templet: type, align: 'center', width: 60},
|
||||
// {title: '类型', templet: '<p>{{d.ismenu ? "菜单" : "按钮"}}</p>', align: 'center', width: 60},
|
||||
{field: 'sort', title: '排序', align: 'center', width: 60},
|
||||
{field: 'ctime',title: '创建时间'},
|
||||
{field: 'create_time',title: '创建时间'},
|
||||
{align: 'center', toolbar: '#tbBar', title: '操作', width: 120}
|
||||
]
|
||||
],
|
||||
@ -72,7 +72,7 @@
|
||||
|
||||
//自定义“状态”列
|
||||
function type(data) {
|
||||
var isMenu = data.isMenu;
|
||||
var isMenu = data.ismenu;
|
||||
var btns = "";
|
||||
if (isMenu == -1) {
|
||||
return "目录";
|
||||
@ -149,7 +149,7 @@
|
||||
$.ajax({
|
||||
type:"post",
|
||||
url:"{:url('AuthRule/edit')}",
|
||||
data:{"id":field.id,"pid":field.pid,"title":field.title,"name":field.name,"icon":field.icon,"sort":field.sort,"ishidden":field.ishidden},
|
||||
data: field,
|
||||
daType:"json",
|
||||
success:function (res){
|
||||
if (res.code == 0) {
|
||||
@ -207,7 +207,7 @@
|
||||
$.ajax({
|
||||
type:"post",
|
||||
url:"{:url('AuthRule/add')}",
|
||||
data:{"pid":field.pid,"title":field.title,"name":field.name,"icon":field.icon,"sort":field.sort,"ishidden":field.ishidden},
|
||||
data: field,
|
||||
daType:"json",
|
||||
success:function (data){
|
||||
if (data.code == 0) {
|
||||
|
@ -109,6 +109,9 @@ layui.config({
|
||||
upload = layui.upload;
|
||||
var editor = layui.editor;
|
||||
|
||||
//获取百度标签标志,tag或者word;
|
||||
var flag = 'word';
|
||||
|
||||
//如果你是采用模版自带的编辑器,你需要开启以下语句来解析。
|
||||
var taonystatus = "{:hook('taonystatus')}";
|
||||
// 编辑器插件启用状态
|
||||
@ -160,15 +163,15 @@ layui.config({
|
||||
if (conf !== "1") {
|
||||
$("#L_title").on("blur", function () {
|
||||
var title = $(this).val();
|
||||
var flag = "on";
|
||||
var content = $("#L_content").val();
|
||||
$.ajax({
|
||||
type: "post",
|
||||
url: "{:url('Forum/getKeywords')}",
|
||||
data: { keywords: keywords, flag: flag },
|
||||
data: { keywords: title, content:content, flag: flag },
|
||||
daType: "json",
|
||||
success: function (data) {
|
||||
if (data.code == 0) {
|
||||
$("input[name='tags']").val(data.data);
|
||||
$("input[name='keywords']").val(data.data.join(','));
|
||||
}
|
||||
},
|
||||
});
|
||||
|
@ -95,7 +95,7 @@ overflow: visible;
|
||||
[
|
||||
{type: 'numbers'},
|
||||
{type: 'checkbox'}
|
||||
,{field: 'tags', title: '分类名', minWidth: 200}
|
||||
,{field: 'catename', title: '分类名', minWidth: 200}
|
||||
,{field: 'ename', title: 'EN别名', width: 100}
|
||||
,{field: 'detpl',title: '模板', align: 'center',width: 100,templet: '#inputSel'}
|
||||
,{title: '图标', align: 'center',width: 50,templet: '<p><i class="layui-icon {{d.icon}}"></i></p>'}
|
||||
@ -136,25 +136,25 @@ overflow: visible;
|
||||
type: 2
|
||||
,title: '编辑分类'
|
||||
,content: forumTagsForm + '?id='+ data.id
|
||||
,area: ['400px', '450px']
|
||||
,area: ['400px', '500px']
|
||||
,btn: ['确定', '取消']
|
||||
,yes: function(index, layero){
|
||||
//获取iframe元素的值
|
||||
var othis = layero.find('iframe').contents().find("#layuiadmin-app-form-tags")
|
||||
,pid = othis.find('input[name="pid"]').val()
|
||||
,sort = othis.find('input[name="sort"]').val()
|
||||
,tags = othis.find('input[name="tags"]').val()
|
||||
,catename = othis.find('input[name="catename"]').val()
|
||||
,ename = othis.find('input[name="ename"]').val()
|
||||
,detpl = othis.find('select[name="detpl"]').val()
|
||||
,icon = othis.find('input[name="icon"]').val()
|
||||
,desc = othis.find('input[name="desc"]').val();
|
||||
|
||||
if(!tags.replace(/\s/g, '')) return;
|
||||
if(!catename.replace(/\s/g, '')) return;
|
||||
|
||||
$.ajax({
|
||||
type:"post",
|
||||
url:forumTagsForm,
|
||||
data:{"id":data.id,"pid":pid,"sort":sort,"catename":tags,"ename":ename,"detpl":detpl,"icon":icon,"desc":desc},
|
||||
data:{"id":data.id,"pid":pid,"sort":sort,"catename":catename,"ename":ename,"detpl":detpl,"icon":icon,"desc":desc},
|
||||
daType:"json",
|
||||
success:function (data){
|
||||
if(data.code == 0){layer.msg(data.msg,{icon:6,time:2000},function(){
|
||||
@ -180,7 +180,7 @@ overflow: visible;
|
||||
var othis = layero.find('iframe').contents().find("#layuiadmin-app-form-tags").click();
|
||||
othis.find('input[name="pid"]').val(data.pid)
|
||||
,othis.find('input[name="sort"]').val(data.sort)
|
||||
,othis.find('input[name="tags"]').val(data.tags)
|
||||
,othis.find('input[name="catename"]').val(data.catename)
|
||||
,othis.find('input[name="ename"]').val(data.ename)
|
||||
,othis.find('input[name="icon"]').val(data.icon)
|
||||
,othis.find('input[name="desc"]').val(data.desc);
|
||||
@ -201,20 +201,20 @@ overflow: visible;
|
||||
,btn: ['确定', '取消']
|
||||
,yes: function(index, layero){
|
||||
var othis = layero.find('iframe').contents().find("#layuiadmin-app-form-tags")
|
||||
,pid = othis.find('input[name="pid"]').val()
|
||||
,sort = othis.find('input[name="sort"]').val()
|
||||
,tags = othis.find('input[name="tags"]').val()
|
||||
,ename = othis.find('input[name="ename"]').val()
|
||||
,detpl = othis.find('select[name="detpl"]').val()
|
||||
,icon = othis.find('input[name="icon"]').val()
|
||||
,desc = othis.find('input[name="desc"]').val();
|
||||
,pid = othis.find('input[name="pid"]').val()
|
||||
,sort = othis.find('input[name="sort"]').val()
|
||||
,catename = othis.find('input[name="catename"]').val()
|
||||
,ename = othis.find('input[name="ename"]').val()
|
||||
,detpl = othis.find('select[name="detpl"]').val()
|
||||
,icon = othis.find('input[name="icon"]').val()
|
||||
,desc = othis.find('input[name="desc"]').val();
|
||||
|
||||
if(!tags.replace(/\s/g, '')) return;
|
||||
if(!catename.replace(/\s/g, '')) return;
|
||||
|
||||
$.ajax({
|
||||
type:"post",
|
||||
url:"{:url('Forum/tagsform')}",
|
||||
data:{pid:pid,"sort":sort,"catename":tags,"ename":ename,"detpl":detpl,"icon":icon,"desc":desc},
|
||||
data:{pid:pid,"sort":sort,"catename":catename,"ename":ename,"detpl":detpl,"icon":icon,"desc":desc},
|
||||
daType:"json",
|
||||
success:function (data){
|
||||
if (data.code == 0) {
|
||||
|
@ -12,7 +12,7 @@
|
||||
<div class="layui-form-item">
|
||||
<label class="layui-form-label">分类名</label>
|
||||
<div class="layui-input-inline">
|
||||
<input type="text" name="tags" lay-verify="required" placeholder="分类名*" autocomplete="off" class="layui-input">
|
||||
<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">
|
||||
|
@ -74,7 +74,7 @@
|
||||
,{field: 'slid_href', title: 'URL', minWidth: 250}
|
||||
,{field: 'slid_color', title: '颜色', width: 80}
|
||||
,{field: 'slid_start', title: '开始', width: 150, sort: true}
|
||||
,{field: 'slid_over', title: '结束', width: 150, sort: true}
|
||||
,{field: 'slid_over', title: '结束','escape':false, width: 150, sort: true}
|
||||
,{field: 'slid_status', title: '状态', width: 80}
|
||||
,{fixed: 'right', title:'操作', toolbar: '#barDemo', width:150}
|
||||
]]
|
||||
|
@ -7,6 +7,8 @@ use think\facade\Db;
|
||||
use think\facade\Session;
|
||||
use taoser\think\Auth;
|
||||
|
||||
define('DS', DIRECTORY_SEPARATOR);
|
||||
|
||||
// 应用公共文件
|
||||
function mailto($to,$title,$content)
|
||||
{
|
||||
@ -210,21 +212,24 @@ function array_child_append($parent, $pid, $child, $child_key_name)
|
||||
return $parent;
|
||||
}
|
||||
|
||||
|
||||
//菜单递归
|
||||
function getTree($data)
|
||||
//菜单无限极分类
|
||||
function getTree($data, $pId='0')
|
||||
{
|
||||
$tree = [];
|
||||
foreach ($data as $array) {
|
||||
|
||||
if(isset($data[$array['pid']])) {
|
||||
$data[$array['pid']]['children'][] = &$data[$array['id']];
|
||||
//$tree = $data;
|
||||
} else {
|
||||
$tree[] = &$data[$array['id']];
|
||||
}
|
||||
}
|
||||
return $tree;
|
||||
// 递归
|
||||
$tree = [];
|
||||
foreach ($data as $k => $v) {
|
||||
if ($v['pid'] == $pId) {
|
||||
$child = getTree($data, $v['id']);
|
||||
if(!empty($child)) {
|
||||
$v['children'] = $child;
|
||||
}
|
||||
$tree[] = $v;
|
||||
}
|
||||
}
|
||||
// 排序
|
||||
$cmf_arr = array_column($tree, 'sort');
|
||||
array_multisort($cmf_arr, SORT_ASC, $tree);
|
||||
return $tree;
|
||||
}
|
||||
|
||||
//按钮权限检查
|
||||
@ -299,4 +304,5 @@ function find_spider(){
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -45,8 +45,7 @@ class AdminController extends \app\BaseController
|
||||
$admin_id = $this->aid;
|
||||
$auth = new Auth();
|
||||
|
||||
$auth_rule_list = Db::name('auth_rule')->where('delete_time',0)->where(['status'=> 1,'ishidden'=>1])->order(['sort' => 'asc'])->select();
|
||||
//var_export($auth_rule_list);
|
||||
$auth_rule_list = Db::name('auth_rule')->where(['delete_time'=> 0,'status'=> 1,'ismenu'=>1])->select();
|
||||
|
||||
foreach ($auth_rule_list as $value) {
|
||||
if ($auth->check($value['name'], $admin_id) || $admin_id == 1) {
|
||||
@ -64,7 +63,7 @@ class AdminController extends \app\BaseController
|
||||
}
|
||||
}
|
||||
|
||||
$menu = !empty($menu) ? array2tree($menu) : [];
|
||||
$menu = !empty($menu) ? getTree($menu) : [];
|
||||
View::assign('menu', $menu);
|
||||
}
|
||||
|
||||
@ -75,13 +74,13 @@ class AdminController extends \app\BaseController
|
||||
protected function getMenus($type)
|
||||
{
|
||||
$menu = [];
|
||||
$auth_rule_list = Db::name('auth_rule')->where(['delete_time'=> 0, 'status'=> 1,'type'=> $type])->order(['sort' => 'ASC', 'id' => 'ASC'])->select();
|
||||
$auth_rule_list = Db::name('auth_rule')->where(['delete_time'=> 0, 'status'=> 1,'type'=> $type])->select();
|
||||
//var_export($auth_rule_list);
|
||||
|
||||
foreach ($auth_rule_list as $value) {
|
||||
$menu[] = $value;
|
||||
}
|
||||
$menus = !empty($menu) ? array2tree($menu) : [];
|
||||
$menus = !empty($menu) ? getTree($menu) : [];
|
||||
//$menu2 = getTree($menu);
|
||||
return $menus;
|
||||
//return View::assign('menus', $menus);
|
||||
|
@ -67,12 +67,8 @@ class BaseController extends BaseCtrl
|
||||
protected function showNav()
|
||||
{
|
||||
//1.查询分类表获取所有分类
|
||||
$cateList = Db::name('cate')->where(['status'=>1,'delete_time'=>0])->order(['id' => 'ASC','sort' => 'ASC'])->cache('catename',3600)->select()->toArray();
|
||||
$cateList = array2tree($cateList);
|
||||
// $cateList = getTree($cateList);
|
||||
|
||||
return $cateList;
|
||||
|
||||
$cateList = Db::name('cate')->where(['status'=>1,'delete_time'=>0])->cache('catename',3600)->select()->toArray();
|
||||
return getTree($cateList);
|
||||
}
|
||||
|
||||
// 显示子导航subnav
|
||||
@ -86,7 +82,7 @@ class BaseController extends BaseCtrl
|
||||
$subCateList = $this->showNav();
|
||||
} else { // 点击分类,获取子分类信息
|
||||
$parentId = $pCate['id'];
|
||||
$subCate = Db::name('cate')->field('id,ename,catename,is_hot,pid')->where(['pid'=>$parentId,'status'=>1,'delete_time'=>0])->order(['id' => 'ASC','sort' => 'ASC'])->select()->toArray();
|
||||
$subCate = Db::name('cate')->field('id,ename,catename,is_hot,pid')->where(['pid'=>$parentId,'status'=>1,'delete_time'=>0])->select()->toArray();
|
||||
if(!empty($subCate)) { // 有子分类
|
||||
$subCateList = array2tree($subCate);
|
||||
} else { //无子分类
|
||||
|
@ -13,21 +13,22 @@ declare (strict_types = 1);
|
||||
namespace app\common\lib;
|
||||
|
||||
use think\facade\Lang;
|
||||
use think\facade\Db;
|
||||
|
||||
class SqlFile
|
||||
{
|
||||
|
||||
protected static $path = null;
|
||||
|
||||
/**
|
||||
* 加载sql文件为分号分割的数组
|
||||
* <br />支持存储过程和函数提取,自动过滤注释
|
||||
* <br />例如: var_export(load_sql_file('mysql_routing_example/fn_cdr_parse_accountcode.sql'));
|
||||
* @param string $path 文件路径
|
||||
* @return boolean|array
|
||||
* @since 1.0 <2015-5-27> SoChishun Added.
|
||||
* @return array
|
||||
*/
|
||||
public function load_sql_file($path, $fn_splitor = ';;') {
|
||||
if (!file_exists($path)) {
|
||||
return false;
|
||||
}
|
||||
public static function loadSqlFile(string $path, $fn_splitor = ';;') : array
|
||||
{
|
||||
$lines = file($path, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES);
|
||||
$aout = [];
|
||||
$str = '';
|
||||
@ -72,4 +73,26 @@ class SqlFile
|
||||
}
|
||||
return $aout;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $sqlFile
|
||||
* @return bool|void
|
||||
* @throws \Exception
|
||||
*/
|
||||
public static function dbExecute($sqlFile)
|
||||
{
|
||||
if (file_exists($sqlFile)) {
|
||||
$sqlArr = self::loadSqlFile($sqlFile);
|
||||
if(!empty($sqlArr)) {
|
||||
foreach($sqlArr as $v){
|
||||
try {
|
||||
Db::execute($v);
|
||||
} catch (\Exception $e) {
|
||||
throw new \Exception($e->getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -70,7 +70,7 @@ class Uploads
|
||||
* @param string $rule 文件命名规则,默认md5,uniqid,date,sha1,为空则取文件上传名称,或者自定义如a.jpg文件名
|
||||
* @return \think\response\Json
|
||||
*/
|
||||
public function put(string $fileName, string $dirName, int $fileSize, string $fileType, string $rule = null)
|
||||
public function put(string $fileName, string $dirName, int $fileSize, string $fileType, string $rule = '')
|
||||
{
|
||||
if(stripos($fileName,'http') !== false) {
|
||||
$file = $fileName;
|
||||
@ -90,7 +90,7 @@ class Uploads
|
||||
} catch (ValidateException $e) {
|
||||
return json(['status'=>-1,'msg'=>$e->getMessage()]);
|
||||
}
|
||||
// 解析存储位置
|
||||
// 解析存储位置 SYS_开头为系统位置
|
||||
$isSys = stripos($dirName, 'SYS_');
|
||||
if($isSys !== false) {
|
||||
$disk = 'sys';
|
||||
@ -107,9 +107,9 @@ class Uploads
|
||||
if(stripos($rule, '.') == false) {
|
||||
$rule = $file->getOriginalName();
|
||||
}
|
||||
$savename = \think\facade\Filesystem::disk($disk)->putFileAs($dirName, $file, $rule);
|
||||
$savename = Filesystem::disk($disk)->putFileAs($dirName, $file, $rule);
|
||||
} else {
|
||||
$savename = \think\facade\Filesystem::disk($disk)->putFile($dirName, $file, $rule);
|
||||
$savename = Filesystem::disk($disk)->putFile($dirName, $file, $rule);
|
||||
}
|
||||
|
||||
if($savename){
|
||||
|
@ -10,8 +10,111 @@
|
||||
*/
|
||||
namespace app\common\lib;
|
||||
|
||||
use think\Exception;
|
||||
|
||||
class Zip
|
||||
{
|
||||
/**
|
||||
* 保持目录结构的压缩方法
|
||||
* @param string $zipFile 压缩输出文件 相对或者绝对路径
|
||||
* @param array|string $folderPaths 要压缩的目录 相对或者绝对路径
|
||||
* @return void
|
||||
*/
|
||||
public static function dirZip(string $zipFile, $folderPaths)
|
||||
{
|
||||
//1. $folderPaths 路径为数组
|
||||
// 初始化zip对象
|
||||
$zip = new \ZipArchive();
|
||||
//打开压缩文件
|
||||
$zip->open($zipFile, \ZipArchive::CREATE | \ZipArchive::OVERWRITE);
|
||||
|
||||
if(is_array($folderPaths)) {
|
||||
foreach($folderPaths as $folderPath) {
|
||||
if(self::getDirSize($folderPath) == 0) {
|
||||
continue;
|
||||
};
|
||||
// 被压缩文件绝对路径
|
||||
$rootPath = realpath($folderPath);
|
||||
// Create recursive directory iterator
|
||||
//获取所有文件数组SplFileInfo[] $files
|
||||
$files = new \RecursiveIteratorIterator(
|
||||
new \RecursiveDirectoryIterator($rootPath),
|
||||
\RecursiveIteratorIterator::LEAVES_ONLY
|
||||
);
|
||||
|
||||
foreach ($files as $name => $file) {
|
||||
//要跳过所有子目录 Skip directories (they would be added automatically)
|
||||
if (!$file->isDir()) {
|
||||
// 真实文件路径
|
||||
$filePath = $file->getRealPath();
|
||||
// zip文件的相对路径
|
||||
$relativePath = str_replace('\\','/',str_replace(root_path(), '', $filePath));
|
||||
//添加文件到压缩包
|
||||
$zip->addFile($filePath, $relativePath);
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// 2. $folderPaths 路径为string
|
||||
if(self::getDirSize($folderPaths) == 0) {
|
||||
throw new \Exception("Directory name must not be empty.");
|
||||
};
|
||||
// 被压缩文件绝对路径
|
||||
$rootPath = realpath($folderPaths);
|
||||
// Create recursive directory iterator
|
||||
//获取所有文件数组SplFileInfo[] $files
|
||||
$files = new \RecursiveIteratorIterator(
|
||||
new \RecursiveDirectoryIterator($rootPath),
|
||||
\RecursiveIteratorIterator::LEAVES_ONLY
|
||||
);
|
||||
|
||||
foreach ($files as $name => $file) {
|
||||
//要跳过所有子目录 Skip directories (they would be added automatically)
|
||||
if (!$file->isDir()) {
|
||||
// 要压缩的文件路径
|
||||
$filePath = $file->getRealPath();
|
||||
// zip目录内文件的相对路径
|
||||
$relativePath = str_replace('\\','/',str_replace(root_path(), '', $filePath));
|
||||
//添加文件到压缩包
|
||||
$zip->addFile($filePath, $relativePath);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$zip->close();
|
||||
}
|
||||
|
||||
/**
|
||||
* 把目录内所有文件进行压缩输出
|
||||
* @param string $zipFile 压缩文件保存路径 相对路径或者绝对路径
|
||||
* @param string $folderPath 要压缩的目录 相对路径或者绝对路径
|
||||
* @return void
|
||||
*/
|
||||
public static function zipDir(string $zipFile, string $folderPath)
|
||||
{
|
||||
// 初始化zip对象
|
||||
$zip = new \ZipArchive();
|
||||
$zip->open($zipFile, \ZipArchive::CREATE | \ZipArchive::OVERWRITE);
|
||||
|
||||
$rootPath = realpath($folderPath);
|
||||
$files = new \RecursiveIteratorIterator(
|
||||
new \RecursiveDirectoryIterator($rootPath),
|
||||
\RecursiveIteratorIterator::LEAVES_ONLY
|
||||
);
|
||||
foreach ($files as $name => $file) {
|
||||
if (!$file->isDir()) {
|
||||
// 要压缩的文件路径
|
||||
$filePath = $file->getRealPath();
|
||||
// zip目录内文件的相对路径
|
||||
$relativePath = substr($filePath, strlen($rootPath) + 1);
|
||||
// 添加 文件 到 压缩包
|
||||
$zip->addFile($filePath, $relativePath);
|
||||
}
|
||||
}
|
||||
|
||||
$zip->close();
|
||||
}
|
||||
|
||||
/**
|
||||
* 压缩文件
|
||||
* @param array $files 待压缩文件 array('d:/test/1.txt','d:/test/2.jpg');【文件地址为绝对路径】
|
||||
@ -49,9 +152,7 @@ class Zip
|
||||
if (empty($path) || empty($filePath)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$zip = new \ZipArchive();
|
||||
|
||||
if ($zip->open($filePath) === true) {
|
||||
$zip->extractTo($path);
|
||||
$zip->close();
|
||||
@ -60,5 +161,30 @@ class Zip
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取文件夹大小
|
||||
* @param $dir 根文件夹路径
|
||||
* @return bool|int
|
||||
*/
|
||||
public static function getDirSize($dir)
|
||||
{
|
||||
if(!is_dir($dir)){
|
||||
return false;
|
||||
}
|
||||
$handle = opendir($dir);
|
||||
$sizeResult = 0;
|
||||
while (false !== ($FolderOrFile = readdir($handle))) {
|
||||
if ($FolderOrFile != "." && $FolderOrFile != "..") {
|
||||
if (is_dir("$dir/$FolderOrFile")) {
|
||||
$sizeResult += self::getDirSize("$dir/$FolderOrFile");
|
||||
} else {
|
||||
$sizeResult += filesize("$dir/$FolderOrFile");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
closedir($handle);
|
||||
return $sizeResult;
|
||||
}
|
||||
}
|
||||
?>
|
@ -111,7 +111,8 @@ class Article extends Model
|
||||
{
|
||||
$artTop = Cache::get('arttop');
|
||||
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])->with([
|
||||
$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])
|
||||
->with([
|
||||
'cate' => function ($query) {
|
||||
$query->where('delete_time', 0)->field('id,catename,ename');
|
||||
},
|
||||
|
@ -30,14 +30,14 @@ class Cate extends Model
|
||||
public function getCateInfo(string $ename)
|
||||
{
|
||||
//
|
||||
return $this::field('ename,catename,detpl,desc')->where('ename',$ename)->cache('cate_'.$ename,600)->find();
|
||||
return $this->field('ename,catename,detpl,desc')->where('ename',$ename)->cache('cate_'.$ename,600)->find();
|
||||
}
|
||||
|
||||
// 删除类别
|
||||
public function del($id)
|
||||
{
|
||||
$cates = $this::field('id,pid')->with('article')->find($id);
|
||||
$sonCate = $this::field('id,pid')->where('pid',$cates['id'])->find();
|
||||
$cates = $this->field('id,pid')->with('article')->find($id);
|
||||
$sonCate = $this->field('id,pid')->where('pid',$cates['id'])->find();
|
||||
if(empty($sonCate)) {
|
||||
$res = $cates->together(['article'])->delete();
|
||||
if($res){
|
||||
@ -48,9 +48,21 @@ class Cate extends Model
|
||||
} else {
|
||||
return '存在子分类,无法删除';
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
// 分类表
|
||||
public function getList()
|
||||
{
|
||||
$data = $this->field('sort,id,pid,catename,ename,detpl,icon,is_hot,desc')->where(['status'=>1])->select()->toArray();
|
||||
// 排序
|
||||
$cmf_arr = array_column($data, 'sort');
|
||||
array_multisort($cmf_arr, SORT_ASC, $data);
|
||||
if(count($data)) {
|
||||
return json(['code'=>0,'msg'=>'ok','data'=>$data]);
|
||||
} else {
|
||||
return json(['code'=>-1,'msg'=>'no data','data'=>'']);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
@ -80,13 +80,13 @@ class Comment extends Model
|
||||
* @param integer $id
|
||||
* @return void
|
||||
*/
|
||||
public function getUserCommentList(int $id) {
|
||||
$userCommList = $this::field('id,user_id,create_time,delete_time,article_id,content')
|
||||
->with(['article' => function(\think\model\Relation $query){
|
||||
$query->withField('id,title,cate_id,delete_time')->where(['status' => 1]);
|
||||
public function getUserCommentList1(int $id) {
|
||||
$userCommList = $this::field('id,user_id,create_time,article_id,content')
|
||||
->with(['article' => function($query){
|
||||
$query->withField('id,title,create_time')->where(['delete_time'=>0,'status' => 1]);
|
||||
}])
|
||||
->where(['user_id' => $id,'status' => 1])
|
||||
//->append(['url'])
|
||||
->append(['url'])
|
||||
->order(['create_time' => 'desc'])
|
||||
//->cache(3600)
|
||||
->select()
|
||||
@ -95,12 +95,39 @@ class Comment extends Model
|
||||
return $userCommList;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取用户评论列表
|
||||
*
|
||||
* @param integer $id
|
||||
* @return void
|
||||
*/
|
||||
public function getUserCommentList(int $id) {
|
||||
$userCommList = Article::field('Article.id,title,Article.create_time')->hasWhere('comments',['status'=>1,'delete_time'=>0])
|
||||
->with(['comments' => function($query) use($id){
|
||||
$query->withField('id,content')->where(['user_id'=>$id,'delete_time'=>0,'status' => 1]);
|
||||
}])
|
||||
->append(['url'])
|
||||
->order(['create_time' => 'desc'])
|
||||
//->cache(3600)
|
||||
->select()
|
||||
->toArray();
|
||||
|
||||
return $userCommList;
|
||||
}
|
||||
|
||||
|
||||
|
||||
// 获取url
|
||||
public function getUrlAttr($value,$data)
|
||||
{
|
||||
// dump($data);
|
||||
if(config('taoler.url_rewrite.article_as') == '<ename>/') {
|
||||
$cate = Cate::field('id,ename')->find($data['article']['cate_id']);
|
||||
return (string) url('detail',['id' => $data['id'],'ename'=>$cate->ename]);
|
||||
|
||||
$article = Article::field('id,cate_id')->with(['cate' => function($query){
|
||||
$query->withField('id,ename')->where(['status' => 1]);
|
||||
}])->find($data['article_id']);
|
||||
|
||||
return (string) url('detail',['id' => $data['article_id'],'ename'=>$article->cate->ename]);
|
||||
} else {
|
||||
return (string) url('detail',['id' => $data['id']]);
|
||||
}
|
||||
|
@ -207,21 +207,22 @@ class User extends BaseController
|
||||
}
|
||||
|
||||
$article = new Article();
|
||||
// $commont = new Comment();
|
||||
$arts = $article->getUserArtList((int) $id);
|
||||
|
||||
// $reys = $commont->getUserCommentList((int) $id);
|
||||
// dump($reys);
|
||||
//用户回答
|
||||
// $commont = new Comment();
|
||||
// $reys = $commont->getUserCommentList((int) $id);
|
||||
|
||||
$reys = Db::name('comment')
|
||||
->alias('c')
|
||||
->join('article a','c.article_id = a.id')
|
||||
->field('a.id,a.title,c.content,c.create_time,c.delete_time,c.status')
|
||||
->join('cate t','a.cate_id = t.id')
|
||||
->field('a.id,a.title,t.ename,c.content,c.create_time,c.delete_time,c.status')
|
||||
->where(['a.delete_time'=>0,'c.delete_time'=>0,'c.status'=>1])
|
||||
->where('c.user_id',$id)
|
||||
->order(['c.create_time'=>'desc'])
|
||||
->cache(3600)->select();
|
||||
|
||||
|
||||
View::assign(['u'=>$u,'arts'=>$arts,'reys'=>$reys,'jspage'=>'']);
|
||||
return View::fetch();
|
||||
}
|
||||
|
@ -1,12 +1,5 @@
|
||||
<?php
|
||||
|
||||
// +----------------------------------------------------------------------
|
||||
// | OneThink [ WE CAN DO IT JUST THINK IT ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | Copyright (c) 2013 http://www.onethink.cn All rights reserved.
|
||||
// +----------------------------------------------------------------------
|
||||
// | Author: 麦当苗儿 <zuojiazi@vip.qq.com> <http://www.zjzit.cn>
|
||||
// +----------------------------------------------------------------------
|
||||
// 检测环境是否支持可写
|
||||
//define('IS_WRITE', true);
|
||||
|
||||
@ -241,7 +234,7 @@ function strReplace($find,$replace,$array){
|
||||
|
||||
foreach ($array as $key => $val) {
|
||||
|
||||
if (is_array($val)) $array[$key]=$this->strReplace($find,$replace,$array[$key]);
|
||||
if (is_array($val)) $array[$key] = $this->strReplace($find,$replace,$array[$key]);
|
||||
|
||||
}
|
||||
|
||||
|
@ -162,12 +162,12 @@ CREATE TABLE `tao_auth_rule` (
|
||||
`title` char(20) NOT NULL DEFAULT '' COMMENT '权限标题',
|
||||
`etitle` varchar(100) NOT NULL DEFAULT '' COMMENT '英文权限标题',
|
||||
`type` tinyint(1) unsigned NOT NULL DEFAULT '1' COMMENT '类型',
|
||||
`status` enum('1','0') NOT NULL DEFAULT '1' COMMENT '菜单1启用,0禁用',
|
||||
`status` tinyint(1) NOT NULL DEFAULT '1' COMMENT '1启用,0禁用',
|
||||
`pid` smallint(5) NOT NULL DEFAULT '0' COMMENT '父级ID',
|
||||
`level` tinyint(1) NOT NULL DEFAULT '1' COMMENT '菜单层级',
|
||||
`icon` varchar(50) NOT NULL DEFAULT '' COMMENT '图标',
|
||||
`ishidden` enum('1','0','-1') NOT NULL DEFAULT '1' COMMENT '0隐藏,1显示-1其它',
|
||||
`sort` tinyint(4) NOT NULL DEFAULT '50' COMMENT '排序',
|
||||
`ismenu` tinyint(1) NOT NULL DEFAULT 1 COMMENT '0目录,1菜单2按钮',
|
||||
`sort` int(10) NOT NULL DEFAULT '50' COMMENT '排序',
|
||||
`condition` char(100) NOT NULL DEFAULT '',
|
||||
`create_time` int(11) NOT NULL DEFAULT '0' COMMENT '创建时间',
|
||||
`update_time` int(11) NOT NULL DEFAULT '0' COMMENT '更新时间',
|
||||
|
@ -36,7 +36,8 @@
|
||||
"yansongda/pay": "~3.1.0",
|
||||
"guzzlehttp/guzzle": "7.0",
|
||||
"php-di/php-di": "^6.4",
|
||||
"workerman/phpsocket.io": "^1.1"
|
||||
"workerman/phpsocket.io": "^1.1",
|
||||
"jaeger/querylist": "^4.2"
|
||||
},
|
||||
"require-dev": {
|
||||
"symfony/var-dumper": "^4.2",
|
||||
|
1061
composer.lock
generated
1061
composer.lock
generated
File diff suppressed because it is too large
Load Diff
@ -16,7 +16,7 @@ return [
|
||||
// 应用名,此项不可更改
|
||||
'appname' => 'TaoLer',
|
||||
// 版本配置
|
||||
'version' => '1.9.29',
|
||||
'version' => '2.0.0',
|
||||
// 加盐
|
||||
'salt' => 'taoler',
|
||||
// 数据库备份目录
|
||||
|
@ -10,6 +10,7 @@
|
||||
*/
|
||||
|
||||
namespace taoler\com;
|
||||
use think\Response;
|
||||
|
||||
class Api
|
||||
{
|
||||
@ -50,7 +51,6 @@ class Api
|
||||
curl_close($ch);
|
||||
if($httpCode == '200'){
|
||||
return json_decode($data);
|
||||
//return $data;
|
||||
} else {
|
||||
//$status ='{"code":-1,"msg":"远程服务器失败"}'; //字符串
|
||||
return json_decode('{"code":-1,"msg":"远程服务器失败,稍后重试"}'); //转换为对象
|
||||
|
@ -3,6 +3,7 @@
|
||||
namespace taoler\com;
|
||||
use RecursiveIteratorIterator;
|
||||
use RecursiveDirectoryIterator;
|
||||
|
||||
class Files
|
||||
{
|
||||
/**
|
||||
@ -12,7 +13,8 @@ class Files
|
||||
*/
|
||||
public static function getDirPath($path)
|
||||
{
|
||||
return substr($path,-1) == '/' ? $path : $path.'/';
|
||||
//去掉path最右侧的/号,再重新组装带/路径
|
||||
return rtrim($path,'/') . '/';
|
||||
}
|
||||
|
||||
/**
|
||||
@ -118,27 +120,22 @@ class Files
|
||||
public static function delDirAndFile(string $dirPath, $nowDir=false )
|
||||
{
|
||||
if(!is_dir($dirPath)) return 'dir not exist';
|
||||
if ( $handle = opendir($dirPath) ) {
|
||||
|
||||
while ( false !== ( $item = readdir( $handle ) ) ) {
|
||||
if ( $item != '.' && $item != '..' ) {
|
||||
if ( $handle = opendir($dirPath) ) {
|
||||
while ( false !== ( $item = readdir( $handle ) ) ) {
|
||||
if ( $item != '.' && $item != '..' ) {
|
||||
$path = $dirPath.$item;
|
||||
if (is_dir($path)) {
|
||||
self::delDirAndFile($path.'/');
|
||||
if (is_dir($path)) {
|
||||
self::delDirAndFile($path.'/');
|
||||
rmdir($path.'/');
|
||||
} else {
|
||||
unlink($path);
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
unlink($path);
|
||||
}
|
||||
}
|
||||
}
|
||||
closedir( $handle );
|
||||
//删除当前文件夹
|
||||
if($nowDir == true){
|
||||
if(rmdir($dirPath)){
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
if(!rmdir($dirPath)) return false;
|
||||
}
|
||||
} else {
|
||||
return false;
|
||||
|
@ -13,7 +13,7 @@ var forms = table.render({
|
||||
,{field: 'poster', title: '账号',width: 80}
|
||||
,{field: 'avatar', title: '头像', width: 60, templet: '#avatarTpl'}
|
||||
,{field: 'title', title: '标题', minWidth: 180,templet: '<div><a href="{{- d.url }}" target="_blank">{{- d.title }}</a></div>'}
|
||||
,{field: 'content', title: '内容', templet: '<div>{{= d.content }}</div>', minWidth: 200}
|
||||
,{field: 'content', title: '内容', 'escape':false, minWidth: 200}
|
||||
,{field: 'posttime', title: '时间',width: 120, sort: true}
|
||||
,{field: 'top', title: '置顶', templet: '#buttonTpl', width: 80, align: 'center'}
|
||||
,{field: 'hot', title: '加精', templet: '#buttonHot', width: 80, align: 'center'}
|
||||
|
@ -995,7 +995,7 @@ layui.define(['layer', 'laytpl', 'form', 'element', 'upload', 'util', 'imgcom'],
|
||||
util.fixbar({
|
||||
bar1: ''
|
||||
,bgcolor: '#009688'
|
||||
,css: {right: 10, bottom: 100}
|
||||
,css: {right: 10, bottom: 50}
|
||||
,click: function(type){
|
||||
//添加文章
|
||||
if(type === 'bar1'){
|
||||
|
@ -1,25 +1,2 @@
|
||||
ALTER TABLE `tao_push_jscode` ADD `type` tinyint(1) NOT NULL DEFAULT '1' COMMENT '1push2taglink' AFTER `jscode`;
|
||||
|
||||
DROP TABLE IF EXISTS `tao_tag`;
|
||||
CREATE TABLE `tao_tag` (
|
||||
`id` int(10) NOT NULL AUTO_INCREMENT COMMENT 'tag自增id',
|
||||
`name` varchar(20) NOT NULL COMMENT '名称',
|
||||
`ename` varchar(20) NOT NULL COMMENT '英文名',
|
||||
`create_time` int NOT NULL COMMENT '创建时间',
|
||||
`update_time` int NOT NULL COMMENT '更新时间',
|
||||
PRIMARY KEY (`id`),
|
||||
KEY `ename` (`ename`) USING BTREE COMMENT 'ename查询tag索引'
|
||||
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8 COMMENT='文章tag表';
|
||||
|
||||
DROP TABLE IF EXISTS `tao_taglist`;
|
||||
CREATE TABLE `tao_taglist` (
|
||||
`id` int(11) NOT NULL AUTO_INCREMENT COMMENT '标签列表id',
|
||||
`tag_id` int NOT NULL COMMENT '标签id',
|
||||
`article_id` int NOT NULL COMMENT '文章id',
|
||||
`create_time` int NOT NULL COMMENT '创建时间',
|
||||
PRIMARY KEY (`id`),
|
||||
KEY `tag_id` (`tag_id`) USING BTREE COMMENT 'tagID索引',
|
||||
KEY `article_id` (`article_id`) USING BTREE COMMENT '文章ID查询索引'
|
||||
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8 COMMENT='tag详细列表';
|
||||
|
||||
ALTER TABLE `tao_article` CHANGE `tags` `keywords` varchar(255) DEFAULT NULL COMMENT '关键词';
|
||||
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目录';
|
559
vendor/cache/adapter-common/AbstractCachePool.php
vendored
Normal file
559
vendor/cache/adapter-common/AbstractCachePool.php
vendored
Normal file
@ -0,0 +1,559 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of php-cache organization.
|
||||
*
|
||||
* (c) 2015 Aaron Scherer <aequasi@gmail.com>, Tobias Nyholm <tobias.nyholm@gmail.com>
|
||||
*
|
||||
* This source file is subject to the MIT license that is bundled
|
||||
* with this source code in the file LICENSE.
|
||||
*/
|
||||
|
||||
namespace Cache\Adapter\Common;
|
||||
|
||||
use Cache\Adapter\Common\Exception\CacheException;
|
||||
use Cache\Adapter\Common\Exception\CachePoolException;
|
||||
use Cache\Adapter\Common\Exception\InvalidArgumentException;
|
||||
use Psr\Cache\CacheItemInterface;
|
||||
use Psr\Log\LoggerAwareInterface;
|
||||
use Psr\Log\LoggerInterface;
|
||||
use Psr\SimpleCache\CacheInterface;
|
||||
|
||||
/**
|
||||
* @author Aaron Scherer <aequasi@gmail.com>
|
||||
* @author Tobias Nyholm <tobias.nyholm@gmail.com>
|
||||
*/
|
||||
abstract class AbstractCachePool implements PhpCachePool, LoggerAwareInterface, CacheInterface
|
||||
{
|
||||
const SEPARATOR_TAG = '!';
|
||||
|
||||
/**
|
||||
* @type LoggerInterface
|
||||
*/
|
||||
private $logger;
|
||||
|
||||
/**
|
||||
* @type PhpCacheItem[] deferred
|
||||
*/
|
||||
protected $deferred = [];
|
||||
|
||||
/**
|
||||
* @param PhpCacheItem $item
|
||||
* @param int|null $ttl seconds from now
|
||||
*
|
||||
* @return bool true if saved
|
||||
*/
|
||||
abstract protected function storeItemInCache(PhpCacheItem $item, $ttl);
|
||||
|
||||
/**
|
||||
* Fetch an object from the cache implementation.
|
||||
*
|
||||
* If it is a cache miss, it MUST return [false, null, [], null]
|
||||
*
|
||||
* @param string $key
|
||||
*
|
||||
* @return array with [isHit, value, tags[], expirationTimestamp]
|
||||
*/
|
||||
abstract protected function fetchObjectFromCache($key);
|
||||
|
||||
/**
|
||||
* Clear all objects from cache.
|
||||
*
|
||||
* @return bool false if error
|
||||
*/
|
||||
abstract protected function clearAllObjectsFromCache();
|
||||
|
||||
/**
|
||||
* Remove one object from cache.
|
||||
*
|
||||
* @param string $key
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
abstract protected function clearOneObjectFromCache($key);
|
||||
|
||||
/**
|
||||
* Get an array with all the values in the list named $name.
|
||||
*
|
||||
* @param string $name
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
abstract protected function getList($name);
|
||||
|
||||
/**
|
||||
* Remove the list.
|
||||
*
|
||||
* @param string $name
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
abstract protected function removeList($name);
|
||||
|
||||
/**
|
||||
* Add a item key on a list named $name.
|
||||
*
|
||||
* @param string $name
|
||||
* @param string $key
|
||||
*/
|
||||
abstract protected function appendListItem($name, $key);
|
||||
|
||||
/**
|
||||
* Remove an item from the list.
|
||||
*
|
||||
* @param string $name
|
||||
* @param string $key
|
||||
*/
|
||||
abstract protected function removeListItem($name, $key);
|
||||
|
||||
/**
|
||||
* Make sure to commit before we destruct.
|
||||
*/
|
||||
public function __destruct()
|
||||
{
|
||||
$this->commit();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getItem($key)
|
||||
{
|
||||
$this->validateKey($key);
|
||||
if (isset($this->deferred[$key])) {
|
||||
/** @type CacheItem $item */
|
||||
$item = clone $this->deferred[$key];
|
||||
$item->moveTagsToPrevious();
|
||||
|
||||
return $item;
|
||||
}
|
||||
|
||||
$func = function () use ($key) {
|
||||
try {
|
||||
return $this->fetchObjectFromCache($key);
|
||||
} catch (\Exception $e) {
|
||||
$this->handleException($e, __FUNCTION__);
|
||||
}
|
||||
};
|
||||
|
||||
return new CacheItem($key, $func);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getItems(array $keys = [])
|
||||
{
|
||||
$items = [];
|
||||
foreach ($keys as $key) {
|
||||
$items[$key] = $this->getItem($key);
|
||||
}
|
||||
|
||||
return $items;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function hasItem($key)
|
||||
{
|
||||
try {
|
||||
return $this->getItem($key)->isHit();
|
||||
} catch (\Exception $e) {
|
||||
$this->handleException($e, __FUNCTION__);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function clear()
|
||||
{
|
||||
// Clear the deferred items
|
||||
$this->deferred = [];
|
||||
|
||||
try {
|
||||
return $this->clearAllObjectsFromCache();
|
||||
} catch (\Exception $e) {
|
||||
$this->handleException($e, __FUNCTION__);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function deleteItem($key)
|
||||
{
|
||||
try {
|
||||
return $this->deleteItems([$key]);
|
||||
} catch (\Exception $e) {
|
||||
$this->handleException($e, __FUNCTION__);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function deleteItems(array $keys)
|
||||
{
|
||||
$deleted = true;
|
||||
foreach ($keys as $key) {
|
||||
$this->validateKey($key);
|
||||
|
||||
// Delete form deferred
|
||||
unset($this->deferred[$key]);
|
||||
|
||||
// We have to commit here to be able to remove deferred hierarchy items
|
||||
$this->commit();
|
||||
$this->preRemoveItem($key);
|
||||
|
||||
if (!$this->clearOneObjectFromCache($key)) {
|
||||
$deleted = false;
|
||||
}
|
||||
}
|
||||
|
||||
return $deleted;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function save(CacheItemInterface $item)
|
||||
{
|
||||
if (!$item instanceof PhpCacheItem) {
|
||||
$e = new InvalidArgumentException('Cache items are not transferable between pools. Item MUST implement PhpCacheItem.');
|
||||
$this->handleException($e, __FUNCTION__);
|
||||
}
|
||||
|
||||
$this->removeTagEntries($item);
|
||||
$this->saveTags($item);
|
||||
$timeToLive = null;
|
||||
if (null !== $timestamp = $item->getExpirationTimestamp()) {
|
||||
$timeToLive = $timestamp - time();
|
||||
|
||||
if ($timeToLive < 0) {
|
||||
return $this->deleteItem($item->getKey());
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
return $this->storeItemInCache($item, $timeToLive);
|
||||
} catch (\Exception $e) {
|
||||
$this->handleException($e, __FUNCTION__);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function saveDeferred(CacheItemInterface $item)
|
||||
{
|
||||
$this->deferred[$item->getKey()] = $item;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function commit()
|
||||
{
|
||||
$saved = true;
|
||||
foreach ($this->deferred as $item) {
|
||||
if (!$this->save($item)) {
|
||||
$saved = false;
|
||||
}
|
||||
}
|
||||
$this->deferred = [];
|
||||
|
||||
return $saved;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $key
|
||||
*
|
||||
* @throws InvalidArgumentException
|
||||
*/
|
||||
protected function validateKey($key)
|
||||
{
|
||||
if (!is_string($key)) {
|
||||
$e = new InvalidArgumentException(sprintf(
|
||||
'Cache key must be string, "%s" given',
|
||||
gettype($key)
|
||||
));
|
||||
$this->handleException($e, __FUNCTION__);
|
||||
}
|
||||
if (!isset($key[0])) {
|
||||
$e = new InvalidArgumentException('Cache key cannot be an empty string');
|
||||
$this->handleException($e, __FUNCTION__);
|
||||
}
|
||||
if (preg_match('|[\{\}\(\)/\\\@\:]|', $key)) {
|
||||
$e = new InvalidArgumentException(sprintf(
|
||||
'Invalid key: "%s". The key contains one or more characters reserved for future extension: {}()/\@:',
|
||||
$key
|
||||
));
|
||||
$this->handleException($e, __FUNCTION__);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param LoggerInterface $logger
|
||||
*/
|
||||
public function setLogger(LoggerInterface $logger): void
|
||||
{
|
||||
$this->logger = $logger;
|
||||
}
|
||||
|
||||
/**
|
||||
* Logs with an arbitrary level if the logger exists.
|
||||
*
|
||||
* @param mixed $level
|
||||
* @param string $message
|
||||
* @param array $context
|
||||
*/
|
||||
protected function log($level, $message, array $context = [])
|
||||
{
|
||||
if ($this->logger !== null) {
|
||||
$this->logger->log($level, $message, $context);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Log exception and rethrow it.
|
||||
*
|
||||
* @param \Exception $e
|
||||
* @param string $function
|
||||
*
|
||||
* @throws CachePoolException
|
||||
*/
|
||||
private function handleException(\Exception $e, $function)
|
||||
{
|
||||
$level = 'alert';
|
||||
if ($e instanceof InvalidArgumentException) {
|
||||
$level = 'warning';
|
||||
}
|
||||
|
||||
$this->log($level, $e->getMessage(), ['exception' => $e]);
|
||||
if (!$e instanceof CacheException) {
|
||||
$e = new CachePoolException(sprintf('Exception thrown when executing "%s". ', $function), 0, $e);
|
||||
}
|
||||
|
||||
throw $e;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $tags
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function invalidateTags(array $tags)
|
||||
{
|
||||
$itemIds = [];
|
||||
foreach ($tags as $tag) {
|
||||
$itemIds = array_merge($itemIds, $this->getList($this->getTagKey($tag)));
|
||||
}
|
||||
|
||||
// Remove all items with the tag
|
||||
$success = $this->deleteItems($itemIds);
|
||||
|
||||
if ($success) {
|
||||
// Remove the tag list
|
||||
foreach ($tags as $tag) {
|
||||
$this->removeList($this->getTagKey($tag));
|
||||
$l = $this->getList($this->getTagKey($tag));
|
||||
}
|
||||
}
|
||||
|
||||
return $success;
|
||||
}
|
||||
|
||||
public function invalidateTag($tag)
|
||||
{
|
||||
return $this->invalidateTags([$tag]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param PhpCacheItem $item
|
||||
*/
|
||||
protected function saveTags(PhpCacheItem $item)
|
||||
{
|
||||
$tags = $item->getTags();
|
||||
foreach ($tags as $tag) {
|
||||
$this->appendListItem($this->getTagKey($tag), $item->getKey());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes the key form all tag lists. When an item with tags is removed
|
||||
* we MUST remove the tags. If we fail to remove the tags a new item with
|
||||
* the same key will automatically get the previous tags.
|
||||
*
|
||||
* @param string $key
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
protected function preRemoveItem($key)
|
||||
{
|
||||
$item = $this->getItem($key);
|
||||
$this->removeTagEntries($item);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param PhpCacheItem $item
|
||||
*/
|
||||
private function removeTagEntries(PhpCacheItem $item)
|
||||
{
|
||||
$tags = $item->getPreviousTags();
|
||||
foreach ($tags as $tag) {
|
||||
$this->removeListItem($this->getTagKey($tag), $item->getKey());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $tag
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
protected function getTagKey($tag)
|
||||
{
|
||||
return 'tag'.self::SEPARATOR_TAG.$tag;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function get($key, $default = null)
|
||||
{
|
||||
$item = $this->getItem($key);
|
||||
if (!$item->isHit()) {
|
||||
return $default;
|
||||
}
|
||||
|
||||
return $item->get();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function set($key, $value, $ttl = null)
|
||||
{
|
||||
$item = $this->getItem($key);
|
||||
$item->set($value);
|
||||
$item->expiresAfter($ttl);
|
||||
|
||||
return $this->save($item);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function delete($key)
|
||||
{
|
||||
return $this->deleteItem($key);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getMultiple($keys, $default = null)
|
||||
{
|
||||
if (!is_array($keys)) {
|
||||
if (!$keys instanceof \Traversable) {
|
||||
throw new InvalidArgumentException('$keys is neither an array nor Traversable');
|
||||
}
|
||||
|
||||
// Since we need to throw an exception if *any* key is invalid, it doesn't
|
||||
// make sense to wrap iterators or something like that.
|
||||
$keys = iterator_to_array($keys, false);
|
||||
}
|
||||
|
||||
$items = $this->getItems($keys);
|
||||
|
||||
return $this->generateValues($default, $items);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $default
|
||||
* @param $items
|
||||
*
|
||||
* @return \Generator
|
||||
*/
|
||||
private function generateValues($default, $items)
|
||||
{
|
||||
foreach ($items as $key => $item) {
|
||||
/** @type $item CacheItemInterface */
|
||||
if (!$item->isHit()) {
|
||||
yield $key => $default;
|
||||
} else {
|
||||
yield $key => $item->get();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function setMultiple($values, $ttl = null)
|
||||
{
|
||||
if (!is_array($values)) {
|
||||
if (!$values instanceof \Traversable) {
|
||||
throw new InvalidArgumentException('$values is neither an array nor Traversable');
|
||||
}
|
||||
}
|
||||
|
||||
$keys = [];
|
||||
$arrayValues = [];
|
||||
foreach ($values as $key => $value) {
|
||||
if (is_int($key)) {
|
||||
$key = (string) $key;
|
||||
}
|
||||
$this->validateKey($key);
|
||||
$keys[] = $key;
|
||||
$arrayValues[$key] = $value;
|
||||
}
|
||||
|
||||
$items = $this->getItems($keys);
|
||||
$itemSuccess = true;
|
||||
foreach ($items as $key => $item) {
|
||||
$item->set($arrayValues[$key]);
|
||||
|
||||
try {
|
||||
$item->expiresAfter($ttl);
|
||||
} catch (InvalidArgumentException $e) {
|
||||
throw new InvalidArgumentException($e->getMessage(), $e->getCode(), $e);
|
||||
}
|
||||
|
||||
$itemSuccess = $itemSuccess && $this->saveDeferred($item);
|
||||
}
|
||||
|
||||
return $itemSuccess && $this->commit();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function deleteMultiple($keys)
|
||||
{
|
||||
if (!is_array($keys)) {
|
||||
if (!$keys instanceof \Traversable) {
|
||||
throw new InvalidArgumentException('$keys is neither an array nor Traversable');
|
||||
}
|
||||
|
||||
// Since we need to throw an exception if *any* key is invalid, it doesn't
|
||||
// make sense to wrap iterators or something like that.
|
||||
$keys = iterator_to_array($keys, false);
|
||||
}
|
||||
|
||||
return $this->deleteItems($keys);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function has($key)
|
||||
{
|
||||
return $this->hasItem($key);
|
||||
}
|
||||
}
|
269
vendor/cache/adapter-common/CacheItem.php
vendored
Normal file
269
vendor/cache/adapter-common/CacheItem.php
vendored
Normal file
@ -0,0 +1,269 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of php-cache organization.
|
||||
*
|
||||
* (c) 2015 Aaron Scherer <aequasi@gmail.com>, Tobias Nyholm <tobias.nyholm@gmail.com>
|
||||
*
|
||||
* This source file is subject to the MIT license that is bundled
|
||||
* with this source code in the file LICENSE.
|
||||
*/
|
||||
|
||||
namespace Cache\Adapter\Common;
|
||||
|
||||
use Cache\Adapter\Common\Exception\InvalidArgumentException;
|
||||
use Cache\TagInterop\TaggableCacheItemInterface;
|
||||
|
||||
/**
|
||||
* @author Aaron Scherer <aequasi@gmail.com>
|
||||
* @author Tobias Nyholm <tobias.nyholm@gmail.com>
|
||||
*/
|
||||
class CacheItem implements PhpCacheItem
|
||||
{
|
||||
/**
|
||||
* @type array
|
||||
*/
|
||||
private $prevTags = [];
|
||||
|
||||
/**
|
||||
* @type array
|
||||
*/
|
||||
private $tags = [];
|
||||
|
||||
/**
|
||||
* @type \Closure
|
||||
*/
|
||||
private $callable;
|
||||
|
||||
/**
|
||||
* @type string
|
||||
*/
|
||||
private $key;
|
||||
|
||||
/**
|
||||
* @type mixed
|
||||
*/
|
||||
private $value;
|
||||
|
||||
/**
|
||||
* The expiration timestamp is the source of truth. This is the UTC timestamp
|
||||
* when the cache item expire. A value of zero means it never expires. A nullvalue
|
||||
* means that no expiration is set.
|
||||
*
|
||||
* @type int|null
|
||||
*/
|
||||
private $expirationTimestamp = null;
|
||||
|
||||
/**
|
||||
* @type bool
|
||||
*/
|
||||
private $hasValue = false;
|
||||
|
||||
/**
|
||||
* @param string $key
|
||||
* @param \Closure|bool $callable or boolean hasValue
|
||||
*/
|
||||
public function __construct($key, $callable = null, $value = null)
|
||||
{
|
||||
$this->key = $key;
|
||||
|
||||
if ($callable === true) {
|
||||
$this->hasValue = true;
|
||||
$this->value = $value;
|
||||
} elseif ($callable !== false) {
|
||||
// This must be a callable or null
|
||||
$this->callable = $callable;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getKey()
|
||||
{
|
||||
return $this->key;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function set($value)
|
||||
{
|
||||
$this->value = $value;
|
||||
$this->hasValue = true;
|
||||
$this->callable = null;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function get()
|
||||
{
|
||||
if (!$this->isHit()) {
|
||||
return;
|
||||
}
|
||||
|
||||
return $this->value;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function isHit()
|
||||
{
|
||||
$this->initialize();
|
||||
|
||||
if (!$this->hasValue) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if ($this->expirationTimestamp !== null) {
|
||||
return $this->expirationTimestamp > time();
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getExpirationTimestamp()
|
||||
{
|
||||
return $this->expirationTimestamp;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function expiresAt($expiration)
|
||||
{
|
||||
if ($expiration instanceof \DateTimeInterface) {
|
||||
$this->expirationTimestamp = $expiration->getTimestamp();
|
||||
} elseif (is_int($expiration) || null === $expiration) {
|
||||
$this->expirationTimestamp = $expiration;
|
||||
} else {
|
||||
throw new InvalidArgumentException('Cache item ttl/expiresAt must be of type integer or \DateTimeInterface.');
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function expiresAfter($time)
|
||||
{
|
||||
if ($time === null) {
|
||||
$this->expirationTimestamp = null;
|
||||
} elseif ($time instanceof \DateInterval) {
|
||||
$date = new \DateTime();
|
||||
$date->add($time);
|
||||
$this->expirationTimestamp = $date->getTimestamp();
|
||||
} elseif (is_int($time)) {
|
||||
$this->expirationTimestamp = time() + $time;
|
||||
} else {
|
||||
throw new InvalidArgumentException('Cache item ttl/expiresAfter must be of type integer or \DateInterval.');
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getPreviousTags()
|
||||
{
|
||||
$this->initialize();
|
||||
|
||||
return $this->prevTags;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getTags()
|
||||
{
|
||||
return $this->tags;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function setTags(array $tags)
|
||||
{
|
||||
$this->tags = [];
|
||||
$this->tag($tags);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a tag to a cache item.
|
||||
*
|
||||
* @param string|string[] $tags A tag or array of tags
|
||||
*
|
||||
* @throws InvalidArgumentException When $tag is not valid.
|
||||
*
|
||||
* @return TaggableCacheItemInterface
|
||||
*/
|
||||
private function tag($tags)
|
||||
{
|
||||
$this->initialize();
|
||||
|
||||
if (!is_array($tags)) {
|
||||
$tags = [$tags];
|
||||
}
|
||||
foreach ($tags as $tag) {
|
||||
if (!is_string($tag)) {
|
||||
throw new InvalidArgumentException(sprintf('Cache tag must be string, "%s" given', is_object($tag) ? get_class($tag) : gettype($tag)));
|
||||
}
|
||||
if (isset($this->tags[$tag])) {
|
||||
continue;
|
||||
}
|
||||
if (!isset($tag[0])) {
|
||||
throw new InvalidArgumentException('Cache tag length must be greater than zero');
|
||||
}
|
||||
if (isset($tag[strcspn($tag, '{}()/\@:')])) {
|
||||
throw new InvalidArgumentException(sprintf('Cache tag "%s" contains reserved characters {}()/\@:', $tag));
|
||||
}
|
||||
$this->tags[$tag] = $tag;
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* If callable is not null, execute it an populate this object with values.
|
||||
*/
|
||||
private function initialize()
|
||||
{
|
||||
if ($this->callable !== null) {
|
||||
// $func will be $adapter->fetchObjectFromCache();
|
||||
$func = $this->callable;
|
||||
$result = $func();
|
||||
$this->hasValue = $result[0];
|
||||
$this->value = $result[1];
|
||||
$this->prevTags = isset($result[2]) ? $result[2] : [];
|
||||
$this->expirationTimestamp = null;
|
||||
|
||||
if (isset($result[3]) && is_int($result[3])) {
|
||||
$this->expirationTimestamp = $result[3];
|
||||
}
|
||||
|
||||
$this->callable = null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @internal This function should never be used and considered private.
|
||||
*
|
||||
* Move tags from $tags to $prevTags
|
||||
*/
|
||||
public function moveTagsToPrevious()
|
||||
{
|
||||
$this->prevTags = $this->tags;
|
||||
$this->tags = [];
|
||||
}
|
||||
}
|
73
vendor/cache/adapter-common/Changelog.md
vendored
Normal file
73
vendor/cache/adapter-common/Changelog.md
vendored
Normal file
@ -0,0 +1,73 @@
|
||||
# Change Log
|
||||
|
||||
The change log describes what is "Added", "Removed", "Changed" or "Fixed" between each release.
|
||||
|
||||
## 1.3.0
|
||||
|
||||
* Support for PHP 8.1
|
||||
* Drop support for PHP < 7.4
|
||||
* Allow psr/cache: ^1.0 || ^2.0
|
||||
|
||||
## 1.2.0
|
||||
|
||||
### Added
|
||||
|
||||
* Support for PHP 8
|
||||
|
||||
## 1.1.0
|
||||
|
||||
### Added
|
||||
|
||||
- Support for storing binary data
|
||||
|
||||
### Fixed
|
||||
|
||||
- Issue with one character variables
|
||||
|
||||
### Changed
|
||||
|
||||
- Tests are now extending `PHPUnit\Framework\TestCase`
|
||||
|
||||
## 1.0.0
|
||||
|
||||
* No changes since 0.4.0.
|
||||
|
||||
## 0.4.0
|
||||
|
||||
### Added
|
||||
|
||||
* `AbstractCachePool` has 4 new abstract methods: `getList`, `removeList`, `appendListItem` and `removeListItem`.
|
||||
* `AbstractCachePool::invalidateTags` and `AbstractCachePool::invalidateTags`
|
||||
* Added interfaces for our items and pools `PhpCachePool` and `PhpCacheItem`
|
||||
* Trait to help adapters to support tags. `TagSupportWithArray`.
|
||||
|
||||
### Changed
|
||||
|
||||
* First parameter to `AbstractCachePool::storeItemInCache` must be a `PhpCacheItem`.
|
||||
* Return value from `AbstractCachePool::fetchObjectFromCache` must be a an array with 4 values. Added expiration timestamp.
|
||||
* `HasExpirationDateInterface` is replaced by `HasExpirationTimestampInterface`
|
||||
* We do not work with `\DateTime` internally anymore. We work with timestamps.
|
||||
|
||||
## 0.3.3
|
||||
|
||||
### Fixed
|
||||
|
||||
* Bugfix when you fetch data from the cache storage that was saved as "non-tagging item" but fetch as a tagging item.
|
||||
|
||||
## 0.3.2
|
||||
|
||||
### Added
|
||||
|
||||
* Cache pools do implement `LoggerAwareInterface`
|
||||
|
||||
## 0.3.0
|
||||
|
||||
### Changed
|
||||
|
||||
* The `AbstractCachePool` does not longer implement `TaggablePoolInterface`. However, the `CacheItem` does still implement `TaggableItemInterface`.
|
||||
* `CacheItem::getKeyFromTaggedKey` has been removed
|
||||
* The `CacheItem`'s second parameter is a callable that must return an array with 3 elements; [`hasValue`, `value`, `tags`].
|
||||
|
||||
## 0.2.0
|
||||
|
||||
* No changelog before this version
|
23
vendor/cache/adapter-common/Exception/CacheException.php
vendored
Normal file
23
vendor/cache/adapter-common/Exception/CacheException.php
vendored
Normal file
@ -0,0 +1,23 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of php-cache organization.
|
||||
*
|
||||
* (c) 2015 Aaron Scherer <aequasi@gmail.com>, Tobias Nyholm <tobias.nyholm@gmail.com>
|
||||
*
|
||||
* This source file is subject to the MIT license that is bundled
|
||||
* with this source code in the file LICENSE.
|
||||
*/
|
||||
|
||||
namespace Cache\Adapter\Common\Exception;
|
||||
|
||||
use Psr\Cache\CacheException as CacheExceptionInterface;
|
||||
|
||||
/**
|
||||
* A base exception. All exceptions in this organization will extend this exception.
|
||||
*
|
||||
* @author Tobias Nyholm <tobias.nyholm@gmail.com>
|
||||
*/
|
||||
abstract class CacheException extends \RuntimeException implements CacheExceptionInterface
|
||||
{
|
||||
}
|
21
vendor/cache/adapter-common/Exception/CachePoolException.php
vendored
Normal file
21
vendor/cache/adapter-common/Exception/CachePoolException.php
vendored
Normal file
@ -0,0 +1,21 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of php-cache organization.
|
||||
*
|
||||
* (c) 2015 Aaron Scherer <aequasi@gmail.com>, Tobias Nyholm <tobias.nyholm@gmail.com>
|
||||
*
|
||||
* This source file is subject to the MIT license that is bundled
|
||||
* with this source code in the file LICENSE.
|
||||
*/
|
||||
|
||||
namespace Cache\Adapter\Common\Exception;
|
||||
|
||||
/**
|
||||
* If an exception is caused by a pool or by the cache storage.
|
||||
*
|
||||
* @author Tobias Nyholm <tobias.nyholm@gmail.com>
|
||||
*/
|
||||
class CachePoolException extends CacheException
|
||||
{
|
||||
}
|
19
vendor/cache/adapter-common/Exception/InvalidArgumentException.php
vendored
Normal file
19
vendor/cache/adapter-common/Exception/InvalidArgumentException.php
vendored
Normal file
@ -0,0 +1,19 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of php-cache organization.
|
||||
*
|
||||
* (c) 2015 Aaron Scherer <aequasi@gmail.com>, Tobias Nyholm <tobias.nyholm@gmail.com>
|
||||
*
|
||||
* This source file is subject to the MIT license that is bundled
|
||||
* with this source code in the file LICENSE.
|
||||
*/
|
||||
|
||||
namespace Cache\Adapter\Common\Exception;
|
||||
|
||||
use Psr\Cache\InvalidArgumentException as CacheInvalidArgumentException;
|
||||
use Psr\SimpleCache\InvalidArgumentException as SimpleCacheInvalidArgumentException;
|
||||
|
||||
class InvalidArgumentException extends CacheException implements CacheInvalidArgumentException, SimpleCacheInvalidArgumentException
|
||||
{
|
||||
}
|
26
vendor/cache/adapter-common/HasExpirationTimestampInterface.php
vendored
Normal file
26
vendor/cache/adapter-common/HasExpirationTimestampInterface.php
vendored
Normal file
@ -0,0 +1,26 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of php-cache organization.
|
||||
*
|
||||
* (c) 2015 Aaron Scherer <aequasi@gmail.com>, Tobias Nyholm <tobias.nyholm@gmail.com>
|
||||
*
|
||||
* This source file is subject to the MIT license that is bundled
|
||||
* with this source code in the file LICENSE.
|
||||
*/
|
||||
|
||||
namespace Cache\Adapter\Common;
|
||||
|
||||
/**
|
||||
* @author Aaron Scherer <aequasi@gmail.com>
|
||||
* @author Tobias Nyholm <tobias.nyholm@gmail.com>
|
||||
*/
|
||||
interface HasExpirationTimestampInterface
|
||||
{
|
||||
/**
|
||||
* The timestamp when the object expires.
|
||||
*
|
||||
* @return int|null
|
||||
*/
|
||||
public function getExpirationTimestamp();
|
||||
}
|
68
vendor/cache/adapter-common/JsonBinaryArmoring.php
vendored
Normal file
68
vendor/cache/adapter-common/JsonBinaryArmoring.php
vendored
Normal file
@ -0,0 +1,68 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of php-cache organization.
|
||||
*
|
||||
* (c) 2015 Aaron Scherer <aequasi@gmail.com>, Tobias Nyholm <tobias.nyholm@gmail.com>
|
||||
*
|
||||
* This source file is subject to the MIT license that is bundled
|
||||
* with this source code in the file LICENSE.
|
||||
*/
|
||||
|
||||
namespace Cache\Adapter\Common;
|
||||
|
||||
/**
|
||||
* This trait provides common routines for safely encoding binary and non-UTF8 data in
|
||||
* JSON. This is needed for components that use JSON natively (currently, the MongoDB
|
||||
* adapter and EncryptedCachePool).
|
||||
*
|
||||
* @author Stephen Clouse <stephen.clouse@noaa.gov>
|
||||
*/
|
||||
trait JsonBinaryArmoring
|
||||
{
|
||||
private static $ESCAPE_JSON_CHARACTERS = [
|
||||
"\x00", "\x01", "\x02", "\x03", "\x04", "\x05", "\x06", "\x07",
|
||||
"\x08", "\x09", "\x0A", "\x0B", "\x0C", "\x0D", "\x0E", "\x0F",
|
||||
"\x10", "\x11", "\x12", "\x13", "\x14", "\x15", "\x16", "\x17",
|
||||
"\x18", "\x19", "\x1A", "\x1B", "\x1C", "\x1D", "\x1E", "\x1F",
|
||||
];
|
||||
|
||||
private static $ENCODED_JSON_CHARACTERS = [
|
||||
'\u0000', '\u0001', '\u0002', '\u0003', '\u0004', '\u0005', '\u0006', '\u0007',
|
||||
'\u0008', '\u0009', '\u000A', '\u000B', '\u000C', '\u000D', '\u000E', '\u000F',
|
||||
'\u0010', '\u0011', '\u0012', '\u0013', '\u0014', '\u0015', '\u0016', '\u0017',
|
||||
'\u0018', '\u0019', '\u001A', '\u001B', '\u001C', '\u001D', '\u001E', '\u001F',
|
||||
];
|
||||
|
||||
/**
|
||||
* Armor a value going into a JSON document.
|
||||
*
|
||||
* @param string $value
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
protected static function jsonArmor($value)
|
||||
{
|
||||
return str_replace(
|
||||
static::$ESCAPE_JSON_CHARACTERS,
|
||||
static::$ENCODED_JSON_CHARACTERS,
|
||||
utf8_encode($value)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* De-armor a value from a JSON document.
|
||||
*
|
||||
* @param string $value
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
protected static function jsonDeArmor($value)
|
||||
{
|
||||
return utf8_decode(str_replace(
|
||||
static::$ENCODED_JSON_CHARACTERS,
|
||||
static::$ESCAPE_JSON_CHARACTERS,
|
||||
$value
|
||||
));
|
||||
}
|
||||
}
|
22
vendor/cache/adapter-common/LICENSE
vendored
Normal file
22
vendor/cache/adapter-common/LICENSE
vendored
Normal file
@ -0,0 +1,22 @@
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2015 Aaron Scherer, Tobias Nyholm
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
|
32
vendor/cache/adapter-common/PhpCacheItem.php
vendored
Normal file
32
vendor/cache/adapter-common/PhpCacheItem.php
vendored
Normal file
@ -0,0 +1,32 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of php-cache organization.
|
||||
*
|
||||
* (c) 2015 Aaron Scherer <aequasi@gmail.com>, Tobias Nyholm <tobias.nyholm@gmail.com>
|
||||
*
|
||||
* This source file is subject to the MIT license that is bundled
|
||||
* with this source code in the file LICENSE.
|
||||
*/
|
||||
|
||||
namespace Cache\Adapter\Common;
|
||||
|
||||
use Cache\TagInterop\TaggableCacheItemInterface;
|
||||
|
||||
/**
|
||||
* @author Tobias Nyholm <tobias.nyholm@gmail.com>
|
||||
*/
|
||||
interface PhpCacheItem extends HasExpirationTimestampInterface, TaggableCacheItemInterface
|
||||
{
|
||||
/**
|
||||
* Get the current tags. These are not the same tags as getPrevious tags. This
|
||||
* is the tags that has been added to the item after the item was fetched from
|
||||
* the cache storage.
|
||||
*
|
||||
* WARNING: This is generally not the function you want to use. Please see
|
||||
* `getPreviousTags`.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getTags();
|
||||
}
|
34
vendor/cache/adapter-common/PhpCachePool.php
vendored
Normal file
34
vendor/cache/adapter-common/PhpCachePool.php
vendored
Normal file
@ -0,0 +1,34 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of php-cache organization.
|
||||
*
|
||||
* (c) 2015 Aaron Scherer <aequasi@gmail.com>, Tobias Nyholm <tobias.nyholm@gmail.com>
|
||||
*
|
||||
* This source file is subject to the MIT license that is bundled
|
||||
* with this source code in the file LICENSE.
|
||||
*/
|
||||
|
||||
namespace Cache\Adapter\Common;
|
||||
|
||||
use Cache\TagInterop\TaggableCacheItemPoolInterface;
|
||||
|
||||
/**
|
||||
* @author Tobias Nyholm <tobias.nyholm@gmail.com>
|
||||
*/
|
||||
interface PhpCachePool extends TaggableCacheItemPoolInterface
|
||||
{
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @return PhpCacheItem
|
||||
*/
|
||||
public function getItem($key);
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @return array|\Traversable|PhpCacheItem[]
|
||||
*/
|
||||
public function getItems(array $keys = []);
|
||||
}
|
15
vendor/cache/adapter-common/README.md
vendored
Normal file
15
vendor/cache/adapter-common/README.md
vendored
Normal file
@ -0,0 +1,15 @@
|
||||
# Common PSR-6 Cache pool
|
||||
[![Gitter](https://badges.gitter.im/php-cache/cache.svg)](https://gitter.im/php-cache/cache?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge)
|
||||
[![Latest Stable Version](https://poser.pugx.org/cache/adapter-common/v/stable)](https://packagist.org/packages/cache/adapter-common)
|
||||
[![codecov.io](https://codecov.io/github/php-cache/adapter-common/coverage.svg?branch=master)](https://codecov.io/github/php-cache/adapter-common?branch=master)
|
||||
[![Total Downloads](https://poser.pugx.org/cache/adapter-common/downloads)](https://packagist.org/packages/cache/adapter-common)
|
||||
[![Monthly Downloads](https://poser.pugx.org/cache/adapter-common/d/monthly.png)](https://packagist.org/packages/cache/adapter-common)
|
||||
[![Software License](https://img.shields.io/badge/license-MIT-brightgreen.svg?style=flat-square)](LICENSE)
|
||||
|
||||
This repository contains shared classes and interfaces used by the PHP Cache organisation. To read about
|
||||
features like tagging and hierarchy support please read the shared documentation at [www.php-cache.com](http://www.php-cache.com).
|
||||
|
||||
### Contribute
|
||||
|
||||
Contributions are very welcome! Send a pull request to the [main repository](https://github.com/php-cache/cache) or
|
||||
report any issues you find on the [issue tracker](http://issues.php-cache.com).
|
88
vendor/cache/adapter-common/TagSupportWithArray.php
vendored
Normal file
88
vendor/cache/adapter-common/TagSupportWithArray.php
vendored
Normal file
@ -0,0 +1,88 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of php-cache organization.
|
||||
*
|
||||
* (c) 2015 Aaron Scherer <aequasi@gmail.com>, Tobias Nyholm <tobias.nyholm@gmail.com>
|
||||
*
|
||||
* This source file is subject to the MIT license that is bundled
|
||||
* with this source code in the file LICENSE.
|
||||
*/
|
||||
|
||||
namespace Cache\Adapter\Common;
|
||||
|
||||
/**
|
||||
* This trait could be used by adapters that do not have a native support for lists.
|
||||
*
|
||||
* @author Tobias Nyholm <tobias.nyholm@gmail.com>
|
||||
*/
|
||||
trait TagSupportWithArray
|
||||
{
|
||||
/**
|
||||
* Get a value from the storage.
|
||||
*
|
||||
* @param string $name
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
abstract public function getDirectValue($name);
|
||||
|
||||
/**
|
||||
* Set a value to the storage.
|
||||
*
|
||||
* @param string $name
|
||||
* @param mixed $value
|
||||
*/
|
||||
abstract public function setDirectValue($name, $value);
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function appendListItem($name, $value)
|
||||
{
|
||||
$data = $this->getDirectValue($name);
|
||||
if (!is_array($data)) {
|
||||
$data = [];
|
||||
}
|
||||
$data[] = $value;
|
||||
$this->setDirectValue($name, $data);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function getList($name)
|
||||
{
|
||||
$data = $this->getDirectValue($name);
|
||||
if (!is_array($data)) {
|
||||
$data = [];
|
||||
}
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function removeList($name)
|
||||
{
|
||||
$this->setDirectValue($name, []);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function removeListItem($name, $key)
|
||||
{
|
||||
$data = $this->getList($name);
|
||||
foreach ($data as $i => $value) {
|
||||
if ($key === $value) {
|
||||
unset($data[$i]);
|
||||
}
|
||||
}
|
||||
|
||||
return $this->setDirectValue($name, $data);
|
||||
}
|
||||
}
|
55
vendor/cache/adapter-common/composer.json
vendored
Normal file
55
vendor/cache/adapter-common/composer.json
vendored
Normal file
@ -0,0 +1,55 @@
|
||||
{
|
||||
"name": "cache/adapter-common",
|
||||
"description": "Common classes for PSR-6 adapters",
|
||||
"license": "MIT",
|
||||
"type": "library",
|
||||
"keywords": [
|
||||
"cache",
|
||||
"psr-6",
|
||||
"tag"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Aaron Scherer",
|
||||
"email": "aequasi@gmail.com",
|
||||
"homepage": "https://github.com/aequasi"
|
||||
},
|
||||
{
|
||||
"name": "Tobias Nyholm",
|
||||
"email": "tobias.nyholm@gmail.com",
|
||||
"homepage": "https://github.com/nyholm"
|
||||
}
|
||||
],
|
||||
"homepage": "http://www.php-cache.com/en/latest/",
|
||||
"require": {
|
||||
"php": ">=7.4",
|
||||
"cache/tag-interop": "^1.0",
|
||||
"psr/cache": "^1.0 || ^2.0",
|
||||
"psr/log": "^1.0 || ^2.0 || ^3.0",
|
||||
"psr/simple-cache": "^1.0"
|
||||
},
|
||||
"require-dev": {
|
||||
"cache/integration-tests": "^0.17",
|
||||
"phpunit/phpunit": "^7.5.20 || ^9.5.10"
|
||||
},
|
||||
"minimum-stability": "dev",
|
||||
"prefer-stable": true,
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Cache\\Adapter\\Common\\": ""
|
||||
}
|
||||
},
|
||||
"autoload-dev": {
|
||||
"psr-4": {
|
||||
"Cache\\Adapter\\Common\\Tests\\": "Tests/"
|
||||
},
|
||||
"exclude-from-classmap": [
|
||||
"/Tests/"
|
||||
]
|
||||
},
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "1.1-dev"
|
||||
}
|
||||
}
|
||||
}
|
64
vendor/cache/filesystem-adapter/Changelog.md
vendored
Normal file
64
vendor/cache/filesystem-adapter/Changelog.md
vendored
Normal file
@ -0,0 +1,64 @@
|
||||
# Change Log
|
||||
|
||||
The change log describes what is "Added", "Removed", "Changed" or "Fixed" between each release.
|
||||
|
||||
## UNRELEASED
|
||||
|
||||
## 1.2.0
|
||||
|
||||
* Support for PHP 8.1
|
||||
* Drop support for PHP < 7.4
|
||||
* Allow psr/cache: ^1.0 || ^2.0
|
||||
|
||||
## 1.1.0
|
||||
|
||||
### Added
|
||||
|
||||
* Support for PHP 8
|
||||
|
||||
### Changed
|
||||
|
||||
* Use `League\Flysystem\FilesystemInterface` instead of concrete `League\Flysystem\Filesystem` class
|
||||
|
||||
## 1.0.0
|
||||
|
||||
* No changes since 0.4.0
|
||||
|
||||
## 0.4.0
|
||||
|
||||
### Added
|
||||
|
||||
* Support for the new `TaggableCacheItemPoolInterface`.
|
||||
* Support for PSR-16 SimpleCache
|
||||
|
||||
### Changed
|
||||
|
||||
* The behavior of `CacheItem::getTags()` has changed. It will not return the tags stored in the cache storage.
|
||||
|
||||
### Removed
|
||||
|
||||
* `CacheItem::getExpirationDate()`. Use `CacheItem::getExpirationTimestamp()`
|
||||
* `CacheItem::getTags()`. Use `CacheItem::getPreviousTags()`
|
||||
* `CacheItem::addTag()`. Use `CacheItem::setTags()`
|
||||
|
||||
## 0.3.3
|
||||
|
||||
### Fixed
|
||||
|
||||
* Race condition in `fetchObjectFromCache`.
|
||||
|
||||
## 0.3.2
|
||||
|
||||
### Changed
|
||||
|
||||
* Using `Filesystem::update` instead of `Filesystem::delete` and `Filesystem::write`.
|
||||
|
||||
## 0.3.1
|
||||
|
||||
### Added
|
||||
|
||||
* Add ability to change cache path in FilesystemCachePool
|
||||
|
||||
## 0.3.0
|
||||
|
||||
* No changelog before this version
|
213
vendor/cache/filesystem-adapter/FilesystemCachePool.php
vendored
Normal file
213
vendor/cache/filesystem-adapter/FilesystemCachePool.php
vendored
Normal file
@ -0,0 +1,213 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of php-cache organization.
|
||||
*
|
||||
* (c) 2015 Aaron Scherer <aequasi@gmail.com>, Tobias Nyholm <tobias.nyholm@gmail.com>
|
||||
*
|
||||
* This source file is subject to the MIT license that is bundled
|
||||
* with this source code in the file LICENSE.
|
||||
*/
|
||||
|
||||
namespace Cache\Adapter\Filesystem;
|
||||
|
||||
use Cache\Adapter\Common\AbstractCachePool;
|
||||
use Cache\Adapter\Common\Exception\InvalidArgumentException;
|
||||
use Cache\Adapter\Common\PhpCacheItem;
|
||||
use League\Flysystem\FileExistsException;
|
||||
use League\Flysystem\FileNotFoundException;
|
||||
use League\Flysystem\FilesystemInterface;
|
||||
|
||||
/**
|
||||
* @author Tobias Nyholm <tobias.nyholm@gmail.com>
|
||||
*/
|
||||
class FilesystemCachePool extends AbstractCachePool
|
||||
{
|
||||
/**
|
||||
* @type FilesystemInterface
|
||||
*/
|
||||
private $filesystem;
|
||||
|
||||
/**
|
||||
* The folder should not begin nor end with a slash. Example: path/to/cache.
|
||||
*
|
||||
* @type string
|
||||
*/
|
||||
private $folder;
|
||||
|
||||
/**
|
||||
* @param FilesystemInterface $filesystem
|
||||
* @param string $folder
|
||||
*/
|
||||
public function __construct(FilesystemInterface $filesystem, $folder = 'cache')
|
||||
{
|
||||
$this->folder = $folder;
|
||||
|
||||
$this->filesystem = $filesystem;
|
||||
$this->filesystem->createDir($this->folder);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $folder
|
||||
*/
|
||||
public function setFolder($folder)
|
||||
{
|
||||
$this->folder = $folder;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function fetchObjectFromCache($key)
|
||||
{
|
||||
$empty = [false, null, [], null];
|
||||
$file = $this->getFilePath($key);
|
||||
|
||||
try {
|
||||
$data = @unserialize($this->filesystem->read($file));
|
||||
if ($data === false) {
|
||||
return $empty;
|
||||
}
|
||||
} catch (FileNotFoundException $e) {
|
||||
return $empty;
|
||||
}
|
||||
|
||||
// Determine expirationTimestamp from data, remove items if expired
|
||||
$expirationTimestamp = $data[2] ?: null;
|
||||
if ($expirationTimestamp !== null && time() > $expirationTimestamp) {
|
||||
foreach ($data[1] as $tag) {
|
||||
$this->removeListItem($this->getTagKey($tag), $key);
|
||||
}
|
||||
$this->forceClear($key);
|
||||
|
||||
return $empty;
|
||||
}
|
||||
|
||||
return [true, $data[0], $data[1], $expirationTimestamp];
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function clearAllObjectsFromCache()
|
||||
{
|
||||
$this->filesystem->deleteDir($this->folder);
|
||||
$this->filesystem->createDir($this->folder);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function clearOneObjectFromCache($key)
|
||||
{
|
||||
return $this->forceClear($key);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function storeItemInCache(PhpCacheItem $item, $ttl)
|
||||
{
|
||||
$data = serialize(
|
||||
[
|
||||
$item->get(),
|
||||
$item->getTags(),
|
||||
$item->getExpirationTimestamp(),
|
||||
]
|
||||
);
|
||||
|
||||
$file = $this->getFilePath($item->getKey());
|
||||
if ($this->filesystem->has($file)) {
|
||||
// Update file if it exists
|
||||
return $this->filesystem->update($file, $data);
|
||||
}
|
||||
|
||||
try {
|
||||
return $this->filesystem->write($file, $data);
|
||||
} catch (FileExistsException $e) {
|
||||
// To handle issues when/if race conditions occurs, we try to update here.
|
||||
return $this->filesystem->update($file, $data);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $key
|
||||
*
|
||||
* @throws InvalidArgumentException
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
private function getFilePath($key)
|
||||
{
|
||||
if (!preg_match('|^[a-zA-Z0-9_\.! ]+$|', $key)) {
|
||||
throw new InvalidArgumentException(sprintf('Invalid key "%s". Valid filenames must match [a-zA-Z0-9_\.! ].', $key));
|
||||
}
|
||||
|
||||
return sprintf('%s/%s', $this->folder, $key);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function getList($name)
|
||||
{
|
||||
$file = $this->getFilePath($name);
|
||||
|
||||
if (!$this->filesystem->has($file)) {
|
||||
$this->filesystem->write($file, serialize([]));
|
||||
}
|
||||
|
||||
return unserialize($this->filesystem->read($file));
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function removeList($name)
|
||||
{
|
||||
$file = $this->getFilePath($name);
|
||||
$this->filesystem->delete($file);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function appendListItem($name, $key)
|
||||
{
|
||||
$list = $this->getList($name);
|
||||
$list[] = $key;
|
||||
|
||||
return $this->filesystem->update($this->getFilePath($name), serialize($list));
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function removeListItem($name, $key)
|
||||
{
|
||||
$list = $this->getList($name);
|
||||
foreach ($list as $i => $item) {
|
||||
if ($item === $key) {
|
||||
unset($list[$i]);
|
||||
}
|
||||
}
|
||||
|
||||
return $this->filesystem->update($this->getFilePath($name), serialize($list));
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $key
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
private function forceClear($key)
|
||||
{
|
||||
try {
|
||||
return $this->filesystem->delete($this->getFilePath($key));
|
||||
} catch (FileNotFoundException $e) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
22
vendor/cache/filesystem-adapter/LICENSE
vendored
Normal file
22
vendor/cache/filesystem-adapter/LICENSE
vendored
Normal file
@ -0,0 +1,22 @@
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2015 Aaron Scherer, Tobias Nyholm
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
|
45
vendor/cache/filesystem-adapter/README.md
vendored
Normal file
45
vendor/cache/filesystem-adapter/README.md
vendored
Normal file
@ -0,0 +1,45 @@
|
||||
# Filesystem PSR-6 Cache pool
|
||||
[![Gitter](https://badges.gitter.im/php-cache/cache.svg)](https://gitter.im/php-cache/cache?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge)
|
||||
[![Latest Stable Version](https://poser.pugx.org/cache/filesystem-adapter/v/stable)](https://packagist.org/packages/cache/filesystem-adapter)
|
||||
[![codecov.io](https://codecov.io/github/php-cache/filesystem-adapter/coverage.svg?branch=master)](https://codecov.io/github/php-cache/filesystem-adapter?branch=master)
|
||||
[![Total Downloads](https://poser.pugx.org/cache/filesystem-adapter/downloads)](https://packagist.org/packages/cache/filesystem-adapter)
|
||||
[![Monthly Downloads](https://poser.pugx.org/cache/filesystem-adapter/d/monthly.png)](https://packagist.org/packages/cache/filesystem-adapter)
|
||||
[![Software License](https://img.shields.io/badge/license-MIT-brightgreen.svg?style=flat-square)](LICENSE)
|
||||
|
||||
This is a PSR-6 cache implementation using Filesystem. It is a part of the PHP Cache organisation. To read about
|
||||
features like tagging and hierarchy support please read the shared documentation at [www.php-cache.com](http://www.php-cache.com).
|
||||
|
||||
This implementation is using the excellent [Flysystem](http://flysystem.thephpleague.com/).
|
||||
|
||||
### Install
|
||||
|
||||
```bash
|
||||
composer require cache/filesystem-adapter
|
||||
```
|
||||
|
||||
### Use
|
||||
|
||||
To create an instance of `FilesystemCachePool` you need to configure a `Filesystem` and its adapter.
|
||||
|
||||
```php
|
||||
use League\Flysystem\Adapter\Local;
|
||||
use League\Flysystem\Filesystem;
|
||||
use Cache\Adapter\Filesystem\FilesystemCachePool;
|
||||
|
||||
$filesystemAdapter = new Local(__DIR__.'/');
|
||||
$filesystem = new Filesystem($filesystemAdapter);
|
||||
|
||||
$pool = new FilesystemCachePool($filesystem);
|
||||
```
|
||||
|
||||
You can change the folder the cache pool will write to through the `setFolder` setter:
|
||||
|
||||
```php
|
||||
$pool = new FilesystemCachePool($filesystem);
|
||||
$pool->setFolder('path/to/cache');
|
||||
```
|
||||
|
||||
### Contribute
|
||||
|
||||
Contributions are very welcome! Send a pull request to the [main repository](https://github.com/php-cache/cache) or
|
||||
report any issues you find on the [issue tracker](http://issues.php-cache.com).
|
55
vendor/cache/filesystem-adapter/composer.json
vendored
Normal file
55
vendor/cache/filesystem-adapter/composer.json
vendored
Normal file
@ -0,0 +1,55 @@
|
||||
{
|
||||
"name": "cache/filesystem-adapter",
|
||||
"description": "A PSR-6 cache implementation using filesystem. This implementation supports tags",
|
||||
"license": "MIT",
|
||||
"type": "library",
|
||||
"keywords": [
|
||||
"cache",
|
||||
"psr-6",
|
||||
"filesystem",
|
||||
"tag"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Aaron Scherer",
|
||||
"email": "aequasi@gmail.com",
|
||||
"homepage": "https://github.com/aequasi"
|
||||
},
|
||||
{
|
||||
"name": "Tobias Nyholm",
|
||||
"email": "tobias.nyholm@gmail.com",
|
||||
"homepage": "https://github.com/nyholm"
|
||||
}
|
||||
],
|
||||
"homepage": "http://www.php-cache.com/en/latest/",
|
||||
"require": {
|
||||
"php": ">=7.4",
|
||||
"cache/adapter-common": "^1.0",
|
||||
"league/flysystem": "^1.0",
|
||||
"psr/cache": "^1.0 || ^2.0",
|
||||
"psr/simple-cache": "^1.0"
|
||||
},
|
||||
"require-dev": {
|
||||
"cache/integration-tests": "^0.17",
|
||||
"phpunit/phpunit": "^7.5.20 || ^9.5.10"
|
||||
},
|
||||
"provide": {
|
||||
"psr/cache-implementation": "^1.0",
|
||||
"psr/simple-cache-implementation": "^1.0"
|
||||
},
|
||||
"minimum-stability": "dev",
|
||||
"prefer-stable": true,
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Cache\\Adapter\\Filesystem\\": ""
|
||||
},
|
||||
"exclude-from-classmap": [
|
||||
"/Tests/"
|
||||
]
|
||||
},
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "1.1-dev"
|
||||
}
|
||||
}
|
||||
}
|
5
vendor/cache/tag-interop/.github/PULL_REQUEST_TEMPLATE.md
vendored
Normal file
5
vendor/cache/tag-interop/.github/PULL_REQUEST_TEMPLATE.md
vendored
Normal file
@ -0,0 +1,5 @@
|
||||
This is a READ ONLY repository.
|
||||
|
||||
Please make your pull request to https://github.com/php-cache/cache
|
||||
|
||||
Thank you for contributing.
|
2
vendor/cache/tag-interop/.gitignore
vendored
Normal file
2
vendor/cache/tag-interop/.gitignore
vendored
Normal file
@ -0,0 +1,2 @@
|
||||
composer.lock
|
||||
vendor
|
22
vendor/cache/tag-interop/.travis.yml
vendored
Normal file
22
vendor/cache/tag-interop/.travis.yml
vendored
Normal file
@ -0,0 +1,22 @@
|
||||
language: php
|
||||
sudo: false
|
||||
|
||||
matrix:
|
||||
include:
|
||||
- php: 7.1
|
||||
|
||||
cache:
|
||||
directories:
|
||||
- "$HOME/.composer/cache"
|
||||
|
||||
install:
|
||||
- composer update --prefer-dist --prefer-stable
|
||||
|
||||
script:
|
||||
- ./vendor/bin/phpunit --coverage-clover=coverage.xml
|
||||
|
||||
after_success:
|
||||
- pip install --user codecov && codecov
|
||||
|
||||
notifications:
|
||||
email: false
|
18
vendor/cache/tag-interop/Changelog.md
vendored
Normal file
18
vendor/cache/tag-interop/Changelog.md
vendored
Normal file
@ -0,0 +1,18 @@
|
||||
# Change Log
|
||||
|
||||
The change log describes what is "Added", "Removed", "Changed" or "Fixed" between each release.
|
||||
|
||||
## 1.1.0
|
||||
|
||||
* Support PHP 8.1
|
||||
* Support for psr/cache v2
|
||||
|
||||
## 1.0.1
|
||||
|
||||
* Support PHP 8
|
||||
|
||||
## 1.0.0
|
||||
|
||||
* First release
|
||||
|
||||
|
22
vendor/cache/tag-interop/LICENSE
vendored
Normal file
22
vendor/cache/tag-interop/LICENSE
vendored
Normal file
@ -0,0 +1,22 @@
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2015 Aaron Scherer, Tobias Nyholm
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
|
25
vendor/cache/tag-interop/README.md
vendored
Normal file
25
vendor/cache/tag-interop/README.md
vendored
Normal file
@ -0,0 +1,25 @@
|
||||
# Tag support for PSR-6 Cache
|
||||
[![Gitter](https://badges.gitter.im/php-cache/cache.svg)](https://gitter.im/php-cache/cache?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge)
|
||||
[![Latest Stable Version](https://poser.pugx.org/cache/tag-interop/v/stable)](https://packagist.org/packages/cache/tag-interop)
|
||||
[![Total Downloads](https://poser.pugx.org/cache/tag-interop/downloads)](https://packagist.org/packages/cache/tag-interop)
|
||||
[![Monthly Downloads](https://poser.pugx.org/cache/tag-interop/d/monthly.png)](https://packagist.org/packages/cache/tag-interop)
|
||||
[![Software License](https://img.shields.io/badge/license-MIT-brightgreen.svg?style=flat-square)](LICENSE)
|
||||
|
||||
This repository holds two interfaces for tagging. These interfaces will make their
|
||||
way into PHP Fig. Representatives from Symfony, PHP-cache and Drupal has worked
|
||||
together to agree on these interfaces.
|
||||
|
||||
### Install
|
||||
|
||||
```bash
|
||||
composer require cache/tag-interop
|
||||
```
|
||||
|
||||
### Use
|
||||
|
||||
Read the [documentation on usage](http://www.php-cache.com/).
|
||||
|
||||
### Contribute
|
||||
|
||||
Contributions are very welcome! Send a pull request to the [main repository](https://github.com/php-cache/cache) or
|
||||
report any issues you find on the [issue tracker](http://issues.php-cache.com).
|
43
vendor/cache/tag-interop/TaggableCacheItemInterface.php
vendored
Normal file
43
vendor/cache/tag-interop/TaggableCacheItemInterface.php
vendored
Normal file
@ -0,0 +1,43 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of php-cache organization.
|
||||
*
|
||||
* (c) 2015 Aaron Scherer <aequasi@gmail.com>, Tobias Nyholm <tobias.nyholm@gmail.com>
|
||||
*
|
||||
* This source file is subject to the MIT license that is bundled
|
||||
* with this source code in the file LICENSE.
|
||||
*/
|
||||
|
||||
namespace Cache\TagInterop;
|
||||
|
||||
use Psr\Cache\CacheItemInterface;
|
||||
use Psr\Cache\InvalidArgumentException;
|
||||
|
||||
/**
|
||||
* An item that supports tags. This interface is a soon-to-be-PSR.
|
||||
*
|
||||
* @author Tobias Nyholm <tobias.nyholm@gmail.com>
|
||||
* @author Nicolas Grekas <p@tchwork.com>
|
||||
*/
|
||||
interface TaggableCacheItemInterface extends CacheItemInterface
|
||||
{
|
||||
/**
|
||||
* Get all existing tags. These are the tags the item has when the item is
|
||||
* returned from the pool.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getPreviousTags();
|
||||
|
||||
/**
|
||||
* Overwrite all tags with a new set of tags.
|
||||
*
|
||||
* @param string[] $tags An array of tags
|
||||
*
|
||||
* @throws InvalidArgumentException When a tag is not valid.
|
||||
*
|
||||
* @return TaggableCacheItemInterface
|
||||
*/
|
||||
public function setTags(array $tags);
|
||||
}
|
60
vendor/cache/tag-interop/TaggableCacheItemPoolInterface.php
vendored
Normal file
60
vendor/cache/tag-interop/TaggableCacheItemPoolInterface.php
vendored
Normal file
@ -0,0 +1,60 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of php-cache organization.
|
||||
*
|
||||
* (c) 2015 Aaron Scherer <aequasi@gmail.com>, Tobias Nyholm <tobias.nyholm@gmail.com>
|
||||
*
|
||||
* This source file is subject to the MIT license that is bundled
|
||||
* with this source code in the file LICENSE.
|
||||
*/
|
||||
|
||||
namespace Cache\TagInterop;
|
||||
|
||||
use Psr\Cache\CacheItemPoolInterface;
|
||||
use Psr\Cache\InvalidArgumentException;
|
||||
|
||||
/**
|
||||
* Interface for invalidating cached items using tags. This interface is a soon-to-be-PSR.
|
||||
*
|
||||
* @author Tobias Nyholm <tobias.nyholm@gmail.com>
|
||||
* @author Nicolas Grekas <p@tchwork.com>
|
||||
*/
|
||||
interface TaggableCacheItemPoolInterface extends CacheItemPoolInterface
|
||||
{
|
||||
/**
|
||||
* Invalidates cached items using a tag.
|
||||
*
|
||||
* @param string $tag The tag to invalidate
|
||||
*
|
||||
* @throws InvalidArgumentException When $tags is not valid
|
||||
*
|
||||
* @return bool True on success
|
||||
*/
|
||||
public function invalidateTag($tag);
|
||||
|
||||
/**
|
||||
* Invalidates cached items using tags.
|
||||
*
|
||||
* @param string[] $tags An array of tags to invalidate
|
||||
*
|
||||
* @throws InvalidArgumentException When $tags is not valid
|
||||
*
|
||||
* @return bool True on success
|
||||
*/
|
||||
public function invalidateTags(array $tags);
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @return TaggableCacheItemInterface
|
||||
*/
|
||||
public function getItem($key);
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @return array|\Traversable|TaggableCacheItemInterface[]
|
||||
*/
|
||||
public function getItems(array $keys = []);
|
||||
}
|
39
vendor/cache/tag-interop/composer.json
vendored
Normal file
39
vendor/cache/tag-interop/composer.json
vendored
Normal file
@ -0,0 +1,39 @@
|
||||
{
|
||||
"name": "cache/tag-interop",
|
||||
"description": "Framework interoperable interfaces for tags",
|
||||
"license": "MIT",
|
||||
"type": "library",
|
||||
"keywords": [
|
||||
"cache",
|
||||
"psr6",
|
||||
"tag",
|
||||
"psr"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Tobias Nyholm",
|
||||
"email": "tobias.nyholm@gmail.com",
|
||||
"homepage": "https://github.com/nyholm"
|
||||
},
|
||||
{
|
||||
"name": "Nicolas Grekas ",
|
||||
"email": "p@tchwork.com",
|
||||
"homepage": "https://github.com/nicolas-grekas"
|
||||
}
|
||||
],
|
||||
"homepage": "https://www.php-cache.com/en/latest/",
|
||||
"require": {
|
||||
"php": "^5.5 || ^7.0 || ^8.0",
|
||||
"psr/cache": "^1.0 || ^2.0"
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Cache\\TagInterop\\": ""
|
||||
}
|
||||
},
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "1.1-dev"
|
||||
}
|
||||
}
|
||||
}
|
13
vendor/composer/autoload_classmap.php
vendored
13
vendor/composer/autoload_classmap.php
vendored
@ -7,9 +7,22 @@ $baseDir = dirname($vendorDir);
|
||||
|
||||
return array(
|
||||
'Attribute' => $vendorDir . '/symfony/polyfill-php80/Resources/stubs/Attribute.php',
|
||||
'Callback' => $vendorDir . '/jaeger/phpquery-single/phpQuery.php',
|
||||
'CallbackBody' => $vendorDir . '/jaeger/phpquery-single/phpQuery.php',
|
||||
'CallbackParam' => $vendorDir . '/jaeger/phpquery-single/phpQuery.php',
|
||||
'CallbackParameterToReference' => $vendorDir . '/jaeger/phpquery-single/phpQuery.php',
|
||||
'CallbackReturnReference' => $vendorDir . '/jaeger/phpquery-single/phpQuery.php',
|
||||
'CallbackReturnValue' => $vendorDir . '/jaeger/phpquery-single/phpQuery.php',
|
||||
'Composer\\InstalledVersions' => $vendorDir . '/composer/InstalledVersions.php',
|
||||
'DOMDocumentWrapper' => $vendorDir . '/jaeger/phpquery-single/phpQuery.php',
|
||||
'DOMEvent' => $vendorDir . '/jaeger/phpquery-single/phpQuery.php',
|
||||
'ICallbackNamed' => $vendorDir . '/jaeger/phpquery-single/phpQuery.php',
|
||||
'PhpToken' => $vendorDir . '/symfony/polyfill-php80/Resources/stubs/PhpToken.php',
|
||||
'Stringable' => $vendorDir . '/symfony/polyfill-php80/Resources/stubs/Stringable.php',
|
||||
'UnhandledMatchError' => $vendorDir . '/symfony/polyfill-php80/Resources/stubs/UnhandledMatchError.php',
|
||||
'ValueError' => $vendorDir . '/symfony/polyfill-php80/Resources/stubs/ValueError.php',
|
||||
'phpQuery' => $vendorDir . '/jaeger/phpquery-single/phpQuery.php',
|
||||
'phpQueryEvents' => $vendorDir . '/jaeger/phpquery-single/phpQuery.php',
|
||||
'phpQueryObject' => $vendorDir . '/jaeger/phpquery-single/phpQuery.php',
|
||||
'phpQueryPlugins' => $vendorDir . '/jaeger/phpquery-single/phpQuery.php',
|
||||
);
|
||||
|
6
vendor/composer/autoload_files.php
vendored
6
vendor/composer/autoload_files.php
vendored
@ -14,10 +14,12 @@ return array(
|
||||
'0e6d7bf4a5811bfa5cf40c5ccd6fae6a' => $vendorDir . '/symfony/polyfill-mbstring/bootstrap.php',
|
||||
'25072dd6e2470089de65ae7bf11d3109' => $vendorDir . '/symfony/polyfill-php72/bootstrap.php',
|
||||
'a4a119a56e50fbb293281d9a48007e0e' => $vendorDir . '/symfony/polyfill-php80/bootstrap.php',
|
||||
'6b998e7ad3182c0d21d23780badfa07b' => $vendorDir . '/yansongda/supports/src/Functions.php',
|
||||
'37a3dc5111fe8f707ab4c132ef1dbc62' => $vendorDir . '/guzzlehttp/guzzle/src/functions_include.php',
|
||||
'b33e3d135e5d9e47d845c576147bda89' => $vendorDir . '/php-di/php-di/src/functions.php',
|
||||
'667aeda72477189d0494fecd327c3641' => $vendorDir . '/symfony/var-dumper/Resources/functions/dump.php',
|
||||
'fe62ba7e10580d903cc46d808b5961a4' => $vendorDir . '/tightenco/collect/src/Collect/Support/helpers.php',
|
||||
'caf31cc6ec7cf2241cb6f12c226c3846' => $vendorDir . '/tightenco/collect/src/Collect/Support/alias.php',
|
||||
'6b998e7ad3182c0d21d23780badfa07b' => $vendorDir . '/yansongda/supports/src/Functions.php',
|
||||
'b33e3d135e5d9e47d845c576147bda89' => $vendorDir . '/php-di/php-di/src/functions.php',
|
||||
'223fa6f9b46fbe5d6b44c5ff847bfceb' => $vendorDir . '/taoser/think-addons/src/helper.php',
|
||||
'1cfd2761b63b0a29ed23657ea394cb2d' => $vendorDir . '/topthink/think-captcha/src/helper.php',
|
||||
'8c783b3a3de2f6d9177022b5ccdcc841' => $vendorDir . '/yansongda/pay/src/Functions.php',
|
||||
|
6
vendor/composer/autoload_psr4.php
vendored
6
vendor/composer/autoload_psr4.php
vendored
@ -22,10 +22,12 @@ return array(
|
||||
'Yansongda\\Supports\\' => array($vendorDir . '/yansongda/supports/src'),
|
||||
'Yansongda\\Pay\\' => array($vendorDir . '/yansongda/pay/src'),
|
||||
'Workerman\\' => array($vendorDir . '/workerman/workerman'),
|
||||
'Tightenco\\Collect\\' => array($vendorDir . '/tightenco/collect/src/Collect'),
|
||||
'Symfony\\Polyfill\\Php80\\' => array($vendorDir . '/symfony/polyfill-php80'),
|
||||
'Symfony\\Polyfill\\Php72\\' => array($vendorDir . '/symfony/polyfill-php72'),
|
||||
'Symfony\\Polyfill\\Mbstring\\' => array($vendorDir . '/symfony/polyfill-mbstring'),
|
||||
'Symfony\\Component\\VarDumper\\' => array($vendorDir . '/symfony/var-dumper'),
|
||||
'QL\\' => array($vendorDir . '/jaeger/querylist/src'),
|
||||
'Psr\\SimpleCache\\' => array($vendorDir . '/psr/simple-cache/src'),
|
||||
'Psr\\Log\\' => array($vendorDir . '/psr/log/Psr/Log'),
|
||||
'Psr\\Http\\Message\\' => array($vendorDir . '/psr/http-message/src'),
|
||||
@ -41,6 +43,7 @@ return array(
|
||||
'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'),
|
||||
'Invoker\\' => array($vendorDir . '/php-di/invoker/src'),
|
||||
'GuzzleHttp\\Psr7\\' => array($vendorDir . '/guzzlehttp/psr7/src'),
|
||||
'GuzzleHttp\\Promise\\' => array($vendorDir . '/guzzlehttp/promises/src'),
|
||||
@ -50,5 +53,8 @@ return array(
|
||||
'DI\\' => array($vendorDir . '/php-di/php-di/src'),
|
||||
'DASPRiD\\Enum\\' => array($vendorDir . '/dasprid/enum/src'),
|
||||
'Channel\\' => array($vendorDir . '/workerman/channel/src'),
|
||||
'Cache\\TagInterop\\' => array($vendorDir . '/cache/tag-interop'),
|
||||
'Cache\\Adapter\\Filesystem\\' => array($vendorDir . '/cache/filesystem-adapter'),
|
||||
'Cache\\Adapter\\Common\\' => array($vendorDir . '/cache/adapter-common'),
|
||||
'BaconQrCode\\' => array($vendorDir . '/bacon/bacon-qr-code/src'),
|
||||
);
|
||||
|
58
vendor/composer/autoload_static.php
vendored
58
vendor/composer/autoload_static.php
vendored
@ -15,10 +15,12 @@ class ComposerStaticInit1b32198725235c8d6500c87262ef30c2
|
||||
'0e6d7bf4a5811bfa5cf40c5ccd6fae6a' => __DIR__ . '/..' . '/symfony/polyfill-mbstring/bootstrap.php',
|
||||
'25072dd6e2470089de65ae7bf11d3109' => __DIR__ . '/..' . '/symfony/polyfill-php72/bootstrap.php',
|
||||
'a4a119a56e50fbb293281d9a48007e0e' => __DIR__ . '/..' . '/symfony/polyfill-php80/bootstrap.php',
|
||||
'6b998e7ad3182c0d21d23780badfa07b' => __DIR__ . '/..' . '/yansongda/supports/src/Functions.php',
|
||||
'37a3dc5111fe8f707ab4c132ef1dbc62' => __DIR__ . '/..' . '/guzzlehttp/guzzle/src/functions_include.php',
|
||||
'b33e3d135e5d9e47d845c576147bda89' => __DIR__ . '/..' . '/php-di/php-di/src/functions.php',
|
||||
'667aeda72477189d0494fecd327c3641' => __DIR__ . '/..' . '/symfony/var-dumper/Resources/functions/dump.php',
|
||||
'fe62ba7e10580d903cc46d808b5961a4' => __DIR__ . '/..' . '/tightenco/collect/src/Collect/Support/helpers.php',
|
||||
'caf31cc6ec7cf2241cb6f12c226c3846' => __DIR__ . '/..' . '/tightenco/collect/src/Collect/Support/alias.php',
|
||||
'6b998e7ad3182c0d21d23780badfa07b' => __DIR__ . '/..' . '/yansongda/supports/src/Functions.php',
|
||||
'b33e3d135e5d9e47d845c576147bda89' => __DIR__ . '/..' . '/php-di/php-di/src/functions.php',
|
||||
'223fa6f9b46fbe5d6b44c5ff847bfceb' => __DIR__ . '/..' . '/taoser/think-addons/src/helper.php',
|
||||
'1cfd2761b63b0a29ed23657ea394cb2d' => __DIR__ . '/..' . '/topthink/think-captcha/src/helper.php',
|
||||
'8c783b3a3de2f6d9177022b5ccdcc841' => __DIR__ . '/..' . '/yansongda/pay/src/Functions.php',
|
||||
@ -63,6 +65,10 @@ class ComposerStaticInit1b32198725235c8d6500c87262ef30c2
|
||||
array (
|
||||
'Workerman\\' => 10,
|
||||
),
|
||||
'T' =>
|
||||
array (
|
||||
'Tightenco\\Collect\\' => 18,
|
||||
),
|
||||
'S' =>
|
||||
array (
|
||||
'Symfony\\Polyfill\\Php80\\' => 23,
|
||||
@ -70,6 +76,10 @@ class ComposerStaticInit1b32198725235c8d6500c87262ef30c2
|
||||
'Symfony\\Polyfill\\Mbstring\\' => 26,
|
||||
'Symfony\\Component\\VarDumper\\' => 28,
|
||||
),
|
||||
'Q' =>
|
||||
array (
|
||||
'QL\\' => 3,
|
||||
),
|
||||
'P' =>
|
||||
array (
|
||||
'Psr\\SimpleCache\\' => 16,
|
||||
@ -91,6 +101,10 @@ class ComposerStaticInit1b32198725235c8d6500c87262ef30c2
|
||||
'League\\Flysystem\\' => 17,
|
||||
'Laravel\\SerializableClosure\\' => 28,
|
||||
),
|
||||
'J' =>
|
||||
array (
|
||||
'Jaeger\\' => 7,
|
||||
),
|
||||
'I' =>
|
||||
array (
|
||||
'Invoker\\' => 8,
|
||||
@ -117,6 +131,9 @@ class ComposerStaticInit1b32198725235c8d6500c87262ef30c2
|
||||
'C' =>
|
||||
array (
|
||||
'Channel\\' => 8,
|
||||
'Cache\\TagInterop\\' => 17,
|
||||
'Cache\\Adapter\\Filesystem\\' => 25,
|
||||
'Cache\\Adapter\\Common\\' => 21,
|
||||
),
|
||||
'B' =>
|
||||
array (
|
||||
@ -193,6 +210,10 @@ class ComposerStaticInit1b32198725235c8d6500c87262ef30c2
|
||||
array (
|
||||
0 => __DIR__ . '/..' . '/workerman/workerman',
|
||||
),
|
||||
'Tightenco\\Collect\\' =>
|
||||
array (
|
||||
0 => __DIR__ . '/..' . '/tightenco/collect/src/Collect',
|
||||
),
|
||||
'Symfony\\Polyfill\\Php80\\' =>
|
||||
array (
|
||||
0 => __DIR__ . '/..' . '/symfony/polyfill-php80',
|
||||
@ -209,6 +230,10 @@ class ComposerStaticInit1b32198725235c8d6500c87262ef30c2
|
||||
array (
|
||||
0 => __DIR__ . '/..' . '/symfony/var-dumper',
|
||||
),
|
||||
'QL\\' =>
|
||||
array (
|
||||
0 => __DIR__ . '/..' . '/jaeger/querylist/src',
|
||||
),
|
||||
'Psr\\SimpleCache\\' =>
|
||||
array (
|
||||
0 => __DIR__ . '/..' . '/psr/simple-cache/src',
|
||||
@ -269,6 +294,10 @@ class ComposerStaticInit1b32198725235c8d6500c87262ef30c2
|
||||
array (
|
||||
0 => __DIR__ . '/..' . '/laravel/serializable-closure/src',
|
||||
),
|
||||
'Jaeger\\' =>
|
||||
array (
|
||||
0 => __DIR__ . '/..' . '/jaeger/g-http/src',
|
||||
),
|
||||
'Invoker\\' =>
|
||||
array (
|
||||
0 => __DIR__ . '/..' . '/php-di/invoker/src',
|
||||
@ -305,6 +334,18 @@ class ComposerStaticInit1b32198725235c8d6500c87262ef30c2
|
||||
array (
|
||||
0 => __DIR__ . '/..' . '/workerman/channel/src',
|
||||
),
|
||||
'Cache\\TagInterop\\' =>
|
||||
array (
|
||||
0 => __DIR__ . '/..' . '/cache/tag-interop',
|
||||
),
|
||||
'Cache\\Adapter\\Filesystem\\' =>
|
||||
array (
|
||||
0 => __DIR__ . '/..' . '/cache/filesystem-adapter',
|
||||
),
|
||||
'Cache\\Adapter\\Common\\' =>
|
||||
array (
|
||||
0 => __DIR__ . '/..' . '/cache/adapter-common',
|
||||
),
|
||||
'BaconQrCode\\' =>
|
||||
array (
|
||||
0 => __DIR__ . '/..' . '/bacon/bacon-qr-code/src',
|
||||
@ -317,11 +358,24 @@ class ComposerStaticInit1b32198725235c8d6500c87262ef30c2
|
||||
|
||||
public static $classMap = array (
|
||||
'Attribute' => __DIR__ . '/..' . '/symfony/polyfill-php80/Resources/stubs/Attribute.php',
|
||||
'Callback' => __DIR__ . '/..' . '/jaeger/phpquery-single/phpQuery.php',
|
||||
'CallbackBody' => __DIR__ . '/..' . '/jaeger/phpquery-single/phpQuery.php',
|
||||
'CallbackParam' => __DIR__ . '/..' . '/jaeger/phpquery-single/phpQuery.php',
|
||||
'CallbackParameterToReference' => __DIR__ . '/..' . '/jaeger/phpquery-single/phpQuery.php',
|
||||
'CallbackReturnReference' => __DIR__ . '/..' . '/jaeger/phpquery-single/phpQuery.php',
|
||||
'CallbackReturnValue' => __DIR__ . '/..' . '/jaeger/phpquery-single/phpQuery.php',
|
||||
'Composer\\InstalledVersions' => __DIR__ . '/..' . '/composer/InstalledVersions.php',
|
||||
'DOMDocumentWrapper' => __DIR__ . '/..' . '/jaeger/phpquery-single/phpQuery.php',
|
||||
'DOMEvent' => __DIR__ . '/..' . '/jaeger/phpquery-single/phpQuery.php',
|
||||
'ICallbackNamed' => __DIR__ . '/..' . '/jaeger/phpquery-single/phpQuery.php',
|
||||
'PhpToken' => __DIR__ . '/..' . '/symfony/polyfill-php80/Resources/stubs/PhpToken.php',
|
||||
'Stringable' => __DIR__ . '/..' . '/symfony/polyfill-php80/Resources/stubs/Stringable.php',
|
||||
'UnhandledMatchError' => __DIR__ . '/..' . '/symfony/polyfill-php80/Resources/stubs/UnhandledMatchError.php',
|
||||
'ValueError' => __DIR__ . '/..' . '/symfony/polyfill-php80/Resources/stubs/ValueError.php',
|
||||
'phpQuery' => __DIR__ . '/..' . '/jaeger/phpquery-single/phpQuery.php',
|
||||
'phpQueryEvents' => __DIR__ . '/..' . '/jaeger/phpquery-single/phpQuery.php',
|
||||
'phpQueryObject' => __DIR__ . '/..' . '/jaeger/phpquery-single/phpQuery.php',
|
||||
'phpQueryPlugins' => __DIR__ . '/..' . '/jaeger/phpquery-single/phpQuery.php',
|
||||
);
|
||||
|
||||
public static function getInitializer(ClassLoader $loader)
|
||||
|
422
vendor/composer/installed.json
vendored
422
vendor/composer/installed.json
vendored
@ -57,6 +57,210 @@
|
||||
},
|
||||
"install-path": "../bacon/bacon-qr-code"
|
||||
},
|
||||
{
|
||||
"name": "cache/adapter-common",
|
||||
"version": "1.3.0",
|
||||
"version_normalized": "1.3.0.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/php-cache/adapter-common.git",
|
||||
"reference": "8788309be72aa7be69b88cdc0687549c74a7d479"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/php-cache/adapter-common/zipball/8788309be72aa7be69b88cdc0687549c74a7d479",
|
||||
"reference": "8788309be72aa7be69b88cdc0687549c74a7d479",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"cache/tag-interop": "^1.0",
|
||||
"php": ">=7.4",
|
||||
"psr/cache": "^1.0 || ^2.0",
|
||||
"psr/log": "^1.0 || ^2.0 || ^3.0",
|
||||
"psr/simple-cache": "^1.0"
|
||||
},
|
||||
"require-dev": {
|
||||
"cache/integration-tests": "^0.17",
|
||||
"phpunit/phpunit": "^7.5.20 || ^9.5.10"
|
||||
},
|
||||
"time": "2022-01-15T15:47:19+00:00",
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "1.1-dev"
|
||||
}
|
||||
},
|
||||
"installation-source": "dist",
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Cache\\Adapter\\Common\\": ""
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Aaron Scherer",
|
||||
"email": "aequasi@gmail.com",
|
||||
"homepage": "https://github.com/aequasi"
|
||||
},
|
||||
{
|
||||
"name": "Tobias Nyholm",
|
||||
"email": "tobias.nyholm@gmail.com",
|
||||
"homepage": "https://github.com/nyholm"
|
||||
}
|
||||
],
|
||||
"description": "Common classes for PSR-6 adapters",
|
||||
"homepage": "http://www.php-cache.com/en/latest/",
|
||||
"keywords": [
|
||||
"cache",
|
||||
"psr-6",
|
||||
"tag"
|
||||
],
|
||||
"support": {
|
||||
"source": "https://github.com/php-cache/adapter-common/tree/1.3.0"
|
||||
},
|
||||
"install-path": "../cache/adapter-common"
|
||||
},
|
||||
{
|
||||
"name": "cache/filesystem-adapter",
|
||||
"version": "1.2.0",
|
||||
"version_normalized": "1.2.0.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/php-cache/filesystem-adapter.git",
|
||||
"reference": "f1faaae40aaa696ef899cef6f6888aedb90b419b"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/php-cache/filesystem-adapter/zipball/f1faaae40aaa696ef899cef6f6888aedb90b419b",
|
||||
"reference": "f1faaae40aaa696ef899cef6f6888aedb90b419b",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"cache/adapter-common": "^1.0",
|
||||
"league/flysystem": "^1.0",
|
||||
"php": ">=7.4",
|
||||
"psr/cache": "^1.0 || ^2.0",
|
||||
"psr/simple-cache": "^1.0"
|
||||
},
|
||||
"provide": {
|
||||
"psr/cache-implementation": "^1.0",
|
||||
"psr/simple-cache-implementation": "^1.0"
|
||||
},
|
||||
"require-dev": {
|
||||
"cache/integration-tests": "^0.17",
|
||||
"phpunit/phpunit": "^7.5.20 || ^9.5.10"
|
||||
},
|
||||
"time": "2022-01-15T15:47:19+00:00",
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "1.1-dev"
|
||||
}
|
||||
},
|
||||
"installation-source": "dist",
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Cache\\Adapter\\Filesystem\\": ""
|
||||
},
|
||||
"exclude-from-classmap": [
|
||||
"/Tests/"
|
||||
]
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Aaron Scherer",
|
||||
"email": "aequasi@gmail.com",
|
||||
"homepage": "https://github.com/aequasi"
|
||||
},
|
||||
{
|
||||
"name": "Tobias Nyholm",
|
||||
"email": "tobias.nyholm@gmail.com",
|
||||
"homepage": "https://github.com/nyholm"
|
||||
}
|
||||
],
|
||||
"description": "A PSR-6 cache implementation using filesystem. This implementation supports tags",
|
||||
"homepage": "http://www.php-cache.com/en/latest/",
|
||||
"keywords": [
|
||||
"cache",
|
||||
"filesystem",
|
||||
"psr-6",
|
||||
"tag"
|
||||
],
|
||||
"support": {
|
||||
"source": "https://github.com/php-cache/filesystem-adapter/tree/1.2.0"
|
||||
},
|
||||
"install-path": "../cache/filesystem-adapter"
|
||||
},
|
||||
{
|
||||
"name": "cache/tag-interop",
|
||||
"version": "1.1.0",
|
||||
"version_normalized": "1.1.0.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/php-cache/tag-interop.git",
|
||||
"reference": "b062b1d735357da50edf8387f7a8696f3027d328"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/php-cache/tag-interop/zipball/b062b1d735357da50edf8387f7a8696f3027d328",
|
||||
"reference": "b062b1d735357da50edf8387f7a8696f3027d328",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": "^5.5 || ^7.0 || ^8.0",
|
||||
"psr/cache": "^1.0 || ^2.0"
|
||||
},
|
||||
"time": "2021-12-31T10:03:23+00:00",
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "1.1-dev"
|
||||
}
|
||||
},
|
||||
"installation-source": "dist",
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Cache\\TagInterop\\": ""
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Tobias Nyholm",
|
||||
"email": "tobias.nyholm@gmail.com",
|
||||
"homepage": "https://github.com/nyholm"
|
||||
},
|
||||
{
|
||||
"name": "Nicolas Grekas",
|
||||
"email": "p@tchwork.com",
|
||||
"homepage": "https://github.com/nicolas-grekas"
|
||||
}
|
||||
],
|
||||
"description": "Framework interoperable interfaces for tags",
|
||||
"homepage": "https://www.php-cache.com/en/latest/",
|
||||
"keywords": [
|
||||
"cache",
|
||||
"psr",
|
||||
"psr6",
|
||||
"tag"
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/php-cache/tag-interop/issues",
|
||||
"source": "https://github.com/php-cache/tag-interop/tree/1.1.0"
|
||||
},
|
||||
"install-path": "../cache/tag-interop"
|
||||
},
|
||||
{
|
||||
"name": "dasprid/enum",
|
||||
"version": "1.0.3",
|
||||
@ -536,6 +740,163 @@
|
||||
],
|
||||
"install-path": "../guzzlehttp/psr7"
|
||||
},
|
||||
{
|
||||
"name": "jaeger/g-http",
|
||||
"version": "V1.7.2",
|
||||
"version_normalized": "1.7.2.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/jae-jae/GHttp.git",
|
||||
"reference": "82585ddd5e2c6651e37ab1d8166efcdbb6b293d4"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/jae-jae/GHttp/zipball/82585ddd5e2c6651e37ab1d8166efcdbb6b293d4",
|
||||
"reference": "82585ddd5e2c6651e37ab1d8166efcdbb6b293d4",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"cache/filesystem-adapter": "^1",
|
||||
"guzzlehttp/guzzle": "^6.0 | ^7.0"
|
||||
},
|
||||
"time": "2021-08-08T04:59:44+00:00",
|
||||
"type": "library",
|
||||
"installation-source": "dist",
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Jaeger\\": "src"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Jaeger",
|
||||
"email": "JaegerCode@gmail.com"
|
||||
}
|
||||
],
|
||||
"description": "Simple Http client base on GuzzleHttp",
|
||||
"support": {
|
||||
"issues": "https://github.com/jae-jae/GHttp/issues",
|
||||
"source": "https://github.com/jae-jae/GHttp/tree/V1.7.2"
|
||||
},
|
||||
"install-path": "../jaeger/g-http"
|
||||
},
|
||||
{
|
||||
"name": "jaeger/phpquery-single",
|
||||
"version": "1.1.1",
|
||||
"version_normalized": "1.1.1.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/jae-jae/phpQuery-single.git",
|
||||
"reference": "39a650ade692a6b480c22220dce0c198d6a946fb"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/jae-jae/phpQuery-single/zipball/39a650ade692a6b480c22220dce0c198d6a946fb",
|
||||
"reference": "39a650ade692a6b480c22220dce0c198d6a946fb",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": ">=5.3.0"
|
||||
},
|
||||
"time": "2022-03-26T15:01:16+00:00",
|
||||
"type": "library",
|
||||
"installation-source": "dist",
|
||||
"autoload": {
|
||||
"classmap": [
|
||||
"phpQuery.php"
|
||||
]
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Tobiasz Cudnik",
|
||||
"email": "tobiasz.cudnik@gmail.com",
|
||||
"homepage": "https://github.com/TobiaszCudnik",
|
||||
"role": "Developer"
|
||||
},
|
||||
{
|
||||
"name": "Jaeger",
|
||||
"role": "Packager"
|
||||
}
|
||||
],
|
||||
"description": "phpQuery单文件版本,是Querylist的依赖(http://querylist.cc/),phpQuery项目主页:http://code.google.com/p/phpquery/",
|
||||
"homepage": "http://code.google.com/p/phpquery/",
|
||||
"support": {
|
||||
"issues": "https://github.com/jae-jae/phpQuery-single/issues",
|
||||
"source": "https://github.com/jae-jae/phpQuery-single/tree/1.1.1"
|
||||
},
|
||||
"install-path": "../jaeger/phpquery-single"
|
||||
},
|
||||
{
|
||||
"name": "jaeger/querylist",
|
||||
"version": "V4.2.8",
|
||||
"version_normalized": "4.2.8.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/jae-jae/QueryList.git",
|
||||
"reference": "39dc0ca9c668bec7a793e20472ccd7d26ef89ea4"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/jae-jae/QueryList/zipball/39dc0ca9c668bec7a793e20472ccd7d26ef89ea4",
|
||||
"reference": "39dc0ca9c668bec7a793e20472ccd7d26ef89ea4",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"ext-dom": "*",
|
||||
"jaeger/g-http": "^1.1",
|
||||
"jaeger/phpquery-single": "^1",
|
||||
"php": ">=7.1",
|
||||
"tightenco/collect": ">5.0"
|
||||
},
|
||||
"require-dev": {
|
||||
"phpunit/phpunit": "^8.5",
|
||||
"symfony/var-dumper": "^3.3"
|
||||
},
|
||||
"time": "2021-07-05T06:07:58+00:00",
|
||||
"type": "library",
|
||||
"installation-source": "dist",
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"QL\\": "src"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Jaeger",
|
||||
"email": "JaegerCode@gmail.com"
|
||||
}
|
||||
],
|
||||
"description": "Simple, elegant, extensible PHP Web Scraper (crawler/spider),Use the css3 dom selector,Based on phpQuery! 简洁、优雅、可扩展的PHP采集工具(爬虫),基于phpQuery。",
|
||||
"homepage": "http://querylist.cc",
|
||||
"keywords": [
|
||||
"QueryList",
|
||||
"phpQuery",
|
||||
"spider"
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/jae-jae/QueryList/issues",
|
||||
"source": "https://github.com/jae-jae/QueryList/tree/V4.2.8"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
"url": "https://opencollective.com/querylist",
|
||||
"type": "open_collective"
|
||||
}
|
||||
],
|
||||
"install-path": "../jaeger/querylist"
|
||||
},
|
||||
{
|
||||
"name": "laravel/serializable-closure",
|
||||
"version": "v1.2.2",
|
||||
@ -2159,6 +2520,63 @@
|
||||
},
|
||||
"install-path": "../taoser/think-setarr"
|
||||
},
|
||||
{
|
||||
"name": "tightenco/collect",
|
||||
"version": "v8.83.23",
|
||||
"version_normalized": "8.83.23.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/tighten/collect.git",
|
||||
"reference": "a4423c6ace6b54ba4f86c0ac9de588c57bc94d79"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/tighten/collect/zipball/a4423c6ace6b54ba4f86c0ac9de588c57bc94d79",
|
||||
"reference": "a4423c6ace6b54ba4f86c0ac9de588c57bc94d79",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": "^7.3|^8.0",
|
||||
"symfony/var-dumper": "^3.4 || ^4.0 || ^5.0 || ^6.0"
|
||||
},
|
||||
"require-dev": {
|
||||
"mockery/mockery": "^1.0",
|
||||
"nesbot/carbon": "^2.23.0",
|
||||
"phpunit/phpunit": "^8.3"
|
||||
},
|
||||
"time": "2022-08-22T17:50:04+00:00",
|
||||
"type": "library",
|
||||
"installation-source": "dist",
|
||||
"autoload": {
|
||||
"files": [
|
||||
"src/Collect/Support/helpers.php",
|
||||
"src/Collect/Support/alias.php"
|
||||
],
|
||||
"psr-4": {
|
||||
"Tightenco\\Collect\\": "src/Collect"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Taylor Otwell",
|
||||
"email": "taylorotwell@gmail.com"
|
||||
}
|
||||
],
|
||||
"description": "Collect - Illuminate Collections as a separate package.",
|
||||
"keywords": [
|
||||
"collection",
|
||||
"laravel"
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/tighten/collect/issues",
|
||||
"source": "https://github.com/tighten/collect/tree/v8.83.23"
|
||||
},
|
||||
"install-path": "../tightenco/collect"
|
||||
},
|
||||
{
|
||||
"name": "topthink/framework",
|
||||
"version": "v6.0.13",
|
||||
@ -3075,10 +3493,6 @@
|
||||
],
|
||||
"dev": true,
|
||||
"dev-package-names": [
|
||||
"symfony/polyfill-mbstring",
|
||||
"symfony/polyfill-php72",
|
||||
"symfony/polyfill-php80",
|
||||
"symfony/var-dumper",
|
||||
"topthink/think-trace"
|
||||
]
|
||||
}
|
||||
|
87
vendor/composer/installed.php
vendored
87
vendor/composer/installed.php
vendored
@ -3,7 +3,7 @@
|
||||
'name' => 'taoser/taoler',
|
||||
'pretty_version' => 'dev-master',
|
||||
'version' => 'dev-master',
|
||||
'reference' => '2f7a73366c80586c404f620fc440626d4c033930',
|
||||
'reference' => '846581c3abfa893a57d4ce930c2fa684dfd688af',
|
||||
'type' => 'project',
|
||||
'install_path' => __DIR__ . '/../../',
|
||||
'aliases' => array(),
|
||||
@ -19,6 +19,33 @@
|
||||
'aliases' => array(),
|
||||
'dev_requirement' => false,
|
||||
),
|
||||
'cache/adapter-common' => array(
|
||||
'pretty_version' => '1.3.0',
|
||||
'version' => '1.3.0.0',
|
||||
'reference' => '8788309be72aa7be69b88cdc0687549c74a7d479',
|
||||
'type' => 'library',
|
||||
'install_path' => __DIR__ . '/../cache/adapter-common',
|
||||
'aliases' => array(),
|
||||
'dev_requirement' => false,
|
||||
),
|
||||
'cache/filesystem-adapter' => array(
|
||||
'pretty_version' => '1.2.0',
|
||||
'version' => '1.2.0.0',
|
||||
'reference' => 'f1faaae40aaa696ef899cef6f6888aedb90b419b',
|
||||
'type' => 'library',
|
||||
'install_path' => __DIR__ . '/../cache/filesystem-adapter',
|
||||
'aliases' => array(),
|
||||
'dev_requirement' => false,
|
||||
),
|
||||
'cache/tag-interop' => array(
|
||||
'pretty_version' => '1.1.0',
|
||||
'version' => '1.1.0.0',
|
||||
'reference' => 'b062b1d735357da50edf8387f7a8696f3027d328',
|
||||
'type' => 'library',
|
||||
'install_path' => __DIR__ . '/../cache/tag-interop',
|
||||
'aliases' => array(),
|
||||
'dev_requirement' => false,
|
||||
),
|
||||
'dasprid/enum' => array(
|
||||
'pretty_version' => '1.0.3',
|
||||
'version' => '1.0.3.0',
|
||||
@ -73,6 +100,33 @@
|
||||
'aliases' => array(),
|
||||
'dev_requirement' => false,
|
||||
),
|
||||
'jaeger/g-http' => array(
|
||||
'pretty_version' => 'V1.7.2',
|
||||
'version' => '1.7.2.0',
|
||||
'reference' => '82585ddd5e2c6651e37ab1d8166efcdbb6b293d4',
|
||||
'type' => 'library',
|
||||
'install_path' => __DIR__ . '/../jaeger/g-http',
|
||||
'aliases' => array(),
|
||||
'dev_requirement' => false,
|
||||
),
|
||||
'jaeger/phpquery-single' => array(
|
||||
'pretty_version' => '1.1.1',
|
||||
'version' => '1.1.1.0',
|
||||
'reference' => '39a650ade692a6b480c22220dce0c198d6a946fb',
|
||||
'type' => 'library',
|
||||
'install_path' => __DIR__ . '/../jaeger/phpquery-single',
|
||||
'aliases' => array(),
|
||||
'dev_requirement' => false,
|
||||
),
|
||||
'jaeger/querylist' => array(
|
||||
'pretty_version' => 'V4.2.8',
|
||||
'version' => '4.2.8.0',
|
||||
'reference' => '39dc0ca9c668bec7a793e20472ccd7d26ef89ea4',
|
||||
'type' => 'library',
|
||||
'install_path' => __DIR__ . '/../jaeger/querylist',
|
||||
'aliases' => array(),
|
||||
'dev_requirement' => false,
|
||||
),
|
||||
'laravel/serializable-closure' => array(
|
||||
'pretty_version' => 'v1.2.2',
|
||||
'version' => '1.2.2.0',
|
||||
@ -172,6 +226,12 @@
|
||||
'aliases' => array(),
|
||||
'dev_requirement' => false,
|
||||
),
|
||||
'psr/cache-implementation' => array(
|
||||
'dev_requirement' => false,
|
||||
'provided' => array(
|
||||
0 => '^1.0',
|
||||
),
|
||||
),
|
||||
'psr/container' => array(
|
||||
'pretty_version' => '1.1.2',
|
||||
'version' => '1.1.2.0',
|
||||
@ -244,6 +304,12 @@
|
||||
'aliases' => array(),
|
||||
'dev_requirement' => false,
|
||||
),
|
||||
'psr/simple-cache-implementation' => array(
|
||||
'dev_requirement' => false,
|
||||
'provided' => array(
|
||||
0 => '^1.0',
|
||||
),
|
||||
),
|
||||
'ralouphie/getallheaders' => array(
|
||||
'pretty_version' => '3.0.3',
|
||||
'version' => '3.0.3.0',
|
||||
@ -260,7 +326,7 @@
|
||||
'type' => 'library',
|
||||
'install_path' => __DIR__ . '/../symfony/polyfill-mbstring',
|
||||
'aliases' => array(),
|
||||
'dev_requirement' => true,
|
||||
'dev_requirement' => false,
|
||||
),
|
||||
'symfony/polyfill-php72' => array(
|
||||
'pretty_version' => 'v1.26.0',
|
||||
@ -269,7 +335,7 @@
|
||||
'type' => 'library',
|
||||
'install_path' => __DIR__ . '/../symfony/polyfill-php72',
|
||||
'aliases' => array(),
|
||||
'dev_requirement' => true,
|
||||
'dev_requirement' => false,
|
||||
),
|
||||
'symfony/polyfill-php80' => array(
|
||||
'pretty_version' => 'v1.26.0',
|
||||
@ -278,7 +344,7 @@
|
||||
'type' => 'library',
|
||||
'install_path' => __DIR__ . '/../symfony/polyfill-php80',
|
||||
'aliases' => array(),
|
||||
'dev_requirement' => true,
|
||||
'dev_requirement' => false,
|
||||
),
|
||||
'symfony/var-dumper' => array(
|
||||
'pretty_version' => 'v4.4.44',
|
||||
@ -287,12 +353,12 @@
|
||||
'type' => 'library',
|
||||
'install_path' => __DIR__ . '/../symfony/var-dumper',
|
||||
'aliases' => array(),
|
||||
'dev_requirement' => true,
|
||||
'dev_requirement' => false,
|
||||
),
|
||||
'taoser/taoler' => array(
|
||||
'pretty_version' => 'dev-master',
|
||||
'version' => 'dev-master',
|
||||
'reference' => '2f7a73366c80586c404f620fc440626d4c033930',
|
||||
'reference' => '846581c3abfa893a57d4ce930c2fa684dfd688af',
|
||||
'type' => 'project',
|
||||
'install_path' => __DIR__ . '/../../',
|
||||
'aliases' => array(),
|
||||
@ -325,6 +391,15 @@
|
||||
'aliases' => array(),
|
||||
'dev_requirement' => false,
|
||||
),
|
||||
'tightenco/collect' => array(
|
||||
'pretty_version' => 'v8.83.23',
|
||||
'version' => '8.83.23.0',
|
||||
'reference' => 'a4423c6ace6b54ba4f86c0ac9de588c57bc94d79',
|
||||
'type' => 'library',
|
||||
'install_path' => __DIR__ . '/../tightenco/collect',
|
||||
'aliases' => array(),
|
||||
'dev_requirement' => false,
|
||||
),
|
||||
'topthink/framework' => array(
|
||||
'pretty_version' => 'v6.0.13',
|
||||
'version' => '6.0.13.0',
|
||||
|
3
vendor/jaeger/g-http/.gitignore
vendored
Normal file
3
vendor/jaeger/g-http/.gitignore
vendored
Normal file
@ -0,0 +1,3 @@
|
||||
.idea
|
||||
/vendor/
|
||||
composer.lock
|
158
vendor/jaeger/g-http/README.md
vendored
Normal file
158
vendor/jaeger/g-http/README.md
vendored
Normal file
@ -0,0 +1,158 @@
|
||||
# GHttp
|
||||
基于GuzzleHttp的简单版Http客户端。 Simple Http client base on GuzzleHttp
|
||||
|
||||
## 安装
|
||||
|
||||
```
|
||||
composer require jaeger/g-http
|
||||
```
|
||||
|
||||
## 用法
|
||||
|
||||
#### 1. get / getJson
|
||||
```php
|
||||
|
||||
use Jaeger\GHttp;
|
||||
|
||||
$rt = GHttp::get('https://www.baidu.com/s?wd=QueryList');
|
||||
|
||||
$rt = GHttp::get('https://www.baidu.com/s','wd=QueryList&wd2=teststr');
|
||||
|
||||
//or
|
||||
|
||||
$rt = GHttp::get('https://www.baidu.com/s',[
|
||||
'wd' => 'QueryList',
|
||||
'wd2' => 'teststr'
|
||||
]);
|
||||
|
||||
//opt
|
||||
|
||||
$rt = GHttp::get('https://www.baidu.com/s',[
|
||||
'wd' => 'QueryList'
|
||||
],[
|
||||
'headers' => [
|
||||
'referer' => 'https://baidu.com',
|
||||
'User-Agent' => 'Mozilla/5.0 (Windows NTChrome/58.0.3029.110 Safari/537.36',
|
||||
'Cookie' => 'cookie xxx'
|
||||
]
|
||||
]);
|
||||
|
||||
$rt = GHttp::getJson('https://xxxx.com/json');
|
||||
|
||||
```
|
||||
|
||||
#### 2.post / postRaw / postJson
|
||||
```php
|
||||
$rt = GHttp::post('https://www.posttestserver.com/post.php',[
|
||||
'name' => 'QueryList',
|
||||
'password' => 'ql'
|
||||
]);
|
||||
|
||||
$rt = GHttp::post('https://www.posttestserver.com/post.php','name=QueryList&password=ql');
|
||||
|
||||
|
||||
$rt = GHttp::postRaw('http://httpbin.org/post','raw data');
|
||||
$rt = GHttp::postRaw('http://httpbin.org/post',['aa' => 11,'bb' => 22]);
|
||||
|
||||
|
||||
$rt = GHttp::postJson('http://httpbin.org/post',['aa' => 11,'bb' => 22]);
|
||||
$rt = GHttp::postJson('http://httpbin.org/post','aa=11&bb=22');
|
||||
|
||||
```
|
||||
#### 3.download
|
||||
|
||||
```php
|
||||
GHttp::download('http://sw.bos.baidu.com/setup.exe','./path/to/xx.exe');
|
||||
```
|
||||
### 4. concurrent requests
|
||||
```php
|
||||
use Jaeger\GHttp;
|
||||
|
||||
$urls = [
|
||||
'http://httpbin.org/get?name=php',
|
||||
'http://httpbin.org/get?name=go',
|
||||
'http://httpbin.org/get?name=c#',
|
||||
'http://httpbin.org/get?name=java'
|
||||
];
|
||||
|
||||
GHttp::multiRequest($urls)->withHeaders([
|
||||
'X-Powered-By' => 'Jaeger'
|
||||
])->withOptions([
|
||||
'timeout' => 10
|
||||
])->concurrency(2)->success(function($response,$index){
|
||||
print_r((String)$response->getBody());
|
||||
print_r($index);
|
||||
})->error(function($reason,$index){
|
||||
print_r($reason);
|
||||
})->get();
|
||||
```
|
||||
|
||||
```php
|
||||
use Jaeger\GHttp;
|
||||
use GuzzleHttp\Psr7\Request;
|
||||
|
||||
$requests = [
|
||||
new Request('POST','http://httpbin.org/post',[
|
||||
'Content-Type' => 'application/x-www-form-urlencoded',
|
||||
'User-Agent' => 'g-http'
|
||||
],http_build_query([
|
||||
'name' => 'php'
|
||||
])),
|
||||
new Request('POST','http://httpbin.org/post',[
|
||||
'Content-Type' => 'application/x-www-form-urlencoded',
|
||||
'User-Agent' => 'g-http'
|
||||
],http_build_query([
|
||||
'name' => 'go'
|
||||
])),
|
||||
new Request('POST','http://httpbin.org/post',[
|
||||
'Content-Type' => 'application/x-www-form-urlencoded',
|
||||
'User-Agent' => 'g-http'
|
||||
],http_build_query([
|
||||
'name' => 'c#'
|
||||
]))
|
||||
];
|
||||
|
||||
GHttp::multiRequest($requests)->success(function($response,$index){
|
||||
print_r((String)$response->getBody());
|
||||
print_r($index);
|
||||
})->post();
|
||||
```
|
||||
### 5. Request with cache
|
||||
|
||||
Base on PHP-Cache: http://www.php-cache.com
|
||||
|
||||
- Use filesystem cache
|
||||
```php
|
||||
use Jaeger\GHttp;
|
||||
|
||||
$rt = GHttp::get('http://httpbin.org/get',[
|
||||
'wd' => 'QueryList'
|
||||
],[
|
||||
'cache' => __DIR__,
|
||||
'cache_ttl' => 120 //seconds
|
||||
]);
|
||||
|
||||
```
|
||||
|
||||
- Use predis cache
|
||||
|
||||
Install predis adapter:
|
||||
```
|
||||
composer require cache/predis-adapter
|
||||
```
|
||||
|
||||
Usage:
|
||||
```php
|
||||
use Jaeger\GHttp;
|
||||
use Cache\Adapter\Predis\PredisCachePool;
|
||||
|
||||
$client = new \Predis\Client('tcp:/127.0.0.1:6379');
|
||||
$pool = new PredisCachePool($client);
|
||||
|
||||
$rt = GHttp::get('http://httpbin.org/get',[
|
||||
'wd' => 'QueryList'
|
||||
],[
|
||||
'cache' => $pool,
|
||||
'cache_ttl' => 120 //seconds
|
||||
]);
|
||||
```
|
20
vendor/jaeger/g-http/composer.json
vendored
Normal file
20
vendor/jaeger/g-http/composer.json
vendored
Normal file
@ -0,0 +1,20 @@
|
||||
{
|
||||
"name": "jaeger/g-http",
|
||||
"description": "Simple Http client base on GuzzleHttp",
|
||||
"license": "MIT",
|
||||
"authors": [
|
||||
{
|
||||
"name": "Jaeger",
|
||||
"email": "JaegerCode@gmail.com"
|
||||
}
|
||||
],
|
||||
"require": {
|
||||
"cache/filesystem-adapter": "^1",
|
||||
"guzzlehttp/guzzle": "^6.0 | ^7.0"
|
||||
},
|
||||
"autoload":{
|
||||
"psr-4":{
|
||||
"Jaeger\\":"src"
|
||||
}
|
||||
}
|
||||
}
|
27
vendor/jaeger/g-http/examples/multi_request.php
vendored
Normal file
27
vendor/jaeger/g-http/examples/multi_request.php
vendored
Normal file
@ -0,0 +1,27 @@
|
||||
<?php
|
||||
/**
|
||||
* Created by PhpStorm.
|
||||
* User: Jaeger <JaegerCode@gmail.com>
|
||||
* Date: 18/12/10
|
||||
* Time: 下午4:04
|
||||
*/
|
||||
require __DIR__.'/../vendor/autoload.php';
|
||||
use Jaeger\GHttp;
|
||||
|
||||
$urls = [
|
||||
'http://httpbin.org/get?name=php',
|
||||
'http://httpbin.org/get?name=go',
|
||||
'http://httpbin.org/get?name=c#',
|
||||
'http://httpbin.org/get?name=java'
|
||||
];
|
||||
|
||||
GHttp::multiRequest($urls)->withHeaders([
|
||||
'X-Powered-By' => 'Jaeger'
|
||||
])->withOptions([
|
||||
'timeout' => 10
|
||||
])->concurrency(2)->success(function($response,$index){
|
||||
print_r((String)$response->getBody());
|
||||
print_r($index);
|
||||
})->error(function($reason,$index){
|
||||
print_r($reason);
|
||||
})->get();
|
37
vendor/jaeger/g-http/examples/multi_request_2.php
vendored
Normal file
37
vendor/jaeger/g-http/examples/multi_request_2.php
vendored
Normal file
@ -0,0 +1,37 @@
|
||||
<?php
|
||||
/**
|
||||
* Created by PhpStorm.
|
||||
* User: Jaeger <JaegerCode@gmail.com>
|
||||
* Date: 18/12/10
|
||||
* Time: 下午6:51
|
||||
*/
|
||||
|
||||
require __DIR__.'/../vendor/autoload.php';
|
||||
use Jaeger\GHttp;
|
||||
use GuzzleHttp\Psr7\Request;
|
||||
|
||||
$requests = [
|
||||
new Request('POST','http://httpbin.org/post',[
|
||||
'Content-Type' => 'application/x-www-form-urlencoded',
|
||||
'User-Agent' => 'g-http'
|
||||
],http_build_query([
|
||||
'name' => 'php'
|
||||
])),
|
||||
new Request('POST','http://httpbin.org/post',[
|
||||
'Content-Type' => 'application/x-www-form-urlencoded',
|
||||
'User-Agent' => 'g-http'
|
||||
],http_build_query([
|
||||
'name' => 'go'
|
||||
])),
|
||||
new Request('POST','http://httpbin.org/post',[
|
||||
'Content-Type' => 'application/x-www-form-urlencoded',
|
||||
'User-Agent' => 'g-http'
|
||||
],http_build_query([
|
||||
'name' => 'c#'
|
||||
]))
|
||||
];
|
||||
|
||||
GHttp::multiRequest($requests)->success(function($response,$index){
|
||||
print_r((String)$response->getBody());
|
||||
print_r($index);
|
||||
})->post();
|
33
vendor/jaeger/g-http/examples/request_with_cache.php
vendored
Normal file
33
vendor/jaeger/g-http/examples/request_with_cache.php
vendored
Normal file
@ -0,0 +1,33 @@
|
||||
<?php
|
||||
/**
|
||||
* Created by PhpStorm.
|
||||
* User: Jaeger <JaegerCode@gmail.com>
|
||||
* Date: 18/12/11
|
||||
* Time: 下午6:48
|
||||
*/
|
||||
|
||||
require __DIR__.'/../vendor/autoload.php';
|
||||
use Jaeger\GHttp;
|
||||
use Cache\Adapter\Predis\PredisCachePool;
|
||||
|
||||
|
||||
$rt = GHttp::get('http://httpbin.org/get',[
|
||||
'wd' => 'QueryList'
|
||||
],[
|
||||
'cache' => __DIR__,
|
||||
'cache_ttl' => 120
|
||||
]);
|
||||
|
||||
print_r($rt);
|
||||
|
||||
$client = new \Predis\Client('tcp:/127.0.0.1:6379');
|
||||
$pool = new PredisCachePool($client);
|
||||
|
||||
$rt = GHttp::get('http://httpbin.org/get',[
|
||||
'wd' => 'QueryList'
|
||||
],[
|
||||
'cache' => $pool,
|
||||
'cache_ttl' => 120
|
||||
]);
|
||||
|
||||
print_r($rt);
|
22
vendor/jaeger/g-http/examples/simple.php
vendored
Normal file
22
vendor/jaeger/g-http/examples/simple.php
vendored
Normal file
@ -0,0 +1,22 @@
|
||||
<?php
|
||||
/**
|
||||
* Created by PhpStorm.
|
||||
* User: Jaeger <JaegerCode@gmail.com>
|
||||
* Date: 18/12/11
|
||||
* Time: 下午6:48
|
||||
*/
|
||||
|
||||
require __DIR__.'/../vendor/autoload.php';
|
||||
use Jaeger\GHttp;
|
||||
|
||||
$rt = GHttp::get('http://httpbin.org/get',[
|
||||
'wd' => 'QueryList'
|
||||
],[
|
||||
'headers' => [
|
||||
'referer' => 'https://baidu.com',
|
||||
'User-Agent' => 'Mozilla/5.0 (Windows NTChrome/58.0.3029.110 Safari/537.36',
|
||||
'Cookie' => 'cookie xxx'
|
||||
],
|
||||
]);
|
||||
|
||||
print_r($rt);
|
65
vendor/jaeger/g-http/src/Cache.php
vendored
Normal file
65
vendor/jaeger/g-http/src/Cache.php
vendored
Normal file
@ -0,0 +1,65 @@
|
||||
<?php
|
||||
/**
|
||||
* Created by PhpStorm.
|
||||
* User: Jaeger <JaegerCode@gmail.com>
|
||||
* Date: 18/12/11
|
||||
* Time: 下午6:39
|
||||
*/
|
||||
|
||||
namespace Jaeger;
|
||||
|
||||
|
||||
use Cache\Adapter\Common\AbstractCachePool;
|
||||
use Cache\Adapter\Filesystem\FilesystemCachePool;
|
||||
use League\Flysystem\Adapter\Local;
|
||||
use League\Flysystem\Filesystem;
|
||||
|
||||
class Cache extends GHttp
|
||||
{
|
||||
public static function remember($name, $arguments)
|
||||
{
|
||||
$cachePool = null;
|
||||
$cacheConfig = self::initCacheConfig($arguments);
|
||||
|
||||
if (empty($cacheConfig['cache'])) {
|
||||
return self::$name(...$arguments);
|
||||
}
|
||||
if (is_string($cacheConfig['cache'])) {
|
||||
$filesystemAdapter = new Local($cacheConfig['cache']);
|
||||
$filesystem = new Filesystem($filesystemAdapter);
|
||||
$cachePool = new FilesystemCachePool($filesystem);
|
||||
}else if ($cacheConfig['cache'] instanceof AbstractCachePool) {
|
||||
$cachePool = $cacheConfig['cache'];
|
||||
}
|
||||
|
||||
$cacheKey = self::getCacheKey($name,$arguments);
|
||||
$data = $cachePool->get($cacheKey);
|
||||
if(empty($data)) {
|
||||
$data = self::$name(...$arguments);
|
||||
if(!empty($data)) {
|
||||
$cachePool->set($cacheKey,$data,$cacheConfig['cache_ttl']);
|
||||
}
|
||||
}
|
||||
return $data;
|
||||
}
|
||||
|
||||
protected static function initCacheConfig($arguments)
|
||||
{
|
||||
$cacheConfig = [
|
||||
'cache' => null,
|
||||
'cache_ttl' => null
|
||||
];
|
||||
if(!empty($arguments[2])) {
|
||||
$cacheConfig = array_merge([
|
||||
'cache' => null,
|
||||
'cache_ttl' => null
|
||||
],$arguments[2]);
|
||||
}
|
||||
return $cacheConfig;
|
||||
}
|
||||
|
||||
protected static function getCacheKey($name, $arguments)
|
||||
{
|
||||
return md5($name.'_'.json_encode($arguments));
|
||||
}
|
||||
}
|
164
vendor/jaeger/g-http/src/GHttp.php
vendored
Normal file
164
vendor/jaeger/g-http/src/GHttp.php
vendored
Normal file
@ -0,0 +1,164 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* 基于GuzzleHttp的简单版Http客户端。 Simple Http client base on GuzzleHttp
|
||||
*
|
||||
* @Author: Jaeger <JaegerCode@gmail.com>
|
||||
*
|
||||
* @Version V1.0
|
||||
*/
|
||||
|
||||
namespace Jaeger;
|
||||
|
||||
use GuzzleHttp\Client;
|
||||
|
||||
/**
|
||||
* Class GHttp
|
||||
* @package Jaeger
|
||||
*
|
||||
* @method static string get($url,$args = null,$otherArgs = [])
|
||||
* @method static mixed getJson($url, $args = null, $otherArgs = [])
|
||||
* @method static string post($url,$args = null,$otherArgs = [])
|
||||
* @method static string postRaw($url, $raw = null, $otherArgs = [])
|
||||
* @method static string postJson($url, $args = null, $otherArgs = [])
|
||||
*/
|
||||
class GHttp
|
||||
{
|
||||
private static $client = null;
|
||||
|
||||
public static function __callStatic($name, $arguments)
|
||||
{
|
||||
$protectedName = '_'.$name;
|
||||
if(method_exists(self::class,$protectedName)){
|
||||
return Cache::remember($protectedName, $arguments);
|
||||
}
|
||||
throw new MethodNotFoundException('Call undefined method '.self::class.':'.$name.'()');
|
||||
}
|
||||
|
||||
public static function getClient(array $config = [])
|
||||
{
|
||||
if(self::$client == null){
|
||||
self::$client = new Client($config);
|
||||
}
|
||||
return self::$client;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $url
|
||||
* @param array $args
|
||||
* @param array $otherArgs
|
||||
* @return string
|
||||
*/
|
||||
protected static function _get($url,$args = null,$otherArgs = [])
|
||||
{
|
||||
is_string($args) && parse_str($args,$args);
|
||||
$args = array_merge([
|
||||
'verify' => false,
|
||||
'query' => $args,
|
||||
'headers' => [
|
||||
'referer' => $url,
|
||||
'User-Agent' => 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.36'
|
||||
]
|
||||
],$otherArgs);
|
||||
$client = self::getClient();
|
||||
$response = $client->request('GET', $url,$args);
|
||||
return (string)$response->getBody();
|
||||
}
|
||||
|
||||
protected static function _getJson($url, $args = null, $otherArgs = [])
|
||||
{
|
||||
$data = self::get($url, $args , $otherArgs);
|
||||
return json_decode($data,JSON_UNESCAPED_UNICODE);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $url
|
||||
* @param array $args
|
||||
* @param array $otherArgs
|
||||
* @return string
|
||||
*/
|
||||
protected static function _post($url,$args = null,$otherArgs = [])
|
||||
{
|
||||
is_string($args) && parse_str($args,$args);
|
||||
$args = array_merge([
|
||||
'verify' => false,
|
||||
'form_params' => $args,
|
||||
'headers' => [
|
||||
'referer' => $url,
|
||||
'User-Agent' => 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.36'
|
||||
]
|
||||
],$otherArgs);
|
||||
$client = self::getClient();
|
||||
$response = $client->request('Post', $url,$args);
|
||||
return (string)$response->getBody();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $url
|
||||
* @param null $raw
|
||||
* @param array $otherArgs
|
||||
* @return string
|
||||
*/
|
||||
protected static function _postRaw($url, $raw = null, $otherArgs = [])
|
||||
{
|
||||
is_array($raw) && $raw = json_encode($raw);
|
||||
$args = array_merge([
|
||||
'verify' => false,
|
||||
'body' => $raw,
|
||||
'headers' => [
|
||||
'referer' => $url,
|
||||
'User-Agent' => 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.36'
|
||||
]
|
||||
],$otherArgs);
|
||||
$client = self::getClient();
|
||||
$response = $client->request('Post', $url,$args);
|
||||
return (string)$response->getBody();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $url
|
||||
* @param null $args
|
||||
* @param array $otherArgs
|
||||
* @return string
|
||||
*/
|
||||
protected static function _postJson($url, $args = null, $otherArgs = [])
|
||||
{
|
||||
is_string($args) && parse_str($args,$args);
|
||||
$args = array_merge([
|
||||
'verify' => false,
|
||||
'json' => $args,
|
||||
'headers' => [
|
||||
'referer' => $url,
|
||||
'User-Agent' => 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.36'
|
||||
]
|
||||
],$otherArgs);
|
||||
$client = self::getClient();
|
||||
$response = $client->request('Post', $url,$args);
|
||||
return (string)$response->getBody();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $url
|
||||
* @param $filePath
|
||||
* @param null $args
|
||||
* @param array $otherArgs
|
||||
* @return string
|
||||
*/
|
||||
public static function download($url,$filePath,$args = null,$otherArgs = [])
|
||||
{
|
||||
$otherArgs = array_merge($otherArgs,[
|
||||
'sink' => $filePath,
|
||||
]);
|
||||
return self::get($url,$args,$otherArgs);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $urls
|
||||
* @return MultiRequest
|
||||
*/
|
||||
public static function multiRequest($urls)
|
||||
{
|
||||
$client = self::getClient();
|
||||
return MultiRequest::newRequest($client)->urls($urls);
|
||||
}
|
||||
}
|
19
vendor/jaeger/g-http/src/MethodNotFoundException.php
vendored
Normal file
19
vendor/jaeger/g-http/src/MethodNotFoundException.php
vendored
Normal file
@ -0,0 +1,19 @@
|
||||
<?php
|
||||
/**
|
||||
* Created by PhpStorm.
|
||||
* User: Jaeger <JaegerCode@gmail.com>
|
||||
* Date: 18/12/12
|
||||
* Time: 上午10:56
|
||||
*/
|
||||
|
||||
namespace Jaeger;
|
||||
use Exception;
|
||||
use Throwable;
|
||||
|
||||
class MethodNotFoundException extends Exception
|
||||
{
|
||||
public function __construct($message = "", $code = 0, Throwable $previous = null)
|
||||
{
|
||||
parent::__construct($message, $code, $previous);
|
||||
}
|
||||
}
|
113
vendor/jaeger/g-http/src/MultiRequest.php
vendored
Normal file
113
vendor/jaeger/g-http/src/MultiRequest.php
vendored
Normal file
@ -0,0 +1,113 @@
|
||||
<?php
|
||||
/**
|
||||
* Created by PhpStorm.
|
||||
* User: Jaeger <JaegerCode@gmail.com>
|
||||
* Date: 18/12/10
|
||||
* Time: 下午6:04
|
||||
*/
|
||||
|
||||
namespace Jaeger;
|
||||
use GuzzleHttp\Client;
|
||||
use Closure;
|
||||
use GuzzleHttp\Pool;
|
||||
use GuzzleHttp\Psr7\Request;
|
||||
|
||||
class MultiRequest
|
||||
{
|
||||
protected $client;
|
||||
protected $headers = [];
|
||||
protected $options = [];
|
||||
protected $successCallback;
|
||||
protected $errorCallback;
|
||||
protected $urls = [];
|
||||
protected $method;
|
||||
protected $concurrency = 5;
|
||||
|
||||
public function __construct(Client $client)
|
||||
{
|
||||
$this->client = $client;
|
||||
$this->headers = [
|
||||
'User-Agent' => 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.36'
|
||||
];
|
||||
}
|
||||
|
||||
public static function newRequest(Client $client)
|
||||
{
|
||||
$request = new self($client);
|
||||
return $request;
|
||||
}
|
||||
|
||||
public function withHeaders($headers)
|
||||
{
|
||||
$this->headers = array_merge($this->headers,$headers);
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function withOptions($options)
|
||||
{
|
||||
$this->options = $options;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function concurrency($concurrency)
|
||||
{
|
||||
$this->concurrency = $concurrency;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function success(Closure $success)
|
||||
{
|
||||
$this->successCallback = $success;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function error(Closure $error)
|
||||
{
|
||||
$this->errorCallback = $error;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function urls(array $urls)
|
||||
{
|
||||
$this->urls = $urls;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function get()
|
||||
{
|
||||
$this->method = 'GET';
|
||||
$this->send();
|
||||
}
|
||||
|
||||
public function post()
|
||||
{
|
||||
$this->method = 'POST';
|
||||
$this->send();
|
||||
}
|
||||
|
||||
protected function send()
|
||||
{
|
||||
$client = $this->client;
|
||||
|
||||
$requests = function ($urls) use($client){
|
||||
foreach ($urls as $url) {
|
||||
if (is_string($url)) {
|
||||
yield new Request($this->method,$url,$this->headers);
|
||||
} else {
|
||||
yield $url;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
$pool = new Pool($client, $requests($this->urls), [
|
||||
'concurrency' => $this->concurrency,
|
||||
'fulfilled' => $this->successCallback,
|
||||
'rejected' => $this->errorCallback,
|
||||
'options' => $this->options
|
||||
]);
|
||||
|
||||
$promise = $pool->promise();
|
||||
$promise->wait();
|
||||
}
|
||||
|
||||
}
|
36
vendor/jaeger/phpquery-single/README.md
vendored
Normal file
36
vendor/jaeger/phpquery-single/README.md
vendored
Normal file
@ -0,0 +1,36 @@
|
||||
# phpQuery-single
|
||||
phpQuery onefile composer.Continuous maintenance,Welcome PR.
|
||||
|
||||
`QueryList` base on phpQuery: https://github.com/jae-jae/QueryList
|
||||
|
||||
phpQuery单文件版本,持续维护,欢迎PR.
|
||||
> phpQuery项目主页:http://code.google.com/p/phpquery/
|
||||
|
||||
`QueryList`是基于phpQuery的采集工具: https://github.com/jae-jae/QueryList
|
||||
|
||||
## Composer Installation
|
||||
Packagist: https://packagist.org/packages/jaeger/phpquery-single
|
||||
```
|
||||
composer require jaeger/phpquery-single
|
||||
```
|
||||
|
||||
## Usage
|
||||
```php
|
||||
$html = <<<STR
|
||||
<div id="one">
|
||||
<div class="two">
|
||||
<a href="http://querylist.cc">QueryList官网</a>
|
||||
<img src="http://querylist.cc/1.jpg" alt="这是图片">
|
||||
<img src="http://querylist.cc/2.jpg" alt="这是图片2">
|
||||
</div>
|
||||
<span>其它的<b>一些</b>文本</span>
|
||||
</div>
|
||||
STR;
|
||||
|
||||
$doc = phpQuery::newDocumentHTML($html);
|
||||
|
||||
$src = $doc->find('.two img:eq(0)')->attr('src');
|
||||
|
||||
echo $src;
|
||||
// http://querylist.cc/1.jpg
|
||||
```
|
24
vendor/jaeger/phpquery-single/composer.json
vendored
Normal file
24
vendor/jaeger/phpquery-single/composer.json
vendored
Normal file
@ -0,0 +1,24 @@
|
||||
{
|
||||
"name": "jaeger/phpquery-single",
|
||||
"description": "phpQuery单文件版本,是Querylist的依赖(http://querylist.cc/),phpQuery项目主页:http://code.google.com/p/phpquery/",
|
||||
"homepage": "http://code.google.com/p/phpquery/",
|
||||
"license": "MIT",
|
||||
"require": {
|
||||
"PHP":">=5.3.0"
|
||||
},
|
||||
"authors": [
|
||||
{
|
||||
"name": "Tobiasz Cudnik"
|
||||
,"email": "tobiasz.cudnik@gmail.com"
|
||||
,"homepage": "https://github.com/TobiaszCudnik"
|
||||
,"role": "Developer"
|
||||
}
|
||||
,{
|
||||
"name": "Jaeger",
|
||||
"role": "Packager"
|
||||
}
|
||||
],
|
||||
"autoload":{
|
||||
"classmap":["phpQuery.php"]
|
||||
}
|
||||
}
|
6086
vendor/jaeger/phpquery-single/phpQuery.php
vendored
Normal file
6086
vendor/jaeger/phpquery-single/phpQuery.php
vendored
Normal file
File diff suppressed because it is too large
Load Diff
12
vendor/jaeger/querylist/.github/FUNDING.yml
vendored
Normal file
12
vendor/jaeger/querylist/.github/FUNDING.yml
vendored
Normal file
@ -0,0 +1,12 @@
|
||||
# These are supported funding model platforms
|
||||
|
||||
github: # Replace with up to 4 GitHub Sponsors-enabled usernames e.g., [user1, user2]
|
||||
patreon: # Replace with a single Patreon username
|
||||
open_collective: querylist # Replace with a single Open Collective username
|
||||
ko_fi: # Replace with a single Ko-fi username
|
||||
tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel
|
||||
community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry
|
||||
liberapay: # Replace with a single Liberapay username
|
||||
issuehunt: # Replace with a single IssueHunt username
|
||||
otechie: # Replace with a single Otechie username
|
||||
custom: # Replace with up to 4 custom sponsorship URLs e.g., ['link1', 'link2']
|
5
vendor/jaeger/querylist/.gitignore
vendored
Normal file
5
vendor/jaeger/querylist/.gitignore
vendored
Normal file
@ -0,0 +1,5 @@
|
||||
/vendor/
|
||||
.idea/
|
||||
composer.lock
|
||||
.DS_Store
|
||||
*.cache
|
309
vendor/jaeger/querylist/README-ZH.md
vendored
Normal file
309
vendor/jaeger/querylist/README-ZH.md
vendored
Normal file
@ -0,0 +1,309 @@
|
||||
<p align="center">
|
||||
<img width="150" src="logo.png" alt="QueryList">
|
||||
<br>
|
||||
<br>
|
||||
</p>
|
||||
|
||||
# QueryList 简介
|
||||
`QueryList`是一套简洁、优雅、可扩展的PHP采集工具(爬虫),基于phpQuery。
|
||||
|
||||
## 特性
|
||||
- 拥有与jQuery完全相同的CSS3 DOM选择器
|
||||
- 拥有与jQuery完全相同的DOM操作API
|
||||
- 拥有通用的列表采集方案
|
||||
- 拥有强大的HTTP请求套件,轻松实现如:模拟登陆、伪造浏览器、HTTP代理等意复杂的网络请求
|
||||
- 拥有乱码解决方案
|
||||
- 拥有强大的内容过滤功能,可使用jQuey选择器来过滤内容
|
||||
- 拥有高度的模块化设计,扩展性强
|
||||
- 拥有富有表现力的API
|
||||
- 拥有高质量文档
|
||||
- 拥有丰富的插件
|
||||
- 拥有专业的问答社区和交流群
|
||||
|
||||
通过插件可以轻松实现诸如:
|
||||
- 多线程采集
|
||||
- 采集JavaScript动态渲染的页面 (PhantomJS/headless WebKit)
|
||||
- 图片本地化
|
||||
- 模拟浏览器行为,如:提交Form表单
|
||||
- 网络爬虫
|
||||
- .....
|
||||
|
||||
## 环境要求
|
||||
- PHP >= 7.1
|
||||
|
||||
> 如果你的PHP版本还停留在PHP5,或者不会使用Composer,你可以选择使用QueryList3,QueryList3支持php5.3以及手动安装。
|
||||
QueryList3 文档:http://v3.querylist.cc
|
||||
|
||||
## 安装
|
||||
通过Composer安装:
|
||||
```
|
||||
composer require jaeger/querylist
|
||||
```
|
||||
|
||||
## 使用
|
||||
|
||||
#### 元素操作
|
||||
- 采集「昵图网」所有图片地址
|
||||
|
||||
```php
|
||||
QueryList::get('http://www.nipic.com')->find('img')->attrs('src');
|
||||
```
|
||||
- 采集百度搜索结果
|
||||
|
||||
```php
|
||||
$ql = QueryList::get('http://www.baidu.com/s?wd=QueryList');
|
||||
|
||||
$ql->find('title')->text(); // 获取网站标题
|
||||
$ql->find('meta[name=keywords]')->content; // 获取网站头部关键词
|
||||
|
||||
$ql->find('h3>a')->texts(); //获取搜索结果标题列表
|
||||
$ql->find('h3>a')->attrs('href'); //获取搜索结果链接列表
|
||||
|
||||
$ql->find('img')->src; //获取第一张图片的链接地址
|
||||
$ql->find('img:eq(1)')->src; //获取第二张图片的链接地址
|
||||
$ql->find('img')->eq(2)->src; //获取第三张图片的链接地址
|
||||
// 遍历所有图片
|
||||
$ql->find('img')->map(function($img){
|
||||
echo $img->alt; //打印图片的alt属性
|
||||
});
|
||||
```
|
||||
- 更多用法
|
||||
|
||||
```php
|
||||
$ql->find('#head')->append('<div>追加内容</div>')->find('div')->htmls();
|
||||
$ql->find('.two')->children('img')->attrs('alt'); //获取class为two元素下的所有img孩子节点
|
||||
//遍历class为two元素下的所有孩子节点
|
||||
$data = $ql->find('.two')->children()->map(function ($item){
|
||||
//用is判断节点类型
|
||||
if($item->is('a')){
|
||||
return $item->text();
|
||||
}elseif($item->is('img'))
|
||||
{
|
||||
return $item->alt;
|
||||
}
|
||||
});
|
||||
|
||||
$ql->find('a')->attr('href', 'newVal')->removeClass('className')->html('newHtml')->...
|
||||
$ql->find('div > p')->add('div > ul')->filter(':has(a)')->find('p:first')->nextAll()->andSelf()->...
|
||||
$ql->find('div.old')->replaceWith( $ql->find('div.new')->clone())->appendTo('.trash')->prepend('Deleted')->...
|
||||
```
|
||||
#### 列表采集
|
||||
采集百度搜索结果列表的标题和链接:
|
||||
```php
|
||||
$data = QueryList::get('http://www.baidu.com/s?wd=QueryList')
|
||||
// 设置采集规则
|
||||
->rules([
|
||||
'title'=>array('h3','text'),
|
||||
'link'=>array('h3>a','href')
|
||||
])
|
||||
->query()->getData();
|
||||
|
||||
print_r($data->all());
|
||||
```
|
||||
采集结果:
|
||||
```
|
||||
Array
|
||||
(
|
||||
[0] => Array
|
||||
(
|
||||
[title] => QueryList|基于phpQuery的无比强大的PHP采集工具
|
||||
[link] => http://www.baidu.com/link?url=GU_YbDT2IHk4ns1tjG2I8_vjmH0SCJEAPuuZN
|
||||
)
|
||||
[1] => Array
|
||||
(
|
||||
[title] => PHP 用QueryList抓取网页内容 - wb145230 - 博客园
|
||||
[link] => http://www.baidu.com/link?url=zn0DXBnrvIF2ibRVW34KcRVFG1_bCdZvqvwIhUqiXaS
|
||||
)
|
||||
[2] => Array
|
||||
(
|
||||
[title] => 介绍- QueryList指导文档
|
||||
[link] => http://www.baidu.com/link?url=pSypvMovqS4v2sWeQo5fDBJ4EoYhXYi0Lxx
|
||||
)
|
||||
//...
|
||||
)
|
||||
```
|
||||
#### 编码转换
|
||||
```php
|
||||
// 输出编码:UTF-8,输入编码:GB2312
|
||||
QueryList::get('https://top.etao.com')->encoding('UTF-8','GB2312')->find('a')->texts();
|
||||
|
||||
// 输出编码:UTF-8,输入编码:自动识别
|
||||
QueryList::get('https://top.etao.com')->encoding('UTF-8')->find('a')->texts();
|
||||
```
|
||||
|
||||
#### HTTP网络操作(GuzzleHttp)
|
||||
- 携带cookie登录新浪微博
|
||||
```php
|
||||
//采集新浪微博需要登录才能访问的页面
|
||||
$ql = QueryList::get('http://weibo.com','param1=testvalue & params2=somevalue',[
|
||||
'headers' => [
|
||||
//填写从浏览器获取到的cookie
|
||||
'Cookie' => 'SINAGLOBAL=546064; wb_cmtLike_2112031=1; wvr=6;....'
|
||||
]
|
||||
]);
|
||||
//echo $ql->getHtml();
|
||||
echo $ql->find('title')->text();
|
||||
//输出: 我的首页 微博-随时随地发现新鲜事
|
||||
```
|
||||
- 使用Http代理
|
||||
```php
|
||||
$urlParams = ['param1' => 'testvalue','params2' => 'somevalue'];
|
||||
$opts = [
|
||||
// 设置http代理
|
||||
'proxy' => 'http://222.141.11.17:8118',
|
||||
//设置超时时间,单位:秒
|
||||
'timeout' => 30,
|
||||
// 伪造http头
|
||||
'headers' => [
|
||||
'Referer' => 'https://querylist.cc/',
|
||||
'User-Agent' => 'testing/1.0',
|
||||
'Accept' => 'application/json',
|
||||
'X-Foo' => ['Bar', 'Baz'],
|
||||
'Cookie' => 'abc=111;xxx=222'
|
||||
]
|
||||
];
|
||||
$ql->get('http://httpbin.org/get',$urlParams,$opts);
|
||||
// echo $ql->getHtml();
|
||||
```
|
||||
|
||||
- 模拟登录
|
||||
```php
|
||||
// 用post登录
|
||||
$ql = QueryList::post('http://xxxx.com/login',[
|
||||
'username' => 'admin',
|
||||
'password' => '123456'
|
||||
])->get('http://xxx.com/admin');
|
||||
//采集需要登录才能访问的页面
|
||||
$ql->get('http://xxx.com/admin/page');
|
||||
//echo $ql->getHtml();
|
||||
```
|
||||
|
||||
#### Form表单操作
|
||||
模拟登陆GitHub
|
||||
```php
|
||||
// 获取QueryList实例
|
||||
$ql = QueryList::getInstance();
|
||||
//获取到登录表单
|
||||
$form = $ql->get('https://github.com/login')->find('form');
|
||||
|
||||
//填写GitHub用户名和密码
|
||||
$form->find('input[name=login]')->val('your github username or email');
|
||||
$form->find('input[name=password]')->val('your github password');
|
||||
|
||||
//序列化表单数据
|
||||
$fromData = $form->serializeArray();
|
||||
$postData = [];
|
||||
foreach ($fromData as $item) {
|
||||
$postData[$item['name']] = $item['value'];
|
||||
}
|
||||
|
||||
//提交登录表单
|
||||
$actionUrl = 'https://github.com'.$form->attr('action');
|
||||
$ql->post($actionUrl,$postData);
|
||||
//判断登录是否成功
|
||||
// echo $ql->getHtml();
|
||||
$userName = $ql->find('.header-nav-current-user>.css-truncate-target')->text();
|
||||
if($userName)
|
||||
{
|
||||
echo '登录成功!欢迎你:'.$userName;
|
||||
}else{
|
||||
echo '登录失败!';
|
||||
}
|
||||
```
|
||||
#### Bind功能扩展
|
||||
自定义扩展一个`myHttp`方法:
|
||||
```php
|
||||
$ql = QueryList::getInstance();
|
||||
|
||||
//绑定一个myHttp方法到QueryList对象
|
||||
$ql->bind('myHttp',function ($url){
|
||||
// $this 为当前的QueryList对象
|
||||
$html = file_get_contents($url);
|
||||
$this->setHtml($html);
|
||||
return $this;
|
||||
});
|
||||
|
||||
//然后就可以通过注册的名字来调用
|
||||
$data = $ql->myHttp('https://toutiao.io')->find('h3 a')->texts();
|
||||
print_r($data->all());
|
||||
```
|
||||
或者把实现体封装到class,然后这样绑定:
|
||||
```php
|
||||
$ql->bind('myHttp',function ($url){
|
||||
return new MyHttp($this,$url);
|
||||
});
|
||||
```
|
||||
|
||||
#### 插件使用
|
||||
- 使用PhantomJS插件采集JavaScript动态渲染的页面:
|
||||
|
||||
```php
|
||||
// 安装时设置PhantomJS二进制文件路径
|
||||
$ql = QueryList::use(PhantomJs::class,'/usr/local/bin/phantomjs');
|
||||
|
||||
// 采集今日头条手机版
|
||||
$data = $ql->browser('https://m.toutiao.com')->find('p')->texts();
|
||||
print_r($data->all());
|
||||
|
||||
// 使用HTTP代理
|
||||
$ql->browser('https://m.toutiao.com',false,[
|
||||
'--proxy' => '192.168.1.42:8080',
|
||||
'--proxy-type' => 'http'
|
||||
])
|
||||
```
|
||||
|
||||
- 使用CURL多线程插件,多线程采集GitHub排行榜:
|
||||
|
||||
```php
|
||||
$ql = QueryList::use(CurlMulti::class);
|
||||
$ql->curlMulti([
|
||||
'https://github.com/trending/php',
|
||||
'https://github.com/trending/go',
|
||||
//.....more urls
|
||||
])
|
||||
// 每个任务成功完成调用此回调
|
||||
->success(function (QueryList $ql,CurlMulti $curl,$r){
|
||||
echo "Current url:{$r['info']['url']} \r\n";
|
||||
$data = $ql->find('h3 a')->texts();
|
||||
print_r($data->all());
|
||||
})
|
||||
// 每个任务失败回调
|
||||
->error(function ($errorInfo,CurlMulti $curl){
|
||||
echo "Current url:{$errorInfo['info']['url']} \r\n";
|
||||
print_r($errorInfo['error']);
|
||||
})
|
||||
->start([
|
||||
// 最大并发数
|
||||
'maxThread' => 10,
|
||||
// 错误重试次数
|
||||
'maxTry' => 3,
|
||||
]);
|
||||
|
||||
```
|
||||
|
||||
## 插件
|
||||
- [jae-jae/QueryList-PhantomJS](https://github.com/jae-jae/QueryList-PhantomJS): 使用PhantomJS采集JavaScript动态渲染的页面
|
||||
- [jae-jae/QueryList-CurlMulti](https://github.com/jae-jae/QueryList-CurlMulti) : Curl多线程采集
|
||||
- [jae-jae/QueryList-AbsoluteUrl](https://github.com/jae-jae/QueryList-AbsoluteUrl) : 转换URL相对路径到绝对路径
|
||||
- [jae-jae/QueryList-Rule-Google](https://github.com/jae-jae/QueryList-Rule-Google) : 谷歌搜索引擎
|
||||
- [jae-jae/QueryList-Rule-Baidu](https://github.com/jae-jae/QueryList-Rule-Baidu) : 百度搜索引擎
|
||||
|
||||
|
||||
查看更多的QueryList插件和基于QueryList的产品:[QueryList社区力量](https://github.com/jae-jae/QueryList-Community)
|
||||
|
||||
## 贡献
|
||||
欢迎为QueryList贡献代码。关于贡献插件可以查看:[QueryList插件贡献说明](https://github.com/jae-jae/QueryList-Community/blob/master/CONTRIBUTING.md)
|
||||
|
||||
## 寻求帮助?
|
||||
- QueryList主页: [http://querylist.cc](http://querylist.cc/)
|
||||
- QueryList文档: [http://doc.querylist.cc](http://doc.querylist.cc/)
|
||||
- QueryList问答:[http://wenda.querylist.cc](http://wenda.querylist.cc/)
|
||||
- QueryList交流QQ群:123266961 <a target="_blank" href="http://shang.qq.com/wpa/qunwpa?idkey=a1b248ae30b3f711bdab4f799df839300dc7fed54331177035efa0513da027f6"><img border="0" src="http://pub.idqqimg.com/wpa/images/group.png" alt="cafeEX" title="cafeEX"></a>
|
||||
- GitHub:https://github.com/jae-jae/QueryList
|
||||
- Git@OSC:http://git.oschina.net/jae/QueryList
|
||||
|
||||
## Author
|
||||
Jaeger <JaegerCode@gmail.com>
|
||||
|
||||
## Lisence
|
||||
QueryList is licensed under the license of MIT. See the LICENSE for more details.
|
304
vendor/jaeger/querylist/README.md
vendored
Normal file
304
vendor/jaeger/querylist/README.md
vendored
Normal file
@ -0,0 +1,304 @@
|
||||
<p align="center">
|
||||
<img width="150" src="logo.png" alt="QueryList">
|
||||
<br>
|
||||
<br>
|
||||
</p>
|
||||
|
||||
# QueryList
|
||||
`QueryList` is a simple, elegant, extensible PHP Web Scraper (crawler/spider) ,based on phpQuery.
|
||||
|
||||
[API Documentation](https://github.com/jae-jae/QueryList/wiki)
|
||||
|
||||
[中文文档](README-ZH.md)
|
||||
|
||||
## Features
|
||||
- Have the same CSS3 DOM selector as jQuery
|
||||
- Have the same DOM manipulation API as jQuery
|
||||
- Have a generic list crawling program
|
||||
- Have a strong HTTP request suite, easy to achieve such as: simulated landing, forged browser, HTTP proxy and other complex network requests
|
||||
- Have a messy code solution
|
||||
- Have powerful content filtering, you can use the jQuey selector to filter content
|
||||
- Has a high degree of modular design, scalability and strong
|
||||
- Have an expressive API
|
||||
- Has a wealth of plug-ins
|
||||
|
||||
Through plug-ins you can easily implement things like:
|
||||
- Multithreaded crawl
|
||||
- Crawl JavaScript dynamic rendering page (PhantomJS/headless WebKit)
|
||||
- Image downloads to local
|
||||
- Simulate browser behavior such as submitting Form forms
|
||||
- Web crawler
|
||||
- .....
|
||||
|
||||
## Requirements
|
||||
- PHP >= 7.1
|
||||
|
||||
## Installation
|
||||
By Composer installation:
|
||||
```
|
||||
composer require jaeger/querylist
|
||||
```
|
||||
|
||||
## Usage
|
||||
|
||||
#### DOM Traversal and Manipulation
|
||||
- Crawl「GitHub」all picture links
|
||||
|
||||
```php
|
||||
QueryList::get('https://github.com')->find('img')->attrs('src');
|
||||
```
|
||||
- Crawl Google search results
|
||||
|
||||
```php
|
||||
$ql = QueryList::get('https://www.google.co.jp/search?q=QueryList');
|
||||
|
||||
$ql->find('title')->text(); //The page title
|
||||
$ql->find('meta[name=keywords]')->content; //The page keywords
|
||||
|
||||
$ql->find('h3>a')->texts(); //Get a list of search results titles
|
||||
$ql->find('h3>a')->attrs('href'); //Get a list of search results links
|
||||
|
||||
$ql->find('img')->src; //Gets the link address of the first image
|
||||
$ql->find('img:eq(1)')->src; //Gets the link address of the second image
|
||||
$ql->find('img')->eq(2)->src; //Gets the link address of the third image
|
||||
// Loop all the images
|
||||
$ql->find('img')->map(function($img){
|
||||
echo $img->alt; //Print the alt attribute of the image
|
||||
});
|
||||
```
|
||||
- More usage
|
||||
|
||||
```php
|
||||
$ql->find('#head')->append('<div>Append content</div>')->find('div')->htmls();
|
||||
$ql->find('.two')->children('img')->attrs('alt'); // Get the class is the "two" element under all img child nodes
|
||||
// Loop class is the "two" element under all child nodes
|
||||
$data = $ql->find('.two')->children()->map(function ($item){
|
||||
// Use "is" to determine the node type
|
||||
if($item->is('a')){
|
||||
return $item->text();
|
||||
}elseif($item->is('img'))
|
||||
{
|
||||
return $item->alt;
|
||||
}
|
||||
});
|
||||
|
||||
$ql->find('a')->attr('href', 'newVal')->removeClass('className')->html('newHtml')->...
|
||||
$ql->find('div > p')->add('div > ul')->filter(':has(a)')->find('p:first')->nextAll()->andSelf()->...
|
||||
$ql->find('div.old')->replaceWith( $ql->find('div.new')->clone())->appendTo('.trash')->prepend('Deleted')->...
|
||||
```
|
||||
#### List crawl
|
||||
Crawl the title and link of the Google search results list:
|
||||
```php
|
||||
$data = QueryList::get('https://www.google.co.jp/search?q=QueryList')
|
||||
// Set the crawl rules
|
||||
->rules([
|
||||
'title'=>array('h3','text'),
|
||||
'link'=>array('h3>a','href')
|
||||
])
|
||||
->query()->getData();
|
||||
|
||||
print_r($data->all());
|
||||
```
|
||||
Results:
|
||||
```
|
||||
Array
|
||||
(
|
||||
[0] => Array
|
||||
(
|
||||
[title] => Angular - QueryList
|
||||
[link] => https://angular.io/api/core/QueryList
|
||||
)
|
||||
[1] => Array
|
||||
(
|
||||
[title] => QueryList | @angular/core - Angularリファレンス - Web Creative Park
|
||||
[link] => http://www.webcreativepark.net/angular/querylist/
|
||||
)
|
||||
[2] => Array
|
||||
(
|
||||
[title] => QueryListにQueryを追加したり、追加されたことを感知する | TIPS ...
|
||||
[link] => http://www.webcreativepark.net/angular/querylist_query_add_subscribe/
|
||||
)
|
||||
//...
|
||||
)
|
||||
```
|
||||
#### Encode convert
|
||||
```php
|
||||
// Out charset :UTF-8
|
||||
// In charset :GB2312
|
||||
QueryList::get('https://top.etao.com')->encoding('UTF-8','GB2312')->find('a')->texts();
|
||||
|
||||
// Out charset:UTF-8
|
||||
// In charset:Automatic Identification
|
||||
QueryList::get('https://top.etao.com')->encoding('UTF-8')->find('a')->texts();
|
||||
```
|
||||
|
||||
#### HTTP Client (GuzzleHttp)
|
||||
- Carry cookie login GitHub
|
||||
```php
|
||||
//Crawl GitHub content
|
||||
$ql = QueryList::get('https://github.com','param1=testvalue & params2=somevalue',[
|
||||
'headers' => [
|
||||
// Fill in the cookie from the browser
|
||||
'Cookie' => 'SINAGLOBAL=546064; wb_cmtLike_2112031=1; wvr=6;....'
|
||||
]
|
||||
]);
|
||||
//echo $ql->getHtml();
|
||||
$userName = $ql->find('.header-nav-current-user>.css-truncate-target')->text();
|
||||
echo $userName;
|
||||
```
|
||||
- Use the Http proxy
|
||||
```php
|
||||
$urlParams = ['param1' => 'testvalue','params2' => 'somevalue'];
|
||||
$opts = [
|
||||
// Set the http proxy
|
||||
'proxy' => 'http://222.141.11.17:8118',
|
||||
//Set the timeout time in seconds
|
||||
'timeout' => 30,
|
||||
// Fake HTTP headers
|
||||
'headers' => [
|
||||
'Referer' => 'https://querylist.cc/',
|
||||
'User-Agent' => 'testing/1.0',
|
||||
'Accept' => 'application/json',
|
||||
'X-Foo' => ['Bar', 'Baz'],
|
||||
'Cookie' => 'abc=111;xxx=222'
|
||||
]
|
||||
];
|
||||
$ql->get('http://httpbin.org/get',$urlParams,$opts);
|
||||
// echo $ql->getHtml();
|
||||
```
|
||||
|
||||
- Analog login
|
||||
```php
|
||||
// Post login
|
||||
$ql = QueryList::post('http://xxxx.com/login',[
|
||||
'username' => 'admin',
|
||||
'password' => '123456'
|
||||
])->get('http://xxx.com/admin');
|
||||
// Crawl pages that need to be logged in to access
|
||||
$ql->get('http://xxx.com/admin/page');
|
||||
//echo $ql->getHtml();
|
||||
```
|
||||
|
||||
#### Submit forms
|
||||
Login GitHub
|
||||
```php
|
||||
// Get the QueryList instance
|
||||
$ql = QueryList::getInstance();
|
||||
// Get the login form
|
||||
$form = $ql->get('https://github.com/login')->find('form');
|
||||
|
||||
// Fill in the GitHub username and password
|
||||
$form->find('input[name=login]')->val('your github username or email');
|
||||
$form->find('input[name=password]')->val('your github password');
|
||||
|
||||
// Serialize the form data
|
||||
$fromData = $form->serializeArray();
|
||||
$postData = [];
|
||||
foreach ($fromData as $item) {
|
||||
$postData[$item['name']] = $item['value'];
|
||||
}
|
||||
|
||||
// Submit the login form
|
||||
$actionUrl = 'https://github.com'.$form->attr('action');
|
||||
$ql->post($actionUrl,$postData);
|
||||
// To determine whether the login is successful
|
||||
// echo $ql->getHtml();
|
||||
$userName = $ql->find('.header-nav-current-user>.css-truncate-target')->text();
|
||||
if($userName)
|
||||
{
|
||||
echo 'Login successful ! Welcome:'.$userName;
|
||||
}else{
|
||||
echo 'Login failed !';
|
||||
}
|
||||
```
|
||||
#### Bind function extension
|
||||
Customize the extension of a `myHttp` method:
|
||||
```php
|
||||
$ql = QueryList::getInstance();
|
||||
|
||||
//Bind a `myHttp` method to the QueryList object
|
||||
$ql->bind('myHttp',function ($url){
|
||||
// $this is the current QueryList object
|
||||
$html = file_get_contents($url);
|
||||
$this->setHtml($html);
|
||||
return $this;
|
||||
});
|
||||
|
||||
// And then you can call by the name of the binding
|
||||
$data = $ql->myHttp('https://toutiao.io')->find('h3 a')->texts();
|
||||
print_r($data->all());
|
||||
```
|
||||
Or package to class, and then bind:
|
||||
```php
|
||||
$ql->bind('myHttp',function ($url){
|
||||
return new MyHttp($this,$url);
|
||||
});
|
||||
```
|
||||
|
||||
#### Plugin used
|
||||
- Use the PhantomJS plugin to crawl JavaScript dynamically rendered pages:
|
||||
|
||||
```php
|
||||
// Set the PhantomJS binary file path during installation
|
||||
$ql = QueryList::use(PhantomJs::class,'/usr/local/bin/phantomjs');
|
||||
|
||||
// Crawl「500px」all picture links
|
||||
$data = $ql->browser('https://500px.com/editors')->find('img')->attrs('src');
|
||||
print_r($data->all());
|
||||
|
||||
// Use the HTTP proxy
|
||||
$ql->browser('https://500px.com/editors',false,[
|
||||
'--proxy' => '192.168.1.42:8080',
|
||||
'--proxy-type' => 'http'
|
||||
])
|
||||
```
|
||||
|
||||
- Using the CURL multithreading plug-in, multi-threaded crawling GitHub trending :
|
||||
|
||||
```php
|
||||
$ql = QueryList::use(CurlMulti::class);
|
||||
$ql->curlMulti([
|
||||
'https://github.com/trending/php',
|
||||
'https://github.com/trending/go',
|
||||
//.....more urls
|
||||
])
|
||||
// Called if task is success
|
||||
->success(function (QueryList $ql,CurlMulti $curl,$r){
|
||||
echo "Current url:{$r['info']['url']} \r\n";
|
||||
$data = $ql->find('h3 a')->texts();
|
||||
print_r($data->all());
|
||||
})
|
||||
// Task fail callback
|
||||
->error(function ($errorInfo,CurlMulti $curl){
|
||||
echo "Current url:{$errorInfo['info']['url']} \r\n";
|
||||
print_r($errorInfo['error']);
|
||||
})
|
||||
->start([
|
||||
// Maximum number of threads
|
||||
'maxThread' => 10,
|
||||
// Number of error retries
|
||||
'maxTry' => 3,
|
||||
]);
|
||||
|
||||
```
|
||||
|
||||
## Plugins
|
||||
- [jae-jae/QueryList-PhantomJS](https://github.com/jae-jae/QueryList-PhantomJS):Use PhantomJS to crawl Javascript dynamically rendered page.
|
||||
- [jae-jae/QueryList-CurlMulti](https://github.com/jae-jae/QueryList-CurlMulti) : Curl multi threading.
|
||||
- [jae-jae/QueryList-AbsoluteUrl](https://github.com/jae-jae/QueryList-AbsoluteUrl) : Converting relative urls to absolute.
|
||||
- [jae-jae/QueryList-Rule-Google](https://github.com/jae-jae/QueryList-Rule-Google) : Google searcher.
|
||||
- [jae-jae/QueryList-Rule-Baidu](https://github.com/jae-jae/QueryList-Rule-Baidu) : Baidu searcher.
|
||||
|
||||
|
||||
View more QueryList plugins and QueryList-based products: [QueryList Community](https://github.com/jae-jae/QueryList-Community)
|
||||
|
||||
## Contributing
|
||||
Welcome to contribute code for the QueryList。About Contributing Plugins can be viewed:[QueryList Plugin Contributing Guide](https://github.com/jae-jae/QueryList-Community/blob/master/CONTRIBUTING.md)
|
||||
|
||||
## Author
|
||||
Jaeger <JaegerCode@gmail.com>
|
||||
|
||||
If this library is useful for you, say thanks [buying me a beer :beer:](https://www.paypal.me/jaepay)!
|
||||
|
||||
## Lisence
|
||||
QueryList is licensed under the license of MIT. See the LICENSE for more details.
|
40
vendor/jaeger/querylist/composer.json
vendored
Normal file
40
vendor/jaeger/querylist/composer.json
vendored
Normal file
@ -0,0 +1,40 @@
|
||||
{
|
||||
"name": "jaeger/querylist",
|
||||
"description": "Simple, elegant, extensible PHP Web Scraper (crawler/spider),Use the css3 dom selector,Based on phpQuery! 简洁、优雅、可扩展的PHP采集工具(爬虫),基于phpQuery。",
|
||||
"keywords":["QueryList","phpQuery","spider"],
|
||||
"homepage": "http://querylist.cc",
|
||||
"require": {
|
||||
"PHP":">=7.1",
|
||||
"jaeger/phpquery-single": "^1",
|
||||
"jaeger/g-http": "^1.1",
|
||||
"ext-dom": "*",
|
||||
"tightenco/collect": ">5.0"
|
||||
},
|
||||
"suggest":{
|
||||
|
||||
},
|
||||
"license": "MIT",
|
||||
"authors": [
|
||||
{
|
||||
"name": "Jaeger",
|
||||
"email": "JaegerCode@gmail.com"
|
||||
}
|
||||
],
|
||||
"autoload":{
|
||||
"psr-4":{
|
||||
"QL\\":"src"
|
||||
}
|
||||
},
|
||||
"autoload-dev": {
|
||||
"psr-4": {
|
||||
"Tests\\": "tests/"
|
||||
}
|
||||
},
|
||||
"require-dev": {
|
||||
"symfony/var-dumper": "^3.3",
|
||||
"phpunit/phpunit": "^8.5"
|
||||
},
|
||||
"scripts": {
|
||||
"test": "./vendor/bin/phpunit"
|
||||
}
|
||||
}
|
BIN
vendor/jaeger/querylist/logo.png
vendored
Normal file
BIN
vendor/jaeger/querylist/logo.png
vendored
Normal file
Binary file not shown.
After Width: | Height: | Size: 15 KiB |
19
vendor/jaeger/querylist/phpunit.xml
vendored
Normal file
19
vendor/jaeger/querylist/phpunit.xml
vendored
Normal file
@ -0,0 +1,19 @@
|
||||
<phpunit
|
||||
bootstrap="vendor/autoload.php"
|
||||
convertErrorsToExceptions="true"
|
||||
convertNoticesToExceptions="true"
|
||||
convertWarningsToExceptions="true"
|
||||
>
|
||||
<testsuites>
|
||||
<testsuite name="querylist">
|
||||
<directory>./tests</directory>
|
||||
</testsuite>
|
||||
</testsuites>
|
||||
|
||||
<filter>
|
||||
<whitelist>
|
||||
<directory suffix=".php">src</directory>
|
||||
</whitelist>
|
||||
</filter>
|
||||
|
||||
</phpunit>
|
94
vendor/jaeger/querylist/src/Config.php
vendored
Normal file
94
vendor/jaeger/querylist/src/Config.php
vendored
Normal file
@ -0,0 +1,94 @@
|
||||
<?php
|
||||
/**
|
||||
* Created by PhpStorm.
|
||||
* User: Jaeger <JaegerCode@gmail.com>
|
||||
* Date: 2017/9/22
|
||||
*/
|
||||
|
||||
namespace QL;
|
||||
use Closure;
|
||||
use Tightenco\Collect\Support\Collection;
|
||||
|
||||
class Config
|
||||
{
|
||||
protected static $instance = null;
|
||||
|
||||
protected $plugins;
|
||||
protected $binds;
|
||||
|
||||
/**
|
||||
* Config constructor.
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
$this->plugins = new Collection();
|
||||
$this->binds = new Collection();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get the Config instance
|
||||
*
|
||||
* @return null|Config
|
||||
*/
|
||||
public static function getInstance()
|
||||
{
|
||||
self::$instance || self::$instance = new self();
|
||||
return self::$instance;
|
||||
}
|
||||
|
||||
/**
|
||||
* Global installation plugin
|
||||
*
|
||||
* @param $plugins
|
||||
* @param array ...$opt
|
||||
* @return $this
|
||||
*/
|
||||
public function use($plugins,...$opt)
|
||||
{
|
||||
if(is_string($plugins)){
|
||||
$this->plugins->push([$plugins,$opt]);
|
||||
}else{
|
||||
$this->plugins = $this->plugins->merge($plugins);
|
||||
}
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Global binding custom method
|
||||
*
|
||||
* @param string $name
|
||||
* @param Closure $provider
|
||||
* @return $this
|
||||
*/
|
||||
public function bind(string $name, Closure $provider)
|
||||
{
|
||||
$this->binds[$name] = $provider;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function bootstrap(QueryList $queryList)
|
||||
{
|
||||
$this->installPlugins($queryList);
|
||||
$this->installBind($queryList);
|
||||
}
|
||||
|
||||
protected function installPlugins(QueryList $queryList)
|
||||
{
|
||||
$this->plugins->each(function($plugin) use($queryList){
|
||||
if(is_string($plugin)){
|
||||
$queryList->use($plugin);
|
||||
}else{
|
||||
$queryList->use($plugin[0],...$plugin[1]);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
protected function installBind(QueryList $queryList)
|
||||
{
|
||||
$this->binds->each(function ($provider,$name) use($queryList){
|
||||
$queryList->bind($name,$provider);
|
||||
});
|
||||
}
|
||||
|
||||
}
|
15
vendor/jaeger/querylist/src/Contracts/PluginContract.php
vendored
Normal file
15
vendor/jaeger/querylist/src/Contracts/PluginContract.php
vendored
Normal file
@ -0,0 +1,15 @@
|
||||
<?php
|
||||
/**
|
||||
* Created by PhpStorm.
|
||||
* User: Jaeger <JaegerCode@gmail.com>
|
||||
* Date: 2017/9/22
|
||||
*/
|
||||
|
||||
namespace QL\Contracts;
|
||||
|
||||
use QL\QueryList;
|
||||
|
||||
interface PluginContract
|
||||
{
|
||||
public static function install(QueryList $queryList,...$opt);
|
||||
}
|
15
vendor/jaeger/querylist/src/Contracts/ServiceProviderContract.php
vendored
Normal file
15
vendor/jaeger/querylist/src/Contracts/ServiceProviderContract.php
vendored
Normal file
@ -0,0 +1,15 @@
|
||||
<?php
|
||||
/**
|
||||
* Created by PhpStorm.
|
||||
* User: Jaeger <JaegerCode@gmail.com>
|
||||
* Date: 2017/9/20
|
||||
*/
|
||||
|
||||
namespace QL\Contracts;
|
||||
|
||||
use QL\Kernel;
|
||||
|
||||
interface ServiceProviderContract
|
||||
{
|
||||
public function register(Kernel $kernel);
|
||||
}
|
30
vendor/jaeger/querylist/src/Dom/Dom.php
vendored
Normal file
30
vendor/jaeger/querylist/src/Dom/Dom.php
vendored
Normal file
@ -0,0 +1,30 @@
|
||||
<?php
|
||||
/**
|
||||
* Created by PhpStorm.
|
||||
* User: Jaeger <JaegerCode@gmail.com>
|
||||
* Date: 2017/9/19
|
||||
*/
|
||||
|
||||
namespace QL\Dom;
|
||||
|
||||
use phpQueryObject;
|
||||
|
||||
class Dom
|
||||
{
|
||||
|
||||
protected $document;
|
||||
|
||||
/**
|
||||
* Dom constructor.
|
||||
*/
|
||||
public function __construct(phpQueryObject $document)
|
||||
{
|
||||
$this->document = $document;
|
||||
}
|
||||
|
||||
public function find($selector)
|
||||
{
|
||||
$elements = $this->document->find($selector);
|
||||
return new Elements($elements);
|
||||
}
|
||||
}
|
260
vendor/jaeger/querylist/src/Dom/Elements.php
vendored
Normal file
260
vendor/jaeger/querylist/src/Dom/Elements.php
vendored
Normal file
@ -0,0 +1,260 @@
|
||||
<?php
|
||||
/**
|
||||
* Created by PhpStorm.
|
||||
* User: Jaeger <JaegerCode@gmail.com>
|
||||
* Date: 2017/9/19
|
||||
*/
|
||||
|
||||
namespace QL\Dom;
|
||||
|
||||
use phpDocumentor\Reflection\Types\Null_;
|
||||
use phpQueryObject;
|
||||
use Tightenco\Collect\Support\Collection;
|
||||
|
||||
/**
|
||||
* Class Elements
|
||||
* @package QL\Dom
|
||||
*
|
||||
* @method Elements toReference(&$var)
|
||||
* @method Elements documentFragment($state = null)
|
||||
* @method Elements toRoot()
|
||||
* @method Elements getDocumentIDRef(&$documentID)
|
||||
* @method Elements getDocument()
|
||||
* @method \DOMDocument getDOMDocument()
|
||||
* @method Elements getDocumentID()
|
||||
* @method Elements unloadDocument()
|
||||
* @method bool isHTML()
|
||||
* @method bool isXHTML()
|
||||
* @method bool isXML()
|
||||
* @method string serialize()
|
||||
* @method array serializeArray($submit = null)
|
||||
* @method \DOMElement|\DOMElement[] get($index = null, $callback1 = null, $callback2 = null, $callback3 = null)
|
||||
* @method string|array getString($index = null, $callback1 = null, $callback2 = null, $callback3 = null)
|
||||
* @method string|array getStrings($index = null, $callback1 = null, $callback2 = null, $callback3 = null)
|
||||
* @method Elements newInstance($newStack = null)
|
||||
* @method Elements find($selectors, $context = null, $noHistory = false)
|
||||
* @method Elements|bool is($selector, $nodes = null)
|
||||
* @method Elements filterCallback($callback, $_skipHistory = false)
|
||||
* @method Elements filter($selectors, $_skipHistory = false)
|
||||
* @method Elements load($url, $data = null, $callback = null)
|
||||
* @method Elements trigger($type, $data = [])
|
||||
* @method Elements triggerHandler($type, $data = [])
|
||||
* @method Elements bind($type, $data, $callback = null)
|
||||
* @method Elements unbind($type = null, $callback = null)
|
||||
* @method Elements change($callback = null)
|
||||
* @method Elements submit($callback = null)
|
||||
* @method Elements click($callback = null)
|
||||
* @method Elements wrapAllOld($wrapper)
|
||||
* @method Elements wrapAll($wrapper)
|
||||
* @method Elements wrapAllPHP($codeBefore, $codeAfter)
|
||||
* @method Elements wrap($wrapper)
|
||||
* @method Elements wrapPHP($codeBefore, $codeAfter)
|
||||
* @method Elements wrapInner($wrapper)
|
||||
* @method Elements wrapInnerPHP($codeBefore, $codeAfter)
|
||||
* @method Elements contents()
|
||||
* @method Elements contentsUnwrap()
|
||||
* @method Elements switchWith($markup)
|
||||
* @method Elements eq($num)
|
||||
* @method Elements size()
|
||||
* @method Elements length()
|
||||
* @method int count()
|
||||
* @method Elements end($level = 1)
|
||||
* @method Elements _clone()
|
||||
* @method Elements replaceWithPHP($code)
|
||||
* @method Elements replaceWith($content)
|
||||
* @method Elements replaceAll($selector)
|
||||
* @method Elements remove($selector = null)
|
||||
* @method Elements|string markup($markup = null, $callback1 = null, $callback2 = null, $callback3 = null)
|
||||
* @method string markupOuter($callback1 = null, $callback2 = null, $callback3 = null)
|
||||
* @method Elements|string html($html = null, $callback1 = null, $callback2 = null, $callback3 = null)
|
||||
* @method Elements|string xml($xml = null, $callback1 = null, $callback2 = null, $callback3 = null)
|
||||
* @method string htmlOuter($callback1 = null, $callback2 = null, $callback3 = null)
|
||||
* @method string xmlOuter($callback1 = null, $callback2 = null, $callback3 = null)
|
||||
* @method Elements php($code)
|
||||
* @method string markupPHP($code)
|
||||
* @method string markupOuterPHP()
|
||||
* @method Elements children($selector)
|
||||
* @method Elements ancestors($selector)
|
||||
* @method Elements append($content)
|
||||
* @method Elements appendPHP($content)
|
||||
* @method Elements appendTo($seletor)
|
||||
* @method Elements prepend($content)
|
||||
* @method Elements prependPHP($content)
|
||||
* @method Elements prependTo($seletor)
|
||||
* @method Elements before($content)
|
||||
* @method Elements beforePHP($content)
|
||||
* @method Elements insertBefore($seletor)
|
||||
* @method Elements after($content)
|
||||
* @method Elements afterPHP($content)
|
||||
* @method Elements insertAfter($seletor)
|
||||
* @method Elements insert($target, $type)
|
||||
* @method int index($subject)
|
||||
* @method Elements slice($start, $end = null)
|
||||
* @method Elements reverse()
|
||||
* @method Elements|string text($text = null, $callback1 = null, $callback2 = null, $callback3 = null)
|
||||
* @method Elements plugin($class, $file = null)
|
||||
* @method Elements _next($selector = null)
|
||||
* @method Elements _prev($selector = null)
|
||||
* @method Elements prev($selector = null)
|
||||
* @method Elements prevAll($selector = null)
|
||||
* @method Elements nextAll($selector = null)
|
||||
* @method Elements siblings($selector = null)
|
||||
* @method Elements not($selector = null)
|
||||
* @method Elements add($selector = null)
|
||||
* @method Elements parent($selector = null)
|
||||
* @method Elements parents($selector = null)
|
||||
* @method Elements stack($nodeTypes = null)
|
||||
* @method Elements|string attr($attr = null, $value = null)
|
||||
* @method Elements attrPHP($attr, $code)
|
||||
* @method Elements removeAttr($attr)
|
||||
* @method Elements|string val($val = null)
|
||||
* @method Elements andSelf()
|
||||
* @method Elements addClass($className)
|
||||
* @method Elements addClassPHP($className)
|
||||
* @method bool hasClass($className)
|
||||
* @method Elements removeClass($className)
|
||||
* @method Elements toggleClass($className)
|
||||
* @method Elements _empty()
|
||||
* @method Elements callback($callback, $param1 = null, $param2 = null, $param3 = null)
|
||||
* @method string data($key, $value = null)
|
||||
* @method Elements removeData($key)
|
||||
* @method void rewind()
|
||||
* @method Elements current()
|
||||
* @method int key()
|
||||
* @method Elements next($cssSelector = null)
|
||||
* @method bool valid()
|
||||
* @method bool offsetExists($offset)
|
||||
* @method Elements offsetGet($offset)
|
||||
* @method void offsetSet($offset, $value)
|
||||
* @method string whois($oneNode)
|
||||
* @method Elements dump()
|
||||
* @method Elements dumpWhois()
|
||||
* @method Elements dumpLength()
|
||||
* @method Elements dumpTree($html, $title)
|
||||
* @method dumpDie()
|
||||
*/
|
||||
class Elements
|
||||
{
|
||||
/**
|
||||
* @var phpQueryObject
|
||||
*/
|
||||
protected $elements;
|
||||
|
||||
/**
|
||||
* Elements constructor.
|
||||
* @param $elements
|
||||
*/
|
||||
public function __construct(phpQueryObject $elements)
|
||||
{
|
||||
$this->elements = $elements;
|
||||
}
|
||||
|
||||
public function __get($name)
|
||||
{
|
||||
return property_exists($this->elements, $name) ? $this->elements->$name : $this->elements->attr($name);
|
||||
}
|
||||
|
||||
public function __call($name, $arguments)
|
||||
{
|
||||
$obj = call_user_func_array([$this->elements, $name], $arguments);
|
||||
if ($obj instanceof phpQueryObject) {
|
||||
$obj = new self($obj);
|
||||
} else if (is_string($obj)) {
|
||||
$obj = trim($obj);
|
||||
}
|
||||
return $obj;
|
||||
}
|
||||
|
||||
/**
|
||||
* Iterating elements
|
||||
*
|
||||
* @param callable $callback
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function each(callable $callback)
|
||||
{
|
||||
foreach ($this->elements as $key => $element) {
|
||||
$break = $callback(new self(pq($element)), $key);
|
||||
if ($break === false) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Iterating elements
|
||||
*
|
||||
* @param $callback
|
||||
* @return \Illuminate\Support\Collection|\Tightenco\Collect\Support\Collection
|
||||
*/
|
||||
public function map($callback)
|
||||
{
|
||||
$collection = new Collection();
|
||||
$this->elements->each(function ($dom) use (& $collection, $callback) {
|
||||
$collection->push($callback(new self(pq($dom))));
|
||||
});
|
||||
return $collection;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the attributes of all the elements
|
||||
*
|
||||
* @param string $attr HTML attribute name
|
||||
* @return \Illuminate\Support\Collection|\Tightenco\Collect\Support\Collection
|
||||
*/
|
||||
public function attrs($attr)
|
||||
{
|
||||
return $this->map(function ($item) use ($attr) {
|
||||
return $item->attr($attr);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the text of all the elements
|
||||
*
|
||||
* @return \Illuminate\Support\Collection|\Tightenco\Collect\Support\Collection
|
||||
*/
|
||||
public function texts()
|
||||
{
|
||||
return $this->map(function ($item) {
|
||||
return trim($item->text());
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the html of all the elements
|
||||
*
|
||||
* @return \Illuminate\Support\Collection|\Tightenco\Collect\Support\Collection
|
||||
*/
|
||||
public function htmls()
|
||||
{
|
||||
return $this->map(function ($item) {
|
||||
return trim($item->html());
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the htmlOuter of all the elements
|
||||
*
|
||||
* @return \Illuminate\Support\Collection|\Tightenco\Collect\Support\Collection
|
||||
*/
|
||||
public function htmlOuters()
|
||||
{
|
||||
return $this->map(function ($item) {
|
||||
return trim($item->htmlOuter());
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @return phpQueryObject
|
||||
*/
|
||||
public function getElements(): phpQueryObject
|
||||
{
|
||||
return $this->elements;
|
||||
}
|
||||
|
||||
}
|
322
vendor/jaeger/querylist/src/Dom/Query.php
vendored
Normal file
322
vendor/jaeger/querylist/src/Dom/Query.php
vendored
Normal file
@ -0,0 +1,322 @@
|
||||
<?php
|
||||
/**
|
||||
* Created by PhpStorm.
|
||||
* User: Jaeger <JaegerCode@gmail.com>
|
||||
* Date: 2017/9/21
|
||||
*/
|
||||
|
||||
namespace QL\Dom;
|
||||
|
||||
use Tightenco\Collect\Support\Collection;
|
||||
use phpQuery;
|
||||
use phpQueryObject;
|
||||
use QL\QueryList;
|
||||
use Closure;
|
||||
|
||||
class Query
|
||||
{
|
||||
protected $html;
|
||||
/**
|
||||
* @var \phpQueryObject
|
||||
*/
|
||||
protected $document;
|
||||
protected $rules;
|
||||
protected $range = null;
|
||||
protected $ql;
|
||||
/**
|
||||
* @var Collection
|
||||
*/
|
||||
protected $data;
|
||||
|
||||
|
||||
public function __construct(QueryList $ql)
|
||||
{
|
||||
$this->ql = $ql;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param bool $rel
|
||||
* @return String
|
||||
*/
|
||||
public function getHtml($rel = true)
|
||||
{
|
||||
return $rel ? $this->document->htmlOuter() : $this->html;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $html
|
||||
* @param null $charset
|
||||
* @return QueryList
|
||||
*/
|
||||
public function setHtml($html, $charset = null)
|
||||
{
|
||||
$this->html = value($html);
|
||||
$this->destroyDocument();
|
||||
$this->document = phpQuery::newDocumentHTML($this->html, $charset);
|
||||
return $this->ql;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get crawl results
|
||||
*
|
||||
* @param Closure|null $callback
|
||||
* @return Collection|static
|
||||
*/
|
||||
public function getData(Closure $callback = null)
|
||||
{
|
||||
return $this->handleData($this->data, $callback);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Collection $data
|
||||
*/
|
||||
public function setData(Collection $data)
|
||||
{
|
||||
$this->data = $data;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Searches for all elements that match the specified expression.
|
||||
*
|
||||
* @param $selector A string containing a selector expression to match elements against.
|
||||
* @return Elements
|
||||
*/
|
||||
public function find($selector)
|
||||
{
|
||||
return (new Dom($this->document))->find($selector);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set crawl rule
|
||||
*
|
||||
* $rules = [
|
||||
* 'rule_name1' => ['selector','HTML attribute | text | html','Tag filter list','callback'],
|
||||
* 'rule_name2' => ['selector','HTML attribute | text | html','Tag filter list','callback'],
|
||||
* // ...
|
||||
* ]
|
||||
*
|
||||
* @param array $rules
|
||||
* @return QueryList
|
||||
*/
|
||||
public function rules(array $rules)
|
||||
{
|
||||
$this->rules = $rules;
|
||||
return $this->ql;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Set the slice area for crawl list
|
||||
*
|
||||
* @param $selector
|
||||
* @return QueryList
|
||||
*/
|
||||
public function range($selector)
|
||||
{
|
||||
$this->range = $selector;
|
||||
return $this->ql;
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove HTML head,try to solve the garbled
|
||||
*
|
||||
* @return QueryList
|
||||
*/
|
||||
public function removeHead()
|
||||
{
|
||||
$html = preg_replace('/(<head>|<head\s+.+?>).+<\/head>/is', '<head></head>', $this->html);
|
||||
$this->setHtml($html);
|
||||
return $this->ql;
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute the query rule
|
||||
*
|
||||
* @param Closure|null $callback
|
||||
* @return QueryList
|
||||
*/
|
||||
public function query(Closure $callback = null)
|
||||
{
|
||||
$this->data = $this->getList();
|
||||
$this->data = $this->handleData($this->data, $callback);
|
||||
return $this->ql;
|
||||
}
|
||||
|
||||
public function handleData(Collection $data, $callback)
|
||||
{
|
||||
if (is_callable($callback)) {
|
||||
if (empty($this->range)) {
|
||||
$data = new Collection($callback($data->all(), null));
|
||||
} else {
|
||||
$data = $data->map($callback);
|
||||
}
|
||||
}
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
protected function getList()
|
||||
{
|
||||
$data = [];
|
||||
if (empty($this->range)) {
|
||||
foreach ($this->rules as $key => $reg_value) {
|
||||
$rule = $this->parseRule($reg_value);
|
||||
$contentElements = $this->document->find($rule['selector']);
|
||||
$data[$key] = $this->extractContent($contentElements, $key, $rule);
|
||||
}
|
||||
} else {
|
||||
$rangeElements = $this->document->find($this->range);
|
||||
$i = 0;
|
||||
foreach ($rangeElements as $element) {
|
||||
foreach ($this->rules as $key => $reg_value) {
|
||||
$rule = $this->parseRule($reg_value);
|
||||
$contentElements = pq($element)->find($rule['selector']);
|
||||
$data[$i][$key] = $this->extractContent($contentElements, $key, $rule);
|
||||
}
|
||||
$i++;
|
||||
}
|
||||
}
|
||||
|
||||
return new Collection($data);
|
||||
}
|
||||
|
||||
protected function extractContent(phpQueryObject $pqObj, $ruleName, $rule)
|
||||
{
|
||||
switch ($rule['attr']) {
|
||||
case 'text':
|
||||
$content = $this->allowTags($pqObj->html(), $rule['filter_tags']);
|
||||
break;
|
||||
case 'texts':
|
||||
$content = (new Elements($pqObj))->map(function (Elements $element) use ($rule) {
|
||||
return $this->allowTags($element->html(), $rule['filter_tags']);
|
||||
})->all();
|
||||
break;
|
||||
case 'html':
|
||||
$content = $this->stripTags($pqObj->html(), $rule['filter_tags']);
|
||||
break;
|
||||
case 'htmls':
|
||||
$content = (new Elements($pqObj))->map(function (Elements $element) use ($rule) {
|
||||
return $this->stripTags($element->html(), $rule['filter_tags']);
|
||||
})->all();
|
||||
break;
|
||||
case 'htmlOuter':
|
||||
$content = $this->stripTags($pqObj->htmlOuter(), $rule['filter_tags']);
|
||||
break;
|
||||
case 'htmlOuters':
|
||||
$content = (new Elements($pqObj))->map(function (Elements $element) use ($rule) {
|
||||
return $this->stripTags($element->htmlOuter(), $rule['filter_tags']);
|
||||
})->all();
|
||||
break;
|
||||
default:
|
||||
if(preg_match('/attr\((.+)\)/', $rule['attr'], $arr)) {
|
||||
$content = $pqObj->attr($arr[1]);
|
||||
} elseif (preg_match('/attrs\((.+)\)/', $rule['attr'], $arr)) {
|
||||
$content = (new Elements($pqObj))->attrs($arr[1])->all();
|
||||
} else {
|
||||
$content = $pqObj->attr($rule['attr']);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
if (is_callable($rule['handle_callback'])) {
|
||||
$content = call_user_func($rule['handle_callback'], $content, $ruleName);
|
||||
}
|
||||
|
||||
return $content;
|
||||
}
|
||||
|
||||
protected function parseRule($rule)
|
||||
{
|
||||
$result = [];
|
||||
$result['selector'] = $rule[0];
|
||||
$result['attr'] = $rule[1];
|
||||
$result['filter_tags'] = $rule[2] ?? '';
|
||||
$result['handle_callback'] = $rule[3] ?? null;
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* 去除特定的html标签
|
||||
* @param string $html
|
||||
* @param string $tags_str 多个标签名之间用空格隔开
|
||||
* @return string
|
||||
*/
|
||||
protected function stripTags($html, $tags_str)
|
||||
{
|
||||
$tagsArr = $this->tag($tags_str);
|
||||
$html = $this->removeTags($html, $tagsArr[1]);
|
||||
$p = array();
|
||||
foreach ($tagsArr[0] as $tag) {
|
||||
$p[] = "/(<(?:\/" . $tag . "|" . $tag . ")[^>]*>)/i";
|
||||
}
|
||||
$html = preg_replace($p, "", trim($html));
|
||||
return $html;
|
||||
}
|
||||
|
||||
/**
|
||||
* 保留特定的html标签
|
||||
* @param string $html
|
||||
* @param string $tags_str 多个标签名之间用空格隔开
|
||||
* @return string
|
||||
*/
|
||||
protected function allowTags($html, $tags_str)
|
||||
{
|
||||
$tagsArr = $this->tag($tags_str);
|
||||
$html = $this->removeTags($html, $tagsArr[1]);
|
||||
$allow = '';
|
||||
foreach ($tagsArr[0] as $tag) {
|
||||
$allow .= "<$tag> ";
|
||||
}
|
||||
return strip_tags(trim($html), $allow);
|
||||
}
|
||||
|
||||
protected function tag($tags_str)
|
||||
{
|
||||
$tagArr = preg_split("/\s+/", $tags_str, -1, PREG_SPLIT_NO_EMPTY);
|
||||
$tags = array(array(), array());
|
||||
foreach ($tagArr as $tag) {
|
||||
if (preg_match('/-(.+)/', $tag, $arr)) {
|
||||
array_push($tags[1], $arr[1]);
|
||||
} else {
|
||||
array_push($tags[0], $tag);
|
||||
}
|
||||
}
|
||||
return $tags;
|
||||
}
|
||||
|
||||
/**
|
||||
* 移除特定的html标签
|
||||
* @param string $html
|
||||
* @param array $tags 标签数组
|
||||
* @return string
|
||||
*/
|
||||
protected function removeTags($html, $tags)
|
||||
{
|
||||
$tag_str = '';
|
||||
if (count($tags)) {
|
||||
foreach ($tags as $tag) {
|
||||
$tag_str .= $tag_str ? ',' . $tag : $tag;
|
||||
}
|
||||
// phpQuery::$defaultCharset = $this->inputEncoding?$this->inputEncoding:$this->htmlEncoding;
|
||||
$doc = phpQuery::newDocumentHTML($html);
|
||||
pq($doc)->find($tag_str)->remove();
|
||||
$html = pq($doc)->htmlOuter();
|
||||
$doc->unloadDocument();
|
||||
}
|
||||
return $html;
|
||||
}
|
||||
|
||||
protected function destroyDocument()
|
||||
{
|
||||
if ($this->document instanceof phpQueryObject) {
|
||||
$this->document->unloadDocument();
|
||||
}
|
||||
}
|
||||
|
||||
public function __destruct()
|
||||
{
|
||||
$this->destroyDocument();
|
||||
}
|
||||
}
|
15
vendor/jaeger/querylist/src/Exceptions/ServiceNotFoundException.php
vendored
Normal file
15
vendor/jaeger/querylist/src/Exceptions/ServiceNotFoundException.php
vendored
Normal file
@ -0,0 +1,15 @@
|
||||
<?php
|
||||
/**
|
||||
* Created by PhpStorm.
|
||||
* User: Jaeger <JaegerCode@gmail.com>
|
||||
* Date: 2017/9/21
|
||||
*/
|
||||
|
||||
namespace QL\Exceptions;
|
||||
|
||||
use Exception;
|
||||
|
||||
class ServiceNotFoundException extends Exception
|
||||
{
|
||||
|
||||
}
|
74
vendor/jaeger/querylist/src/Kernel.php
vendored
Normal file
74
vendor/jaeger/querylist/src/Kernel.php
vendored
Normal file
@ -0,0 +1,74 @@
|
||||
<?php
|
||||
/**
|
||||
* Created by PhpStorm.
|
||||
* User: Jaeger <JaegerCode@gmail.com>
|
||||
* Date: 2017/9/21
|
||||
*/
|
||||
|
||||
namespace QL;
|
||||
|
||||
use QL\Contracts\ServiceProviderContract;
|
||||
use QL\Exceptions\ServiceNotFoundException;
|
||||
use QL\Providers\EncodeServiceProvider;
|
||||
use Closure;
|
||||
use QL\Providers\HttpServiceProvider;
|
||||
use QL\Providers\PluginServiceProvider;
|
||||
use QL\Providers\SystemServiceProvider;
|
||||
use Tightenco\Collect\Support\Collection;
|
||||
|
||||
class Kernel
|
||||
{
|
||||
protected $providers = [
|
||||
SystemServiceProvider::class,
|
||||
HttpServiceProvider::class,
|
||||
EncodeServiceProvider::class,
|
||||
PluginServiceProvider::class
|
||||
];
|
||||
|
||||
protected $binds;
|
||||
protected $ql;
|
||||
|
||||
/**
|
||||
* Kernel constructor.
|
||||
* @param $ql
|
||||
*/
|
||||
public function __construct(QueryList $ql)
|
||||
{
|
||||
$this->ql = $ql;
|
||||
$this->binds = new Collection();
|
||||
}
|
||||
|
||||
public function bootstrap()
|
||||
{
|
||||
//注册服务提供者
|
||||
$this->registerProviders();
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function registerProviders()
|
||||
{
|
||||
foreach ($this->providers as $provider) {
|
||||
$this->register(new $provider());
|
||||
}
|
||||
}
|
||||
|
||||
public function bind(string $name,Closure $provider)
|
||||
{
|
||||
$this->binds[$name] = $provider;
|
||||
}
|
||||
|
||||
public function getService(string $name)
|
||||
{
|
||||
if(!$this->binds->offsetExists($name)){
|
||||
throw new ServiceNotFoundException("Service: {$name} not found!");
|
||||
}
|
||||
return $this->binds[$name];
|
||||
}
|
||||
|
||||
private function register(ServiceProviderContract $instance)
|
||||
{
|
||||
$instance->register($this);
|
||||
}
|
||||
|
||||
|
||||
}
|
22
vendor/jaeger/querylist/src/Providers/EncodeServiceProvider.php
vendored
Normal file
22
vendor/jaeger/querylist/src/Providers/EncodeServiceProvider.php
vendored
Normal file
@ -0,0 +1,22 @@
|
||||
<?php
|
||||
/**
|
||||
* Created by PhpStorm.
|
||||
* User: Jaeger <JaegerCode@gmail.com>
|
||||
* Date: 2017/9/20
|
||||
*/
|
||||
|
||||
namespace QL\Providers;
|
||||
|
||||
use QL\Contracts\ServiceProviderContract;
|
||||
use QL\Kernel;
|
||||
use QL\Services\EncodeService;
|
||||
|
||||
class EncodeServiceProvider implements ServiceProviderContract
|
||||
{
|
||||
public function register(Kernel $kernel)
|
||||
{
|
||||
$kernel->bind('encoding',function (string $outputEncoding,string $inputEncoding = null){
|
||||
return EncodeService::convert($this,$outputEncoding,$inputEncoding);
|
||||
});
|
||||
}
|
||||
}
|
40
vendor/jaeger/querylist/src/Providers/HttpServiceProvider.php
vendored
Normal file
40
vendor/jaeger/querylist/src/Providers/HttpServiceProvider.php
vendored
Normal file
@ -0,0 +1,40 @@
|
||||
<?php
|
||||
/**
|
||||
* Created by PhpStorm.
|
||||
* User: Jaeger <JaegerCode@gmail.com>
|
||||
* Date: 2017/9/22
|
||||
*/
|
||||
|
||||
namespace QL\Providers;
|
||||
|
||||
|
||||
use QL\Contracts\ServiceProviderContract;
|
||||
use QL\Kernel;
|
||||
use QL\Services\HttpService;
|
||||
use QL\Services\MultiRequestService;
|
||||
|
||||
class HttpServiceProvider implements ServiceProviderContract
|
||||
{
|
||||
public function register(Kernel $kernel)
|
||||
{
|
||||
$kernel->bind('get',function (...$args){
|
||||
return HttpService::get($this,...$args);
|
||||
});
|
||||
|
||||
$kernel->bind('post',function (...$args){
|
||||
return HttpService::post($this,...$args);
|
||||
});
|
||||
|
||||
$kernel->bind('postJson',function (...$args){
|
||||
return HttpService::postJson($this,...$args);
|
||||
});
|
||||
|
||||
$kernel->bind('multiGet',function (...$args){
|
||||
return new MultiRequestService($this,'get',...$args);
|
||||
});
|
||||
|
||||
$kernel->bind('multiPost',function (...$args){
|
||||
return new MultiRequestService($this,'post',...$args);
|
||||
});
|
||||
}
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user