symlink-8.x-1.x-dev/symlink.module

symlink.module
<?php

/**
 * @file
 * Contains symlink.module.
 */

use Drupal\Core\Routing\RouteMatchInterface;
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\Entity\EntityInterface;
use Drupal\Core\Entity\Display\EntityViewDisplayInterface;

/**
 * Implements hook_help().
 */
function symlink_help($route_name, RouteMatchInterface $route_match) {
  switch ($route_name) {
    // Main module help for the symlink module.
    case 'help.page.symlink':
      $output = '<h3>' . t('About symlink') . '</h3>';
      $output .= '<p>' . t("Symlinks are special nodes that will point to
      target nodes and display the content of the target node when they are
      displayed. This will let you have a better experience when you need to
      add a node in multiple locations of the menu try while maintaining a
      proper trail/breadcrumb structure.") . '</p>';
      return $output;

    default:
      return '';
  }
}

/**
 * Implements hook_form_FORM_ID_alter().
 */
function symlink_form_node_symlink_form_alter(&$form, FormStateInterface $form_state, $form_id) {
  $symlink = $_REQUEST['symlink'] ?? '';

  if (!$symlink) {
    return;
  }

  $node = _symlink_get_target_node($symlink);

  if (!$node) {
    return;
  }

  $form['field_symlink']['widget'][0]['value']['#default_value'] = empty($node->get('nid')->value) ? '' : "node/{$node->id()}";
  $form['title']['widget'][0]['value']['#default_value'] = $node->get('title')->getString() ?? '';
}

/**
 * Implements hook_ENTITY_TYPE_view().
 */
function symlink_node_view(array &$build, EntityInterface $entity, EntityViewDisplayInterface $display, $view_mode) {
  if (
      (method_exists($entity, 'getType'))
      && (method_exists($entity, 'get'))
      && ('symlink' != $entity->getType())
  ) {
    return;
  }

  $symlink = $entity->get('field_symlink')->getString();
  $node = _symlink_get_target_node($symlink);

  if (!$node) {
    return;
  }

  $output = \Drupal::entityTypeManager()
    ->getViewBuilder('node')
    ->view($node, $view_mode);

  // Remove the redundant node title.
  $output['#node']->setTitle("");

  $build['symlink_target_content'] = [
    '#markup' => \Drupal::service('renderer')->render($output),
  ];
}

/**
 * Helper function to find the node referenced by the symlink.
 *
 * @param string $symlink
 *   The node's canonical id.
 *
 * @return mixed|NULL $node
 *   The target node object or NULL if not found.
 */
function _symlink_get_target_node(string $symlink) {
  $exploded_symlink = explode('/', $symlink, 2);

  if (count($exploded_symlink) != 2) {
    // TODO: Log something here
    return NULL;
  }

  [$entity_type_id, $nid] = $exploded_symlink;

  $nid = (int) $nid;

  if ($nid) {
    try {
      $storage = Drupal::entityTypeManager()->getStorage($entity_type_id);
    } catch (Exception $e) {
      \Drupal::logger('symlink')->error($e->getMessage(), ['entity_type_id' => $entity_type_id]);
      return NULL;
    }

    $node = $storage->load($nid);

    if (
      (method_exists($node, 'getType'))
      && (method_exists($node, 'get'))
      && ('symlink' == $node->getType())
    ) {
      $existing_symlink = $node->get('field_symlink')->getString();

      if ($existing_symlink) {
        // If the target of a symlink is another symlink, then dig deeper until
        // a valid node target is found.
        return _symlink_get_target_node($existing_symlink);
      }
      else {
        return NULL;
      }

    }

    return $node;

  }
  else {
    return NULL;
  }
}

Главная | Обратная связь

drupal hosting | друпал хостинг | it patrol .inc