Form.php 7.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346
  1. <?php
  2. /**
  3. * Copyright © Magento, Inc. All rights reserved.
  4. * See COPYING.txt for license details.
  5. */
  6. namespace Magento\Framework\Data;
  7. use Magento\Framework\Data\Form\Element\AbstractElement;
  8. use Magento\Framework\Data\Form\Element\Collection as ElementCollection;
  9. use Magento\Framework\Data\Form\Element\CollectionFactory as ElementCollectionFactory;
  10. use Magento\Framework\Data\Form\Element\Factory;
  11. use Magento\Framework\Data\Form\Element\Renderer\RendererInterface;
  12. use Magento\Framework\Data\Form\FormKey;
  13. use Magento\Framework\Profiler;
  14. /**
  15. * @api
  16. * @since 100.0.2
  17. */
  18. class Form extends \Magento\Framework\Data\Form\AbstractForm
  19. {
  20. /**
  21. * All form elements collection
  22. *
  23. * @var ElementCollection
  24. */
  25. protected $_allElements;
  26. /**
  27. * form elements index
  28. *
  29. * @var array
  30. */
  31. protected $_elementsIndex;
  32. /**
  33. * @var FormKey
  34. */
  35. protected $formKey;
  36. /**
  37. * @var RendererInterface
  38. */
  39. protected static $_defaultElementRenderer;
  40. /**
  41. * @var RendererInterface
  42. */
  43. protected static $_defaultFieldsetRenderer;
  44. /**
  45. * @var RendererInterface
  46. */
  47. protected static $_defaultFieldsetElementRenderer;
  48. /**
  49. * @param Factory $factoryElement
  50. * @param ElementCollectionFactory $factoryCollection
  51. * @param FormKey $formKey
  52. * @param array $data
  53. */
  54. public function __construct(
  55. Factory $factoryElement,
  56. ElementCollectionFactory $factoryCollection,
  57. FormKey $formKey,
  58. $data = []
  59. ) {
  60. parent::__construct($factoryElement, $factoryCollection, $data);
  61. $this->_allElements = $this->_factoryCollection->create(['container' => $this]);
  62. $this->formKey = $formKey;
  63. }
  64. /**
  65. * @param RendererInterface $renderer
  66. * @return void
  67. */
  68. public static function setElementRenderer(RendererInterface $renderer = null)
  69. {
  70. self::$_defaultElementRenderer = $renderer;
  71. }
  72. /**
  73. * @param RendererInterface $renderer
  74. * @return void
  75. */
  76. public static function setFieldsetRenderer(RendererInterface $renderer = null)
  77. {
  78. self::$_defaultFieldsetRenderer = $renderer;
  79. }
  80. /**
  81. * @param RendererInterface $renderer
  82. * @return void
  83. */
  84. public static function setFieldsetElementRenderer(RendererInterface $renderer = null)
  85. {
  86. self::$_defaultFieldsetElementRenderer = $renderer;
  87. }
  88. /**
  89. * @return RendererInterface
  90. */
  91. public static function getElementRenderer()
  92. {
  93. return self::$_defaultElementRenderer;
  94. }
  95. /**
  96. * @return RendererInterface
  97. */
  98. public static function getFieldsetRenderer()
  99. {
  100. return self::$_defaultFieldsetRenderer;
  101. }
  102. /**
  103. * @return RendererInterface
  104. */
  105. public static function getFieldsetElementRenderer()
  106. {
  107. return self::$_defaultFieldsetElementRenderer;
  108. }
  109. /**
  110. * Return allowed HTML form attributes
  111. *
  112. * @return string[]
  113. */
  114. public function getHtmlAttributes()
  115. {
  116. return ['id', 'name', 'method', 'action', 'enctype', 'class', 'onsubmit', 'target'];
  117. }
  118. /**
  119. * Add form element
  120. *
  121. * @param AbstractElement $element
  122. * @param bool $after
  123. * @return $this
  124. */
  125. public function addElement(AbstractElement $element, $after = false)
  126. {
  127. $this->checkElementId($element->getId());
  128. parent::addElement($element, $after);
  129. $this->addElementToCollection($element);
  130. return $this;
  131. }
  132. /**
  133. * Check existing element
  134. *
  135. * @param string $elementId
  136. * @return bool
  137. */
  138. protected function _elementIdExists($elementId)
  139. {
  140. return isset($this->_elementsIndex[$elementId]);
  141. }
  142. /**
  143. * @param AbstractElement $element
  144. * @return $this
  145. */
  146. public function addElementToCollection($element)
  147. {
  148. $this->_elementsIndex[$element->getId()] = $element;
  149. $this->_allElements->add($element);
  150. return $this;
  151. }
  152. /**
  153. * @param string $elementId
  154. * @return bool
  155. * @throws \Exception
  156. */
  157. public function checkElementId($elementId)
  158. {
  159. if ($this->_elementIdExists($elementId)) {
  160. throw new \InvalidArgumentException(
  161. 'An element with a "' . $elementId . '" ID already exists.'
  162. );
  163. }
  164. return true;
  165. }
  166. /**
  167. * @return $this
  168. */
  169. public function getForm()
  170. {
  171. return $this;
  172. }
  173. /**
  174. * Retrieve form element by id
  175. *
  176. * @param string $elementId
  177. * @return null|AbstractElement
  178. */
  179. public function getElement($elementId)
  180. {
  181. if ($this->_elementIdExists($elementId)) {
  182. return $this->_elementsIndex[$elementId];
  183. }
  184. return null;
  185. }
  186. /**
  187. * @param array $values
  188. * @return $this
  189. */
  190. public function setValues($values)
  191. {
  192. foreach ($this->_allElements as $element) {
  193. if (isset($values[$element->getId()])) {
  194. $element->setValue($values[$element->getId()]);
  195. } else {
  196. $element->setValue(null);
  197. }
  198. }
  199. return $this;
  200. }
  201. /**
  202. * @param array $values
  203. * @return $this
  204. */
  205. public function addValues($values)
  206. {
  207. if (!is_array($values)) {
  208. return $this;
  209. }
  210. foreach ($values as $elementId => $value) {
  211. $element = $this->getElement($elementId);
  212. if ($element) {
  213. $element->setValue($value);
  214. }
  215. }
  216. return $this;
  217. }
  218. /**
  219. * Add suffix to name of all elements
  220. *
  221. * @param string $suffix
  222. * @return $this
  223. */
  224. public function addFieldNameSuffix($suffix)
  225. {
  226. foreach ($this->_allElements as $element) {
  227. $name = $element->getName();
  228. if ($name) {
  229. $element->setName($this->addSuffixToName($name, $suffix));
  230. }
  231. }
  232. return $this;
  233. }
  234. /**
  235. * @param string $name
  236. * @param string $suffix
  237. * @return string
  238. */
  239. public function addSuffixToName($name, $suffix)
  240. {
  241. if (!$name) {
  242. return $suffix;
  243. }
  244. $vars = explode('[', $name);
  245. $newName = $suffix;
  246. foreach ($vars as $index => $value) {
  247. $newName .= '[' . $value;
  248. if ($index == 0) {
  249. $newName .= ']';
  250. }
  251. }
  252. return $newName;
  253. }
  254. /**
  255. * @param string $elementId
  256. * @return $this
  257. */
  258. public function removeField($elementId)
  259. {
  260. if ($this->_elementIdExists($elementId)) {
  261. unset($this->_elementsIndex[$elementId]);
  262. }
  263. return $this;
  264. }
  265. /**
  266. * @param string $prefix
  267. * @return $this
  268. */
  269. public function setFieldContainerIdPrefix($prefix)
  270. {
  271. $this->setData('field_container_id_prefix', $prefix);
  272. return $this;
  273. }
  274. /**
  275. * @return string
  276. */
  277. public function getFieldContainerIdPrefix()
  278. {
  279. return $this->getData('field_container_id_prefix');
  280. }
  281. /**
  282. * @return string
  283. */
  284. public function toHtml()
  285. {
  286. Profiler::start('form/toHtml');
  287. $html = '';
  288. $useContainer = $this->getUseContainer();
  289. if ($useContainer) {
  290. $html .= '<form ' . $this->serialize($this->getHtmlAttributes()) . '>';
  291. $html .= '<div>';
  292. if (strtolower($this->getData('method')) == 'post') {
  293. $html .= '<input name="form_key" type="hidden" value="' . $this->formKey->getFormKey() . '" />';
  294. }
  295. $html .= '</div>';
  296. }
  297. foreach ($this->getElements() as $element) {
  298. $html .= $element->toHtml();
  299. }
  300. if ($useContainer) {
  301. $html .= '</form>';
  302. }
  303. Profiler::stop('form/toHtml');
  304. return $html;
  305. }
  306. /**
  307. * @return string
  308. */
  309. public function getHtml()
  310. {
  311. return $this->toHtml();
  312. }
  313. }