497 lines
		
	
	
		
			11 KiB
		
	
	
	
		
			PHP
		
	
	
	
	
	
			
		
		
	
	
			497 lines
		
	
	
		
			11 KiB
		
	
	
	
		
			PHP
		
	
	
	
	
	
| <?php
 | ||
| /**
 | ||
|  * @package   FOF
 | ||
|  * @copyright Copyright (c)2010-2021 Nicholas K. Dionysopoulos / Akeeba Ltd
 | ||
|  * @license   GNU General Public License version 2, or later
 | ||
|  */
 | ||
| 
 | ||
| namespace FOF30\Render;
 | ||
| 
 | ||
| defined('_JEXEC') || die;
 | ||
| 
 | ||
| use FOF30\Container\Container;
 | ||
| use FOF30\Toolbar\Toolbar;
 | ||
| use JHtmlSidebar;
 | ||
| use Joomla\CMS\Factory as JoomlaFactory;
 | ||
| use Joomla\CMS\HTML\HTMLHelper;
 | ||
| use Joomla\CMS\Toolbar\Toolbar as JoomlaToolbar;
 | ||
| 
 | ||
| /**
 | ||
|  * Renderer class for use with Joomla! 3.x and 4.x
 | ||
|  *
 | ||
|  * Renderer options
 | ||
|  *
 | ||
|  * wrapper_id              The ID of the wrapper DIV. Default: akeeba-renderjoomla
 | ||
|  * linkbar_style           Style for linkbars: joomla3|classic. Default: joomla3
 | ||
|  * remove_wrapper_classes  Comma-separated list of classes to REMOVE from the container
 | ||
|  * add_wrapper_classes     Comma-separated list of classes to ADD to the container
 | ||
|  *
 | ||
|  * @package FOF30\Render
 | ||
|  * @since   3.6.0
 | ||
|  */
 | ||
| class Joomla extends RenderBase implements RenderInterface
 | ||
| {
 | ||
| 	/** @inheritDoc */
 | ||
| 	public function __construct(Container $container)
 | ||
| 	{
 | ||
| 		$this->priority = 30;
 | ||
| 		$this->enabled  = true;
 | ||
| 
 | ||
| 		parent::__construct($container);
 | ||
| 	}
 | ||
| 
 | ||
| 	/**
 | ||
| 	 * Echoes any HTML to show before the view template
 | ||
| 	 *
 | ||
| 	 * @param   string  $view  The current view
 | ||
| 	 * @param   string  $task  The current task
 | ||
| 	 *
 | ||
| 	 * @return  void
 | ||
| 	 */
 | ||
| 	function preRender(string $view, string $task): void
 | ||
| 	{
 | ||
| 		$input    = $this->container->input;
 | ||
| 		$platform = $this->container->platform;
 | ||
| 
 | ||
| 		$format = $input->getCmd('format', 'html');
 | ||
| 
 | ||
| 		if (empty($format))
 | ||
| 		{
 | ||
| 			$format = 'html';
 | ||
| 		}
 | ||
| 
 | ||
| 		if ($format != 'html')
 | ||
| 		{
 | ||
| 			return;
 | ||
| 		}
 | ||
| 
 | ||
| 		if ($platform->isCli())
 | ||
| 		{
 | ||
| 			return;
 | ||
| 		}
 | ||
| 
 | ||
| 		HTMLHelper::_('behavior.core');
 | ||
| 		HTMLHelper::_('jquery.framework', true);
 | ||
| 
 | ||
| 		// Wrap output in various classes
 | ||
| 		$versionParts = explode('.', JVERSION);
 | ||
| 		$minorVersion = $versionParts[0] . $versionParts[1];
 | ||
| 		$majorVersion = $versionParts[0];
 | ||
| 
 | ||
| 		$classes = [];
 | ||
| 
 | ||
| 		if ($platform->isBackend())
 | ||
| 		{
 | ||
| 			$area            = $platform->isBackend() ? 'admin' : 'site';
 | ||
| 			$option          = $input->getCmd('option', '');
 | ||
| 			$viewForCssClass = $input->getCmd('view', '');
 | ||
| 			$layout          = $input->getCmd('layout', '');
 | ||
| 			$taskForCssClass = $input->getCmd('task', '');
 | ||
| 
 | ||
| 			$classes = [
 | ||
| 				'joomla-version-' . $majorVersion,
 | ||
| 				'joomla-version-' . $minorVersion,
 | ||
| 				$area,
 | ||
| 				$option,
 | ||
| 				'view-' . $view,
 | ||
| 				'view-' . $viewForCssClass,
 | ||
| 				'layout-' . $layout,
 | ||
| 				'task-' . $task,
 | ||
| 				'task-' . $taskForCssClass,
 | ||
| 				// We have a floating sidebar, they said. It looks great, they said. They must've been blind, I say!
 | ||
| 				'j-toggle-main',
 | ||
| 				'j-toggle-transition',
 | ||
| 				'row-fluid',
 | ||
| 			];
 | ||
| 
 | ||
| 			$classes = array_unique($classes);
 | ||
| 		}
 | ||
| 
 | ||
| 		$this->openPageWrapper($classes);
 | ||
| 
 | ||
| 		// Render the submenu and toolbar
 | ||
| 		if ($input->getBool('render_toolbar', true))
 | ||
| 		{
 | ||
| 			$this->renderButtons($view, $task);
 | ||
| 			$this->renderLinkbar($view, $task);
 | ||
| 		}
 | ||
| 
 | ||
| 		parent::preRender($view, $task);
 | ||
| 	}
 | ||
| 
 | ||
| 	/**
 | ||
| 	 * Echoes any HTML to show after the view template
 | ||
| 	 *
 | ||
| 	 * @param   string  $view  The current view
 | ||
| 	 * @param   string  $task  The current task
 | ||
| 	 *
 | ||
| 	 * @return  void
 | ||
| 	 */
 | ||
| 	function postRender(string $view, string $task): void
 | ||
| 	{
 | ||
| 		$input    = $this->container->input;
 | ||
| 		$platform = $this->container->platform;
 | ||
| 
 | ||
| 		$format = $input->getCmd('format', 'html');
 | ||
| 
 | ||
| 		if (empty($format))
 | ||
| 		{
 | ||
| 			$format = 'html';
 | ||
| 		}
 | ||
| 
 | ||
| 		if ($format != 'html')
 | ||
| 		{
 | ||
| 			return;
 | ||
| 		}
 | ||
| 
 | ||
| 		// Closing tag only if we're not in CLI
 | ||
| 		if ($platform->isCli())
 | ||
| 		{
 | ||
| 			return;
 | ||
| 		}
 | ||
| 
 | ||
| 		// Closes akeeba-renderjoomla div
 | ||
| 		$this->closePageWrapper();
 | ||
| 	}
 | ||
| 
 | ||
| 	/**
 | ||
| 	 * Renders the submenu (link bar)
 | ||
| 	 *
 | ||
| 	 * @param   string  $view  The active view name
 | ||
| 	 * @param   string  $task  The current task
 | ||
| 	 *
 | ||
| 	 * @return  void
 | ||
| 	 */
 | ||
| 	protected function renderLinkbar(string $view, string $task): void
 | ||
| 	{
 | ||
| 		$style = $this->getOption('linkbar_style', 'joomla');
 | ||
| 
 | ||
| 		switch ($style)
 | ||
| 		{
 | ||
| 			case 'joomla':
 | ||
| 				$this->renderLinkbar_joomla($view, $task);
 | ||
| 				break;
 | ||
| 
 | ||
| 			case 'classic':
 | ||
| 			default:
 | ||
| 				$this->renderLinkbar_classic($view, $task);
 | ||
| 				break;
 | ||
| 		}
 | ||
| 	}
 | ||
| 
 | ||
| 	/**
 | ||
| 	 * Renders the submenu (link bar) in F0F's classic style, using a Bootstrapped
 | ||
| 	 * tab bar.
 | ||
| 	 *
 | ||
| 	 * @param   string  $view  The active view name
 | ||
| 	 * @param   string  $task  The current task
 | ||
| 	 *
 | ||
| 	 * @return  void
 | ||
| 	 */
 | ||
| 	protected function renderLinkbar_classic(string $view, string $task): void
 | ||
| 	{
 | ||
| 		$platform = $this->container->platform;
 | ||
| 
 | ||
| 		if ($platform->isCli())
 | ||
| 		{
 | ||
| 			return;
 | ||
| 		}
 | ||
| 
 | ||
| 		$isJoomla4 = version_compare(JVERSION, '3.99999.99999', 'gt');
 | ||
| 		$isJoomla3 = !$isJoomla4 && version_compare(JVERSION, '3.0.0', 'ge');
 | ||
| 
 | ||
| 		// Do not render a submenu unless we are in the the admin area
 | ||
| 		$toolbar               = $this->container->toolbar;
 | ||
| 		$renderFrontendSubmenu = $toolbar->getRenderFrontendSubmenu();
 | ||
| 
 | ||
| 		if (!$platform->isBackend() && !$renderFrontendSubmenu)
 | ||
| 		{
 | ||
| 			return;
 | ||
| 		}
 | ||
| 
 | ||
| 		$links = $toolbar->getLinks();
 | ||
| 
 | ||
| 		if (!empty($links))
 | ||
| 		{
 | ||
| 			echo "<ul class=\"nav nav-tabs\">\n";
 | ||
| 
 | ||
| 			foreach ($links as $link)
 | ||
| 			{
 | ||
| 				$dropdown = false;
 | ||
| 
 | ||
| 				if (array_key_exists('dropdown', $link))
 | ||
| 				{
 | ||
| 					$dropdown = $link['dropdown'];
 | ||
| 				}
 | ||
| 
 | ||
| 				if ($dropdown)
 | ||
| 				{
 | ||
| 					echo "<li";
 | ||
| 					$class = 'nav-item dropdown';
 | ||
| 
 | ||
| 					if ($link['active'])
 | ||
| 					{
 | ||
| 						$class .= ' active';
 | ||
| 					}
 | ||
| 
 | ||
| 					echo ' class="' . $class . '">';
 | ||
| 
 | ||
| 					echo '<a class="nav-link dropdown-toggle" data-toggle="dropdown" href="#">';
 | ||
| 
 | ||
| 					if ($link['icon'])
 | ||
| 					{
 | ||
| 						echo "<i class=\"icon icon-" . $link['icon'] . "\"></i>";
 | ||
| 					}
 | ||
| 
 | ||
| 					echo $link['name'];
 | ||
| 					echo '<b class="caret"></b>';
 | ||
| 					echo '</a>';
 | ||
| 
 | ||
| 					echo "\n<ul class=\"dropdown-menu\">";
 | ||
| 
 | ||
| 					foreach ($link['items'] as $item)
 | ||
| 					{
 | ||
| 						echo "<li class=\"dropdown-item";
 | ||
| 
 | ||
| 						if ($item['active'])
 | ||
| 						{
 | ||
| 							echo ' active';
 | ||
| 						}
 | ||
| 
 | ||
| 						echo "\">";
 | ||
| 
 | ||
| 						if ($item['icon'])
 | ||
| 						{
 | ||
| 							echo "<i class=\"icon icon-" . $item['icon'] . "\"></i>";
 | ||
| 						}
 | ||
| 
 | ||
| 						if ($item['link'])
 | ||
| 						{
 | ||
| 							echo "<a href=\"" . $item['link'] . "\">" . $item['name'] . "</a>";
 | ||
| 						}
 | ||
| 						else
 | ||
| 						{
 | ||
| 							echo $item['name'];
 | ||
| 						}
 | ||
| 
 | ||
| 						echo "</li>";
 | ||
| 					}
 | ||
| 
 | ||
| 					echo "</ul>\n";
 | ||
| 				}
 | ||
| 				else
 | ||
| 				{
 | ||
| 					echo "<li class=\"nav-item";
 | ||
| 
 | ||
| 					if ($link['active'] && $isJoomla3)
 | ||
| 					{
 | ||
| 						echo ' active"';
 | ||
| 					}
 | ||
| 
 | ||
| 					echo "\">";
 | ||
| 
 | ||
| 					if ($link['icon'])
 | ||
| 					{
 | ||
| 						echo "<span class=\"icon icon-" . $link['icon'] . "\"></span>";
 | ||
| 					}
 | ||
| 
 | ||
| 					if ($isJoomla3)
 | ||
| 					{
 | ||
| 						if ($link['link'])
 | ||
| 						{
 | ||
| 							echo "<a href=\"" . $link['link'] . "\">" . $link['name'] . "</a>";
 | ||
| 						}
 | ||
| 						else
 | ||
| 						{
 | ||
| 							echo $link['name'];
 | ||
| 						}
 | ||
| 					}
 | ||
| 					else
 | ||
| 					{
 | ||
| 						$class = $link['active'] ? 'active' : '';
 | ||
| 
 | ||
| 						$href = $link['link'] ?: '#';
 | ||
| 
 | ||
| 						echo "<a href=\"$href\" class=\"nav-link $class\">{$link['name']}</a>";
 | ||
| 					}
 | ||
| 				}
 | ||
| 
 | ||
| 				echo "</li>\n";
 | ||
| 			}
 | ||
| 
 | ||
| 			echo "</ul>\n";
 | ||
| 		}
 | ||
| 	}
 | ||
| 
 | ||
| 	/**
 | ||
| 	 * Renders the submenu (link bar) using Joomla!'s style. On Joomla! 2.5 this
 | ||
| 	 * is a list of bar separated links, on Joomla! 3 it's a sidebar at the
 | ||
| 	 * left-hand side of the page.
 | ||
| 	 *
 | ||
| 	 * @param   string  $view  The active view name
 | ||
| 	 * @param   string  $task  The current task
 | ||
| 	 *
 | ||
| 	 * @return  void
 | ||
| 	 */
 | ||
| 	protected function renderLinkbar_joomla(string $view, string $task): void
 | ||
| 	{
 | ||
| 		$platform = $this->container->platform;
 | ||
| 
 | ||
| 		// On command line don't do anything
 | ||
| 		if ($platform->isCli())
 | ||
| 		{
 | ||
| 			return;
 | ||
| 		}
 | ||
| 
 | ||
| 		// Do not render a submenu unless we are in the the admin area
 | ||
| 		$toolbar               = $this->container->toolbar;
 | ||
| 		$renderFrontendSubmenu = $toolbar->getRenderFrontendSubmenu();
 | ||
| 
 | ||
| 		if (!$platform->isBackend() && !$renderFrontendSubmenu)
 | ||
| 		{
 | ||
| 			return;
 | ||
| 		}
 | ||
| 
 | ||
| 		$this->renderLinkbarItems($toolbar);
 | ||
| 	}
 | ||
| 
 | ||
| 	/**
 | ||
| 	 * Render the linkbar
 | ||
| 	 *
 | ||
| 	 * @param   Toolbar  $toolbar  An FOF toolbar object
 | ||
| 	 *
 | ||
| 	 * @return  void
 | ||
| 	 */
 | ||
| 	protected function renderLinkbarItems(Toolbar $toolbar): void
 | ||
| 	{
 | ||
| 		$links = $toolbar->getLinks();
 | ||
| 
 | ||
| 		if (!empty($links))
 | ||
| 		{
 | ||
| 			foreach ($links as $link)
 | ||
| 			{
 | ||
| 				JHtmlSidebar::addEntry($link['name'], $link['link'], $link['active']);
 | ||
| 
 | ||
| 				$dropdown = false;
 | ||
| 
 | ||
| 				if (array_key_exists('dropdown', $link))
 | ||
| 				{
 | ||
| 					$dropdown = $link['dropdown'];
 | ||
| 				}
 | ||
| 
 | ||
| 				if ($dropdown)
 | ||
| 				{
 | ||
| 					foreach ($link['items'] as $item)
 | ||
| 					{
 | ||
| 						JHtmlSidebar::addEntry('– ' . $item['name'], $item['link'], $item['active']);
 | ||
| 					}
 | ||
| 				}
 | ||
| 			}
 | ||
| 		}
 | ||
| 	}
 | ||
| 
 | ||
| 	/**
 | ||
| 	 * Renders the toolbar buttons
 | ||
| 	 *
 | ||
| 	 * @param   string  $view  The active view name
 | ||
| 	 * @param   string  $task  The current task
 | ||
| 	 *
 | ||
| 	 * @return  void
 | ||
| 	 */
 | ||
| 	protected function renderButtons(string $view, string $task): void
 | ||
| 	{
 | ||
| 		$platform = $this->container->platform;
 | ||
| 
 | ||
| 		if ($platform->isCli())
 | ||
| 		{
 | ||
| 			return;
 | ||
| 		}
 | ||
| 
 | ||
| 		// Do not render buttons unless we are in the the frontend area and we are asked to do so
 | ||
| 		$toolbar               = $this->container->toolbar;
 | ||
| 		$renderFrontendButtons = $toolbar->getRenderFrontendButtons();
 | ||
| 
 | ||
| 		// Load main backend language, in order to display toolbar strings
 | ||
| 		// (JTOOLBAR_BACK, JTOOLBAR_PUBLISH etc etc)
 | ||
| 		$platform->loadTranslations('joomla');
 | ||
| 
 | ||
| 		if ($platform->isBackend() || !$renderFrontendButtons)
 | ||
| 		{
 | ||
| 			return;
 | ||
| 		}
 | ||
| 
 | ||
| 		$bar   = JoomlaToolbar::getInstance('toolbar');
 | ||
| 		$items = $bar->getItems();
 | ||
| 
 | ||
| 		$substitutions = [
 | ||
| 			'icon-32-new'       => 'icon-plus',
 | ||
| 			'icon-32-publish'   => 'icon-eye-open',
 | ||
| 			'icon-32-unpublish' => 'icon-eye-close',
 | ||
| 			'icon-32-delete'    => 'icon-trash',
 | ||
| 			'icon-32-edit'      => 'icon-edit',
 | ||
| 			'icon-32-copy'      => 'icon-th-large',
 | ||
| 			'icon-32-cancel'    => 'icon-remove',
 | ||
| 			'icon-32-back'      => 'icon-circle-arrow-left',
 | ||
| 			'icon-32-apply'     => 'icon-ok',
 | ||
| 			'icon-32-save'      => 'icon-hdd',
 | ||
| 			'icon-32-save-new'  => 'icon-repeat',
 | ||
| 		];
 | ||
| 
 | ||
| 		if (isset(JoomlaFactory::getApplication()->JComponentTitle))
 | ||
| 		{
 | ||
| 			$title = JoomlaFactory::getApplication()->JComponentTitle;
 | ||
| 		}
 | ||
| 		else
 | ||
| 		{
 | ||
| 			$title = '';
 | ||
| 		}
 | ||
| 
 | ||
| 		$html    = [];
 | ||
| 		$actions = [];
 | ||
| 
 | ||
| 		// We have to use the same id we're using inside other renderers
 | ||
| 		$html[] = '<div class="well" id="FOFHeaderContainer">';
 | ||
| 		$html[] = '<div class="titleContainer">' . $title . '</div>';
 | ||
| 		$html[] = '<div class="buttonsContainer">';
 | ||
| 
 | ||
| 		foreach ($items as $node)
 | ||
| 		{
 | ||
| 			$type   = $node[0];
 | ||
| 			$button = $bar->loadButtonType($type);
 | ||
| 
 | ||
| 			if ($button !== false)
 | ||
| 			{
 | ||
| 				$action    = call_user_func_array([&$button, 'fetchButton'], $node);
 | ||
| 				$action    = str_replace('class="toolbar"', 'class="toolbar btn"', $action);
 | ||
| 				$action    = str_replace('<span ', '<i ', $action);
 | ||
| 				$action    = str_replace('</span>', '</i>', $action);
 | ||
| 				$action    = str_replace(array_keys($substitutions), array_values($substitutions), $action);
 | ||
| 				$actions[] = $action;
 | ||
| 			}
 | ||
| 		}
 | ||
| 
 | ||
| 		$html   = array_merge($html, $actions);
 | ||
| 		$html[] = '</div>';
 | ||
| 		$html[] = '</div>';
 | ||
| 
 | ||
| 		echo implode("\n", $html);
 | ||
| 	}
 | ||
| 
 | ||
| 	/**
 | ||
| 	 * Opens the wrapper DIV element. Our component's output will be inside this wrapper.
 | ||
| 	 *
 | ||
| 	 * @param   array  $classes  An array of additional CSS classes to add to the outer page wrapper element.
 | ||
| 	 *
 | ||
| 	 * @return  void
 | ||
| 	 */
 | ||
| 	protected function openPageWrapper(array $classes): void
 | ||
| 	{
 | ||
| 		$this->setOption('wrapper_id', $this->getOption('wrapper_id', 'akeeba-renderjoomla'));
 | ||
| 
 | ||
| 		$classes[] = 'akeeba-renderer-joomla';
 | ||
| 
 | ||
| 		parent::openPageWrapper($classes);
 | ||
| 	}
 | ||
| 
 | ||
| }
 |