Skip to content

Commit

Permalink
Merge branch 'release-10.1' into release-10.1-tweak-narrow-sidebar
Browse files Browse the repository at this point in the history
  • Loading branch information
demiankatz committed Nov 22, 2024
2 parents 2c90571 + 3349d4d commit c2ba2ef
Show file tree
Hide file tree
Showing 22 changed files with 732 additions and 221 deletions.
2 changes: 1 addition & 1 deletion languages/fi.ini
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ APA Citation = "APA-viite"
APA Edition Citation = "APA-viite (7. p.)"
applied_filter = "Käytetty suodatus:"
applied_filters = "Käytetyt suodattimet:"
Apply filters = "Käytä"
Apply filters = "Ota suodattimet käyttöön"
Archival Material = "Arkistomateriaali"
Article = "Artikkeli"
Ask a Librarian = "Kysy kirjastosta"
Expand Down
2 changes: 1 addition & 1 deletion languages/sv.ini
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ APA Citation = "APA-referens"
APA Edition Citation = "APA-referens (7:e uppl.)"
applied_filter = "Filter i bruk:"
applied_filters = "Aktiva filter:"
Apply filters = "Använd"
Apply filters = "Tillämpa filter"
Archival Material = "Arkivmaterial"
Article = "Artikel"
Ask a Librarian = "Fråga biblioteket"
Expand Down
65 changes: 35 additions & 30 deletions module/VuFind/src/VuFind/Search/Base/FacetCache.php
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,8 @@
namespace VuFind\Search\Base;

use VuFind\Cache\Manager as CacheManager;
use VuFind\Config\PluginManager as ConfigManager;
use VuFind\Search\Solr\HierarchicalFacetHelper;

use function in_array;

Expand All @@ -46,39 +48,22 @@ abstract class FacetCache
{
use \VuFind\Log\VarDumperTrait;

/**
* Cache manager
*
* @var CacheManager
*/
protected $cacheManager;

/**
* Currently selected language
*
* @var string
*/
protected $language;

/**
* Search results object.
*
* @var Results
*/
protected $results;

/**
* Constructor
*
* @param Results $r Search results object
* @param CacheManager $cm Cache manager
* @param string $language Active UI language
* @param Results $results Search results object
* @param CacheManager $cacheManager Cache manager
* @param string $language Active UI language
* @param ?HierarchicalFacetHelper $hierarchicalFacetHelper Hierarchical facet helper
* @param ?ConfigManager $configManager Configuration manager
*/
public function __construct(Results $r, CacheManager $cm, $language = 'en')
{
$this->results = $r;
$this->cacheManager = $cm;
$this->language = $language;
public function __construct(
protected Results $results,
protected CacheManager $cacheManager,
protected $language = 'en',
protected ?HierarchicalFacetHelper $hierarchicalFacetHelper = null,
protected ?ConfigManager $configManager = null
) {
}

/**
Expand Down Expand Up @@ -153,7 +138,27 @@ public function getList($context = 'Advanced')
throw new \Exception('Invalid context: ' . $context);
}
// For now, all contexts are handled the same way.
return $this->getFacetResults('init' . $context . 'Facets');
$facetList = $this->getFacetResults('init' . $context . 'Facets');

// Temporary context-specific sort fix for Advanced and HomePage:
if (in_array($context, ['Advanced', 'HomePage']) && $this->hierarchicalFacetHelper && $this->configManager) {
$options = $this->results->getOptions();
$facetConfig = $this->configManager->get($this->results->getOptions()->getFacetsIni())->toArray();
$sortOptions = array_merge(
$options->getHierarchicalFacetSortSettings(),
$facetConfig[$context . '_Settings']['hierarchicalFacetSortOptions'] ?? []
);
$defaultSort = 'HomePage' === $context ? 'all' : 'top';
foreach ($options->getHierarchicalFacets() as $facet) {
if (!empty($facetList[$facet]['list'])) {
$this->hierarchicalFacetHelper->sortFacetList(
$facetList[$facet]['list'],
$sortOptions[$facet] ?? $sortOptions['*'] ?? $defaultSort,
);
}
}
}
return $facetList;
}

/**
Expand Down
5 changes: 4 additions & 1 deletion module/VuFind/src/VuFind/Search/Base/FacetCacheFactory.php
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@
use Psr\Container\ContainerExceptionInterface as ContainerException;
use Psr\Container\ContainerInterface;
use VuFind\I18n\Locale\LocaleSettings;
use VuFind\Search\Solr\HierarchicalFacetHelper;

use function count;

Expand Down Expand Up @@ -91,6 +92,8 @@ public function __invoke(
$results = $this->getResults($container, $requestedNamespace);
$cacheManager = $container->get(\VuFind\Cache\Manager::class);
$language = $container->get(LocaleSettings::class)->getUserLocale();
return new $requestedName($results, $cacheManager, $language);
$hierarchicalFacetHelper = $container->get(HierarchicalFacetHelper::class);
$configManager = $container->get(\VuFind\Config\PluginManager::class);
return new $requestedName($results, $cacheManager, $language, $hierarchicalFacetHelper, $configManager);
}
}
71 changes: 45 additions & 26 deletions module/VuFind/src/VuFind/Search/Solr/HierarchicalFacetHelper.php
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,6 @@

use function array_slice;
use function count;
use function is_string;
use function strlen;

/**
Expand All @@ -63,6 +62,27 @@ class HierarchicalFacetHelper implements
use TranslatorAwareTrait;
use HasSorterTrait;

/**
* Internal constant for sorting by count
*
* @var int
*/
protected const SORT_COUNT = 0;

/**
* Internal constant for sorting top level alphabetically and the rest by count
*
* @var int
*/
protected const SORT_TOP = 1;

/**
* Internal constant for sorting all levels alphabetically
*
* @var int
*/
protected const SORT_ALL = 2;

/**
* View renderer
*
Expand All @@ -84,7 +104,9 @@ public function setViewRenderer(RendererInterface $renderer): void

/**
* Helper method for building hierarchical facets:
* Sort a facet list according to the given sort order
* Sort a facet list according to the given sort order.
*
* Supports both flattened and hierarchical facet lists.
*
* @param array $facetList Facet list returned from Solr
* @param boolean|string $order Sort order:
Expand All @@ -96,28 +118,13 @@ public function setViewRenderer(RendererInterface $renderer): void
*/
public function sortFacetList(&$facetList, $order = null)
{
// We need a boolean flag indicating whether or not to sort only the top
// level of the hierarchy. If we received a string configuration option,
// we should set the flag accordingly (boolean values of $order are
// supported for backward compatibility).
$topLevel = $order ?? 'count';
if (is_string($topLevel)) {
switch (strtolower(trim($topLevel))) {
case 'top':
$topLevel = true;
break;
case 'all':
$topLevel = false;
break;
case '':
case 'count':
// At present, we assume the incoming list is already sorted by
// count, so no further action is needed. If in future we need
// to support re-sorting an arbitrary list, rather than simply
// operating on raw Solr values, we may need to implement logic.
return;
}
}
// Map $order to a sort setting that's simple and fast to compare (boolean values of $order are
// supported for backward compatibility):
$sort = match ($order) {
true, 'top' => static::SORT_TOP,
false, 'all' => static::SORT_ALL,
default => static::SORT_COUNT,
};

// Parse level from each facet value so that the sort function
// can run faster
Expand All @@ -129,8 +136,11 @@ public function sortFacetList(&$facetList, $order = null)
}
// Avoid problems having the reference set further below
unset($facetItem);
$sortFunc = function ($a, $b) use ($topLevel) {
if ($a['level'] == $b['level'] && (!$topLevel || $a['level'] == 0)) {
$sortFunc = function ($a, $b) use ($sort) {
if (
$a['level'] == $b['level']
&& ($sort === static::SORT_ALL || ($a['level'] == 0 && $sort === static::SORT_TOP))
) {
$aText = $a['displayText'] == $a['value']
? $this->formatDisplayText($a['displayText'])
: $a['displayText'];
Expand All @@ -144,6 +154,15 @@ public function sortFacetList(&$facetList, $order = null)
: $a['level'] - $b['level'];
};
usort($facetList, $sortFunc);

// Sort children too if available:
foreach ($facetList as &$facetItem) {
if (!empty($facetItem['children'])) {
$this->sortFacetList($facetItem['children'], static::SORT_ALL === $sort ? 'all' : 'count');
}
}
// Unset reference:
unset($facetItem);
}

/**
Expand Down
78 changes: 78 additions & 0 deletions module/VuFind/src/VuFindTest/Feature/CacheManagementTrait.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
<?php

/**
* Trait adding the ability to clear object cache.
*
* PHP version 8
*
* Copyright (C) The National Library of Finland 2024.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2,
* as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*
* @category VuFind
* @package Tests
* @author Ere Maijala <[email protected]>
* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License
* @link https://vufind.org/wiki/development:testing:unit_tests Wiki
*/

namespace VuFindTest\Feature;

use Laminas\Http\Request;
use VuFindHttp\HttpService;

/**
* Trait adding the ability to clear object cache.
*
* @category VuFind
* @package Tests
* @author Ere Maijala <[email protected]>
* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License
* @link https://vufind.org/wiki/development:testing:unit_tests Wiki
*/
trait CacheManagementTrait
{
/**
* Get configuration required for cache clear permission
*
* @return array
*/
protected function getCacheClearPermissionConfig(): array
{
return [
'permissions' => [
'enable-admin-cache-api' => [
'permission' => 'access.api.admin.cache',
'require' => 'ANY',
'role' => 'guest',
],
],
];
}

/**
* Call the API to clear object cache
*
* @return voi
*/
protected function clearObjectCache(): void
{
$http = new HttpService();
$client = $http->createClient($this->getVuFindUrl('/api/v1/admin/cache?id=object'), Request::METHOD_DELETE);
$response = $client->send();
if (200 !== $response->getStatusCode()) {
throw new \Exception('Could not clear object cache: ' . $response->getBody());
}
}
}
Loading

0 comments on commit c2ba2ef

Please sign in to comment.