You are here

sbp_nodes.module in Search by Page 6

Same filename and directory in other branches
  1. 7 sbp_nodes.module

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

sbp_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
 */

/**
 * Implementation of Search by Page hook_sbp_paths().
 *
 * Returns a list of all the nodes that should be indexed.
 */
function sbp_nodes_sbp_paths($environment) {

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

  // 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 = array();
  foreach ($typelist as $key => $item) {
    if ($item) {
      $toindex[] = $key;
    }
  }
  if (!count($toindex)) {
    return array();
  }

  // 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_sbp_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 = db_query('SELECT n.nid, n.language FROM {node} n WHERE n.status=1 AND n.type IN (' . db_placeholders($toindex, 'varchar') . ')', $toindex);
  $role = search_by_page_setting_get('sbp_nodes_role', $environment, DRUPAL_ANONYMOUS_RID);
  $min_time = search_by_page_setting_get('sbp_nodes_min_time', $environment, 1);
  $max_time = search_by_page_setting_get('sbp_nodes_max_time', $environment, 0);
  $langs = language_list();
  $langs = array_keys($langs);
  $ret = array();
  while ($item = db_fetch_object($res)) {
    $stuff = array(
      'id' => $item->nid,
      'role' => $role,
      'min_time' => $min_time,
      'max_time' => $max_time,
    );
    if ($item->language) {
      $stuff['languages'] = array(
        $item->language,
      );
    }
    else {

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

/**
 * Implementation of Search by Page hook_sbp_query_modify().
 *
 * Adds an access permission check to the search query.
 */
function sbp_nodes_sbp_query_modify($environment) {

  // Get node access permissions from db_rewrite_sql()
  $stuff = search_by_page_unique_rewrite('sbpn_');

  // Form join/where clauses, only allowing published nodes, plus
  // node access stuff
  $join = '';
  if ($stuff[0]) {
    $join .= 'LEFT JOIN ({node} sbpn_n ' . $stuff[0] . ')';
  }
  else {

    // PostgreSQL doesn't support simple joins with ().
    $join .= 'LEFT JOIN {node} sbpn_n';
  }
  $join .= ' ON sbpn_n.nid = sp.modid';
  $where = 'sbpn_n.status = 1';
  if ($stuff[1]) {
    $where .= ' AND ' . $stuff[1];
  }
  return array(
    'join' => $join,
    'where' => $where,
    'arguments' => array(),
  );
}

/**
 * Implementation of Search by Page hook_sbp_details().
 *
 * Returns details for a particular node ID, for particular search keys.
 */
function sbp_nodes_sbp_details($id, $environment, $keys = NULL) {
  $id = intval($id);
  if (!$id) {
    return NULL;
  }
  $node = node_load($id, NULL, TRUE);
  if (!$node->title) {
    return NULL;
  }

  // Get basic node info
  $ret = array(
    'type' => check_plain(node_get_types('name', $node)),
    'title' => search_by_page_strip_tags($node->title, $environment),
    'user' => theme('username', $node),
    'date' => $node->changed,
  );
  if (!$keys) {
    return $ret;
  }

  // See if we want to display an excerpt or a teaser
  if (search_by_page_setting_get('sbp_nodes_display_type', $environment, 'excerpts') == 'excerpts') {

    // Render this node, to get snippet, if excerpt is requested
    if ($keys) {
      $content = menu_execute_active_handler('node/' . $id);
      if (!is_int($content)) {
        $ret['snippet'] = search_by_page_excerpt($keys, search_by_page_strip_tags($content, $environment));
      }
    }
  }
  else {

    // We want a teaser
    $ret['snippet'] = search_by_page_strip_tags(node_view($node, TRUE, FALSE, FALSE), $environment);
  }
  return $ret;
}

/**
 * Implementation of Search by Page hook_sbp_settings().
 *
 * Adds a node type selection form to the Search by Page settings page.
 */
function sbp_nodes_sbp_settings($environment) {
  $form = array();
  $form['sbp_nodes'] = array(
    '#type' => 'fieldset',
    '#collapsible' => TRUE,
    '#weight' => -80,
    '#title' => t('Nodes'),
  );
  $form['sbp_nodes']['sbp_nodes_types_indexed'] = array(
    '#type' => 'checkboxes',
    '#title' => t('Content types to index'),
    '#default_value' => search_by_page_setting_get('sbp_nodes_types_indexed', $environment, array()),
    '#options' => node_get_types('names'),
    '#description' => t('Choose which content types you would like to have indexed by Search by Page'),
  );
  $form['sbp_nodes']['sbp_nodes_display_type'] = array(
    '#type' => 'radios',
    '#title' => t('Display in search results'),
    '#default_value' => search_by_page_setting_get('sbp_nodes_display_type', $environment, 'excerpts'),
    '#options' => array(
      '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['sbp_nodes']['sbp_nodes_role'] = array(
    '#type' => 'radios',
    '#title' => t('Role for indexing'),
    '#options' => user_roles(),
    '#default_value' => search_by_page_setting_get('sbp_nodes_role', $environment, DRUPAL_ANONYMOUS_RID),
    '#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 = array(
    '1' => t('1 second'),
    '3600' => t('1 hour'),
    '86400' => t('1 day'),
    '604800' => t('1 week'),
    '31449600' => t('1 year'),
    '0' => t('Never'),
  );
  $form['sbp_nodes']['sbp_nodes_min_time'] = array(
    '#type' => 'select',
    '#title' => t('Minimum reindexing time'),
    '#options' => $times,
    '#default_value' => search_by_page_setting_get('sbp_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['sbp_nodes']['sbp_nodes_max_time'] = array(
    '#type' => 'select',
    '#title' => t('Maximum reindexing time'),
    '#options' => $times,
    '#default_value' => search_by_page_setting_get('sbp_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;
}

/**
 * Implementation of hook_nodeapi().
 *
 * When a node is updated, sets it for reindexing at the next cron run.
 * When it's deleted, remove it from the search index.
 */
function sbp_nodes_nodeapi(&$node, $op, $teaser = NULL, $page = NULL) {
  switch ($op) {
    case 'update':
      search_by_page_force_reindex('sbp_nodes', $node->nid);
      break;
    case 'delete':
      search_by_page_force_remove('sbp_nodes', $node->nid);
      break;
  }
}

/**
 * Implementation of hook_comment().
 *
 * When a comment is added, edited, or deleted, set its node for reindexing
 * at the next cron run.
 */
function sbp_nodes_comment($a1, $op) {
  switch ($op) {
    case 'insert':
    case 'update':
    case 'delete':
    case 'publish':
    case 'unpublish':
      search_by_page_force_reindex('sbp_nodes', is_array($a1) ? $a1['nid'] : $a1->nid);
      break;
  }
}

Related topics

Functions

Namesort descending Description
sbp_nodes_comment Implementation of hook_comment().
sbp_nodes_nodeapi Implementation of hook_nodeapi().
sbp_nodes_sbp_details Implementation of Search by Page hook_sbp_details().
sbp_nodes_sbp_paths Implementation of Search by Page hook_sbp_paths().
sbp_nodes_sbp_query_modify Implementation of Search by Page hook_sbp_query_modify().
sbp_nodes_sbp_settings Implementation of Search by Page hook_sbp_settings().