You are here

function search_by_page_attach_search_by_page_paths in Search by Page 8

Implements Search by Page hook_search_by_page_paths().

Returns a list of all the files that should be indexed, and also saves information in a DB table for future reference.

File

search_by_page_attach/search_by_page_attach.module, line 20
Module file for Search by Page Attachments, a sub-module for Search by Page.

Code

function search_by_page_attach_search_by_page_paths($environment) {
  global $user;
  $save_user = $user;

  // Make a list of the previously-existing information, so we can remove
  // any we don't still need at the end.
  $prev_objs = \Drupal::database()
    ->query('SELECT * FROM {sbpa_attachments} WHERE environment = :env', [
    ':env' => $environment,
  ])
    ->fetchAll();
  $previous = array();
  $indx = 0;
  foreach ($prev_objs as $item) {
    $previous[$item->objtype][$item->bundle][$item->fieldname][$item->objid][$item->fileid] = $indx;
    $indx++;
  }
  $ret = array();

  // Make a list of content types they wanted to index.
  // Read from setting, and convert to an array of just the 1 values
  // Setting is from checkboxes, so it's like array('mytype' => 'mytype',
  // 'othertype' => 0).
  $typelist = \Drupal::service('search_by_page.settings')
    ->setSetting('search_by_page_attach_node_types', $environment, array());
  if (!is_array($typelist) || !count($typelist)) {
    return $ret;
  }
  $bundles = array();
  foreach ($typelist as $key => $item) {
    if ($item) {
      $bundles[] = $key;
    }
  }
  if (!count($bundles)) {
    return $ret;
  }

  // Make a list of fields they wanted to index.
  // Read from setting, and convert to an array of just the 1 values
  // Setting is from checkboxes, so it's like array('myfield' => 'myfield',
  // 'otherfield' => 0).
  $fieldlist = \Drupal::service('search_by_page.settings')
    ->setSetting('search_by_page_attach_field_types', $environment, array());
  if (!is_array($fieldlist) || !count($fieldlist)) {
    return $ret;
  }
  $fieldtypes = array();
  foreach ($fieldlist as $key => $value) {
    if ($value) {
      $fieldtypes[] = $key;
    }
  }
  if (!count($fieldtypes)) {
    return $ret;
  }
  $role = \Drupal::service('search_by_page.settings')
    ->getSetting('search_by_page_attach_role', $environment, AccountInterface::ANONYMOUS_ROLE);
  $languageManager = new \Drupal\Core\Language\LanguageManager();
  $langs = $languageManager
    ->getLanguages();
  $langs = array_keys($langs);
  $min_time = \Drupal::service('search_by_page.settings')
    ->getSettings('search_by_page_attach_min_time', $environment, 0);
  $max_time = \Drupal::service('search_by_page.settings')
    ->getSetting('search_by_page_attach_max_time', $environment, 0);

  // Find all file attachments on those types, build array of paths,
  // and save info in DB.
  // 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.
  // Important: Make sure to refresh the entity loading cache, because other
  // cron things could have loaded and then modified the objects. For
  // instance, doing a node_view() will remove all non-displayed files from
  // file fields, sigh. Also be sure to use the indexing user here.
  entity_get_controller('node')
    ->resetCache();
  $users = _search_by_page_indexing_users($role);
  $user = array_shift($users);
  foreach ($fieldtypes as $field_name) {
    $query = new EntityFieldQuery();
    $query
      ->entityCondition('entity_type', 'node', '=')
      ->entityCondition('bundle', $bundles, 'IN')
      ->addTag('DANGEROUS_ACCESS_CHECK_OPT_OUT')
      ->fieldCondition($field_name);
    $results = $query
      ->execute();
    if (!$results) {
      continue;
    }
    $objs = entity_load('node', array_keys($results['node']));
    if (!count($objs)) {
      continue;
    }
    foreach ($objs as $id => $obj) {

      // If this object has a language, use that; otherwise, all languages.
      $retlangs = $langs;
      if (isset($obj->language) && $obj->language && $obj->language != LANGUAGE_NONE) {
        $retlangs = array(
          $obj->language,
        );
      }
      $fields = _search_by_page_attach_object_fields($obj, $field_name);
      $bundle = $obj->type;
      foreach ($fields as $field) {
        $file = file_load($field['fid']);
        $display = 1;
        if (isset($field['display']) && !$field['display']) {
          $display = 0;
        }

        // Save this file as information in our database of files we've indexed.
        if (isset($previous['node'][$bundle][$field_name][$id][$file->fid])) {
          $indx = $previous['node'][$bundle][$field_name][$id][$file->fid];
          $prev = $prev_objs[$indx];
          $newid = $prev->sbpaid;
          \Drupal::database()
            ->update('sbpa_attachments')
            ->fields(array(
            'objtype' => 'node',
            'objid' => $id,
            'bundle' => $bundle,
            'fieldname' => $field_name,
            'fileid' => $file->fid,
            'environment' => $environment,
            'display' => $display,
          ))
            ->condition('sbpaid', $newid)
            ->execute();
          unset($prev_objs[$indx]);
          unset($previous['node'][$bundle][$field_name][$id][$file->fid]);
        }
        else {
          $newid = \Drupal::database()
            ->insert('sbpa_attachments')
            ->fields(array(
            'objtype' => 'node',
            'objid' => $id,
            'bundle' => $bundle,
            'fieldname' => $field_name,
            'fileid' => $file->fid,
            'environment' => $environment,
            'display' => $display,
          ))
            ->execute();
        }

        // Add it to the information for Search by Page.
        $ret[$file->uri] = array(
          'id' => $newid,
          'role' => $role,
          'languages' => $retlangs,
          'min_time' => $min_time,
          'max_time' => $max_time,
        );
      }
    }
  }

  // Set the global $user back to what it was.
  $user = $save_user;
  drupal_static_reset('user_access');
  entity_get_controller('node')
    ->resetCache();

  // Now take care of anything left over in $prev_objs - should be removed
  // now from our table. Search by Page will take care of removing from
  // the search index and its tables.
  $toremove = array();
  foreach ($prev_objs as $item) {
    $toremove[] = $item->sbpaid;
  }
  if (count($toremove)) {
    \Drupal::database()
      ->delete('sbpa_attachments')
      ->condition('sbpaid', $toremove)
      ->execute();
  }
  return $ret;
}