Apache2 License
// +----------------------------------------------------------------------
namespace system;
use think\Facade;
/**
* 表单生成器
* SAPHP框架专用
*/
class Form extends Facade
{
protected static function getFacadeClass()
{
return 'system\FormBuilder';
}
}
class FormBuilder
{
/**
* Item宽度
*
* @var integer
*/
public $width = 100;
/**
* 标签宽度
*
* @var integer
*/
public $labelwidth = 110;
/**
* 公用属性
*
* @var array
*/
public $attrs = [
'type',
'name',
'min',
'max',
'maxlength',
'required',
'readonly',
'disabled',
'placeholder',
];
public $replace = [];
/**
* @var object 对象实例
*/
protected static $instance = null;
/**
* 表单类型
*
* @var boolean
*/
protected $formtype = true;
/**
* 类构造函数
* class constructor.
*/
public function __construct()
{}
/**
* 初始化
* @access public
* @param array $options 参数
* @return object|FormBuilder|null
*/
public static function instance(array $options = [])
{
if (is_null(self::$instance)) {
self::$instance = new static($options);
}
// 返回实例
return self::$instance;
}
/**
* 开始生成元素
*
* @param array $data
* @param bool $formType
* @return string
*/
public function itemElem(array $data = [], bool $formType = true): string
{
$this->formtype = $formType;
if ($data['tag'] == 'tab') {
return $this->tab($data);
}
if ($data['tag'] == 'grid') {
return $this->grid($data);
}
$itemHtml = '
width) {
$itemHtml .= 'style="width:' . $data['width'] . '%;"';
}
}
$itemHtml .= '>' . PHP_EOL;
if (isset($data['label'])) {
$itemHtml .= $this->label($data['label'], $data) . PHP_EOL;
}
$itemHtml .= $this->block($data) . PHP_EOL;
$itemHtml .= '
' . PHP_EOL;
return $itemHtml;
}
/**
* 生成Label标签
*
* @param string $text
* @param array $data
* @return string
*/
public function label(string $text, array $data = []): string
{
$label = '';
}
/**
* 生成BLOCK区块
*
* @param array $data
* @return string
*/
public function block(array $data = []): string
{
$block = 'labelwidth) {
$style = 'margin-left:' . ($data['labelwidth'] + 30) . 'px';
}
}
}
if (isset($style)) {
$block .= ' style="' . $style . '"';
}
$block .= '>';
$block .= call_user_func([Form::instance(), $data['tag']], $data);
$block .= '
';
return $block;
}
/**
* 获取input
*
* @param array $data
* @return string
*/
public function input(array $data = []): string
{
$value = $this->formtype ? 'value="{$data.' . $data['name'] . '}"' : '';
return 'attributes($data) . $value . ' >';
}
/**
* 获取多行编辑
*
* @param array $data
* @return string
*/
public function textarea(array $data = []): string
{
$value = $this->formtype ? '{$data.' . $data['name'] . '}' : '';
return '';
}
/**
* 获取单选框
*
* @param array $data
* @return string|string[]
* @throws \Exception
*/
public function radio(array $data = [])
{
return $this->radioCheckSelect($data,'radio');
}
/**
* 获取多选框
*
* @param array $data
* @return string|string[]
* @throws \Exception
*/
public function checkbox(array $data = [])
{
if (!$this->formtype) {
throw new \Exception('多选框不支持生成内置表单');
}
return $this->radioCheckSelect($data,'checkbox','[]');
}
/**
* 获取下拉框
*
* @param array $data
* @return string|string[]
* @throws \Exception
*/
public function select(array $data = [])
{
return $this->radioCheckSelect($data,'select');
}
/**
* 验证选项
*
* @param array $options
* @return string|string[]|null
* @throws \Exception
*/
public function validOptions(array $options = [])
{
if (!is_array($options) || !$options) {
throw new \Exception("Options is Empty", 1);
}
$export = var_exports($options, true);
return preg_replace('/\s+/', '', $export);
}
/**
* 获取PHP代码
*
* @param [type] $argc
* @param [type] $options
* @return string
*/
public function getVarPHPList($argc = null, $options = null): string
{
return PHP_EOL . "$$argc = $options;";
}
/**
* 获取模板
*
* @param array $data
* @param string $type
* @param string $attr
* @return string|string[]
* @throws \Exception
*/
public function radioCheckSelect(array $data = [], string $type = '', string $attr = '' )
{
$options = $this->validOptions($data['options']);
$varName = ucfirst($data['name']).'_LIST';
$getAttr = $this->attributes($data,$attr);
$varHtml = $this->getVarPHPList($varName, $options);
$varHtml .= read_file($this->getHtmlTpl($type));
$this->replace = [
'varlist' => $varName,
'field' => $data['name'],
'attributes' => $getAttr,
];
foreach ($this->replace as $key => $value) {
$varHtml = str_replace("{%$key%}", $value, $varHtml);
}
return $varHtml;
}
/**
* 获取日期
*
* @param array $data
* @return string
*/
public function date(array $data = []): string
{
$value = $this->formtype ? 'value="{$data.' . $data['name'] . '}"' : '';
return 'attributes($data) . $value . ' >';
}
/**
* 获取颜色选择器
*
* @param array $data
* @return string
* @throws \Exception
*/
public function colorpicker(array $data = []): string
{
$value = $this->formtype ? 'value="{$data.' . $data['name'] . '}"' : '';
if (!$this->formtype) {
throw new \Exception('颜色选择器不支持生成内置表单');
}
return <<attributes($data)} {$value} >
Eof;
}
/**
* 获取滑块
*
* @param array $data
* @return string
*/
public function slider(array $data = []): string
{
$value = $this->formtype ? 'value="{$data.' . $data['name'] . '}"' : '';
return <<
attributes($data)} >
Eof;
}
/**
* 获取评分
*
* @param array $data
* @return string
* @throws \Exception
*/
public function rate(array $data = []): string
{
$value = $this->formtype ? 'value="{$data.' . $data['name'] . '}"' : '';
if (!$this->formtype) {
throw new \Exception("评分组件不支持生成内置表单");
}
return <<
attributes($data)} >
Eof;
}
/**
* 获取开关
*
* @param array $data
* @return string
*/
public function switch(array $data = []): string
{
$value = $this->formtype ? 'value="{$data.' . $data['name'] . '}"' : '';
$param = '$data.' . $data['name'];
return <<
checked lay-skin="switch" />
Eof;
}
/**
* 获取级联选择器
*
* @param array $data
* @return string
* @throws \Exception
*/
public function cascader(array $data = [])
{
if (!$this->formtype) {
throw new \Exception("级联选择器不支持生成内置表单");
}
$value = 'value="{$data.' . $data['name'] . '}"';
return <<attributes($data)} {$value} />
Eof;
}
/**
* 获取富文本
*
* @param array $data
* @return string
* @throws \Exception
*/
public function editor(array $data = []): string
{
if (!$this->formtype) {
throw new \Exception("富文本不支持生成内置表单");
}
// 非INPUT表单 值
$value = '{$data.' . $data['name'] . '}';
return <<attributes($data)} type="layui-textarea" >{$value}
Eof;
}
/**
* 获取上传模板
*
* @param array $data
* @return false|string|string[]
* @throws \Exception
*/
public function upload(array $data = [])
{
if (!$this->formtype && ($data['uploadtype'] == 'multiple' || $data['uploadtype'] == 'images')) {
throw new \Exception("上传组件仅支持 File类型 生成内置表单");
}
$value = $this->formtype ? '{$data.' . $data['name'] . '}' : '';
$varHtml = read_file($this->getHtmlTpl($data['uploadtype']));
$this->replace = [
'value' => $value,
'field' => $data['name'],
'accept' => $data['data_accept'],
'size' => (string)$data['data_size'],
];
foreach ($this->replace as $key => $value) {
$varHtml = str_replace("{%$key%}", $value, $varHtml);
}
return $varHtml;
}
/**
* 获取TAGS模板
*
* @param array $data
* @return string
* @throws \Exception
*/
public function tags(array $data = []): string
{
$value = 'value="{$data.' . $data['name'] . '}"';
return '';
}
/**
* 获取JSON模板
*
* @param array $data
* @return false|string|string[]
* @throws \Exception
*/
public function json(array $data = [])
{
if (!$this->formtype) {
throw new \Exception("JSON组件不支持生成内置表单");
}
$value = $this->formtype ? 'value="{$data.' . $data['name'] . '}"' : '';
$jsonHtml = read_file($this->getHtmlTpl($data['tag']));
$this->replace = [
'value' => $value,
'field' => $data['name'],
];
foreach ($this->replace as $key => $value) {
$jsonHtml = str_replace("{%$key%}", $value, $jsonHtml);
}
return $jsonHtml;
}
/**
* 获取提示器
*
* @param array $data
* @return string
*/
public function tips(array $data = []): string
{
return '
';
}
/**
* 获取便签
*
* @param array $data
* @return string
*/
public function note(array $data = []): string
{
return '' . $data['textarea'] . '
';
}
/**
* 获取横线
*
* @param array $data
* @return string
*/
public function subtraction(array $data = []): string
{
return '
';
}
/**
* 获取行高
*
* @param array $data
* @return string
*/
public function space(array $data = []): string
{
return '';
}
/**
* 获取选项卡
*
* @param array $data
* @return string
*/
public function tab(array $data = []): string
{
$tabHtml = '';
$tabHtml .= '
';
$tabContent = '';
foreach ($data['options'] as $key => $option) {
$tabHtml .= '- ' . $option['title'] . '
';
$tabContent .= '';
foreach ($data['children'][$key] as $children) {
foreach ($children as $elem) {
$tabContent .= $this->itemElem($elem);
}
}
$tabContent .= '
';
}
$tabHtml .= '
';
$tabHtml .= '
' . $tabContent . '
';
$tabHtml .= '
';
return $tabHtml;
}
/**
* 获取布局组件
*
* @param array $data
* @return string
*/
public function grid(array $data = []): string
{
$gridHtml = '';
return $gridHtml;
}
/**
* 获取表单属性
*
* @param array $data
* @param string $suffix
* @return string
*/
public function attributes(array $data = [], string $suffix = ''): string
{
$vars = [];
foreach ($data as $key => $elem) {
if (array_search($key, $this->attrs)) {
if (!$elem) {
continue;
}
// 单独处理NAME值
if ($key == 'name') {
$elem .= $suffix;
}
$vars[] = $key . '="' . $elem . '"';
} else {
if (strstr($key, 'lay_') || strstr($key, 'data_')) {
$_key = str_replace('_', '-', $key);
$vars[] = $_key . '="' . $elem . '"';
}
}
}
return count($vars) > 0 ? ' ' . implode(' ', $vars) : '';
}
/**
* 获取模板文件
*
* @param [type] $name
* @return string
*/
protected function getHtmlTpl($name): string
{
return __DIR__ . DIRECTORY_SEPARATOR . 'form' . DIRECTORY_SEPARATOR . $name . '.html';
}
}