micronode-1.0.0/micronode.module

micronode.module
<?php

/**
 * @file
 * Contains micronode hooks.
 */

declare(strict_types=1);

use Drupal\Core\Access\AccessResult;
use Drupal\Core\Cache\Cache;
use Drupal\Core\Config\Entity\ThirdPartySettingsInterface;
use Drupal\Core\Entity\EntityInterface;
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\Session\AccountInterface;
use Drupal\node\NodeInterface;
use Drupal\node\NodeTypeInterface;

/**
 * Implements hook_form_BASE_FORM_ID_alter().
 */
function micronode_form_node_type_form_alter(&$form, FormStateInterface $form_state, $form_id) {
  /** @var \Drupal\node\NodeTypeInterface $type */
  $type = $form_state->getFormObject()->getEntity();

  $settings = $type->getThirdPartySettings('micronode');
  $label = $type->label();
  $form['micronode'] = [
    '#type' => 'details',
    '#title' => t('Micro-content settings'),
    '#tree' => TRUE,
  ];
  if (isset($form['additional_settings']) && $form['additional_settings']['#type'] === 'vertical_tabs') {
    $form['micronode']['#group'] = 'additional_settings';
  }
  $form['micronode']['micronode_is_microcontent'] = [
    '#type' => 'checkbox',
    '#title' => t('Is micro-content'),
    '#description' => t('If true, this @label will not be accessible on its own page, except for users with permission to edit it. It will also be removed from admin lists of content.', [
      '@label' => !empty($label) ? $label : t('content'),
    ]),
    '#default_value' => !empty($settings['micronode_is_microcontent']),
  ];

  $form['#entity_builders'][] = 'micronode_microcontent_entity_builder';
  $form['#validate'][] = 'micronode_node_type_form_validate';
}

/**
 * Additional entity builder callback for our node type forms.
 *
 * @see micronode_form_node_type_form_alter()
 */
function micronode_microcontent_entity_builder($entity_type, ThirdPartySettingsInterface $type, &$form, FormStateInterface $form_state) {
  $microcontent_values = $form_state->getValue('micronode');
  foreach ($microcontent_values as $key => $value) {
    $type->setThirdPartySetting('micronode', $key, $value);
  }
}

/**
 * Validate handler for node type forms.
 *
 * @see micronode_form_node_type_form_alter()
 */
function micronode_node_type_form_validate(&$form, FormStateInterface $form_state) {
  $type = $form_state->getFormObject()->getEntity();
  assert($type instanceof NodeTypeInterface);
  // We are only concerned with update operations.
  if ($type->isNew()) {
    return;
  }
  $type_setting = $type->getThirdPartySetting('micronode', 'micronode_is_microcontent', NULL);
  $original_setting = $form['micronode']['micronode_is_microcontent']['#default_value'] ?? NULL;
  if (is_null($original_setting)) {
    return;
  }
  // If the type has changed its micro-content status, wipe out cached data,
  // since nodes would now possibly need to be displayed in different places
  // based on their new status (i.e. views).
  if (!is_null($type_setting) && ((bool) $original_setting <> (bool) $type_setting)) {
    foreach (Cache::getBins() as $cache_backend) {
      $cache_backend->deleteAll();
    }
  }
}

/**
 * Implements hook_ENTITY_TYPE_access().
 */
function micronode_node_access(EntityInterface $entity, $operation, AccountInterface $account) {
  // Check access for micro-content.
  // No need to check admin operations or editor's access, they can see it.
  if ($operation === 'view' && !$entity->access('update', $account)) {
    // Bail out early if this node hasn't been flagged as microcontent.
    /** @var \Drupal\node\NodeInterface $entity */
    if (!micronode_is_micro_content($entity)) {
      return AccessResult::neutral();
    }
    // Deny access to non-editor users (visitors) that are trying to see this
    // node on its own canonical route.
    $route_match = \Drupal::routeMatch();
    if ($route_match->getRouteName() === 'entity.node.canonical') {
      $node_from_route = $route_match->getParameter('node');
      if ($node_from_route->id() == $entity->id()) {
        return AccessResult::forbidden('This content is marked as hidden micro-content and cannot be accessed through this path.');
      }
    }
  }

  return AccessResult::neutral();
}

/**
 * Implements hook_menu_links_discovered_alter().
 */
function micronode_menu_links_discovered_alter(&$links) {
  // Bail out if admin toolbar isn't present.
  if (!\Drupal::moduleHandler()->moduleExists('admin_toolbar_tools')) {
    return;
  }

  $micro_content_types = micronode_get_node_types(TRUE);

  // Move micro-content types out of the existing "Add Content" list, and place
  // them under the new "Add Micro-Content" we have created in our yml file.
  foreach ($micro_content_types as $type_id => $type) {
    $links["admin_toolbar_tools.extra_links:node.add.{$type_id}"]['parent'] = 'micronode.add_microcontent_page';
  }
  // Set the weight of the "Add content" link so that it shows up right before
  // the "Add micro-content" one.
  $links['admin_toolbar_tools.extra_links:node.add']['weight'] = -14;
}

/**
 * Helper to return types filtered by the micro-content flag.
 *
 * @param bool|null $return_microcontent
 *   What to include in the results:
 *   - TRUE: Only micro-content types.
 *   - FALSE: Only non-micro-content types.
 *   - NULL: Return all types. This is the default option.
 *
 * @return \Drupal\node\NodeTypeInterface[]
 *   An associative array of content types keyed by their type ids.
 */
function micronode_get_node_types($return_microcontent = NULL) {
  $cache = \Drupal::service('cache.default');
  $arg_string = $return_microcontent ? 'TRUE' : ($return_microcontent === NULL ? 'NULL' : 'FALSE');
  $cid = "micronode_get_node_types:$arg_string";
  if ($cached = $cache->get($cid)) {
    return $cached->data;
  }
  if (!isset($types)) {
    /** @var \Drupal\node\NodeTypeInterface[] $types */
    $types = [];
    foreach (\Drupal::entityTypeManager()->getStorage('node_type')->loadMultiple() as $type) {
      /** @var \Drupal\node\NodeTypeInterface $type */
      // If the caller requested all types, just add it here.
      if ($return_microcontent === NULL) {
        $types[$type->id()] = $type;
        continue;
      }
      $is_microcontent = (bool) $type->getThirdPartySetting('micronode', 'micronode_is_microcontent', FALSE);
      if ($return_microcontent === TRUE && $is_microcontent === TRUE) {
        $types[$type->id()] = $type;
      }
      elseif ($return_microcontent === FALSE && $is_microcontent === FALSE) {
        $types[$type->id()] = $type;
      }
    }
  }
  // Cache the result.
  $cache->set(
    $cid,
    $types,
    Cache::PERMANENT,
    ['config:node_type_list']
  );

  return $types;
}

/**
 * Detects whether a given node is to be treated as micro-content.
 *
 * @param \Drupal\node\NodeInterface $node
 *   The node object.
 *
 * @return bool
 *   TRUE if the node passed in is to be treated as micro-content, FALSE
 *   otherwise.
 */
function micronode_is_micro_content(NodeInterface $node) {
  $micro_content_types = array_keys(micronode_get_node_types(TRUE));
  return in_array($node->getType(), $micro_content_types, TRUE);
}

/**
 * Implements hook_form_views_exposed_form_alter().
 */
function micronode_form_views_exposed_form_alter(&$form, FormStateInterface $form_state, $form_id) {
  // Remove types from exposed filters when 'Is Micro-content' filter is in use.
  if ($view = $form_state->getStorage()['view']) {
    $filters = $view->getHandlers('filter');
    if (isset($filters['micronode_is_microcontent'])) {
      $return_microcontent = $view->display_handler->getHandler('filter', 'micronode_is_microcontent')->value;
      $allowed_bundles = array_keys(micronode_get_node_types($return_microcontent));
      foreach ($filters as $id => $definition) {
        if (isset($definition['exposed']) && $definition['exposed'] && $definition['plugin_id'] == 'bundle') {
          foreach ($form[$id]['#options'] as $key => $value) {
            if (is_string($value) && !in_array($key, $allowed_bundles, TRUE)) {
              unset($form[$id]['#options'][$key]);
            }
          }
        }
      }
    }
  }
}

/**
 * Implements hook_views_plugins_wizard_alter().
 */
function micronode_views_plugins_wizard_alter(array &$plugins) {
  // Hijack the Node views wizard plugin and make it use our subclass instead.
  if (!empty($plugins['node'])) {
    $plugins['node']['class'] = 'Drupal\micronode\Plugin\views\wizard\Micronode';
  }
}

/**
 * Implements hook_element_info_alter().
 */
function micronode_element_info_alter(array &$info) {
  // Add a #process method to disallow micronodes from entity_autocomplete
  // unless they are explicitly allowed.
  array_unshift($info['entity_autocomplete']['#process'], '\Drupal\micronode\MicronodeAutocompleteHelper::disallowMicronodes');
}

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

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