提交测试

This commit is contained in:
tiansf 2024-12-26 19:14:44 +08:00
parent fcd7859cf4
commit f12c82f274
84 changed files with 5407 additions and 1230 deletions

View File

@ -248,7 +248,7 @@ class Base extends Controller{
if($info){
$insert_data = [
'url_data'=>"https://tc.pcxbc.com/upload_pic/".$new_filename,
'name'=>$name,
'name'=>$new_filename,
'create_time'=>date('Y-m-d H:i:s'),
];
$pic_result = Db::table('admin_pic_manage')->insertGetId($insert_data);

View File

@ -0,0 +1,98 @@
<?php
namespace app\admin\controller;
use think\Controller;
use think\Db;
use think\Log;
use app\admin\controller\Download;
class Business extends Base{
protected $page_num = 10;
protected $file_max_pic = 1024*1024*5;//xxxMB
protected $information_msg_list_arr = [
'1' => '身高管理',
'2' => '体重管理',
'3' => '肺活训练',
'4' => '跳绳训练',
'5' => '中考体测',
'6' => '公告',
];
###################################################banner图管理start###################################################
###################################################banner图管理start###################################################
###################################################banner图管理start###################################################
public function business_index($page = 1){
$data = input();
$pd = true;
$parameter = [];
if(array_key_exists('tt', $data)){
$page = $data['page_num'];
unset($data['page_num']);
unset($data['tt']);
$pd = false;
// if($data['status_num'] === "0" || $data['status_num'] === "1"){
// $parameter['is_del'] = $data['status_num'];
// }
// if($data['tel']){
// $parameter['tel'] = $data['tel'];
// }
// if($data['email']){
// $parameter['email'] = $data['email'];
// }
// if($data['s_time']){
// $parameter['create_time'] = ['>=',$data['s_time']];
// }
// if($data['e_time']){
// $parameter['create_time'] = ['<=',$data['e_time']];
// }
}
$num = Db::table('admin_business_cooperation_log')->where($parameter)->count();
$result = Db::table('admin_business_cooperation_log')->where($parameter)->order('id desc')->page($page,$this->page_num)->select();
// dump($result);
// die;
if(!$pd){
$return_result['num'] = $num;
$return_result['data'] = $result;
return $this->msg(0,'success',$return_result);
}
$this->assign([
'result' => $result,
'num' => $num,
]);
return $this->fetch();
}
// 下载表单
public function business_download(){
$result = Db::table('admin_business_cooperation_log')->select();
for ($i=0; $i < count($result); $i++) {
unset($result[$i]['ROW_NUMBER']);
}
// ->field("name as '客户姓名',tel as '联系电话',company as '公司名称',intention_data as '合作意向',notes_data as '备注',create_time as '添加时间'")
$execl_data = [
['客户姓名','联系电话','公司名称','合作意向','备注','添加时间'],
];
for ($i=0; $i < count($result); $i++) {
$temporary_arr = [];
array_push($temporary_arr, $result[$i]['name']);
array_push($temporary_arr, $result[$i]['tel']);
array_push($temporary_arr, $result[$i]['company']);
array_push($temporary_arr, $result[$i]['intention_data']);
array_push($temporary_arr, $result[$i]['notes_data']);
array_push($temporary_arr, $result[$i]['create_time']);
array_push($execl_data, $temporary_arr);
}
$download = new Download();
$download->downloadExcel($execl_data, '用户信息.xlsx');
}
}

View File

@ -204,4 +204,56 @@ class Device extends Base{
// return $this->msg(10002);
// }
}
################################################################以下为设备提供接口################################################################
################################################################以下为设备提供接口################################################################
################################################################以下为设备提供接口################################################################
public function device_request_api(){
$data = input();
$result = Db::table('app_device_log_test')->insert(['content'=>json_encode($data),'create_time'=>date('Y-m-d H:i:s)')]);
if($result){
return $this->msg(0,'success');
}else{
return $this->msg(10002,'存储失败');
}
}
public function see_device_msg(){
$result = Db::table('app_device_log_test')->select();
if(count($result) <= 0){
echo "没有找到请求记录";
}
$neirong = '';
foreach ($result as $key => $value) {
$temporary_arr1 = json_decode($value['content'],true);
if(count($temporary_arr1) == 0){
$temporary_arr2 = '请求参数为:</br>'."本次未发送请求参数</br>";
}else{
$temporary_arr2 = '请求参数为:</br>';
}
foreach ($temporary_arr1 as $k => $v) {
$temporary_arr2 = $temporary_arr2.$k."(参数名):".$v."(参数值)</br>";
}
$neirong = $neirong.$temporary_arr2.'请求时间为:'.$value['create_time']."</br></br></br>";
}
echo $neirong;
}
}

View File

@ -0,0 +1,141 @@
<?php
namespace app\admin\controller;
use think\Controller;
use think\Db;
use app\bj\controller\Common;
use think\Log;
use \think\Validate;
use PhpOffice\PhpSpreadsheet\Spreadsheet;
use PhpOffice\PhpSpreadsheet\Writer\Xlsx;
use PhpOffice\PhpSpreadsheet\Style\Border;
use PhpOffice\PhpSpreadsheet\Style\Fill;
use PhpOffice\PhpSpreadsheet\Style\Alignment;
class Download extends Controller{
protected $ceshiyong_token = 'caadd1be045a65f30b92aa805f1de54a';
// // 测试后端判断是否微信环境
// function is_wechat() {
// // 获取 User-Agent 字符串
// $userAgent = $_SERVER['HTTP_USER_AGENT'];
// // 检查 User-Agent 字符串中是否包含 "MicroMessenger"
// if (strpos($userAgent, 'MicroMessenger') !== false) {
// echo "是微信浏览器";
// }else{
// echo "不是微信浏览器";
// }
// }
/**
* 下载 Excel 文件
*
* @param array $data 要导出的数据
* @param string $filename 文件名
* @return void
*/
public function downloadExcel($ceshiyong_data, $filename = 'data.xlsx')
{
// 创建一个新的 Spreadsheet 对象
$spreadsheet = new Spreadsheet();
$sheet = $spreadsheet->getActiveSheet();
// 获取列数
$columnCount = count($ceshiyong_data[0]);
// 添加标题到工作表中
$titles = $ceshiyong_data[0];
for ($colIndex = 0; $colIndex < $columnCount; $colIndex++) {
$sheet->setCellValueByColumnAndRow($colIndex + 1, 1, $titles[$colIndex]);
}
// 添加数据到工作表中
$data = array_slice($ceshiyong_data, 1);
foreach ($data as $rowIndex => $rowData) {
for ($colIndex = 0; $colIndex < $columnCount; $colIndex++) {
$sheet->setCellValueByColumnAndRow($colIndex + 1, $rowIndex + 2, $rowData[$colIndex]);
}
}
// 设置表头样式
$headerStyle = [
'font' => [
'bold' => true,
],
'fill' => [
'fillType' => Fill::FILL_SOLID,
'startColor' => [
'argb' => 'FFFFC000', // 橙色
],
],
'alignment' => [
'horizontal' => Alignment::HORIZONTAL_CENTER,
],
'borders' => [
'allBorders' => [
'borderStyle' => Border::BORDER_THIN,
],
],
];
$sheet->getStyle('A1:' . $this->getExcelColumnName($columnCount) . '1')->applyFromArray($headerStyle);
// 设置所有内容居中
$allContentStyle = [
'alignment' => [
'horizontal' => Alignment::HORIZONTAL_CENTER,
],
'borders' => [
'allBorders' => [
'borderStyle' => Border::BORDER_THIN,
],
],
];
$sheet->getStyle('A1:' . $this->getExcelColumnName($columnCount) . (count($ceshiyong_data) + 1))->applyFromArray($allContentStyle);
// 设置斑马纹效果
$rowCount = count($ceshiyong_data) - 1; // 数据行数
for ($rowIndex = 1; $rowIndex <= $rowCount; $rowIndex++) {
$row = $rowIndex + 1; // 数据行从第二行开始
$rowStyle = [
'fill' => [
'fillType' => Fill::FILL_SOLID,
'startColor' => [
'argb' => ($rowIndex % 2 == 0) ? 'FFDDDDDD' : 'FFFFFFFF', // 偶数行浅灰色,奇数行白色
],
],
];
$sheet->getStyle('A' . $row . ':' . $this->getExcelColumnName($columnCount) . $row)->applyFromArray($rowStyle);
}
// 设置响应头以触发文件下载
header('Content-Type: application/vnd.openxmlformats-officedocument.spreadsheetml.sheet');
header('Content-Disposition: attachment;filename="' . $filename . '"');
header('Cache-Control: max-age=0');
// 保存并输出 Excel 文件
$writer = new Xlsx($spreadsheet);
$writer->save('php://output');
exit;
}
/**
* 获取 Excel 列名
*
* @param int $index 列索引从1开始
* @return string Excel 列名
*/
private function getExcelColumnName($index)
{
$columnName = '';
while ($index > 0) {
$remainder = ($index - 1) % 26;
$columnName = chr(65 + $remainder) . $columnName;
$index = intval(($index - 1) / 26);
}
return $columnName;
}
}

View File

@ -74,6 +74,8 @@ class Editortext extends Base{
public function model_content(){
$data = input();
// dump($data);
// die;
// $data['id'] = '3';
if(!array_key_exists('id', $data)){
return $this->msg(10001,'id缺失');

View File

@ -28,7 +28,7 @@ class Notice extends Base{
$data = input();
$pd = true;
$parameter = [];
$parameter['scene_data'] = 3;
// $parameter['scene_data'] = 3;
if(array_key_exists('tt', $data)){
$page = $data['page_num'];
unset($data['page_num']);
@ -90,7 +90,7 @@ class Notice extends Base{
'title' => $data['title'],
'pic' => $data['banner_img'],
'type' => $data['type'],
'jump_url' => '',
'jump_url' => $data['jump_url'],
'parameter_data' => $data['parameter_data'],
'create_time' => date('Y-m-d H:i:s'),
'scene_data' => $data['scene_data'],
@ -98,9 +98,9 @@ class Notice extends Base{
$pic_data = Db::table('admin_pic_manage')->where(['id'=>$action_data['pic']])->find();
$action_data['pic'] = $pic_data['url_data'];
if($action_data['type'] == 1){
$action_data['jump_url'] = "https://tc.pcxbc.com/editortext/model_content?id=".$action_data['parameter_data'];
$action_data['jump_url'] = "https://tc.pcxbc.com/editortext/model_content";
}else if($action_data['type'] == 2){
$action_data['jump_url'] = $data['jump_url'];
$action_data['jump_url'] = "weixin://dl/business/?appid=".$data['parameter_data']."&path=".$data['jump_url'];
}else{
return $this->msg(10002,'选择类型错误');
}

View File

@ -0,0 +1,237 @@
<!DOCTYPE html>
<html class="x-admin-sm">
<head>
<meta charset="UTF-8">
<title>添加banner</title>
<meta name="renderer" content="webkit">
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
<meta name="viewport" content="width=device-width,user-scalable=yes, minimum-scale=0.4, initial-scale=0.8,target-densitydpi=low-dpi" />
<link rel="stylesheet" href="/x_admin/css/font.css">
<link rel="stylesheet" href="/x_admin/css/xadmin.css">
<script type="text/javascript" src="/x_admin/lib/layui/layui.js" charset="utf-8"></script>
<script type="text/javascript" src="/x_admin/js/xadmin.js"></script>
<script type="text/javascript" src="/x_admin/js/jq.js"></script>
</head>
<body>
<div class="layui-fluid">
<div class="layui-row" id="app_all">
<form action="" method="post" class="layui-form layui-form-pane">
<div class="layui-form-item">
<label for="title_v" class="layui-form-label">
<span class="x-red"></span>标题描述
</label>
<div class="layui-input-inline" style="width: 80%;">
<input type="text" id="title_v" name="title_v" lay-verify="title_v" autocomplete="off" class="layui-input">
</div>
</div>
<div class="layui-form-item">
<label for="pic_v" class="layui-form-label">
<span class="x-red"></span>选择封面
</label>
<div class="layui-input-inline">
<div class="layui-btn" onclick="xadmin.open('图片管理','/admin/pic','80%','80%')">点击选择</div>
<!-- <input type="file" id="upload_file_app" accept="image/*" lay-verify="upload_file_app" name="data_excel" class="layui-btn layui-btn-normal layui-btn-mini"> -->
</div>
</div>
<div class="layui-form-item">
<label for="yulan_v" class="layui-form-label">
<span class="x-red"></span>预览
</label>
<div class="layui-input-inline">
<img id="preview_img" style="max-width:500px;box-shadow: 0px 0px 1px;" src="" alt="">
<input type="hidden" name="banner_img" id="banner_img" lay-verify="banner_img" value=""></input>
</div>
</div>
<div class="layui-form-item">
<label for="scene_data" class="layui-form-label">
<span class="x-red"></span>选择场景
</label>
<div class="layui-input-inline" style="width: 80%;">
<select id="scene_data" name="scene_data" lay-filter="scene_data" lay-verify="scene_data">
<option value="0">请选择使用场景</option>
<option value="1">首屏弹窗</option>
<option value="2">滚动公告</option>
<option value="3">首页banner</option>
</select>
</div>
</div>
<div class="layui-form-item">
<label for="data_type" class="layui-form-label">
<span class="x-red"></span>选择类型
</label>
<div class="layui-input-inline" style="width: 80%;">
<select id="data_type" name="data_type" lay-filter="data_type" lay-verify="data_type">
<option value="0">请选择跳转类型</option>
<option value="1">站内文章</option>
<option value="2">微信小程序</option>
</select>
</div>
</div>
<div class="layui-form-item">
<label for="parameter_data" class="layui-form-label">
<span class="x-red"></span>填写关键参数
</label>
<div class="layui-input-inline" style="width: 80%;">
<input type="text" id="parameter_data" name="parameter_data" lay-verify="parameter_data" autocomplete="off" class="layui-input" onfocus="pd_data_type()">
</div>
</div>
<div class="layui-form-item">
<label for="jump_url" class="layui-form-label">
<span class="x-red"></span>页面路径
</label>
<div class="layui-input-inline" style="width: 80%;">
<input type="text" id="jump_url" name="jump_url" lay-verify="jump_url" autocomplete="off" class="layui-input" placeholder="若选择站内文章,则无需填写该项">
</div>
</div>
<div class="layui-form-item" style="display: flex;flex-direction: row;justify-content: center;">
<button class="layui-btn" lay-filter="add" lay-submit="">增加</button>
</div>
</form>
</div>
</div>
<script>
var ts = true
var pic_data = []
function receiveParamFromIframe(param) {
pic_data = param
if(pic_data.length > 0){
var img = document.getElementById('preview_img');
img.src = pic_data[1]; // 设置图片预览的src属性
img.style.display = 'block'; // 显示图片预览
$('#banner_img').val(pic_data[0])
}
}
function receiveParamFromIframe_information(param) {
$('#parameter_data').val(param);
layer.msg('已选择文章ID为'+param)
}
function pd_data_type(){
console.log($('#data_type').val())
if($('#data_type').val() == 1){
xadmin.open('资讯简易列表','/notice/information_msg_list','80%','80%')
$('#parameter_data').blur()
}else if($('#data_type').val() == 2){
layer.msg('请填写微信小程序APPID')
$('#jump_url').attr('placeholder', '填写页面路径前请先确认已经配置小程序的URL Scheme');
if(ts){
layer.alert(
"您选择了小程序类型填写页面路径前请先确认已经配置小程序的URL Scheme。小程序后台->账号设置->隐私与安全->明文scheme拉起此小程序->配置->在“小程序 path”中添加页面路径多个路径以回车换行的方式书写",
{icon: 6}
);
ts = false;
}
}else{
layer.msg('请选择跳转类型')
}
}
</script>
<script>
var form
layui.use(['form'], function () {
form = layui.form;
form.verify({
title_v: function(value) {
if (value == '') {
return '请先填写标题描述';
}
},
banner_img: function(value) {
if (value == '') {
return '请先选择封面';
}
},
data_type: function(value) {
if (value == 0) {
return '请先选择类型';
}
},
scene_data: function(value) {
if (value == 0) {
return '请先选择使用场景';
}
},
parameter_data: function(value) {
if (value == 0) {
return '请先填写关键参数信息';
}
},
jump_url: function(value) {
if ($('#data_type').val() == 2) {
if($('#jump_url').val() == ''){
return '请先填写微信小程序页面路径';
}
}
},
});
//监听提交
form.on('submit(add)',function(data) {
//发异步把数据提交给php
add_data()
return false;
});
});
// 功能性~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
function add_data(){
load()
var data = {
'title':$('#title_v').val(),
'banner_img':$('#banner_img').val(),
'type':$('#data_type').val(),
'scene_data':$('#scene_data').val(),
'parameter_data':$('#parameter_data').val(),
'jump_url':$('#jump_url').val(),
'action_type':'add',
}
$.ajax({
url: "banner_add_or_update_action", //请求的url地址s
dataType: "json", //返回格式为json
async: true,//请求是否异步默认为异步这也是ajax重要特性
data: data, //参数值
type: "POST", //请求方式
success:function(req){
c_load()
if(req.code == 0){
layer.alert("增加成功", {icon: 6},function() {
//关闭当前frame
xadmin.close();
// 可以对父窗口进行刷新
xadmin.father_reload();
});
}else{
layer.alert("增加失败"+req.msg, {icon: 6},function() {
//关闭当前frame
xadmin.close();
// 可以对父窗口进行刷新
xadmin.father_reload();
});
}
},
error:function(){
//请求出错处理
pd = true
}
});
}
//加载提示开启
function load() {
var index = layer.load(1, {
shade: [0.1, '#fff'] //0.1透明度的白色背景
});
}
// 关闭加载提示
function c_load() {
layer.close(layer.index)
}
</script>
</body>
</html>

View File

@ -0,0 +1,265 @@
<!DOCTYPE html>
<html class="x-admin-sm">
<head>
<meta charset="UTF-8">
<title>添加banner</title>
<meta name="renderer" content="webkit">
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
<meta name="viewport" content="width=device-width,user-scalable=yes, minimum-scale=0.4, initial-scale=0.8,target-densitydpi=low-dpi" />
<link rel="stylesheet" href="/x_admin/css/font.css">
<link rel="stylesheet" href="/x_admin/css/xadmin.css">
<script type="text/javascript" src="/x_admin/lib/layui/layui.js" charset="utf-8"></script>
<script type="text/javascript" src="/x_admin/js/xadmin.js"></script>
<script type="text/javascript" src="/x_admin/js/jq.js"></script>
</head>
<body>
<div class="layui-fluid">
<div class="layui-row" id="app_all">
<form action="" method="post" class="layui-form layui-form-pane">
<div class="layui-form-item">
<label for="title_v" class="layui-form-label">
<span class="x-red"></span>标题描述
</label>
<div class="layui-input-inline" style="width: 80%;">
<input type="text" id="title_v" name="title_v" lay-verify="title_v" autocomplete="off" class="layui-input" value="{$result.title}">
</div>
</div>
<div class="layui-form-item">
<label for="pic_v" class="layui-form-label">
<span class="x-red"></span>选择封面
</label>
<div class="layui-input-inline">
<div class="layui-btn" onclick="xadmin.open('图片管理','/admin/pic','80%','80%')">点击选择</div>
<!-- <input type="file" id="upload_file_app" accept="image/*" lay-verify="upload_file_app" name="data_excel" class="layui-btn layui-btn-normal layui-btn-mini"> -->
</div>
</div>
<div class="layui-form-item">
<label for="yulan_v" class="layui-form-label">
<span class="x-red"></span>预览
</label>
<div class="layui-input-inline">
<img id="preview_img" style="max-width:500px;box-shadow: 0px 0px 1px;" src="{$result.pic}" alt="">
<input type="hidden" name="banner_img" id="banner_img" lay-verify="banner_img" value="{$result.pic_id}"></input>
</div>
</div>
<div class="layui-form-item">
<label for="scene_data" class="layui-form-label">
<span class="x-red"></span>选择场景
</label>
<div class="layui-input-inline" style="width: 80%;">
<select id="scene_data" name="scene_data" lay-filter="scene_data" lay-verify="scene_data">
{if condition="$result.type == 1"}
<option value="0">请选择使用场景</option>
<option value="1" selected>首屏弹窗</option>
<option value="2">滚动公告</option>
<option value="3">首页banner</option>
{elseif condition="$result.type == 2"/}
<option value="0">请选择使用场景</option>
<option value="1">首屏弹窗</option>
<option value="2" selected>滚动公告</option>
<option value="3">首页banner</option>
{elseif condition="$result.type == 3"/}
<option value="0">请选择使用场景</option>
<option value="1">首屏弹窗</option>
<option value="2">滚动公告</option>
<option value="3" selected>首页banner</option>
{else /}
<option value="0" selected>请选择使用场景</option>
<option value="1">首屏弹窗</option>
<option value="2">滚动公告</option>
<option value="3">首页banner</option>
{/if}
</select>
</div>
</div>
<div class="layui-form-item">
<label for="data_type" class="layui-form-label">
<span class="x-red"></span>选择类型
</label>
<div class="layui-input-inline" style="width: 80%;">
<select id="data_type" name="data_type" lay-filter="data_type" lay-verify="data_type">
{if condition="$result.type == 1"}
<option value="0">请选择跳转类型</option>
<option value="1" selected>站内文章</option>
<option value="2">微信小程序</option>
{elseif condition="$result.type == 2"/}
<option value="0">请选择跳转类型</option>
<option value="1">站内文章</option>
<option value="2" selected>微信小程序</option>
{else /}
<option value="0" selected>请选择跳转类型</option>
<option value="1">站内文章</option>
<option value="2">微信小程序</option>
{/if}
</select>
</div>
</div>
<div class="layui-form-item">
<label for="parameter_data" class="layui-form-label">
<span class="x-red"></span>填写关键参数
</label>
<div class="layui-input-inline" style="width: 80%;">
<input type="text" id="parameter_data" name="parameter_data" lay-verify="parameter_data" autocomplete="off" class="layui-input" onfocus="pd_data_type()" value="{$result.parameter_data}">
</div>
</div>
<div class="layui-form-item">
<label for="jump_url" class="layui-form-label">
<span class="x-red"></span>页面路径
</label>
<div class="layui-input-inline" style="width: 80%;">
<input type="text" id="jump_url" name="jump_url" lay-verify="jump_url" autocomplete="off" class="layui-input" placeholder="若选择站内文章,则无需填写该项" value="{$result.jump_url}">
</div>
</div>
<div class="layui-form-item" style="display: flex;flex-direction: row;justify-content: center;">
<button class="layui-btn" lay-filter="add" lay-submit="">修改</button>
</div>
</form>
</div>
</div>
<script>
var ts = true
var data_id = "{$result.id}"
var pic_data = []
function receiveParamFromIframe(param) {
pic_data = param
if(pic_data.length > 0){
var img = document.getElementById('preview_img');
img.src = pic_data[1]; // 设置图片预览的src属性
img.style.display = 'block'; // 显示图片预览
$('#banner_img').val(pic_data[0])
}
}
function receiveParamFromIframe_information(param) {
$('#parameter_data').val(param);
layer.msg('已选择文章ID为'+param)
}
function pd_data_type(){
console.log($('#data_type').val())
if($('#data_type').val() == 1){
xadmin.open('资讯简易列表','/notice/information_msg_list','80%','80%')
$('#parameter_data').blur()
}else if($('#data_type').val() == 2){
layer.msg('请填写微信小程序APPID')
if(ts){
layer.alert(
"您选择了小程序类型填写页面路径前请先确认已经配置小程序的URL Scheme。小程序后台->账号设置->隐私与安全->明文scheme拉起此小程序->配置->在“小程序 path”中添加页面路径多个路径以回车换行的方式书写",
{icon: 6}
);
ts = false;
}
}else{
layer.msg('请选择跳转类型')
}
}
</script>
<script>
var form
layui.use(['form'], function () {
form = layui.form;
form.verify({
title_v: function(value) {
if (value == '') {
return '请先填写标题描述';
}
},
banner_img: function(value) {
if (value == '') {
return '请先选择封面';
}
},
data_type: function(value) {
if (value == 0) {
return '请先选择类型';
}
},
scene_data: function(value) {
if (value == 0) {
return '请先选择使用场景';
}
},
parameter_data: function(value) {
if (value == 0) {
return '请先填写关键参数信息';
}
},
jump_url: function(value) {
if ($('#data_type').val() == 2) {
if($('#jump_url').val() == ''){
return '请先填写微信小程序页面路径';
}
}
},
});
//监听提交
form.on('submit(add)',function(data) {
//发异步把数据提交给php
add_data()
return false;
});
});
// 功能性~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
function add_data(){
load()
var data = {
'id':data_id,
'title':$('#title_v').val(),
'banner_img':$('#banner_img').val(),
'type':$('#data_type').val(),
'scene_data':$('#scene_data').val(),
'parameter_data':$('#parameter_data').val(),
'jump_url':$('#jump_url').val(),
'action_type':'update',
}
$.ajax({
url: "banner_add_or_update_action", //请求的url地址s
dataType: "json", //返回格式为json
async: true,//请求是否异步默认为异步这也是ajax重要特性
data: data, //参数值
type: "POST", //请求方式
success:function(req){
c_load()
if(req.code == 0){
layer.alert("修改成功", {icon: 6},function() {
//关闭当前frame
xadmin.close();
// 可以对父窗口进行刷新
xadmin.father_reload();
});
}else{
layer.alert("修改失败"+req.msg, {icon: 6},function() {
//关闭当前frame
xadmin.close();
// 可以对父窗口进行刷新
xadmin.father_reload();
});
}
},
error:function(){
//请求出错处理
pd = true
}
});
}
//加载提示开启
function load() {
var index = layer.load(1, {
shade: [0.1, '#fff'] //0.1透明度的白色背景
});
}
// 关闭加载提示
function c_load() {
layer.close(layer.index)
}
</script>
</body>
</html>

View File

@ -0,0 +1,212 @@
<!DOCTYPE html>
<html class="x-admin-sm">
<head>
<meta charset="UTF-8">
<title>banner图管理</title>
<meta name="renderer" content="webkit">
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
<meta name="viewport" content="width=device-width,user-scalable=yes, minimum-scale=0.4, initial-scale=0.8,target-densitydpi=low-dpi" />
<link rel="stylesheet" href="/x_admin/css/font.css">
<link rel="stylesheet" href="/x_admin/css/xadmin.css">
<script src="/x_admin/lib/layui/layui.js" charset="utf-8"></script>
<script type="text/javascript" src="/x_admin/js/xadmin.js"></script>
<style>
/* th{
min-width:30px;
} */
</style>
</head>
<body>
<div class="x-nav">
<span class="layui-breadcrumb">
<a href="">首页</a>
<a href="">演示</a>
<a>
<cite>导航元素</cite></a>
</span>
<a class="layui-btn layui-btn-small" style="line-height:1.6em;margin-top:3px;float:right" onclick="location.reload()" title="刷新">
<i class="layui-icon layui-icon-refresh" style="line-height:30px"></i></a>
</div>
<div class="layui-fluid">
<div class="layui-row layui-col-space15">
<div class="layui-col-md12">
<div class="layui-card">
<!-- <div class="layui-card-body ">
<form class="layui-form layui-col-space5">
<div class="layui-inline layui-show-xs-block">
<input class="layui-input" autocomplete="off" placeholder="开始日" name="start" id="s_time">
</div>
<div class="layui-inline layui-show-xs-block">
<input class="layui-input" autocomplete="off" placeholder="截止日" name="end" id="e_time">
</div>
<div class="layui-inline layui-show-xs-block">
<input type="text" name="username" placeholder="请输入用户手机" autocomplete="off" class="layui-input" id="tel">
</div>
<div class="layui-inline layui-show-xs-block">
<input type="text" name="username" placeholder="请输入用户邮箱" autocomplete="off" class="layui-input" id="email">
</div>
<div class="layui-input-inline layui-show-xs-block">
<select name="contrller" id="status_num">
<option value="">状态</option>
<option value="0">启用</option>
<option value="1">停用</option>
</select>
</div>
<div class="layui-inline layui-show-xs-block">
<div class="layui-btn" lay-submit="" lay-filter="sreach" onclick="find('y')"><i class="layui-icon">&#xe615;</i></div>
</div>
</form>
</div> -->
<div class="layui-card-header">
<!-- <button class="layui-btn layui-btn-danger" onclick="delAll()"><i class="layui-icon"></i>批量停用</button> -->
<!-- <button class="layui-btn" onclick="xadmin.open('添加用户','/appversion/app_add','100%','100%')"><i class="layui-icon"></i>添加</button> -->
<!-- <button class="layui-btn" onclick="xadmin.open('下载execl','/business/business_download','80%','80%')">下载execl</button> -->
<a href="/business/business_download"><button class="layui-btn">下载execl</button></a>
</div>
<div class="layui-card-body layui-table-body layui-table-main">
<table class="layui-table layui-form">
<thead>
<tr>
<th style="min-width: 30px;width:50px;">ID</th>
<th>客户姓名</th>
<th>联系电话</th>
<th>公司名称</th>
<th>合作意向</th>
<th>备注</th>
<th>添加时间</th>
</tr>
</thead>
<tbody id='content'>
{volist name="result" id="vo"}
<tr>
<td>{$vo.id}</td>
<td>{$vo.name}</td>
<td>{$vo.tel}</td>
<td>{$vo.company}</td>
<td>{$vo.intention_data}</td>
<td>{$vo.notes_data}</td>
<td>{$vo.create_time}</td>
</tr>
{/volist}
</tbody>
</table>
</div>
<div class="layui-card-body ">
<div id="page" style="text-align: center;">
</div>
</div>
</div>
</div>
</div>
</div>
</body>
<script>
var page_num;
var laypage;
var all_page = "{$num}";
layui.use('laypage', function () {
laypage = layui.laypage;
//执行一个laypage实例
laypage.render({
elem: 'page',
count: all_page, //数据总数,从服务端得到
limit: 10,
groups:10,
jump: function (obj, first) {
//首次不执行
if (!first) {
//obj包含了当前分页的所有参数比如
console.log(obj.curr); //得到当前页,以便向服务端请求对应页的数据。
console.log(obj.limit); //得到每页显示的条数
page_num = obj.curr;
find("n")
}
}
});
});
function find(pd) {
if(!page_num || pd == 'y'){
page_num = 1;
}
page({
"page_num":page_num,
"tt":1},pd);
}
function page(data,pd) {
console.log(data)
load()
$.ajax({
url: "business_index", //请求的url地址s
dataType: "json", //返回格式为json
async: true,//请求是否异步默认为异步这也是ajax重要特性
data: data, //参数值
type: "POST", //请求方式
success: function (req) {
console.log(req)
c_load();
if (req['code'] == 0) {
var str,str_s,str_c,str_all="";
for (let i = 0; i < req['data']['data'].length; i++) {
str_c = "<tr>"+
"<td>"+ req['data']['data'][i]['id'] +"</td>"+
"<td>"+ req['data']['data'][i]['name'] +"</td>"+
"<td>"+ req['data']['data'][i]['tel'] +"</td>"+
"<td>"+ req['data']['data'][i]['company'] +"</td>"+
"<td>"+ req['data']['data'][i]['intention_data'] +"</td>"+
"<td>"+ req['data']['data'][i]['notes_data'] +"</td>"+
"<td>"+ req['data']['data'][i]['create_time'] +"</td>"+
+'</tr>'
str_all = str_all+str_c;
}
$('#content').html(str_all);
form.render();
if(pd == 'y'){
$("#page").html("")
laypage.render({
elem: 'page',
count: req['data']['num'], //数据总数,从服务端得到
limit: 10,
groups:10,
jump: function (obj, first) {
//首次不执行
if (!first) {
//obj包含了当前分页的所有参数比如
console.log(obj.curr); //得到当前页,以便向服务端请求对应页的数据。
console.log(obj.limit); //得到每页显示的条数
page_num = obj.curr;
// page({"page":page_num,"tt":1});
find("n")
}
}
});
}
} else {
layer.msg(req['msg'])
}
},
error: function () {
//请求出错处理
}
});
}
//加载提示开启
function load() {
var index = layer.load(1, {
shade: [0.1, '#fff'] //0.1透明度的白色背景
});
}
// 关闭加载提示
function c_load() {
layer.close(layer.index)
}
</script>
</html>

View File

@ -0,0 +1,397 @@
<!DOCTYPE html>
<html class="x-admin-sm">
<head>
<meta charset="UTF-8">
<title>设备管理_add</title>
<meta name="renderer" content="webkit">
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
<meta name="viewport" content="width=device-width,user-scalable=yes, minimum-scale=0.4, initial-scale=0.8,target-densitydpi=low-dpi" />
<link rel="stylesheet" href="/x_admin/css/font.css">
<link rel="stylesheet" href="/x_admin/css/xadmin.css">
<script type="text/javascript" src="/x_admin/lib/layui/layui.js" charset="utf-8"></script>
<script type="text/javascript" src="/x_admin/js/xadmin.js"></script>
<script type="text/javascript" src="/x_admin/js/jq.js"></script>
<link href="/rich_text_editor/style.css" rel="stylesheet">
<script src="/rich_text_editor/index.js"></script>
<style>
#editor—wrapper {
border: 1px solid #ccc;
z-index: 100; /* 按需定义 */
}
#toolbar-container { border-bottom: 1px solid #ccc; }
#editor-container { height: 500px; }
</style>
</head>
<body>
<div class="layui-fluid">
<div class="layui-row" id="app_all">
<form action="" method="post" class="layui-form layui-form-pane">
<div class="layui-form-item">
<label for="title_v" class="layui-form-label">
<span class="x-red"></span>标题描述
</label>
<div class="layui-input-inline">
<input type="text" id="title_v" name="title_v" required="" lay-verify="title_v" autocomplete="off" class="layui-input" value="{$result.title}">
</div>
</div>
<div class="layui-form-item">
<label for="title_v" class="layui-form-label">
<span class="x-red"></span>上传封面
</label>
<div class="layui-input-inline">
<input type="file" id="upload_file_app" accept="image/*" lay-verify="upload_file_app" name="data_excel" class="layui-btn layui-btn-normal layui-btn-mini">
</div>
</div>
<div class="layui-form-item">
<label for="title_v" class="layui-form-label">
<span class="x-red"></span>预览
</label>
<div class="layui-input-inline">
<img id="preview_img" style="max-width:500px;" src="http://tc.pcxbc.com/{$result.cover_image}" alt="">
</div>
</div>
<div class="layui-form-item layui-form-text" style="max-width: 440px;">
<label class="layui-form-label">
发布板块
</label>
<table class="layui-table layui-input-block">
<tbody>
<tr>
<td>
{if condition="strpos($result.sector, '1') !== false && strpos($result.sector, '2') !== false && strpos($result.sector, '3') !== false"}
<input name="id[]" lay-skin="primary" type="checkbox" checked value="" title="全选" lay-filter="sector_all">
{else /}
<input name="id[]" lay-skin="primary" type="checkbox" value="" title="全选" lay-filter="sector_all">
{/if}
</td>
<td>
<div class="layui-input-block">
{if condition="strpos($result.sector, '1') !== false"}
<input name="id[]" lay-skin="primary" type="checkbox" checked value="1" title="推荐" lay-filter="sector_child">
{else /}
<input name="id[]" lay-skin="primary" type="checkbox" value="1" title="推荐" lay-filter="sector_child">
{/if}
{if condition="strpos($result.sector, '2') !== false"}
<input name="id[]" lay-skin="primary" type="checkbox" checked value="2" title="公告" lay-filter="sector_child">
{else /}
<input name="id[]" lay-skin="primary" type="checkbox" value="2" title="公告" lay-filter="sector_child">
{/if}
{if condition="strpos($result.sector, '3') !== false"}
<input name="id[]" lay-skin="primary" type="checkbox" checked value="3" title="圈" lay-filter="sector_child">
{else /}
<input name="id[]" lay-skin="primary" type="checkbox" value="3" title="圈" lay-filter="sector_child">
{/if}
</div>
</td>
</tr>
</tbody>
</table>
</div>
<div class="layui-form-item layui-form-text" style="max-width: 440px;">
<label class="layui-form-label">
发布类型
</label>
<table class="layui-table layui-input-block">
<tbody>
<tr>
<td>
{if condition="strpos($result.type, '1') !== false && strpos($result.type, '2') !== false && strpos($result.type, '3') !== false && strpos($result.type, '4') !== false && strpos($result.type, '5') !== false"}
<input name="id[]" lay-skin="primary" type="checkbox" checked value="" title="全选" lay-filter="type_all">
{else /}
<input name="id[]" lay-skin="primary" type="checkbox" value="" title="全选" lay-filter="type_all">
{/if}
</td>
<td>
<div class="layui-input-block">
{if condition="strpos($result.type, '1') !== false"}
<input name="id[]" lay-skin="primary" type="checkbox" checked value="1" title="身高管理" lay-filter="type_child">
{else /}
<input name="id[]" lay-skin="primary" type="checkbox" value="1" title="身高管理" lay-filter="type_child">
{/if}
{if condition="strpos($result.type, '2') !== false"}
<input name="id[]" lay-skin="primary" type="checkbox" checked value="2" title="体重管理" lay-filter="type_child">
{else /}
<input name="id[]" lay-skin="primary" type="checkbox" value="2" title="体重管理" lay-filter="type_child">
{/if}
{if condition="strpos($result.type, '3') !== false"}
<input name="id[]" lay-skin="primary" type="checkbox" checked value="3" title="肺活训练" lay-filter="type_child">
{else /}
<input name="id[]" lay-skin="primary" type="checkbox" value="3" title="肺活训练" lay-filter="type_child">
{/if}
{if condition="strpos($result.type, '4') !== false"}
<input name="id[]" lay-skin="primary" type="checkbox" checked value="4" title="跳绳训练" lay-filter="type_child">
{else /}
<input name="id[]" lay-skin="primary" type="checkbox" value="4" title="跳绳训练" lay-filter="type_child">
{/if}
{if condition="strpos($result.type, '5') !== false"}
<input name="id[]" lay-skin="primary" type="checkbox" checked value="5" title="中考体测" lay-filter="type_child">
{else /}
<input name="id[]" lay-skin="primary" type="checkbox" value="5" title="中考体测" lay-filter="type_child">
{/if}
</div>
</td>
</tr>
</tbody>
</table>
</div>
<div class="layui-form-item layui-form-text" style="max-width: 90%;">
<label for="desc" class="layui-form-label">
内容编辑
</label>
<div id="editor—wrapper">
<div id="toolbar-container"><!-- 工具栏 --></div>
<div id="editor-container"><!-- 编辑器 --></div>
</div>
</div>
<div class="layui-form-item">
<!-- <label for="L_repass" class="layui-form-label"></label> -->
<!-- <div class="layui-btn" id="add" lay-filter="add" lay-submit="">增加</div>
<input value="登录" lay-submit lay-filter="add" type="submit" class="layui-btn"> -->
<button class="layui-btn" lay-filter="add" lay-submit="">修改</button>
</div>
</form>
</div>
</div>
<script>
$('#upload_file_app').on('change', function() {
// 获取被选择的文件
var fileInput = $(this)[0];
var file = fileInput.files[0];
// 检查是否有文件被选择
if (file) {
var reader = new FileReader();
reader.onload = function(e) {
var img = document.getElementById('preview_img');
img.src = e.target.result; // 设置图片预览的src属性
img.style.display = 'block'; // 显示图片预览
};
reader.readAsDataURL(file); // 读取文件内容作为Data URL
}
});
</script>
<script>
var content_str = '{$result.content}';
// var content_str = '';
var html
const { createEditor, createToolbar } = window.wangEditor
const editorConfig = {
placeholder: 'Type here...',
onChange(editor) {
html = editor.getHtml()
html = html.replace(/\r?\n|\r/g, '');
// console.log('editor content', html)
// 也可以同步到 <textarea>
},
MENU_CONF: {}
}
editorConfig.MENU_CONF['uploadImage'] = {
server: '/editortext/upload_pic_action',
maxNumberOfFiles: 1,
maxFileSize: 10 * 1024 * 1024, // 10M
onError(file, err, res) {
// console.log(`${file.name} 上传出错`, err, res)
// console.log(file)
// console.log(err.message)
alert(err.message)
},
}
editorConfig.MENU_CONF['uploadVideo'] = {
server: '/editortext/upload_video_action',
maxFileSize: 100 * 1024 * 1024, // 100M
maxNumberOfFiles: 1,
onError(file, err, res) {
// console.log(`${file.name} 上传出错`, err, res)
// console.log(file)
// console.log(err.message)
alert(err.message)
},
}
const editor = createEditor({
selector: '#editor-container',
html: '<p><br></p>',
config: editorConfig,
mode: 'default', // or 'simple'
})
const toolbarConfig = {}
const toolbar = createToolbar({
editor,
selector: '#toolbar-container',
config: toolbarConfig,
mode: 'default', // or 'simple'
})
editor.setHtml(content_str)
</script>
<script>
var form
var id = '{$result.id}'
var sector_arr = '{$result.sector}'.split(",")
var type_arr = '{$result.type}'.split(",")
console.log(sector_arr)
var pd = true
layui.use(['form'], function () {
form = layui.form;
form.verify({
title_v: function(value) {
if (value == '') {
return '请先选择添加标题';
}
},
});
//监听提交
form.on('submit(add)',function(data) {
//发异步把数据提交给php
// console.log(html);
// console.log(sector_arr);
add_data()
return false;
});
form.on('checkbox(sector_all)', function(data){
if(data.elem.checked){
$(data.elem).parent().siblings('td').find('input').prop("checked", true);
form.render();
sector_arr = ['1','2','3','4','5'];
}else{
$(data.elem).parent().siblings('td').find('input').prop("checked", false);
form.render();
sector_arr = [];
}
console.log(sector_arr)
});
form.on('checkbox(sector_child)', function(data){
if(data.elem.checked){
$(data.elem).parent().siblings('td').find('input').prop("checked", true);
form.render();
sector_arr.push($(data.elem).val());
}else{
$(data.elem).parent().siblings('td').find('input').prop("checked", false);
form.render();
if (sector_arr.includes($(data.elem).val())) {
// 如果包含,则删除第一个匹配的元素
let index = sector_arr.indexOf($(data.elem).val());
if (index !== -1) {
sector_arr.splice(index, 1);
}
}
}
console.log(sector_arr)
});
form.on('checkbox(type_all)', function(data){
if(data.elem.checked){
$(data.elem).parent().siblings('td').find('input').prop("checked", true);
form.render();
type_arr = ['1','2','3','4','5'];
}else{
$(data.elem).parent().siblings('td').find('input').prop("checked", false);
form.render();
type_arr = [];
}
console.log(type_arr)
});
form.on('checkbox(type_child)', function(data){
if(data.elem.checked){
$(data.elem).parent().siblings('td').find('input').prop("checked", true);
form.render();
type_arr.push($(data.elem).val());
}else{
$(data.elem).parent().siblings('td').find('input').prop("checked", false);
form.render();
if (type_arr.includes($(data.elem).val())) {
// 如果包含,则删除第一个匹配的元素
let index = type_arr.indexOf($(data.elem).val());
if (index !== -1) {
type_arr.splice(index, 1);
}
}
}
console.log(type_arr)
});
});
// 功能性~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
function add_data(){
if(pd === false){
return
}
var formdata = new FormData();
formdata.append('cover_image',$('#upload_file_app')[0].files[0])
formdata.append('id',id)
formdata.append('title',$("#title_v").val())
formdata.append('sector',sector_arr)
formdata.append('type',type_arr)
html = html.replace(/['"]/g, '\\$&');
formdata.append('content',html)
console.log(formdata)
load()
pd = false
$.ajax({
url:"/editortext/edit_content_action", //请求的url地址
contentType:false,
processData:false,
async:true,//请求是否异步默认为异步这也是ajax重要特性
data:formdata, //参数值
type:"POST", //请求方式
success:function(req){
c_load()
pd = true
console.log()
if(req.code == 0){
layer.alert("修改成功", {icon: 6},function() {
//关闭当前frame
xadmin.close();
// 可以对父窗口进行刷新
xadmin.father_reload();
});
}else{
layer.alert("修改失败"+req.msg, {icon: 6},function() {
//关闭当前frame
xadmin.close();
// 可以对父窗口进行刷新
xadmin.father_reload();
});
}
//请求成功时处理
console.log(req)
},
error:function(){
//请求出错处理
pd = true
}
});
}
//加载提示开启
function load() {
var index = layer.load(1, {
shade: [0.1, '#fff'] //0.1透明度的白色背景
});
}
// 关闭加载提示
function c_load() {
layer.close(layer.index)
}
</script>
</body>
</html>

View File

@ -0,0 +1,198 @@
<!DOCTYPE html>
<html class="x-admin-sm">
<head>
<meta charset="UTF-8">
<title>简要资讯列表</title>
<meta name="renderer" content="webkit">
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
<meta name="viewport" content="width=device-width,user-scalable=yes, minimum-scale=0.4, initial-scale=0.8,target-densitydpi=low-dpi" />
<link rel="stylesheet" href="/x_admin/css/font.css">
<link rel="stylesheet" href="/x_admin/css/xadmin.css">
<script src="/x_admin/lib/layui/layui.js" charset="utf-8"></script>
<script type="text/javascript" src="/x_admin/js/xadmin.js"></script>
</head>
<body>
<div class="layui-fluid">
<div class="layui-row layui-col-space15">
<div class="layui-col-md12">
<div class="layui-card">
<div class="layui-card-body layui-table-body layui-table-main">
<table class="layui-table layui-form">
<thead>
<tr>
<th style="min-width: 30px;width:50px;">ID</th>
<th>标题</th>
<th style="min-width: 30px;width:115px;">类型</th>
<th>操作</th>
</tr>
</thead>
<tbody id='content'>
{volist name="result" id="vo"}
<tr>
<td>{$vo.id}</td>
<td>{$vo.title}</td>
<td>{$vo.type}</td>
<td class="td-status">
<button class="layui-btn" onclick="sendParamToParent('{$vo.id}')">选择</button>
</td>
</tr>
{/volist}
</tbody>
</table>
</div>
<div class="layui-card-body ">
<div id="page" style="text-align: center;">
</div>
</div>
</div>
</div>
</div>
</div>
</body>
<script>
function sendParamToParent(id) {
var param = id; // 这是要传递的参数
// 调用父窗口的一个函数,并传递参数
if (window.parent && window.parent.receiveParamFromIframe) {
window.parent.receiveParamFromIframe_information(param);
} else {
layer.msg('文章选择失败');
}
xadmin.close();
}
</script>
<script>
var form
layui.use(['laydate','form'], function(){
var laydate = layui.laydate;
form = layui.form;
//执行一个laydate实例
laydate.render({
elem: '#s_time' //指定元素
});
//执行一个laydate实例
laydate.render({
elem: '#e_time' //指定元素
});
});
var page_num;
var laypage;
var all_page = "{$num}";
layui.use('laypage', function () {
laypage = layui.laypage;
//执行一个laypage实例
laypage.render({
elem: 'page',
count: all_page, //数据总数,从服务端得到
limit: 10,
groups:10,
jump: function (obj, first) {
//首次不执行
if (!first) {
//obj包含了当前分页的所有参数比如
console.log(obj.curr); //得到当前页,以便向服务端请求对应页的数据。
console.log(obj.limit); //得到每页显示的条数
page_num = obj.curr;
jump_page(page_num)
}
}
});
});
function find(pd) {
if(!page_num || pd == 'y'){
page_num = 1;
}
page({
"page_num":page_num,
"tt":1},pd);
}
function page(data,pd) {
console.log(data)
load()
$.ajax({
url: "index", //请求的url地址s
dataType: "json", //返回格式为json
async: true,//请求是否异步默认为异步这也是ajax重要特性
data: data, //参数值
type: "POST", //请求方式
success: function (req) {
console.log(req)
c_load();
if (req['code'] == 0) {
var str,str_s,str_c,str_all="";
for (let i = 0; i < req['data']['data'].length; i++) {
if(req['data']['data'][i]['is_del'] == 1){
str = '<span onclick="app_stop(this,\''+ req['data']['data'][i]['id'] +'\')" class="layui-btn layui-btn-normal layui-btn-mini layui-btn-disabled" title="停用">已停用</span>'
}else{
str = '<span onclick="app_stop(this,\''+ req['data']['data'][i]['id'] +'\')" class="layui-btn layui-btn-normal layui-btn-mini" title="启用">已启用</span>'
}
str_c = "<tr>"+
"<td>"+ req['data']['data'][i]['id'] +"</td>"+
"<td>"+ req['data']['data'][i]['title'] +"</td>"+
"<td>"+ req['data']['data'][i]['create_time'] +"</td>"+
"<td>"+ req['data']['data'][i]['update_time'] +"</td>"+
'<td><input type="text" class="layui-input x-sort top_up_edit" name="order_edit" value="'+ req['data']['data'][i]['top_up'] +'" onblur="edit_order_action(this,\''+ req['data']['data'][i]['top_up'] +'\',\'top\',\''+ req['data']['data'][i]['id'] +'\')"></td>'+
'<td><input type="text" class="layui-input x-sort loop_img_edit" name="order_edit" value="'+ req['data']['data'][i]['loop_img'] +'" onblur="edit_order_action(this,\''+ req['data']['data'][i]['loop_img'] +'\',\'loop\',\''+ req['data']['data'][i]['id'] +'\')"></td>'+
'<td class="td-status">'+
'<button class="layui-btn" onclick="xadmin.open(\'查看\',\'/editortext/edit_content?id='+ req['data']['data'][i]['id'] +'\',\'100%\',\'100%\')">查看</button>'+
str+
'</td></tr>'
str_all = str_all+str_c;
}
$('#content').html(str_all);
form.render();
if(pd == 'y'){
$("#page").html("")
laypage.render({
elem: 'page',
count: req['data']['num'], //数据总数,从服务端得到
limit: 10,
groups:10,
jump: function (obj, first) {
//首次不执行
if (!first) {
//obj包含了当前分页的所有参数比如
console.log(obj.curr); //得到当前页,以便向服务端请求对应页的数据。
console.log(obj.limit); //得到每页显示的条数
page_num = obj.curr;
// page({"page":page_num,"tt":1});
find("n")
}
}
});
}
} else {
layer.msg(req['msg'])
}
},
error: function () {
//请求出错处理
}
});
}
//加载提示开启
function load() {
var index = layer.load(1, {
shade: [0.1, '#fff'] //0.1透明度的白色背景
});
}
// 关闭加载提示
function c_load() {
layer.close(layer.index)
}
</script>
</html>

View File

@ -0,0 +1,294 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>{$result.title}</title>
<script src="/x_admin/js/jq.js"></script>
<script type="text/javascript" src="/x_admin/lib/layui/layui.js" charset="utf-8"></script>
<script type="text/javascript" src="/x_admin/js/xadmin.js"></script>
<style>
*{
margin: 0 0;
padding: 0 0;
}
/* body{
display: flex;
flex-direction: column;
flex-wrap: nowrap;
align-items: center;
} */
#big_box{
width: 90vw;
position: absolute;
top: 0;
left:0;
right: 0;
margin: 0 auto;
display: flex;
flex-direction: column;
justify-content: center;
/* background-color: red; */
}
.content{
width: 100%;
}
p{
margin: 2vw 0;
}
img{
max-width: 100%;
display: block;
}
video{
max-width: 100%;
}
.action_region{
width: 100%;
margin-bottom: 15vw;
display: flex;
justify-content: flex-end;
flex-direction: row;
flex-wrap: nowrap;
align-items: center;
}
.action_region span{
font-size: 6vw;
}
#is_like{
display: flex;
flex-direction: row;
flex-wrap: nowrap;
justify-content: center;
align-items: center;
}
#reading{
display: flex;
flex-direction: row;
flex-wrap: nowrap;
justify-content: center;
align-items: center;
}
.heart_full, .heart_empty {
cursor: pointer;
transition: all 0.3s ease;
position: relative;
display: inline-block;
width: 7vw; /* 心形的宽度 */
height: 7vw; /* 心形的高度 */
cursor: pointer;
}
.heart_full::before {
position: absolute;
content: "";
top: 0;
left: 0;
width: 100%;
height: 100%;
background-repeat: no-repeat;
background-position: center;
background-size: contain;
background-image: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path fill="%23FF0000" d="M12 21.35l-1.45-1.32C5.4 15.36 2 12.28 2 8.5 2 5.42 4.42 3 7.5 3c1.74 0 3.41.81 4.5 2.09C13.09 3.81 14.76 3 16.5 3 19.58 3 22 5.42 22 8.5c0 3.78-3.4 6.86-8.55 11.54L12 21.35z"/></svg>');
}
.heart_empty::before {
position: absolute;
content: "";
top: 0;
left: 0;
width: 100%;
height: 100%;
background-repeat: no-repeat;
background-position: center;
background-size: contain;
background-image: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path fill="%23888888" d="M12 21.35l-1.45-1.32C5.4 15.36 2 12.28 2 8.5 2 5.42 4.42 3 7.5 3c1.74 0 3.41.81 4.5 2.09C13.09 3.81 14.76 3 16.5 3 19.58 3 22 5.42 22 8.5c0 3.78-3.4 6.86-8.55 11.54L12 21.35z"/></svg>');
}
.reading {
position: relative;
display: inline-block;
width: 7vw; /* 书籍的宽度 */
height: 7vw; /* 书籍的高度 */
cursor: pointer;
}
.reading::before {
content: "";
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
background-repeat: no-repeat;
background-position: center;
background-size: contain;
background-image: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path fill="%23FFA500" d="M18 2H6c-1.1 0-2 .9-2 2v16c0 1.1.9 2 2 2h12c1.1 0 2-.9 2-2V4c0-1.1-.9-2-2-2zm0 18H6V4h12v16zM8 10h4v2H8v-2zm0 4h4v2H8v-2z"/></svg>');
}
table {
border-collapse: collapse; /* 这将合并表格边框,使得单元格之间没有间距 */
}
th{
background-color: #f5f2f0;
border: 1px solid #ccc;
text-align: center;
}
td{
border: 1px solid #ccc;
}
/* 外部容器的样式 */
.table-container {
max-width: 90vw; /* 最大宽度为视口宽度的80% */
overflow-x: auto; /* 水平方向溢出时显示滚动条 */
margin: 0 auto; /* 可选:让容器水平居中 */
}
</style>
</head>
<body>
<div id="big_box">
<div class="content">{$result.content}</div>
<div class="action_region">
<div id="is_like">
<div id="is_like_a" class=""></div>
<span class="is_like_num">{$result.i_like}</span>
</div>
<div id="reading">
<div class="reading"></div>
<span class="reading_num">{$result.reading}</span>
</div>
</div>
</div>
</body>
</html>
<script>
var user_like = "{$result.user_like}";
var i_like_num = parseInt("{$result.i_like}");
// 根据 user_like 的值设置初始类
var isLikeElement = document.getElementById('is_like_a');
if (user_like == 1) {
isLikeElement.classList.add('heart_full');
} else {
isLikeElement.classList.add('heart_empty');
}
document.getElementById('is_like_a').addEventListener('click', function() {
load()
if(user_like == 3){
c_load()
alert('请登录');
}else{
user_like_do()
}
});
function user_like_do(){
$.ajax({
url:"/testedition/user_like_it", //请求的url地址
dataType:"json", //返回格式为json
async:true,//请求是否异步默认为异步这也是ajax重要特性
data:{"id":"{$result.id}",'token':"{$result.token}"}, //参数值
type:"POST", //请求方式
success:function(req){
c_load()
//请求成功时处理
if(req.code == 0){
if(req.data.user_like == 1){
i_like_num = i_like_num + 1;
isLikeElement.classList.remove('heart_empty');
isLikeElement.classList.add('heart_full');
document.querySelector('.is_like_num').innerHTML = i_like_num;
}else if(req.data.user_like == 0){
i_like_num = i_like_num - 1;
isLikeElement.classList.remove('heart_full');
isLikeElement.classList.add('heart_empty');
document.querySelector('.is_like_num').innerHTML = i_like_num;
}
}
},
error:function(){
//请求出错处理
}
});
}
//加载提示开启
function load() {
var index = layer.load(1, {
shade: [0.1, '#fff'] //0.1透明度的白色背景
});
}
// 关闭加载提示
function c_load() {
layer.close(layer.index)
}
</script>
<script>
// 获取页面上所有的 video 元素
const videos = document.querySelectorAll('video');
let hasScrolled = false;
// 监听滑动事件
document.addEventListener('touchstart', handleScroll, { passive: true });
function handleScroll() {
if (!hasScrolled) {
hasScrolled = true;
playFirstFrameAndPause(videos);
// 移除滑动事件监听器,避免多次触发
document.removeEventListener('touchstart', handleScroll);
}
}
function playFirstFrameAndPause(videos) {
videos.forEach(video => {
video.currentTime = 0; // 设置当前时间为 0 秒
video.play().then(() => {
video.pause(); // 立即暂停,显示第一帧
}).catch(error => {
console.error('Error playing video:', error);
});
});
}
</script>
<script>
window.onload = function() {
var content_data = '{$result.content}'
document.querySelector('div.content').innerHTML = content_data.replace(/\\/g, '');
// 获取页面上的所有表格
var tables = document.getElementsByTagName('table');
// 遍历每个表格
for (var i = 0; i < tables.length; i++) {
var table = tables[i];
// 创建一个div容器
var container = document.createElement('div');
container.className = 'table-container'; // 应用CSS样式
// 将表格移动到容器中
table.parentNode.insertBefore(container, table);
container.appendChild(table);
// 强制浏览器重新计算布局,以便我们可以获取正确的宽度
// 注意:这种方法可能不是最高效的,但在这种简单场景下通常足够
var style = window.getComputedStyle(table);
var tableWidth = parseFloat(style.width.replace('px', ''));
var viewportWidth = window.innerWidth || document.documentElement.clientWidth;
var maxWidth = viewportWidth * 0.8; // 计算80vw的值
// 如果表格宽度超过了80vw则不需要额外操作因为容器已经设置了max-width
// 但为了演示,我们可以检查并打印出信息
if (tableWidth > maxWidth) {
console.log('Table ' + (i + 1) + ' is wider than 80vw and is wrapped in a container.');
} else {
// 实际上,如果表格没有超过宽度,你可能想要移除容器或做一些其他处理
// 但在这个例子中我们保留容器因为max-width会确保它不会溢出
console.log('Table ' + (i + 1) + ' fits within 80vw, but is still wrapped in a container for demonstration.');
}
// 注意由于我们设置了容器的max-width为80vw并且overflow-x为auto
// 所以即使表格宽度超过容器的宽度滚动条也会自动出现无需额外JS处理。
}
};
</script>

View File

@ -0,0 +1,314 @@
<!DOCTYPE html>
<html class="x-admin-sm">
<head>
<meta charset="UTF-8">
<title>弹窗图管理</title>
<meta name="renderer" content="webkit">
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
<meta name="viewport" content="width=device-width,user-scalable=yes, minimum-scale=0.4, initial-scale=0.8,target-densitydpi=low-dpi" />
<link rel="stylesheet" href="/x_admin/css/font.css">
<link rel="stylesheet" href="/x_admin/css/xadmin.css">
<script src="/x_admin/lib/layui/layui.js" charset="utf-8"></script>
<script type="text/javascript" src="/x_admin/js/xadmin.js"></script>
<style>
/* th{
min-width:30px;
} */
</style>
</head>
<body>
<div class="x-nav">
<span class="layui-breadcrumb">
<a href="">首页</a>
<a href="">演示</a>
<a>
<cite>导航元素</cite></a>
</span>
<a class="layui-btn layui-btn-small" style="line-height:1.6em;margin-top:3px;float:right" onclick="location.reload()" title="刷新">
<i class="layui-icon layui-icon-refresh" style="line-height:30px"></i></a>
</div>
<div class="layui-fluid">
<div class="layui-row layui-col-space15">
<div class="layui-col-md12">
<div class="layui-card">
<!-- <div class="layui-card-body ">
<form class="layui-form layui-col-space5">
<div class="layui-inline layui-show-xs-block">
<input class="layui-input" autocomplete="off" placeholder="开始日" name="start" id="s_time">
</div>
<div class="layui-inline layui-show-xs-block">
<input class="layui-input" autocomplete="off" placeholder="截止日" name="end" id="e_time">
</div>
<div class="layui-inline layui-show-xs-block">
<input type="text" name="username" placeholder="请输入用户手机" autocomplete="off" class="layui-input" id="tel">
</div>
<div class="layui-inline layui-show-xs-block">
<input type="text" name="username" placeholder="请输入用户邮箱" autocomplete="off" class="layui-input" id="email">
</div>
<div class="layui-input-inline layui-show-xs-block">
<select name="contrller" id="status_num">
<option value="">状态</option>
<option value="0">启用</option>
<option value="1">停用</option>
</select>
</div>
<div class="layui-inline layui-show-xs-block">
<div class="layui-btn" lay-submit="" lay-filter="sreach" onclick="find('y')"><i class="layui-icon">&#xe615;</i></div>
</div>
</form>
</div> -->
<div class="layui-card-header">
<!-- <button class="layui-btn layui-btn-danger" onclick="delAll()"><i class="layui-icon"></i>批量停用</button> -->
<!-- <button class="layui-btn" onclick="xadmin.open('添加用户','/appversion/app_add','100%','100%')"><i class="layui-icon"></i>添加</button> -->
<button class="layui-btn" onclick="xadmin.open('添加banner','/notice/banner_add','80%','80%')"><i class="layui-icon"></i>添加</button>
</div>
<div class="layui-card-body layui-table-body layui-table-main">
<table class="layui-table layui-form">
<thead>
<tr>
<th style="min-width: 30px;width:50px;">ID</th>
<th>标题</th>
<th style="min-width: 30px;width:115px;">创建时间</th>
<th>封面预览</th>
<th style="min-width: 30px;width:50px;">轮播排序</th>
<th>操作</th>
</tr>
</thead>
<tbody id='content'>
{volist name="result" id="vo"}
<tr>
<td>{$vo.id}</td>
<td>{$vo.title}</td>
<td>{$vo.create_time}</td>
<td><img src="{$vo.pic}" alt=""></td>
<td><input type="text" class="layui-input x-sort loop_img_edit" name="order_edit" value="{$vo.sort_num}" onblur="edit_order_action(this,'{$vo.sort_num}','{$vo.id}')"></td>
<td class="td-status">
<button class="layui-btn" onclick="xadmin.open('查看','/notice/banner_edit?id={$vo.id}','80%','80%')">查看</button>
{if condition="$vo.is_del == 1"}
<span onclick="app_stop(this,'{$vo.id}')" class="layui-btn layui-btn-normal layui-btn-mini layui-btn-disabled" title="停用">已停用</span>
{else /}
<span onclick="app_stop(this,'{$vo.id}')" class="layui-btn layui-btn-normal layui-btn-mini" title="启用">已启用</span>
{/if}
</td>
</tr>
{/volist}
</tbody>
</table>
</div>
<div class="layui-card-body ">
<div id="page" style="text-align: center;">
</div>
</div>
</div>
</div>
</div>
</div>
</body>
<script>
var form
layui.use(['laydate','form'], function(){
var laydate = layui.laydate;
form = layui.form;
//执行一个laydate实例
laydate.render({
elem: '#s_time' //指定元素
});
//执行一个laydate实例
laydate.render({
elem: '#e_time' //指定元素
});
});
var page_num;
var laypage;
var all_page = "{$num}";
layui.use('laypage', function () {
laypage = layui.laypage;
//执行一个laypage实例
laypage.render({
elem: 'page',
count: all_page, //数据总数,从服务端得到
limit: 10,
groups:10,
jump: function (obj, first) {
//首次不执行
if (!first) {
//obj包含了当前分页的所有参数比如
console.log(obj.curr); //得到当前页,以便向服务端请求对应页的数据。
console.log(obj.limit); //得到每页显示的条数
page_num = obj.curr;
find("n")
}
}
});
});
function edit_order_action(e,data,id){
if($(e).val() == data){
return
}
load()
$.ajax({
url:"/notice/pop_update_sort", //请求的url地址
dataType:"json", //返回格式为json
async:true,//请求是否异步默认为异步这也是ajax重要特性
data:{
"id":id,
'data':$(e).val(),
}, //参数值
type:"POST", //请求方式
success:function(req){
c_load()
//请求成功时处理
if(req['code'] == 0){
layer.msg('操作成功!',{icon: 6});
}else{
layer.msg('操作失败!',{icon: 5});
}
},
error:function(){
//请求出错处理
}});
}
/*用户-停用*/
function app_stop(obj,id){
// return
var title = '',is_del,num
if($(obj).attr('title')=='启用'){
title = '停用'
is_del = 1
num = 5
}else{
title = '启用'
is_del = 0
num = 6
}
layer.confirm('确认要'+ title +'吗?',function(index){
load()
$.ajax({
url:"/notice/pop_stop_run", //请求的url地址
dataType:"json", //返回格式为json
async:true,//请求是否异步默认为异步这也是ajax重要特性
data:{"id":id,'data':is_del}, //参数值
type:"POST", //请求方式
success:function(req){
c_load()
//请求成功时处理
if(req['code'] == 0){
//发异步把用户状态进行更改
$(obj).attr('title',title)
if(is_del == 1){
$(obj).parents("tr").find(".td-status").find('span').addClass('layui-btn-disabled').html('已'+ title);
}else{
$(obj).parents("tr").find(".td-status").find('span').removeClass('layui-btn-disabled').html('已'+ title);
}
layer.msg('已'+ title,{icon: num});
}else{
layer.msg('操作失败!',{icon: 5});
}
},
error:function(){
//请求出错处理
}});
});
}
function find(pd) {
if(!page_num || pd == 'y'){
page_num = 1;
}
page({
"page_num":page_num,
"tt":1},pd);
}
function page(data,pd) {
console.log(data)
load()
$.ajax({
url: "index", //请求的url地址s
dataType: "json", //返回格式为json
async: true,//请求是否异步默认为异步这也是ajax重要特性
data: data, //参数值
type: "POST", //请求方式
success: function (req) {
console.log(req)
c_load();
if (req['code'] == 0) {
var str,str_s,str_c,str_all="";
for (let i = 0; i < req['data']['data'].length; i++) {
if(req['data']['data'][i]['is_del'] == 1){
str = '<span onclick="app_stop(this,\''+ req['data']['data'][i]['id'] +'\')" class="layui-btn layui-btn-normal layui-btn-mini layui-btn-disabled" title="停用">已停用</span>'
}else{
str = '<span onclick="app_stop(this,\''+ req['data']['data'][i]['id'] +'\')" class="layui-btn layui-btn-normal layui-btn-mini" title="启用">已启用</span>'
}
str_c = "<tr>"+
"<td>"+ req['data']['data'][i]['id'] +"</td>"+
"<td>"+ req['data']['data'][i]['title'] +"</td>"+
"<td>"+ req['data']['data'][i]['create_time'] +"</td>"+
"<td>"+ req['data']['data'][i]['update_time'] +"</td>"+
'<td><input type="text" class="layui-input x-sort top_up_edit" name="order_edit" value="'+ req['data']['data'][i]['top_up'] +'" onblur="edit_order_action(this,\''+ req['data']['data'][i]['top_up'] +'\',\'top\',\''+ req['data']['data'][i]['id'] +'\')"></td>'+
'<td><input type="text" class="layui-input x-sort loop_img_edit" name="order_edit" value="'+ req['data']['data'][i]['loop_img'] +'" onblur="edit_order_action(this,\''+ req['data']['data'][i]['loop_img'] +'\',\'loop\',\''+ req['data']['data'][i]['id'] +'\')"></td>'+
'<td class="td-status">'+
'<button class="layui-btn" onclick="xadmin.open(\'查看\',\'/editortext/edit_content?id='+ req['data']['data'][i]['id'] +'\',\'100%\',\'100%\')">查看</button>'+
str+
'</td></tr>'
str_all = str_all+str_c;
}
$('#content').html(str_all);
form.render();
if(pd == 'y'){
$("#page").html("")
laypage.render({
elem: 'page',
count: req['data']['num'], //数据总数,从服务端得到
limit: 10,
groups:10,
jump: function (obj, first) {
//首次不执行
if (!first) {
//obj包含了当前分页的所有参数比如
console.log(obj.curr); //得到当前页,以便向服务端请求对应页的数据。
console.log(obj.limit); //得到每页显示的条数
page_num = obj.curr;
// page({"page":page_num,"tt":1});
find("n")
}
}
});
}
} else {
layer.msg(req['msg'])
}
},
error: function () {
//请求出错处理
}
});
}
//加载提示开启
function load() {
var index = layer.load(1, {
shade: [0.1, '#fff'] //0.1透明度的白色背景
});
}
// 关闭加载提示
function c_load() {
layer.close(layer.index)
}
</script>
</html>

View File

@ -144,21 +144,24 @@
<i class="iconfont">&#xe6a7;</i>
<cite>操作管理</cite></a>
</li>
<!-- <li>
<a onclick="xadmin.add_tab('首页弹窗管理','/notice/pop_index')">
<i class="iconfont">&#xe6a7;</i>
<cite>首页弹窗管理</cite></a>
</li>
<li>
<a onclick="xadmin.add_tab('公告管理','/notice/notice_index')">
<i class="iconfont">&#xe6a7;</i>
<cite>公告管理</cite></a>
</li> -->
</ul>
</li>
<li>
<a href="javascript:;">
<i class="iconfont left-nav-li" lay-tips="城市联动">&#xe723;</i>
<i class="iconfont left-nav-li" lay-tips="商业合作">&#xe723;</i>
<cite>商业合作</cite>
<i class="iconfont nav_right">&#xe697;</i></a>
<ul class="sub-menu">
<li>
<a onclick="xadmin.add_tab('操作管理','/business/business_index')">
<i class="iconfont">&#xe6a7;</i>
<cite>操作管理</cite></a>
</li>
</ul>
</li>
<!-- <li>
<a href="javascript:;">
<i class="iconfont left-nav-li" lay-tips="技术支持管理">&#xe723;</i>
<cite>技术支持管理</cite>
<i class="iconfont nav_right">&#xe697;</i></a>
<ul class="sub-menu">
@ -168,7 +171,7 @@
<cite>技术支持列表</cite></a>
</li>
</ul>
</li>
</li> -->
<!-- <li>
<a href="javascript:;">
<i class="iconfont left-nav-li" lay-tips="管理员管理">&#xe726;</i>

View File

@ -21,6 +21,7 @@
<label for="title_v" class="layui-form-label">
<span class="x-red"></span>标题描述
</label>
<div class="layui-input-inline" style="width: 80%;">
<input type="text" id="title_v" name="title_v" lay-verify="title_v" autocomplete="off" class="layui-input">
</div>
@ -91,6 +92,7 @@
</div>
</div>
<script>
var ts = true
var pic_data = []
function receiveParamFromIframe(param) {
pic_data = param
@ -113,6 +115,14 @@
$('#parameter_data').blur()
}else if($('#data_type').val() == 2){
layer.msg('请填写微信小程序APPID')
$('#jump_url').attr('placeholder', '填写页面路径前请先确认已经配置小程序的URL Scheme');
if(ts){
layer.alert(
"您选择了小程序类型填写页面路径前请先确认已经配置小程序的URL Scheme。小程序后台->账号设置->隐私与安全->明文scheme拉起此小程序->配置->在“小程序 path”中添加页面路径多个路径以回车换行的方式书写",
{icon: 6}
);
ts = false;
}
}else{
layer.msg('请选择跳转类型')
}
@ -150,7 +160,9 @@
},
jump_url: function(value) {
if ($('#data_type').val() == 2) {
return '请先填写微信小程序页面路径';
if($('#jump_url').val() == ''){
return '请先填写微信小程序页面路径';
}
}
},

View File

@ -119,6 +119,7 @@
</div>
</div>
<script>
var ts = true
var data_id = "{$result.id}"
var pic_data = []
function receiveParamFromIframe(param) {
@ -142,6 +143,13 @@
$('#parameter_data').blur()
}else if($('#data_type').val() == 2){
layer.msg('请填写微信小程序APPID')
if(ts){
layer.alert(
"您选择了小程序类型填写页面路径前请先确认已经配置小程序的URL Scheme。小程序后台->账号设置->隐私与安全->明文scheme拉起此小程序->配置->在“小程序 path”中添加页面路径多个路径以回车换行的方式书写",
{icon: 6}
);
ts = false;
}
}else{
layer.msg('请选择跳转类型')
}
@ -179,7 +187,9 @@
},
jump_url: function(value) {
if ($('#data_type').val() == 2) {
return '请先填写微信小程序页面路径';
if($('#jump_url').val() == ''){
return '请先填写微信小程序页面路径';
}
}
},

View File

@ -2,7 +2,7 @@
<html class="x-admin-sm">
<head>
<meta charset="UTF-8">
<title>banner图管理</title>
<title>操作管理</title>
<meta name="renderer" content="webkit">
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
<meta name="viewport" content="width=device-width,user-scalable=yes, minimum-scale=0.4, initial-scale=0.8,target-densitydpi=low-dpi" />

View File

@ -614,7 +614,11 @@ class Base extends Controller{
// 处理身高体重的单位转换它们为cm和kg。
function convertHeightAndWeight($height, $weight) {
public function convertHeightAndWeight($height, $weight) {
// 加 bcadd(,,20)
// 减 bcsub(,,20)
// 乘 bcmul(,,20)
// 除 bcdiv(,,20)
// 定义单位转换比例
$heightConversion = [
'cm' => 1,
@ -635,8 +639,17 @@ class Base extends Controller{
];
// 处理 height
if (preg_match('/([\d.]+)(cm|inch|ft-in)/', $height, $matches)) {
$heightValue = floatval($matches[1]);
// $heightValue = floatval($matches[1]);
$heightValue = $matches[1];
$heightUnit = $matches[2];
if($heightUnit == 'ft-in'){
// 如果单位为st:lb但是数据格式不对
$heightValue = str_replace($heightUnit, "", $height);
if(count(explode('-', $heightValue)) < 2){
$heightValue = str_replace("-", "", $heightValue);
$heightValue = $heightValue."-0";
}
}
if (isset($heightConversion[$heightUnit])) {
if (is_callable($heightConversion[$heightUnit])) {
$heightInCm = $heightConversion[$heightUnit]($heightValue);
@ -656,10 +669,19 @@ class Base extends Controller{
}
}
// 处理 weight
if (preg_match('/([\d.]+)(kg|斤|st:lb|lb)/', $weight, $matches)) {
$weightValue = floatval($matches[1]);
if (preg_match('/([\d.:]+)(kg|斤|st:lb|lb)/', $weight, $matches)) {
$weightValue = $matches[1];
$weightUnit = $matches[2];
if($weightUnit == 'st:lb'){
// 如果单位为st:lb但是数据格式不对
$weightValue = str_replace($weightUnit, "", $weight);
if(count(explode(':', $weightValue)) < 2){
$weightValue = str_replace(":", "", $weightValue);
$weightValue = $weightValue.":0";
}
}
if (isset($weightConversion[$weightUnit])) {
if (is_callable($weightConversion[$weightUnit])) {
$weightInKg = $weightConversion[$weightUnit]($weightValue);
@ -678,10 +700,10 @@ class Base extends Controller{
$weightInKg = false;
}
}
return [
'height_in_cm' => $heightInCm,
'weight_in_kg' => $weightInKg
'height_in_cm' => bcmul($heightInCm,1,2),
'weight_in_kg' => bcmul($weightInKg,1,2)
];
}

View File

@ -31,6 +31,28 @@ class Download extends Base{
return $this->fetch();
}
public function business_cooperation(){
return $this->fetch();
}
public function business_cooperation_action(){
$data = input();
$result = Db::table('admin_business_cooperation_log')->insert([
'name'=>$data['name'],
'tel'=>$data['phone'],
'company'=>$data['company'],
'intention_data'=>implode(',',$data['selectedValues']),
'notes_data'=>$data['remark'],
'create_time'=>date('Y-m-d H:i:s'),
]);
if($result){
$this->send_email_api_error(["tsf3920322@126.com"],['title'=>'商户合作','from_user_name'=>'reedaw商务','content'=>'有一封商户合作']);
return json(['code'=>0,'msg'=>'提交成功']);
}else{
return json(['code'=>10001,'msg'=>'网络错误,请直接联系商务合作电话/微信13590959084']);
}
}
public function ceshi(){
$data = input();
$url = 'https://klcz.pcxbc.com/open-api/calc/healthcalc/bodyfat3';

View File

@ -25,9 +25,7 @@ class Msginformation extends Base{
// 获取板块,及板块下类型标签
public function get_sector_label_msg($data = ['token'=>'6441bf7dabea7b3360a30240d3b19fc5']){
try {
if(count(input('post.')) > 0){
$data = input('post.');
}
$data = input('post.');
if(!array_key_exists('token', $data)){
return $this->msg(10001);
}
@ -72,6 +70,10 @@ class Msginformation extends Base{
}
if(!$this->verify_data_is_ok($data['page'],'intnum')){
return $this->msg(10005);
}else{
if($data['page'] < 1){
return $this->msg(10005,'页码不能小于1');
}
}
$return_data = $this->get_sector_content_msg_action($data);
@ -214,6 +216,38 @@ class Msginformation extends Base{
return $this->msg(99999);
}
}
// 给微信使用的中间页(拉起微信)
// public function open_wechat_content($data=['id'=>8]){
public function open_wechat_content(){
try {
$data = input();
if(!array_key_exists('id', $data)){
$this->record_api_log($data, null, ['code'=>10001,'msg'=>'',[]]);
return $this->msg(10001);
}
$url = Db::table('admin_notice_banner')->where(['id'=>$data['id']])->field('type,jump_url')->find();
if(!$url['type'] || $url['type'] != 2){
echo '<div style="font-size: 30px;font-weight: bold;">页面跑丢了... =。=</div>';
die;
}
header('Location: '.$url['jump_url']);
} catch (\Exception $e) {
// 捕获异常
$logContent["flie"] = $e->getFile();
$logContent["line"] = $e->getLine();
$logContent['all_content'] = "异常信息:\n";
$logContent['all_content'] .= "消息: " . $e->getMessage() . "\n";
$logContent['all_content'] .= "代码: " . $e->getCode() . "\n";
$logContent['all_content'] .= "文件: " . $e->getFile() . "\n";
$logContent['all_content'] .= "行号: " . $e->getLine() . "\n";
$logContent['all_content'] .= "跟踪信息:\n" . $e->getTraceAsString() . "\n";
$this->record_api_log($data, $logContent, null);
return $this->msg(99999);
}
}
################################################################业务################################################################
################################################################get_sector_label_msg
public function get_sector_label_msg_action($data){
@ -232,8 +266,6 @@ class Msginformation extends Base{
]
],
];
// 获取需要版块id start
$sector = Db::query("
SELECT
@ -266,12 +298,14 @@ class Msginformation extends Base{
");
if(count($loop_result) > 0){
foreach ($loop_result as $k => $v) {
$loop_result[$key]['jump_url'] = "https://tc.pcxbc.com/editortext/model_content?id=".$v['id']."&token=".$data['token'];
// $loop_result[$key]['jump_url'] = "https://tc.pcxbc.com/editortext/model_content?id=".$v['id']."&token=".$data['token'];
$loop_result[$key]['jump_url'] = "https://tc.pcxbc.com/editortext/model_content";
}
}
$Template_arr[$value]['loop_data'] = $loop_result;
array_push($return_data, $Template_arr[$value]);
}
// 填充进去版块的轮播end
return $this->msg($return_data);
}
@ -308,7 +342,8 @@ class Msginformation extends Base{
");
if(count($content_result) > 0){
foreach ($content_result as $key => $value) {
$content_result[$key]['jump_url'] = "https://tc.pcxbc.com/editortext/model_content?id=".$value['id']."&token=".$data['token'];
// $content_result[$key]['jump_url'] = "https://tc.pcxbc.com/editortext/model_content?id=".$value['id']."&token=".$data['token'];
$content_result[$key]['jump_url'] = "https://tc.pcxbc.com/editortext/model_content";
}
}
$return_result['content_data'] = $content_result;
@ -391,6 +426,7 @@ class Msginformation extends Base{
'notice'=>[],
'banner'=>[]
];
// return $this->msg($return_data);
// 所有可用记录
$all_data = Db::table($this->msginformation_use_db_name['3'])->where(['is_del'=>0])->select();
// 用户阅读记录
@ -407,12 +443,14 @@ class Msginformation extends Base{
if($value['scene_data'] != 3){
unset($all_data[$key]);
}else{
$all_data[$key]['jump_url'] = $all_data[$key]['jump_url']."&token=".$data['token'];
// $all_data[$key]['jump_url'] = $all_data[$key]['jump_url']."&token=".$data['token'];
$all_data[$key]['jump_url'] = $all_data[$key]['jump_url'];
$all_data[$key]['type'] = 'h5';
$all_data[$key]['id'] = $value['parameter_data'];
}
}else{
$all_data[$key]['jump_url'] = $all_data[$key]['jump_url']."&token=".$data['token'];
// $all_data[$key]['jump_url'] = $all_data[$key]['jump_url']."&token=".$data['token'];
$all_data[$key]['jump_url'] = $all_data[$key]['jump_url'];
$all_data[$key]['type'] = 'h5';
$all_data[$key]['id'] = $value['parameter_data'];
}
@ -430,6 +468,9 @@ class Msginformation extends Base{
$all_data[$key]['appid'] = $appid;
$all_data[$key]['path'] = $path;
// 重新定义跳转链接为中间页
$all_data[$key]['jump_url'] = "https://tc.pcxbc.com/open_wechat_content";
}
// $all_data[$key]['id'] = $all_data[$key]['parameter_data'];
unset($all_data[$key]['parameter_data']);

View File

@ -0,0 +1,398 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport"
content="width=device-width, initial-scale=1,minimum-scale=1, maximum-scale=1,user-scalable=no">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<meta http-equiv="Access-Control-Allow-Origin" content="*">
<meta name="apple-mobile-web-app-capable" content="yes">
<meta name="apple-mobile-web-app-status-bar-style" content="black">
<meta name="format-detection" content="telephone=no, email=no">
<meta name="full-screen" content="true">
<meta name="screen-orientation" content="portrait">
<meta name="x5-fullscreen" content="true">
<meta name="360-fullscreen" content="true">
<title>商务合作</title>
<script src="/x_admin/js/jq.js"></script>
<script type="text/javascript" src="/x_admin/lib/layui/layui.js" charset="utf-8"></script>
<script type="text/javascript" src="/x_admin/js/xadmin.js"></script>
<style>
*{
padding: 0 0;
margin: 0 0;
}
.big_box{
width: 100vw;
min-height: 100vh;
position: absolute;
top: 0;
left: 0;
background: url(/tsf/business_bg.jpg) no-repeat;
background-size: 100% 100%;
display: flex;
flex-direction: column;
flex-wrap: nowrap;
align-items: center;
}
.content{
width: 85vw;
max-width: 880px;
display: flex;
flex-direction: column;
flex-wrap: nowrap;
border-radius: 1vw;
background-color: white;
margin: 24px 0;
overflow: hidden;
align-items: center;
}
.content img{
width: 100%;
height: auto;
}
.content_c{
width: 100%;
padding: 2% 12%;
box-sizing: border-box;
}
.title_t{
border: none;
text-align: center;
color: rgba(8, 14, 23, 0.9);
font-weight: 600;
font-size: 28px;
line-height: 40px;
word-break: break-all;
white-space: pre-wrap;
overflow: visible;
margin: 4% 0;
}
.title_c2{
font-size: 12px;
margin-bottom: 10%;
}
.title_c2 span{
color: rgb(17, 106, 240);
}
.write_box{
width: 100%;
font-size: 16px;
margin: 10% 0;
}
.write_box_t{
font-weight: 600;
}
.write_box_r{
color: red;
}
.write_k{
padding: 8px 12px;
position: relative;
border-radius: 6px;
border: 1px solid rgba(8, 14, 23, 0.24);
display: flex;
outline: 0 !important;
word-break: break-all;
margin: 2% 0;
}
.write_k textarea{
width: 100%;
resize: none;
text-overflow: ellipsis;
line-height: 22px;
border: none !important;
border-radius: 0;
background: transparent !important;
box-shadow: none !important;
outline: 0 !important;
cursor: auto;
padding: 0;
min-height: 22px;
margin: 0 1%;
}
.ksapc-select-write {
width: 100%;
}
.ksapc-select-write-tip {
margin-bottom: 10px;
font-size: 14px;
color: #8E9095;
}
.ksapc-select-write-tile {
width: 100%;
}
.ksapc-checkboxgroup {
width: 100%;
}
.ksapc-row {
display: flex;
flex-wrap: wrap;
gap: 14px;
}
.ksapc-col {
flex: 1 1 48%; /* 两列布局 */
}
.ksapc-checkbox {
display: flex;
align-items: center;
}
.ksapc-checkbox input {
margin-right: 8px;
}
.ksapc-checkbox span{
font-size: 14px;
cursor: pointer;
}
#onload{
width: 20vw;
height: 5vw;
min-width: 200px;
min-height: 45px;
background-color: #0A6CFF;
color: white;
border-radius: 10px;
line-height: 5vw;
text-align: center;
font-size: 15px;
font-weight: bold;
margin-bottom: 35px;
cursor: pointer; /* 添加小手图标 */
}
</style>
</head>
<body id="box_k">
<div class="big_box">
<div class="content">
<img src="/tsf/business_title.jpg" alt="">
<div class="content_c">
<div class="title_t">商务合作意向登记表</div>
<div class="title_c2">
智能设备产品包<span>含身高测量仪、体重体脂秤、宠物秤, 母婴秤,厨房秤,商业秤,身高体重/体脂秤,八电极体脂秤,运动训练设备</span>等;软件包含就智能健康管理系统,智能硬件管理系统等,支持智能设备选购/定制、健康系统对接/定制行业解决方案等您也可以直接拨打或微信联系13590959084期待与您合作
</div>
<div class="write_box">
<div class="write_box_t">
<span class="write_box_r">*</span>&nbsp; 1.客户姓名
</div>
<div class="write_k">
<textarea placeholder="请输入" rows="1" oninput="autoResize(this)" class="name-input"></textarea>
</div>
</div>
<div class="write_box">
<div class="write_box_t">
<span class="write_box_r">*</span>&nbsp; 2.联系电话
</div>
<div class="write_k">
<textarea placeholder="请输入手机号" rows="1" oninput="autoResize(this)" class="phone-input"></textarea>
</div>
</div>
<div class="write_box">
<div class="write_box_t">
<span class="write_box_r">*</span>&nbsp; 3.公司名称
</div>
<div class="write_k">
<textarea placeholder="请输入" rows="1" oninput="autoResize(this)" class="company-input"></textarea>
</div>
</div>
<div class="write_box">
<div class="write_box_t">
<span class="write_box_r">*</span>&nbsp; 4.合作意向
</div>
<div class="write_k" style="border: none;">
<div class="ksapc-select-write">
<div class="ksapc-select-write-tip" id="selectedCount">此题已选择 0/6 项</div>
<div class="ksapc-select-write-tile">
<div class="ksapc-checkboxgroup">
<div class="ksapc-row">
<div class="ksapc-col">
<label class="ksapc-checkbox">
<input type="checkbox" class="option-checkbox" value="智能设备">
<span>智能设备</span>
</label>
</div>
<div class="ksapc-col">
<label class="ksapc-checkbox">
<input type="checkbox" class="option-checkbox" value="健康软件">
<span>健康软件</span>
</label>
</div>
<div class="ksapc-col">
<label class="ksapc-checkbox">
<input type="checkbox" class="option-checkbox" value="解决方案">
<span>解决方案</span>
</label>
</div>
<div class="ksapc-col">
<label class="ksapc-checkbox">
<input type="checkbox" class="option-checkbox" value="系统定制">
<span>系统定制</span>
</label>
</div>
<div class="ksapc-col">
<label class="ksapc-checkbox">
<input type="checkbox" class="option-checkbox" value="设备定制">
<span>设备定制</span>
</label>
</div>
<div class="ksapc-col">
<label class="ksapc-checkbox">
<input type="checkbox" class="option-checkbox" value="其它">
<span>其它可联系商务合作13590959084</span>
</label>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="write_box">
<div class="write_box_t">
<span class="write_box_r">*</span>&nbsp; 5.备注
</div>
<div class="write_k">
<textarea placeholder="请输入" rows="1" oninput="autoResize(this)" class="remark-input"></textarea>
</div>
</div>
<div class="write_box" style="color: #8E9095;">
商务合作电话/微信13590959084
</div>
</div>
<div id="onload">提交</div>
</div>
</div>
</body>
</html>
<script>
var selectedValues = [];
function autoResize(textarea) {
textarea.style.height = 'auto'; // 重置高度
textarea.style.height = textarea.scrollHeight + 'px'; // 设置为内容高度
}
document.addEventListener('DOMContentLoaded', function() {
// 获取 #onload 元素
const onloadElement = document.getElementById('onload');
// 计算 #onload 元素的高度
const height = onloadElement.offsetHeight;
// 设置 #onload 元素的行高与高度一致
onloadElement.style.lineHeight = height + 'px';
const checkboxes = document.querySelectorAll('.option-checkbox');
const selectedCountElement = document.getElementById('selectedCount');
let selectedCount = 0;
function updateSelectedCount() {
selectedCount = 0;
selectedValues = [];
checkboxes.forEach(checkbox => {
if (checkbox.checked) {
selectedCount++;
selectedValues.push(checkbox.value);
}
});
selectedCountElement.textContent = `此题已选择 ${selectedCount}/6 项`;
console.log('Selected Values:', selectedValues);
}
checkboxes.forEach(checkbox => {
checkbox.addEventListener('change', updateSelectedCount);
});
$('#onload').on('click', function() {
// 获取所有需要检查的输入字段
const nameInput = document.querySelector('.name-input');
const phoneInput = document.querySelector('.phone-input');
const companyInput = document.querySelector('.company-input');
const remarkInput = document.querySelector('.remark-input');
// 检查每个字段是否为空
let hasError = false;
let errorMessage = '';
if (!nameInput || nameInput.value.trim() === '') {
hasError = true;
errorMessage += '1. 客户姓名\n';
}
if (!phoneInput || phoneInput.value.trim() === '') {
hasError = true;
errorMessage += '2. 联系电话\n';
}
if (!companyInput || companyInput.value.trim() === '') {
hasError = true;
errorMessage += '3. 公司名称\n';
}
if (selectedCount === 0) {
hasError = true;
errorMessage += '4. 合作意向\n';
}
if (!remarkInput || remarkInput.value.trim() === '') {
hasError = true;
errorMessage += '5. 备注\n';
}
if (hasError) {
layer.msg('以下项目未填写或未选择:\n' + errorMessage, {icon: 2});
// alert('以下项目未填写或未选择:\n' + errorMessage);
return;
}
var index = layer.load(1, {
shade: [0.1, '#fff'] //0.1透明度的白色背景
});
// 如果所有字段都填写了,执行提交操作
$.ajax({
url: "business_cooperation_action", // 请求的url地址
dataType: "json", // 返回格式为json
async: true, // 请求是否异步默认为异步这也是ajax重要特性
data: {
"name": nameInput.value,
"phone": phoneInput.value,
"company": companyInput.value,
"selectedValues": selectedValues,
"remark": remarkInput.value
},
type: "POST", // 请求方式
success: function(req) {
layer.close(layer.index)
// 请求成功时处理
if(req.code == 0){
layer.msg(req.msg, {icon: 1});
setTimeout(() => {
window.location.reload();
}, 2000);
}else{
layer.msg(req.msg, {icon: 2});
}
},
error: function() {
layer.close(layer.index)
// 请求出错处理
layer.msg('网络错误了,请直接联系商务合作电话/微信13590959084', {icon: 2});
}
});
});
});
</script>

View File

@ -21,6 +21,13 @@ Route::any('/testedition/download', 'testapp/download/demo');
Route::any('/ceshi', 'app/download/ceshi');
Route::any('/get_class', 'admin/demo/get_class_xuesheng');
// 商务合作页面
Route::any('/business_cooperation', 'app/download/business_cooperation');
Route::any('/testedition/business_cooperation', 'testapp/download/business_cooperation');
Route::any('/business_cooperation_action', 'app/download/business_cooperation_action');
// // ################################################################二维码入口################################################################
// // ################################################################二维码入口################################################################
// 配合小白快乐成长&宠物小白使用
@ -28,9 +35,16 @@ Route::any('/ordinary_code', 'code/qrcode/ordinary_code');
// 配合reedaw&宠物小白使用
Route::any('/bluetooth_code', 'code/qrcode/bluetooth_code');
// // ################################################################设备请求入口################################################################
// // ################################################################设备请求入口################################################################
Route::any('/device_api_1', 'admin/device/device_request_api');
// Route::any('/CityList.js', 'tsf/CityList.js');
Route::any('/see_device_msg', 'admin/device/see_device_msg');
// // ################################################################管理后台################################################################
// // ################################################################管理后台################################################################
@ -113,7 +127,12 @@ Route::any('/notice/pop_edit', 'admin/notice/pop_edit');
Route::any('/notice/pop_add_or_update_action', 'admin/notice/pop_add_or_update_action');
Route::any('/notice/pop_update_sort', 'admin/notice/pop_update_sort');
Route::any('/notice/pop_stop_run', 'admin/notice/pop_stop_run');
// 公告管理
// 商业合作
Route::any('/business/business_index', 'admin/business/business_index');
Route::any('/business/business_download', 'admin/business/business_download');
// 联系我们H5
@ -367,6 +386,10 @@ Route::any('/testedition/get_recommend_information', 'testapp/Msginformation/get
Route::any('/get_business_cooperation_url', 'app/Msginformation/get_business_cooperation_url');
Route::any('/testedition/get_business_cooperation_url', 'testapp/Msginformation/get_business_cooperation_url');
// 重定向微信
Route::any('/open_wechat_content', 'app/Msginformation/open_wechat_content');
@ -375,6 +398,7 @@ Route::any('/testedition/get_business_cooperation_url', 'testapp/Msginformation/
// // ################################################################其它测试################################################################
// // ################################################################其它测试################################################################
Route::any('/is_wechat', 'admin/download/is_wechat');
Route::any('/use_test', 'admin/base/use_test');
// Route::any('/skip_kcal_calculate', 'app/skip/skip_kcal_calculate');
// Route::any('/readexcel', 'admin/execlaa/readexcel');

View File

@ -615,6 +615,10 @@ class Base extends Controller{
// 处理身高体重的单位转换它们为cm和kg。
function convertHeightAndWeight($height, $weight) {
// 加 bcadd(,,20)
// 减 bcsub(,,20)
// 乘 bcmul(,,20)
// 除 bcdiv(,,20)
// 定义单位转换比例
$heightConversion = [
'cm' => 1,
@ -635,8 +639,17 @@ class Base extends Controller{
];
// 处理 height
if (preg_match('/([\d.]+)(cm|inch|ft-in)/', $height, $matches)) {
$heightValue = floatval($matches[1]);
// $heightValue = floatval($matches[1]);
$heightValue = $matches[1];
$heightUnit = $matches[2];
if($heightUnit == 'ft-in'){
// 如果单位为st:lb但是数据格式不对
$heightValue = str_replace($heightUnit, "", $height);
if(count(explode('-', $heightValue)) < 2){
$heightValue = str_replace("-", "", $heightValue);
$heightValue = $heightValue."-0";
}
}
if (isset($heightConversion[$heightUnit])) {
if (is_callable($heightConversion[$heightUnit])) {
$heightInCm = $heightConversion[$heightUnit]($heightValue);
@ -656,10 +669,19 @@ class Base extends Controller{
}
}
// 处理 weight
if (preg_match('/([\d.]+)(kg|斤|st:lb|lb)/', $weight, $matches)) {
$weightValue = floatval($matches[1]);
if (preg_match('/([\d.:]+)(kg|斤|st:lb|lb)/', $weight, $matches)) {
$weightValue = $matches[1];
$weightUnit = $matches[2];
if($weightUnit == 'st:lb'){
// 如果单位为st:lb但是数据格式不对
$weightValue = str_replace($weightUnit, "", $weight);
if(count(explode(':', $weightValue)) < 2){
$weightValue = str_replace(":", "", $weightValue);
$weightValue = $weightValue.":0";
}
}
if (isset($weightConversion[$weightUnit])) {
if (is_callable($weightConversion[$weightUnit])) {
$weightInKg = $weightConversion[$weightUnit]($weightValue);
@ -678,10 +700,10 @@ class Base extends Controller{
$weightInKg = false;
}
}
return [
'height_in_cm' => $heightInCm,
'weight_in_kg' => $weightInKg
'height_in_cm' => bcmul($heightInCm,1,2),
'weight_in_kg' => bcmul($weightInKg,1,2)
];
}

View File

@ -241,7 +241,7 @@ class Card extends Base{
// 设备记录
// $data = ['id'=>'2','time'=>'1991-04-20 10:10:10','height'=>'15.1','weight'=>'75.1']
// public function card_manual_recording_device($data = ['aud_id'=>'37','height'=>'169.60,inch','weight'=>'52.45,lb','adc'=>'520.3','token'=>'591b70e0d80b5fa6d77e6e1384453ab9']){
public function card_manual_recording_device($data = ['aud_id'=>'37','height'=>'169.60斤','weight'=>'52.45斤','adc'=>'520.3','token'=>'591b70e0d80b5fa6d77e6e1384453ab9']){
public function card_manual_recording_device($data = ['aud_id'=>'37','height'=>'6-10ft-in','weight'=>'2:5.07st:lb','adc'=>'520.3','token'=>'591b70e0d80b5fa6d77e6e1384453ab9']){
try {
// 你的业务逻辑
if(count(input('post.')) > 0){
@ -267,34 +267,7 @@ class Card extends Base{
}
$data['height'] = $temporary_data['height_in_cm'];
$data['weight'] = $temporary_data['weight_in_kg'];
// if(!$this->verify_data_is_ok($data['height'],'num')){
// return $this->msg(10005);
// }
// if(!$this->verify_data_is_ok($data['weight'],'num')){
// return $this->msg(10005);
// }
// $data['height'] = explode(',',$data['height']);
// if(count($data['height']) < 2){
// return $this->msg(10005);
// }
// if(!$this->verify_data_is_ok($data['height'][0],'num')){
// return $this->msg(10005);
// }
// if(!in_array($data['height'][1],$this->unit_data['height'])){
// return $this->msg(10005);
// }
// $data['weight'] = explode(',',$data['weight']);
// if(count($data['height']) < 2){
// return $this->msg(10005);
// }
// if(!$this->verify_data_is_ok($data['weight'][0],'num')){
// return $this->msg(10005);
// }
// if(!in_array($data['weight'][1],$this->unit_data['weight'])){
// return $this->msg(10005);
// }
die;
$data['time'] = date('Y-m-d H:i:s');
$data['acd_id'] = '2';
$return_data = $this->set_user_body_data($data,'by_device');
@ -898,7 +871,6 @@ class Card extends Base{
// // 这里开始转换不同单位的身高体重为cm跟kgend
// $adc_type = $type;
// $data['type'] = 1;
// 判断头围数据是否存在是否合理
if(array_key_exists('head_data', $data)){
if(!$this->verify_data_is_ok($data['head_data'],'num')){

View File

@ -1,36 +1,57 @@
<?php
namespace app\app\controller;
namespace app\testapp\controller;
use think\Controller;
use think\Db;
class Download extends Base{
public function demo(){
// $num = Db::table('app_version_log')->order('id desc')->find();
// echo '你好,这里仅仅是个下载展示页面-1';
// echo '<br><a href="'.$num['download_url'].'">点击下载</a>';
$url = Db::table('app_version_log')->order('id desc')->find();
$this->assign([
'url' => $url['download_url'],
]);
return $this->fetch();
}
public function demo2(){
$url = Db::table('app_version_log')->order('id desc')->find();
$this->assign([
'url' => $url['download_url'],
]);
return $this->fetch();
}
public function business_cooperation(){
return $this->fetch();
}
public function business_cooperation_action(){
$data = input();
$result = Db::table('admin_business_cooperation_log')->insert([
'name'=>$data['name'],
'tel'=>$data['phone'],
'company'=>$data['company'],
'intention_data'=>implode(',',$data['selectedValues']),
'notes_data'=>$data['remark'],
'create_time'=>date('Y-m-d H:i:s'),
]);
if($result){
return json(['code'=>0,'msg'=>'提交成功']);
}else{
return json(['code'=>10001,'msg'=>'网络错误,请直接联系商务合作电话/微信13590959084']);
}
}
#########################################################################其它#########################################################################
#########################################################################其它#########################################################################
#########################################################################其它#########################################################################
public function ceshi(){
$data = input();
$url = 'https://klcz.pcxbc.com/open-api/calc/healthcalc/bodyfat3';

View File

@ -1,6 +1,6 @@
<?php
namespace app\testapp\controller;
namespace app\app\controller;
use think\Db;
@ -25,9 +25,7 @@ class Msginformation extends Base{
// 获取板块,及板块下类型标签
public function get_sector_label_msg($data = ['token'=>'6441bf7dabea7b3360a30240d3b19fc5']){
try {
if(count(input('post.')) > 0){
$data = input('post.');
}
$data = input('post.');
if(!array_key_exists('token', $data)){
return $this->msg(10001);
}
@ -72,6 +70,10 @@ class Msginformation extends Base{
}
if(!$this->verify_data_is_ok($data['page'],'intnum')){
return $this->msg(10005);
}else{
if($data['page'] < 1){
return $this->msg(10005,'页码不能小于1');
}
}
$return_data = $this->get_sector_content_msg_action($data);
@ -131,7 +133,7 @@ class Msginformation extends Base{
}
// 获取公告文章信息列表&banner
public function get_recommend_information($data=['token'=>'6441bf7dabea7b3360a30240d3b19fc5']){
// try {
try {
if(count(input('post.')) > 0){
$data = input('post.');
}
@ -145,19 +147,19 @@ class Msginformation extends Base{
$return_result = $this->get_recommend_information_action($data);
$this->record_api_log($data, null, $return_result);
return $return_result;
// } catch (\Exception $e) {
// // 捕获异常
// $logContent["flie"] = $e->getFile();
// $logContent["line"] = $e->getLine();
// $logContent['all_content'] = "异常信息:\n";
// $logContent['all_content'] .= "消息: " . $e->getMessage() . "\n";
// $logContent['all_content'] .= "代码: " . $e->getCode() . "\n";
// $logContent['all_content'] .= "文件: " . $e->getFile() . "\n";
// $logContent['all_content'] .= "行号: " . $e->getLine() . "\n";
// $logContent['all_content'] .= "跟踪信息:\n" . $e->getTraceAsString() . "\n";
// $this->record_api_log($data, $logContent, null);
// return $this->msg(99999);
// }
} catch (\Exception $e) {
// 捕获异常
$logContent["flie"] = $e->getFile();
$logContent["line"] = $e->getLine();
$logContent['all_content'] = "异常信息:\n";
$logContent['all_content'] .= "消息: " . $e->getMessage() . "\n";
$logContent['all_content'] .= "代码: " . $e->getCode() . "\n";
$logContent['all_content'] .= "文件: " . $e->getFile() . "\n";
$logContent['all_content'] .= "行号: " . $e->getLine() . "\n";
$logContent['all_content'] .= "跟踪信息:\n" . $e->getTraceAsString() . "\n";
$this->record_api_log($data, $logContent, null);
return $this->msg(99999);
}
}
// 获取商务合作链接
@ -214,6 +216,38 @@ class Msginformation extends Base{
return $this->msg(99999);
}
}
// 给微信使用的中间页(拉起微信)
// public function open_wechat_content($data=['id'=>8]){
public function open_wechat_content(){
try {
$data = input();
if(!array_key_exists('id', $data)){
$this->record_api_log($data, null, ['code'=>10001,'msg'=>'',[]]);
return $this->msg(10001);
}
$url = Db::table('admin_notice_banner')->where(['id'=>$data['id']])->field('type,jump_url')->find();
if(!$url['type'] || $url['type'] != 2){
echo '<div style="font-size: 30px;font-weight: bold;">页面跑丢了... =。=</div>';
die;
}
header('Location: '.$url['jump_url']);
} catch (\Exception $e) {
// 捕获异常
$logContent["flie"] = $e->getFile();
$logContent["line"] = $e->getLine();
$logContent['all_content'] = "异常信息:\n";
$logContent['all_content'] .= "消息: " . $e->getMessage() . "\n";
$logContent['all_content'] .= "代码: " . $e->getCode() . "\n";
$logContent['all_content'] .= "文件: " . $e->getFile() . "\n";
$logContent['all_content'] .= "行号: " . $e->getLine() . "\n";
$logContent['all_content'] .= "跟踪信息:\n" . $e->getTraceAsString() . "\n";
$this->record_api_log($data, $logContent, null);
return $this->msg(99999);
}
}
################################################################业务################################################################
################################################################get_sector_label_msg
public function get_sector_label_msg_action($data){
@ -264,7 +298,8 @@ class Msginformation extends Base{
");
if(count($loop_result) > 0){
foreach ($loop_result as $k => $v) {
$loop_result[$key]['jump_url'] = "https://tc.pcxbc.com/editortext/model_content?id=".$v['id']."&token=".$data['token'];
// $loop_result[$key]['jump_url'] = "https://tc.pcxbc.com/editortext/model_content?id=".$v['id']."&token=".$data['token'];
$loop_result[$key]['jump_url'] = "https://tc.pcxbc.com/editortext/model_content";
}
}
$Template_arr[$value]['loop_data'] = $loop_result;
@ -307,7 +342,8 @@ class Msginformation extends Base{
");
if(count($content_result) > 0){
foreach ($content_result as $key => $value) {
$content_result[$key]['jump_url'] = "https://tc.pcxbc.com/editortext/model_content?id=".$value['id']."&token=".$data['token'];
// $content_result[$key]['jump_url'] = "https://tc.pcxbc.com/editortext/model_content?id=".$value['id']."&token=".$data['token'];
$content_result[$key]['jump_url'] = "https://tc.pcxbc.com/editortext/model_content";
}
}
$return_result['content_data'] = $content_result;
@ -390,7 +426,7 @@ class Msginformation extends Base{
'notice'=>[],
'banner'=>[]
];
return $this->msg($return_data);
// return $this->msg($return_data);
// 所有可用记录
$all_data = Db::table($this->msginformation_use_db_name['3'])->where(['is_del'=>0])->select();
// 用户阅读记录
@ -407,12 +443,14 @@ class Msginformation extends Base{
if($value['scene_data'] != 3){
unset($all_data[$key]);
}else{
$all_data[$key]['jump_url'] = $all_data[$key]['jump_url']."&token=".$data['token'];
// $all_data[$key]['jump_url'] = $all_data[$key]['jump_url']."&token=".$data['token'];
$all_data[$key]['jump_url'] = $all_data[$key]['jump_url'];
$all_data[$key]['type'] = 'h5';
$all_data[$key]['id'] = $value['parameter_data'];
}
}else{
$all_data[$key]['jump_url'] = $all_data[$key]['jump_url']."&token=".$data['token'];
// $all_data[$key]['jump_url'] = $all_data[$key]['jump_url']."&token=".$data['token'];
$all_data[$key]['jump_url'] = $all_data[$key]['jump_url'];
$all_data[$key]['type'] = 'h5';
$all_data[$key]['id'] = $value['parameter_data'];
}
@ -430,6 +468,9 @@ class Msginformation extends Base{
$all_data[$key]['appid'] = $appid;
$all_data[$key]['path'] = $path;
// 重新定义跳转链接为中间页
$all_data[$key]['jump_url'] = "https://tc.pcxbc.com/open_wechat_content";
}
// $all_data[$key]['id'] = $all_data[$key]['parameter_data'];
unset($all_data[$key]['parameter_data']);

View File

@ -0,0 +1,377 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport"
content="width=device-width, initial-scale=1,minimum-scale=1, maximum-scale=1,user-scalable=no">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<meta http-equiv="Access-Control-Allow-Origin" content="*">
<meta name="apple-mobile-web-app-capable" content="yes">
<meta name="apple-mobile-web-app-status-bar-style" content="black">
<meta name="format-detection" content="telephone=no, email=no">
<meta name="full-screen" content="true">
<meta name="screen-orientation" content="portrait">
<meta name="x5-fullscreen" content="true">
<meta name="360-fullscreen" content="true">
<title>商务合作</title>
<script src="/x_admin/js/jq.js"></script>
<style>
*{
padding: 0 0;
margin: 0 0;
}
.big_box{
width: 100vw;
min-height: 100vh;
position: absolute;
top: 0;
left: 0;
background: url(/tsf/business_bg.jpg) no-repeat;
background-size: 100% 100%;
display: flex;
flex-direction: column;
flex-wrap: nowrap;
align-items: center;
}
.content{
width: 85vw;
max-width: 880px;
display: flex;
flex-direction: column;
flex-wrap: nowrap;
border-radius: 1vw;
background-color: white;
margin: 24px 0;
overflow: hidden;
align-items: center;
}
.content img{
width: 100%;
height: auto;
}
.content_c{
width: 100%;
padding: 2% 12%;
box-sizing: border-box;
}
.title_t{
border: none;
text-align: center;
color: rgba(8, 14, 23, 0.9);
font-weight: 600;
font-size: 28px;
line-height: 40px;
word-break: break-all;
white-space: pre-wrap;
overflow: visible;
margin: 4% 0;
}
.title_c2{
font-size: 12px;
margin-bottom: 10%;
}
.title_c2 span{
color: rgb(17, 106, 240);
}
.write_box{
width: 100%;
font-size: 16px;
margin: 10% 0;
}
.write_box_t{
font-weight: 600;
}
.write_box_r{
color: red;
}
.write_k{
padding: 8px 12px;
position: relative;
border-radius: 6px;
border: 1px solid rgba(8, 14, 23, 0.24);
display: flex;
outline: 0 !important;
word-break: break-all;
margin: 2% 0;
}
.write_k textarea{
width: 100%;
resize: none;
text-overflow: ellipsis;
line-height: 22px;
border: none !important;
border-radius: 0;
background: transparent !important;
box-shadow: none !important;
outline: 0 !important;
cursor: auto;
padding: 0;
min-height: 22px;
margin: 0 1%;
}
.ksapc-select-write {
width: 100%;
}
.ksapc-select-write-tip {
margin-bottom: 10px;
font-size: 14px;
color: #8E9095;
}
.ksapc-select-write-tile {
width: 100%;
}
.ksapc-checkboxgroup {
width: 100%;
}
.ksapc-row {
display: flex;
flex-wrap: wrap;
gap: 14px;
}
.ksapc-col {
flex: 1 1 48%; /* 两列布局 */
}
.ksapc-checkbox {
display: flex;
align-items: center;
}
.ksapc-checkbox input {
margin-right: 8px;
}
.ksapc-checkbox span{
font-size: 14px;
cursor: pointer;
}
#onload{
width: 20vw;
height: 5vw;
background-color: #0A6CFF;
color: white;
border-radius: 10px;
line-height: 5vw;
text-align: center;
font-size: 15px;
font-weight: bold;
margin-bottom: 35px;
cursor: pointer; /* 添加小手图标 */
}
</style>
</head>
<body id="box_k">
<div class="big_box">
<div class="content">
<img src="/tsf/business_title.jpg" alt="">
<div class="content_c">
<div class="title_t">商务合作意向登记表</div>
<div class="title_c2">
智能设备产品包<span>含身高测量仪、体重体脂秤、宠物秤, 母婴秤,厨房秤,商业秤,身高体重/体脂秤,八电极体脂秤,运动训练设备</span>等;软件包含就智能健康管理系统,智能硬件管理系统等,支持智能设备选购/定制、健康系统对接/定制行业解决方案等您也可以直接拨打或微信联系13590959084期待与您合作
</div>
<div class="write_box">
<div class="write_box_t">
<span class="write_box_r">*</span>&nbsp; 1.客户姓名
</div>
<div class="write_k">
<textarea placeholder="请输入" rows="1" oninput="autoResize(this)" class="name-input"></textarea>
</div>
</div>
<div class="write_box">
<div class="write_box_t">
<span class="write_box_r">*</span>&nbsp; 2.联系电话
</div>
<div class="write_k">
<textarea placeholder="请输入手机号" rows="1" oninput="autoResize(this)" class="phone-input"></textarea>
</div>
</div>
<div class="write_box">
<div class="write_box_t">
<span class="write_box_r">*</span>&nbsp; 3.公司名称
</div>
<div class="write_k">
<textarea placeholder="请输入" rows="1" oninput="autoResize(this)" class="company-input"></textarea>
</div>
</div>
<div class="write_box">
<div class="write_box_t">
<span class="write_box_r">*</span>&nbsp; 4.合作意向
</div>
<div class="write_k" style="border: none;">
<div class="ksapc-select-write">
<div class="ksapc-select-write-tip" id="selectedCount">此题已选择 0/6 项</div>
<div class="ksapc-select-write-tile">
<div class="ksapc-checkboxgroup">
<div class="ksapc-row">
<div class="ksapc-col">
<label class="ksapc-checkbox">
<input type="checkbox" class="option-checkbox" value="智能设备">
<span>智能设备</span>
</label>
</div>
<div class="ksapc-col">
<label class="ksapc-checkbox">
<input type="checkbox" class="option-checkbox" value="健康软件">
<span>健康软件</span>
</label>
</div>
<div class="ksapc-col">
<label class="ksapc-checkbox">
<input type="checkbox" class="option-checkbox" value="解决方案">
<span>解决方案</span>
</label>
</div>
<div class="ksapc-col">
<label class="ksapc-checkbox">
<input type="checkbox" class="option-checkbox" value="系统定制">
<span>系统定制</span>
</label>
</div>
<div class="ksapc-col">
<label class="ksapc-checkbox">
<input type="checkbox" class="option-checkbox" value="设备定制">
<span>设备定制</span>
</label>
</div>
<div class="ksapc-col">
<label class="ksapc-checkbox">
<input type="checkbox" class="option-checkbox" value="其它">
<span>其它可联系商务合作13590959084</span>
</label>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="write_box">
<div class="write_box_t">
<span class="write_box_r">*</span>&nbsp; 5.备注
</div>
<div class="write_k">
<textarea placeholder="请输入" rows="1" oninput="autoResize(this)" class="remark-input"></textarea>
</div>
</div>
<div class="write_box" style="color: #8E9095;">
商务合作电话/微信13590959084
</div>
</div>
<div id="onload">提交</div>
</div>
</div>
</body>
</html>
<script>
var selectedValues = [];
function autoResize(textarea) {
textarea.style.height = 'auto'; // 重置高度
textarea.style.height = textarea.scrollHeight + 'px'; // 设置为内容高度
}
document.addEventListener('DOMContentLoaded', function() {
const checkboxes = document.querySelectorAll('.option-checkbox');
const selectedCountElement = document.getElementById('selectedCount');
let selectedCount = 0;
function updateSelectedCount() {
selectedCount = 0;
selectedValues = [];
checkboxes.forEach(checkbox => {
if (checkbox.checked) {
selectedCount++;
selectedValues.push(checkbox.value);
}
});
selectedCountElement.textContent = `此题已选择 ${selectedCount}/6 项`;
console.log('Selected Values:', selectedValues);
}
checkboxes.forEach(checkbox => {
checkbox.addEventListener('change', updateSelectedCount);
});
$('#onload').on('click', function() {
var index = layer.load(1, {
shade: [0.1, '#fff'] //0.1透明度的白色背景
});
// 获取所有需要检查的输入字段
const nameInput = document.querySelector('.name-input');
const phoneInput = document.querySelector('.phone-input');
const companyInput = document.querySelector('.company-input');
const remarkInput = document.querySelector('.remark-input');
// 检查每个字段是否为空
let hasError = false;
let errorMessage = '';
if (!nameInput || nameInput.value.trim() === '') {
hasError = true;
errorMessage += '1. 客户姓名\n';
}
if (!phoneInput || phoneInput.value.trim() === '') {
hasError = true;
errorMessage += '2. 联系电话\n';
}
if (!companyInput || companyInput.value.trim() === '') {
hasError = true;
errorMessage += '3. 公司名称\n';
}
if (selectedCount === 0) {
hasError = true;
errorMessage += '4. 合作意向\n';
}
if (!remarkInput || remarkInput.value.trim() === '') {
hasError = true;
errorMessage += '5. 备注\n';
}
if (hasError) {
alert('以下项目未填写或未选择:\n' + errorMessage);
return;
}
// 如果所有字段都填写了,执行提交操作
$.ajax({
url: "business_cooperation_action", // 请求的url地址
dataType: "json", // 返回格式为json
async: true, // 请求是否异步默认为异步这也是ajax重要特性
data: {
"name": nameInput.value,
"phone": phoneInput.value,
"company": companyInput.value,
"selectedValues": selectedValues,
"remark": remarkInput.value
},
type: "POST", // 请求方式
success: function(req) {
layer.close(layer.index)
// 请求成功时处理
layer.msg(req.msg, {icon: 2});
if(req.code == 0){
setTimeout(() => {
window.location.reload();
}, 1000);
}
},
error: function() {
layer.close(layer.index)
// 请求出错处理
alert('提交失败,请重试。');
}
});
});
});
</script>

View File

@ -30,6 +30,9 @@
"think-path": "thinkphp"
},
"config": {
"preferred-install": "dist"
"preferred-install": "dist",
"allow-plugins": {
"topthink/think-installer": true
}
}
}

BIN
public/tsf/business_bg.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

18
vendor/autoload.php vendored
View File

@ -2,6 +2,24 @@
// autoload.php @generated by Composer
if (PHP_VERSION_ID < 50600) {
if (!headers_sent()) {
header('HTTP/1.1 500 Internal Server Error');
}
$err = 'Composer 2.3.0 dropped support for autoloading on PHP <5.6 and you are running '.PHP_VERSION.', please upgrade PHP or use Composer 2.2 LTS via "composer self-update --2.2". Aborting.'.PHP_EOL;
if (!ini_get('display_errors')) {
if (PHP_SAPI === 'cli' || PHP_SAPI === 'phpdbg') {
fwrite(STDERR, $err);
} elseif (!headers_sent()) {
echo $err;
}
}
trigger_error(
$err,
E_USER_ERROR
);
}
require_once __DIR__ . '/composer/autoload_real.php';
return ComposerAutoloaderInit2bc4f313dba415539e266f7ac2c87dcd::getLoader();

View File

@ -37,26 +37,81 @@ namespace Composer\Autoload;
*
* @author Fabien Potencier <fabien@symfony.com>
* @author Jordi Boggiano <j.boggiano@seld.be>
* @see http://www.php-fig.org/psr/psr-0/
* @see http://www.php-fig.org/psr/psr-4/
* @see https://www.php-fig.org/psr/psr-0/
* @see https://www.php-fig.org/psr/psr-4/
*/
class ClassLoader
{
/** @var \Closure(string):void */
private static $includeFile;
/** @var string|null */
private $vendorDir;
// PSR-4
/**
* @var array<string, array<string, int>>
*/
private $prefixLengthsPsr4 = array();
/**
* @var array<string, list<string>>
*/
private $prefixDirsPsr4 = array();
/**
* @var list<string>
*/
private $fallbackDirsPsr4 = array();
// PSR-0
/**
* List of PSR-0 prefixes
*
* Structured as array('F (first letter)' => array('Foo\Bar (full prefix)' => array('path', 'path2')))
*
* @var array<string, array<string, list<string>>>
*/
private $prefixesPsr0 = array();
/**
* @var list<string>
*/
private $fallbackDirsPsr0 = array();
/** @var bool */
private $useIncludePath = false;
/**
* @var array<string, string>
*/
private $classMap = array();
/** @var bool */
private $classMapAuthoritative = false;
/**
* @var array<string, bool>
*/
private $missingClasses = array();
/** @var string|null */
private $apcuPrefix;
/**
* @var array<string, self>
*/
private static $registeredLoaders = array();
/**
* @param string|null $vendorDir
*/
public function __construct($vendorDir = null)
{
$this->vendorDir = $vendorDir;
self::initializeIncludeClosure();
}
/**
* @return array<string, list<string>>
*/
public function getPrefixes()
{
if (!empty($this->prefixesPsr0)) {
@ -66,28 +121,42 @@ class ClassLoader
return array();
}
/**
* @return array<string, list<string>>
*/
public function getPrefixesPsr4()
{
return $this->prefixDirsPsr4;
}
/**
* @return list<string>
*/
public function getFallbackDirs()
{
return $this->fallbackDirsPsr0;
}
/**
* @return list<string>
*/
public function getFallbackDirsPsr4()
{
return $this->fallbackDirsPsr4;
}
/**
* @return array<string, string> Array of classname => path
*/
public function getClassMap()
{
return $this->classMap;
}
/**
* @param array $classMap Class to filename map
* @param array<string, string> $classMap Class to filename map
*
* @return void
*/
public function addClassMap(array $classMap)
{
@ -102,22 +171,25 @@ class ClassLoader
* Registers a set of PSR-0 directories for a given prefix, either
* appending or prepending to the ones previously set for this prefix.
*
* @param string $prefix The prefix
* @param array|string $paths The PSR-0 root directories
* @param bool $prepend Whether to prepend the directories
* @param string $prefix The prefix
* @param list<string>|string $paths The PSR-0 root directories
* @param bool $prepend Whether to prepend the directories
*
* @return void
*/
public function add($prefix, $paths, $prepend = false)
{
$paths = (array) $paths;
if (!$prefix) {
if ($prepend) {
$this->fallbackDirsPsr0 = array_merge(
(array) $paths,
$paths,
$this->fallbackDirsPsr0
);
} else {
$this->fallbackDirsPsr0 = array_merge(
$this->fallbackDirsPsr0,
(array) $paths
$paths
);
}
@ -126,19 +198,19 @@ class ClassLoader
$first = $prefix[0];
if (!isset($this->prefixesPsr0[$first][$prefix])) {
$this->prefixesPsr0[$first][$prefix] = (array) $paths;
$this->prefixesPsr0[$first][$prefix] = $paths;
return;
}
if ($prepend) {
$this->prefixesPsr0[$first][$prefix] = array_merge(
(array) $paths,
$paths,
$this->prefixesPsr0[$first][$prefix]
);
} else {
$this->prefixesPsr0[$first][$prefix] = array_merge(
$this->prefixesPsr0[$first][$prefix],
(array) $paths
$paths
);
}
}
@ -147,25 +219,28 @@ class ClassLoader
* Registers a set of PSR-4 directories for a given namespace, either
* appending or prepending to the ones previously set for this namespace.
*
* @param string $prefix The prefix/namespace, with trailing '\\'
* @param array|string $paths The PSR-4 base directories
* @param bool $prepend Whether to prepend the directories
* @param string $prefix The prefix/namespace, with trailing '\\'
* @param list<string>|string $paths The PSR-4 base directories
* @param bool $prepend Whether to prepend the directories
*
* @throws \InvalidArgumentException
*
* @return void
*/
public function addPsr4($prefix, $paths, $prepend = false)
{
$paths = (array) $paths;
if (!$prefix) {
// Register directories for the root namespace.
if ($prepend) {
$this->fallbackDirsPsr4 = array_merge(
(array) $paths,
$paths,
$this->fallbackDirsPsr4
);
} else {
$this->fallbackDirsPsr4 = array_merge(
$this->fallbackDirsPsr4,
(array) $paths
$paths
);
}
} elseif (!isset($this->prefixDirsPsr4[$prefix])) {
@ -175,18 +250,18 @@ class ClassLoader
throw new \InvalidArgumentException("A non-empty PSR-4 prefix must end with a namespace separator.");
}
$this->prefixLengthsPsr4[$prefix[0]][$prefix] = $length;
$this->prefixDirsPsr4[$prefix] = (array) $paths;
$this->prefixDirsPsr4[$prefix] = $paths;
} elseif ($prepend) {
// Prepend directories for an already registered namespace.
$this->prefixDirsPsr4[$prefix] = array_merge(
(array) $paths,
$paths,
$this->prefixDirsPsr4[$prefix]
);
} else {
// Append directories for an already registered namespace.
$this->prefixDirsPsr4[$prefix] = array_merge(
$this->prefixDirsPsr4[$prefix],
(array) $paths
$paths
);
}
}
@ -195,8 +270,10 @@ class ClassLoader
* Registers a set of PSR-0 directories for a given prefix,
* replacing any others previously set for this prefix.
*
* @param string $prefix The prefix
* @param array|string $paths The PSR-0 base directories
* @param string $prefix The prefix
* @param list<string>|string $paths The PSR-0 base directories
*
* @return void
*/
public function set($prefix, $paths)
{
@ -211,10 +288,12 @@ class ClassLoader
* Registers a set of PSR-4 directories for a given namespace,
* replacing any others previously set for this namespace.
*
* @param string $prefix The prefix/namespace, with trailing '\\'
* @param array|string $paths The PSR-4 base directories
* @param string $prefix The prefix/namespace, with trailing '\\'
* @param list<string>|string $paths The PSR-4 base directories
*
* @throws \InvalidArgumentException
*
* @return void
*/
public function setPsr4($prefix, $paths)
{
@ -234,6 +313,8 @@ class ClassLoader
* Turns on searching the include path for class files.
*
* @param bool $useIncludePath
*
* @return void
*/
public function setUseIncludePath($useIncludePath)
{
@ -256,6 +337,8 @@ class ClassLoader
* that have not been registered with the class map.
*
* @param bool $classMapAuthoritative
*
* @return void
*/
public function setClassMapAuthoritative($classMapAuthoritative)
{
@ -276,6 +359,8 @@ class ClassLoader
* APCu prefix to use to cache found/not-found classes, if the extension is enabled.
*
* @param string|null $apcuPrefix
*
* @return void
*/
public function setApcuPrefix($apcuPrefix)
{
@ -296,33 +381,55 @@ class ClassLoader
* Registers this instance as an autoloader.
*
* @param bool $prepend Whether to prepend the autoloader or not
*
* @return void
*/
public function register($prepend = false)
{
spl_autoload_register(array($this, 'loadClass'), true, $prepend);
if (null === $this->vendorDir) {
return;
}
if ($prepend) {
self::$registeredLoaders = array($this->vendorDir => $this) + self::$registeredLoaders;
} else {
unset(self::$registeredLoaders[$this->vendorDir]);
self::$registeredLoaders[$this->vendorDir] = $this;
}
}
/**
* Unregisters this instance as an autoloader.
*
* @return void
*/
public function unregister()
{
spl_autoload_unregister(array($this, 'loadClass'));
if (null !== $this->vendorDir) {
unset(self::$registeredLoaders[$this->vendorDir]);
}
}
/**
* Loads the given class or interface.
*
* @param string $class The name of the class
* @return bool|null True if loaded, null otherwise
* @return true|null True if loaded, null otherwise
*/
public function loadClass($class)
{
if ($file = $this->findFile($class)) {
includeFile($file);
$includeFile = self::$includeFile;
$includeFile($file);
return true;
}
return null;
}
/**
@ -367,6 +474,21 @@ class ClassLoader
return $file;
}
/**
* Returns the currently registered loaders keyed by their corresponding vendor directories.
*
* @return array<string, self>
*/
public static function getRegisteredLoaders()
{
return self::$registeredLoaders;
}
/**
* @param string $class
* @param string $ext
* @return string|false
*/
private function findFileWithExtension($class, $ext)
{
// PSR-4 lookup
@ -432,14 +554,26 @@ class ClassLoader
return false;
}
}
/**
* Scope isolated include.
*
* Prevents access to $this/self from included files.
*/
function includeFile($file)
{
include $file;
/**
* @return void
*/
private static function initializeIncludeClosure()
{
if (self::$includeFile !== null) {
return;
}
/**
* Scope isolated include.
*
* Prevents access to $this/self from included files.
*
* @param string $file
* @return void
*/
self::$includeFile = \Closure::bind(static function($file) {
include $file;
}, null, null);
}
}

362
vendor/composer/InstalledVersions.php vendored Normal file
View File

@ -0,0 +1,362 @@
<?php
/*
* This file is part of Composer.
*
* (c) Nils Adermann <naderman@naderman.de>
* Jordi Boggiano <j.boggiano@seld.be>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Composer;
use Composer\Autoload\ClassLoader;
use Composer\Semver\VersionParser;
/**
* This class is copied in every Composer installed project and available to all
*
* See also https://getcomposer.org/doc/07-runtime.md#installed-versions
*
* To require its presence, you can require `composer-runtime-api ^2.0`
*
* @final
*/
class InstalledVersions
{
/**
* @var mixed[]|null
* @psalm-var array{root: array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool}, versions: array<string, array{pretty_version?: string, version?: string, reference?: string|null, type?: string, install_path?: string, aliases?: string[], dev_requirement: bool, replaced?: string[], provided?: string[]}>}|array{}|null
*/
private static $installed;
/**
* @var bool|null
*/
private static $canGetVendors;
/**
* @var array[]
* @psalm-var array<string, array{root: array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool}, versions: array<string, array{pretty_version?: string, version?: string, reference?: string|null, type?: string, install_path?: string, aliases?: string[], dev_requirement: bool, replaced?: string[], provided?: string[]}>}>
*/
private static $installedByVendor = array();
/**
* Returns a list of all package names which are present, either by being installed, replaced or provided
*
* @return string[]
* @psalm-return list<string>
*/
public static function getInstalledPackages()
{
$packages = array();
foreach (self::getInstalled() as $installed) {
$packages[] = array_keys($installed['versions']);
}
if (1 === \count($packages)) {
return $packages[0];
}
return array_keys(array_flip(\call_user_func_array('array_merge', $packages)));
}
/**
* Returns a list of all package names with a specific type e.g. 'library'
*
* @param string $type
* @return string[]
* @psalm-return list<string>
*/
public static function getInstalledPackagesByType($type)
{
$packagesByType = array();
foreach (self::getInstalled() as $installed) {
foreach ($installed['versions'] as $name => $package) {
if (isset($package['type']) && $package['type'] === $type) {
$packagesByType[] = $name;
}
}
}
return $packagesByType;
}
/**
* Checks whether the given package is installed
*
* This also returns true if the package name is provided or replaced by another package
*
* @param string $packageName
* @param bool $includeDevRequirements
* @return bool
*/
public static function isInstalled($packageName, $includeDevRequirements = true)
{
foreach (self::getInstalled() as $installed) {
if (isset($installed['versions'][$packageName])) {
return $includeDevRequirements || !isset($installed['versions'][$packageName]['dev_requirement']) || $installed['versions'][$packageName]['dev_requirement'] === false;
}
}
return false;
}
/**
* Checks whether the given package satisfies a version constraint
*
* e.g. If you want to know whether version 2.3+ of package foo/bar is installed, you would call:
*
* Composer\InstalledVersions::satisfies(new VersionParser, 'foo/bar', '^2.3')
*
* @param VersionParser $parser Install composer/semver to have access to this class and functionality
* @param string $packageName
* @param string|null $constraint A version constraint to check for, if you pass one you have to make sure composer/semver is required by your package
* @return bool
*/
public static function satisfies(VersionParser $parser, $packageName, $constraint)
{
$constraint = $parser->parseConstraints((string) $constraint);
$provided = $parser->parseConstraints(self::getVersionRanges($packageName));
return $provided->matches($constraint);
}
/**
* Returns a version constraint representing all the range(s) which are installed for a given package
*
* It is easier to use this via isInstalled() with the $constraint argument if you need to check
* whether a given version of a package is installed, and not just whether it exists
*
* @param string $packageName
* @return string Version constraint usable with composer/semver
*/
public static function getVersionRanges($packageName)
{
foreach (self::getInstalled() as $installed) {
if (!isset($installed['versions'][$packageName])) {
continue;
}
$ranges = array();
if (isset($installed['versions'][$packageName]['pretty_version'])) {
$ranges[] = $installed['versions'][$packageName]['pretty_version'];
}
if (array_key_exists('aliases', $installed['versions'][$packageName])) {
$ranges = array_merge($ranges, $installed['versions'][$packageName]['aliases']);
}
if (array_key_exists('replaced', $installed['versions'][$packageName])) {
$ranges = array_merge($ranges, $installed['versions'][$packageName]['replaced']);
}
if (array_key_exists('provided', $installed['versions'][$packageName])) {
$ranges = array_merge($ranges, $installed['versions'][$packageName]['provided']);
}
return implode(' || ', $ranges);
}
throw new \OutOfBoundsException('Package "' . $packageName . '" is not installed');
}
/**
* @param string $packageName
* @return string|null If the package is being replaced or provided but is not really installed, null will be returned as version, use satisfies or getVersionRanges if you need to know if a given version is present
*/
public static function getVersion($packageName)
{
foreach (self::getInstalled() as $installed) {
if (!isset($installed['versions'][$packageName])) {
continue;
}
if (!isset($installed['versions'][$packageName]['version'])) {
return null;
}
return $installed['versions'][$packageName]['version'];
}
throw new \OutOfBoundsException('Package "' . $packageName . '" is not installed');
}
/**
* @param string $packageName
* @return string|null If the package is being replaced or provided but is not really installed, null will be returned as version, use satisfies or getVersionRanges if you need to know if a given version is present
*/
public static function getPrettyVersion($packageName)
{
foreach (self::getInstalled() as $installed) {
if (!isset($installed['versions'][$packageName])) {
continue;
}
if (!isset($installed['versions'][$packageName]['pretty_version'])) {
return null;
}
return $installed['versions'][$packageName]['pretty_version'];
}
throw new \OutOfBoundsException('Package "' . $packageName . '" is not installed');
}
/**
* @param string $packageName
* @return string|null If the package is being replaced or provided but is not really installed, null will be returned as reference
*/
public static function getReference($packageName)
{
foreach (self::getInstalled() as $installed) {
if (!isset($installed['versions'][$packageName])) {
continue;
}
if (!isset($installed['versions'][$packageName]['reference'])) {
return null;
}
return $installed['versions'][$packageName]['reference'];
}
throw new \OutOfBoundsException('Package "' . $packageName . '" is not installed');
}
/**
* @param string $packageName
* @return string|null If the package is being replaced or provided but is not really installed, null will be returned as install path. Packages of type metapackages also have a null install path.
*/
public static function getInstallPath($packageName)
{
foreach (self::getInstalled() as $installed) {
if (!isset($installed['versions'][$packageName])) {
continue;
}
return isset($installed['versions'][$packageName]['install_path']) ? $installed['versions'][$packageName]['install_path'] : null;
}
throw new \OutOfBoundsException('Package "' . $packageName . '" is not installed');
}
/**
* @return array
* @psalm-return array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool}
*/
public static function getRootPackage()
{
$installed = self::getInstalled();
return $installed[0]['root'];
}
/**
* Returns the raw installed.php data for custom implementations
*
* @deprecated Use getAllRawData() instead which returns all datasets for all autoloaders present in the process. getRawData only returns the first dataset loaded, which may not be what you expect.
* @return array[]
* @psalm-return array{root: array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool}, versions: array<string, array{pretty_version?: string, version?: string, reference?: string|null, type?: string, install_path?: string, aliases?: string[], dev_requirement: bool, replaced?: string[], provided?: string[]}>}
*/
public static function getRawData()
{
@trigger_error('getRawData only returns the first dataset loaded, which may not be what you expect. Use getAllRawData() instead which returns all datasets for all autoloaders present in the process.', E_USER_DEPRECATED);
if (null === self::$installed) {
// only require the installed.php file if this file is loaded from its dumped location,
// and not from its source location in the composer/composer package, see https://github.com/composer/composer/issues/9937
if (substr(__DIR__, -8, 1) !== 'C') {
self::$installed = include __DIR__ . '/installed.php';
} else {
self::$installed = array();
}
}
return self::$installed;
}
/**
* Returns the raw data of all installed.php which are currently loaded for custom implementations
*
* @return array[]
* @psalm-return list<array{root: array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool}, versions: array<string, array{pretty_version?: string, version?: string, reference?: string|null, type?: string, install_path?: string, aliases?: string[], dev_requirement: bool, replaced?: string[], provided?: string[]}>}>
*/
public static function getAllRawData()
{
return self::getInstalled();
}
/**
* Lets you reload the static array from another file
*
* This is only useful for complex integrations in which a project needs to use
* this class but then also needs to execute another project's autoloader in process,
* and wants to ensure both projects have access to their version of installed.php.
*
* A typical case would be PHPUnit, where it would need to make sure it reads all
* the data it needs from this class, then call reload() with
* `require $CWD/vendor/composer/installed.php` (or similar) as input to make sure
* the project in which it runs can then also use this class safely, without
* interference between PHPUnit's dependencies and the project's dependencies.
*
* @param array[] $data A vendor/composer/installed.php data set
* @return void
*
* @psalm-param array{root: array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool}, versions: array<string, array{pretty_version?: string, version?: string, reference?: string|null, type?: string, install_path?: string, aliases?: string[], dev_requirement: bool, replaced?: string[], provided?: string[]}>} $data
*/
public static function reload($data)
{
self::$installed = $data;
self::$installedByVendor = array();
}
/**
* @return array[]
* @psalm-return list<array{root: array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool}, versions: array<string, array{pretty_version?: string, version?: string, reference?: string|null, type?: string, install_path?: string, aliases?: string[], dev_requirement: bool, replaced?: string[], provided?: string[]}>}>
*/
private static function getInstalled()
{
if (null === self::$canGetVendors) {
self::$canGetVendors = method_exists('Composer\Autoload\ClassLoader', 'getRegisteredLoaders');
}
$installed = array();
$copiedLocalDir = false;
if (self::$canGetVendors) {
foreach (ClassLoader::getRegisteredLoaders() as $vendorDir => $loader) {
if (isset(self::$installedByVendor[$vendorDir])) {
$installed[] = self::$installedByVendor[$vendorDir];
} elseif (is_file($vendorDir.'/composer/installed.php')) {
/** @var array{root: array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool}, versions: array<string, array{pretty_version?: string, version?: string, reference?: string|null, type?: string, install_path?: string, aliases?: string[], dev_requirement: bool, replaced?: string[], provided?: string[]}>} $required */
$required = require $vendorDir.'/composer/installed.php';
self::$installedByVendor[$vendorDir] = $required;
$installed[] = $required;
if (strtr($vendorDir.'/composer', '\\', '/') === strtr(__DIR__, '\\', '/')) {
self::$installed = $required;
$copiedLocalDir = true;
}
}
}
}
if (null === self::$installed) {
// only require the installed.php file if this file is loaded from its dumped location,
// and not from its source location in the composer/composer package, see https://github.com/composer/composer/issues/9937
if (substr(__DIR__, -8, 1) !== 'C') {
/** @var array{root: array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool}, versions: array<string, array{pretty_version?: string, version?: string, reference?: string|null, type?: string, install_path?: string, aliases?: string[], dev_requirement: bool, replaced?: string[], provided?: string[]}>} $required */
$required = require __DIR__ . '/installed.php';
self::$installed = $required;
} else {
self::$installed = array();
}
}
if (self::$installed !== array() && !$copiedLocalDir) {
$installed[] = self::$installed;
}
return $installed;
}
}

View File

@ -2,9 +2,10 @@
// autoload_classmap.php @generated by Composer
$vendorDir = dirname(dirname(__FILE__));
$vendorDir = dirname(__DIR__);
$baseDir = dirname($vendorDir);
return array(
'Composer\\InstalledVersions' => $vendorDir . '/composer/InstalledVersions.php',
'Stringable' => $vendorDir . '/myclabs/php-enum/stubs/Stringable.php',
);

View File

@ -2,7 +2,7 @@
// autoload_files.php @generated by Composer
$vendorDir = dirname(dirname(__FILE__));
$vendorDir = dirname(__DIR__);
$baseDir = dirname($vendorDir);
return array(

View File

@ -2,7 +2,7 @@
// autoload_namespaces.php @generated by Composer
$vendorDir = dirname(dirname(__FILE__));
$vendorDir = dirname(__DIR__);
$baseDir = dirname($vendorDir);
return array(

View File

@ -2,7 +2,7 @@
// autoload_psr4.php @generated by Composer
$vendorDir = dirname(dirname(__FILE__));
$vendorDir = dirname(__DIR__);
$baseDir = dirname($vendorDir);
return array(

View File

@ -22,52 +22,29 @@ class ComposerAutoloaderInit2bc4f313dba415539e266f7ac2c87dcd
return self::$loader;
}
require __DIR__ . '/platform_check.php';
spl_autoload_register(array('ComposerAutoloaderInit2bc4f313dba415539e266f7ac2c87dcd', 'loadClassLoader'), true, true);
self::$loader = $loader = new \Composer\Autoload\ClassLoader();
self::$loader = $loader = new \Composer\Autoload\ClassLoader(\dirname(__DIR__));
spl_autoload_unregister(array('ComposerAutoloaderInit2bc4f313dba415539e266f7ac2c87dcd', 'loadClassLoader'));
$useStaticLoader = PHP_VERSION_ID >= 50600 && !defined('HHVM_VERSION') && (!function_exists('zend_loader_file_encoded') || !zend_loader_file_encoded());
if ($useStaticLoader) {
require_once __DIR__ . '/autoload_static.php';
call_user_func(\Composer\Autoload\ComposerStaticInit2bc4f313dba415539e266f7ac2c87dcd::getInitializer($loader));
} else {
$map = require __DIR__ . '/autoload_namespaces.php';
foreach ($map as $namespace => $path) {
$loader->set($namespace, $path);
}
$map = require __DIR__ . '/autoload_psr4.php';
foreach ($map as $namespace => $path) {
$loader->setPsr4($namespace, $path);
}
$classMap = require __DIR__ . '/autoload_classmap.php';
if ($classMap) {
$loader->addClassMap($classMap);
}
}
require __DIR__ . '/autoload_static.php';
call_user_func(\Composer\Autoload\ComposerStaticInit2bc4f313dba415539e266f7ac2c87dcd::getInitializer($loader));
$loader->register(true);
if ($useStaticLoader) {
$includeFiles = Composer\Autoload\ComposerStaticInit2bc4f313dba415539e266f7ac2c87dcd::$files;
} else {
$includeFiles = require __DIR__ . '/autoload_files.php';
}
foreach ($includeFiles as $fileIdentifier => $file) {
composerRequire2bc4f313dba415539e266f7ac2c87dcd($fileIdentifier, $file);
$filesToLoad = \Composer\Autoload\ComposerStaticInit2bc4f313dba415539e266f7ac2c87dcd::$files;
$requireFile = \Closure::bind(static function ($fileIdentifier, $file) {
if (empty($GLOBALS['__composer_autoload_files'][$fileIdentifier])) {
$GLOBALS['__composer_autoload_files'][$fileIdentifier] = true;
require $file;
}
}, null, null);
foreach ($filesToLoad as $fileIdentifier => $file) {
$requireFile($fileIdentifier, $file);
}
return $loader;
}
}
function composerRequire2bc4f313dba415539e266f7ac2c87dcd($fileIdentifier, $file)
{
if (empty($GLOBALS['__composer_autoload_files'][$fileIdentifier])) {
require $file;
$GLOBALS['__composer_autoload_files'][$fileIdentifier] = true;
}
}

View File

@ -115,6 +115,7 @@ class ComposerStaticInit2bc4f313dba415539e266f7ac2c87dcd
);
public static $classMap = array (
'Composer\\InstalledVersions' => __DIR__ . '/..' . '/composer/InstalledVersions.php',
'Stringable' => __DIR__ . '/..' . '/myclabs/php-enum/stubs/Stringable.php',
);

File diff suppressed because it is too large Load Diff

149
vendor/composer/installed.php vendored Normal file
View File

@ -0,0 +1,149 @@
<?php return array(
'root' => array(
'name' => 'topthink/think',
'pretty_version' => 'dev-main',
'version' => 'dev-main',
'reference' => 'fcd7859cf4ed7d92ea7f2b5250e35e824d6b0d57',
'type' => 'project',
'install_path' => __DIR__ . '/../../',
'aliases' => array(),
'dev' => true,
),
'versions' => array(
'ezyang/htmlpurifier' => array(
'pretty_version' => 'v4.18.0',
'version' => '4.18.0.0',
'reference' => 'cb56001e54359df7ae76dc522d08845dc741621b',
'type' => 'library',
'install_path' => __DIR__ . '/../ezyang/htmlpurifier',
'aliases' => array(),
'dev_requirement' => false,
),
'maennchen/zipstream-php' => array(
'pretty_version' => '2.1.0',
'version' => '2.1.0.0',
'reference' => 'c4c5803cc1f93df3d2448478ef79394a5981cc58',
'type' => 'library',
'install_path' => __DIR__ . '/../maennchen/zipstream-php',
'aliases' => array(),
'dev_requirement' => false,
),
'markbaker/complex' => array(
'pretty_version' => '3.0.2',
'version' => '3.0.2.0',
'reference' => '95c56caa1cf5c766ad6d65b6344b807c1e8405b9',
'type' => 'library',
'install_path' => __DIR__ . '/../markbaker/complex',
'aliases' => array(),
'dev_requirement' => false,
),
'markbaker/matrix' => array(
'pretty_version' => '3.0.1',
'version' => '3.0.1.0',
'reference' => '728434227fe21be27ff6d86621a1b13107a2562c',
'type' => 'library',
'install_path' => __DIR__ . '/../markbaker/matrix',
'aliases' => array(),
'dev_requirement' => false,
),
'myclabs/php-enum' => array(
'pretty_version' => '1.8.4',
'version' => '1.8.4.0',
'reference' => 'a867478eae49c9f59ece437ae7f9506bfaa27483',
'type' => 'library',
'install_path' => __DIR__ . '/../myclabs/php-enum',
'aliases' => array(),
'dev_requirement' => false,
),
'phpmailer/phpmailer' => array(
'pretty_version' => 'v6.9.3',
'version' => '6.9.3.0',
'reference' => '2f5c94fe7493efc213f643c23b1b1c249d40f47e',
'type' => 'library',
'install_path' => __DIR__ . '/../phpmailer/phpmailer',
'aliases' => array(),
'dev_requirement' => false,
),
'phpoffice/phpspreadsheet' => array(
'pretty_version' => '1.25.2',
'version' => '1.25.2.0',
'reference' => 'a317a09e7def49852400a4b3eca4a4b0790ceeb5',
'type' => 'library',
'install_path' => __DIR__ . '/../phpoffice/phpspreadsheet',
'aliases' => array(),
'dev_requirement' => false,
),
'psr/http-client' => array(
'pretty_version' => '1.0.3',
'version' => '1.0.3.0',
'reference' => 'bb5906edc1c324c9a05aa0873d40117941e5fa90',
'type' => 'library',
'install_path' => __DIR__ . '/../psr/http-client',
'aliases' => array(),
'dev_requirement' => false,
),
'psr/http-factory' => array(
'pretty_version' => '1.1.0',
'version' => '1.1.0.0',
'reference' => '2b4765fddfe3b508ac62f829e852b1501d3f6e8a',
'type' => 'library',
'install_path' => __DIR__ . '/../psr/http-factory',
'aliases' => array(),
'dev_requirement' => false,
),
'psr/http-message' => array(
'pretty_version' => '1.1',
'version' => '1.1.0.0',
'reference' => 'cb6ce4845ce34a8ad9e68117c10ee90a29919eba',
'type' => 'library',
'install_path' => __DIR__ . '/../psr/http-message',
'aliases' => array(),
'dev_requirement' => false,
),
'psr/simple-cache' => array(
'pretty_version' => '1.0.1',
'version' => '1.0.1.0',
'reference' => '408d5eafb83c57f6365a3ca330ff23aa4a5fa39b',
'type' => 'library',
'install_path' => __DIR__ . '/../psr/simple-cache',
'aliases' => array(),
'dev_requirement' => false,
),
'symfony/polyfill-mbstring' => array(
'pretty_version' => 'v1.31.0',
'version' => '1.31.0.0',
'reference' => '85181ba99b2345b0ef10ce42ecac37612d9fd341',
'type' => 'library',
'install_path' => __DIR__ . '/../symfony/polyfill-mbstring',
'aliases' => array(),
'dev_requirement' => false,
),
'topthink/framework' => array(
'pretty_version' => 'v5.0.25',
'version' => '5.0.25.0',
'reference' => '643c58ed1bd22a2823ce5e95b3b68a5075f9087c',
'type' => 'think-framework',
'install_path' => __DIR__ . '/../../thinkphp',
'aliases' => array(),
'dev_requirement' => false,
),
'topthink/think' => array(
'pretty_version' => 'dev-main',
'version' => 'dev-main',
'reference' => 'fcd7859cf4ed7d92ea7f2b5250e35e824d6b0d57',
'type' => 'project',
'install_path' => __DIR__ . '/../../',
'aliases' => array(),
'dev_requirement' => false,
),
'topthink/think-installer' => array(
'pretty_version' => 'v1.0.14',
'version' => '1.0.14.0',
'reference' => 'eae1740ac264a55c06134b6685dfb9f837d004d1',
'type' => 'composer-plugin',
'install_path' => __DIR__ . '/../topthink/think-installer',
'aliases' => array(),
'dev_requirement' => false,
),
),
);

26
vendor/composer/platform_check.php vendored Normal file
View File

@ -0,0 +1,26 @@
<?php
// platform_check.php @generated by Composer
$issues = array();
if (!(PHP_VERSION_ID >= 70300)) {
$issues[] = 'Your Composer dependencies require a PHP version ">= 7.3.0". You are running ' . PHP_VERSION . '.';
}
if ($issues) {
if (!headers_sent()) {
header('HTTP/1.1 500 Internal Server Error');
}
if (!ini_get('display_errors')) {
if (PHP_SAPI === 'cli' || PHP_SAPI === 'phpdbg') {
fwrite(STDERR, 'Composer detected issues in your platform:' . PHP_EOL.PHP_EOL . implode(PHP_EOL, $issues) . PHP_EOL.PHP_EOL);
} elseif (!headers_sent()) {
echo 'Composer detected issues in your platform:' . PHP_EOL.PHP_EOL . str_replace('You are running '.PHP_VERSION.'.', '', implode(PHP_EOL, $issues)) . PHP_EOL.PHP_EOL;
}
}
trigger_error(
'Composer detected issues in your platform: ' . implode(' ', $issues),
E_USER_ERROR
);
}

View File

@ -1 +1 @@
4.17.0
4.18.0

View File

@ -13,7 +13,7 @@
}
],
"require": {
"php": "~5.6.0 || ~7.0.0 || ~7.1.0 || ~7.2.0 || ~7.3.0 || ~7.4.0 || ~8.0.0 || ~8.1.0 || ~8.2.0 || ~8.3.0"
"php": "~5.6.0 || ~7.0.0 || ~7.1.0 || ~7.2.0 || ~7.3.0 || ~7.4.0 || ~8.0.0 || ~8.1.0 || ~8.2.0 || ~8.3.0 || ~8.4.0"
},
"require-dev": {
"cerdic/css-tidy": "^1.7 || ^2.0",

View File

@ -7,7 +7,7 @@
* primary concern and you are using an opcode cache. PLEASE DO NOT EDIT THIS
* FILE, changes will be overwritten the next time the script is run.
*
* @version 4.17.0
* @version 4.18.0
*
* @warning
* You must *not* include any other HTML Purifier files before this file,
@ -101,6 +101,7 @@ require 'HTMLPurifier/AttrDef/CSS/Length.php';
require 'HTMLPurifier/AttrDef/CSS/ListStyle.php';
require 'HTMLPurifier/AttrDef/CSS/Multiple.php';
require 'HTMLPurifier/AttrDef/CSS/Percentage.php';
require 'HTMLPurifier/AttrDef/CSS/Ratio.php';
require 'HTMLPurifier/AttrDef/CSS/TextDecoration.php';
require 'HTMLPurifier/AttrDef/CSS/URI.php';
require 'HTMLPurifier/AttrDef/HTML/Bool.php';

View File

@ -19,7 +19,7 @@
*/
/*
HTML Purifier 4.17.0 - Standards Compliant HTML Filtering
HTML Purifier 4.18.0 - Standards Compliant HTML Filtering
Copyright (C) 2006-2008 Edward Z. Yang
This library is free software; you can redistribute it and/or
@ -58,12 +58,12 @@ class HTMLPurifier
* Version of HTML Purifier.
* @type string
*/
public $version = '4.17.0';
public $version = '4.18.0';
/**
* Constant with version of HTML Purifier.
*/
const VERSION = '4.17.0';
const VERSION = '4.18.0';
/**
* Global configuration object.

View File

@ -95,6 +95,7 @@ require_once $__dir . '/HTMLPurifier/AttrDef/CSS/Length.php';
require_once $__dir . '/HTMLPurifier/AttrDef/CSS/ListStyle.php';
require_once $__dir . '/HTMLPurifier/AttrDef/CSS/Multiple.php';
require_once $__dir . '/HTMLPurifier/AttrDef/CSS/Percentage.php';
require_once $__dir . '/HTMLPurifier/AttrDef/CSS/Ratio.php';
require_once $__dir . '/HTMLPurifier/AttrDef/CSS/TextDecoration.php';
require_once $__dir . '/HTMLPurifier/AttrDef/CSS/URI.php';
require_once $__dir . '/HTMLPurifier/AttrDef/HTML/Bool.php';

View File

@ -27,6 +27,13 @@ class HTMLPurifier_AttrDef_CSS extends HTMLPurifier_AttrDef
$definition = $config->getCSSDefinition();
$allow_duplicates = $config->get("CSS.AllowDuplicates");
$universal_attrdef = new HTMLPurifier_AttrDef_Enum(
array(
'initial',
'inherit',
'unset',
)
);
// According to the CSS2.1 spec, the places where a
// non-delimiting semicolon can appear are in strings
@ -96,16 +103,13 @@ class HTMLPurifier_AttrDef_CSS extends HTMLPurifier_AttrDef
if (!$ok) {
continue;
}
// inefficient call, since the validator will do this again
if (strtolower(trim($value)) !== 'inherit') {
// inherit works for everything (but only on the base property)
$result = $universal_attrdef->validate($value, $config, $context);
if ($result === false) {
$result = $definition->info[$property]->validate(
$value,
$config,
$context
);
} else {
$result = 'inherit';
}
if ($result === false) {
continue;

View File

@ -0,0 +1,46 @@
<?php
/**
* Validates a ratio as defined by the CSS spec.
*/
class HTMLPurifier_AttrDef_CSS_Ratio extends HTMLPurifier_AttrDef
{
/**
* @param string $ratio Ratio to validate
* @param HTMLPurifier_Config $config Configuration options
* @param HTMLPurifier_Context $context Context
*
* @return string|boolean
*
* @warning Some contexts do not pass $config, $context. These
* variables should not be used without checking HTMLPurifier_Length
*/
public function validate($ratio, $config, $context)
{
$ratio = $this->parseCDATA($ratio);
$parts = explode('/', $ratio, 2);
$length = count($parts);
if ($length < 1 || $length > 2) {
return false;
}
$num = new \HTMLPurifier_AttrDef_CSS_Number();
if ($length === 1) {
return $num->validate($parts[0], $config, $context);
}
$num1 = $num->validate($parts[0], $config, $context);
$num2 = $num->validate($parts[1], $config, $context);
if ($num1 === false || $num2 === false) {
return false;
}
return $num1 . '/' . $num2;
}
}
// vim: et sw=4 sts=4

View File

@ -63,24 +63,18 @@ class HTMLPurifier_AttrDef_URI_Host extends HTMLPurifier_AttrDef
// This doesn't match I18N domain names, but we don't have proper IRI support,
// so force users to insert Punycode.
// There is not a good sense in which underscores should be
// allowed, since it's technically not! (And if you go as
// far to allow everything as specified by the DNS spec...
// well, that's literally everything, modulo some space limits
// for the components and the overall name (which, by the way,
// we are NOT checking!). So we (arbitrarily) decide this:
// let's allow underscores wherever we would have allowed
// hyphens, if they are enabled. This is a pretty good match
// for browser behavior, for example, a large number of browsers
// cannot handle foo_.example.com, but foo_bar.example.com is
// fairly well supported.
// Underscores defined as Unreserved Characters in RFC 3986 are
// allowed in a URI. There are cases where we want to consider a
// URI containing "_" such as "_dmarc.example.com".
// Underscores are not allowed in the default. If you want to
// allow it, set Core.AllowHostnameUnderscore to true.
$underscore = $config->get('Core.AllowHostnameUnderscore') ? '_' : '';
// Based off of RFC 1738, but amended so that
// as per RFC 3696, the top label need only not be all numeric.
// The productions describing this are:
$a = '[a-z]'; // alpha
$an = '[a-z0-9]'; // alphanum
$an = "[a-z0-9$underscore]"; // alphanum
$and = "[a-z0-9-$underscore]"; // alphanum | "-"
// domainlabel = alphanum | alphanum *( alphanum | "-" ) alphanum
$domainlabel = "$an(?:$and*$an)?";

View File

@ -116,8 +116,6 @@ class HTMLPurifier_CSSDefinition extends HTMLPurifier_Definition
'auto',
'cover',
'contain',
'initial',
'inherit',
]
),
new HTMLPurifier_AttrDef_CSS_Percentage(),
@ -236,21 +234,20 @@ class HTMLPurifier_CSSDefinition extends HTMLPurifier_Definition
[
new HTMLPurifier_AttrDef_CSS_Length('0'),
new HTMLPurifier_AttrDef_CSS_Percentage(true),
new HTMLPurifier_AttrDef_Enum(['auto', 'initial', 'inherit'])
new HTMLPurifier_AttrDef_Enum(['auto'])
]
);
$trusted_min_wh = new HTMLPurifier_AttrDef_CSS_Composite(
[
new HTMLPurifier_AttrDef_CSS_Length('0'),
new HTMLPurifier_AttrDef_CSS_Percentage(true),
new HTMLPurifier_AttrDef_Enum(['initial', 'inherit'])
]
);
$trusted_max_wh = new HTMLPurifier_AttrDef_CSS_Composite(
[
new HTMLPurifier_AttrDef_CSS_Length('0'),
new HTMLPurifier_AttrDef_CSS_Percentage(true),
new HTMLPurifier_AttrDef_Enum(['none', 'initial', 'inherit'])
new HTMLPurifier_AttrDef_Enum(['none'])
]
);
$max = $config->get('CSS.MaxImgLength');
@ -278,12 +275,7 @@ class HTMLPurifier_CSSDefinition extends HTMLPurifier_Definition
new HTMLPurifier_AttrDef_Switch(
'img',
// For img tags:
new HTMLPurifier_AttrDef_CSS_Composite(
[
new HTMLPurifier_AttrDef_CSS_Length('0', $max),
new HTMLPurifier_AttrDef_Enum(['initial', 'inherit'])
]
),
new HTMLPurifier_AttrDef_CSS_Length('0', $max),
// For everyone else:
$trusted_min_wh
);
@ -297,22 +289,29 @@ class HTMLPurifier_CSSDefinition extends HTMLPurifier_Definition
new HTMLPurifier_AttrDef_CSS_Composite(
[
new HTMLPurifier_AttrDef_CSS_Length('0', $max),
new HTMLPurifier_AttrDef_Enum(['none', 'initial', 'inherit'])
new HTMLPurifier_AttrDef_Enum(['none'])
]
),
// For everyone else:
$trusted_max_wh
);
$this->info['aspect-ratio'] = new HTMLPurifier_AttrDef_CSS_Multiple(
new HTMLPurifier_AttrDef_CSS_Composite([
new HTMLPurifier_AttrDef_CSS_Ratio(),
new HTMLPurifier_AttrDef_Enum(['auto']),
])
);
// text-decoration and related shorthands
$this->info['text-decoration'] = new HTMLPurifier_AttrDef_CSS_TextDecoration();
$this->info['text-decoration-line'] = new HTMLPurifier_AttrDef_Enum(
['none', 'underline', 'overline', 'line-through', 'initial', 'inherit']
['none', 'underline', 'overline', 'line-through']
);
$this->info['text-decoration-style'] = new HTMLPurifier_AttrDef_Enum(
['solid', 'double', 'dotted', 'dashed', 'wavy', 'initial', 'inherit']
['solid', 'double', 'dotted', 'dashed', 'wavy']
);
$this->info['text-decoration-color'] = new HTMLPurifier_AttrDef_CSS_Color();
@ -320,7 +319,7 @@ class HTMLPurifier_CSSDefinition extends HTMLPurifier_Definition
$this->info['text-decoration-thickness'] = new HTMLPurifier_AttrDef_CSS_Composite([
new HTMLPurifier_AttrDef_CSS_Length(),
new HTMLPurifier_AttrDef_CSS_Percentage(),
new HTMLPurifier_AttrDef_Enum(['auto', 'from-font', 'initial', 'inherit'])
new HTMLPurifier_AttrDef_Enum(['auto', 'from-font'])
]);
$this->info['font-family'] = new HTMLPurifier_AttrDef_CSS_FontFamily();

View File

@ -190,6 +190,9 @@ class HTMLPurifier_ChildDef_Table extends HTMLPurifier_ChildDef
$current_tr_tbody = null;
foreach($content as $node) {
if (!isset($node->name)) {
continue;
}
switch ($node->name) {
case 'tbody':
$current_tr_tbody = null;

View File

@ -21,7 +21,7 @@ class HTMLPurifier_Config
* HTML Purifier's version
* @type string
*/
public $version = '4.17.0';
public $version = '4.18.0';
/**
* Whether or not to automatically finalize

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,10 @@
Core.RemoveBlanks
TYPE: bool
DEFAULT: false
VERSION: 4.18
--DESCRIPTION--
<p>
If set to true, blank nodes will be removed. This can be useful for maintaining
backwards compatibility when upgrading from previous versions of PHP.
</p>
--# vim: et sw=4 sts=4

View File

@ -116,8 +116,8 @@ class HTMLPurifier_EntityParser
protected function entityCallback($matches)
{
$entity = $matches[0];
$hex_part = @$matches[1];
$dec_part = @$matches[2];
$hex_part = isset($matches[1]) ? $matches[1] : null;
$dec_part = isset($matches[2]) ? $matches[2] : null;
$named_part = empty($matches[3]) ? (empty($matches[4]) ? "" : $matches[4]) : $matches[3];
if ($hex_part !== NULL && $hex_part !== "") {
return HTMLPurifier_Encoder::unichr(hexdec($hex_part));

View File

@ -54,6 +54,11 @@ class HTMLPurifier_Filter_ExtractStyleBlocks extends HTMLPurifier_Filter
*/
private $_enum_attrdef;
/**
* @type HTMLPurifier_AttrDef_Enum
*/
private $_universal_attrdef;
public function __construct()
{
$this->_tidy = new csstidy();
@ -70,6 +75,13 @@ class HTMLPurifier_Filter_ExtractStyleBlocks extends HTMLPurifier_Filter
'focus'
)
);
$this->_universal_attrdef = new HTMLPurifier_AttrDef_Enum(
array(
'initial',
'inherit',
'unset',
)
);
}
/**
@ -307,6 +319,11 @@ class HTMLPurifier_Filter_ExtractStyleBlocks extends HTMLPurifier_Filter
unset($style[$name]);
continue;
}
$uni_ret = $this->_universal_attrdef->validate($value, $config, $context);
if ($uni_ret !== false) {
$style[$name] = $uni_ret;
continue;
}
$def = $css_definition->info[$name];
$ret = $def->validate($value, $config, $context);
if ($ret === false) {

View File

@ -28,22 +28,28 @@ class HTMLPurifier_HTMLModule_Iframe extends HTMLPurifier_HTMLModule
if ($config->get('HTML.SafeIframe')) {
$this->safe = true;
}
$attrs = array(
'src' => 'URI#embedded',
'width' => 'Length',
'height' => 'Length',
'name' => 'ID',
'scrolling' => 'Enum#yes,no,auto',
'frameborder' => 'Enum#0,1',
'longdesc' => 'URI',
'marginheight' => 'Pixels',
'marginwidth' => 'Pixels',
);
if ($config->get('HTML.Trusted')) {
$attrs['allowfullscreen'] = 'Bool#allowfullscreen';
}
$this->addElement(
'iframe',
'Inline',
'Flow',
'Common',
array(
'src' => 'URI#embedded',
'width' => 'Length',
'height' => 'Length',
'name' => 'ID',
'scrolling' => 'Enum#yes,no,auto',
'frameborder' => 'Enum#0,1',
'longdesc' => 'URI',
'marginheight' => 'Pixels',
'marginwidth' => 'Pixels',
)
$attrs
);
}
}

View File

@ -269,20 +269,6 @@ class HTMLPurifier_Lexer
);
}
/**
* Special Internet Explorer conditional comments should be removed.
* @param string $string HTML string to process.
* @return string HTML with conditional comments removed.
*/
protected static function removeIEConditional($string)
{
return preg_replace(
'#<!--\[if [^>]+\]>.*?<!\[endif\]-->#si', // probably should generalize for all strings
'',
$string
);
}
/**
* Callback function for escapeCDATA() that does the work.
*
@ -323,8 +309,6 @@ class HTMLPurifier_Lexer
// escape CDATA
$html = $this->escapeCDATA($html);
$html = $this->removeIEConditional($html);
// extract body from document if applicable
if ($config->get('Core.ConvertDocumentToFragment')) {
$e = false;

View File

@ -72,6 +72,9 @@ class HTMLPurifier_Lexer_DOMLex extends HTMLPurifier_Lexer
if ($config->get('Core.AllowParseManyTags') && defined('LIBXML_PARSEHUGE')) {
$options |= LIBXML_PARSEHUGE;
}
if ($config->get('Core.RemoveBlanks') && defined('LIBXML_NOBLANKS')) {
$options |= LIBXML_NOBLANKS;
}
set_error_handler(array($this, 'muteErrorHandler'));
// loadHTML() fails on PHP 5.3 when second parameter is given

View File

@ -44,7 +44,7 @@ abstract class HTMLPurifier_Token_Tag extends HTMLPurifier_Token
$this->name = ctype_lower($name) ? $name : strtolower($name);
foreach ($attr as $key => $value) {
// normalization only necessary when key is not lowercase
if (!ctype_lower($key)) {
if (!ctype_lower((string)$key)) {
$new_key = strtolower($key);
if (!isset($attr[$new_key])) {
$attr[$new_key] = $attr[$key];

View File

@ -41,13 +41,13 @@ you should look at before rolling your own. Try [SwiftMailer](https://swiftmaile
, [Laminas/Mail](https://docs.laminas.dev/laminas-mail/), [ZetaComponents](https://github.com/zetacomponents/Mail), etc.
## License
This software is distributed under the [LGPL 2.1](http://www.gnu.org/licenses/lgpl-2.1.html) license, along with the [GPL Cooperation Commitment](https://gplcc.github.io/gplcc/). Please read [LICENSE](https://github.com/PHPMailer/PHPMailer/blob/master/LICENSE) for information on the software availability and distribution.
This software is distributed under the [LGPL 2.1](https://www.gnu.org/licenses/old-licenses/lgpl-2.1.html) license, along with the [GPL Cooperation Commitment](https://gplcc.github.io/gplcc/). Please read [LICENSE](https://github.com/PHPMailer/PHPMailer/blob/master/LICENSE) for information on the software availability and distribution.
## Installation & loading
PHPMailer is available on [Packagist](https://packagist.org/packages/phpmailer/phpmailer) (using semantic versioning), and installation via [Composer](https://getcomposer.org) is the recommended way to install PHPMailer. Just add this line to your `composer.json` file:
```json
"phpmailer/phpmailer": "^6.9.1"
"phpmailer/phpmailer": "^6.9.2"
```
or run
@ -144,7 +144,7 @@ If you are re-using the instance (e.g. when sending to a mailing list), you may
That's it. You should now be ready to use PHPMailer!
## Localization
PHPMailer defaults to English, but in the [language](https://github.com/PHPMailer/PHPMailer/tree/master/language/) folder, you'll find many translations for PHPMailer error messages that you may encounter. Their filenames contain [ISO 639-1](http://en.wikipedia.org/wiki/ISO_639-1) language code for the translations, for example `fr` for French. To specify a language, you need to tell PHPMailer which one to use, like this:
PHPMailer defaults to English, but in the [language](https://github.com/PHPMailer/PHPMailer/tree/master/language/) folder, you'll find many translations for PHPMailer error messages that you may encounter. Their filenames contain [ISO 639-1](https://en.wikipedia.org/wiki/ISO_639-1) language code for the translations, for example `fr` for French. To specify a language, you need to tell PHPMailer which one to use, like this:
```php
//To load the French version
@ -162,9 +162,9 @@ To reduce PHPMailer's deployed code footprint, examples are not included if you
Complete generated API documentation is [available online](https://phpmailer.github.io/PHPMailer/).
You can generate complete API-level documentation by running `phpdoc` in the top-level folder, and documentation will appear in the `docs` folder, though you'll need to have [PHPDocumentor](http://www.phpdoc.org) installed. You may find [the unit tests](https://github.com/PHPMailer/PHPMailer/blob/master/test/PHPMailerTest.php) a good reference for how to do various operations such as encryption.
You can generate complete API-level documentation by running `phpdoc` in the top-level folder, and documentation will appear in the `docs` folder, though you'll need to have [PHPDocumentor](https://www.phpdoc.org) installed. You may find [the unit tests](https://github.com/PHPMailer/PHPMailer/blob/master/test/PHPMailer/PHPMailerTest.php) a good reference for how to do various operations such as encryption.
If the documentation doesn't cover what you need, search the [many questions on Stack Overflow](http://stackoverflow.com/questions/tagged/phpmailer), and before you ask a question about "SMTP Error: Could not connect to SMTP host.", [read the troubleshooting guide](https://github.com/PHPMailer/PHPMailer/wiki/Troubleshooting).
If the documentation doesn't cover what you need, search the [many questions on Stack Overflow](https://stackoverflow.com/questions/tagged/phpmailer), and before you ask a question about "SMTP Error: Could not connect to SMTP host.", [read the troubleshooting guide](https://github.com/PHPMailer/PHPMailer/wiki/Troubleshooting).
## Tests
[PHPMailer tests](https://github.com/PHPMailer/PHPMailer/tree/master/test/) use PHPUnit 9, with [a polyfill](https://github.com/Yoast/PHPUnit-Polyfills) to let 9-style tests run on older PHPUnit and PHP versions.
@ -213,7 +213,7 @@ use. [Learn more.](https://tidelift.com/subscription/pkg/packagist-phpmailer-php
See [changelog](changelog.md).
## History
- PHPMailer was originally written in 2001 by Brent R. Matzelle as a [SourceForge project](http://sourceforge.net/projects/phpmailer/).
- PHPMailer was originally written in 2001 by Brent R. Matzelle as a [SourceForge project](https://sourceforge.net/projects/phpmailer/).
- [Marcus Bointon](https://github.com/Synchro) (`coolbru` on SF) and Andy Prevost (`codeworxtech`) took over the project in 2004.
- Became an Apache incubator project on Google Code in 2010, managed by Jim Jagielski.
- Marcus created [his fork on GitHub](https://github.com/Synchro/PHPMailer) in 2008.

View File

@ -13,13 +13,13 @@ PHPMailer versions 6.1.5 and earlier contain an output escaping bug that occurs
PHPMailer versions prior to 6.0.6 and 5.2.27 are vulnerable to an object injection attack by passing `phar://` paths into `addAttachment()` and other functions that may receive unfiltered local paths, possibly leading to RCE. Recorded as [CVE-2018-19296](https://web.nvd.nist.gov/view/vuln/detail?vulnId=CVE-2018-19296). See [this article](https://knasmueller.net/5-answers-about-php-phar-exploitation) for more info on this type of vulnerability. Mitigated by blocking the use of paths containing URL-protocol style prefixes such as `phar://`. Reported by Sehun Oh of cyberone.kr.
PHPMailer versions prior to 5.2.24 (released July 26th 2017) have an XSS vulnerability in one of the code examples, [CVE-2017-11503](https://web.nvd.nist.gov/view/vuln/detail?vulnId=CVE-2017-11503). The `code_generator.phps` example did not filter user input prior to output. This file is distributed with a `.phps` extension, so it it not normally executable unless it is explicitly renamed, and the file is not included when PHPMailer is loaded through composer, so it is safe by default. There was also an undisclosed potential XSS vulnerability in the default exception handler (unused by default). Patches for both issues kindly provided by Patrick Monnerat of the Fedora Project.
PHPMailer versions prior to 5.2.24 (released July 26th 2017) have an XSS vulnerability in one of the code examples, [CVE-2017-11503](https://web.nvd.nist.gov/view/vuln/detail?vulnId=CVE-2017-11503). The `code_generator.phps` example did not filter user input prior to output. This file is distributed with a `.phps` extension, so it is not normally executable unless it is explicitly renamed, and the file is not included when PHPMailer is loaded through composer, so it is safe by default. There was also an undisclosed potential XSS vulnerability in the default exception handler (unused by default). Patches for both issues kindly provided by Patrick Monnerat of the Fedora Project.
PHPMailer versions prior to 5.2.22 (released January 9th 2017) have a local file disclosure vulnerability, [CVE-2017-5223](https://web.nvd.nist.gov/view/vuln/detail?vulnId=CVE-2017-5223). If content passed into `msgHTML()` is sourced from unfiltered user input, relative paths can map to absolute local file paths and added as attachments. Also note that `addAttachment` (just like `file_get_contents`, `passthru`, `unlink`, etc) should not be passed user-sourced params either! Reported by Yongxiang Li of Asiasecurity.
PHPMailer versions prior to 5.2.20 (released December 28th 2016) are vulnerable to [CVE-2016-10045](https://web.nvd.nist.gov/view/vuln/detail?vulnId=CVE-2016-10045) a remote code execution vulnerability, responsibly reported by [Dawid Golunski](https://legalhackers.com/advisories/PHPMailer-Exploit-Remote-Code-Exec-CVE-2016-10045-Vuln-Patch-Bypass.html), and patched by Paul Buonopane (@Zenexer).
PHPMailer versions prior to 5.2.18 (released December 2016) are vulnerable to [CVE-2016-10033](https://web.nvd.nist.gov/view/vuln/detail?vulnId=CVE-2016-10033) a remote code execution vulnerability, responsibly reported by [Dawid Golunski](http://legalhackers.com/advisories/PHPMailer-Exploit-Remote-Code-Exec-CVE-2016-10033-Vuln.html).
PHPMailer versions prior to 5.2.18 (released December 2016) are vulnerable to [CVE-2016-10033](https://web.nvd.nist.gov/view/vuln/detail?vulnId=CVE-2016-10033) a remote code execution vulnerability, responsibly reported by [Dawid Golunski](https://legalhackers.com/advisories/PHPMailer-Exploit-Remote-Code-Exec-CVE-2016-10033-Vuln.html).
PHPMailer versions prior to 5.2.14 (released November 2015) are vulnerable to [CVE-2015-8476](https://web.nvd.nist.gov/view/vuln/detail?vulnId=CVE-2015-8476) an SMTP CRLF injection bug permitting arbitrary message sending.

View File

@ -1 +1 @@
6.9.1
6.9.3

View File

@ -28,7 +28,8 @@
"config": {
"allow-plugins": {
"dealerdirect/phpcodesniffer-composer-installer": true
}
},
"lock": false
},
"require": {
"php": ">=5.5.0",

View File

@ -12,7 +12,7 @@
* @copyright 2012 - 2020 Marcus Bointon
* @copyright 2010 - 2012 Jim Jagielski
* @copyright 2004 - 2009 Andy Prevost
* @license http://www.gnu.org/copyleft/lesser.html GNU Lesser General Public License
* @license https://www.gnu.org/licenses/old-licenses/lgpl-2.1.html GNU Lesser General Public License
* @note This program is distributed in the hope that it will be useful - WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE.
@ -36,7 +36,7 @@ namespace PHPMailer\PHPMailer;
* Aliases for League Provider Classes
* Make sure you have added these to your composer.json and run `composer install`
* Plenty to choose from here:
* @see http://oauth2-client.thephpleague.com/providers/thirdparty/
* @see https://oauth2-client.thephpleague.com/providers/thirdparty/
*/
//@see https://github.com/thephpleague/oauth2-google
use League\OAuth2\Client\Provider\Google;
@ -178,5 +178,5 @@ if (!isset($_GET['code'])) {
);
//Use this to interact with an API on the users behalf
//Use this to get a new access token if the old one expires
echo 'Refresh Token: ', $token->getRefreshToken();
echo 'Refresh Token: ', htmlspecialchars($token->getRefreshToken());
}

View File

@ -5,27 +5,32 @@
* @package PHPMailer
* @author Matt Sturdy <matt.sturdy@gmail.com>
* @author Crystopher Glodzienski Cardoso <crystopher.glodzienski@gmail.com>
* @author Daniel Cruz <danicruz0415@gmail.com>
*/
$PHPMAILER_LANG['authenticate'] = 'Error SMTP: Imposible autentificar.';
$PHPMAILER_LANG['buggy_php'] = 'Tu versión de PHP está afectada por un bug que puede resultar en mensajes corruptos. Para arreglarlo, cambia a enviar usando SMTP, deshabilita la opción mail.add_x_header en tu php.ini, cambia a MacOS o Linux, o actualiza tu PHP a la versión 7.0.17+ o 7.1.3+.';
$PHPMAILER_LANG['connect_host'] = 'Error SMTP: Imposible conectar al servidor SMTP.';
$PHPMAILER_LANG['data_not_accepted'] = 'Error SMTP: Datos no aceptados.';
$PHPMAILER_LANG['empty_message'] = 'El cuerpo del mensaje está vacío.';
$PHPMAILER_LANG['encoding'] = 'Codificación desconocida: ';
$PHPMAILER_LANG['execute'] = 'Imposible ejecutar: ';
$PHPMAILER_LANG['extension_missing'] = 'Extensión faltante: ';
$PHPMAILER_LANG['file_access'] = 'Imposible acceder al archivo: ';
$PHPMAILER_LANG['file_open'] = 'Error de Archivo: Imposible abrir el archivo: ';
$PHPMAILER_LANG['from_failed'] = 'La(s) siguiente(s) direcciones de remitente fallaron: ';
$PHPMAILER_LANG['instantiate'] = 'Imposible crear una instancia de la función Mail.';
$PHPMAILER_LANG['invalid_address'] = 'Imposible enviar: dirección de email inválido: ';
$PHPMAILER_LANG['invalid_header'] = 'Nombre o valor de encabezado no válido';
$PHPMAILER_LANG['invalid_hostentry'] = 'Hostentry inválido: ';
$PHPMAILER_LANG['invalid_host'] = 'Host inválido: ';
$PHPMAILER_LANG['mailer_not_supported'] = ' mailer no está soportado.';
$PHPMAILER_LANG['provide_address'] = 'Debe proporcionar al menos una dirección de email de destino.';
$PHPMAILER_LANG['recipients_failed'] = 'Error SMTP: Los siguientes destinos fallaron: ';
$PHPMAILER_LANG['signing'] = 'Error al firmar: ';
$PHPMAILER_LANG['smtp_connect_failed'] = 'SMTP Connect() falló.';
$PHPMAILER_LANG['smtp_error'] = 'Error del servidor SMTP: ';
$PHPMAILER_LANG['variable_set'] = 'No se pudo configurar la variable: ';
$PHPMAILER_LANG['extension_missing'] = 'Extensión faltante: ';
$PHPMAILER_LANG['smtp_code'] = 'Código del servidor SMTP: ';
$PHPMAILER_LANG['smtp_code_ex'] = 'Información adicional del servidor SMTP: ';
$PHPMAILER_LANG['invalid_header'] = 'Nombre o valor de encabezado no válido';
$PHPMAILER_LANG['smtp_connect_failed'] = 'SMTP Connect() falló.';
$PHPMAILER_LANG['smtp_detail'] = 'Detalle: ';
$PHPMAILER_LANG['smtp_error'] = 'Error del servidor SMTP: ';
$PHPMAILER_LANG['variable_set'] = 'No se pudo configurar la variable: ';

View File

@ -6,7 +6,6 @@
* Some French punctuation requires a thin non-breaking space (U+202F) character before it,
* for example before a colon or exclamation mark.
* There is one of these characters between these quotes: ""
* @see http://unicode.org/udhr/n/notes_fra.html
*/
$PHPMAILER_LANG['authenticate'] = 'Erreur SMTP: échec de lauthentification.';
@ -31,7 +30,7 @@ $PHPMAILER_LANG['recipients_failed'] = 'Erreur SMTP:les destinataires s
$PHPMAILER_LANG['signing'] = 'Erreur de signature: ';
$PHPMAILER_LANG['smtp_code'] = 'Code SMTP: ';
$PHPMAILER_LANG['smtp_code_ex'] = 'Informations supplémentaires SMTP: ';
$PHPMAILER_LANG['smtp_connect_failed'] = 'La fonction SMTP connect() a échouée.';
$PHPMAILER_LANG['smtp_connect_failed'] = 'La fonction SMTP connect() a échoué.';
$PHPMAILER_LANG['smtp_detail'] = 'Détails: ';
$PHPMAILER_LANG['smtp_error'] = 'Erreur du serveur SMTP: ';
$PHPMAILER_LANG['variable_set'] = 'Impossible dinitialiser ou de réinitialiser une variable: ';

View File

@ -3,27 +3,35 @@
/**
* Japanese PHPMailer language file: refer to English translation for definitive list
* @package PHPMailer
* @author Mitsuhiro Yoshida <http://mitstek.com/>
* @author Mitsuhiro Yoshida <https://mitstek.com>
* @author Yoshi Sakai <http://bluemooninc.jp/>
* @author Arisophy <https://github.com/arisophy/>
* @author ARAKI Musashi <https://github.com/arakim/>
*/
$PHPMAILER_LANG['authenticate'] = 'SMTPエラー: 認証できませんでした。';
$PHPMAILER_LANG['buggy_php'] = 'ご利用のバージョンのPHPには不具合があり、メッセージが破損するおそれがあります。問題の解決は以下のいずれかを行ってください。SMTPでの送信に切り替える。php.iniのmail.add_x_headerをoffにする。MacOSまたはLinuxに切り替える。PHPバージョン7.0.17以降または7.1.3以降にアップグレードする。';
$PHPMAILER_LANG['connect_host'] = 'SMTPエラー: SMTPホストに接続できませんでした。';
$PHPMAILER_LANG['data_not_accepted'] = 'SMTPエラー: データが受け付けられませんでした。';
$PHPMAILER_LANG['empty_message'] = 'メール本文が空です。';
$PHPMAILER_LANG['encoding'] = '不明なエンコーディング: ';
$PHPMAILER_LANG['execute'] = '実行できませんでした: ';
$PHPMAILER_LANG['extension_missing'] = '拡張機能が見つかりません: ';
$PHPMAILER_LANG['file_access'] = 'ファイルにアクセスできません: ';
$PHPMAILER_LANG['file_open'] = 'ファイルエラー: ファイルを開けません: ';
$PHPMAILER_LANG['from_failed'] = 'Fromアドレスを登録する際にエラーが発生しました: ';
$PHPMAILER_LANG['instantiate'] = 'メール関数が正常に動作しませんでした。';
$PHPMAILER_LANG['invalid_address'] = '不正なメールアドレス: ';
$PHPMAILER_LANG['provide_address'] = '少なくとも1つメールアドレスを 指定する必要があります。';
$PHPMAILER_LANG['invalid_header'] = '不正なヘッダー名またはその内容';
$PHPMAILER_LANG['invalid_hostentry'] = '不正なホストエントリー: ';
$PHPMAILER_LANG['invalid_host'] = '不正なホスト: ';
$PHPMAILER_LANG['mailer_not_supported'] = ' メーラーがサポートされていません。';
$PHPMAILER_LANG['provide_address'] = '少なくとも1つメールアドレスを 指定する必要があります。';
$PHPMAILER_LANG['recipients_failed'] = 'SMTPエラー: 次の受信者アドレスに 間違いがあります: ';
$PHPMAILER_LANG['signing'] = '署名エラー: ';
$PHPMAILER_LANG['smtp_code'] = 'SMTPコード: ';
$PHPMAILER_LANG['smtp_code_ex'] = 'SMTP追加情報: ';
$PHPMAILER_LANG['smtp_connect_failed'] = 'SMTP接続に失敗しました。';
$PHPMAILER_LANG['smtp_detail'] = '詳細: ';
$PHPMAILER_LANG['smtp_error'] = 'SMTPサーバーエラー: ';
$PHPMAILER_LANG['variable_set'] = '変数が存在しません: ';
$PHPMAILER_LANG['extension_missing'] = '拡張機能が見つかりません: ';

View File

@ -0,0 +1,27 @@
<?php
/**
* Kurdish (Sorani) PHPMailer language file: refer to English translation for definitive list
* @package PHPMailer
* @author Halo Salman <halo@home4t.com>
*/
$PHPMAILER_LANG['authenticate'] = 'هەڵەی SMTP : نەتوانرا کۆدەکە پشتڕاست بکرێتەوە ';
$PHPMAILER_LANG['connect_host'] = 'هەڵەی SMTP: نەتوانرا پەیوەندی بە سێرڤەرەوە بکات SMTP.';
$PHPMAILER_LANG['data_not_accepted'] = 'هەڵەی SMTP: ئەو زانیاریانە قبوڵ نەکرا.';
$PHPMAILER_LANG['empty_message'] = 'پەیامەکە بەتاڵە';
$PHPMAILER_LANG['encoding'] = 'کۆدکردنی نەزانراو : ';
$PHPMAILER_LANG['execute'] = 'ناتوانرێت جێبەجێ بکرێت: ';
$PHPMAILER_LANG['file_access'] = 'ناتوانرێت دەستت بگات بە فایلەکە: ';
$PHPMAILER_LANG['file_open'] = 'هەڵەی پەڕگە(فایل): ناتوانرێت بکرێتەوە: ';
$PHPMAILER_LANG['from_failed'] = 'هەڵە لە ئاستی ناونیشانی نێرەر: ';
$PHPMAILER_LANG['instantiate'] = 'ناتوانرێت خزمەتگوزاری پۆستە پێشکەش بکرێت.';
$PHPMAILER_LANG['invalid_address'] = 'نەتوانرا بنێردرێت ، چونکە ناونیشانی ئیمەیڵەکە نادروستە: ';
$PHPMAILER_LANG['mailer_not_supported'] = ' مەیلەر پشتگیری ناکات';
$PHPMAILER_LANG['provide_address'] = 'دەبێت ناونیشانی ئیمەیڵی لانیکەم یەک وەرگر دابین بکرێت.';
$PHPMAILER_LANG['recipients_failed'] = ' هەڵەی SMTP: ئەم هەڵانەی خوارەوەشکستی هێنا لە ناردن بۆ هەردووکیان: ';
$PHPMAILER_LANG['signing'] = 'هەڵەی واژۆ: ';
$PHPMAILER_LANG['smtp_connect_failed'] = 'SMTP Connect()پەیوەندی شکستی هێنا .';
$PHPMAILER_LANG['smtp_error'] = 'هەڵەی ئاستی سێرڤەری SMTP: ';
$PHPMAILER_LANG['variable_set'] = 'ناتوانرێت بیگۆڕیت یان دوبارە بینێریتەوە: ';
$PHPMAILER_LANG['extension_missing'] = 'درێژکراوە نەماوە: ';

View File

@ -5,24 +5,32 @@
* @package PHPMailer
* @author Alexey Chumakov <alex@chumakov.ru>
* @author Foster Snowhill <i18n@forstwoof.ru>
* @author ProjectSoft <projectsoft2009@yandex.ru>
*/
$PHPMAILER_LANG['authenticate'] = 'Ошибка SMTP: ошибка авторизации.';
$PHPMAILER_LANG['authenticate'] = 'Ошибка SMTP: не удалось пройти аутентификацию.';
$PHPMAILER_LANG['buggy_php'] = 'В вашей версии PHP есть ошибка, которая может привести к повреждению сообщений. Чтобы исправить, переключитесь на отправку по SMTP, отключите опцию mail.add_x_header в ваш php.ini, переключитесь на MacOS или Linux или обновите PHP до версии 7.0.17+ или 7.1.3+.';
$PHPMAILER_LANG['connect_host'] = 'Ошибка SMTP: не удается подключиться к SMTP-серверу.';
$PHPMAILER_LANG['data_not_accepted'] = 'Ошибка SMTP: данные не приняты.';
$PHPMAILER_LANG['empty_message'] = 'Пустое сообщение';
$PHPMAILER_LANG['encoding'] = 'Неизвестная кодировка: ';
$PHPMAILER_LANG['execute'] = 'Невозможно выполнить команду: ';
$PHPMAILER_LANG['extension_missing'] = 'Расширение отсутствует: ';
$PHPMAILER_LANG['file_access'] = 'Нет доступа к файлу: ';
$PHPMAILER_LANG['file_open'] = 'Файловая ошибка: не удаётся открыть файл: ';
$PHPMAILER_LANG['from_failed'] = 'Неверный адрес отправителя: ';
$PHPMAILER_LANG['instantiate'] = 'Невозможно запустить функцию mail().';
$PHPMAILER_LANG['provide_address'] = 'Пожалуйста, введите хотя бы один email-адрес получателя.';
$PHPMAILER_LANG['mailer_not_supported'] = ' — почтовый сервер не поддерживается.';
$PHPMAILER_LANG['recipients_failed'] = 'Ошибка SMTP: не удалась отправка таким адресатам: ';
$PHPMAILER_LANG['empty_message'] = 'Пустое сообщение';
$PHPMAILER_LANG['invalid_address'] = 'Не отправлено из-за неправильного формата email-адреса: ';
$PHPMAILER_LANG['invalid_header'] = 'Неверное имя или значение заголовка';
$PHPMAILER_LANG['invalid_hostentry'] = 'Неверная запись хоста: ';
$PHPMAILER_LANG['invalid_host'] = 'Неверный хост: ';
$PHPMAILER_LANG['mailer_not_supported'] = ' — почтовый сервер не поддерживается.';
$PHPMAILER_LANG['provide_address'] = 'Вы должны указать хотя бы один адрес электронной почты получателя.';
$PHPMAILER_LANG['recipients_failed'] = 'Ошибка SMTP: Ошибка следующих получателей: ';
$PHPMAILER_LANG['signing'] = 'Ошибка подписи: ';
$PHPMAILER_LANG['smtp_connect_failed'] = 'Ошибка соединения с SMTP-сервером';
$PHPMAILER_LANG['smtp_code'] = 'Код SMTP: ';
$PHPMAILER_LANG['smtp_code_ex'] = 'Дополнительная информация SMTP: ';
$PHPMAILER_LANG['smtp_connect_failed'] = 'Ошибка соединения с SMTP-сервером.';
$PHPMAILER_LANG['smtp_detail'] = 'Детали: ';
$PHPMAILER_LANG['smtp_error'] = 'Ошибка SMTP-сервера: ';
$PHPMAILER_LANG['variable_set'] = 'Невозможно установить или сбросить переменную: ';
$PHPMAILER_LANG['extension_missing'] = 'Расширение отсутствует: ';

View File

@ -11,21 +11,28 @@
*/
$PHPMAILER_LANG['authenticate'] = 'SMTP Hatası: Oturum açılamadı.';
$PHPMAILER_LANG['buggy_php'] = 'PHP sürümünüz iletilerin bozulmasına neden olabilecek bir hatadan etkileniyor. Bunu düzeltmek için, SMTP kullanarak göndermeye geçin, mail.add_x_header seçeneğini devre dışı bırakın php.ini dosyanızdaki mail.add_x_header seçeneğini devre dışı bırakın, MacOS veya Linux geçin veya PHP sürümünü 7.0.17+ veya 7.1.3+ sürümüne yükseltin,';
$PHPMAILER_LANG['connect_host'] = 'SMTP Hatası: SMTP sunucusuna bağlanılamadı.';
$PHPMAILER_LANG['data_not_accepted'] = 'SMTP Hatası: Veri kabul edilmedi.';
$PHPMAILER_LANG['empty_message'] = 'Mesajın içeriği boş';
$PHPMAILER_LANG['encoding'] = 'Bilinmeyen karakter kodlama: ';
$PHPMAILER_LANG['execute'] = 'Çalıştırılamadı: ';
$PHPMAILER_LANG['extension_missing'] = 'Eklenti bulunamadı: ';
$PHPMAILER_LANG['file_access'] = 'Dosyaya erişilemedi: ';
$PHPMAILER_LANG['file_open'] = 'Dosya Hatası: Dosya açılamadı: ';
$PHPMAILER_LANG['from_failed'] = 'Belirtilen adreslere gönderme başarısız: ';
$PHPMAILER_LANG['instantiate'] = 'Örnek e-posta fonksiyonu oluşturulamadı.';
$PHPMAILER_LANG['invalid_address'] = 'Geçersiz e-posta adresi: ';
$PHPMAILER_LANG['invalid_header'] = 'Geçersiz başlık adı veya değeri: ';
$PHPMAILER_LANG['invalid_hostentry'] = 'Geçersiz ana bilgisayar girişi: ';
$PHPMAILER_LANG['invalid_host'] = 'Geçersiz ana bilgisayar: ';
$PHPMAILER_LANG['mailer_not_supported'] = ' e-posta kütüphanesi desteklenmiyor.';
$PHPMAILER_LANG['provide_address'] = 'En az bir alıcı e-posta adresi belirtmelisiniz.';
$PHPMAILER_LANG['recipients_failed'] = 'SMTP Hatası: Belirtilen alıcılara ulaşılamadı: ';
$PHPMAILER_LANG['signing'] = 'İmzalama hatası: ';
$PHPMAILER_LANG['smtp_code'] = 'SMTP kodu: ';
$PHPMAILER_LANG['smtp_code_ex'] = 'ek SMTP bilgileri: ';
$PHPMAILER_LANG['smtp_connect_failed'] = 'SMTP connect() fonksiyonu başarısız.';
$PHPMAILER_LANG['smtp_detail'] = 'SMTP SMTP Detayı: ';
$PHPMAILER_LANG['smtp_error'] = 'SMTP sunucu hatası: ';
$PHPMAILER_LANG['variable_set'] = 'Değişken ayarlanamadı ya da sıfırlanamadı: ';
$PHPMAILER_LANG['extension_missing'] = 'Eklenti bulunamadı: ';

View File

@ -0,0 +1,30 @@
<?php
/**
* Urdu PHPMailer language file: refer to English translation for definitive list
* @package PHPMailer
* @author Saqib Ali Siddiqui <saqibsra@gmail.com>
*/
$PHPMAILER_LANG['authenticate'] = 'SMTP خرابی: تصدیق کرنے سے قاصر۔';
$PHPMAILER_LANG['connect_host'] = 'SMTP خرابی: سرور سے منسلک ہونے سے قاصر۔';
$PHPMAILER_LANG['data_not_accepted'] = 'SMTP خرابی: ڈیٹا قبول نہیں کیا گیا۔';
$PHPMAILER_LANG['empty_message'] = 'پیغام کی باڈی خالی ہے۔';
$PHPMAILER_LANG['encoding'] = 'نامعلوم انکوڈنگ: ';
$PHPMAILER_LANG['execute'] = 'عمل کرنے کے قابل نہیں ';
$PHPMAILER_LANG['file_access'] = 'فائل تک رسائی سے قاصر:';
$PHPMAILER_LANG['file_open'] = 'فائل کی خرابی: فائل کو کھولنے سے قاصر:';
$PHPMAILER_LANG['from_failed'] = 'درج ذیل بھیجنے والے کا پتہ ناکام ہو گیا:';
$PHPMAILER_LANG['instantiate'] = 'میل فنکشن کی مثال بنانے سے قاصر۔';
$PHPMAILER_LANG['invalid_address'] = 'بھیجنے سے قاصر: غلط ای میل پتہ:';
$PHPMAILER_LANG['mailer_not_supported'] = ' میلر تعاون یافتہ نہیں ہے۔';
$PHPMAILER_LANG['provide_address'] = 'آپ کو کم از کم ایک منزل کا ای میل پتہ فراہم کرنا چاہیے۔';
$PHPMAILER_LANG['recipients_failed'] = 'SMTP خرابی: درج ذیل پتہ پر نہیں بھیجا جاسکا: ';
$PHPMAILER_LANG['signing'] = 'دستخط کی خرابی: ';
$PHPMAILER_LANG['smtp_connect_failed'] = 'SMTP ملنا ناکام ہوا';
$PHPMAILER_LANG['smtp_error'] = 'SMTP سرور کی خرابی: ';
$PHPMAILER_LANG['variable_set'] = 'متغیر سیٹ نہیں کیا جا سکا: ';
$PHPMAILER_LANG['extension_missing'] = 'ایکٹینشن موجود نہیں ہے۔ ';
$PHPMAILER_LANG['smtp_code'] = 'SMTP سرور کوڈ: ';
$PHPMAILER_LANG['smtp_code_ex'] = 'اضافی SMTP سرور کی معلومات:';
$PHPMAILER_LANG['invalid_header'] = 'غلط ہیڈر کا نام یا قدر';

View File

@ -13,7 +13,7 @@
* @copyright 2012 - 2023 Marcus Bointon
* @copyright 2010 - 2012 Jim Jagielski
* @copyright 2004 - 2009 Andy Prevost
* @license http://www.gnu.org/copyleft/lesser.html GNU Lesser General Public License
* @license https://www.gnu.org/licenses/old-licenses/lgpl-2.1.html GNU Lesser General Public License
* @note This program is distributed in the hope that it will be useful - WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE.

View File

@ -13,7 +13,7 @@
* @copyright 2012 - 2020 Marcus Bointon
* @copyright 2010 - 2012 Jim Jagielski
* @copyright 2004 - 2009 Andy Prevost
* @license http://www.gnu.org/copyleft/lesser.html GNU Lesser General Public License
* @license https://www.gnu.org/licenses/old-licenses/lgpl-2.1.html GNU Lesser General Public License
* @note This program is distributed in the hope that it will be useful - WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE.

View File

@ -13,7 +13,7 @@
* @copyright 2012 - 2020 Marcus Bointon
* @copyright 2010 - 2012 Jim Jagielski
* @copyright 2004 - 2009 Andy Prevost
* @license http://www.gnu.org/copyleft/lesser.html GNU Lesser General Public License
* @license https://www.gnu.org/licenses/old-licenses/lgpl-2.1.html GNU Lesser General Public License
* @note This program is distributed in the hope that it will be useful - WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE.
@ -29,7 +29,7 @@ use League\OAuth2\Client\Token\AccessToken;
* OAuth - OAuth2 authentication wrapper class.
* Uses the oauth2-client package from the League of Extraordinary Packages.
*
* @see http://oauth2-client.thephpleague.com
* @see https://oauth2-client.thephpleague.com
*
* @author Marcus Bointon (Synchro/coolbru) <phpmailer@synchromedia.co.uk>
*/

View File

@ -13,7 +13,7 @@
* @copyright 2012 - 2020 Marcus Bointon
* @copyright 2010 - 2012 Jim Jagielski
* @copyright 2004 - 2009 Andy Prevost
* @license http://www.gnu.org/copyleft/lesser.html GNU Lesser General Public License
* @license https://www.gnu.org/licenses/old-licenses/lgpl-2.1.html GNU Lesser General Public License
* @note This program is distributed in the hope that it will be useful - WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE.

View File

@ -13,7 +13,7 @@
* @copyright 2012 - 2020 Marcus Bointon
* @copyright 2010 - 2012 Jim Jagielski
* @copyright 2004 - 2009 Andy Prevost
* @license http://www.gnu.org/copyleft/lesser.html GNU Lesser General Public License
* @license https://www.gnu.org/licenses/old-licenses/lgpl-2.1.html GNU Lesser General Public License
* @note This program is distributed in the hope that it will be useful - WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE.
@ -152,8 +152,7 @@ class PHPMailer
* Only supported in simple alt or alt_inline message types
* To generate iCal event structures, use classes like EasyPeasyICS or iCalcreator.
*
* @see http://sprain.ch/blog/downloads/php-class-easypeasyics-create-ical-files-with-php/
* @see http://kigkonsult.se/iCalcreator/
* @see https://kigkonsult.se/iCalcreator/
*
* @var string
*/
@ -254,7 +253,7 @@ class PHPMailer
* You can set your own, but it must be in the format "<id@domain>",
* as defined in RFC5322 section 3.6.4 or it will be ignored.
*
* @see https://tools.ietf.org/html/rfc5322#section-3.6.4
* @see https://www.rfc-editor.org/rfc/rfc5322#section-3.6.4
*
* @var string
*/
@ -358,7 +357,7 @@ class PHPMailer
public $AuthType = '';
/**
* SMTP SMTPXClient command attibutes
* SMTP SMTPXClient command attributes
*
* @var array
*/
@ -388,7 +387,7 @@ class PHPMailer
* 'DELAY' will notify you if there is an unusual delay in delivery, but the actual
* delivery's outcome (success or failure) is not yet decided.
*
* @see https://tools.ietf.org/html/rfc3461 See section 4.1 for more information about NOTIFY
* @see https://www.rfc-editor.org/rfc/rfc3461.html#section-4.1 for more information about NOTIFY
*/
public $dsn = '';
@ -468,7 +467,7 @@ class PHPMailer
* Only applicable when sending via SMTP.
*
* @see https://en.wikipedia.org/wiki/Variable_envelope_return_path
* @see http://www.postfix.org/VERP_README.html Postfix VERP info
* @see https://www.postfix.org/VERP_README.html Postfix VERP info
*
* @var bool
*/
@ -551,10 +550,10 @@ class PHPMailer
* The function that handles the result of the send email action.
* It is called out by send() for each email sent.
*
* Value can be any php callable: http://www.php.net/is_callable
* Value can be any php callable: https://www.php.net/is_callable
*
* Parameters:
* bool $result result of the send action
* bool $result result of the send action
* array $to email addresses of the recipients
* array $cc cc email addresses
* array $bcc bcc email addresses
@ -757,7 +756,7 @@ class PHPMailer
*
* @var string
*/
const VERSION = '6.9.1';
const VERSION = '6.9.3';
/**
* Error severity: message only, continue processing.
@ -903,7 +902,7 @@ class PHPMailer
}
//Is this a PSR-3 logger?
if ($this->Debugoutput instanceof \Psr\Log\LoggerInterface) {
$this->Debugoutput->debug($str);
$this->Debugoutput->debug(rtrim($str, "\r\n"));
return;
}
@ -1072,7 +1071,7 @@ class PHPMailer
* be modified after calling this function), addition of such addresses is delayed until send().
* Addresses that have been added already return false, but do not throw exceptions.
*
* @param string $kind One of 'to', 'cc', 'bcc', or 'ReplyTo'
* @param string $kind One of 'to', 'cc', 'bcc', or 'Reply-To'
* @param string $address The email address
* @param string $name An optional username associated with the address
*
@ -1212,7 +1211,7 @@ class PHPMailer
* Uses the imap_rfc822_parse_adrlist function if the IMAP extension is available.
* Note that quotes in the name part are removed.
*
* @see http://www.andrew.cmu.edu/user/agreen1/testing/mrbs/web/Mail/RFC822.php A more careful implementation
* @see https://www.andrew.cmu.edu/user/agreen1/testing/mrbs/web/Mail/RFC822.php A more careful implementation
*
* @param string $addrstr The address list string
* @param bool $useimap Whether to use the IMAP extension to parse the list
@ -1407,7 +1406,6 @@ class PHPMailer
* * IPv6 literals: 'first.last@[IPv6:a1::]'
* Not all of these will necessarily work for sending!
*
* @see http://squiloople.com/2009/12/20/email-address-validation/
* @copyright 2009-2010 Michael Rushton
* Feel free to use and redistribute this code. But please keep this copyright notice.
*/
@ -1734,9 +1732,8 @@ class PHPMailer
//This sets the SMTP envelope sender which gets turned into a return-path header by the receiver
//A space after `-f` is optional, but there is a long history of its presence
//causing problems, so we don't use one
//Exim docs: http://www.exim.org/exim-html-current/doc/html/spec_html/ch-the_exim_command_line.html
//Sendmail docs: http://www.sendmail.org/~ca/email/man/sendmail.html
//Qmail docs: http://www.qmail.org/man/man8/qmail-inject.html
//Exim docs: https://www.exim.org/exim-html-current/doc/html/spec_html/ch-the_exim_command_line.html
//Sendmail docs: https://www.sendmail.org/~ca/email/man/sendmail.html
//Example problem: https://www.drupal.org/node/1057954
//PHP 5.6 workaround
@ -1874,7 +1871,7 @@ class PHPMailer
*/
protected static function isPermittedPath($path)
{
//Matches scheme definition from https://tools.ietf.org/html/rfc3986#section-3.1
//Matches scheme definition from https://www.rfc-editor.org/rfc/rfc3986#section-3.1
return !preg_match('#^[a-z][a-z\d+.-]*://#i', $path);
}
@ -1901,7 +1898,7 @@ class PHPMailer
/**
* Send mail using the PHP mail() function.
*
* @see http://www.php.net/manual/en/book.mail.php
* @see https://www.php.net/manual/en/book.mail.php
*
* @param string $header The message headers
* @param string $body The message body
@ -1931,9 +1928,8 @@ class PHPMailer
//This sets the SMTP envelope sender which gets turned into a return-path header by the receiver
//A space after `-f` is optional, but there is a long history of its presence
//causing problems, so we don't use one
//Exim docs: http://www.exim.org/exim-html-current/doc/html/spec_html/ch-the_exim_command_line.html
//Sendmail docs: http://www.sendmail.org/~ca/email/man/sendmail.html
//Qmail docs: http://www.qmail.org/man/man8/qmail-inject.html
//Exim docs: https://www.exim.org/exim-html-current/doc/html/spec_html/ch-the_exim_command_line.html
//Sendmail docs: https://www.sendmail.org/~ca/email/man/sendmail.html
//Example problem: https://www.drupal.org/node/1057954
//CVE-2016-10033, CVE-2016-10045: Don't pass -f if characters will be escaped.
@ -2709,7 +2705,7 @@ class PHPMailer
}
//Only allow a custom message ID if it conforms to RFC 5322 section 3.6.4
//https://tools.ietf.org/html/rfc5322#section-3.6.4
//https://www.rfc-editor.org/rfc/rfc5322#section-3.6.4
if (
'' !== $this->MessageID &&
preg_match(
@ -3634,7 +3630,7 @@ class PHPMailer
* without breaking lines within a character.
* Adapted from a function by paravoid.
*
* @see http://www.php.net/manual/en/function.mb-encode-mimeheader.php#60283
* @see https://www.php.net/manual/en/function.mb-encode-mimeheader.php#60283
*
* @param string $str multi-byte text to wrap encode
* @param string $linebreak string to use as linefeed/end-of-line
@ -3690,7 +3686,7 @@ class PHPMailer
/**
* Encode a string using Q encoding.
*
* @see http://tools.ietf.org/html/rfc2047#section-4.2
* @see https://www.rfc-editor.org/rfc/rfc2047#section-4.2
*
* @param string $str the text to encode
* @param string $position Where the text is going to be used, see the RFC for what that means
@ -4228,7 +4224,7 @@ class PHPMailer
$result = $_SERVER['SERVER_NAME'];
} elseif (function_exists('gethostname') && gethostname() !== false) {
$result = gethostname();
} elseif (php_uname('n') !== false) {
} elseif (php_uname('n') !== '') {
$result = php_uname('n');
}
if (!static::isValidHost($result)) {
@ -4253,7 +4249,7 @@ class PHPMailer
empty($host)
|| !is_string($host)
|| strlen($host) > 256
|| !preg_match('/^([a-zA-Z\d.-]*|\[[a-fA-F\d:]+\])$/', $host)
|| !preg_match('/^([a-z\d.-]*|\[[a-f\d:]+\])$/i', $host)
) {
return false;
}
@ -4267,8 +4263,8 @@ class PHPMailer
//Is it a valid IPv4 address?
return filter_var($host, FILTER_VALIDATE_IP, FILTER_FLAG_IPV4) !== false;
}
//Is it a syntactically valid hostname (when embeded in a URL)?
return filter_var('http://' . $host, FILTER_VALIDATE_URL) !== false;
//Is it a syntactically valid hostname (when embedded in a URL)?
return filter_var('https://' . $host, FILTER_VALIDATE_URL) !== false;
}
/**
@ -4679,7 +4675,7 @@ class PHPMailer
* Multi-byte-safe pathinfo replacement.
* Drop-in replacement for pathinfo(), but multibyte- and cross-platform-safe.
*
* @see http://www.php.net/manual/en/function.pathinfo.php#107461
* @see https://www.php.net/manual/en/function.pathinfo.php#107461
*
* @param string $path A filename or path, does not need to exist as a file
* @param int|string $options Either a PATHINFO_* constant,
@ -4914,7 +4910,7 @@ class PHPMailer
* Uses the 'relaxed' algorithm from RFC6376 section 3.4.2.
* Canonicalized headers should *always* use CRLF, regardless of mailer setting.
*
* @see https://tools.ietf.org/html/rfc6376#section-3.4.2
* @see https://www.rfc-editor.org/rfc/rfc6376#section-3.4.2
*
* @param string $signHeader Header
*
@ -4926,7 +4922,7 @@ class PHPMailer
$signHeader = static::normalizeBreaks($signHeader, self::CRLF);
//Unfold header lines
//Note PCRE \s is too broad a definition of whitespace; RFC5322 defines it as `[ \t]`
//@see https://tools.ietf.org/html/rfc5322#section-2.2
//@see https://www.rfc-editor.org/rfc/rfc5322#section-2.2
//That means this may break if you do something daft like put vertical tabs in your headers.
$signHeader = preg_replace('/\r\n[ \t]+/', ' ', $signHeader);
//Break headers out into an array
@ -4958,7 +4954,7 @@ class PHPMailer
* Uses the 'simple' algorithm from RFC6376 section 3.4.3.
* Canonicalized bodies should *always* use CRLF, regardless of mailer setting.
*
* @see https://tools.ietf.org/html/rfc6376#section-3.4.3
* @see https://www.rfc-editor.org/rfc/rfc6376#section-3.4.3
*
* @param string $body Message Body
*
@ -4994,7 +4990,7 @@ class PHPMailer
$DKIMquery = 'dns/txt'; //Query method
$DKIMtime = time();
//Always sign these headers without being asked
//Recommended list from https://tools.ietf.org/html/rfc6376#section-5.4.1
//Recommended list from https://www.rfc-editor.org/rfc/rfc6376#section-5.4.1
$autoSignHeaders = [
'from',
'to',
@ -5100,7 +5096,7 @@ class PHPMailer
}
//The DKIM-Signature header is included in the signature *except for* the value of the `b` tag
//which is appended after calculating the signature
//https://tools.ietf.org/html/rfc6376#section-3.5
//https://www.rfc-editor.org/rfc/rfc6376#section-3.5
$dkimSignatureHeader = 'DKIM-Signature: v=1;' .
' d=' . $this->DKIM_domain . ';' .
' s=' . $this->DKIM_selector . ';' . static::$LE .

View File

@ -13,7 +13,7 @@
* @copyright 2012 - 2020 Marcus Bointon
* @copyright 2010 - 2012 Jim Jagielski
* @copyright 2004 - 2009 Andy Prevost
* @license http://www.gnu.org/copyleft/lesser.html GNU Lesser General Public License
* @license https://www.gnu.org/licenses/old-licenses/lgpl-2.1.html GNU Lesser General Public License
* @note This program is distributed in the hope that it will be useful - WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE.
@ -46,7 +46,7 @@ class POP3
*
* @var string
*/
const VERSION = '6.9.1';
const VERSION = '6.9.3';
/**
* Default POP3 port number.
@ -250,7 +250,9 @@ class POP3
//On Windows this will raise a PHP Warning error if the hostname doesn't exist.
//Rather than suppress it with @fsockopen, capture it cleanly instead
set_error_handler([$this, 'catchWarning']);
set_error_handler(function () {
call_user_func_array([$this, 'catchWarning'], func_get_args());
});
if (false === $port) {
$port = static::DEFAULT_PORT;

View File

@ -13,7 +13,7 @@
* @copyright 2012 - 2020 Marcus Bointon
* @copyright 2010 - 2012 Jim Jagielski
* @copyright 2004 - 2009 Andy Prevost
* @license http://www.gnu.org/copyleft/lesser.html GNU Lesser General Public License
* @license https://www.gnu.org/licenses/old-licenses/lgpl-2.1.html GNU Lesser General Public License
* @note This program is distributed in the hope that it will be useful - WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE.
@ -35,7 +35,7 @@ class SMTP
*
* @var string
*/
const VERSION = '6.9.1';
const VERSION = '6.9.3';
/**
* SMTP line break constant.
@ -62,7 +62,7 @@ class SMTP
* The maximum line length allowed by RFC 5321 section 4.5.3.1.6,
* *excluding* a trailing CRLF break.
*
* @see https://tools.ietf.org/html/rfc5321#section-4.5.3.1.6
* @see https://www.rfc-editor.org/rfc/rfc5321#section-4.5.3.1.6
*
* @var int
*/
@ -72,7 +72,7 @@ class SMTP
* The maximum line length allowed for replies in RFC 5321 section 4.5.3.1.5,
* *including* a trailing CRLF line break.
*
* @see https://tools.ietf.org/html/rfc5321#section-4.5.3.1.5
* @see https://www.rfc-editor.org/rfc/rfc5321#section-4.5.3.1.5
*
* @var int
*/
@ -152,8 +152,8 @@ class SMTP
/**
* Whether to use VERP.
*
* @see http://en.wikipedia.org/wiki/Variable_envelope_return_path
* @see http://www.postfix.org/VERP_README.html Info on VERP
* @see https://en.wikipedia.org/wiki/Variable_envelope_return_path
* @see https://www.postfix.org/VERP_README.html Info on VERP
*
* @var bool
*/
@ -164,7 +164,7 @@ class SMTP
* Default of 5 minutes (300sec) is from RFC2821 section 4.5.3.2.
* This needs to be quite high to function correctly with hosts using greetdelay as an anti-spam measure.
*
* @see http://tools.ietf.org/html/rfc2821#section-4.5.3.2
* @see https://www.rfc-editor.org/rfc/rfc2821#section-4.5.3.2
*
* @var int
*/
@ -187,12 +187,12 @@ class SMTP
*/
protected $smtp_transaction_id_patterns = [
'exim' => '/[\d]{3} OK id=(.*)/',
'sendmail' => '/[\d]{3} 2.0.0 (.*) Message/',
'postfix' => '/[\d]{3} 2.0.0 Ok: queued as (.*)/',
'Microsoft_ESMTP' => '/[0-9]{3} 2.[\d].0 (.*)@(?:.*) Queued mail for delivery/',
'sendmail' => '/[\d]{3} 2\.0\.0 (.*) Message/',
'postfix' => '/[\d]{3} 2\.0\.0 Ok: queued as (.*)/',
'Microsoft_ESMTP' => '/[0-9]{3} 2\.[\d]\.0 (.*)@(?:.*) Queued mail for delivery/',
'Amazon_SES' => '/[\d]{3} Ok (.*)/',
'SendGrid' => '/[\d]{3} Ok: queued as (.*)/',
'CampaignMonitor' => '/[\d]{3} 2.0.0 OK:([a-zA-Z\d]{48})/',
'CampaignMonitor' => '/[\d]{3} 2\.0\.0 OK:([a-zA-Z\d]{48})/',
'Haraka' => '/[\d]{3} Message Queued \((.*)\)/',
'ZoneMTA' => '/[\d]{3} Message queued as (.*)/',
'Mailjet' => '/[\d]{3} OK queued as (.*)/',
@ -280,7 +280,8 @@ class SMTP
}
//Is this a PSR-3 logger?
if ($this->Debugoutput instanceof \Psr\Log\LoggerInterface) {
$this->Debugoutput->debug($str);
//Remove trailing line breaks potentially added by calls to SMTP::client_send()
$this->Debugoutput->debug(rtrim($str, "\r\n"));
return;
}
@ -293,6 +294,7 @@ class SMTP
switch ($this->Debugoutput) {
case 'error_log':
//Don't output, just log
/** @noinspection ForgottenDebugOutputInspection */
error_log($str);
break;
case 'html':
@ -371,7 +373,7 @@ class SMTP
}
//Anything other than a 220 response means something went wrong
//RFC 5321 says the server will wait for us to send a QUIT in response to a 554 error
//https://tools.ietf.org/html/rfc5321#section-3.1
//https://www.rfc-editor.org/rfc/rfc5321#section-3.1
if ($responseCode === 554) {
$this->quit();
}
@ -404,7 +406,9 @@ class SMTP
$errstr = '';
if ($streamok) {
$socket_context = stream_context_create($options);
set_error_handler([$this, 'errorHandler']);
set_error_handler(function () {
call_user_func_array([$this, 'errorHandler'], func_get_args());
});
$connection = stream_socket_client(
$host . ':' . $port,
$errno,
@ -419,7 +423,9 @@ class SMTP
'Connection: stream_socket_client not available, falling back to fsockopen',
self::DEBUG_CONNECTION
);
set_error_handler([$this, 'errorHandler']);
set_error_handler(function () {
call_user_func_array([$this, 'errorHandler'], func_get_args());
});
$connection = fsockopen(
$host,
$port,
@ -483,7 +489,9 @@ class SMTP
}
//Begin encrypted connection
set_error_handler([$this, 'errorHandler']);
set_error_handler(function () {
call_user_func_array([$this, 'errorHandler'], func_get_args());
});
$crypto_ok = stream_socket_enable_crypto(
$this->smtp_conn,
true,
@ -574,7 +582,7 @@ class SMTP
}
//Send encoded username and password
if (
//Format from https://tools.ietf.org/html/rfc4616#section-2
//Format from https://www.rfc-editor.org/rfc/rfc4616#section-2
//We skip the first field (it's forgery), so the string starts with a null byte
!$this->sendCommand(
'User & Password',
@ -648,7 +656,7 @@ class SMTP
}
//The following borrowed from
//http://php.net/manual/en/function.mhash.php#27225
//https://www.php.net/manual/en/function.mhash.php#27225
//RFC 2104 HMAC implementation for php.
//Creates an md5 HMAC.
@ -787,7 +795,7 @@ class SMTP
//Send the lines to the server
foreach ($lines_out as $line_out) {
//Dot-stuffing as per RFC5321 section 4.5.2
//https://tools.ietf.org/html/rfc5321#section-4.5.2
//https://www.rfc-editor.org/rfc/rfc5321#section-4.5.2
if (!empty($line_out) && $line_out[0] === '.') {
$line_out = '.' . $line_out;
}
@ -1162,7 +1170,9 @@ class SMTP
} else {
$this->edebug('CLIENT -> SERVER: ' . $data, self::DEBUG_CLIENT);
}
set_error_handler([$this, 'errorHandler']);
set_error_handler(function () {
call_user_func_array([$this, 'errorHandler'], func_get_args());
});
$result = fwrite($this->smtp_conn, $data);
restore_error_handler();
@ -1265,7 +1275,9 @@ class SMTP
while (is_resource($this->smtp_conn) && !feof($this->smtp_conn)) {
//Must pass vars in here as params are by reference
//solution for signals inspired by https://github.com/symfony/symfony/pull/6540
set_error_handler([$this, 'errorHandler']);
set_error_handler(function () {
call_user_func_array([$this, 'errorHandler'], func_get_args());
});
$n = stream_select($selR, $selW, $selW, $this->Timelimit);
restore_error_handler();

View File

@ -48,6 +48,11 @@ namespace Symfony\Polyfill\Mbstring;
* - mb_strstr - Finds first occurrence of a string within another
* - mb_strwidth - Return width of string
* - mb_substr_count - Count the number of substring occurrences
* - mb_ucfirst - Make a string's first character uppercase
* - mb_lcfirst - Make a string's first character lowercase
* - mb_trim - Strip whitespace (or other characters) from the beginning and end of a string
* - mb_ltrim - Strip whitespace (or other characters) from the beginning of a string
* - mb_rtrim - Strip whitespace (or other characters) from the end of a string
*
* Not implemented:
* - mb_convert_kana - Convert "kana" one from another ("zen-kaku", "han-kaku" and more)
@ -80,6 +85,15 @@ final class Mbstring
public static function mb_convert_encoding($s, $toEncoding, $fromEncoding = null)
{
if (\is_array($s)) {
$r = [];
foreach ($s as $str) {
$r[] = self::mb_convert_encoding($str, $toEncoding, $fromEncoding);
}
return $r;
}
if (\is_array($fromEncoding) || (null !== $fromEncoding && false !== strpos($fromEncoding, ','))) {
$fromEncoding = self::mb_detect_encoding($s, $fromEncoding);
} else {
@ -410,12 +424,6 @@ final class Mbstring
public static function mb_check_encoding($var = null, $encoding = null)
{
if (PHP_VERSION_ID < 70200 && \is_array($var)) {
trigger_error('mb_check_encoding() expects parameter 1 to be string, array given', \E_USER_WARNING);
return null;
}
if (null === $encoding) {
if (null === $var) {
return false;
@ -437,7 +445,6 @@ final class Mbstring
}
return true;
}
public static function mb_detect_encoding($str, $encodingList = null, $strict = false)
@ -827,7 +834,7 @@ final class Mbstring
return $code;
}
public static function mb_str_pad(string $string, int $length, string $pad_string = ' ', int $pad_type = \STR_PAD_RIGHT, string $encoding = null): string
public static function mb_str_pad(string $string, int $length, string $pad_string = ' ', int $pad_type = \STR_PAD_RIGHT, ?string $encoding = null): string
{
if (!\in_array($pad_type, [\STR_PAD_RIGHT, \STR_PAD_LEFT, \STR_PAD_BOTH], true)) {
throw new \ValueError('mb_str_pad(): Argument #4 ($pad_type) must be STR_PAD_LEFT, STR_PAD_RIGHT, or STR_PAD_BOTH');
@ -835,17 +842,8 @@ final class Mbstring
if (null === $encoding) {
$encoding = self::mb_internal_encoding();
}
try {
$validEncoding = @self::mb_check_encoding('', $encoding);
} catch (\ValueError $e) {
throw new \ValueError(sprintf('mb_str_pad(): Argument #5 ($encoding) must be a valid encoding, "%s" given', $encoding));
}
// BC for PHP 7.3 and lower
if (!$validEncoding) {
throw new \ValueError(sprintf('mb_str_pad(): Argument #5 ($encoding) must be a valid encoding, "%s" given', $encoding));
} else {
self::assertEncoding($encoding, 'mb_str_pad(): Argument #5 ($encoding) must be a valid encoding, "%s" given');
}
if (self::mb_strlen($pad_string, $encoding) <= 0) {
@ -871,6 +869,34 @@ final class Mbstring
}
}
public static function mb_ucfirst(string $string, ?string $encoding = null): string
{
if (null === $encoding) {
$encoding = self::mb_internal_encoding();
} else {
self::assertEncoding($encoding, 'mb_ucfirst(): Argument #2 ($encoding) must be a valid encoding, "%s" given');
}
$firstChar = mb_substr($string, 0, 1, $encoding);
$firstChar = mb_convert_case($firstChar, \MB_CASE_TITLE, $encoding);
return $firstChar.mb_substr($string, 1, null, $encoding);
}
public static function mb_lcfirst(string $string, ?string $encoding = null): string
{
if (null === $encoding) {
$encoding = self::mb_internal_encoding();
} else {
self::assertEncoding($encoding, 'mb_lcfirst(): Argument #2 ($encoding) must be a valid encoding, "%s" given');
}
$firstChar = mb_substr($string, 0, 1, $encoding);
$firstChar = mb_convert_case($firstChar, \MB_CASE_LOWER, $encoding);
return $firstChar.mb_substr($string, 1, null, $encoding);
}
private static function getSubpart($pos, $part, $haystack, $encoding)
{
if (false === $pos) {
@ -944,4 +970,76 @@ final class Mbstring
return $encoding;
}
public static function mb_trim(string $string, ?string $characters = null, ?string $encoding = null): string
{
return self::mb_internal_trim('{^[%s]+|[%1$s]+$}Du', $string, $characters, $encoding, __FUNCTION__);
}
public static function mb_ltrim(string $string, ?string $characters = null, ?string $encoding = null): string
{
return self::mb_internal_trim('{^[%s]+}Du', $string, $characters, $encoding, __FUNCTION__);
}
public static function mb_rtrim(string $string, ?string $characters = null, ?string $encoding = null): string
{
return self::mb_internal_trim('{[%s]+$}D', $string, $characters, $encoding, __FUNCTION__);
}
private static function mb_internal_trim(string $regex, string $string, ?string $characters, ?string $encoding, string $function): string
{
if (null === $encoding) {
$encoding = self::mb_internal_encoding();
} else {
self::assertEncoding($encoding, $function.'(): Argument #3 ($encoding) must be a valid encoding, "%s" given');
}
if ('' === $characters) {
return null === $encoding ? $string : self::mb_convert_encoding($string, $encoding);
}
if ('UTF-8' === $encoding) {
$encoding = null;
if (!preg_match('//u', $string)) {
$string = @iconv('UTF-8', 'UTF-8//IGNORE', $string);
}
if (null !== $characters && !preg_match('//u', $characters)) {
$characters = @iconv('UTF-8', 'UTF-8//IGNORE', $characters);
}
} else {
$string = iconv($encoding, 'UTF-8//IGNORE', $string);
if (null !== $characters) {
$characters = iconv($encoding, 'UTF-8//IGNORE', $characters);
}
}
if (null === $characters) {
$characters = "\\0 \f\n\r\t\v\u{00A0}\u{1680}\u{2000}\u{2001}\u{2002}\u{2003}\u{2004}\u{2005}\u{2006}\u{2007}\u{2008}\u{2009}\u{200A}\u{2028}\u{2029}\u{202F}\u{205F}\u{3000}\u{0085}\u{180E}";
} else {
$characters = preg_quote($characters);
}
$string = preg_replace(sprintf($regex, $characters), '', $string);
if (null === $encoding) {
return $string;
}
return iconv('UTF-8', $encoding.'//IGNORE', $string);
}
private static function assertEncoding(string $encoding, string $errorFormat): void
{
try {
$validEncoding = @self::mb_check_encoding('', $encoding);
} catch (\ValueError $e) {
throw new \ValueError(sprintf($errorFormat, $encoding));
}
// BC for PHP 7.3 and lower
if (!$validEncoding) {
throw new \ValueError(sprintf($errorFormat, $encoding));
}
}
}

View File

@ -136,6 +136,27 @@ if (!function_exists('mb_str_pad')) {
function mb_str_pad(string $string, int $length, string $pad_string = ' ', int $pad_type = STR_PAD_RIGHT, ?string $encoding = null): string { return p\Mbstring::mb_str_pad($string, $length, $pad_string, $pad_type, $encoding); }
}
if (!function_exists('mb_ucfirst')) {
function mb_ucfirst(string $string, ?string $encoding = null): string { return p\Mbstring::mb_ucfirst($string, $encoding); }
}
if (!function_exists('mb_lcfirst')) {
function mb_lcfirst(string $string, ?string $encoding = null): string { return p\Mbstring::mb_lcfirst($string, $encoding); }
}
if (!function_exists('mb_trim')) {
function mb_trim(string $string, ?string $characters = null, ?string $encoding = null): string { return p\Mbstring::mb_trim($string, $characters, $encoding); }
}
if (!function_exists('mb_ltrim')) {
function mb_ltrim(string $string, ?string $characters = null, ?string $encoding = null): string { return p\Mbstring::mb_ltrim($string, $characters, $encoding); }
}
if (!function_exists('mb_rtrim')) {
function mb_rtrim(string $string, ?string $characters = null, ?string $encoding = null): string { return p\Mbstring::mb_rtrim($string, $characters, $encoding); }
}
if (extension_loaded('mbstring')) {
return;
}

View File

@ -93,7 +93,7 @@ if (!function_exists('mb_strstr')) {
function mb_strstr(?string $haystack, ?string $needle, ?bool $before_needle = false, ?string $encoding = null): string|false { return p\Mbstring::mb_strstr((string) $haystack, (string) $needle, (bool) $before_needle, $encoding); }
}
if (!function_exists('mb_get_info')) {
function mb_get_info(?string $type = 'all'): array|string|int|false { return p\Mbstring::mb_get_info((string) $type); }
function mb_get_info(?string $type = 'all'): array|string|int|false|null { return p\Mbstring::mb_get_info((string) $type); }
}
if (!function_exists('mb_http_output')) {
function mb_http_output(?string $encoding = null): string|bool { return p\Mbstring::mb_http_output($encoding); }
@ -132,6 +132,26 @@ if (!function_exists('mb_str_pad')) {
function mb_str_pad(string $string, int $length, string $pad_string = ' ', int $pad_type = STR_PAD_RIGHT, ?string $encoding = null): string { return p\Mbstring::mb_str_pad($string, $length, $pad_string, $pad_type, $encoding); }
}
if (!function_exists('mb_ucfirst')) {
function mb_ucfirst($string, ?string $encoding = null): string { return p\Mbstring::mb_ucfirst($string, $encoding); }
}
if (!function_exists('mb_lcfirst')) {
function mb_lcfirst($string, ?string $encoding = null): string { return p\Mbstring::mb_lcfirst($string, $encoding); }
}
if (!function_exists('mb_trim')) {
function mb_trim(string $string, ?string $characters = null, ?string $encoding = null): string { return p\Mbstring::mb_trim($string, $characters, $encoding); }
}
if (!function_exists('mb_ltrim')) {
function mb_ltrim(string $string, ?string $characters = null, ?string $encoding = null): string { return p\Mbstring::mb_ltrim($string, $characters, $encoding); }
}
if (!function_exists('mb_rtrim')) {
function mb_rtrim(string $string, ?string $characters = null, ?string $encoding = null): string { return p\Mbstring::mb_rtrim($string, $characters, $encoding); }
}
if (extension_loaded('mbstring')) {
return;
}

View File

@ -16,7 +16,7 @@
}
],
"require": {
"php": ">=7.1"
"php": ">=7.2"
},
"provide": {
"ext-mbstring": "*"