foldershare-8.x-1.2/src/ManageSearch.php

src/ManageSearch.php
<?php

namespace Drupal\foldershare;

use Drupal\foldershare\Entity\FolderShare;
use Drupal\foldershare\Entity\FolderShareScheduledTask;

/**
 * Manages search features for FolderShare entities.
 *
 * This class provides static methods to manage search indexing for
 * FolderShare entities. Supported operations include:
 * - Clearing the index.
 * - Deleting index entries for specific entities.
 * - Marking index entries as out of date for specific entities.
 * - Updating the index.
 *
 * This method also provides methods to query configuration settings for
 * indexing and check the amount of indexing work pending.
 *
 * The following search modules are supported:
 * - "search" in Drupal core. See also FolderShare's search plugin.
 *
 * <B>Access control</B>
 * This class's methods do not do access control. The caller should check
 * access as needed by their situation.
 *
 * @ingroup foldershare
 *
 * @see \Drupal\foldershare\Settings
 * @see \Drupal\foldershare\Entity\FolderShare
 * @see \Drupal\foldershare\Entity\FolderShare\Plugin\Search\FolderShareSearch
 */
final class ManageSearch {

  /*--------------------------------------------------------------------
   *
   * Search plugin operations.
   *
   *-------------------------------------------------------------------*/

  /**
   * Returns the Drupal core "search" plugin instance for FolderShare.
   *
   * The FolderShare module provides a custom search plugin that supports
   * search indexing of FolderShare entities and implements a
   * FolderShare-specific search form.
   *
   * If the Drupal core "search" module is not enabled or FolderShare's
   * search plugin is not enabled, this method returns a NULL.
   *
   * @return \Drupal\search\Plugin\SearchInterface
   *   Returns the module's search plugin object, or NULL if the plugin
   *   is not found or if it is currently disabled.
   *
   * @see \Drupal\foldershare\Entity\FolderShare\Plugin\Search\FolderShareSearch
   */
  private static function findSearchPlugin() {
    if (\Drupal::moduleHandler()->moduleExists('search') === FALSE) {
      return NULL;
    }

    $searchPageRepository = \Drupal::service('search.search_page_repository');

    // Loop over all *indexable* search pages. A page is not indexable if
    // the page is disabled or the plugin does not support indexing.
    foreach ($searchPageRepository->getIndexableSearchPages() as $page) {
      $plugin = $page->getPlugin();
      if ($plugin->getType() === Constants::SEARCH_INDEX) {
        return $plugin;
      }
    }

    return NULL;
  }

  /**
   * Returns the list of file name extensions for indexed file content.
   *
   * The FolderShare module's search plugin supports optional indexing of
   * text file content. This method returns the configured set of file name
   * extensions for which indexing is enabled.
   *
   * If the Drupal core "search" module is not enabled, FolderShare's
   * search plugin is not enabled, or if there are no file extensions
   * supported for indexing, this method returns an empty string.
   *
   * @return string
   *   Returns a space-separated list of file name extensions supported for
   *   file content indexing.
   *
   * @see ::isIndexFileContentEnabled()
   * @see ::getIndexFileContentMaximumSize()
   * @see \Drupal\foldershare\Entity\FolderShare\Plugin\Search\FolderShareSearch
   */
  public static function getIndexFileContentExtensions() {
    $plugin = self::findSearchPlugin();
    if ($plugin !== NULL &&
        method_exists($plugin, 'getSearchFileExtensions') === TRUE) {
      return $plugin->getSearchFileExtensions();
    }

    return '';
  }

  /**
   * Returns the maximum number of bytes indexed from file content.
   *
   * The FolderShare module's search plugin supports optional indexing of
   * text file content. This method returns the configured maximum number of
   * bytes to read and index from the start of the file.
   *
   * If the Drupal core "search" module is not enabled, FolderShare's
   * search plugin is not enabled, or if the maximum indexing size has
   * been set to zero, this method returns a zero.
   *
   * @return int
   *   Returns the maximum number of bytes indexed from file content.
   *
   * @see ::isIndexFileContentEnabled()
   * @see ::getIndexFileContentExtensions()
   * @see \Drupal\foldershare\Entity\FolderShare\Plugin\Search\FolderShareSearch
   */
  public static function getIndexFileContentMaximumSize() {
    $plugin = self::findSearchPlugin();
    if ($plugin !== NULL &&
        method_exists($plugin, 'getSearchFileSize') === TRUE) {
      return $plugin->getSearchFileSize();
    }

    return 0;
  }

  /**
   * Returns TRUE if the module's search plugin indexes file content.
   *
   * The FolderShare module's search plugin supports optional indexing of
   * text file content. This method returns TRUE if this feature is enabled.
   *
   * If the Drupal core "search" module is not enabled, FolderShare's
   * search plugin is not enabled, or if file content indexing has been
   * disabled, this method returns FALSE.
   *
   * @return bool
   *   Returns TRUE if file content indexing is enabled.
   *
   * @see ::getIndexFileContentMaximumSize()
   * @see ::getIndexFileContentExtensions()
   * @see \Drupal\foldershare\Entity\FolderShare\Plugin\Search\FolderShareSearch
   */
  public static function isIndexFileContentEnabled() {
    $plugin = self::findSearchPlugin();
    if ($plugin !== NULL &&
        method_exists($plugin, 'getSearchFileContent') === TRUE) {
      return $plugin->getSearchFileContent();
    }

    return FALSE;
  }

  /**
   * Returns TRUE if the module's search plugin is enabled.
   *
   * If the Drupal core "search" module is not enabled, FolderShare's
   * search plugin is not enabled, this method returns FALSE.
   *
   * @return bool
   *   Returns TRUE if the search plugin is enabled.
   *
   * @see \Drupal\foldershare\Entity\FolderShare\Plugin\Search\FolderShareSearch
   */
  public static function isSearchEnabled() {
    return (self::findSearchPlugin() !== NULL);
  }

  /*--------------------------------------------------------------------
   *
   * Search index operations.
   *
   *-------------------------------------------------------------------*/

  /**
   * Clears the search index of all FolderShare entries.
   *
   * @see ::deleteFromIndex()
   * @see ::getIndexStatus()
   * @see ::getNumberToIndex()
   * @see ::markForReindex()
   * @see search_index_clear()
   * @see \Drupal\search\Plugin\SearchIndexingInterface::indexClear()
   * @see \Drupal\foldershare\Entity\FolderShare\Plugin\Search\FolderShareSearch
   */
  public static function clearIndex() {
    $plugin = self::findSearchPlugin();
    if ($plugin !== NULL) {
      // Search plugins are only guaranteed to implement SearchInterface,
      // though most also implement SearchIndexingInterface. This adds
      // indexClear().
      if (method_exists($plugin, 'indexClear') === TRUE) {
        $plugin->indexClear();
      }
      else {
        search_index_clear(Constants::SEARCH_INDEX);
      }
    }
    elseif (\Drupal::moduleHandler()->moduleExists('search') === TRUE) {
      search_index_clear(Constants::SEARCH_INDEX);
    }
  }

  /**
   * Deletes the search index entries for a list of FolderShare items.
   *
   * @param \Drupal\foldershare\Entity\FolderShare[]|\Drupal\foldershare\Entity\FolderShare $items
   *   (optional, default = NULL) With a NULL, the entire search index is
   *   cleared by forwarding to clearIndex(). Otherwise each non-NULL
   *   FolderShare entity given is deleted from the search index.
   *
   * @see ::clearIndex()
   * @see ::getNumberToIndex()
   * @see ::markForReindex()
   * @see search_index_clear()
   * @see \Drupal\foldershare\Entity\FolderShare\Plugin\Search\FolderShareSearch
   */
  public static function deleteFromIndex($items = NULL) {
    if ($items === NULL) {
      self::clearIndex();
      return;
    }

    if (\Drupal::moduleHandler()->moduleExists('search') === FALSE) {
      return;
    }

    if (is_object($items) === TRUE) {
      $items = [$items];
    }

    if (is_array($items) === TRUE) {
      foreach ($items as $item) {
        if ($item !== NULL && $item instanceof FolderShare) {
          search_index_clear(
            Constants::SEARCH_INDEX,
            (int) $item->id(),
            $item->langcode->value);
        }
      }
    }
  }

  /**
   * Returns the number of FolderShare items remaining to index.
   *
   * The number of items remaining to index includes all items that have
   * been added, but not yet indexed a first time, and all items that have
   * been changed and are now in need of reindexing.
   *
   * A zero is returned if the Drupal core "search" module is not installed,
   * if this module's search plugin is not enabled, or if there is nothing
   * pending to index.
   *
   * @return int
   *   Returns the number of FolderShare items in need of indexing.
   *
   * @see ::getIndexStatus()
   * @see ::markForReindex()
   * @see \Drupal\search\Plugin\SearchIndexingInterface::indexStatus()
   * @see \Drupal\foldershare\Entity\FolderShare\Plugin\Search\FolderShareSearch
   */
  public static function getNumberToIndex() {
    $plugin = self::findSearchPlugin();
    if ($plugin !== NULL && method_exists($plugin, 'indexStatus') === TRUE) {
      // Search plugins are only guaranteed to implement SearchInterface,
      // though most also implement SearchIndexingInterface. This adds
      // indexStatus().
      $answer = $plugin->indexStatus();
      return $answer['remaining'];
    }

    return 0;
  }

  /**
   * Returns the indexing status.
   *
   * The returned status is an associative array with two values:
   * - 'total' has the total number of items.
   * - 'remaining' has the number of items to index.
   *
   * Zeros are returned if the Drupal core "search" module is not installed,
   * or if this module's search plugin is not enabled.
   *
   * @return array
   *   Returns an associative array with 'total' and 'remaining' values.
   *
   * @see ::getNumberToIndex()
   * @see ::markForReindex()
   * @see \Drupal\search\Plugin\SearchIndexingInterface::indexStatus()
   * @see \Drupal\foldershare\Entity\FolderShare\Plugin\Search\FolderShareSearch
   */
  public static function getIndexStatus() {
    $plugin = self::findSearchPlugin();
    if ($plugin !== NULL && method_exists($plugin, 'indexStatus') === TRUE) {
      // Search plugins are only guaranteed to implement SearchInterface,
      // though most also implement SearchIndexingInterface. This adds
      // indexStatus().
      return $plugin->indexStatus();
    }

    return [
      'total'     => 0,
      'remaining' => 0,
    ];
  }

  /**
   * Marks a list of FolderShare items as in need of search reindexing.
   *
   * When an item is marked, future search indexing runs will rebuild
   * the index's entry for the item.
   *
   * This method is typically called whenever an item is changed and
   * saved back to the database.
   *
   * No action is taken if the Drupal core "search" module is not installed,
   * or if this module's search plugin is not enabled.
   *
   * @param \Drupal\foldershare\Entity\FolderShare[]|\Drupal\foldershare\Entity\FolderShare $items
   *   (optional, default = NULL) With a NULL, the entire search index is
   *   marked for reindexing. Otherwise each non-NULL FolderShare entity is
   *   marked for reindexing.
   *
   * @see ::clearIndex()
   * @see ::getIndexStatus()
   * @see ::getNumberToIndex()
   * @see ::deleteFromIndex()
   * @see search_mark_for_reindex()
   * @see \Drupal\search\Plugin\SearchIndexingInterface::markForReindex()
   * @see \Drupal\foldershare\Entity\FolderShare\Plugin\Search\FolderShareSearch
   */
  public static function markForReindex($items = NULL) {
    if ($items === NULL) {
      $plugin = self::findSearchPlugin();
      if ($plugin === NULL) {
        return;
      }

      // Search plugins are only guaranteed to implement SearchInterface,
      // though most also implement SearchIndexingInterface. This adds
      // markForReindex().
      if (method_exists($plugin, 'markForReindex') === TRUE) {
        $plugin->markForReindex();
      }
      else {
        search_mark_for_reindex(Constants::SEARCH_INDEX);
      }

      return;
    }

    if (\Drupal::moduleHandler()->moduleExists('search') === FALSE) {
      return;
    }

    if (is_object($items) === TRUE) {
      $items = [$items];
    }

    if (is_array($items) === TRUE) {
      foreach ($items as $item) {
        if ($item !== NULL && $item instanceof FolderShare) {
          search_mark_for_reindex(Constants::SEARCH_INDEX, (int) $item->id());
        }
      }
    }
  }

  /**
   * Updates the search index for pending FolderShare items.
   *
   * If a list of items is provided, the index entries for those items
   * are updated. Otherwise any pending items are updated.
   *
   * @param \Drupal\foldershare\Entity\FolderShare[]|\Drupal\foldershare\Entity\FolderShare $items
   *   (optional, default = NULL) With a NULL, pending items are indexed
   *   by the search plugin. Otherwise each non-NULL FolderShare entity
   *   is indexed by the search plugin.
   *
   * @see ::getIndexStatus()
   * @see ::getNumberToIndex()
   * @see search_cron()
   * @see search_update_totals()
   * @see \Drupal\search\Plugin\SearchIndexingInterface::updateIndex()
   * @see \Drupal\foldershare\Entity\FolderShare\Plugin\Search\FolderShareSearch
   */
  public static function updateIndex($items = NULL) {
    $plugin = self::findSearchPlugin();
    if ($plugin === NULL) {
      return;
    }

    // Register the search module's shutdown function to insure that
    // search totals are always updated.
    drupal_register_shutdown_function('search_update_totals');

    if ($items === NULL) {
      // Search plugins are only guaranteed to implement SearchInterface,
      // though most also implement SearchIndexingInterface. This adds
      // updateIndex().
      if (method_exists($plugin, 'updateIndex') === TRUE) {
        $plugin->updateIndex();
      }
    }
    elseif (method_exists($plugin, 'indexItem') === TRUE) {
      // FolderShare's search plugin supports indexItem().
      foreach ($items as $item) {
        if ($item !== NULL && $item instanceof FolderShare) {
          $plugin->indexItem($item);
        }
      }
    }
    else {
      // Mark each of the items as in need of re-indexing, then
      // update the whole index.
      self::markForReindex($items);

      // Search plugins are only guaranteed to implement SearchInterface,
      // though most also implement SearchIndexingInterface. This adds
      // updateIndex().
      if (method_exists($plugin, 'updateIndex') === TRUE) {
        $plugin->updateIndex();
      }
    }
  }

  /*--------------------------------------------------------------------
   *
   * Index scheduling.
   *
   *-------------------------------------------------------------------*/

  /**
   * Returns the search indexing task run interval.
   *
   * The run interval indicates the time between execution of the search
   * indexing scheduled task. Known values are:
   *
   * - 'system' = the index is serviced by the system (e.g. CRON).
   * - '1min' = the index is serviced every minute.
   * - '5min' = the index is serviced every 5 minutes.
   * - '10min' = the index is serviced every 10 minutes.
   * - '15min' = the index is serviced every 15 minutes.
   * - '30min' = the index is serviced every 30 minutes.
   * - 'hourly' = the index is serviced every hour.
   * - 'daily' = the index is serviced every day.
   *
   * @return string
   *   Returns the run interval setting.
   *
   * @see \Drupal\foldershare\Settings::getSearchIndexInterval()
   */
  public static function getIndexInterval() {
    return Settings::getSearchIndexInterval();
  }

  /**
   * Returns the search indexing task run interval in seconds.
   *
   * The current run interval is interpreted to compute and return the
   * interval time in seconds. A zero value indicates the interval is
   * 'system', which disables task scheduling and leaves indexing to CRON.
   *
   * @return int
   *   Returns the run interval in seconds. Zero is returned if the
   *   interval is 'system'.
   *
   * @see ::getIndexInterval()
   * @see \Drupal\foldershare\Settings::getSearchIndexInterval()
   */
  private static function getIndexIntervalSeconds() {
    switch (self::getIndexInterval()) {
      default:
      case 'system':
        // No indexing task.
        return 0;

      case '1min':
        // 60 seconds/minute.
        return 60;

      case '5min':
        // 5 min * 60 seconds/minute.
        return (5 * 60);

      case '10min':
        // 10 min * 60 seconds/minute.
        return (10 * 60);

      case '15min':
        // 15 min * 60 seconds/minute.
        return (15 * 60);

      case '30min':
        // 30 min * 60 seconds/minute.
        return (30 * 60);

      case 'hourly':
        // 60 minutes/hour * 60 seconds/minute.
        return (60 * 60);

      case 'daily':
        // 24 hours/day * 60 minutes/hour * 60 seconds/minute.
        return (24 * 60 * 60);
    }
  }

  /**
   * Schedules search indexing using the current indexing interval.
   *
   * <B>This method is internal and strictly for use by the FolderShare
   * module itself.</B>
   *
   * The current search indexing task is deleted, if there is one. If the
   * current scheduling interval is not 'system' (i.e. CRON-based execution),
   * a new search indexing task is scheduled.
   *
   * No task is scheduled if search indexing is disabled.
   *
   * @see ::isSearchEnabled()
   * @see ::getIndexInterval()
   * @see ::taskUpdateIndex()
   * @see \Drupal\foldershare\Settings::getSearchIndexInterval()
   */
  public static function scheduleSearchIndexing() {
    // Delete any pending search tasks.
    FolderShareScheduledTask::deleteTasks(
      '\Drupal\foldershare\ManageSearch::taskUpdateIndex');

    if (self::isSearchEnabled() === FALSE) {
      // No search.
      return;
    }

    $seconds = self::getIndexIntervalSeconds();
    if ($seconds === 0) {
      // There is no scheduled search index task.
      return;
    }

    // Schedule a new task with the current interval.
    $t = time();
    FolderShareScheduledTask::createTask(
      $t + $seconds,
      '\Drupal\foldershare\ManageSearch::taskUpdateIndex',
      (int) \Drupal::currentUser()->id(),
      NULL,
      $t,
      self::getIndexInterval() . ' search index update',
      0);
  }

  /*---------------------------------------------------------------------
   *
   * Search index update task.
   *
   *---------------------------------------------------------------------*/

  /**
   * Updates the search index as a scheduled task.
   *
   * <B>This method is internal and strictly for use by the FolderShare
   * module itself.</B>
   *
   * The task updates the search index, processing entries based upon search
   * settings. If the current indexing interval is 'system', or if search
   * is disabled, this task aborts without re-scheduling itself. Otherwise
   * it updates the search index and reschedules itself at the configured
   * time interval in the future.
   *
   * @param int $requester
   *   The user ID of the user that requested the update. This is ignored.
   * @param array $parameters
   *   The queued task's parameters. This is ignored.
   * @param int $started
   *   The timestamp of the start date & time for an operation that causes
   *   a chain of tasks.
   * @param string $comments
   *   A comment on the current task.
   * @param int $executionTime
   *   The accumulated total execution time of the task chain, in seconds.
   *
   * @see ::getIndexInterval()
   * @see ::isSearchEnabled()
   * @see ::scheduleSearchIndexing()
   * @see ::updateIndex()
   */
  public static function taskUpdateIndex(
    int $requester,
    array $parameters,
    int $started,
    string $comments,
    int $executionTime) {

    if (self::isSearchEnabled() === FALSE) {
      // No search.
      return;
    }

    $seconds = self::getIndexIntervalSeconds();
    if ($seconds === 0) {
      // There is no scheduled search index task.
      return;
    }

    // Schedule the next task with the current interval.
    $t = time();
    FolderShareScheduledTask::createTask(
      $t + $seconds,
      '\Drupal\foldershare\ManageSearch::taskUpdateIndex',
      $requester,
      NULL,
      $t,
      self::getIndexInterval() . ' search index update',
      0);

    // Update the search index.
    self::updateIndex();
  }

}

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

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