Skip to content

Commit

Permalink
Fix hierarchical facet sorting on home page and advanced search form.
Browse files Browse the repository at this point in the history
  • Loading branch information
EreMaijala committed Nov 21, 2024
1 parent 8efc209 commit 7bae2c2
Show file tree
Hide file tree
Showing 22 changed files with 139 additions and 128 deletions.
61 changes: 7 additions & 54 deletions module/VuFind/src/VuFind/Controller/AbstractSolrSearch.php
Original file line number Diff line number Diff line change
Expand Up @@ -61,17 +61,12 @@ protected function addFacetDetailsToView(ViewModel $view, $list = 'Advanced'): v
$facets = $this->getService(\VuFind\Search\FacetCache\PluginManager::class)
->get($this->searchClassId)
->getList($list);
$view->hierarchicalFacets
= $this->getHierarchicalFacets($view->options->getFacetsIni());
$view->hierarchicalFacetsSortOptions
= $this->getAdvancedHierarchicalFacetsSortOptions(
$view->options->getFacetsIni()
);
$view->hierarchicalFacets = $view->options->getHierarchicalFacets();
$view->hierarchicalFacetsSortOptions = $view->options->getAdvancedSearchHierarchicalFacetSortSettings();
$view->facetList = $this->processAdvancedFacets(
$facets,
$view->saved ?? false,
$view->hierarchicalFacets,
$view->hierarchicalFacetsSortOptions
$view->hierarchicalFacets
);
}

Expand Down Expand Up @@ -148,20 +143,16 @@ protected function getIllustrationSettings($savedSearch = false)
/**
* Process the facets to be used as limits on the Advanced Search screen.
*
* @param array $facetList The advanced facet values
* @param object $searchObject Saved search object
* (false if none)
* @param array $hierarchicalFacets Hierarchical facet list (if any)
* @param array $hierarchicalFacetsSortOptions Hierarchical facet sort options
* (if any)
* @param array $facetList The advanced facet values
* @param object $searchObject Saved search object (false if none)
* @param array $hierarchicalFacets Hierarchical facet list (if any)
*
* @return array Sorted facets, with selected values flagged.
*/
protected function processAdvancedFacets(
$facetList,
$searchObject = false,
$hierarchicalFacets = [],
$hierarchicalFacetsSortOptions = []
$hierarchicalFacets = []
) {
$facetHelper = null;
$options = null;
Expand Down Expand Up @@ -209,42 +200,4 @@ protected function processAdvancedFacets(
}
return $facetList;
}

/**
* Get an array of hierarchical facets
*
* @param string $config Name of facet configuration file to load.
*
* @return array Facets
*/
protected function getHierarchicalFacets($config)
{
$facetConfig = $this->getConfig($config);
return isset($facetConfig->SpecialFacets->hierarchical)
? $facetConfig->SpecialFacets->hierarchical->toArray()
: [];
}

/**
* Get an array of hierarchical facet sort options for Advanced search
*
* @param string $config Name of facet configuration file to load.
*
* @return array
*/
protected function getAdvancedHierarchicalFacetsSortOptions($config)
{
$facetConfig = $this->getConfig($config);
$baseConfig
= isset($facetConfig->SpecialFacets->hierarchicalFacetSortOptions)
? $facetConfig->SpecialFacets->hierarchicalFacetSortOptions->toArray()
: [];
$advancedConfig
= isset($facetConfig->Advanced_Settings->hierarchicalFacetSortOptions)
? $facetConfig->Advanced_Settings->hierarchicalFacetSortOptions
->toArray()
: [];

return array_merge($baseConfig, $advancedConfig);
}
}
18 changes: 10 additions & 8 deletions module/VuFind/src/VuFind/Search/Base/FacetCache.php
Original file line number Diff line number Diff line change
Expand Up @@ -91,9 +91,11 @@ abstract protected function getCacheNamespace();
/**
* Get the cache key for the provided method.
*
* @param string $context Facet context
*
* @return string
*/
protected function getCacheKey()
protected function getCacheKey(string $context)
{
$params = $this->results->getParams();
$facetConfig = $params->getFacetConfig();
Expand All @@ -103,17 +105,18 @@ protected function getCacheKey()
// Factor operator settings into cache key:
array_map([$params, 'getFacetOperator'], array_keys($facetConfig)),
];
return $this->language . md5($this->varDump($settings));
return $this->language . "_{$context}_" . md5($this->varDump($settings));
}

/**
* Perform the actual facet lookup.
*
* @param string $initMethod Name of params method to use to request facets
* @param string $context Facet context ('Advanced' for advanced search form)
*
* @return array
*/
protected function getFacetResults($initMethod)
protected function getFacetResults($initMethod, string $context = 'Advanced')
{
// Check if we have facet results cached, and build them if we don't.
$cache = $this->cacheManager->getCache('object', $this->getCacheNamespace());
Expand All @@ -122,15 +125,15 @@ protected function getFacetResults($initMethod)
// Note that we need to initialize the parameters BEFORE generating the
// cache key to ensure that the key is based on the proper settings.
$params->$initMethod();
$cacheKey = $this->getCacheKey();
$cacheKey = $this->getCacheKey($context);
if (!($list = $cache->getItem($cacheKey))) {
// Avoid a backend request if there are no facets configured by the given
// init method.
if (!empty($params->getFacetConfig())) {
// We only care about facet lists, so don't get any results (this
// improves performance):
$params->setLimit(0);
$list = $this->results->getFacetList();
$list = $this->results->getFacetList(null, $context);
} else {
$list = [];
}
Expand All @@ -143,7 +146,7 @@ protected function getFacetResults($initMethod)
/**
* Return facet information. This data may come from the cache.
*
* @param string $context Context of list to retrieve ('Advanced' or 'HomePage')
* @param string $context Context of list to retrieve ('Advanced', 'HomePage' or 'NewItems')
*
* @return array
*/
Expand All @@ -152,8 +155,7 @@ public function getList($context = 'Advanced')
if (!in_array($context, ['Advanced', 'HomePage', 'NewItems'])) {
throw new \Exception('Invalid context: ' . $context);
}
// For now, all contexts are handled the same way.
return $this->getFacetResults('init' . $context . 'Facets');
return $this->getFacetResults('init' . $context . 'Facets', $context);
}

/**
Expand Down
40 changes: 40 additions & 0 deletions module/VuFind/src/VuFind/Search/Base/Options.php
Original file line number Diff line number Diff line change
Expand Up @@ -238,6 +238,20 @@ abstract class Options implements TranslatorAwareInterface
*/
protected $hierarchicalFacetSortSettings = [];

/**
* Hierarchical facet sort settings for advanced search form
*
* @var array
*/
protected $advancedSearchHierarchicalFacetSortSettings = [];

/**
* Hierarchical facet sort settings for home page
*
* @var array
*/
protected $homePageHierarchicalFacetSortSettings = [];

/**
* Spelling setting
*
Expand Down Expand Up @@ -850,6 +864,32 @@ public function getHierarchicalFacetSortSettings()
return $this->hierarchicalFacetSortSettings;
}

/**
* Get hierarchical facet sort settings for advanced search form.
*
* @return array
*/
public function getAdvancedSearchHierarchicalFacetSortSettings()
{
return array_merge(
$this->hierarchicalFacetSortSettings,
$this->advancedSearchHierarchicalFacetSortSettings
);
}

/**
* Get hierarchical facet sort settings for home page.
*
* @return array
*/
public function getHomePageHierarchicalFacetSortSettings()
{
return array_merge(
$this->hierarchicalFacetSortSettings,
$this->homePageHierarchicalFacetSortSettings
);
}

/**
* Get current spellcheck setting and (optionally) change it.
*
Expand Down
53 changes: 24 additions & 29 deletions module/VuFind/src/VuFind/Search/Base/Results.php
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,6 @@
use function func_get_args;
use function get_class;
use function in_array;
use function is_callable;
use function is_object;

/**
Expand Down Expand Up @@ -324,12 +323,13 @@ public function performAndProcessSearch()
/**
* Returns the stored list of facets for the last search
*
* @param array $filter Array of field => on-screen description listing
* @param array $filter Array of field => on-screen description listing
* all of the desired facet fields; set to null to get all configured values.
* @param string $context Any special context ('Advanced' for advanced search form, 'HomePage' for home page)
*
* @return array Facets data arrays
*/
abstract public function getFacetList($filter = null);
abstract public function getFacetList($filter = null, string $context = '');

/**
* Abstract support method for performAndProcessSearch -- perform a search based
Expand Down Expand Up @@ -857,13 +857,14 @@ public function getExtraSearchBackendDetails()
* A helper method that converts the list of facets for the last search from
* RecordCollection's facet list.
*
* @param array $facetList Facet list
* @param array $filter Array of field => on-screen description listing
* @param array $facetList Facet list
* @param array $filter Array of field => on-screen description listing
* all of the desired facet fields; set to null to get all configured values.
* @param string $context Context ('Advanced' for advanced search form)
*
* @return array Facets data arrays
*/
protected function buildFacetList(array $facetList, array $filter = null): array
protected function buildFacetList(array $facetList, array $filter = null, string $context = ''): array
{
// If there is no filter, we'll use all facets as the filter:
if (null === $filter) {
Expand All @@ -873,17 +874,17 @@ protected function buildFacetList(array $facetList, array $filter = null): array
// Start building the facet list:
$result = [];

// Loop through every field returned by the result set
$translatedFacets = $this->getOptions()->getTranslatedFacets();
$hierarchicalFacets
= is_callable([$this->getOptions(), 'getHierarchicalFacets'])
? $this->getOptions()->getHierarchicalFacets()
: [];
$hierarchicalFacetSortSettings
= is_callable([$this->getOptions(), 'getHierarchicalFacetSortSettings'])
? $this->getOptions()->getHierarchicalFacetSortSettings()
: [];
$options = $this->getOptions();
$translatedFacets = $options->getTranslatedFacets();
$hierarchicalFacets = $options->getHierarchicalFacets();
$hierarchicalFacetSortSettings = match ($context) {
'Advanced' => $options->getAdvancedSearchHierarchicalFacetSortSettings(),
'HomePage' => $options->getHomePageHierarchicalFacetSortSettings(),
default => $options->getHierarchicalFacetSortSettings(),
};

// Loop through every field returned by the result set
$params = $this->getParams();
foreach (array_keys($filter) as $field) {
$data = $facetList[$field] ?? [];
// Skip empty arrays:
Expand All @@ -898,27 +899,24 @@ protected function buildFacetList(array $facetList, array $filter = null): array
// Should we translate values for the current facet?
$translate = in_array($field, $translatedFacets);
$hierarchical = in_array($field, $hierarchicalFacets);
$operator = $this->getParams()->getFacetOperator($field);
$operator = $params->getFacetOperator($field);
$resultList = [];
// Loop through values:
foreach ($data as $value => $count) {
$displayText = $this->getParams()
->getFacetValueRawDisplayText($field, $value);
$displayText = $params->getFacetValueRawDisplayText($field, $value);
if ($hierarchical) {
if (!$this->hierarchicalFacetHelper) {
throw new \Exception(
get_class($this)
. ': hierarchical facet helper unavailable'
);
}
$displayText = $this->hierarchicalFacetHelper
->formatDisplayText($displayText);
$displayText = $this->hierarchicalFacetHelper->formatDisplayText($displayText);
}
$displayText = $translate
? $this->getParams()->translateFacetValue($field, $displayText)
? $params->translateFacetValue($field, $displayText)
: $displayText;
$isApplied = $this->getParams()->hasFilter("$field:" . $value)
|| $this->getParams()->hasFilter("~$field:" . $value);
$isApplied = $params->hasFilter("$field:" . $value) || $params->hasFilter("~$field:" . $value);

// Store the collected values:
$resultList[] = compact(
Expand All @@ -931,12 +929,9 @@ protected function buildFacetList(array $facetList, array $filter = null): array
}

if ($hierarchical) {
$sort = $hierarchicalFacetSortSettings[$field]
?? $hierarchicalFacetSortSettings['*'] ?? 'count';
$sort = $hierarchicalFacetSortSettings[$field] ?? $hierarchicalFacetSortSettings['*'] ?? 'count';
$this->hierarchicalFacetHelper->sortFacetList($resultList, $sort);

$resultList
= $this->hierarchicalFacetHelper->buildFacetArray($field, $resultList);
$resultList = $this->hierarchicalFacetHelper->buildFacetArray($field, $resultList);
}

$result[$field]['list'] = $resultList;
Expand Down
5 changes: 3 additions & 2 deletions module/VuFind/src/VuFind/Search/BrowZine/Results.php
Original file line number Diff line number Diff line change
Expand Up @@ -52,12 +52,13 @@ class Results extends \VuFind\Search\Base\Results
/**
* Returns the stored list of facets for the last search
*
* @param array $filter Array of field => on-screen description listing
* @param array $filter Array of field => on-screen description listing
* all of the desired facet fields; set to null to get all configured values.
* @param string $context Any special context ('Advanced' for advanced search form, 'HomePage' for home page)
*
* @return array Facets data arrays
*/
public function getFacetList($filter = null)
public function getFacetList($filter = null, string $context = '')
{
// Not supported
return [];
Expand Down
5 changes: 3 additions & 2 deletions module/VuFind/src/VuFind/Search/Combined/Results.php
Original file line number Diff line number Diff line change
Expand Up @@ -43,12 +43,13 @@ class Results extends \VuFind\Search\Base\Results
/**
* Returns the stored list of facets for the last search
*
* @param array $filter Array of field => on-screen description listing
* @param array $filter Array of field => on-screen description listing
* all of the desired facet fields; set to null to get all configured values.
* @param string $context Any special context ('Advanced' for advanced search form, 'HomePage' for home page)
*
* @return array Facets data arrays
*/
public function getFacetList($filter = null)
public function getFacetList($filter = null, string $context = '')
{
// Not relevant:
return [];
Expand Down
5 changes: 3 additions & 2 deletions module/VuFind/src/VuFind/Search/EDS/Results.php
Original file line number Diff line number Diff line change
Expand Up @@ -100,12 +100,13 @@ protected function performSearch()
/**
* Returns the stored list of facets for the last search
*
* @param array $filter Array of field => on-screen description listing
* @param array $filter Array of field => on-screen description listing
* all of the desired facet fields; set to null to get all configured values.
* @param string $context Any special context ('Advanced' for advanced search form, 'HomePage' for home page)
*
* @return array Facets data arrays
*/
public function getFacetList($filter = null)
public function getFacetList($filter = null, string $context = '')
{
if (null === $this->responseFacets) {
$this->performAndProcessSearch();
Expand Down
5 changes: 3 additions & 2 deletions module/VuFind/src/VuFind/Search/EIT/Results.php
Original file line number Diff line number Diff line change
Expand Up @@ -82,12 +82,13 @@ protected function performSearch()
/**
* Returns the stored list of facets for the last search
*
* @param array $filter Array of field => on-screen description listing
* @param array $filter Array of field => on-screen description listing
* all of the desired facet fields; set to null to get all configured values.
* @param string $context Any special context ('Advanced' for advanced search form, 'HomePage' for home page)
*
* @return array Facets data arrays
*/
public function getFacetList($filter = null)
public function getFacetList($filter = null, string $context = '')
{
// No facets in EIT:
return [];
Expand Down
Loading

0 comments on commit 7bae2c2

Please sign in to comment.