Commit ab89981c authored by FredericoT's avatar FredericoT Committed by mikeker

Issue #2348825 by Frederico | netsensei: Port the URL processor.

parent 51ae2439
<?php
/**
* @file
* Contains Drupal\facetapi\Plugin\Block\FacetUrlProcessor.
*/
namespace Drupal\facetapi\Plugin\Url;
/**
* In D7 this was the abstract class extended by all url processor plugins.
* This called FacetApiUrlProcessor but the name would then no longer be consistent
* with the FacetBlock class. Revisit the naming convention in this module?
*
* Url processor plugins provided a pluggable method of retrieving facet data.
* Most commonly facet data was retrieved from a query string variable via $_GET,
* however custom plugis could be written to retrieve data from the path as well.
* In addition to facet data retrieval, the url processor plugin was also
* responsible for building facet links and setting breadcrumb trails.
*
* Each adapter instance was associated with a single url processor plugin. The
* plugin was associated with the adapter via hook_facetapi_searcher_info()
* implementations.
*
* All functions and comments in this class have currently been copy/pasted verbatim
* and then tweaked to provide a skeleton that describes what the D7 version used to handle.
*/
abstract class FacetUrlProcessor {
/**
* Held the adapter that the url processor plugin was associated with.
*
* @var FacetapiAdapter
*/
protected $adapter;
/**
* An array of facet params, usually $_GET.
*
* @var array.
*/
protected $params = array();
/**
* The array key in FacetapiUrlProcessor::params that would contain the facet data.
* Also gets defined in the function parameters again.
* Try and keep this in one place if possible?
*
* @var string
*/
protected $filterKey = 'f';
/**
* Constructed the FacetapiUrlProcessor object.
*
* @param FacetapiAdapter $adapter
* The adapter that the url processor plugin would get associated with.
*/
public function __construct(FacetapiAdapter $adapter) {
$this->adapter = $adapter;
}
/**
* Fetched parameters from the source, usually $_GET.
*
* This method would be invoked in FacetapiAdapter::__construct().
*
* @return array
* An associative array containing the params, usually $_GET.
*/
abstract public function fetchParams();
/**
* Normalized the array returned by FacetapiAdapter::fetchParams().
*
* When extracting data from a source such as $_GET, there are certain items
* that you might not want, for example the "q" or "page" keys. This method is
* useful for filtering those out. In addition, plugins that do not get data
* from $_GET can use this method to normalize the data into an associative
* array that closely matches the data structure of $_GET.
*
* @param array $params
* An array of keyed params, usually as $_GET.
* @param string $filter_key
* The array key in $params containing the facet data, defaults to "f".
* Hardcoded to 'f' in D7 but actually it is already defined in the filterKey property
* so it might make sense to no longer hardcode this in here if this function remains?
*
* @return array
* An associative array containing the normalized params.
*/
abstract public function normalizeParams(array $params, $filter_key = 'f');
/**
* Returned the query string variables for a facet item.
*
* The return array must be able to be passed as the "query" key of the
* options array passed as the second argument to the url() function. See
* http://api.drupal.org/api/drupal/includes%21common.inc/function/url/7 for
* more details.
*
* @param array $facet
* The facet definition as returned by facetapi_facet_load().
* @param array $values
* An array containing the item's values being added to or removed from the
* query string dependent on whether or not the item is active.
* @param int $active
* An integer flagging whether the item is active or not. 1 if the item is
* active, 0 if it is not.
*
* @return array
* The query string variables.
*/
abstract public function getQueryString(array $facet, array $values, $active);
/**
* Returned the path for a facet item.
*
* This function seems to take more parameters then it needs
* and is not used in the standard url processor?
*
* @param array $facet
* The facet definition.
* @param array $values
* An array containing the item's values being added to or removed from the
* query string dependent on whether or not the item is active.
* @param int $active
* An integer flagging whether the item is active or not.
*
* @return string
* The path of the facet.
*/
public function getFacetPath(array $facet, array $values, $active) {
// Simply returned the search path defined by the adapter
return $this->adapter->getSearchPath();
}
/**
* This was used by the breadcrumb trail for active searches.
*
* This method was called by FacetapiAdapter::processFacets(), which in turn was called
* directly by the backend to search the chain of Facet API events.
*
* This functionality might be moved in D8 or become an option rather then
* remain standard functionality
*/
abstract public function setBreadcrumb();
/**
* Used to set the normalized parameters.
*
* This method was usually called by FacetapiAdapter::setParams() and would very
* rarely get called directly.
*
* @param array $params
* An array of normalized params hat have already been passed through
* FacetapiUrlProcessor::normalizeParams().
* @param string $filter_key
* The array key in $params containing the facet data, defaults to "f".
* Hardcoded to 'f' in D7 but actually it is already defined in the filterKey property
* so it might make sense to no longer hardcode this in here if this function remains?
*
* @return FacetapiUrlParser
* An instance of this class.
*/
public function setParams(array $params, $filter_key = 'f') {
$this->params = $params;
$this->filterKey = $filter_key;
if (!isset($this->params[$this->filterKey]) || !is_array($this->params[$this->filterKey])) {
$this->params[$this->filterKey] = array();
}
return $this;
}
/**
* A simple getter that returned the params property.
*
* @return array
* An array containing the params.
*/
public function getParams() {
return $this->params;
}
/**
* Removed an item from the $this->params array.
*
* @param int $pos
* The zero-based position of the value in the source data.
*/
public function removeParam($pos) {
unset($this->params[$this->filterKey][$pos]);
}
/**
* A simple getter that returned the filter key property.
*
* @return string
* A string containing the filter key.
*/
public function getFilterKey() {
return $this->filterKey;
}
/**
* A function that allowed for processor specific overrides to the settings form.
*/
public function settingsForm(&$form, &$form_state) {
// Nothing to do...
}
/**
* Provided default values for the backend specific settings.
*
* @return array
* The defaults keyed by setting name to value.
*/
public function getDefaultSettings() {
return array();
}
}
<?php
/**
* @file
* Contains Drupal\facetapi\Plugin\Block\FacetUrlProcessor.
*/
namespace Drupal\facetapi\Plugin\Url;
/**
* In D7 this was the standard url processor
* This called FacetApiUrlProcessorStandard but the name would then no longer be consistent
* with the FacetBlock class. Revisit the naming convention in this module?
*
* This was the standard url processor plugin that retrieved facet data from the query string.
*
* This plugin retrieved facet data from $_GET, and stored all information in
* the "f" query string variable by default.
*
* All functions and comments in this class have currently been copy/pasted verbatim
* and then tweaked to provide a skeleton that describes what the D7 version used to handle.
*/
class FacetUrlProcessorStandard extends FacetUrlProcessor {
/**
* Stored the "limit_active_items" settings for each facet.
*
* @var array
*/
protected $limitActiveItems = array();
/**
* Implemented FacetapiUrlProcessor::fetchParams().
*
* Used the $_GET variable as the source for facet data.
*/
public function fetchParams() {
return $_GET;
}
/**
* Implemented FacetapiUrlProcessor::normalizeParams().
*
* Striped the "q" and "page" variables from the params array.
*
* @param array $params
* An array of keyed params, usually as $_GET.
* @param string $filter_key
* The array key in $params containing the facet data, defaults to "f".
* Hardcoded to 'f' in D7 but actually it is already defined in the filterKey property
* so it might make sense to no longer hardcode this in here if this function remains?
*
* @return array
* An associative array containing the normalized params.
*/
public function normalizeParams(array $params, $filter_key = 'f') {
return drupal_get_query_parameters($params, array('q', 'page'));
}
/**
* Implemented FacetapiUrlProcessor::getQueryString().
*
* @param array $facet
* The facet definition as returned by facetapi_facet_load().
* @param array $values
* An array containing the item's values being added to or removed from the
* query string dependent on whether or not the item is active.
* @param int $active
* An integer flagging whether the item is active or not. 1 if the item is
* active, 0 if it is not.
*
* @return array
* The query string variables.
*/
public function getQueryString(array $facet, array $values, $active) {
$qstring = $this->params;
$active_items = $this->adapter->getActiveItems($facet);
// Appends to qstring if inactive, removes if active.
foreach ($values as $value) {
if ($active && isset($active_items[$value])) {
unset($qstring[$this->filterKey][$active_items[$value]['pos']]);
}
elseif (!$active) {
$field_alias = rawurlencode($facet['field alias']);
// Strips all other filters for this facet if limit option is set.
if ($this->limitActiveItems($facet)) {
foreach ($qstring[$this->filterKey] as $pos => $filter) {
// Refactor the if statement to best practises?
// (strpos($filter, $field_alias) === 0) or (strpos($filter, $field_alias) === FALSE)
if (0 === strpos($filter, $field_alias)) {
unset($qstring[$this->filterKey][$pos]);
}
}
}
// Adds the filter to the query string.
$qstring[$this->filterKey][] = $field_alias . ':' . $value;
}
}
// Removes duplicates, resets array keys and returns query string.
// @see http://drupal.org/node/1340528
$qstring[$this->filterKey] = array_values(array_unique($qstring[$this->filterKey]));
return array_filter($qstring);
}
/**
* Checked the facet's global "limit_active_items" settings.
*
* @param array $facet
* The facet definition as returned by facetapi_facet_load().
*
* @return int
* Whether or not to limit active items to one per facet.
*/
public function limitActiveItems(array $facet) {
// If the limit property is not set for this facet
// retreive the settings from the facet via the adapter
if (!isset($this->limitActiveItems[$facet['name']])) {
$settings = $this->adapter->getFacetSettingsGlobal($facet);
$this->limitActiveItems[$facet['name']] = $settings->settings['limit_active_items'];
}
return $this->limitActiveItems[$facet['name']];
}
/**
* Implemented FacetapiUrlProcessor::setBreadcrumb().
*/
public function setBreadcrumb() {
// Get the current breadcrumbs
$breadcrumb = drupal_get_breadcrumb();
// Gets search keys and active items from the adapter.
$keys = $this->adapter->getSearchKeys();
$active_items = $this->adapter->getAllActiveItems();
// Get the current menu item.
// Variable is not used however. Remove this line?
$item = menu_get_item();
// Initializes base breadcrumb query.
$query = $this->params;
unset($query[$this->filterKey]);
// Adds the current search to the query.
if ($keys) {
// The last item should be text, not a link.
$breadcrumb[] = $active_items ? l($keys, current_path(), array('query' => $query)) : check_plain($keys);
}
// Adds filters to the breadcrumb trail.
$last = end($active_items);
foreach ($active_items as $item) {
// Add items in the 'field_alias:value' format
$query[$this->filterKey][] = rawurlencode($item['field alias']) . ':' . $item['value'];
// Replaces with the mapped value.
$value = $this->adapter->getMappedValue($item['facets'][0], $item['value']);
// The last item should be text, not a link.
if ($last == $item) {
$breadcrumb[] = !empty($value['#html']) ? $value['#markup'] : check_plain($value['#markup']);
}
else {
// Appends the filter to the breadcrumb trail.
$breadcrumb[] = l($value['#markup'], current_path(), array('query' => $query, 'html' => !empty($value['#html'])));
}
}
// Sets the breadcrumb trail with the keys and filters.
drupal_set_breadcrumb($breadcrumb);
}
/**
* Allowed for processor specific overrides to the settings form.
*/
public function settingsForm(&$form, &$form_state) {
$facet = $form['#facetapi']['facet'];
$settings = $this->adapter->getFacetSettingsGlobal($facet);
// Add the limit active item field to the form
$form['global']['limit_active_items'] = array(
'#type' => 'checkbox',
'#title' => t('Limit to one active item'),
'#prefix' => '<div class="facetapi-global-setting">',
'#suffix' => '</div>',
'#default_value' => !empty($settings->settings['limit_active_items']),
'#description' => t('Enabling this option allows only one item to be active at a time.'),
);
}
/**
* Provided default values for the backend specific settings.
*
* @return array
* The defaults keyed by setting name to value. Defaults to '0'.
*/
public function getDefaultSettings() {
return array(
'limit_active_items' => 0
);
}
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment