优化查询速度

This commit is contained in:
taoser 2024-04-14 12:08:53 +08:00
parent fe2d08ca8e
commit a8943fa6aa
69 changed files with 3055 additions and 2175 deletions

View File

@ -16,7 +16,6 @@ use think\facade\Request;
use think\facade\View; use think\facade\View;
use think\facade\Db; use think\facade\Db;
use think\facade\Session; use think\facade\Session;
use think\facade\Cache;
use app\BaseController as BaseCtrl; use app\BaseController as BaseCtrl;
/** /**
@ -62,28 +61,28 @@ class BaseController extends BaseCtrl
private function setUid() private function setUid()
{ {
if(Session::has('user_id')) { if(Session::has('user_id')) {
$this->uid = Session::get('user_id'); $this->uid = Session::get('user_id') ?? -1;
} }
} }
private function setUser() private function setUser()
{ {
if(Session::has('user_id')) { if(Session::has('user_id')) {
$this->uid = Session::get('user_id'); $this->uid = Session::get('user_id') ?? -1;
} }
} }
// 显示子导航subnav // 显示子导航subnav
protected function showSubnav() protected function showSubnav()
{ {
$subCateList = []; // 没有点击任何分类,点击首页获取全部分类信息
//1.查询父分类id //1.查询父分类id
$pCate = Db::name('cate')->field('id,pid,ename,catename,is_hot')->where(['ename'=>input('ename'),'status'=>1,'delete_time'=>0])->find(); $pCate = Db::name('cate')->field('id,pid,ename,catename,is_hot')->where(['ename'=>input('ename'),'status'=>1,'delete_time'=>0])->find();
if(empty($pCate)) { // 没有点击任何分类,点击首页获取全部分类信息 if(!is_null($pCate)) { // 点击分类,获取子分类信息
$subCateList = [];
} else { // 点击分类,获取子分类信息
$parentId = $pCate['id']; $parentId = $pCate['id'];
$subCate = Db::name('cate')->field('id,ename,catename,is_hot,pid')->where(['pid'=>$parentId,'status'=>1,'delete_time'=>0])->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)) { // 有子分类 if(!empty($subCate)) { // 有子分类
$subCateList = array2tree($subCate); $subCateList = array2tree($subCate);
} else { //无子分类 } else { //无子分类
@ -106,16 +105,13 @@ class BaseController extends BaseCtrl
//显示当前登录用户 //显示当前登录用户
protected function showUser($id) protected function showUser($id)
{ {
$user = Cache::get('user'.$id); if($id == -1) return [];
if(!$user){
//1.查询用户 //1.查询用户
$user = Db::name('user') $user = Db::name('user')
->alias('u') ->alias('u')
->join('user_viprule v','v.vip = u.vip') ->join('user_viprule v','v.vip = u.vip')
->field('u.id as id,v.id as vid,name,nickname,user_img,sex,area_id,auth,city,phone,email,active,sign,point,u.vip as vip,nick,u.create_time as cteate_time') ->field('u.id as id,v.id as vid,name,nickname,user_img,sex,area_id,auth,city,phone,email,active,sign,point,u.vip as vip,nick,u.create_time as create_time')
->find($id); ->find((int)$id);
Cache::tag('user')->set('user'.$id, $user, 600);
}
return $user; return $user;
} }

View File

@ -2,11 +2,11 @@
/* /*
* @Author: TaoLer <317927823@qq.com> * @Author: TaoLer <317927823@qq.com>
* @Date: 2021-12-06 16:04:50 * @Date: 2021-12-06 16:04:50
* @LastEditTime: 2022-08-16 14:16:40 * @LastEditTime: 2024-04-12 19:32:40
* @LastEditors: TaoLer * @LastEditors: TaoLer
* @Description: 优化版 * @Description: 优化版
* @FilePath: \TaoLer\app\common\lib\SqlFile.php * @FilePath: \TaoLer\app\common\lib\SqlFile.php
* Copyright (c) 2020~2022 https://www.aieok.com All rights reserved. * Copyright (c) 2020~2024 https://www.aieok.com All rights reserved.
*/ */
declare (strict_types = 1); declare (strict_types = 1);
@ -84,6 +84,9 @@ class SqlFile
if (file_exists($sqlFile)) { if (file_exists($sqlFile)) {
$sqlArr = self::loadSqlFile($sqlFile); $sqlArr = self::loadSqlFile($sqlFile);
if(!empty($sqlArr)) { if(!empty($sqlArr)) {
$orginal = 'tao_'; //sql默认表前缀
$prefix = config('database.mysql.prefix'); // 现在表前缀
($orginal == $prefix) ? true : $sqlArr = str_replace(" `{$orginal}", " `{$prefix}", $sqlArr); //替换数组中表前缀
foreach($sqlArr as $v){ foreach($sqlArr as $v){
try { try {
Db::execute($v); Db::execute($v);

View File

@ -110,10 +110,10 @@ class Article extends Model
*/ */
public function getArtTop(int $num) public function getArtTop(int $num)
{ {
return Cache::remember('topArticle', function() use($num){ return Cache::remember('topArticle', function() use($num){
$topIdArr = $this::where(['is_top' => 1, 'status' => 1])->limit($num)->column('id');
return $this::field('id,title,title_color,cate_id,user_id,create_time,is_top,pv,upzip,has_img,has_video,has_audio,read_type') return $this::field('id,title,title_color,cate_id,user_id,create_time,is_top,pv,upzip,has_img,has_video,has_audio,read_type')
->where(['is_top' => 1, 'status' => 1]) ->where('id', 'in', $topIdArr)
->with([ ->with([
'cate' => function (Query $query) { 'cate' => function (Query $query) {
$query->where('delete_time', 0)->field('id,catename,ename'); $query->where('delete_time', 0)->field('id,catename,ename');
@ -122,8 +122,7 @@ class Article extends Model
$query->field('id,name,nickname,user_img'); $query->field('id,name,nickname,user_img');
} }
])->withCount(['comments']) ])->withCount(['comments'])
->order('create_time', 'desc') ->order('id', 'desc')
->limit($num)
->append(['url']) ->append(['url'])
->select() ->select()
->toArray(); ->toArray();
@ -151,8 +150,9 @@ class Article extends Model
} ]) } ])
->withCount(['comments']) ->withCount(['comments'])
->where('status', '=', 1) ->where('status', '=', 1)
->order('create_time','desc') ->order('id','desc')
->limit($num) ->limit($num)
->hidden(['art_pass'])
->append(['url']) ->append(['url'])
->select(); ->select();
@ -163,7 +163,7 @@ class Article extends Model
/** /**
* 热点文章 * 热点文章
* @param int $num 热点列表数量 * @param int $num 热点列表数量 评论或者pv排序
* @return \think\Collection * @return \think\Collection
* @throws \think\db\exception\DataNotFoundException * @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\DbException * @throws \think\db\exception\DbException
@ -171,17 +171,48 @@ class Article extends Model
*/ */
public function getArtHot(int $num) public function getArtHot(int $num)
{ {
return Cache::remember('article_hot', function() use($num){
$comments = Comment::field('article_id,count(*) as count')
->where('comment.delete_time',0)
->hasWhere('article',['status' =>1, 'delete_time' => 0])
->group('article_id')
->order('count','desc')
->limit($num)
->select();
$idArr = [];
foreach($comments as $v) {
$idArr[] = $v->article_id;
}
$where = [];
if(count($idArr)) {
// 评论数
$where = [
['id', 'in', $idArr]
];
$artHot = $this::field('id,cate_id,title,create_time') $artHot = $this::field('id,cate_id,title,create_time')
->withCount('comments') ->withCount('comments')
->where(['status' => 1]) ->where($where)
->whereMonth('create_time') //->whereYear('create_time')
->order('comments_count','desc') // ->order('comments_count','desc')
->limit($num)
->withCache(600)
->append(['url']) ->append(['url'])
->select(); ->select();
} else {
// pv数
$where = [
['status', '=', 1]
];
$artHot = $this::field('id,cate_id,title,create_time')
->withCount('comments')
->where($where)
->whereMonth('create_time')
->order('pv','desc')
->limit($num)
->append(['url'])
->select();
}
return $artHot; return $artHot;
}, 3600);
} }
/** /**
@ -223,12 +254,6 @@ class Article extends Model
*/ */
public function getCateList(string $ename, string $type, int $page = 1) public function getCateList(string $ename, string $type, int $page = 1)
{ {
$where = [];
$cateId = Cate::where('ename',$ename)->value('id');
if($cateId){
$where[] = ['cate_id' ,'=', $cateId];
}
switch ($type) { switch ($type) {
//查询文章,15个分1页 //查询文章,15个分1页
case 'jie': case 'jie':
@ -244,10 +269,28 @@ class Article extends Model
$where[] = ['jie','=', 0]; $where[] = ['jie','=', 0];
break; break;
} }
$where[] = ['status', '=', 1]; $where[] = ['status', '=', 1];
return Cache::remember('cate_list_'.$ename.$type.$page, function() use($where,$page){ return Cache::remember('cate_list_'.$ename.$type.$page, function() use($where,$ename,$page){
return $this::field('id,cate_id,user_id,title,content,title_color,create_time,is_top,is_hot,pv,jie,upzip,has_img,has_video,has_audio,read_type,art_pass') $cateId = Cate::where('ename',$ename)->value('id');
if($cateId){
$where[] = ['cate_id' ,'=', $cateId];
}
$list = $this::field('id')->where($where)->order(['id'=>'desc'])->paginate([
'list_rows' => 15,
'page' => $page
])->toArray();
$idArr = [];
if($list['total'] > 0) {
foreach($list['data'] as $v) {
$idArr[] = $v['id'];
}
}
$data = $this::field('id,cate_id,user_id,title,content,title_color,create_time,is_top,is_hot,pv,jie,upzip,has_img,has_video,has_audio,read_type,art_pass')
->with([ ->with([
'cate' => function($query) { 'cate' => function($query) {
$query->field('id,catename,ename'); $query->field('id,catename,ename');
@ -256,13 +299,19 @@ class Article extends Model
$query->field('id,name,nickname,user_img,vip'); $query->field('id,name,nickname,user_img,vip');
} }
])->withCount(['comments']) ])->withCount(['comments'])
->where($where) ->where('id','in',$idArr)
->limit(15) ->order(['id'=>'desc'])
->order(['create_time'=>'desc']) ->append(['url'])
->paginate([ ->hidden(['art_pass'])
'list_rows' => 15, ->select()
'page' => $page ->toArray();
])->append(['url'])->toArray(); return [
'total' => $list['total'],
'per_page' => $list['per_page'],
'current_page' => $list['current_page'],
'last_page' => $list['last_page'],
'data' => $data
];
}, 600); }, 600);
} }
@ -273,7 +322,7 @@ class Article extends Model
$query->where(['delete_time'=>0,'status'=>1])->field('id,ename'); $query->where(['delete_time'=>0,'status'=>1])->field('id,ename');
}]) }])
->where(['user_id' => $id,'status' => 1]) ->where(['user_id' => $id,'status' => 1])
->order(['create_time'=>'desc']) ->order('id','desc')
->append(['url']) ->append(['url'])
->limit(25) ->limit(25)
->cache(3600) ->cache(3600)
@ -296,7 +345,7 @@ class Article extends Model
$map[] = ['title','like','%'.$keywords.'%']; $map[] = ['title','like','%'.$keywords.'%'];
$res = Article::where($map) $res = Article::where($map)
->withCount('comments') ->withCount('comments')
->order('create_time','desc') ->order('id','desc')
->append(['url']) ->append(['url'])
->paginate(10); ->paginate(10);
@ -366,20 +415,30 @@ class Article extends Model
public function getPrevNextArticle($id, $cid) public function getPrevNextArticle($id, $cid)
{ {
//上一篇 //上一篇
$previous = $this::field('id,title,cate_id') $pIds = $this::where([
->where([ ['id', '>=', $id], // >= <= 条件可以使用索引
['id', '<', $id],
['cate_id', '=', $cid], ['cate_id', '=', $cid],
['status', '=',1] ['status', '=',1]
])->order('id desc')->limit(1)->append(['url'])->select()->toArray(); ])->order('id asc')->limit(2)->column('id');
if(count($pIds) === 2) {
$previous = $this::field('id,title,cate_id')->append(['url'])->find($pIds[1])->toArray();
} else {
$previous = [];
}
//下一篇 //下一篇
$next = $this::field('id,title,cate_id') $nids = $this::where([
->where([ ['id', '<=', $id],
['id', '>', $id],
['cate_id', '=', $cid], ['cate_id', '=', $cid],
['status', '=',1] ['status', '=',1]
])->order('id asc')->limit(1)->append(['url'])->select()->toArray(); ])->order('id desc')->limit(2)->column('id');
if(count($nids) === 2) {
$next = $this::field('id,title,cate_id')->append(['url'])->find($nids[1])->toArray();
} else {
$next = [];
}
return ['previous' => $previous, 'next' => $next]; return ['previous' => $previous, 'next' => $next];
} }
@ -398,7 +457,7 @@ class Article extends Model
]) ])
->where(['status' => 1]) ->where(['status' => 1])
->where($where) ->where($where)
->order('create_time', 'desc') ->order('id', 'desc')
->paginate([ ->paginate([
'list_rows' => $limit, 'list_rows' => $limit,
'page' => $page 'page' => $page
@ -418,7 +477,7 @@ class Article extends Model
} }
]) ])
->where($where) ->where($where)
->order('create_time', 'desc') ->order('id', 'desc')
->paginate([ ->paginate([
'list_rows' => $limit, 'list_rows' => $limit,
'page' => $page 'page' => $page

View File

@ -63,13 +63,13 @@ class Cate extends Model
public function del($id) public function del($id)
{ {
$cates = $this->field('id,pid')->with('article')->find($id); $cates = $this->field('id,pid')->with('article')->find($id);
$sonCate = $this->field('id,pid')->where('pid',$cates['id'])->find(); $sonCate = $this::where('pid',$cates['id'])->count();
if(empty($sonCate)) { if($sonCate > 0) {
return '存在子分类,无法删除';
}
$res = $cates->together(['article'])->delete(); $res = $cates->together(['article'])->delete();
return $res ? 1 : '删除失败'; return $res ? 1 : '删除失败';
} }
return '存在子分类,无法删除';
}
// 分类表 // 分类表
public function getList() public function getList()
@ -121,12 +121,12 @@ class Cate extends Model
public function getUrlAttr($value,$data) public function getUrlAttr($value,$data)
{ {
// 栏目下存在帖子则返回正常url,否则为死链 // 栏目下存在帖子则返回正常url,否则为死链
$articleArr = Article::field('id')->where('cate_id', $data['id'])->find(); $articleCount = Article::where('cate_id', $data['id'])->count();
if(empty($articleArr)) { if($articleCount > 0) {
return (string) url('cate',['ename' => $data['ename']]);
}
return 'javascript:void(0);'; return 'javascript:void(0);';
} }
return (string) url('cate',['ename' => $data['ename']]);;
}
} }

View File

@ -33,13 +33,12 @@ class MessageTo extends Model
//得到消息数 //得到消息数
public function getMsgNum($id) public function getMsgNum($id)
{ {
$msg = $this::where(['receve_id'=>$id,'is_read'=>0])->column('id'); $msgNum = $this::where(['receve_id'=>$id,'is_read'=>0])->count('id');
if($num = count($msg)) { if($msgNum) {
return $num; return $msgNum;
} else { }
return 0; return 0;
} }
}
} }

View File

@ -50,6 +50,7 @@ class Article extends BaseController
//分类列表 //分类列表
$artList = $this->model->getCateList($ename,$type,$page); $artList = $this->model->getCateList($ename,$type,$page);
// halt($artList);
// 热议文章 // 热议文章
$artHot = $this->model->getArtHot(10); $artHot = $this->model->getArtHot(10);
@ -118,15 +119,15 @@ class Article extends BaseController
//上一篇下一篇 //上一篇下一篇
$upDownArt = $this->model->getPrevNextArticle($id,$artDetail['cate_id']); $upDownArt = $this->model->getPrevNextArticle($id,$artDetail['cate_id']);
if(empty($upDownArt['previous'][0])) { if(empty($upDownArt['previous'])) {
$previous = '前面已经没有了!'; $previous = '前面已经没有了!';
} else { } else {
$previous = '<a href="' . $upDownArt['previous'][0]['url'] . '" rel="prev">' . $upDownArt['previous'][0]['title'] . '</a>'; $previous = '<a href="' . $upDownArt['previous']['url'] . '" rel="prev">' . $upDownArt['previous']['title'] . '</a>';
} }
if(empty($upDownArt['next'][0])) { if(empty($upDownArt['next'])) {
$next = '已经是最新的内容了!'; $next = '已经是最新的内容了!';
} else { } else {
$next = '<a href="' . $upDownArt['next'][0]['url'] . '" rel="prev">' . $upDownArt['next'][0]['title'] . '</a>'; $next = '<a href="' . $upDownArt['next']['url'] . '" rel="prev">' . $upDownArt['next']['title'] . '</a>';
} }
//评论 //评论
@ -440,7 +441,7 @@ class Article extends BaseController
*/ */
public function delete() public function delete()
{ {
$article = $this->model->find(input('id')); $article = $this->model->find((int)input('id'));
$result = $article->together(['comments'])->delete(); $result = $article->together(['comments'])->delete();
if($result) { if($result) {
return Msgres::success('delete_success'); return Msgres::success('delete_success');

View File

@ -11,7 +11,6 @@
namespace app\index\controller; namespace app\index\controller;
use app\common\controller\BaseController; use app\common\controller\BaseController;
use app\common\lib\facade\HttpHelper;
use think\facade\View; use think\facade\View;
use think\facade\Request; use think\facade\Request;
use think\facade\Db; use think\facade\Db;
@ -32,6 +31,22 @@ class Index extends BaseController
*/ */
public function index() public function index()
{ {
// $res = get_addons_info('callme1');
// halt($res);
// $htmlString = "<p>这是一个<a href='http://example.com'>链接</a>和其他文本。</p>";
// $cleanString = preg_replace("/<a\b[^>]*>(.*?)<\/a>/is", "", $htmlString);
// //$cleanString = preg_replace("(<a [^>]*>|</a>)","",$htmlString);
// echo $cleanString;
// $ip = file_get_contents('https://myip.ipip.net');
// echo "My public IP address is: " . $ip;
// $alipay = AlipayFactory::createPayMethod();
// $weixin = WeixinFactory::createPayMethod();
// $a = $alipay->index();
// $b= $weixin->index();
// var_dump($a,$b);
$types = input('type'); $types = input('type');
//置顶文章 //置顶文章
$artTop = Article::getArtTop(5); $artTop = Article::getArtTop(5);

View File

@ -11,7 +11,6 @@
namespace app\index\controller; namespace app\index\controller;
use app\common\controller\BaseController; use app\common\controller\BaseController;
use think\facade\Session;
use think\facade\Request; use think\facade\Request;
use think\facade\Db; use think\facade\Db;
use app\common\model\Message as MessageModel; use app\common\model\Message as MessageModel;
@ -25,12 +24,8 @@ class Message extends BaseController
{ {
$messgeto = new MessageTo(); $messgeto = new MessageTo();
$num = $messgeto->getMsgNum($this->uid); $num = $messgeto->getMsgNum($this->uid);
if($num){ if($num) return json(['status' =>0,'count' => $num, 'msg' => 'ok']);
$res = ['status' =>0,'count' => $num, 'msg' => 'ok']; return json(['status' =>0,'count' => 0, 'msg' => 'no message']);
} else {
$res = ['status' =>0,'count' => 0, 'msg' => 'no message'];
}
return json($res);
} }
//消息查询 //消息查询
@ -82,18 +77,20 @@ class Message extends BaseController
$uid = $this->uid; $uid = $this->uid;
$id = Request::only(['id']); $id = Request::only(['id']);
if($id['id'] == 'true'){ if($id['id'] == 'true'){
//删除所有此用户消息 // id为'true' 删除所有此用户消息
$msg = Db::name('message_to')->where(['receve_id'=>$uid,'delete_time'=>0])->useSoftDelete('delete_time',time())->delete(); $msg = Db::name('message_to')->where(['receve_id' => $uid])->delete();
} else { } else {
//删除单条消息 //删除单条消息
$msg = Db::name('message_to')->where('id',$id['id'])->useSoftDelete('delete_time',time())->delete(); $msg = Db::name('message_to')->where('id', $id['id'])->delete();
} }
if($msg){ if($msg){
$res = ['status'=>0]; $res = ['status'=>0];
}
return $res; return $res;
}
} }

View File

@ -301,10 +301,7 @@ class User extends BaseController
public function home($id) public function home($id)
{ {
//用户 //用户
$u = Cache::get('user'.$id); $u = Db::name('user')->field('name,nickname,city,sex,sign,user_img,point,vip,create_time')->find($id);
if(!$u){
$u = Db::name('user')->field('name,nickname,city,sex,sign,user_img,point,vip,create_time')->cache(3600)->find($id);
}
$article = new Article(); $article = new Article();
$arts = $article->getUserArtList((int) $id); $arts = $article->getUserArtList((int) $id);
@ -320,7 +317,7 @@ class User extends BaseController
->field('a.id,a.title,t.ename,c.content,c.create_time,c.delete_time,c.status') ->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(['a.delete_time'=>0,'c.delete_time'=>0,'c.status'=>1])
->where('c.user_id',$id) ->where('c.user_id',$id)
->order(['c.create_time'=>'desc']) ->order(['c.id'=>'desc'])
->limit(10) ->limit(10)
->cache(3600)->select(); ->cache(3600)->select();

View File

@ -430,7 +430,8 @@ CREATE TABLE `tao_message_to` (
`create_time` int NOT NULL DEFAULT 0 COMMENT '创建时间', `create_time` int NOT NULL DEFAULT 0 COMMENT '创建时间',
`update_time` int NOT NULL DEFAULT 0 COMMENT '更新时间', `update_time` int NOT NULL DEFAULT 0 COMMENT '更新时间',
`delete_time` int NOT NULL DEFAULT 0 COMMENT '删除时间', `delete_time` int NOT NULL DEFAULT 0 COMMENT '删除时间',
PRIMARY KEY (`id`) USING BTREE PRIMARY KEY (`id`) USING BTREE,
INDEX `idx_mesto_receveid`(`receve_id`) USING BTREE COMMENT '收件人ID'
) ENGINE = MyISAM AUTO_INCREMENT = 1 CHARACTER SET = utf8 COLLATE = utf8_general_ci COMMENT = '消息详细表' ROW_FORMAT = Dynamic; ) ENGINE = MyISAM AUTO_INCREMENT = 1 CHARACTER SET = utf8 COLLATE = utf8_general_ci COMMENT = '消息详细表' ROW_FORMAT = Dynamic;
-- ---------------------------- -- ----------------------------

72
composer.lock generated
View File

@ -799,16 +799,16 @@
}, },
{ {
"name": "jaeger/querylist", "name": "jaeger/querylist",
"version": "V4.2.8", "version": "V4.2.9",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/jae-jae/QueryList.git", "url": "https://github.com/jae-jae/QueryList.git",
"reference": "39dc0ca9c668bec7a793e20472ccd7d26ef89ea4" "reference": "7aae3aed38214d3d7096174faf49f6c41b2dd550"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/jae-jae/QueryList/zipball/39dc0ca9c668bec7a793e20472ccd7d26ef89ea4", "url": "https://api.github.com/repos/jae-jae/QueryList/zipball/7aae3aed38214d3d7096174faf49f6c41b2dd550",
"reference": "39dc0ca9c668bec7a793e20472ccd7d26ef89ea4", "reference": "7aae3aed38214d3d7096174faf49f6c41b2dd550",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
@ -816,11 +816,10 @@
"jaeger/g-http": "^1.1", "jaeger/g-http": "^1.1",
"jaeger/phpquery-single": "^1", "jaeger/phpquery-single": "^1",
"php": ">=7.1", "php": ">=7.1",
"tightenco/collect": ">5.0" "symfony/var-dumper": ">3.4"
}, },
"require-dev": { "require-dev": {
"phpunit/phpunit": "^8.5", "phpunit/phpunit": "^8.5"
"symfony/var-dumper": "^3.3"
}, },
"type": "library", "type": "library",
"autoload": { "autoload": {
@ -847,7 +846,7 @@
], ],
"support": { "support": {
"issues": "https://github.com/jae-jae/QueryList/issues", "issues": "https://github.com/jae-jae/QueryList/issues",
"source": "https://github.com/jae-jae/QueryList/tree/V4.2.8" "source": "https://github.com/jae-jae/QueryList/tree/V4.2.9"
}, },
"funding": [ "funding": [
{ {
@ -855,7 +854,7 @@
"type": "open_collective" "type": "open_collective"
} }
], ],
"time": "2021-07-05T06:07:58+00:00" "time": "2024-04-12T06:29:50+00:00"
}, },
{ {
"name": "laravel/serializable-closure", "name": "laravel/serializable-closure",
@ -2404,61 +2403,6 @@
}, },
"time": "2022-04-16T23:08:43+00:00" "time": "2022-04-16T23:08:43+00:00"
}, },
{
"name": "tightenco/collect",
"version": "v8.83.27",
"source": {
"type": "git",
"url": "https://github.com/tighten/collect.git",
"reference": "07eed6cf7441c7a69c379fdcb118eec1a1fdd0e6"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/tighten/collect/zipball/07eed6cf7441c7a69c379fdcb118eec1a1fdd0e6",
"reference": "07eed6cf7441c7a69c379fdcb118eec1a1fdd0e6",
"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"
},
"type": "library",
"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.27"
},
"abandoned": "illuminate/collections",
"time": "2023-01-13T18:05:42+00:00"
},
{ {
"name": "topthink/framework", "name": "topthink/framework",
"version": "v6.1.4", "version": "v6.1.4",

View File

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

View File

@ -434,7 +434,6 @@ body .layui-edit-face .layui-layer-content{padding:0; background-color:#fff; co
.jie-row li i, .jie-row li em, .jie-row li cite{font-size:12px; color:#999; font-style: normal;} .jie-row li i, .jie-row li em, .jie-row li cite{font-size:12px; color:#999; font-style: normal;}
.jie-row li .mine-edit{margin-left:15px; padding:0 6px; background-color: #8FCDA0; color:#fff; font-size:12px;} .jie-row li .mine-edit{margin-left:15px; padding:0 6px; background-color: #8FCDA0; color:#fff; font-size:12px;}
.jie-row li em{position:absolute; right:0; top:0;} .jie-row li em{position:absolute; right:0; top:0;}
.jie-row li .jie-user{}
.jie-row li .jie-title{max-width: 70%; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;} .jie-row li .jie-title{max-width: 70%; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;}
.jie-row li .jie-user img{position:relative; top: 16px; width: 35px; height: 35px;} .jie-row li .jie-user img{position:relative; top: 16px; width: 35px; height: 35px;}
@ -792,7 +791,7 @@ p {
margin: 0; margin: 0;
white-space: normal; white-space: normal;
word-break: break-all; word-break: break-all;
-webkit-user-select: none; /* -webkit-user-select: none; */
} }
code[class*="language-"], pre[class*="language-"] { code[class*="language-"], pre[class*="language-"] {

View File

@ -1,21 +1,16 @@
/** /**
TaoLer社区修改 www.aieok.com TaoLer社区修改 www.aieok.com
@Name: Fly社区主入口 @Name: Fly社区主入口
2021-5.21 2024-4.7
*/ */
layui.define(['layer', 'laytpl', 'form', 'element', 'upload', 'util', 'imgcom'], function(exports){ layui.define(['layer', 'form', 'util'], function(exports){
var $ = layui.jquery var $ = layui.jquery
,layer = layui.layer ,layer = layui.layer
,laytpl = layui.laytpl
,form = layui.form ,form = layui.form
,element = layui.element
,upload = layui.upload
,util = layui.util ,util = layui.util
,imgcom = layui.imgcom
,device = layui.device() ,device = layui.device()
,DISABLED = 'layui-btn-disabled';
var uid = layui.cache.user.uid; var uid = layui.cache.user.uid;
var login = $('.fly-nav-user').attr('userlogin'); var login = $('.fly-nav-user').attr('userlogin');
@ -93,522 +88,13 @@ layui.define(['layer', 'laytpl', 'form', 'element', 'upload', 'util', 'imgcom'],
,form: {} ,form: {}
//简易编辑器 //简易编辑器 -移除 -2024/4/7
,layEditor: function(options){
var html = ['<div class="layui-unselect fly-edit">'
,'<span type="strong" title="加粗"><i class="layui-icon layedit-tool-b layedit-tool-active" title="加粗" lay-command="Bold" layedit-event="b" "=""></i></span>'
,'<span type="face" title="表情"><i class="iconfont icon-yxj-expression" style="top: 1px;"></i></span>'
,'<span type="picture" title="图片img[src]"><i class="iconfont icon-tupian"></i></span>'
,'<span type="video" title="视频"><i class="layui-icon layui-icon-video"></i></span>'
,'<span type="audio" title="音频"><i class="layui-icon layui-icon-headset"></i></span>'
,'<span type="href" title="超链接格式a(href)[text]"><i class="iconfont icon-lianjie"></i></span>'
,'<span type="quote" title="引用"><i class="iconfont icon-yinyong" style="top: 1px;"></i></span>'
,'<span type="code" title="插入代码" class="layui-hide-xs"><i class="iconfont icon-emwdaima" style="top: 1px;"></i></span>'
,'<span type="hr" title="水平线">hr</span>'
,'<span type="preview" title="预览"><i class="iconfont icon-yulan1"></i></span>'
,'</div>'].join('');
var closeTips = function(){
layer.close(mod.face.index);
};
var log = {}, mod = {
//加粗
strong: function(editor){
var str = window.getSelection().toString();
if(!str == ''){
//var strB = '<b>'+ str + '</b>';
layui.focusInsert(editor[0], '[strong]'+ str + '[/strong]');
//console.log(str);
// console.log(strB);
}
},
face: function(editor, self){ //插入表情
var str = '', ul, face = fly.faces;
for(var key in face){
str += '<li title="'+ key +'"><img src="'+ face[key] +'"></li>';
}
str = '<ul id="LAY-editface" class="layui-clear" style="margin: -10px 0 0 -1px;">'+ str +'</ul>';
layer.close(mod.face.index);
mod.face.index = layer.tips(str, self, {
tips: 3
,time: 0
,skin: 'layui-edit-face'
,tipsMore: true
});
$(document).off('click', closeTips).on('click', closeTips);
$('#LAY-editface li').on('click', function(){
var title = $(this).attr('title') + ' ';
layui.focusInsert(editor[0], 'face' + title);
editor.trigger('keyup');
});
}
,picture: function(editor){ //插入图片
//判断登陆
if(uid == -1){
layer.msg('请登录再发图', {icon: 6}, function(){
location.href = login;
})
return false;
}
layer.open({
type: 1
,id: 'fly-jie-upload'
,title: '插入图片'
,area: 'auto'
,shade: false
//,area: '465px'
,fixed: false
,offset: [
editor.offset().top - $(window).scrollTop() + 'px'
,editor.offset().left + 'px'
]
,skin: 'layui-layer-border'
,content: ['<ul class="layui-form layui-form-pane" style="margin: 20px;">'
,'<li class="layui-form-item">'
,'<label class="layui-form-label">URL</label>'
,'<div class="layui-input-inline">'
,'<input required name="image" placeholder="支持粘贴远程图片地址" value="" class="layui-input">'
,'</div>'
,'<button type="button" class="layui-btn layui-btn-primary" id="uploadImg"><i class="layui-icon">&#xe67c;</i>上传图片</button>'
,'</li>'
,'<li class="layui-form-item" style="text-align: center;">'
,'<button type="button" lay-submit lay-filter="uploadImages" class="layui-btn" id="img-button">确认</button>'
,'</li>'
,'</ul>'].join('')
,success: function(layero, index){
var image = layero.find('input[name="image"]');
//执行上传实例
upload.render({
elem: '#uploadImg'
,accept: 'images'
,acceptMime: 'image/*'
,exts: 'jpg|png|gif|bmp|jpeg'
,url: uploads
,data: {type:'image'}
,auto: false
//,bindAction: '#img-button' //指向一个按钮触发上传
//,field: 'image'
,size: 10240
,choose: function (obj) { //选择文件后的回调
imgcom.uploads(obj);
}
,done: function(res){
if(res.status == 0){
//console.log(res.url);
image.val(res.url);
} else {
layer.msg(res.msg, {icon: 5});
}
}
,error: function(){
layer.msg('系统错误,请联系管理员');
}
});
form.on('submit(uploadImages)', function(data){
var field = data.field;
if(!field.image) return image.focus();
layui.focusInsert(editor[0], 'img['+ field.image + '] ');
layer.close(index);
editor.trigger('keyup');
});
}
});
}
,href: function(editor){ //超链接
layer.prompt({
title: '请输入合法链接'
,shade: false
,fixed: false
,id: 'LAY_flyedit_href'
,offset: [
editor.offset().top - $(window).scrollTop() + 1 + 'px'
,editor.offset().left + 1 + 'px'
]
}, function(val, index, elem){
if(!/^http(s*):\/\/[\S]/.test(val)){
layer.tips('请务必 http 或 https 开头', elem, {tips:1})
return;
}
layui.focusInsert(editor[0], ' a('+ val +')['+ val + '] ');
layer.close(index);
editor.trigger('keyup');
});
}
,quote: function(editor){ //引用
layer.prompt({
title: '请输入引用内容'
,formType: 2
,maxlength: 10000
,shade: false
,id: 'LAY_flyedit_quote'
,offset: [
editor.offset().top - $(window).scrollTop() + 1 + 'px'
,editor.offset().left + 1 + 'px'
]
,area: ['300px', '100px']
}, function(val, index, elem){
layui.focusInsert(editor[0], '[quote]\n '+ val + '\n[/quote]\n');
layer.close(index);
editor.trigger('keyup');
});
}
,code: function(editor){ //插入代码
layer.prompt({
title: '请贴入代码'
,formType: 2
,maxlength: 10000
,shade: false
,id: 'LAY_flyedit_code'
,area: ['800px', '360px']
}, function(val, index, elem){
layui.focusInsert(editor[0], '[pre]\n'+ val + '\n[/pre]\n');
layer.close(index);
editor.trigger('keyup');
});
}
,hr: function(editor){ //插入水平分割线
layui.focusInsert(editor[0], '[hr]\n');
editor.trigger('keyup');
}
,video: function(editor){ //插入视频
//判断登陆
if(uid == -1){
layer.msg('请登录再发视频', {icon: 6}, function(){
location.href = login;
})
return false;
}
layer.open({
type: 1
,id: 'fly-jie-video-upload'
,title: '插入视频'
,area: 'auto'
,shade: false
//,area: '465px'
,fixed: false
,offset: [
editor.offset().top - $(window).scrollTop() + 'px'
,editor.offset().left + 'px'
]
,skin: 'layui-layer-border'
,content: ['<ul class="layui-form layui-form-pane" style="margin: 20px;">'
,'<li class="layui-form-item">'
,'<label class="layui-form-label">封面</label>'
,'<div class="layui-input-inline">'
,'<input type="text" required name="cover" placeholder="支持粘贴远程图片地址" value="" class="layui-input">'
,'</div>'
,'<button type="button" lay-type="image" class="layui-btn" id="video-img"><i class="layui-icon">&#xe67c;</i>上传封图</button>'
,'</li>'
,'<li class="layui-form-item">'
,'<label class="layui-form-label">URL</label>'
,'<div class="layui-input-inline">'
,'<input type="text" required name="video" placeholder="支持粘贴远程视频地址" value="" class="layui-input">'
,'</div>'
,'<button type="button" lay-type="video" class="layui-btn" id="layedit-video"><i class="layui-icon layui-icon-video"></i>上传视频</button>'
,'</li>'
,'<li class="layui-form-item" style="text-align: center;">'
,'<button type="button" lay-submit lay-filter="uploadImages" class="layui-btn">确认</button>'
,'</li>'
,'</ul>'].join('')
,success: function(layero, index){
var video = layero.find('input[name="video"]'), cover = layero.find('input[name="cover"]');
//上传视频
upload.render({
url: uploads
,data: {type:'video'}
,accept: 'video'
,acceptMime: 'video/mp4'
,exts: 'mp4'
,elem: '#layedit-video'
,before: function(obj){ //obj参数包含的信息跟 choose回调完全一致可参见上文。
layer.load(2); //上传loading
}
,done: function(res){
if(res.status == 0){
video.val(res.url);
} else {
layer.msg(res.msg, {icon: 5});
}
layer.closeAll('loading');
}
});
//上传图片
upload.render({
elem: '#video-img'
,accept: 'images'
,acceptMime: 'image/*'
,exts: 'jpg|png|gif|bmp|jpeg'
,url: uploads
,data: {type:'image'}
,auto: false
//,bindAction: '#img-button' //指向一个按钮触发上传
//,field: 'image'
,size: 10240
,choose: function (obj) { //选择文件后的回调
imgcom.uploads(obj);
}
,done: function(res){
if(res.status == 0){
cover.val(res.url);
} else {
layer.msg(res.msg, {icon: 5});
}
}
,error: function(){
layer.msg('系统错误,请联系管理员');
}
});
form.on('submit(uploadImages)', function(data){
var field = data.field;
if(!field.video) return video.focus();
layui.focusInsert(editor[0], 'video('+field.cover+')['+ field.video + '] ');
layer.close(index);
});
}
});
}
,audio: function(editor){ //插入音频
//判断登陆
if(uid == -1){
layer.msg('请登录再发布', {icon: 6}, function(){
location.href = login;
})
return false;
}
layer.open({
type: 1
,id: 'fly-jie-audio-upload'
,title: '插入音频'
,area: 'auto'
,shade: false
//,area: '465px'
,fixed: false
,offset: [
editor.offset().top - $(window).scrollTop() + 'px'
,editor.offset().left + 'px'
]
,skin: 'layui-layer-border'
,content: ['<ul class="layui-form layui-form-pane" style="margin: 20px;">'
,'<li class="layui-form-item">'
,'<label class="layui-form-label">URL</label>'
,'<div class="layui-input-inline">'
,'<input required name="audio" placeholder="支持直接粘贴远程音频地址" value="" class="layui-input">'
,'</div>'
,'<button required type="button" name="file" lay-type="audio" class="layui-btn upload-audio"><i class="layui-icon layui-icon-headset"></i>上传音频</button>'
,'</li>'
,'<li class="layui-form-item" style="text-align: center;">'
,'<button type="button" lay-submit lay-filter="uploadImages" class="layui-btn">确认</button>'
,'</li>'
,'</ul>'].join('')
,success: function(layero, index){
var loding,audio = layero.find('input[name="audio"]');
upload.render({
url: uploads
,data: {type:'audio'}
,elem: '#fly-jie-audio-upload .upload-audio'
,accept: 'audio'
,acceptMime: 'audio/*'
,exts: 'mp3|m4a'
,before: function(obj){
//loding = layer.msg('文件上传中,请稍等哦', { icon: 16 ,shade:0.3,time:0 });
layer.load(2); //上传loading
}
,done: function(res){
if(res.status == 0){
audio.val(res.url);
} else {
layer.msg(res.msg, {icon: 5});
}
layer.closeAll('loading');
}
});
form.on('submit(uploadImages)', function(data){
var field = data.field;
if(!field.audio) return audio.focus();
layui.focusInsert(editor[0], 'audio['+ field.audio + '] ');
layer.close(index);
});
}
});
}
,preview: function(editor, span){ //预览
var othis = $(span), getContent = function(){
var content = editor.val();
return /^\{html\}/.test(content) ? content.replace(/^\{html\}/, '') : fly.content(content)
}, isMobile = device.ios || device.android;
if(mod.preview.isOpen) return layer.close(mod.preview.index);
mod.preview.index = layer.open({
type: 1
,title: '预览'
,shade: false
,offset: 'r'
,id: 'LAY_flyedit_preview'
,area: [
isMobile ? '100%' : '775px'
,'100%'
]
,scrollbar: isMobile ? false : true
,anim: -1
,isOutAnim: false
,content: '<div class="detail-body layui-text" style="margin:20px;">'+ getContent() +'</div>'
,success: function(layero){
editor.on('keyup', function(val){
layero.find('.detail-body').html(getContent());
});
mod.preview.isOpen = true;
othis.addClass('layui-this');
}
,end: function(){
delete mod.preview.isOpen;
othis.removeClass('layui-this');
}
});
}
};
layui.use('face', function(face){
options = options || {};
fly.faces = face;
$(options.elem).each(function(index){
var that = this, othis = $(that), parent = othis.parent();
parent.prepend(html);
parent.find('.fly-edit span').on('click', function(event){
var type = $(this).attr('type');
mod[type].call(that, othis, this);
if(type === 'face'){
event.stopPropagation()
}
});
});
});
}
,escape: function(html){
return String(html||'').replace(/&(?!#?[a-zA-Z0-9]+;)/g, '&amp;')
.replace(/</g, '&lt;').replace(/>/g, '&gt;').replace(/'/g, '&#39;').replace(/"/g, '&quot;');
}
//内容转义
,content: function(content){
var util = fly
,item = fly.faces;
//支持的html标签
var html = function(end){
return new RegExp('\\n*\\|\\-'+ (end||'') +'(div|span|p|button|table|thead|th|tbody|tr|td|ul|li|ol|li|dl|dt|dd|h2|h3|h4|h5)([\\s\\S]*?)\\-\\|\\n*', 'g');
};
//XSS
content = util.escape(content||'')
//转义图片
.replace(/img\[([^\s]+?)\]/g, function(img){
return '<div><img src="' + img.replace(/(^img\[)|(\]$)/g, '') + '"></div>';
})
//转义@
.replace(/@(\S+)(\s+?|$)/g, '@<a href="javascript:;" class="fly-aite">$1</a>$2')
//转义表情
.replace(/face\[([^\s\[\]]+?)\]/g, function(face){
var alt = face.replace(/^face/g, '');
return '<img alt="'+ alt +'" title="'+ alt +'" src="' + item[alt] + '">';
})
//转义脚本
.replace(/a(\(javascript:)(.+)(;*\))/g, 'a(javascript:layer.msg(\'非法脚本\');)')
//转义链接
.replace(/a\([\s\S]+?\)\[[\s\S]*?\]/g, function(str){
var href = (str.match(/a\(([\s\S]+?)\)\[/)||[])[1];
var text = (str.match(/\)\[([\s\S]*?)\]/)||[])[1];
if(!href) return str;
var rel = /^(http(s)*:\/\/)\b(?!(\w+\.)*(sentsin.com|layui.com))\b/.test(href.replace(/\s/g, ''));
return '<a href="'+ href +'" style="color: red;" target="_blank"'+ (rel ? ' rel="nofollow"' : '') +'>'+ (text||href) +'</a>';
})
//转义横线
.replace(/\[hr\]\n*/g, '<hr>')
//转义表格
.replace(/\[table\]([\s\S]*)\[\/table\]\n*/g, function(str){
return str.replace(/\[(thead|th|tbody|tr|td)\]\n*/g, '<$1>')
.replace(/\n*\[\/(thead|th|tbody|tr|td)\]\n*/g, '</$1>')
.replace(/\[table\]\n*/g, '<table class="layui-table">')
.replace(/\n*\[\/table\]\n*/g, '</table>');
})
//转义 div/span
.replace(/\n*\[(div|span)([\s\S]*?)\]([\s\S]*?)\[\/(div|span)\]\n*/g, function(str){
return str.replace(/\[(div|span)([\s\S]*?)\]\n*/g, '<$1 $2>')
.replace(/\n*\[\/(div|span)\]\n*/g, '</$1>');
})
//转义列表
.replace(/\[ul\]([\s\S]*)\[\/ul\]\n*/g, function(str){
return str.replace(/\[li\]\n*/g, '<li>')
.replace(/\n*\[\/li\]\n*/g, '</li>')
.replace(/\[ul\]\n*/g, '<ul>')
.replace(/\n*\[\/ul\]\n*/g, '</ul>');
})
//转义代码
.replace(/\[pre\]([\s\S]*)\[\/pre\]\n*/g, function(str){
return str.replace(/\[pre\]\n*/g, '<pre>')
.replace(/\n*\[\/pre\]\n*/g, '</pre>');
})
//转义引用
.replace(/\[quote\]([\s\S]*)\[\/quote\]\n*/g, function(str){
return str.replace(/\[quote\]\n*/g, '<div class="layui-elem-quote">')
.replace(/\n*\[\/quote\]\n*/g, '</div>');
})
//转义加粗
.replace(/\[strong\]([\s\S]*)\[\/strong\]\n*/g, function(str){
return str.replace(/\[strong\]\n*/g,'<b>')
.replace(/\n*\[\/strong\]\n*/g, '</b>');
})
//转义换行
.replace(/\n/g, '<br>')
//转义视频
.replace(/video\(.*?\)\[([^\s]+?)\]/g, function(str){
var cover = (str.match(/video\(([\s\S]+?)\)\[/)||[])[1];
var video = (str.match(/\)\[([^\s]+?)\]/)||[])[1];
cover = cover ? cover : '/static/res/images/video_cover.jpg';
return '<video poster="'+ cover + '" controls crossorigin><source src="'+ video + '" type="video/mp4"></video>';
})
//转义音频
.replace(/audio\[([^\s]+?)\]/g, function(audio){
return '<audio controls><source src="'+ audio.replace(/(^audio\[)|(\]$)/g, '')+ '" type="audio/mp3"></audio>';
})
return content;
}
//新消息通知 //新消息通知
,newmsg: function(){ ,newmsg: function(){
var elemUser = $('.fly-nav-user'); var elemUser = $('.fly-nav-user');
var messageNums = elemUser.attr('msg-url'), var messageNums = elemUser.attr('msg-url');
messageRead = elemUser.attr('readMsg-url'); var messageRead = elemUser.attr('readMsg-url');
if(uid != -1 && elemUser[0]){ if(uid != -1 && elemUser[0]){
fly.json(messageNums, { fly.json(messageNums, {
_: new Date().getTime() _: new Date().getTime()
@ -813,9 +299,7 @@ layui.define(['layer', 'laytpl', 'form', 'element', 'upload', 'util', 'imgcom'],
} }
//加载编辑器 //加载编辑器
// fly.layEditor({
// elem: '.fly-editor'
// });
//手机设备的简单适配 用户中心底部左侧栏导航 //手机设备的简单适配 用户中心底部左侧栏导航
var treeMobile = $('.site-tree-mobile') var treeMobile = $('.site-tree-mobile')

View File

@ -11,13 +11,11 @@ return array(
'7b11c4dc42b3b3023073cb14e519683c' => $vendorDir . '/ralouphie/getallheaders/src/getallheaders.php', '7b11c4dc42b3b3023073cb14e519683c' => $vendorDir . '/ralouphie/getallheaders/src/getallheaders.php',
'c964ee0ededf28c96ebd9db5099ef910' => $vendorDir . '/guzzlehttp/promises/src/functions_include.php', 'c964ee0ededf28c96ebd9db5099ef910' => $vendorDir . '/guzzlehttp/promises/src/functions_include.php',
'a0edc8309cc5e1d60e3047b5df6b7052' => $vendorDir . '/guzzlehttp/psr7/src/functions_include.php', 'a0edc8309cc5e1d60e3047b5df6b7052' => $vendorDir . '/guzzlehttp/psr7/src/functions_include.php',
'a4a119a56e50fbb293281d9a48007e0e' => $vendorDir . '/symfony/polyfill-php80/bootstrap.php',
'37a3dc5111fe8f707ab4c132ef1dbc62' => $vendorDir . '/guzzlehttp/guzzle/src/functions_include.php', '37a3dc5111fe8f707ab4c132ef1dbc62' => $vendorDir . '/guzzlehttp/guzzle/src/functions_include.php',
'a4a119a56e50fbb293281d9a48007e0e' => $vendorDir . '/symfony/polyfill-php80/bootstrap.php',
'0e6d7bf4a5811bfa5cf40c5ccd6fae6a' => $vendorDir . '/symfony/polyfill-mbstring/bootstrap.php', '0e6d7bf4a5811bfa5cf40c5ccd6fae6a' => $vendorDir . '/symfony/polyfill-mbstring/bootstrap.php',
'25072dd6e2470089de65ae7bf11d3109' => $vendorDir . '/symfony/polyfill-php72/bootstrap.php', '25072dd6e2470089de65ae7bf11d3109' => $vendorDir . '/symfony/polyfill-php72/bootstrap.php',
'667aeda72477189d0494fecd327c3641' => $vendorDir . '/symfony/var-dumper/Resources/functions/dump.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', '6b998e7ad3182c0d21d23780badfa07b' => $vendorDir . '/yansongda/supports/src/Functions.php',
'b33e3d135e5d9e47d845c576147bda89' => $vendorDir . '/php-di/php-di/src/functions.php', 'b33e3d135e5d9e47d845c576147bda89' => $vendorDir . '/php-di/php-di/src/functions.php',
'223fa6f9b46fbe5d6b44c5ff847bfceb' => $vendorDir . '/taoser/think-addons/src/helper.php', '223fa6f9b46fbe5d6b44c5ff847bfceb' => $vendorDir . '/taoser/think-addons/src/helper.php',

View File

@ -21,7 +21,6 @@ return array(
'Yansongda\\Supports\\' => array($vendorDir . '/yansongda/supports/src'), 'Yansongda\\Supports\\' => array($vendorDir . '/yansongda/supports/src'),
'Yansongda\\Pay\\' => array($vendorDir . '/yansongda/pay/src'), 'Yansongda\\Pay\\' => array($vendorDir . '/yansongda/pay/src'),
'Workerman\\' => array($vendorDir . '/workerman/workerman'), 'Workerman\\' => array($vendorDir . '/workerman/workerman'),
'Tightenco\\Collect\\' => array($vendorDir . '/tightenco/collect/src/Collect'),
'Symfony\\Polyfill\\Php80\\' => array($vendorDir . '/symfony/polyfill-php80'), 'Symfony\\Polyfill\\Php80\\' => array($vendorDir . '/symfony/polyfill-php80'),
'Symfony\\Polyfill\\Php72\\' => array($vendorDir . '/symfony/polyfill-php72'), 'Symfony\\Polyfill\\Php72\\' => array($vendorDir . '/symfony/polyfill-php72'),
'Symfony\\Polyfill\\Mbstring\\' => array($vendorDir . '/symfony/polyfill-mbstring'), 'Symfony\\Polyfill\\Mbstring\\' => array($vendorDir . '/symfony/polyfill-mbstring'),

View File

@ -12,13 +12,11 @@ class ComposerStaticInit1b32198725235c8d6500c87262ef30c2
'7b11c4dc42b3b3023073cb14e519683c' => __DIR__ . '/..' . '/ralouphie/getallheaders/src/getallheaders.php', '7b11c4dc42b3b3023073cb14e519683c' => __DIR__ . '/..' . '/ralouphie/getallheaders/src/getallheaders.php',
'c964ee0ededf28c96ebd9db5099ef910' => __DIR__ . '/..' . '/guzzlehttp/promises/src/functions_include.php', 'c964ee0ededf28c96ebd9db5099ef910' => __DIR__ . '/..' . '/guzzlehttp/promises/src/functions_include.php',
'a0edc8309cc5e1d60e3047b5df6b7052' => __DIR__ . '/..' . '/guzzlehttp/psr7/src/functions_include.php', 'a0edc8309cc5e1d60e3047b5df6b7052' => __DIR__ . '/..' . '/guzzlehttp/psr7/src/functions_include.php',
'a4a119a56e50fbb293281d9a48007e0e' => __DIR__ . '/..' . '/symfony/polyfill-php80/bootstrap.php',
'37a3dc5111fe8f707ab4c132ef1dbc62' => __DIR__ . '/..' . '/guzzlehttp/guzzle/src/functions_include.php', '37a3dc5111fe8f707ab4c132ef1dbc62' => __DIR__ . '/..' . '/guzzlehttp/guzzle/src/functions_include.php',
'a4a119a56e50fbb293281d9a48007e0e' => __DIR__ . '/..' . '/symfony/polyfill-php80/bootstrap.php',
'0e6d7bf4a5811bfa5cf40c5ccd6fae6a' => __DIR__ . '/..' . '/symfony/polyfill-mbstring/bootstrap.php', '0e6d7bf4a5811bfa5cf40c5ccd6fae6a' => __DIR__ . '/..' . '/symfony/polyfill-mbstring/bootstrap.php',
'25072dd6e2470089de65ae7bf11d3109' => __DIR__ . '/..' . '/symfony/polyfill-php72/bootstrap.php', '25072dd6e2470089de65ae7bf11d3109' => __DIR__ . '/..' . '/symfony/polyfill-php72/bootstrap.php',
'667aeda72477189d0494fecd327c3641' => __DIR__ . '/..' . '/symfony/var-dumper/Resources/functions/dump.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', '6b998e7ad3182c0d21d23780badfa07b' => __DIR__ . '/..' . '/yansongda/supports/src/Functions.php',
'b33e3d135e5d9e47d845c576147bda89' => __DIR__ . '/..' . '/php-di/php-di/src/functions.php', 'b33e3d135e5d9e47d845c576147bda89' => __DIR__ . '/..' . '/php-di/php-di/src/functions.php',
'223fa6f9b46fbe5d6b44c5ff847bfceb' => __DIR__ . '/..' . '/taoser/think-addons/src/helper.php', '223fa6f9b46fbe5d6b44c5ff847bfceb' => __DIR__ . '/..' . '/taoser/think-addons/src/helper.php',
@ -61,10 +59,6 @@ class ComposerStaticInit1b32198725235c8d6500c87262ef30c2
array ( array (
'Workerman\\' => 10, 'Workerman\\' => 10,
), ),
'T' =>
array (
'Tightenco\\Collect\\' => 18,
),
'S' => 'S' =>
array ( array (
'Symfony\\Polyfill\\Php80\\' => 23, 'Symfony\\Polyfill\\Php80\\' => 23,
@ -206,10 +200,6 @@ class ComposerStaticInit1b32198725235c8d6500c87262ef30c2
array ( array (
0 => __DIR__ . '/..' . '/workerman/workerman', 0 => __DIR__ . '/..' . '/workerman/workerman',
), ),
'Tightenco\\Collect\\' =>
array (
0 => __DIR__ . '/..' . '/tightenco/collect/src/Collect',
),
'Symfony\\Polyfill\\Php80\\' => 'Symfony\\Polyfill\\Php80\\' =>
array ( array (
0 => __DIR__ . '/..' . '/symfony/polyfill-php80', 0 => __DIR__ . '/..' . '/symfony/polyfill-php80',

View File

@ -847,17 +847,17 @@
}, },
{ {
"name": "jaeger/querylist", "name": "jaeger/querylist",
"version": "V4.2.8", "version": "V4.2.9",
"version_normalized": "4.2.8.0", "version_normalized": "4.2.9.0",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/jae-jae/QueryList.git", "url": "https://github.com/jae-jae/QueryList.git",
"reference": "39dc0ca9c668bec7a793e20472ccd7d26ef89ea4" "reference": "7aae3aed38214d3d7096174faf49f6c41b2dd550"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/jae-jae/QueryList/zipball/39dc0ca9c668bec7a793e20472ccd7d26ef89ea4", "url": "https://api.github.com/repos/jae-jae/QueryList/zipball/7aae3aed38214d3d7096174faf49f6c41b2dd550",
"reference": "39dc0ca9c668bec7a793e20472ccd7d26ef89ea4", "reference": "7aae3aed38214d3d7096174faf49f6c41b2dd550",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
@ -865,13 +865,12 @@
"jaeger/g-http": "^1.1", "jaeger/g-http": "^1.1",
"jaeger/phpquery-single": "^1", "jaeger/phpquery-single": "^1",
"php": ">=7.1", "php": ">=7.1",
"tightenco/collect": ">5.0" "symfony/var-dumper": ">3.4"
}, },
"require-dev": { "require-dev": {
"phpunit/phpunit": "^8.5", "phpunit/phpunit": "^8.5"
"symfony/var-dumper": "^3.3"
}, },
"time": "2021-07-05T06:07:58+00:00", "time": "2024-04-12T06:29:50+00:00",
"type": "library", "type": "library",
"installation-source": "dist", "installation-source": "dist",
"autoload": { "autoload": {
@ -898,7 +897,7 @@
], ],
"support": { "support": {
"issues": "https://github.com/jae-jae/QueryList/issues", "issues": "https://github.com/jae-jae/QueryList/issues",
"source": "https://github.com/jae-jae/QueryList/tree/V4.2.8" "source": "https://github.com/jae-jae/QueryList/tree/V4.2.9"
}, },
"funding": [ "funding": [
{ {
@ -2578,69 +2577,6 @@
}, },
"install-path": "../taoser/think-setarr" "install-path": "../taoser/think-setarr"
}, },
{
"name": "tightenco/collect",
"version": "v8.83.27",
"version_normalized": "8.83.27.0",
"source": {
"type": "git",
"url": "https://github.com/tighten/collect.git",
"reference": "07eed6cf7441c7a69c379fdcb118eec1a1fdd0e6"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/tighten/collect/zipball/07eed6cf7441c7a69c379fdcb118eec1a1fdd0e6",
"reference": "07eed6cf7441c7a69c379fdcb118eec1a1fdd0e6",
"shasum": "",
"mirrors": [
{
"url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%",
"preferred": true
}
]
},
"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": "2023-01-13T18:05:42+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.27"
},
"install-path": "../tightenco/collect"
},
{ {
"name": "topthink/framework", "name": "topthink/framework",
"version": "v6.1.4", "version": "v6.1.4",

View File

@ -3,7 +3,7 @@
'name' => 'taoser/taoler', 'name' => 'taoser/taoler',
'pretty_version' => '2.3.10.x-dev', 'pretty_version' => '2.3.10.x-dev',
'version' => '2.3.10.9999999-dev', 'version' => '2.3.10.9999999-dev',
'reference' => '2e95b716720018a27230c873200926631e74e781', 'reference' => '158340e85a56ec3bd70563cef0bf1491468d7370',
'type' => 'project', 'type' => 'project',
'install_path' => __DIR__ . '/../../', 'install_path' => __DIR__ . '/../../',
'aliases' => array(), 'aliases' => array(),
@ -119,9 +119,9 @@
'dev_requirement' => false, 'dev_requirement' => false,
), ),
'jaeger/querylist' => array( 'jaeger/querylist' => array(
'pretty_version' => 'V4.2.8', 'pretty_version' => 'V4.2.9',
'version' => '4.2.8.0', 'version' => '4.2.9.0',
'reference' => '39dc0ca9c668bec7a793e20472ccd7d26ef89ea4', 'reference' => '7aae3aed38214d3d7096174faf49f6c41b2dd550',
'type' => 'library', 'type' => 'library',
'install_path' => __DIR__ . '/../jaeger/querylist', 'install_path' => __DIR__ . '/../jaeger/querylist',
'aliases' => array(), 'aliases' => array(),
@ -358,7 +358,7 @@
'taoser/taoler' => array( 'taoser/taoler' => array(
'pretty_version' => '2.3.10.x-dev', 'pretty_version' => '2.3.10.x-dev',
'version' => '2.3.10.9999999-dev', 'version' => '2.3.10.9999999-dev',
'reference' => '2e95b716720018a27230c873200926631e74e781', 'reference' => '158340e85a56ec3bd70563cef0bf1491468d7370',
'type' => 'project', 'type' => 'project',
'install_path' => __DIR__ . '/../../', 'install_path' => __DIR__ . '/../../',
'aliases' => array(), 'aliases' => array(),
@ -391,15 +391,6 @@
'aliases' => array(), 'aliases' => array(),
'dev_requirement' => false, 'dev_requirement' => false,
), ),
'tightenco/collect' => array(
'pretty_version' => 'v8.83.27',
'version' => '8.83.27.0',
'reference' => '07eed6cf7441c7a69c379fdcb118eec1a1fdd0e6',
'type' => 'library',
'install_path' => __DIR__ . '/../tightenco/collect',
'aliases' => array(),
'dev_requirement' => false,
),
'topthink/framework' => array( 'topthink/framework' => array(
'pretty_version' => 'v6.1.4', 'pretty_version' => 'v6.1.4',
'version' => '6.1.4.0', 'version' => '6.1.4.0',

View File

@ -1,12 +0,0 @@
# 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']

View File

@ -1,5 +0,0 @@
/vendor/
.idea/
composer.lock
.DS_Store
*.cache

View File

@ -8,7 +8,7 @@
"jaeger/phpquery-single": "^1", "jaeger/phpquery-single": "^1",
"jaeger/g-http": "^1.1", "jaeger/g-http": "^1.1",
"ext-dom": "*", "ext-dom": "*",
"tightenco/collect": ">5.0" "symfony/var-dumper": ">3.4"
}, },
"suggest":{ "suggest":{
@ -26,12 +26,15 @@
} }
}, },
"autoload-dev": { "autoload-dev": {
"files": [
"src/Collect/Support/helpers.php",
"src/Collect/Support/alias.php"
],
"psr-4": { "psr-4": {
"Tests\\": "tests/" "Tests\\": "tests/"
} }
}, },
"require-dev": { "require-dev": {
"symfony/var-dumper": "^3.3",
"phpunit/phpunit": "^8.5" "phpunit/phpunit": "^8.5"
}, },
"scripts": { "scripts": {

View File

@ -1,19 +0,0 @@
<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>

View File

@ -0,0 +1,109 @@
<?php
namespace QL\Collect\Conditionable;
class HigherOrderWhenProxy
{
/**
* The target being conditionally operated on.
*
* @var mixed
*/
protected $target;
/**
* The condition for proxying.
*
* @var bool
*/
protected $condition;
/**
* Indicates whether the proxy has a condition.
*
* @var bool
*/
protected $hasCondition = false;
/**
* Determine whether the condition should be negated.
*
* @var bool
*/
protected $negateConditionOnCapture;
/**
* Create a new proxy instance.
*
* @param mixed $target
* @return void
*/
public function __construct($target)
{
$this->target = $target;
}
/**
* Set the condition on the proxy.
*
* @param bool $condition
* @return $this
*/
public function condition($condition)
{
[$this->condition, $this->hasCondition] = [$condition, true];
return $this;
}
/**
* Indicate that the condition should be negated.
*
* @return $this
*/
public function negateConditionOnCapture()
{
$this->negateConditionOnCapture = true;
return $this;
}
/**
* Proxy accessing an attribute onto the target.
*
* @param string $key
* @return mixed
*/
public function __get($key)
{
if (! $this->hasCondition) {
$condition = $this->target->{$key};
return $this->condition($this->negateConditionOnCapture ? ! $condition : $condition);
}
return $this->condition
? $this->target->{$key}
: $this->target;
}
/**
* Proxy a method call on the target.
*
* @param string $method
* @param array $parameters
* @return mixed
*/
public function __call($method, $parameters)
{
if (! $this->hasCondition) {
$condition = $this->target->{$method}(...$parameters);
return $this->condition($this->negateConditionOnCapture ? ! $condition : $condition);
}
return $this->condition
? $this->target->{$method}(...$parameters)
: $this->target;
}
}

View File

@ -0,0 +1,17 @@
<?php
namespace QL\Collect\Contracts\Support;
/**
* @template TKey of array-key
* @template TValue
*/
interface Arrayable
{
/**
* Get the instance as an array.
*
* @return array<TKey, TValue>
*/
public function toArray();
}

View File

@ -1,6 +1,6 @@
<?php <?php
namespace Tightenco\Collect\Contracts\Support; namespace QL\Collect\Contracts\Support;
interface CanBeEscapedWhenCastToString interface CanBeEscapedWhenCastToString
{ {

View File

@ -1,6 +1,6 @@
<?php <?php
namespace Tightenco\Collect\Contracts\Support; namespace QL\Collect\Contracts\Support;
interface Htmlable interface Htmlable
{ {

View File

@ -1,6 +1,6 @@
<?php <?php
namespace Tightenco\Collect\Contracts\Support; namespace QL\Collect\Contracts\Support;
interface Jsonable interface Jsonable
{ {

View File

@ -1,9 +1,10 @@
<?php <?php
namespace Tightenco\Collect\Support; namespace QL\Collect\Support;
use ArgumentCountError;
use ArrayAccess; use ArrayAccess;
use Tightenco\Collect\Support\Traits\Macroable; use QL\Collect\Support\Traits\Macroable;
use InvalidArgumentException; use InvalidArgumentException;
class Arr class Arr
@ -25,7 +26,7 @@ class Arr
* Add an element to an array using "dot" notation if it doesn't exist. * Add an element to an array using "dot" notation if it doesn't exist.
* *
* @param array $array * @param array $array
* @param string $key * @param string|int|float $key
* @param mixed $value * @param mixed $value
* @return array * @return array
*/ */
@ -142,7 +143,7 @@ class Arr
* Get all of the given array except for a specified array of keys. * Get all of the given array except for a specified array of keys.
* *
* @param array $array * @param array $array
* @param array|string $keys * @param array|string|int|float $keys
* @return array * @return array
*/ */
public static function except($array, $keys) public static function except($array, $keys)
@ -169,6 +170,10 @@ class Arr
return $array->offsetExists($key); return $array->offsetExists($key);
} }
if (is_float($key)) {
$key = (string) $key;
}
return array_key_exists($key, $array); return array_key_exists($key, $array);
} }
@ -252,7 +257,7 @@ class Arr
* Remove one or many array items from a given array using "dot" notation. * Remove one or many array items from a given array using "dot" notation.
* *
* @param array $array * @param array $array
* @param array|string $keys * @param array|string|int|float $keys
* @return void * @return void
*/ */
public static function forget(&$array, $keys) public static function forget(&$array, $keys)
@ -281,7 +286,7 @@ class Arr
while (count($parts) > 1) { while (count($parts) > 1) {
$part = array_shift($parts); $part = array_shift($parts);
if (isset($array[$part]) && is_array($array[$part])) { if (isset($array[$part]) && static::accessible($array[$part])) {
$array = &$array[$part]; $array = &$array[$part];
} else { } else {
continue 2; continue 2;
@ -314,7 +319,7 @@ class Arr
return $array[$key]; return $array[$key];
} }
if (strpos($key, '.') === false) { if (! str_contains($key, '.')) {
return $array[$key] ?? value($default); return $array[$key] ?? value($default);
} }
@ -423,6 +428,59 @@ class Arr
return ! self::isAssoc($array); return ! self::isAssoc($array);
} }
/**
* Join all items using a string. The final items can use a separate glue string.
*
* @param array $array
* @param string $glue
* @param string $finalGlue
* @return string
*/
public static function join($array, $glue, $finalGlue = '')
{
if ($finalGlue === '') {
return implode($glue, $array);
}
if (count($array) === 0) {
return '';
}
if (count($array) === 1) {
return end($array);
}
$finalItem = array_pop($array);
return implode($glue, $array).$finalGlue.$finalItem;
}
/**
* Key an associative array by a field or using a callback.
*
* @param array $array
* @param callable|array|string $keyBy
* @return array
*/
public static function keyBy($array, $keyBy)
{
return Collection::make($array)->keyBy($keyBy)->all();
}
/**
* Prepend the key names of an associative array.
*
* @param array $array
* @param string $prependWith
* @return array
*/
public static function prependKeysWith($array, $prependWith)
{
return Collection::make($array)->mapWithKeys(function ($item, $key) use ($prependWith) {
return [$prependWith.$key => $item];
})->all();
}
/** /**
* Get a subset of the items from the given array. * Get a subset of the items from the given array.
* *
@ -487,6 +545,26 @@ class Arr
return [$value, $key]; return [$value, $key];
} }
/**
* Run a map over each of the items in the array.
*
* @param array $array
* @param callable $callback
* @return array
*/
public static function map(array $array, callable $callback)
{
$keys = array_keys($array);
try {
$items = array_map($callback, $array, $keys);
} catch (ArgumentCountError) {
$items = array_map($callback, $array);
}
return array_combine($keys, $items);
}
/** /**
* Push an item onto the beginning of an array. * Push an item onto the beginning of an array.
* *
@ -539,7 +617,7 @@ class Arr
* *
* @param array $array * @param array $array
* @param int|null $number * @param int|null $number
* @param bool|false $preserveKeys * @param bool $preserveKeys
* @return mixed * @return mixed
* *
* @throws \InvalidArgumentException * @throws \InvalidArgumentException
@ -587,7 +665,7 @@ class Arr
* If no key is given to the method, the entire array will be replaced. * If no key is given to the method, the entire array will be replaced.
* *
* @param array $array * @param array $array
* @param string|null $key * @param string|int|null $key
* @param mixed $value * @param mixed $value
* @return array * @return array
*/ */
@ -653,6 +731,18 @@ class Arr
return Collection::make($array)->sortBy($callback)->all(); return Collection::make($array)->sortBy($callback)->all();
} }
/**
* Sort the array in descending order using the given callback or "dot" notation.
*
* @param array $array
* @param callable|array|string|null $callback
* @return array
*/
public static function sortDesc($array, $callback = null)
{
return Collection::make($array)->sortByDesc($callback)->all();
}
/** /**
* Recursively sort an array by keys and values. * Recursively sort an array by keys and values.
* *
@ -705,6 +795,29 @@ class Arr
return implode(' ', $classes); return implode(' ', $classes);
} }
/**
* Conditionally compile styles from an array into a style list.
*
* @param array $array
* @return string
*/
public static function toCssStyles($array)
{
$styleList = static::wrap($array);
$styles = [];
foreach ($styleList as $class => $constraint) {
if (is_numeric($class)) {
$styles[] = Str::finish($constraint, ';');
} elseif ($constraint) {
$styles[] = Str::finish($class, ';');
}
}
return implode(' ', $styles);
}
/** /**
* Filter the array using the given callback. * Filter the array using the given callback.
* *
@ -725,9 +838,7 @@ class Arr
*/ */
public static function whereNotNull($array) public static function whereNotNull($array)
{ {
return static::where($array, function ($value) { return static::where($array, fn ($value) => ! is_null($value));
return ! is_null($value);
});
} }
/** /**

View File

@ -1,16 +1,16 @@
<?php <?php
namespace Tightenco\Collect\Support; namespace QL\Collect\Support;
/** /**
* @mixin \Tightenco\Collect\Support\Enumerable * @mixin \QL\Collect\Support\Enumerable
*/ */
class HigherOrderCollectionProxy class HigherOrderCollectionProxy
{ {
/** /**
* The collection being operated on. * The collection being operated on.
* *
* @var \Tightenco\Collect\Support\Enumerable * @var \QL\Collect\Support\Enumerable
*/ */
protected $collection; protected $collection;
@ -24,7 +24,7 @@ class HigherOrderCollectionProxy
/** /**
* Create a new proxy instance. * Create a new proxy instance.
* *
* @param \Tightenco\Collect\Support\Enumerable $collection * @param \QL\Collect\Support\Enumerable $collection
* @param string $method * @param string $method
* @return void * @return void
*/ */

View File

@ -1,31 +1,43 @@
<?php <?php
namespace Tightenco\Collect\Support; namespace QL\Collect\Support;
use ArrayIterator; use ArrayIterator;
use Closure; use Closure;
use DateTimeInterface; use DateTimeInterface;
use Tightenco\Collect\Contracts\Support\CanBeEscapedWhenCastToString; use Generator;
use Tightenco\Collect\Support\Traits\EnumeratesValues; use QL\Collect\Contracts\Support\CanBeEscapedWhenCastToString;
use Tightenco\Collect\Support\Traits\Macroable; use QL\Collect\Support\Traits\EnumeratesValues;
use QL\Collect\Support\Traits\Macroable;
use InvalidArgumentException;
use IteratorAggregate; use IteratorAggregate;
use stdClass; use stdClass;
use Traversable;
/**
* @template TKey of array-key
* @template TValue
*
* @implements \QL\Collect\Support\Enumerable<TKey, TValue>
*/
class LazyCollection implements CanBeEscapedWhenCastToString, Enumerable class LazyCollection implements CanBeEscapedWhenCastToString, Enumerable
{ {
/**
* @use \QL\Collect\Support\Traits\EnumeratesValues<TKey, TValue>
*/
use EnumeratesValues, Macroable; use EnumeratesValues, Macroable;
/** /**
* The source from which to generate items. * The source from which to generate items.
* *
* @var callable|static * @var (Closure(): \Generator<TKey, TValue, mixed, void>)|static|array<TKey, TValue>
*/ */
public $source; public $source;
/** /**
* Create a new lazy collection instance. * Create a new lazy collection instance.
* *
* @param mixed $source * @param \QL\Collect\Contracts\Support\Arrayable<TKey, TValue>|iterable<TKey, TValue>|(Closure(): \Generator<TKey, TValue, mixed, void>)|self<TKey, TValue>|array<TKey, TValue>|null $source
* @return void * @return void
*/ */
public function __construct($source = null) public function __construct($source = null)
@ -34,17 +46,35 @@ class LazyCollection implements CanBeEscapedWhenCastToString, Enumerable
$this->source = $source; $this->source = $source;
} elseif (is_null($source)) { } elseif (is_null($source)) {
$this->source = static::empty(); $this->source = static::empty();
} elseif ($source instanceof Generator) {
throw new InvalidArgumentException(
'Generators should not be passed directly to LazyCollection. Instead, pass a generator function.'
);
} else { } else {
$this->source = $this->getArrayableItems($source); $this->source = $this->getArrayableItems($source);
} }
} }
/**
* Create a new collection instance if the value isn't one already.
*
* @template TMakeKey of array-key
* @template TMakeValue
*
* @param \QL\Collect\Contracts\Support\Arrayable<TMakeKey, TMakeValue>|iterable<TMakeKey, TMakeValue>|(Closure(): \Generator<TMakeKey, TMakeValue, mixed, void>)|self<TMakeKey, TMakeValue>|array<TMakeKey, TMakeValue>|null $items
* @return static<TMakeKey, TMakeValue>
*/
public static function make($items = [])
{
return new static($items);
}
/** /**
* Create a collection with the given range. * Create a collection with the given range.
* *
* @param int $from * @param int $from
* @param int $to * @param int $to
* @return static * @return static<int, int>
*/ */
public static function range($from, $to) public static function range($from, $to)
{ {
@ -64,7 +94,7 @@ class LazyCollection implements CanBeEscapedWhenCastToString, Enumerable
/** /**
* Get all items in the enumerable. * Get all items in the enumerable.
* *
* @return array * @return array<TKey, TValue>
*/ */
public function all() public function all()
{ {
@ -126,8 +156,8 @@ class LazyCollection implements CanBeEscapedWhenCastToString, Enumerable
/** /**
* Get the average value of a given key. * Get the average value of a given key.
* *
* @param callable|string|null $callback * @param (callable(TValue): float|int)|string|null $callback
* @return mixed * @return float|int|null
*/ */
public function avg($callback = null) public function avg($callback = null)
{ {
@ -137,8 +167,8 @@ class LazyCollection implements CanBeEscapedWhenCastToString, Enumerable
/** /**
* Get the median of a given key. * Get the median of a given key.
* *
* @param string|array|null $key * @param string|array<array-key, string>|null $key
* @return mixed * @return float|int|null
*/ */
public function median($key = null) public function median($key = null)
{ {
@ -148,8 +178,8 @@ class LazyCollection implements CanBeEscapedWhenCastToString, Enumerable
/** /**
* Get the mode of a given key. * Get the mode of a given key.
* *
* @param string|array|null $key * @param string|array<string>|null $key
* @return array|null * @return array<int, float|int>|null
*/ */
public function mode($key = null) public function mode($key = null)
{ {
@ -159,7 +189,7 @@ class LazyCollection implements CanBeEscapedWhenCastToString, Enumerable
/** /**
* Collapse the collection of items into a single array. * Collapse the collection of items into a single array.
* *
* @return static * @return static<int, mixed>
*/ */
public function collapse() public function collapse()
{ {
@ -177,7 +207,7 @@ class LazyCollection implements CanBeEscapedWhenCastToString, Enumerable
/** /**
* Determine if an item exists in the enumerable. * Determine if an item exists in the enumerable.
* *
* @param mixed $key * @param (callable(TValue, TKey): bool)|TValue|string $key
* @param mixed $operator * @param mixed $operator
* @param mixed $value * @param mixed $value
* @return bool * @return bool
@ -187,6 +217,7 @@ class LazyCollection implements CanBeEscapedWhenCastToString, Enumerable
if (func_num_args() === 1 && $this->useAsCallable($key)) { if (func_num_args() === 1 && $this->useAsCallable($key)) {
$placeholder = new stdClass; $placeholder = new stdClass;
/** @var callable $key */
return $this->first($key, $placeholder) !== $placeholder; return $this->first($key, $placeholder) !== $placeholder;
} }
@ -205,6 +236,32 @@ class LazyCollection implements CanBeEscapedWhenCastToString, Enumerable
return $this->contains($this->operatorForWhere(...func_get_args())); return $this->contains($this->operatorForWhere(...func_get_args()));
} }
/**
* Determine if an item exists, using strict comparison.
*
* @param (callable(TValue): bool)|TValue|array-key $key
* @param TValue|null $value
* @return bool
*/
public function containsStrict($key, $value = null)
{
if (func_num_args() === 2) {
return $this->contains(fn ($item) => data_get($item, $key) === $value);
}
if ($this->useAsCallable($key)) {
return ! is_null($this->first($key));
}
foreach ($this as $item) {
if ($item === $key) {
return true;
}
}
return false;
}
/** /**
* Determine if an item is not contained in the enumerable. * Determine if an item is not contained in the enumerable.
* *
@ -221,8 +278,11 @@ class LazyCollection implements CanBeEscapedWhenCastToString, Enumerable
/** /**
* Cross join the given iterables, returning all possible permutations. * Cross join the given iterables, returning all possible permutations.
* *
* @param array ...$arrays * @template TCrossJoinKey
* @return static * @template TCrossJoinValue
*
* @param \QL\Collect\Contracts\Support\Arrayable<TCrossJoinKey, TCrossJoinValue>|iterable<TCrossJoinKey, TCrossJoinValue> ...$arrays
* @return static<int, array<int, TValue|TCrossJoinValue>>
*/ */
public function crossJoin(...$arrays) public function crossJoin(...$arrays)
{ {
@ -232,8 +292,8 @@ class LazyCollection implements CanBeEscapedWhenCastToString, Enumerable
/** /**
* Count the number of items in the collection by a field or using a callback. * Count the number of items in the collection by a field or using a callback.
* *
* @param callable|string $countBy * @param (callable(TValue, TKey): array-key)|string|null $countBy
* @return static * @return static<array-key, int>
*/ */
public function countBy($countBy = null) public function countBy($countBy = null)
{ {
@ -261,7 +321,7 @@ class LazyCollection implements CanBeEscapedWhenCastToString, Enumerable
/** /**
* Get the items that are not present in the given items. * Get the items that are not present in the given items.
* *
* @param mixed $items * @param \QL\Collect\Contracts\Support\Arrayable<array-key, TValue>|iterable<array-key, TValue> $items
* @return static * @return static
*/ */
public function diff($items) public function diff($items)
@ -272,8 +332,8 @@ class LazyCollection implements CanBeEscapedWhenCastToString, Enumerable
/** /**
* Get the items that are not present in the given items, using the callback. * Get the items that are not present in the given items, using the callback.
* *
* @param mixed $items * @param \QL\Collect\Contracts\Support\Arrayable<array-key, TValue>|iterable<array-key, TValue> $items
* @param callable $callback * @param callable(TValue, TValue): int $callback
* @return static * @return static
*/ */
public function diffUsing($items, callable $callback) public function diffUsing($items, callable $callback)
@ -284,7 +344,7 @@ class LazyCollection implements CanBeEscapedWhenCastToString, Enumerable
/** /**
* Get the items whose keys and values are not present in the given items. * Get the items whose keys and values are not present in the given items.
* *
* @param mixed $items * @param \QL\Collect\Contracts\Support\Arrayable<TKey, TValue>|iterable<TKey, TValue> $items
* @return static * @return static
*/ */
public function diffAssoc($items) public function diffAssoc($items)
@ -295,8 +355,8 @@ class LazyCollection implements CanBeEscapedWhenCastToString, Enumerable
/** /**
* Get the items whose keys and values are not present in the given items, using the callback. * Get the items whose keys and values are not present in the given items, using the callback.
* *
* @param mixed $items * @param \QL\Collect\Contracts\Support\Arrayable<TKey, TValue>|iterable<TKey, TValue> $items
* @param callable $callback * @param callable(TKey, TKey): int $callback
* @return static * @return static
*/ */
public function diffAssocUsing($items, callable $callback) public function diffAssocUsing($items, callable $callback)
@ -307,7 +367,7 @@ class LazyCollection implements CanBeEscapedWhenCastToString, Enumerable
/** /**
* Get the items whose keys are not present in the given items. * Get the items whose keys are not present in the given items.
* *
* @param mixed $items * @param \QL\Collect\Contracts\Support\Arrayable<TKey, TValue>|iterable<TKey, TValue> $items
* @return static * @return static
*/ */
public function diffKeys($items) public function diffKeys($items)
@ -318,8 +378,8 @@ class LazyCollection implements CanBeEscapedWhenCastToString, Enumerable
/** /**
* Get the items whose keys are not present in the given items, using the callback. * Get the items whose keys are not present in the given items, using the callback.
* *
* @param mixed $items * @param \QL\Collect\Contracts\Support\Arrayable<TKey, TValue>|iterable<TKey, TValue> $items
* @param callable $callback * @param callable(TKey, TKey): int $callback
* @return static * @return static
*/ */
public function diffKeysUsing($items, callable $callback) public function diffKeysUsing($items, callable $callback)
@ -330,7 +390,7 @@ class LazyCollection implements CanBeEscapedWhenCastToString, Enumerable
/** /**
* Retrieve duplicate items. * Retrieve duplicate items.
* *
* @param callable|string|null $callback * @param (callable(TValue): bool)|string|null $callback
* @param bool $strict * @param bool $strict
* @return static * @return static
*/ */
@ -342,7 +402,7 @@ class LazyCollection implements CanBeEscapedWhenCastToString, Enumerable
/** /**
* Retrieve duplicate items using strict comparison. * Retrieve duplicate items using strict comparison.
* *
* @param callable|string|null $callback * @param (callable(TValue): bool)|string|null $callback
* @return static * @return static
*/ */
public function duplicatesStrict($callback = null) public function duplicatesStrict($callback = null)
@ -353,7 +413,7 @@ class LazyCollection implements CanBeEscapedWhenCastToString, Enumerable
/** /**
* Get all items except for those with the specified keys. * Get all items except for those with the specified keys.
* *
* @param mixed $keys * @param \QL\Collect\Support\Enumerable<array-key, TKey>|array<array-key, TKey> $keys
* @return static * @return static
*/ */
public function except($keys) public function except($keys)
@ -364,15 +424,13 @@ class LazyCollection implements CanBeEscapedWhenCastToString, Enumerable
/** /**
* Run a filter over each of the items. * Run a filter over each of the items.
* *
* @param callable|null $callback * @param (callable(TValue, TKey): bool)|null $callback
* @return static * @return static
*/ */
public function filter(callable $callback = null) public function filter(callable $callback = null)
{ {
if (is_null($callback)) { if (is_null($callback)) {
$callback = function ($value) { $callback = fn ($value) => (bool) $value;
return (bool) $value;
};
} }
return new static(function () use ($callback) { return new static(function () use ($callback) {
@ -387,9 +445,11 @@ class LazyCollection implements CanBeEscapedWhenCastToString, Enumerable
/** /**
* Get the first item from the enumerable passing the given truth test. * Get the first item from the enumerable passing the given truth test.
* *
* @param callable|null $callback * @template TFirstDefault
* @param mixed $default *
* @return mixed * @param (callable(TValue): bool)|null $callback
* @param TFirstDefault|(\Closure(): TFirstDefault) $default
* @return TValue|TFirstDefault
*/ */
public function first(callable $callback = null, $default = null) public function first(callable $callback = null, $default = null)
{ {
@ -416,7 +476,7 @@ class LazyCollection implements CanBeEscapedWhenCastToString, Enumerable
* Get a flattened list of the items in the collection. * Get a flattened list of the items in the collection.
* *
* @param int $depth * @param int $depth
* @return static * @return static<int, mixed>
*/ */
public function flatten($depth = INF) public function flatten($depth = INF)
{ {
@ -438,7 +498,7 @@ class LazyCollection implements CanBeEscapedWhenCastToString, Enumerable
/** /**
* Flip the items in the collection. * Flip the items in the collection.
* *
* @return static * @return static<TValue, TKey>
*/ */
public function flip() public function flip()
{ {
@ -452,9 +512,11 @@ class LazyCollection implements CanBeEscapedWhenCastToString, Enumerable
/** /**
* Get an item by key. * Get an item by key.
* *
* @param mixed $key * @template TGetDefault
* @param mixed $default *
* @return mixed * @param TKey|null $key
* @param TGetDefault|(\Closure(): TGetDefault) $default
* @return TValue|TGetDefault
*/ */
public function get($key, $default = null) public function get($key, $default = null)
{ {
@ -474,9 +536,9 @@ class LazyCollection implements CanBeEscapedWhenCastToString, Enumerable
/** /**
* Group an associative array by a field or using a callback. * Group an associative array by a field or using a callback.
* *
* @param array|callable|string $groupBy * @param (callable(TValue, TKey): array-key)|array|string $groupBy
* @param bool $preserveKeys * @param bool $preserveKeys
* @return static * @return static<array-key, static<array-key, TValue>>
*/ */
public function groupBy($groupBy, $preserveKeys = false) public function groupBy($groupBy, $preserveKeys = false)
{ {
@ -486,8 +548,8 @@ class LazyCollection implements CanBeEscapedWhenCastToString, Enumerable
/** /**
* Key an associative array by a field or using a callback. * Key an associative array by a field or using a callback.
* *
* @param callable|string $keyBy * @param (callable(TValue, TKey): array-key)|array|string $keyBy
* @return static * @return static<array-key, TValue>
*/ */
public function keyBy($keyBy) public function keyBy($keyBy)
{ {
@ -548,7 +610,7 @@ class LazyCollection implements CanBeEscapedWhenCastToString, Enumerable
/** /**
* Concatenate values of a given key as a string. * Concatenate values of a given key as a string.
* *
* @param string $value * @param callable|string $value
* @param string|null $glue * @param string|null $glue
* @return string * @return string
*/ */
@ -560,7 +622,7 @@ class LazyCollection implements CanBeEscapedWhenCastToString, Enumerable
/** /**
* Intersect the collection with the given items. * Intersect the collection with the given items.
* *
* @param mixed $items * @param \QL\Collect\Contracts\Support\Arrayable<TKey, TValue>|iterable<TKey, TValue> $items
* @return static * @return static
*/ */
public function intersect($items) public function intersect($items)
@ -568,10 +630,45 @@ class LazyCollection implements CanBeEscapedWhenCastToString, Enumerable
return $this->passthru('intersect', func_get_args()); return $this->passthru('intersect', func_get_args());
} }
/**
* Intersect the collection with the given items, using the callback.
*
* @param \QL\Collect\Contracts\Support\Arrayable<array-key, TValue>|iterable<array-key, TValue> $items
* @param callable(TValue, TValue): int $callback
* @return static
*/
public function intersectUsing()
{
return $this->passthru('intersectUsing', func_get_args());
}
/**
* Intersect the collection with the given items with additional index check.
*
* @param \QL\Collect\Contracts\Support\Arrayable<TKey, TValue>|iterable<TKey, TValue> $items
* @return static
*/
public function intersectAssoc($items)
{
return $this->passthru('intersectAssoc', func_get_args());
}
/**
* Intersect the collection with the given items with additional index check, using the callback.
*
* @param \QL\Collect\Contracts\Support\Arrayable<array-key, TValue>|iterable<array-key, TValue> $items
* @param callable(TValue, TValue): int $callback
* @return static
*/
public function intersectAssocUsing($items, callable $callback)
{
return $this->passthru('intersectAssocUsing', func_get_args());
}
/** /**
* Intersect the collection with the given items by key. * Intersect the collection with the given items by key.
* *
* @param mixed $items * @param \QL\Collect\Contracts\Support\Arrayable<TKey, TValue>|iterable<TKey, TValue> $items
* @return static * @return static
*/ */
public function intersectByKeys($items) public function intersectByKeys($items)
@ -614,7 +711,7 @@ class LazyCollection implements CanBeEscapedWhenCastToString, Enumerable
/** /**
* Get the keys of the collection items. * Get the keys of the collection items.
* *
* @return static * @return static<int, TKey>
*/ */
public function keys() public function keys()
{ {
@ -628,9 +725,11 @@ class LazyCollection implements CanBeEscapedWhenCastToString, Enumerable
/** /**
* Get the last item from the collection. * Get the last item from the collection.
* *
* @param callable|null $callback * @template TLastDefault
* @param mixed $default *
* @return mixed * @param (callable(TValue, TKey): bool)|null $callback
* @param TLastDefault|(\Closure(): TLastDefault) $default
* @return TValue|TLastDefault
*/ */
public function last(callable $callback = null, $default = null) public function last(callable $callback = null, $default = null)
{ {
@ -648,9 +747,9 @@ class LazyCollection implements CanBeEscapedWhenCastToString, Enumerable
/** /**
* Get the values of a given key. * Get the values of a given key.
* *
* @param string|array $value * @param string|array<array-key, string> $value
* @param string|null $key * @param string|null $key
* @return static * @return static<int, mixed>
*/ */
public function pluck($value, $key = null) public function pluck($value, $key = null)
{ {
@ -678,8 +777,10 @@ class LazyCollection implements CanBeEscapedWhenCastToString, Enumerable
/** /**
* Run a map over each of the items. * Run a map over each of the items.
* *
* @param callable $callback * @template TMapValue
* @return static *
* @param callable(TValue, TKey): TMapValue $callback
* @return static<TKey, TMapValue>
*/ */
public function map(callable $callback) public function map(callable $callback)
{ {
@ -695,8 +796,11 @@ class LazyCollection implements CanBeEscapedWhenCastToString, Enumerable
* *
* The callback should return an associative array with a single key/value pair. * The callback should return an associative array with a single key/value pair.
* *
* @param callable $callback * @template TMapToDictionaryKey of array-key
* @return static * @template TMapToDictionaryValue
*
* @param callable(TValue, TKey): array<TMapToDictionaryKey, TMapToDictionaryValue> $callback
* @return static<TMapToDictionaryKey, array<int, TMapToDictionaryValue>>
*/ */
public function mapToDictionary(callable $callback) public function mapToDictionary(callable $callback)
{ {
@ -708,8 +812,11 @@ class LazyCollection implements CanBeEscapedWhenCastToString, Enumerable
* *
* The callback should return an associative array with a single key/value pair. * The callback should return an associative array with a single key/value pair.
* *
* @param callable $callback * @template TMapWithKeysKey of array-key
* @return static * @template TMapWithKeysValue
*
* @param callable(TValue, TKey): array<TMapWithKeysKey, TMapWithKeysValue> $callback
* @return static<TMapWithKeysKey, TMapWithKeysValue>
*/ */
public function mapWithKeys(callable $callback) public function mapWithKeys(callable $callback)
{ {
@ -723,7 +830,7 @@ class LazyCollection implements CanBeEscapedWhenCastToString, Enumerable
/** /**
* Merge the collection with the given items. * Merge the collection with the given items.
* *
* @param mixed $items * @param \QL\Collect\Contracts\Support\Arrayable<TKey, TValue>|iterable<TKey, TValue> $items
* @return static * @return static
*/ */
public function merge($items) public function merge($items)
@ -734,8 +841,10 @@ class LazyCollection implements CanBeEscapedWhenCastToString, Enumerable
/** /**
* Recursively merge the collection with the given items. * Recursively merge the collection with the given items.
* *
* @param mixed $items * @template TMergeRecursiveValue
* @return static *
* @param \QL\Collect\Contracts\Support\Arrayable<TKey, TMergeRecursiveValue>|iterable<TKey, TMergeRecursiveValue> $items
* @return static<TKey, TValue|TMergeRecursiveValue>
*/ */
public function mergeRecursive($items) public function mergeRecursive($items)
{ {
@ -745,8 +854,10 @@ class LazyCollection implements CanBeEscapedWhenCastToString, Enumerable
/** /**
* Create a collection by using this collection for keys and another for its values. * Create a collection by using this collection for keys and another for its values.
* *
* @param mixed $values * @template TCombineValue
* @return static *
* @param \IteratorAggregate<array-key, TCombineValue>|array<array-key, TCombineValue>|(callable(): \Generator<array-key, TCombineValue>) $values
* @return static<TValue, TCombineValue>
*/ */
public function combine($values) public function combine($values)
{ {
@ -776,7 +887,7 @@ class LazyCollection implements CanBeEscapedWhenCastToString, Enumerable
/** /**
* Union the collection with the given items. * Union the collection with the given items.
* *
* @param mixed $items * @param \QL\Collect\Contracts\Support\Arrayable<TKey, TValue>|iterable<TKey, TValue> $items
* @return static * @return static
*/ */
public function union($items) public function union($items)
@ -809,7 +920,7 @@ class LazyCollection implements CanBeEscapedWhenCastToString, Enumerable
/** /**
* Get the items with the specified keys. * Get the items with the specified keys.
* *
* @param mixed $keys * @param \QL\Collect\Support\Enumerable<array-key, TKey>|array<array-key, TKey>|string $keys
* @return static * @return static
*/ */
public function only($keys) public function only($keys)
@ -844,7 +955,7 @@ class LazyCollection implements CanBeEscapedWhenCastToString, Enumerable
/** /**
* Push all of the given items onto the collection. * Push all of the given items onto the collection.
* *
* @param iterable $source * @param iterable<array-key, TValue> $source
* @return static * @return static
*/ */
public function concat($source) public function concat($source)
@ -859,7 +970,7 @@ class LazyCollection implements CanBeEscapedWhenCastToString, Enumerable
* Get one or a specified number of items randomly from the collection. * Get one or a specified number of items randomly from the collection.
* *
* @param int|null $number * @param int|null $number
* @return static|mixed * @return static<int, TValue>|TValue
* *
* @throws \InvalidArgumentException * @throws \InvalidArgumentException
*/ */
@ -873,7 +984,7 @@ class LazyCollection implements CanBeEscapedWhenCastToString, Enumerable
/** /**
* Replace the collection items with the given items. * Replace the collection items with the given items.
* *
* @param mixed $items * @param \QL\Collect\Contracts\Support\Arrayable<TKey, TValue>|iterable<TKey, TValue> $items
* @return static * @return static
*/ */
public function replace($items) public function replace($items)
@ -900,7 +1011,7 @@ class LazyCollection implements CanBeEscapedWhenCastToString, Enumerable
/** /**
* Recursively replace the collection items with the given items. * Recursively replace the collection items with the given items.
* *
* @param mixed $items * @param \QL\Collect\Contracts\Support\Arrayable<TKey, TValue>|iterable<TKey, TValue> $items
* @return static * @return static
*/ */
public function replaceRecursive($items) public function replaceRecursive($items)
@ -921,12 +1032,13 @@ class LazyCollection implements CanBeEscapedWhenCastToString, Enumerable
/** /**
* Search the collection for a given value and return the corresponding key if successful. * Search the collection for a given value and return the corresponding key if successful.
* *
* @param mixed $value * @param TValue|(callable(TValue,TKey): bool) $value
* @param bool $strict * @param bool $strict
* @return mixed * @return TKey|bool
*/ */
public function search($value, $strict = false) public function search($value, $strict = false)
{ {
/** @var (callable(TValue,TKey): bool) $predicate */
$predicate = $this->useAsCallable($value) $predicate = $this->useAsCallable($value)
? $value ? $value
: function ($item) use ($value, $strict) { : function ($item) use ($value, $strict) {
@ -958,7 +1070,7 @@ class LazyCollection implements CanBeEscapedWhenCastToString, Enumerable
* *
* @param int $size * @param int $size
* @param int $step * @param int $step
* @return static * @return static<int, static>
*/ */
public function sliding($size = 2, $step = 1) public function sliding($size = 2, $step = 1)
{ {
@ -971,7 +1083,7 @@ class LazyCollection implements CanBeEscapedWhenCastToString, Enumerable
$chunk[$iterator->key()] = $iterator->current(); $chunk[$iterator->key()] = $iterator->current();
if (count($chunk) == $size) { if (count($chunk) == $size) {
yield tap(new static($chunk), function () use (&$chunk, $step) { yield (new static($chunk))->tap(function () use (&$chunk, $step) {
$chunk = array_slice($chunk, $step, null, true); $chunk = array_slice($chunk, $step, null, true);
}); });
@ -1018,7 +1130,7 @@ class LazyCollection implements CanBeEscapedWhenCastToString, Enumerable
/** /**
* Skip items in the collection until the given condition is met. * Skip items in the collection until the given condition is met.
* *
* @param mixed $value * @param TValue|callable(TValue,TKey): bool $value
* @return static * @return static
*/ */
public function skipUntil($value) public function skipUntil($value)
@ -1031,7 +1143,7 @@ class LazyCollection implements CanBeEscapedWhenCastToString, Enumerable
/** /**
* Skip items in the collection while the given condition is met. * Skip items in the collection while the given condition is met.
* *
* @param mixed $value * @param TValue|callable(TValue,TKey): bool $value
* @return static * @return static
*/ */
public function skipWhile($value) public function skipWhile($value)
@ -1075,7 +1187,7 @@ class LazyCollection implements CanBeEscapedWhenCastToString, Enumerable
* Split a collection into a certain number of groups. * Split a collection into a certain number of groups.
* *
* @param int $numberOfGroups * @param int $numberOfGroups
* @return static * @return static<int, static>
*/ */
public function split($numberOfGroups) public function split($numberOfGroups)
{ {
@ -1085,13 +1197,13 @@ class LazyCollection implements CanBeEscapedWhenCastToString, Enumerable
/** /**
* Get the first item in the collection, but only if exactly one item exists. Otherwise, throw an exception. * Get the first item in the collection, but only if exactly one item exists. Otherwise, throw an exception.
* *
* @param mixed $key * @param (callable(TValue, TKey): bool)|string $key
* @param mixed $operator * @param mixed $operator
* @param mixed $value * @param mixed $value
* @return mixed * @return TValue
* *
* @throws \Tightenco\Collect\Support\ItemNotFoundException * @throws \QL\Collect\Support\ItemNotFoundException
* @throws \Tightenco\Collect\Support\MultipleItemsFoundException * @throws \QL\Collect\Support\MultipleItemsFoundException
*/ */
public function sole($key = null, $operator = null, $value = null) public function sole($key = null, $operator = null, $value = null)
{ {
@ -1100,7 +1212,7 @@ class LazyCollection implements CanBeEscapedWhenCastToString, Enumerable
: $key; : $key;
return $this return $this
->when($filter) ->unless($filter == null)
->filter($filter) ->filter($filter)
->take(2) ->take(2)
->collect() ->collect()
@ -1110,12 +1222,12 @@ class LazyCollection implements CanBeEscapedWhenCastToString, Enumerable
/** /**
* Get the first item in the collection but throw an exception if no matching items exist. * Get the first item in the collection but throw an exception if no matching items exist.
* *
* @param mixed $key * @param (callable(TValue, TKey): bool)|string $key
* @param mixed $operator * @param mixed $operator
* @param mixed $value * @param mixed $value
* @return mixed * @return TValue
* *
* @throws \Tightenco\Collect\Support\ItemNotFoundException * @throws \QL\Collect\Support\ItemNotFoundException
*/ */
public function firstOrFail($key = null, $operator = null, $value = null) public function firstOrFail($key = null, $operator = null, $value = null)
{ {
@ -1124,7 +1236,7 @@ class LazyCollection implements CanBeEscapedWhenCastToString, Enumerable
: $key; : $key;
return $this return $this
->when($filter) ->unless($filter == null)
->filter($filter) ->filter($filter)
->take(1) ->take(1)
->collect() ->collect()
@ -1135,7 +1247,7 @@ class LazyCollection implements CanBeEscapedWhenCastToString, Enumerable
* Chunk the collection into chunks of the given size. * Chunk the collection into chunks of the given size.
* *
* @param int $size * @param int $size
* @return static * @return static<int, static>
*/ */
public function chunk($size) public function chunk($size)
{ {
@ -1174,7 +1286,7 @@ class LazyCollection implements CanBeEscapedWhenCastToString, Enumerable
* Split a collection into a certain number of groups, and fill the first groups completely. * Split a collection into a certain number of groups, and fill the first groups completely.
* *
* @param int $numberOfGroups * @param int $numberOfGroups
* @return static * @return static<int, static>
*/ */
public function splitIn($numberOfGroups) public function splitIn($numberOfGroups)
{ {
@ -1184,8 +1296,8 @@ class LazyCollection implements CanBeEscapedWhenCastToString, Enumerable
/** /**
* Chunk the collection into chunks with a callback. * Chunk the collection into chunks with a callback.
* *
* @param callable $callback * @param callable(TValue, TKey, Collection<TKey, TValue>): bool $callback
* @return static * @return static<int, static<int, TValue>>
*/ */
public function chunkWhile(callable $callback) public function chunkWhile(callable $callback)
{ {
@ -1221,7 +1333,7 @@ class LazyCollection implements CanBeEscapedWhenCastToString, Enumerable
/** /**
* Sort through each item with a callback. * Sort through each item with a callback.
* *
* @param callable|null|int $callback * @param (callable(TValue, TValue): int)|null|int $callback
* @return static * @return static
*/ */
public function sort($callback = null) public function sort($callback = null)
@ -1243,7 +1355,7 @@ class LazyCollection implements CanBeEscapedWhenCastToString, Enumerable
/** /**
* Sort the collection using the given callback. * Sort the collection using the given callback.
* *
* @param callable|string $callback * @param array<array-key, (callable(TValue, TValue): mixed)|(callable(TValue, TKey): mixed)|string|array{string, string}>|(callable(TValue, TKey): mixed)|string $callback
* @param int $options * @param int $options
* @param bool $descending * @param bool $descending
* @return static * @return static
@ -1256,7 +1368,7 @@ class LazyCollection implements CanBeEscapedWhenCastToString, Enumerable
/** /**
* Sort the collection in descending order using the given callback. * Sort the collection in descending order using the given callback.
* *
* @param callable|string $callback * @param array<array-key, (callable(TValue, TValue): mixed)|(callable(TValue, TKey): mixed)|string|array{string, string}>|(callable(TValue, TKey): mixed)|string $callback
* @param int $options * @param int $options
* @return static * @return static
*/ */
@ -1291,7 +1403,7 @@ class LazyCollection implements CanBeEscapedWhenCastToString, Enumerable
/** /**
* Sort the collection keys using a callback. * Sort the collection keys using a callback.
* *
* @param callable $callback * @param callable(TKey, TKey): int $callback
* @return static * @return static
*/ */
public function sortKeysUsing(callable $callback) public function sortKeysUsing(callable $callback)
@ -1331,11 +1443,12 @@ class LazyCollection implements CanBeEscapedWhenCastToString, Enumerable
/** /**
* Take items in the collection until the given condition is met. * Take items in the collection until the given condition is met.
* *
* @param mixed $value * @param TValue|callable(TValue,TKey): bool $value
* @return static * @return static
*/ */
public function takeUntil($value) public function takeUntil($value)
{ {
/** @var callable(TValue, TKey): bool $callback */
$callback = $this->useAsCallable($value) ? $value : $this->equality($value); $callback = $this->useAsCallable($value) ? $value : $this->equality($value);
return new static(function () use ($callback) { return new static(function () use ($callback) {
@ -1359,30 +1472,39 @@ class LazyCollection implements CanBeEscapedWhenCastToString, Enumerable
{ {
$timeout = $timeout->getTimestamp(); $timeout = $timeout->getTimestamp();
return $this->takeWhile(function () use ($timeout) { return new static(function () use ($timeout) {
return $this->now() < $timeout; if ($this->now() >= $timeout) {
return;
}
foreach ($this as $key => $value) {
yield $key => $value;
if ($this->now() >= $timeout) {
break;
}
}
}); });
} }
/** /**
* Take items in the collection while the given condition is met. * Take items in the collection while the given condition is met.
* *
* @param mixed $value * @param TValue|callable(TValue,TKey): bool $value
* @return static * @return static
*/ */
public function takeWhile($value) public function takeWhile($value)
{ {
/** @var callable(TValue, TKey): bool $callback */
$callback = $this->useAsCallable($value) ? $value : $this->equality($value); $callback = $this->useAsCallable($value) ? $value : $this->equality($value);
return $this->takeUntil(function ($item, $key) use ($callback) { return $this->takeUntil(fn ($item, $key) => ! $callback($item, $key));
return ! $callback($item, $key);
});
} }
/** /**
* Pass each item in the collection to the given callback, lazily. * Pass each item in the collection to the given callback, lazily.
* *
* @param callable $callback * @param callable(TValue, TKey): mixed $callback
* @return static * @return static
*/ */
public function tapEach(callable $callback) public function tapEach(callable $callback)
@ -1409,7 +1531,7 @@ class LazyCollection implements CanBeEscapedWhenCastToString, Enumerable
/** /**
* Return only unique items from the collection array. * Return only unique items from the collection array.
* *
* @param string|callable|null $key * @param (callable(TValue, TKey): mixed)|string|null $key
* @param bool $strict * @param bool $strict
* @return static * @return static
*/ */
@ -1433,7 +1555,7 @@ class LazyCollection implements CanBeEscapedWhenCastToString, Enumerable
/** /**
* Reset the keys on the underlying array. * Reset the keys on the underlying array.
* *
* @return static * @return static<int, TValue>
*/ */
public function values() public function values()
{ {
@ -1450,8 +1572,10 @@ class LazyCollection implements CanBeEscapedWhenCastToString, Enumerable
* e.g. new LazyCollection([1, 2, 3])->zip([4, 5, 6]); * e.g. new LazyCollection([1, 2, 3])->zip([4, 5, 6]);
* => [[1, 4], [2, 5], [3, 6]] * => [[1, 4], [2, 5], [3, 6]]
* *
* @param mixed ...$items * @template TZipValue
* @return static *
* @param \QL\Collect\Contracts\Support\Arrayable<array-key, TZipValue>|iterable<array-key, TZipValue> ...$items
* @return static<int, static<int, TValue|TZipValue>>
*/ */
public function zip($items) public function zip($items)
{ {
@ -1473,9 +1597,11 @@ class LazyCollection implements CanBeEscapedWhenCastToString, Enumerable
/** /**
* Pad collection to the specified length with a value. * Pad collection to the specified length with a value.
* *
* @template TPadValue
*
* @param int $size * @param int $size
* @param mixed $value * @param TPadValue $value
* @return static * @return static<int, TValue|TPadValue>
*/ */
public function pad($size, $value) public function pad($size, $value)
{ {
@ -1501,10 +1627,9 @@ class LazyCollection implements CanBeEscapedWhenCastToString, Enumerable
/** /**
* Get the values iterator. * Get the values iterator.
* *
* @return \Traversable * @return \Traversable<TKey, TValue>
*/ */
#[\ReturnTypeWillChange] public function getIterator(): Traversable
public function getIterator()
{ {
return $this->makeIterator($this->source); return $this->makeIterator($this->source);
} }
@ -1514,8 +1639,7 @@ class LazyCollection implements CanBeEscapedWhenCastToString, Enumerable
* *
* @return int * @return int
*/ */
#[\ReturnTypeWillChange] public function count(): int
public function count()
{ {
if (is_array($this->source)) { if (is_array($this->source)) {
return count($this->source); return count($this->source);
@ -1527,8 +1651,11 @@ class LazyCollection implements CanBeEscapedWhenCastToString, Enumerable
/** /**
* Make an iterator from the given source. * Make an iterator from the given source.
* *
* @param mixed $source * @template TIteratorKey of array-key
* @return \Traversable * @template TIteratorValue
*
* @param \IteratorAggregate<TIteratorKey, TIteratorValue>|array<TIteratorKey, TIteratorValue>|(callable(): \Generator<TIteratorKey, TIteratorValue>) $source
* @return \Traversable<TIteratorKey, TIteratorValue>
*/ */
protected function makeIterator($source) protected function makeIterator($source)
{ {
@ -1540,15 +1667,23 @@ class LazyCollection implements CanBeEscapedWhenCastToString, Enumerable
return new ArrayIterator($source); return new ArrayIterator($source);
} }
return $source(); if (is_callable($source)) {
$maybeTraversable = $source();
return $maybeTraversable instanceof Traversable
? $maybeTraversable
: new ArrayIterator(Arr::wrap($maybeTraversable));
}
return new ArrayIterator((array) $source);
} }
/** /**
* Explode the "value" and "key" arguments passed to "pluck". * Explode the "value" and "key" arguments passed to "pluck".
* *
* @param string|array $value * @param string|string[] $value
* @param string|array|null $key * @param string|string[]|null $key
* @return array * @return array{string[],string[]|null}
*/ */
protected function explodePluckParameters($value, $key) protected function explodePluckParameters($value, $key)
{ {
@ -1563,7 +1698,7 @@ class LazyCollection implements CanBeEscapedWhenCastToString, Enumerable
* Pass this lazy collection through a method on the collection class. * Pass this lazy collection through a method on the collection class.
* *
* @param string $method * @param string $method
* @param array $params * @param array<mixed> $params
* @return static * @return static
*/ */
protected function passthru($method, array $params) protected function passthru($method, array $params)

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,73 @@
<?php
namespace QL\Collect\Support\Traits;
use Closure;
use QL\Collect\Conditionable\HigherOrderWhenProxy;
trait Conditionable
{
/**
* Apply the callback if the given "value" is (or resolves to) truthy.
*
* @template TWhenParameter
* @template TWhenReturnType
*
* @param (\Closure($this): TWhenParameter)|TWhenParameter|null $value
* @param (callable($this, TWhenParameter): TWhenReturnType)|null $callback
* @param (callable($this, TWhenParameter): TWhenReturnType)|null $default
* @return $this|TWhenReturnType
*/
public function when($value = null, callable $callback = null, callable $default = null)
{
$value = $value instanceof Closure ? $value($this) : $value;
if (func_num_args() === 0) {
return new HigherOrderWhenProxy($this);
}
if (func_num_args() === 1) {
return (new HigherOrderWhenProxy($this))->condition($value);
}
if ($value) {
return $callback($this, $value) ?? $this;
} elseif ($default) {
return $default($this, $value) ?? $this;
}
return $this;
}
/**
* Apply the callback if the given "value" is (or resolves to) falsy.
*
* @template TUnlessParameter
* @template TUnlessReturnType
*
* @param (\Closure($this): TUnlessParameter)|TUnlessParameter|null $value
* @param (callable($this, TUnlessParameter): TUnlessReturnType)|null $callback
* @param (callable($this, TUnlessParameter): TUnlessReturnType)|null $default
* @return $this|TUnlessReturnType
*/
public function unless($value = null, callable $callback = null, callable $default = null)
{
$value = $value instanceof Closure ? $value($this) : $value;
if (func_num_args() === 0) {
return (new HigherOrderWhenProxy($this))->negateConditionOnCapture();
}
if (func_num_args() === 1) {
return (new HigherOrderWhenProxy($this))->condition(! $value);
}
if (! $value) {
return $callback($this, $value) ?? $this;
} elseif ($default) {
return $default($this, $value) ?? $this;
}
return $this;
}
}

View File

@ -1,17 +1,16 @@
<?php <?php
namespace Tightenco\Collect\Support\Traits; namespace QL\Collect\Support\Traits;
use CachingIterator; use CachingIterator;
use Closure; use Closure;
use Exception; use Exception;
use Tightenco\Collect\Contracts\Support\Arrayable; use QL\Collect\Contracts\Support\Arrayable;
use Tightenco\Collect\Contracts\Support\Jsonable; use QL\Collect\Contracts\Support\Jsonable;
use Tightenco\Collect\Support\Arr; use QL\Collect\Support\Arr;
use Tightenco\Collect\Support\Collection; use QL\Collect\Support\Collection;
use Tightenco\Collect\Support\Enumerable; use QL\Collect\Support\Enumerable;
use Tightenco\Collect\Support\HigherOrderCollectionProxy; use QL\Collect\Support\HigherOrderCollectionProxy;
use Tightenco\Collect\Support\HigherOrderWhenProxy;
use JsonSerializable; use JsonSerializable;
use Symfony\Component\VarDumper\VarDumper; use Symfony\Component\VarDumper\VarDumper;
use Traversable; use Traversable;
@ -19,6 +18,9 @@ use UnexpectedValueException;
use UnitEnum; use UnitEnum;
/** /**
* @template TKey of array-key
* @template TValue
*
* @property-read HigherOrderCollectionProxy $average * @property-read HigherOrderCollectionProxy $average
* @property-read HigherOrderCollectionProxy $avg * @property-read HigherOrderCollectionProxy $avg
* @property-read HigherOrderCollectionProxy $contains * @property-read HigherOrderCollectionProxy $contains
@ -35,19 +37,23 @@ use UnitEnum;
* @property-read HigherOrderCollectionProxy $min * @property-read HigherOrderCollectionProxy $min
* @property-read HigherOrderCollectionProxy $partition * @property-read HigherOrderCollectionProxy $partition
* @property-read HigherOrderCollectionProxy $reject * @property-read HigherOrderCollectionProxy $reject
* @property-read HigherOrderCollectionProxy $skipUntil
* @property-read HigherOrderCollectionProxy $skipWhile
* @property-read HigherOrderCollectionProxy $some * @property-read HigherOrderCollectionProxy $some
* @property-read HigherOrderCollectionProxy $sortBy * @property-read HigherOrderCollectionProxy $sortBy
* @property-read HigherOrderCollectionProxy $sortByDesc * @property-read HigherOrderCollectionProxy $sortByDesc
* @property-read HigherOrderCollectionProxy $skipUntil
* @property-read HigherOrderCollectionProxy $skipWhile
* @property-read HigherOrderCollectionProxy $sum * @property-read HigherOrderCollectionProxy $sum
* @property-read HigherOrderCollectionProxy $takeUntil * @property-read HigherOrderCollectionProxy $takeUntil
* @property-read HigherOrderCollectionProxy $takeWhile * @property-read HigherOrderCollectionProxy $takeWhile
* @property-read HigherOrderCollectionProxy $unique * @property-read HigherOrderCollectionProxy $unique
* @property-read HigherOrderCollectionProxy $unless
* @property-read HigherOrderCollectionProxy $until * @property-read HigherOrderCollectionProxy $until
* @property-read HigherOrderCollectionProxy $when
*/ */
trait EnumeratesValues trait EnumeratesValues
{ {
use Conditionable;
/** /**
* Indicates that the object's string representation should be escaped when __toString is invoked. * Indicates that the object's string representation should be escaped when __toString is invoked.
* *
@ -58,7 +64,7 @@ trait EnumeratesValues
/** /**
* The methods that can be proxied. * The methods that can be proxied.
* *
* @var string[] * @var array<int, string>
*/ */
protected static $proxies = [ protected static $proxies = [
'average', 'average',
@ -86,14 +92,19 @@ trait EnumeratesValues
'takeUntil', 'takeUntil',
'takeWhile', 'takeWhile',
'unique', 'unique',
'unless',
'until', 'until',
'when',
]; ];
/** /**
* Create a new collection instance if the value isn't one already. * Create a new collection instance if the value isn't one already.
* *
* @param mixed $items * @template TMakeKey of array-key
* @return static * @template TMakeValue
*
* @param \QL\Collect\Contracts\Support\Arrayable<TMakeKey, TMakeValue>|iterable<TMakeKey, TMakeValue>|null $items
* @return static<TMakeKey, TMakeValue>
*/ */
public static function make($items = []) public static function make($items = [])
{ {
@ -103,8 +114,10 @@ trait EnumeratesValues
/** /**
* Wrap the given value in a collection if applicable. * Wrap the given value in a collection if applicable.
* *
* @param mixed $value * @template TWrapValue
* @return static *
* @param iterable<array-key, TWrapValue>|TWrapValue $value
* @return static<array-key, TWrapValue>
*/ */
public static function wrap($value) public static function wrap($value)
{ {
@ -116,8 +129,11 @@ trait EnumeratesValues
/** /**
* Get the underlying items from the given collection if applicable. * Get the underlying items from the given collection if applicable.
* *
* @param array|static $value * @template TUnwrapKey of array-key
* @return array * @template TUnwrapValue
*
* @param array<TUnwrapKey, TUnwrapValue>|static<TUnwrapKey, TUnwrapValue> $value
* @return array<TUnwrapKey, TUnwrapValue>
*/ */
public static function unwrap($value) public static function unwrap($value)
{ {
@ -137,9 +153,11 @@ trait EnumeratesValues
/** /**
* Create a new collection by invoking the callback a given amount of times. * Create a new collection by invoking the callback a given amount of times.
* *
* @template TTimesValue
*
* @param int $number * @param int $number
* @param callable|null $callback * @param (callable(int): TTimesValue)|null $callback
* @return static * @return static<int, TTimesValue>
*/ */
public static function times($number, callable $callback = null) public static function times($number, callable $callback = null)
{ {
@ -148,15 +166,15 @@ trait EnumeratesValues
} }
return static::range(1, $number) return static::range(1, $number)
->when($callback) ->unless($callback == null)
->map($callback); ->map($callback);
} }
/** /**
* Alias for the "avg" method. * Alias for the "avg" method.
* *
* @param callable|string|null $callback * @param (callable(TValue): float|int)|string|null $callback
* @return mixed * @return float|int|null
*/ */
public function average($callback = null) public function average($callback = null)
{ {
@ -166,7 +184,7 @@ trait EnumeratesValues
/** /**
* Alias for the "contains" method. * Alias for the "contains" method.
* *
* @param mixed $key * @param (callable(TValue, TKey): bool)|TValue|string $key
* @param mixed $operator * @param mixed $operator
* @param mixed $value * @param mixed $value
* @return bool * @return bool
@ -176,39 +194,11 @@ trait EnumeratesValues
return $this->contains(...func_get_args()); return $this->contains(...func_get_args());
} }
/**
* Determine if an item exists, using strict comparison.
*
* @param mixed $key
* @param mixed $value
* @return bool
*/
public function containsStrict($key, $value = null)
{
if (func_num_args() === 2) {
return $this->contains(function ($item) use ($key, $value) {
return data_get($item, $key) === $value;
});
}
if ($this->useAsCallable($key)) {
return ! is_null($this->first($key));
}
foreach ($this as $item) {
if ($item === $key) {
return true;
}
}
return false;
}
/** /**
* Dump the items and end the script. * Dump the items and end the script.
* *
* @param mixed ...$args * @param mixed ...$args
* @return void * @return never
*/ */
public function dd(...$args) public function dd(...$args)
{ {
@ -236,7 +226,7 @@ trait EnumeratesValues
/** /**
* Execute a callback over each item. * Execute a callback over each item.
* *
* @param callable $callback * @param callable(TValue, TKey): mixed $callback
* @return $this * @return $this
*/ */
public function each(callable $callback) public function each(callable $callback)
@ -253,7 +243,7 @@ trait EnumeratesValues
/** /**
* Execute a callback over each nested chunk of items. * Execute a callback over each nested chunk of items.
* *
* @param callable $callback * @param callable(...mixed): mixed $callback
* @return static * @return static
*/ */
public function eachSpread(callable $callback) public function eachSpread(callable $callback)
@ -268,7 +258,7 @@ trait EnumeratesValues
/** /**
* Determine if all items pass the given truth test. * Determine if all items pass the given truth test.
* *
* @param string|callable $key * @param (callable(TValue, TKey): bool)|TValue|string $key
* @param mixed $operator * @param mixed $operator
* @param mixed $value * @param mixed $value
* @return bool * @return bool
@ -293,16 +283,32 @@ trait EnumeratesValues
/** /**
* Get the first item by the given key value pair. * Get the first item by the given key value pair.
* *
* @param string $key * @param callable|string $key
* @param mixed $operator * @param mixed $operator
* @param mixed $value * @param mixed $value
* @return mixed * @return TValue|null
*/ */
public function firstWhere($key, $operator = null, $value = null) public function firstWhere($key, $operator = null, $value = null)
{ {
return $this->first($this->operatorForWhere(...func_get_args())); return $this->first($this->operatorForWhere(...func_get_args()));
} }
/**
* Get a single key's value from the first matching item in the collection.
*
* @param string $key
* @param mixed $default
* @return mixed
*/
public function value($key, $default = null)
{
if ($value = $this->firstWhere($key)) {
return data_get($value, $key, $default);
}
return value($default);
}
/** /**
* Determine if the collection is not empty. * Determine if the collection is not empty.
* *
@ -316,8 +322,10 @@ trait EnumeratesValues
/** /**
* Run a map over each nested chunk of items. * Run a map over each nested chunk of items.
* *
* @param callable $callback * @template TMapSpreadValue
* @return static *
* @param callable(mixed): TMapSpreadValue $callback
* @return static<TKey, TMapSpreadValue>
*/ */
public function mapSpread(callable $callback) public function mapSpread(callable $callback)
{ {
@ -333,8 +341,11 @@ trait EnumeratesValues
* *
* The callback should return an associative array with a single key/value pair. * The callback should return an associative array with a single key/value pair.
* *
* @param callable $callback * @template TMapToGroupsKey of array-key
* @return static * @template TMapToGroupsValue
*
* @param callable(TValue, TKey): array<TMapToGroupsKey, TMapToGroupsValue> $callback
* @return static<TMapToGroupsKey, static<int, TMapToGroupsValue>>
*/ */
public function mapToGroups(callable $callback) public function mapToGroups(callable $callback)
{ {
@ -346,8 +357,11 @@ trait EnumeratesValues
/** /**
* Map a collection and flatten the result by a single level. * Map a collection and flatten the result by a single level.
* *
* @param callable $callback * @template TFlatMapKey of array-key
* @return static * @template TFlatMapValue
*
* @param callable(TValue, TKey): (\QL\Collect\Support\Collection<TFlatMapKey, TFlatMapValue>|array<TFlatMapKey, TFlatMapValue>) $callback
* @return static<TFlatMapKey, TFlatMapValue>
*/ */
public function flatMap(callable $callback) public function flatMap(callable $callback)
{ {
@ -357,48 +371,42 @@ trait EnumeratesValues
/** /**
* Map the values into a new class. * Map the values into a new class.
* *
* @param string $class * @template TMapIntoValue
* @return static *
* @param class-string<TMapIntoValue> $class
* @return static<TKey, TMapIntoValue>
*/ */
public function mapInto($class) public function mapInto($class)
{ {
return $this->map(function ($value, $key) use ($class) { return $this->map(fn ($value, $key) => new $class($value, $key));
return new $class($value, $key);
});
} }
/** /**
* Get the min value of a given key. * Get the min value of a given key.
* *
* @param callable|string|null $callback * @param (callable(TValue):mixed)|string|null $callback
* @return mixed * @return mixed
*/ */
public function min($callback = null) public function min($callback = null)
{ {
$callback = $this->valueRetriever($callback); $callback = $this->valueRetriever($callback);
return $this->map(function ($value) use ($callback) { return $this->map(fn ($value) => $callback($value))
return $callback($value); ->filter(fn ($value) => ! is_null($value))
})->filter(function ($value) { ->reduce(fn ($result, $value) => is_null($result) || $value < $result ? $value : $result);
return ! is_null($value);
})->reduce(function ($result, $value) {
return is_null($result) || $value < $result ? $value : $result;
});
} }
/** /**
* Get the max value of a given key. * Get the max value of a given key.
* *
* @param callable|string|null $callback * @param (callable(TValue):mixed)|string|null $callback
* @return mixed * @return mixed
*/ */
public function max($callback = null) public function max($callback = null)
{ {
$callback = $this->valueRetriever($callback); $callback = $this->valueRetriever($callback);
return $this->filter(function ($value) { return $this->filter(fn ($value) => ! is_null($value))->reduce(function ($result, $item) use ($callback) {
return ! is_null($value);
})->reduce(function ($result, $item) use ($callback) {
$value = $callback($item); $value = $callback($item);
return is_null($result) || $value > $result ? $value : $result; return is_null($result) || $value > $result ? $value : $result;
@ -422,10 +430,10 @@ trait EnumeratesValues
/** /**
* Partition the collection into two arrays using the given callback or key. * Partition the collection into two arrays using the given callback or key.
* *
* @param callable|string $key * @param (callable(TValue, TKey): bool)|TValue|string $key
* @param mixed $operator * @param TValue|string|null $operator
* @param mixed $value * @param TValue|null $value
* @return static * @return static<int<0, 1>, static<TKey, TValue>>
*/ */
public function partition($key, $operator = null, $value = null) public function partition($key, $operator = null, $value = null)
{ {
@ -450,7 +458,7 @@ trait EnumeratesValues
/** /**
* Get the sum of the given values. * Get the sum of the given values.
* *
* @param callable|string|null $callback * @param (callable(TValue): mixed)|string|null $callback
* @return mixed * @return mixed
*/ */
public function sum($callback = null) public function sum($callback = null)
@ -459,40 +467,17 @@ trait EnumeratesValues
? $this->identity() ? $this->identity()
: $this->valueRetriever($callback); : $this->valueRetriever($callback);
return $this->reduce(function ($result, $item) use ($callback) { return $this->reduce(fn ($result, $item) => $result + $callback($item), 0);
return $result + $callback($item);
}, 0);
}
/**
* Apply the callback if the value is truthy.
*
* @param bool|mixed $value
* @param callable|null $callback
* @param callable|null $default
* @return static|mixed
*/
public function when($value, callable $callback = null, callable $default = null)
{
if (! $callback) {
return new HigherOrderWhenProxy($this, $value);
}
if ($value) {
return $callback($this, $value);
} elseif ($default) {
return $default($this, $value);
}
return $this;
} }
/** /**
* Apply the callback if the collection is empty. * Apply the callback if the collection is empty.
* *
* @param callable $callback * @template TWhenEmptyReturnType
* @param callable|null $default *
* @return static|mixed * @param (callable($this): TWhenEmptyReturnType) $callback
* @param (callable($this): TWhenEmptyReturnType)|null $default
* @return $this|TWhenEmptyReturnType
*/ */
public function whenEmpty(callable $callback, callable $default = null) public function whenEmpty(callable $callback, callable $default = null)
{ {
@ -502,34 +487,25 @@ trait EnumeratesValues
/** /**
* Apply the callback if the collection is not empty. * Apply the callback if the collection is not empty.
* *
* @param callable $callback * @template TWhenNotEmptyReturnType
* @param callable|null $default *
* @return static|mixed * @param callable($this): TWhenNotEmptyReturnType $callback
* @param (callable($this): TWhenNotEmptyReturnType)|null $default
* @return $this|TWhenNotEmptyReturnType
*/ */
public function whenNotEmpty(callable $callback, callable $default = null) public function whenNotEmpty(callable $callback, callable $default = null)
{ {
return $this->when($this->isNotEmpty(), $callback, $default); return $this->when($this->isNotEmpty(), $callback, $default);
} }
/**
* Apply the callback if the value is falsy.
*
* @param bool $value
* @param callable $callback
* @param callable|null $default
* @return static|mixed
*/
public function unless($value, callable $callback, callable $default = null)
{
return $this->when(! $value, $callback, $default);
}
/** /**
* Apply the callback unless the collection is empty. * Apply the callback unless the collection is empty.
* *
* @param callable $callback * @template TUnlessEmptyReturnType
* @param callable|null $default *
* @return static|mixed * @param callable($this): TUnlessEmptyReturnType $callback
* @param (callable($this): TUnlessEmptyReturnType)|null $default
* @return $this|TUnlessEmptyReturnType
*/ */
public function unlessEmpty(callable $callback, callable $default = null) public function unlessEmpty(callable $callback, callable $default = null)
{ {
@ -539,9 +515,11 @@ trait EnumeratesValues
/** /**
* Apply the callback unless the collection is not empty. * Apply the callback unless the collection is not empty.
* *
* @param callable $callback * @template TUnlessNotEmptyReturnType
* @param callable|null $default *
* @return static|mixed * @param callable($this): TUnlessNotEmptyReturnType $callback
* @param (callable($this): TUnlessNotEmptyReturnType)|null $default
* @return $this|TUnlessNotEmptyReturnType
*/ */
public function unlessNotEmpty(callable $callback, callable $default = null) public function unlessNotEmpty(callable $callback, callable $default = null)
{ {
@ -551,7 +529,7 @@ trait EnumeratesValues
/** /**
* Filter items by the given key value pair. * Filter items by the given key value pair.
* *
* @param string $key * @param callable|string $key
* @param mixed $operator * @param mixed $operator
* @param mixed $value * @param mixed $value
* @return static * @return static
@ -599,7 +577,7 @@ trait EnumeratesValues
* Filter items by the given key value pair. * Filter items by the given key value pair.
* *
* @param string $key * @param string $key
* @param mixed $values * @param \QL\Collect\Contracts\Support\Arrayable|iterable $values
* @param bool $strict * @param bool $strict
* @return static * @return static
*/ */
@ -607,16 +585,14 @@ trait EnumeratesValues
{ {
$values = $this->getArrayableItems($values); $values = $this->getArrayableItems($values);
return $this->filter(function ($item) use ($key, $values, $strict) { return $this->filter(fn ($item) => in_array(data_get($item, $key), $values, $strict));
return in_array(data_get($item, $key), $values, $strict);
});
} }
/** /**
* Filter items by the given key value pair using strict comparison. * Filter items by the given key value pair using strict comparison.
* *
* @param string $key * @param string $key
* @param mixed $values * @param \QL\Collect\Contracts\Support\Arrayable|iterable $values
* @return static * @return static
*/ */
public function whereInStrict($key, $values) public function whereInStrict($key, $values)
@ -628,7 +604,7 @@ trait EnumeratesValues
* Filter items such that the value of the given key is between the given values. * Filter items such that the value of the given key is between the given values.
* *
* @param string $key * @param string $key
* @param array $values * @param \QL\Collect\Contracts\Support\Arrayable|iterable $values
* @return static * @return static
*/ */
public function whereBetween($key, $values) public function whereBetween($key, $values)
@ -640,21 +616,21 @@ trait EnumeratesValues
* Filter items such that the value of the given key is not between the given values. * Filter items such that the value of the given key is not between the given values.
* *
* @param string $key * @param string $key
* @param array $values * @param \QL\Collect\Contracts\Support\Arrayable|iterable $values
* @return static * @return static
*/ */
public function whereNotBetween($key, $values) public function whereNotBetween($key, $values)
{ {
return $this->filter(function ($item) use ($key, $values) { return $this->filter(
return data_get($item, $key) < reset($values) || data_get($item, $key) > end($values); fn ($item) => data_get($item, $key) < reset($values) || data_get($item, $key) > end($values)
}); );
} }
/** /**
* Filter items by the given key value pair. * Filter items by the given key value pair.
* *
* @param string $key * @param string $key
* @param mixed $values * @param \QL\Collect\Contracts\Support\Arrayable|iterable $values
* @param bool $strict * @param bool $strict
* @return static * @return static
*/ */
@ -662,16 +638,14 @@ trait EnumeratesValues
{ {
$values = $this->getArrayableItems($values); $values = $this->getArrayableItems($values);
return $this->reject(function ($item) use ($key, $values, $strict) { return $this->reject(fn ($item) => in_array(data_get($item, $key), $values, $strict));
return in_array(data_get($item, $key), $values, $strict);
});
} }
/** /**
* Filter items by the given key value pair using strict comparison. * Filter items by the given key value pair using strict comparison.
* *
* @param string $key * @param string $key
* @param mixed $values * @param \QL\Collect\Contracts\Support\Arrayable|iterable $values
* @return static * @return static
*/ */
public function whereNotInStrict($key, $values) public function whereNotInStrict($key, $values)
@ -682,8 +656,10 @@ trait EnumeratesValues
/** /**
* Filter the items, removing any items that don't match the given type(s). * Filter the items, removing any items that don't match the given type(s).
* *
* @param string|string[] $type * @template TWhereInstanceOf
* @return static *
* @param class-string<TWhereInstanceOf>|array<array-key, class-string<TWhereInstanceOf>> $type
* @return static<TKey, TWhereInstanceOf>
*/ */
public function whereInstanceOf($type) public function whereInstanceOf($type)
{ {
@ -705,8 +681,10 @@ trait EnumeratesValues
/** /**
* Pass the collection to the given callback and return the result. * Pass the collection to the given callback and return the result.
* *
* @param callable $callback * @template TPipeReturnType
* @return mixed *
* @param callable($this): TPipeReturnType $callback
* @return TPipeReturnType
*/ */
public function pipe(callable $callback) public function pipe(callable $callback)
{ {
@ -716,7 +694,7 @@ trait EnumeratesValues
/** /**
* Pass the collection into a new class. * Pass the collection into a new class.
* *
* @param string $class * @param class-string $class
* @return mixed * @return mixed
*/ */
public function pipeInto($class) public function pipeInto($class)
@ -727,38 +705,26 @@ trait EnumeratesValues
/** /**
* Pass the collection through a series of callable pipes and return the result. * Pass the collection through a series of callable pipes and return the result.
* *
* @param array<callable> $pipes * @param array<callable> $callbacks
* @return mixed * @return mixed
*/ */
public function pipeThrough($pipes) public function pipeThrough($callbacks)
{ {
return static::make($pipes)->reduce( return Collection::make($callbacks)->reduce(
function ($carry, $pipe) { fn ($carry, $callback) => $callback($carry),
return $pipe($carry);
},
$this, $this,
); );
} }
/**
* Pass the collection to the given callback and then return it.
*
* @param callable $callback
* @return $this
*/
public function tap(callable $callback)
{
$callback(clone $this);
return $this;
}
/** /**
* Reduce the collection to a single value. * Reduce the collection to a single value.
* *
* @param callable $callback * @template TReduceInitial
* @param mixed $initial * @template TReduceReturnType
* @return mixed *
* @param callable(TReduceInitial|TReduceReturnType, TValue, TKey): TReduceReturnType $callback
* @param TReduceInitial $initial
* @return TReduceReturnType
*/ */
public function reduce(callable $callback, $initial = null) public function reduce(callable $callback, $initial = null)
{ {
@ -771,22 +737,6 @@ trait EnumeratesValues
return $result; return $result;
} }
/**
* Reduce the collection to multiple aggregate values.
*
* @param callable $callback
* @param mixed ...$initial
* @return array
*
* @deprecated Use "reduceSpread" instead
*
* @throws \UnexpectedValueException
*/
public function reduceMany(callable $callback, ...$initial)
{
return $this->reduceSpread($callback, ...$initial);
}
/** /**
* Reduce the collection to multiple aggregate values. * Reduce the collection to multiple aggregate values.
* *
@ -805,7 +755,7 @@ trait EnumeratesValues
if (! is_array($result)) { if (! is_array($result)) {
throw new UnexpectedValueException(sprintf( throw new UnexpectedValueException(sprintf(
"%s::reduceMany expects reducer to return an array, but got a '%s' instead.", "%s::reduceSpread expects reducer to return an array, but got a '%s' instead.",
class_basename(static::class), gettype($result) class_basename(static::class), gettype($result)
)); ));
} }
@ -814,22 +764,10 @@ trait EnumeratesValues
return $result; return $result;
} }
/**
* Reduce an associative collection to a single value.
*
* @param callable $callback
* @param mixed $initial
* @return mixed
*/
public function reduceWithKeys(callable $callback, $initial = null)
{
return $this->reduce($callback, $initial);
}
/** /**
* Create a collection of all elements that do not pass a given truth test. * Create a collection of all elements that do not pass a given truth test.
* *
* @param callable|mixed $callback * @param (callable(TValue, TKey): bool)|bool|TValue $callback
* @return static * @return static
*/ */
public function reject($callback = true) public function reject($callback = true)
@ -843,10 +781,45 @@ trait EnumeratesValues
}); });
} }
/**
* Pass the collection to the given callback and then return it.
*
* @param callable($this): mixed $callback
* @return $this
*/
public function tap(callable $callback)
{
$callback($this);
return $this;
}
/**
* Return only unique items from the collection array.
*
* @param (callable(TValue, TKey): mixed)|string|null $key
* @param bool $strict
* @return static
*/
public function unique($key = null, $strict = false)
{
$callback = $this->valueRetriever($key);
$exists = [];
return $this->reject(function ($item, $key) use ($callback, $strict, &$exists) {
if (in_array($id = $callback($item, $key), $exists, $strict)) {
return true;
}
$exists[] = $id;
});
}
/** /**
* Return only unique items from the collection array using strict comparison. * Return only unique items from the collection array using strict comparison.
* *
* @param string|callable|null $key * @param (callable(TValue, TKey): mixed)|string|null $key
* @return static * @return static
*/ */
public function uniqueStrict($key = null) public function uniqueStrict($key = null)
@ -857,7 +830,7 @@ trait EnumeratesValues
/** /**
* Collect the values into a collection. * Collect the values into a collection.
* *
* @return \Tightenco\Collect\Support\Collection * @return \QL\Collect\Support\Collection<TKey, TValue>
*/ */
public function collect() public function collect()
{ {
@ -867,22 +840,19 @@ trait EnumeratesValues
/** /**
* Get the collection of items as a plain array. * Get the collection of items as a plain array.
* *
* @return array * @return array<TKey, mixed>
*/ */
public function toArray() public function toArray()
{ {
return $this->map(function ($value) { return $this->map(fn ($value) => $value instanceof Arrayable ? $value->toArray() : $value)->all();
return $value instanceof Arrayable ? $value->toArray() : $value;
})->all();
} }
/** /**
* Convert the object into something JSON serializable. * Convert the object into something JSON serializable.
* *
* @return array * @return array<TKey, mixed>
*/ */
#[\ReturnTypeWillChange] public function jsonSerialize(): array
public function jsonSerialize()
{ {
return array_map(function ($value) { return array_map(function ($value) {
if ($value instanceof JsonSerializable) { if ($value instanceof JsonSerializable) {
@ -976,7 +946,7 @@ trait EnumeratesValues
* Results array of items from Collection or Arrayable. * Results array of items from Collection or Arrayable.
* *
* @param mixed $items * @param mixed $items
* @return array * @return array<TKey, TValue>
*/ */
protected function getArrayableItems($items) protected function getArrayableItems($items)
{ {
@ -986,12 +956,12 @@ trait EnumeratesValues
return $items->all(); return $items->all();
} elseif ($items instanceof Arrayable) { } elseif ($items instanceof Arrayable) {
return $items->toArray(); return $items->toArray();
} elseif ($items instanceof Traversable) {
return iterator_to_array($items);
} elseif ($items instanceof Jsonable) { } elseif ($items instanceof Jsonable) {
return json_decode($items->toJson(), true); return json_decode($items->toJson(), true);
} elseif ($items instanceof JsonSerializable) { } elseif ($items instanceof JsonSerializable) {
return (array) $items->jsonSerialize(); return (array) $items->jsonSerialize();
} elseif ($items instanceof Traversable) {
return iterator_to_array($items);
} elseif ($items instanceof UnitEnum) { } elseif ($items instanceof UnitEnum) {
return [$items]; return [$items];
} }
@ -1002,13 +972,17 @@ trait EnumeratesValues
/** /**
* Get an operator checker callback. * Get an operator checker callback.
* *
* @param string $key * @param callable|string $key
* @param string|null $operator * @param string|null $operator
* @param mixed $value * @param mixed $value
* @return \Closure * @return \Closure
*/ */
protected function operatorForWhere($key, $operator = null, $value = null) protected function operatorForWhere($key, $operator = null, $value = null)
{ {
if ($this->useAsCallable($key)) {
return $key;
}
if (func_num_args() === 1) { if (func_num_args() === 1) {
$value = true; $value = true;
@ -1044,6 +1018,7 @@ trait EnumeratesValues
case '>=': return $retrieved >= $value; case '>=': return $retrieved >= $value;
case '===': return $retrieved === $value; case '===': return $retrieved === $value;
case '!==': return $retrieved !== $value; case '!==': return $retrieved !== $value;
case '<=>': return $retrieved <=> $value;
} }
}; };
} }
@ -1071,22 +1046,18 @@ trait EnumeratesValues
return $value; return $value;
} }
return function ($item) use ($value) { return fn ($item) => data_get($item, $value);
return data_get($item, $value);
};
} }
/** /**
* Make a function to check an item's equality. * Make a function to check an item's equality.
* *
* @param mixed $value * @param mixed $value
* @return \Closure * @return \Closure(mixed): bool
*/ */
protected function equality($value) protected function equality($value)
{ {
return function ($item) use ($value) { return fn ($item) => $item === $value;
return $item === $value;
};
} }
/** /**
@ -1097,20 +1068,16 @@ trait EnumeratesValues
*/ */
protected function negate(Closure $callback) protected function negate(Closure $callback)
{ {
return function (...$params) use ($callback) { return fn (...$params) => ! $callback(...$params);
return ! $callback(...$params);
};
} }
/** /**
* Make a function that returns what's passed to it. * Make a function that returns what's passed to it.
* *
* @return \Closure * @return \Closure(TValue): TValue
*/ */
protected function identity() protected function identity()
{ {
return function ($value) { return fn ($value) => $value;
return $value;
};
} }
} }

View File

@ -1,6 +1,6 @@
<?php <?php
namespace Tightenco\Collect\Support\Traits; namespace QL\Collect\Support\Traits;
use BadMethodCallException; use BadMethodCallException;
use Closure; use Closure;

View File

@ -1,6 +1,6 @@
<?php <?php
namespace Tightenco\Collect\Support\Traits; namespace QL\Collect\Support\Traits;
trait Tappable trait Tappable
{ {
@ -8,7 +8,7 @@ trait Tappable
* Call the given Closure with this instance then return the instance. * Call the given Closure with this instance then return the instance.
* *
* @param callable|null $callback * @param callable|null $callback
* @return $this|\Tightenco\Collect\Support\HigherOrderTapProxy * @return $this|\QL\Collect\Support\HigherOrderTapProxy
*/ */
public function tap($callback = null) public function tap($callback = null)
{ {

View File

@ -0,0 +1,23 @@
<?php
$aliases = [
QL\Collect\Contracts\Support\Arrayable::class => Illuminate\Contracts\Support\Arrayable::class,
QL\Collect\Contracts\Support\Jsonable::class => Illuminate\Contracts\Support\Jsonable::class,
QL\Collect\Contracts\Support\Htmlable::class => Illuminate\Contracts\Support\Htmlable::class,
QL\Collect\Contracts\Support\CanBeEscapedWhenCastToString::class => Illuminate\Contracts\Support\CanBeEscapedWhenCastToString::class,
QL\Collect\Support\Arr::class => Illuminate\Support\Arr::class,
QL\Collect\Support\Collection::class => Illuminate\Support\Collection::class,
QL\Collect\Support\Enumerable::class => Illuminate\Support\Enumerable::class,
QL\Collect\Support\HigherOrderCollectionProxy::class => Illuminate\Support\HigherOrderCollectionProxy::class,
QL\Collect\Support\LazyCollection::class => Illuminate\Support\LazyCollection::class,
QL\Collect\Support\Traits\EnumeratesValues::class => Illuminate\Support\Traits\EnumeratesValues::class,
];
# echo "\n\n-- Aliasing....\n---------------------------------------------\n\n";
foreach ($aliases as $tighten => $illuminate) {
if (! class_exists($illuminate) && ! interface_exists($illuminate) && ! trait_exists($illuminate)) {
# echo "Aliasing {$tighten} to {$illuminate}.\n";
class_alias($tighten, $illuminate);
}
}

View File

@ -1,8 +1,8 @@
<?php <?php
use Tightenco\Collect\Support\Arr; use QL\Collect\Support\Arr;
use Tightenco\Collect\Support\Collection; use QL\Collect\Support\Collection;
use Tightenco\Collect\Support\HigherOrderTapProxy; use QL\Collect\Support\HigherOrderTapProxy;
use Symfony\Component\VarDumper\VarDumper; use Symfony\Component\VarDumper\VarDumper;
if (! class_exists(Illuminate\Support\Collection::class)) { if (! class_exists(Illuminate\Support\Collection::class)) {
@ -11,7 +11,7 @@ if (! class_exists(Illuminate\Support\Collection::class)) {
* Create a collection from the given value. * Create a collection from the given value.
* *
* @param mixed $value * @param mixed $value
* @return \Tightenco\Collect\Support\Collection * @return \QL\Collect\Support\Collection
*/ */
function collect($value = null) function collect($value = null)
{ {

View File

@ -7,7 +7,7 @@
namespace QL; namespace QL;
use Closure; use Closure;
use Tightenco\Collect\Support\Collection; use QL\Collect\Support\Collection;
class Config class Config
{ {

View File

@ -9,7 +9,7 @@ namespace QL\Dom;
use phpDocumentor\Reflection\Types\Null_; use phpDocumentor\Reflection\Types\Null_;
use phpQueryObject; use phpQueryObject;
use Tightenco\Collect\Support\Collection; use QL\Collect\Support\Collection;
/** /**
* Class Elements * Class Elements
@ -188,7 +188,7 @@ class Elements
* Iterating elements * Iterating elements
* *
* @param $callback * @param $callback
* @return \Illuminate\Support\Collection|\Tightenco\Collect\Support\Collection * @return \Illuminate\Support\Collection|\QL\Collect\Support\Collection
*/ */
public function map($callback) public function map($callback)
{ {
@ -203,7 +203,7 @@ class Elements
* Gets the attributes of all the elements * Gets the attributes of all the elements
* *
* @param string $attr HTML attribute name * @param string $attr HTML attribute name
* @return \Illuminate\Support\Collection|\Tightenco\Collect\Support\Collection * @return \Illuminate\Support\Collection|\QL\Collect\Support\Collection
*/ */
public function attrs($attr) public function attrs($attr)
{ {
@ -215,7 +215,7 @@ class Elements
/** /**
* Gets the text of all the elements * Gets the text of all the elements
* *
* @return \Illuminate\Support\Collection|\Tightenco\Collect\Support\Collection * @return \Illuminate\Support\Collection|\QL\Collect\Support\Collection
*/ */
public function texts() public function texts()
{ {
@ -227,7 +227,7 @@ class Elements
/** /**
* Gets the html of all the elements * Gets the html of all the elements
* *
* @return \Illuminate\Support\Collection|\Tightenco\Collect\Support\Collection * @return \Illuminate\Support\Collection|\QL\Collect\Support\Collection
*/ */
public function htmls() public function htmls()
{ {
@ -239,7 +239,7 @@ class Elements
/** /**
* Gets the htmlOuter of all the elements * Gets the htmlOuter of all the elements
* *
* @return \Illuminate\Support\Collection|\Tightenco\Collect\Support\Collection * @return \Illuminate\Support\Collection|\QL\Collect\Support\Collection
*/ */
public function htmlOuters() public function htmlOuters()
{ {

View File

@ -7,7 +7,7 @@
namespace QL\Dom; namespace QL\Dom;
use Tightenco\Collect\Support\Collection; use QL\Collect\Support\Collection;
use phpQuery; use phpQuery;
use phpQueryObject; use phpQueryObject;
use QL\QueryList; use QL\QueryList;
@ -125,8 +125,8 @@ class Query
*/ */
public function removeHead() public function removeHead()
{ {
$html = preg_replace('/(<head>|<head\s+.+?>).+<\/head>/is', '<head></head>', $this->html); $html = preg_replace('/(<head>|<head\s+.+?>).+?<\/head>/is', '<head></head>', $this->html);
$this->setHtml($html); $html && $this->setHtml($html);
return $this->ql; return $this->ql;
} }

View File

@ -14,7 +14,7 @@ use Closure;
use QL\Providers\HttpServiceProvider; use QL\Providers\HttpServiceProvider;
use QL\Providers\PluginServiceProvider; use QL\Providers\PluginServiceProvider;
use QL\Providers\SystemServiceProvider; use QL\Providers\SystemServiceProvider;
use Tightenco\Collect\Support\Collection; use QL\Collect\Support\Collection;
class Kernel class Kernel
{ {

View File

@ -14,7 +14,7 @@
namespace QL; namespace QL;
use phpQuery; use phpQuery;
use QL\Dom\Query; use QL\Dom\Query;
use Tightenco\Collect\Support\Collection; use QL\Collect\Support\Collection;
use Closure; use Closure;
use QL\Services\MultiRequestService; use QL\Services\MultiRequestService;

View File

@ -13,7 +13,6 @@ use Jaeger\GHttp;
use Closure; use Closure;
use GuzzleHttp\Psr7\Response; use GuzzleHttp\Psr7\Response;
use QL\QueryList; use QL\QueryList;
use GuzzleHttp\Exception\RequestException;
/** /**
* Class MultiRequestService * Class MultiRequestService
@ -53,7 +52,7 @@ class MultiRequestService
public function error(Closure $error) public function error(Closure $error)
{ {
$this->multiRequest = $this->multiRequest->error(function(RequestException $reason, $index) use($error){ $this->multiRequest = $this->multiRequest->error(function($reason, $index) use($error){
$error($this->ql,$reason, $index); $error($this->ql,$reason, $index);
}); });
return $this; return $this;

View File

@ -1,71 +0,0 @@
<?php
/**
* Created by PhpStorm.
* User: x
* Date: 2018/12/10
* Time: 12:46 AM
*/
namespace Tests\Dom;
use QL\QueryList;
use Tests\TestCaseBase;
class FindTest extends TestCaseBase
{
protected $html;
protected $ql;
protected function setUp(): void
{
$this->html = $this->getSnippet('snippet-1');
$this->ql = QueryList::html($this->html);
}
/**
* @test
*/
public function find_first_dom_attr()
{
$img = [];
$img[] = $this->ql->find('img')->attr('src');
$img[] = $this->ql->find('img')->src;
$img[] = $this->ql->find('img:eq(0)')->src;
$img[] = $this->ql->find('img')->eq(0)->src;
$alt = $this->ql->find('img')->alt;
$abc = $this->ql->find('img')->abc;
$this->assertCount(1,array_unique($img));
$this->assertEquals($alt,'这是图片');
$this->assertEquals($abc,'这是一个自定义属性');
}
/**
* @test
*/
public function find_second_dom_attr()
{
$img2 = [];
$img2[] = $this->ql->find('img')->eq(1)->alt;
$img2[] = $this->ql->find('img:eq(1)')->alt;
$img2[] = $this->ql->find('.second_pic')->alt;
$this->assertCount(1,array_unique($img2));
}
/**
* @test
*/
public function find_dom_all_attr()
{
$imgAttr = $this->ql->find('img:eq(0)')->attr('*');
$linkAttr = $this->ql->find('a:eq(1)')->attr('*');
$this->assertCount(3,$imgAttr);
$this->assertCount(1,$linkAttr);
}
}

View File

@ -1,43 +0,0 @@
<?php
/**
* Created by PhpStorm.
* User: Jaeger <JaegerCode@gmail.com>
* Date: 18/12/12
* Time: 下午12:25
*/
namespace Tests\Dom;
use QL\QueryList;
use Tests\TestCaseBase;
use Tightenco\Collect\Support\Collection;
class RulesTest extends TestCaseBase
{
protected $html;
protected $ql;
protected function setUp(): void
{
$this->html = $this->getSnippet('snippet-2');
$this->ql = QueryList::html($this->html);
}
/**
* @test
*/
public function get_data_by_rules()
{
$rules = [
'a' => ['a','text'],
'img_src' => ['img','src'],
'img_alt' => ['img','alt']
];
$range = 'ul>li';
$data = QueryList::rules($rules)->range($range)->html($this->html)->query()->getData();
$this->assertInstanceOf(Collection::class,$data);
$this->assertCount(3,$data);
$this->assertEquals('http://querylist.com/2.jpg',$data[1]['img_src']);
}
}

View File

@ -1,103 +0,0 @@
<?php
/**
* Created by PhpStorm.
* User: x
* Date: 2018/12/10
* Time: 12:35 AM
*/
namespace Tests\Feature;
use GuzzleHttp\Handler\MockHandler;
use GuzzleHttp\Psr7\Response;
use QL\QueryList;
use Tests\TestCaseBase;
class HttpTest extends TestCaseBase
{
protected $urls;
protected function setUp(): void
{
$this->urls = [
'http://httpbin.org/get?name=php',
'http://httpbin.org/get?name=golang',
'http://httpbin.org/get?name=c++',
'http://httpbin.org/get?name=java'
];
}
/**
* @test
*/
public function can_post_json_data()
{
$mock = new MockHandler([new Response()]);
$data = [
'name' => 'foo'
];
QueryList::postJson('http://foo.com',$data,[
'handler' => $mock
]);
$this->assertEquals((string)$mock->getLastRequest()->getBody(),json_encode($data));
}
/**
* @test
*/
public function concurrent_requests_base_use()
{
$urls = $this->urls;
QueryList::getInstance()
->multiGet($urls)
->success(function(QueryList $ql,Response $response, $index) use($urls){
$body = json_decode((string)$response->getBody(),true);
$this->assertEquals($urls[$index],$body['url']);
})->send();
}
/**
* @test
*/
public function concurrent_requests_advanced_use()
{
$ua = 'QueryList/4.0';
$errorUrl = 'http://web-site-not-exist.com';
$urls = array_merge($this->urls,[$errorUrl]);
QueryList::rules([])
->multiGet($urls)
->concurrency(2)
->withOptions([
'timeout' => 60
])
->withHeaders([
'User-Agent' => $ua
])
->success(function (QueryList $ql, Response $response, $index) use($ua){
$body = json_decode((string)$response->getBody(),true);
$this->assertEquals($ua,$body['headers']['User-Agent']);
})
->error(function (QueryList $ql, $reason, $index) use($urls,$errorUrl){
$this->assertEquals($urls[$index],$errorUrl);
})
->send();
}
/**
* @test
*/
public function request_with_cache()
{
$url = $this->urls[0];
$data = QueryList::get($url,null,[
'cache' => sys_get_temp_dir(),
'cache_ttl' => 600
])->getHtml();
$data = json_decode($data,true);
$this->assertEquals($url,$data['url']);
}
}

View File

@ -1,48 +0,0 @@
<?php
/**
* Created by PhpStorm.
* User: x
* Date: 2018/12/9
* Time: 11:10 PM
*/
namespace Tests\Feature;
use QL\QueryList;
use Tests\TestCaseBase;
class InstanceTest extends TestCaseBase
{
protected $html;
protected function setUp(): void
{
$this->html = $this->getSnippet('snippet-1');
}
/**
* @test
*/
public function singleton_instance_mode()
{
$ql = QueryList::getInstance()->html($this->html);
$ql2 = QueryList::getInstance();
$this->assertEquals($ql->getHtml(),$ql2->getHtml());
}
/**
* @test
*/
public function get_new_object()
{
$ql = (new QueryList())->html($this->html);
$ql2 = (new QueryList())->html('');
$this->assertNotEquals($ql->getHtml(),$ql2->getHtml());
$ql = QueryList::range('')->html($this->html);
$ql2 = QueryList::range('')->html('');
$this->assertNotEquals($ql->getHtml(),$ql2->getHtml());
}
}

View File

@ -1,36 +0,0 @@
<?php
/**
* Created by PhpStorm.
* User: x
* Date: 2018/12/10
* Time: 1:14 AM
*/
namespace Tests\Feature;
use QL\QueryList;
use Tests\TestCaseBase;
class MethodTest extends TestCaseBase
{
protected $html;
protected function setUp(): void
{
$this->html = $this->getSnippet('snippet-1');
}
/**
* @test
*/
public function pipe()
{
$html = $this->html;
$qlHtml = QueryList::pipe(function(QueryList $ql) use($html){
$ql->setHtml($html);
return $ql;
})->getHtml(false);
$this->assertEquals($html,$qlHtml);
}
}

View File

@ -1,20 +0,0 @@
<?php
/**
* Created by PhpStorm.
* User: x
* Date: 2018/12/9
* Time: 11:43 PM
*/
namespace Tests;
use PHPUnit\Framework\TestCase;
class TestCaseBase extends TestCase
{
public function getSnippet($name)
{
return file_get_contents(__DIR__.'/assets/'.$name.'.html');
}
}

View File

@ -1,9 +0,0 @@
<div id="one">
<div class="two">
<a href="http://querylist.cc">QueryList官网</a>
<img src="http://querylist.com/1.jpg" alt="这是图片" abc="这是一个自定义属性">
<img class="second_pic" src="http://querylist.com/2.jpg" alt="这是图片2">
<a href="http://doc.querylist.cc">QueryList文档</a>
</div>
<span>其它的<b>一些</b>文本</span>
</div>

View File

@ -1,16 +0,0 @@
<div id="one">
<ul>
<li>
<a href="http://querylist.cc">QueryList官网</a>
<img src="http://querylist.com/1.jpg" alt="这是图片1" abc="这是一个自定义属性1">
</li>
<li>
<a href="http://v3.querylist.cc">QueryList V3文档</a>
<img src="http://querylist.com/2.jpg" alt="这是图片2" abc="这是一个自定义属性2">
</li>
<li>
<a href="http://v4.querylist.cc">QueryList V4文档</a>
<img src="http://querylist.com/3.jpg" alt="这是图片3" abc="这是一个自定义属性3">
</li>
</ul>
</div>

View File

@ -1,5 +0,0 @@
<?php
set_time_limit(0);
require __DIR__.'/../vendor/autoload.php';

2
vendor/services.php vendored
View File

@ -1,5 +1,5 @@
<?php <?php
// This file is automatically generated at:2024-04-01 10:28:47 // This file is automatically generated at:2024-04-13 11:41:14
declare (strict_types = 1); declare (strict_types = 1);
return array ( return array (
0 => 'taoser\\addons\\Service', 0 => 'taoser\\addons\\Service',

View File

@ -1,41 +0,0 @@
name: Run tests
on:
push:
branches: [laravel-9-ongoing, laravel-8-ongoing]
pull_request:
jobs:
tests:
strategy:
matrix:
os: [Ubuntu, macOS]
php: [7.3, 7.4, 8.0, 8.1]
include:
- os: Ubuntu
os-version: ubuntu-latest
- os: macOS
os-version: macos-latest
name: ${{ matrix.os }} - PHP ${{ matrix.php }}
runs-on: ${{ matrix.os-version }}
steps:
- name: Checkout code
uses: actions/checkout@v1
- name: Setup PHP
uses: shivammathur/setup-php@v2
with:
php-version: ${{ matrix.php }}
extensions: posix, dom, curl, libxml, mbstring, zip, pcntl, pdo, sqlite, pdo_sqlite, bcmath, soap, intl, gd, exif, iconv, imagick
coverage: none
- name: Install dependencies
run: composer update --prefer-stable --prefer-dist --no-interaction
- name: Run tests
run: bash upgrade.sh

View File

@ -1,67 +0,0 @@
#!/bin/bash
GREEN='\033[0;32m'
RED='\033[0;31m'
WHITE='\033[0;37m'
RESET='\033[0m'
function validateVersion()
{
echo ""
passedVersion=$1
echo -e "${WHITE}-- Validating tag '$passedVersion'...${RESET}"
# Todo: validate the version here using a regex; if fail, just exit
# ... expect 8.75.0, with no v in front of it
if [[ $passedVersion == '' ]]; then
echo -e "\n-- Invalid tag. Tags should be structured without v; e.g. 8.57.0"
exit
fi
echo -e "${WHITE}-- Tag valid.${RESET}"
echo ""
}
# Exit script if any command fails (e.g. phpunit)
set -e
# Require confirmation it's set up corrctly
echo
echo -e "${WHITE}-- This script is meant to be run after running upgrade.sh, BEFORE committing to Git.${RESET}"
while true; do
echo -e "${GREEN}-- Is that the current state of your local project?${RESET}"
read -p "-- (y/n) " yn
case $yn in
[Yy]* ) break;;
[Nn]* ) exit;;
* ) echo "Please answer y or n.";;
esac
done
# Get the version and exit if not valid
validateVersion $1
# Create official v prefaced version
version="v$1"
# Run tests (and bail if they fail)
phpunit
echo -e "\n${WHITE}-- Tests succeeded.${RESET}"
# Branch
echo -e "\n${WHITE}-- Creating a Git branch '$version-changes'...${RESET}\n"
git checkout -b $version-changes
# Add and commit, with "v8.57.0 changes" as the commit name
git add -A
git commit -m "$version changes"
echo
echo -e "${WHITE}-- Git committed.${RESET}"
# Push
git push -u origin $version-changes

View File

@ -1,51 +0,0 @@
{
"name": "tightenco/collect",
"description": "Collect - Illuminate Collections as a separate package.",
"keywords": ["laravel", "collection"],
"license": "MIT",
"authors": [
{
"name": "Taylor Otwell",
"email": "taylorotwell@gmail.com"
}
],
"require": {
"php": "^7.3|^8.0",
"symfony/var-dumper": "^3.4 || ^4.0 || ^5.0 || ^6.0"
},
"require-dev": {
"mockery/mockery": "^1.0",
"phpunit/phpunit": "^8.3",
"nesbot/carbon": "^2.23.0"
},
"autoload": {
"files": [
"src/Collect/Support/helpers.php",
"src/Collect/Support/alias.php"
],
"psr-4": {
"Tightenco\\Collect\\": "src/Collect"
}
},
"autoload-dev": {
"files": [
"tests/files/Support/Carbon.php",
"tests/files/Support/HtmlString.php",
"tests/files/Support/HigherOrderTapProxy.php",
"tests/files/Support/Str.php",
"tests/files/Support/Traits/Conditionable.php",
"tests/files/Support/Stringable.php",
"tests/files/Support/ItemNotFoundException.php",
"tests/files/Support/MultipleItemsFoundException.php",
"tests/Support/Concerns/CountsEnumerations.php"
]
},
"scripts": {
"test": [
"@composer install",
"phpunit"
]
},
"minimum-stability": "dev",
"prefer-stable": true
}

View File

@ -1,13 +0,0 @@
<?php
namespace Tightenco\Collect\Contracts\Support;
interface Arrayable
{
/**
* Get the instance as an array.
*
* @return array
*/
public function toArray();
}

View File

@ -1,63 +0,0 @@
<?php
namespace Tightenco\Collect\Support;
/**
* @mixin \Tightenco\Collect\Support\Enumerable
*/
class HigherOrderWhenProxy
{
/**
* The collection being operated on.
*
* @var \Tightenco\Collect\Support\Enumerable
*/
protected $collection;
/**
* The condition for proxying.
*
* @var bool
*/
protected $condition;
/**
* Create a new proxy instance.
*
* @param \Tightenco\Collect\Support\Enumerable $collection
* @param bool $condition
* @return void
*/
public function __construct(Enumerable $collection, $condition)
{
$this->condition = $condition;
$this->collection = $collection;
}
/**
* Proxy accessing an attribute onto the collection.
*
* @param string $key
* @return mixed
*/
public function __get($key)
{
return $this->condition
? $this->collection->{$key}
: $this->collection;
}
/**
* Proxy a method call onto the collection.
*
* @param string $method
* @param array $parameters
* @return mixed
*/
public function __call($method, $parameters)
{
return $this->condition
? $this->collection->{$method}(...$parameters)
: $this->collection;
}
}

View File

@ -1,24 +0,0 @@
<?php
$aliases = [
Tightenco\Collect\Contracts\Support\Arrayable::class => Illuminate\Contracts\Support\Arrayable::class,
Tightenco\Collect\Contracts\Support\Jsonable::class => Illuminate\Contracts\Support\Jsonable::class,
Tightenco\Collect\Contracts\Support\Htmlable::class => Illuminate\Contracts\Support\Htmlable::class,
Tightenco\Collect\Contracts\Support\CanBeEscapedWhenCastToString::class => Illuminate\Contracts\Support\CanBeEscapedWhenCastToString::class,
Tightenco\Collect\Support\Arr::class => Illuminate\Support\Arr::class,
Tightenco\Collect\Support\Collection::class => Illuminate\Support\Collection::class,
Tightenco\Collect\Support\Enumerable::class => Illuminate\Support\Enumerable::class,
Tightenco\Collect\Support\HigherOrderCollectionProxy::class => Illuminate\Support\HigherOrderCollectionProxy::class,
Tightenco\Collect\Support\HigherOrderWhenProxy::class => Illuminate\Support\HigherOrderWhenProxy::class,
Tightenco\Collect\Support\LazyCollection::class => Illuminate\Support\LazyCollection::class,
Tightenco\Collect\Support\Traits\EnumeratesValues::class => Illuminate\Support\Traits\EnumeratesValues::class,
];
# echo "\n\n-- Aliasing....\n---------------------------------------------\n\n";
foreach ($aliases as $tighten => $illuminate) {
if (! class_exists($illuminate) && ! interface_exists($illuminate) && ! trait_exists($illuminate)) {
# echo "Aliasing {$tighten} to {$illuminate}.\n";
class_alias($tighten, $illuminate);
}
}

View File

@ -18,7 +18,7 @@
<div class="layui-row layui-col-space15"> <div class="layui-row layui-col-space15">
<div class="layui-col-md8"> <div class="layui-col-md8">
<div class="fly-panel" style="margin-bottom: 0;"> <div class="fly-panel" style="margin-bottom: 0;">
<div class="layui-tab layui-tab-card"> <div class="layui-tab layui-tab-card" style="margin-top: 0px;">
<ul class="layui-tab-title"> <ul class="layui-tab-title">
<li {if condition="$type eq 'all'" } class="layui-this" {/if}><a href="{$Request.domain}{:url('cate_type',['ename' => $Request.param.ename,'type' => 'all'])} " >{:lang('all')}</a></li> <li {if condition="$type eq 'all'" } class="layui-this" {/if}><a href="{$Request.domain}{:url('cate_type',['ename' => $Request.param.ename,'type' => 'all'])} " >{:lang('all')}</a></li>
<li {if condition="$type eq 'jie'" } class="layui-this" {/if}><a href="{$Request.domain}{:url('cate_type',['ename' => $Request.param.ename,'type' => 'jie'])} ">{:lang('end')}</a></li> <li {if condition="$type eq 'jie'" } class="layui-this" {/if}><a href="{$Request.domain}{:url('cate_type',['ename' => $Request.param.ename,'type' => 'jie'])} ">{:lang('end')}</a></li>

View File

@ -229,7 +229,6 @@
<div class="user-img"> <div class="user-img">
<a href="{$Request.domain}{:url('user/home',['id'=>$article.user.id])}"> <a href="{$Request.domain}{:url('user/home',['id'=>$article.user.id])}">
<img class="" src="{$Request.domain}{$article.user.user_img}" alt="{$article.user.name}" /> <img class="" src="{$Request.domain}{$article.user.user_img}" alt="{$article.user.name}" />
{if($article.user.vip > 0)}<i class="iconfont icon-renzheng" title="认证信息"></i>{/if}
</a> </a>
</div> </div>
<div class="questions"> <div class="questions">

View File

@ -24,7 +24,7 @@
<img src="{$Request.domain}{$art.user.user_img}" alt="{$art.user.name}"> <img src="{$Request.domain}{$art.user.user_img}" alt="{$art.user.name}">
</a> </a>
<h2> <h2>
<a href="{$Request.domain}/{$art.url}" style="color:{$art.title_color ?? '#333'};">{$art.title}</a> <a href="{$Request.domain}{$art.url}" style="color:{$art.title_color ?? '#333'};">{$art.title}</a>
</h2> </h2>
<div class="fly-list-info"> <div class="fly-list-info">

View File

@ -245,7 +245,6 @@
<div class="user-img"> <div class="user-img">
<a href="{$Request.domain}{:url('user/home',['id'=>$article.user.id])}"> <a href="{$Request.domain}{:url('user/home',['id'=>$article.user.id])}">
<img class="" src="{$Request.domain}{$article.user.user_img}" alt="{$article.user.name}" /> <img class="" src="{$Request.domain}{$article.user.user_img}" alt="{$article.user.name}" />
{if($article.user.vip > 0)}<i class="iconfont icon-renzheng" title="认证信息"></i>{/if}
</a> </a>
</div> </div>
<div class="questions"> <div class="questions">

View File

@ -25,7 +25,9 @@
<div class="fly-panel"> <div class="fly-panel">
<div class="fly-panel-title fly-filter"> <div class="fly-panel-title fly-filter">
<span>{:lang('top')}</span> <span>{:lang('top')}</span>
{if hook('signstatushook') == 1}
<a href="#signin" class="layui-hide-sm layui-show-xs-block fly-right" id="LAY_goSignin">{:lang('go sign')}</a> <a href="#signin" class="layui-hide-sm layui-show-xs-block fly-right" id="LAY_goSignin">{:lang('go sign')}</a>
{/if}
</div> </div>
<ul class="fly-list"> <ul class="fly-list">
{if config('taoler.config.top_show') == 1} {if config('taoler.config.top_show') == 1}

View File

@ -14,11 +14,13 @@
Hi<span style="color: red">{:session('user_name')}</span>,你已是我们的正式社员。 Hi<span style="color: red">{:session('user_name')}</span>,你已是我们的正式社员。
</div> </div>
<div class="layui-row layui-col-space20"> <div class="layui-row layui-col-space20">
{if hook('signstatushook') == 1}
<div class="layui-col-md6"> <div class="layui-col-md6">
<div class="fly-panel fly-signin"> <div class="fly-panel fly-signin">
{:hook('signhook', ['id'=>1])} {:hook('signhook', ['id'=>1])}
</div> </div>
</div> </div>
{/if}
<div class="layui-col-md6"> <div class="layui-col-md6">
<div class="fly-panel fly-panel-border"> <div class="fly-panel-title"> 我的会员信息 </div> <div class="fly-panel fly-panel-border"> <div class="fly-panel-title"> 我的会员信息 </div>
<div class="fly-panel-main layui-text" style="padding: 18px 15px; height: 50px; line-height: 26px;"> <div class="fly-panel-main layui-text" style="padding: 18px 15px; height: 50px; line-height: 26px;">