You are here

entity_hierarchy_views.module in Entity Reference Hierarchy 8

File

entity_hierarchy_views/entity_hierarchy_views.module
View source
<?php

/**
 * @file
 * Contains entity_hierarchy_views.module..
 */
use Drupal\Core\Routing\RouteMatchInterface;
use Drupal\views\Views;
use Drupal\entity_hierarchy\HierarchyManager;
use Drupal\Core\Form\FormStateInterface;
use Drupal\node\NodeTypeInterface;
use Drupal\Core\Entity\EntityInterface;
use Drupal\node\NodeInterface;
use Drupal\Core\Entity\Display\EntityViewDisplayInterface;

/**
 * Implements hook_help().
 */
function entity_hierarchy_views_help($route_name, RouteMatchInterface $route_match) {
  switch ($route_name) {

    // Main module help for the entity_hierarchy_views module.
    case 'help.page.entity_hierarchy_views':
      $output = '';
      $output .= '<h3>' . t('About') . '</h3>';
      $output .= '<p>' . t('Provides views that may be embedded on hierarchy pages (e.g. to list all child pages by child weight).') . '</p>';
      return $output;
    default:
  }
}

/**
 * Implements hook_form_alter().
 */
function entity_hierarchy_views_form_alter(&$form, \Drupal\Core\Form\FormStateInterface $form_state, $form_id) {

  //  dpm($form_id);
}

/**
 * Implements hook_entity_hierarchy_node_type_settings_form().
 */
function entity_hierarchy_views_form_node_type_form_alter(&$form, FormStateInterface $form_state, $form_id) {

  /** @var \Drupal\entity_hierarchy\HierarchyManager $hierarchy_manager */
  $hierarchy_manager = \Drupal::service('entity_hierarchy.manager');
  $type = $form['type']['#default_value'];

  // The content type
  //  $form = array();
  $config = \Drupal::config('entity_hierarchy.settings');
  if ($hierarchy_manager
    ->hierarchyCanBeParent($type)) {
    $form['hierarchy']['nh_default_children_view'] = array(
      '#type' => 'select',
      '#title' => t('Default Children View'),
      '#multiple' => FALSE,
      '#options' => _entity_hierarchy_views_view_options(),
      '#required' => FALSE,
      '#default_value' => $config
        ->get('nh_default_children_view_' . $type),
      '#description' => t('Default for the embed children view feature.'),
    );
  }
  $form['#entity_builders'][] = 'entity_hierarchy_views_form_node_type_form_builder';
  return $form;
}
function entity_hierarchy_views_form_node_type_form_builder($entity_type, NodeTypeInterface $type, &$form, FormStateInterface $form_state) {
  $node_type = $type
    ->get('type');
  $config = \Drupal::getContainer()
    ->get('config.factory')
    ->getEditable('entity_hierarchy.settings');
  $config
    ->set('nh_default_children_view_' . $node_type, $form_state
    ->getValue('nh_default_children_view'));
  $config
    ->save();
}

/**
 * Prepare a list of views for selection.
 */
function _entity_hierarchy_views_view_options() {
  $options = array();
  $options[0] = '-- ' . t('NONE') . ' --';
  $views = _entity_hierarchy_views_get_embed_views();
  foreach ($views as $item) {
    $options[$item['name'] . ':' . $item['display']] = $item['title'];
  }
  return $options;
}

/**
 * Get a list of views that can be embedded.
 */
function _entity_hierarchy_views_get_embed_views($reset = FALSE) {
  $used_views =& drupal_static(__FUNCTION__);
  if (!isset($used_views) || $reset) {
    $views = Views::getApplicableViews('hierarchy_embed_display');
    foreach ($views as $data) {
      list($view_id, $display_id) = $data;
      $view = Views::getView($view_id);
      $view
        ->setDisplay($display_id);
      $display_object = $view
        ->getDisplay();
      $display_title = $display_object->display['display_title'];
      $used_views[] = array(
        'name' => $view_id,
        'display' => $display_id,
        'title' => $display_title,
      );
      $view
        ->destroy();
    }
  }
  return isset($used_views) ? $used_views : array();
}

/**
 * @todo Please document this function.
 * @see http://drupal.org/node/1354
 */
function entity_hierarchy_views_form_node_form_alter(&$form, FormStateInterface $form_state, $form_id) {

  //  $form = array();
  $node = $form_state
    ->getFormObject()
    ->getEntity();

  /** @var \Drupal\entity_hierarchy\HierarchyManager $hierarchy_manager */
  $hierarchy_manager = \Drupal::service('entity_hierarchy.manager');
  $type = $node
    ->getType();

  //  dpm($node);
  //  dpm($node->nh_children_view);
  $default_value = NULL;
  if (!empty($node->nh_children_view)) {
    $display = !empty($node->nh_children_view_display) ? $node->nh_children_view_display : 'default';
    $default_value = $node->nh_children_view . ':' . $display;
  }
  if ($node && $hierarchy_manager
    ->hierarchyCanBeParent($type)) {
    $form['hierarchy']['nh_children_view'] = array(
      '#type' => \Drupal::currentUser()
        ->hasPermission('edit embedded child view') ? 'select' : 'value',
      '#title' => t('Embed Children View'),
      '#multiple' => FALSE,
      '#options' => _entity_hierarchy_views_view_options(),
      '#required' => FALSE,
      '#default_value' => $default_value,
      '#description' => t("Embed a view containing this node's children into the node's page view"),
    );
    $form['#entity_builders'][] = 'entity_hierarchy_views_node_builder';
  }
}

/**
 * Entity form builder adds the hierarchy information to the node object. More
 * officially, this builds an updated entity object based upon the submitted
 * form values.
 *
 * This function is called from the #entity_builders callback.
 *
 * @see entity_hierarchy_views_form_node_form_alter
 * @see EntityForm::buildEntity
 *
 * As per https://www.drupal.org/node/2420295, an entity field may be better
 * suited to this task.
 * @see \Drupal\Core\Entity\ContentEntityBase
 * @see core/lib/Drupal/Core/Entity/ContentEntityBase.php
 */
function entity_hierarchy_views_node_builder($entity_type, NodeInterface $node, &$form, FormStateInterface $form_state) {
  $node->nh_children_view = $form_state
    ->getValue('nh_children_view');
}

/**
 * Implements hook_ENTITY_TYPE_load().
 */
function entity_hierarchy_views_node_load($nodes) {
  foreach ($nodes as $node) {
    $nid = $node
      ->id();
    $results = db_query('SELECT nh_children_view, nh_children_view_display FROM {entity_hierarchy_views} WHERE nid = :nid', array(
      ':nid' => $nid,
    ))
      ->fetchObject();

    //    dpm($node);
    //    dpm($results);
    if ($results) {
      $node->nh_children_view = $results->nh_children_view;
      $node->nh_children_view_display = $results->nh_children_view_display;
    }
  }
}

/**
 * Implements hook_ENTITY_TYPE_prepare_form().
 *
 * Set a default embedded view.
 */
function entity_hierarchy_views_node_prepare_form(EntityInterface $node, $operation, FormStateInterface $form_state) {
  $config = \Drupal::getContainer()
    ->get('config.factory')
    ->getEditable('entity_hierarchy.settings');

  // Set the default children view if there is one for this type and if the node has not been saved yet.
  if (empty($node
    ->id()) && empty($node->nh_children_view) && ($children_view = $config
    ->get('nh_default_children_view_' . $node
    ->getType()))) {
    list($node->nh_children_view, $node->nh_children_view_display) = explode(':', $children_view);
  }
}

/**
 * Implements hook_ENTITY_TYPE_insert().
 */
function entity_hierarchy_views_node_insert(EntityInterface $node) {
  $config = \Drupal::getContainer()
    ->get('config.factory')
    ->getEditable('entity_hierarchy.settings');

  // If the user has access to edit the view, update as usual.
  if (\Drupal::currentUser()
    ->hasPermission('edit embedded child view')) {
    entity_hierarchy_views_update($node);
  }
  elseif ($children_view = $config
    ->get('nh_default_children_view_' . $node
    ->getType())) {
    list($view, $display) = explode(':', $children_view);
    $id = db_insert('entity_hierarchy_views')
      ->fields(array(
      'nid' => $node->nid,
      'nh_children_view' => $view,
    ))
      ->execute();
  }
}

/**
 * Implements hook_ENTITY_TYPE_update().
 */
function entity_hierarchy_views_node_update(EntityInterface $node) {
  return entity_hierarchy_views_update($node);
}

/**
 * Update the given embedded view.
 */
function entity_hierarchy_views_update($node) {
  if (\Drupal::currentUser()
    ->hasPermission('edit embedded child view')) {
    db_delete('entity_hierarchy_views')
      ->condition('nid', $node
      ->id())
      ->execute();
    if (!empty($node->nh_children_view)) {
      $parts = explode(':', $node->nh_children_view);
      if (!empty($parts[0])) {
        $view = $parts[0];
      }
      if (!empty($parts[1])) {
        $display = $parts[1];
      }
      else {

        // If this update is not from a form submit then the display may be stored separately.
        $display = !empty($node->nh_children_view_display) ? $node->nh_children_view_display : 'default';
      }
      $id = db_insert('entity_hierarchy_views')
        ->fields(array(
        'nid' => $node
          ->id(),
        'nh_children_view' => $view,
        'nh_children_view_display' => $display,
      ))
        ->execute();
    }
  }
}

/**
 * Delete the node_hierarchy_views row when a node is deleted.
 *
 * Implements hook_ENTITY_TYPE_delete().
 */
function entity_hierarchy_views_node_delete(EntityInterface $node) {
  db_delete('entity_hierarchy_views')
    ->condition('nid', $node
    ->id())
    ->execute();
}

/**
 * Implements hook_ENTITY_TYPE_view().
 *
 * Add the embedded children view to the node body if appropriate.
 *
 * Todo: hide view if empty and user adds title.
 * See https://www.drupal.org/node/1343430
 */
function entity_hierarchy_views_node_view(array &$build, NodeInterface $node, EntityViewDisplayInterface $display, $view_mode) {
  if ($view_mode == 'full' && \Drupal::currentUser()
    ->hasPermission('access embedded child view')) {
    static $depth = 0;

    // Make sure we don't go through more than 3 iterations to prevent memory or call stack errors.
    if ($depth++ < 3) {

      // Get the arguments to send to the view. This should allow other view arguments to work.
      $current_path = \Drupal::service('path.current')
        ->getPath();
      $arguments = explode('/', $current_path);

      // First arg will be 'node', the second will be the node id, so remove them.
      array_shift($arguments);
      array_shift($arguments);
      if ($view = Views::getView($node->nh_children_view)) {

        // If we want a title, add the following:
        // $title = $view->getTitle();
        // $view->setTitle('$title'); might work
        // $build['entity_hierarchy_views_embed']['#prefix'] = '<h2 id="hierarchy-title" class ="views-title">'.$title.'</h2>';
        $display = @$node->nh_children_view_display ? @$node->nh_children_view_display : 'default';
        $view
          ->setDisplay($display);
        $view
          ->setArguments($arguments);
        $build['entity_hierarchy_views_embed'] = $view
          ->render();
        $build['entity_hierarchy_views_embed']['#weight'] = 1001;
      }
    }
  }
}

Functions

Namesort descending Description
entity_hierarchy_views_form_alter Implements hook_form_alter().
entity_hierarchy_views_form_node_form_alter @todo Please document this function.
entity_hierarchy_views_form_node_type_form_alter Implements hook_entity_hierarchy_node_type_settings_form().
entity_hierarchy_views_form_node_type_form_builder
entity_hierarchy_views_help Implements hook_help().
entity_hierarchy_views_node_builder Entity form builder adds the hierarchy information to the node object. More officially, this builds an updated entity object based upon the submitted form values.
entity_hierarchy_views_node_delete Delete the node_hierarchy_views row when a node is deleted.
entity_hierarchy_views_node_insert Implements hook_ENTITY_TYPE_insert().
entity_hierarchy_views_node_load Implements hook_ENTITY_TYPE_load().
entity_hierarchy_views_node_prepare_form Implements hook_ENTITY_TYPE_prepare_form().
entity_hierarchy_views_node_update Implements hook_ENTITY_TYPE_update().
entity_hierarchy_views_node_view Implements hook_ENTITY_TYPE_view().
entity_hierarchy_views_update Update the given embedded view.
_entity_hierarchy_views_get_embed_views Get a list of views that can be embedded.
_entity_hierarchy_views_view_options Prepare a list of views for selection.