From 2427e7e582ff3311b0537a2bd7893beed313df3a Mon Sep 17 00:00:00 2001 From: Ere Maijala Date: Mon, 14 Aug 2023 15:57:33 +0300 Subject: [PATCH] Move record version key handling to the new Versions helper. This makes the functionality reusable and overridable. --- module/VuFind/config/module.config.php | 1 + .../Feature/RecordVersionsSearchTrait.php | 36 +++--- .../src/VuFind/Record/VersionsHelper.php | 110 ++++++++++++++++++ .../VuFind/Record/VersionsHelperFactory.php | 75 ++++++++++++ 4 files changed, 202 insertions(+), 20 deletions(-) create mode 100644 module/VuFind/src/VuFind/Record/VersionsHelper.php create mode 100644 module/VuFind/src/VuFind/Record/VersionsHelperFactory.php diff --git a/module/VuFind/config/module.config.php b/module/VuFind/config/module.config.php index 2268626755b..b9175e0d7cc 100644 --- a/module/VuFind/config/module.config.php +++ b/module/VuFind/config/module.config.php @@ -444,6 +444,7 @@ '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 c268b8c508c..9ce5d4dc542 100644 --- a/module/VuFind/src/VuFind/Controller/Feature/RecordVersionsSearchTrait.php +++ b/module/VuFind/src/VuFind/Controller/Feature/RecordVersionsSearchTrait.php @@ -48,30 +48,26 @@ trait RecordVersionsSearchTrait */ public function versionsAction() { - $id = $this->params()->fromQuery('id'); - $keys = $this->params()->fromQuery('keys'); - $record = null; - if ($id) { - $loader = $this->serviceLocator->get(\VuFind\Record\Loader::class); - $record = $loader->load($id, $this->searchClassId, true); - if ($record instanceof \VuFind\RecordDriver\Missing) { - $record = null; - } else { - $keys = $record->tryMethod('getWorkKeys'); - } + $versionsHelper + = $this->serviceLocator->get(\VuFind\Record\VersionsHelper::class); + $driverAndKeys = $versionsHelper->getDriverAndWorkKeysFromParams( + $this->params()->fromQuery(), + $this->searchClassId + ); + $record = $driverAndKeys['driver']; + if ($record instanceof \VuFind\RecordDriver\Missing) { + $record = null; } - if (empty($keys)) { + if (empty($driverAndKeys['keys'])) { return $this->forwardTo('Search', 'Home'); } - $mapFunc = function ($val) { - return '"' . addcslashes($val, '"') . '"'; - }; - $query = $this->getRequest()->getQuery(); - $query->lookfor = implode(' OR ', array_map($mapFunc, (array)$keys)); - $query->type = 'WorkKeys'; + $query->lookfor = $versionsHelper->getSearchStringFromWorkKeys( + (array)$driverAndKeys['keys'] + ); + $query->type = $versionsHelper->getWorkKeysSearchType(); // Don't save to history -- history page doesn't handle correctly: $this->saveToHistory = false; @@ -94,8 +90,8 @@ public function versionsAction() // won't in RSS mode): if (isset($view->results)) { $view->results->getUrlQuery() - ->setDefaultParameter('id', $id) - ->setDefaultParameter('keys', $keys) + ->setDefaultParameter('id', $this->params()->fromQuery('id')) + ->setDefaultParameter('keys', $this->params()->fromQuery('keys')) ->setSuppressQuery(true); $view->driver = $record; } diff --git a/module/VuFind/src/VuFind/Record/VersionsHelper.php b/module/VuFind/src/VuFind/Record/VersionsHelper.php new file mode 100644 index 00000000000..3ec02e5ab2e --- /dev/null +++ b/module/VuFind/src/VuFind/Record/VersionsHelper.php @@ -0,0 +1,110 @@ + + * @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 driver 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 driver and keys + */ + public function getDriverAndWorkKeysFromParams( + array $params, + string $backend + ): array { + $id = $params['id'] ?? null; + $keys = $params['keys'] ?? null; + $driver = null; + if ($id) { + $driver = $this->recordLoader->load($id, $backend, true); + if (!($driver instanceof \VuFind\RecordDriver\Missing)) { + $keys = $driver->tryMethod('getWorkKeys') ?? $keys; + } + } + return compact('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, (array)$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 new file mode 100644 index 00000000000..202959d8268 --- /dev/null +++ b/module/VuFind/src/VuFind/Record/VersionsHelperFactory.php @@ -0,0 +1,75 @@ + + * @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) + ); + } +}