Current File : /home/pacjaorg/public_html/kmm/libraries/src/Toolbar/Toolbar.php |
<?php
/**
* Joomla! Content Management System
*
* @copyright (C) 2006 Open Source Matters, Inc. <https://www.joomla.org>
* @license GNU General Public License version 2 or later; see LICENSE.txt
*/
namespace Joomla\CMS\Toolbar;
use Joomla\CMS\Factory;
use Joomla\CMS\Language\Text;
use Joomla\CMS\Layout\FileLayout;
use Joomla\CMS\Log\Log;
use Joomla\CMS\Toolbar\Button\BasicButton;
use Joomla\CMS\Toolbar\Button\ConfirmButton;
use Joomla\CMS\Toolbar\Button\CustomButton;
use Joomla\CMS\Toolbar\Button\DropdownButton;
use Joomla\CMS\Toolbar\Button\HelpButton;
use Joomla\CMS\Toolbar\Button\InlinehelpButton;
use Joomla\CMS\Toolbar\Button\LinkButton;
use Joomla\CMS\Toolbar\Button\PopupButton;
use Joomla\CMS\Toolbar\Button\SeparatorButton;
use Joomla\CMS\Toolbar\Button\StandardButton;
// phpcs:disable PSR1.Files.SideEffects
\defined('JPATH_PLATFORM') or die;
// phpcs:enable PSR1.Files.SideEffects
/**
* ToolBar handler
*
* @method StandardButton standardButton(string $name = '', string $text = '', string $task = '')
* @method SeparatorButton separatorButton(string $name = '', string $text = '', string $task = '')
* @method PopupButton popupButton(string $name = '', string $text = '', string $task = '')
* @method LinkButton linkButton(string $name = '', string $text = '', string $task = '')
* @method HelpButton helpButton(string $name = '', string $text = '', string $task = '')
* @method InlinehelpButton inlinehelpButton(string $name = '', string $text = '', string $task = '')
* @method CustomButton customButton(string $name = '', string $text = '', string $task = '')
* @method ConfirmButton confirmButton(string $name = '', string $text = '', string $task = '')
* @method BasicButton basicButton(string $name = '', string $text = '', string $task = '')
* @method DropdownButton dropdownButton(string $name = '', string $text = '', string $task = '')
*
* @since 1.5
*/
class Toolbar
{
use CoreButtonsTrait;
/**
* Toolbar name
*
* @var string
* @since 1.5
*/
protected $_name = '';
/**
* Toolbar array
*
* @var array
* @since 1.5
*/
protected $_bar = [];
/**
* Directories, where button types can be stored.
*
* @var array
* @since 1.5
*/
protected $_buttonPath = [];
/**
* Stores the singleton instances of various toolbar.
*
* @var Toolbar[]
* @since 2.5
*/
protected static $instances = [];
/**
* Factory for creating Toolbar API objects
*
* @var ToolbarFactoryInterface
* @since 4.0.0
*/
protected $factory;
/**
* Constructor
*
* @param string $name The toolbar name.
* @param ToolbarFactoryInterface $factory The toolbar factory.
*
* @since 1.5
*/
public function __construct($name = 'toolbar', ToolbarFactoryInterface $factory = null)
{
$this->_name = $name;
// At 5.0, require the factory to be injected
if (!$factory) {
@trigger_error(
sprintf(
'As of Joomla! 5.0, a %1$s must be provided to a %2$s object when creating it.',
ToolbarFactoryInterface::class,
\get_class($this)
),
E_USER_DEPRECATED
);
$factory = new ContainerAwareToolbarFactory();
$factory->setContainer(Factory::getContainer());
}
$this->setFactory($factory);
// Set base path to find buttons.
$this->_buttonPath[] = __DIR__ . '/Button';
}
/**
* Returns the global Toolbar object, only creating it if it doesn't already exist.
*
* @param string $name The name of the toolbar.
*
* @return Toolbar The Toolbar object.
*
* @since 1.5
*
* @deprecated 4.0 will be removed in 6.0
* Use the ToolbarFactoryInterface instead
* Example:
* Factory::getContainer()->get(ToolbarFactoryInterface::class)->createToolbar($name)
*
* @todo Needs a proper replacement before removal as ToolbarFactoryInterface alone does not share the object everywhere
*
* @throws \Joomla\DI\Exception\KeyNotFoundException
*/
public static function getInstance($name = 'toolbar')
{
if (empty(self::$instances[$name])) {
self::$instances[$name] = Factory::getContainer()->get(ToolbarFactoryInterface::class)->createToolbar($name);
}
return self::$instances[$name];
}
/**
* Set the factory instance
*
* @param ToolbarFactoryInterface $factory The factory instance
*
* @return $this
*
* @since 4.0.0
*/
public function setFactory(ToolbarFactoryInterface $factory): self
{
$this->factory = $factory;
return $this;
}
/**
* Append a button to toolbar.
*
* @param ToolbarButton $button The button instance.
* @param array $args The more arguments.
*
* @return ToolbarButton|boolean Return button instance to help chaining configure. If using legacy arguments
* returns true
*
* @since 1.5
*/
public function appendButton($button, ...$args)
{
if ($button instanceof ToolbarButton) {
$button->setParent($this);
$this->_bar[] = $button;
return $button;
}
// B/C
array_unshift($args, $button);
$this->_bar[] = $args;
@trigger_error(
sprintf(
'%s::appendButton() should only accept %s instance in Joomla 5.0.',
static::class,
ToolbarButton::class
),
E_USER_DEPRECATED
);
return true;
}
/**
* Get the list of toolbar links.
*
* @return array
*
* @since 1.6
*/
public function getItems()
{
return $this->_bar;
}
/**
* Set the button list.
*
* @param ToolbarButton[] $items The button list array.
*
* @return static
*
* @since 4.0.0
*/
public function setItems(array $items): self
{
$this->_bar = $items;
return $this;
}
/**
* Get the name of the toolbar.
*
* @return string
*
* @since 1.6
*/
public function getName()
{
return $this->_name;
}
/**
* Prepend a button to toolbar.
*
* @param ToolbarButton $button The button instance.
* @param array $args The more arguments.
*
* @return ToolbarButton|boolean Return button instance to help chaining configure. If using legacy arguments
* returns true
*
* @since 1.5
*/
public function prependButton($button, ...$args)
{
if ($button instanceof ToolbarButton) {
$button->setParent($this);
array_unshift($this->_bar, $button);
return $button;
}
// B/C
array_unshift($args, $button);
array_unshift($this->_bar, $args);
@trigger_error(
sprintf(
'%s::prependButton() should only accept %s instance in Joomla 5.0.',
static::class,
ToolbarButton::class
),
E_USER_DEPRECATED
);
return true;
}
/**
* Render a toolbar.
*
* @param array $options The options of toolbar.
*
* @return string HTML for the toolbar.
*
* @throws \Exception
* @since 1.5
*/
public function render(array $options = [])
{
$html = [];
$isChild = !empty($options['is_child']);
// Start toolbar div.
if (!$isChild) {
$layout = new FileLayout('joomla.toolbar.containeropen');
$html[] = $layout->render(['id' => $this->_name]);
}
$len = count($this->_bar);
// Render each button in the toolbar.
foreach ($this->_bar as $i => $button) {
if ($button instanceof ToolbarButton) {
// Child dropdown only support new syntax
$button->setOption('is_child', $isChild);
$button->setOption('is_first_child', $i === 0);
$button->setOption('is_last_child', $i === $len - 1);
$html[] = $button->render();
} else {
// B/C
$html[] = $this->renderButton($button);
}
}
// End toolbar div.
if (!$isChild) {
$layout = new FileLayout('joomla.toolbar.containerclose');
$html[] = $layout->render([]);
}
return implode('', $html);
}
/**
* Render a button.
*
* @param array &$node A toolbar node.
*
* @return string
*
* @since 1.5
* @throws \Exception
*/
public function renderButton(&$node)
{
// Get the button type.
$type = $node[0];
$button = $this->loadButtonType($type);
// Check for error.
if ($button === false) {
throw new \UnexpectedValueException(Text::sprintf('JLIB_HTML_BUTTON_NOT_DEFINED', $type));
}
$button->setParent($this);
return $button->render($node);
}
/**
* Loads a button type.
*
* @param string $type Button Type
* @param boolean $new False by default
*
* @return false|ToolbarButton
*
* @since 1.5
*/
public function loadButtonType($type, $new = false)
{
// For B/C, catch the exceptions thrown by the factory
try {
return $this->factory->createButton($this, $type);
} catch (\InvalidArgumentException $e) {
Log::add($e->getMessage(), Log::WARNING, 'jerror');
return false;
}
}
/**
* Add a directory where Toolbar should search for button types in LIFO order.
*
* You may either pass a string or an array of directories.
*
* Toolbar will be searching for an element type in the same order you
* added them. If the parameter type cannot be found in the custom folders,
* it will look in libraries/joomla/html/toolbar/button.
*
* @param mixed $path Directory or directories to search.
*
* @return void
*
* @since 1.5
*
* @deprecated 4.0 will be removed in 6.0
* ToolbarButton classes should be autoloaded via namespaces
*/
public function addButtonPath($path)
{
@trigger_error(
sprintf(
'Registering lookup paths for toolbar buttons is deprecated and will be removed in Joomla 5.0.'
. ' %1$s objects should be autoloaded or a custom %2$s implementation supporting path lookups provided.',
ToolbarButton::class,
ToolbarFactoryInterface::class
),
E_USER_DEPRECATED
);
// Loop through the path directories.
foreach ((array) $path as $dir) {
// No surrounding spaces allowed!
$dir = trim($dir);
// Add trailing separators as needed.
if (substr($dir, -1) !== DIRECTORY_SEPARATOR) {
// Directory
$dir .= DIRECTORY_SEPARATOR;
}
// Add to the top of the search dirs.
array_unshift($this->_buttonPath, $dir);
}
}
/**
* Get the lookup paths for button objects
*
* @return array
*
* @since 4.0.0
* @deprecated 4.0 will be removed in 6.0
* ToolbarButton buttons should be autoloaded via namespaces
*/
public function getButtonPath(): array
{
@trigger_error(
sprintf(
'Lookup paths for %s objects is deprecated and will be removed in Joomla 5.0.',
ToolbarButton::class
),
E_USER_DEPRECATED
);
return $this->_buttonPath;
}
/**
* Create child toolbar.
*
* @param string $name The toolbar name.
*
* @return static
*
* @since 4.0.0
*/
public function createChild($name): self
{
return new static($name, $this->factory);
}
/**
* Magic method proxy.
*
* @param string $name The method name.
* @param array $args The method arguments.
*
* @return ToolbarButton
*
* @throws \Exception
*
* @since 4.0.0
*/
public function __call($name, $args)
{
if (strtolower(substr($name, -6)) === 'button') {
$type = substr($name, 0, -6);
$button = $this->factory->createButton($this, $type);
$button->name($args[0] ?? '')
->text($args[1] ?? '')
->task($args[2] ?? '');
return $this->appendButton($button);
}
throw new \BadMethodCallException(
sprintf(
'Method %s() not found in class: %s',
$name,
static::class
)
);
}
}