View source
<?php
namespace Drupal\ultimenu;
use Drupal\Component\Utility\Html;
use Drupal\Component\Utility\Unicode;
use Drupal\Core\Config\ConfigFactoryInterface;
use Drupal\Core\Entity\EntityInterface;
use Drupal\Core\Extension\InfoParserInterface;
use Drupal\Core\Language\LanguageManagerInterface;
use Drupal\Core\Session\AccountInterface;
use Drupal\Core\Transliteration\PhpTransliteration;
use Drupal\Core\Path\PathMatcherInterface;
use Drupal\path_alias\AliasRepositoryInterface;
use Symfony\Component\DependencyInjection\ContainerInterface;
class UltimenuTool implements UltimenuToolInterface {
use UltimenuTrait;
protected $currentUser;
protected $pathMatcher;
protected $aliasRepository;
protected $infoParser;
protected $languageManager;
protected $transliteration;
protected $themeRegions;
public function __construct(ConfigFactoryInterface $config_factory, AccountInterface $current_user, PathMatcherInterface $path_matcher, AliasRepositoryInterface $alias_repository, InfoParserInterface $info_parser, LanguageManagerInterface $language_manager, PhpTransliteration $transliteration) {
$this->configFactory = $config_factory;
$this->currentUser = $current_user;
$this->pathMatcher = $path_matcher;
$this->aliasRepository = $alias_repository;
$this->infoParser = $info_parser;
$this->languageManager = $language_manager;
$this->transliteration = $transliteration;
}
public static function create(ContainerInterface $container) {
return new static($container
->get('config.factory'), $container
->get('current_user'), $container
->get('path.matcher'), $container
->get('path_alias.repository'), $container
->get('info_parser'), $container
->get('language_manager'), $container
->get('transliteration'));
}
public function getPathMatcher() {
return $this->pathMatcher;
}
public function getShortenedHash($key) {
return substr(sha1($key), 0, 8);
}
public function getShortenedUuid($key) {
list(, $uuid) = array_pad(array_map('trim', explode(":", $key, 2)), 2, NULL);
$uuid = str_replace('.', '__', $uuid ?: $key);
list($shortened_uuid, ) = array_pad(array_map('trim', explode("-", $uuid, 2)), 2, NULL);
return $shortened_uuid;
}
public function truncateRegionKey($string, $max_length = self::MAX_LENGTH) {
$langcode = $this->languageManager
->getCurrentLanguage()
->getId();
$transformed = $this->transliteration
->transliterate($string, $langcode);
$transformed = Html::decodeEntities($transformed);
$transformed = mb_strtolower(str_replace([
'menu-',
'-menu',
], '', $transformed));
$transformed = preg_replace('/[\\W\\s]+/', '_', $transformed);
$transformed = trim($transformed, '_');
$transformed = Unicode::truncate($transformed, $max_length, TRUE, FALSE);
return $transformed;
}
public function getRegionKey($link, $max_length = self::MAX_LENGTH) {
$menu_name = $link
->getMenuName();
$key = $link
->getPluginId();
$title = $this
->getTitle($link);
$goodies = $this
->getSetting('goodies');
$is_mlid = isset($goodies['ultimenu-mlid']) && $goodies['ultimenu-mlid'];
$is_hash = isset($goodies['ultimenu-mlid-hash']) && $goodies['ultimenu-mlid-hash'];
$menu_name = $this
->truncateRegionKey($menu_name, $max_length);
if ($is_hash) {
$menu_item = $this
->getShortenedHash($key);
}
elseif ($is_mlid) {
$menu_item = $this
->getShortenedUuid($key);
}
else {
$menu_item = $this
->truncateRegionKey(trim($title), $max_length);
}
return 'ultimenu_' . $menu_name . '_' . $menu_item;
}
public function getTitle($link) {
return $this
->extractTitle($link)['title'];
}
public function extractTitle($link) {
$title = strip_tags($link
->getTitle());
$is_icon = substr($title, 0, 5) === 'icon-';
$is_fontawesome = substr($title, 0, 3) === 'fa-';
if (strpos($title, '|') !== FALSE && ($is_icon || $is_fontawesome)) {
list($icon_class, $title) = array_pad(array_map('trim', explode("|", $title, 2)), 2, NULL);
return [
'icon' => $icon_class,
'title' => $title,
'fa' => $is_fontawesome,
];
}
return [
'title' => trim($title),
];
}
public function extractTitleHtml($link) {
$icon = '';
$goodies = $this
->getSetting('goodies');
$titles = $this
->extractTitle($link);
$title_html = $title = $titles['title'];
if (!empty($titles['icon'])) {
$icon_class = $titles['fa'] ? 'fa ' . $titles['icon'] : 'icon ' . $titles['icon'];
$icon = '<span class="ultimenu__icon ' . $icon_class . '" aria-hidden="true"></span>';
}
if (!empty($goodies['menu-desc']) && ($description = $link
->getDescription())) {
$description = '<small>' . strip_tags($description, '<em><strong><i><b>') . '</small>';
$title_html = !empty($goodies['desc-top']) ? $description . $title : $title . $description;
}
if ($icon) {
$title_html = $icon . '<span class="ultimenu__title">' . $title_html . '</span>';
}
return [
'title' => $title,
'title_html' => $title_html,
];
}
public function parseThemeInfo(array $ultimenu_regions = []) {
if (!isset($this->themeRegions)) {
$theme = $this
->getThemeDefault();
$file = drupal_get_path('theme', $theme) . '/' . $theme . '.info.yml';
$info = $this->infoParser
->parse($file);
$regions = [];
foreach ($info['regions'] as $key => $region) {
if (array_key_exists($key, $ultimenu_regions)) {
$regions[$key] = $region;
}
}
$this->themeRegions = $regions;
}
return $this->themeRegions;
}
public function isAllowedBlock(EntityInterface $block, array $config) {
$access = $block
->access('view', $this->currentUser, TRUE);
$allowed = $access
->isAllowed();
if (!$allowed && ($match = $this
->isPageMatch($block, $config))) {
if ($roles = $this
->getAllowedRoles($block)) {
$allowed = $this
->isAllowedByRole($block, $roles);
}
else {
$allowed = !empty($match);
}
}
return $allowed;
}
public function getRequestPath(EntityInterface $block) {
if ($visibility = $block
->getVisibility()) {
return empty($visibility['request_path']) ? FALSE : $visibility['request_path'];
}
return FALSE;
}
public function getVisiblePages(EntityInterface $block) {
$pages = '';
if ($request_path = $this
->getRequestPath($block)) {
$pages = empty($request_path['negate']) ? $request_path['pages'] : '';
}
return $pages;
}
public function getAllowedRoles(EntityInterface &$block) {
if ($visibility_config = $block
->getVisibility()) {
if (isset($visibility_config['user_role'])) {
return array_values($visibility_config['user_role']['roles']);
}
}
return [];
}
public function isAllowedByRole(EntityInterface &$block, array $roles = []) {
$current_user_roles = array_values($this->currentUser
->getRoles());
foreach ($current_user_roles as $role) {
if (in_array($role, $roles)) {
return TRUE;
}
}
return FALSE;
}
public function isPageMatch(EntityInterface $block, array $config = []) {
$page_match = FALSE;
if ($pages = $this
->getVisiblePages($block)) {
$path = $config['current_path'];
$langcode = $this->languageManager
->getCurrentLanguage()
->getId();
$path_check = $this->aliasRepository
->lookupByAlias($path, $langcode);
$path_alias = mb_strtolower($path_check['alias']);
$page_match = $this->pathMatcher
->matchPath($path_alias, $pages);
if ($path_alias != $path) {
$page_match = $page_match || $this->pathMatcher
->matchPath($path, $pages);
}
}
return $page_match;
}
}