You are here

social_path_manager.module in Open Social 8.8

The Social Path Manager module.

File

modules/custom/social_path_manager/social_path_manager.module
View source
<?php

/**
 * @file
 * The Social Path Manager module.
 */
use Drupal\Core\Entity\EntityInterface;
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\Url;
use Drupal\group\Entity\Group;
use Drupal\group\Entity\GroupInterface;
use Drupal\group\Entity\GroupType;

/**
 * Implements hook_form_alter().
 */
function social_path_manager_form_alter(&$form, FormStateInterface $form_state, $form_id) {
  $social_group_types = _social_path_manager_group_types();
  $group_forms = [];
  foreach ($social_group_types as $social_group_type) {
    $group_forms['edit'][] = "group_{$social_group_type}_edit_form";
    $group_forms['add'][] = "group_{$social_group_type}_add_form";
  }
  if (in_array($form_id, $group_forms['add'], TRUE) || in_array($form_id, $group_forms['edit'], TRUE)) {
    $form['path']['#type'] = 'fieldset';
  }
  $user_forms = [
    'user_register_form',
    'user_form',
  ];

  // Hide the URL alias for user forms, doesn't do anything.
  if (!empty($form['path']) && in_array($form_id, $user_forms, TRUE)) {
    unset($form['path']);
  }
}

/**
 * Implements hook_module_implements_alter().
 */
function social_path_manager_module_implements_alter(&$implementations, $hook) {
  if ($hook === 'form_alter') {
    $group = $implementations['social_path_manager'];
    unset($implementations['social_path_manager']);
    $implementations['social_path_manager'] = $group;
  }
}

/**
 * Implements hook_entity_insert().
 */
function social_path_manager_entity_insert(EntityInterface $entity) {
  _social_path_manager_update_alias($entity, 'create');
}

/**
 * Implements hook_entity_update().
 */
function social_path_manager_entity_update(EntityInterface $entity) {
  _social_path_manager_update_alias($entity, 'update');
}

/**
 * Implements hook_entity_delete().
 */
function social_path_manager_entity_delete(EntityInterface $entity) {
  _social_path_manager_update_alias($entity, 'delete');
}

/**
 * Implements hook_batch_alter().
 */
function social_path_manager_batch_alter(&$batch) {
  if (!isset($batch['source_url'])) {
    return;
  }

  /** @var \Drupal\Core\Url $url */
  $url =& $batch['source_url'];

  // Bulk generate aliases include group tabs.
  if ($url
    ->getRouteName() === 'pathauto.bulk.update.form') {
    $options = $batch['form_state']
      ->getValue('update');
    $action = $batch['form_state']
      ->getValue('action');

    // Check if the operation contains a group update.
    if ($options['canonical_entities:group'] === 'canonical_entities:group') {

      // Set additional batch to create group aliases for group tabs.
      $batch['operations'][] = [
        '_social_path_manager_update_group_tab_aliases',
        [
          'canonical_entities:group',
          $action,
        ],
      ];
      batch_set($batch);
    }
  }
}

/**
 * Common batch processing callback for all operations.
 *
 * @throws \Exception
 */
function _social_path_manager_update_group_tab_aliases($id, $action) {
  $group_ids = array_keys(\Drupal::entityQuery('group')
    ->execute());
  $created = 0;
  $groups = Group::loadMultiple($group_ids);
  foreach ($groups as $group) {
    _social_path_manager_update_alias($group, $action, TRUE);
    $created++;
  }
  \Drupal::service('messenger')
    ->addMessage(\Drupal::translation()
    ->formatPlural($created, 'Generated 1 group tab aliases.', 'Generated @count group tab aliases.'));
}

/**
 * Get a full list of group types.
 *
 * @return array
 *   List of group types.
 */
function _social_path_manager_group_types() {
  $types =& drupal_static(__FUNCTION__);
  if (!isset($types)) {
    $types = [];

    /** @var \Drupal\group\Entity\GroupType $group_type */
    foreach (GroupType::loadMultiple() as $group_type) {
      $types[] = $group_type
        ->id();
    }
  }

  // Allow other modules to change the group types.
  \Drupal::moduleHandler()
    ->alter('social_path_manager_group_types', $types);
  return $types;
}

/**
 * Get a list of tabs used in groups.
 *
 * @return array
 *   Array of group tabs.
 */
function _social_path_manager_group_tabs() {
  $tabs =& drupal_static(__FUNCTION__);
  if (!isset($tabs)) {

    /** @var \Drupal\Core\Menu\LocalTaskManager $taskManager */
    $taskManager = Drupal::service('plugin.manager.menu.local_task');
    $tabs = [];
    $group_tabs = $taskManager
      ->getLocalTasksForRoute('entity.group.canonical');
    $group_tabs = $group_tabs[0];

    // Loop over the available tabs on a group.
    foreach ($group_tabs as $key => $localtask) {

      /** @var \Drupal\Core\Url $localtask */
      $tabs[$key] = $localtask
        ->getRouteName();
    }

    // Allow other modules to change the group tabs.
    \Drupal::moduleHandler()
      ->alter('social_path_manager_group_tabs', $tabs);
  }
  return $tabs;
}

/**
 * Implements hook_social_path_manager_group_tabs_alter().
 */
function social_path_manager_social_path_manager_group_tabs_alter(array &$tabs) {
  foreach ($tabs as $key => $route) {

    // Only allow tabs that are part of the group.
    if ($key === 'social_group.stream' || strpos($key, 'social_group') === FALSE) {
      unset($tabs[$key]);
    }
  }
}

/**
 * Get the url suffix for a giving route of a group.
 *
 * @param \Drupal\group\Entity\GroupInterface $group
 *   The group being updated.
 * @param string $route
 *   The route of the tab being updated.
 *
 * @return string
 *   The url suffix of the tab.
 */
function _social_path_manager_get_path_suffix(GroupInterface $group, $route) {
  $url = Url::fromRoute($route, [
    'group' => $group
      ->id(),
  ]);

  // Get the last part of the url.
  $url = explode('/', $url
    ->getInternalPath());
  return end($url);
}

/**
 * Create the aliases for the views of the group.
 *
 * @param \Drupal\Core\Entity\EntityInterface $entity
 *   The entity that is the parent for the alias.
 * @param string $op
 *   The operation that is being performed.
 * @param bool $bulk
 *   Parameter to tell if the operation is coming from a bulk or not.
 *
 * @throws \Exception
 */
function _social_path_manager_update_alias(EntityInterface $entity, $op, $bulk = FALSE) {
  if ($entity
    ->getEntityTypeId() === 'group') {
    switch ($op) {
      case 'all':
      case 'update':
      case 'create':

        /** @var \Drupal\Core\Path\AliasManager $pam */
        $pam = \Drupal::service('path.alias_manager');

        // If it's a bulk generate then get the alias by path.
        if ($bulk === TRUE) {
          $url = Url::fromRoute('entity.group.canonical', [
            'group' => $entity
              ->id(),
          ]);
          $url = $url
            ->getInternalPath();
          $path['alias'] = $pam
            ->getAliasByPath('/' . $url);
        }
        else {

          // New alias.
          $path = \Drupal::service('pathauto.generator')
            ->updateEntityAlias($entity, 'update');
        }

        // Check if the alias changed.
        // If yes, then change all the other views.
        if (!empty($path)) {
          foreach (_social_path_manager_group_tabs() as $route) {
            $suffix = _social_path_manager_get_path_suffix($entity, $route);

            // Get alias of the group tab.
            $grouptab_alias = $pam
              ->getAliasByPath('/group/' . $entity
              ->id() . '/' . $suffix);

            /** @var \Drupal\Core\Path\AliasStorage $pas */
            $pas = \Drupal::service('path.alias_storage');

            // Check of the alias is an alias or path.
            $is_alias = $pas
              ->aliasExists($grouptab_alias, 'und');

            // Create a new alias when it does not exist.
            if ($op === 'create' && $is_alias === FALSE) {

              // Insert the alias for the other views.
              $pas
                ->save('/group/' . $entity
                ->id() . '/' . $suffix, $path['alias'] . '/' . $suffix, 'und');
            }

            // Update alias by deleting the old one and creating a new one.
            if ($op === 'update' || $op === 'all') {
              \Drupal::service('pathauto.alias_storage_helper')
                ->deleteBySourcePrefix('/group/' . $entity
                ->id() . '/' . $suffix);
              $pas
                ->save('/group/' . $entity
                ->id() . '/' . $suffix, $path['alias'] . '/' . $suffix, 'und');
            }
          }

          // Clear cache of the group tag and rebuild routes.
          \Drupal::service('cache_tags.invalidator')
            ->invalidateTags([
            'group:' . $entity
              ->id(),
          ]);
          \Drupal::service('router.builder')
            ->rebuild();
        }
        break;
      case 'delete':

        // Delete all the aliases of the deleted group.
        $storage_helper = \Drupal::service('pathauto.alias_storage_helper');
        $storage_helper
          ->deleteBySourcePrefix('/group/' . $entity
          ->id());
        break;
    }
  }
}

/**
 * Implements hook_preprocess_HOOK().
 */
function social_path_manager_preprocess_block(&$variables) {

  /** @var \Drupal\node\Entity\Node $node */
  $node = \Drupal::routeMatch()
    ->getParameter('node');

  // Due to PR #1427 there are now two heroes shown on pages
  // with a certain url alias. Due to the refactor in socialpagetitleblock.
  if ($node !== NULL) {
    if (!empty($variables['elements']['#plugin_id']) && $variables['elements']['#plugin_id'] === 'social_page_title_block' && $variables['elements']['#id'] === 'socialblue_pagetitleblock_content') {
      $current_url = Url::fromRoute('<current>');
      $current_path = $current_url
        ->toString();
      $paths_to_exclude = [
        'edit',
        'add',
        'delete',
      ];
      $in_path = str_replace($paths_to_exclude, '', $current_path) !== $current_path;

      // We make sure there are no two heroes shown only page titles.
      if ($in_path) {
        $variables['content']['#type'] = 'page_title';
        if (!empty($variables['content']['#hero_node'])) {
          unset($variables['content']['#hero_node']);
        }
      }
    }
  }
}