domain_menus.module in Domain Menus for Domains 9.x
Same filename and directory in other branches
Domain menus implementation through entity create, delete, and access customizations.
File
domain_menus.moduleView source
<?php
/**
* @file
* Domain menus implementation through entity create, delete, and access customizations.
*/
use Drupal\Core\Access\AccessResult;
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\Entity\EntityInterface;
use Drupal\Core\Render\Markup;
use Drupal\Core\Routing\RouteMatchInterface;
use Drupal\Core\Session\AccountInterface;
use Drupal\system\Entity\Menu;
const DOMAIN_MENUS_MENU_ID_PATTERN = 'dm@domain_domainid-@menu_name';
# eg. dm12345678-alt, menu machine names 27 chars max
const DOMAIN_MENUS_MENU_LABEL_PATTERN = 'Domain menu for @domain_label (@menu_name)';
# pattern helps group domain menus together, a-z sort
const DOMAIN_MENUS_SETTINGS = 'domain_menus.settings';
/**
* Implements hook_help().
*
* @inheritdoc
*/
function domain_menus_help($route_name, RouteMatchInterface $route_match) {
switch ($route_name) {
case 'help.page.domain_menus':
$text = file_get_contents(dirname(__FILE__) . "/README.txt");
$output = nl2br($text);
return $output;
break;
}
}
/**
* Helper function to tell if a menu is a domain menu.
* If a menu has the domain_menus third party setting, it's considered a domain menu.
* @todo maybe do in_array('domain_menus', $entity->getDependencies()['module']) instead
*/
function _domain_menus_is_domain_menu(EntityInterface $menu) {
$menu_domains = $menu
->getThirdPartySetting("domain_menus", "domains");
if ($menu_domains !== NULL) {
return TRUE;
}
return FALSE;
}
/**
* Helper function to get domain_menus settings by name.
*/
function _domain_menus_get_setting($key) {
return \Drupal::config(DOMAIN_MENUS_SETTINGS)
->get($key);
}
/**
* Helper function to get list of domains as form options.
*/
function _domain_menus_domain_options() {
$options = [];
$domains = \Drupal::entityTypeManager()
->getStorage('domain')
->loadMultiple();
foreach ($domains as $domain) {
$options[$domain
->id()] = $domain
->label();
}
return $options;
}
/**
* Helper function to save third party settings on form submit.
*/
function _domain_menus_menu_form_submit($form, FormStateInterface &$form_state) {
$menu = $form_state
->getFormObject()
->getEntity();
// filter out unchecked options
$values = array_diff($form_state
->getValue('domain_menus_menu_domains'), array(
'0',
));
if (!empty($values)) {
$menu
->setThirdPartySetting('domain_menus', 'domains', $values);
}
else {
$menu
->unsetThirdPartySetting('domain_menus', 'domains');
}
$menu
->save();
}
/**
* Implements hook_form_alter().
*/
function domain_menus_form_alter(&$form, FormStateInterface $form_state, $form_id) {
if ($form_id == 'menu_add_form' || $form_id == 'menu_edit_form') {
if (\Drupal::currentUser()
->hasPermission('administer menu')) {
$menu = $form_state
->getFormObject()
->getEntity();
$menu_auto_created = $menu
->getThirdPartySetting('domain_menus', 'auto-created', 0);
if ($menu_auto_created != 1) {
$options = _domain_menus_domain_options();
$default_value = $menu
->getThirdPartySetting('domain_menus', 'domains', []);
$form['domain_menus_menu_domains'] = array(
'#type' => 'checkboxes',
'#title' => t('Domain(s)'),
'#description' => t('Select the domain assignment of this menu. Leave empty if menu should not be considered a domain menu.'),
'#options' => $options,
'#default_value' => $default_value,
);
$form['actions']['submit']['#submit'][] = "_domain_menus_menu_form_submit";
}
}
}
}
/**
* Implements hook_FORM_ID_form_alter().
*
* Unset all parent links that are not on the default or current domain menu.
*/
function domain_menus_form_menu_link_content_menu_link_content_form_alter(&$form, FormStateInterface $form_state, $form_id) {
if (!empty($form['menu_parent']['#default_value'])) {
list($default_menu_id) = explode(':', $form['menu_parent']['#default_value']);
if ($menu = Menu::load($default_menu_id)) {
if (_domain_menus_is_domain_menu($menu)) {
foreach ($form['menu_parent']['#options'] as $key => $name) {
if (strpos($key, $default_menu_id . ':') !== 0) {
unset($form['menu_parent']['#options'][$key]);
}
}
}
}
}
}
/**
* Implements hook_ENTITY_TYPE_insert().
*
* Create domain menus for the domain being created.
*/
function domain_menus_domain_insert(EntityInterface $entity) {
$domain = $entity;
$domain_id = $domain
->id();
$domain_domainid = $domain
->getDomainId();
$domain_label = Markup::create($domain
->label());
$domain_menus = _domain_menus_get_setting('domain_menus_menu_names');
if (!empty($domain_menus)) {
$menu_names = explode("\r\n", $domain_menus);
if (!empty($menu_names)) {
foreach ($menu_names as $menu_name) {
if (!empty($menu_name)) {
$menu_name = Markup::create($menu_name);
$menu = Menu::create(array(
'id' => trim(t(DOMAIN_MENUS_MENU_ID_PATTERN, [
'@domain_domainid' => $domain_domainid,
'@menu_name' => $menu_name,
])),
'label' => trim(t(DOMAIN_MENUS_MENU_LABEL_PATTERN, [
'@domain_label' => $domain_label,
'@menu_name' => $menu_name,
])),
));
$menu
->setThirdPartySetting('domain_menus', 'domains', array(
$domain_id => $domain_id,
));
$menu
->setThirdPartySetting('domain_menus', 'auto-created', 1);
$menu
->save();
}
}
}
}
}
/**
* Implements hook_ENTITY_TYPE_delete().
*
* Delete domain menus of the domain being deleted.
* If a domain menu has assignment to multiple domains, remove the deleted domain from assignment instead of deleting the menu.
*/
function domain_menus_domain_delete(EntityInterface $entity) {
$domain = $entity;
$domain_id = $domain
->id();
$domain_domainid = $domain
->getDomainId();
$menus = \Drupal::entityTypeManager()
->getStorage('menu')
->loadMultiple();
if (!empty($menus)) {
foreach ($menus as $menu) {
$menu_domains = $menu
->getThirdPartySetting("domain_menus", "domains", []);
if (array_key_exists($domain_id, $menu_domains)) {
unset($menu_domains[$domain_id]);
if (empty($menu_domains)) {
$menu
->delete();
}
else {
$menu
->setThirdPartySetting('domain_menus', 'domains', $menu_domains);
$menu
->save();
}
}
}
}
}
/**
* Implements hook_ENTITY_TYPE_create_access().
*
* Allow menu link create access to domain menus based on domain_menus permissions
*/
function domain_menus_menu_link_content_create_access(AccountInterface $account, array $context, $entity_bundle) {
$route = Drupal::routeMatch();
if ($menu = $route
->getParameter('menu')) {
if (_domain_menus_is_domain_menu($menu)) {
$menu_id = $menu
->id();
$menu_domains = $menu
->getThirdPartySetting("domain_menus", "domains", []);
$user = \Drupal::entityTypeManager()
->getStorage('user')
->load($account
->id());
//$user_domains = \Drupal::service('domain_access.manager')->getAccessValues($user);
$user_domains_string = $user
->get(DOMAIN_ACCESS_FIELD)
->getString();
$user_domains = explode(', ', $user_domains_string);
$menu_and_user_domains = array_intersect($menu_domains, $user_domains);
$active_domain = \Drupal::service('domain.negotiator')
->getActiveDomain();
$active_domain_id = $active_domain
->id();
// permission check order matters, do "edit assigned domain menus" first
if ($account
->hasPermission('edit assigned domain menus')) {
if (!empty($menu_and_user_domains)) {
return AccessResult::allowed();
}
}
elseif ($account
->hasPermission('edit active domain menus')) {
if (in_array($active_domain_id, $menu_and_user_domains)) {
return AccessResult::allowed();
}
}
}
}
return AccessResult::neutral();
}
/**
* Implements hook_ENTITY_TYPE_access().
*
* Allow menu link edit access in domain menus based on domain_menus permissions
*/
function domain_menus_menu_link_content_access(EntityInterface $entity, $operation, AccountInterface $account) {
$menu_link = $entity;
$menu_id = $menu_link
->getMenuName();
$menu = Menu::load($menu_id);
$menu_domains = $menu
->getThirdPartySetting("domain_menus", "domains", []);
$user = \Drupal::entityTypeManager()
->getStorage('user')
->load($account
->id());
//$user_domains = \Drupal::service('domain_access.manager')->getAccessValues($user);
$user_domains_string = $user
->get(DOMAIN_ACCESS_FIELD)
->getString();
$user_domains = explode(', ', $user_domains_string);
$menu_and_user_domains = array_intersect($menu_domains, $user_domains);
$active_domain = \Drupal::service('domain.negotiator')
->getActiveDomain();
$active_domain_id = $active_domain
->id();
// permission check order matters, do "edit assigned domain menus" first
if ($account
->hasPermission('edit assigned domain menus')) {
if (!empty($menu_and_user_domains)) {
return AccessResult::allowed();
}
}
elseif ($account
->hasPermission('edit active domain menus')) {
if (in_array($active_domain_id, $menu_and_user_domains)) {
return AccessResult::allowed();
}
}
return AccessResult::neutral();
}
/**
* Implements hook_ENTITY_TYPE_access().
*
* Allow domain menus edit access based on domain_menus permissions
*/
function domain_menus_menu_access(EntityInterface $entity, $operation, AccountInterface $account) {
$menu = $entity;
$menu_domains = $menu
->getThirdPartySetting("domain_menus", "domains", []);
$user = \Drupal::entityTypeManager()
->getStorage('user')
->load($account
->id());
//$user_domains = \Drupal::service('domain_access.manager')->getAccessValues($user);
$user_domains_string = $user
->get(DOMAIN_ACCESS_FIELD)
->getString();
$user_domains = explode(', ', $user_domains_string);
$menu_and_user_domains = array_intersect($menu_domains, $user_domains);
$active_domain = \Drupal::service('domain.negotiator')
->getActiveDomain();
$active_domain_id = $active_domain
->id();
// permission check order matters, do "edit assigned domain menus" first
if ($account
->hasPermission('edit assigned domain menus')) {
if (!empty($menu_and_user_domains)) {
return AccessResult::allowed();
}
}
elseif ($account
->hasPermission('edit active domain menus')) {
if (in_array($active_domain_id, $menu_and_user_domains)) {
return AccessResult::allowed();
}
}
return AccessResult::neutral();
}
Functions
Name | Description |
---|---|
domain_menus_domain_delete | Implements hook_ENTITY_TYPE_delete(). |
domain_menus_domain_insert | Implements hook_ENTITY_TYPE_insert(). |
domain_menus_form_alter | Implements hook_form_alter(). |
domain_menus_form_menu_link_content_menu_link_content_form_alter | Implements hook_FORM_ID_form_alter(). |
domain_menus_help | Implements hook_help(). |
domain_menus_menu_access | Implements hook_ENTITY_TYPE_access(). |
domain_menus_menu_link_content_access | Implements hook_ENTITY_TYPE_access(). |
domain_menus_menu_link_content_create_access | Implements hook_ENTITY_TYPE_create_access(). |
_domain_menus_domain_options | Helper function to get list of domains as form options. |
_domain_menus_get_setting | Helper function to get domain_menus settings by name. |
_domain_menus_is_domain_menu | Helper function to tell if a menu is a domain menu. If a menu has the domain_menus third party setting, it's considered a domain menu. @todo maybe do in_array('domain_menus', $entity->getDependencies()['module']) instead |
_domain_menus_menu_form_submit | Helper function to save third party settings on form submit. |