View source
<?php
namespace Drupal\modal_page\Service;
use Drupal\Component\Utility\Xss;
use Drupal\Component\Uuid\UuidInterface;
use Drupal\Core\Entity\EntityTypeManagerInterface;
use Drupal\Core\Language\LanguageManagerInterface;
use Drupal\Core\Path\PathMatcherInterface;
use Drupal\Core\StringTranslation\StringTranslationTrait;
use Symfony\Component\HttpFoundation\RequestStack;
use Drupal\Core\Session\AccountProxyInterface;
use Drupal\Core\Database\Connection;
use Drupal\Core\Config\ConfigFactoryInterface;
use Drupal\Component\Utility\Html;
use Drupal\path_alias\AliasManagerInterface;
use Drupal\Core\Extension\ModuleHandlerInterface;
use Drupal\Core\Path\CurrentPathStack;
class ModalPageService {
use StringTranslationTrait;
protected $uuidService;
protected $languageManager;
protected $entityTypeManager;
protected $pathMatcher;
protected $request;
protected $configFactory;
protected $database;
protected $currentUser;
protected $aliasManager;
protected $currentPath;
protected $projectHandler;
public function __construct(LanguageManagerInterface $language_manager, EntityTypeManagerInterface $entity_manager, ConfigFactoryInterface $config_factory, Connection $database, RequestStack $request_stack, PathMatcherInterface $path_matcher, UuidInterface $uuid_service, AccountProxyInterface $current_user, AliasManagerInterface $alias_manager, ModuleHandlerInterface $project_handler, CurrentPathStack $current_path) {
$this->languageManager = $language_manager;
$this->entityTypeManager = $entity_manager;
$this->pathMatcher = $path_matcher;
$this->request = $request_stack
->getCurrentRequest();
$this->configFactory = $config_factory;
$this->database = $database;
$this->uuidService = $uuid_service;
$this->currentUser = $current_user;
$this->aliasManager = $alias_manager;
$this->projectHandler = $project_handler;
$this->currentPath = $current_path;
}
public function getModalsToShow() {
$modals = $this
->loadModalsToShow();
if (empty($modals)) {
return FALSE;
}
foreach ($modals as $key => $modal) {
$body = '';
if (is_string($modal
->getBody()) && !empty($modal
->getBody())) {
$body = $this
->clearText($modal
->getBody());
}
if (!empty($modal
->getBody()['value'])) {
$body = [
'#type' => 'processed_text',
'#text' => $modal
->getBody()['value'],
'#format' => $modal
->getBody()['format'],
];
}
$modal
->setBody($body);
if (empty($modal
->getTopRightButtonLabel()) || $modal
->getTopRightButtonLabel() == 'x') {
$modal
->setTopRightButtonLabel('×');
}
if (empty($modal
->getEnableDontShowAgainOption())) {
$modal
->setDontShowAgainLabel(FALSE);
}
$modalClass = 'modal fade js-modal-page-show';
if (!empty($modal
->getModalClass())) {
$modalClass .= ' ' . $modal
->getModalClass();
}
$modal
->setModalClass($modalClass);
$headerClass = $modal
->getHeaderClass();
if (empty($modal
->getInsertHorizontalLineHeader())) {
$headerClass .= ' modal-no-border';
$modal
->setHeaderClass($headerClass);
}
$footerClass = $modal
->getFooterClass();
if (empty($modal
->getInsertHorizontalLineFooter())) {
$footerClass .= ' modal-no-border';
$modal
->setFooterClass($footerClass);
}
$closeModalEscKey = 'true';
if (empty($modal
->getCloseModalEscKey())) {
$closeModalEscKey = 'false';
}
$modal
->setCloseModalEscKey($closeModalEscKey);
$closeModalClickingOutside = 'true';
if (empty($modal
->getCloseModalClickingOutside())) {
$closeModalClickingOutside = 'static';
}
$modal
->setCloseModalClickingOutside($closeModalClickingOutside);
$modals[$key] = $modal;
}
return $modals;
}
public function loadModalsToShow() {
$modalToShow = FALSE;
$modalsToShow = [];
$currentPath = $this
->getCurrentPath();
$parameters = $this->request->query
->all();
$modalParameter = empty($parameters['modal']) ? FALSE : Html::escape($parameters['modal']);
if (!empty($modalParameter)) {
$modalParameter = $this
->clearText($modalParameter);
}
$modals = $this->entityTypeManager
->getStorage('modal')
->loadMultiple();
foreach ($modals as $modal) {
if (empty($modal
->getPublished())) {
continue;
}
if (empty($modal
->getType())) {
continue;
}
$modalType = $modal
->getType();
switch ($modalType) {
case 'page':
$modalToShow = $this
->getModalToShowByPage($modal, $currentPath);
break;
case 'parameter':
$modalToShow = $this
->getModalToShowByParameter($modal, $modalParameter);
break;
}
if (!empty($modalToShow) && $this
->verifyUserHasPermissionOnModal($modalToShow)) {
if (empty($this
->verifyModalShouldAppearOnThisLanguage($modalToShow))) {
continue;
}
$modalId = $modalToShow
->id();
$this->projectHandler
->alter('modal', $modalToShow, $modalId);
$hookModalFormIdAlterName = 'modal_' . $modalId;
$this->projectHandler
->alter($hookModalFormIdAlterName, $modalToShow, $modalId);
$modalsToShow[] = $modalToShow;
}
}
return $modalsToShow;
}
public function verifyUserHasPermissionOnModal($modal) {
if (empty(array_filter($modal
->getRoles()))) {
return TRUE;
}
$user = $this->entityTypeManager
->getStorage('user')
->load($this->currentUser
->id());
if (empty($user) || empty($modal
->getRoles())) {
return FALSE;
}
$roles = $modal
->getRoles();
foreach ($roles as $roleId => $role) {
if (empty($role)) {
return FALSE;
}
if (!empty($roleId) && $user
->hasRole($roleId)) {
return TRUE;
}
}
return FALSE;
}
public function verifyModalShouldAppearOnThisLanguage($modal) {
$languagesToShow = $modal
->getLanguagesToShow();
$languagesToShow = array_filter($languagesToShow);
if (empty($languagesToShow)) {
return TRUE;
}
$langCode = $this->languageManager
->getCurrentLanguage()
->getId();
if (!empty($languagesToShow[$langCode])) {
return TRUE;
}
return FALSE;
}
public function clearText($text) {
if (empty(is_string($text))) {
$text = (string) $text;
}
$text = Xss::filter($text, $this
->getAllowTags());
return trim($text);
}
public function getCurrentPath() : string {
$currentPath = $this->request
->getRequestUri();
if ($this->pathMatcher
->isFrontPage()) {
$currentPath = '<front>';
}
return $currentPath;
}
public function getModalToShowByPage($modal, $currentPath) {
$pages = $modal
->getPages();
$pages = explode(PHP_EOL, $pages);
foreach ($pages as $page) {
$path = mb_strtolower($page);
if ($path != '<front>') {
$path = Xss::filter($path);
}
$path = trim($path);
$currentPath = $this->currentPath
->getPath();
$currentPath = $this->aliasManager
->getAliasByPath($currentPath);
if (strpos($currentPath, '/node/') !== FALSE && strpos($currentPath, '/node/') === 0) {
$currentPath = $this->aliasManager
->getAliasByPath($currentPath);
}
$currentPath = mb_strtolower($currentPath);
$shouldAppear = $this
->verifyModalShouldAppearOnThisPath($path, $currentPath);
if (!empty($shouldAppear)) {
return $modal;
}
}
}
public function verifyModalShouldAppearOnThisPath($path, $currentPath) {
$path = preg_quote($path, '/');
$path = str_replace('\\*', '.*', $path);
return preg_match('/^' . $path . '$/i', $currentPath);
}
public function getModalToShowByParameter($modal, $modalParamenter) {
$parameters = $modal
->getParameters();
$parameters = explode(PHP_EOL, $parameters);
foreach ($parameters as $parameter) {
$parameter = trim($parameter);
if ($modalParamenter == $parameter) {
return $modal;
}
}
return FALSE;
}
public function getAllowTags() : array {
$config = $this->configFactory
->get('modal_page.settings');
$allowedTags = $config
->get('allowed_tags') ?? "h1,h2,a,b,big,code,del,em,i,ins,pre,q,small,span,strong,sub,sup,tt,ol,ul,li,p,br,img";
$tags = explode(",", $allowedTags);
return $tags;
}
public function importModalConfigToEntity() {
$language = $this->languageManager
->getCurrentLanguage()
->getId();
$config = $this->configFactory
->get('modal_page.settings');
$modals = $config
->get('modals');
$modalsByParameter = $config
->get('modals_by_parameter');
$allowTags = $this
->getAllowTags();
if (empty($modals) && empty($modalsByParameter)) {
return FALSE;
}
if (!empty($modals)) {
$modalsSettings = explode(PHP_EOL, $modals);
foreach ($modalsSettings as $modal_settings) {
$modal = explode('|', $modal_settings);
$path = $modal[0];
if ($path != '<front>') {
$path = Xss::filter($modal[0]);
}
$path = trim($path);
$path = ltrim($path, '/');
$title = Xss::filter($modal[1], $allowTags);
$title = trim($title);
$text = Xss::filter($modal[2], $allowTags);
$text = trim($text);
$button = Xss::filter($modal[3]);
$button = trim($button);
$uuid = $this->uuidService
->generate();
$modal = [
'uuid' => $uuid,
'title' => $title,
'body' => $text,
'type' => 'page',
'pages' => $path,
'ok_label_button' => $button,
'langcode' => $language,
'created' => time(),
'changed' => time(),
];
$query = $this->database
->insert('modal');
$query
->fields($modal);
$query
->execute();
}
}
if (!empty($modalsByParameter)) {
$modalsSettings = explode(PHP_EOL, $modalsByParameter);
foreach ($modalsSettings as $modal_settings) {
$modal = explode('|', $modal_settings);
$parameter_settings = Xss::filter($modal[0]);
$parameter = trim($parameter_settings);
$parameter_data = explode('=', $parameter);
$parameter_value = $parameter_data[1];
$title = Xss::filter($modal[1], $allowTags);
$title = trim($title);
$text = Xss::filter($modal[2], $allowTags);
$text = trim($text);
$button = Xss::filter($modal[3]);
$button = trim($button);
$uuid = $this->uuidService
->generate();
$modal = [
'uuid' => $uuid,
'title' => $title,
'body' => $text,
'type' => 'parameter',
'parameters' => $parameter_value,
'ok_label_button' => $button,
'langcode' => $language,
'created' => time(),
'changed' => time(),
];
$query = $this->database
->insert('modal');
$query
->fields($modal);
$query
->execute();
}
}
}
public function prepareClass($class) {
if (empty($class)) {
return FALSE;
}
$class = strtolower($class);
$class = str_replace(',', ' ', $class);
$class = str_replace(' ', ' ', $class);
return $class;
}
}