You are here

search_by_page_nodes.module in Search by Page 8

Module file for Search by Page Nodes, a sub-module for Search by Page.

Allows you to add node pages by content type to Search by Page.

File

search_by_page_nodes/search_by_page_nodes.module
View source
<?php

/**
 * @file
 * Module file for Search by Page Nodes, a sub-module for Search by Page.
 *
 * Allows you to add node pages by content type to Search by Page.
 * @ingroup search_by_page
 */
use Drupal\Core\Session\AccountInterface;
use Drupal\Component\Utility\Html;

/**
 * Implements Search by Page hook_search_by_page_paths().
 *
 * Returns a list of all the nodes that should be indexed.
 */
function search_by_page_nodes_search_by_page_paths($environment) {

  // What node types do they want to index?
  $typelist = search_by_page_setting_get('search_by_page_nodes_types_indexed', $environment, []);
  if (!is_array($typelist) || !count($typelist)) {
    return [];
  }

  // This variable comes from a checkbox array form element. So it
  // gives us an array like 'page' => 'page', 'story' => 0
  // meaning page should be indexed, but not story
  // so pick out the ones to actually index
  $toindex = [];
  foreach ($typelist as $key => $item) {
    if ($item) {
      $toindex[] = $key;
    }
  }
  if (!count($toindex)) {
    return [];
  }

  // Find all published nodes of those types, and build array of paths
  // Note that we don't want to check for access permissions here! We
  // want to index everything, independent of access rights. Access
  // permission checking is done during the search step -- see
  // hook_search_by_page_query_modify() implementation below. This is the same
  // procedure followed in node_search(), which performs searching for
  // the core Search module, and node_update_index(), which indexes
  // everything for Search without access checks.
  $res = \Drupal::database()
    ->query('SELECT n.nid, n.language FROM {node} n WHERE n.status=1 AND n.type IN (:toindex)', [
    ':toindex' => $toindex,
  ])
    ->fetchAll();
  $role = search_by_page_setting_get('search_by_page_nodes_role', $environment, AccountInterface::ANONYMOUS_ROLE);
  $min_time = search_by_page_setting_get('search_by_page_nodes_min_time', $environment, 1);
  $max_time = search_by_page_setting_get('search_by_page_nodes_max_time', $environment, 0);
  $languageManager = new \Drupal\Core\Language\LanguageManager();
  $langs = $languageManager
    ->getLanguages();
  $langs = array_keys($langs);
  $ret = [];
  foreach ($res as $item) {
    $stuff = [
      'id' => $item->nid,
      'role' => $role,
      'min_time' => $min_time,
      'max_time' => $max_time,
    ];
    if ($item->language && $item->language != LANGUAGE_NONE) {
      $stuff['languages'] = [
        $item->language,
      ];
    }
    else {

      // language-neutral - index in all languages
      $stuff['languages'] = $langs;
    }
    $ret['node/' . $item->nid] = $stuff;
  }
  return $ret;
}

/**
 * Implements Search by Page hook_search_by_page_query_modify().
 *
 * Adds an access permission check to the search query.
 */
function search_by_page_nodes_search_by_page_query_modify($environment, $query) {
  $cond = new \Drupal\Core\Database\Query\Condition('AND');
  if (!\Drupal::currentUser()
    ->hasPermission('access content')) {

    // This user cannot access content, so don't bother with the query
    // mods, they should not see anything from this module.
    $cond
      ->where('0=1');
    return $cond;
  }

  // Join to the node table and mark it as a node access query.
  $query
    ->leftJoin('node', 'sbpn_n', 'sbpn_n.nid = sp.modid');
  $query
    ->addTag('node_access');

  // Make sure also only to allow published content.
  $cond = new \Drupal\Core\Database\Query\Condition('AND');
  $cond
    ->condition('sbpn_n.status', 1);
  return $cond;
}

/**
 * Implements Search by Page hook_search_by_page_details().
 *
 * Returns details for a particular node ID, for particular search keys.
 */
function search_by_page_nodes_search_by_page_details($id, $environment, $keys = NULL) {
  $id = intval($id);
  if (!$id) {
    return NULL;
  }
  $node = \Drupal\node\Entity\Node::load($id);
  if (!$node->title) {
    return NULL;
  }
  $type = node_type_get_type($node);

  // Get basic node info
  $ret = [
    'type' => Html::escape($type->name),
    'title' => search_by_page_strip_tags($node->title, $environment),
    'user' => theme('username', [
      'account' => $node,
    ]),
    'date' => $node->changed,
    'object' => $node,
  ];
  if (!$keys) {
    return $ret;
  }

  // See if we want to display an excerpt or a teaser
  if (\Drupal::service('search_by_page.settings')
    ->getSetting('search_by_page_nodes_display_type', $environment, 'excerpts') == 'excerpts') {
    $content = search_by_page_stored_page_content('search_by_page_nodes', $id, $environment);
    if ($content) {
      $ret['snippet'] = \Drupal::service('search_by_page.settings')
        ->excerpt($keys, $content);
    }
  }
  else {

    // We want a teaser
    $view = node_view($node, 'teaser');
    $ret['snippet'] = search_by_page_strip_tags(\Drupal::service('renderer')
      ->render($view), $environment);
  }
  return $ret;
}

/**
 * Implements Search by Page hook_search_by_page_settings().
 *
 * Adds a node type selection form to the Search by Page settings page.
 */
function search_by_page_nodes_search_by_page_settings($environment) {
  $form = [];
  $form['search_by_page_nodes'] = [
    '#type' => 'fieldset',
    '#collapsible' => TRUE,
    '#weight' => -80,
    '#title' => t('Nodes'),
  ];
  $form['search_by_page_nodes']['search_by_page_nodes_types_indexed'] = [
    '#type' => 'checkboxes',
    '#title' => t('Content types to index'),
    '#default_value' => \Drupal::service('search_by_page.settings')
      ->getSetting('search_by_page_nodes_types_indexed', $environment, []),
    '#options' => node_type_get_names(),
    '#description' => t('Choose which content types you would like to have indexed by Search by Page'),
  ];
  $form['search_by_page_nodes']['search_by_page_nodes_display_type'] = [
    '#type' => 'radios',
    '#title' => t('Display in search results'),
    '#default_value' => \Drupal::service('search_by_page.settings')
      ->getSetting('search_by_page_nodes_display_type', $environment, 'excerpts'),
    '#options' => [
      'excerpts' => t('Excerpts with search keywords highlighted'),
      'teasers' => t('Teasers'),
    ],
    '#description' => t('Note that search keyword highlighting may not work correctly if you are using a stemming module.'),
  ];
  $form['search_by_page_nodes']['search_by_page_nodes_role'] = [
    '#type' => 'radios',
    '#title' => t('Role for indexing'),
    '#options' => user_roles(),
    '#default_value' => \Drupal::service('search_by_page.settings')
      ->getSetting('search_by_page_nodes_role', $environment, AccountInterface::ANONYMOUS_ROLE),
    '#weight' => 4,
    '#description' => t("When Search by Page indexes pages for searching, the pages will be viewed from the perspective and permissions of a user with this role."),
  ];
  $times = [
    '1' => t('1 second'),
    '3600' => t('1 hour'),
    '86400' => t('1 day'),
    '604800' => t('1 week'),
    '31449600' => t('1 year'),
    '0' => t('Never'),
  ];
  $form['search_by_page_nodes']['search_by_page_nodes_min_time'] = [
    '#type' => 'select',
    '#title' => t('Minimum reindexing time'),
    '#options' => $times,
    '#default_value' => \Drupal::service('search_by_page.settings')
      ->getSetting('search_by_page_nodes_min_time', $environment, 1),
    '#weight' => 5,
    '#description' => t("After indexing any new and updated content items, Search by Page also cycles through previously-indexed content items, in case the rendered view of the item page has changed (even though the item itself hasn't changed, your site may include other information with the main content that can change independently). On some sites, you may want to limit the amount of reindexing, by setting a minimum time -- content will not be reindexed until this time has passed, unless the content item itself or its comments have been updated."),
  ];
  $form['search_by_page_nodes']['search_by_page_nodes_max_time'] = [
    '#type' => 'select',
    '#title' => t('Maximum reindexing time'),
    '#options' => $times,
    '#default_value' => \Drupal::service('search_by_page.settings')
      ->getSetting('search_by_page_nodes_max_time', $environment, 0),
    '#weight' => 6,
    '#description' => t("Conversely to the minimum reindexing time (see above), Search by Page can be set to prioritize reindexing each content item page (by marking it as needing immediate reindexing) after this amount of time has passed. This has higher priority than the cycle-through reindexing of the setting above.") . ' ' . t('But be careful with this setting! If you set it too small, it can interfere with new content being indexed, because the reindexed content will have equal priority to content that has never been indexed. So make sure your settings allow for enough time for new content to be indexed before forcing reindexing.'),
  ];
  return $form;
}

/**
 * Implements hook_node_update().
 *
 * When a node is updated, sets it up for reindexing at the next cron run.
 */
function search_by_page_nodes_node_update($node) {
  search_by_page_force_reindex('search_by_page_nodes', $node->nid);
}

/**
 * Implements hook_node_delete().
 *
 * When a node is deleted, remove it from the search index.
 */
function search_by_page_nodes_node_delete($node) {
  search_by_page_force_remove('search_by_page_nodes', $node->nid);
}

/**
 * Implements hook_comment_insert().
 *
 * When a comment is added, edited, or deleted, set its node for reindexing
 * at the next cron run.
 */
function search_by_page_nodes_comment_insert($comment) {
  search_by_page_force_reindex('search_by_page_nodes', $comment->nid);
}

/**
 * Implements hook_comment_update().
 *
 * When a comment is added, edited, or deleted, set its node for reindexing
 * at the next cron run.
 */
function search_by_page_nodes_comment_update($comment) {
  search_by_page_force_reindex('search_by_page_nodes', $comment->nid);
}

/**
 * Implements hook_comment_delete().
 *
 * When a comment is added, edited, or deleted, set its node for reindexing
 * at the next cron run.
 */
function search_by_page_nodes_comment_delete($comment) {
  search_by_page_force_reindex('search_by_page_nodes', $comment->nid);
}

/**
 * Implements hook_comment_publish().
 *
 * When a comment is added, edited, or deleted, set its node for reindexing
 * at the next cron run.
 */
function search_by_page_nodes_comment_publish($comment) {
  search_by_page_force_reindex('search_by_page_nodes', $comment->nid);
}

/**
 * Implements hook_comment_unpublish().
 *
 * When a comment is added, edited, or deleted, set its node for reindexing
 * at the next cron run.
 */
function search_by_page_nodes_comment_unpublish($comment) {
  search_by_page_force_reindex('search_by_page_nodes', $comment->nid);
}

Functions

Namesort descending Description
search_by_page_nodes_comment_delete Implements hook_comment_delete().
search_by_page_nodes_comment_insert Implements hook_comment_insert().
search_by_page_nodes_comment_publish Implements hook_comment_publish().
search_by_page_nodes_comment_unpublish Implements hook_comment_unpublish().
search_by_page_nodes_comment_update Implements hook_comment_update().
search_by_page_nodes_node_delete Implements hook_node_delete().
search_by_page_nodes_node_update Implements hook_node_update().
search_by_page_nodes_search_by_page_details Implements Search by Page hook_search_by_page_details().
search_by_page_nodes_search_by_page_paths Implements Search by Page hook_search_by_page_paths().
search_by_page_nodes_search_by_page_query_modify Implements Search by Page hook_search_by_page_query_modify().
search_by_page_nodes_search_by_page_settings Implements Search by Page hook_search_by_page_settings().