Further modules included.
[yaffs-website] / web / modules / contrib / advanced_help / src / Plugin / Search / AdvancedHelpSearch.php
diff --git a/web/modules/contrib/advanced_help/src/Plugin/Search/AdvancedHelpSearch.php b/web/modules/contrib/advanced_help/src/Plugin/Search/AdvancedHelpSearch.php
new file mode 100644 (file)
index 0000000..3618df0
--- /dev/null
@@ -0,0 +1,267 @@
+<?php
+
+namespace Drupal\advanced_help\Plugin\Search;
+
+use Drupal\Core\Access\AccessResult;
+use Drupal\Core\Database\Connection;
+use Drupal\Core\Session\AccountInterface;
+use Drupal\Core\Access\AccessibleInterface;
+use Drupal\search\Plugin\SearchPluginBase;
+use Drupal\advanced_help\AdvancedHelpManager;
+use Drupal\search\Plugin\SearchIndexingInterface;
+use Drupal\Core\Config\Config;
+use Symfony\Component\DependencyInjection\ContainerInterface;
+
+/**
+ * Executes a keyword search for Advanced Help against the {advanced_help} topic pages.
+ *
+ * @SearchPlugin(
+ *   id = "advanced_help_search",
+ *   title = @Translation("Advanced Help")
+ * )
+ */
+class AdvancedHelpSearch extends SearchPluginBase implements AccessibleInterface, SearchIndexingInterface {
+
+  /**
+   * The database connection.
+   *
+   * @var \Drupal\Core\Database\Connection
+   */
+  protected $database;
+
+  /**
+   * The current user.
+   *
+   * @var \Drupal\Core\Session\AccountInterface
+   */
+  protected $currentUser;
+
+  /**
+   * Advanced Help Manager.
+   * @var \Drupal\advanced_help\AdvancedHelpManager
+   */
+  protected $advancedHelp;
+
+  /**
+   * A config object for 'search.settings'.
+   *
+   * @var \Drupal\Core\Config\Config
+   */
+  protected $searchSettings;
+
+
+  /**
+   * {@inheritdoc}
+   */
+  static public function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition) {
+    return new static(
+      $container->get('database'),
+      $container->get('plugin.manager.advanced_help'),
+      $container->get('current_user'),
+      $container->get('config.factory')->get('search.settings'),
+      $configuration,
+      $plugin_id,
+      $plugin_definition
+    );
+  }
+
+  /**
+   * Creates a UserSearch object.
+   *
+   * @param Connection $database
+   *   The database connection.
+   * @param \Drupal\advanced_help\AdvancedHelpManager $advanced_help
+   *   The advanced Help manager.
+   * @param \Drupal\Core\Session\AccountInterface $current_user
+   *   The current user.
+   * @param array $configuration
+   * @param \Drupal\Core\Config\Config $search_settings
+   * @param string $plugin_id
+   *   The plugin_id for the plugin instance.
+   * @param mixed $plugin_definition
+   *   The plugin implementation definition.
+   */
+  public function __construct(Connection $database, AdvancedHelpManager $advanced_help, AccountInterface $current_user, Config $search_settings, array $configuration, $plugin_id, $plugin_definition) {
+    $this->database = $database;
+    $this->advancedHelp = $advanced_help;
+    $this->currentUser = $current_user;
+    $this->searchSettings = $search_settings;
+
+    parent::__construct($configuration, $plugin_id, $plugin_definition);
+
+    $this->addCacheTags(['user_list']);
+  }
+
+  public function access($operation = 'view', AccountInterface $account = NULL, $return_as_object = FALSE) {
+    $result = AccessResult::allowedIf(!empty($account) && $account->hasPermission('access user profiles'))->cachePerPermissions();
+    return $return_as_object ? $result : $result->isAllowed();
+  }
+
+  /**
+   * Gets search id for each topic.
+   *
+   * Get or create an sid (search id) that correlates to each topic for
+   * the search system.
+   * @param array $topics
+   * @return array
+   */
+  private function getSids($topics) {
+    $language = \Drupal::languageManager()->getCurrentLanguage()->getId();
+    $result = $this->database->select('advanced_help_index', 'ahi')
+      ->fields('ahi', ['sid', 'module', 'topic', 'langcode'])
+      ->condition('langcode', $language)
+      ->execute();
+    foreach ($result as $sid) {
+      if (empty($topics[$sid->module][$sid->topic])) {
+        $this->database->query("DELETE FROM {advanced_help_index} WHERE sid = :sid", [':sid' => $sid->sid]);
+      }
+      else {
+        $topics[$sid->module][$sid->topic]['sid'] = $sid->sid;
+      }
+    }
+    return $topics;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function execute() {
+    if ($this->isSearchExecutable()) {
+      $keys = $this->keywords;
+
+      // Build matching conditions.
+      $query = $this->database
+        ->select('search_index', 'i', ['target' => 'replica'])
+        ->extend('Drupal\search\SearchQuery')
+        ->extend('Drupal\Core\Database\Query\PagerSelectExtender');
+      $query->join('advanced_help_index', 'ahi', 'ahi.sid = i.sid');
+      $query->join('search_dataset', 'sd', "ahi.sid = sd.sid AND sd.type = '{$this->pluginId}'");
+      $query->searchExpression($keys, $this->getPluginId());
+
+      $find = $query
+        ->fields('i', ['langcode'])
+        ->fields('ahi', ['module', 'topic'])
+        ->fields('sd', ['data'])
+        ->groupBy('i.langcode, ahi.module, ahi.topic, sd.data')
+        ->limit(10)
+        ->execute();
+
+      $results = [];
+      foreach ($find as $key => $item) {
+        $result = [
+          'link' => '/help/ah/' . $item->module . '/' . $item->topic,
+          'title' => $item->topic,
+          'score' => $item->calculated_score,
+          'snippet' => search_excerpt($keys, $item->data, $item->langcode),
+          'langcode' => $item->langcode,
+        ];
+        $results[] = $result;
+      }
+
+      return $results;
+    }
+    return [];
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function updateIndex() {
+    // Interpret the cron limit setting as the maximum number of nodes to index
+    // per cron run.
+    $limit = (int)$this->searchSettings->get('index.cron_limit');
+    $language = \Drupal::languageManager()->getCurrentLanguage()->getId();
+    $topics = $this->getSids($this->advancedHelp->getTopics());
+
+    // If we got interrupted by limit, this will contain the last module
+    // and topic we looked at.
+    $last = \Drupal::state()->get($this->getPluginId() . '.last_cron', ['time' => 0]);
+    $count = 0;
+    foreach ($topics as $module => $module_topics) {
+      // Fast forward if necessary.
+      if (!empty($last['module']) && $last['module'] != $module) {
+        continue;
+      }
+
+      foreach ($module_topics as $topic => $info) {
+        // Fast forward if necessary.
+        if (!empty($last['topic']) && $last['topic'] != $topic) {
+          continue;
+        }
+
+        //If we've been looking to catch up, and we have, reset so we
+        // stop fast forwarding.
+        if (!empty($last['module'])) {
+          unset($last['topic']);
+          unset($last['module']);
+        }
+
+        $file = $this->advancedHelp->getTopicFileName($module, $topic);
+        if ($file && (empty($info['sid']) || filemtime($file) > $last['time'])) {
+          if (empty($info['sid'])) {
+            $info['sid'] = $this->database->insert('advanced_help_index')
+              ->fields([
+                'module' => $module,
+                'topic' => $topic,
+                'langcode' => $language
+              ])
+              ->execute();
+          }
+        }
+
+        // Update index, using search index "type" equal to the plugin ID.
+        search_index($this->getPluginId(), $info['sid'], $language, file_get_contents($file));
+        $count++;
+        if ($count >= $limit) {
+          $last['module'] = $module;
+          $last['topic'] = $topic;
+          \Drupal::state()->set($this->getPluginId() . '.last_cron', $last);
+          return;
+        }
+      }
+    }
+    \Drupal::state()->set($this->getPluginId() . '.last_cron', ['time' => time()]);
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function indexClear() {
+    search_index_clear($this->getPluginId());
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function markForReindex() {
+    search_mark_for_reindex($this->getPluginId());
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function indexStatus() {
+    $topics = $this->advancedHelp->getTopics();
+    $total = 0;
+    foreach ($topics as $module => $module_topics) {
+      foreach ($module_topics as $topic => $info) {
+        $file = $this->advancedHelp->getTopicFileName($module, $topic);
+        if ($file) {
+          $total++;
+        }
+      }
+    }
+    $last_cron = \Drupal::state()->get($this->getPluginId() . '.last_cron', ['time' => 0]);
+    $indexed = 0;
+    if ($last_cron['time'] != 0) {
+      $indexed = $this->database->select('search_dataset', 'sd')
+        ->fields('sd', ['sid'])
+        ->condition('type', $this->getPluginId())
+        ->condition('reindex', 0)
+        ->countQuery()
+        ->execute()
+        ->fetchField();
+    }
+    return ['remaining' => $total - $indexed, 'total' => $total];
+  }
+}
\ No newline at end of file