You are here

group_content_menu.module in Group Content Menu 8

Provides a group content menu entity type.

File

group_content_menu.module
View source
<?php

/**
 * @file
 * Provides a group content menu entity type.
 */
use Drupal\Core\Entity\EntityInterface;
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\Render\Element;
use Drupal\Core\Url;
use Drupal\group\Entity\GroupInterface;
use Drupal\group\Entity\GroupType;
use Drupal\group_content_menu\Entity\GroupContentMenuType;
use Drupal\group_content_menu\GroupContentMenuInterface;
use Drupal\group_content_menu\NodeFormAlter;
use Drupal\menu_link_content\Entity\MenuLinkContent;
use Drupal\node\NodeInterface;

/**
 * Implements hook_theme().
 */
function group_content_menu_theme() {
  return [
    'group_content_menu' => [
      'render element' => 'elements',
    ],
    'menu__group_menu' => [
      'base hook' => 'menu',
      'variables' => [
        'items' => [],
        'attributes' => [],
      ],
    ],
  ];
}

/**
 * Prepares variables for group content menu templates.
 *
 * Default template: group-content-menu.html.twig.
 *
 * @param array $variables
 *   An associative array containing:
 *   - elements: An associative array containing the group content menu
 *     information and any fields attached to the entity.
 *   - attributes: HTML attributes for the containing element.
 */
function template_preprocess_group_content_menu(array &$variables) {
  foreach (Element::children($variables['elements']) as $key) {
    $variables['content'][$key] = $variables['elements'][$key];
  }
}

/**
 * Implements hook_entity_operation().
 */
function group_content_menu_entity_operation($entity) {
  $operations = [];
  if ($entity
    ->getEntityTypeId() == 'group' && \Drupal::moduleHandler()
    ->moduleExists('views')) {
    if ($entity
      ->hasPermission('access group content menu overview', \Drupal::currentUser())) {
      $operations['menus'] = [
        'title' => t('Menus'),
        'weight' => 20,
        'url' => Url::fromRoute('entity.group_content_menu.collection', [
          'group' => $entity
            ->id(),
        ]),
      ];
    }
  }
  return $operations;
}

/**
 * Implements hook_module_implements_alter().
 */
function group_content_menu_module_implements_alter(&$implementations, $hook) {

  // Make sure our hook_node_form_alter runs after the menu_ui module.
  if ($hook === 'form_alter' && isset($implementations['group_content_menu'])) {
    $group_content_menu = $implementations['group_content_menu'];
    unset($implementations['group_content_menu']);
    $implementations['group_content_menu'] = $group_content_menu;
  }
}

/**
 * Implements hook_form_BASE_FORM_ID_alter().
 */
function group_content_menu_form_node_form_alter(&$form, FormStateInterface $form_state) {
  \Drupal::classResolver(NodeFormAlter::class)
    ->alter($form, $form_state);
}

/**
 * Implements hook_ENTITY_TYPE_insert().
 */
function group_content_menu_group_insert(EntityInterface $entity) {
  $plugins = group_content_menu_get_plugins_per_group($entity);

  // If there are no group menus enabled, bail.
  if (!$plugins) {
    return;
  }
  foreach ($plugins as $plugin) {
    $group_type_configuration = $plugin
      ->getConfiguration();
    $auto_create_group_menu = $group_type_configuration['auto_create_group_menu'];
    if (!$auto_create_group_menu) {
      continue;
    }
    $group_content_type = GroupContentMenuType::load($plugin
      ->getDerivativeId());
    $group_menu = \Drupal::entityTypeManager()
      ->getStorage('group_content_menu')
      ->create([
      'label' => $group_content_type
        ->label(),
      'bundle' => $plugin
        ->getDerivativeId(),
    ]);
    $group_menu
      ->save();

    // Add menu link for group if enabled.
    $auto_create_home_link = $group_type_configuration['auto_create_home_link'];
    if ($auto_create_home_link) {
      $menu_name = GroupContentMenuInterface::MENU_PREFIX . $group_menu
        ->id();
      $menu_link = \Drupal::entityTypeManager()
        ->getStorage('menu_link_content')
        ->create([
        'title' => $group_type_configuration['auto_create_home_link_title'],
        'link' => [
          'uri' => 'internal:/group/' . $entity
            ->id(),
        ],
        'menu_name' => $menu_name,
      ]);
      $menu_link
        ->save();
    }
    $group_content = \Drupal::entityTypeManager()
      ->getStorage('group_content')
      ->create([
      'type' => $plugin
        ->getContentTypeConfigId(),
      'gid' => $entity
        ->id(),
      'label' => $group_content_type
        ->label(),
      'entity_id' => $group_menu,
    ]);
    $group_content
      ->save();
  }
}

/**
 * Implements hook_ENTITY_TYPE_delete().
 */
function group_content_menu_group_delete(EntityInterface $entity) {

  // Remove the group menu and recursively its links on group deletion.
  foreach (group_content_menu_get_menus_per_group($entity) as $group_content) {
    $group_content
      ->getEntity()
      ->delete();
  }
}

/**
 * Get group content menus per group.
 *
 * @param \Drupal\group\Entity\GroupInterface $group
 *   The group.
 *
 * @return \Drupal\group\Entity\GroupContentInterface[]
 *   The related group contents.
 */
function group_content_menu_get_menus_per_group(GroupInterface $group) {
  $plugins = group_content_menu_get_plugins_per_group($group);
  $instances = [];
  foreach (array_keys($plugins) as $plugin_id) {
    $instances[] = \Drupal::entityTypeManager()
      ->getStorage('group_content')
      ->loadByGroup($group, $plugin_id);
  }
  return $instances ? array_merge(...$instances) : [];
}

/**
 * Get group content menu plugins per group.
 *
 * @param \Drupal\group\Entity\GroupInterface $group
 *   The group.
 *
 * @return \Drupal\group\Plugin\GroupContentEnablerInterface[]
 *   The group menu plugins.
 */
function group_content_menu_get_plugins_per_group(GroupInterface $group) {
  $group_type = GroupType::load($group
    ->bundle());

  /** @var \Drupal\group\Plugin\GroupContentEnablerManagerInterface $plugin_manager */
  $plugin_manager = \Drupal::service('plugin.manager.group_content_enabler');
  $installed = $plugin_manager
    ->getInstalled($group_type);
  return array_filter($installed
    ->getIterator()
    ->getArrayCopy(), static function ($plugin_id) {
    return strpos($plugin_id, 'group_content_menu:') === 0;
  }, ARRAY_FILTER_USE_KEY);
}

/**
 * Returns the definition for a menu link for the given node.
 *
 * @param \Drupal\node\NodeInterface $node
 *   The node entity.
 * @param array $menu_names
 *   The menu names.
 *
 * @return array
 *   An array that contains default values for the menu link form.
 */
function group_content_menu_get_menu_link_default(NodeInterface $node, array $menu_names) {

  /** @var \Drupal\node\NodeTypeInterface $node_type */
  $node_type = $node->type->entity;
  $menu_name = strtok($node_type
    ->getThirdPartySetting('menu_ui', 'parent', 'main:'), ':');
  $defaults = [
    'entity_id' => 0,
    'id' => '',
    'title' => '',
    'title_max_length' => 128,
    'description' => '',
    'description_max_length' => 128,
    'menu_name' => $menu_name,
    'parent' => '',
    'weight' => 0,
  ];
  if (empty($menu_names)) {

    // No menu is yet available.
    return $defaults;
  }
  if ($node
    ->id()) {
    $query = \Drupal::entityQuery('menu_link_content')
      ->condition('link.uri', 'entity:node/' . $node
      ->id())
      ->condition('menu_name', $menu_names, 'IN')
      ->sort('id', 'ASC')
      ->range(0, 1);
    $result = $query
      ->execute();
    $id = !empty($result) ? reset($result) : FALSE;
    if ($id) {
      $menu_link = MenuLinkContent::load($id);
      $menu_link = \Drupal::service('entity.repository')
        ->getTranslationFromContext($menu_link);
      $defaults = [
        'entity_id' => $menu_link
          ->id(),
        'id' => $menu_link
          ->getPluginId(),
        'title' => $menu_link
          ->getTitle(),
        'title_max_length' => $menu_link
          ->getFieldDefinitions()['title']
          ->getSetting('max_length'),
        'description' => $menu_link
          ->getDescription(),
        'description_max_length' => $menu_link
          ->getFieldDefinitions()['description']
          ->getSetting('max_length'),
        'menu_name' => $menu_link
          ->getMenuName(),
        'parent' => $menu_link
          ->getParentId(),
        'weight' => $menu_link
          ->getWeight(),
      ];
    }
  }
  return $defaults;
}