facets.module 5.56 KB
Newer Older
1 2 3 4
<?php

/**
 * @file
5
 * Contains facets.module
6 7
 */

8
use Drupal\Component\Utility\Html;
9
use Drupal\Core\Routing\RouteMatchInterface;
10
use Drupal\facets\Entity\Facet;
11
use Drupal\facets\Entity\FacetSource;
Nick_vh's avatar
Nick_vh committed
12
use Drupal\search_api\Query\QueryInterface;
13
use Drupal\views\Entity\View;
14
use Drupal\Core\Entity\EntityInterface;
15
use Symfony\Component\DependencyInjection\Exception\ServiceNotFoundException;
16 17 18 19

/**
 * Implements hook_help().
 */
20
function facets_help($route_name, RouteMatchInterface $route_match) {
21
  switch ($route_name) {
22 23
    // Main module help for the facets module.
    case 'help.page.facets':
24 25
      $output = '';
      $output .= '<h3>' . t('About') . '</h3>';
26
      $output .= '<p>' . t('Facets test') . '</p>';
27
      return $output;
28
    case 'facets.overview':
29
      return t('Below is a list of facets grouped by facetsources they are associated with. A facetsource is the instance where the facet does the actual filtering, for example a View on a Search API index.');
30 31 32
  }
}

33 34 35 36 37 38 39 40 41 42 43 44 45
/**
 * Implements hook_theme().
 */
function facets_theme($existing, $type, $theme, $path) {
  $result_item_variables = [
    'variables' => ['value' => '', 'show_count' => FALSE, 'count' => NULL],
  ];
  return [
    'facets_result_item' => $result_item_variables,
    'facets_result_item_active' => $result_item_variables,
  ];
}

Nick_vh's avatar
Nick_vh committed
46 47 48 49 50
/**
 * Implementation of hook_search_api_query_alter.
 *
 * @param \Drupal\search_api\Query\QueryInterface $query
 */
51
function facets_search_api_query_alter(QueryInterface &$query) {
52 53 54
  if ($query->getIndex()->getServerInstance()->supportsFeature('search_api_facets')) {
    /** @var \Drupal\facets\FacetManager\DefaultFacetManager $facet_manager */
    $facet_manager = \Drupal::service('facets.manager');
Nick_vh's avatar
Nick_vh committed
55

56
    $search_id = $query->getSearchId();
Nick_vh's avatar
Nick_vh committed
57

58 59 60
    // Add the active filters.
    $facet_manager->alterQuery($query, $search_id);
  }
Nick_vh's avatar
Nick_vh committed
61
}
62 63 64 65 66 67 68

/**
 * Implements hook_entity_presave().
 *
 * We implement this to make sure that a facet gets removed on view updates, so
 * we don't get broken facet blocks.
 */
69
function facets_entity_presave(EntityInterface $entity) {
70 71 72 73 74 75 76 77 78 79 80 81 82
  // Make sure that we only react on view entities with changed displays.
  if ($entity instanceof View && !empty($entity->original)) {
    if ($entity->original->get('display') != $entity->get('display')) {

      /** @var \Drupal\facets\FacetSource\FacetSourcePluginManager $facet_source_plugin_manager */
      $facet_source_plugin_manager = \Drupal::getContainer()
        ->get('plugin.manager.facets.facet_source');
      $definitions = $facet_source_plugin_manager->getDefinitions();

      // Setup an array of sources that are deleted.
      $sources = [];
      foreach ($entity->original->get('display') as $k => $display) {
        // Check if the current display is also a facet source plugin and that
83 84 85
        // is removed from the view. We use the double underscore here to make
        // sure that we use core convention of "plugin:derived_plugin".
        $test = 'views_page:' . $entity->id() . '__' . $display['id'];
86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113
        if (array_key_exists($test, $definitions) && !array_key_exists($k, $entity->get('display'))) {
          $entity_id = str_replace(':', '__', $test);
          $source_entity = FacetSource::load($entity_id);
          if (!is_null($source_entity)) {
            $source_entity->delete();
            $sources[] = $test;
          }
        }
      }


      // Loop over all deleted sources and delete the facets that were linked to
      // that source.
      if (count($sources) > 0) {
        /** @var \Drupal\facets\FacetManager\DefaultFacetManager $fm */
        $fm = \Drupal::getContainer()->get('facets.manager');
        foreach ($sources as $source) {
          $facets = $fm->getFacetsByFacetSourceId($source);
          foreach ($facets as $facet) {
            $facet->delete();
          }
        }
      }
      $facet_source_plugin_manager->clearCachedDefinitions();
    }
  }

}
114 115 116 117 118 119 120 121 122 123 124 125 126

/**
 * Implements hook_preprocess_block().
 *
 * Adds a class for the widget to the facet block to allow for more specific
 * styling.
 */
function facets_preprocess_block(&$variables) {
  if ($variables['configuration']['provider'] == 'facets') {
    $facet = Facet::load($variables['derivative_plugin_id']);
    $variables['attributes']['class'][] = 'block-facet-widget--' . Html::cleanCssIdentifier($facet->getWidget()['type']);
  }
}
127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163

/**
 * Implements hook_entity_predelete().
 *
 * We implement this hook to make sure that facet source plugins are cleared
 * when a view is deleted. It also deletes facets that are created on those
 * plugins.
 */
function facets_entity_predelete(Drupal\Core\Entity\EntityInterface $entity) {
  if ($entity instanceof View) {
    $facet_source_plugin_manager = \Drupal::getContainer()
      ->get('plugin.manager.facets.facet_source');

    $definitions = $facet_source_plugin_manager->getDefinitions();
    if (!is_array($definitions)) {
      return;
    }
    foreach ($definitions as $plugin_id => $definition) {
      if (strpos($plugin_id, 'views_page:' . $entity->id() . '__') !== FALSE) {
        try {
          $facetManager = \Drupal::getContainer()->get('facets.manager');
        } catch (ServiceNotFoundException $e) {
          \Drupal::logger('facets')->log(Drupal\Core\Logger\RfcLogLevel::DEBUG, 'Facet manager not found on trying to delete a view.');
          return;
        }
        $facets = $facetManager->getFacetsByFacetSourceId($plugin_id);
        foreach ($facets as $facet) {
          $facet->delete();
        }
      }
    }

    // Clear cached plugin definitions for facet source to make sure we don't
    // show stale data.
    $facet_source_plugin_manager->clearCachedDefinitions();
  }
}