SplitButton.php 6.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238
  1. <?php
  2. /**
  3. * Copyright © Magento, Inc. All rights reserved.
  4. * See COPYING.txt for license details.
  5. */
  6. namespace Magento\Backend\Block\Widget\Button;
  7. /**
  8. * Split button widget
  9. *
  10. * @method array getOptions()
  11. * @method string getButtonClass()
  12. * @method string getClass()
  13. * @method string getLabel()
  14. * @method string getTitle()
  15. * @method bool getDisabled()
  16. * @method string getStyle()
  17. * @method array getDataAttribute()
  18. * @api
  19. * @since 100.0.2
  20. */
  21. class SplitButton extends \Magento\Backend\Block\Widget
  22. {
  23. /**
  24. * Define block template
  25. *
  26. * @return void
  27. */
  28. protected function _construct()
  29. {
  30. if (!$this->hasTemplate()) {
  31. $this->setTemplate('Magento_Backend::widget/button/split.phtml');
  32. }
  33. parent::_construct();
  34. }
  35. /**
  36. * Retrieve <div> wrapper attributes html
  37. *
  38. * @return string
  39. */
  40. public function getAttributesHtml()
  41. {
  42. $title = $this->getTitle();
  43. if (!$title) {
  44. $title = $this->getLabel();
  45. }
  46. $classes = [];
  47. if ($this->hasSplit()) {
  48. $classes[] = 'actions-split';
  49. }
  50. //@TODO Perhaps use $this->getClass() instead
  51. if ($this->getButtonClass()) {
  52. $classes[] = $this->getButtonClass();
  53. }
  54. $attributes = ['id' => $this->getId(), 'title' => $title, 'class' => join(' ', $classes)];
  55. $html = $this->_getAttributesString($attributes);
  56. return $html;
  57. }
  58. /**
  59. * Retrieve button attributes html
  60. *
  61. * @return string
  62. */
  63. public function getButtonAttributesHtml()
  64. {
  65. $disabled = $this->getDisabled() ? 'disabled' : '';
  66. $title = $this->getTitle();
  67. if (!$title) {
  68. $title = $this->getLabel();
  69. }
  70. $classes = [];
  71. $classes[] = 'action-default';
  72. $classes[] = 'primary';
  73. // @TODO Perhaps use $this->getButtonClass() instead
  74. if ($this->getClass()) {
  75. $classes[] = $this->getClass();
  76. }
  77. if ($disabled) {
  78. $classes[] = $disabled;
  79. }
  80. $attributes = [
  81. 'id' => $this->getId() . '-button',
  82. 'title' => $title,
  83. 'class' => join(' ', $classes),
  84. 'disabled' => $disabled,
  85. 'style' => $this->getStyle(),
  86. ];
  87. //TODO perhaps we need to skip data-mage-init when disabled="disabled"
  88. if ($this->getDataAttribute()) {
  89. $this->_getDataAttributes($this->getDataAttribute(), $attributes);
  90. }
  91. $html = $this->_getAttributesString($attributes);
  92. $html .= $this->getUiId();
  93. return $html;
  94. }
  95. /**
  96. * Retrieve toggle button attributes html
  97. *
  98. * @return string
  99. */
  100. public function getToggleAttributesHtml()
  101. {
  102. $disabled = $this->getDisabled() ? 'disabled' : '';
  103. $title = $this->getTitle();
  104. if (!$title) {
  105. $title = $this->getLabel();
  106. }
  107. $classes = [];
  108. $classes[] = 'action-toggle';
  109. $classes[] = 'primary';
  110. if ($this->getClass()) {
  111. $classes[] = $this->getClass();
  112. }
  113. if ($disabled) {
  114. $classes[] = $disabled;
  115. }
  116. $attributes = ['title' => $title, 'class' => join(' ', $classes), 'disabled' => $disabled];
  117. $this->_getDataAttributes(['mage-init' => '{"dropdown": {}}', 'toggle' => 'dropdown'], $attributes);
  118. $html = $this->_getAttributesString($attributes);
  119. $html .= $this->getUiId('dropdown');
  120. return $html;
  121. }
  122. /**
  123. * Retrieve options attributes html
  124. *
  125. * @param string $key
  126. * @param array $option
  127. * @return string
  128. * @SuppressWarnings(PHPMD.NPathComplexity)
  129. */
  130. public function getOptionAttributesHtml($key, $option)
  131. {
  132. $disabled = isset($option['disabled']) && $option['disabled'] ? 'disabled' : '';
  133. if (isset($option['title'])) {
  134. $title = $option['title'];
  135. } else {
  136. $title = $option['label'];
  137. }
  138. $classes = [];
  139. $classes[] = 'item';
  140. if (!empty($option['default'])) {
  141. $classes[] = 'item-default';
  142. }
  143. if ($disabled) {
  144. $classes[] = $disabled;
  145. }
  146. $attributes = $this->_prepareOptionAttributes($option, $title, $classes, $disabled);
  147. $html = $this->_getAttributesString($attributes);
  148. $html .= $this->getUiId(isset($option['id']) ? $option['id'] : 'item' . '-' . $key);
  149. return $html;
  150. }
  151. /**
  152. * Checks if the button needs actions-split functionality
  153. *
  154. * If this function returns false then split button will be rendered as simple button
  155. *
  156. * @return bool
  157. */
  158. public function hasSplit()
  159. {
  160. return $this->hasData('has_split') ? (bool)$this->getData('has_split') : true;
  161. }
  162. /**
  163. * Add data attributes to $attributes array
  164. *
  165. * @param array $data
  166. * @param array &$attributes
  167. * @return void
  168. */
  169. protected function _getDataAttributes($data, &$attributes)
  170. {
  171. foreach ($data as $key => $attr) {
  172. $attributes['data-' . $key] = is_scalar($attr) ? $attr : json_encode($attr);
  173. }
  174. }
  175. /**
  176. * Prepare option attributes
  177. *
  178. * @param array $option
  179. * @param string $title
  180. * @param string $classes
  181. * @param string $disabled
  182. * @return array
  183. * @SuppressWarnings(PHPMD.NPathComplexity)
  184. */
  185. protected function _prepareOptionAttributes($option, $title, $classes, $disabled)
  186. {
  187. $attributes = [
  188. 'id' => isset($option['id']) ? $this->getId() . '-' . $option['id'] : '',
  189. 'title' => $title,
  190. 'class' => join(' ', $classes),
  191. 'onclick' => isset($option['onclick']) ? $option['onclick'] : '',
  192. 'style' => isset($option['style']) ? $option['style'] : '',
  193. 'disabled' => $disabled,
  194. ];
  195. if (isset($option['data_attribute'])) {
  196. $this->_getDataAttributes($option['data_attribute'], $attributes);
  197. }
  198. return $attributes;
  199. }
  200. /**
  201. * Render attributes array as attributes string
  202. *
  203. * @param array $attributes
  204. * @return string
  205. */
  206. protected function _getAttributesString($attributes)
  207. {
  208. $html = [];
  209. foreach ($attributes as $attributeKey => $attributeValue) {
  210. if ($attributeValue === null || $attributeValue == '') {
  211. continue;
  212. }
  213. $html[] = $attributeKey . '="' . $this->escapeHtmlAttr($attributeValue, false) . '"';
  214. }
  215. return join(' ', $html);
  216. }
  217. }