From 4ae7a3ea51be50bc1d9f067d1ac1746791b463b7 Mon Sep 17 00:00:00 2001 From: taoser Date: Sun, 20 Nov 2022 21:56:09 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BC=98=E5=8C=96=E6=8F=92=E4=BB=B6=E9=A1=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/admin/controller/Addons.php | 100 +- app/admin/controller/Set.php | 76 +- app/admin/view/addons/config.html | 120 +- app/admin/view/addons/index.html | 24 +- app/admin/view/public/side_menu.html | 5 +- app/admin/view/set/system/server.html | 73 -- app/admin/view/set/system/website.html | 1055 +++++++-------- app/common.php | 29 +- app/index/controller/Article.php | 4 +- app/index/controller/Login.php | 6 +- app/index/controller/User.php | 2 +- composer.json | 5 +- composer.lock | 150 ++- extend/taoler/com/Api.php | 5 + extend/taoler/com/FormHelper.php | 18 + extend/taoler/com/FormHlp.php | 1128 +++++++++++++++++ public/static/admin/modules/webset.js | 114 -- vendor/composer/autoload_files.php | 2 +- vendor/composer/autoload_psr4.php | 1 + vendor/composer/autoload_static.php | 7 +- vendor/composer/installed.json | 171 ++- vendor/composer/installed.php | 49 +- vendor/endroid/qr-code/README.md | 20 +- .../endroid/qr-code/src/Builder/Builder.php | 3 +- vendor/endroid/qr-code/src/Color/Color.php | 5 + .../qr-code/src/Color/ColorInterface.php | 2 + .../src/Exception/ValidationException.php | 28 + .../qr-code/src/Writer/DebugWriter.php | 6 +- .../endroid/qr-code/src/Writer/EpsWriter.php | 2 +- .../endroid/qr-code/src/Writer/PdfWriter.php | 2 +- .../endroid/qr-code/src/Writer/PngWriter.php | 14 +- .../src/Writer/Result/AbstractResult.php | 14 + .../src/Writer/Result/BinaryResult.php | 12 +- .../src/Writer/Result/ConsoleResult.php | 52 +- .../qr-code/src/Writer/Result/DebugResult.php | 12 +- .../qr-code/src/Writer/Result/EpsResult.php | 6 +- .../qr-code/src/Writer/Result/PdfResult.php | 6 +- .../qr-code/src/Writer/Result/PngResult.php | 6 +- .../src/Writer/Result/ResultInterface.php | 4 + .../qr-code/src/Writer/Result/SvgResult.php | 11 +- .../endroid/qr-code/src/Writer/SvgWriter.php | 2 +- vendor/league/flysystem/src/Adapter/Ftp.php | 4 +- vendor/services.php | 2 +- vendor/symfony/var-exporter/CHANGELOG.md | 12 + .../Exception/ClassNotFoundException.php | 20 + .../Exception/ExceptionInterface.php | 16 + .../NotInstantiableTypeException.php | 20 + vendor/symfony/var-exporter/Instantiator.php | 92 ++ .../var-exporter/Internal/Exporter.php | 406 ++++++ .../var-exporter/Internal/Hydrator.php | 152 +++ .../var-exporter/Internal/Reference.php | 30 + .../var-exporter/Internal/Registry.php | 146 +++ .../symfony/var-exporter/Internal/Values.php | 27 + vendor/symfony/var-exporter/LICENSE | 19 + vendor/symfony/var-exporter/README.md | 38 + vendor/symfony/var-exporter/VarExporter.php | 115 ++ vendor/symfony/var-exporter/composer.json | 32 + vendor/taoser/think-addons/.idea/.gitignore | 8 + vendor/taoser/think-addons/.idea/modules.xml | 8 + vendor/taoser/think-addons/.idea/php.xml | 4 + .../think-addons/.idea/think-addons.iml | 12 + vendor/taoser/think-addons/.idea/vcs.xml | 6 + vendor/taoser/think-addons/README.md | 4 +- vendor/taoser/think-addons/composer.json | 3 +- .../think-addons/src/addons/Controller.php | 1 + .../think-addons/src/addons/Service.php | 19 +- vendor/taoser/think-addons/src/helper.php | 196 +-- vendor/workerman/workerman/Protocols/Http.php | 49 +- .../workerman/Protocols/Http/Request.php | 3 + vendor/workerman/workerman/Worker.php | 28 +- view/taoler/index/article/ask/detail.html | 2 +- view/taoler/index/article/blog/detail.html | 2 +- view/taoler/index/article/posts/detail.html | 6 +- view/taoler/index/user/home.html | 2 +- 74 files changed, 3573 insertions(+), 1262 deletions(-) create mode 100644 extend/taoler/com/FormHelper.php create mode 100644 extend/taoler/com/FormHlp.php create mode 100644 vendor/endroid/qr-code/src/Exception/ValidationException.php create mode 100644 vendor/symfony/var-exporter/CHANGELOG.md create mode 100644 vendor/symfony/var-exporter/Exception/ClassNotFoundException.php create mode 100644 vendor/symfony/var-exporter/Exception/ExceptionInterface.php create mode 100644 vendor/symfony/var-exporter/Exception/NotInstantiableTypeException.php create mode 100644 vendor/symfony/var-exporter/Instantiator.php create mode 100644 vendor/symfony/var-exporter/Internal/Exporter.php create mode 100644 vendor/symfony/var-exporter/Internal/Hydrator.php create mode 100644 vendor/symfony/var-exporter/Internal/Reference.php create mode 100644 vendor/symfony/var-exporter/Internal/Registry.php create mode 100644 vendor/symfony/var-exporter/Internal/Values.php create mode 100644 vendor/symfony/var-exporter/LICENSE create mode 100644 vendor/symfony/var-exporter/README.md create mode 100644 vendor/symfony/var-exporter/VarExporter.php create mode 100644 vendor/symfony/var-exporter/composer.json create mode 100644 vendor/taoser/think-addons/.idea/.gitignore create mode 100644 vendor/taoser/think-addons/.idea/modules.xml create mode 100644 vendor/taoser/think-addons/.idea/php.xml create mode 100644 vendor/taoser/think-addons/.idea/think-addons.iml create mode 100644 vendor/taoser/think-addons/.idea/vcs.xml diff --git a/app/admin/controller/Addons.php b/app/admin/controller/Addons.php index 6e0c952..e6a1e35 100644 --- a/app/admin/controller/Addons.php +++ b/app/admin/controller/Addons.php @@ -12,6 +12,7 @@ use taoler\com\Api; use app\common\lib\Zip; use think\response\Json; use app\admin\model\AuthRule; +use Symfony\Component\VarExporter\VarExporter; class Addons extends AdminController { @@ -27,7 +28,7 @@ class Addons extends AdminController * 插件列表 * @return Json */ - public function addonsList() :Json + public function addonsList() { $type = input('type'); @@ -177,13 +178,13 @@ class Addons extends AdminController } //是否安装? $addInstalledVersion = get_addons_info($data['name']); -// if(!empty($addInstalledVersion)){ -// $verRes = version_compare($data['version'],$addInstalledVersion['version'],'>'); -// if(!$verRes){ -// return json(['code'=>-1,'msg'=>'不能降级,请选择正确版本']); -// } -// //$tpl_ver_res = version_compare($addInstalledVersion['template_version'], config('taoler.template_version'),'<'); -// } + if(!empty($addInstalledVersion)){ + $verRes = version_compare($data['version'],$addInstalledVersion['version'],'>'); + if(!$verRes){ + return json(['code'=>-1,'msg'=>'不能降级,请选择正确版本']); + } + //$tpl_ver_res = version_compare($addInstalledVersion['template_version'], config('taoler.template_version'),'<'); + } $file_url = $addons->addons_src; //判断远程文件是否可用存在 @@ -239,25 +240,18 @@ class Addons extends AdminController SqlFile::dbExecute($sqlInstallFile); } //安装菜单 - $menuFile = root_path().'addons/'.$data['name'].'/menu.php'; - if(file_exists($menuFile)) { - include_once $menuFile; - $menu = Config::get('menu'); - - if(!empty($menu)){ - if(isset($menu['is_nav']) && $menu['is_nav']==1){ - $pid = 0; - }else{ - $pid = AuthRule::where('name','addons')->value('id'); - } - $menu_arr[] = $menu['menu']; - $this->addAddonMenu($menu_arr, (int)$pid,1); + $menu = get_addons_menu($data['name']); + if(!empty($menu)){ + if(isset($menu['is_nav']) && $menu['is_nav']==1){ + $pid = 0; + }else{ + $pid = AuthRule::where('name','addons')->value('id'); } + $menu_arr[] = $menu['menu']; + $this->addAddonMenu($menu_arr, (int)$pid,1); } - - - Files::delDirAndFile('../runtime/addons/'); + Files::delDirAndFile('../runtime/addons/'.$data['name'] . DS); return json(['code'=>0,'msg'=>'插件安装成功!']); @@ -265,21 +259,16 @@ class Addons extends AdminController /** * 卸载插件 */ - public function delete() + public function uninstall() { $name = input('name'); - $addonsPath = '../addons/'.$name; - $staticPath = 'addons/'.$name; //卸载菜单 - $menuFile = root_path().'addons/'.$name.'/menu.php'; - if(file_exists($menuFile)) { - include_once $menuFile; - $menu = Config::get('menu'); - if(!empty($menu)){ - $menu_arr[] = $menu['menu']; - $this->delAddonMenu($menu_arr); - } + $menu = get_addons_menu($name); + if(!empty($menu)){ + $menu_arr[] = $menu['menu']; +// halt( $menu_arr); + $this->delAddonMenu($menu_arr); } //卸载插件数据库 @@ -288,16 +277,30 @@ class Addons extends AdminController SqlFile::dbExecute($sqlUninstallFile); } - if (is_dir($staticPath)) { - Files::delDir($staticPath); + + // 插件addons下目录 + $addonsDir = root_path() . 'addons' . DS . $name . DS; + // 插件管理后台目录 + $admin_controller = app_path() . 'controller' . DS . $name . DS; + $admin_model = app_path() . 'model' . DS . $name . DS; + $admin_view = app_path() . 'view' . DS . $name . DS; + $admin_validate = app_path() . 'validate' . DS . $name . DS; + // 插件静态资源目录 + $addon_public = public_path() . 'addons' . DS . $name . DS; + + try { + if(file_exists($addonsDir)) Files::delDir($addonsDir); + if(file_exists($admin_controller)) Files::delDir($admin_controller); + if(file_exists($admin_model)) Files::delDir($admin_model); + if(file_exists($admin_view)) Files::delDir($admin_view); + if(file_exists($admin_validate)) Files::delDir($admin_validate); + if(file_exists($addon_public)) Files::delDir($addon_public); + + } catch (\Exception $e) { + return json(['code' => -1, 'msg' => $e->getMessage()]); } - $res = Files::delDir($addonsPath); - if($res){ - return json(['code'=>0,'msg'=>'卸载成功']); - } else { - return json(['code'=>-1,'msg'=>'卸载失败']); - } - return json(['code'=>0,'msg'=>'卸载成功']); + + return json(['code' => 0, 'msg' => '插件卸载成功']); } //启用插件 @@ -329,7 +332,7 @@ class Addons extends AdminController $config = get_addons_config($name); if(empty($config)) return json(['code'=>-1,'msg'=>'无配置项!']); if(Request::isAjax()){ - $params = Request::param('params/a'); + $params = Request::param('params/a',[],'trim'); if ($params) { foreach ($config as $k => &$v) { if (isset($params[$k])) { @@ -359,7 +362,10 @@ class Addons extends AdminController //模板引擎初始化 $view = ['formData'=>$config,'title'=>'title']; View::assign($view); - return View::fetch(); + $configFile = root_path() . 'addons' . DS . $name . DS . 'config.html'; + $viewFile = is_file($configFile) ? $configFile : ''; + + return View::fetch($viewFile); } @@ -396,7 +402,7 @@ class Addons extends AdminController try { $v['name'] = trim($v['name'],'/'); $menu_rule = AuthRule::withTrashed()->where('name',$v['name'])->find(); - if($menu_rule){ + if(!is_null($menu_rule)){ $menu_rule->delete(true); if ($hasChild) { $this->delAddonMenu($v['sublist']); diff --git a/app/admin/controller/Set.php b/app/admin/controller/Set.php index fad8966..ac8afc6 100644 --- a/app/admin/controller/Set.php +++ b/app/admin/controller/Set.php @@ -23,6 +23,7 @@ use think\facade\Session; use think\facade\Cookie; use taoser\SetArr; use app\common\lib\SetArr as SetArrConf; +use think\response\Json; class Set extends AdminController { @@ -35,7 +36,6 @@ class Set extends AdminController //网站设置显示 public function index() { - $mailserver = MailServer::find(1); $template = Files::getDirName('../view'); $email = Db::name('admin')->where('id',1)->value('email'); @@ -44,7 +44,7 @@ class Set extends AdminController $admin_map = array_search('admin',config('app.app_map')); $index_map = $index_map ? $index_map : ''; $admin_map = $admin_map ? $admin_map : ''; - View::assign(['sysInfo'=>$this->sysInfo,'mailserver'=>$mailserver,'template'=>$template,'email'=>$email,'index_map'=>$index_map,'admin_map'=>$admin_map]); + View::assign(['sysInfo'=>$this->sysInfo,'template'=>$template,'email'=>$email,'index_map'=>$index_map,'admin_map'=>$admin_map]); // 域名绑定 if(!empty(config('app.domain_bind'))){ @@ -98,69 +98,6 @@ class Set extends AdminController return View::fetch('set/system/server'); } - /**邮箱设置 - * parem $id - */ - public function email() - { - $mailserver = MailServer::find(1); - //邮箱配置 - if(Request::isAjax()){ - $data = Request::only(['host','port','mail','nickname','password']); - $res = $mailserver->save($data); - if($res){ - return json(['code'=>0,'msg'=>'更新成功']); - } else { - return json(['code'=>-1,'msg'=>'更新失败']); - } - } - } - - /** - * 发验证码 - * - * @return void - */ - public function sendMailCode() - { - if(Request::isPost()){ - $email = Request::param('email'); - $code = mt_rand('1111','9999'); - Cache::set('test_code',$code,600); - $result = mailto($email,'邮箱服务配置','Hi亲爱的管理员:
您正在配置您站点的邮箱服务,配置成功后,可以收到来自网站的发帖,评论等即时信息。请在10分钟内把激活码填入激活码框内,您的激活码为:'.$code); - if($result){ - $res = ['code'=>0,'msg'=>'请去邮箱获取测试码']; - }else{ - $res = ['code'=>-1,'msg'=>'邮箱配置错误或无服务能力,请排查!']; - } - } - return json($res); - } - - /** - * 邮件激活 - * - * @return void - */ - public function activeMailServer() - { - if(Request::isPost()){ - $eCode = Request::param('code'); - $sCode = Cache::get('test_code'); - if($eCode == $sCode){ - $result = Db::name('mail_server')->update(['id'=>1,'active'=>1]); - if($result){ - $res = ['code'=>0,'msg'=>'邮箱服务激活成功']; - } else { - $res = ['code'=>-1,'msg'=>'激活服务出错!']; - } - }else{ - $res = ['code'=>-1,'msg'=>'激活码错误!!!']; - } - } - return json($res); - } - /**基础服务配置 * parem $id */ @@ -320,11 +257,10 @@ class Set extends AdminController } - /** - * URL美化,设置访问链接 - * - * @return void - */ + /** + * URL美化,设置访问链接 + * @return Json + */ public function setUrl() { $data = Request::only(['article_as','cate_as']); diff --git a/app/admin/view/addons/config.html b/app/admin/view/addons/config.html index 1631b6c..399fe57 100644 --- a/app/admin/view/addons/config.html +++ b/app/admin/view/addons/config.html @@ -2,45 +2,53 @@ {block name="body"}
- {foreach name="formData" item="vo" key="k"} - {php}$name = "params[".$k."]";{/php} - {switch name="$vo.type"} - {case value="text"} - {:form_input($name,'text',['label'=>$vo.title,'tip'=>$vo.tip],$vo.value)} - {/case} - {case value="textarea"} - {:form_textarea($name,['label'=>$vo.title,'tip'=>$vo.tip],$vo.value)} - {/case} - {case value="password"} - {:form_input($name,'password',['label'=>$vo.title,'tip'=>$vo.tip],$vo.value)} - {/case} - {case value="radio"} - {:form_radio($name,$vo.content,['label'=>$vo.title,'tip'=>$vo.tip],$vo.value)} - {/case} - {case value="select"} - {:form_select($name,$vo.content,['label'=>$vo.title,'verify'=>$vo.rule,'tip'=>$vo.tip,'search'=>1] ,[],$vo.value)} - {/case} - {case value="image"} - {:form_upload($name,$vo.value,['label'=>$vo.title,'tip'=>$vo.tip,'verify'=>$vo.rule,'type'=>'radio','num'=>'1','mime'=>'image'])} - {/case} - {case value="images"} - {:form_upload($name,$vo.value,['label'=>$vo.title,'tip'=>$vo.tip,'verify'=>$vo.rule,'type'=>'checkbox','num'=>$vo.num,'mime'=>'image'])} - {/case} - {case value="file"} - {:form_upload($name,$vo.value,['label'=>$vo.title,'tip'=>$vo.tip,'verify'=>$vo.rule,'type'=>'radio','num'=>$vo.num,'mime'=>'*'])} - {/case} - {case value="files"} - {:form_upload($name,$vo.value,['label'=>$vo.title,'tip'=>$vo.tip,'verify'=>$vo.rule,'type'=>'checkbox','num'=>$vo.num,'mime'=>'*'])} - {/case} - {case value="editor"} - {:form_editor($name,$name,2,['label'=>$vo.title,'tip'=>$vo.tip,'verify'=>$vo.rule])} - {/case} - {case value="array"} - {:form_arrays($name,['label'=>$vo.title,'tip'=>$vo.tip,'verify'=>$vo.rule],$vo.value?$vo.value:$vo.content)} - {/case} - {/switch} - {/foreach} - + {foreach name="formData" item="vo" key="k"} + {php}$name = "params[".$k."]";{/php} + {switch name="$vo.type"} + {case value="text"} + {:form_input($name,'text',['label'=>$vo.title,'verify'=>$vo.rule,'tips'=>$vo.tips],$vo.value)} + {/case} + {case value="textarea"} + {:form_textarea($name,['label'=>$vo.title,'tips'=>$vo.tips],$vo.value)} + {/case} + {case value="password"} + {:form_input($name,'password',['label'=>$vo.title,'tips'=>$vo.tips],$vo.value)} + {/case} + {case value="radio"} + {:form_radio($name,$vo.content,['label'=>$vo.title,'tips'=>$vo.tips],$vo.value)} + {/case} + {case value="checkbox"} + {:form_checkbox($name, $vo.content,['label'=>$vo.title, 'verify' =>$vo.rule,'tips'=>$vo.tips,], $vo['value'])}; + {/case} + {case value="switch"} + {:form_switch($name, $vo.content,['label'=>$vo.title, 'verify' =>$vo.rule,'tips'=>$vo.tips,], $vo['value'])}; + {/case} + {case value="select"} + {:form_select($name,$vo.content,['label'=>$vo.title,'verify'=>$vo.rule,'tips'=>$vo.tips,'search'=>1] ,[],$vo.value)} + {/case} + {case value="selects"} + {:form_select($name,$vo.content,['label'=>$vo.title,'multipsle'=>1.,'verify'=>$vo.rule,'tips'=>$vo.tips,'search'=>1] ,[],$vo.value)} + {/case} + {case value="image"} + {:form_upload($name,$vo.value,['label'=>$vo.title,'tips'=>$vo.tips,'verify'=>$vo.rule,'type'=>'radio','num'=>'1','mime'=>'images'])} + {/case} + {case value="images"} + {:form_upload($name,$vo.value,['label'=>$vo.title,'tips'=>$vo.tips,'verify'=>$vo.rule,'type'=>'checkbox','num'=>$vo.num,'mime'=>'images'])} + {/case} + {case value="file"} + {:form_upload($name,$vo.value,['label'=>$vo.title,'tips'=>$vo.tips,'verify'=>$vo.rule,'type'=>'radio','num'=>$vo.num,'mime'=>'*'])} + {/case} + {case value="files"} + {:form_upload($name,$vo.value,['label'=>$vo.title,'tips'=>$vo.tips,'verify'=>$vo.rule,'type'=>'checkbox','num'=>$vo.num,'mime'=>'*'])} + {/case} + {case value="editor"} + {:form_editor($name,2,['label'=>$vo.title,'tips'=>$vo.tips,'verify'=>$vo.rule])} + {/case} + {case value="array"} + {:form_arrays($name,$vo.value?$vo.value:$vo.content,['label'=>$vo.title,'tips'=>$vo.tips,'verify'=>$vo.rule])} + {/case} + {/switch} + {/foreach}
@@ -48,4 +56,38 @@
{/block} {block name="js"} + {/block} \ No newline at end of file diff --git a/app/admin/view/addons/index.html b/app/admin/view/addons/index.html index 7c4b75a..5edaafd 100644 --- a/app/admin/view/addons/index.html +++ b/app/admin/view/addons/index.html @@ -6,9 +6,7 @@
-
- 插件分类 -
+
插件分类
- 设置 @@ -61,13 +59,12 @@ + {/block} diff --git a/app/common.php b/app/common.php index 292a2e5..b9ca2bc 100644 --- a/app/common.php +++ b/app/common.php @@ -1,14 +1,13 @@ SMTPDebug = 0; // Enable verbose debug output +// $mail->SMTPDebug = SMTP::DEBUG_SERVER; $mail->CharSet = 'utf-8'; //b $mail->isSMTP(); // Set mailer to use SMTP $mail->Host = $mailserver['host']; // Specify main and backup SMTP servers @@ -24,6 +24,7 @@ try { $mail->Username = $mailserver['mail']; // SMTP username $mail->Password = $mailserver['password']; // SMTP password $mail->SMTPSecure = 'tls'; // Enable TLS encryption, `ssl` also accepted +// $mail->SMTPSecure = PHPMailer::ENCRYPTION_SMTPS; $mail->Port = $mailserver['port']; // TCP port to connect to //Recipients @@ -306,3 +307,27 @@ function find_spider(){ return false; } +if (!function_exists('__')) { + + /** + * 获取语言变量值 + * @param string $name 语言变量名 + * @param array $vars 动态变量值 + * @param string $lang 语言 + * @return mixed + */ + function __($name, $vars = [], $lang = '') + { + if (is_numeric($name) || !$name) { + return $name; + } + if (!is_array($vars)) { + $vars = func_get_args(); + array_shift($vars); + $lang = ''; + } + return \think\facade\Lang::get($name, $vars, $lang); + } +} + + diff --git a/app/index/controller/Article.php b/app/index/controller/Article.php index 9d9b244..5320dfa 100644 --- a/app/index/controller/Article.php +++ b/app/index/controller/Article.php @@ -223,7 +223,7 @@ class Article extends BaseController } $data = ['title'=>$title,'content'=>'评论通知','link'=>$link,'user_id'=>$sendId,'type'=>2]; //type=2为评论留言 Message::sendMsg($sendId,$receveId,$data); - if(Config::get('taoler.config.email_notice')) mailto($this->showUser(1)['email'],'评论审核通知','Hi亲爱的管理员:
用户'.$this->showUser($this->uid)['name'].'刚刚对 '.$title.' 发表了评论,请尽快处理。'); + if(Config::get('taoler.config.email_notice')) hook('mailtohook',[$this->showUser(1)['email'],'评论审核通知','Hi亲爱的管理员:
用户'.$this->showUser($this->uid)['name'].'刚刚对 '.$title.' 发表了评论,请尽快处理。']); $res = ['code'=>0, 'msg'=>$msg]; } else { $res = ['code'=>-1, 'msg'=>'留言失败']; @@ -290,7 +290,7 @@ class Article extends BaseController // 清除文章tag缓存 Cache::tag('tagArtDetail')->clear(); // 发提醒邮件 - if(Config::get('taoler.config.email_notice')) mailto($this->showUser(1)['email'],'发帖审核通知','Hi亲爱的管理员:
用户'.$this->showUser($this->uid)['name'].'刚刚发表了 '.$data['title'].' 新的帖子,请尽快处理。'); + if(Config::get('taoler.config.email_notice')) hook('mailtohook',[$this->showUser(1)['email'],'发帖审核通知','Hi亲爱的管理员:
用户'.$this->showUser($this->uid)['name'].'刚刚发表了 '.$data['title'].' 新的帖子,请尽快处理。']); $link = $this->getRouteUrl((int)$aid, $cate_ename); // 推送给百度收录接口 diff --git a/app/index/controller/Login.php b/app/index/controller/Login.php index e71c813..6aefce3 100644 --- a/app/index/controller/Login.php +++ b/app/index/controller/Login.php @@ -135,7 +135,7 @@ class Login extends BaseController if ($result['code'] == 1) { $res = ['code'=>0,'msg'=>$result['msg'],'url'=>(string) url('login/index')]; - if(Config::get('taoler.config.email_notice')) mailto($this->showUser(1)['email'],'注册新用户通知','Hi亲爱的管理员:
新用户 '.$data['name'].' 刚刚注册了新的账号,请尽快处理。'); + if(Config::get('taoler.config.email_notice')) hook('mailtohook',[$this->showUser(1)['email'],'注册新用户通知','Hi亲爱的管理员:
新用户 '.$data['name'].' 刚刚注册了新的账号,请尽快处理。']); }else { $res = ['code'=>-1,'msg'=>$result]; } @@ -164,7 +164,7 @@ class Login extends BaseController Cache::set('code',$code,600); Cache::set('userid',$user['id'],600); - $result = mailto($data['email'],'重置密码','Hi亲爱的'.$user['name'].':
您正在维护您的信息,请在10分钟内验证,您的验证码为:'.$code); + $result = hook('mailtohook',[$data['email'],'重置密码','Hi亲爱的'.$user['name'].':
您正在维护您的信息,请在10分钟内验证,您的验证码为:'.$code]); if($result){ Cache::set('repass','postcode',60); //设置repass标志为1存入Cache $res = ['code'=>0,'msg'=>'验证码已发送成功,请去邮箱查看!','url'=>(string) url('login/postcode')]; @@ -247,7 +247,7 @@ class Login extends BaseController $code = mt_rand('1111','9999'); Cache::set($email, $code, 600); - $result = mailto($email,'注册邮箱验证码','Hi亲爱的新用户:
您正在注册我们站点的新账户,请在10分钟内验证,您的验证码为:'.$code); + $result = hook('mailtohook',[$email,'注册邮箱验证码','Hi亲爱的新用户:
您正在注册我们站点的新账户,请在10分钟内验证,您的验证码为:'.$code]); if($result == 1) { $res = ['code' => 0, 'msg' => '验证码已发送成功,请去邮箱查看!']; } else { diff --git a/app/index/controller/User.php b/app/index/controller/User.php index 2a4e5ba..a3b02e5 100644 --- a/app/index/controller/User.php +++ b/app/index/controller/User.php @@ -250,7 +250,7 @@ class User extends BaseController $email = Request::param('email'); $url = Request::domain().Request::root().'/active/index?url='.time().md5($email).$this->uid; $content = "Hi亲爱的{$this->showUser($this->uid)['name']}:
您正在进行邮箱激活,请在10分钟内完成激活。 请点击进行激活
若无法跳转请复制链接激活:{$url}"; - $res = mailto($email,'邮箱激活',$content); + $res = hook('mailtohook',[$email,'邮箱激活',$content]); if($res){ return json(['status'=>0]); }else{ diff --git a/composer.json b/composer.json index 81f9d19..8854e41 100644 --- a/composer.json +++ b/composer.json @@ -7,7 +7,7 @@ "thinkphp", "ORM" ], - "homepage": "http://www.aieok.com/", + "homepage": "https://www.aieok.com/", "license": "Apache-2.0", "authors": [ { @@ -37,7 +37,8 @@ "guzzlehttp/guzzle": "7.0", "php-di/php-di": "^6.4", "workerman/phpsocket.io": "^1.1", - "jaeger/querylist": "^4.2" + "jaeger/querylist": "^4.2", + "symfony/var-exporter": "^5.4" }, "require-dev": { "symfony/var-dumper": "^4.2", diff --git a/composer.lock b/composer.lock index 58105fa..a1e0266 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "c80928616d71c7770ef136acd370770e", + "content-hash": "775d0e3963da1506fb878faca1e62b31", "packages": [ { "name": "bacon/bacon-qr-code", @@ -304,16 +304,16 @@ }, { "name": "endroid/qr-code", - "version": "4.5.0", + "version": "4.6.0", "source": { "type": "git", "url": "https://github.com/endroid/qr-code.git", - "reference": "36681470bd10352b53bcb9731bdf2270e0d79b22" + "reference": "b60873b14e2ca7bf3c3746f5e032023095a7e05c" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/endroid/qr-code/zipball/36681470bd10352b53bcb9731bdf2270e0d79b22", - "reference": "36681470bd10352b53bcb9731bdf2270e0d79b22", + "url": "https://api.github.com/repos/endroid/qr-code/zipball/b60873b14e2ca7bf3c3746f5e032023095a7e05c", + "reference": "b60873b14e2ca7bf3c3746f5e032023095a7e05c", "shasum": "" }, "require": { @@ -364,7 +364,7 @@ ], "support": { "issues": "https://github.com/endroid/qr-code/issues", - "source": "https://github.com/endroid/qr-code/tree/4.5.0" + "source": "https://github.com/endroid/qr-code/tree/4.6.0" }, "funding": [ { @@ -372,7 +372,7 @@ "type": "github" } ], - "time": "2022-08-21T09:22:43+00:00" + "time": "2022-10-04T17:13:41+00:00" }, { "name": "firebase/php-jwt", @@ -920,16 +920,16 @@ }, { "name": "league/flysystem", - "version": "1.1.9", + "version": "1.1.10", "source": { "type": "git", "url": "https://github.com/thephpleague/flysystem.git", - "reference": "094defdb4a7001845300334e7c1ee2335925ef99" + "reference": "3239285c825c152bcc315fe0e87d6b55f5972ed1" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/thephpleague/flysystem/zipball/094defdb4a7001845300334e7c1ee2335925ef99", - "reference": "094defdb4a7001845300334e7c1ee2335925ef99", + "url": "https://api.github.com/repos/thephpleague/flysystem/zipball/3239285c825c152bcc315fe0e87d6b55f5972ed1", + "reference": "3239285c825c152bcc315fe0e87d6b55f5972ed1", "shasum": "" }, "require": { @@ -1002,7 +1002,7 @@ ], "support": { "issues": "https://github.com/thephpleague/flysystem/issues", - "source": "https://github.com/thephpleague/flysystem/tree/1.1.9" + "source": "https://github.com/thephpleague/flysystem/tree/1.1.10" }, "funding": [ { @@ -1010,7 +1010,7 @@ "type": "other" } ], - "time": "2021-12-09T09:40:50+00:00" + "time": "2022-10-04T09:16:37+00:00" }, { "name": "league/flysystem-cached-adapter", @@ -2130,16 +2130,16 @@ }, { "name": "symfony/var-dumper", - "version": "v4.4.44", + "version": "v4.4.46", "source": { "type": "git", "url": "https://github.com/symfony/var-dumper.git", - "reference": "f19951007dae942cc79b979c1fe26bfdfbeb54ed" + "reference": "90425fd98d1ecad98e4b2dca9f54f62069193b15" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/var-dumper/zipball/f19951007dae942cc79b979c1fe26bfdfbeb54ed", - "reference": "f19951007dae942cc79b979c1fe26bfdfbeb54ed", + "url": "https://api.github.com/repos/symfony/var-dumper/zipball/90425fd98d1ecad98e4b2dca9f54f62069193b15", + "reference": "90425fd98d1ecad98e4b2dca9f54f62069193b15", "shasum": "" }, "require": { @@ -2199,7 +2199,7 @@ "dump" ], "support": { - "source": "https://github.com/symfony/var-dumper/tree/v4.4.44" + "source": "https://github.com/symfony/var-dumper/tree/v4.4.46" }, "funding": [ { @@ -2215,24 +2215,98 @@ "type": "tidelift" } ], - "time": "2022-07-20T09:59:04+00:00" + "time": "2022-09-03T23:07:25+00:00" }, { - "name": "taoser/think-addons", - "version": "v1.0.3", + "name": "symfony/var-exporter", + "version": "v5.4.10", "source": { "type": "git", - "url": "https://github.com/taoser/think-addons.git", - "reference": "4329bb368fc87d7ca2fe0b2ac6e6e8d6bc13011f" + "url": "https://github.com/symfony/var-exporter.git", + "reference": "8fc03ee75eeece3d9be1ef47d26d79bea1afb340" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/taoser/think-addons/zipball/4329bb368fc87d7ca2fe0b2ac6e6e8d6bc13011f", - "reference": "4329bb368fc87d7ca2fe0b2ac6e6e8d6bc13011f", + "url": "https://api.github.com/repos/symfony/var-exporter/zipball/8fc03ee75eeece3d9be1ef47d26d79bea1afb340", + "reference": "8fc03ee75eeece3d9be1ef47d26d79bea1afb340", + "shasum": "" + }, + "require": { + "php": ">=7.2.5", + "symfony/polyfill-php80": "^1.16" + }, + "require-dev": { + "symfony/var-dumper": "^4.4.9|^5.0.9|^6.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "Symfony\\Component\\VarExporter\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Allows exporting any serializable PHP data structure to plain PHP code", + "homepage": "https://symfony.com", + "keywords": [ + "clone", + "construct", + "export", + "hydrate", + "instantiate", + "serialize" + ], + "support": { + "source": "https://github.com/symfony/var-exporter/tree/v5.4.10" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2022-05-27T12:56:18+00:00" + }, + { + "name": "taoser/think-addons", + "version": "v1.0.6", + "source": { + "type": "git", + "url": "https://github.com/taoser/think-addons.git", + "reference": "e6e35bfd8b93dc469ebb5c5530ba350131bd7541" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/taoser/think-addons/zipball/e6e35bfd8b93dc469ebb5c5530ba350131bd7541", + "reference": "e6e35bfd8b93dc469ebb5c5530ba350131bd7541", "shasum": "" }, "require": { "php": ">=7.1.0", + "symfony/var-exporter": "^5.4", "topthink/framework": "^6.0", "topthink/think-helper": "^3.0.0", "topthink/think-view": "^1.0" @@ -2269,9 +2343,9 @@ "description": "The ThinkPHP6 Addons Package", "support": { "issues": "https://github.com/taoser/think-addons/issues", - "source": "https://github.com/taoser/think-addons/tree/v1.0.3" + "source": "https://github.com/taoser/think-addons/tree/v1.0.6" }, - "time": "2022-06-04T08:08:23+00:00" + "time": "2022-10-06T13:11:38+00:00" }, { "name": "taoser/think-auth", @@ -2368,16 +2442,16 @@ }, { "name": "tightenco/collect", - "version": "v8.83.23", + "version": "v8.83.25", "source": { "type": "git", "url": "https://github.com/tighten/collect.git", - "reference": "a4423c6ace6b54ba4f86c0ac9de588c57bc94d79" + "reference": "7d2a6fc5e97c5f7209a780bea98f35042c1fd0ea" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/tighten/collect/zipball/a4423c6ace6b54ba4f86c0ac9de588c57bc94d79", - "reference": "a4423c6ace6b54ba4f86c0ac9de588c57bc94d79", + "url": "https://api.github.com/repos/tighten/collect/zipball/7d2a6fc5e97c5f7209a780bea98f35042c1fd0ea", + "reference": "7d2a6fc5e97c5f7209a780bea98f35042c1fd0ea", "shasum": "" }, "require": { @@ -2416,9 +2490,9 @@ ], "support": { "issues": "https://github.com/tighten/collect/issues", - "source": "https://github.com/tighten/collect/tree/v8.83.23" + "source": "https://github.com/tighten/collect/tree/v8.83.25" }, - "time": "2022-08-22T17:50:04+00:00" + "time": "2022-08-22T17:55:07+00:00" }, { "name": "topthink/framework", @@ -2999,16 +3073,16 @@ }, { "name": "workerman/workerman", - "version": "v4.1.0", + "version": "v4.1.3", "source": { "type": "git", "url": "https://github.com/walkor/workerman.git", - "reference": "88ddf517e5c35bee072b2e453c4fcca0c6f1e59a" + "reference": "01028d8008c5691ec38c5f675fc13d76496a6db9" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/walkor/workerman/zipball/88ddf517e5c35bee072b2e453c4fcca0c6f1e59a", - "reference": "88ddf517e5c35bee072b2e453c4fcca0c6f1e59a", + "url": "https://api.github.com/repos/walkor/workerman/zipball/01028d8008c5691ec38c5f675fc13d76496a6db9", + "reference": "01028d8008c5691ec38c5f675fc13d76496a6db9", "shasum": "" }, "require": { @@ -3058,7 +3132,7 @@ "type": "patreon" } ], - "time": "2022-08-20T10:16:22+00:00" + "time": "2022-09-23T14:05:12+00:00" }, { "name": "yansongda/pay", diff --git a/extend/taoler/com/Api.php b/extend/taoler/com/Api.php index 21604d8..cd31604 100644 --- a/extend/taoler/com/Api.php +++ b/extend/taoler/com/Api.php @@ -14,6 +14,11 @@ use think\Response; class Api { + /** + * @param $url + * @param $data + * @return mixed|\think\response\Json + */ public static function urlPost($url, $data) { if($url == ''){ diff --git a/extend/taoler/com/FormHelper.php b/extend/taoler/com/FormHelper.php new file mode 100644 index 0000000..18a8385 --- /dev/null +++ b/extend/taoler/com/FormHelper.php @@ -0,0 +1,18 @@ +readonlyOrdisabled($options) ? $this->readonlyOrdisabled($options) : $this->readonlyOrdisabled($options); + $disorread = $disorread ? 'layui-disabled' : ''; + if ($type == 'hidden') { + return 'verify($options) . $this->filter($options) . $this->readonlyOrdisabled($options) . ' autocomplete="off" placeholder="' . $placeholder . '" class="layui-input ' . $this->addClass($options) . ' ' . $disorread . '" ' . $value . '/>'; + } + $str = '
'.$this->label($label,$options). '
+ addextend($options) . ' type="' . $type . '" name="' . $name . '" required ' . $this->verify($options) . $this->filter($options) . $this->readonlyOrdisabled($options) . ' autocomplete="off" + placeholder="' . lang($placeholder) . '" ' . $this->addstyle($options) . ' class="layui-input ' . $this->addClass($options) . ' ' . $disorread . '"' . $value . '/> + ' . $this->tips($options) . ' +
'; + return $str; + } + + /** + * @param string $name + * @param array $options + * @param mixed|null $value + * @return string + */ + public function text(string $name,array $options = [], mixed $value = null) + { + return $this->input( $name,'text',$options, $value); + } + + /** + * 创建一个密码输入字段 + * + * @param string $name + * @param array $options + * + * @return string + */ + public function password(string $name, array $options = []) + { + $options['verify'] = isset($options['verify'])?$options['verify']:'pass'; + return $this->input($name, 'password', $options); + } + + /** + * 创建一个范围输入选择器 + * + * @param string $name + * @param null $value + * @param array $options + * + * @return string + */ + public function range($name, $options = [], $value = null) + { + $label = $options['label'] ?? $name; + $tips = $options['tips'] ?? $label; + $placeholder = $options['placeholder'] ?? $tips; + $value = !is_null($value) ? 'value="' . $value . '"' : ''; + $disorread = $this->readonlyOrdisabled($options) ? $this->readonlyOrdisabled($options) : $this->readonlyOrdisabled($options); + $disorread = $disorread ? 'layui-disabled' : ''; + return '
'.$this->label($label, $options).' +
+
+ verify($options) . $this->filter($options) . $this->readonlyOrdisabled($options) .' type="text" name="'.$name.'_min" placeholder="'.lang($placeholder).'" autocomplete="off" class="layui-input ' . $this->addClass($options) . ' ' . $disorread . '" ' . $value . '/> +
+
-
+
+ verify($options) . $this->filter($options) . $this->readonlyOrdisabled($options) .' type="text" name="'.$name.'_max" placeholder="'.lang($placeholder).'" autocomplete="off" class="layui-input ' . $this->addClass($options) . ' ' . $disorread . '" ' . $value . '/> +
+
+
'; + } + + /** + * 创建一个隐藏的输入字段 + * + * @param string $name + * @param null $value + * @param array $options + * + * @return string + */ + public function hidden($name, $options = [],$value = null) + { + return $this->input( $name,'hidden', $options, $value); + } + + /** + * 创建一个电子邮件输入字段 + * + * @param string $name + * @param null $value + * @param array $options + * + * @return string + */ + public function email($name, $options = [],$value = null) + { + $options['verify'] = isset($options['verify'])?$options['verify']:'email'; + return $this->input( $name,'email', $options, $value); + } + + /** + * 创建一个tel输入字段 + * + * @param string $name + * @param null $value + * @param array $options + * + * @return string + */ + public function tel($name, $options = [],$value = null) + { + $options['verify'] = isset($options['verify'])?$options['verify']:'phone'; + return $this->input( $name,'tel', $options, $value); + } + + /** + * 创建一个数字输入字段 + * + * @param string $name + * @param null $value + * @param array $options + * + * @return string + */ + public function number($name, $options = [],$value = null) + { + $options['verify'] = isset($options['verify'])?$options['verify']:'number'; + return $this->input( $name,'number', $options, $value); + } + + /** + * 创建一个url输入字段 + * + * @param string $name + * @param null $value + * @param array $options + * + * @return string + */ + public function url($name, $options = [],$value = null) + { + $options['verify'] = isset($options['verify'])?$options['verify']:'url'; + return $this->input( $name,'url', $options, $value); + } + + /** + * 评分 + * @param $name + * @param $options + * @param $value + * @return string + */ + public function rate($name = '', $options = [], $value = '') + { + $label = $options['label'] ?? $name; + $id = ($options['id']) ?? $name; + $value = !is_null($value) ? $value : ''; + $data_value = ''; + foreach ($options as $key => $val) { + $data_value .= ' data-'.$key.'="'.$val.'" '; + } + $disorread = $this->readonlyOrdisabled($options) ? $this->readonlyOrdisabled($options) : $this->readonlyOrdisabled($options); + $disorread = $disorread ? 'layui-disabled' : ''; + $op = json_encode($options,JSON_UNESCAPED_UNICODE); + $str = "
+ " .$this->label($label,$options) . " +
+ +
addextend($options) . $this->addstyle($options) ." data-name='" . $name . "' data-value ='" . $value . "' id='" . $id . "' lay-filter='rate' class='" . $this->addClass($options) . "' data-options='" . $op . "'> + " . $this->tips($options) . "
"; + return $str; + } + /** + * 滑块 + * @param $name + * @param $options + * @param $value + * @return string + */ + public function slider($name = '', $options = [], $value = '') + { + $label = $options['label'] ?? $name; + $id = ($options['id']) ?? $name; + $value = !is_null($value) ? $value : ''; + $data_value = ''; + foreach ($options as $key => $val) { + $data_value .= ' data-'.$key.'="'.$val.'" '; + } + $disorread = $this->readonlyOrdisabled($options) ? $this->readonlyOrdisabled($options) : $this->readonlyOrdisabled($options); + $disorread = $disorread ? 'layui-disabled' : ''; + $op = json_encode($options,JSON_UNESCAPED_UNICODE); + $str = "
". $this->label($label, $options)." +
+ +
addextend($options) ." style='top:16px' data-name='" . $name . "' data-value ='" . $value . "' id='" . $id . "' lay-filter='slider' class='" . $this->addClass($options) . "' data-options='" . $op . "'> + " . $this->tips($options) . " +
"; + return $str; + } + /** + * @param $name + * @param $radiolist + * @param array $options + * @param string $value + * @return string + */ + public function radio($name = '', $radiolist=[], $options = [], $value = '') + { + if (is_null($radiolist)) { + $radiolist = $name; + } + $label = $options['label'] ?? $name; + $input = ''; + if (is_string($radiolist) && strpos($radiolist, "\n") !== false) $radiolist = explode("\n", $radiolist); + if (is_array($radiolist)) { + foreach ($radiolist as $k => $v) { + if (is_string($v) && strpos($v, ':') !== false) { + $v = explode(":", $v); + $input .= 'addextend($options) . ' ' . $this->addstyle($options) . ' class="' . $this->addClass($options) . '" type="radio"' . $this->selectedOrchecked($value, $v[0], 2) . ' name="' . $name . '" ' . $this->verify($options) . $this->filter($options) . $this->readonlyOrdisabled($options) . ' value="' . $v[0] . '" title="' . lang($v[1]) . '" />'; + } else { + $input .= 'addextend($options) . ' ' . $this->addstyle($options) . ' class="' . $this->addClass($options) . '" type="radio"' . $this->selectedOrchecked($value, $k, 2) . ' name="' . $name . '" ' . $this->verify($options) . $this->filter($options) . $this->readonlyOrdisabled($options) . ' value="' . $k . '" title="' . lang($v) . '" />'; + } + } + } else { + $input .= 'addextend($options) . ' ' . $this->addstyle($options) . ' class="' . $this->addClass($options) . '" type="radio" name="' . $name . '" ' . $this->verify($options) . $this->filter($options) . ' value="' . $radiolist . '" title="' . lang($radiolist) . '" />'; + } + + $str = '
' .$this->label($label,$options) . ' +
+ ' . $input . ' + ' . $this->tips($options) . ' +
+
'; + return $str; + } + + /** + * 生成开关 + * @param $name + * @param $value + * @param array $options + * @return string + * switch是关键字不能用 + */ + + public function switchs($name = '', $switch=[], $options = [], $value = '') + { + $label = $options['label'] ?? $name; + $switchArr = $switch; + if (is_string($switch) && strpos($switch, '|')) { + $switchArr = implode('|', $switch); + } + $checked = $value ? 'checked' : ''; + $switchStr = $switchArr ? lang($switchArr[1]) . '|' . lang($switchArr[0]) : lang('open') . '|' . 'close'; + $str = '
' .$this->label($label,$options) . ' +
+ addextend($options) . ' ' . $this->addstyle($options) . ' class="' . $this->addClass($options) . '" type="checkbox" value="' . $value . '" checked="" name="' . $name . '" ' . $this->verify($options) . $this->filter($options) . $this->readonlyOrdisabled($options) . ' lay-skin="switch" lay-text="' . $switchStr . '" data-text="' . lang($value) . '"/> + ' . $this->tips($options) . ' +
+
'; + + return $str; + } + + /** + * 多选 + * @param null $name + * @param array $list + * @param array $options + * @param $value + * @return string + */ + public function checkbox($name = '', $list = [], $options = [], $value = '') + { + if (empty($value)) $value = $name; + if (is_string($value) && strpos($value, "\n") !== false) $value = explode("\n", $value); + if (is_string($value) && strpos($value, ",") !== false) $value = explode(",", $value); + if (is_string($value) && strpos($value, "|") !== false) $value = explode("|", $value); + if (is_string($list) && strpos($list, "\n") !== false) $list = explode("\n", $list); + if (is_string($list) && strpos($list, ",") !== false) $list = explode(",", $list); + if (is_string($list) && strpos($list, "|") !== false) $list = explode("|", $list); + if ( + is_string($value) + && strpos($value, "\n") === false + && strpos($value, ",") === false + && strpos($value, "|") === false + ) $value = explode(",", $value); + $input = '';$skin = ''; + if (isset($options['skin'])) $skin = 'lay-skin="' . $options['skin'] . '"'; + if (is_array($list) && $list) { + foreach ($list as $k => $v) { + if (is_string($v) && strpos($v, ':') !== false) { + $v = explode(":", $v); + $check = ''; + if (is_array($value) && in_array($v[0], $value) || $value == $v[0]) { + $check = 'checked'; + } + $input .= 'addextend($options) . ' ' . $this->addstyle($options) . ' class="' . $this->addClass($options) . '" type="checkbox" ' . $check . ' value="' . $k . '" name="' . $name . '[' . $v[0] . ']" ' . $skin . $this->verify($options) . $this->filter($options) . $this->readonlyOrdisabled($options) . ' title="' . lang($v[1]) . '"/>'; + } else { + $check = ''; + if ((is_array($value) && is_array($v) && in_array($v[0], $value)) || $value == $v) { + $check = 'checked'; + } elseif ((is_array($value) && is_string($v) && in_array($k, $value)) || $value == $v) { + $check = 'checked'; + } + $input .= 'addextend($options) . ' ' . $this->addstyle($options) . ' class="' . $this->addClass($options) . '" type="checkbox" ' . $check . ' value="' . $k . '" name="' . $name . '[' . $k . ']" ' . $skin . $this->verify($options) . $this->filter($options) . $this->readonlyOrdisabled($options) . ' title="' . lang($v) . '"/>'; + } + } + } else { + $input .= 'addextend($options) . ' ' . $this->addstyle($options) . ' class="' . $this->addClass($options) . '" type="checkbox" name="' . $name . '[]" ' . $skin . $this->verify($options) . $this->filter($options) . $this->readonlyOrdisabled($options) . ' title="' . lang($value) . '"/>'; + } + $label = $options['label'] ?? $name; + $str = '
' .$this->label($label,$options) . ' +
+ ' . $input . $this->tips($options) . ' +
'; + return $str; + } + + /** + * 数组表单 + * @param null $name + * @param array $options + * @param array $list + * @return string + */ + public function arrays($name = '', $list = [], $options = []) + { + $label = $options['label'] ?? $name; + $arr = ''; + $i = 0; + if (empty($list)) { + $arr .= '
' .$this->label($label,$options) . '
+ verify($options) . ' type="text" name="' . $name . '[key][]" value="" placeholder="' . lang('key') . '" autocomplete="off" class="layui-input input-double-width"> +
+
+ verify($options) . ' type="text" name="' . $name . '[value][]" value="" placeholder="' . lang('value') . '" autocomplete="off" class="layui-input input-double-width"> +
+ +
'; + } + foreach ($list as $key => $value) { + if ($i == 0) { + $arr .= '
' .$this->label($label,$options) . '
+ verify($options) . ' type="text" name="' . $name . '[key][]" value="' . $key . '" placeholder="' . lang('key') . '" autocomplete="off" class="layui-input input-double-width"> +
+
+ verify($options) . ' type="text" name="' . $name . '[value][]" value="' . $value . '" placeholder="' . lang('value') . '" autocomplete="off" class="layui-input input-double-width"> +
+ +
';; + } else { + $arr .= '
+ verify($options) . ' type="text" name="' . $name . '[key][]" value="' . $key . '" placeholder="' . lang('key') . '" autocomplete="off" class="layui-input input-double-width"> +
+ verify($options) . ' type="text" name="' . $name . '[value][]" value="' . $value . '" placeholder="' . lang('value') . '" autocomplete="off" class="layui-input input-double-width"> +
+ +
'; + } + $i++; + } + $str = '
' . $arr . '
'; + return $str; + } + + /** + * 文本 + * @param null $name + * @param array $options + * @param $value + * @return string + */ + public function textarea($name = '', $options = [], $value = '') + { + $label = $options['label'] ?? $name; + $tips = $options['tips'] ?? $name; + $placeholder = $options['placeholder'] ?? $tips; + $str = '
' .$this->label($label,$options) . '
+ + ' . $this->tips($options) . ' +
'; + return $str; + } + + /** + * @param $name + * @param $select + * @param $options + * @param $attr + * @param $value + * @return string + */ + public function selectn($name = '', $select= [], $options=[], $attr=[], $value='') + { + $label = $options['label'] ?? $name; + $options['url'] = $options['url'] ?? ''; + $options['delimiter'] = $options['delimiter'] ?? ''; + $options['search']= isset($options['search']) ? true : ''; + $options['num'] = $options['num'] ?? 3; + $options['last'] = $options['last'] ?? ''; + if ($attr) { + $attr = is_array($attr) ? implode(',', $attr) : $attr; + } + $op = ''; + foreach ($options as $key => $val) { + $op .= ' data-'.$key.'="'.$val.'" '; + } + $op .='data-value="' . $value . '" data-attr="' . $attr . '"'; + if (is_array($select)) { + $op .= ' data-data="' . json_encode($select, JSON_UNESCAPED_UNICODE) . '"'; + } + if (is_object($select)) { + $op .= ' data-data="' . json_encode((array)$select, JSON_UNESCAPED_UNICODE) .'"'; + } + $str = '
' .$this->label($label,$options) . ' +
+
addextend($options) . ' id="' . $name . '"' . $op . ' lay-filter="selectN" ' . $this->addClass($options) . ' name="' . $name . '" ' . ' ' . $this->search($options) . ' ' . $this->readonlyOrdisabled($options) . ' > +
+ ' . $this->tips($options) . ' +
+
'; + return $str; + } + /** + * @param $name + * @param $select + * @param $options + * @param $attr + * @param $value + * @return string + */ + public function selectplus($name = '', $select= [], $options=[], $attr=[], $value='') + { + $options['url'] = $options['url'] ?? ''; + $id = $options['id'] ?? $name; + $label = $options['label'] ?? $name; + $options['delimiter'] = $options['delimiter'] ?? ''; + $options['fielddelimiter'] = $options['fielddelimiter'] ?? ''; + $multiple = isset($options['multiple']) ? 'multiple="multiple"' : ''; + $options['multiple'] = $multiple?1:''; + if ($attr) { + $attr = is_array($attr) ? implode(',', $attr) : $attr; + } + $op = ''; + foreach ($options as $key => $val) { + $op .= ' data-'.$key.'="'.$val.'" '; + } + $op .= ' data-value="' . $value . '" data-attr="' . $attr . '" '; + if (is_array($select)) { + $op .= " data-data='" . json_encode($select, JSON_UNESCAPED_UNICODE) . "'"; + } + if (is_object($select)) { + $op .= ' data-data="' . json_encode((array)$select, JSON_UNESCAPED_UNICODE) . '"'; + } + $str = '
' .$this->label($label,$options) . ' +
+
addextend($options) . $op . ' lay-filter="selectPlus" ' . $this->addClass($options) . ' name="' . $name . '" ' . $multiple . ' ' . $this->search($options) . ' ' . $this->readonlyOrdisabled($options) . ' > + +
+ ' . $this->tips($options) . ' +
+
'; + return $str; + } + /** + * @param $name + * @param $select + * @param $options + * @param $attr + * @param $value + * @return string + */ + public function multiselect($name = '', $select=[], $options=[], $attr=[], $value='') + { + $op = ''; + if ($select) { + foreach ($select as $k => $v) { + $selected = ''; + if (is_array($value) && is_array($attr) && !empty($attr) && in_array($v[$attr[0]], $value) || (is_array($attr) && !empty($attr) && $v[$attr[0]] == $value)) { + $selected = 'selected'; + } + if ($value != null && $value && in_array($k, $value) && !$attr) { + $selected = 'selected'; + } + if (!empty($attr)) { + $op .= ''; + } else { + $op .= ''; + } + } + } + $id = $options['id']??$name; + $label = $options['label'] ?? $name; + $url = $options['url'] ?? ''; + $multiple = ''; + if (isset($options['multiple'])) { + $multiple = 'multiple="multiple"'; + } + if (isset($options['default'])) { + $default = lang($options['default']); + } else { + $default = lang('Default'); + } + $attr = is_array($attr) ? implode(',', $attr) : $attr; + $str = '
' .$this->label($label,$options) . ' +
+ + ' . $this->tips($options) . ' +
+
'; + return $str; + } + /** + * @param $name + * @param $select + * @param $options + * @param $attr + * @param $value + * @return string + */ + public function xmselect($name = '', $select=[], $options=[], $attr=[], $value='') + { + $op = ''; + if (is_array($select)) { + $op .= " data-data='" . json_encode($select, JSON_UNESCAPED_UNICODE) . "'"; + } + if (is_object($select)) { + $op .= " data-data='" . json_encode((array)$select, JSON_UNESCAPED_UNICODE) . "'"; + } + $attr = is_array($attr) ? implode(',', $attr):$attr; + $attr ? $op .= ' data-attr="' . $attr . '"' : ""; + $value = is_array($value) ? implode($value) : $value; + $value ? $op .= ' data-value="' . $value . '"' : ""; + $options['lang'] = $options['lang'] ?? ''; + $options['tips'] = $options['tips']?? ''; + $options['empty'] = $options['empty'] ?? ''; + $options['repeat'] = $options['repeat'] ??''; + $options['content'] = $options['content'] ?? ''; + $options['searchTips'] = $options['searchTips'] ?? ''; + $options['style'] = $options['style'] ?? ''; + $options['filterable'] = $options['filterable'] ?? ''; + $options['remoteSearch'] = $options['remoteSearch'] ?? ''; + $options['remoteMethod'] = $options['remoteMethod'] ?? ''; + $options['height'] = $options['height'] ??''; + $options['paging'] = $options['paging'] ??''; + $options['size'] = $options['size'] ??''; + $options['pageSize'] = $options['pageSize'] ??''; + $options['pageRemote'] = $options['pageRemote'] ??''; + $options['clickClose'] = $options['clickClose'] ??''; + $options['reqext'] = $options['reqtext'] ??''; + $options['radio'] = $options['radio'] ?? ''; + $options['url'] = $options['url'] ??''; + $options['tree'] = $options['tree'] ??''; + $options['prop'] = $options['prop'] ??''; + $options['parentField'] = $options['parentField'] ??'pid'; + $options['max'] = $options['max'] ??''; + $options['verify'] = $options['verify'] ??''; + $options['disabled'] = $options['disabled'] ??''; + $options['create'] = $options['create'] ??''; + $options['theme'] = $options['theme'] ??''; + $options['value'] = $options['value'] ??''; + $options['autorow'] = $options['autorow'] ??''; + $options['toolbar'] = isset($options['toolbar'])?json_encode($options['toolbar'],JSON_UNESCAPED_UNICODE) : ''; + foreach($options as $key=>$val){ + $op .= ' data-'.$key.'="'.$val.'" '; + } + $label = $options['label'] ?? $name; + $str = '
' .$this->label($label,$options) . ' +
addextend($options) . ' ' . $this->addstyle($options) . ' id="' . $name . '" name="' . $name . '" class="layui-input-block ' . $this->addClass($options) . '" ' . $op . ' lay-filter="xmSelect"> + ' . $this->tips($options) . ' +
+
'; + return $str; + } + + /** + * 创建动态下拉列表字段 + * @param $name + * @param $options + * @param $value + * @return string + */ + public function selectpage(string $name,array $lists= [],array $options = [],mixed $value=null) + { + + $url = $options['url']??''; + foreach ($options as $k => $v) { + $op['extend']['data-'.$k] = $v; + } + $op['extend']['lay-filter'] = 'selectPage'; + $op['extend']['data-data'] = empty($lists)?'':json_encode($lists); + $op['extend']['data-field'] = $options['field']??'title'; + $op['extend']['data-primarykey'] = $options['field']??'id'; + $op['extend']['data-multiple'] = $options['multiple']??''; + $op['extend']['data-init'] = $value; + $options = array_merge($options,$op); + return $this->input($name,'text',$options, $value); + } + /** + * @param $name + * @param $value + * @param array $options + * @return string + * tag + */ + public function tags($name = '', $options = [], $value = '') + { + $label = $options['label'] ?? $name; + $id = $options['id'] ?? $name; + $str = '
' .$this->label($label,$options) . ' +
+
+ + verify($options) . $this->addextend($options) . ' ' . $this->addstyle($options) . ' class="' . $this->addClass($options) . '" id="' . $id . '" lay-filter="tags" type="text" placeholder="' . lang("Space To Generate Tags") . '" ' . $this->filter($options) . $this->readonlyOrdisabled($options) . '/> +
+
+
'; + return $str; + } + + /** + * @param $name + * @param $value + * @param array $options + * @return string + * 颜色选择 + */ + public function color($name = '', $options = [], $value = '') + { + + $id = $options['id'] ?? $name;$label = $options['label'] ?? $name;$format = $options['format'] ?? 'hex'; + $str = '
' .$this->label($label,$options) . ' +
+ verify($options) . $this->addstyle($options) . ' class="layui-input layui-input-inline' . $this->addClass($options) . '" type="text" name="' . $name . '" value="' . $value . '"' . $this->filter($options) . $this->readonlyOrdisabled($options) . '/> +
addextend($options) . ' id="' . $id . '" lay-filter="colorPicker" data-name="' . $name . '" data-format = "' . $format . '" >
+
+
'; + return $str; + } + + /** + * @param $name + * @param $value + * @param array $options + * @return string + * 图标,有点小问题 + */ + public function icon($name = '', $options = [], $value = '') + { + $name = $name ? $name : 'icon'; + $label = $options['label'] ?? $name; + $value = $value ? $value : 'layui-icon-rate'; + $id = $options['id'] ?? $name; + $str = '
' .$this->label($label,$options) . ' +
+ verify($options) . $this->addextend($options) . ' type="hidden" name="' . $name . '" id="' . $id . '" value="' . $value . '" + lay-filter="iconPickers" class="hide ' . $this->addClass($options) . '" /> +
+
'; + return $str; + } + + /** + * @param null $name + * @param array $options + * @return string + * 日期 + */ + public function date($name='', $options=[], $value='') + { + $op = ''; + if (isset($options['range'])) { + $op .= 'data-range="' . $options['range'] . '"'; + } + if (isset($options['type'])) { + $op .= 'data-type="' . $options['type'] . '"'; + } + if (isset($options['format'])) { + $op .= 'data-format="' . $options['format'] . '"'; + } + $label = $options['label'] ?? $name; + $str = '
' .$this->label($label,$options) . ' +
+ verify($options) . $this->addextend($options) . ' ' . $this->addstyle($options) . ' class="layui-input ' . $this->addClass($options) . '" type="text" name="' . $name . '" value="' . $value . '" lay-filter="date" ' . $op . ' placeholder="yyyy-MM-dd HH:mm:ss"/> +
+
'; + return $str; + } + /** + * 城市选择 + * @param string $name + * @param $options + * @return string + */ + public function city($name = 'cityPicker', $options = []) + { + $id = $options['id'] ?? $name; + $options['provinceId'] = $options['provinceId'] ?? 'province_id'; + $options['cityId'] = $options['cityId'] ?? 'city_id'; + $options['districtId'] = $options['districtId'] ?? 'area_id'; + $attr = 'data-districtid="' . $options['districtId'] . '" data-cityid="' . $options['cityId'] . '" data-provinceid="' . $options['provinceId'] . '"'; + $str = '
+ +
+ verify($options) . $this->addextend($options) . ' type="hidden" autocomplete="on" class="layui-input ' . $this->addClass($options) . '" ' . $attr . ' lay-filter="cityPicker" id="' . $id . '" name="' . $name . '" readonly="readonly" data-toggle="city-picker" placeholder="请选择"/> +
+
'; + return $str; + } + + /** + * 城市选择 + * @param string $name + * @param $options + * @return string + */ + public function region($name = 'regionCheck', $options = []) + { + $label = $options['label'] ?? $name; + $id = $options['id'] ?? $name; + $str = '
' .$this->label($label,$options) . ' +
+ +
verify($options) . $this->addextend($options) . ' ' . $this->addstyle($options) . ' class="' . $this->addClass($options) . '" id="' . $id . '" name="' . $name . '" lay-filter="regionCheck"> +
+
+
'; + return $str; + } + + /** + * @param string $name + * @param $id + * @param int $type + * @param array $options + * @return string + * 编辑器 + */ + public function editor($name = 'container', $type = 1, $options = [], $value = '') + { + $id = $options['id'] ?? $name; + $height = $options['height'] ?? '400px'; + $path = $options['path'] ?? 'upload'; + $label = $options['label'] ?? $name; + $str = '
' .$this->label($label,$options) . ' +
'; + if ($type == 1) { + //百度。quill wangeditor ckeditor,editormd + $textarea = ''; + if (!empty($options['textarea'])) { + $textarea = ''; + } + //百度。quill wangeditor ckeditor + $str .= '
addextend($options) . ' data-value="' . htmlentities($value) . '" id="' . $id . '" name="' . $name . '" + data-editor="' . $type . '" lay-filter="editor" lay-editor data-path="' . $path . '" data-height="' . $height . '" type="text/plain" > + ' . $textarea . '
'; + } else { + //LAYEDIT tinyedit + $str .= ''; + } + $str .= '
'; + return $str; + } + /** + * 上传 + * @param string $name + * @param string $formData + * @param array $options + * @return string + */ + public function upload($name = 'avatar', $formData = '', $options = [], $value = '') + { + if (!isset($options['type'])) $options['type'] = 'radio'; + if (!isset($options['mime'])) $options['mime'] = 'images'; + if (!isset($options['num'])) $options['num'] = 1; + if (isset($options['num']) && $options['num'] == '*') $options['num'] = 100; + if (!isset($options['path'])) $options['path'] = 'upload'; //上传路劲 + $id = $options['id']??$name; + $css = isset($options['css']) ? $options['css'] : 'display:inline-block;'; + $label = $options['label'] ?? $name; + $li = ''; + $croper_container = ''; + if (isset($options['cropper'])) { + $width = $options['width'] ?? '300'; + $height = $options['height'] ?? '300'; + $mark = $options['mark'] ?? '1'; + $area = $options['area'] ?? '800px'; + $cops = ['name'=>$name,'path' => $options['path'], 'width' => $width, 'height' => $height, 'mark' => $mark, 'area' => $area]; + $crpperops = 'data-value="' . json_encode($cops, true) . '"'; + $data_value = ''; + foreach ($cops as $key => $val) { + $data_value .= ' data-'.$key.'="'.$val.'" '; + } + $croper_container = ''; + $options['type'] = 'radio'; + $css .= 'width:53%!important;'; + } + $values = []; + $formData = is_object($formData) ? ($formData->toArray()) : $formData; + if ($formData && is_array($formData) && array_key_exists($name, $formData)) { + $values = explode(',', $formData[$name]); + } elseif ($formData && is_string($formData)) { + $values = explode(',', $formData); + } + $values = $value ? explode(',', $value) : $values; + if ($value) $values = explode(',', $value); + if (!empty(array_filter($values))) { + foreach ($values as $k => $v) { + if ($k + 1 <= $options['num']) { + switch ($options['mime']) { + case 'video': + $li .= '
  • +
  • '; + break; + case 'audio': + $li .= '
  • +
  • '; + break; + case 'images': + $li .= '
  • +
  • '; + break; + case 'image': + $li .= '
  • +
  • '; + break; + case 'zip': + $li .= '
  • +
  • '; + break; + case 'office': + $li .= '
  • +
  • '; + break; + default: + $li .= '
  • +
  • '; + break; + } + } + } + $value = implode(',', $values); + } + $op = [ + 'name' => $name, + 'path' => $options['path'] ?? 'upload', + 'mime' => $options['mime'] ?? '*', + 'num' => $options['num'] ?? '', + 'type' => $options['type'] ?? '', + 'size' => $options['size'] ?? '', + 'exts' => $options['exts'] ?? '*', + 'accept' => $options['accept'] ?? 'file', + 'multiple' => $options['multiple'] ?? '', + 'selecturl' => $options['selecturl'] ?? '', + 'tableurl' => $options['tableurl'] ?? '', + ]; + $data_value = ''; + foreach ($op as $key => $val) { + $data_value .= ' data-'.$key.'="'.$val.'" '; + } + $op = " data-value='" . json_encode($op, true) . "'"; + $select_container = ''; + if ((isset($options['select']) && $options['select']) || !isset($options['select'])) { + $options['select'] = $options['select'] ?? 'upload-select'; //可选upload-choose + $select_container = ''; + } + $str = '
    ' .$this->label($label,$options) . ' +
    +
    + addextend($options) . ' ' . $this->addstyle($options) . ' value="' . $value . '" style="' . $css . ' ;width:65% " type="text" name="' . $name . '" class="layui-input attach ' . $this->addClass($options) . '"' . $this->verify($options) . '/> + ' . $croper_container . ' + + ' . $select_container . ' +
    ' + . $li . ' +
    +
    + ' . $this->tips($options) . ' +
    +
    '; + return $str; + } + /** + * @param bool $reset + * @param array $options + * @return string + */ + public function closebtn($reset = true, $options = []) + { + $show = ''; + if (!isset($options['show'])) { + $show = 'layui-hide'; + } + $str = '
    + +
    '; + + return $str; + } + + + /** + * @param bool $reset + * @param array $options + * @return string + */ + public function submitbtn($reset=true, $options=[]) + { + $show = ''; + if (!isset($options['show'])) { + $show = 'layui-hide'; + } + $str = '
    + '; + if ($reset) { + $str .= ''; + } + $str .= '
    '; + return $str; + } + + /** + * @param $label + * @param $options + * @return string + */ + public function label($label,$options= [],$escape_html = true){ + if ($escape_html) { + $label = $this->entities($label); + } + return ''; + } + + /** + * 将HTML字符串转换为实体 + * + * @param string $value + * + * @return string + */ + protected function entities($value) + { + return htmlentities($value, ENT_QUOTES, 'UTF-8', false); + } + /** + * @param $options + * @return string + * 提示 + */ + protected function tips($options = []) + { + $tips = ''; + if (isset($options['tips'])) { + $tips = '
    ' . lang($options['tips']) . '
    '; + } + return $tips; + } + + /** + * @ 验证 + * @return string + */ + protected function verify($options = []) + { + $verify = ''; + if (isset($options['verify'])) { + $verify .= ' lay-verify="' . $options['verify'] . '"'; + } + $type ='tips'; + if (isset($options['verType']) && $options['verType']) { + $type = $options['verType']; + } + $verify.= ' lay-verType="' . $type . '" '; + if (isset($options['reqText']) && $options['reqText']) { + $verify.= ' lay-reqText="' . $options['reqText'] . '" '; + } + return $verify; + } + + /** 过滤 + * @param $options + * @return string + */ + protected function filter($options = []) + { + $filter = ''; + if (isset($options['filter'])) { + $filter = 'lay-filter="' . $options['filter'] . '"'; + } + return $filter; + } + + /**搜索 + * @return string + */ + protected function search($options = []) + { + $search = ''; + if (!isset($options['search']) || $options['search'] == true) { + $search = 'lay-search'; + } + return $search; + } + /** + * @param $ops + * @param $val + * @param int $type + * @return string + * 是否选中 + */ + protected function selectedOrchecked($select=[], $val='', $type = 1) + { + if ($select == $val) { + if ($type == 1) return 'selected'; + return 'checked'; + } else { + return ''; + } + } + + protected function labelRequire($options=[]) + { + + if (isset($options['verify']) && ($options['verify'] == 'required' || strpos($options['verify'], 'required') !== false)) { + return 'required'; + } + return ''; + } + + protected function readonlyOrdisabled($options=[]) + { + + if (isset($options['readonly']) && $options['readonly']) { + return 'readonly'; + } + if (isset($options['disabled']) && $options['disabled']) { + return 'disabled'; + } + return ''; + } + //自定义class属性 + protected function addClass($options=[]) + { + if (isset($options['class']) && $options['class']) { + $classArr = is_array($options['class']) ? $options['class'] : explode(',', $options['class']); + return ' ' .implode(' ', $classArr).' '; + } + return ''; + } + protected function addstyle( $options=[]) + { + if (isset($options['style']) && $options['style']) { + return ' style="' . $options['style'] . '" '; + } + return ' '; + } + protected function addextend($options=[]) + { + if (isset($options['extend']) && $options['extend']) { + if(is_array($options['extend'])) { + $attr = ' '; + foreach($options['extend'] as $key => $value) { + $attr.= $key .'="'.$value . '"'; + } + return $attr; + }else{ + return ' ' . $options['extend'].' '; + } + } + if (isset($options['extend']) && $options['extend']) { + return ' ' . $options['extend'].' '; + } + return ' '; + } + +} diff --git a/public/static/admin/modules/webset.js b/public/static/admin/modules/webset.js index d26cffc..40b24ed 100644 --- a/public/static/admin/modules/webset.js +++ b/public/static/admin/modules/webset.js @@ -5,118 +5,6 @@ layui.define(['table', 'form'], function(exports){ ,table = layui.table ,form = layui.form; - //签到规则 - table.render({ - elem: '#sign-rule', - url: signSignRule, - cols:[[ - {type: 'numbers', fixed: 'left'}, - {field: 'days',title: '天数'}, - {field: 'score',title: '积分'}, - {field: 'ctime',title: '时间'}, - {title: '操作', width: 150, align:'center', toolbar: '#sign-rule-button'} - - ]] - ,page: true - ,limit: 10 - ,height: 'full-220' - ,text: '对不起,加载出现异常!' - }); - - //监听工具条 - table.on('tool(sign-rule)', function(obj){ - var data = obj.data; - if(obj.event === 'del'){ - layer.prompt({ - formType: 1 - ,title: '敏感操作,请验证口令' - }, function(value, index){ - layer.close(index); - - layer.confirm('真的删除行么', function(index){ - //obj.del(); - $.ajax({ - type:'post', - url:signDelete, - data:{id:data.id}, - dataType:'json', - success:function(data){ - if(data.code == 0){ - layer.msg(data.msg,{ - icon:6, - time:2000 - }); - } else { - layer.open({ - title:'删除失败', - content:data.msg, - icon:5, - adim:6 - }) - } - } - }); - table.reload('sign-rule'); - layer.close(index); - }); - }); - } else if(obj.event === 'edit'){ - var tr = $(obj.tr); - - layer.open({ - type: 2 - ,title: '编辑签到' - ,content: signSignEdit +'?id='+ data.id - ,maxmin: true - ,area: ['350px', '300px'] - ,btn: ['确定', '取消'] - ,yes: function(index, layero){ - - var iframeWindow = window['layui-layer-iframe'+ index] - ,submitID = 'LAY-user-sign-submit' - ,submit = layero.find('iframe').contents().find('#'+ submitID); - - //监听提交 - iframeWindow.layui.form.on('submit('+ submitID +')', function(data){ - var field = data.field; //获取提交的字段 - - //提交 Ajax 成功后,静态更新表格中的数据 - $.ajax({ - type:"post", - url:signSignEdit, - data:field, - daType:"json", - success:function (res){ - if (res.code == 0) { - layer.msg(res.msg,{ - icon:6, - time:2000 - }); - } else { - layer.open({ - tiele:'修改失败', - content:res.msg, - icon:5, - anim:6 - }); - } - } - }); - - table.reload('sign-rule'); //数据刷新 - layer.close(index); //关闭弹层 - }); - - submit.trigger('click'); - } - ,success: function(layero, index){ - - } - }); - } - }); - - //Vip规则 table.render({ elem: '#vip-rule', @@ -230,7 +118,5 @@ layui.define(['table', 'form'], function(exports){ } }); - - exports('webset', {}) }); \ No newline at end of file diff --git a/vendor/composer/autoload_files.php b/vendor/composer/autoload_files.php index f3d9ee5..054fc09 100644 --- a/vendor/composer/autoload_files.php +++ b/vendor/composer/autoload_files.php @@ -8,12 +8,12 @@ $baseDir = dirname($vendorDir); return array( '9b552a3cc426e3287cc811caefa3cf53' => $vendorDir . '/topthink/think-helper/src/helper.php', '35fab96057f1bf5e7aba31a8a6d5fdde' => $vendorDir . '/topthink/think-orm/stubs/load_stubs.php', + 'a4a119a56e50fbb293281d9a48007e0e' => $vendorDir . '/symfony/polyfill-php80/bootstrap.php', '7b11c4dc42b3b3023073cb14e519683c' => $vendorDir . '/ralouphie/getallheaders/src/getallheaders.php', 'c964ee0ededf28c96ebd9db5099ef910' => $vendorDir . '/guzzlehttp/promises/src/functions_include.php', 'a0edc8309cc5e1d60e3047b5df6b7052' => $vendorDir . '/guzzlehttp/psr7/src/functions_include.php', '0e6d7bf4a5811bfa5cf40c5ccd6fae6a' => $vendorDir . '/symfony/polyfill-mbstring/bootstrap.php', '25072dd6e2470089de65ae7bf11d3109' => $vendorDir . '/symfony/polyfill-php72/bootstrap.php', - 'a4a119a56e50fbb293281d9a48007e0e' => $vendorDir . '/symfony/polyfill-php80/bootstrap.php', '37a3dc5111fe8f707ab4c132ef1dbc62' => $vendorDir . '/guzzlehttp/guzzle/src/functions_include.php', '667aeda72477189d0494fecd327c3641' => $vendorDir . '/symfony/var-dumper/Resources/functions/dump.php', 'fe62ba7e10580d903cc46d808b5961a4' => $vendorDir . '/tightenco/collect/src/Collect/Support/helpers.php', diff --git a/vendor/composer/autoload_psr4.php b/vendor/composer/autoload_psr4.php index 256a9d5..7307fa2 100644 --- a/vendor/composer/autoload_psr4.php +++ b/vendor/composer/autoload_psr4.php @@ -26,6 +26,7 @@ return array( 'Symfony\\Polyfill\\Php80\\' => array($vendorDir . '/symfony/polyfill-php80'), 'Symfony\\Polyfill\\Php72\\' => array($vendorDir . '/symfony/polyfill-php72'), 'Symfony\\Polyfill\\Mbstring\\' => array($vendorDir . '/symfony/polyfill-mbstring'), + 'Symfony\\Component\\VarExporter\\' => array($vendorDir . '/symfony/var-exporter'), 'Symfony\\Component\\VarDumper\\' => array($vendorDir . '/symfony/var-dumper'), 'QL\\' => array($vendorDir . '/jaeger/querylist/src'), 'Psr\\SimpleCache\\' => array($vendorDir . '/psr/simple-cache/src'), diff --git a/vendor/composer/autoload_static.php b/vendor/composer/autoload_static.php index 3449295..619065f 100644 --- a/vendor/composer/autoload_static.php +++ b/vendor/composer/autoload_static.php @@ -9,12 +9,12 @@ class ComposerStaticInit1b32198725235c8d6500c87262ef30c2 public static $files = array ( '9b552a3cc426e3287cc811caefa3cf53' => __DIR__ . '/..' . '/topthink/think-helper/src/helper.php', '35fab96057f1bf5e7aba31a8a6d5fdde' => __DIR__ . '/..' . '/topthink/think-orm/stubs/load_stubs.php', + 'a4a119a56e50fbb293281d9a48007e0e' => __DIR__ . '/..' . '/symfony/polyfill-php80/bootstrap.php', '7b11c4dc42b3b3023073cb14e519683c' => __DIR__ . '/..' . '/ralouphie/getallheaders/src/getallheaders.php', 'c964ee0ededf28c96ebd9db5099ef910' => __DIR__ . '/..' . '/guzzlehttp/promises/src/functions_include.php', 'a0edc8309cc5e1d60e3047b5df6b7052' => __DIR__ . '/..' . '/guzzlehttp/psr7/src/functions_include.php', '0e6d7bf4a5811bfa5cf40c5ccd6fae6a' => __DIR__ . '/..' . '/symfony/polyfill-mbstring/bootstrap.php', '25072dd6e2470089de65ae7bf11d3109' => __DIR__ . '/..' . '/symfony/polyfill-php72/bootstrap.php', - 'a4a119a56e50fbb293281d9a48007e0e' => __DIR__ . '/..' . '/symfony/polyfill-php80/bootstrap.php', '37a3dc5111fe8f707ab4c132ef1dbc62' => __DIR__ . '/..' . '/guzzlehttp/guzzle/src/functions_include.php', '667aeda72477189d0494fecd327c3641' => __DIR__ . '/..' . '/symfony/var-dumper/Resources/functions/dump.php', 'fe62ba7e10580d903cc46d808b5961a4' => __DIR__ . '/..' . '/tightenco/collect/src/Collect/Support/helpers.php', @@ -74,6 +74,7 @@ class ComposerStaticInit1b32198725235c8d6500c87262ef30c2 'Symfony\\Polyfill\\Php80\\' => 23, 'Symfony\\Polyfill\\Php72\\' => 23, 'Symfony\\Polyfill\\Mbstring\\' => 26, + 'Symfony\\Component\\VarExporter\\' => 30, 'Symfony\\Component\\VarDumper\\' => 28, ), 'Q' => @@ -226,6 +227,10 @@ class ComposerStaticInit1b32198725235c8d6500c87262ef30c2 array ( 0 => __DIR__ . '/..' . '/symfony/polyfill-mbstring', ), + 'Symfony\\Component\\VarExporter\\' => + array ( + 0 => __DIR__ . '/..' . '/symfony/var-exporter', + ), 'Symfony\\Component\\VarDumper\\' => array ( 0 => __DIR__ . '/..' . '/symfony/var-dumper', diff --git a/vendor/composer/installed.json b/vendor/composer/installed.json index 89cfec6..fcfa688 100644 --- a/vendor/composer/installed.json +++ b/vendor/composer/installed.json @@ -313,17 +313,17 @@ }, { "name": "endroid/qr-code", - "version": "4.5.0", - "version_normalized": "4.5.0.0", + "version": "4.6.0", + "version_normalized": "4.6.0.0", "source": { "type": "git", "url": "https://github.com/endroid/qr-code.git", - "reference": "36681470bd10352b53bcb9731bdf2270e0d79b22" + "reference": "b60873b14e2ca7bf3c3746f5e032023095a7e05c" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/endroid/qr-code/zipball/36681470bd10352b53bcb9731bdf2270e0d79b22", - "reference": "36681470bd10352b53bcb9731bdf2270e0d79b22", + "url": "https://api.github.com/repos/endroid/qr-code/zipball/b60873b14e2ca7bf3c3746f5e032023095a7e05c", + "reference": "b60873b14e2ca7bf3c3746f5e032023095a7e05c", "shasum": "" }, "require": { @@ -342,7 +342,7 @@ "roave/security-advisories": "Makes sure package versions with known security issues are not installed", "setasign/fpdf": "Enables you to use the PDF writer" }, - "time": "2022-08-21T09:22:43+00:00", + "time": "2022-10-04T17:13:41+00:00", "type": "library", "extra": { "branch-alias": { @@ -376,7 +376,7 @@ ], "support": { "issues": "https://github.com/endroid/qr-code/issues", - "source": "https://github.com/endroid/qr-code/tree/4.5.0" + "source": "https://github.com/endroid/qr-code/tree/4.6.0" }, "funding": [ { @@ -962,24 +962,18 @@ }, { "name": "league/flysystem", - "version": "1.1.9", - "version_normalized": "1.1.9.0", + "version": "1.1.10", + "version_normalized": "1.1.10.0", "source": { "type": "git", "url": "https://github.com/thephpleague/flysystem.git", - "reference": "094defdb4a7001845300334e7c1ee2335925ef99" + "reference": "3239285c825c152bcc315fe0e87d6b55f5972ed1" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/thephpleague/flysystem/zipball/094defdb4a7001845300334e7c1ee2335925ef99", - "reference": "094defdb4a7001845300334e7c1ee2335925ef99", - "shasum": "", - "mirrors": [ - { - "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%", - "preferred": true - } - ] + "url": "https://api.github.com/repos/thephpleague/flysystem/zipball/3239285c825c152bcc315fe0e87d6b55f5972ed1", + "reference": "3239285c825c152bcc315fe0e87d6b55f5972ed1", + "shasum": "" }, "require": { "ext-fileinfo": "*", @@ -1008,7 +1002,7 @@ "spatie/flysystem-dropbox": "Allows you to use Dropbox storage", "srmklive/flysystem-dropbox-v2": "Allows you to use Dropbox storage for PHP 5 applications" }, - "time": "2021-12-09T09:40:50+00:00", + "time": "2022-10-04T09:16:37+00:00", "type": "library", "extra": { "branch-alias": { @@ -1053,7 +1047,7 @@ ], "support": { "issues": "https://github.com/thephpleague/flysystem/issues", - "source": "https://github.com/thephpleague/flysystem/tree/1.1.9" + "source": "https://github.com/thephpleague/flysystem/tree/1.1.10" }, "funding": [ { @@ -2270,17 +2264,17 @@ }, { "name": "symfony/var-dumper", - "version": "v4.4.44", - "version_normalized": "4.4.44.0", + "version": "v4.4.46", + "version_normalized": "4.4.46.0", "source": { "type": "git", "url": "https://github.com/symfony/var-dumper.git", - "reference": "f19951007dae942cc79b979c1fe26bfdfbeb54ed" + "reference": "90425fd98d1ecad98e4b2dca9f54f62069193b15" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/var-dumper/zipball/f19951007dae942cc79b979c1fe26bfdfbeb54ed", - "reference": "f19951007dae942cc79b979c1fe26bfdfbeb54ed", + "url": "https://api.github.com/repos/symfony/var-dumper/zipball/90425fd98d1ecad98e4b2dca9f54f62069193b15", + "reference": "90425fd98d1ecad98e4b2dca9f54f62069193b15", "shasum": "" }, "require": { @@ -2304,7 +2298,7 @@ "ext-intl": "To show region name in time zone dump", "symfony/console": "To use the ServerDumpCommand and/or the bin/var-dump-server script" }, - "time": "2022-07-20T09:59:04+00:00", + "time": "2022-09-03T23:07:25+00:00", "bin": [ "Resources/bin/var-dump-server" ], @@ -2342,7 +2336,7 @@ "dump" ], "support": { - "source": "https://github.com/symfony/var-dumper/tree/v4.4.44" + "source": "https://github.com/symfony/var-dumper/tree/v4.4.46" }, "funding": [ { @@ -2361,27 +2355,104 @@ "install-path": "../symfony/var-dumper" }, { - "name": "taoser/think-addons", - "version": "v1.0.3", - "version_normalized": "1.0.3.0", + "name": "symfony/var-exporter", + "version": "v5.4.10", + "version_normalized": "5.4.10.0", "source": { "type": "git", - "url": "https://github.com/taoser/think-addons.git", - "reference": "4329bb368fc87d7ca2fe0b2ac6e6e8d6bc13011f" + "url": "https://github.com/symfony/var-exporter.git", + "reference": "8fc03ee75eeece3d9be1ef47d26d79bea1afb340" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/taoser/think-addons/zipball/4329bb368fc87d7ca2fe0b2ac6e6e8d6bc13011f", - "reference": "4329bb368fc87d7ca2fe0b2ac6e6e8d6bc13011f", + "url": "https://api.github.com/repos/symfony/var-exporter/zipball/8fc03ee75eeece3d9be1ef47d26d79bea1afb340", + "reference": "8fc03ee75eeece3d9be1ef47d26d79bea1afb340", + "shasum": "" + }, + "require": { + "php": ">=7.2.5", + "symfony/polyfill-php80": "^1.16" + }, + "require-dev": { + "symfony/var-dumper": "^4.4.9|^5.0.9|^6.0" + }, + "time": "2022-05-27T12:56:18+00:00", + "type": "library", + "installation-source": "dist", + "autoload": { + "psr-4": { + "Symfony\\Component\\VarExporter\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Allows exporting any serializable PHP data structure to plain PHP code", + "homepage": "https://symfony.com", + "keywords": [ + "clone", + "construct", + "export", + "hydrate", + "instantiate", + "serialize" + ], + "support": { + "source": "https://github.com/symfony/var-exporter/tree/v5.4.10" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "install-path": "../symfony/var-exporter" + }, + { + "name": "taoser/think-addons", + "version": "v1.0.6", + "version_normalized": "1.0.6.0", + "source": { + "type": "git", + "url": "https://github.com/taoser/think-addons.git", + "reference": "e6e35bfd8b93dc469ebb5c5530ba350131bd7541" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/taoser/think-addons/zipball/e6e35bfd8b93dc469ebb5c5530ba350131bd7541", + "reference": "e6e35bfd8b93dc469ebb5c5530ba350131bd7541", "shasum": "" }, "require": { "php": ">=7.1.0", + "symfony/var-exporter": "^5.4", "topthink/framework": "^6.0", "topthink/think-helper": "^3.0.0", "topthink/think-view": "^1.0" }, - "time": "2022-06-04T08:08:23+00:00", + "time": "2022-10-06T13:11:38+00:00", "type": "library", "extra": { "think": { @@ -2415,7 +2486,7 @@ "description": "The ThinkPHP6 Addons Package", "support": { "issues": "https://github.com/taoser/think-addons/issues", - "source": "https://github.com/taoser/think-addons/tree/v1.0.3" + "source": "https://github.com/taoser/think-addons/tree/v1.0.6" }, "install-path": "../taoser/think-addons" }, @@ -2522,17 +2593,17 @@ }, { "name": "tightenco/collect", - "version": "v8.83.23", - "version_normalized": "8.83.23.0", + "version": "v8.83.25", + "version_normalized": "8.83.25.0", "source": { "type": "git", "url": "https://github.com/tighten/collect.git", - "reference": "a4423c6ace6b54ba4f86c0ac9de588c57bc94d79" + "reference": "7d2a6fc5e97c5f7209a780bea98f35042c1fd0ea" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/tighten/collect/zipball/a4423c6ace6b54ba4f86c0ac9de588c57bc94d79", - "reference": "a4423c6ace6b54ba4f86c0ac9de588c57bc94d79", + "url": "https://api.github.com/repos/tighten/collect/zipball/7d2a6fc5e97c5f7209a780bea98f35042c1fd0ea", + "reference": "7d2a6fc5e97c5f7209a780bea98f35042c1fd0ea", "shasum": "" }, "require": { @@ -2544,7 +2615,7 @@ "nesbot/carbon": "^2.23.0", "phpunit/phpunit": "^8.3" }, - "time": "2022-08-22T17:50:04+00:00", + "time": "2022-08-22T17:55:07+00:00", "type": "library", "installation-source": "dist", "autoload": { @@ -2573,7 +2644,7 @@ ], "support": { "issues": "https://github.com/tighten/collect/issues", - "source": "https://github.com/tighten/collect/tree/v8.83.23" + "source": "https://github.com/tighten/collect/tree/v8.83.25" }, "install-path": "../tightenco/collect" }, @@ -3282,17 +3353,17 @@ }, { "name": "workerman/workerman", - "version": "v4.1.0", - "version_normalized": "4.1.0.0", + "version": "v4.1.3", + "version_normalized": "4.1.3.0", "source": { "type": "git", "url": "https://github.com/walkor/workerman.git", - "reference": "88ddf517e5c35bee072b2e453c4fcca0c6f1e59a" + "reference": "01028d8008c5691ec38c5f675fc13d76496a6db9" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/walkor/workerman/zipball/88ddf517e5c35bee072b2e453c4fcca0c6f1e59a", - "reference": "88ddf517e5c35bee072b2e453c4fcca0c6f1e59a", + "url": "https://api.github.com/repos/walkor/workerman/zipball/01028d8008c5691ec38c5f675fc13d76496a6db9", + "reference": "01028d8008c5691ec38c5f675fc13d76496a6db9", "shasum": "" }, "require": { @@ -3301,7 +3372,7 @@ "suggest": { "ext-event": "For better performance. " }, - "time": "2022-08-20T10:16:22+00:00", + "time": "2022-09-23T14:05:12+00:00", "type": "library", "installation-source": "dist", "autoload": { diff --git a/vendor/composer/installed.php b/vendor/composer/installed.php index a909776..96651aa 100644 --- a/vendor/composer/installed.php +++ b/vendor/composer/installed.php @@ -3,7 +3,7 @@ 'name' => 'taoser/taoler', 'pretty_version' => 'dev-master', 'version' => 'dev-master', - 'reference' => '846581c3abfa893a57d4ce930c2fa684dfd688af', + 'reference' => '9f89482c951e9a44bf0e2e4bf91c7e7ccb0fc8dd', 'type' => 'project', 'install_path' => __DIR__ . '/../../', 'aliases' => array(), @@ -56,9 +56,9 @@ 'dev_requirement' => false, ), 'endroid/qr-code' => array( - 'pretty_version' => '4.5.0', - 'version' => '4.5.0.0', - 'reference' => '36681470bd10352b53bcb9731bdf2270e0d79b22', + 'pretty_version' => '4.6.0', + 'version' => '4.6.0.0', + 'reference' => 'b60873b14e2ca7bf3c3746f5e032023095a7e05c', 'type' => 'library', 'install_path' => __DIR__ . '/../endroid/qr-code', 'aliases' => array(), @@ -137,9 +137,9 @@ 'dev_requirement' => false, ), 'league/flysystem' => array( - 'pretty_version' => '1.1.9', - 'version' => '1.1.9.0', - 'reference' => '094defdb4a7001845300334e7c1ee2335925ef99', + 'pretty_version' => '1.1.10', + 'version' => '1.1.10.0', + 'reference' => '3239285c825c152bcc315fe0e87d6b55f5972ed1', 'type' => 'library', 'install_path' => __DIR__ . '/../league/flysystem', 'aliases' => array(), @@ -347,27 +347,36 @@ 'dev_requirement' => false, ), 'symfony/var-dumper' => array( - 'pretty_version' => 'v4.4.44', - 'version' => '4.4.44.0', - 'reference' => 'f19951007dae942cc79b979c1fe26bfdfbeb54ed', + 'pretty_version' => 'v4.4.46', + 'version' => '4.4.46.0', + 'reference' => '90425fd98d1ecad98e4b2dca9f54f62069193b15', 'type' => 'library', 'install_path' => __DIR__ . '/../symfony/var-dumper', 'aliases' => array(), 'dev_requirement' => false, ), + 'symfony/var-exporter' => array( + 'pretty_version' => 'v5.4.10', + 'version' => '5.4.10.0', + 'reference' => '8fc03ee75eeece3d9be1ef47d26d79bea1afb340', + 'type' => 'library', + 'install_path' => __DIR__ . '/../symfony/var-exporter', + 'aliases' => array(), + 'dev_requirement' => false, + ), 'taoser/taoler' => array( 'pretty_version' => 'dev-master', 'version' => 'dev-master', - 'reference' => '846581c3abfa893a57d4ce930c2fa684dfd688af', + 'reference' => '9f89482c951e9a44bf0e2e4bf91c7e7ccb0fc8dd', 'type' => 'project', 'install_path' => __DIR__ . '/../../', 'aliases' => array(), 'dev_requirement' => false, ), 'taoser/think-addons' => array( - 'pretty_version' => 'v1.0.3', - 'version' => '1.0.3.0', - 'reference' => '4329bb368fc87d7ca2fe0b2ac6e6e8d6bc13011f', + 'pretty_version' => 'v1.0.6', + 'version' => '1.0.6.0', + 'reference' => 'e6e35bfd8b93dc469ebb5c5530ba350131bd7541', 'type' => 'library', 'install_path' => __DIR__ . '/../taoser/think-addons', 'aliases' => array(), @@ -392,9 +401,9 @@ 'dev_requirement' => false, ), 'tightenco/collect' => array( - 'pretty_version' => 'v8.83.23', - 'version' => '8.83.23.0', - 'reference' => 'a4423c6ace6b54ba4f86c0ac9de588c57bc94d79', + 'pretty_version' => 'v8.83.25', + 'version' => '8.83.25.0', + 'reference' => '7d2a6fc5e97c5f7209a780bea98f35042c1fd0ea', 'type' => 'library', 'install_path' => __DIR__ . '/../tightenco/collect', 'aliases' => array(), @@ -518,9 +527,9 @@ 'dev_requirement' => false, ), 'workerman/workerman' => array( - 'pretty_version' => 'v4.1.0', - 'version' => '4.1.0.0', - 'reference' => '88ddf517e5c35bee072b2e453c4fcca0c6f1e59a', + 'pretty_version' => 'v4.1.3', + 'version' => '4.1.3.0', + 'reference' => '01028d8008c5691ec38c5f675fc13d76496a6db9', 'type' => 'library', 'install_path' => __DIR__ . '/../workerman/workerman', 'aliases' => array(), diff --git a/vendor/endroid/qr-code/README.md b/vendor/endroid/qr-code/README.md index ea91971..121a7f0 100644 --- a/vendor/endroid/qr-code/README.md +++ b/vendor/endroid/qr-code/README.md @@ -51,6 +51,7 @@ $result = Builder::create() ->labelText('This is the label') ->labelFont(new NotoSans(20)) ->labelAlignment(new LabelAlignmentCenter()) + ->validateResult(false) ->build(); ``` @@ -65,11 +66,12 @@ use Endroid\QrCode\Label\Label; use Endroid\QrCode\Logo\Logo; use Endroid\QrCode\RoundBlockSizeMode\RoundBlockSizeModeMargin; use Endroid\QrCode\Writer\PngWriter; +use Endroid\QrCode\Writer\ValidationException; $writer = new PngWriter(); // Create QR code -$qrCode = QrCode::create('Data') +$qrCode = QrCode::create('Life is too short to be generating QR codes') ->setEncoding(new Encoding('UTF-8')) ->setErrorCorrectionLevel(new ErrorCorrectionLevelLow()) ->setSize(300) @@ -87,6 +89,9 @@ $label = Label::create('Label') ->setTextColor(new Color(255, 0, 0)); $result = $writer->write($qrCode, $logo, $label); + +// Validate the result +$writer->validateResult($result, 'Life is too short to be generating QR codes'); ``` ## Usage: working with results @@ -149,13 +154,14 @@ size can result in additional padding to compensate for the rounding difference. And finally the encoding (default UTF-8 to support large character sets) can be set to `ISO-8859-1` if possible to improve readability. -## Built-in validation reader +## Validating the generated QR code -You can enable the built-in validation reader (disabled by default) by calling -setValidateResult(true). This validation reader does not guarantee that the QR -code will be readable by all readers but it helps you provide a minimum level -of quality. Take note that the validator can consume quite amount of additional -resources and it should be installed separately only if you use it. +If you need to be extra sure the QR code you generated is readable and contains +the exact data you requested you can enable the validation reader, which is +disabled by default. You can do this either via the builder or directly on any +writer that supports validation. See the examples above. + +Please note that validation affects performance so only use it in case of problems. ## Symfony integration diff --git a/vendor/endroid/qr-code/src/Builder/Builder.php b/vendor/endroid/qr-code/src/Builder/Builder.php index c00be13..63fd28b 100644 --- a/vendor/endroid/qr-code/src/Builder/Builder.php +++ b/vendor/endroid/qr-code/src/Builder/Builder.php @@ -7,6 +7,7 @@ namespace Endroid\QrCode\Builder; use Endroid\QrCode\Color\ColorInterface; use Endroid\QrCode\Encoding\EncodingInterface; use Endroid\QrCode\ErrorCorrectionLevel\ErrorCorrectionLevelInterface; +use Endroid\QrCode\Exception\ValidationException; use Endroid\QrCode\Label\Alignment\LabelAlignmentInterface; use Endroid\QrCode\Label\Font\FontInterface; use Endroid\QrCode\Label\Label; @@ -216,7 +217,7 @@ class Builder implements BuilderInterface $writer = $this->options['writer']; if ($this->options['validateResult'] && !$writer instanceof ValidatingWriterInterface) { - throw new \Exception('Unable to validate result with '.get_class($writer)); + throw ValidationException::createForUnsupportedWriter(strval(get_class($writer))); } /** @var QrCode $qrCode */ diff --git a/vendor/endroid/qr-code/src/Color/Color.php b/vendor/endroid/qr-code/src/Color/Color.php index 26d9c4a..7426225 100644 --- a/vendor/endroid/qr-code/src/Color/Color.php +++ b/vendor/endroid/qr-code/src/Color/Color.php @@ -44,6 +44,11 @@ final class Color implements ColorInterface return 1 - $this->alpha / 127; } + public function getHex(): string + { + return sprintf('#%02x%02x%02x', $this->red, $this->green, $this->blue); + } + public function toArray(): array { return [ diff --git a/vendor/endroid/qr-code/src/Color/ColorInterface.php b/vendor/endroid/qr-code/src/Color/ColorInterface.php index 91d3818..398be26 100644 --- a/vendor/endroid/qr-code/src/Color/ColorInterface.php +++ b/vendor/endroid/qr-code/src/Color/ColorInterface.php @@ -16,6 +16,8 @@ interface ColorInterface public function getOpacity(): float; + public function getHex(): string; + /** @return array */ public function toArray(): array; } diff --git a/vendor/endroid/qr-code/src/Exception/ValidationException.php b/vendor/endroid/qr-code/src/Exception/ValidationException.php new file mode 100644 index 0000000..88e3f0f --- /dev/null +++ b/vendor/endroid/qr-code/src/Exception/ValidationException.php @@ -0,0 +1,28 @@ +create($qrCode); + + return new DebugResult($matrix, $qrCode, $logo, $label, $options); } public function validateResult(ResultInterface $result, string $expectedData): void diff --git a/vendor/endroid/qr-code/src/Writer/EpsWriter.php b/vendor/endroid/qr-code/src/Writer/EpsWriter.php index 2ffd219..eb0a0cd 100644 --- a/vendor/endroid/qr-code/src/Writer/EpsWriter.php +++ b/vendor/endroid/qr-code/src/Writer/EpsWriter.php @@ -39,6 +39,6 @@ final class EpsWriter implements WriterInterface } } - return new EpsResult($lines); + return new EpsResult($matrix, $lines); } } diff --git a/vendor/endroid/qr-code/src/Writer/PdfWriter.php b/vendor/endroid/qr-code/src/Writer/PdfWriter.php index 78f0603..a087ba7 100644 --- a/vendor/endroid/qr-code/src/Writer/PdfWriter.php +++ b/vendor/endroid/qr-code/src/Writer/PdfWriter.php @@ -99,7 +99,7 @@ final class PdfWriter implements WriterInterface $fpdf->Cell($matrix->getOuterSize(), 0, $label->getText(), 0, 0, 'C'); } - return new PdfResult($fpdf); + return new PdfResult($matrix, $fpdf); } private function addLogo(LogoInterface $logo, \FPDF $fpdf, float $x, float $y, float $size): void diff --git a/vendor/endroid/qr-code/src/Writer/PngWriter.php b/vendor/endroid/qr-code/src/Writer/PngWriter.php index e944d84..e66a80e 100644 --- a/vendor/endroid/qr-code/src/Writer/PngWriter.php +++ b/vendor/endroid/qr-code/src/Writer/PngWriter.php @@ -5,6 +5,7 @@ declare(strict_types=1); namespace Endroid\QrCode\Writer; use Endroid\QrCode\Bacon\MatrixFactory; +use Endroid\QrCode\Exception\ValidationException; use Endroid\QrCode\ImageData\LabelImageData; use Endroid\QrCode\ImageData\LogoImageData; use Endroid\QrCode\Label\Alignment\LabelAlignmentLeft; @@ -110,7 +111,7 @@ final class PngWriter implements WriterInterface, ValidatingWriterInterface imagesavealpha($targetImage, true); } - $result = new PngResult($targetImage); + $result = new PngResult($matrix, $targetImage); if ($logo instanceof LogoInterface) { $result = $this->addLogo($logo, $result); @@ -174,7 +175,7 @@ final class PngWriter implements WriterInterface, ValidatingWriterInterface imagedestroy($logoImageData->getImage()); } - return new PngResult($targetImage); + return new PngResult($result->getMatrix(), $targetImage); } private function addLabel(LabelInterface $label, PngResult $result): PngResult @@ -203,7 +204,7 @@ final class PngWriter implements WriterInterface, ValidatingWriterInterface imagettftext($targetImage, $label->getFont()->getSize(), 0, $x, $y, $textColor, $label->getFont()->getPath(), $label->getText()); - return new PngResult($targetImage); + return new PngResult($result->getMatrix(), $targetImage); } public function validateResult(ResultInterface $result, string $expectedData): void @@ -211,17 +212,16 @@ final class PngWriter implements WriterInterface, ValidatingWriterInterface $string = $result->getString(); if (!class_exists(QrReader::class)) { - throw new \Exception('Please install khanamiryan/qrcode-detector-decoder or disable image validation'); + throw ValidationException::createForMissingPackage('khanamiryan/qrcode-detector-decoder'); } if (PHP_VERSION_ID >= 80000) { - throw new \Exception('The validator is not compatible with PHP 8 yet, see https://github.com/khanamiryan/php-qrcode-detector-decoder/pull/103'); + throw ValidationException::createForIncompatiblePhpVersion(); } $reader = new QrReader($string, QrReader::SOURCE_TYPE_BLOB); if ($reader->text() !== $expectedData) { - throw new \Exception('Built-in validation reader read "'.$reader->text().'" instead of "'.$expectedData.'". - Adjust your parameters to increase readability or disable built-in validation.'); + throw ValidationException::createForInvalidData($expectedData, strval($reader->text())); } } } diff --git a/vendor/endroid/qr-code/src/Writer/Result/AbstractResult.php b/vendor/endroid/qr-code/src/Writer/Result/AbstractResult.php index 43b680b..acc1e5c 100644 --- a/vendor/endroid/qr-code/src/Writer/Result/AbstractResult.php +++ b/vendor/endroid/qr-code/src/Writer/Result/AbstractResult.php @@ -4,8 +4,22 @@ declare(strict_types=1); namespace Endroid\QrCode\Writer\Result; +use Endroid\QrCode\Matrix\MatrixInterface; + abstract class AbstractResult implements ResultInterface { + private MatrixInterface $matrix; + + public function __construct(MatrixInterface $matrix) + { + $this->matrix = $matrix; + } + + public function getMatrix(): MatrixInterface + { + return $this->matrix; + } + public function getDataUri(): string { return 'data:'.$this->getMimeType().';base64,'.base64_encode($this->getString()); diff --git a/vendor/endroid/qr-code/src/Writer/Result/BinaryResult.php b/vendor/endroid/qr-code/src/Writer/Result/BinaryResult.php index 0618940..386fb6a 100644 --- a/vendor/endroid/qr-code/src/Writer/Result/BinaryResult.php +++ b/vendor/endroid/qr-code/src/Writer/Result/BinaryResult.php @@ -8,19 +8,19 @@ use Endroid\QrCode\Matrix\MatrixInterface; final class BinaryResult extends AbstractResult { - private MatrixInterface $matrix; - public function __construct(MatrixInterface $matrix) { - $this->matrix = $matrix; + parent::__construct($matrix); } public function getString(): string { + $matrix = $this->getMatrix(); + $binaryString = ''; - for ($rowIndex = 0; $rowIndex < $this->matrix->getBlockCount(); ++$rowIndex) { - for ($columnIndex = 0; $columnIndex < $this->matrix->getBlockCount(); ++$columnIndex) { - $binaryString .= $this->matrix->getBlockValue($rowIndex, $columnIndex); + for ($rowIndex = 0; $rowIndex < $matrix->getBlockCount(); ++$rowIndex) { + for ($columnIndex = 0; $columnIndex < $matrix->getBlockCount(); ++$columnIndex) { + $binaryString .= $matrix->getBlockValue($rowIndex, $columnIndex); } $binaryString .= "\n"; } diff --git a/vendor/endroid/qr-code/src/Writer/Result/ConsoleResult.php b/vendor/endroid/qr-code/src/Writer/Result/ConsoleResult.php index 98f5f04..1da8984 100644 --- a/vendor/endroid/qr-code/src/Writer/Result/ConsoleResult.php +++ b/vendor/endroid/qr-code/src/Writer/Result/ConsoleResult.php @@ -7,27 +7,24 @@ namespace Endroid\QrCode\Writer\Result; use Endroid\QrCode\Color\ColorInterface; use Endroid\QrCode\Matrix\MatrixInterface; -/** - * Implementation of ResultInterface for printing a QR-Code on command line interface. - */ class ConsoleResult extends AbstractResult { - protected MatrixInterface $matrix; - protected string $colorEscapeCode; - - public const twoblocks = [ + private const TWO_BLOCKS = [ 0 => ' ', 1 => "\xe2\x96\x80", 2 => "\xe2\x96\x84", 3 => "\xe2\x96\x88", ]; - /** - * Ctor. - */ - public function __construct(MatrixInterface $matrix, ColorInterface $foreground, ColorInterface $background) - { - $this->matrix = $matrix; + private string $colorEscapeCode; + + public function __construct( + MatrixInterface $matrix, + ColorInterface $foreground, + ColorInterface $background + ) { + parent::__construct($matrix); + $this->colorEscapeCode = sprintf( "\e[38;2;%d;%d;%dm\e[48;2;%d;%d;%dm", $foreground->getRed(), @@ -46,28 +43,27 @@ class ConsoleResult extends AbstractResult public function getString(): string { - $side = $this->matrix->getBlockCount(); - $marginLeft = $this->colorEscapeCode.self::twoblocks[0].self::twoblocks[0]; - $marginRight = self::twoblocks[0].self::twoblocks[0]."\e[0m".PHP_EOL; - $marginVertical = $marginLeft.str_repeat(self::twoblocks[0], $side).$marginRight; + $matrix = $this->getMatrix(); - ob_start(); - echo $marginVertical; // margin-top + $side = $matrix->getBlockCount(); + $marginLeft = $this->colorEscapeCode.self::TWO_BLOCKS[0].self::TWO_BLOCKS[0]; + $marginRight = self::TWO_BLOCKS[0].self::TWO_BLOCKS[0]."\e[0m".PHP_EOL; + $marginVertical = $marginLeft.str_repeat(self::TWO_BLOCKS[0], $side).$marginRight; + $qrCodeString = $marginVertical; for ($rowIndex = 0; $rowIndex < $side; $rowIndex += 2) { - echo $marginLeft; // margin-left + $qrCodeString .= $marginLeft; for ($columnIndex = 0; $columnIndex < $side; ++$columnIndex) { - $combined = $this->matrix->getBlockValue($rowIndex, $columnIndex); - if (($rowIndex + 1) < $side) { - $combined |= $this->matrix->getBlockValue($rowIndex + 1, $columnIndex) << 1; + $combined = $matrix->getBlockValue($rowIndex, $columnIndex); + if ($rowIndex + 1 < $side) { + $combined |= $matrix->getBlockValue($rowIndex + 1, $columnIndex) << 1; } - echo self::twoblocks[$combined]; + $qrCodeString .= self::TWO_BLOCKS[$combined]; } - echo $marginRight; // margin-right + $qrCodeString .= $marginRight; } + $qrCodeString .= $marginVertical; - echo $marginVertical; // margin-bottom - - return (string) ob_get_clean(); + return $qrCodeString; } } diff --git a/vendor/endroid/qr-code/src/Writer/Result/DebugResult.php b/vendor/endroid/qr-code/src/Writer/Result/DebugResult.php index c3cbff0..4c4fad2 100644 --- a/vendor/endroid/qr-code/src/Writer/Result/DebugResult.php +++ b/vendor/endroid/qr-code/src/Writer/Result/DebugResult.php @@ -6,6 +6,7 @@ namespace Endroid\QrCode\Writer\Result; use Endroid\QrCode\Label\LabelInterface; use Endroid\QrCode\Logo\LogoInterface; +use Endroid\QrCode\Matrix\MatrixInterface; use Endroid\QrCode\QrCodeInterface; final class DebugResult extends AbstractResult @@ -20,8 +21,15 @@ final class DebugResult extends AbstractResult private bool $validateResult = false; /** @param array $options */ - public function __construct(QrCodeInterface $qrCode, LogoInterface $logo = null, LabelInterface $label = null, array $options = []) - { + public function __construct( + MatrixInterface $matrix, + QrCodeInterface $qrCode, + LogoInterface $logo = null, + LabelInterface $label = null, + array $options = [] + ) { + parent::__construct($matrix); + $this->qrCode = $qrCode; $this->logo = $logo; $this->label = $label; diff --git a/vendor/endroid/qr-code/src/Writer/Result/EpsResult.php b/vendor/endroid/qr-code/src/Writer/Result/EpsResult.php index 0e55991..cda126a 100644 --- a/vendor/endroid/qr-code/src/Writer/Result/EpsResult.php +++ b/vendor/endroid/qr-code/src/Writer/Result/EpsResult.php @@ -4,14 +4,18 @@ declare(strict_types=1); namespace Endroid\QrCode\Writer\Result; +use Endroid\QrCode\Matrix\MatrixInterface; + final class EpsResult extends AbstractResult { /** @var array */ private array $lines; /** @param array $lines */ - public function __construct(array $lines) + public function __construct(MatrixInterface $matrix, array $lines) { + parent::__construct($matrix); + $this->lines = $lines; } diff --git a/vendor/endroid/qr-code/src/Writer/Result/PdfResult.php b/vendor/endroid/qr-code/src/Writer/Result/PdfResult.php index b4c644f..28445fc 100644 --- a/vendor/endroid/qr-code/src/Writer/Result/PdfResult.php +++ b/vendor/endroid/qr-code/src/Writer/Result/PdfResult.php @@ -4,12 +4,16 @@ declare(strict_types=1); namespace Endroid\QrCode\Writer\Result; +use Endroid\QrCode\Matrix\MatrixInterface; + final class PdfResult extends AbstractResult { private \FPDF $fpdf; - public function __construct(\FPDF $fpdf) + public function __construct(MatrixInterface $matrix, \FPDF $fpdf) { + parent::__construct($matrix); + $this->fpdf = $fpdf; } diff --git a/vendor/endroid/qr-code/src/Writer/Result/PngResult.php b/vendor/endroid/qr-code/src/Writer/Result/PngResult.php index efa26c5..bbf795d 100644 --- a/vendor/endroid/qr-code/src/Writer/Result/PngResult.php +++ b/vendor/endroid/qr-code/src/Writer/Result/PngResult.php @@ -4,14 +4,18 @@ declare(strict_types=1); namespace Endroid\QrCode\Writer\Result; +use Endroid\QrCode\Matrix\MatrixInterface; + final class PngResult extends AbstractResult { /** @var mixed */ private $image; /** @param mixed $image */ - public function __construct($image) + public function __construct(MatrixInterface $matrix, $image) { + parent::__construct($matrix); + $this->image = $image; } diff --git a/vendor/endroid/qr-code/src/Writer/Result/ResultInterface.php b/vendor/endroid/qr-code/src/Writer/Result/ResultInterface.php index a255605..2cd387e 100644 --- a/vendor/endroid/qr-code/src/Writer/Result/ResultInterface.php +++ b/vendor/endroid/qr-code/src/Writer/Result/ResultInterface.php @@ -4,8 +4,12 @@ declare(strict_types=1); namespace Endroid\QrCode\Writer\Result; +use Endroid\QrCode\Matrix\MatrixInterface; + interface ResultInterface { + public function getMatrix(): MatrixInterface; + public function getString(): string; public function getDataUri(): string; diff --git a/vendor/endroid/qr-code/src/Writer/Result/SvgResult.php b/vendor/endroid/qr-code/src/Writer/Result/SvgResult.php index 295202c..32ea84a 100644 --- a/vendor/endroid/qr-code/src/Writer/Result/SvgResult.php +++ b/vendor/endroid/qr-code/src/Writer/Result/SvgResult.php @@ -4,13 +4,20 @@ declare(strict_types=1); namespace Endroid\QrCode\Writer\Result; +use Endroid\QrCode\Matrix\MatrixInterface; + final class SvgResult extends AbstractResult { private \SimpleXMLElement $xml; private bool $excludeXmlDeclaration; - public function __construct(\SimpleXMLElement $xml, bool $excludeXmlDeclaration = false) - { + public function __construct( + MatrixInterface $matrix, + \SimpleXMLElement $xml, + bool $excludeXmlDeclaration = false + ) { + parent::__construct($matrix); + $this->xml = $xml; $this->excludeXmlDeclaration = $excludeXmlDeclaration; } diff --git a/vendor/endroid/qr-code/src/Writer/SvgWriter.php b/vendor/endroid/qr-code/src/Writer/SvgWriter.php index 29c4108..f0857c4 100644 --- a/vendor/endroid/qr-code/src/Writer/SvgWriter.php +++ b/vendor/endroid/qr-code/src/Writer/SvgWriter.php @@ -72,7 +72,7 @@ final class SvgWriter implements WriterInterface } } - $result = new SvgResult($xml, boolval($options[self::WRITER_OPTION_EXCLUDE_XML_DECLARATION])); + $result = new SvgResult($matrix, $xml, boolval($options[self::WRITER_OPTION_EXCLUDE_XML_DECLARATION])); if ($logo instanceof LogoInterface) { $this->addLogo($logo, $result, $options); diff --git a/vendor/league/flysystem/src/Adapter/Ftp.php b/vendor/league/flysystem/src/Adapter/Ftp.php index caa8b91..b7886bb 100644 --- a/vendor/league/flysystem/src/Adapter/Ftp.php +++ b/vendor/league/flysystem/src/Adapter/Ftp.php @@ -572,9 +572,9 @@ class Ftp extends AbstractFtpAdapter private function getRawExecResponseCode($command) { - $response = @ftp_raw($this->connection, trim($command)); + $response = @ftp_raw($this->connection, trim($command)) ?: []; - return (int) preg_replace('/\D/', '', implode(' ', $response)); + return (int) preg_replace('/\D/', '', implode(' ', (array) $response)); } private function hasFtpConnection(): bool diff --git a/vendor/services.php b/vendor/services.php index 9904150..14f61ff 100644 --- a/vendor/services.php +++ b/vendor/services.php @@ -1,5 +1,5 @@ 'taoser\\addons\\Service', diff --git a/vendor/symfony/var-exporter/CHANGELOG.md b/vendor/symfony/var-exporter/CHANGELOG.md new file mode 100644 index 0000000..3406c30 --- /dev/null +++ b/vendor/symfony/var-exporter/CHANGELOG.md @@ -0,0 +1,12 @@ +CHANGELOG +========= + +5.1.0 +----- + + * added argument `array &$foundClasses` to `VarExporter::export()` to ease with preloading exported values + +4.2.0 +----- + + * added the component diff --git a/vendor/symfony/var-exporter/Exception/ClassNotFoundException.php b/vendor/symfony/var-exporter/Exception/ClassNotFoundException.php new file mode 100644 index 0000000..4cebe44 --- /dev/null +++ b/vendor/symfony/var-exporter/Exception/ClassNotFoundException.php @@ -0,0 +1,20 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\VarExporter\Exception; + +class ClassNotFoundException extends \Exception implements ExceptionInterface +{ + public function __construct(string $class, \Throwable $previous = null) + { + parent::__construct(sprintf('Class "%s" not found.', $class), 0, $previous); + } +} diff --git a/vendor/symfony/var-exporter/Exception/ExceptionInterface.php b/vendor/symfony/var-exporter/Exception/ExceptionInterface.php new file mode 100644 index 0000000..adfaed4 --- /dev/null +++ b/vendor/symfony/var-exporter/Exception/ExceptionInterface.php @@ -0,0 +1,16 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\VarExporter\Exception; + +interface ExceptionInterface extends \Throwable +{ +} diff --git a/vendor/symfony/var-exporter/Exception/NotInstantiableTypeException.php b/vendor/symfony/var-exporter/Exception/NotInstantiableTypeException.php new file mode 100644 index 0000000..771ee61 --- /dev/null +++ b/vendor/symfony/var-exporter/Exception/NotInstantiableTypeException.php @@ -0,0 +1,20 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\VarExporter\Exception; + +class NotInstantiableTypeException extends \Exception implements ExceptionInterface +{ + public function __construct(string $type, \Throwable $previous = null) + { + parent::__construct(sprintf('Type "%s" is not instantiable.', $type), 0, $previous); + } +} diff --git a/vendor/symfony/var-exporter/Instantiator.php b/vendor/symfony/var-exporter/Instantiator.php new file mode 100644 index 0000000..368c769 --- /dev/null +++ b/vendor/symfony/var-exporter/Instantiator.php @@ -0,0 +1,92 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\VarExporter; + +use Symfony\Component\VarExporter\Exception\ExceptionInterface; +use Symfony\Component\VarExporter\Exception\NotInstantiableTypeException; +use Symfony\Component\VarExporter\Internal\Hydrator; +use Symfony\Component\VarExporter\Internal\Registry; + +/** + * A utility class to create objects without calling their constructor. + * + * @author Nicolas Grekas + */ +final class Instantiator +{ + /** + * Creates an object and sets its properties without calling its constructor nor any other methods. + * + * For example: + * + * // creates an empty instance of Foo + * Instantiator::instantiate(Foo::class); + * + * // creates a Foo instance and sets one of its properties + * Instantiator::instantiate(Foo::class, ['propertyName' => $propertyValue]); + * + * // creates a Foo instance and sets a private property defined on its parent Bar class + * Instantiator::instantiate(Foo::class, [], [ + * Bar::class => ['privateBarProperty' => $propertyValue], + * ]); + * + * Instances of ArrayObject, ArrayIterator and SplObjectStorage can be created + * by using the special "\0" property name to define their internal value: + * + * // creates an SplObjectStorage where $info1 is attached to $obj1, etc. + * Instantiator::instantiate(SplObjectStorage::class, ["\0" => [$obj1, $info1, $obj2, $info2...]]); + * + * // creates an ArrayObject populated with $inputArray + * Instantiator::instantiate(ArrayObject::class, ["\0" => [$inputArray]]); + * + * @param string $class The class of the instance to create + * @param array $properties The properties to set on the instance + * @param array $privateProperties The private properties to set on the instance, + * keyed by their declaring class + * + * @throws ExceptionInterface When the instance cannot be created + */ + public static function instantiate(string $class, array $properties = [], array $privateProperties = []): object + { + $reflector = Registry::$reflectors[$class] ?? Registry::getClassReflector($class); + + if (Registry::$cloneable[$class]) { + $wrappedInstance = [clone Registry::$prototypes[$class]]; + } elseif (Registry::$instantiableWithoutConstructor[$class]) { + $wrappedInstance = [$reflector->newInstanceWithoutConstructor()]; + } elseif (null === Registry::$prototypes[$class]) { + throw new NotInstantiableTypeException($class); + } elseif ($reflector->implementsInterface('Serializable') && (\PHP_VERSION_ID < 70400 || !method_exists($class, '__unserialize'))) { + $wrappedInstance = [unserialize('C:'.\strlen($class).':"'.$class.'":0:{}')]; + } else { + $wrappedInstance = [unserialize('O:'.\strlen($class).':"'.$class.'":0:{}')]; + } + + if ($properties) { + $privateProperties[$class] = isset($privateProperties[$class]) ? $properties + $privateProperties[$class] : $properties; + } + + foreach ($privateProperties as $class => $properties) { + if (!$properties) { + continue; + } + foreach ($properties as $name => $value) { + // because they're also used for "unserialization", hydrators + // deal with array of instances, so we need to wrap values + $properties[$name] = [$value]; + } + (Hydrator::$hydrators[$class] ?? Hydrator::getHydrator($class))($properties, $wrappedInstance); + } + + return $wrappedInstance[0]; + } +} diff --git a/vendor/symfony/var-exporter/Internal/Exporter.php b/vendor/symfony/var-exporter/Internal/Exporter.php new file mode 100644 index 0000000..a034ddd --- /dev/null +++ b/vendor/symfony/var-exporter/Internal/Exporter.php @@ -0,0 +1,406 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\VarExporter\Internal; + +use Symfony\Component\VarExporter\Exception\NotInstantiableTypeException; + +/** + * @author Nicolas Grekas + * + * @internal + */ +class Exporter +{ + /** + * Prepares an array of values for VarExporter. + * + * For performance this method is public and has no type-hints. + * + * @param array &$values + * @param \SplObjectStorage $objectsPool + * @param array &$refsPool + * @param int &$objectsCount + * @param bool &$valuesAreStatic + * + * @throws NotInstantiableTypeException When a value cannot be serialized + */ + public static function prepare($values, $objectsPool, &$refsPool, &$objectsCount, &$valuesAreStatic): array + { + $refs = $values; + foreach ($values as $k => $value) { + if (\is_resource($value)) { + throw new NotInstantiableTypeException(get_resource_type($value).' resource'); + } + $refs[$k] = $objectsPool; + + if ($isRef = !$valueIsStatic = $values[$k] !== $objectsPool) { + $values[$k] = &$value; // Break hard references to make $values completely + unset($value); // independent from the original structure + $refs[$k] = $value = $values[$k]; + if ($value instanceof Reference && 0 > $value->id) { + $valuesAreStatic = false; + ++$value->count; + continue; + } + $refsPool[] = [&$refs[$k], $value, &$value]; + $refs[$k] = $values[$k] = new Reference(-\count($refsPool), $value); + } + + if (\is_array($value)) { + if ($value) { + $value = self::prepare($value, $objectsPool, $refsPool, $objectsCount, $valueIsStatic); + } + goto handle_value; + } elseif (!\is_object($value) || $value instanceof \UnitEnum) { + goto handle_value; + } + + $valueIsStatic = false; + if (isset($objectsPool[$value])) { + ++$objectsCount; + $value = new Reference($objectsPool[$value][0]); + goto handle_value; + } + + $class = \get_class($value); + $reflector = Registry::$reflectors[$class] ?? Registry::getClassReflector($class); + + if ($reflector->hasMethod('__serialize')) { + if (!$reflector->getMethod('__serialize')->isPublic()) { + throw new \Error(sprintf('Call to %s method "%s::__serialize()".', $reflector->getMethod('__serialize')->isProtected() ? 'protected' : 'private', $class)); + } + + if (!\is_array($properties = $value->__serialize())) { + throw new \TypeError($class.'::__serialize() must return an array'); + } + + goto prepare_value; + } + + $properties = []; + $sleep = null; + $proto = Registry::$prototypes[$class]; + + if (($value instanceof \ArrayIterator || $value instanceof \ArrayObject) && null !== $proto) { + // ArrayIterator and ArrayObject need special care because their "flags" + // option changes the behavior of the (array) casting operator. + [$arrayValue, $properties] = self::getArrayObjectProperties($value, $proto); + + // populates Registry::$prototypes[$class] with a new instance + Registry::getClassReflector($class, Registry::$instantiableWithoutConstructor[$class], Registry::$cloneable[$class]); + } elseif ($value instanceof \SplObjectStorage && Registry::$cloneable[$class] && null !== $proto) { + // By implementing Serializable, SplObjectStorage breaks + // internal references; let's deal with it on our own. + foreach (clone $value as $v) { + $properties[] = $v; + $properties[] = $value[$v]; + } + $properties = ['SplObjectStorage' => ["\0" => $properties]]; + $arrayValue = (array) $value; + } elseif ($value instanceof \Serializable + || $value instanceof \__PHP_Incomplete_Class + || \PHP_VERSION_ID < 80200 && $value instanceof \DatePeriod + ) { + ++$objectsCount; + $objectsPool[$value] = [$id = \count($objectsPool), serialize($value), [], 0]; + $value = new Reference($id); + goto handle_value; + } else { + if (method_exists($class, '__sleep')) { + if (!\is_array($sleep = $value->__sleep())) { + trigger_error('serialize(): __sleep should return an array only containing the names of instance-variables to serialize', \E_USER_NOTICE); + $value = null; + goto handle_value; + } + $sleep = array_flip($sleep); + } + + $arrayValue = (array) $value; + } + + $proto = (array) $proto; + + foreach ($arrayValue as $name => $v) { + $i = 0; + $n = (string) $name; + if ('' === $n || "\0" !== $n[0]) { + $c = \PHP_VERSION_ID >= 80100 && $reflector->hasProperty($n) && ($p = $reflector->getProperty($n))->isReadOnly() ? $p->class : 'stdClass'; + } elseif ('*' === $n[1]) { + $n = substr($n, 3); + $c = $reflector->getProperty($n)->class; + if ('Error' === $c) { + $c = 'TypeError'; + } elseif ('Exception' === $c) { + $c = 'ErrorException'; + } + } else { + $i = strpos($n, "\0", 2); + $c = substr($n, 1, $i - 1); + $n = substr($n, 1 + $i); + } + if (null !== $sleep) { + if (!isset($sleep[$n]) || ($i && $c !== $class)) { + continue; + } + $sleep[$n] = false; + } + if (!\array_key_exists($name, $proto) || $proto[$name] !== $v || "\x00Error\x00trace" === $name || "\x00Exception\x00trace" === $name) { + $properties[$c][$n] = $v; + } + } + if ($sleep) { + foreach ($sleep as $n => $v) { + if (false !== $v) { + trigger_error(sprintf('serialize(): "%s" returned as member variable from __sleep() but does not exist', $n), \E_USER_NOTICE); + } + } + } + + prepare_value: + $objectsPool[$value] = [$id = \count($objectsPool)]; + $properties = self::prepare($properties, $objectsPool, $refsPool, $objectsCount, $valueIsStatic); + ++$objectsCount; + $objectsPool[$value] = [$id, $class, $properties, method_exists($class, '__unserialize') ? -$objectsCount : (method_exists($class, '__wakeup') ? $objectsCount : 0)]; + + $value = new Reference($id); + + handle_value: + if ($isRef) { + unset($value); // Break the hard reference created above + } elseif (!$valueIsStatic) { + $values[$k] = $value; + } + $valuesAreStatic = $valueIsStatic && $valuesAreStatic; + } + + return $values; + } + + public static function export($value, string $indent = '') + { + switch (true) { + case \is_int($value) || \is_float($value): return var_export($value, true); + case [] === $value: return '[]'; + case false === $value: return 'false'; + case true === $value: return 'true'; + case null === $value: return 'null'; + case '' === $value: return "''"; + case $value instanceof \UnitEnum: return ltrim(var_export($value, true), '\\'); + } + + if ($value instanceof Reference) { + if (0 <= $value->id) { + return '$o['.$value->id.']'; + } + if (!$value->count) { + return self::export($value->value, $indent); + } + $value = -$value->id; + + return '&$r['.$value.']'; + } + $subIndent = $indent.' '; + + if (\is_string($value)) { + $code = sprintf("'%s'", addcslashes($value, "'\\")); + + $code = preg_replace_callback("/((?:[\\0\\r\\n]|\u{202A}|\u{202B}|\u{202D}|\u{202E}|\u{2066}|\u{2067}|\u{2068}|\u{202C}|\u{2069})++)(.)/", function ($m) use ($subIndent) { + $m[1] = sprintf('\'."%s".\'', str_replace( + ["\0", "\r", "\n", "\u{202A}", "\u{202B}", "\u{202D}", "\u{202E}", "\u{2066}", "\u{2067}", "\u{2068}", "\u{202C}", "\u{2069}", '\n\\'], + ['\0', '\r', '\n', '\u{202A}', '\u{202B}', '\u{202D}', '\u{202E}', '\u{2066}', '\u{2067}', '\u{2068}', '\u{202C}', '\u{2069}', '\n"'."\n".$subIndent.'."\\'], + $m[1] + )); + + if ("'" === $m[2]) { + return substr($m[1], 0, -2); + } + + if ('n".\'' === substr($m[1], -4)) { + return substr_replace($m[1], "\n".$subIndent.".'".$m[2], -2); + } + + return $m[1].$m[2]; + }, $code, -1, $count); + + if ($count && str_starts_with($code, "''.")) { + $code = substr($code, 3); + } + + return $code; + } + + if (\is_array($value)) { + $j = -1; + $code = ''; + foreach ($value as $k => $v) { + $code .= $subIndent; + if (!\is_int($k) || 1 !== $k - $j) { + $code .= self::export($k, $subIndent).' => '; + } + if (\is_int($k) && $k > $j) { + $j = $k; + } + $code .= self::export($v, $subIndent).",\n"; + } + + return "[\n".$code.$indent.']'; + } + + if ($value instanceof Values) { + $code = $subIndent."\$r = [],\n"; + foreach ($value->values as $k => $v) { + $code .= $subIndent.'$r['.$k.'] = '.self::export($v, $subIndent).",\n"; + } + + return "[\n".$code.$indent.']'; + } + + if ($value instanceof Registry) { + return self::exportRegistry($value, $indent, $subIndent); + } + + if ($value instanceof Hydrator) { + return self::exportHydrator($value, $indent, $subIndent); + } + + throw new \UnexpectedValueException(sprintf('Cannot export value of type "%s".', get_debug_type($value))); + } + + private static function exportRegistry(Registry $value, string $indent, string $subIndent): string + { + $code = ''; + $serializables = []; + $seen = []; + $prototypesAccess = 0; + $factoriesAccess = 0; + $r = '\\'.Registry::class; + $j = -1; + + foreach ($value->classes as $k => $class) { + if (':' === ($class[1] ?? null)) { + $serializables[$k] = $class; + continue; + } + if (!Registry::$instantiableWithoutConstructor[$class]) { + if (is_subclass_of($class, 'Serializable') && !method_exists($class, '__unserialize')) { + $serializables[$k] = 'C:'.\strlen($class).':"'.$class.'":0:{}'; + } else { + $serializables[$k] = 'O:'.\strlen($class).':"'.$class.'":0:{}'; + } + if (is_subclass_of($class, 'Throwable')) { + $eol = is_subclass_of($class, 'Error') ? "\0Error\0" : "\0Exception\0"; + $serializables[$k] = substr_replace($serializables[$k], '1:{s:'.(5 + \strlen($eol)).':"'.$eol.'trace";a:0:{}}', -4); + } + continue; + } + $code .= $subIndent.(1 !== $k - $j ? $k.' => ' : ''); + $j = $k; + $eol = ",\n"; + $c = '['.self::export($class).']'; + + if ($seen[$class] ?? false) { + if (Registry::$cloneable[$class]) { + ++$prototypesAccess; + $code .= 'clone $p'.$c; + } else { + ++$factoriesAccess; + $code .= '$f'.$c.'()'; + } + } else { + $seen[$class] = true; + if (Registry::$cloneable[$class]) { + $code .= 'clone ('.($prototypesAccess++ ? '$p' : '($p = &'.$r.'::$prototypes)').$c.' ?? '.$r.'::p'; + } else { + $code .= '('.($factoriesAccess++ ? '$f' : '($f = &'.$r.'::$factories)').$c.' ?? '.$r.'::f'; + $eol = '()'.$eol; + } + $code .= '('.substr($c, 1, -1).'))'; + } + $code .= $eol; + } + + if (1 === $prototypesAccess) { + $code = str_replace('($p = &'.$r.'::$prototypes)', $r.'::$prototypes', $code); + } + if (1 === $factoriesAccess) { + $code = str_replace('($f = &'.$r.'::$factories)', $r.'::$factories', $code); + } + if ('' !== $code) { + $code = "\n".$code.$indent; + } + + if ($serializables) { + $code = $r.'::unserialize(['.$code.'], '.self::export($serializables, $indent).')'; + } else { + $code = '['.$code.']'; + } + + return '$o = '.$code; + } + + private static function exportHydrator(Hydrator $value, string $indent, string $subIndent): string + { + $code = ''; + foreach ($value->properties as $class => $properties) { + $code .= $subIndent.' '.self::export($class).' => '.self::export($properties, $subIndent.' ').",\n"; + } + + $code = [ + self::export($value->registry, $subIndent), + self::export($value->values, $subIndent), + '' !== $code ? "[\n".$code.$subIndent.']' : '[]', + self::export($value->value, $subIndent), + self::export($value->wakeups, $subIndent), + ]; + + return '\\'.\get_class($value)."::hydrate(\n".$subIndent.implode(",\n".$subIndent, $code)."\n".$indent.')'; + } + + /** + * @param \ArrayIterator|\ArrayObject $value + * @param \ArrayIterator|\ArrayObject $proto + */ + private static function getArrayObjectProperties($value, $proto): array + { + $reflector = $value instanceof \ArrayIterator ? 'ArrayIterator' : 'ArrayObject'; + $reflector = Registry::$reflectors[$reflector] ?? Registry::getClassReflector($reflector); + + $properties = [ + $arrayValue = (array) $value, + $reflector->getMethod('getFlags')->invoke($value), + $value instanceof \ArrayObject ? $reflector->getMethod('getIteratorClass')->invoke($value) : 'ArrayIterator', + ]; + + $reflector = $reflector->getMethod('setFlags'); + $reflector->invoke($proto, \ArrayObject::STD_PROP_LIST); + + if ($properties[1] & \ArrayObject::STD_PROP_LIST) { + $reflector->invoke($value, 0); + $properties[0] = (array) $value; + } else { + $reflector->invoke($value, \ArrayObject::STD_PROP_LIST); + $arrayValue = (array) $value; + } + $reflector->invoke($value, $properties[1]); + + if ([[], 0, 'ArrayIterator'] === $properties) { + $properties = []; + } else { + if ('ArrayIterator' === $properties[2]) { + unset($properties[2]); + } + $properties = [$reflector->class => ["\0" => $properties]]; + } + + return [$arrayValue, $properties]; + } +} diff --git a/vendor/symfony/var-exporter/Internal/Hydrator.php b/vendor/symfony/var-exporter/Internal/Hydrator.php new file mode 100644 index 0000000..5ed6bdc --- /dev/null +++ b/vendor/symfony/var-exporter/Internal/Hydrator.php @@ -0,0 +1,152 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\VarExporter\Internal; + +use Symfony\Component\VarExporter\Exception\ClassNotFoundException; + +/** + * @author Nicolas Grekas + * + * @internal + */ +class Hydrator +{ + public static $hydrators = []; + + public $registry; + public $values; + public $properties; + public $value; + public $wakeups; + + public function __construct(?Registry $registry, ?Values $values, array $properties, $value, array $wakeups) + { + $this->registry = $registry; + $this->values = $values; + $this->properties = $properties; + $this->value = $value; + $this->wakeups = $wakeups; + } + + public static function hydrate($objects, $values, $properties, $value, $wakeups) + { + foreach ($properties as $class => $vars) { + (self::$hydrators[$class] ?? self::getHydrator($class))($vars, $objects); + } + foreach ($wakeups as $k => $v) { + if (\is_array($v)) { + $objects[-$k]->__unserialize($v); + } else { + $objects[$v]->__wakeup(); + } + } + + return $value; + } + + public static function getHydrator($class) + { + switch ($class) { + case 'stdClass': + return self::$hydrators[$class] = static function ($properties, $objects) { + foreach ($properties as $name => $values) { + foreach ($values as $i => $v) { + $objects[$i]->$name = $v; + } + } + }; + + case 'ErrorException': + return self::$hydrators[$class] = (self::$hydrators['stdClass'] ?? self::getHydrator('stdClass'))->bindTo(null, new class() extends \ErrorException { + }); + + case 'TypeError': + return self::$hydrators[$class] = (self::$hydrators['stdClass'] ?? self::getHydrator('stdClass'))->bindTo(null, new class() extends \Error { + }); + + case 'SplObjectStorage': + return self::$hydrators[$class] = static function ($properties, $objects) { + foreach ($properties as $name => $values) { + if ("\0" === $name) { + foreach ($values as $i => $v) { + for ($j = 0; $j < \count($v); ++$j) { + $objects[$i]->attach($v[$j], $v[++$j]); + } + } + continue; + } + foreach ($values as $i => $v) { + $objects[$i]->$name = $v; + } + } + }; + } + + if (!class_exists($class) && !interface_exists($class, false) && !trait_exists($class, false)) { + throw new ClassNotFoundException($class); + } + $classReflector = new \ReflectionClass($class); + + switch ($class) { + case 'ArrayIterator': + case 'ArrayObject': + $constructor = \Closure::fromCallable([$classReflector->getConstructor(), 'invokeArgs']); + + return self::$hydrators[$class] = static function ($properties, $objects) use ($constructor) { + foreach ($properties as $name => $values) { + if ("\0" !== $name) { + foreach ($values as $i => $v) { + $objects[$i]->$name = $v; + } + } + } + foreach ($properties["\0"] ?? [] as $i => $v) { + $constructor($objects[$i], $v); + } + }; + } + + if (!$classReflector->isInternal()) { + return self::$hydrators[$class] = (self::$hydrators['stdClass'] ?? self::getHydrator('stdClass'))->bindTo(null, $class); + } + + if ($classReflector->name !== $class) { + return self::$hydrators[$classReflector->name] ?? self::getHydrator($classReflector->name); + } + + $propertySetters = []; + foreach ($classReflector->getProperties() as $propertyReflector) { + if (!$propertyReflector->isStatic()) { + $propertyReflector->setAccessible(true); + $propertySetters[$propertyReflector->name] = \Closure::fromCallable([$propertyReflector, 'setValue']); + } + } + + if (!$propertySetters) { + return self::$hydrators[$class] = self::$hydrators['stdClass'] ?? self::getHydrator('stdClass'); + } + + return self::$hydrators[$class] = static function ($properties, $objects) use ($propertySetters) { + foreach ($properties as $name => $values) { + if ($setValue = $propertySetters[$name] ?? null) { + foreach ($values as $i => $v) { + $setValue($objects[$i], $v); + } + continue; + } + foreach ($values as $i => $v) { + $objects[$i]->$name = $v; + } + } + }; + } +} diff --git a/vendor/symfony/var-exporter/Internal/Reference.php b/vendor/symfony/var-exporter/Internal/Reference.php new file mode 100644 index 0000000..e371c07 --- /dev/null +++ b/vendor/symfony/var-exporter/Internal/Reference.php @@ -0,0 +1,30 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\VarExporter\Internal; + +/** + * @author Nicolas Grekas + * + * @internal + */ +class Reference +{ + public $id; + public $value; + public $count = 0; + + public function __construct(int $id, $value = null) + { + $this->id = $id; + $this->value = $value; + } +} diff --git a/vendor/symfony/var-exporter/Internal/Registry.php b/vendor/symfony/var-exporter/Internal/Registry.php new file mode 100644 index 0000000..24b77b9 --- /dev/null +++ b/vendor/symfony/var-exporter/Internal/Registry.php @@ -0,0 +1,146 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\VarExporter\Internal; + +use Symfony\Component\VarExporter\Exception\ClassNotFoundException; +use Symfony\Component\VarExporter\Exception\NotInstantiableTypeException; + +/** + * @author Nicolas Grekas + * + * @internal + */ +class Registry +{ + public static $reflectors = []; + public static $prototypes = []; + public static $factories = []; + public static $cloneable = []; + public static $instantiableWithoutConstructor = []; + + public $classes = []; + + public function __construct(array $classes) + { + $this->classes = $classes; + } + + public static function unserialize($objects, $serializables) + { + $unserializeCallback = ini_set('unserialize_callback_func', __CLASS__.'::getClassReflector'); + + try { + foreach ($serializables as $k => $v) { + $objects[$k] = unserialize($v); + } + } finally { + ini_set('unserialize_callback_func', $unserializeCallback); + } + + return $objects; + } + + public static function p($class) + { + self::getClassReflector($class, true, true); + + return self::$prototypes[$class]; + } + + public static function f($class) + { + $reflector = self::$reflectors[$class] ?? self::getClassReflector($class, true, false); + + return self::$factories[$class] = \Closure::fromCallable([$reflector, 'newInstanceWithoutConstructor']); + } + + public static function getClassReflector($class, $instantiableWithoutConstructor = false, $cloneable = null) + { + if (!($isClass = class_exists($class)) && !interface_exists($class, false) && !trait_exists($class, false)) { + throw new ClassNotFoundException($class); + } + $reflector = new \ReflectionClass($class); + + if ($instantiableWithoutConstructor) { + $proto = $reflector->newInstanceWithoutConstructor(); + } elseif (!$isClass || $reflector->isAbstract()) { + throw new NotInstantiableTypeException($class); + } elseif ($reflector->name !== $class) { + $reflector = self::$reflectors[$name = $reflector->name] ?? self::getClassReflector($name, false, $cloneable); + self::$cloneable[$class] = self::$cloneable[$name]; + self::$instantiableWithoutConstructor[$class] = self::$instantiableWithoutConstructor[$name]; + self::$prototypes[$class] = self::$prototypes[$name]; + + return self::$reflectors[$class] = $reflector; + } else { + try { + $proto = $reflector->newInstanceWithoutConstructor(); + $instantiableWithoutConstructor = true; + } catch (\ReflectionException $e) { + $proto = $reflector->implementsInterface('Serializable') && !method_exists($class, '__unserialize') ? 'C:' : 'O:'; + if ('C:' === $proto && !$reflector->getMethod('unserialize')->isInternal()) { + $proto = null; + } else { + try { + $proto = @unserialize($proto.\strlen($class).':"'.$class.'":0:{}'); + } catch (\Exception $e) { + if (__FILE__ !== $e->getFile()) { + throw $e; + } + throw new NotInstantiableTypeException($class, $e); + } + if (false === $proto) { + throw new NotInstantiableTypeException($class); + } + } + } + if (null !== $proto && !$proto instanceof \Throwable && !$proto instanceof \Serializable && !method_exists($class, '__sleep') && (\PHP_VERSION_ID < 70400 || !method_exists($class, '__serialize'))) { + try { + serialize($proto); + } catch (\Exception $e) { + throw new NotInstantiableTypeException($class, $e); + } + } + } + + if (null === $cloneable) { + if (($proto instanceof \Reflector || $proto instanceof \ReflectionGenerator || $proto instanceof \ReflectionType || $proto instanceof \IteratorIterator || $proto instanceof \RecursiveIteratorIterator) && (!$proto instanceof \Serializable && !method_exists($proto, '__wakeup') && (\PHP_VERSION_ID < 70400 || !method_exists($class, '__unserialize')))) { + throw new NotInstantiableTypeException($class); + } + + $cloneable = $reflector->isCloneable() && !$reflector->hasMethod('__clone'); + } + + self::$cloneable[$class] = $cloneable; + self::$instantiableWithoutConstructor[$class] = $instantiableWithoutConstructor; + self::$prototypes[$class] = $proto; + + if ($proto instanceof \Throwable) { + static $setTrace; + + if (null === $setTrace) { + $setTrace = [ + new \ReflectionProperty(\Error::class, 'trace'), + new \ReflectionProperty(\Exception::class, 'trace'), + ]; + $setTrace[0]->setAccessible(true); + $setTrace[1]->setAccessible(true); + $setTrace[0] = \Closure::fromCallable([$setTrace[0], 'setValue']); + $setTrace[1] = \Closure::fromCallable([$setTrace[1], 'setValue']); + } + + $setTrace[$proto instanceof \Exception]($proto, []); + } + + return self::$reflectors[$class] = $reflector; + } +} diff --git a/vendor/symfony/var-exporter/Internal/Values.php b/vendor/symfony/var-exporter/Internal/Values.php new file mode 100644 index 0000000..21ae04e --- /dev/null +++ b/vendor/symfony/var-exporter/Internal/Values.php @@ -0,0 +1,27 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\VarExporter\Internal; + +/** + * @author Nicolas Grekas + * + * @internal + */ +class Values +{ + public $values; + + public function __construct(array $values) + { + $this->values = $values; + } +} diff --git a/vendor/symfony/var-exporter/LICENSE b/vendor/symfony/var-exporter/LICENSE new file mode 100644 index 0000000..74cdc2d --- /dev/null +++ b/vendor/symfony/var-exporter/LICENSE @@ -0,0 +1,19 @@ +Copyright (c) 2018-2022 Fabien Potencier + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is furnished +to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/vendor/symfony/var-exporter/README.md b/vendor/symfony/var-exporter/README.md new file mode 100644 index 0000000..a34e4c2 --- /dev/null +++ b/vendor/symfony/var-exporter/README.md @@ -0,0 +1,38 @@ +VarExporter Component +===================== + +The VarExporter component allows exporting any serializable PHP data structure to +plain PHP code. While doing so, it preserves all the semantics associated with +the serialization mechanism of PHP (`__wakeup`, `__sleep`, `Serializable`, +`__serialize`, `__unserialize`). + +It also provides an instantiator that allows creating and populating objects +without calling their constructor nor any other methods. + +The reason to use this component *vs* `serialize()` or +[igbinary](https://github.com/igbinary/igbinary) is performance: thanks to +OPcache, the resulting code is significantly faster and more memory efficient +than using `unserialize()` or `igbinary_unserialize()`. + +Unlike `var_export()`, this works on any serializable PHP value. + +It also provides a few improvements over `var_export()`/`serialize()`: + + * the output is PSR-2 compatible; + * the output can be re-indented without messing up with `\r` or `\n` in the data + * missing classes throw a `ClassNotFoundException` instead of being unserialized to + `PHP_Incomplete_Class` objects; + * references involving `SplObjectStorage`, `ArrayObject` or `ArrayIterator` + instances are preserved; + * `Reflection*`, `IteratorIterator` and `RecursiveIteratorIterator` classes + throw an exception when being serialized (their unserialized version is broken + anyway, see https://bugs.php.net/76737). + +Resources +--------- + + * [Documentation](https://symfony.com/doc/current/components/var_exporter.html) + * [Contributing](https://symfony.com/doc/current/contributing/index.html) + * [Report issues](https://github.com/symfony/symfony/issues) and + [send Pull Requests](https://github.com/symfony/symfony/pulls) + in the [main Symfony repository](https://github.com/symfony/symfony) diff --git a/vendor/symfony/var-exporter/VarExporter.php b/vendor/symfony/var-exporter/VarExporter.php new file mode 100644 index 0000000..003388e --- /dev/null +++ b/vendor/symfony/var-exporter/VarExporter.php @@ -0,0 +1,115 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\VarExporter; + +use Symfony\Component\VarExporter\Exception\ExceptionInterface; +use Symfony\Component\VarExporter\Internal\Exporter; +use Symfony\Component\VarExporter\Internal\Hydrator; +use Symfony\Component\VarExporter\Internal\Registry; +use Symfony\Component\VarExporter\Internal\Values; + +/** + * Exports serializable PHP values to PHP code. + * + * VarExporter allows serializing PHP data structures to plain PHP code (like var_export()) + * while preserving all the semantics associated with serialize() (unlike var_export()). + * + * By leveraging OPcache, the generated PHP code is faster than doing the same with unserialize(). + * + * @author Nicolas Grekas + */ +final class VarExporter +{ + /** + * Exports a serializable PHP value to PHP code. + * + * @param mixed $value The value to export + * @param bool &$isStaticValue Set to true after execution if the provided value is static, false otherwise + * @param bool &$classes Classes found in the value are added to this list as both keys and values + * + * @throws ExceptionInterface When the provided value cannot be serialized + */ + public static function export($value, bool &$isStaticValue = null, array &$foundClasses = []): string + { + $isStaticValue = true; + + if (!\is_object($value) && !(\is_array($value) && $value) && !\is_resource($value) || $value instanceof \UnitEnum) { + return Exporter::export($value); + } + + $objectsPool = new \SplObjectStorage(); + $refsPool = []; + $objectsCount = 0; + + try { + $value = Exporter::prepare([$value], $objectsPool, $refsPool, $objectsCount, $isStaticValue)[0]; + } finally { + $references = []; + foreach ($refsPool as $i => $v) { + if ($v[0]->count) { + $references[1 + $i] = $v[2]; + } + $v[0] = $v[1]; + } + } + + if ($isStaticValue) { + return Exporter::export($value); + } + + $classes = []; + $values = []; + $states = []; + foreach ($objectsPool as $i => $v) { + [, $class, $values[], $wakeup] = $objectsPool[$v]; + $foundClasses[$class] = $classes[] = $class; + + if (0 < $wakeup) { + $states[$wakeup] = $i; + } elseif (0 > $wakeup) { + $states[-$wakeup] = [$i, array_pop($values)]; + $values[] = []; + } + } + ksort($states); + + $wakeups = [null]; + foreach ($states as $k => $v) { + if (\is_array($v)) { + $wakeups[-$v[0]] = $v[1]; + } else { + $wakeups[] = $v; + } + } + + if (null === $wakeups[0]) { + unset($wakeups[0]); + } + + $properties = []; + foreach ($values as $i => $vars) { + foreach ($vars as $class => $values) { + foreach ($values as $name => $v) { + $properties[$class][$name][$i] = $v; + } + } + } + + if ($classes || $references) { + $value = new Hydrator(new Registry($classes), $references ? new Values($references) : null, $properties, $value, $wakeups); + } else { + $isStaticValue = true; + } + + return Exporter::export($value); + } +} diff --git a/vendor/symfony/var-exporter/composer.json b/vendor/symfony/var-exporter/composer.json new file mode 100644 index 0000000..29d4901 --- /dev/null +++ b/vendor/symfony/var-exporter/composer.json @@ -0,0 +1,32 @@ +{ + "name": "symfony/var-exporter", + "type": "library", + "description": "Allows exporting any serializable PHP data structure to plain PHP code", + "keywords": ["export", "serialize", "instantiate", "hydrate", "construct", "clone"], + "homepage": "https://symfony.com", + "license": "MIT", + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "require": { + "php": ">=7.2.5", + "symfony/polyfill-php80": "^1.16" + }, + "require-dev": { + "symfony/var-dumper": "^4.4.9|^5.0.9|^6.0" + }, + "autoload": { + "psr-4": { "Symfony\\Component\\VarExporter\\": "" }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "minimum-stability": "dev" +} diff --git a/vendor/taoser/think-addons/.idea/.gitignore b/vendor/taoser/think-addons/.idea/.gitignore new file mode 100644 index 0000000..35410ca --- /dev/null +++ b/vendor/taoser/think-addons/.idea/.gitignore @@ -0,0 +1,8 @@ +# 默认忽略的文件 +/shelf/ +/workspace.xml +# 基于编辑器的 HTTP 客户端请求 +/httpRequests/ +# Datasource local storage ignored files +/dataSources/ +/dataSources.local.xml diff --git a/vendor/taoser/think-addons/.idea/modules.xml b/vendor/taoser/think-addons/.idea/modules.xml new file mode 100644 index 0000000..19996b5 --- /dev/null +++ b/vendor/taoser/think-addons/.idea/modules.xml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/vendor/taoser/think-addons/.idea/php.xml b/vendor/taoser/think-addons/.idea/php.xml new file mode 100644 index 0000000..10b171f --- /dev/null +++ b/vendor/taoser/think-addons/.idea/php.xml @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/vendor/taoser/think-addons/.idea/think-addons.iml b/vendor/taoser/think-addons/.idea/think-addons.iml new file mode 100644 index 0000000..314c2bf --- /dev/null +++ b/vendor/taoser/think-addons/.idea/think-addons.iml @@ -0,0 +1,12 @@ + + + + + + + + + + + + \ No newline at end of file diff --git a/vendor/taoser/think-addons/.idea/vcs.xml b/vendor/taoser/think-addons/.idea/vcs.xml new file mode 100644 index 0000000..94a25f7 --- /dev/null +++ b/vendor/taoser/think-addons/.idea/vcs.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/vendor/taoser/think-addons/README.md b/vendor/taoser/think-addons/README.md index e22ba1c..5ca893c 100644 --- a/vendor/taoser/think-addons/README.md +++ b/vendor/taoser/think-addons/README.md @@ -28,7 +28,9 @@ php think addons:config 'testhook'=>'test' // 键为钩子名称,用于在业务中自定义钩子处理,值为实现该钩子的插件, // 多个插件可以用数组也可以用逗号分割 ], - 'route' => [], + 'route' => [ + "/demo" => "demo/test/demo", // 键为请求中的路由地址,值为插件/控制器/方法 + ], 'service' => [], ]; ``` diff --git a/vendor/taoser/think-addons/composer.json b/vendor/taoser/think-addons/composer.json index d4879cf..81d0f06 100644 --- a/vendor/taoser/think-addons/composer.json +++ b/vendor/taoser/think-addons/composer.json @@ -12,7 +12,8 @@ "php": ">=7.1.0", "topthink/framework": "^6.0", "topthink/think-view": "^1.0", - "topthink/think-helper": "^3.0.0" + "topthink/think-helper": "^3.0.0", + "symfony/var-exporter": "^5.4" }, "autoload": { "psr-4": { diff --git a/vendor/taoser/think-addons/src/addons/Controller.php b/vendor/taoser/think-addons/src/addons/Controller.php index 16d1d5e..4985fff 100644 --- a/vendor/taoser/think-addons/src/addons/Controller.php +++ b/vendor/taoser/think-addons/src/addons/Controller.php @@ -7,6 +7,7 @@ namespace taoser\addons; use app\BaseController; use think\App; use think\helper\Str; +use think\facade\Lang; use think\facade\Config; use think\facade\View; diff --git a/vendor/taoser/think-addons/src/addons/Service.php b/vendor/taoser/think-addons/src/addons/Service.php index b78b0b9..f921ad4 100644 --- a/vendor/taoser/think-addons/src/addons/Service.php +++ b/vendor/taoser/think-addons/src/addons/Service.php @@ -29,16 +29,14 @@ class Service extends \think\Service // 自动载入插件 $this->autoload(); // 加载系统语言包 - Lang::load([ - $this->app->getRootPath() . '/vendor/taoser/think-addons/src/lang/zh-cn.php' - ]); - + $this->loadLang(); + // 加载自定义路由 $this->loadRoutes(); // 加载插件事件 $this->loadEvent(); // 加载插件系统服务 $this->loadService(); - //加载配置 + // 加载配置 $this->loadConfig(); } @@ -67,7 +65,7 @@ class Service extends \think\Service foreach ($val['rule'] as $k => $rule) { [$addon, $controller, $action] = explode('/', $rule); $rules[$k] = [ - 'addons' => $addon, + 'addon' => $addon, 'controller' => $controller, 'action' => $action, 'indomain' => 1, @@ -88,7 +86,7 @@ class Service extends \think\Service ->name($key) ->completeMatch(true) ->append([ - 'addons' => $addon, + 'addon' => $addon, 'controller' => $controller, 'action' => $action ]); @@ -97,6 +95,13 @@ class Service extends \think\Service }); } + private function loadLang() + { + Lang::load([ + $this->app->getRootPath() . '/vendor/taoser/think-addons/src/lang/zh-cn.php' + ]); + } + /** * 自定义路由文件 */ diff --git a/vendor/taoser/think-addons/src/helper.php b/vendor/taoser/think-addons/src/helper.php index 912ec0c..b726ddc 100644 --- a/vendor/taoser/think-addons/src/helper.php +++ b/vendor/taoser/think-addons/src/helper.php @@ -10,6 +10,9 @@ use think\facade\Cache; use think\helper\{ Str, Arr }; +use Symfony\Component\VarExporter\VarExporter; + +define('DS', DIRECTORY_SEPARATOR); \think\Console::starting(function (\think\Console $console) { $console->addCommands([ @@ -22,9 +25,7 @@ spl_autoload_register(function ($class) { $class = ltrim($class, '\\'); - //$dir = app()->getRootPath(); - $app = new App(); - $dir = $app::getRootPath(); + $dir = App::getRootPath(); $namespace = 'addons'; if (strpos($class, $namespace) === 0) { @@ -41,12 +42,9 @@ spl_autoload_register(function ($class) { include $dir; return true; } - return false; } - return false; - }); if (!function_exists('hook')) { @@ -82,49 +80,6 @@ if (!function_exists('get_addons_info')) { } } -/** - * 设置基础配置信息 - * @param string $name 插件名 - * @param array $array 配置数据 - * @return boolean - * @throws Exception - */ -if (!function_exists('set_addons_info')) { - - function set_addons_info($name, $array) - { - $service = new Service(App::instance()); // 获取service 服务 - $addons_path = $service->getAddonsPath(); - // 插件列表 - $file = $addons_path . $name . DIRECTORY_SEPARATOR . 'info.ini'; - $addon = get_addons_instance($name); - $array = $addon->setInfo($name, $array); - $array['status'] ? $addon->enabled() : $addon->disabled(); - if (!isset($array['name']) || !isset($array['title']) || !isset($array['version'])) { - throw new Exception("Failed to write plugin config"); - } - $res = array(); - foreach ($array as $key => $val) { - if (is_array($val)) { - $res[] = "[$key]"; - foreach ($val as $k => $v) - $res[] = "$k = " . (is_numeric($v) ? $v : $v); - } else - $res[] = "$key = " . (is_numeric($val) ? $val : $val); - } - - if ($handle = fopen($file, 'w')) { - fwrite($handle, implode("\n", $res) . "\n"); - fclose($handle); - //清空当前配置缓存 - Config::set($array, "addon_{$name}_info"); - Cache::delete('addonslist'); - } else { - throw new Exception("File does not have write permission"); - } - return true; - } -} if (!function_exists('get_addons_instance')) { /** @@ -181,45 +136,6 @@ if (!function_exists('get_addons_class')) { } } -if (!function_exists('get_addons_config')) { - /** - * 获取插件的配置 - * @param string $name 插件名 - * @return mixed|null - */ - function get_addons_config($name) - { - $addon = get_addons_instance($name); - if (!$addon) { - return []; - } - - return $addon->getConfig($name); - } -} - -if (!function_exists('set_addons_config')) { - - function set_addons_config($name, $array) - { - $service = new Service(App::instance()); // 获取service 服务 - $addons_path = $service->getAddonsPath(); - // 插件列表 - $file = $addons_path . $name . DIRECTORY_SEPARATOR . 'config.php'; - if (!is_writable($file)) { - throw new \Exception(lang("addons.php File does not have write permission")); - } - if ($handle = fopen($file, 'w')) { - fwrite($handle, "getAddonsPath(); + // 插件列表 + $file = $addons_path . $name . DIRECTORY_SEPARATOR . 'info.ini'; + $addon = get_addons_instance($name); + $array = $addon->setInfo($name, $array); + $array['status'] ? $addon->enabled() : $addon->disabled(); + if (!isset($array['name']) || !isset($array['title']) || !isset($array['version'])) { + throw new Exception("Failed to write plugin config"); + } + $res = array(); + foreach ($array as $key => $val) { + if (is_array($val)) { + $res[] = "[$key]"; + foreach ($val as $k => $v) + $res[] = "$k = " . (is_numeric($v) ? $v : $v); + } else + $res[] = "$key = " . (is_numeric($val) ? $val : $val); + } + + if ($handle = fopen($file, 'w')) { + fwrite($handle, implode("\n", $res) . "\n"); + fclose($handle); + //清空当前配置缓存 + Config::set($array, "addon_{$name}_info"); + Cache::delete('addonslist'); + } else { + throw new Exception("File does not have write permission"); + } + return true; + } +} + + +if (!function_exists('get_addons_config')) { + /** + * 获取插件的配置 + * @param string $name 插件名 + * @return mixed|null + */ + function get_addons_config($name) + { + $addon = get_addons_instance($name); + if (!$addon) { + return []; + } + + return $addon->getConfig($name); + } +} + +if (!function_exists('set_addons_config')) { + /** + * 设置插件配置文件 + * @param string $name + * @param array $array + * @return bool + * @throws Exception + */ + function set_addons_config(string $name, array $array) + { + $service = new Service(App::instance()); // 获取service 服务 + $addons_path = $service->getAddonsPath(); + // 插件列表 + $file = $addons_path . $name . DIRECTORY_SEPARATOR . 'config.php'; + if (!is_writable($file)) { + throw new \Exception(lang("addons.php File does not have write permission")); + } + if ($handle = fopen($file, 'w')) { + fwrite($handle, "getRootPath() . 'addons' . DS . $name . DS . 'menu.php'; + if(file_exists($menu)){ + return include_once $menu; + } + return []; + } +} + diff --git a/vendor/workerman/workerman/Protocols/Http.php b/vendor/workerman/workerman/Protocols/Http.php index e6df897..9e5d928 100644 --- a/vendor/workerman/workerman/Protocols/Http.php +++ b/vendor/workerman/workerman/Protocols/Http.php @@ -94,60 +94,58 @@ class Http */ public static function input($recv_buffer, TcpConnection $connection) { - static $input = array(); + static $input = []; if (!isset($recv_buffer[512]) && isset($input[$recv_buffer])) { return $input[$recv_buffer]; } $crlf_pos = \strpos($recv_buffer, "\r\n\r\n"); if (false === $crlf_pos) { // Judge whether the package length exceeds the limit. - if ($recv_len = \strlen($recv_buffer) >= 16384) { + if (\strlen($recv_buffer) >= 16384) { $connection->close("HTTP/1.1 413 Request Entity Too Large\r\n\r\n", true); return 0; } return 0; } - $head_len = $crlf_pos + 4; + $length = $crlf_pos + 4; $method = \strstr($recv_buffer, ' ', true); - if ($method === 'GET' || $method === 'OPTIONS' || $method === 'HEAD' || $method === 'DELETE') { - if (!isset($recv_buffer[512])) { - $input[$recv_buffer] = $head_len; - if (\count($input) > 512) { - unset($input[key($input)]); - } - } - return $head_len; - } else if ($method !== 'POST' && $method !== 'PUT' && $method !== 'PATCH') { + if (!\in_array($method, ['GET', 'POST', 'OPTIONS', 'HEAD', 'DELETE', 'PUT', 'PATCH'])) { $connection->close("HTTP/1.1 400 Bad Request\r\n\r\n", true); return 0; } $header = \substr($recv_buffer, 0, $crlf_pos); - $length = false; if ($pos = \strpos($header, "\r\nContent-Length: ")) { - $length = $head_len + (int)\substr($header, $pos + 18, 10); + $length = $length + (int)\substr($header, $pos + 18, 10); + $has_content_length = true; } else if (\preg_match("/\r\ncontent-length: ?(\d+)/i", $header, $match)) { - $length = $head_len + $match[1]; + $length = $length + $match[1]; + $has_content_length = true; + } else { + $has_content_length = false; + if (false !== stripos($header, "\r\nTransfer-Encoding:")) { + $connection->close("HTTP/1.1 400 Bad Request\r\n\r\n", true); + return 0; + } } - if ($length !== false) { - if (!isset($recv_buffer[512])) { - $input[$recv_buffer] = $length; - if (\count($input) > 512) { - unset($input[key($input)]); - } - } + if ($has_content_length) { if ($length > $connection->maxPackageSize) { $connection->close("HTTP/1.1 413 Request Entity Too Large\r\n\r\n", true); return 0; } - return $length; } - $connection->close("HTTP/1.1 400 Bad Request\r\n\r\n", true); - return 0; + if (!isset($recv_buffer[512])) { + $input[$recv_buffer] = $length; + if (\count($input) > 512) { + unset($input[key($input)]); + } + } + + return $length; } /** @@ -221,6 +219,7 @@ class Http $file = $response->file['file']; $offset = $response->file['offset']; $length = $response->file['length']; + clearstatcache(); $file_size = (int)\filesize($file); $body_len = $length > 0 ? $length : $file_size - $offset; $response->withHeaders(array( diff --git a/vendor/workerman/workerman/Protocols/Http/Request.php b/vendor/workerman/workerman/Protocols/Http/Request.php index 47f7f0a..39e9998 100644 --- a/vendor/workerman/workerman/Protocols/Http/Request.php +++ b/vendor/workerman/workerman/Protocols/Http/Request.php @@ -520,6 +520,9 @@ class Request { $file = []; $boundary = "\r\n$boundary"; + if (\strlen($this->_buffer) < $section_start_offset) { + return 0; + } $section_end_offset = \strpos($this->_buffer, $boundary, $section_start_offset); if (!$section_end_offset) { return 0; diff --git a/vendor/workerman/workerman/Worker.php b/vendor/workerman/workerman/Worker.php index 03c6e38..738b171 100644 --- a/vendor/workerman/workerman/Worker.php +++ b/vendor/workerman/workerman/Worker.php @@ -33,7 +33,7 @@ class Worker * * @var string */ - const VERSION = '4.1.0'; + const VERSION = '4.1.3'; /** * Status starting. @@ -548,11 +548,13 @@ class Worker { static::checkSapiEnv(); static::init(); + static::lock(); static::parseCommand(); static::daemonize(); static::initWorkers(); static::installSignal(); static::saveMasterPid(); + static::lock(\LOCK_UN); static::displayUI(); static::forkWorkers(); static::resetStd(); @@ -629,24 +631,16 @@ class Worker * * @return void */ - protected static function lock() + protected static function lock($flag = \LOCK_EX) { - $fd = \fopen(static::$_startFile, 'r'); - if ($fd && !flock($fd, LOCK_EX)) { - static::log('Workerman['.static::$_startFile.'] already running.'); - exit; + static $fd; + if (\DIRECTORY_SEPARATOR !== '/') { + return; + } + $fd = $fd ?: \fopen(static::$pidFile . '.lock', 'a+'); + if ($fd) { + flock($fd, $flag); } - } - - /** - * Unlock. - * - * @return void - */ - protected static function unlock() - { - $fd = \fopen(static::$_startFile, 'r'); - $fd && flock($fd, \LOCK_UN); } /** diff --git a/view/taoler/index/article/ask/detail.html b/view/taoler/index/article/ask/detail.html index 1c221bf..06a2958 100644 --- a/view/taoler/index/article/ask/detail.html +++ b/view/taoler/index/article/ask/detail.html @@ -81,7 +81,7 @@ {if condition="$article.user.id eq $vo.user.id"}({:lang('poster')}){/if}
    -
    {$vo.user.city}
    +
    {:hook('ipShow',$vo.user.city)}
    {if $vo.cai == 1}{/if}
    {$vo.content|raw}
    diff --git a/view/taoler/index/article/blog/detail.html b/view/taoler/index/article/blog/detail.html index 0e3ed79..90fe37c 100644 --- a/view/taoler/index/article/blog/detail.html +++ b/view/taoler/index/article/blog/detail.html @@ -130,7 +130,7 @@ {if condition="$article.user.id eq $vo.user.id"}({:lang('poster')}){/if}
    -
    {$vo.user.city}
    +
    {:hook('ipShow',$vo.user.city)}
    {if $vo.cai == 1}{/if}
    {$vo.content|raw}
    diff --git a/view/taoler/index/article/posts/detail.html b/view/taoler/index/article/posts/detail.html index febd5af..17dcf06 100644 --- a/view/taoler/index/article/posts/detail.html +++ b/view/taoler/index/article/posts/detail.html @@ -47,8 +47,8 @@
    - ・ - {$article.user.city} + + {:hook('ipShow',$article.user.city)}

    @@ -101,7 +101,7 @@ {if condition="$article.user.id eq $vo.user.id"}({:lang('poster')}){/if} -
    {$vo.user.city}
    +
    {:hook('ipShow',$vo.user.city)}
    {if $vo.cai == 1}{/if}
    {$vo.content|raw}
    diff --git a/view/taoler/index/user/home.html b/view/taoler/index/user/home.html index f73f866..01813df 100644 --- a/view/taoler/index/user/home.html +++ b/view/taoler/index/user/home.html @@ -34,7 +34,7 @@

    {$u.point} {:lang('accumulate points')} {$u.create_time|date='Y-m-d'} {:lang('join')} - {:session('user_id') ? '来自'.$u.city: lang('log in to view')} + {if session('user_id')}来自{:hook('ipShow',$u.city)} {else /} lang('log in to view') {/if}

    ({$u.sign ? $u.sign|raw : lang('it is not signed yet')})