[ Index ] |
PHP Cross Reference of Joomla 4.2.2 documentation |
[Summary view] [Print] [Text view]
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 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
Generated: Wed Sep 7 05:41:13 2022 | Chilli.vc Blog - For Webmaster,Blog-Writer,System Admin and Domainer |