Current Path : /var/www/www-root/data/www.catalog.monolith-realty.ru/bitrix/modules/ui/lib/buttons/ |
Current File : /var/www/www-root/data/www.catalog.monolith-realty.ru/bitrix/modules/ui/lib/buttons/basebutton.php |
<?php namespace Bitrix\UI\Buttons; use Bitrix\Main\ArgumentException; use Bitrix\Main\Localization\Loc; use Bitrix\Main\Security\Random; use Bitrix\Main\UI\Extension; use Bitrix\UI\Contract; //We know about lazy load. So, the code loads common messages for default buttons, //which implemented by subclasses of BaseButton. Loc::loadLanguageFile(__FILE__); class BaseButton implements Contract\Renderable { const UNIQ_ID_DATA_ATTR = 'btn-uniqid'; const JSON_OPTIONS_DATA_ATTR = 'json-options'; /** @var string */ protected $id; /** @var string */ protected $text; /** @var string */ protected $tag = Tag::BUTTON; /** @var string */ protected $baseClass = "ui-btn"; /** @var string */ protected $link; /** @var integer|string */ protected $counter; /** @var array */ protected $events = []; /** @var ButtonAttributes */ private $attributes; final public function __construct(array $params = []) { $this->attributes = new ButtonAttributes(); $this->attributes->addDataAttribute(self::UNIQ_ID_DATA_ATTR, $this->generateUniqid()); $this->addClass($this->getBaseClass()); $this->init($params); } /** * @return array */ protected function getDefaultParameters() { return []; } protected function init(array $params = []) { $this->buildFromArray(array_merge( $this->getDefaultParameters(), $params )); } final public static function create(array $params = []) { return new static($params); } protected function buildFromArray($params) { if (isset($params['text'])) { $this->setText($params['text']); } if (!empty($params['styles'])) { $this->setStyles($params['styles']); } if (!empty($params['maxWidth'])) { $this->setMaxWidth($params['maxWidth']); } if (!empty($params['className']) && is_string($params['className'])) { $params['classList'] = array_filter(explode(' ', $params['className'])); } if (empty($params['classList'])) { $params['classList'] = []; } $params['classList'] = array_merge( [$this->getBaseClass()], $params['classList'] ); $this->getAttributeCollection()->setClassList($params['classList']); if (!empty($params['counter'])) { $this->setCounter($params['counter']); } if (!empty($params['id'])) { $this->setId($params['id']); } if (!empty($params['tag'])) { $this->setTag($params['tag']); } if (!empty($params['link'])) { $this->setLink($params['link']); } if (!empty($params['click'])) { $this->bindEvent('click', $params['click']); } if (!empty($params['onclick'])) { $this->bindEvent('click', $params['onclick']); } if (!empty($params['events'])) { $this->bindEvents($params['events']); } if (isset($params['dataset']) && is_array($params['dataset'])) { foreach ($params['dataset'] as $name => $value) { $this->addDataAttribute($name, $value); } } } protected function listExtensions() { return []; } public static function getJsClass() { return 'BX.UI.' . (new \ReflectionClass(get_called_class()))->getShortName(); } protected function appendDefaultJsonOption(ButtonAttributes $attributes) { if (count($this->getEvents()) > 0) { $attributes->addJsonOption('events', $this->getEvents()); } return $attributes; } public function render($jsInit = true) { Extension::load($this->listExtensions()); $output = ''; $tagName = $this->getTag(); $attributes = clone $this->getAttributeCollection(); $this->appendDefaultJsonOption($attributes); switch ($tagName) { case Tag::LINK: case Tag::BUTTON: if ($tagName === Tag::LINK && $this->getLink()) { $attributes['href'] = $this->getLink(); } $inner = $this->renderInner(); $output = "<{$tagName} {$attributes}>{$inner}</{$tagName}>"; break; case Tag::INPUT: case Tag::SUBMIT: $attributes['value'] = htmlspecialcharsbx($this->getText()); $attributes['type'] = Tag::BUTTON; if ($tagName === Tag::SUBMIT) { $tagName = Tag::INPUT; $attributes['type'] = Tag::SUBMIT; } $output = "<{$tagName} {$attributes}/>"; break; } if ($jsInit) { $js = $this->renderJavascript(); if ($js) { $output .= "<script>BX.ready(function(){ {$js} });</script>"; } } return $output; } protected function generateUniqid() { return 'uibtn-' . Random::getString(8); } public function isInputTag() { return $this->isInputType(); } public function isInputType() { return in_array($this->tag, [ Tag::INPUT, Tag::SUBMIT, ], true); } protected function renderInner() { $counter = $this->getCounter(); return ( (!empty($this->getText()) ? '<span class="ui-btn-text">'.htmlspecialcharsbx($this->getText()).'</span>' : ''). ($counter !== null ? '<span class="ui-btn-counter">'.htmlspecialcharsbx($counter).'</span>' : '' ) ); } protected function renderJavascript() { $selector = $this->getQuerySelector(); return "BX.UI.ButtonManager.createFromNode(document.querySelector('{$selector}'));"; } protected function getQuerySelector() { $tag = $this->getTag(); $uniqId = $this->getUniqId(); $uniqIdName = "data-" . self::UNIQ_ID_DATA_ATTR; return "{$tag}[{$uniqIdName}=\"{$uniqId}\"]"; } public function getUniqId() { return $this->getAttributeCollection()->getDataAttribute(self::UNIQ_ID_DATA_ATTR); } public function getId() { return $this->id; } public function setId($id) { $this->id = $id; return $this; } public function getMaxWidth() { return isset($this->getAttributeCollection()['style']['max-width'])? $this->getAttributeCollection()['style']['max-width'] : null; } public function setMaxWidth($width) { if (!isset($this->getAttributeCollection()['style'])) { $this->getAttributeCollection()['style'] = []; } $this->getAttributeCollection()['style']['max-width'] = $width; return $this; } public function getLink() { return $this->link; } public function setLink($link) { if (is_string($link) && !empty($link)) { $this->link = $link; $this->setTag(Tag::LINK); } return $this; } public function getCounter() { return $this->counter; } public function setCounter($counter) { if (in_array($counter, [0, '0', '', null, false], true)) { $this->counter = null; } else if ((is_int($counter) && $counter > 0) || (is_string($counter) && mb_strlen($counter))) { $this->counter = $counter; } return $this; } public function addClass($className) { $this->getAttributeCollection()->addClass($className); return $this; } public function unsetClass($className) { $this->getAttributeCollection()->removeClass($className); return $this; } public function removeClass($className) { return $this->unsetClass($className); } public function hasClass($className) { return $this->getAttributeCollection()->hasClass($className); } public function getClassList() { return $this->getAttributeCollection()['class']?: []; } public function addAttribute($name, $value = null) { if (mb_strtolower($name) === 'class') { throw new ArgumentException('Could not add "class" attribute. You should use ::addClass()', 'class'); } $this->getAttributeCollection()[$name] = $value; return $this; } public function unsetAttribute($name) { unset($this->getAttributeCollection()[$name]); return $this; } public function removeAttribute($name) { return $this->unsetAttribute($name); } public function getAttribute($name, $defaultValue = null) { return $this->getAttributeCollection()->getAttribute($name, $defaultValue); } public function addDataAttribute($name, $value = null) { $this->getAttributeCollection()->addDataAttribute($name, $value); return $this; } public function getDataAttribute($name, $defaultValue = null) { return $this->getAttributeCollection()->getDataAttribute($name, $defaultValue); } public function setDataRole($dataRole) { $this->addDataAttribute('role', $dataRole); return $this; } public function getDataRole() { return $this->getDataAttribute('role'); } public function setStyles(array $styles) { $this->getAttributeCollection()['style'] = $styles; } public function getStyles() { return $this->getAttributeCollection()['style']; } /** * @return ButtonAttributes */ public function getAttributeCollection() { return $this->attributes; } /** * @return string */ public function getText() { return $this->text; } /** * @param string $text * * @return static */ public function setText($text) { $this->text = $text; return $this; } /** * @return string */ public function getTag() { return $this->tag; } /** * @param string $tag * * @return static */ public function setTag($tag) { $this->tag = $tag; return $this; } /** * @return string */ public function getBaseClass() { return $this->baseClass; } /** * @param bool $flag * @return static */ public function setDisabled($flag = true) { if ($flag === false) { unset($this->getAttributeCollection()['disabled']); } else { $this->getAttributeCollection()['disabled'] = true; } return $this; } /** * @return bool */ public function isDisabled() { return $this->getAttributeCollection()['disabled'] === true; } /** * @return array */ public function getEvents() { return $this->events; } /** * @param string $eventName * @param string|JsHandler $fn Link to js function which will be invoked. * @see in js BX.UI.BaseButton.handleEvent to know order of arguments in event handler. * * @return $this */ public function bindEvent($eventName, $fn) { if (is_string($fn)) { $fn = new JsHandler($fn); } $this->events[$eventName] = $fn; return $this; } /** * @param array $events * * @return $this */ public function bindEvents(array $events) { foreach ($events as $name => $fn) { $this->bindEvent($name, $fn); } return $this; } /** * @param string $eventName * * @return $this */ public function unbindEvent($eventName) { unset($this->events[$eventName]); return $this; } /** * @return $this */ public function unbindEvents() { unset($this->events); return $this; } }