diff --git a/module/VuFind/config/module.config.php b/module/VuFind/config/module.config.php index 7c0ceb4b974..c86270a438d 100644 --- a/module/VuFind/config/module.config.php +++ b/module/VuFind/config/module.config.php @@ -457,7 +457,6 @@ 'VuFind\Record\FallbackLoader\PluginManager' => 'VuFind\ServiceManager\AbstractPluginManagerFactory', 'VuFind\Record\Loader' => 'VuFind\Record\LoaderFactory', 'VuFind\Record\Router' => 'VuFind\Service\ServiceWithConfigIniFactory', - 'VuFind\Record\VersionsHelper' => 'VuFind\Record\VersionsHelperFactory', 'VuFind\RecordDriver\PluginManager' => 'VuFind\ServiceManager\AbstractPluginManagerFactory', 'VuFind\RecordTab\PluginManager' => 'VuFind\ServiceManager\AbstractPluginManagerFactory', 'VuFind\RecordTab\TabManager' => 'VuFind\RecordTab\TabManagerFactory', diff --git a/module/VuFind/src/VuFind/Controller/Feature/RecordVersionsSearchTrait.php b/module/VuFind/src/VuFind/Controller/Feature/RecordVersionsSearchTrait.php index 0a76afc38aa..84bded8fa21 100644 --- a/module/VuFind/src/VuFind/Controller/Feature/RecordVersionsSearchTrait.php +++ b/module/VuFind/src/VuFind/Controller/Feature/RecordVersionsSearchTrait.php @@ -2,7 +2,7 @@ /** * VuFind Action Feature Trait - Record Versions Search - * Depends on method getSearchResultsView and record driver's method getWorkKeys. + * Depends on method getSearchResultsView. * * PHP version 8 * @@ -52,23 +52,15 @@ trait RecordVersionsSearchTrait */ public function versionsAction() { - $versionsHelper - = $this->serviceLocator->get(\VuFind\Record\VersionsHelper::class); - $keyData = $versionsHelper->getIdDriverAndWorkKeysFromParams( - $this->params()->fromQuery(), - $this->searchClassId - ); - if (empty($keyData['keys'])) { - return $this->forwardTo('Search', 'Home'); - } - - $query = new WorkKeysQuery(null, $keyData['keys']); - // Don't save to history -- history page doesn't handle correctly: $this->saveToHistory = false; - $callback = function ($runner, $params, $searchId) use ($query) { - $params->setQuery($query); + $id = null; + $callback = function ($runner, $params, $searchId) use (&$id) { + $query = $params->getQuery(); + if ($query instanceof WorkKeysQuery) { + $id = $query->getId(); + } $defaultCallback = is_callable([$this, 'getSearchSetupCallback']) ? $this->getSearchSetupCallback() : null; if (is_callable($defaultCallback)) { @@ -80,19 +72,10 @@ public function versionsAction() }; $view = $this->getSearchResultsView($callback); - - if (isset($view->results)) { - // Customize the URL helper to make sure it builds proper versions URLs - // (but only do this if we have access to a results object, which we - // won't in RSS mode): - $view->results->getUrlQuery() - ->setDefaultParameter('id', $keyData['id']) - // original keys from the query, if it had any: - ->setDefaultParameter('keys', $this->params()->fromQuery('keys')) - ->setSuppressQuery(true); - $view->driver = $keyData['driver']; + if (null !== $id) { + $loader = $this->serviceLocator->get(\VuFind\Record\Loader::class); + $view->driver = $loader->load($id, $this->searchClassId); } - return $view; } } diff --git a/module/VuFind/src/VuFind/Record/VersionsHelper.php b/module/VuFind/src/VuFind/Record/VersionsHelper.php deleted file mode 100644 index 856410bbea0..00000000000 --- a/module/VuFind/src/VuFind/Record/VersionsHelper.php +++ /dev/null @@ -1,112 +0,0 @@ - - * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License - * @link https://vufind.org Main Page - */ - -namespace VuFind\Record; - -/** - * Helper that provides support methods for record versions search - * - * @category VuFind - * @package Record - * @author Ere Maijala - * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License - * @link https://vufind.org Main Page - */ -class VersionsHelper -{ - /** - * Record loader - * - * @var Loader - */ - protected $recordLoader; - - /** - * Constructor - * - * @param Loader $recordLoader Record loader - */ - public function __construct( - Loader $recordLoader - ) { - $this->recordLoader = $recordLoader; - } - - /** - * Get record id, record driver (if available) and work keys from query params - * - * @param array $params Query params containing id and/or keys - * @param string $backend Search backend ID - * - * @return array with id, driver and keys - */ - public function getIdDriverAndWorkKeysFromParams( - array $params, - string $backend - ): array { - $id = $params['id'] ?? null; - $keys = (array)($params['keys'] ?? []); - $driver = null; - if ($id) { - $driver = $this->recordLoader->load($id, $backend, true); - if ($driver instanceof \VuFind\RecordDriver\Missing) { - $driver = null; - } else { - $keys = $driver->tryMethod('getWorkKeys') ?? $keys; - } - } - return compact('id', 'driver', 'keys'); - } - - /** - * Convert work keys to a search string - * - * @param array $keys Work keys - * - * @return string - */ - public function getSearchStringFromWorkKeys(array $keys): string - { - $mapFunc = function ($val) { - return '"' . addcslashes($val, '"') . '"'; - }; - - return implode(' OR ', array_map($mapFunc, $keys)); - } - - /** - * Get search type for work keys search - * - * @return string - */ - public function getWorkKeysSearchType(): string - { - return 'WorkKeys'; - } -} diff --git a/module/VuFind/src/VuFind/Record/VersionsHelperFactory.php b/module/VuFind/src/VuFind/Record/VersionsHelperFactory.php deleted file mode 100644 index 202959d8268..00000000000 --- a/module/VuFind/src/VuFind/Record/VersionsHelperFactory.php +++ /dev/null @@ -1,75 +0,0 @@ - - * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License - * @link https://vufind.org/wiki/development Wiki - */ - -namespace VuFind\Record; - -use Laminas\ServiceManager\Exception\ServiceNotCreatedException; -use Laminas\ServiceManager\Exception\ServiceNotFoundException; -use Laminas\ServiceManager\Factory\FactoryInterface; -use Psr\Container\ContainerExceptionInterface as ContainerException; -use Psr\Container\ContainerInterface; - -/** - * Versions helper factory. - * - * @category VuFind - * @package Record - * @author Ere Maijala - * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License - * @link https://vufind.org/wiki/development Wiki - */ -class VersionsHelperFactory implements FactoryInterface -{ - /** - * Create an object - * - * @param ContainerInterface $container Service manager - * @param string $requestedName Service being created - * @param null|array $options Extra options (optional) - * - * @return object - * - * @throws ServiceNotFoundException if unable to resolve the service. - * @throws ServiceNotCreatedException if an exception is raised when - * creating a service. - * @throws ContainerException&\Throwable if any other error occurs - */ - public function __invoke( - ContainerInterface $container, - $requestedName, - array $options = null - ) { - if (!empty($options)) { - throw new \Exception('Unexpected options passed to factory.'); - } - return new $requestedName( - $container->get(\VuFind\Record\Loader::class) - ); - } -} diff --git a/module/VuFind/src/VuFind/RecordDriver/Feature/VersionAwareTrait.php b/module/VuFind/src/VuFind/RecordDriver/Feature/VersionAwareTrait.php index 6287489fb59..e2fe3a3108d 100644 --- a/module/VuFind/src/VuFind/RecordDriver/Feature/VersionAwareTrait.php +++ b/module/VuFind/src/VuFind/RecordDriver/Feature/VersionAwareTrait.php @@ -70,7 +70,7 @@ public function getOtherVersionCount() } if (!isset($this->otherVersionsCount)) { - if (!($workKeys = $this->tryMethod('getWorkKeys'))) { + if (!$this->tryMethod('getWorkKeys')) { if (!($this instanceof VersionAwareInterface)) { throw new \Exception( 'VersionAwareTrait requires VersionAwareInterface' @@ -84,7 +84,7 @@ public function getOtherVersionCount() $command = new WorkExpressionsCommand( $this->getSourceIdentifier(), $this->getUniqueID(), - $workKeys, + false, $params ); $results = $this->searchService->invoke($command)->getResult(); @@ -104,11 +104,7 @@ public function getOtherVersionCount() */ public function getVersions($includeSelf = false, $count = 20, $offset = 0) { - if (null === $this->searchService) { - return false; - } - - if (!($workKeys = $this->getWorkKeys())) { + if (null === $this->searchService || !$this->getWorkKeys()) { return false; } @@ -118,8 +114,8 @@ public function getVersions($includeSelf = false, $count = 20, $offset = 0) $params->add('start', $offset); $command = new WorkExpressionsCommand( $this->getSourceIdentifier(), - $includeSelf ? '' : $this->getUniqueID(), - $workKeys, + $this->getUniqueID(), + $includeSelf, $params ); $this->otherVersions = $this->searchService->invoke( diff --git a/module/VuFind/src/VuFind/Search/QueryAdapter.php b/module/VuFind/src/VuFind/Search/QueryAdapter.php index 22aa0772067..1184ee1cf3b 100644 --- a/module/VuFind/src/VuFind/Search/QueryAdapter.php +++ b/module/VuFind/src/VuFind/Search/QueryAdapter.php @@ -58,12 +58,18 @@ abstract class QueryAdapter * * @param array $search Minified search arguments * - * @return Query|QueryGroup + * @return Query|QueryGroup|WorkKeysQuery */ public static function deminify(array $search) { + $type = $search['s'] ?? null; + if ('w' === $type) { + // WorkKeysQuery + return new WorkKeysQuery($search['l'], $search['i']); + } // Use array_key_exists since null is also valid - if (array_key_exists('l', $search)) { + if ('b' === $type || array_key_exists('l', $search)) { + // Basic search $handler = $search['i'] ?? $search['f']; return new Query( $search['l'], @@ -109,7 +115,7 @@ public static function display(AbstractQuery $query, $translate, $showName) // Work keys query: if ($query instanceof WorkKeysQuery) { - return $query->getId() ?? ''; + return $translate('Versions') . ' - ' . ($query->getId() ?? ''); } // Complex case -- advanced query: @@ -179,15 +185,25 @@ protected static function displayAdvanced( /** * Convert user request parameters into a query (currently for advanced searches - * only). + * and work keys searches only). * * @param Parameters $request User-submitted parameters * @param string $defaultHandler Default search handler * - * @return Query|QueryGroup + * @return Query|QueryGroup|WorkKeysQuery */ public static function fromRequest(Parameters $request, $defaultHandler) { + // Check for a work keys query first (id and keys included for back-compatibility): + if ( + $request->get('search') === 'versions' + || ($request->offsetExists('id') && $request->offsetExists('keys')) + ) { + if (null !== ($id = $request->offsetGet('id'))) { + return new WorkKeysQuery($id, true); + } + } + $groups = []; // Loop through all parameters and look for 'lookforX' foreach ($request as $key => $value) { @@ -245,10 +261,20 @@ public static function minify(AbstractQuery $query, $topLevel = true) [ 'l' => $query->getString(), 'i' => $query->getHandler(), + 's' => 'b', ], ]; } + // WorkKeys query: + if ($query instanceof WorkKeysQuery) { + return [ + 'l' => $query->getId(), + 'i' => $query->getIncludeSelf(), + 's' => 'w', + ]; + } + // Advanced query: $retVal = []; $operator = $query->isNegated() ? 'NOT' : $query->getOperator(); @@ -257,6 +283,7 @@ public static function minify(AbstractQuery $query, $topLevel = true) $retVal[] = [ 'g' => self::minify($current, false), 'j' => $operator, + 's' => 'a', ]; } elseif ($current instanceof QueryGroup) { throw new \Exception('Not sure how to minify this query!'); diff --git a/module/VuFind/src/VuFind/Search/UrlQueryHelper.php b/module/VuFind/src/VuFind/Search/UrlQueryHelper.php index d6a1d45c813..af7fe615160 100644 --- a/module/VuFind/src/VuFind/Search/UrlQueryHelper.php +++ b/module/VuFind/src/VuFind/Search/UrlQueryHelper.php @@ -32,6 +32,7 @@ use VuFindSearch\Query\AbstractQuery; use VuFindSearch\Query\Query; use VuFindSearch\Query\QueryGroup; +use VuFindSearch\Query\WorkKeysQuery; use function call_user_func; use function count; @@ -182,6 +183,9 @@ protected function regenerateSearchQueryParams() if (!empty($type)) { $this->urlParams['type'] = $type; } + } elseif ($this->queryObject instanceof WorkKeysQuery) { + $this->urlParams['id'] = $this->queryObject->getId(); + $this->urlParams['search'] = 'versions'; } } diff --git a/module/VuFind/src/VuFind/View/Helper/Root/RecordLinker.php b/module/VuFind/src/VuFind/View/Helper/Root/RecordLinker.php index cf4fc20740f..af612fee5ea 100644 --- a/module/VuFind/src/VuFind/View/Helper/Root/RecordLinker.php +++ b/module/VuFind/src/VuFind/View/Helper/Root/RecordLinker.php @@ -35,7 +35,6 @@ use function is_array; use function is_string; -use function strlen; /** * Record linker view helper @@ -301,17 +300,11 @@ public function getVersionsSearchUrl($driver) $urlParams = [ 'id' => $driver->getUniqueID(), - 'keys' => $driver->tryMethod('getWorkKeys', [], []), + 'search' => 'versions', ]; $urlHelper = $this->getView()->plugin('url'); - $url = $urlHelper($route, [], ['query' => $urlParams]); - if (strlen($url) > 2048) { - // URL too long, leave out keys (we'll use the record ID primarily anyway): - unset($urlParams['keys']); - $url = $urlHelper($route, [], ['query' => $urlParams]); - } - return $url; + return $urlHelper($route, [], ['query' => $urlParams]); } /** diff --git a/module/VuFind/tests/fixtures/searches/advanced/min b/module/VuFind/tests/fixtures/searches/advanced/min index d4800c374cf..85977849dd8 100644 --- a/module/VuFind/tests/fixtures/searches/advanced/min +++ b/module/VuFind/tests/fixtures/searches/advanced/min @@ -1 +1 @@ -a:3:{i:0;a:2:{s:1:"g";a:3:{i:0;a:3:{s:1:"f";s:10:"CallNumber";s:1:"l";s:7:"oranges";s:1:"b";s:3:"AND";}i:1;a:3:{s:1:"f";s:3:"toc";s:1:"l";s:7:"bananas";s:1:"b";s:3:"AND";}i:2;a:3:{s:1:"f";s:3:"ISN";s:1:"l";s:5:"pears";s:1:"b";s:3:"AND";}}s:1:"j";s:2:"OR";}i:1;a:2:{s:1:"g";a:2:{i:0;a:3:{s:1:"f";s:5:"Title";s:1:"l";s:4:"cars";s:1:"b";s:2:"OR";}i:1;a:3:{s:1:"f";s:7:"Subject";s:1:"l";s:6:"trucks";s:1:"b";s:2:"OR";}}s:1:"j";s:2:"OR";}i:2;a:2:{s:1:"g";a:1:{i:0;a:3:{s:1:"f";s:9:"AllFields";s:1:"l";s:5:"squid";s:1:"b";s:3:"NOT";}}s:1:"j";s:2:"OR";}} \ No newline at end of file +a:3:{i:0;a:3:{s:1:"g";a:3:{i:0;a:3:{s:1:"f";s:10:"CallNumber";s:1:"l";s:7:"oranges";s:1:"b";s:3:"AND";}i:1;a:3:{s:1:"f";s:3:"toc";s:1:"l";s:7:"bananas";s:1:"b";s:3:"AND";}i:2;a:3:{s:1:"f";s:3:"ISN";s:1:"l";s:5:"pears";s:1:"b";s:3:"AND";}}s:1:"j";s:2:"OR";s:1:"s";s:1:"a";}i:1;a:3:{s:1:"g";a:2:{i:0;a:3:{s:1:"f";s:5:"Title";s:1:"l";s:4:"cars";s:1:"b";s:2:"OR";}i:1;a:3:{s:1:"f";s:7:"Subject";s:1:"l";s:6:"trucks";s:1:"b";s:2:"OR";}}s:1:"j";s:2:"OR";s:1:"s";s:1:"a";}i:2;a:3:{s:1:"g";a:1:{i:0;a:3:{s:1:"f";s:9:"AllFields";s:1:"l";s:5:"squid";s:1:"b";s:3:"NOT";}}s:1:"j";s:2:"OR";s:1:"s";s:1:"a";}} \ No newline at end of file diff --git a/module/VuFind/tests/fixtures/searches/advanced/min-legacy b/module/VuFind/tests/fixtures/searches/advanced/min-legacy new file mode 100644 index 00000000000..d4800c374cf --- /dev/null +++ b/module/VuFind/tests/fixtures/searches/advanced/min-legacy @@ -0,0 +1 @@ +a:3:{i:0;a:2:{s:1:"g";a:3:{i:0;a:3:{s:1:"f";s:10:"CallNumber";s:1:"l";s:7:"oranges";s:1:"b";s:3:"AND";}i:1;a:3:{s:1:"f";s:3:"toc";s:1:"l";s:7:"bananas";s:1:"b";s:3:"AND";}i:2;a:3:{s:1:"f";s:3:"ISN";s:1:"l";s:5:"pears";s:1:"b";s:3:"AND";}}s:1:"j";s:2:"OR";}i:1;a:2:{s:1:"g";a:2:{i:0;a:3:{s:1:"f";s:5:"Title";s:1:"l";s:4:"cars";s:1:"b";s:2:"OR";}i:1;a:3:{s:1:"f";s:7:"Subject";s:1:"l";s:6:"trucks";s:1:"b";s:2:"OR";}}s:1:"j";s:2:"OR";}i:2;a:2:{s:1:"g";a:1:{i:0;a:3:{s:1:"f";s:9:"AllFields";s:1:"l";s:5:"squid";s:1:"b";s:3:"NOT";}}s:1:"j";s:2:"OR";}} \ No newline at end of file diff --git a/module/VuFind/tests/fixtures/searches/basic/min b/module/VuFind/tests/fixtures/searches/basic/min index 8198399dfe3..e530405d984 100644 --- a/module/VuFind/tests/fixtures/searches/basic/min +++ b/module/VuFind/tests/fixtures/searches/basic/min @@ -1 +1 @@ -a:1:{i:0;a:2:{s:1:"i";s:6:"Author";s:1:"l";s:10:"john smith";}} \ No newline at end of file +a:1:{i:0;a:3:{s:1:"l";s:10:"john smith";s:1:"i";s:6:"Author";s:1:"s";s:1:"b";}} \ No newline at end of file diff --git a/module/VuFind/tests/fixtures/searches/basic/min-legacy b/module/VuFind/tests/fixtures/searches/basic/min-legacy new file mode 100644 index 00000000000..8198399dfe3 --- /dev/null +++ b/module/VuFind/tests/fixtures/searches/basic/min-legacy @@ -0,0 +1 @@ +a:1:{i:0;a:2:{s:1:"i";s:6:"Author";s:1:"l";s:10:"john smith";}} \ No newline at end of file diff --git a/module/VuFind/tests/fixtures/searches/workkeys/min b/module/VuFind/tests/fixtures/searches/workkeys/min new file mode 100644 index 00000000000..b56110db3c9 --- /dev/null +++ b/module/VuFind/tests/fixtures/searches/workkeys/min @@ -0,0 +1 @@ +a:3:{s:1:"l";s:2:"id";s:1:"i";b:1;s:1:"s";s:1:"w";} \ No newline at end of file diff --git a/module/VuFind/tests/fixtures/searches/workkeys/query b/module/VuFind/tests/fixtures/searches/workkeys/query new file mode 100644 index 00000000000..1eec6e8ee38 Binary files /dev/null and b/module/VuFind/tests/fixtures/searches/workkeys/query differ diff --git a/module/VuFind/tests/unit-tests/src/VuFindTest/Search/QueryAdapterTest.php b/module/VuFind/tests/unit-tests/src/VuFindTest/Search/QueryAdapterTest.php index 6cbf333391c..e7d73305381 100644 --- a/module/VuFind/tests/unit-tests/src/VuFindTest/Search/QueryAdapterTest.php +++ b/module/VuFind/tests/unit-tests/src/VuFindTest/Search/QueryAdapterTest.php @@ -47,24 +47,46 @@ class QueryAdapterTest extends \PHPUnit\Framework\TestCase { use \VuFindTest\Feature\FixtureTrait; + /** + * Data provider for testConversions + * + * @return array + */ + public function conversionsProvider(): array + { + return [ + ['basic', true], + ['advanced', true], + ['workkeys', false], + ]; + } + /** * Test various conversions. * + * @param string $type Search type + * @param bool $legacy Whether to test legacy version deminification + * + * @dataProvider conversionsProvider + * * @return void */ - public function testConversions() + public function testConversions(string $type, bool $legacy) { - $cases = ['basic', 'advanced']; - foreach ($cases as $case) { - // Load minified, unminified, and Query object data: - $min = unserialize($this->getFixture('searches/' . $case . '/min')); - $q = unserialize($this->getFixture('searches/' . $case . '/query')); + // Load minified, unminified, and Query object data: + $min = unserialize($this->getFixture('searches/' . $type . '/min')); + $q = unserialize($this->getFixture('searches/' . $type . '/query')); + + // Test conversion of minified data: + $this->assertEquals($q, QueryAdapter::deminify($min)); - // Test conversion of minified data: - $this->assertEquals($q, QueryAdapter::deminify($min)); + // Test minification of a Query: + $this->assertEquals($min, QueryAdapter::minify($q)); - // Test minification of a Query: - $this->assertEquals($min, QueryAdapter::minify($q)); + if ($legacy) { + // Test conversion of legacy minified data: + $legacyMin = unserialize($this->getFixture('searches/' . $type . '/min-legacy')); + $this->assertEquals($q, QueryAdapter::deminify($legacyMin)); } } diff --git a/module/VuFindSearch/src/VuFindSearch/Backend/Solr/Backend.php b/module/VuFindSearch/src/VuFindSearch/Backend/Solr/Backend.php index c9a27d409a7..7137037a68d 100644 --- a/module/VuFindSearch/src/VuFindSearch/Backend/Solr/Backend.php +++ b/module/VuFindSearch/src/VuFindSearch/Backend/Solr/Backend.php @@ -137,7 +137,7 @@ public function search( ParamBag $params = null ) { if ($query instanceof WorkKeysQuery) { - return $this->workExpressions($query->getId(), $query->getWorkKeys(), $params); + return $this->workExpressions($query->getId(), $query->getIncludeSelf(), $params); } $json = $this->rawJsonSearch($query, $offset, $limit, $params); $collection = $this->createRecordCollection($json); @@ -422,18 +422,28 @@ public function alphabeticBrowse( * Return work expressions. * * @param string $id Id of record to compare with - * @param array $workKeys Work identification keys + * @param array $includeSelf Whether to include the record to compare with in the results * @param ParamBag $defaultParams Search backend parameters * * @return RecordCollectionInterface */ - public function workExpressions($id, $workKeys, ParamBag $defaultParams = null) - { + public function workExpressions( + string $id, + bool $includeSelf, + ParamBag $defaultParams = null + ): RecordCollectionInterface { + $recordResponse = $this->connector->retrieve($id); + $recordCollection = $this->createRecordCollection($recordResponse); + $record = $recordCollection->first(); + if (!$record || !($workKeys = $record->getWorkKeys())) { + return $this->createRecordCollection('{}'); + } + $params = $defaultParams ? clone $defaultParams : new \VuFindSearch\ParamBag(); $this->injectResponseWriter($params); $params->set('q', "{!terms f=work_keys_str_mv separator=\"\u{001f}\"}" . implode("\u{001f}", $workKeys)); - if ($id) { + if (!$includeSelf) { $params->add('fq', sprintf('-id:"%s"', addcslashes($id, '"'))); } if (!$params->hasParam('rows')) { diff --git a/module/VuFindSearch/src/VuFindSearch/Command/WorkExpressionsCommand.php b/module/VuFindSearch/src/VuFindSearch/Command/WorkExpressionsCommand.php index 444263ced7d..0ff5433e64a 100644 --- a/module/VuFindSearch/src/VuFindSearch/Command/WorkExpressionsCommand.php +++ b/module/VuFindSearch/src/VuFindSearch/Command/WorkExpressionsCommand.php @@ -30,7 +30,6 @@ namespace VuFindSearch\Command; -use VuFindSearch\Backend\BackendInterface; use VuFindSearch\Command\Feature\RecordIdentifierTrait; use VuFindSearch\Feature\WorkExpressionsInterface; use VuFindSearch\ParamBag; @@ -50,29 +49,28 @@ class WorkExpressionsCommand extends CallMethodCommand use RecordIdentifierTrait; /** - * Work identification keys. + * Whether to include the record to compare with in the results * - * @var ?array + * @var bool */ - protected $workKeys; + protected $includeSelf; /** * WorkExpressionsCommand constructor. * - * @param string $backendId Search backend identifier - * @param string $id Identifier of record to compare with - * @param ?array $workKeys Work identification keys (optional; retrieved from - * the record to compare with if not specified) - * @param ?ParamBag $params Search backend parameters + * @param string $backendId Search backend identifier + * @param string $id Identifier of record to compare with + * @param bool $includeSelf Whether to include the record to compare with in the results + * @param ?ParamBag $params Search backend parameters */ public function __construct( string $backendId, string $id, - ?array $workKeys, + bool $includeSelf, ?ParamBag $params = null ) { $this->id = $id; - $this->workKeys = $workKeys; + $this->includeSelf = $includeSelf; parent::__construct( $backendId, WorkExpressionsInterface::class, @@ -90,41 +88,18 @@ public function getArguments(): array { return [ $this->getRecordIdentifier(), - $this->getWorkKeys(), + $this->getIncludeSelf(), $this->getSearchParameters(), ]; } /** - * Execute command on backend. + * Return "include self" setting. * - * @param BackendInterface $backend Backend - * - * @return CommandInterface Command instance for method chaining - */ - public function execute(BackendInterface $backend): CommandInterface - { - $id = $this->getRecordIdentifier(); - $workKeys = $this->getWorkKeys(); - - if (empty($workKeys)) { - $records = $backend->retrieve($id)->getRecords(); - if (!empty($records[0])) { - $fields = $records[0]->getRawData(); - $this->workKeys = $fields['work_keys_str_mv'] ?? []; - } - } - - return parent::execute($backend); - } - - /** - * Return work identification keys. - * - * @return array|null + * @return bool */ - public function getWorkKeys(): ?array + public function getIncludeSelf(): bool { - return $this->workKeys; + return $this->includeSelf; } } diff --git a/module/VuFindSearch/src/VuFindSearch/Feature/WorkExpressionsInterface.php b/module/VuFindSearch/src/VuFindSearch/Feature/WorkExpressionsInterface.php index bae5a079eca..42b4fe99275 100644 --- a/module/VuFindSearch/src/VuFindSearch/Feature/WorkExpressionsInterface.php +++ b/module/VuFindSearch/src/VuFindSearch/Feature/WorkExpressionsInterface.php @@ -30,6 +30,7 @@ namespace VuFindSearch\Feature; use VuFindSearch\ParamBag; +use VuFindSearch\Response\RecordCollectionInterface; /** * Work expressions feature interface definition. @@ -46,10 +47,14 @@ interface WorkExpressionsInterface * Return work expressions. * * @param string $id Id of record to compare with - * @param array $workKeys Work identification keys + * @param array $includeSelf Whether to include the record to compare with in the results * @param ParamBag $defaultParams Search backend parameters * * @return RecordCollectionInterface */ - public function workExpressions($id, $workKeys, ParamBag $defaultParams = null); + public function workExpressions( + string $id, + bool $includeSelf, + ParamBag $defaultParams = null + ): RecordCollectionInterface; } diff --git a/module/VuFindSearch/src/VuFindSearch/Query/WorkKeysQuery.php b/module/VuFindSearch/src/VuFindSearch/Query/WorkKeysQuery.php index e9095124187..a0e3396edf6 100644 --- a/module/VuFindSearch/src/VuFindSearch/Query/WorkKeysQuery.php +++ b/module/VuFindSearch/src/VuFindSearch/Query/WorkKeysQuery.php @@ -29,8 +29,6 @@ namespace VuFindSearch\Query; -use function in_array; - /** * A work keys query. * @@ -50,22 +48,22 @@ class WorkKeysQuery extends AbstractQuery protected $id; /** - * Work keys + * Whether to include the record to compare with in the results * - * @var array + * @var bool */ - protected $workKeys; + protected $includeSelf; /** * Constructor. * - * @param ?string $id Record ID - * @param array $workKeys Work keys + * @param ?string $id Record ID + * @param boo $includeSelf Whether to include the record to compare with in the results */ - public function __construct(?string $id, array $workKeys) + public function __construct(?string $id, bool $includeSelf) { $this->id = $id; - $this->workKeys = $workKeys; + $this->includeSelf = $includeSelf; } /** @@ -91,25 +89,25 @@ public function setId(?string $id) } /** - * Return work keys + * Return "include self" setting * - * @return array + * @return bool */ - public function getWorkKeys(): array + public function getIncludeSelf(): bool { - return $this->workKeys; + return $this->includeSelf; } /** - * Set work keys + * Set "include self" setting * - * @param array $workKeys Work keys + * @param bool $includeSelf New value * * @return void */ - public function setWorkKeys(array $workKeys): void + public function setIncludeSelf(bool $includeSelf): void { - $this->workKeys = $workKeys; + $this->includeSelf = $includeSelf; } /** @@ -124,7 +122,7 @@ public function setWorkKeys(array $workKeys): void */ public function containsTerm($needle, $normalizer = null) { - return in_array($normalizer ? $normalizer($needle) : $needle, $this->workKeys); + return false; } /** @@ -134,7 +132,7 @@ public function containsTerm($needle, $normalizer = null) */ public function getAllTerms() { - return implode(',', $this->workKeys); + return $this->id; } /** @@ -149,11 +147,6 @@ public function getAllTerms() */ public function replaceTerm($from, $to, $normalizer = null) { - $from = $normalizer ? $normalizer($from) : $from; - $to = $normalizer ? $normalizer($to) : $to; - - if (false !== ($i = array_search($from, $this->workKeys))) { - $this->workKeys[$i] = $to; - } + // Not applicable } } diff --git a/module/VuFindSearch/tests/unit-tests/src/VuFindTest/Command/WorkExpressionsCommandTest.php b/module/VuFindSearch/tests/unit-tests/src/VuFindTest/Command/WorkExpressionsCommandTest.php index 5c46bce3cb4..47045b76ed4 100644 --- a/module/VuFindSearch/tests/unit-tests/src/VuFindTest/Command/WorkExpressionsCommandTest.php +++ b/module/VuFindSearch/tests/unit-tests/src/VuFindTest/Command/WorkExpressionsCommandTest.php @@ -30,6 +30,7 @@ namespace VuFindTest\Command; use PHPUnit\Framework\TestCase; +use VuFindSearch\Backend\Solr\Response\Json\RecordCollection; use VuFindSearch\Command\WorkExpressionsCommand; /** @@ -57,57 +58,19 @@ public function testBasicUsageOfCommand(): void ->disableOriginalConstructor()->getMock(); $backend->expects($this->once())->method('getIdentifier') ->will($this->returnValue($backendId)); + $result = new RecordCollection([]); $backend->expects($this->once())->method('workExpressions') ->with( $this->equalTo('id'), - $this->equalTo(['key1', 'key2']), + $this->equalTo(true), $this->equalTo($params) - )->will($this->returnValue('result')); // not a realistic value! + )->willReturn($result); // not a realistic value! $command = new WorkExpressionsCommand( $backendId, 'id', - ['key1', 'key2'], + true, $params ); - $this->assertEquals('result', $command->execute($backend)->getResult()); - } - - /** - * Test that the command looks up work keys if they are omitted - * - * @return void - */ - public function testWorkKeyAutofill() - { - $params = new \VuFindSearch\ParamBag([]); - $backendId = 'bar'; - $backend = $this - ->getMockBuilder(\VuFindSearch\Backend\Solr\Backend::class) - ->disableOriginalConstructor()->getMock(); - $collection = new \VuFindSearch\Backend\Solr\Response\Json\RecordCollection( - ['response' => ['numFound' => 1]] - ); - $mockRecord = $this->getMockBuilder(\VuFind\RecordDriver\SolrDefault::class) - ->disableOriginalConstructor()->getMock(); - $mockRecord->expects($this->once())->method('getRawData') - ->will($this->returnValue(['work_keys_str_mv' => ['key1', 'key2']])); - $collection->add($mockRecord); - $backend->expects($this->once())->method('retrieve') - ->with($this->equalTo('id')) - ->will($this->returnValue($collection)); - $backend->expects($this->once())->method('getIdentifier') - ->will($this->returnValue($backendId)); - $backend->expects($this->once())->method('workExpressions') - ->with( - $this->equalTo('id'), - $this->equalTo(['key1', 'key2']), - $this->equalTo($params) - )->will($this->returnValue('result')); // not a realistic value! - $command = new WorkExpressionsCommand( - $backendId, - 'id', - null - ); - $this->assertEquals('result', $command->execute($backend)->getResult()); + $this->assertEquals($result, $command->execute($backend)->getResult()); } }