You are here

search_files_attachments.module in Search Files 6.2

Same filename and directory in other branches
  1. 7.2 search_files_attachments.module

Used to index files in attachments

File

search_files_attachments.module
View source
<?php

/**
 * @file
 * Used to index files in attachments
 */

/**
 * Implementation of hook_nodeapi().
 */
function search_files_attachments_nodeapi(&$node, $op) {
  switch ($op) {
    case 'delete':

      // Remove any files from the search index
      if (!empty($node->files)) {
        foreach ($node->files as $fid) {
          if (is_object($fid)) {
            $fid = get_object_vars($fid);
          }
          search_wipe($fid['fid'], 'search_files_att');
        }
      }
      break;
    case 'presave':

      // Remove files from the search index if needed.
      if (!empty($node->files)) {
        foreach ($node->files as $fid) {
          if (is_object($fid)) {
            $fid = get_object_vars($fid);
          }
          if ($fid['remove'] == 1) {
            search_wipe($fid['fid'], 'search_files_att');
          }
        }
      }
      break;
  }
}

/**
 * Implementation of hook_menu().
 */
function search_files_attachments_menu() {
  $items = array();
  $items['admin/settings/search_files/attachments'] = array(
    'title' => 'Attachments',
    'description' => 'Configure Search Files Attachments Module',
    'page callback' => 'search_files_attachments_dashboard',
    'access arguments' => array(
      'administer search_files configuration',
    ),
    'type' => MENU_NORMAL_ITEM,
    'weight' => 1,
  );
  $items['admin/settings/search_files/attachments/dashboard'] = array(
    'title' => 'Dashboard',
    'description' => 'Dashboard for Search Files in Attachments Module',
    'page callback' => 'search_files_attachments_dashboard',
    'access arguments' => array(
      'administer search_files configuration',
    ),
    'type' => MENU_DEFAULT_LOCAL_TASK,
    'weight' => 0,
  );
  $items['admin/settings/search_files/attachments/update_index'] = array(
    'title' => 'Update index',
    'description' => 'manually run hook update_index',
    'page callback' => 'search_files_attachments_update_index',
    'access arguments' => array(
      'administer search_files configuration',
    ),
    'type' => MENU_CALLBACK,
  );
  $items['admin/settings/search_files/attachments/settings'] = array(
    'title' => 'Settings',
    'description' => 'Change settings for Search Files Attachments Module',
    'page callback' => 'drupal_get_form',
    'page arguments' => array(
      'search_files_attachments_settings_form',
    ),
    'access arguments' => array(
      'administer search_files configuration',
    ),
    'type' => MENU_LOCAL_TASK,
    'weight' => 1,
  );
  return $items;
}

/**
 * Implementation of hook_search().
 */
function search_files_attachments_search($op = 'search', $keys = NULL) {
  switch ($op) {
    case 'name':
      if (user_access('view search_files results') && !variable_get('search_files_attachments_tab_disabled', FALSE)) {
        return variable_get('search_files_attachments_tab_label', t('Attachments'));
      }
      break;
    case 'reset':
      db_query("UPDATE {search_dataset} SET reindex = %d WHERE type = 'search_files_att'", time());
      return;
    case 'status':
      $total = db_result(db_query("\n        SELECT count(*) FROM {files} f\n        JOIN {search_files_helpers} h\n        ON SUBSTRING_INDEX(f.filename,'.',-1) = h.extension\n        WHERE status = 1\n        "));
      $remaining = db_result(db_query("\n                     SELECT count(*)\n                     FROM {files} AS f\n                     JOIN {search_files_helpers} h\n                     ON SUBSTRING_INDEX(f.filename,'.',-1) = h.extension\n                     LEFT JOIN {search_dataset} AS d\n                     ON d.sid = f.fid\n                     WHERE (\n                       d.type = 'search_files_att'\n                       AND f.status = 1\n                       AND (d.sid IS NULL OR d.reindex <> 0)\n                     )\n                   "));
      return array(
        'remaining' => $remaining,
        'total' => $total,
      );
    case 'search':

      // Build matching conditions
      list($join1, $where1) = _db_rewrite_sql();
      $arguments1 = array();
      $conditions1 = 'f.status = 1';
      $ranking = array();
      $arguments2 = array();
      $join2 = '';
      $total = 0;

      // base rankings off node rank settings
      if ($weight = (int) variable_get('node_rank_relevance', 5)) {

        // Average relevance values hover around 0.15
        $ranking[] = '%d * i.relevance';
        $arguments2[] = $weight;
        $total += $weight;
      }
      if ($weight = (int) variable_get('node_rank_recent', 5)) {

        // Exponential decay with half-life of 6 months, starting at last indexed node
        $ranking[] = '(%d * POW(2, (f.timestamp) - %d) * 6.43e-8)';
        $arguments2[] = $weight;
        $arguments2[] = (int) variable_get('node_cron_last', 0);
        $total += $weight;
      }

      // When all search factors are disabled (ie they have a weight of zero),
      // the default score is based only on keyword relevance and there is no need to
      // adjust the score of each item.
      if ($total == 0) {
        $select2 = 'i.relevance AS score';
        $total = 1;
      }
      else {
        $select2 = implode(' + ', $ranking) . ' AS score';
      }

      // Do search.
      $find = do_search($keys, 'search_files_att', 'INNER JOIN {files} f ON f.fid = i.sid INNER JOIN {upload} u ON u.fid = f.fid INNER JOIN {node} n ON n.vid = u.vid ' . $join1, $conditions1 . (empty($where1) ? '' : ' AND ' . $where1), $arguments1, $select2, $join2, $arguments2);

      // Load results.
      $results = array();
      $search_queries = array();
      $upload_module = module_exists('upload');
      $filefield_module = module_exists('filefield');
      $file_fields = array();
      if ($upload_module) {
        $search_queries[] = "SELECT f.*, d.data, u.nid\n                        FROM {files} AS f\n                        JOIN {upload} AS u\n                        USING(fid)\n                        INNER JOIN {search_dataset} AS d\n                        ON f.fid = d.sid\n                        WHERE fid = %d AND d.type = 'search_files_att'";
      }
      if ($filefield_module) {
        $fields = content_fields();
        foreach ($fields as $field) {
          if ($field['type'] == 'filefield') {
            $field_info = content_database_info($field);
            $search_queries[] = "SELECT f.*, d.data, u.nid\n                                  FROM {files} AS f\n                                  JOIN {" . $field_info['table'] . "} AS u\n                                  ON u." . $field_info['columns']['fid']['column'] . " = f.fid\n                                  INNER JOIN {search_dataset} AS d\n                                  ON f.fid = d.sid\n                                  WHERE fid = %d";
          }
        }
      }
      foreach ($find as $item) {

        // Build the node body.
        foreach ($search_queries as $search_query) {
          $file = db_fetch_object(db_query($search_query, $item->sid));
          $node = node_load($file->nid);
          $realpath = realpath($file->filepath);
          if (is_file($realpath)) {
            $fileinfo = (object) pathinfo($realpath);
            $results[] = array(
              'link' => file_create_url($file->filepath),
              'title' => $file->filename,
              'user' => theme('username', $node),
              'date' => $file->timestamp,
              'type' => check_plain(search_files_helper_name($fileinfo->extension)),
              'node' => $node,
              'score' => $item->score / $total,
              'extra' => array(
                t('Attached to ') . node_get_types('name', $node) . ' ' . l(t($node->title), 'node/' . $node->nid),
              ),
              'snippet' => search_excerpt($keys, $file->data),
            );
          }
        }
      }
      return $results;
  }
}

/**
 * Implementation of hook_update_index().
 */
function search_files_attachments_update_index() {
  variable_set('search_files_attachments_last_index', time());
  $limit = (int) variable_get('search_cron_limit', 100);

  /* select known files related to search_files_att and marked for reindexing UNION
   *        or any new files not yet indexed
   */
  $result = db_query_range("\n    SELECT f.fid, f.filepath, d.reindex\n    FROM {node} n, {upload} u, {files} f\n    LEFT JOIN {search_dataset} d\n    ON d.type = 'search_files_att' AND d.sid = f.fid\n    WHERE (d.sid IS NULL OR d.reindex <> 0) AND n.vid = u.vid AND u.fid = f.fid\n    ORDER BY d.reindex ASC, f.fid ASC", 0, $limit);
  $found = $count = 0;
  while ($file = db_fetch_object($result)) {
    $found++;
    if (search_files_attachments_index_file($file)) {
      $count++;
    }
  }

  // if we were called manually from dashboard, return to where we come from
  if (preg_match('/search_files\\/(attachments|directories)$/', $_SERVER['HTTP_REFERER'])) {
    search_files_update_totals('search_files_att');
    drupal_goto($_SERVER['HTTP_REFERER']);
  }
}

/**
 * get files to index
 */
function search_files_attachments_index_file($file) {
  $contents = search_files_attachments_get_file_contents($file->filepath);
  if ($contents) {
    $contents = search_files_convert_to_utf8("{$file->filename} " . $contents);
  }
  search_index($file->fid, 'search_files_att', $contents);
  return $contents;
}

/**
 * get the file contents using the helpers configured in the search_files_module
 */
function search_files_attachments_get_file_contents($path) {
  $helpers = search_files_get_helpers();
  $realpath = realpath($path);
  $pathinfo = (object) pathinfo($realpath);
  $file_exists = is_file($realpath);
  $helper_exists = array_key_exists($pathinfo->extension, $helpers);
  if ($helper_exists && $file_exists) {
    $cmd = preg_replace('/%file%/', escapeshellarg($realpath), $helpers[$pathinfo->extension]);
    $contents = shell_exec($cmd);
    return $contents;
  }
  return FALSE;
}

/**
 * generate the settings form for the search_files module using the
 * system_settings_form() function
 */
function search_files_attachments_settings_form() {
  $form = array();
  $form['search_files_attachments_tab_label'] = array(
    '#title' => 'Search Label',
    '#type' => 'textfield',
    '#description' => 'What do you want the Search tab to be labeled?',
    '#default_value' => variable_get('search_files_attachments_tab_label', t('Attachments')),
  );
  $form['search_files_attachments_tab_disabled'] = array(
    '#title' => t('Disable search attachments tab'),
    '#type' => 'checkbox',
    '#default_value' => variable_get('search_files_attachments_tab_disabled', FALSE),
    '#return_value' => 1,
  );
  return system_settings_form($form);
}

/**
 * generate the search_files_directories dashboard page
 */
function search_files_attachments_dashboard() {
  $output = '';
  $lastindex = variable_get('search_files_attachments_last_index', 0);
  if ($lastindex == 0) {
    $output .= sprintf("%s = <i>%s</i><br/>\n", t('Last Index'), t('never'));
  }
  else {
    $output .= sprintf("%s = %s<br/>\n", t('Last Index'), format_date($lastindex, $type = 'custom', $format = 'Y-m-d H:i:s', $timezone = NULL, $langcode = NULL));
  }
  $sql = "SELECT count(*) FROM {search_dataset} WHERE type = 'search_files_att'";
  $result = db_query($sql);
  $result = db_result($result);
  $output .= sprintf("Files indexed = %s<br/>\n", $result);
  $sql = "SELECT count(*) FROM {search_dataset} WHERE (type = 'search_files_att' AND reindex > 0)";
  $result = db_query($sql);
  $result = db_result($result);
  $output .= sprintf("Files indexed and scheduled for reindexing = %s<br/>\n", $result);
  $output .= l(t('Update index'), 'admin/settings/search_files/attachments/update_index');
  $output .= "<br/>\n";
  return $output;
}

Functions

Namesort descending Description
search_files_attachments_dashboard generate the search_files_directories dashboard page
search_files_attachments_get_file_contents get the file contents using the helpers configured in the search_files_module
search_files_attachments_index_file get files to index
search_files_attachments_menu Implementation of hook_menu().
search_files_attachments_nodeapi Implementation of hook_nodeapi().
search_files_attachments_search Implementation of hook_search().
search_files_attachments_settings_form generate the settings form for the search_files module using the system_settings_form() function
search_files_attachments_update_index Implementation of hook_update_index().