688 lines
30 KiB
PHP
688 lines
30 KiB
PHP
<?php
|
|
// +----------------------------------------------------------------------
|
|
// | ShopXO 国内领先企业级B2C免费开源电商系统
|
|
// +----------------------------------------------------------------------
|
|
// | Copyright (c) 2011~2099 http://shopxo.net All rights reserved.
|
|
// +----------------------------------------------------------------------
|
|
// | Licensed ( https://opensource.org/licenses/mit-license.php )
|
|
// +----------------------------------------------------------------------
|
|
// | Author: Devil
|
|
// +----------------------------------------------------------------------
|
|
namespace app\module;
|
|
|
|
use app\service\ResourcesService;
|
|
|
|
/**
|
|
* form表单处理服务层
|
|
* @author Devil
|
|
* @blog http://gong.gg/
|
|
* @version 1.0.0
|
|
* @date 2021-02-14
|
|
* @desc description
|
|
*/
|
|
class FormInputModule
|
|
{
|
|
/**
|
|
* 配置数据展示处理
|
|
* @author Devil
|
|
* @blog http://gong.gg/
|
|
* @version 1.0.0
|
|
* @date 2024-08-22
|
|
* @desc description
|
|
* @param [array] $config [配置数据]
|
|
* @param [array] $params [输入参数]
|
|
*/
|
|
public static function ConfigViewHandle($config, $params = [])
|
|
{
|
|
// 是否为空
|
|
if(!empty($config))
|
|
{
|
|
// 非数组处理
|
|
if(!is_array($config))
|
|
{
|
|
$config = json_decode($config, true);
|
|
}
|
|
|
|
// 数据处理
|
|
$config = self::ConfigViewAnnexHandle($config);
|
|
|
|
// forminput显示数据处理钩子
|
|
$hook_name = 'plugins_module_forminput_view_data_handle';
|
|
MyEventTrigger($hook_name, [
|
|
'hook_name' => $hook_name,
|
|
'is_backend' => true,
|
|
'config' => &$config,
|
|
'params' => $params,
|
|
]);
|
|
}
|
|
return $config;
|
|
}
|
|
|
|
/**
|
|
* 配置数据展示附件地址处理
|
|
* @author Devil
|
|
* @blog http://gong.gg/
|
|
* @version 1.0.0
|
|
* @date 2024-09-05
|
|
* @desc description
|
|
* @param [array] $data [配置数据]
|
|
*/
|
|
public static function ConfigViewAnnexHandle($data)
|
|
{
|
|
if(!empty($data) && is_array($data))
|
|
{
|
|
foreach($data as $k=>$v)
|
|
{
|
|
if(!empty($v) && is_array($v))
|
|
{
|
|
// 附件
|
|
if(!empty($v[0]) && isset($v[0]['url']))
|
|
{
|
|
$data[$k][0]['url'] = ResourcesService::AttachmentPathViewHandle($v[0]['url']);
|
|
} else {
|
|
$data[$k] = self::ConfigViewAnnexHandle($v);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
return $data;
|
|
}
|
|
|
|
/**
|
|
* 配置数据保存处理
|
|
* @author Devil
|
|
* @blog http://gong.gg/
|
|
* @version 1.0.0
|
|
* @date 2024-08-22
|
|
* @desc description
|
|
* @param [array] $config [配置数据]
|
|
*/
|
|
public static function ConfigSaveHandle($config)
|
|
{
|
|
if(!empty($config))
|
|
{
|
|
// 非数组处理
|
|
if(!is_array($config))
|
|
{
|
|
$config = json_decode(htmlspecialchars_decode($config), true);
|
|
}
|
|
|
|
// 数据处理
|
|
$config = self::ConfigSaveAnnexHandle($config);
|
|
|
|
// forminput保存数据处理钩子
|
|
$hook_name = 'plugins_module_forminput_save_data_handle';
|
|
MyEventTrigger($hook_name, [
|
|
'hook_name' => $hook_name,
|
|
'is_backend' => true,
|
|
'config' => &$config,
|
|
]);
|
|
|
|
// 转为json格式
|
|
$config = json_encode($config, JSON_UNESCAPED_UNICODE);
|
|
}
|
|
return $config;
|
|
}
|
|
|
|
/**
|
|
* 配置数据保存附件地址处理
|
|
* @author Devil
|
|
* @blog http://gong.gg/
|
|
* @version 1.0.0
|
|
* @date 2024-09-05
|
|
* @desc description
|
|
* @param [array] $data [配置数据]
|
|
*/
|
|
public static function ConfigSaveAnnexHandle($data)
|
|
{
|
|
if(!empty($data) && is_array($data))
|
|
{
|
|
foreach($data as $k=>$v)
|
|
{
|
|
if(!empty($v) && is_array($v))
|
|
{
|
|
// 附件
|
|
if(!empty($v[0]) && isset($v[0]['url']))
|
|
{
|
|
$data[$k][0]['url'] = ResourcesService::AttachmentPathHandle($v[0]['url']);
|
|
} else {
|
|
$data[$k] = self::ConfigSaveAnnexHandle($v);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
return $data;
|
|
}
|
|
|
|
/**
|
|
* 表单数据保存处理
|
|
* @author Devil
|
|
* @blog http://gong.gg/
|
|
* @version 1.0.0
|
|
* @date 2025-07-30
|
|
* @desc description
|
|
* @param [array] $config [表单配置]
|
|
* @param [array] $data [保存的表单数据]
|
|
* @param [string] $parent_name [父级表单名称]
|
|
* @param [boolean] $is_check [是否验证数据]
|
|
*/
|
|
public static function FormInputDataWriteHandle($config, $data, $parent_name = '', $is_check = true)
|
|
{
|
|
$result = [];
|
|
if(!empty($config) && !empty($config['diy_data']))
|
|
{
|
|
foreach($config['diy_data'] as $v)
|
|
{
|
|
// 是否启用
|
|
if(!isset($v['is_enable']) || $v['is_enable'] != 1)
|
|
{
|
|
continue;
|
|
}
|
|
|
|
// 是否存在表单名称
|
|
$form_name = empty($v['form_name']) ? (empty($v['id']) ? '' : $v['id']) : $v['form_name'];
|
|
if(empty($form_name))
|
|
{
|
|
continue;
|
|
}
|
|
|
|
// 配置和基础
|
|
if(empty($v['com_data']) || empty($v['key']))
|
|
{
|
|
continue;
|
|
}
|
|
|
|
// 非这些多数据格式的数据,是否需要填写
|
|
if(!in_array($v['key'], ['checkbox', 'select-multi', 'radio-btns', 'select', 'date-group', 'address']))
|
|
{
|
|
if($is_check && isset($v['com_data']['is_required']) && $v['com_data']['is_required'] == 1 && empty($data[$form_name]))
|
|
{
|
|
if(in_array($v['key'], ['upload-img', 'upload-attachments', 'upload-video']))
|
|
{
|
|
// 上传
|
|
$msg = MyLang('not_upload_error');
|
|
} else if(in_array($v['key'], ['score']))
|
|
{
|
|
// 选择
|
|
$msg = MyLang('not_choice_error');
|
|
} else {
|
|
// 填写
|
|
$msg = MyLang('not_fill_in_error');
|
|
}
|
|
return DataReturn($msg.'('.$parent_name.$v['name'].')', -1);
|
|
}
|
|
}
|
|
|
|
// 自定义列
|
|
$custom_option_list = empty($data[$form_name.'_custom_option_list']) ? [] : (is_array($data[$form_name.'_custom_option_list']) ? $data[$form_name.'_custom_option_list'] : json_decode(base64_decode(urldecode($data[$form_name.'_custom_option_list'])), true));
|
|
$name = empty($v['com_data']['title']) ? $v['name'] : $v['com_data']['title'];
|
|
switch($v['key'])
|
|
{
|
|
// 子表单
|
|
case 'subform' :
|
|
$temp_item = [];
|
|
if(!empty($data[$form_name]))
|
|
{
|
|
foreach($data[$form_name] as $sbk=>$sbv)
|
|
{
|
|
$res = self::FormInputDataWriteHandle(['diy_data'=>$v['com_data']['children']], $sbv, $name.'-', $is_check);
|
|
if($res['code'] == 0)
|
|
{
|
|
$temp_item[] = $res['data'];
|
|
} else {
|
|
if($is_check)
|
|
{
|
|
return $res;
|
|
} else {
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
if(!empty($temp_item))
|
|
{
|
|
$result[$form_name] = [
|
|
'name' => $name,
|
|
'value' => $temp_item,
|
|
'key' => $v['key'],
|
|
];
|
|
}
|
|
break;
|
|
|
|
// 富文本
|
|
case 'rich-text' :
|
|
if(array_key_exists($form_name, $data))
|
|
{
|
|
$value = $data[$form_name];
|
|
if(!empty($value))
|
|
{
|
|
$value = ResourcesService::ContentStaticReplace(htmlspecialchars_decode($value), 'add');
|
|
}
|
|
$result[$form_name] = [
|
|
'name' => $name,
|
|
'value' => $value,
|
|
'key' => $v['key'],
|
|
];
|
|
}
|
|
break;
|
|
|
|
// 附件
|
|
case 'upload-img' :
|
|
case 'upload-video' :
|
|
case 'upload-attachments' :
|
|
if(array_key_exists($form_name, $data))
|
|
{
|
|
$value = $data[$form_name];
|
|
if(!empty($value))
|
|
{
|
|
$value = is_array($value) ? $value : json_decode(base64_decode(urldecode($value)), true);
|
|
if(!empty($value) && is_array($value))
|
|
{
|
|
$value = ResourcesService::AttachmentPathHandle($value, 'url');
|
|
} else {
|
|
$value = '';
|
|
}
|
|
}
|
|
$result[$form_name] = [
|
|
'name' => $name,
|
|
'value' => $value,
|
|
'key' => $v['key'],
|
|
];
|
|
}
|
|
break;
|
|
|
|
// 复选
|
|
case 'checkbox' :
|
|
// 下拉多选
|
|
case 'select-multi' :
|
|
$temp_item = [];
|
|
if(array_key_exists($form_name, $data))
|
|
{
|
|
$temp_value = [];
|
|
$value = $data[$form_name];
|
|
if($value !== '')
|
|
{
|
|
if(!is_array($value))
|
|
{
|
|
$value = explode(',', $value);
|
|
}
|
|
$option_arr = array_merge(empty($v['com_data']['option_list']) ? [] : $v['com_data']['option_list'], $custom_option_list);
|
|
if(!empty($option_arr))
|
|
{
|
|
foreach($option_arr as $ov)
|
|
{
|
|
if(!empty($ov['value']) && in_array($ov['value'], $value))
|
|
{
|
|
$temp_value[] = $ov;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
$temp_item = [
|
|
'name' => $name,
|
|
'value' => empty($temp_value) ? '' : array_column($temp_value, 'value'),
|
|
'key' => $v['key'],
|
|
'value_text' => empty($temp_value) ? '' : implode(', ', array_column($temp_value, 'name')),
|
|
];
|
|
if(!empty($custom_option_list))
|
|
{
|
|
$temp_item['custom_option_list'] = $custom_option_list;
|
|
}
|
|
}
|
|
if(!empty($temp_item))
|
|
{
|
|
$result[$form_name] = $temp_item;
|
|
} else {
|
|
if($is_check && isset($v['com_data']['is_required']) && $v['com_data']['is_required'] == 1 && empty($data[$form_name]))
|
|
{
|
|
return DataReturn(MyLang('not_fill_in_error').'('.$parent_name.$name.')', -1);
|
|
}
|
|
}
|
|
break;
|
|
// 单选
|
|
case 'radio-btns' :
|
|
// 下拉单选
|
|
case 'select' :
|
|
$temp_item = [];
|
|
if(array_key_exists($form_name, $data))
|
|
{
|
|
$temp_value_text = '';
|
|
$temp_value = '';
|
|
if($data[$form_name] !== '')
|
|
{
|
|
$option_arr = array_merge(empty($v['com_data']['option_list']) ? [] : $v['com_data']['option_list'], $custom_option_list);
|
|
if(!empty($option_arr))
|
|
{
|
|
foreach($option_arr as $ov)
|
|
{
|
|
if(!empty($ov['value']) && $ov['value'] == $data[$form_name])
|
|
{
|
|
$temp_value_text = $ov['name'];
|
|
$temp_value = $ov['value'];
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
$temp_item = [
|
|
'name' => $name,
|
|
'value' => $temp_value,
|
|
'key' => $v['key'],
|
|
];
|
|
if(isset($data[$form_name.'_other_value']))
|
|
{
|
|
$temp_item['other_value'] = $data[$form_name.'_other_value'];
|
|
}
|
|
$temp_item['value_text'] = empty($temp_item['other_value']) ? $temp_value_text : $temp_item['other_value'];
|
|
}
|
|
if(!empty($temp_item))
|
|
{
|
|
$result[$form_name] = $temp_item;
|
|
} else {
|
|
if($is_check && isset($v['com_data']['is_required']) && $v['com_data']['is_required'] == 1 && empty($data[$form_name]))
|
|
{
|
|
return DataReturn(MyLang('not_fill_in_error').'('.$parent_name.$name.')', -1);
|
|
}
|
|
}
|
|
break;
|
|
|
|
// 时间组
|
|
case 'date-group' :
|
|
$temp_value = [];
|
|
$start_key = $form_name.'_start';
|
|
$temp_value[0] = array_key_exists($start_key, $data) ? $data[$start_key] : '';
|
|
$end_key = $form_name.'_end';
|
|
$temp_value[1] = array_key_exists($end_key, $data) ? $data[$end_key] : '';
|
|
if(count(array_filter($temp_value)) > 0)
|
|
{
|
|
$result[$form_name] = [
|
|
'name' => $name,
|
|
'value' => $temp_value,
|
|
'key' => $v['key'],
|
|
'value_text' => implode(' ~ ', $temp_value),
|
|
];
|
|
} else {
|
|
if($is_check && isset($v['com_data']['is_required']) && $v['com_data']['is_required'] == 1 && empty($data[$form_name]))
|
|
{
|
|
return DataReturn(MyLang('not_fill_in_error').'('.$parent_name.$name.')', -1);
|
|
}
|
|
}
|
|
break;
|
|
|
|
// 地区地址
|
|
case 'address' :
|
|
$temp_value = [];
|
|
$arr = [
|
|
'province_id',
|
|
'city_id',
|
|
'county_id',
|
|
'province_name',
|
|
'city_name',
|
|
'county_name',
|
|
'address',
|
|
];
|
|
foreach($arr as $tv)
|
|
{
|
|
$ads_key = $form_name.'_'.$tv;
|
|
$temp_value[$tv] = array_key_exists($ads_key, $data) ? $data[$ads_key] : '';
|
|
}
|
|
if(count(array_filter($temp_value)) > 0)
|
|
{
|
|
$result[$form_name] = [
|
|
'name' => $name,
|
|
'value' => $temp_value,
|
|
'key' => $v['key'],
|
|
'value_text' => $temp_value['province_name'].$temp_value['city_name'].$temp_value['county_name'].$temp_value['address'],
|
|
];
|
|
} else {
|
|
if($is_check && isset($v['com_data']['is_required']) && $v['com_data']['is_required'] == 1 && empty($data[$form_name]))
|
|
{
|
|
return DataReturn(MyLang('not_fill_in_error').'('.$parent_name.$name.')', -1);
|
|
}
|
|
}
|
|
break;
|
|
|
|
// 手机
|
|
case 'phone' :
|
|
// 是否需要短信验证码
|
|
if($is_check && !empty($data[$form_name]) && isset($v['com_data']['is_sms_verification']) && $v['com_data']['is_sms_verification'] == 1)
|
|
{
|
|
// 是否存在验证码
|
|
if(empty($data[$form_name.'_verify']))
|
|
{
|
|
return DataReturn(MyLang('verify_code_empty_tips').'('.$parent_name.$name.')', -1);
|
|
}
|
|
// 验证码校验
|
|
$verify_params = [
|
|
'key_prefix' => 'forminput_'.md5($data[$form_name]),
|
|
'expire_time' => MyC('common_verify_expire_time'),
|
|
];
|
|
$obj = new \base\Sms($verify_params);
|
|
// 是否已过期
|
|
if(!$obj->CheckExpire())
|
|
{
|
|
return DataReturn(MyLang('verify_code_expire_tips').'('.$parent_name.$name.')', -1);
|
|
}
|
|
// 是否正确
|
|
if(!$obj->CheckCorrect($data[$form_name.'_verify']))
|
|
{
|
|
return DataReturn(MyLang('verify_code_error_tips').'('.$parent_name.$name.')', -1);
|
|
}
|
|
}
|
|
if(!empty($data[$form_name]))
|
|
{
|
|
$result[$form_name] = [
|
|
'name' => $name,
|
|
'value' => $data[$form_name],
|
|
'key' => $v['key'],
|
|
];
|
|
}
|
|
break;
|
|
|
|
// 默认
|
|
default :
|
|
// 是否限制字数
|
|
if(isset($data[$form_name]) && isset($v['com_data']['is_limit_num']) && $v['com_data']['is_limit_num'] == 1)
|
|
{
|
|
if($is_check)
|
|
{
|
|
// 当前数值长度
|
|
$len = strlen($data[$form_name]);
|
|
// 最小值
|
|
if(!empty($v['com_data']['min_num']) && $len < $v['com_data']['min_num'])
|
|
{
|
|
return DataReturn(MyLang('data_length_min_tips').'('.$len.'<'.$v['com_data']['min_num'].' '.$name.')', -1);
|
|
}
|
|
// 最大值
|
|
if(!empty($v['com_data']['max_num']) && $len > $v['com_data']['max_num'])
|
|
{
|
|
return DataReturn(MyLang('data_length_max_tips').'('.$v['com_data']['max_num'].'>'.$len.' '.$name.')', -1);
|
|
}
|
|
}
|
|
}
|
|
if(array_key_exists($form_name, $data))
|
|
{
|
|
$result[$form_name] = [
|
|
'name' => $name,
|
|
'value' => $data[$form_name],
|
|
'key' => $v['key'],
|
|
];
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
return DataReturn('success', 0, $result);
|
|
}
|
|
|
|
/**
|
|
* 表单数据显示处理
|
|
* @author Devil
|
|
* @blog http://gong.gg/
|
|
* @version 1.0.0
|
|
* @date 2025-07-30
|
|
* @desc description
|
|
* @param [array] $data [表单保存的数据]
|
|
*/
|
|
public static function FormInputDataViewHandle($data)
|
|
{
|
|
if(!empty($data))
|
|
{
|
|
if(!is_array($data))
|
|
{
|
|
$data = json_decode($data, true);
|
|
}
|
|
foreach($data as &$v)
|
|
{
|
|
if(!empty($v['key']))
|
|
{
|
|
switch($v['key'])
|
|
{
|
|
// 子表单
|
|
case 'subform' :
|
|
if(!empty($v['value']) && is_array($v['value']))
|
|
{
|
|
foreach($v['value'] as $sk=>$sv)
|
|
{
|
|
if(!empty($sv) && is_array($sv))
|
|
{
|
|
foreach($sv as $sks=>$svs)
|
|
{
|
|
// 根据表单类型处理数据格式
|
|
switch($svs['key'])
|
|
{
|
|
// 附件
|
|
case 'upload-img' :
|
|
case 'upload-video' :
|
|
case 'upload-attachments' :
|
|
if(is_array($v['value'][$sk][$sks]['value']))
|
|
{
|
|
$v['value'][$sk][$sks]['value'] = ResourcesService::AttachmentPathViewHandle($svs['value'], 'url');
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
break;
|
|
|
|
// 富文本
|
|
case 'rich-text' :
|
|
$v['value'] = ResourcesService::ContentStaticReplace($v['value'], 'get');
|
|
break;
|
|
// 附件
|
|
case 'upload-img' :
|
|
case 'upload-video' :
|
|
case 'upload-attachments' :
|
|
if(is_array($v['value']))
|
|
{
|
|
$v['value'] = ResourcesService::AttachmentPathViewHandle($v['value'], 'url');
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
return $data;
|
|
}
|
|
|
|
/**
|
|
* 表单编辑数据合并
|
|
* @author Devil
|
|
* @blog http://gong.gg/
|
|
* @version 1.0.0
|
|
* @date 2025-10-15
|
|
* @desc description
|
|
* @param [array] $config [表单配置]
|
|
* @param [array] $data [编辑数据]
|
|
*/
|
|
public static function FormInputDataValueMerge($config, $data)
|
|
{
|
|
if(!empty($config) && !empty($config['diy_data']) && !empty($data))
|
|
{
|
|
$data = self::FormInputDataViewHandle($data);
|
|
foreach($config['diy_data'] as &$v)
|
|
{
|
|
$form_name = empty($v['form_name']) ? (empty($v['id']) ? '' : $v['id']) : $v['form_name'];
|
|
if(!empty($v['key']) && isset($data[$form_name]))
|
|
{
|
|
// 数据
|
|
$temp = $data[$form_name];
|
|
|
|
// 覆盖默认值
|
|
$v['com_data']['form_value'] = isset($temp['value']) ? $temp['value'] : '';
|
|
// 根据类型处理数据
|
|
switch($v['key'])
|
|
{
|
|
// 子表单
|
|
case 'subform' :
|
|
if(!empty($v['com_data']['form_value']) && is_array($v['com_data']['form_value']))
|
|
{
|
|
foreach($v['com_data']['form_value'] as $sk=>$sv)
|
|
{
|
|
if(!empty($sv) && is_array($sv))
|
|
{
|
|
foreach($sv as $sks=>$svs)
|
|
{
|
|
// 子数据
|
|
$temp_sub = isset($svs['value']) ? $svs['value'] : '';
|
|
|
|
// 截取value数据
|
|
$v['com_data']['form_value'][$sk][$sks] = $temp_sub;
|
|
|
|
// 根据表单类型处理数据格式
|
|
switch($svs['key'])
|
|
{
|
|
// 地址
|
|
case 'address' :
|
|
if(!empty($temp_sub))
|
|
{
|
|
foreach($temp_sub as $dk=>$dv)
|
|
{
|
|
if(in_array($dk, ['province_name', 'city_name', 'county_name']))
|
|
{
|
|
$v['com_data']['form_value'][$sk][$sks.'_'.$dk] = $dv;
|
|
}
|
|
}
|
|
$v['com_data']['form_value'][$sk][$sks] = [$temp_sub['province_id'], $temp_sub['city_id'], $temp_sub['county_id']];
|
|
}
|
|
break;
|
|
}
|
|
// 自定义数据项
|
|
if(!empty($svs['custom_option_list']))
|
|
{
|
|
$v['com_data']['form_value'][$sk][$sks.'_custom_option_list'] = $svs['custom_option_list'];
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
break;
|
|
|
|
// 地址
|
|
case 'address' :
|
|
$v['com_data']['form_value'] = [$temp['value']['province_id'], $temp['value']['city_id'], $temp['value']['county_id']];
|
|
unset($temp['value']['province_id'], $temp['value']['city_id'], $temp['value']['county_id']);
|
|
$v['com_data'] = array_merge($v['com_data'], $temp['value']);
|
|
break;
|
|
}
|
|
|
|
// 其他值
|
|
if($v['com_data']['form_value'] == 'other')
|
|
{
|
|
$v['com_data']['other_value'] = isset($temp['other_value']) ? $temp['other_value'] : '';
|
|
}
|
|
|
|
// 自定义数据项
|
|
if(!empty($temp['custom_option_list']))
|
|
{
|
|
$v['com_data']['custom_option_list'] = $temp['custom_option_list'];
|
|
}
|
|
}
|
|
}
|
|
}
|
|
return $config;
|
|
}
|
|
}
|
|
?>
|