[ Index ]

PHP Cross Reference of Joomla 4.2.2 documentation

title

Body

[close]

/libraries/src/Toolbar/ -> ToolbarButton.php (source)

   1  <?php
   2  
   3  /**
   4   * Joomla! Content Management System
   5   *
   6   * @copyright  (C) 2006 Open Source Matters, Inc. <https://www.joomla.org>
   7   * @license    GNU General Public License version 2 or later; see LICENSE.txt
   8   */
   9  
  10  namespace Joomla\CMS\Toolbar;
  11  
  12  use Joomla\CMS\Language\Text;
  13  use Joomla\CMS\Layout\FileLayout;
  14  use Joomla\Utilities\ArrayHelper;
  15  
  16  // phpcs:disable PSR1.Files.SideEffects
  17  \defined('JPATH_PLATFORM') or die;
  18  // phpcs:enable PSR1.Files.SideEffects
  19  
  20  /**
  21   * The ToolbarButton class.
  22   *
  23   * @method self text(string $value)
  24   * @method self task(string $value)
  25   * @method self icon(string $value)
  26   * @method self buttonClass(string $value)
  27   * @method self attributes(array $value)
  28   * @method self onclick(array $value)
  29   * @method self listCheck(bool $value)
  30   * @method self listCheckMessage(string $value)
  31   * @method self form(string $value)
  32   * @method self formValidation(bool $value)
  33   * @method string  getText()
  34   * @method string  getTask()
  35   * @method string  getIcon()
  36   * @method string  getButtonClass()
  37   * @method array   getAttributes()
  38   * @method string  getOnclick()
  39   * @method bool    getListCheck()
  40   * @method string  getListCheckMessage()
  41   * @method string  getForm()
  42   * @method bool    getFormValidation()
  43   *
  44   * @since  4.0.0
  45   */
  46  abstract class ToolbarButton
  47  {
  48      /**
  49       * Name of this button.
  50       *
  51       * @var  string
  52       *
  53       * @since  4.0.0
  54       */
  55      protected $name;
  56  
  57      /**
  58       * Reference to the object that instantiated the element
  59       *
  60       * @var    Toolbar
  61       *
  62       * @since  4.0.0
  63       */
  64      protected $parent;
  65  
  66      /**
  67       * The layout path to render this button.
  68       *
  69       * @var  string
  70       *
  71       * @since  4.0.0
  72       */
  73      protected $layout;
  74  
  75      /**
  76       * Button options.
  77       *
  78       * @var  array
  79       *
  80       * @since  4.0.0
  81       */
  82      protected $options = [];
  83  
  84      /**
  85       * Used to track an ids, to avoid duplication
  86       *
  87       * @var    array
  88       *
  89       * @since  4.0.0
  90       */
  91      protected static $idCounter = [];
  92  
  93      /**
  94       * Init this class.
  95       *
  96       * @param   string  $name     Name of this button.
  97       * @param   string  $text     The button text, will auto translate.
  98       * @param   array   $options  Button options.
  99       *
 100       * @since  4.0.0
 101       *
 102       * @throws \InvalidArgumentException
 103       */
 104      public function __construct(string $name = '', string $text = '', array $options = [])
 105      {
 106          $this->name($name)
 107              ->text($text);
 108  
 109          $this->options = ArrayHelper::mergeRecursive($this->options, $options);
 110      }
 111  
 112      /**
 113       * Prepare options for this button.
 114       *
 115       * @param   array  &$options  The options about this button.
 116       *
 117       * @return  void
 118       *
 119       * @since  4.0.0
 120       */
 121      protected function prepareOptions(array &$options)
 122      {
 123          $options['name']  = $this->getName();
 124          $options['text']  = Text::_($this->getText());
 125          $options['class'] = $this->getIcon() ?: $this->fetchIconClass($this->getName());
 126          $options['id']    = $this->ensureUniqueId($this->fetchId());
 127  
 128          if (!empty($options['is_child'])) {
 129              $options['tagName'] = 'button';
 130              $options['btnClass'] = ($options['button_class'] ?? '') . ' dropdown-item';
 131              $options['attributes']['type'] = 'button';
 132  
 133              if ($options['is_first_child']) {
 134                  $options['btnClass'] .= ' first';
 135              }
 136  
 137              if ($options['is_last_child']) {
 138                  $options['btnClass'] .= ' last';
 139              }
 140          } else {
 141              $options['tagName'] = 'button';
 142              $options['btnClass'] = ($options['button_class'] ?? 'btn btn-primary');
 143              $options['attributes']['type'] = 'button';
 144          }
 145      }
 146  
 147      /**
 148       * Get the HTML to render the button
 149       *
 150       * @param   array  &$definition  Parameters to be passed
 151       *
 152       * @return  string
 153       *
 154       * @since   3.0
 155       *
 156       * @throws \Exception
 157       */
 158      public function render(&$definition = null)
 159      {
 160          if ($definition === null) {
 161              $action = $this->renderButton($this->options);
 162          } elseif (\is_array($definition)) {
 163              // For B/C
 164              $action = $this->fetchButton(...$definition);
 165          } else {
 166              throw new \InvalidArgumentException('Wrong argument: $definition, should be NULL or array.');
 167          }
 168  
 169          // Build the HTML Button
 170          $layout = new FileLayout('joomla.toolbar.base');
 171  
 172          return $layout->render(
 173              [
 174                  'action' => $action,
 175                  'options' => $this->options
 176              ]
 177          );
 178      }
 179  
 180      /**
 181       * Render button HTML.
 182       *
 183       * @param   array  &$options  The button options.
 184       *
 185       * @return  string  The button HTML.
 186       *
 187       * @since   4.0.0
 188       */
 189      protected function renderButton(array &$options): string
 190      {
 191          $this->prepareOptions($options);
 192  
 193          // Prepare custom attributes.
 194          unset(
 195              $options['attributes']['id'],
 196              $options['attributes']['class']
 197          );
 198  
 199          $options['htmlAttributes'] = ArrayHelper::toString($options['attributes']);
 200  
 201          // Isolate button class from icon class
 202          $buttonClass = str_replace('icon-', '', $this->getName());
 203          $iconclass = $options['btnClass'] ?? '';
 204          $options['btnClass'] = 'button-' . $buttonClass . ' ' . $iconclass;
 205  
 206          // Instantiate a new LayoutFile instance and render the layout
 207          $layout = new FileLayout($this->layout);
 208  
 209          return $layout->render($options);
 210      }
 211  
 212      /**
 213       * Get the button CSS Id.
 214       *
 215       * @return  string  Button CSS Id
 216       *
 217       * @since   3.0
 218       */
 219      protected function fetchId()
 220      {
 221          return $this->parent->getName() . '-' . str_ireplace(' ', '-', $this->getName());
 222      }
 223  
 224      /**
 225       * Method to get the CSS class name for an icon identifier
 226       *
 227       * Can be redefined in the final class
 228       *
 229       * @param   string  $identifier  Icon identification string
 230       *
 231       * @return  string  CSS class name
 232       *
 233       * @since   3.0
 234       */
 235      public function fetchIconClass($identifier)
 236      {
 237          // It's an ugly hack, but this allows templates to define the icon classes for the toolbar
 238          $layout = new FileLayout('joomla.toolbar.iconclass');
 239  
 240          return $layout->render(array('icon' => $identifier));
 241      }
 242  
 243      /**
 244       * Get the button
 245       *
 246       * Defined in the final button class
 247       *
 248       * @return  string
 249       *
 250       * @since   3.0
 251       *
 252       * @deprecated  5.0 Use render() instead.
 253       */
 254      abstract public function fetchButton();
 255  
 256      /**
 257       * Get parent toolbar instance.
 258       *
 259       * @return  Toolbar
 260       *
 261       * @since   4.0.0
 262       */
 263      public function getParent(): Toolbar
 264      {
 265          return $this->parent;
 266      }
 267  
 268      /**
 269       * Set parent Toolbar instance.
 270       *
 271       * @param   Toolbar  $parent  The parent Toolbar instance to set.
 272       *
 273       * @return  static  Return self to support chaining.
 274       *
 275       * @since   4.0.0
 276       */
 277      public function setParent(Toolbar $parent): self
 278      {
 279          $this->parent = $parent;
 280  
 281          return $this;
 282      }
 283  
 284      /**
 285       * Get button options.
 286       *
 287       * @return  array
 288       *
 289       * @since  4.0.0
 290       */
 291      public function getOptions(): array
 292      {
 293          return $this->options;
 294      }
 295  
 296      /**
 297       * Set all options.
 298       *
 299       * @param   array  $options  The button options.
 300       *
 301       * @return  static  Return self to support chaining.
 302       *
 303       * @since  4.0.0
 304       */
 305      public function setOptions(array $options): self
 306      {
 307          $this->options = $options;
 308  
 309          return $this;
 310      }
 311  
 312      /**
 313       * Get single option value.
 314       *
 315       * @param   string  $name     The option name.
 316       * @param   mixed   $default  The default value if this name not exists.
 317       *
 318       * @return  mixed
 319       *
 320       * @since  4.0.0
 321       */
 322      public function getOption(string $name, $default = null)
 323      {
 324          return $this->options[$name] ?? $default;
 325      }
 326  
 327      /**
 328       * Set option value.
 329       *
 330       * @param   string  $name   The option name to store value.
 331       * @param   mixed   $value  The option value.
 332       *
 333       * @return  static
 334       *
 335       * @since  4.0.0
 336       */
 337      public function setOption(string $name, $value): self
 338      {
 339          $this->options[$name] = $value;
 340  
 341          return $this;
 342      }
 343  
 344      /**
 345       * Get button name.
 346       *
 347       * @return  string
 348       *
 349       * @since  4.0.0
 350       */
 351      public function getName(): string
 352      {
 353          return $this->name;
 354      }
 355  
 356      /**
 357       * Set button name.
 358       *
 359       * @param   string  $name  The button name.
 360       *
 361       * @return  static  Return self to support chaining.
 362       *
 363       * @since  4.0.0
 364       */
 365      public function name(string $name): self
 366      {
 367          $this->name = $name;
 368  
 369          return $this;
 370      }
 371  
 372      /**
 373       * Get layout path.
 374       *
 375       * @return  string
 376       *
 377       * @since  4.0.0
 378       */
 379      public function getLayout(): string
 380      {
 381          return $this->layout;
 382      }
 383  
 384      /**
 385       * Set layout path.
 386       *
 387       * @param   string  $layout  The layout path name to render.
 388       *
 389       * @return  static  Return self to support chaining.
 390       *
 391       * @since  4.0.0
 392       */
 393      public function layout(string $layout): self
 394      {
 395          $this->layout = $layout;
 396  
 397          return $this;
 398      }
 399  
 400      /**
 401       * Make sure the id is unique
 402       *
 403       * @param   string  $id  The id string.
 404       *
 405       * @return  string
 406       *
 407       * @since   4.0.0
 408       */
 409      protected function ensureUniqueId(string $id): string
 410      {
 411          if (\array_key_exists($id, static::$idCounter)) {
 412              static::$idCounter[$id]++;
 413  
 414              $id .= static::$idCounter[$id];
 415          } else {
 416              static::$idCounter[$id] = 0;
 417          }
 418  
 419          return $id;
 420      }
 421  
 422      /**
 423       * Magiix method to adapt option accessors.
 424       *
 425       * @param   string  $name  The method name.
 426       * @param   array   $args  The method arguments.
 427       *
 428       * @return  mixed
 429       *
 430       * @throws \LogicException
 431       *
 432       * @since  4.0.0
 433       */
 434      public function __call(string $name, array $args)
 435      {
 436          // Getter
 437          if (stripos($name, 'get') === 0) {
 438              $fieldName = static::findOptionName(lcfirst(substr($name, 3)));
 439  
 440              if ($fieldName !== false) {
 441                  return $this->getOption($fieldName);
 442              }
 443          } else {
 444              // Setter
 445              $fieldName = static::findOptionName($name);
 446  
 447              if ($fieldName !== false) {
 448                  if (!\array_key_exists(0, $args)) {
 449                      throw new \InvalidArgumentException(
 450                          sprintf(
 451                              '%s::%s() miss first argument.',
 452                              \get_called_class(),
 453                              $name
 454                          )
 455                      );
 456                  }
 457  
 458                  return $this->setOption($fieldName, $args[0]);
 459              }
 460          }
 461  
 462          throw new \BadMethodCallException(
 463              sprintf(
 464                  'Method %s() not found in class: %s',
 465                  $name,
 466                  \get_called_class()
 467              )
 468          );
 469      }
 470  
 471      /**
 472       * Find field option name from accessors.
 473       *
 474       * @param   string  $name  The field name.
 475       *
 476       * @return  boolean|string
 477       *
 478       * @since  4.0.0
 479       */
 480      private static function findOptionName(string $name)
 481      {
 482          $accessors = static::getAccessors();
 483  
 484          if (\in_array($name, $accessors, true)) {
 485              return $accessors[array_search($name, $accessors, true)];
 486          }
 487  
 488          // Getter with alias
 489          if (isset($accessors[$name])) {
 490              return $accessors[$name];
 491          }
 492  
 493          return false;
 494      }
 495  
 496      /**
 497       * Method to configure available option accessors.
 498       *
 499       * @return  array
 500       *
 501       * @since  4.0.0
 502       */
 503      protected static function getAccessors(): array
 504      {
 505          return [
 506              'text',
 507              'task',
 508              'icon',
 509              'attributes',
 510              'onclick',
 511              'buttonClass' => 'button_class',
 512              'listCheck',
 513              'listCheckMessage',
 514              'form',
 515              'formValidation',
 516          ];
 517      }
 518  }


Generated: Wed Sep 7 05:41:13 2022 Chilli.vc Blog - For Webmaster,Blog-Writer,System Admin and Domainer