Form.php 9.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450
  1. <?php
  2. /**
  3. * PHP表单生成器
  4. *
  5. * @package FormBuilder
  6. * @author xaboy <xaboy2005@qq.com>
  7. * @version 2.0
  8. * @license MIT
  9. * @link https://github.com/xaboy/form-builder
  10. */
  11. namespace FormBuilder;
  12. use FormBuilder\Contract\BootstrapInterface;
  13. use FormBuilder\Contract\ConfigInterface;
  14. use FormBuilder\Exception\FormBuilderException;
  15. use FormBuilder\UI\Iview\Bootstrap as IViewBootstrap;
  16. use FormBuilder\UI\Elm\Bootstrap as ElmBootstrap;
  17. class Form
  18. {
  19. protected $headers = [];
  20. protected $formContentType = 'application/x-www-form-urlencoded';
  21. /**
  22. * @var BootstrapInterface
  23. */
  24. protected $ui;
  25. /**
  26. * @var array|ConfigInterface
  27. */
  28. protected $config;
  29. protected $action;
  30. protected $method = 'POST';
  31. protected $title = 'FormBuilder';
  32. protected $rule;
  33. protected $formData = [];
  34. protected $dependScript = [
  35. '<script src="https://unpkg.com/jquery@3.3.1/dist/jquery.min.js"></script>',
  36. '<script src="https://unpkg.com/vue@2.5.13/dist/vue.min.js"></script>',
  37. '<script src="https://unpkg.com/@form-create/data@1.0.0/dist/province_city.js"></script>',
  38. '<script src="https://unpkg.com/@form-create/data@1.0.0/dist/province_city_area.js"></script>'
  39. ];
  40. /**
  41. * Form constructor.
  42. * @param BootstrapInterface $ui
  43. * @param string $action
  44. * @param array $rule
  45. * @param array $config
  46. * @throws FormBuilderException
  47. */
  48. protected function __construct(BootstrapInterface $ui, $action = '', $rule = [], $config = [])
  49. {
  50. $this->action = $action;
  51. $this->rule = $rule;
  52. $this->config = $config;
  53. $this->ui = $ui;
  54. $ui->init($this);
  55. $this->checkFieldUnique();
  56. }
  57. /**
  58. * @return string
  59. */
  60. public function getFormContentType()
  61. {
  62. return $this->formContentType;
  63. }
  64. /**
  65. * @param string $name
  66. * @param string $value
  67. * @return $this
  68. */
  69. public function setHeader($name, $value)
  70. {
  71. $this->headers[$name] = (string)$value;
  72. return $this;
  73. }
  74. /**
  75. * @param array $headers
  76. * @return $this
  77. */
  78. public function headers(array $headers)
  79. {
  80. $this->headers = $headers;
  81. return $this;
  82. }
  83. /**
  84. * @param array $formData
  85. * @return $this
  86. */
  87. public function formData(array $formData)
  88. {
  89. $this->formData = $formData;
  90. return $this;
  91. }
  92. /**
  93. * @param $field
  94. * @param $value
  95. * @return $this
  96. */
  97. public function setValue($field, $value)
  98. {
  99. $this->formData[$field] = $value;
  100. return $this;
  101. }
  102. /**
  103. * @return false|string
  104. */
  105. public function parseHeaders()
  106. {
  107. return json_encode((object)$this->headers);
  108. }
  109. /**
  110. * @param $formContentType
  111. * @return $this
  112. */
  113. public function setFormContentType($formContentType)
  114. {
  115. $this->formContentType = (string)$formContentType;
  116. return $this;
  117. }
  118. public function setDependScript(array $dependScript)
  119. {
  120. $this->dependScript = $dependScript;
  121. return $this;
  122. }
  123. /**
  124. * @param string $title
  125. * @return $this
  126. */
  127. public function setTitle($title)
  128. {
  129. $this->title = (string)$title;
  130. return $this;
  131. }
  132. /**
  133. * @param string $method
  134. * @return $this
  135. */
  136. public function setMethod($method)
  137. {
  138. $this->method = (string)$method;
  139. return $this;
  140. }
  141. /**
  142. * @return string|null
  143. */
  144. public function getTitle()
  145. {
  146. return $this->title;
  147. }
  148. /**
  149. * @return string|null
  150. */
  151. public function getMethod()
  152. {
  153. return $this->method;
  154. }
  155. /**
  156. * @param array $rule
  157. * @return $this
  158. * @throws FormBuilderException
  159. */
  160. public function setRule(array $rule)
  161. {
  162. $this->rule = $rule;
  163. $this->checkFieldUnique();
  164. return $this;
  165. }
  166. /**
  167. * @param array|ConfigInterface $config
  168. * @return $this
  169. */
  170. public function setConfig($config)
  171. {
  172. if (is_array($config) || $config instanceof ConfigInterface)
  173. $this->config = $config;
  174. return $this;
  175. }
  176. /**
  177. * 追加组件
  178. *
  179. * @param $component
  180. * @return $this
  181. * @throws FormBuilderException
  182. */
  183. public function append($component)
  184. {
  185. $this->rule[] = $component;
  186. $this->checkFieldUnique();
  187. return $this;
  188. }
  189. /**
  190. * 开头插入组件
  191. *
  192. * @param $component
  193. * @return $this
  194. * @throws FormBuilderException
  195. */
  196. public function prepend($component)
  197. {
  198. array_unshift($this->rule, $component);
  199. $this->checkFieldUnique();
  200. return $this;
  201. }
  202. /**
  203. * @param $action
  204. * @return $this
  205. */
  206. public function setAction($action)
  207. {
  208. $this->action = (string)$action;
  209. return $this;
  210. }
  211. /**
  212. * @return string
  213. */
  214. public function getAction()
  215. {
  216. return $this->action;
  217. }
  218. /**
  219. * 提交按钮显示状态
  220. *
  221. * @param $isShow
  222. * @return $this
  223. */
  224. public function showSubmitBtn($isShow)
  225. {
  226. if ($this->config instanceof ConfigInterface)
  227. $this->config->submitBtn(!!$isShow);
  228. else
  229. $this->config['submitBtn'] = !!$isShow;
  230. return $this;
  231. }
  232. /**
  233. * 重置按钮显示状态
  234. *
  235. * @param $isShow
  236. * @return $this
  237. */
  238. public function showResetBtn($isShow)
  239. {
  240. if ($this->config instanceof ConfigInterface)
  241. $this->config->resetBtn(!!$isShow);
  242. else
  243. $this->config['resetBtn'] = !!$isShow;
  244. return $this;
  245. }
  246. protected function parseFormComponent($rule)
  247. {
  248. if (Util::isComponent($rule)) {
  249. $rule = $rule->build();
  250. }
  251. return $rule;
  252. }
  253. public function getDependScript()
  254. {
  255. return $this->dependScript;
  256. }
  257. /**
  258. * 获取表单生成规则
  259. *
  260. * @return array
  261. */
  262. public function formRule()
  263. {
  264. $rules = [];
  265. foreach ($this->rule as $rule) {
  266. $rule = $this->parseFormComponent($rule);
  267. if (isset($rule['field']) && isset($this->formData[$rule['field']])) {
  268. $rule['value'] = $this->formData[$rule['field']];
  269. }
  270. $rules[] = $rule;
  271. }
  272. return $rules;
  273. }
  274. /**
  275. * @return false|string
  276. */
  277. public function parseFormRule()
  278. {
  279. return json_encode($this->formRule());
  280. }
  281. /**
  282. * @return false|string
  283. */
  284. public function parseFormConfig()
  285. {
  286. return json_encode((object)$this->formConfig());
  287. }
  288. /**
  289. * @return string
  290. */
  291. public function parseDependScript()
  292. {
  293. return implode("\r\n", $this->dependScript);
  294. }
  295. /**
  296. * 获取表单配置
  297. *
  298. * @return array
  299. */
  300. public function formConfig()
  301. {
  302. $config = $this->config;
  303. if ($config instanceof ConfigInterface) return $config->getConfig();
  304. foreach ($config as $k => $v) {
  305. $config[$k] = $this->parseFormComponent($v);
  306. }
  307. return $config;
  308. }
  309. /**
  310. * 获取表单创建的 js 代码
  311. *
  312. * @return false|string
  313. */
  314. public function formScript()
  315. {
  316. return $this->template(dirname(__FILE__) . DIRECTORY_SEPARATOR . 'Template' . DIRECTORY_SEPARATOR . 'createScript.min.php');
  317. }
  318. /**
  319. * 获取表单视图
  320. *
  321. * @return string
  322. */
  323. public function view()
  324. {
  325. return $this->template(dirname(__FILE__) . DIRECTORY_SEPARATOR . 'Template' . DIRECTORY_SEPARATOR . 'form.php');
  326. }
  327. /**
  328. * 自定义表单页面
  329. *
  330. * @param $templateDir
  331. * @return false|string
  332. */
  333. public function template($templateDir)
  334. {
  335. ob_start();
  336. $form = $this;
  337. require $templateDir;
  338. $html = ob_get_clean();
  339. return $html;
  340. }
  341. /**
  342. * 检查field 是否重复
  343. *
  344. * @param null $rules
  345. * @param array $fields
  346. * @return array
  347. * @throws FormBuilderException
  348. */
  349. protected function checkFieldUnique($rules = null, $fields = [])
  350. {
  351. if (is_null($rules)) $rules = $this->rule;
  352. foreach ($rules as $rule) {
  353. $rule = $this->parseFormComponent($rule);
  354. $field = isset($rule['field']) ? $rule['field'] : null;
  355. if (isset($rule['children']) && count($rule['children']))
  356. $fields = $this->checkFieldUnique($rule['children'], $fields);
  357. if (is_null($field) || $field === '')
  358. continue;
  359. else if (isset($fields[$field]))
  360. throw new FormBuilderException('组件的 field 不能重复');
  361. else
  362. $fields[$field] = true;
  363. }
  364. return $fields;
  365. }
  366. /**
  367. * Iview 版表单生成器
  368. *
  369. * @param string $action
  370. * @param array $rule
  371. * @param array|ConfigInterface $config
  372. * @return Form
  373. * @throws FormBuilderException
  374. */
  375. public static function iview($action = '', $rule = [], $config = [])
  376. {
  377. return new self(new IViewBootstrap(), $action, $rule, $config);
  378. }
  379. /**
  380. * element-ui 版表单生成器
  381. *
  382. * @param string $action
  383. * @param array $rule
  384. * @param array|ConfigInterface $config
  385. * @return Form
  386. * @throws FormBuilderException
  387. */
  388. public static function elm($action = '', $rule = [], $config = [])
  389. {
  390. return new self(new ElmBootstrap(), $action, $rule, $config);
  391. }
  392. }