myvideogamelist.com/app/Core/Menu.php
Jimmy Brancaccio b39ecf1638 Initial Commit
The initial public commit of MVGL website code.
2024-01-14 13:51:43 -06:00

521 lines
14 KiB
PHP

<?php
namespace App\Core;
use App\Core\Adapters\Theme;
class Menu
{
// Menu config
public $items;
// Current page path
private $path;
// Default menu tag
private $parentTag = 'div';
// Default menu item tag
private $itemTag = 'div';
// Default icon visibility
private $displayIcons = true;
// Hide root level icons
private $hideRootLevelIcons = false;
// Menu registered callbacks
private $callbacks = array();
// Default item link class
private $itemLinkClass = '';
// Default icon type in menu config
private $iconType = 'svg';
// Default root icon
private $iconRoot = '';
// Hide root arrow
private $hideRootArrow = false;
// Iteration level
private $linkLevel = 0;
/**
* Private Methods.
*
*/
private function _generateItem($item, $level = 0)
{
$classes = array('menu-item');
$attributes = array();
// Set iteration level
$this->linkLevel = $level;
// Overcome recursive infinite loop
if ($level > 10000) {
return;
}
// Process callable item
if (is_callable($item)) {
$item = call_user_func($item);
}
// Exit if item is null
if ($item === null) {
return;
}
// Handle menu item visiblity with callback function
if (isset($item['hide'])) {
if (is_callable($item['hide'])) {
$hide = call_user_func($item['hide'], $this, $item);
} else {
$hide = $item['hide'];
}
if ($hide === true) {
return;
}
}
if (isset($item['sub']) && ($this->_matchParentItemByPath($item) === true)) {
$classes[] = 'here show';
}
if (isset($item['attributes']) && isset($item['attributes']['item'])) {
$attributes = $item['attributes']['item'];
} elseif (isset($item['attributes']) && isset($item['attributes']['link']) === false) {
$attributes = $item['attributes'];
}
if (isset($item['classes']) && isset($item['classes']['item'])) {
$classes[] = $item['classes']['item'];
}
echo '<' . $this->itemTag . ' ' . Util::getHtmlAttributes($attributes) . Util::getHtmlClass($classes) . '>';
if (isset($item['custom'])) {
$this->_generateItemCustom($item);
}
if (isset($item['content'])) {
$this->_generateItemContent($item);
}
if (isset($item['title']) || isset($item['breadcrumb-title'])) {
$this->_generateItemLink($item);
}
if (isset($item['heading'])) {
$this->_generateItemHeading($item);
}
if (isset($item['sub'])) {
$this->_generateItemSub($item['sub'], $level++);
}
echo '</' . $this->itemTag . '>';
}
private function _generateItemLink($item)
{
$classes = array('menu-link');
$attributes = array();
$tag = 'a';
// Construct li ks attributes
if (isset($item['path'])) {
// Assign the page URL
$attributes['href'] = Theme::getPageUrl($item['path']);
// Handle open in new tab mode
if (isset($item['new-tab']) && $item['new-tab'] === true) {
$attributes['target'] = 'blank';
}
// Add special attribute for links to pro pages
if (Theme::isFreeVersion() === true && Theme::isProPage($item['path']) === true) {
$attributes['data-kt-page'] = 'pro';
}
} else {
$tag = 'span';
}
if (isset($item['attributes']) && isset($item['attributes']['link'])) {
$attributes = array_merge($attributes, $item['attributes']['link']);
}
if ($this->_matchItemByPath($item) === true) {
$classes[] = 'active';
}
if (!empty($this->itemLinkClass)) {
$classes[] = $this->itemLinkClass;
}
if (isset($item['classes']) && isset($item['classes']['link'])) {
$classes[] = $item['classes']['link'];
}
echo '<' . $tag . Util::getHtmlClass($classes) . Util::getHtmlAttributes($attributes) . '>';
if ($this->displayIcons !== false) {
$this->_generateItemLinkIcon($item);
}
$this->_generateItemLinkBullet($item);
if (isset($item['title'])) {
$this->_generateItemLinkTitle($item);
}
$this->_generateItemLinkBadge($item);
if (isset($item['sub']) && @$item['arrow'] !== false) {
if (!($this->hideRootArrow === true && $this->linkLevel === 0)) {
$this->_generateItemLinkArrow($item);
}
}
echo '</' . $tag . '>';
}
private function _generateItemLinkTitle($item)
{
$classes = array('menu-title');
if (isset($item['classes']) && isset($item['classes']['title'])) {
$classes[] = $item['classes']['title'];
}
if (!is_string($item['title']) && is_callable($item['title'])) {
$item['title'] = call_user_func($item['title'], $item);
}
echo '<span ' . Util::getHtmlClass($classes) . '>';
if (isset($this->callbacks['title']) && is_callable($this->callbacks['title'])) {
echo call_user_func($this->callbacks['title'], $item, $item['title']);
} else {
echo __($item['title']);
// Append exclusive badge
if (isset($item['path']) && Theme::isExclusivePage($item['path']) === true) {
echo '<span class="badge badge-exclusive badge-light-success fw-bold fs-9 px-2 py-1 ms-1">Exclusive</span>';
}
// Append pro badge
if (Theme::isFreeVersion()) {
if ((isset($item['path']) && Theme::isProPage($item['path']) === true) || (isset($item['pro']) && $item['pro'] === true)) {
echo '<span class="badge badge-pro badge-light-danger fw-bold fs-9 px-2 py-1 ms-1">Pro</span>';
}
}
}
echo '</span>';
}
private function _generateItemLinkIcon($item)
{
$classes = array('menu-icon');
if (isset($item['classes']) && isset($item['classes']['icon'])) {
$classes[] = $item['classes']['icon'];
}
if (isset($item['icon'])) {
echo '<span ' . Util::getHtmlClass($classes) . '>';
if ($this->linkLevel === 0 && !empty($this->iconRoot)) {
echo $this->iconRoot;
} else {
if (is_array($item['icon'])) {
echo $item['icon'][$this->iconType];
} else {
echo $item['icon'];
}
}
echo '</span>';
return;
}
}
private function _generateItemLinkBullet($item)
{
if (isset($item['icon']) === true && $this->displayIcons !== false) {
return;
}
$classes = array('menu-bullet');
if (isset($item['classes']) && isset($item['classes']['bullet'])) {
$classes[] = $item['classes']['bullet'];
}
if (isset($item['bullet'])) {
echo '<span ' . Util::getHtmlClass($classes) . '>';
if (isset($item['bullet'])) {
echo $item['bullet'];
}
echo '</span>';
}
}
private function _generateItemLinkBadge($item)
{
$classes = array('menu-badge');
if (isset($item['classes']) && isset($item['classes']['badge'])) {
$classes[] = $item['classes']['badge'];
}
if (isset($item['badge'])) {
echo '<span ' . Util::getHtmlClass($classes) . '>';
echo $item['badge'];
echo '</span>';
}
}
private function _generateItemLinkArrow($item)
{
$classes = array('menu-arrow');
if (isset($item['classes']['arrow'])) {
$classes[] = $item['classes']['arrow'];
}
echo '<span ' . Util::getHtmlClass($classes) . '>';
echo '</span>';
}
private function _generateItemSub($sub, $level)
{
$classes = array('menu-sub');
if (isset($sub['class'])) {
$classes[] = $sub['class'];
}
echo '<' . $this->parentTag . ' ' . Util::getHtmlClass($classes) . '>';
if (isset($sub['view'])) {
Theme::getView($sub['view']);
} else {
foreach ($sub['items'] as $item) {
$this->_generateItem($item, $level++);
}
}
echo '</' . $this->parentTag . '>';
}
private function _generateItemHeading($item)
{
$classes = array('menu-content');
if (isset($item['heading'])) {
if (isset($this->callbacks['heading']) && is_callable($this->callbacks['heading'])) {
echo call_user_func($this->callbacks['heading'], $item['heading']);
} else {
echo '<h3 ' . Util::getHtmlClass($classes) . '>';
echo $item['heading'];
echo '</h3>';
}
}
}
private function _generateItemContent($item)
{
$classes = array('menu-content');
if (isset($item['classes']) && isset($item['classes']['content'])) {
$classes[] = $item['classes']['content'];
}
if (isset($item['content'])) {
echo '<div ' . Util::getHtmlClass($classes) . '>';
echo $item['content'];
echo '</div>';
}
}
private function _generateItemCustom($item)
{
if (isset($item['custom'])) {
echo $item['custom'];
}
}
private function _matchParentItemByPath($item, $level = 0)
{
if ($level > 1000) {
return false;
}
if ($this->_matchItemByPath($item) === true) {
return true;
} else {
if (isset($item['sub']) && isset($item['sub']['items'])) {
foreach ($item['sub']['items'] as $currentItem) {
if ($this->_matchParentItemByPath($currentItem, $level++) === true) {
return true;
}
}
}
return false;
}
}
private function _matchItemByPath($item)
{
if (isset($item['path']) && ($this->path === $item['path'] || $this->path === $item['path'] . '/index')) {
return true;
} else {
return false;
}
}
private function _buildBreadcrumb($items, &$breadcrumb, $options, $level = 0)
{
if ($level > 10000) {
return false;
}
foreach ($items as $item) {
$title = '';
if (isset($item['breadcrumb-title'])) {
$title = $item['breadcrumb-title'];
} elseif (isset($item['title'])) {
if (!is_string($item['title']) && is_callable($item['title'])) {
$title = call_user_func($item['title'], $item);
} else {
$title = $item['title'];
}
} elseif (isset($item['heading'])) {
$title = $item['heading'];
}
if (isset($item['path']) && ($item['path'] === $this->path || $item['path'] . '/index' === $this->path)) {
if (@$options['skip-active'] !== true) {
$breadcrumb[] = array(
'title' => $title,
'path' => isset($item['path']) ? $item['path'] : '',
'active' => true
);
}
return true;
} elseif (isset($item['sub']) && isset($item['sub']['items'])) {
if ($this->_buildBreadcrumb($item['sub']['items'], $breadcrumb, $options, $level++) === true) {
$breadcrumb[] = array(
'title' => $title,
'path' => isset($item['path']) ? $item['path'] : ( isset($item['alt-path']) ? $item['alt-path'] : ''),
'active' => false
);
return true;
}
}
}
return false;
}
/**
* Public Methods.
*
*/
public function __construct($items, $path = '')
{
$this->items = $items;
$this->path = $path;
return $this;
}
/**
* options: array('includeHomeLink' => boolean, 'homeLink' => array(), 'skipCurrentPage' => boolean)
*
*/
public function getBreadcrumb($options = array())
{
$breadcrumb = array();
//$includeHomeLink = true, $homeLink = null
$this->_buildBreadcrumb($this->items, $breadcrumb, $options);
$breadcrumb = array_reverse($breadcrumb, true);
if (!empty($breadcrumb)) {
if (isset($options['home'])) {
array_unshift($breadcrumb, $options['home']);
} else {
array_unshift($breadcrumb, array(
'title' => 'Home',
'path' => 'index',
'active' => false
));
}
}
return $breadcrumb;
}
public function setPath($path)
{
$this->path = $path;
}
public function displayIcons($flag)
{
$this->displayIcons = $flag;
}
public function hideRootArrow($flag)
{
$this->hideRootArrow = $flag;
}
public function setItemTag($tagName)
{
$this->itemTag = $tagName;
}
public function setIconType($type)
{
$this->iconType = $type;
}
public function setDefaultRootIcon($icon)
{
$this->iconRoot = $icon;
}
public function setItemLinkClass($class)
{
$this->itemLinkClass = $class;
}
public function addCallback($target, $callback)
{
if (!is_string($callback) && is_callable($callback)) {
$this->callbacks[$target] = $callback;
}
}
public function build()
{
foreach ($this->items as $item) {
$this->_generateItem($item);
}
}
}