forked from bmcclure/drupal-search_filters
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
0 parents
commit bb7a6bd
Showing
9 changed files
with
284 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
.idea/ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
{ | ||
"name": "drupal/search_filters", | ||
"type": "drupal-module", | ||
"description": "Customizes taxonomy-based search filtering", | ||
"keywords": ["Drupal"], | ||
"license": "GPL-2.0+", | ||
"homepage": "https://www.drupal.org/project/search_filters", | ||
"minimum-stability": "dev", | ||
"support": { | ||
"issues": "https://www.drupal.org/project/issues/search_filters", | ||
"source": "http://cgit.drupalcode.org/search_filters" | ||
}, | ||
"require": { } | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
name: Search filters | ||
type: module | ||
description: Customizes taxonomy-based search filtering | ||
core: 8.x | ||
package: Search |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
search_filters.admin_settings: | ||
route_name: search_filters.admin_settings | ||
title: 'Search filters' | ||
description: 'Configure search filter mappings.' | ||
parent: system.admin_config_search |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
<?php | ||
|
||
/** | ||
* @file | ||
* Contains search_filters.module. | ||
*/ | ||
|
||
use Drupal\Core\Routing\RouteMatchInterface; | ||
|
||
/** | ||
* Implements hook_help(). | ||
*/ | ||
function search_filters_help($route_name, RouteMatchInterface $route_match) { | ||
switch ($route_name) { | ||
// Main module help for the search_filters module. | ||
case 'help.page.search_filters': | ||
$output = ''; | ||
$output .= '<h3>' . t('About') . '</h3>'; | ||
$output .= '<p>' . t('Customizes taxonomy-based search filtering') . '</p>'; | ||
return $output; | ||
|
||
default: | ||
} | ||
} | ||
|
||
/** | ||
* Implements hook_entity_presave(). | ||
*/ | ||
function search_filters_entity_presave(Drupal\Core\Entity\EntityInterface $entity) { | ||
$mapping = new \Drupal\search_filters\SearchFiltersMapping(); | ||
|
||
$mapping->setFiltersOnEntity($entity); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
'administer search filters': | ||
title: 'Administer search filters' |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
search_filters.admin_settings: | ||
path: /admin/config/search/search-filters | ||
defaults: | ||
_title: 'Search Filters' | ||
_form: \Drupal\search_filters\Form\SettingsForm | ||
requirements: | ||
_permission: 'administer search filters' |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,68 @@ | ||
<?php | ||
|
||
namespace Drupal\search_filters\Form; | ||
|
||
use Drupal\Core\Form\ConfigFormBase; | ||
use Drupal\Core\Form\FormStateInterface; | ||
|
||
class SettingsForm extends ConfigFormBase { | ||
|
||
/** | ||
* {@inheritdoc} | ||
*/ | ||
public function getFormId() { | ||
return 'search_filters_admin_settings'; | ||
} | ||
|
||
/** | ||
* {@inheritdoc} | ||
*/ | ||
public function submitForm(array &$form, FormStateInterface $form_state) { | ||
$this->config('search_filters.settings') | ||
->set('bundle_mapping', $form_state->getValue('bundle_mapping')) | ||
->set('vocabulary', $form_state->getValue('vocabulary')) | ||
->set('field_name', $form_state->getValue('field_name')) | ||
->save(); | ||
|
||
parent::submitForm($form, $form_state); | ||
} | ||
|
||
/** | ||
* {@inheritdoc} | ||
*/ | ||
protected function getEditableConfigNames() { | ||
return ['search_filters.settings']; | ||
} | ||
|
||
public function buildForm(array $form, FormStateInterface $form_state) { | ||
$config = $this->config('search_filters.settings'); | ||
|
||
$form['information'] = [ | ||
'#markup' => '<p>After saving these settings, any affected entities will need to be re-saved.</p>', | ||
]; | ||
|
||
$form['vocabulary'] = [ | ||
'#type' => 'textfield', | ||
'#title' => $this->t('Filters vocabulary'), | ||
'#description' => $this->t('The taxonomy vocabulary ID to use for the search filters.'), | ||
'#default_value' => $config->get('vocabulary'), | ||
]; | ||
|
||
$form['field_name'] = [ | ||
'#type' => 'textfield', | ||
'#title' => $this->t('Field name'), | ||
'#description' => $this->t('The name of the term reference field to store the filter values in.'), | ||
'#default_value' => $config->get('field_name'), | ||
]; | ||
|
||
$form['bundle_mapping'] = [ | ||
'#type' => 'textarea', | ||
'#title' => $this->t('Bundle mapping'), | ||
'#description' => $this->t('A list of mappings in the format "entity_type:bundle:Term Name", one per line. Bundle can be * for a wildcard. Term name can also be in the format [field_name] to use a field from the entity as the term.'), | ||
'#default_value' => $config->get('bundle_mapping'), | ||
]; | ||
|
||
return parent::buildForm($form, $form_state); | ||
} | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,149 @@ | ||
<?php | ||
|
||
namespace Drupal\search_filters; | ||
|
||
use Drupal\Core\Entity\EntityInterface; | ||
use Drupal\Core\Entity\FieldableEntityInterface; | ||
use Drupal\taxonomy\Entity\Vocabulary; | ||
use Drupal\taxonomy\VocabularyInterface; | ||
|
||
class SearchFiltersMapping { | ||
protected $mapping = []; | ||
protected $config; | ||
|
||
public function __construct($mapping = NULL) { | ||
$this->config = \Drupal::config('search_filters.settings'); | ||
|
||
if (is_null($mapping)) { | ||
$mapping = $this->config->get('bundle_mapping'); | ||
} | ||
|
||
$this->setMapping($mapping); | ||
} | ||
|
||
public function setMapping($mapping = NULL) { | ||
$this->mapping = []; | ||
|
||
if (is_array($mapping)) { | ||
$this->mapping = $mapping; | ||
} elseif (is_string($mapping)) { | ||
$bundle_mapping = preg_split('/(\r\n|\r|\n)/', $mapping); | ||
|
||
foreach ($bundle_mapping as $line) { | ||
list($entity_type, $bundle, $values) = explode(':', $line, 3); | ||
|
||
$values = explode('|', $values); | ||
|
||
foreach ($values as $value) { | ||
$this->mapping[$entity_type][$bundle][] = $value; | ||
} | ||
} | ||
} | ||
} | ||
|
||
public function shouldSetFilters(EntityInterface $entity) { | ||
if (!$entity instanceof FieldableEntityInterface) { | ||
return FALSE; | ||
} | ||
|
||
$config = \Drupal::config('search_filters.settings'); | ||
|
||
if (empty($config->get('vocabulary')) || empty($config->get('field_name'))) { | ||
return FALSE; | ||
} | ||
|
||
$vocabulary = Vocabulary::load($config->get('vocabulary')); | ||
|
||
if (!$vocabulary instanceof VocabularyInterface) { | ||
return FALSE; | ||
} | ||
|
||
$field_name = $config->get('field_name'); | ||
|
||
if (!$entity->hasField($field_name)) { | ||
return FALSE; | ||
} | ||
|
||
if (!array_key_exists($entity->getEntityTypeId(), $this->mapping)) { | ||
return FALSE; | ||
} | ||
|
||
return (array_key_exists($entity->bundle(), $this->mapping[$entity->getEntityTypeId()]) | ||
|| array_key_exists('*', $this->mapping[$entity->getEntityTypeId()])); | ||
} | ||
|
||
public function setFiltersOnEntity(EntityInterface $entity) { | ||
if (!$this->shouldSetFilters($entity)) { | ||
return; | ||
} | ||
|
||
/** @var FieldableEntityInterface $entity */ | ||
|
||
$this->clearFilterValues($entity); | ||
|
||
foreach ([$entity->bundle(), '*'] as $bundle_key) { | ||
if (array_key_exists($bundle_key, $this->mapping[$entity->getEntityTypeId()])) { | ||
foreach ($this->mapping[$entity->getEntityTypeId()][$bundle_key] as $term_name) { | ||
$this->setFilterOnEntity($term_name, $entity); | ||
} | ||
} | ||
} | ||
} | ||
|
||
protected function clearFilterValues(FieldableEntityInterface $entity) { | ||
$config = \Drupal::config('search_filters.settings'); | ||
|
||
$field_name = $config->get('field_name'); | ||
|
||
if ($entity->hasField($field_name)) { | ||
$entity->get($field_name)->setValue([]); | ||
} | ||
} | ||
|
||
protected function setFilterOnEntity($term_name, FieldableEntityInterface $entity) { | ||
if (strpos($term_name, '[') === 0) { | ||
$name_field = str_replace(['[', ']'], '', $term_name); | ||
|
||
if (!$entity->hasField($name_field) || $entity->get($name_field)->isEmpty()) { | ||
return; | ||
} | ||
|
||
$term_name = $entity->get($name_field)->value; | ||
} | ||
|
||
$config = \Drupal::config('search_filters.settings'); | ||
|
||
$properties = [ | ||
'vid' => $config->get('vocabulary'), | ||
'name' => $term_name, | ||
]; | ||
|
||
$terms = \Drupal::entityTypeManager()->getStorage('taxonomy_term')->loadByProperties($properties); | ||
|
||
$term = reset($terms); | ||
|
||
if (empty($term)) { | ||
$term = \Drupal::entityTypeManager()->getStorage('taxonomy_term')->create($properties); | ||
$term->save(); | ||
} | ||
|
||
$field_name = $config->get('field_name'); | ||
|
||
$values = $entity->get($field_name)->getValue(); | ||
|
||
$exists = FALSE; | ||
|
||
foreach ($values as $item) { | ||
if ($item['target_id'] == $term->id()) { | ||
$exists = TRUE; | ||
break; | ||
} | ||
} | ||
|
||
if (!$exists) { | ||
$values[] = ['target_id' => $term->id()]; | ||
} | ||
|
||
$entity->get($field_name)->setValue($values); | ||
} | ||
} |