You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
535 lines
12 KiB
535 lines
12 KiB
<?php
|
|
/**
|
|
* PHP表单生成器
|
|
*
|
|
* @package FormBuilder
|
|
* @author xaboy <xaboy2005@qq.com>
|
|
* @version 2.0
|
|
* @license MIT
|
|
* @link https://github.com/xaboy/form-builder
|
|
* @document http://php.form-create.com
|
|
*/
|
|
|
|
namespace FormBuilder;
|
|
|
|
|
|
use FormBuilder\Contract\BootstrapInterface;
|
|
use FormBuilder\Contract\ConfigInterface;
|
|
use FormBuilder\Exception\FormBuilderException;
|
|
use FormBuilder\UI\Iview\Bootstrap as IViewBootstrap;
|
|
use FormBuilder\UI\Elm\Bootstrap as ElmBootstrap;
|
|
|
|
class Form
|
|
{
|
|
protected $headers = [];
|
|
|
|
protected $formContentType = 'application/x-www-form-urlencoded';
|
|
|
|
/**
|
|
* @var BootstrapInterface
|
|
*/
|
|
protected $ui;
|
|
|
|
/**
|
|
* @var array|ConfigInterface
|
|
*/
|
|
protected $config;
|
|
|
|
protected $action;
|
|
|
|
protected $method = 'POST';
|
|
|
|
protected $title = 'FormBuilder';
|
|
|
|
protected $rule;
|
|
|
|
protected $formData = [];
|
|
|
|
protected $dependScript = [
|
|
'<script src="https://unpkg.com/jquery@3.3.1/dist/jquery.min.js"></script>',
|
|
'<script src="https://unpkg.com/vue@2.5.13/dist/vue.min.js"></script>',
|
|
'<script src="https://unpkg.com/@form-create/data@1.0.0/dist/province_city.js"></script>',
|
|
'<script src="https://unpkg.com/@form-create/data@1.0.0/dist/province_city_area.js"></script>'
|
|
];
|
|
|
|
protected $template;
|
|
|
|
/**
|
|
* Form constructor.
|
|
* @param BootstrapInterface $ui
|
|
* @param string $action
|
|
* @param array $rule
|
|
* @param array $config
|
|
* @throws FormBuilderException
|
|
*/
|
|
protected function __construct(BootstrapInterface $ui, $action = '', $rule = [], $config = [])
|
|
{
|
|
$this->action = $action;
|
|
$this->rule = $rule;
|
|
$this->config = $config;
|
|
$this->ui = $ui;
|
|
$ui->init($this);
|
|
$this->checkFieldUnique();
|
|
$this->template = dirname(__FILE__) . DIRECTORY_SEPARATOR . 'Template' . DIRECTORY_SEPARATOR . 'form.php';
|
|
}
|
|
|
|
/**
|
|
* @return string
|
|
*/
|
|
public function getFormContentType()
|
|
{
|
|
return $this->formContentType;
|
|
}
|
|
|
|
/**
|
|
* @param string $name
|
|
* @param string $value
|
|
* @return $this
|
|
*/
|
|
public function setHeader($name, $value)
|
|
{
|
|
$this->headers[$name] = (string)$value;
|
|
|
|
return $this;
|
|
}
|
|
|
|
/**
|
|
* @param array $headers
|
|
* @return $this
|
|
*/
|
|
public function headers(array $headers)
|
|
{
|
|
$this->headers = $headers;
|
|
|
|
return $this;
|
|
}
|
|
|
|
/**
|
|
* @param array $formData
|
|
* @return $this
|
|
*/
|
|
public function formData(array $formData)
|
|
{
|
|
$this->formData = $formData;
|
|
return $this;
|
|
}
|
|
|
|
/**
|
|
* @param $field
|
|
* @param $value
|
|
* @return $this
|
|
*/
|
|
public function setValue($field, $value)
|
|
{
|
|
$this->formData[$field] = $value;
|
|
return $this;
|
|
}
|
|
|
|
/**
|
|
* @return false|string
|
|
*/
|
|
public function parseHeaders()
|
|
{
|
|
return json_encode((object)$this->headers);
|
|
}
|
|
|
|
/**
|
|
* @param $formContentType
|
|
* @return $this
|
|
*/
|
|
public function setFormContentType($formContentType)
|
|
{
|
|
$this->formContentType = (string)$formContentType;
|
|
|
|
return $this;
|
|
}
|
|
|
|
public function setDependScript(array $dependScript)
|
|
{
|
|
$this->dependScript = $dependScript;
|
|
|
|
return $this;
|
|
}
|
|
|
|
/**
|
|
* @param string $title
|
|
* @return $this
|
|
*/
|
|
public function setTitle($title)
|
|
{
|
|
$this->title = (string)$title;
|
|
|
|
return $this;
|
|
}
|
|
|
|
/**
|
|
* @param string $method
|
|
* @return $this
|
|
*/
|
|
public function setMethod($method)
|
|
{
|
|
$this->method = (string)$method;
|
|
|
|
return $this;
|
|
}
|
|
|
|
/**
|
|
* @return string|null
|
|
*/
|
|
public function getTitle()
|
|
{
|
|
return $this->title;
|
|
}
|
|
|
|
/**
|
|
* @return string|null
|
|
*/
|
|
public function getMethod()
|
|
{
|
|
return $this->method;
|
|
}
|
|
|
|
/**
|
|
* @param array $rule
|
|
* @return $this
|
|
* @throws FormBuilderException
|
|
*/
|
|
public function setRule(array $rule)
|
|
{
|
|
$this->rule = $rule;
|
|
$this->checkFieldUnique();
|
|
return $this;
|
|
}
|
|
|
|
/**
|
|
* @param array|ConfigInterface $config
|
|
* @return $this
|
|
*/
|
|
public function setConfig($config)
|
|
{
|
|
if (is_array($config) || $config instanceof ConfigInterface)
|
|
$this->config = $config;
|
|
return $this;
|
|
}
|
|
|
|
/**
|
|
* 追加组件
|
|
*
|
|
* @param $component
|
|
* @return $this
|
|
* @throws FormBuilderException
|
|
*/
|
|
public function append($component)
|
|
{
|
|
$this->rule[] = $component;
|
|
$this->checkFieldUnique();
|
|
return $this;
|
|
}
|
|
|
|
/**
|
|
* 开头插入组件
|
|
*
|
|
* @param $component
|
|
* @return $this
|
|
* @throws FormBuilderException
|
|
*/
|
|
public function prepend($component)
|
|
{
|
|
array_unshift($this->rule, $component);
|
|
$this->checkFieldUnique();
|
|
return $this;
|
|
}
|
|
|
|
/**
|
|
* @param $action
|
|
* @return $this
|
|
*/
|
|
public function setAction($action)
|
|
{
|
|
$this->action = (string)$action;
|
|
return $this;
|
|
}
|
|
|
|
/**
|
|
* @return string
|
|
*/
|
|
public function getAction()
|
|
{
|
|
return $this->action;
|
|
}
|
|
|
|
/**
|
|
* 提交按钮显示状态
|
|
*
|
|
* @param $isShow
|
|
* @return $this
|
|
*/
|
|
public function showSubmitBtn($isShow)
|
|
{
|
|
if ($this->config instanceof ConfigInterface)
|
|
$this->config->submitBtn(!!$isShow);
|
|
else
|
|
$this->config['submitBtn'] = !!$isShow;
|
|
return $this;
|
|
}
|
|
|
|
/**
|
|
* 重置按钮显示状态
|
|
*
|
|
* @param $isShow
|
|
* @return $this
|
|
*/
|
|
public function showResetBtn($isShow)
|
|
{
|
|
if ($this->config instanceof ConfigInterface)
|
|
$this->config->resetBtn(!!$isShow);
|
|
else
|
|
$this->config['resetBtn'] = !!$isShow;
|
|
return $this;
|
|
}
|
|
|
|
/**
|
|
* 设置组件全局配置
|
|
* @param string $componentName
|
|
* @param array $config
|
|
* @return $this
|
|
*/
|
|
public function componentGlobalConfig($componentName, array $config)
|
|
{
|
|
if ($this->config instanceof ConfigInterface)
|
|
$this->config->componentGlobalConfig($componentName, $config);
|
|
else {
|
|
if (!isset($this->config['global'])) $this->config['global'] = [];
|
|
$this->config['global'][$componentName] = $config;
|
|
}
|
|
return $this;
|
|
}
|
|
|
|
protected function parseFormComponent($rule)
|
|
{
|
|
if (Util::isComponent($rule)) {
|
|
$rule = $rule->build();
|
|
} else {
|
|
if (isset($rule['children']) && is_array($rule['children'])) {
|
|
foreach ($rule['children'] as $i => $child) {
|
|
$rule['children'][$i] = $this->parseFormComponent($child);
|
|
}
|
|
}
|
|
if (isset($rule['control'])) {
|
|
foreach ($rule['control'] as $i => $child) {
|
|
foreach ($child['rule'] as $k => $rule) {
|
|
$child['rule'][$k] = Util::isComponent($rule) ? $rule->build() : $rule;
|
|
}
|
|
$rule['control'][$i] = $child;
|
|
}
|
|
}
|
|
}
|
|
return $rule;
|
|
}
|
|
|
|
public function getDependScript()
|
|
{
|
|
return $this->dependScript;
|
|
}
|
|
|
|
/**
|
|
* @param array $formData
|
|
* @param array $rule
|
|
* @return array
|
|
*/
|
|
protected function deepSetFormData($formData, $rule)
|
|
{
|
|
if (!count($formData)) return $rule;
|
|
foreach ($rule as $k => $item) {
|
|
if (is_array($item)) {
|
|
if (isset($item['field']) && isset($formData[$item['field']])) {
|
|
$item['value'] = $formData[$item['field']];
|
|
}
|
|
if (isset($item['children']) && is_array($item['children']) && count($item['children'])) {
|
|
$item['children'] = $this->deepSetFormData($formData, $item['children']);
|
|
}
|
|
if (isset($item['control']) && count($item['control'])) {
|
|
foreach ($item['control'] as $_k => $_rule) {
|
|
$item['control'][$_k]['rule'] = $this->deepSetFormData($formData, $_rule['rule']);
|
|
}
|
|
}
|
|
}
|
|
$rule[$k] = $item;
|
|
}
|
|
|
|
return $rule;
|
|
}
|
|
|
|
/**
|
|
* 获取表单生成规则
|
|
*
|
|
* @return array
|
|
*/
|
|
public function formRule()
|
|
{
|
|
$rules = [];
|
|
foreach ($this->rule as $rule) {
|
|
$rules[] = $this->parseFormComponent($rule);
|
|
}
|
|
return $this->deepSetFormData($this->formData, $rules);
|
|
}
|
|
|
|
/**
|
|
* @return false|string
|
|
*/
|
|
public function parseFormRule()
|
|
{
|
|
return json_encode($this->formRule());
|
|
}
|
|
|
|
/**
|
|
* @return false|string
|
|
*/
|
|
public function parseFormConfig()
|
|
{
|
|
return json_encode((object)$this->formConfig());
|
|
}
|
|
|
|
/**
|
|
* @return string
|
|
*/
|
|
public function parseDependScript()
|
|
{
|
|
return implode("\r\n", $this->dependScript);
|
|
}
|
|
|
|
/**
|
|
* 获取表单配置
|
|
*
|
|
* @return array
|
|
*/
|
|
public function formConfig()
|
|
{
|
|
$config = $this->config;
|
|
if ($config instanceof ConfigInterface) return $config->getConfig();
|
|
foreach ($config as $k => $v) {
|
|
$config[$k] = $this->parseFormComponent($v);
|
|
}
|
|
return $config;
|
|
}
|
|
|
|
|
|
/**
|
|
* 获取表单创建的 js 代码
|
|
*
|
|
* @return false|string
|
|
*/
|
|
public function formScript()
|
|
{
|
|
return $this->template(dirname(__FILE__) . DIRECTORY_SEPARATOR . 'Template' . DIRECTORY_SEPARATOR . 'createScript.min.php');
|
|
}
|
|
|
|
/**
|
|
* 获取表单视图
|
|
*
|
|
* @return string
|
|
*/
|
|
public function view()
|
|
{
|
|
return $this->template($this->template);
|
|
}
|
|
|
|
/**
|
|
* 自定义表单页面
|
|
*
|
|
* @param $templateDir
|
|
* @return false|string
|
|
*/
|
|
public function template($templateDir)
|
|
{
|
|
ob_start();
|
|
$form = $this;
|
|
require $templateDir;
|
|
$html = ob_get_clean();
|
|
return $html;
|
|
}
|
|
|
|
/**
|
|
* 设置模板
|
|
*
|
|
* @param string $templateDir
|
|
* @return $this
|
|
*/
|
|
public function setTemplate($templateDir)
|
|
{
|
|
$this->template = $templateDir;
|
|
return $this;
|
|
}
|
|
|
|
/**
|
|
* 检查field 是否重复
|
|
*
|
|
* @param null $rules
|
|
* @param array $fields
|
|
* @return array
|
|
* @throws FormBuilderException
|
|
*/
|
|
protected function checkFieldUnique($rules = null, $fields = [])
|
|
{
|
|
if (is_null($rules)) $rules = $this->rule;
|
|
|
|
foreach ($rules as $rule) {
|
|
$rule = $this->parseFormComponent($rule);
|
|
$field = isset($rule['field']) ? $rule['field'] : null;
|
|
|
|
if (isset($rule['children']) && count($rule['children']))
|
|
$fields = $this->checkFieldUnique($rule['children'], $fields);
|
|
|
|
if (is_null($field) || $field === '')
|
|
continue;
|
|
else if (isset($fields[$field]))
|
|
throw new FormBuilderException('组件的 field 不能重复');
|
|
else
|
|
$fields[$field] = true;
|
|
}
|
|
|
|
return $fields;
|
|
}
|
|
|
|
/**
|
|
* Iview 版表单生成器
|
|
*
|
|
* @param string $action
|
|
* @param array $rule
|
|
* @param array|ConfigInterface $config
|
|
* @return Form
|
|
* @throws FormBuilderException
|
|
*/
|
|
public static function iview($action = '', $rule = [], $config = [])
|
|
{
|
|
return new self(new IViewBootstrap(), $action, $rule, $config);
|
|
}
|
|
|
|
/**
|
|
* Iview v4 版表单生成器
|
|
*
|
|
* @param string $action
|
|
* @param array $rule
|
|
* @param array|ConfigInterface $config
|
|
* @return Form
|
|
* @throws FormBuilderException
|
|
*/
|
|
public static function iview4($action = '', $rule = [], $config = [])
|
|
{
|
|
return new self(new IViewBootstrap(4), $action, $rule, $config);
|
|
}
|
|
|
|
/**
|
|
* element-ui 版表单生成器
|
|
*
|
|
* @param string $action
|
|
* @param array $rule
|
|
* @param array|ConfigInterface $config
|
|
* @return Form
|
|
* @throws FormBuilderException
|
|
*/
|
|
public static function elm($action = '', $rule = [], $config = [])
|
|
{
|
|
return new self(new ElmBootstrap(), $action, $rule, $config);
|
|
}
|
|
} |