class FacetapiFacetProcessor in Facet API 6.3
Same name and namespace in other branches
- 7.2 plugins/facetapi/adapter.inc \FacetapiFacetProcessor
- 7 plugins/facetapi/adapter.inc \FacetapiFacetProcessor
Processes facets, initializes the build.
Hierarchy
- class \FacetapiFacetProcessor
Expanded class hierarchy of FacetapiFacetProcessor
File
- plugins/
facetapi/ adapter.inc, line 1089 - Adapter plugin and adapter related calsses.
View source
class FacetapiFacetProcessor {
/**
* An array of mapped values keyed by their raw value.
*
* @var $map
*/
protected $map = array();
/**
* The facet being processed.
*
* @var FacetapiFacet
*/
protected $facet;
/**
* The facet's initialized render array.
*
* @var array
*/
protected $build = array();
/**
* Arrays of children keyed by their active parent's value.
*
* @var array
*/
protected $activeChildren = array();
/**
* Constructor, initializes render array.
*
* @param FacetapiFacet $facet
* The facet being processed.
*
*/
public function __construct(FacetapiFacet $facet) {
$this->facet = $facet;
}
/**
* Processes the facet items.
*/
public function process() {
$this->build = array();
// Only initializes facet if a query type plugin is registered for it.
// NOTE: We don't use the chaining pattern so the methods can be tested.
if ($this->facet
->getAdapter()
->getFacetQuery($this->facet
->getFacet())) {
$this->build = $this
->initializeBuild($this->build);
$this->build = $this
->mapValues($this->build);
if ($this->build) {
$settings = $this->facet
->getSettings();
if (!$settings->settings['flatten']) {
$this->build = $this
->processHierarchy($this->build);
}
$this
->processQueryStrings($this->build);
}
}
}
/**
* Helper function to get the facet's active items.
*
* @return array
* The facet's active items.
*/
public function getActiveItems() {
return $this->facet
->getAdapter()
->getActiveItems($this->facet
->getFacet());
}
/**
* Gets an active item's children.
*
* @param string $value
* The value of the active item.
*
* @return array
* The active item's childen.
*/
public function getActiveChildren($value) {
return isset($this->activeChildren[$value]) ? $this->activeChildren[$value] : array();
}
/**
* Gets the initialized render array.
*/
public function getBuild() {
return $this->build;
}
/**
* Returns the human readable value associated with a raw value.
*
* @param string $value
* The raw value passed through the query string.
*
* @return string
* The mapped value.
*/
public function getMappedValue($value) {
return isset($this->map[$value]) ? $this->map[$value] : array(
'#value' => $value,
);
}
/**
* Initializes the facet's render array.
*
* @return array
* The initialized render array.
*/
protected function initializeBuild() {
$build = array();
// Build array defaults.
$defaults = array(
'#value' => '',
'#path' => $this->facet
->getAdapter()
->getSearchPath(),
'#html' => FALSE,
'#indexed_value' => '',
'#count' => 0,
'#active' => 0,
'#item_parents' => array(),
'#item_children' => array(),
);
// Builds render arrays for each item.
$adapter = $this->facet
->getAdapter();
$build = $adapter
->getFacetQuery($this->facet
->getFacet())
->build();
// Invoke the alter callbacks for the facet.
foreach ($this->facet['alter callbacks'] as $callback) {
$callback($build, $adapter, $this->facet
->getFacet());
}
// Iterates over the render array and merges in defaults.
foreach (element_children($build) as $value) {
$item_defaults = array(
'#value' => $value,
'#indexed_value' => $value,
'#active' => $adapter
->itemActive($this->facet['name'], $value),
);
$build[$value] = array_merge($defaults, $item_defaults, $build[$value]);
}
return $build;
}
/**
* Maps the IDs to human readable values via the mapping callback.
*
* @param array $build
* The initialized render array.
*
* @return array
* The initialized render array with mapped values.
*/
protected function mapValues(array $build) {
if ($this->facet['map callback']) {
// Gets available items and active items, runs through map callback only
// when there are values to map.
// NOTE: array_merge() doesn't work here when the values are numeric.
if ($values = array_unique(array_keys($build + $this
->getActiveItems()))) {
$this->map = call_user_func($this->facet['map callback'], $values, $this->facet['map options']);
// Normalize all mapped values to a two element array.
foreach ($this->map as $key => $value) {
if (!is_array($value)) {
$this->map[$key] = array();
$this->map[$key]['#value'] = $value;
$this->map[$key]['#html'] = FALSE;
}
if (isset($build[$key])) {
$build[$key]['#value'] = $this->map[$key]['#value'];
$build[$key]['#html'] = !empty($this->map[$key]['#html']);
}
}
}
}
return $build;
}
/**
* Processes hierarchical relationships between the facet items.
*
* @param array $build
* The initialized render array.
*
* @return array
* The initialized render array with processed hierarchical relationships.
*/
protected function processHierarchy(array $build) {
// Builds the hierarchy information if the hierarchy callback is defined.
if ($this->facet['hierarchy callback']) {
$parents = $this->facet['hierarchy callback'](array_keys($build));
foreach ($parents as $value => $parents) {
foreach ($parents as $parent) {
if (isset($build[$parent]) && isset($build[$value])) {
// Use a reference so we see the updated data.
$build[$parent]['#item_children'][$value] =& $build[$value];
$build[$value]['#item_parents'][$parent] = $parent;
}
}
}
}
// Tests whether parents have an active child.
// @todo: Can we make this more efficient?
do {
$active = 0;
foreach ($build as $value => $item) {
if ($item['#active'] && !empty($item['#item_parents'])) {
// @todo Can we build facets with multiple parents? Core taxonomy
// form cannot, so we will need a check here.
foreach ($item['#item_parents'] as $parent) {
if (!$build[$parent]['#active']) {
$active = $build[$parent]['#active'] = 1;
}
}
}
}
} while ($active);
// Since the children are copied to their parent's "#item_parents" property
// during processing, we have to filter the original child items from the
// top level of the hierarchy.
return array_filter($build, 'facetapi_filter_top_level_children');
}
/**
* Initializes the render array's query string variables.
*
* @param array &$build
* The initialized render array.
*/
protected function processQueryStrings(array &$build) {
foreach ($build as $value => &$item) {
$values = array(
$value,
);
// Calculate paths for the children.
if (!empty($item['#item_children'])) {
$this
->processQueryStrings($item['#item_children']);
// Merges the childrens' values if the item is active so the children
// are deactivated along with the parent.
if ($item['#active']) {
$values = array_merge(facetapi_get_child_values($item['#item_children']), $values);
}
}
// Stores this item's active children so we can deactivate them in the
// current search block as well.
$this->activeChildren[$value] = $values;
// Formats path and query string for facet item, sets theme function.
$item['#path'] = $this
->getFacetPath($values, $item['#active']);
$item['#query'] = $this
->getQueryString($values, $item['#active']);
}
}
/**
* Helper function that returns the path for a facet item.
*
* @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
* The facet path.
*/
public function getFacetPath(array $values, $active) {
return $this->facet
->getAdapter()
->getFacetPath($this->facet
->getFacet(), $values, $active);
}
/**
* Helper function that returns the query string variables for a facet item.
*
* @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
* An array containing the query string variables.
*/
public function getQueryString(array $values, $active) {
return $this->facet
->getAdapter()
->getQueryString($this->facet
->getFacet(), $values, $active);
}
}
Members
Name | Modifiers | Type | Description | Overrides |
---|---|---|---|---|
FacetapiFacetProcessor:: |
protected | property | Arrays of children keyed by their active parent's value. | |
FacetapiFacetProcessor:: |
protected | property | The facet's initialized render array. | |
FacetapiFacetProcessor:: |
protected | property | The facet being processed. | |
FacetapiFacetProcessor:: |
protected | property | An array of mapped values keyed by their raw value. | |
FacetapiFacetProcessor:: |
public | function | Gets an active item's children. | |
FacetapiFacetProcessor:: |
public | function | Helper function to get the facet's active items. | |
FacetapiFacetProcessor:: |
public | function | Gets the initialized render array. | |
FacetapiFacetProcessor:: |
public | function | Helper function that returns the path for a facet item. | |
FacetapiFacetProcessor:: |
public | function | Returns the human readable value associated with a raw value. | |
FacetapiFacetProcessor:: |
public | function | Helper function that returns the query string variables for a facet item. | |
FacetapiFacetProcessor:: |
protected | function | Initializes the facet's render array. | |
FacetapiFacetProcessor:: |
protected | function | Maps the IDs to human readable values via the mapping callback. | |
FacetapiFacetProcessor:: |
public | function | Processes the facet items. | |
FacetapiFacetProcessor:: |
protected | function | Processes hierarchical relationships between the facet items. | |
FacetapiFacetProcessor:: |
protected | function | Initializes the render array's query string variables. | |
FacetapiFacetProcessor:: |
public | function | Constructor, initializes render array. |