PageRenderTime 43ms CodeModel.GetById 15ms RepoModel.GetById 0ms app.codeStats 0ms

/lib/internal/Magento/Framework/Data/Form/Element/AbstractElement.php

https://gitlab.com/crazybutterfly815/magento2
PHP | 576 lines | 290 code | 54 blank | 232 comment | 35 complexity | 0f9e4d7f6dcc6dbd41345cd6eff7cdde MD5 | raw file
  1. <?php
  2. /**
  3. * Copyright © 2016 Magento. All rights reserved.
  4. * See COPYING.txt for license details.
  5. */
  6. namespace Magento\Framework\Data\Form\Element;
  7. use Magento\Framework\Data\Form;
  8. use Magento\Framework\Data\Form\AbstractForm;
  9. use Magento\Framework\Data\Form\Element\Renderer\RendererInterface;
  10. use Magento\Framework\Escaper;
  11. /**
  12. * Data form abstract class
  13. *
  14. * @author Magento Core Team <core@magentocommerce.com>
  15. * @SuppressWarnings(PHPMD.NumberOfChildren)
  16. */
  17. abstract class AbstractElement extends AbstractForm
  18. {
  19. /**
  20. * @var string|int
  21. */
  22. protected $_id;
  23. /**
  24. * @var string
  25. */
  26. protected $_type;
  27. /**
  28. * @var Form
  29. */
  30. protected $_form;
  31. /**
  32. * @var array
  33. */
  34. protected $_elements;
  35. /**
  36. * @var RendererInterface
  37. */
  38. protected $_renderer;
  39. /**
  40. * Shows whether current element belongs to Basic or Advanced form layout
  41. *
  42. * @var bool
  43. */
  44. protected $_advanced = false;
  45. /**
  46. * @var Escaper
  47. */
  48. protected $_escaper;
  49. /**
  50. * Lock html attribute
  51. *
  52. * @var string
  53. */
  54. private $lockHtmlAttribute = 'data-locked';
  55. /**
  56. * @param Factory $factoryElement
  57. * @param CollectionFactory $factoryCollection
  58. * @param Escaper $escaper
  59. * @param array $data
  60. */
  61. public function __construct(
  62. Factory $factoryElement,
  63. CollectionFactory $factoryCollection,
  64. Escaper $escaper,
  65. $data = []
  66. ) {
  67. $this->_escaper = $escaper;
  68. parent::__construct($factoryElement, $factoryCollection, $data);
  69. $this->_renderer = \Magento\Framework\Data\Form::getElementRenderer();
  70. }
  71. /**
  72. * Add form element
  73. *
  74. * @param AbstractElement $element
  75. * @param bool $after
  76. * @return Form
  77. */
  78. public function addElement(AbstractElement $element, $after = false)
  79. {
  80. if ($this->getForm()) {
  81. $this->getForm()->checkElementId($element->getId());
  82. $this->getForm()->addElementToCollection($element);
  83. }
  84. parent::addElement($element, $after);
  85. return $this;
  86. }
  87. /**
  88. * Shows whether current element belongs to Basic or Advanced form layout
  89. *
  90. * @return bool
  91. */
  92. public function isAdvanced()
  93. {
  94. return $this->_advanced;
  95. }
  96. /**
  97. * Set _advanced layout property
  98. *
  99. * @param bool $advanced
  100. * @return $this
  101. */
  102. public function setAdvanced($advanced)
  103. {
  104. $this->_advanced = $advanced;
  105. return $this;
  106. }
  107. /**
  108. * Get id.
  109. *
  110. * @return string|int
  111. */
  112. public function getId()
  113. {
  114. return $this->_id;
  115. }
  116. /**
  117. * Get type.
  118. *
  119. * @return string
  120. */
  121. public function getType()
  122. {
  123. return $this->_type;
  124. }
  125. /**
  126. * Get form
  127. *
  128. * @return Form
  129. */
  130. public function getForm()
  131. {
  132. return $this->_form;
  133. }
  134. /**
  135. * Set the Id.
  136. *
  137. * @param string|int $id
  138. * @return $this
  139. */
  140. public function setId($id)
  141. {
  142. $this->_id = $id;
  143. $this->setData('html_id', $id);
  144. return $this;
  145. }
  146. /**
  147. * Get the Html Id.
  148. *
  149. * @return string
  150. */
  151. public function getHtmlId()
  152. {
  153. return $this->getForm()->getHtmlIdPrefix() . $this->getData('html_id') . $this->getForm()->getHtmlIdSuffix();
  154. }
  155. /**
  156. * Get the name.
  157. *
  158. * @return mixed
  159. */
  160. public function getName()
  161. {
  162. $name = $this->getData('name');
  163. if ($suffix = $this->getForm()->getFieldNameSuffix()) {
  164. $name = $this->getForm()->addSuffixToName($name, $suffix);
  165. }
  166. return $name;
  167. }
  168. /**
  169. * Set the type.
  170. *
  171. * @param string $type
  172. * @return $this
  173. */
  174. public function setType($type)
  175. {
  176. $this->_type = $type;
  177. $this->setData('type', $type);
  178. return $this;
  179. }
  180. /**
  181. * @param AbstractForm $form
  182. * @return $this
  183. */
  184. public function setForm($form)
  185. {
  186. $this->_form = $form;
  187. return $this;
  188. }
  189. /**
  190. * Remove field
  191. *
  192. * @param string $elementId
  193. * @return AbstractForm
  194. */
  195. public function removeField($elementId)
  196. {
  197. $this->getForm()->removeField($elementId);
  198. return parent::removeField($elementId);
  199. }
  200. /**
  201. * Return the attributes for Html.
  202. *
  203. * @return string[]
  204. */
  205. public function getHtmlAttributes()
  206. {
  207. return [
  208. 'type',
  209. 'title',
  210. 'class',
  211. 'style',
  212. 'onclick',
  213. 'onchange',
  214. 'disabled',
  215. 'readonly',
  216. 'tabindex',
  217. 'placeholder',
  218. 'data-form-part',
  219. 'data-role',
  220. 'data-action',
  221. 'checked',
  222. ];
  223. }
  224. /**
  225. * Add a class.
  226. *
  227. * @param string $class
  228. * @return $this
  229. */
  230. public function addClass($class)
  231. {
  232. $oldClass = $this->getClass();
  233. $this->setClass($oldClass . ' ' . $class);
  234. return $this;
  235. }
  236. /**
  237. * Remove CSS class
  238. *
  239. * @param string $class
  240. * @return $this
  241. */
  242. public function removeClass($class)
  243. {
  244. $classes = array_unique(explode(' ', $this->getClass()));
  245. if (false !== ($key = array_search($class, $classes))) {
  246. unset($classes[$key]);
  247. }
  248. $this->setClass(implode(' ', $classes));
  249. return $this;
  250. }
  251. /**
  252. * Escape a string's contents.
  253. *
  254. * @param string $string
  255. * @return string
  256. */
  257. protected function _escape($string)
  258. {
  259. return htmlspecialchars($string, ENT_COMPAT);
  260. }
  261. /**
  262. * Return the escaped value of the element specified by the given index.
  263. *
  264. * @param null|int|string $index
  265. * @return string
  266. */
  267. public function getEscapedValue($index = null)
  268. {
  269. $value = $this->getValue($index);
  270. if ($filter = $this->getValueFilter()) {
  271. $value = $filter->filter($value);
  272. }
  273. return $this->_escape($value);
  274. }
  275. /**
  276. * Set the renderer.
  277. *
  278. * @param RendererInterface $renderer
  279. * @return $this
  280. */
  281. public function setRenderer(RendererInterface $renderer)
  282. {
  283. $this->_renderer = $renderer;
  284. return $this;
  285. }
  286. /**
  287. * Get the renderer.
  288. *
  289. * @return RendererInterface
  290. */
  291. public function getRenderer()
  292. {
  293. return $this->_renderer;
  294. }
  295. /**
  296. * @param null|string $suffix
  297. * @return string
  298. */
  299. protected function _getUiId($suffix = null)
  300. {
  301. if ($this->_renderer instanceof \Magento\Framework\View\Element\AbstractBlock) {
  302. return $this->_renderer->getUiId($this->getType(), $this->getName(), $suffix);
  303. } else {
  304. return ' data-ui-id="form-element-' . $this->getName() . ($suffix ?: '') . '"';
  305. }
  306. }
  307. /**
  308. * Get the Html for the element.
  309. *
  310. * @return string
  311. */
  312. public function getElementHtml()
  313. {
  314. $html = '';
  315. $htmlId = $this->getHtmlId();
  316. $beforeElementHtml = $this->getBeforeElementHtml();
  317. if ($beforeElementHtml) {
  318. $html .= '<label class="addbefore" for="' . $htmlId . '">' . $beforeElementHtml . '</label>';
  319. }
  320. $html .= '<input id="' . $htmlId . '" name="' . $this->getName() . '" ' . $this->_getUiId() . ' value="' .
  321. $this->getEscapedValue() . '" ' . $this->serialize($this->getHtmlAttributes()) . '/>';
  322. $afterElementJs = $this->getAfterElementJs();
  323. if ($afterElementJs) {
  324. $html .= $afterElementJs;
  325. }
  326. $afterElementHtml = $this->getAfterElementHtml();
  327. if ($afterElementHtml) {
  328. $html .= '<label class="addafter" for="' . $htmlId . '">' . $afterElementHtml . '</label>';
  329. }
  330. return $html;
  331. }
  332. /**
  333. * Get the before element html.
  334. *
  335. * @return mixed
  336. */
  337. public function getBeforeElementHtml()
  338. {
  339. return $this->getData('before_element_html');
  340. }
  341. /**
  342. * Get the after element html.
  343. *
  344. * @return mixed
  345. */
  346. public function getAfterElementHtml()
  347. {
  348. return $this->getData('after_element_html');
  349. }
  350. /**
  351. * Get the after element Javascript.
  352. *
  353. * @return mixed
  354. */
  355. public function getAfterElementJs()
  356. {
  357. return $this->getData('after_element_js');
  358. }
  359. /**
  360. * Render HTML for element's label
  361. *
  362. * @param string $idSuffix
  363. * @param string $scopeLabel
  364. * @return string
  365. */
  366. public function getLabelHtml($idSuffix = '', $scopeLabel = '')
  367. {
  368. $scopeLabel = $scopeLabel ? ' data-config-scope="' . $scopeLabel . '"' : '';
  369. if ($this->getLabel() !== null) {
  370. $html = '<label class="label admin__field-label" for="' .
  371. $this->getHtmlId() . $idSuffix . '"' . $this->_getUiId(
  372. 'label'
  373. ) . '><span' . $scopeLabel . '>' . $this->_escape(
  374. $this->getLabel()
  375. ) . '</span></label>' . "\n";
  376. } else {
  377. $html = '';
  378. }
  379. return $html;
  380. }
  381. /**
  382. * Get the default html.
  383. *
  384. * @return mixed
  385. */
  386. public function getDefaultHtml()
  387. {
  388. $html = $this->getData('default_html');
  389. if ($html === null) {
  390. $html = $this->getNoSpan() === true ? '' : '<div class="admin__field">' . "\n";
  391. $html .= $this->getLabelHtml();
  392. $html .= $this->getElementHtml();
  393. $html .= $this->getNoSpan() === true ? '' : '</div>' . "\n";
  394. }
  395. return $html;
  396. }
  397. /**
  398. * Get the html.
  399. *
  400. * @return mixed
  401. */
  402. public function getHtml()
  403. {
  404. if ($this->getRequired()) {
  405. $this->addClass('required-entry _required');
  406. }
  407. if ($this->_renderer) {
  408. $html = $this->_renderer->render($this);
  409. } else {
  410. $html = $this->getDefaultHtml();
  411. }
  412. return $html;
  413. }
  414. /**
  415. * Get the html.
  416. *
  417. * @return mixed
  418. */
  419. public function toHtml()
  420. {
  421. return $this->getHtml();
  422. }
  423. /**
  424. * Serialize the element.
  425. *
  426. * @param string[] $attributes
  427. * @param string $valueSeparator
  428. * @param string $fieldSeparator
  429. * @param string $quote
  430. * @return string
  431. */
  432. public function serialize($attributes = [], $valueSeparator = '=', $fieldSeparator = ' ', $quote = '"')
  433. {
  434. if ($this->isLocked() && !empty($attributes)) {
  435. $attributes[] = $this->lockHtmlAttribute;
  436. }
  437. if (in_array('disabled', $attributes) && !empty($this->_data['disabled'])) {
  438. $this->_data['disabled'] = 'disabled';
  439. } else {
  440. unset($this->_data['disabled']);
  441. }
  442. if (in_array('checked', $attributes) && !empty($this->_data['checked'])) {
  443. $this->_data['checked'] = 'checked';
  444. } else {
  445. unset($this->_data['checked']);
  446. }
  447. return parent::serialize($attributes, $valueSeparator, $fieldSeparator, $quote);
  448. }
  449. /**
  450. * Indicates the elements readonly status.
  451. *
  452. * @return mixed
  453. */
  454. public function getReadonly()
  455. {
  456. if ($this->hasData('readonly_disabled')) {
  457. return $this->_getData('readonly_disabled');
  458. }
  459. return $this->_getData('readonly');
  460. }
  461. /**
  462. * Get the container Id.
  463. *
  464. * @return mixed
  465. */
  466. public function getHtmlContainerId()
  467. {
  468. if ($this->hasData('container_id')) {
  469. return $this->getData('container_id');
  470. } elseif ($idPrefix = $this->getForm()->getFieldContainerIdPrefix()) {
  471. return $idPrefix . $this->getId();
  472. }
  473. return '';
  474. }
  475. /**
  476. * Add specified values to element values
  477. *
  478. * @param string|int|array $values
  479. * @param bool $overwrite
  480. * @return $this
  481. * @SuppressWarnings(PHPMD.CyclomaticComplexity)
  482. */
  483. public function addElementValues($values, $overwrite = false)
  484. {
  485. if (empty($values) || is_string($values) && trim($values) == '') {
  486. return $this;
  487. }
  488. if (!is_array($values)) {
  489. $values = $this->_escaper->escapeHtml(trim($values));
  490. $values = [$values => $values];
  491. }
  492. $elementValues = $this->getValues();
  493. if (!empty($elementValues)) {
  494. foreach ($values as $key => $value) {
  495. if (isset($elementValues[$key]) && $overwrite || !isset($elementValues[$key])) {
  496. $elementValues[$key] = $this->_escaper->escapeHtml($value);
  497. }
  498. }
  499. $values = $elementValues;
  500. }
  501. $this->setValues($values);
  502. return $this;
  503. }
  504. /**
  505. * Lock element
  506. *
  507. * @return void
  508. */
  509. public function lock()
  510. {
  511. $this->setData($this->lockHtmlAttribute, 1);
  512. }
  513. /**
  514. * Is element locked
  515. *
  516. * @return bool
  517. */
  518. public function isLocked()
  519. {
  520. return $this->getData($this->lockHtmlAttribute) == 1;
  521. }
  522. }