summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorborisson_2015-12-20 09:38:29 (GMT)
committerJoris Vercammen2015-12-20 09:38:29 (GMT)
commit79dfe113e463d01d77076265f6d0d78b29383d6b (patch)
treec92f26344e48a7652811e947a76189c582b47d66
parentdba815bf3dc387e415ed405abdd90283c6a304af (diff)
Issue #2612090 by borisson_: Add a storage for facetSource specific config
-rw-r--r--config/schema/facets.facetsource.schema.yml16
-rw-r--r--core_search_facets/src/Plugin/CoreSearchFacetSourceInterface.php4
-rw-r--r--core_search_facets/src/Plugin/facets/facet_source/CoreNodeSearchFacetSource.php5
-rw-r--r--facets.routing.yml9
-rw-r--r--src/Annotation/FacetsFacetSource.php2
-rw-r--r--src/Controller/FacetSourceController.php31
-rw-r--r--src/Entity/Facet.php46
-rw-r--r--src/Entity/FacetSource.php98
-rw-r--r--src/FacetInterface.php12
-rw-r--r--src/FacetListBuilder.php11
-rw-r--r--src/FacetManager/DefaultFacetManager.php8
-rw-r--r--src/FacetSource/FacetSourcePluginBase.php4
-rw-r--r--src/FacetSource/FacetSourcePluginInterface.php (renamed from src/FacetSource/FacetSourceInterface.php)10
-rw-r--r--src/FacetSource/FacetSourcePluginManager.php2
-rw-r--r--src/FacetSourceInterface.php41
-rw-r--r--src/Form/FacetForm.php2
-rw-r--r--src/Form/FacetSourceEditForm.php88
-rw-r--r--src/Plugin/facets/facet_source/SearchApiBaseFacetSource.php5
-rw-r--r--src/Processor/UrlProcessorPluginBase.php13
-rw-r--r--src/Tests/FacetSourceTest.php40
-rw-r--r--tests/src/Unit/Plugin/processor/QueryStringUrlProcessorTest.php71
21 files changed, 479 insertions, 39 deletions
diff --git a/config/schema/facets.facetsource.schema.yml b/config/schema/facets.facetsource.schema.yml
new file mode 100644
index 0000000..962703e
--- /dev/null
+++ b/config/schema/facets.facetsource.schema.yml
@@ -0,0 +1,16 @@
+facets.facet_source.*:
+ type: config_entity
+ label : 'Facet Source'
+ mapping:
+ uuid:
+ type: string
+ label: 'UUID'
+ id:
+ type: string
+ label: 'ID'
+ name:
+ type: label
+ label: Name'
+ filterKey:
+ type: string
+ label: 'Filter key'
diff --git a/core_search_facets/src/Plugin/CoreSearchFacetSourceInterface.php b/core_search_facets/src/Plugin/CoreSearchFacetSourceInterface.php
index fa16be5..24486a2 100644
--- a/core_search_facets/src/Plugin/CoreSearchFacetSourceInterface.php
+++ b/core_search_facets/src/Plugin/CoreSearchFacetSourceInterface.php
@@ -2,7 +2,7 @@
/**
* @file
- * Contains \Drupal\core_search_facets\Plugin\FacetSourceInterface.
+ * Contains \Drupal\core_search_facets\Plugin\CoreSearchFacetSourceInterface.
*/
namespace Drupal\core_search_facets\Plugin;
@@ -14,7 +14,7 @@ use Drupal\facets\FacetInterface;
*
* A facet source is used to abstract the data source where facets can be added
* to. A good example of this is a search api view. There are other possible
- * facet data sources, these all implement the FacetSourceInterface.
+ * facet data sources, these all implement the FacetSourcePluginInterface.
*/
interface CoreSearchFacetSourceInterface {
diff --git a/core_search_facets/src/Plugin/facets/facet_source/CoreNodeSearchFacetSource.php b/core_search_facets/src/Plugin/facets/facet_source/CoreNodeSearchFacetSource.php
index 38b135e..12e6319 100644
--- a/core_search_facets/src/Plugin/facets/facet_source/CoreNodeSearchFacetSource.php
+++ b/core_search_facets/src/Plugin/facets/facet_source/CoreNodeSearchFacetSource.php
@@ -12,10 +12,9 @@ use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\StringTranslation\StringTranslationTrait;
use Drupal\core_search_facets\Plugin\CoreSearchFacetSourceInterface;
use Drupal\facets\FacetInterface;
-use Drupal\facets\FacetSource\FacetSourceInterface;
use Drupal\facets\FacetSource\FacetSourcePluginBase;
+use Drupal\facets\FacetSource\FacetSourcePluginInterface;
use Drupal\field\Entity\FieldConfig;
-use Drupal\field\Entity\FieldStorageConfig;
use Drupal\search\SearchPageInterface;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Symfony\Component\HttpFoundation\RequestStack;
@@ -178,7 +177,7 @@ class CoreNodeSearchFacetSource extends FacetSourcePluginBase implements CoreSea
/**
* {@inheritdoc}
*/
- public function buildConfigurationForm(array $form, FormStateInterface $form_state, FacetInterface $facet, FacetSourceInterface $facet_source) {
+ public function buildConfigurationForm(array $form, FormStateInterface $form_state, FacetInterface $facet, FacetSourcePluginInterface $facet_source) {
$form['field_identifier'] = [
'#type' => 'select',
diff --git a/facets.routing.yml b/facets.routing.yml
index 576dd64..5202aa7 100644
--- a/facets.routing.yml
+++ b/facets.routing.yml
@@ -41,3 +41,12 @@ entity.facets_facet.display_form:
_entity_form: 'facets_facet.display'
requirements:
_entity_access: 'facets_facet.edit'
+
+
+entity.facets_facetsource.edit_form:
+ path: '/admin/config/search/facets/facet-sources/{source_id}/edit'
+ defaults:
+ _controller: '\Drupal\facets\Controller\FacetSourceController::facetSourceConfigForm'
+ _title: 'Edit facet source configuration'
+ requirements:
+ _entity_create_access: 'facets_facet'
diff --git a/src/Annotation/FacetsFacetSource.php b/src/Annotation/FacetsFacetSource.php
index bfe425c..7389e31 100644
--- a/src/Annotation/FacetsFacetSource.php
+++ b/src/Annotation/FacetsFacetSource.php
@@ -13,7 +13,7 @@ use Drupal\Component\Annotation\Plugin;
* Defines a Facets facet source annotation.
*
* @see \Drupal\facets\FacetSource\FacetSourcePluginManager
- * @see \Drupal\facets\FacetSource\FacetSourceInterface
+ * @see \Drupal\facets\FacetSource\FacetSourcePluginInterface
* @see \Drupal\facets\FacetSource\FacetSourcePluginBase
* @see plugin_api
*
diff --git a/src/Controller/FacetSourceController.php b/src/Controller/FacetSourceController.php
new file mode 100644
index 0000000..578e7c9
--- /dev/null
+++ b/src/Controller/FacetSourceController.php
@@ -0,0 +1,31 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\facets\Controller\FacetSourceController.
+ */
+
+namespace Drupal\facets\Controller;
+
+use Drupal\Core\Controller\ControllerBase;
+
+/**
+ * Provides route responses for facet source configuration.
+ */
+class FacetSourceController extends ControllerBase {
+
+ /**
+ * Configuration for the facet source.
+ *
+ * @param string $source_id
+ * The plugin id.
+ *
+ * @return array
+ * A renderable array containing the form.
+ */
+ public function facetSourceConfigForm($source_id) {
+ // Returns the render array of the FacetSourceConfigForm.
+ return $this->formBuilder()->getForm('\Drupal\facets\Form\FacetSourceEditForm');
+ }
+
+}
diff --git a/src/Entity/Facet.php b/src/Entity/Facet.php
index 889a074..88c71bd 100644
--- a/src/Entity/Facet.php
+++ b/src/Entity/Facet.php
@@ -131,7 +131,7 @@ class Facet extends ConfigEntityBase implements FacetInterface {
/**
* The facet source belonging to this facet.
*
- * @var \Drupal\facets\FacetSource\FacetSourceInterface
+ * @var \Drupal\facets\FacetSource\FacetSourcePluginInterface
*
* @see getFacetSource()
*/
@@ -187,6 +187,14 @@ class Facet extends ConfigEntityBase implements FacetInterface {
protected $widget_plugin_manager;
/**
+ * The facet source config object.
+ *
+ * @var \Drupal\Facets\FacetSourceInterface
+ * The facet source config object.
+ */
+ protected $facetSourceConfig;
+
+ /**
* {@inheritdoc}
*/
public function __construct(array $values, $entity_type) {
@@ -371,6 +379,40 @@ class Facet extends ConfigEntityBase implements FacetInterface {
}
/**
+ * {@inheritdoc}
+ */
+ public function getFacetSourceConfig() {
+ // Return the facet source config object, if it's already set on the facet.
+ if ($this->facetSourceConfig instanceof FacetSource) {
+ return $this->facetSourceConfig;
+ }
+
+ $storage = \Drupal::entityTypeManager()->getStorage('facets_facet_source');
+ $source_id = str_replace(':', '__', $this->facet_source_id);
+
+ // Load and return the facet source config object from the storage.
+ $facet_source = $storage->load($source_id);
+ if ($facet_source instanceof FacetSource) {
+ $this->facetSourceConfig = $facet_source;
+ return $this->facetSourceConfig;
+ }
+
+ // We didn't have a facet source config entity yet for this facet source
+ // plugin, so we create it on the fly.
+ $facet_source = new FacetSource(
+ [
+ 'id' => $source_id,
+ 'name' => $this->facet_source_id,
+ ],
+ 'facets_facet_source'
+ );
+ $facet_source->save();
+
+ $this->facetSourceConfig = $facet_source;
+ return $this->facetSourceConfig;
+ }
+
+ /**
* Retrieves all processors supported by this facet.
*
* @return \Drupal\facets\Processor\ProcessorInterface[]
@@ -458,7 +500,7 @@ class Facet extends ConfigEntityBase implements FacetInterface {
// Create our settings for this facet source..
$config = isset($this->facetSourcePlugins[$name]) ? $this->facetSourcePlugins[$name] : [];
- /* @var $facet_source \Drupal\facets\FacetSource\FacetSourceInterface */
+ /* @var $facet_source \Drupal\facets\FacetSource\FacetSourcePluginInterface */
$facet_source = $facet_source_plugin_manager->createInstance($name, $config);
$this->facetSourcePlugins[$name] = $facet_source;
}
diff --git a/src/Entity/FacetSource.php b/src/Entity/FacetSource.php
new file mode 100644
index 0000000..3d3f7ad
--- /dev/null
+++ b/src/Entity/FacetSource.php
@@ -0,0 +1,98 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\facets\Entity\FacetSource.
+ */
+
+namespace Drupal\facets\Entity;
+
+use Drupal\Core\Config\Entity\ConfigEntityBase;
+use Drupal\facets\FacetSourceInterface;
+
+/**
+ * Defines the facet source configuration entity.
+ *
+ * @ConfigEntityType(
+ * id = "facets_facet_source",
+ * label = @Translation("Facet source"),
+ * handlers = {
+ * "storage" = "Drupal\Core\Config\Entity\ConfigEntityStorage",
+ * "list_builder" = "Drupal\facets\FacetListBuilder",
+ * "form" = {
+ * "default" = "Drupal\facets\Form\FacetSourceEditForm",
+ * "edit" = "Drupal\facets\Form\FacetSourceEditForm",
+ * "display" = "Drupal\facets\Form\FacetSourceDisplayForm",
+ * "delete" = "Drupal\facets\Form\FacetSourceDeleteConfirmForm",
+ * },
+ * },
+ * admin_permission = "administer facets",
+ * config_prefix = "facet_source",
+ * entity_keys = {
+ * "id" = "id",
+ * "label" = "name",
+ * "uuid" = "uuid"
+ * },
+ * config_export = {
+ * "id",
+ * "name",
+ * "filterKey"
+ * },
+ * links = {
+ * "canonical" = "/admin/config/search/facets/facet-sources/",
+ * "edit-form" = "/admin/config/search/facets/facet-sources/{facets_facet_source}/edit"
+ * }
+ * )
+ */
+class FacetSource extends ConfigEntityBase implements FacetSourceInterface {
+
+ /**
+ * The ID of the facet source.
+ *
+ * @var string
+ */
+ protected $id;
+
+ /**
+ * A name to be displayed for the facet source.
+ *
+ * @var string
+ */
+ protected $name;
+
+ /**
+ * The key, used for filters in the query string.
+ *
+ * @var string
+ */
+ protected $filterKey;
+
+ /**
+ * {@inheritdoc}
+ */
+ public function id() {
+ return $this->id;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function getName() {
+ return $this->name;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function setFilterKey($filter_key) {
+ $this->filterKey = $filter_key;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function getFilterKey() {
+ return $this->filterKey;
+ }
+
+}
diff --git a/src/FacetInterface.php b/src/FacetInterface.php
index 7e39f2a..58c1cd1 100644
--- a/src/FacetInterface.php
+++ b/src/FacetInterface.php
@@ -200,18 +200,26 @@ interface FacetInterface extends ConfigEntityInterface {
/**
* Returns the plugin instance of a facet source.
*
- * @return \Drupal\facets\FacetSource\FacetSourceInterface
+ * @return \Drupal\facets\FacetSource\FacetSourcePluginInterface
* The plugin instance for the facet source.
*/
public function getFacetSource();
/**
+ * Returns the facet source configuration object.
+ *
+ * @return \Drupal\facets\FacetSourceInterface
+ * A facet source configuration object.
+ */
+ public function getFacetSourceConfig();
+
+ /**
* Load the facet sources for this facet.
*
* @param bool|TRUE $only_enabled
* Only return enabled facet sources.
*
- * @return \Drupal\facets\FacetSource\FacetSourceInterface[]
+ * @return \Drupal\facets\FacetSource\FacetSourcePluginInterface[]
* An array of facet sources.
*/
public function getFacetSources($only_enabled = TRUE);
diff --git a/src/FacetListBuilder.php b/src/FacetListBuilder.php
index 3469a79..bb63d04 100644
--- a/src/FacetListBuilder.php
+++ b/src/FacetListBuilder.php
@@ -10,6 +10,7 @@ namespace Drupal\facets;
use Drupal\Core\Config\Entity\ConfigEntityInterface;
use Drupal\Core\Config\Entity\ConfigEntityListBuilder;
use Drupal\Core\Entity\EntityInterface;
+use Drupal\Core\Link;
/**
* Builds a listing of facet entities.
@@ -134,7 +135,13 @@ class FacetListBuilder extends ConfigEntityListBuilder {
'status' => array(
'data' => '',
),
- 'operations' => array(),
+ 'operations' => array(
+ 'data' => Link::createFromRoute(
+ $this->t('Configure'),
+ 'entity.facets_facetsource.edit_form',
+ ['source_id' => $facet_source['id']]
+ )->toRenderable(),
+ ),
),
'class' => array('facet-source'),
);
@@ -153,7 +160,7 @@ class FacetListBuilder extends ConfigEntityListBuilder {
'#markup' => $this->t(
'You currently have no facet sources defined. You should start by adding a facet source before creating facets.<br />
An example of a facet source is a view based on Search API or a Search API page.
- Other modules can also implement a facet source by providing a plugin that implements the FacetSourceInterface.'
+ Other modules can also implement a facet source by providing a plugin that implements the FacetSourcePluginInterface.'
),
];
}
diff --git a/src/FacetManager/DefaultFacetManager.php b/src/FacetManager/DefaultFacetManager.php
index 254ee04..29bd459 100644
--- a/src/FacetManager/DefaultFacetManager.php
+++ b/src/FacetManager/DefaultFacetManager.php
@@ -96,7 +96,7 @@ class DefaultFacetManager {
*
* @var string
*
- * @see \Drupal\facets\FacetSource\FacetSourceInterface
+ * @see \Drupal\facets\FacetSource\FacetSourcePluginInterface
*/
protected $facetSourceId;
@@ -211,7 +211,7 @@ class DefaultFacetManager {
$processor_definition = $processor->getPluginDefinition();
if (is_array($processor_definition['stages']) && array_key_exists(ProcessorInterface::STAGE_PRE_QUERY, $processor_definition['stages'])) {
/** @var PreQueryProcessorInterface $pre_query_processor */
- $pre_query_processor = $this->processorPluginManager->createInstance($processor->getPluginDefinition()['id']);
+ $pre_query_processor = $this->processorPluginManager->createInstance($processor->getPluginDefinition()['id'], ['facet' => $facet]);
if (!$pre_query_processor instanceof PreQueryProcessorInterface) {
throw new InvalidProcessorException(new FormattableMarkup("The processor @processor has a pre_query definition but doesn't implement the required PreQueryProcessorInterface interface", ['@processor' => $processor_configuration['processor_id']]));
}
@@ -275,7 +275,7 @@ class DefaultFacetManager {
$processor_definition = $this->processorPluginManager->getDefinition($processor->getPluginDefinition()['id']);
if (is_array($processor_definition['stages']) && array_key_exists(ProcessorInterface::STAGE_BUILD, $processor_definition['stages'])) {
/** @var BuildProcessorInterface $build_processor */
- $build_processor = $this->processorPluginManager->createInstance($processor->getPluginDefinition()['id']);
+ $build_processor = $this->processorPluginManager->createInstance($processor->getPluginDefinition()['id'], ['facet' => $facet]);
if (!$build_processor instanceof BuildProcessorInterface) {
throw new InvalidProcessorException(new FormattableMarkup("The processor @processor has a build definition but doesn't implement the required BuildProcessorInterface interface", ['@processor' => $processor['processor_id']]));
}
@@ -308,7 +308,7 @@ class DefaultFacetManager {
*/
public function updateResults() {
// Get an instance of the facet source.
- /** @var \drupal\facets\FacetSource\FacetSourceInterface $facet_source_plugin */
+ /** @var \drupal\facets\FacetSource\FacetSourcePluginInterface $facet_source_plugin */
$facet_source_plugin = $this->facetSourcePluginManager->createInstance($this->facetSourceId);
$facet_source_plugin->fillFacetsWithResults($this->facets);
diff --git a/src/FacetSource/FacetSourcePluginBase.php b/src/FacetSource/FacetSourcePluginBase.php
index 127b721..53dba89 100644
--- a/src/FacetSource/FacetSourcePluginBase.php
+++ b/src/FacetSource/FacetSourcePluginBase.php
@@ -23,10 +23,10 @@ use Drupal\Facets\FacetInterface;
*
* @see \Drupal\facets\Annotation\FacetsFacetSource
* @see \Drupal\facets\FacetSource\FacetSourcePluginManager
- * @see \Drupal\facets\FacetSource\FacetSourceInterface
+ * @see \Drupal\facets\FacetSource\FacetSourcePluginInterface
* @see plugin_api
*/
-abstract class FacetSourcePluginBase extends PluginBase implements FacetSourceInterface, ContainerFactoryPluginInterface {
+abstract class FacetSourcePluginBase extends PluginBase implements FacetSourcePluginInterface, ContainerFactoryPluginInterface {
/**
* The plugin manager.
diff --git a/src/FacetSource/FacetSourceInterface.php b/src/FacetSource/FacetSourcePluginInterface.php
index aef8c7a..93c114e 100644
--- a/src/FacetSource/FacetSourceInterface.php
+++ b/src/FacetSource/FacetSourcePluginInterface.php
@@ -2,7 +2,7 @@
/**
* @file
- * Contains \Drupal\facets\FacetSource\FacetSourceInterface.
+ * Contains \Drupal\facets\FacetSource\FacetSourcePluginInterface.
*/
namespace Drupal\facets\FacetSource;
@@ -15,11 +15,11 @@ use Drupal\facets\FacetInterface;
*
* A facet source is used to abstract the data source where facets can be added
* to. A good example of this is a search api view. There are other possible
- * facet data sources, these all implement the FacetSourceInterface.
+ * facet data sources, these all implement the FacetSourcePluginInterface.
*
* @see plugin_api
*/
-interface FacetSourceInterface {
+interface FacetSourcePluginInterface {
/**
* Adds a configuration form for this facet source.
@@ -30,10 +30,10 @@ interface FacetSourceInterface {
* The current form state.
* @param \Drupal\facets\FacetInterface $facet
* The facet being edited.
- * @param \Drupal\facets\FacetSource\FacetSourceInterface $facet_source
+ * @param \Drupal\facets\FacetSource\FacetSourcePluginInterface $facet_source
* The facet source being edited.
*/
- public function buildConfigurationForm(array $form, FormStateInterface $form_state, FacetInterface $facet, FacetSourceInterface $facet_source);
+ public function buildConfigurationForm(array $form, FormStateInterface $form_state, FacetInterface $facet, FacetSourcePluginInterface $facet_source);
/**
* Fill in facet data in to the configured facets.
diff --git a/src/FacetSource/FacetSourcePluginManager.php b/src/FacetSource/FacetSourcePluginManager.php
index 377af69..1b62874 100644
--- a/src/FacetSource/FacetSourcePluginManager.php
+++ b/src/FacetSource/FacetSourcePluginManager.php
@@ -32,7 +32,7 @@ class FacetSourcePluginManager extends DefaultPluginManager {
* The module handler.
*/
public function __construct(\Traversable $namespaces, CacheBackendInterface $cache_backend, ModuleHandlerInterface $module_handler) {
- parent::__construct('Plugin/facets/facet_source', $namespaces, $module_handler, 'Drupal\facets\FacetSource\FacetSourceInterface', 'Drupal\facets\Annotation\FacetsFacetSource');
+ parent::__construct('Plugin/facets/facet_source', $namespaces, $module_handler, 'Drupal\facets\FacetSource\FacetSourcePluginInterface', 'Drupal\facets\Annotation\FacetsFacetSource');
}
}
diff --git a/src/FacetSourceInterface.php b/src/FacetSourceInterface.php
new file mode 100644
index 0000000..8395760
--- /dev/null
+++ b/src/FacetSourceInterface.php
@@ -0,0 +1,41 @@
+<?php
+
+/**
+ * @file
+ * Contains Drupal\facets\FacetSourceInterface.
+ */
+
+namespace Drupal\facets;
+
+use Drupal\Core\Config\Entity\ConfigEntityInterface;
+
+/**
+ * The facet source entity.
+ */
+interface FacetSourceInterface extends ConfigEntityInterface {
+
+ /**
+ * Returns the label of the facet source.
+ *
+ * @return string
+ * The facet name.
+ */
+ public function getName();
+
+ /**
+ * Gets the filter key for this facet source.
+ *
+ * @return string
+ * The filter key.
+ */
+ public function getFilterKey();
+
+ /**
+ * Sets the filter key for this facet source.
+ *
+ * @param string $filter_key
+ * The filter key.
+ */
+ public function setFilterKey($filter_key);
+
+}
diff --git a/src/Form/FacetForm.php b/src/Form/FacetForm.php
index fbbf518..d16a815 100644
--- a/src/Form/FacetForm.php
+++ b/src/Form/FacetForm.php
@@ -247,7 +247,7 @@ class FacetForm extends EntityForm {
$facet_source_id = $this->getEntity()->getFacetSourceId();
if (!is_null($facet_source_id) && $facet_source_id !== '') {
- /** @var \Drupal\facets\FacetSource\FacetSourceInterface $facet_source */
+ /** @var \Drupal\facets\FacetSource\FacetSourcePluginInterface $facet_source */
$facet_source = $this->getFacetSourcePluginManager()->createInstance($facet_source_id);
if ($config_form = $facet_source->buildConfigurationForm([], $form_state, $this->getEntity(), $facet_source)) {
diff --git a/src/Form/FacetSourceEditForm.php b/src/Form/FacetSourceEditForm.php
new file mode 100644
index 0000000..067a39f
--- /dev/null
+++ b/src/Form/FacetSourceEditForm.php
@@ -0,0 +1,88 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\facets\Form\FacetSourceEditForm.
+ */
+
+namespace Drupal\facets\Form;
+
+use Drupal\Core\Entity\EntityForm;
+use Drupal\Core\Form\FormStateInterface;
+use Drupal\facets\Entity\FacetSource;
+
+/**
+ * Provides a form for editing facet sources.
+ *
+ * Configuration saved trough this form is specific for a facet source and can
+ * be used by all facets on this facet source.
+ */
+class FacetSourceEditForm extends EntityForm {
+
+ /**
+ * Constructs a FacetSourceEditForm.
+ */
+ public function __construct() {
+ $facet_source_storage = \Drupal::entityTypeManager()->getStorage('facets_facet_source');
+
+ // Make sure we remove colons from the source id, those are disallowed in
+ // the entity id.
+ $source_id = $this->getRequest()->get('source_id');
+ $source_id = str_replace(':', '__', $source_id);
+
+ $facet_source = $facet_source_storage->load($source_id);
+
+ if ($facet_source instanceof FacetSource) {
+ $this->setEntity($facet_source);
+ }
+ else {
+
+ // We didn't have a facet source config entity yet for this facet source
+ // plugin, so we create it on the fly.
+ $facet_source = new FacetSource(
+ [
+ 'id' => $source_id,
+ 'name' => $this->getRequest()->get('source_id'),
+ ],
+ 'facets_facet_source'
+ );
+ $facet_source->save();
+ $this->setEntity($facet_source);
+ }
+
+ $this->setModuleHandler(\Drupal::moduleHandler());
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function getFormId() {
+ return 'facet_source_edit_form';
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function buildForm(array $form, FormStateInterface $form_state) {
+
+ /** @var \Drupal\facets\FacetSourceInterface $facet_source */
+ $facet_source = $this->getEntity();
+
+ // Filter key setting.
+ $form['filterKey'] = [
+ '#type' => 'textfield',
+ '#title' => $this->t('Filter key'),
+ '#size' => 20,
+ '#maxlength' => 255,
+ '#default_value' => $facet_source->getFilterKey(),
+ '#description' => $this->t(
+ 'The key used in the url to identify the facet source.
+ When using multiple facet sources you should make sure each facet source has a different filter key.'
+ ),
+ ];
+
+ // The parent's form build method will add a save button.
+ return parent::buildForm($form, $form_state);
+ }
+
+}
diff --git a/src/Plugin/facets/facet_source/SearchApiBaseFacetSource.php b/src/Plugin/facets/facet_source/SearchApiBaseFacetSource.php
index b7f86d5..74e98c8 100644
--- a/src/Plugin/facets/facet_source/SearchApiBaseFacetSource.php
+++ b/src/Plugin/facets/facet_source/SearchApiBaseFacetSource.php
@@ -10,10 +10,9 @@ use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\StringTranslation\StringTranslationTrait;
use Drupal\facets\Exception\InvalidQueryTypeException;
use Drupal\facets\FacetInterface;
+use Drupal\facets\FacetSource\FacetSourcePluginInterface;
use Drupal\search_api\Backend\BackendInterface;
-use Drupal\facets\FacetSource\FacetSourceInterface;
use Drupal\facets\FacetSource\FacetSourcePluginBase;
-use Drupal\search_api\FacetsQueryTypeMappingInterface;
use Symfony\Component\DependencyInjection\ContainerInterface;
/**
@@ -66,7 +65,7 @@ abstract class SearchApiBaseFacetSource extends FacetSourcePluginBase {
/**
* {@inheritdoc}
*/
- public function buildConfigurationForm(array $form, FormStateInterface $form_state, FacetInterface $facet, FacetSourceInterface $facet_source) {
+ public function buildConfigurationForm(array $form, FormStateInterface $form_state, FacetInterface $facet, FacetSourcePluginInterface $facet_source) {
$form['field_identifier'] = [
'#type' => 'select',
diff --git a/src/Processor/UrlProcessorPluginBase.php b/src/Processor/UrlProcessorPluginBase.php
index ee8af0b..99d5875 100644
--- a/src/Processor/UrlProcessorPluginBase.php
+++ b/src/Processor/UrlProcessorPluginBase.php
@@ -7,6 +7,7 @@
namespace Drupal\facets\Processor;
use Drupal\Core\Plugin\ContainerFactoryPluginInterface;
+use Drupal\facets\Exception\InvalidProcessorException;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Symfony\Component\HttpFoundation\Request;
@@ -53,6 +54,18 @@ abstract class UrlProcessorPluginBase extends ProcessorPluginBase implements Url
public function __construct(array $configuration, $plugin_id, $plugin_definition, Request $request) {
parent::__construct($configuration, $plugin_id, $plugin_definition);
$this->request = $request;
+
+ if (!isset($configuration['facet'])) {
+ throw new InvalidProcessorException();
+ }
+
+ /** @var \Drupal\facets\FacetInterface $facet */
+ $facet = $configuration['facet'];
+
+ /** @var \Drupal\facets\FacetSourceInterface $facet_source_config */
+ $facet_source_config = $facet->getFacetSourceConfig();
+
+ $this->filterKey = $facet_source_config->getFilterKey() ?: 'f';
}
/**
diff --git a/src/Tests/FacetSourceTest.php b/src/Tests/FacetSourceTest.php
new file mode 100644
index 0000000..3beef1d
--- /dev/null
+++ b/src/Tests/FacetSourceTest.php
@@ -0,0 +1,40 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\facets\Tests\FacetSourceTest.
+ */
+
+namespace Drupal\facets\Tests;
+
+use \Drupal\facets\Tests\WebTestBase as FacetWebTestBase;
+
+/**
+ * Tests the functionality of the facet source config entity.
+ *
+ * @group facets
+ */
+class FacetSourceTest extends FacetWebTestBase {
+
+ /**
+ * Test the facet source editing.
+ */
+ public function testFacetSource() {
+ // Make sure we're logged in with a user that has sufficient permissions.
+ $this->drupalLogin($this->adminUser);
+
+ // Test the overview.
+ $this->drupalGet('admin/config/search/facets');
+ $this->assertLink($this->t('Configure'));
+ $this->clickLink($this->t('Configure'));
+
+ // Test the edit page.
+ $this->assertField('filterKey');
+ $this->drupalPostForm(NULL, array('filterKey' => 'fq'), $this->t('Save'));
+
+ // Test that saving worked.
+ $this->assertField('filterKey');
+ $this->assertRaw('fq');
+ }
+
+}
diff --git a/tests/src/Unit/Plugin/processor/QueryStringUrlProcessorTest.php b/tests/src/Unit/Plugin/processor/QueryStringUrlProcessorTest.php
index 2315ddf..d23054b 100644
--- a/tests/src/Unit/Plugin/processor/QueryStringUrlProcessorTest.php
+++ b/tests/src/Unit/Plugin/processor/QueryStringUrlProcessorTest.php
@@ -8,6 +8,7 @@
namespace Drupal\Tests\facets\Unit\Plugin\Processor;
use Drupal\facets\Entity\Facet;
+use Drupal\facets\Entity\FacetSource;
use Drupal\facets\Plugin\facets\processor\QueryStringUrlProcessor;
use Drupal\facets\Result\Result;
use Drupal\Tests\UnitTestCase;
@@ -49,6 +50,8 @@ class QueryStringUrlProcessorTest extends UnitTestCase {
new Result('duck', 'Duck', 15),
new Result('alpaca', 'Alpaca', 25),
];
+
+ $this->setContainer();
}
/**
@@ -62,7 +65,7 @@ class QueryStringUrlProcessorTest extends UnitTestCase {
$request = new Request();
$request->query->set('f', ['test:badger']);
- $this->processor = new QueryStringUrlProcessor([], 'query_string', [], $request);
+ $this->processor = new QueryStringUrlProcessor(['facet' => $facet], 'query_string', [], $request);
$this->processor->preQuery($facet);
$this->assertEquals(['badger'], $facet->getActiveItems());
@@ -79,7 +82,7 @@ class QueryStringUrlProcessorTest extends UnitTestCase {
$request = new Request();
$request->query->set('f', ['test:badger', 'test:mushroom', 'donkey:kong']);
- $this->processor = new QueryStringUrlProcessor([], 'query_string', [], $request);
+ $this->processor = new QueryStringUrlProcessor(['facet' => $facet], 'query_string', [], $request);
$this->processor->preQuery($facet);
$this->assertEquals(['badger', 'mushroom'], $facet->getActiveItems());
@@ -95,7 +98,7 @@ class QueryStringUrlProcessorTest extends UnitTestCase {
$request = new Request();
$request->query->set('f', []);
- $this->processor = new QueryStringUrlProcessor([], 'query_string', [], $request);
+ $this->processor = new QueryStringUrlProcessor(['facet' => $facet], 'query_string', [], $request);
$results = $this->processor->build($facet, []);
$this->assertEmpty($results);
}
@@ -111,9 +114,7 @@ class QueryStringUrlProcessorTest extends UnitTestCase {
$request = new Request();
$request->query->set('f', []);
- $this->setContainer();
-
- $this->processor = new QueryStringUrlProcessor([], 'query_string', [], $request);
+ $this->processor = new QueryStringUrlProcessor(['facet' => $facet], 'query_string', [], $request);
$results = $this->processor->build($facet, $this->originalResults);
/** @var \Drupal\facets\Result\ResultInterface $r */
@@ -137,9 +138,7 @@ class QueryStringUrlProcessorTest extends UnitTestCase {
$request = new Request();
$request->query->set('f', ['king:kong']);
- $this->setContainer();
-
- $this->processor = new QueryStringUrlProcessor([], 'query_string', [], $request);
+ $this->processor = new QueryStringUrlProcessor(['facet' => $facet], 'query_string', [], $request);
$results = $this->processor->build($facet, $original_results);
/** @var \Drupal\facets\Result\ResultInterface $r */
@@ -155,6 +154,46 @@ class QueryStringUrlProcessorTest extends UnitTestCase {
}
/**
+ * Test that the facet source configuration filter key override works.
+ */
+ public function testFacetSourceFilterKeyOverride() {
+ $facet_source = new FacetSource(['filterKey' => 'ab'], 'facets_facet_source');
+
+ // Override the container with the new facet source.
+ $storage = $this->getMock('\Drupal\Core\Entity\EntityStorageInterface');
+ $storage->expects($this->once())
+ ->method('load')
+ ->willReturn($facet_source);
+ $em = $this->getMockBuilder('\Drupal\Core\Entity\EntityTypeManagerInterface')
+ ->disableOriginalConstructor()
+ ->getMock();
+ $em->expects($this->any())
+ ->method('getStorage')
+ ->willReturn($storage);
+
+ $container = \Drupal::getContainer();
+ $container->set('entity_type.manager', $em);
+ \Drupal::setContainer($container);
+
+ $facet = new Facet([], 'facet');
+ $facet->setFieldIdentifier('test');
+ $facet->setFacetSourceId('facet_source__dummy');
+
+ $request = new Request();
+ $request->query->set('ab', []);
+
+ $this->processor = new QueryStringUrlProcessor(['facet' => $facet], 'query_string', [], $request);
+ $results = $this->processor->build($facet, $this->originalResults);
+
+ /** @var \Drupal\facets\Result\ResultInterface $r */
+ foreach ($results as $r) {
+ $this->assertInstanceOf('\Drupal\facets\Result\ResultInterface', $r);
+ $this->assertEquals('route:test?ab[0]=test%3A' . $r->getRawValue(), $r->getUrl()->toUriString());
+ }
+
+ }
+
+ /**
* Set the container for use in unit tests.
*/
protected function setContainer() {
@@ -170,21 +209,31 @@ class QueryStringUrlProcessorTest extends UnitTestCase {
]
);
- $fsi = $this->getMockBuilder('\Drupal\facets\FacetSource\FacetSourceInterface')
+ $fsi = $this->getMockBuilder('\Drupal\facets\FacetSource\FacetSourcePluginInterface')
->disableOriginalConstructor()
->getMock();
$fsi->method('getPath')
->willReturn('search/test');
- $manager = $this->getMockBuilder('Drupal\facets\FacetSource\FacetSourcePluginManager')
+ $manager = $this->getMockBuilder('\Drupal\facets\FacetSource\FacetSourcePluginManager')
->disableOriginalConstructor()
->getMock();
$manager->method('createInstance')
->willReturn($fsi);
+ $storage = $this->getMock('\Drupal\Core\Entity\EntityStorageInterface');
+ $em = $this->getMockBuilder('\Drupal\Core\Entity\EntityTypeManagerInterface')
+ ->disableOriginalConstructor()
+ ->getMock();
+ $em->expects($this->any())
+ ->method('getStorage')
+ ->willReturn($storage);
+
$container = new ContainerBuilder();
$container->set('router.no_access_checks', $router);
$container->set('plugin.manager.facets.facet_source', $manager);
+ $container->set('entity_type.manager', $em);
+ $container->set('entity.manager', $em);
\Drupal::setContainer($container);
}