From 9263c835e22c54475f42760c4609ce46648f7fa1 Mon Sep 17 00:00:00 2001 From: Maccabee Levine Date: Fri, 4 Oct 2024 16:34:41 +0000 Subject: [PATCH 01/34] Add ProQuest Federated Search Gateway backend. First working draft. --- module/VuFind/config/module.config.php | 8 + .../Controller/ProQuestFSGController.php | 68 ++++++ .../ProQuestFSGrecordController.php | 71 ++++++ .../src/VuFind/RecordDriver/PluginManager.php | 1 + .../src/VuFind/RecordDriver/ProQuestFSG.php | 85 ++++++++ .../src/VuFind/Search/BackendRegistry.php | 1 + .../Factory/ProQuestFSGBackendFactory.php | 156 +++++++++++++ .../VuFind/Search/Options/PluginManager.php | 2 + .../VuFind/Search/Params/PluginManager.php | 2 + .../src/VuFind/Search/ProQuestFSG/Options.php | 117 ++++++++++ .../src/VuFind/Search/ProQuestFSG/Params.php | 62 ++++++ .../src/VuFind/Search/ProQuestFSG/Results.php | 91 ++++++++ .../VuFind/Search/Results/PluginManager.php | 2 + module/VuFind/xsl/sru-convert-simple.xsl | 39 ++++ .../Backend/ProQuestFSG/Backend.php | 205 ++++++++++++++++++ .../Backend/ProQuestFSG/Connector.php | 199 +++++++++++++++++ .../Backend/ProQuestFSG/QueryBuilder.php | 193 +++++++++++++++++ .../ProQuestFSG/Response/XML/Record.php | 79 +++++++ .../Response/XML/RecordCollection.php | 87 ++++++++ .../Response/XML/RecordCollectionFactory.php | 116 ++++++++++ .../VuFindSearch/Backend/SRU/Connector.php | 3 +- .../VuFindSearch/Backend/Solr/Connector.php | 3 +- .../templates/proquestfsg/home.phtml | 1 + .../templates/proquestfsg/results.phtml | 1 + 24 files changed, 1590 insertions(+), 2 deletions(-) create mode 100644 module/VuFind/src/VuFind/Controller/ProQuestFSGController.php create mode 100644 module/VuFind/src/VuFind/Controller/ProQuestFSGrecordController.php create mode 100644 module/VuFind/src/VuFind/RecordDriver/ProQuestFSG.php create mode 100644 module/VuFind/src/VuFind/Search/Factory/ProQuestFSGBackendFactory.php create mode 100644 module/VuFind/src/VuFind/Search/ProQuestFSG/Options.php create mode 100644 module/VuFind/src/VuFind/Search/ProQuestFSG/Params.php create mode 100644 module/VuFind/src/VuFind/Search/ProQuestFSG/Results.php create mode 100644 module/VuFind/xsl/sru-convert-simple.xsl create mode 100644 module/VuFindSearch/src/VuFindSearch/Backend/ProQuestFSG/Backend.php create mode 100644 module/VuFindSearch/src/VuFindSearch/Backend/ProQuestFSG/Connector.php create mode 100644 module/VuFindSearch/src/VuFindSearch/Backend/ProQuestFSG/QueryBuilder.php create mode 100644 module/VuFindSearch/src/VuFindSearch/Backend/ProQuestFSG/Response/XML/Record.php create mode 100644 module/VuFindSearch/src/VuFindSearch/Backend/ProQuestFSG/Response/XML/RecordCollection.php create mode 100644 module/VuFindSearch/src/VuFindSearch/Backend/ProQuestFSG/Response/XML/RecordCollectionFactory.php create mode 100644 themes/bootstrap3/templates/proquestfsg/home.phtml create mode 100644 themes/bootstrap3/templates/proquestfsg/results.phtml diff --git a/module/VuFind/config/module.config.php b/module/VuFind/config/module.config.php index 9f09b72181c..cf8136f5808 100644 --- a/module/VuFind/config/module.config.php +++ b/module/VuFind/config/module.config.php @@ -211,6 +211,8 @@ 'VuFind\Controller\Pazpar2Controller' => 'VuFind\Controller\AbstractBaseFactory', 'VuFind\Controller\PrimoController' => 'VuFind\Controller\AbstractBaseFactory', 'VuFind\Controller\PrimorecordController' => 'VuFind\Controller\AbstractBaseFactory', + 'VuFind\Controller\ProQuestFSGController' => 'VuFind\Controller\AbstractBaseFactory', + 'VuFind\Controller\ProQuestFSGrecordController' => 'VuFind\Controller\AbstractBaseFactory', 'VuFind\Controller\QRCodeController' => 'VuFind\Controller\QRCodeControllerFactory', 'VuFind\Controller\RecordController' => 'VuFind\Controller\AbstractBaseWithConfigFactory', 'VuFind\Controller\RecordsController' => 'VuFind\Controller\AbstractBaseFactory', @@ -323,6 +325,10 @@ 'primo' => 'VuFind\Controller\PrimoController', 'PrimoRecord' => 'VuFind\Controller\PrimorecordController', 'primorecord' => 'VuFind\Controller\PrimorecordController', + 'ProQuestFSG' => 'VuFind\Controller\ProQuestFSGController', + 'proquestfsg' => 'VuFind\Controller\ProQuestFSGController', + 'ProQuestFSGRecord' => 'VuFind\Controller\ProQuestFSGrecordController', + 'proquestfsgrecord' => 'VuFind\Controller\ProQuestFSGrecordController', 'QRCode' => 'VuFind\Controller\QRCodeController', 'qrcode' => 'VuFind\Controller\QRCodeController', 'Record' => 'VuFind\Controller\RecordController', @@ -735,6 +741,7 @@ 'epfrecord' => 'EPFRecord', 'missingrecord' => 'MissingRecord', 'primorecord' => 'PrimoRecord', + 'proquestfsgrecord' => 'ProQuestFSGRecord', 'solrauthrecord' => 'AuthorityRecord', 'summonrecord' => 'SummonRecord', 'worldcatrecord' => 'WorldcatRecord', @@ -804,6 +811,7 @@ 'Overdrive/MyContent','Overdrive/Hold', 'Pazpar2/Home', 'Pazpar2/Search', 'Primo/Advanced', 'Primo/CitedBy', 'Primo/Cites', 'Primo/Home', 'Primo/Search', + 'ProQuestFSG/Home', 'ProQuestFSG/Results', 'QRCode/Show', 'QRCode/Unavailable', 'Records/Home', 'Relais/Login', 'Relais/Request', 'Search/Advanced', diff --git a/module/VuFind/src/VuFind/Controller/ProQuestFSGController.php b/module/VuFind/src/VuFind/Controller/ProQuestFSGController.php new file mode 100644 index 00000000000..437d43cb3fc --- /dev/null +++ b/module/VuFind/src/VuFind/Controller/ProQuestFSGController.php @@ -0,0 +1,68 @@ + + * @author Maccabee Levine + * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License + * @link https://vufind.org Main Site + */ + +namespace VuFind\Controller; + +use Laminas\ServiceManager\ServiceLocatorInterface; + +/** + * ProQuest Federated Search Gateway Controller + * + * @category VuFind + * @package Controller + * @author Demian Katz + * @author Maccabee Levine + * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License + * @link https://vufind.org Main Site + */ +class ProQuestFSGController extends AbstractSearch +{ + /** + * Constructor + * + * @param ServiceLocatorInterface $sm Service locator + */ + public function __construct(ServiceLocatorInterface $sm) + { + $this->searchClassId = 'ProQuestFSG'; + parent::__construct($sm); + } + + /** + * Is the result scroller active? + * + * @return bool + */ + // protected function resultScrollerActive() + // { + // $config = $this->getService(\VuFind\Config\PluginManager::class)->get('LibGuidesAZ'); + // return $config->Record->next_prev_navigation ?? false; + // } +} diff --git a/module/VuFind/src/VuFind/Controller/ProQuestFSGrecordController.php b/module/VuFind/src/VuFind/Controller/ProQuestFSGrecordController.php new file mode 100644 index 00000000000..b901747fea0 --- /dev/null +++ b/module/VuFind/src/VuFind/Controller/ProQuestFSGrecordController.php @@ -0,0 +1,71 @@ + + * @author Maccabee Levine + * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License + * @link https://vufind.org Main Site + */ + +namespace VuFind\Controller; + +use Laminas\ServiceManager\ServiceLocatorInterface; + +/** + * ProQuest Federated Search Gateway Record Controller + * + * @category VuFind + * @package Controller + * @author Demian Katz + * @author Maccabee Levine + * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License + * @link https://vufind.org Main Site + */ +class ProQuestFSGrecordController extends AbstractRecord +{ + /** + * Constructor + * + * @param ServiceLocatorInterface $sm Service locator + */ + public function __construct(ServiceLocatorInterface $sm) + { + // Override some defaults: + $this->sourceId = 'ProQuestFSG'; + + // Call standard record controller initialization: + parent::__construct($sm); + } + + /** + * Is the result scroller active? + * + * @return bool + */ + // protected function resultScrollerActive() + // { + // $config = $this->getService(\VuFind\Config\PluginManager::class)->get('ProQuestFSG'); + // return $config->Record->next_prev_navigation ?? false; + // } +} diff --git a/module/VuFind/src/VuFind/RecordDriver/PluginManager.php b/module/VuFind/src/VuFind/RecordDriver/PluginManager.php index 5aadca04f97..8d740aa16b8 100644 --- a/module/VuFind/src/VuFind/RecordDriver/PluginManager.php +++ b/module/VuFind/src/VuFind/RecordDriver/PluginManager.php @@ -59,6 +59,7 @@ class PluginManager extends \VuFind\ServiceManager\AbstractPluginManager 'missing' => Missing::class, 'pazpar2' => Pazpar2::class, 'primo' => Primo::class, + 'proquestfsg' => ProQuestFSG::class, 'search2default' => Search2Default::class, 'solrarchivesspace' => SolrArchivesSpace::class, 'solrauth' => SolrAuthMarc::class, // legacy name diff --git a/module/VuFind/src/VuFind/RecordDriver/ProQuestFSG.php b/module/VuFind/src/VuFind/RecordDriver/ProQuestFSG.php new file mode 100644 index 00000000000..8575115c08d --- /dev/null +++ b/module/VuFind/src/VuFind/RecordDriver/ProQuestFSG.php @@ -0,0 +1,85 @@ + + * @author Maccabee Levine + * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License + * @link https://vufind.org/wiki/development:plugins:record_drivers Wiki + */ + +namespace VuFind\RecordDriver; + +use VuFind\RecordDriver\Feature\MarcAdvancedTrait; +use VuFind\RecordDriver\Feature\MarcBasicTrait; +use VuFind\RecordDriver\Feature\MarcReaderTrait; + +/** + * Model for MARC records in ProQuest Federated Search Gateway. + * + * @category VuFind + * @package RecordDrivers + * @author Demian Katz + * @author Maccabee Levine + * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License + * @link https://vufind.org/wiki/development:plugins:record_drivers Wiki + */ +class ProQuestFSG extends DefaultRecord +{ + use MarcReaderTrait, MarcAdvancedTrait, MarcBasicTrait { + MarcBasicTrait::getNewerTitles insteadof MarcAdvancedTrait; + MarcBasicTrait::getPreviousTitles insteadof MarcAdvancedTrait; + } + + /** + * Set raw data to initialize the object. + * + * @param mixed $data Raw data representing the record; Record Model + * objects are normally constructed by Record Driver objects using data + * passed in from a Search Results object. In this case, $data is a MARCXML + * document. + * + * @return void + */ + public function setRawData($data) + { + // Ensure that $driver->setRawData($driver->getRawData()) doesn't blow up: + if (isset($data['fullrecord'])) { + $data = $data['fullrecord']; + } + + // Map the WorldCat response into a format that the parent Solr-based + // record driver can understand. + parent::setRawData(['fullrecord' => $data]); + } + + // /** + // * Get the OCLC number of the record. + // * + // * @return array + // */ + // public function getOCLC() + // { + // return [$this->getUniqueID()]; + // } +} diff --git a/module/VuFind/src/VuFind/Search/BackendRegistry.php b/module/VuFind/src/VuFind/Search/BackendRegistry.php index 5065d41c14a..f7fa9598ff8 100644 --- a/module/VuFind/src/VuFind/Search/BackendRegistry.php +++ b/module/VuFind/src/VuFind/Search/BackendRegistry.php @@ -69,6 +69,7 @@ class BackendRegistry extends \VuFind\ServiceManager\AbstractPluginManager 'LibGuidesAZ' => Factory\LibGuidesAZBackendFactory::class, 'Pazpar2' => Factory\Pazpar2BackendFactory::class, 'Primo' => Factory\PrimoBackendFactory::class, + 'ProQuestFSG' => Factory\ProQuestFSGBackendFactory::class, 'Search2' => Factory\Search2BackendFactory::class, 'Search2Collection' => Factory\Search2BackendFactory::class, 'Solr' => Factory\SolrDefaultBackendFactory::class, diff --git a/module/VuFind/src/VuFind/Search/Factory/ProQuestFSGBackendFactory.php b/module/VuFind/src/VuFind/Search/Factory/ProQuestFSGBackendFactory.php new file mode 100644 index 00000000000..c641114ce6f --- /dev/null +++ b/module/VuFind/src/VuFind/Search/Factory/ProQuestFSGBackendFactory.php @@ -0,0 +1,156 @@ + + * @author Maccabee Levine + * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License + * @link https://vufind.org Main Site + */ + +namespace VuFind\Search\Factory; + +use Psr\Container\ContainerInterface; +use VuFindSearch\Backend\ProQuestFSG\Backend; +use VuFindSearch\Backend\ProQuestFSG\Connector; +use VuFindSearch\Backend\ProQuestFSG\QueryBuilder; +use VuFindSearch\Backend\ProQuestFSG\Response\XML\RecordCollectionFactory; + +/** + * Factory for ProQuest Federated Search Gateway backends. + * + * @category VuFind + * @package Search + * @author David Maus + * @author Maccabee Levine + * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License + * @link https://vufind.org Main Site + */ +class ProQuestFSGBackendFactory extends AbstractBackendFactory +{ + /** + * Logger. + * + * @var \Laminas\Log\LoggerInterface + */ + protected $logger; + + /** + * VuFind configuration + * + * @var \Laminas\Config\Config + */ + protected $config; + + // /** + // * WorldCat configuration + // * + // * @var \Laminas\Config\Config + // */ + // protected $wcConfig; + + /** + * Create service + * + * @param ContainerInterface $sm Service manager + * @param string $name Requested service name (unused) + * @param array $options Extra options (unused) + * + * @return Backend + * + * @SuppressWarnings(PHPMD.UnusedFormalParameter) + */ + public function __invoke(ContainerInterface $sm, $name, array $options = null) + { + $this->setup($sm); + $this->config = $this->getService(\VuFind\Config\PluginManager::class)->get('config'); + // $this->wcConfig = $this->getService(\VuFind\Config\PluginManager::class)->get('WorldCat'); + if ($this->serviceLocator->has(\VuFind\Log\Logger::class)) { + $this->logger = $this->getService(\VuFind\Log\Logger::class); + } + $connector = $this->createConnector(); + $backend = $this->createBackend($connector); + return $backend; + } + + /** + * Create the WorldCat backend. + * + * @param Connector $connector Connector + * + * @return Backend + */ + protected function createBackend(Connector $connector) + { + $backend = new Backend($connector, $this->createRecordCollectionFactory()); + $backend->setLogger($this->logger); + // $backend->setQueryBuilder($this->createQueryBuilder()); + return $backend; + } + + /** + * Create the WorldCat connector. + * + * @return Connector + */ + protected function createConnector() + { + // $wsKey = $this->config->WorldCat->apiKey ?? null; + // $connectorOptions = isset($this->wcConfig->Connector) + // ? $this->wcConfig->Connector->toArray() : []; + $connector = new Connector( + // $wsKey, + $this->createHttpClient(), + // $connectorOptions + ); + $connector->setLogger($this->logger); + return $connector; + } + + /** + * Create the WorldCat query builder. + * + * @return QueryBuilder + */ + protected function createQueryBuilder() + { + $exclude = $this->config->WorldCat->OCLCCode ?? null; + return new QueryBuilder($exclude); + } + + /** + * Create the record collection factory + * + * @return RecordCollectionFactory + */ + protected function createRecordCollectionFactory() + { + $manager = $this->getService(\VuFind\RecordDriver\PluginManager::class); + $callback = function ($data) use ($manager) { + $driver = $manager->get('ProQuestFSG'); + $driver->setRawData($data); + return $driver; + }; + return new RecordCollectionFactory($callback); + } +} diff --git a/module/VuFind/src/VuFind/Search/Options/PluginManager.php b/module/VuFind/src/VuFind/Search/Options/PluginManager.php index 11ea33724fe..63d7fafd800 100644 --- a/module/VuFind/src/VuFind/Search/Options/PluginManager.php +++ b/module/VuFind/src/VuFind/Search/Options/PluginManager.php @@ -59,6 +59,7 @@ class PluginManager extends \VuFind\ServiceManager\AbstractPluginManager 'mixedlist' => \VuFind\Search\MixedList\Options::class, 'pazpar2' => \VuFind\Search\Pazpar2\Options::class, 'primo' => \VuFind\Search\Primo\Options::class, + 'proquestfsg' => \VuFind\Search\ProQuestFSG\Options::class, 'search2' => \VuFind\Search\Search2\Options::class, 'search2collection' => \VuFind\Search\Search2\Options::class, 'solr' => \VuFind\Search\Solr\Options::class, @@ -93,6 +94,7 @@ class PluginManager extends \VuFind\ServiceManager\AbstractPluginManager \VuFind\Search\MixedList\Options::class => OptionsFactory::class, \VuFind\Search\Pazpar2\Options::class => OptionsFactory::class, \VuFind\Search\Primo\Options::class => OptionsFactory::class, + \VuFind\Search\ProQuestFSG\Options::class => OptionsFactory::class, \VuFind\Search\Search2\Options::class => OptionsFactory::class, \VuFind\Search\Search2Collection\Options::class => OptionsFactory::class, \VuFind\Search\Solr\Options::class => OptionsFactory::class, diff --git a/module/VuFind/src/VuFind/Search/Params/PluginManager.php b/module/VuFind/src/VuFind/Search/Params/PluginManager.php index b2085b8bbd8..6c7431687ac 100644 --- a/module/VuFind/src/VuFind/Search/Params/PluginManager.php +++ b/module/VuFind/src/VuFind/Search/Params/PluginManager.php @@ -59,6 +59,7 @@ class PluginManager extends \VuFind\ServiceManager\AbstractPluginManager 'mixedlist' => \VuFind\Search\MixedList\Params::class, 'pazpar2' => \VuFind\Search\Pazpar2\Params::class, 'primo' => \VuFind\Search\Primo\Params::class, + 'proquestfsg' => \VuFind\Search\ProQuestFSG\Params::class, 'search2' => \VuFind\Search\Search2\Params::class, 'solr' => \VuFind\Search\Solr\Params::class, 'solrauth' => \VuFind\Search\SolrAuth\Params::class, @@ -92,6 +93,7 @@ class PluginManager extends \VuFind\ServiceManager\AbstractPluginManager \VuFind\Search\MixedList\Params::class => ParamsFactory::class, \VuFind\Search\Pazpar2\Params::class => ParamsFactory::class, \VuFind\Search\Primo\Params::class => ParamsFactory::class, + \VuFind\Search\ProQuestFSG\Params::class => ParamsFactory::class, \VuFind\Search\Search2\Params::class => \VuFind\Search\Solr\ParamsFactory::class, \VuFind\Search\Solr\Params::class => diff --git a/module/VuFind/src/VuFind/Search/ProQuestFSG/Options.php b/module/VuFind/src/VuFind/Search/ProQuestFSG/Options.php new file mode 100644 index 00000000000..5906c929bc9 --- /dev/null +++ b/module/VuFind/src/VuFind/Search/ProQuestFSG/Options.php @@ -0,0 +1,117 @@ + + * @author Maccabee Levine + * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License + * @link https://vufind.org Main Page + */ + +namespace VuFind\Search\ProQuestFSG; + +use function count; + +/** + * ProQuest Federated Search Gateway Search Options + * + * @category VuFind + * @package Search_ProQuestFSG + * @author Demian Katz + * @author Maccabee Levine + * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License + * @link https://vufind.org Main Page + */ +class Options extends \VuFind\Search\Base\Options +{ + /** + * Constructor + * + * @param \VuFind\Config\PluginManager $configLoader Config loader + */ + public function __construct(\VuFind\Config\PluginManager $configLoader) + { + parent::__construct($configLoader); + $this->searchIni = $this->facetsIni = 'ProQuestFSG'; + + // Load the configuration file: + $searchSettings = $configLoader->get($this->searchIni); + + // // Search handler setup: + // $this->defaultHandler = 'srw.kw'; + // if (isset($searchSettings->Basic_Searches)) { + // foreach ($searchSettings->Basic_Searches as $key => $value) { + // $this->basicHandlers[$key] = $value; + // } + // } + // if (isset($searchSettings->Advanced_Searches)) { + // foreach ($searchSettings->Advanced_Searches as $key => $value) { + // $this->advancedHandlers[$key] = $value; + // } + // } + + // // Load sort preferences: + // if (isset($searchSettings->Sorting)) { + // foreach ($searchSettings->Sorting as $key => $value) { + // $this->sortOptions[$key] = $value; + // } + // } + // if (isset($searchSettings->General->default_sort)) { + // $this->defaultSort = $searchSettings->General->default_sort; + // } + // if ( + // isset($searchSettings->DefaultSortingByType) + // && count($searchSettings->DefaultSortingByType) > 0 + // ) { + // foreach ($searchSettings->DefaultSortingByType as $key => $val) { + // $this->defaultSortByHandler[$key] = $val; + // } + // } + // // Load list view for result (controls AJAX embedding vs. linking) + // if (isset($searchSettings->List->view)) { + // $this->listviewOption = $searchSettings->List->view; + // } + } + + /** + * Return the route name for the search results action. + * + * @return string + */ + public function getSearchAction() + { + return 'proquestfsg-results'; + } + + /** + * Return the route name of the action used for performing advanced searches. + * Returns false if the feature is not supported. + * + * @return string|bool + */ + public function getAdvancedSearchAction() + { + // return 'worldcat-advanced'; + return false; + } +} diff --git a/module/VuFind/src/VuFind/Search/ProQuestFSG/Params.php b/module/VuFind/src/VuFind/Search/ProQuestFSG/Params.php new file mode 100644 index 00000000000..dc301d469ff --- /dev/null +++ b/module/VuFind/src/VuFind/Search/ProQuestFSG/Params.php @@ -0,0 +1,62 @@ + + * @author Maccabee Levine + * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License + * @link https://vufind.org Main Page + */ + +namespace VuFind\Search\ProQuestFSG; + +use VuFindSearch\ParamBag; + +/** + * ProQuest Federated Search Gateway Search Parameters + * + * @category VuFind + * @package Search_ProQuestFSG + * @author Demian Katz + * @author Maccabee Levine + * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License + * @link https://vufind.org Main Page + */ +class Params extends \VuFind\Search\Base\Params +{ + /** + * Create search backend parameters for advanced features. + * + * @return ParamBag + */ + public function getBackendParameters() + { + $backendParams = new ParamBag(); + + // // Sort + // $sort = $this->getSort(); + // $backendParams->set('sortKeys', empty($sort) ? 'relevance' : $sort); + + return $backendParams; + } +} diff --git a/module/VuFind/src/VuFind/Search/ProQuestFSG/Results.php b/module/VuFind/src/VuFind/Search/ProQuestFSG/Results.php new file mode 100644 index 00000000000..6cb52c6609d --- /dev/null +++ b/module/VuFind/src/VuFind/Search/ProQuestFSG/Results.php @@ -0,0 +1,91 @@ + + * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License + * @link https://vufind.org Main Page + */ + +namespace VuFind\Search\ProQuestFSG; + +use VuFindSearch\Command\SearchCommand; + +/** + * ProQuest Federated Search Gateway Search Parameters + * + * @category VuFind + * @package Search_ProQuestFSG + * @author Demian Katz + * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License + * @link https://vufind.org Main Page + */ +class Results extends \VuFind\Search\Base\Results +{ + /** + * Search backend identifier. + * + * @var string + */ + protected $backendId = 'ProQuestFSG'; + + /** + * Support method for performAndProcessSearch -- perform a search based on the + * parameters passed to the object. + * + * @return void + */ + protected function performSearch() + { + $query = $this->getParams()->getQuery(); + $limit = $this->getParams()->getLimit(); + $offset = $this->getStartRecord(); + $params = $this->getParams()->getBackendParameters(); + $command = new SearchCommand( + $this->backendId, + $query, + $offset, + $limit, + $params + ); + $collection = $this->getSearchService() + ->invoke($command)->getResult(); + + $this->resultTotal = $collection->getTotal(); + $this->results = $collection->getRecords(); + } + + /** + * Returns the stored list of facets for the last search + * + * @param array $filter Array of field => on-screen description listing + * all of the desired facet fields; set to null to get all configured values. + * + * @return array Facets data arrays + */ + public function getFacetList($filter = null) + { + // No facets in WorldCat: + return []; + } +} diff --git a/module/VuFind/src/VuFind/Search/Results/PluginManager.php b/module/VuFind/src/VuFind/Search/Results/PluginManager.php index e665d64c265..bb7cabfe0b7 100644 --- a/module/VuFind/src/VuFind/Search/Results/PluginManager.php +++ b/module/VuFind/src/VuFind/Search/Results/PluginManager.php @@ -59,6 +59,7 @@ class PluginManager extends \VuFind\ServiceManager\AbstractPluginManager 'mixedlist' => \VuFind\Search\MixedList\Results::class, 'pazpar2' => \VuFind\Search\Pazpar2\Results::class, 'primo' => \VuFind\Search\Primo\Results::class, + 'proquestfsg' => \VuFind\Search\ProQuestFSG\Results::class, 'search2' => \VuFind\Search\Search2\Results::class, 'search2collection' => \VuFind\Search\Search2Collection\Results::class, 'solr' => \VuFind\Search\Solr\Results::class, @@ -94,6 +95,7 @@ class PluginManager extends \VuFind\ServiceManager\AbstractPluginManager \VuFind\Search\MixedList\Results::class => ResultsFactory::class, \VuFind\Search\Pazpar2\Results::class => ResultsFactory::class, \VuFind\Search\Primo\Results::class => ResultsFactory::class, + \VuFind\Search\ProQuestFSG\Results::class => ResultsFactory::class, \VuFind\Search\Search2\Results::class => \VuFind\Search\Search2\ResultsFactory::class, \VuFind\Search\Search2Collection\Results::class => ResultsFactory::class, diff --git a/module/VuFind/xsl/sru-convert-simple.xsl b/module/VuFind/xsl/sru-convert-simple.xsl new file mode 100644 index 00000000000..dd620adca8b --- /dev/null +++ b/module/VuFind/xsl/sru-convert-simple.xsl @@ -0,0 +1,39 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/module/VuFindSearch/src/VuFindSearch/Backend/ProQuestFSG/Backend.php b/module/VuFindSearch/src/VuFindSearch/Backend/ProQuestFSG/Backend.php new file mode 100644 index 00000000000..897ed4aa2d4 --- /dev/null +++ b/module/VuFindSearch/src/VuFindSearch/Backend/ProQuestFSG/Backend.php @@ -0,0 +1,205 @@ + + * @author Maccabee Levine + * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License + * @link https://vufind.org + */ + +namespace VuFindSearch\Backend\ProQuestFSG; + +use VuFindSearch\Backend\AbstractBackend; +use VuFindSearch\ParamBag; +use VuFindSearch\Query\AbstractQuery; +use VuFindSearch\Response\RecordCollectionFactoryInterface; +use VuFindSearch\Response\RecordCollectionInterface; + +/** + * ProQuest Federated Search Gateway backend. + * + * @category VuFind + * @package Search + * @author David Maus + * @author Maccabee Levine + * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License + * @link https://vufind.org + */ +class Backend extends AbstractBackend +{ + /** + * Connector. + * + * @var Connector + */ + protected $connector; + + /** + * Query builder. + * + * @var QueryBuilder + */ + protected $queryBuilder = null; + + /** + * Constructor. + * + * @param Connector $connector WorldCat connector + * @param RecordCollectionFactoryInterface $factory Record collection factory + * (null for default) + * + * @return void + */ + public function __construct( + Connector $connector, + RecordCollectionFactoryInterface $factory = null + ) { + if (null !== $factory) { + $this->setRecordCollectionFactory($factory); + } + $this->connector = $connector; + $this->identifier = 'ProQuestFSG'; + } + + /** + * Perform a search and return record collection. + * + * @param AbstractQuery $query Search query + * @param int $offset Search offset + * @param int $limit Search limit + * @param ParamBag $params Search backend parameters + * + * @return RecordCollectionInterface + */ + public function search( + AbstractQuery $query, + $offset, + $limit, + ParamBag $params = null + ) { + if (null === $params) { + $params = new ParamBag(); + } + $params->mergeWith($this->getQueryBuilder()->build($query)); + $response = $this->connector->search($params, $offset, $limit); + $collection = $this->createRecordCollection($response); + $this->injectSourceIdentifier($collection); + return $collection; + } + + /** + * Retrieve a single document. + * + * @param string $id Document identifier + * @param ParamBag $params Search backend parameters + * + * @return RecordCollectionInterface + */ + public function retrieve($id, ParamBag $params = null) + { + $response = $this->connector->getRecord($id, $params); + $collection = $this->createRecordCollection($response); + $this->injectSourceIdentifier($collection); + return $collection; + } + + /** + * Set the query builder. + * + * @param QueryBuilder $queryBuilder Query builder + * + * @return void + */ + // public function setQueryBuilder(QueryBuilder $queryBuilder) + // { + // $this->queryBuilder = $queryBuilder; + // } + + /** + * Return query builder. + * + * Lazy loads an empty QueryBuilder if none was set. + * + * @return QueryBuilder + */ + public function getQueryBuilder() + { + if (!$this->queryBuilder) { + $this->queryBuilder = new QueryBuilder(); + } + return $this->queryBuilder; + } + + /** + * Return the record collection factory. + * + * Lazy loads a generic collection factory. + * + * @return RecordCollectionFactoryInterface + */ + public function getRecordCollectionFactory() + { + if ($this->collectionFactory === null) { + $this->collectionFactory = new Response\XML\RecordCollectionFactory(); + } + return $this->collectionFactory; + } + + /** + * Get holdings information for the specified record. + * + * @param string $id Record to obtain holdings for. + * + * @throws \Exception + * @return \SimpleXMLElement + */ + // public function getHoldings($id) + // { + // return $this->getConnector()->getHoldings($id); + // } + + /** + * Return the WorldCat connector. + * + * @return Connector + */ + // public function getConnector() + // { + // return $this->connector; + // } + + /// Internal API + + /** + * Create record collection. + * + * @param array $records Records to process + * + * @return RecordCollectionInterface + */ + protected function createRecordCollection($records) + { + return $this->getRecordCollectionFactory()->factory($records); + } +} diff --git a/module/VuFindSearch/src/VuFindSearch/Backend/ProQuestFSG/Connector.php b/module/VuFindSearch/src/VuFindSearch/Backend/ProQuestFSG/Connector.php new file mode 100644 index 00000000000..ceb90bb0532 --- /dev/null +++ b/module/VuFindSearch/src/VuFindSearch/Backend/ProQuestFSG/Connector.php @@ -0,0 +1,199 @@ + + * @author Demian Katz + * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License + * @link https://vufind.org/wiki/development Wiki + */ + +namespace VuFindSearch\Backend\ProQuestFSG; + +use VuFindSearch\ParamBag; + +/** + * WorldCat SRU Search Interface + * + * @category VuFind + * @package WorldCat + * @author Andrew S. Nagy + * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License + * @link https://vufind.org/wiki/development Wiki + */ +class Connector extends \VuFindSearch\Backend\SRU\Connector +{ + // /** + // * OCLC API key + // * + // * @var string + // */ + // protected $wskey; + + // /** + // * Additional options + // * + // * @var array + // */ + // protected $options; + + /** + * The version to specify in the URL + * + * @var string + */ + protected $sruVersion = '1.2'; + + /** + * Constructor + * + * @param string $wsKey Web services key + * @param \Laminas\Http\Client $client An HTTP client object + * @param array $options Additional config settings + */ + public function __construct( + // $wsKey, + \Laminas\Http\Client $client, + array $options = [] + ) { + parent::__construct( + 'https://fedsearch.proquest.com/search/sru' . '/all_subscribed', + $client + ); + // $this->wskey = $wsKey; + // $this->options = $options; + } + + // /** + // * Get holdings information for the specified record. + // * + // * @param string $id Record to obtain holdings for. + // * + // * @throws \Exception + // * @return \SimpleXMLElement + // */ + // public function getHoldings($id) + // { + // $this->client->resetParameters(); + // if (!isset($this->options['useFrbrGroupingForHoldings'])) { + // $grouping = 'on'; // default to "on" for backward compatibility + // } else { + // $grouping = $this->options['useFrbrGroupingForHoldings'] ? 'on' : 'off'; + // } + // $uri = "http://www.worldcat.org/webservices/catalog/content/libraries/{$id}" + // . "?wskey={$this->wskey}&servicelevel=full&frbrGrouping=$grouping"; + // if (isset($this->options['latLon'])) { + // [$lat, $lon] = explode(',', $this->options['latLon']); + // $uri .= '&lat=' . urlencode($lat) . '&lon=' . urlencode($lon); + // } + // $this->client->setUri($uri); + // $this->debug('Connect: ' . $uri); + // $result = $this->client->setMethod('POST')->send(); + // $this->checkForHttpError($result); + + // return simplexml_load_string($result->getBody()); + // } + + /** + * Retrieve a specific record. + * + * @param string $id Record ID to retrieve + * @param ParamBag $params Parameters + * + * @throws \Exception + * @return string MARC XML + */ + public function getRecord($id, ParamBag $params = null) + { + // $params = $params ?: new ParamBag(); + // $params->set('servicelevel', 'full'); + // $params->set('wskey', $this->wskey); + + // $this->client->resetParameters(); + // $uri = 'http://www.worldcat.org/webservices/catalog/content/' . $id; + // $uri .= '?' . implode('&', $params->request()); + // $this->client->setUri($uri); + // $this->debug('Connect: ' . $uri); + // $result = $this->client->setMethod('POST')->send(); + // $this->checkForHttpError($result); + + // // Check for error message in response: + // $body = $result->getBody(); + // $xml = simplexml_load_string($body); + // $error = isset($xml->diagnostic); + + // return [ + // 'docs' => $error ? [] : [$body], + // 'offset' => 0, + // 'total' => $error ? 0 : 1, + // ]; + + $params->set('query', "rec.identifier = \"{$id}\""); + return $this->search($params, 0, 1); + } + + /** + * Execute a search. + * + * @param ParamBag $params Parameters + * @param int $offset Search offset + * @param int $limit Search limit + * + * @return string + */ + public function search(ParamBag $params, $offset, $limit) + { + // $params->set('startRecord', $offset); + // $params->set('maximumRecords', $limit); + // $params->set('servicelevel', 'full'); + // $params->set('wskey', $this->wskey); + + // $response = $this->call('POST', $params->getArrayCopy(), false); + + $response = $this->sruSearch( + $params->get('query')[0], + $offset, + $limit, null, 'marcxml', + true + ); + + // $xml = simplexml_load_string($response); + // $docs = $xml->records->record ?? []; + $finalDocs = []; + // foreach ($docs as $doc) { + foreach ($response->record as $doc) { + $finalDocs[] = $doc->asXML(); + } + // return [ + // 'docs' => $finalDocs, + // 'offset' => $offset, + // 'total' => (int)($xml->numberOfRecords ?? 0), + // ]; + // return $response; + return [ + 'docs' => $finalDocs, + 'offset' => $offset, + 'total' => (int)($response->RecordCount), + ]; + } +} diff --git a/module/VuFindSearch/src/VuFindSearch/Backend/ProQuestFSG/QueryBuilder.php b/module/VuFindSearch/src/VuFindSearch/Backend/ProQuestFSG/QueryBuilder.php new file mode 100644 index 00000000000..82ab323af05 --- /dev/null +++ b/module/VuFindSearch/src/VuFindSearch/Backend/ProQuestFSG/QueryBuilder.php @@ -0,0 +1,193 @@ + + * @author David Maus + * @author Demian Katz + * @author Maccabee Levine + * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License + * @link https://vufind.org + */ + +namespace VuFindSearch\Backend\ProQuestFSG; + +use VuFindSearch\ParamBag; +use VuFindSearch\Query\AbstractQuery; +use VuFindSearch\Query\Query; +use VuFindSearch\Query\QueryGroup; + +use function count; + +/** + * ProQuest Federated Search Gateway QueryBuilder. + * + * @category VuFind + * @package Search + * @author Andrew S. Nagy + * @author David Maus + * @author Demian Katz + * @author Maccabee Levine + * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License + * @link https://vufind.org + */ +class QueryBuilder +{ + /** + * OCLC code to exclude from results + * + * @var string + */ + protected $oclcCodeToExclude; + + /// Public API + + // /** + // * Constructor + // * + // * @param string $exclude OCLC code to exclude from results + // */ + // public function __construct($exclude = null) + // { + // $this->oclcCodeToExclude = $exclude; + // } + + /** + * Return WorldCat search parameters based on a user query and params. + * + * @param AbstractQuery $query User query + * @param ?ParamBag $params Search backend parameters + * + * @return ParamBag + * + * @SuppressWarnings(PHPMD.UnusedFormalParameter) + */ + public function build(AbstractQuery $query, ?ParamBag $params = null) + { + // Build base query + $queryStr = $this->abstractQueryToString($query); + + // // Exclude current library from results (if applicable) + // if (null !== $this->oclcCodeToExclude) { + // $queryStr .= ' not srw.li all "' . $this->oclcCodeToExclude . '"'; + // } + + // Send back results + $newParams = new ParamBag(); + $newParams->set('query', $queryStr); + return $newParams; + } + + /// Internal API + + /** + * Convert an AbstractQuery object to a query string. + * + * @param AbstractQuery $query Query to convert + * + * @return string + */ + protected function abstractQueryToString(AbstractQuery $query) + { + // if ($query instanceof Query) { + return $this->queryToString($query); + // } else { + // return $this->queryGroupToString($query); + // } + } + + // /** + // * Convert a QueryGroup object to a query string. + // * + // * @param QueryGroup $query QueryGroup to convert + // * + // * @return string + // */ + // protected function queryGroupToString(QueryGroup $query) + // { + // $groups = $excludes = []; + + // foreach ($query->getQueries() as $params) { + // // Advanced Search + // if ($params instanceof QueryGroup) { + // $thisGroup = []; + // // Process each search group + // foreach ($params->getQueries() as $group) { + // // Build this group individually as a basic search + // $thisGroup[] = $this->abstractQueryToString($group); + // } + // // Is this an exclusion (NOT) group or a normal group? + // if ($params->isNegated()) { + // $excludes[] = implode(' OR ', $thisGroup); + // } else { + // $groups[] + // = implode(' ' . $params->getOperator() . ' ', $thisGroup); + // } + // } else { + // // Basic Search + // $groups[] = $this->queryToString($params); + // } + // } + + // // Put our advanced search together + // $queryStr = ''; + // if (count($groups) > 0) { + // $queryStr + // .= '(' . implode(') ' . $query->getOperator() . ' (', $groups) . ')'; + // } + // // and concatenate exclusion after that + // if (count($excludes) > 0) { + // $queryStr .= ' NOT ((' . implode(') OR (', $excludes) . '))'; + // } + + // return $queryStr; + // } + + /** + * Convert a single Query object to a query string. + * + * @param Query $query Query to convert + * + * @return string + */ + protected function queryToString(Query $query) + { + // Clean and validate input: + $index = $query->getHandler(); + if (empty($index)) { + // No handler? Just accept query string as-is; no modifications needed. + return $query->getString(); + } + $lookfor = str_replace('"', '', $query->getString()); + + // The index may contain multiple parts -- we want to search all listed index + // fields: + $index = explode(':', $index); + $clauses = []; + foreach ($index as $currentIndex) { + $clauses[] = "{$currentIndex} all \"{$lookfor}\""; + } + + return '(' . implode(' OR ', $clauses) . ')'; + } +} diff --git a/module/VuFindSearch/src/VuFindSearch/Backend/ProQuestFSG/Response/XML/Record.php b/module/VuFindSearch/src/VuFindSearch/Backend/ProQuestFSG/Response/XML/Record.php new file mode 100644 index 00000000000..151be7f09a8 --- /dev/null +++ b/module/VuFindSearch/src/VuFindSearch/Backend/ProQuestFSG/Response/XML/Record.php @@ -0,0 +1,79 @@ + + * @author Maccabee Levine + * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License + * @link https://vufind.org + */ + +namespace VuFindSearch\Backend\ProQuestFSG\Response\XML; + +use VuFind\Marc\MarcReader; +use VuFindSearch\Response\RecordInterface; + +/** + * Simple ProQuest Federated Search Gateway record. + * + * @category VuFind + * @package Search + * @author David Maus + * @author Maccabee Levine + * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License + * @link https://vufind.org + */ +class Record implements RecordInterface +{ + use \VuFindSearch\Response\RecordTrait; + + /** + * MARC record. + * + * @var MarcReader + */ + protected $marc; + + /** + * Constructor. + * + * @param MarcReader $marc MARC record + * + * @return void + */ + public function __construct(MarcReader $marc) + { + $this->marc = $marc; + $this->setSourceIdentifiers('ProQuestFSG'); + } + + /** + * Get MARC record + * + * @return MarcReader + */ + public function getMarc(): MarcReader + { + return $this->marc; + } +} diff --git a/module/VuFindSearch/src/VuFindSearch/Backend/ProQuestFSG/Response/XML/RecordCollection.php b/module/VuFindSearch/src/VuFindSearch/Backend/ProQuestFSG/Response/XML/RecordCollection.php new file mode 100644 index 00000000000..eded5c3cd3b --- /dev/null +++ b/module/VuFindSearch/src/VuFindSearch/Backend/ProQuestFSG/Response/XML/RecordCollection.php @@ -0,0 +1,87 @@ + + * @author Maccabee Levine + * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License + * @link https://vufind.org + */ + +namespace VuFindSearch\Backend\ProQuestFSG\Response\XML; + +use VuFindSearch\Response\AbstractRecordCollection; + +/** + * ProQuest Federated Search Gateway record collection. + * + * @category VuFind + * @package Search + * @author David Maus + * @author Maccabee Levine + * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License + * @link https://vufind.org + */ +class RecordCollection extends AbstractRecordCollection +{ + /** + * Raw response. + * + * @var array + */ + protected $response; + + /** + * Constructor. + * + * @param array $response WorldCat response + * + * @return void + */ + public function __construct(array $response) + { + $this->response = $response; + $this->offset = $this->response['offset']; + $this->rewind(); + } + + /** + * Return total number of records found. + * + * @return int + */ + public function getTotal() + { + return $this->response['total']; + } + + /** + * Return facet information. + * + * @return array + */ + public function getFacets() + { + return []; // not supported by WorldCat + } +} diff --git a/module/VuFindSearch/src/VuFindSearch/Backend/ProQuestFSG/Response/XML/RecordCollectionFactory.php b/module/VuFindSearch/src/VuFindSearch/Backend/ProQuestFSG/Response/XML/RecordCollectionFactory.php new file mode 100644 index 00000000000..2784c8b2d64 --- /dev/null +++ b/module/VuFindSearch/src/VuFindSearch/Backend/ProQuestFSG/Response/XML/RecordCollectionFactory.php @@ -0,0 +1,116 @@ + + * @author Maccabee Levine + * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License + * @link https://vufind.org + */ + +namespace VuFindSearch\Backend\ProQuestFSG\Response\XML; + +use VuFind\Marc\MarcReader; +use VuFindSearch\Exception\InvalidArgumentException; +use VuFindSearch\Response\RecordCollectionFactoryInterface; + +use function call_user_func; +use function gettype; +use function is_array; +use function is_callable; +use function sprintf; + +/** + * Simple XML-based factory for record collection. + * + * @category VuFind + * @package Search + * @author David Maus + * @author Maccabee Levine + * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License + * @link https://vufind.org + */ +class RecordCollectionFactory implements RecordCollectionFactoryInterface +{ + /** + * Factory to turn data into a record object. + * + * @var callable + */ + protected $recordFactory; + + /** + * Class of collection. + * + * @var string + */ + protected $collectionClass; + + /** + * Constructor. + * + * @param callable $recordFactory Record factory function (null for default) + * @param string $collectionClass Class of collection + * + * @return void + */ + public function __construct($recordFactory = null, $collectionClass = null) + { + if (null === $recordFactory) { + $recordFactory = function ($i) { + // return new Record(new MarcReader($i)); + $reader = new MarcReader($i); + $record = new Record($reader); + return $record; + }; + } elseif (!is_callable($recordFactory)) { + throw new InvalidArgumentException('Record factory must be callable.'); + } + $this->recordFactory = $recordFactory; + $this->collectionClass = $collectionClass ?? RecordCollection::class; + } + + /** + * Return record collection. + * + * @param array $response Collection of XML documents + * + * @return RecordCollection + */ + public function factory($response) + { + if (!is_array($response)) { + throw new InvalidArgumentException( + sprintf( + 'Unexpected type of value: Expected array, got %s', + gettype($response) + ) + ); + } + $collection = new $this->collectionClass($response); + foreach ($response['docs'] as $doc) { + $collection->add(call_user_func($this->recordFactory, $doc), false); + } + return $collection; + } +} diff --git a/module/VuFindSearch/src/VuFindSearch/Backend/SRU/Connector.php b/module/VuFindSearch/src/VuFindSearch/Backend/SRU/Connector.php index 31a5524d071..98c39c89bb7 100644 --- a/module/VuFindSearch/src/VuFindSearch/Backend/SRU/Connector.php +++ b/module/VuFindSearch/src/VuFindSearch/Backend/SRU/Connector.php @@ -246,7 +246,8 @@ protected function call($method = 'GET', $params = null, $process = true) protected function process($response) { // Send back either the raw XML or a SimpleXML object, as requested: - $result = XSLTProcessor::process('sru-convert.xsl', $response); + // $result = XSLTProcessor::process('sru-convert.xsl', $response); + $result = XSLTProcessor::process('sru-convert-simple.xsl', $response); if (!$result) { throw new BackendException( sprintf('Error processing SRU response: %20s', $response) diff --git a/module/VuFindSearch/src/VuFindSearch/Backend/Solr/Connector.php b/module/VuFindSearch/src/VuFindSearch/Backend/Solr/Connector.php index 5a33b7c878a..3dac06c8764 100644 --- a/module/VuFindSearch/src/VuFindSearch/Backend/Solr/Connector.php +++ b/module/VuFindSearch/src/VuFindSearch/Backend/Solr/Connector.php @@ -242,7 +242,8 @@ public function search(ParamBag $params) { $handler = $this->map->getHandler(__FUNCTION__); $this->map->prepare(__FUNCTION__, $params); - return $this->query($handler, $params, true); + $foo = $this->query($handler, $params, true); + return $foo; } /** diff --git a/themes/bootstrap3/templates/proquestfsg/home.phtml b/themes/bootstrap3/templates/proquestfsg/home.phtml new file mode 100644 index 00000000000..2b84165e5e2 --- /dev/null +++ b/themes/bootstrap3/templates/proquestfsg/home.phtml @@ -0,0 +1 @@ +render('search/home.phtml'); diff --git a/themes/bootstrap3/templates/proquestfsg/results.phtml b/themes/bootstrap3/templates/proquestfsg/results.phtml new file mode 100644 index 00000000000..1de7448817b --- /dev/null +++ b/themes/bootstrap3/templates/proquestfsg/results.phtml @@ -0,0 +1 @@ +render('search/results.phtml'); From 518de13d7a89d16b0a66b69ce0c4cf4726362930 Mon Sep 17 00:00:00 2001 From: Maccabee Levine Date: Fri, 4 Oct 2024 17:23:04 +0000 Subject: [PATCH 02/34] Support basic search indices --- config/vufind/ProQuestFSG.ini | 12 ++++++++++++ .../Search/Factory/ProQuestFSGBackendFactory.php | 12 ------------ .../VuFind/src/VuFind/Search/ProQuestFSG/Options.php | 12 ++++++------ .../Backend/ProQuestFSG/QueryBuilder.php | 11 +---------- 4 files changed, 19 insertions(+), 28 deletions(-) create mode 100644 config/vufind/ProQuestFSG.ini diff --git a/config/vufind/ProQuestFSG.ini b/config/vufind/ProQuestFSG.ini new file mode 100644 index 00000000000..5dcb3dfd517 --- /dev/null +++ b/config/vufind/ProQuestFSG.ini @@ -0,0 +1,12 @@ +; This section shows which search types will display in the basic search box at +; the top of Primo pages. The name of each setting below corresponds with an +; index defined in the Primo API. The value of each setting is the text to +; display on screen. All on-screen text will be run through the translator, so +; be sure to update language files if necessary. The order of these settings +; will be maintained in the drop-down list in the UI. +[Basic_Searches] +cql.serverChoice = "All Fields" +title = Title +author = Author +subject = Subject +;abstract = Abstract diff --git a/module/VuFind/src/VuFind/Search/Factory/ProQuestFSGBackendFactory.php b/module/VuFind/src/VuFind/Search/Factory/ProQuestFSGBackendFactory.php index c641114ce6f..8f7a3eaf4be 100644 --- a/module/VuFind/src/VuFind/Search/Factory/ProQuestFSGBackendFactory.php +++ b/module/VuFind/src/VuFind/Search/Factory/ProQuestFSGBackendFactory.php @@ -104,7 +104,6 @@ protected function createBackend(Connector $connector) { $backend = new Backend($connector, $this->createRecordCollectionFactory()); $backend->setLogger($this->logger); - // $backend->setQueryBuilder($this->createQueryBuilder()); return $backend; } @@ -127,17 +126,6 @@ protected function createConnector() return $connector; } - /** - * Create the WorldCat query builder. - * - * @return QueryBuilder - */ - protected function createQueryBuilder() - { - $exclude = $this->config->WorldCat->OCLCCode ?? null; - return new QueryBuilder($exclude); - } - /** * Create the record collection factory * diff --git a/module/VuFind/src/VuFind/Search/ProQuestFSG/Options.php b/module/VuFind/src/VuFind/Search/ProQuestFSG/Options.php index 5906c929bc9..87b8670c260 100644 --- a/module/VuFind/src/VuFind/Search/ProQuestFSG/Options.php +++ b/module/VuFind/src/VuFind/Search/ProQuestFSG/Options.php @@ -58,12 +58,12 @@ public function __construct(\VuFind\Config\PluginManager $configLoader) $searchSettings = $configLoader->get($this->searchIni); // // Search handler setup: - // $this->defaultHandler = 'srw.kw'; - // if (isset($searchSettings->Basic_Searches)) { - // foreach ($searchSettings->Basic_Searches as $key => $value) { - // $this->basicHandlers[$key] = $value; - // } - // } + $this->defaultHandler = 'cql.serverChoice'; + if (isset($searchSettings->Basic_Searches)) { + foreach ($searchSettings->Basic_Searches as $key => $value) { + $this->basicHandlers[$key] = $value; + } + } // if (isset($searchSettings->Advanced_Searches)) { // foreach ($searchSettings->Advanced_Searches as $key => $value) { // $this->advancedHandlers[$key] = $value; diff --git a/module/VuFindSearch/src/VuFindSearch/Backend/ProQuestFSG/QueryBuilder.php b/module/VuFindSearch/src/VuFindSearch/Backend/ProQuestFSG/QueryBuilder.php index 82ab323af05..616cff0e0ac 100644 --- a/module/VuFindSearch/src/VuFindSearch/Backend/ProQuestFSG/QueryBuilder.php +++ b/module/VuFindSearch/src/VuFindSearch/Backend/ProQuestFSG/QueryBuilder.php @@ -179,15 +179,6 @@ protected function queryToString(Query $query) return $query->getString(); } $lookfor = str_replace('"', '', $query->getString()); - - // The index may contain multiple parts -- we want to search all listed index - // fields: - $index = explode(':', $index); - $clauses = []; - foreach ($index as $currentIndex) { - $clauses[] = "{$currentIndex} all \"{$lookfor}\""; - } - - return '(' . implode(' OR ', $clauses) . ')'; + return "({$index} all \"{$lookfor}\")"; } } From e6c1cd19f930781ee274292addcf657a6a5a4796 Mon Sep 17 00:00:00 2001 From: Maccabee Levine Date: Fri, 4 Oct 2024 17:55:23 +0000 Subject: [PATCH 03/34] Implement sorting --- config/vufind/ProQuestFSG.ini | 17 +++++++++++- .../src/VuFind/Search/ProQuestFSG/Options.php | 26 +++++++------------ .../src/VuFind/Search/ProQuestFSG/Params.php | 6 ++--- .../Backend/ProQuestFSG/Connector.php | 4 ++- .../VuFindSearch/Backend/SRU/Connector.php | 2 +- 5 files changed, 32 insertions(+), 23 deletions(-) diff --git a/config/vufind/ProQuestFSG.ini b/config/vufind/ProQuestFSG.ini index 5dcb3dfd517..9cae6b564c5 100644 --- a/config/vufind/ProQuestFSG.ini +++ b/config/vufind/ProQuestFSG.ini @@ -1,3 +1,11 @@ +; This section contains global settings affecting search behavior. +; For ProQuest Federated Search Gateway API documentation: +; https://support.proquest.com/s/article/ProQuest-Academic-Platform-Federated-Search-Options +[General] +; This setting controls the default sort order of search results; the selected +; option should be one of the options present in the [Sorting] section below. +default_sort = relevance + ; This section shows which search types will display in the basic search box at ; the top of Primo pages. The name of each setting below corresponds with an ; index defined in the Primo API. The value of each setting is the text to @@ -5,8 +13,15 @@ ; be sure to update language files if necessary. The order of these settings ; will be maintained in the drop-down list in the UI. [Basic_Searches] -cql.serverChoice = "All Fields" +cql.serverChoice = "All Fields" title = Title author = Author subject = Subject ;abstract = Abstract +; This section defines the sort options available on search results. +[Sorting] +relevance = sort_relevance +date/descending = sort_year +date/ascending = sort_year_asc + +; This section allows you to specify hidden sorting options. They can be used to create a diff --git a/module/VuFind/src/VuFind/Search/ProQuestFSG/Options.php b/module/VuFind/src/VuFind/Search/ProQuestFSG/Options.php index 87b8670c260..14122c4e26a 100644 --- a/module/VuFind/src/VuFind/Search/ProQuestFSG/Options.php +++ b/module/VuFind/src/VuFind/Search/ProQuestFSG/Options.php @@ -70,23 +70,15 @@ public function __construct(\VuFind\Config\PluginManager $configLoader) // } // } - // // Load sort preferences: - // if (isset($searchSettings->Sorting)) { - // foreach ($searchSettings->Sorting as $key => $value) { - // $this->sortOptions[$key] = $value; - // } - // } - // if (isset($searchSettings->General->default_sort)) { - // $this->defaultSort = $searchSettings->General->default_sort; - // } - // if ( - // isset($searchSettings->DefaultSortingByType) - // && count($searchSettings->DefaultSortingByType) > 0 - // ) { - // foreach ($searchSettings->DefaultSortingByType as $key => $val) { - // $this->defaultSortByHandler[$key] = $val; - // } - // } + // Load sort preferences: + if (isset($searchSettings->Sorting)) { + foreach ($searchSettings->Sorting as $key => $value) { + $this->sortOptions[$key] = $value; + } + } + if (isset($searchSettings->General->default_sort)) { + $this->defaultSort = $searchSettings->General->default_sort; + } // // Load list view for result (controls AJAX embedding vs. linking) // if (isset($searchSettings->List->view)) { // $this->listviewOption = $searchSettings->List->view; diff --git a/module/VuFind/src/VuFind/Search/ProQuestFSG/Params.php b/module/VuFind/src/VuFind/Search/ProQuestFSG/Params.php index dc301d469ff..ebc66f5e949 100644 --- a/module/VuFind/src/VuFind/Search/ProQuestFSG/Params.php +++ b/module/VuFind/src/VuFind/Search/ProQuestFSG/Params.php @@ -53,9 +53,9 @@ public function getBackendParameters() { $backendParams = new ParamBag(); - // // Sort - // $sort = $this->getSort(); - // $backendParams->set('sortKeys', empty($sort) ? 'relevance' : $sort); + // Sort + $sort = $this->getSort(); + $backendParams->set('sortKey', empty($sort) ? 'relevance' : $sort); return $backendParams; } diff --git a/module/VuFindSearch/src/VuFindSearch/Backend/ProQuestFSG/Connector.php b/module/VuFindSearch/src/VuFindSearch/Backend/ProQuestFSG/Connector.php index ceb90bb0532..88105075dcd 100644 --- a/module/VuFindSearch/src/VuFindSearch/Backend/ProQuestFSG/Connector.php +++ b/module/VuFindSearch/src/VuFindSearch/Backend/ProQuestFSG/Connector.php @@ -173,7 +173,9 @@ public function search(ParamBag $params, $offset, $limit) $response = $this->sruSearch( $params->get('query')[0], $offset, - $limit, null, 'marcxml', + $limit, + $params->get('sortKey')[0] ?? null, + 'marcxml', true ); diff --git a/module/VuFindSearch/src/VuFindSearch/Backend/SRU/Connector.php b/module/VuFindSearch/src/VuFindSearch/Backend/SRU/Connector.php index 98c39c89bb7..5058fc4b4eb 100644 --- a/module/VuFindSearch/src/VuFindSearch/Backend/SRU/Connector.php +++ b/module/VuFindSearch/src/VuFindSearch/Backend/SRU/Connector.php @@ -173,7 +173,7 @@ public function sruSearch( $options['maximumRecords'] = $limit; } if (null !== $sortBy) { - $options['sortKeys'] = $sortBy; + $options['query'] .= " sortBy {$sortBy}"; } return $this->call('GET', $options, $process); From 300c51f9ef75b0e0e48aa4f3152741662997a2e2 Mon Sep 17 00:00:00 2001 From: Maccabee Levine Date: Fri, 4 Oct 2024 18:13:53 +0000 Subject: [PATCH 04/34] Add search result limits --- config/vufind/ProQuestFSG.ini | 11 +++++++++++ .../VuFind/src/VuFind/Search/ProQuestFSG/Options.php | 10 ++++++++++ 2 files changed, 21 insertions(+) diff --git a/config/vufind/ProQuestFSG.ini b/config/vufind/ProQuestFSG.ini index 9cae6b564c5..f4073576d09 100644 --- a/config/vufind/ProQuestFSG.ini +++ b/config/vufind/ProQuestFSG.ini @@ -5,6 +5,17 @@ ; This setting controls the default sort order of search results; the selected ; option should be one of the options present in the [Sorting] section below. default_sort = relevance +; This section controls the result limit options for search results. default_limit +; sets the default number of results per page. limit_options is a comma-separated +; list of numbers to be presented to the end-user. If only one limit is required, +; set default_limit and leave limit_options commented out. +; WARNING: using large limits may cause problems due to a variety of limitations, +; especially if you support bulk operations (which can cause large URLs/requests). +; If you must support large page sizes, you may need to raise the PHP memory_limit +; and max_input_vars settings and/or adjust the Apache LimitRequestLine setting. +default_limit = 20 +; limit_options = 10,20,40,60,80,100 + ; This section shows which search types will display in the basic search box at ; the top of Primo pages. The name of each setting below corresponds with an diff --git a/module/VuFind/src/VuFind/Search/ProQuestFSG/Options.php b/module/VuFind/src/VuFind/Search/ProQuestFSG/Options.php index 14122c4e26a..c33015dbda1 100644 --- a/module/VuFind/src/VuFind/Search/ProQuestFSG/Options.php +++ b/module/VuFind/src/VuFind/Search/ProQuestFSG/Options.php @@ -44,6 +44,8 @@ */ class Options extends \VuFind\Search\Base\Options { + use \VuFind\Config\Feature\ExplodeSettingTrait; + /** * Constructor * @@ -57,6 +59,14 @@ public function __construct(\VuFind\Config\PluginManager $configLoader) // Load the configuration file: $searchSettings = $configLoader->get($this->searchIni); + // Set up limit preferences + if (isset($searchSettings->General->default_limit)) { + $this->defaultLimit = $searchSettings->General->default_limit; + } + if (isset($searchSettings->General->limit_options)) { + $this->limitOptions = $this->explodeListSetting($searchSettings->General->limit_options); + } + // // Search handler setup: $this->defaultHandler = 'cql.serverChoice'; if (isset($searchSettings->Basic_Searches)) { From df23ce69e41fbb9f8401f1ad4f6a40484c698c2e Mon Sep 17 00:00:00 2001 From: Maccabee Levine Date: Fri, 4 Oct 2024 20:20:48 +0000 Subject: [PATCH 05/34] Display database facets --- config/vufind/ProQuestFSG.ini | 14 ++++++ .../src/VuFind/Search/ProQuestFSG/Options.php | 2 +- .../src/VuFind/Search/ProQuestFSG/Params.php | 5 ++ .../src/VuFind/Search/ProQuestFSG/Results.php | 23 ++++++++- module/VuFind/xsl/sru-convert-simple.xsl | 21 +++----- .../Backend/ProQuestFSG/Connector.php | 49 ++++++++++--------- .../Response/XML/RecordCollection.php | 2 +- 7 files changed, 76 insertions(+), 40 deletions(-) diff --git a/config/vufind/ProQuestFSG.ini b/config/vufind/ProQuestFSG.ini index f4073576d09..cd78ca339a1 100644 --- a/config/vufind/ProQuestFSG.ini +++ b/config/vufind/ProQuestFSG.ini @@ -16,6 +16,19 @@ default_sort = relevance default_limit = 20 ; limit_options = 10,20,40,60,80,100 +; These are the default recommendations modules to use when no specific setting +; are found in the [TopRecommendations], [SideRecommendations] or +; [NoResultsRecommendations] sections below. +; See the comments above those sections for details on legal settings. You may +; repeat these lines to load multiple recommendations. +;default_top_recommend[] = TopFacets:FacetsTop:Primo +default_side_recommend[] = SideFacets:Facets:CheckboxFacets:ProQuestFSG + +; The order of display is as shown below +; The name of the index field is on the left +; The display name of the field is on the right +[Facets] +Databases = "Source" ; This section shows which search types will display in the basic search box at ; the top of Primo pages. The name of each setting below corresponds with an @@ -29,6 +42,7 @@ title = Title author = Author subject = Subject ;abstract = Abstract + ; This section defines the sort options available on search results. [Sorting] relevance = sort_relevance diff --git a/module/VuFind/src/VuFind/Search/ProQuestFSG/Options.php b/module/VuFind/src/VuFind/Search/ProQuestFSG/Options.php index c33015dbda1..a8747662e79 100644 --- a/module/VuFind/src/VuFind/Search/ProQuestFSG/Options.php +++ b/module/VuFind/src/VuFind/Search/ProQuestFSG/Options.php @@ -53,8 +53,8 @@ class Options extends \VuFind\Search\Base\Options */ public function __construct(\VuFind\Config\PluginManager $configLoader) { - parent::__construct($configLoader); $this->searchIni = $this->facetsIni = 'ProQuestFSG'; + parent::__construct($configLoader); // Load the configuration file: $searchSettings = $configLoader->get($this->searchIni); diff --git a/module/VuFind/src/VuFind/Search/ProQuestFSG/Params.php b/module/VuFind/src/VuFind/Search/ProQuestFSG/Params.php index ebc66f5e949..6c81de65d77 100644 --- a/module/VuFind/src/VuFind/Search/ProQuestFSG/Params.php +++ b/module/VuFind/src/VuFind/Search/ProQuestFSG/Params.php @@ -52,11 +52,16 @@ class Params extends \VuFind\Search\Base\Params public function getBackendParameters() { $backendParams = new ParamBag(); + $backendParams->set('operation', 'searchRetrieve'); + $backendParams->set('recordSchema', 'marcxml'); // Sort $sort = $this->getSort(); $backendParams->set('sortKey', empty($sort) ? 'relevance' : $sort); + // Facets + $backendParams->set('x-navigators', 'database'); + return $backendParams; } } diff --git a/module/VuFind/src/VuFind/Search/ProQuestFSG/Results.php b/module/VuFind/src/VuFind/Search/ProQuestFSG/Results.php index 6cb52c6609d..880ea64b3be 100644 --- a/module/VuFind/src/VuFind/Search/ProQuestFSG/Results.php +++ b/module/VuFind/src/VuFind/Search/ProQuestFSG/Results.php @@ -49,6 +49,10 @@ class Results extends \VuFind\Search\Base\Results */ protected $backendId = 'ProQuestFSG'; + protected $responseFacets = null; + + protected $simplifiedResponseFacets = null; + /** * Support method for performAndProcessSearch -- perform a search based on the * parameters passed to the object. @@ -73,6 +77,8 @@ protected function performSearch() $this->resultTotal = $collection->getTotal(); $this->results = $collection->getRecords(); + $this->responseFacets = $collection->getFacets(); + $this->simplifiedResponseFacets = $this->simplifyFacets($this->responseFacets); } /** @@ -85,7 +91,20 @@ protected function performSearch() */ public function getFacetList($filter = null) { - // No facets in WorldCat: - return []; + return $this->buildFacetList($this->simplifiedResponseFacets, $filter); + } + + protected function simplifyFacets($rawFacets) + { + $simpleFacets = []; + foreach ($rawFacets as $label => $rawFacet) { + $simpleFacet = []; + foreach ($rawFacet as $rawFacetValue) { + $simpleFacet[$rawFacetValue['name']] = $rawFacetValue['count']; + } + $simpleFacets[$label] = $simpleFacet; + } + return $simpleFacets; } + } diff --git a/module/VuFind/xsl/sru-convert-simple.xsl b/module/VuFind/xsl/sru-convert-simple.xsl index dd620adca8b..cbbd054f12b 100644 --- a/module/VuFind/xsl/sru-convert-simple.xsl +++ b/module/VuFind/xsl/sru-convert-simple.xsl @@ -8,8 +8,8 @@ - + @@ -21,18 +21,13 @@ - - - - - - - - - - - - + + + + + + + diff --git a/module/VuFindSearch/src/VuFindSearch/Backend/ProQuestFSG/Connector.php b/module/VuFindSearch/src/VuFindSearch/Backend/ProQuestFSG/Connector.php index 88105075dcd..a1e455c1657 100644 --- a/module/VuFindSearch/src/VuFindSearch/Backend/ProQuestFSG/Connector.php +++ b/module/VuFindSearch/src/VuFindSearch/Backend/ProQuestFSG/Connector.php @@ -163,39 +163,42 @@ public function getRecord($id, ParamBag $params = null) */ public function search(ParamBag $params, $offset, $limit) { - // $params->set('startRecord', $offset); - // $params->set('maximumRecords', $limit); - // $params->set('servicelevel', 'full'); - // $params->set('wskey', $this->wskey); - - // $response = $this->call('POST', $params->getArrayCopy(), false); + $options = $params->getArrayCopy(); + $options['startRecord'] = $offset; + if (null !== $limit) { + $options['maximumRecords'] = $limit; + } + $sortKey = $params->get('sortKey')[0] ?? null; + if (null !== $sortKey) { + $options['query'][0] .= " sortBy {$sortKey}"; + unset($options['sortKey']); + } - $response = $this->sruSearch( - $params->get('query')[0], - $offset, - $limit, - $params->get('sortKey')[0] ?? null, - 'marcxml', - true - ); + $response = $this->call('GET', $options, true); - // $xml = simplexml_load_string($response); - // $docs = $xml->records->record ?? []; $finalDocs = []; - // foreach ($docs as $doc) { foreach ($response->record as $doc) { $finalDocs[] = $doc->asXML(); } - // return [ - // 'docs' => $finalDocs, - // 'offset' => $offset, - // 'total' => (int)($xml->numberOfRecords ?? 0), - // ]; - // return $response; + + $databases = []; + foreach (($response->Facets->Databases->Database ?? []) as $database) { + $databases[] = [ + 'id' => strval($database->databaseId), + 'code' => strval($database->databaseCode), + 'name' => strval($database->databaseName), + 'count' => intval($database->numberOfRecords), + ]; + } + $facets = [ + 'Databases' => $databases, + ]; + return [ 'docs' => $finalDocs, 'offset' => $offset, 'total' => (int)($response->RecordCount), + 'facets' => $facets, ]; } } diff --git a/module/VuFindSearch/src/VuFindSearch/Backend/ProQuestFSG/Response/XML/RecordCollection.php b/module/VuFindSearch/src/VuFindSearch/Backend/ProQuestFSG/Response/XML/RecordCollection.php index eded5c3cd3b..4d63b741f11 100644 --- a/module/VuFindSearch/src/VuFindSearch/Backend/ProQuestFSG/Response/XML/RecordCollection.php +++ b/module/VuFindSearch/src/VuFindSearch/Backend/ProQuestFSG/Response/XML/RecordCollection.php @@ -82,6 +82,6 @@ public function getTotal() */ public function getFacets() { - return []; // not supported by WorldCat + return $this->response['facets']; } } From 0fb4406f922546a4087d3b870165b243edc8bd55 Mon Sep 17 00:00:00 2001 From: Maccabee Levine Date: Mon, 7 Oct 2024 14:03:20 +0000 Subject: [PATCH 06/34] Apply database filter --- .../src/VuFind/Search/ProQuestFSG/Options.php | 2 + .../src/VuFind/Search/ProQuestFSG/Params.php | 41 +++++++++++++++++++ .../src/VuFind/Search/ProQuestFSG/Results.php | 3 +- .../Backend/ProQuestFSG/Connector.php | 19 ++++++++- .../VuFindSearch/Backend/SRU/Connector.php | 6 ++- 5 files changed, 66 insertions(+), 5 deletions(-) diff --git a/module/VuFind/src/VuFind/Search/ProQuestFSG/Options.php b/module/VuFind/src/VuFind/Search/ProQuestFSG/Options.php index a8747662e79..84a56fc8b8a 100644 --- a/module/VuFind/src/VuFind/Search/ProQuestFSG/Options.php +++ b/module/VuFind/src/VuFind/Search/ProQuestFSG/Options.php @@ -46,6 +46,8 @@ class Options extends \VuFind\Search\Base\Options { use \VuFind\Config\Feature\ExplodeSettingTrait; + // protected $defaultFacetDelimiter = '|'; + /** * Constructor * diff --git a/module/VuFind/src/VuFind/Search/ProQuestFSG/Params.php b/module/VuFind/src/VuFind/Search/ProQuestFSG/Params.php index 6c81de65d77..06cf314e2c3 100644 --- a/module/VuFind/src/VuFind/Search/ProQuestFSG/Params.php +++ b/module/VuFind/src/VuFind/Search/ProQuestFSG/Params.php @@ -62,6 +62,47 @@ public function getBackendParameters() // Facets $backendParams->set('x-navigators', 'database'); + $filterList = $this->getFilterList(); + if (!empty($filterList)) { + // Loop through all filters and add appropriate values to request: + foreach ($filterList as $filterArray) { + foreach ($filterArray as $filt) { + // $fq = $filt['field'] + // . ($this->filterRequiresFacetOperator($filt['field']) ? + // ":{$this->getFacetOperator($filt['field'], $filt['operator'])}" : '') + // . ":{$filt['value']}"; + // $params->add('filters', $fq); + $value = explode('|', $filt['value'])[0]; + $backendParams->add('filters', $filt['field'] . ':' . $value); + } + } + } + + return $backendParams; } + + /** + * Get a display text for a facet field. + * + * @param string $field Facet field + * @param string $value Facet value + * + * @return string + */ + public function getFacetValueRawDisplayText(string $field, string $value): string + { + $parts = explode('|', $value); + return end($parts); + // // Check for delimited facets -- if $field is a delimited facet field, + // // process $displayText accordingly: + // $delimitedFacetFields = $this->getOptions()->getDelimitedFacets(true); + // if (isset($delimitedFacetFields[$field])) { + // $parts = explode($delimitedFacetFields[$field], $value); + // return end($parts); + // } + + // return $value; + } + } diff --git a/module/VuFind/src/VuFind/Search/ProQuestFSG/Results.php b/module/VuFind/src/VuFind/Search/ProQuestFSG/Results.php index 880ea64b3be..275ad7ccdef 100644 --- a/module/VuFind/src/VuFind/Search/ProQuestFSG/Results.php +++ b/module/VuFind/src/VuFind/Search/ProQuestFSG/Results.php @@ -100,7 +100,8 @@ protected function simplifyFacets($rawFacets) foreach ($rawFacets as $label => $rawFacet) { $simpleFacet = []; foreach ($rawFacet as $rawFacetValue) { - $simpleFacet[$rawFacetValue['name']] = $rawFacetValue['count']; + $facetName = "{$rawFacetValue['code']}|{$rawFacetValue['name']}"; + $simpleFacet[$facetName] = $rawFacetValue['count']; } $simpleFacets[$label] = $simpleFacet; } diff --git a/module/VuFindSearch/src/VuFindSearch/Backend/ProQuestFSG/Connector.php b/module/VuFindSearch/src/VuFindSearch/Backend/ProQuestFSG/Connector.php index a1e455c1657..843ee75d7e8 100644 --- a/module/VuFindSearch/src/VuFindSearch/Backend/ProQuestFSG/Connector.php +++ b/module/VuFindSearch/src/VuFindSearch/Backend/ProQuestFSG/Connector.php @@ -64,6 +64,9 @@ class Connector extends \VuFindSearch\Backend\SRU\Connector */ protected $sruVersion = '1.2'; + protected $defaultPath = '/all_subscribed'; + + /** * Constructor * @@ -77,7 +80,7 @@ public function __construct( array $options = [] ) { parent::__construct( - 'https://fedsearch.proquest.com/search/sru' . '/all_subscribed', + 'https://fedsearch.proquest.com/search/sru', $client ); // $this->wskey = $wsKey; @@ -168,13 +171,25 @@ public function search(ParamBag $params, $offset, $limit) if (null !== $limit) { $options['maximumRecords'] = $limit; } + + $path = $this->defaultPath; + foreach (($options['filters'] ?? []) as $filter) { + [$filterKey, $filterValue] = explode(':', $filter, 2); + if ('Databases' == $filterKey) { + $path = '/' . $filterValue; + } + else { + // TODO normal filters that actually use filter strings on the query. + } + } + $sortKey = $params->get('sortKey')[0] ?? null; if (null !== $sortKey) { $options['query'][0] .= " sortBy {$sortKey}"; unset($options['sortKey']); } - $response = $this->call('GET', $options, true); + $response = $this->call('GET', $path, $options, true); $finalDocs = []; foreach ($response->record as $doc) { diff --git a/module/VuFindSearch/src/VuFindSearch/Backend/SRU/Connector.php b/module/VuFindSearch/src/VuFindSearch/Backend/SRU/Connector.php index 5058fc4b4eb..c19fd15e3f1 100644 --- a/module/VuFindSearch/src/VuFindSearch/Backend/SRU/Connector.php +++ b/module/VuFindSearch/src/VuFindSearch/Backend/SRU/Connector.php @@ -70,6 +70,8 @@ class Connector implements \Laminas\Log\LoggerAwareInterface */ protected $host; + protected $defaultPath = ''; + /** * The version to specify in the URL * @@ -203,7 +205,7 @@ public function checkForHttpError($result) * * @return string|SimpleXMLElement The response from the XServer */ - protected function call($method = 'GET', $params = null, $process = true) + protected function call($method = 'GET', $path = '', $params = null, $process = true) { $queryString = ''; if ($params) { @@ -222,7 +224,7 @@ protected function call($method = 'GET', $params = null, $process = true) $queryString = implode('&', $query); } - $url = $this->host . '?' . $queryString; + $url = $this->host . $path . '?' . $queryString; $this->debug('Connect: ' . $url); // Send Request From 0f3021c672f0011b2328f0986c4620cbd4b118ed Mon Sep 17 00:00:00 2001 From: Maccabee Levine Date: Mon, 7 Oct 2024 14:22:25 +0000 Subject: [PATCH 07/34] Support checkbox filters --- config/vufind/ProQuestFSG.ini | 9 +++++++++ .../src/VuFindSearch/Backend/ProQuestFSG/Connector.php | 7 ++++++- 2 files changed, 15 insertions(+), 1 deletion(-) diff --git a/config/vufind/ProQuestFSG.ini b/config/vufind/ProQuestFSG.ini index cd78ca339a1..65589e77730 100644 --- a/config/vufind/ProQuestFSG.ini +++ b/config/vufind/ProQuestFSG.ini @@ -30,6 +30,15 @@ default_side_recommend[] = SideFacets:Facets:CheckboxFacets:ProQuestFSG [Facets] Databases = "Source" +; Checkbox facets are facets, which are getting displayed as checkboxes +; pcAvailability is a special facet. It's used to show all records found in +; PrimoCentral without checking the local availability against a holdingsfile. +[CheckboxFacets] +limitFullText = "fulltext_limit" +limitScholarlyJournals = "scholarly_limit" +limitPeerReviewed = "peer_reviewed_limit" + + ; This section shows which search types will display in the basic search box at ; the top of Primo pages. The name of each setting below corresponds with an ; index defined in the Primo API. The value of each setting is the text to diff --git a/module/VuFindSearch/src/VuFindSearch/Backend/ProQuestFSG/Connector.php b/module/VuFindSearch/src/VuFindSearch/Backend/ProQuestFSG/Connector.php index 843ee75d7e8..386c6e4c4af 100644 --- a/module/VuFindSearch/src/VuFindSearch/Backend/ProQuestFSG/Connector.php +++ b/module/VuFindSearch/src/VuFindSearch/Backend/ProQuestFSG/Connector.php @@ -179,9 +179,14 @@ public function search(ParamBag $params, $offset, $limit) $path = '/' . $filterValue; } else { - // TODO normal filters that actually use filter strings on the query. + $filterRelationValue = $filterValue ? + '=' . $filterValue : + '=1'; + $filterString = " and ({$filterKey}{$filterRelationValue})"; + $options['query'][0] .= $filterString; } } + unset($options['filters']); $sortKey = $params->get('sortKey')[0] ?? null; if (null !== $sortKey) { From ebab9827aeb18929d7924d79f1f4568b84ffe5dc Mon Sep 17 00:00:00 2001 From: Maccabee Levine Date: Mon, 7 Oct 2024 14:45:37 +0000 Subject: [PATCH 08/34] Add OOTB facet settings --- config/vufind/ProQuestFSG.ini | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/config/vufind/ProQuestFSG.ini b/config/vufind/ProQuestFSG.ini index 65589e77730..915da01258d 100644 --- a/config/vufind/ProQuestFSG.ini +++ b/config/vufind/ProQuestFSG.ini @@ -38,6 +38,16 @@ limitFullText = "fulltext_limit" limitScholarlyJournals = "scholarly_limit" limitPeerReviewed = "peer_reviewed_limit" +; Facet display settings +[Results_Settings] +; By default, the side facets will only show 6 facets and then the "show more" +; button. This can get configured with the showMore settings. +; You can use the * to set a new default setting. +showMore[*] = 6 +; Or you can set a facet specific value by using the facet name as index. +;showMore['rtype'] = 10 +; Do we want any facets to be collapsed by default? +;collapsedFacets = * ; This section shows which search types will display in the basic search box at ; the top of Primo pages. The name of each setting below corresponds with an From 8305dd5ccce6ac236cd0a3706041ed25bfe3d998 Mon Sep 17 00:00:00 2001 From: Maccabee Levine Date: Mon, 7 Oct 2024 18:53:27 +0000 Subject: [PATCH 09/34] Add SearchCache support --- config/vufind/ProQuestFSG.ini | 14 +++++++++++ .../Factory/ProQuestFSGBackendFactory.php | 17 +++++++------ .../VuFindSearch/Backend/SRU/Connector.php | 24 ++++++++++++++++--- 3 files changed, 45 insertions(+), 10 deletions(-) diff --git a/config/vufind/ProQuestFSG.ini b/config/vufind/ProQuestFSG.ini index 915da01258d..4e31882e849 100644 --- a/config/vufind/ProQuestFSG.ini +++ b/config/vufind/ProQuestFSG.ini @@ -69,3 +69,17 @@ date/descending = sort_year date/ascending = sort_year_asc ; This section allows you to specify hidden sorting options. They can be used to create a + +; This section provides settings for optional caching of search requests. +[SearchCache] +; Supported adapters: Memcached, Filesystem. Others may also work, but have not been +; tested. +;adapter = Memcached +; Comma-separated list of servers for Memcached adapter: +;options[servers] = "localhost:11211" +; Cache directory for Filesystem adapter: +;options[cache_dir] = "/tmp/search-cache" +; Other options. See https://docs.laminas.dev/laminas-cache/storage/adapter/ for +; documentation on options for different adapters. +; ttl, Time to Live, i.e. cache entry life time in seconds. 300 seconds by default. +;options[ttl] = 300 diff --git a/module/VuFind/src/VuFind/Search/Factory/ProQuestFSGBackendFactory.php b/module/VuFind/src/VuFind/Search/Factory/ProQuestFSGBackendFactory.php index 8f7a3eaf4be..792f4c38da5 100644 --- a/module/VuFind/src/VuFind/Search/Factory/ProQuestFSGBackendFactory.php +++ b/module/VuFind/src/VuFind/Search/Factory/ProQuestFSGBackendFactory.php @@ -62,12 +62,12 @@ class ProQuestFSGBackendFactory extends AbstractBackendFactory */ protected $config; - // /** - // * WorldCat configuration - // * - // * @var \Laminas\Config\Config - // */ - // protected $wcConfig; + /** + * ProQuestFSG configuration + * + * @var \Laminas\Config\Config + */ + protected $proQuestFSGConfig; /** * Create service @@ -84,7 +84,7 @@ public function __invoke(ContainerInterface $sm, $name, array $options = null) { $this->setup($sm); $this->config = $this->getService(\VuFind\Config\PluginManager::class)->get('config'); - // $this->wcConfig = $this->getService(\VuFind\Config\PluginManager::class)->get('WorldCat'); + $this->proQuestFSGConfig = $this->getService(\VuFind\Config\PluginManager::class)->get('ProQuestFSG'); if ($this->serviceLocator->has(\VuFind\Log\Logger::class)) { $this->logger = $this->getService(\VuFind\Log\Logger::class); } @@ -123,6 +123,9 @@ protected function createConnector() // $connectorOptions ); $connector->setLogger($this->logger); + if ($cache = $this->createConnectorCache($this->proQuestFSGConfig)) { + $connector->setCache($cache); + } return $connector; } diff --git a/module/VuFindSearch/src/VuFindSearch/Backend/SRU/Connector.php b/module/VuFindSearch/src/VuFindSearch/Backend/SRU/Connector.php index c19fd15e3f1..99dbd4adc03 100644 --- a/module/VuFindSearch/src/VuFindSearch/Backend/SRU/Connector.php +++ b/module/VuFindSearch/src/VuFindSearch/Backend/SRU/Connector.php @@ -48,6 +48,7 @@ class Connector implements \Laminas\Log\LoggerAwareInterface { use \VuFind\Log\LoggerAwareTrait; + use \VuFindSearch\Backend\Feature\ConnectorCacheTrait; /** * Whether to Serialize to a PHP Array or not. @@ -230,11 +231,28 @@ protected function call($method = 'GET', $path = '', $params = null, $process = // Send Request $this->client->resetParameters(); $this->client->setUri($url); - $result = $this->client->setMethod($method)->send(); - $this->checkForHttpError($result); + + // Check cache: + $cacheKey = null; + if ($this->cache) { + $cacheKey = $this->getCacheKey($this->client); + $resultBody = $this->getCachedData($cacheKey); + } + + if (!$resultBody) { + $result = $this->client->setMethod($method)->send(); + $this->checkForHttpError($result); + $resultBody = $result->getBody(); + if ($cacheKey) { + $this->putCachedData($cacheKey, $resultBody); + } + } // Return processed or unprocessed response, as appropriate: - return $process ? $this->process($result->getBody()) : $result->getBody(); + if ($process) { + $resultBody = $this->process($resultBody); + } + return $resultBody; } /** From a23fefc710ffb3f55b7c67ec8c97db482b6a4ea2 Mon Sep 17 00:00:00 2001 From: Maccabee Levine Date: Mon, 7 Oct 2024 19:45:42 +0000 Subject: [PATCH 10/34] Fix NPE --- module/VuFindSearch/src/VuFindSearch/Backend/SRU/Connector.php | 1 + 1 file changed, 1 insertion(+) diff --git a/module/VuFindSearch/src/VuFindSearch/Backend/SRU/Connector.php b/module/VuFindSearch/src/VuFindSearch/Backend/SRU/Connector.php index 99dbd4adc03..c4a1473f9b7 100644 --- a/module/VuFindSearch/src/VuFindSearch/Backend/SRU/Connector.php +++ b/module/VuFindSearch/src/VuFindSearch/Backend/SRU/Connector.php @@ -234,6 +234,7 @@ protected function call($method = 'GET', $path = '', $params = null, $process = // Check cache: $cacheKey = null; + $resultBody = null; if ($this->cache) { $cacheKey = $this->getCacheKey($this->client); $resultBody = $this->getCachedData($cacheKey); From d77a08df47609ba873c6077757ac0f683d5f79ee Mon Sep 17 00:00:00 2001 From: Maccabee Levine Date: Mon, 7 Oct 2024 19:46:03 +0000 Subject: [PATCH 11/34] Fix single record load --- .../ProQuestFSGrecordController.php | 25 +++++++++++++++++++ .../Backend/ProQuestFSG/Connector.php | 2 +- 2 files changed, 26 insertions(+), 1 deletion(-) diff --git a/module/VuFind/src/VuFind/Controller/ProQuestFSGrecordController.php b/module/VuFind/src/VuFind/Controller/ProQuestFSGrecordController.php index b901747fea0..e3a21d6b3f1 100644 --- a/module/VuFind/src/VuFind/Controller/ProQuestFSGrecordController.php +++ b/module/VuFind/src/VuFind/Controller/ProQuestFSGrecordController.php @@ -31,6 +31,7 @@ namespace VuFind\Controller; use Laminas\ServiceManager\ServiceLocatorInterface; +use VuFindSearch\ParamBag; /** * ProQuest Federated Search Gateway Record Controller @@ -58,6 +59,30 @@ public function __construct(ServiceLocatorInterface $sm) parent::__construct($sm); } + /** + * Load the record requested by the user; note that this is not done in the + * init() method since we don't want to perform an expensive search twice + * when homeAction() forwards to another method. + * + * @param ParamBag $params Search backend parameters + * @param bool $force Set to true to force a reload of the record, even if + * already loaded (useful if loading a record using different parameters) + * + * @return AbstractRecordDriver + */ + protected function loadRecord(ParamBag $params = null, bool $force = false) + { + if (null === $params) { + $params = new ParamBag(); + } + + $paramsService = $this->serviceLocator->get(\VuFind\Search\Params\PluginManager::class) + ->get('VuFind\Search\ProQuestFSG\Params'); + $params->mergeWith($paramsService->getBackendParameters()); + + return parent::loadRecord($params, $force); + } + /** * Is the result scroller active? * diff --git a/module/VuFindSearch/src/VuFindSearch/Backend/ProQuestFSG/Connector.php b/module/VuFindSearch/src/VuFindSearch/Backend/ProQuestFSG/Connector.php index 386c6e4c4af..75180ee902d 100644 --- a/module/VuFindSearch/src/VuFindSearch/Backend/ProQuestFSG/Connector.php +++ b/module/VuFindSearch/src/VuFindSearch/Backend/ProQuestFSG/Connector.php @@ -152,7 +152,7 @@ public function getRecord($id, ParamBag $params = null) // ]; $params->set('query', "rec.identifier = \"{$id}\""); - return $this->search($params, 0, 1); + return $this->search($params, 1, 1); } /** From fc896322934aafb31d4d732035729c4e81cbe02c Mon Sep 17 00:00:00 2001 From: Maccabee Levine Date: Tue, 8 Oct 2024 14:23:33 +0000 Subject: [PATCH 12/34] Add next_prev_navigation --- config/vufind/ProQuestFSG.ini | 6 ++++++ .../src/VuFind/Controller/ProQuestFSGController.php | 10 +++++----- .../VuFind/Controller/ProQuestFSGrecordController.php | 10 +++++----- 3 files changed, 16 insertions(+), 10 deletions(-) diff --git a/config/vufind/ProQuestFSG.ini b/config/vufind/ProQuestFSG.ini index 4e31882e849..0053c49c241 100644 --- a/config/vufind/ProQuestFSG.ini +++ b/config/vufind/ProQuestFSG.ini @@ -70,6 +70,12 @@ date/ascending = sort_year_asc ; This section allows you to specify hidden sorting options. They can be used to create a +; This section controls the behavior of the EDSRecord module. +[Record] +; Set this to true in order to enable "next" and "previous" links to navigate +; through the current result set from within the record view. +next_prev_navigation = false + ; This section provides settings for optional caching of search requests. [SearchCache] ; Supported adapters: Memcached, Filesystem. Others may also work, but have not been diff --git a/module/VuFind/src/VuFind/Controller/ProQuestFSGController.php b/module/VuFind/src/VuFind/Controller/ProQuestFSGController.php index 437d43cb3fc..4a0d4db5eb2 100644 --- a/module/VuFind/src/VuFind/Controller/ProQuestFSGController.php +++ b/module/VuFind/src/VuFind/Controller/ProQuestFSGController.php @@ -60,9 +60,9 @@ public function __construct(ServiceLocatorInterface $sm) * * @return bool */ - // protected function resultScrollerActive() - // { - // $config = $this->getService(\VuFind\Config\PluginManager::class)->get('LibGuidesAZ'); - // return $config->Record->next_prev_navigation ?? false; - // } + protected function resultScrollerActive() + { + $config = $this->getService(\VuFind\Config\PluginManager::class)->get('ProQuestFSG'); + return $config->Record->next_prev_navigation ?? false; + } } diff --git a/module/VuFind/src/VuFind/Controller/ProQuestFSGrecordController.php b/module/VuFind/src/VuFind/Controller/ProQuestFSGrecordController.php index e3a21d6b3f1..2fd79c34f41 100644 --- a/module/VuFind/src/VuFind/Controller/ProQuestFSGrecordController.php +++ b/module/VuFind/src/VuFind/Controller/ProQuestFSGrecordController.php @@ -88,9 +88,9 @@ protected function loadRecord(ParamBag $params = null, bool $force = false) * * @return bool */ - // protected function resultScrollerActive() - // { - // $config = $this->getService(\VuFind\Config\PluginManager::class)->get('ProQuestFSG'); - // return $config->Record->next_prev_navigation ?? false; - // } + protected function resultScrollerActive() + { + $config = $this->getService(\VuFind\Config\PluginManager::class)->get('ProQuestFSG'); + return $config->Record->next_prev_navigation ?? false; + } } From 5d5b9d0920dc72d5ed77402d3b37f7038c476e46 Mon Sep 17 00:00:00 2001 From: Maccabee Levine Date: Tue, 8 Oct 2024 14:24:14 +0000 Subject: [PATCH 13/34] Fix copy/paste typo --- config/vufind/ProQuestFSG.ini | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/config/vufind/ProQuestFSG.ini b/config/vufind/ProQuestFSG.ini index 0053c49c241..e74665377aa 100644 --- a/config/vufind/ProQuestFSG.ini +++ b/config/vufind/ProQuestFSG.ini @@ -70,7 +70,7 @@ date/ascending = sort_year_asc ; This section allows you to specify hidden sorting options. They can be used to create a -; This section controls the behavior of the EDSRecord module. +; This section controls the behavior of the ProQuestFSGRecord module. [Record] ; Set this to true in order to enable "next" and "previous" links to navigate ; through the current result set from within the record view. From 896ba946091011c6352ed276a4720fe3bd2a0ed2 Mon Sep 17 00:00:00 2001 From: Maccabee Levine Date: Tue, 8 Oct 2024 14:37:57 +0000 Subject: [PATCH 14/34] Remove dead code --- .../src/VuFind/RecordDriver/ProQuestFSG.php | 10 --- .../Factory/ProQuestFSGBackendFactory.php | 9 +-- .../src/VuFind/Search/ProQuestFSG/Options.php | 6 +- .../src/VuFind/Search/ProQuestFSG/Params.php | 14 ---- .../Backend/ProQuestFSG/Backend.php | 35 --------- .../Backend/ProQuestFSG/Connector.php | 75 ++----------------- .../Backend/ProQuestFSG/QueryBuilder.php | 15 ---- .../VuFindSearch/Backend/SRU/Connector.php | 1 - .../VuFindSearch/Backend/Solr/Connector.php | 3 +- 9 files changed, 12 insertions(+), 156 deletions(-) diff --git a/module/VuFind/src/VuFind/RecordDriver/ProQuestFSG.php b/module/VuFind/src/VuFind/RecordDriver/ProQuestFSG.php index 8575115c08d..0ae74e4536c 100644 --- a/module/VuFind/src/VuFind/RecordDriver/ProQuestFSG.php +++ b/module/VuFind/src/VuFind/RecordDriver/ProQuestFSG.php @@ -72,14 +72,4 @@ public function setRawData($data) // record driver can understand. parent::setRawData(['fullrecord' => $data]); } - - // /** - // * Get the OCLC number of the record. - // * - // * @return array - // */ - // public function getOCLC() - // { - // return [$this->getUniqueID()]; - // } } diff --git a/module/VuFind/src/VuFind/Search/Factory/ProQuestFSGBackendFactory.php b/module/VuFind/src/VuFind/Search/Factory/ProQuestFSGBackendFactory.php index 792f4c38da5..f31032b5c0b 100644 --- a/module/VuFind/src/VuFind/Search/Factory/ProQuestFSGBackendFactory.php +++ b/module/VuFind/src/VuFind/Search/Factory/ProQuestFSGBackendFactory.php @@ -33,7 +33,6 @@ use Psr\Container\ContainerInterface; use VuFindSearch\Backend\ProQuestFSG\Backend; use VuFindSearch\Backend\ProQuestFSG\Connector; -use VuFindSearch\Backend\ProQuestFSG\QueryBuilder; use VuFindSearch\Backend\ProQuestFSG\Response\XML\RecordCollectionFactory; /** @@ -114,13 +113,11 @@ protected function createBackend(Connector $connector) */ protected function createConnector() { - // $wsKey = $this->config->WorldCat->apiKey ?? null; - // $connectorOptions = isset($this->wcConfig->Connector) - // ? $this->wcConfig->Connector->toArray() : []; + $connectorOptions = isset($this->wcConfig->Connector) + ? $this->proQuestFSGConfig->Connector->toArray() : []; $connector = new Connector( - // $wsKey, $this->createHttpClient(), - // $connectorOptions + $connectorOptions ); $connector->setLogger($this->logger); if ($cache = $this->createConnectorCache($this->proQuestFSGConfig)) { diff --git a/module/VuFind/src/VuFind/Search/ProQuestFSG/Options.php b/module/VuFind/src/VuFind/Search/ProQuestFSG/Options.php index 84a56fc8b8a..4a3c8b0a69e 100644 --- a/module/VuFind/src/VuFind/Search/ProQuestFSG/Options.php +++ b/module/VuFind/src/VuFind/Search/ProQuestFSG/Options.php @@ -30,8 +30,6 @@ namespace VuFind\Search\ProQuestFSG; -use function count; - /** * ProQuest Federated Search Gateway Search Options * @@ -46,8 +44,6 @@ class Options extends \VuFind\Search\Base\Options { use \VuFind\Config\Feature\ExplodeSettingTrait; - // protected $defaultFacetDelimiter = '|'; - /** * Constructor * @@ -115,7 +111,7 @@ public function getSearchAction() */ public function getAdvancedSearchAction() { - // return 'worldcat-advanced'; + // return 'proquestfsg-advanced'; return false; } } diff --git a/module/VuFind/src/VuFind/Search/ProQuestFSG/Params.php b/module/VuFind/src/VuFind/Search/ProQuestFSG/Params.php index 06cf314e2c3..09dfe8399f3 100644 --- a/module/VuFind/src/VuFind/Search/ProQuestFSG/Params.php +++ b/module/VuFind/src/VuFind/Search/ProQuestFSG/Params.php @@ -67,11 +67,6 @@ public function getBackendParameters() // Loop through all filters and add appropriate values to request: foreach ($filterList as $filterArray) { foreach ($filterArray as $filt) { - // $fq = $filt['field'] - // . ($this->filterRequiresFacetOperator($filt['field']) ? - // ":{$this->getFacetOperator($filt['field'], $filt['operator'])}" : '') - // . ":{$filt['value']}"; - // $params->add('filters', $fq); $value = explode('|', $filt['value'])[0]; $backendParams->add('filters', $filt['field'] . ':' . $value); } @@ -94,15 +89,6 @@ public function getFacetValueRawDisplayText(string $field, string $value): strin { $parts = explode('|', $value); return end($parts); - // // Check for delimited facets -- if $field is a delimited facet field, - // // process $displayText accordingly: - // $delimitedFacetFields = $this->getOptions()->getDelimitedFacets(true); - // if (isset($delimitedFacetFields[$field])) { - // $parts = explode($delimitedFacetFields[$field], $value); - // return end($parts); - // } - - // return $value; } } diff --git a/module/VuFindSearch/src/VuFindSearch/Backend/ProQuestFSG/Backend.php b/module/VuFindSearch/src/VuFindSearch/Backend/ProQuestFSG/Backend.php index 897ed4aa2d4..445083d883c 100644 --- a/module/VuFindSearch/src/VuFindSearch/Backend/ProQuestFSG/Backend.php +++ b/module/VuFindSearch/src/VuFindSearch/Backend/ProQuestFSG/Backend.php @@ -124,18 +124,6 @@ public function retrieve($id, ParamBag $params = null) return $collection; } - /** - * Set the query builder. - * - * @param QueryBuilder $queryBuilder Query builder - * - * @return void - */ - // public function setQueryBuilder(QueryBuilder $queryBuilder) - // { - // $this->queryBuilder = $queryBuilder; - // } - /** * Return query builder. * @@ -166,29 +154,6 @@ public function getRecordCollectionFactory() return $this->collectionFactory; } - /** - * Get holdings information for the specified record. - * - * @param string $id Record to obtain holdings for. - * - * @throws \Exception - * @return \SimpleXMLElement - */ - // public function getHoldings($id) - // { - // return $this->getConnector()->getHoldings($id); - // } - - /** - * Return the WorldCat connector. - * - * @return Connector - */ - // public function getConnector() - // { - // return $this->connector; - // } - /// Internal API /** diff --git a/module/VuFindSearch/src/VuFindSearch/Backend/ProQuestFSG/Connector.php b/module/VuFindSearch/src/VuFindSearch/Backend/ProQuestFSG/Connector.php index 75180ee902d..e183520ceca 100644 --- a/module/VuFindSearch/src/VuFindSearch/Backend/ProQuestFSG/Connector.php +++ b/module/VuFindSearch/src/VuFindSearch/Backend/ProQuestFSG/Connector.php @@ -43,19 +43,12 @@ */ class Connector extends \VuFindSearch\Backend\SRU\Connector { - // /** - // * OCLC API key - // * - // * @var string - // */ - // protected $wskey; - - // /** - // * Additional options - // * - // * @var array - // */ - // protected $options; + /** + * Additional options + * + * @var array + */ + protected $options; /** * The version to specify in the URL @@ -83,40 +76,9 @@ public function __construct( 'https://fedsearch.proquest.com/search/sru', $client ); - // $this->wskey = $wsKey; - // $this->options = $options; + $this->options = $options; } - // /** - // * Get holdings information for the specified record. - // * - // * @param string $id Record to obtain holdings for. - // * - // * @throws \Exception - // * @return \SimpleXMLElement - // */ - // public function getHoldings($id) - // { - // $this->client->resetParameters(); - // if (!isset($this->options['useFrbrGroupingForHoldings'])) { - // $grouping = 'on'; // default to "on" for backward compatibility - // } else { - // $grouping = $this->options['useFrbrGroupingForHoldings'] ? 'on' : 'off'; - // } - // $uri = "http://www.worldcat.org/webservices/catalog/content/libraries/{$id}" - // . "?wskey={$this->wskey}&servicelevel=full&frbrGrouping=$grouping"; - // if (isset($this->options['latLon'])) { - // [$lat, $lon] = explode(',', $this->options['latLon']); - // $uri .= '&lat=' . urlencode($lat) . '&lon=' . urlencode($lon); - // } - // $this->client->setUri($uri); - // $this->debug('Connect: ' . $uri); - // $result = $this->client->setMethod('POST')->send(); - // $this->checkForHttpError($result); - - // return simplexml_load_string($result->getBody()); - // } - /** * Retrieve a specific record. * @@ -128,29 +90,6 @@ public function __construct( */ public function getRecord($id, ParamBag $params = null) { - // $params = $params ?: new ParamBag(); - // $params->set('servicelevel', 'full'); - // $params->set('wskey', $this->wskey); - - // $this->client->resetParameters(); - // $uri = 'http://www.worldcat.org/webservices/catalog/content/' . $id; - // $uri .= '?' . implode('&', $params->request()); - // $this->client->setUri($uri); - // $this->debug('Connect: ' . $uri); - // $result = $this->client->setMethod('POST')->send(); - // $this->checkForHttpError($result); - - // // Check for error message in response: - // $body = $result->getBody(); - // $xml = simplexml_load_string($body); - // $error = isset($xml->diagnostic); - - // return [ - // 'docs' => $error ? [] : [$body], - // 'offset' => 0, - // 'total' => $error ? 0 : 1, - // ]; - $params->set('query', "rec.identifier = \"{$id}\""); return $this->search($params, 1, 1); } diff --git a/module/VuFindSearch/src/VuFindSearch/Backend/ProQuestFSG/QueryBuilder.php b/module/VuFindSearch/src/VuFindSearch/Backend/ProQuestFSG/QueryBuilder.php index 616cff0e0ac..918550dd1c5 100644 --- a/module/VuFindSearch/src/VuFindSearch/Backend/ProQuestFSG/QueryBuilder.php +++ b/module/VuFindSearch/src/VuFindSearch/Backend/ProQuestFSG/QueryBuilder.php @@ -62,16 +62,6 @@ class QueryBuilder /// Public API - // /** - // * Constructor - // * - // * @param string $exclude OCLC code to exclude from results - // */ - // public function __construct($exclude = null) - // { - // $this->oclcCodeToExclude = $exclude; - // } - /** * Return WorldCat search parameters based on a user query and params. * @@ -87,11 +77,6 @@ public function build(AbstractQuery $query, ?ParamBag $params = null) // Build base query $queryStr = $this->abstractQueryToString($query); - // // Exclude current library from results (if applicable) - // if (null !== $this->oclcCodeToExclude) { - // $queryStr .= ' not srw.li all "' . $this->oclcCodeToExclude . '"'; - // } - // Send back results $newParams = new ParamBag(); $newParams->set('query', $queryStr); diff --git a/module/VuFindSearch/src/VuFindSearch/Backend/SRU/Connector.php b/module/VuFindSearch/src/VuFindSearch/Backend/SRU/Connector.php index c4a1473f9b7..219bb93dc7a 100644 --- a/module/VuFindSearch/src/VuFindSearch/Backend/SRU/Connector.php +++ b/module/VuFindSearch/src/VuFindSearch/Backend/SRU/Connector.php @@ -267,7 +267,6 @@ protected function call($method = 'GET', $path = '', $params = null, $process = protected function process($response) { // Send back either the raw XML or a SimpleXML object, as requested: - // $result = XSLTProcessor::process('sru-convert.xsl', $response); $result = XSLTProcessor::process('sru-convert-simple.xsl', $response); if (!$result) { throw new BackendException( diff --git a/module/VuFindSearch/src/VuFindSearch/Backend/Solr/Connector.php b/module/VuFindSearch/src/VuFindSearch/Backend/Solr/Connector.php index 3dac06c8764..5a33b7c878a 100644 --- a/module/VuFindSearch/src/VuFindSearch/Backend/Solr/Connector.php +++ b/module/VuFindSearch/src/VuFindSearch/Backend/Solr/Connector.php @@ -242,8 +242,7 @@ public function search(ParamBag $params) { $handler = $this->map->getHandler(__FUNCTION__); $this->map->prepare(__FUNCTION__, $params); - $foo = $this->query($handler, $params, true); - return $foo; + return $this->query($handler, $params, true); } /** From 6ffeaa3c316510e476995ccf990d31bd80806048 Mon Sep 17 00:00:00 2001 From: Maccabee Levine Date: Tue, 8 Oct 2024 14:43:12 +0000 Subject: [PATCH 15/34] Add retain/reset filters configs that work OOTB --- config/vufind/ProQuestFSG.ini | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/config/vufind/ProQuestFSG.ini b/config/vufind/ProQuestFSG.ini index e74665377aa..8024bb4092a 100644 --- a/config/vufind/ProQuestFSG.ini +++ b/config/vufind/ProQuestFSG.ini @@ -23,6 +23,19 @@ default_limit = 20 ; repeat these lines to load multiple recommendations. ;default_top_recommend[] = TopFacets:FacetsTop:Primo default_side_recommend[] = SideFacets:Facets:CheckboxFacets:ProQuestFSG +;default_noresults_recommend[] = SwitchTab +default_noresults_recommend[] = RemoveFilters + +; When you filter a search using facets, should VuFind retain your current filters +; on the next search and provide a reset button to clear them (true), or should it +; always perform new searches unfiltered (false)? +; retain_filters_by_default = true +retain_filters_by_default = false + +; Whether to always (when there are active filters) display the "Reset Filters" +; button regardless of the retain_filters_by_default setting. Default is false. +; always_display_reset_filters = false +always_display_reset_filters = true ; The order of display is as shown below ; The name of the index field is on the left From d856c11478f2d93e6384e0db7fee34c091720e72 Mon Sep 17 00:00:00 2001 From: Maccabee Levine Date: Tue, 8 Oct 2024 14:53:07 +0000 Subject: [PATCH 16/34] Add pagination and recommendation settings, work OOTB --- config/vufind/ProQuestFSG.ini | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/config/vufind/ProQuestFSG.ini b/config/vufind/ProQuestFSG.ini index 8024bb4092a..a94af5091d5 100644 --- a/config/vufind/ProQuestFSG.ini +++ b/config/vufind/ProQuestFSG.ini @@ -37,6 +37,30 @@ retain_filters_by_default = false ; always_display_reset_filters = false always_display_reset_filters = true +; This controls whether results are loaded with JavaScript when paging or changing +; settings. Loading results this way improves performance and accessibility, and is +; enabled by default. Loading will automatically fall back to non-JS mode if +; JavaScript is not supported by the browser. +load_results_with_js = true + +; This setting can be used to configure pagination control on top of results. +; Possible options are: +; empty string or false No top pagination (default) +; simple Simple next/prev button pagination +; full Full pagination alike to the one at the bottom of results +;top_paginator = simple + +; The following two sections can be used to associate specific recommendations +; modules with specific search types defined in the [Basic_Searches] section +; below. For all the details on how these sections work, see the comments above +; the equivalent sections of searches.ini. Recommendations work the same in +; ProQuestFSG as they do in the regular Search module. +;[SideRecommendations] +; No search-specific settings by default -- add your own here. +;[TopRecommendations] +; No search-specific settings by default -- add your own here. + + ; The order of display is as shown below ; The name of the index field is on the left ; The display name of the field is on the right From b5a7ddd6ce3c169a0e1c1b4e0124d8e88b4a81a3 Mon Sep 17 00:00:00 2001 From: Maccabee Levine Date: Tue, 8 Oct 2024 17:57:03 +0000 Subject: [PATCH 17/34] Simply constant backend params --- .../ProQuestFSGrecordController.php | 24 ------------------- .../src/VuFind/Search/ProQuestFSG/Params.php | 2 -- .../Backend/ProQuestFSG/Connector.php | 4 ++++ 3 files changed, 4 insertions(+), 26 deletions(-) diff --git a/module/VuFind/src/VuFind/Controller/ProQuestFSGrecordController.php b/module/VuFind/src/VuFind/Controller/ProQuestFSGrecordController.php index 2fd79c34f41..0fc3543516a 100644 --- a/module/VuFind/src/VuFind/Controller/ProQuestFSGrecordController.php +++ b/module/VuFind/src/VuFind/Controller/ProQuestFSGrecordController.php @@ -59,30 +59,6 @@ public function __construct(ServiceLocatorInterface $sm) parent::__construct($sm); } - /** - * Load the record requested by the user; note that this is not done in the - * init() method since we don't want to perform an expensive search twice - * when homeAction() forwards to another method. - * - * @param ParamBag $params Search backend parameters - * @param bool $force Set to true to force a reload of the record, even if - * already loaded (useful if loading a record using different parameters) - * - * @return AbstractRecordDriver - */ - protected function loadRecord(ParamBag $params = null, bool $force = false) - { - if (null === $params) { - $params = new ParamBag(); - } - - $paramsService = $this->serviceLocator->get(\VuFind\Search\Params\PluginManager::class) - ->get('VuFind\Search\ProQuestFSG\Params'); - $params->mergeWith($paramsService->getBackendParameters()); - - return parent::loadRecord($params, $force); - } - /** * Is the result scroller active? * diff --git a/module/VuFind/src/VuFind/Search/ProQuestFSG/Params.php b/module/VuFind/src/VuFind/Search/ProQuestFSG/Params.php index 09dfe8399f3..b43890daa82 100644 --- a/module/VuFind/src/VuFind/Search/ProQuestFSG/Params.php +++ b/module/VuFind/src/VuFind/Search/ProQuestFSG/Params.php @@ -52,8 +52,6 @@ class Params extends \VuFind\Search\Base\Params public function getBackendParameters() { $backendParams = new ParamBag(); - $backendParams->set('operation', 'searchRetrieve'); - $backendParams->set('recordSchema', 'marcxml'); // Sort $sort = $this->getSort(); diff --git a/module/VuFindSearch/src/VuFindSearch/Backend/ProQuestFSG/Connector.php b/module/VuFindSearch/src/VuFindSearch/Backend/ProQuestFSG/Connector.php index e183520ceca..741c249fdf5 100644 --- a/module/VuFindSearch/src/VuFindSearch/Backend/ProQuestFSG/Connector.php +++ b/module/VuFindSearch/src/VuFindSearch/Backend/ProQuestFSG/Connector.php @@ -105,6 +105,10 @@ public function getRecord($id, ParamBag $params = null) */ public function search(ParamBag $params, $offset, $limit) { + // Constant params + $params->set('operation', 'searchRetrieve'); + $params->set('recordSchema', 'marcxml'); + $options = $params->getArrayCopy(); $options['startRecord'] = $offset; if (null !== $limit) { From 2d8b4c80c3cf97087c82ecd50f0a04dafb76bb21 Mon Sep 17 00:00:00 2001 From: Maccabee Levine Date: Tue, 8 Oct 2024 17:58:17 +0000 Subject: [PATCH 18/34] Support list view options --- config/vufind/ProQuestFSG.ini | 13 +++++++++++++ .../src/VuFind/Search/ProQuestFSG/Options.php | 8 ++++---- 2 files changed, 17 insertions(+), 4 deletions(-) diff --git a/config/vufind/ProQuestFSG.ini b/config/vufind/ProQuestFSG.ini index a94af5091d5..e8f2e1313a1 100644 --- a/config/vufind/ProQuestFSG.ini +++ b/config/vufind/ProQuestFSG.ini @@ -113,6 +113,19 @@ date/ascending = sort_year_asc ; through the current result set from within the record view. next_prev_navigation = false +; This section controls what happens when a record title in a search result list +; is clicked. VuFind can either embed the full result directly in the list using +; AJAX or can display it at its own separate URL as a full HTML page. +; full - separate page (default) +; tabs - embedded using tabs (see record/tabs.phtml) +; accordion - embedded using an accordion (see record/accordion.phtml) +; NOTE: To turn this feature on for favorite lists, see the lists_view setting +; in the [Social] section of config.ini. +; NOTE: This feature is incompatible with SyndeticsPlus content; please use +; regular Syndetics if necessary. +[List] +view=full + ; This section provides settings for optional caching of search requests. [SearchCache] ; Supported adapters: Memcached, Filesystem. Others may also work, but have not been diff --git a/module/VuFind/src/VuFind/Search/ProQuestFSG/Options.php b/module/VuFind/src/VuFind/Search/ProQuestFSG/Options.php index 4a3c8b0a69e..177532d9396 100644 --- a/module/VuFind/src/VuFind/Search/ProQuestFSG/Options.php +++ b/module/VuFind/src/VuFind/Search/ProQuestFSG/Options.php @@ -87,10 +87,10 @@ public function __construct(\VuFind\Config\PluginManager $configLoader) if (isset($searchSettings->General->default_sort)) { $this->defaultSort = $searchSettings->General->default_sort; } - // // Load list view for result (controls AJAX embedding vs. linking) - // if (isset($searchSettings->List->view)) { - // $this->listviewOption = $searchSettings->List->view; - // } + // Load list view for result (controls AJAX embedding vs. linking) + if (isset($searchSettings->List->view)) { + $this->listviewOption = $searchSettings->List->view; + } } /** From f40b553d2395ad0257aa9eca1785d61fc23fb8ae Mon Sep 17 00:00:00 2001 From: Maccabee Levine Date: Tue, 8 Oct 2024 17:59:23 +0000 Subject: [PATCH 19/34] Fix typo --- module/VuFind/src/VuFind/Search/ProQuestFSG/Options.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/module/VuFind/src/VuFind/Search/ProQuestFSG/Options.php b/module/VuFind/src/VuFind/Search/ProQuestFSG/Options.php index 177532d9396..c5726ed6152 100644 --- a/module/VuFind/src/VuFind/Search/ProQuestFSG/Options.php +++ b/module/VuFind/src/VuFind/Search/ProQuestFSG/Options.php @@ -65,7 +65,7 @@ public function __construct(\VuFind\Config\PluginManager $configLoader) $this->limitOptions = $this->explodeListSetting($searchSettings->General->limit_options); } - // // Search handler setup: + // Search handler setup: $this->defaultHandler = 'cql.serverChoice'; if (isset($searchSettings->Basic_Searches)) { foreach ($searchSettings->Basic_Searches as $key => $value) { From a14a8012cad3b1053aaf4057eda5aeace696a29b Mon Sep 17 00:00:00 2001 From: Maccabee Levine Date: Tue, 8 Oct 2024 18:01:56 +0000 Subject: [PATCH 20/34] Remove dead code --- .../src/VuFindSearch/Backend/ProQuestFSG/Connector.php | 1 - 1 file changed, 1 deletion(-) diff --git a/module/VuFindSearch/src/VuFindSearch/Backend/ProQuestFSG/Connector.php b/module/VuFindSearch/src/VuFindSearch/Backend/ProQuestFSG/Connector.php index 741c249fdf5..db41d72f7cf 100644 --- a/module/VuFindSearch/src/VuFindSearch/Backend/ProQuestFSG/Connector.php +++ b/module/VuFindSearch/src/VuFindSearch/Backend/ProQuestFSG/Connector.php @@ -68,7 +68,6 @@ class Connector extends \VuFindSearch\Backend\SRU\Connector * @param array $options Additional config settings */ public function __construct( - // $wsKey, \Laminas\Http\Client $client, array $options = [] ) { From 86abb6772ce6806ebb7b14eac2e5bf0c1888c885 Mon Sep 17 00:00:00 2001 From: Maccabee Levine Date: Tue, 8 Oct 2024 18:34:04 +0000 Subject: [PATCH 21/34] Add advanced search support --- config/vufind/ProQuestFSG.ini | 9 ++ module/VuFind/config/module.config.php | 2 +- .../src/VuFind/Search/ProQuestFSG/Options.php | 13 ++- .../Backend/ProQuestFSG/QueryBuilder.php | 94 +++++++++---------- .../templates/proquestfsg/advanced.phtml | 1 + 5 files changed, 64 insertions(+), 55 deletions(-) create mode 100644 themes/bootstrap3/templates/proquestfsg/advanced.phtml diff --git a/config/vufind/ProQuestFSG.ini b/config/vufind/ProQuestFSG.ini index e8f2e1313a1..dcaa1c6025d 100644 --- a/config/vufind/ProQuestFSG.ini +++ b/config/vufind/ProQuestFSG.ini @@ -99,6 +99,15 @@ author = Author subject = Subject ;abstract = Abstract +; This section defines which search options will be included on the advanced +; search screen. All the notes above [Basic_Searches] also apply here. +[Advanced_Searches] +cql.serverChoice = "All Fields" +title = Title +author = Author +subject = Subject +;abstract = Abstract + ; This section defines the sort options available on search results. [Sorting] relevance = sort_relevance diff --git a/module/VuFind/config/module.config.php b/module/VuFind/config/module.config.php index cf8136f5808..9b424572786 100644 --- a/module/VuFind/config/module.config.php +++ b/module/VuFind/config/module.config.php @@ -811,7 +811,7 @@ 'Overdrive/MyContent','Overdrive/Hold', 'Pazpar2/Home', 'Pazpar2/Search', 'Primo/Advanced', 'Primo/CitedBy', 'Primo/Cites', 'Primo/Home', 'Primo/Search', - 'ProQuestFSG/Home', 'ProQuestFSG/Results', + 'ProQuestFSG/Advanced', 'ProQuestFSG/Home', 'ProQuestFSG/Results', 'QRCode/Show', 'QRCode/Unavailable', 'Records/Home', 'Relais/Login', 'Relais/Request', 'Search/Advanced', diff --git a/module/VuFind/src/VuFind/Search/ProQuestFSG/Options.php b/module/VuFind/src/VuFind/Search/ProQuestFSG/Options.php index c5726ed6152..160be08f15a 100644 --- a/module/VuFind/src/VuFind/Search/ProQuestFSG/Options.php +++ b/module/VuFind/src/VuFind/Search/ProQuestFSG/Options.php @@ -72,11 +72,11 @@ public function __construct(\VuFind\Config\PluginManager $configLoader) $this->basicHandlers[$key] = $value; } } - // if (isset($searchSettings->Advanced_Searches)) { - // foreach ($searchSettings->Advanced_Searches as $key => $value) { - // $this->advancedHandlers[$key] = $value; - // } - // } + if (isset($searchSettings->Advanced_Searches)) { + foreach ($searchSettings->Advanced_Searches as $key => $value) { + $this->advancedHandlers[$key] = $value; + } + } // Load sort preferences: if (isset($searchSettings->Sorting)) { @@ -111,7 +111,6 @@ public function getSearchAction() */ public function getAdvancedSearchAction() { - // return 'proquestfsg-advanced'; - return false; + return 'proquestfsg-advanced'; } } diff --git a/module/VuFindSearch/src/VuFindSearch/Backend/ProQuestFSG/QueryBuilder.php b/module/VuFindSearch/src/VuFindSearch/Backend/ProQuestFSG/QueryBuilder.php index 918550dd1c5..56992e765f2 100644 --- a/module/VuFindSearch/src/VuFindSearch/Backend/ProQuestFSG/QueryBuilder.php +++ b/module/VuFindSearch/src/VuFindSearch/Backend/ProQuestFSG/QueryBuilder.php @@ -94,59 +94,59 @@ public function build(AbstractQuery $query, ?ParamBag $params = null) */ protected function abstractQueryToString(AbstractQuery $query) { - // if ($query instanceof Query) { + if ($query instanceof Query) { return $this->queryToString($query); - // } else { - // return $this->queryGroupToString($query); - // } + } else { + return $this->queryGroupToString($query); + } } - // /** - // * Convert a QueryGroup object to a query string. - // * - // * @param QueryGroup $query QueryGroup to convert - // * - // * @return string - // */ - // protected function queryGroupToString(QueryGroup $query) - // { - // $groups = $excludes = []; + /** + * Convert a QueryGroup object to a query string. + * + * @param QueryGroup $query QueryGroup to convert + * + * @return string + */ + protected function queryGroupToString(QueryGroup $query) + { + $groups = $excludes = []; - // foreach ($query->getQueries() as $params) { - // // Advanced Search - // if ($params instanceof QueryGroup) { - // $thisGroup = []; - // // Process each search group - // foreach ($params->getQueries() as $group) { - // // Build this group individually as a basic search - // $thisGroup[] = $this->abstractQueryToString($group); - // } - // // Is this an exclusion (NOT) group or a normal group? - // if ($params->isNegated()) { - // $excludes[] = implode(' OR ', $thisGroup); - // } else { - // $groups[] - // = implode(' ' . $params->getOperator() . ' ', $thisGroup); - // } - // } else { - // // Basic Search - // $groups[] = $this->queryToString($params); - // } - // } + foreach ($query->getQueries() as $params) { + // Advanced Search + if ($params instanceof QueryGroup) { + $thisGroup = []; + // Process each search group + foreach ($params->getQueries() as $group) { + // Build this group individually as a basic search + $thisGroup[] = $this->abstractQueryToString($group); + } + // Is this an exclusion (NOT) group or a normal group? + if ($params->isNegated()) { + $excludes[] = implode(' OR ', $thisGroup); + } else { + $groups[] + = implode(' ' . $params->getOperator() . ' ', $thisGroup); + } + } else { + // Basic Search + $groups[] = $this->queryToString($params); + } + } - // // Put our advanced search together - // $queryStr = ''; - // if (count($groups) > 0) { - // $queryStr - // .= '(' . implode(') ' . $query->getOperator() . ' (', $groups) . ')'; - // } - // // and concatenate exclusion after that - // if (count($excludes) > 0) { - // $queryStr .= ' NOT ((' . implode(') OR (', $excludes) . '))'; - // } + // Put our advanced search together + $queryStr = ''; + if (count($groups) > 0) { + $queryStr + .= '(' . implode(') ' . $query->getOperator() . ' (', $groups) . ')'; + } + // and concatenate exclusion after that + if (count($excludes) > 0) { + $queryStr .= ' NOT ((' . implode(') OR (', $excludes) . '))'; + } - // return $queryStr; - // } + return $queryStr; + } /** * Convert a single Query object to a query string. diff --git a/themes/bootstrap3/templates/proquestfsg/advanced.phtml b/themes/bootstrap3/templates/proquestfsg/advanced.phtml new file mode 100644 index 00000000000..c7d90465afa --- /dev/null +++ b/themes/bootstrap3/templates/proquestfsg/advanced.phtml @@ -0,0 +1 @@ +render('search/advanced/layout.phtml'); From ec2dc6c3c51635378b567c21707ccda02fd1d7df Mon Sep 17 00:00:00 2001 From: Maccabee Levine Date: Tue, 8 Oct 2024 18:52:43 +0000 Subject: [PATCH 22/34] Fix styles and add missing comments --- .../Controller/ProQuestFSGrecordController.php | 1 - .../src/VuFind/Search/ProQuestFSG/Options.php | 2 +- .../src/VuFind/Search/ProQuestFSG/Params.php | 2 -- .../src/VuFind/Search/ProQuestFSG/Results.php | 18 +++++++++++++++++- .../Backend/ProQuestFSG/Connector.php | 13 +++++++++---- .../Backend/ProQuestFSG/QueryBuilder.php | 7 ------- .../src/VuFindSearch/Backend/SRU/Connector.php | 3 ++- 7 files changed, 29 insertions(+), 17 deletions(-) diff --git a/module/VuFind/src/VuFind/Controller/ProQuestFSGrecordController.php b/module/VuFind/src/VuFind/Controller/ProQuestFSGrecordController.php index 0fc3543516a..0b26f5bebf6 100644 --- a/module/VuFind/src/VuFind/Controller/ProQuestFSGrecordController.php +++ b/module/VuFind/src/VuFind/Controller/ProQuestFSGrecordController.php @@ -31,7 +31,6 @@ namespace VuFind\Controller; use Laminas\ServiceManager\ServiceLocatorInterface; -use VuFindSearch\ParamBag; /** * ProQuest Federated Search Gateway Record Controller diff --git a/module/VuFind/src/VuFind/Search/ProQuestFSG/Options.php b/module/VuFind/src/VuFind/Search/ProQuestFSG/Options.php index 160be08f15a..3951d0620ed 100644 --- a/module/VuFind/src/VuFind/Search/ProQuestFSG/Options.php +++ b/module/VuFind/src/VuFind/Search/ProQuestFSG/Options.php @@ -64,7 +64,7 @@ public function __construct(\VuFind\Config\PluginManager $configLoader) if (isset($searchSettings->General->limit_options)) { $this->limitOptions = $this->explodeListSetting($searchSettings->General->limit_options); } - + // Search handler setup: $this->defaultHandler = 'cql.serverChoice'; if (isset($searchSettings->Basic_Searches)) { diff --git a/module/VuFind/src/VuFind/Search/ProQuestFSG/Params.php b/module/VuFind/src/VuFind/Search/ProQuestFSG/Params.php index b43890daa82..16aa1daf97f 100644 --- a/module/VuFind/src/VuFind/Search/ProQuestFSG/Params.php +++ b/module/VuFind/src/VuFind/Search/ProQuestFSG/Params.php @@ -71,7 +71,6 @@ public function getBackendParameters() } } - return $backendParams; } @@ -88,5 +87,4 @@ public function getFacetValueRawDisplayText(string $field, string $value): strin $parts = explode('|', $value); return end($parts); } - } diff --git a/module/VuFind/src/VuFind/Search/ProQuestFSG/Results.php b/module/VuFind/src/VuFind/Search/ProQuestFSG/Results.php index 275ad7ccdef..8324d2beff0 100644 --- a/module/VuFind/src/VuFind/Search/ProQuestFSG/Results.php +++ b/module/VuFind/src/VuFind/Search/ProQuestFSG/Results.php @@ -49,8 +49,18 @@ class Results extends \VuFind\Search\Base\Results */ protected $backendId = 'ProQuestFSG'; + /** + * Facets returned in search response. + * + * @var array + */ protected $responseFacets = null; + /** + * Simplified version of result facets. + * + * @var array + */ protected $simplifiedResponseFacets = null; /** @@ -94,6 +104,13 @@ public function getFacetList($filter = null) return $this->buildFacetList($this->simplifiedResponseFacets, $filter); } + /** + * Simply raw ProQuestFSG facets to the form that VuFind templates expect. + * + * @param array $rawFacets Raw facts returned from the record collection + * + * @return array Simple format of facets + */ protected function simplifyFacets($rawFacets) { $simpleFacets = []; @@ -107,5 +124,4 @@ protected function simplifyFacets($rawFacets) } return $simpleFacets; } - } diff --git a/module/VuFindSearch/src/VuFindSearch/Backend/ProQuestFSG/Connector.php b/module/VuFindSearch/src/VuFindSearch/Backend/ProQuestFSG/Connector.php index db41d72f7cf..08ad2c0e271 100644 --- a/module/VuFindSearch/src/VuFindSearch/Backend/ProQuestFSG/Connector.php +++ b/module/VuFindSearch/src/VuFindSearch/Backend/ProQuestFSG/Connector.php @@ -32,6 +32,9 @@ use VuFindSearch\ParamBag; +use function intval; +use function strval; + /** * WorldCat SRU Search Interface * @@ -57,13 +60,16 @@ class Connector extends \VuFindSearch\Backend\SRU\Connector */ protected $sruVersion = '1.2'; + /** + * The default path, if a particular database target is not indicated. + * + * @var string + */ protected $defaultPath = '/all_subscribed'; - /** * Constructor * - * @param string $wsKey Web services key * @param \Laminas\Http\Client $client An HTTP client object * @param array $options Additional config settings */ @@ -119,8 +125,7 @@ public function search(ParamBag $params, $offset, $limit) [$filterKey, $filterValue] = explode(':', $filter, 2); if ('Databases' == $filterKey) { $path = '/' . $filterValue; - } - else { + } else { $filterRelationValue = $filterValue ? '=' . $filterValue : '=1'; diff --git a/module/VuFindSearch/src/VuFindSearch/Backend/ProQuestFSG/QueryBuilder.php b/module/VuFindSearch/src/VuFindSearch/Backend/ProQuestFSG/QueryBuilder.php index 56992e765f2..f43457cdd2b 100644 --- a/module/VuFindSearch/src/VuFindSearch/Backend/ProQuestFSG/QueryBuilder.php +++ b/module/VuFindSearch/src/VuFindSearch/Backend/ProQuestFSG/QueryBuilder.php @@ -53,13 +53,6 @@ */ class QueryBuilder { - /** - * OCLC code to exclude from results - * - * @var string - */ - protected $oclcCodeToExclude; - /// Public API /** diff --git a/module/VuFindSearch/src/VuFindSearch/Backend/SRU/Connector.php b/module/VuFindSearch/src/VuFindSearch/Backend/SRU/Connector.php index 219bb93dc7a..46caf14a6b1 100644 --- a/module/VuFindSearch/src/VuFindSearch/Backend/SRU/Connector.php +++ b/module/VuFindSearch/src/VuFindSearch/Backend/SRU/Connector.php @@ -201,6 +201,7 @@ public function checkForHttpError($result) * Submit REST Request * * @param string $method HTTP Method to use: GET or POST + * @param string $path URL path following $this->host * @param array $params An array of parameters for the request * @param bool $process Should we convert the MARCXML? * @@ -246,7 +247,7 @@ protected function call($method = 'GET', $path = '', $params = null, $process = $resultBody = $result->getBody(); if ($cacheKey) { $this->putCachedData($cacheKey, $resultBody); - } + } } // Return processed or unprocessed response, as appropriate: From 4a0b7b594ce49dd1dd105f2392de4da026a2fd76 Mon Sep 17 00:00:00 2001 From: Maccabee Levine Date: Wed, 9 Oct 2024 13:49:12 +0000 Subject: [PATCH 23/34] Strip html from title --- module/VuFind/src/VuFind/RecordDriver/ProQuestFSG.php | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/module/VuFind/src/VuFind/RecordDriver/ProQuestFSG.php b/module/VuFind/src/VuFind/RecordDriver/ProQuestFSG.php index 0ae74e4536c..00314ceda5e 100644 --- a/module/VuFind/src/VuFind/RecordDriver/ProQuestFSG.php +++ b/module/VuFind/src/VuFind/RecordDriver/ProQuestFSG.php @@ -49,6 +49,7 @@ class ProQuestFSG extends DefaultRecord use MarcReaderTrait, MarcAdvancedTrait, MarcBasicTrait { MarcBasicTrait::getNewerTitles insteadof MarcAdvancedTrait; MarcBasicTrait::getPreviousTitles insteadof MarcAdvancedTrait; + MarcBasicTrait::getShortTitle as marcGetShortTitle; } /** @@ -72,4 +73,14 @@ public function setRawData($data) // record driver can understand. parent::setRawData(['fullrecord' => $data]); } + + /** + * Get the short (pre-subtitle) title of the record. + * + * @return string + */ + public function getShortTitle() + { + return strip_tags($this->marcGetShortTitle()); + } } From d6988308d0472ccc887fd72f740469fa4dfbc154 Mon Sep 17 00:00:00 2001 From: Maccabee Levine Date: Wed, 6 Nov 2024 15:53:36 +0000 Subject: [PATCH 24/34] Convert to bootstrap5 --- themes/bootstrap5/templates/proquestfsg/advanced.phtml | 1 + themes/bootstrap5/templates/proquestfsg/home.phtml | 1 + themes/bootstrap5/templates/proquestfsg/results.phtml | 1 + 3 files changed, 3 insertions(+) create mode 100644 themes/bootstrap5/templates/proquestfsg/advanced.phtml create mode 100644 themes/bootstrap5/templates/proquestfsg/home.phtml create mode 100644 themes/bootstrap5/templates/proquestfsg/results.phtml diff --git a/themes/bootstrap5/templates/proquestfsg/advanced.phtml b/themes/bootstrap5/templates/proquestfsg/advanced.phtml new file mode 100644 index 00000000000..c7d90465afa --- /dev/null +++ b/themes/bootstrap5/templates/proquestfsg/advanced.phtml @@ -0,0 +1 @@ +render('search/advanced/layout.phtml'); diff --git a/themes/bootstrap5/templates/proquestfsg/home.phtml b/themes/bootstrap5/templates/proquestfsg/home.phtml new file mode 100644 index 00000000000..2b84165e5e2 --- /dev/null +++ b/themes/bootstrap5/templates/proquestfsg/home.phtml @@ -0,0 +1 @@ +render('search/home.phtml'); diff --git a/themes/bootstrap5/templates/proquestfsg/results.phtml b/themes/bootstrap5/templates/proquestfsg/results.phtml new file mode 100644 index 00000000000..1de7448817b --- /dev/null +++ b/themes/bootstrap5/templates/proquestfsg/results.phtml @@ -0,0 +1 @@ +render('search/results.phtml'); From 9670ee6ef4926a212afe0fb742655c2c0451f7a5 Mon Sep 17 00:00:00 2001 From: Maccabee Levine Date: Wed, 6 Nov 2024 16:28:01 +0000 Subject: [PATCH 25/34] Add recommendation module --- languages/en.ini | 2 + .../src/VuFind/Recommend/PluginManager.php | 4 ++ .../VuFind/Recommend/ProQuestFSGResults.php | 66 +++++++++++++++++++ .../Recommend/ProQuestFSGResultsDeferred.php | 56 ++++++++++++++++ .../Recommend/ProQuestFSGResults.phtml | 32 +++++++++ .../ProQuestFSG/link-author.phtml | 1 + .../Recommend/ProQuestFSGResults.phtml | 32 +++++++++ .../ProQuestFSG/link-author.phtml | 1 + 8 files changed, 194 insertions(+) create mode 100644 module/VuFind/src/VuFind/Recommend/ProQuestFSGResults.php create mode 100644 module/VuFind/src/VuFind/Recommend/ProQuestFSGResultsDeferred.php create mode 100644 themes/bootstrap3/templates/Recommend/ProQuestFSGResults.phtml create mode 100644 themes/bootstrap3/templates/RecordDriver/ProQuestFSG/link-author.phtml create mode 100644 themes/bootstrap5/templates/Recommend/ProQuestFSGResults.phtml create mode 100644 themes/bootstrap5/templates/RecordDriver/ProQuestFSG/link-author.phtml diff --git a/languages/en.ini b/languages/en.ini index e82696e28f5..08f952a12f8 100644 --- a/languages/en.ini +++ b/languages/en.ini @@ -1122,6 +1122,8 @@ Production Credits = "Production Credits" Profile = "Profile" profile_update = "Your profile was updated as requested" pronounced = "pronounced" +proquestfsg_recommendations = "ProQuest Results" +proquestfsg_recommendations_more = "More ProQuest Results" Provider = "Provider" proxied_user = "Place request for proxied user" proxy_hold_place_success_html = 'Your proxy request was successful. Your Holds and Recalls.' diff --git a/module/VuFind/src/VuFind/Recommend/PluginManager.php b/module/VuFind/src/VuFind/Recommend/PluginManager.php index a7d4542bbe8..cf1e277ae72 100644 --- a/module/VuFind/src/VuFind/Recommend/PluginManager.php +++ b/module/VuFind/src/VuFind/Recommend/PluginManager.php @@ -77,6 +77,8 @@ class PluginManager extends \VuFind\ServiceManager\AbstractPluginManager 'libguidesazresultsdeferred' => LibGuidesAZResultsDeferred::class, 'libraryh3lp' => Libraryh3lp::class, 'mapselection' => MapSelection::class, + 'proquestfsgresults' => ProQuestFSGResults::class, + 'proquestfsgresultsdeferred' => ProQuestFSGResultsDeferred::class, 'sidefacets' => SideFacets::class, 'sidefacetsdeferred' => SideFacetsDeferred::class, 'openlibrarysubjects' => OpenLibrarySubjects::class, @@ -141,6 +143,8 @@ class PluginManager extends \VuFind\ServiceManager\AbstractPluginManager MapSelection::class => MapSelectionFactory::class, OpenLibrarySubjects::class => InvokableFactory::class, OpenLibrarySubjectsDeferred::class => InvokableFactory::class, + ProQuestFSGResults::class => AbstractSearchObjectFactory::class, + ProQuestFSGResultsDeferred::class => InvokableFactory::class, PubDateVisAjax::class => InvokableFactory::class, RandomRecommend::class => RandomRecommendFactory::class, RecommendLinks::class => InjectConfigManagerFactory::class, diff --git a/module/VuFind/src/VuFind/Recommend/ProQuestFSGResults.php b/module/VuFind/src/VuFind/Recommend/ProQuestFSGResults.php new file mode 100644 index 00000000000..c5264d1e010 --- /dev/null +++ b/module/VuFind/src/VuFind/Recommend/ProQuestFSGResults.php @@ -0,0 +1,66 @@ + + * @author Maccabee Levine + * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License + * @link https://vufind.org/wiki/development:plugins:recommendation_modules Wiki + */ + +namespace VuFind\Recommend; + +/** + * ProQuestFSGResults Recommendations Module + * + * This class provides recommendations by doing a search of the ProQuestFSG backend. + * + * @category VuFind + * @package Recommendations + * @author Demian Katz + * @author Maccabee Levine + * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License + * @link https://vufind.org/wiki/development:plugins:recommendation_modules Wiki + */ +class ProQuestFSGResults extends AbstractSearchObject +{ + /** + * Get the search class ID to use for building search objects. + * + * @return string + */ + protected function getSearchClassId() + { + return 'ProQuestFSG'; + } + + /** + * Get the default heading for this recommendation module. + * + * @return string + */ + protected function getDefaultHeading() + { + return 'proquestfsg_recommendations'; + } +} diff --git a/module/VuFind/src/VuFind/Recommend/ProQuestFSGResultsDeferred.php b/module/VuFind/src/VuFind/Recommend/ProQuestFSGResultsDeferred.php new file mode 100644 index 00000000000..8337d0aa5a9 --- /dev/null +++ b/module/VuFind/src/VuFind/Recommend/ProQuestFSGResultsDeferred.php @@ -0,0 +1,56 @@ + + * @author Maccabee Levine + * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License + * @link https://vufind.org/wiki/development:plugins:recommendation_modules Wiki + */ + +namespace VuFind\Recommend; + +/** + * ProQuestFSGResultsDeferred Recommendations Module + * + * This class sets up an AJAX call to trigger a call to the ProQuestFSGResults module. + * + * @category VuFind + * @package Recommendations + * @author Demian Katz + * @author Maccabee Levine + * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License + * @link https://vufind.org/wiki/development:plugins:recommendation_modules Wiki + */ +class ProQuestFSGResultsDeferred extends AbstractSearchObjectDeferred +{ + /** + * Store the configuration of the recommendation module. + * + * @return string Module name in call to AjaxHandler + */ + protected function getAjaxModule() + { + return 'ProQuestFSGResults'; + } +} diff --git a/themes/bootstrap3/templates/Recommend/ProQuestFSGResults.phtml b/themes/bootstrap3/templates/Recommend/ProQuestFSGResults.phtml new file mode 100644 index 00000000000..062a6b132ae --- /dev/null +++ b/themes/bootstrap3/templates/Recommend/ProQuestFSGResults.phtml @@ -0,0 +1,32 @@ +recommend->getResults(); + $results = $searchObject->getResults(); + $heading = $this->recommend->getHeading(); +?> + +

transEsc($heading)?>

+ + diff --git a/themes/bootstrap3/templates/RecordDriver/ProQuestFSG/link-author.phtml b/themes/bootstrap3/templates/RecordDriver/ProQuestFSG/link-author.phtml new file mode 100644 index 00000000000..d39a425beac --- /dev/null +++ b/themes/bootstrap3/templates/RecordDriver/ProQuestFSG/link-author.phtml @@ -0,0 +1 @@ +render('RecordDriver/DefaultRecord/link-generic.phtml', compact('driver', 'lookfor') + ['type' => 'author', 'quoteQuery' => false]); diff --git a/themes/bootstrap5/templates/Recommend/ProQuestFSGResults.phtml b/themes/bootstrap5/templates/Recommend/ProQuestFSGResults.phtml new file mode 100644 index 00000000000..062a6b132ae --- /dev/null +++ b/themes/bootstrap5/templates/Recommend/ProQuestFSGResults.phtml @@ -0,0 +1,32 @@ +recommend->getResults(); + $results = $searchObject->getResults(); + $heading = $this->recommend->getHeading(); +?> + +

transEsc($heading)?>

+ + diff --git a/themes/bootstrap5/templates/RecordDriver/ProQuestFSG/link-author.phtml b/themes/bootstrap5/templates/RecordDriver/ProQuestFSG/link-author.phtml new file mode 100644 index 00000000000..d39a425beac --- /dev/null +++ b/themes/bootstrap5/templates/RecordDriver/ProQuestFSG/link-author.phtml @@ -0,0 +1 @@ +render('RecordDriver/DefaultRecord/link-generic.phtml', compact('driver', 'lookfor') + ['type' => 'author', 'quoteQuery' => false]); From 2e85a0f227f275214c557d4f92779f595ac298cd Mon Sep 17 00:00:00 2001 From: Maccabee Levine Date: Wed, 6 Nov 2024 16:31:04 +0000 Subject: [PATCH 26/34] Fix styles --- module/VuFind/src/VuFind/Recommend/ProQuestFSGResults.php | 4 ++-- .../src/VuFind/Recommend/ProQuestFSGResultsDeferred.php | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/module/VuFind/src/VuFind/Recommend/ProQuestFSGResults.php b/module/VuFind/src/VuFind/Recommend/ProQuestFSGResults.php index c5264d1e010..655f50e6dc5 100644 --- a/module/VuFind/src/VuFind/Recommend/ProQuestFSGResults.php +++ b/module/VuFind/src/VuFind/Recommend/ProQuestFSGResults.php @@ -23,7 +23,7 @@ * @category VuFind * @package Recommendations * @author Demian Katz - * @author Maccabee Levine + * @author Maccabee Levine * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License * @link https://vufind.org/wiki/development:plugins:recommendation_modules Wiki */ @@ -38,7 +38,7 @@ * @category VuFind * @package Recommendations * @author Demian Katz - * @author Maccabee Levine + * @author Maccabee Levine * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License * @link https://vufind.org/wiki/development:plugins:recommendation_modules Wiki */ diff --git a/module/VuFind/src/VuFind/Recommend/ProQuestFSGResultsDeferred.php b/module/VuFind/src/VuFind/Recommend/ProQuestFSGResultsDeferred.php index 8337d0aa5a9..757ec26f4ae 100644 --- a/module/VuFind/src/VuFind/Recommend/ProQuestFSGResultsDeferred.php +++ b/module/VuFind/src/VuFind/Recommend/ProQuestFSGResultsDeferred.php @@ -23,7 +23,7 @@ * @category VuFind * @package Recommendations * @author Demian Katz - * @author Maccabee Levine + * @author Maccabee Levine * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License * @link https://vufind.org/wiki/development:plugins:recommendation_modules Wiki */ @@ -38,7 +38,7 @@ * @category VuFind * @package Recommendations * @author Demian Katz - * @author Maccabee Levine + * @author Maccabee Levine * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License * @link https://vufind.org/wiki/development:plugins:recommendation_modules Wiki */ From d22ff049a129ffed5ad44317342538fd51a0ce50 Mon Sep 17 00:00:00 2001 From: Maccabee Levine Date: Wed, 6 Nov 2024 16:44:17 +0000 Subject: [PATCH 27/34] Fix copy/paste typos --- module/VuFind/src/VuFind/RecordDriver/ProQuestFSG.php | 2 +- .../src/VuFind/Search/Factory/ProQuestFSGBackendFactory.php | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/module/VuFind/src/VuFind/RecordDriver/ProQuestFSG.php b/module/VuFind/src/VuFind/RecordDriver/ProQuestFSG.php index 00314ceda5e..7ff652db1a1 100644 --- a/module/VuFind/src/VuFind/RecordDriver/ProQuestFSG.php +++ b/module/VuFind/src/VuFind/RecordDriver/ProQuestFSG.php @@ -69,7 +69,7 @@ public function setRawData($data) $data = $data['fullrecord']; } - // Map the WorldCat response into a format that the parent Solr-based + // Map the ProQuestFSG response into a format that the parent Solr-based // record driver can understand. parent::setRawData(['fullrecord' => $data]); } diff --git a/module/VuFind/src/VuFind/Search/Factory/ProQuestFSGBackendFactory.php b/module/VuFind/src/VuFind/Search/Factory/ProQuestFSGBackendFactory.php index f31032b5c0b..b6784776ccf 100644 --- a/module/VuFind/src/VuFind/Search/Factory/ProQuestFSGBackendFactory.php +++ b/module/VuFind/src/VuFind/Search/Factory/ProQuestFSGBackendFactory.php @@ -93,7 +93,7 @@ public function __invoke(ContainerInterface $sm, $name, array $options = null) } /** - * Create the WorldCat backend. + * Create the ProQuestFSG backend. * * @param Connector $connector Connector * @@ -107,7 +107,7 @@ protected function createBackend(Connector $connector) } /** - * Create the WorldCat connector. + * Create the ProQuestFSG connector. * * @return Connector */ From 1741fb94851d0a03f7922bdd3ec7ccc1443a9b84 Mon Sep 17 00:00:00 2001 From: Maccabee Levine Date: Wed, 6 Nov 2024 16:51:54 +0000 Subject: [PATCH 28/34] Fix more typos --- .../src/VuFindSearch/Backend/ProQuestFSG/Backend.php | 2 +- .../src/VuFindSearch/Backend/ProQuestFSG/Connector.php | 8 ++++---- .../src/VuFindSearch/Backend/ProQuestFSG/QueryBuilder.php | 2 +- .../Backend/ProQuestFSG/Response/XML/RecordCollection.php | 2 +- 4 files changed, 7 insertions(+), 7 deletions(-) diff --git a/module/VuFindSearch/src/VuFindSearch/Backend/ProQuestFSG/Backend.php b/module/VuFindSearch/src/VuFindSearch/Backend/ProQuestFSG/Backend.php index 445083d883c..bb069a7a497 100644 --- a/module/VuFindSearch/src/VuFindSearch/Backend/ProQuestFSG/Backend.php +++ b/module/VuFindSearch/src/VuFindSearch/Backend/ProQuestFSG/Backend.php @@ -65,7 +65,7 @@ class Backend extends AbstractBackend /** * Constructor. * - * @param Connector $connector WorldCat connector + * @param Connector $connector ProQuestFSG connector * @param RecordCollectionFactoryInterface $factory Record collection factory * (null for default) * diff --git a/module/VuFindSearch/src/VuFindSearch/Backend/ProQuestFSG/Connector.php b/module/VuFindSearch/src/VuFindSearch/Backend/ProQuestFSG/Connector.php index 08ad2c0e271..adb6acbbeba 100644 --- a/module/VuFindSearch/src/VuFindSearch/Backend/ProQuestFSG/Connector.php +++ b/module/VuFindSearch/src/VuFindSearch/Backend/ProQuestFSG/Connector.php @@ -1,7 +1,7 @@ * @author Demian Katz * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License @@ -36,10 +36,10 @@ use function strval; /** - * WorldCat SRU Search Interface + * ProQuestFSG SRU Search Interface * * @category VuFind - * @package WorldCat + * @package ProQuestFSG * @author Andrew S. Nagy * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License * @link https://vufind.org/wiki/development Wiki diff --git a/module/VuFindSearch/src/VuFindSearch/Backend/ProQuestFSG/QueryBuilder.php b/module/VuFindSearch/src/VuFindSearch/Backend/ProQuestFSG/QueryBuilder.php index f43457cdd2b..ebccd18e497 100644 --- a/module/VuFindSearch/src/VuFindSearch/Backend/ProQuestFSG/QueryBuilder.php +++ b/module/VuFindSearch/src/VuFindSearch/Backend/ProQuestFSG/QueryBuilder.php @@ -56,7 +56,7 @@ class QueryBuilder /// Public API /** - * Return WorldCat search parameters based on a user query and params. + * Return ProQuestFSG search parameters based on a user query and params. * * @param AbstractQuery $query User query * @param ?ParamBag $params Search backend parameters diff --git a/module/VuFindSearch/src/VuFindSearch/Backend/ProQuestFSG/Response/XML/RecordCollection.php b/module/VuFindSearch/src/VuFindSearch/Backend/ProQuestFSG/Response/XML/RecordCollection.php index 4d63b741f11..fa32c5acf45 100644 --- a/module/VuFindSearch/src/VuFindSearch/Backend/ProQuestFSG/Response/XML/RecordCollection.php +++ b/module/VuFindSearch/src/VuFindSearch/Backend/ProQuestFSG/Response/XML/RecordCollection.php @@ -54,7 +54,7 @@ class RecordCollection extends AbstractRecordCollection /** * Constructor. * - * @param array $response WorldCat response + * @param array $response ProQuestFSG response * * @return void */ From f58c0a4eb12accc281805ed96296b42f504b3729 Mon Sep 17 00:00:00 2001 From: Maccabee Levine Date: Fri, 8 Nov 2024 16:25:17 +0000 Subject: [PATCH 29/34] Add tests --- .../proquestfsg/connector_record.json | 10 + .../proquestfsg/connector_searchresult.json | 138 ++++++++ .../tests/fixtures/proquestfsg/record.xml | 136 ++++++++ .../fixtures/proquestfsg/searchresult.xml | 318 ++++++++++++++++++ .../ProQuestFSGResultsDeferredTest.php | 62 ++++ .../Backend/ProQuestFSG/Connector.php | 5 +- .../Backend/ProQuestFSG/BackendTest.php | 133 ++++++++ .../Backend/ProQuestFSG/ConnectorTest.php | 124 +++++++ 8 files changed, 924 insertions(+), 2 deletions(-) create mode 100644 module/VuFind/tests/fixtures/proquestfsg/connector_record.json create mode 100644 module/VuFind/tests/fixtures/proquestfsg/connector_searchresult.json create mode 100644 module/VuFind/tests/fixtures/proquestfsg/record.xml create mode 100644 module/VuFind/tests/fixtures/proquestfsg/searchresult.xml create mode 100644 module/VuFind/tests/unit-tests/src/VuFindTest/Recommend/ProQuestFSGResultsDeferredTest.php create mode 100644 module/VuFindSearch/tests/unit-tests/src/VuFindTest/Backend/ProQuestFSG/BackendTest.php create mode 100644 module/VuFindSearch/tests/unit-tests/src/VuFindTest/Backend/ProQuestFSG/ConnectorTest.php diff --git a/module/VuFind/tests/fixtures/proquestfsg/connector_record.json b/module/VuFind/tests/fixtures/proquestfsg/connector_record.json new file mode 100644 index 00000000000..06569695d17 --- /dev/null +++ b/module/VuFind/tests/fixtures/proquestfsg/connector_record.json @@ -0,0 +1,10 @@ +{ + "docs": [ + "\n00000nab a2200000uu 4500<\/leader>\n2811962947<\/controlfield>\nUK-CbPIL<\/controlfield>\n\n0164-0178<\/subfield>\n<\/datafield>\n\n1086-3141<\/subfield>\n<\/datafield>\n\n0146-5511<\/subfield>\n<\/datafield>\n\n0002-9068<\/subfield>\n<\/datafield>\n\n10.1353\/ajh.2021.0054<\/subfield>\ndoi<\/subfield>\n<\/datafield>\n\n2811962947<\/subfield>\n<\/datafield>\n\nd20211001<\/subfield>\nd20211031<\/subfield>\n<\/datafield>\n\n12342<\/subfield>\nnlm<\/subfield>\n<\/datafield>\n\nEichler-Levine, Jodi<\/subfield>\n<\/datafield>\n\n<i>Jewish Identity in American Art: A Golden Age since the 1970s<\/i> by Matthew Baigell (review)<\/subfield>\n<\/datafield>\n\nJohns Hopkins University Press<\/subfield>\nOct 2021<\/subfield>\n<\/datafield>\n\nBook Review<\/subfield>\n<\/datafield>\n\nJewish Identity in American Art is strongest when its author deploys close readings of the images at hand, often interspersed with artist statements and quotes from interviews.\n\nThe book would be helpful both for teaching recent Jewish art history and as an introduction for readers who are unfamiliar with the scope of the field.\n\nJodi Eichler-Levine Jodi Eichler-Levine is Berman Professor of Religion Studies and Associate Professor of Religion Studies at Lehigh University.<\/subfield>\n<\/datafield>\n\nReligion<\/subfield>\n<\/datafield>\n\nJudaism<\/subfield>\n<\/datafield>\n\nJewish art<\/subfield>\n<\/datafield>\n\nVisual artists<\/subfield>\n<\/datafield>\n\nArt history<\/subfield>\n<\/datafield>\n\nWomen<\/subfield>\n<\/datafield>\n\nArt<\/subfield>\n<\/datafield>\n\nBooks<\/subfield>\n<\/datafield>\n\nPainting<\/subfield>\n<\/datafield>\n\nAmerican Jewish History<\/subfield>\nvol. 105, no. 4 (Oct 2021), p. 570<\/subfield>\n<\/datafield>\n\nProQuest<\/subfield>\nReligion Database<\/subfield>\n<\/datafield>\n\nCitation\/Abstract<\/subfield>\nhttps:\/\/www.proquest.com\/docview\/2811962947\/abstract\/embedded\/UHA0DUZFOHJEPDBM?source=fedsrch<\/subfield>\n<\/datafield>\n\nFull Text<\/subfield>\nhttps:\/\/www.proquest.com\/docview\/2811962947\/fulltext\/embedded\/UHA0DUZFOHJEPDBM?source=fedsrch<\/subfield>\n<\/datafield>\n\nFull Text - PDF<\/subfield>\nhttps:\/\/www.proquest.com\/docview\/2811962947\/fulltextPDF\/embedded\/UHA0DUZFOHJEPDBM?source=fedsrch<\/subfield>\n<\/datafield>\n<\/record>" + ], + "offset": 1, + "total": 1, + "facets": { + "Databases": [] + } +} \ No newline at end of file diff --git a/module/VuFind/tests/fixtures/proquestfsg/connector_searchresult.json b/module/VuFind/tests/fixtures/proquestfsg/connector_searchresult.json new file mode 100644 index 00000000000..a2c76c60f26 --- /dev/null +++ b/module/VuFind/tests/fixtures/proquestfsg/connector_searchresult.json @@ -0,0 +1,138 @@ +{ + "docs": [ + "\n00000nab a2200000uu 4500<\/leader>\n2615626038<\/controlfield>\nUK-CbPIL<\/controlfield>\n\n0164-0178<\/subfield>\n<\/datafield>\n\n1086-3141<\/subfield>\n<\/datafield>\n\n0146-5511<\/subfield>\n<\/datafield>\n\n0002-9068<\/subfield>\n<\/datafield>\n\n2615626038<\/subfield>\n<\/datafield>\n\nd20210701<\/subfield>\nd20210731<\/subfield>\n<\/datafield>\n\n12342<\/subfield>\nnlm<\/subfield>\n<\/datafield>\n\nJenna Weissman Joselit<\/subfield>\n<\/datafield>\n\n<i>Painted Pomegranates and Needlepoint Rabbis: How Jews Craft Resilience and Craft Community<\/i> by Jodi Eichler-Levine (review)<\/subfield>\n<\/datafield>\n\nJohns Hopkins University Press<\/subfield>\nJul 2021<\/subfield>\n<\/datafield>\n\nBook Review<\/subfield>\n<\/datafield>\n\nThe Pomegranate Guild of Judaic Needlework, established in 1977 to foster \"synagogue decoration, Judaic symbolism, Jewish art and Judaic embroidery,\" and Jewish Hearts for Pittsburgh, a digital group some one thousand members strong that arose more recently, in the wake of the deadly 2018 Tree of Life shootings, are among them (103).\n\nPaying close attention to what they created, Eichler-Levine, herself a member of the Jewish craft community, explores a wide array of handmade goods, from the Pussyhat, the hot pink knitted cap with pointed cat ears worn by millions of women in 2017 in protest against then-President Trump, to the traditional wimple whose impetus has recently expanded to include all sorts of lifecycle moments, not just the birth of a son.\n\nIn its compelling analysis and, yes, in its embrace of Jewish women's craft culture, the book repeatedly rings the bell in favor of material culture, sounding now and again much more like a brief, an exercise in special pleading, than a confident narrative.<\/subfield>\n<\/datafield>\n\nJudaic studies<\/subfield>\n<\/datafield>\n\nClergy<\/subfield>\n<\/datafield>\n\nJewish people<\/subfield>\n<\/datafield>\n\nSymbolism<\/subfield>\n<\/datafield>\n\nAmerican Jewish History<\/subfield>\nvol. 105, no. 3 (Jul 2021), p. 433<\/subfield>\n<\/datafield>\n\nProQuest<\/subfield>\nReligion Database<\/subfield>\n<\/datafield>\n\nCitation\/Abstract<\/subfield>\nhttps:\/\/www.proquest.com\/docview\/2615626038\/abstract\/embedded\/UHA0DUZFOHJEPDBM?source=fedsrch<\/subfield>\n<\/datafield>\n\nFull Text<\/subfield>\nhttps:\/\/www.proquest.com\/docview\/2615626038\/fulltext\/embedded\/UHA0DUZFOHJEPDBM?source=fedsrch<\/subfield>\n<\/datafield>\n\nFull Text - PDF<\/subfield>\nhttps:\/\/www.proquest.com\/docview\/2615626038\/fulltextPDF\/embedded\/UHA0DUZFOHJEPDBM?source=fedsrch<\/subfield>\n<\/datafield>\n<\/record>", + "\n00000nab a2200000uu 4500<\/leader>\n2432781939<\/controlfield>\nUK-CbPIL<\/controlfield>\n\n1948-7428<\/subfield>\n<\/datafield>\n\n1948-741X<\/subfield>\n<\/datafield>\n\n0042-6598<\/subfield>\n<\/datafield>\n\n2432781939<\/subfield>\n<\/datafield>\n\nd20200815<\/subfield>\n<\/datafield>\n\n157528<\/subfield>\nnlm<\/subfield>\n<\/datafield>\n\nPAINTED POMEGRANATES AND NEEDLEPOINT RABBIS<\/subfield>\n<\/datafield>\n\nKirkus Media LLC<\/subfield>\nAug 15, 2020<\/subfield>\n<\/datafield>\n\nBook Review<\/subfield>\n<\/datafield>\n\nAn academic look at Jewish crafts.<\/subfield>\n<\/datafield>\n\nNonfiction<\/subfield>\n<\/datafield>\n\nHandicrafts<\/subfield>\n<\/datafield>\n\nJewish people<\/subfield>\n<\/datafield>\n\nJews<\/subfield>\n<\/datafield>\n\nEthnology<\/subfield>\n<\/datafield>\n\nEthnic Groups<\/subfield>\n<\/datafield>\n\nCoping<\/subfield>\n<\/datafield>\n\nResilience (Psychology)<\/subfield>\n<\/datafield>\n\nResistance (Psychology)<\/subfield>\n<\/datafield>\n\nKirkus Reviews<\/subfield>\nvol. LXXXVIII, no. 16 (Aug 15, 2020)<\/subfield>\n<\/datafield>\n\nProQuest<\/subfield>\nLibrary Science Database<\/subfield>\n<\/datafield>\n\nCitation\/Abstract<\/subfield>\nhttps:\/\/www.proquest.com\/docview\/2432781939\/abstract\/embedded\/UHA0DUZFOHJEPDBM?source=fedsrch<\/subfield>\n<\/datafield>\n\nFull Text<\/subfield>\nhttps:\/\/www.proquest.com\/docview\/2432781939\/fulltext\/embedded\/UHA0DUZFOHJEPDBM?source=fedsrch<\/subfield>\n<\/datafield>\n<\/record>" + ], + "offset": 1, + "total": 31, + "facets": { + "Databases": [ + { + "id": "1009388", + "code": "ebookcentral1", + "name": "Ebook Central", + "count": 11 + }, + { + "id": "1009240", + "code": "publiccontent", + "name": "Publicly Available Content Database", + "count": 1 + }, + { + "id": "1007107", + "code": "nahs", + "name": "Nursing & Allied Health Database", + "count": 1 + }, + { + "id": "10000155", + "code": "healthcompleteshell", + "name": "Health & Medical Collection", + "count": 1 + }, + { + "id": "10000025", + "code": "pqrl", + "name": "Research Library", + "count": 20 + }, + { + "id": "1000001", + "code": "abiglobal", + "name": "ABI\/INFORM Global", + "count": 1 + }, + { + "id": "1007133", + "code": "abitrade", + "name": "ABI\/INFORM Trade & Industry", + "count": 1 + }, + { + "id": "1007139", + "code": "abidateline", + "name": "ABI\/INFORM Dateline", + "count": 1 + }, + { + "id": "1005641", + "code": "religion", + "name": "Religion Database", + "count": 10 + }, + { + "id": "1005922", + "code": "washingtonpost", + "name": "The Washington Post", + "count": 1 + }, + { + "id": "1009068", + "code": "northeastnews1", + "name": "U.S. Northeast Newsstream", + "count": 1 + }, + { + "id": "1007200", + "code": "socscijournals", + "name": "Social Science Database", + "count": 5 + }, + { + "id": "1005684", + "code": "politicalscience", + "name": "Political Science Database", + "count": 2 + }, + { + "id": "1007566", + "code": "wpsa", + "name": "Worldwide Political Science Abstracts", + "count": 1 + }, + { + "id": "1007519", + "code": "lisa", + "name": "Library & Information Science Abstracts (LISA)", + "count": 1 + }, + { + "id": "1006545", + "code": "libraryscience", + "name": "Library Science Database", + "count": 2 + }, + { + "id": "1007161", + "code": "education", + "name": "Education Database", + "count": 2 + }, + { + "id": "1007480", + "code": "socabs", + "name": "Sociological Abstracts", + "count": 3 + }, + { + "id": "1005683", + "code": "sociology", + "name": "Sociology Database", + "count": 2 + }, + { + "id": "1007409", + "code": "ibss", + "name": "International Bibliography of the Social Sciences (IBSS)", + "count": 4 + }, + { + "id": "1010268", + "code": "pqdtglobal1", + "name": "ProQuest Dissertations & Theses Global", + "count": 4 + } + ] + } +} \ No newline at end of file diff --git a/module/VuFind/tests/fixtures/proquestfsg/record.xml b/module/VuFind/tests/fixtures/proquestfsg/record.xml new file mode 100644 index 00000000000..ce8f45f1cef --- /dev/null +++ b/module/VuFind/tests/fixtures/proquestfsg/record.xml @@ -0,0 +1,136 @@ + + + 1.2 + 1 + + + 1 + marcxml + xml + + + 00000nab a2200000uu 4500 + 2811962947 + UK-CbPIL + + 0164-0178 + + + 1086-3141 + + + 0146-5511 + + + 0002-9068 + + + 10.1353/ajh.2021.0054 + doi + + + 2811962947 + + + d20211001 + d20211031 + + + 12342 + nlm + + + Eichler-Levine, Jodi + + + <i>Jewish Identity in American Art: A Golden Age since the 1970s</i> by Matthew Baigell (review) + + + Johns Hopkins University Press + Oct 2021 + + + Book Review + + + Jewish Identity in American Art is strongest when its author deploys close readings of the images at hand, often interspersed with artist statements and quotes from interviews. + +The book would be helpful both for teaching recent Jewish art history and as an introduction for readers who are unfamiliar with the scope of the field. + +Jodi Eichler-Levine Jodi Eichler-Levine is Berman Professor of Religion Studies and Associate Professor of Religion Studies at Lehigh University. + + + Religion + + + Judaism + + + Jewish art + + + Visual artists + + + Art history + + + Women + + + Art + + + Books + + + Painting + + + American Jewish History + vol. 105, no. 4 (Oct 2021), p. 570 + + + ProQuest + Religion Database + + + Citation/Abstract + https://www.proquest.com/docview/2811962947/abstract/embedded/UHA0DUZFOHJEPDBM?source=fedsrch + + + Full Text + https://www.proquest.com/docview/2811962947/fulltext/embedded/UHA0DUZFOHJEPDBM?source=fedsrch + + + Full Text - PDF + https://www.proquest.com/docview/2811962947/fulltextPDF/embedded/UHA0DUZFOHJEPDBM?source=fedsrch + + + + + + + Original CQL query: rec.identifier="2811962947" + Converted to ProQuest query: AN(2811962947) + ProQuest limiters: None + Navigators: database + Sort order: relevance + Databases searched by this request are: 20drama:1008836 abidateline:1007139 abiglobal:1000001 abitrade:1007133 accountingtaxbanking:10000231 africannews:1007059 agriculturejournals:1007160 americanperiodicals:10000019 anz:1009046 anznews:1007061 artshumanities:1000277 asianeuropeanbusiness:10000236 asianews:1007060 assia:1007429 avon:1009174 aws:1008818 biologicalscijournals:1007856 britishperiodicals:10000001 canadiannews:1007330 career:10000026 cbcacomplete:10000023 cbs60m:1009241 chicagotribune:1005635 compscijour:1008043 conteurope:1009048 coronavirus:1009903 criminaljusticeperiodicals:1007025 eaasdb:1009715 eas:1010553 eastcentraleurope:1009050 eastsouthasia:1009049 ebookcentral1:1009388 education:1007161 eebo:1009636 engindex:10000353 engineeringjournals:1007853 eric:1007399 esdb:1009714 europeannews:1007062 familyhealth:1006520 globalwires:1009054 healthcompleteshell:10000155 healthmanagement:1006481 hightechjournals:1007852 hispanicnews:1009047 hnpnewyorktimes:1007155 hnppennsylvaniacollection:1009887 hnpphiladelphiainquirer:1009157 hnppittsburghpostgazette:1009159 ibss:1007409 indianjournals:10000204 latimes:1005692 latinamericaiberian:1009056 latinamericanews1:1009057 latx:1010284 libraryscience:1006545 linguistics:1009059 lisa:1007519 litcollectioneawso:1009776 litcollectionlittheory:1010514 llba:1007521 marketresearch:10000239 materialsscijournals:1007851 medline:1007527 middleeastafrica:1009060 middleeastnews:1006075 midwestnews1:1009067 military:1007156 msindex:10000352 nahs:1007107 ncjrs:1007535 northcentralnews:1009065 northeastnews1:1009068 nytimes:1005701 pais:10000017 physicaleducation:1007555 pilots:1007557 policyfile:1009062 politicalscience:1005684 pqdtglobal1:1010268 pqdtlocal1006887:1006887 pqrl:10000025 psychology:1007106 publiccontent:1009240 publichealth:1007617 religion:1005641 rsa:1010010 sciencejournals:1000283 socabs:1007480 socialservices:1007485 sociology:1005683 socscijournals:1007200 southcentralnews:1009066 southeastnews:1009069 tdmstudiounl:1010230 telecomms:1006986 turkey:1009063 ukireland:1009064 wallstreetjournal:1006968 washingtonpost:1005922 westnews:1009070 wlitshell:10000365 wma:10000228 wpsa:1007566 wwd:1008717 + Subscribed databases (codes and IDs) are: Academic databases - 20drama:1008836 abidateline:1007139 abiglobal:1000001 abitrade:1007133 accountingtaxbanking:10000231 africannews:1007059 agriculturejournals:1007160 americanperiodicals:10000019 anz:1009046 anznews:1007061 artshumanities:1000277 asianeuropeanbusiness:10000236 asianews:1007060 assia:1007429 avon:1009174 aws:1008818 biologicalscijournals:1007856 britishperiodicals:10000001 canadiannews:1007330 career:10000026 cbcacomplete:10000023 cbs60m:1009241 chicagotribune:1005635 compscijour:1008043 conteurope:1009048 coronavirus:1009903 criminaljusticeperiodicals:1007025 eaasdb:1009715 eas:1010553 eastcentraleurope:1009050 eastsouthasia:1009049 ebookcentral1:1009388 education:1007161 eebo:1009636 engindex:10000353 engineeringjournals:1007853 eric:1007399 esdb:1009714 europeannews:1007062 familyhealth:1006520 globalwires:1009054 healthcompleteshell:10000155 healthmanagement:1006481 hightechjournals:1007852 hispanicnews:1009047 hnpnewyorktimes:1007155 hnppennsylvaniacollection:1009887 hnpphiladelphiainquirer:1009157 hnppittsburghpostgazette:1009159 ibss:1007409 indianjournals:10000204 latimes:1005692 latinamericaiberian:1009056 latinamericanews1:1009057 latx:1010284 libraryscience:1006545 linguistics:1009059 lisa:1007519 litcollectioneawso:1009776 litcollectionlittheory:1010514 llba:1007521 marketresearch:10000239 materialsscijournals:1007851 medline:1007527 middleeastafrica:1009060 middleeastnews:1006075 midwestnews1:1009067 military:1007156 msindex:10000352 nahs:1007107 ncjrs:1007535 northcentralnews:1009065 northeastnews1:1009068 nytimes:1005701 pais:10000017 physicaleducation:1007555 pilots:1007557 policyfile:1009062 politicalscience:1005684 pqdtglobal1:1010268 pqdtlocal1006887:1006887 pqrl:10000025 psychology:1007106 publiccontent:1009240 publichealth:1007617 religion:1005641 rsa:1010010 sciencejournals:1000283 socabs:1007480 socialservices:1007485 sociology:1005683 socscijournals:1007200 southcentralnews:1009066 southeastnews:1009069 tdmstudiounl:1010230 telecomms:1006986 turkey:1009063 ukireland:1009064 wallstreetjournal:1006968 washingtonpost:1005922 westnews:1009070 wlitshell:10000365 wma:10000228 wpsa:1007566 wwd:1008717; + XML Gateway software version: 2024.11.0.1605, dated 2024-10-31 + Execution time: authentication 0.0s; search 0.3s; retrieval 0.0s; total 0.3s + + 1005641 + religion + Religion Database + 1 + + + 10000025 + pqrl + Research Library + 7 + + + \ No newline at end of file diff --git a/module/VuFind/tests/fixtures/proquestfsg/searchresult.xml b/module/VuFind/tests/fixtures/proquestfsg/searchresult.xml new file mode 100644 index 00000000000..dd8607f6cdc --- /dev/null +++ b/module/VuFind/tests/fixtures/proquestfsg/searchresult.xml @@ -0,0 +1,318 @@ + + + 1.2 + 31 + + + 1 + marcxml + xml + + + 00000nab a2200000uu 4500 + 2615626038 + UK-CbPIL + + 0164-0178 + + + 1086-3141 + + + 0146-5511 + + + 0002-9068 + + + 2615626038 + + + d20210701 + d20210731 + + + 12342 + nlm + + + Jenna Weissman Joselit + + + <i>Painted Pomegranates and Needlepoint Rabbis: How Jews Craft Resilience and Craft Community</i> by Jodi Eichler-Levine (review) + + + Johns Hopkins University Press + Jul 2021 + + + Book Review + + + The Pomegranate Guild of Judaic Needlework, established in 1977 to foster "synagogue decoration, Judaic symbolism, Jewish art and Judaic embroidery," and Jewish Hearts for Pittsburgh, a digital group some one thousand members strong that arose more recently, in the wake of the deadly 2018 Tree of Life shootings, are among them (103). + +Paying close attention to what they created, Eichler-Levine, herself a member of the Jewish craft community, explores a wide array of handmade goods, from the Pussyhat, the hot pink knitted cap with pointed cat ears worn by millions of women in 2017 in protest against then-President Trump, to the traditional wimple whose impetus has recently expanded to include all sorts of lifecycle moments, not just the birth of a son. + +In its compelling analysis and, yes, in its embrace of Jewish women's craft culture, the book repeatedly rings the bell in favor of material culture, sounding now and again much more like a brief, an exercise in special pleading, than a confident narrative. + + + Judaic studies + + + Clergy + + + Jewish people + + + Symbolism + + + American Jewish History + vol. 105, no. 3 (Jul 2021), p. 433 + + + ProQuest + Religion Database + + + Citation/Abstract + https://www.proquest.com/docview/2615626038/abstract/embedded/UHA0DUZFOHJEPDBM?source=fedsrch + + + Full Text + https://www.proquest.com/docview/2615626038/fulltext/embedded/UHA0DUZFOHJEPDBM?source=fedsrch + + + Full Text - PDF + https://www.proquest.com/docview/2615626038/fulltextPDF/embedded/UHA0DUZFOHJEPDBM?source=fedsrch + + + + + + 2 + marcxml + xml + + + 00000nab a2200000uu 4500 + 2432781939 + UK-CbPIL + + 1948-7428 + + + 1948-741X + + + 0042-6598 + + + 2432781939 + + + d20200815 + + + 157528 + nlm + + + PAINTED POMEGRANATES AND NEEDLEPOINT RABBIS + + + Kirkus Media LLC + Aug 15, 2020 + + + Book Review + + + An academic look at Jewish crafts. + + + Nonfiction + + + Handicrafts + + + Jewish people + + + Jews + + + Ethnology + + + Ethnic Groups + + + Coping + + + Resilience (Psychology) + + + Resistance (Psychology) + + + Kirkus Reviews + vol. LXXXVIII, no. 16 (Aug 15, 2020) + + + ProQuest + Library Science Database + + + Citation/Abstract + https://www.proquest.com/docview/2432781939/abstract/embedded/UHA0DUZFOHJEPDBM?source=fedsrch + + + Full Text + https://www.proquest.com/docview/2432781939/fulltext/embedded/UHA0DUZFOHJEPDBM?source=fedsrch + + + + + + + Original CQL query: (cql.serverChoice all "painted pomegranates and needlepoint rabbis") + Converted to ProQuest query: ALLFIELDS("painted" AND "pomegranates" AND "and" AND "needlepoint" AND "rabbis") + ProQuest limiters: None + Navigators: database + Sort order: relevance + Databases searched by this request are: 20drama:1008836 abidateline:1007139 abiglobal:1000001 abitrade:1007133 accountingtaxbanking:10000231 africannews:1007059 agriculturejournals:1007160 americanperiodicals:10000019 anz:1009046 anznews:1007061 artshumanities:1000277 asianeuropeanbusiness:10000236 asianews:1007060 assia:1007429 avon:1009174 aws:1008818 biologicalscijournals:1007856 britishperiodicals:10000001 canadiannews:1007330 career:10000026 cbcacomplete:10000023 cbs60m:1009241 chicagotribune:1005635 compscijour:1008043 conteurope:1009048 coronavirus:1009903 criminaljusticeperiodicals:1007025 eaasdb:1009715 eas:1010553 eastcentraleurope:1009050 eastsouthasia:1009049 ebookcentral1:1009388 education:1007161 eebo:1009636 engindex:10000353 engineeringjournals:1007853 eric:1007399 esdb:1009714 europeannews:1007062 familyhealth:1006520 globalwires:1009054 healthcompleteshell:10000155 healthmanagement:1006481 hightechjournals:1007852 hispanicnews:1009047 hnpnewyorktimes:1007155 hnppennsylvaniacollection:1009887 hnpphiladelphiainquirer:1009157 hnppittsburghpostgazette:1009159 ibss:1007409 indianjournals:10000204 latimes:1005692 latinamericaiberian:1009056 latinamericanews1:1009057 latx:1010284 libraryscience:1006545 linguistics:1009059 lisa:1007519 litcollectioneawso:1009776 litcollectionlittheory:1010514 llba:1007521 marketresearch:10000239 materialsscijournals:1007851 medline:1007527 middleeastafrica:1009060 middleeastnews:1006075 midwestnews1:1009067 military:1007156 msindex:10000352 nahs:1007107 ncjrs:1007535 northcentralnews:1009065 northeastnews1:1009068 nytimes:1005701 pais:10000017 physicaleducation:1007555 pilots:1007557 policyfile:1009062 politicalscience:1005684 pqdtglobal1:1010268 pqdtlocal1006887:1006887 pqrl:10000025 psychology:1007106 publiccontent:1009240 publichealth:1007617 religion:1005641 rsa:1010010 sciencejournals:1000283 socabs:1007480 socialservices:1007485 sociology:1005683 socscijournals:1007200 southcentralnews:1009066 southeastnews:1009069 tdmstudiounl:1010230 telecomms:1006986 turkey:1009063 ukireland:1009064 wallstreetjournal:1006968 washingtonpost:1005922 westnews:1009070 wlitshell:10000365 wma:10000228 wpsa:1007566 wwd:1008717 + Subscribed databases (codes and IDs) are: Academic databases - 20drama:1008836 abidateline:1007139 abiglobal:1000001 abitrade:1007133 accountingtaxbanking:10000231 africannews:1007059 agriculturejournals:1007160 americanperiodicals:10000019 anz:1009046 anznews:1007061 artshumanities:1000277 asianeuropeanbusiness:10000236 asianews:1007060 assia:1007429 avon:1009174 aws:1008818 biologicalscijournals:1007856 britishperiodicals:10000001 canadiannews:1007330 career:10000026 cbcacomplete:10000023 cbs60m:1009241 chicagotribune:1005635 compscijour:1008043 conteurope:1009048 coronavirus:1009903 criminaljusticeperiodicals:1007025 eaasdb:1009715 eas:1010553 eastcentraleurope:1009050 eastsouthasia:1009049 ebookcentral1:1009388 education:1007161 eebo:1009636 engindex:10000353 engineeringjournals:1007853 eric:1007399 esdb:1009714 europeannews:1007062 familyhealth:1006520 globalwires:1009054 healthcompleteshell:10000155 healthmanagement:1006481 hightechjournals:1007852 hispanicnews:1009047 hnpnewyorktimes:1007155 hnppennsylvaniacollection:1009887 hnpphiladelphiainquirer:1009157 hnppittsburghpostgazette:1009159 ibss:1007409 indianjournals:10000204 latimes:1005692 latinamericaiberian:1009056 latinamericanews1:1009057 latx:1010284 libraryscience:1006545 linguistics:1009059 lisa:1007519 litcollectioneawso:1009776 litcollectionlittheory:1010514 llba:1007521 marketresearch:10000239 materialsscijournals:1007851 medline:1007527 middleeastafrica:1009060 middleeastnews:1006075 midwestnews1:1009067 military:1007156 msindex:10000352 nahs:1007107 ncjrs:1007535 northcentralnews:1009065 northeastnews1:1009068 nytimes:1005701 pais:10000017 physicaleducation:1007555 pilots:1007557 policyfile:1009062 politicalscience:1005684 pqdtglobal1:1010268 pqdtlocal1006887:1006887 pqrl:10000025 psychology:1007106 publiccontent:1009240 publichealth:1007617 religion:1005641 rsa:1010010 sciencejournals:1000283 socabs:1007480 socialservices:1007485 sociology:1005683 socscijournals:1007200 southcentralnews:1009066 southeastnews:1009069 tdmstudiounl:1010230 telecomms:1006986 turkey:1009063 ukireland:1009064 wallstreetjournal:1006968 washingtonpost:1005922 westnews:1009070 wlitshell:10000365 wma:10000228 wpsa:1007566 wwd:1008717; + XML Gateway software version: 2024.11.0.1605, dated 2024-10-31 + Execution time: authentication 0.3s; search 0.2s; retrieval 0.0s; total 0.4s + + 1007107 + nahs + Nursing & Allied Health Database + 1 + + + 1009068 + northeastnews1 + U.S. Northeast Newsstream + 1 + + + 1005922 + washingtonpost + The Washington Post + 1 + + + 1005641 + religion + Religion Database + 10 + + + 10000025 + pqrl + Research Library + 20 + + + 10000155 + healthcompleteshell + Health & Medical Collection + 1 + + + 1009240 + publiccontent + Publicly Available Content Database + 1 + + + 1007139 + abidateline + ABI/INFORM Dateline + 1 + + + 1007133 + abitrade + ABI/INFORM Trade & Industry + 1 + + + 1000001 + abiglobal + ABI/INFORM Global + 1 + + + 1009388 + ebookcentral1 + Ebook Central + 11 + + + 1005683 + sociology + Sociology Database + 2 + + + 1007480 + socabs + Sociological Abstracts + 3 + + + 1007519 + lisa + Library & Information Science Abstracts (LISA) + 1 + + + 1006545 + libraryscience + Library Science Database + 2 + + + 1007409 + ibss + International Bibliography of the Social Sciences (IBSS) + 4 + + + 1007566 + wpsa + Worldwide Political Science Abstracts + 1 + + + 1005684 + politicalscience + Political Science Database + 2 + + + 1007161 + education + Education Database + 2 + + + 1007200 + socscijournals + Social Science Database + 5 + + + 1010268 + pqdtglobal1 + ProQuest Dissertations & Theses Global + 4 + + + \ No newline at end of file diff --git a/module/VuFind/tests/unit-tests/src/VuFindTest/Recommend/ProQuestFSGResultsDeferredTest.php b/module/VuFind/tests/unit-tests/src/VuFindTest/Recommend/ProQuestFSGResultsDeferredTest.php new file mode 100644 index 00000000000..093fa86867c --- /dev/null +++ b/module/VuFind/tests/unit-tests/src/VuFindTest/Recommend/ProQuestFSGResultsDeferredTest.php @@ -0,0 +1,62 @@ + + * @author Maccabee Levine + * @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\Recommend; + +/** + * ProQuestFSGResultsDeferred recommendation module Test Class + * + * @category VuFind + * @package Tests + * @author Demian Katz + * @author Maccabee Levine + * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License + * @link https://vufind.org/wiki/development:testing:unit_tests Wiki + */ +class ProQuestFSGResultsDeferredTest extends \VuFindTest\Unit\RecommendDeferredTestCase +{ + /** + * Test standard operation + * + * @return void + */ + public function testStandardOperation() + { + $mod = $this->getRecommend( + \VuFind\Recommend\ProQuestFSGResultsDeferred::class, + ':3', + new \Laminas\Stdlib\Parameters(['lookfor' => 'foo']) + ); + $this->assertEquals( + 'mod=ProQuestFSGResults¶ms=lookfor%3A3&lookfor=foo', + $mod->getUrlParams() + ); + } +} diff --git a/module/VuFindSearch/src/VuFindSearch/Backend/ProQuestFSG/Connector.php b/module/VuFindSearch/src/VuFindSearch/Backend/ProQuestFSG/Connector.php index adb6acbbeba..a1e3d18ac99 100644 --- a/module/VuFindSearch/src/VuFindSearch/Backend/ProQuestFSG/Connector.php +++ b/module/VuFindSearch/src/VuFindSearch/Backend/ProQuestFSG/Connector.php @@ -91,10 +91,11 @@ public function __construct( * @param ParamBag $params Parameters * * @throws \Exception - * @return string MARC XML + * @return array */ public function getRecord($id, ParamBag $params = null) { + $params ??= new ParamBag(); $params->set('query', "rec.identifier = \"{$id}\""); return $this->search($params, 1, 1); } @@ -106,7 +107,7 @@ public function getRecord($id, ParamBag $params = null) * @param int $offset Search offset * @param int $limit Search limit * - * @return string + * @return array */ public function search(ParamBag $params, $offset, $limit) { diff --git a/module/VuFindSearch/tests/unit-tests/src/VuFindTest/Backend/ProQuestFSG/BackendTest.php b/module/VuFindSearch/tests/unit-tests/src/VuFindTest/Backend/ProQuestFSG/BackendTest.php new file mode 100644 index 00000000000..0ee11d7f9db --- /dev/null +++ b/module/VuFindSearch/tests/unit-tests/src/VuFindTest/Backend/ProQuestFSG/BackendTest.php @@ -0,0 +1,133 @@ + + * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License + * @link https://vufind.org + */ + +namespace VuFindTest\Backend\ProQuestFSG; + +use PHPUnit\Framework\MockObject\MockObject; +use PHPUnit\Framework\TestCase; +use VuFindSearch\Backend\ProQuestFSG\Backend; +use VuFindSearch\Backend\ProQuestFSG\Connector; +use VuFindSearch\Backend\ProQuestFSG\Response\XML\RecordCollectionFactory; + +/** + * Unit tests for ProQuestFSG backend. + * + * @category VuFind + * @package Search + * @author Maccabee Levine + * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License + * @link https://vufind.org + */ +class BackendTest extends TestCase +{ + use \VuFindTest\Feature\FixtureTrait; + + /** + * Test performing a search. + * + * @return void + */ + public function testSearch() + { + $connector = $this->getConnector('proquestfsg/connector_searchresult.json'); + $backend = new Backend( + $connector, + $this->getRecordCollectionFactory() + ); + $collection = $backend->search( + new \VuFindSearch\Query\Query( + 'painted pomegranates and needlepoint rabbis', + 'cql.serverChoice' + ), + 1, + 20 + ); + $this->assertCount(2, $collection); + $this->assertEquals('ProQuestFSG', $collection->getSourceIdentifier()); + $this->assertEquals( + 'ProQuestFSG', + $collection->getRecords()[0]->getSourceIdentifier() + ); + } + + /** + * Test retrieving a record. + * + * @return void + */ + public function testRetrieve() + { + $connector = $this->getConnector('proquestfsg/connector_record.json'); + $backend = new Backend( + $connector, + $this->getRecordCollectionFactory() + ); + $collection = $backend->retrieve( + '2811962947' + ); + $this->assertCount(1, $collection); + $this->assertEquals('ProQuestFSG', $collection->getSourceIdentifier()); + $this->assertEquals( + 'ProQuestFSG', + $collection->getRecords()[0]->getSourceIdentifier() + ); + } + + /** + * Build a RecordCollectionFactory. + * + * @return RecordCollectionFactory + */ + protected function getRecordCollectionFactory(): RecordCollectionFactory + { + $callback = function ($data) { + $driver = new \VuFind\RecordDriver\ProQuestFSG(); + $driver->setRawData($data); + return $driver; + }; + return new RecordCollectionFactory($callback); + } + + /** + * Mock a connector. + * + * @param string $responseFixtureName Fixture to load for connector response + * + * @return Connector + */ + protected function getConnector($responseFixtureName): MockObject&Connector + { + $fixture = $this->getFixture($responseFixtureName); + $response = json_decode($fixture, true); + $connector = $this->createMock(Connector::class); + $connector->method('search')->willReturn($response); + $connector->method('getRecord')->willReturn($response); + return $connector; + } +} diff --git a/module/VuFindSearch/tests/unit-tests/src/VuFindTest/Backend/ProQuestFSG/ConnectorTest.php b/module/VuFindSearch/tests/unit-tests/src/VuFindTest/Backend/ProQuestFSG/ConnectorTest.php new file mode 100644 index 00000000000..2e5f21025d0 --- /dev/null +++ b/module/VuFindSearch/tests/unit-tests/src/VuFindTest/Backend/ProQuestFSG/ConnectorTest.php @@ -0,0 +1,124 @@ + + * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License + * @link https://vufind.org + */ + +namespace VuFindTest\Backend\ProQuestFSG; + +use Laminas\Http\Client; +use VuFindSearch\Backend\ProQuestFSG\Connector; +use VuFindSearch\ParamBag; + +/** + * Unit tests for ProQuestFSG connector. + * + * @category VuFind + * @package Search + * @author Maccabee Levine + * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License + * @link https://vufind.org + */ +class ConnectorTest extends \PHPUnit\Framework\TestCase +{ + use \VuFindTest\Feature\FixtureTrait; + + /** + * Test search. + * + * @return void + */ + public function testSearch() + { + $responseBody = $this->getFixture('proquestfsg/searchresult.xml'); + $connector = $this->getConnector( + $this->getMockClient($responseBody) + ); + $params = new ParamBag([ + 'query' => '(cql.serverChoice all "painted pomegranates and needlepoint rabbis")', + 'x-navigators' => 'database', + 'sortKey' => 'relevance', + ]); + $searchResult = $connector->search($params, 1, 2); + $this->assertEquals(1, $searchResult['offset']); + $this->assertEquals(31, $searchResult['total']); + $this->assertCount(21, $searchResult['facets']['Databases']); + $this->assertCount(2, $searchResult['docs']); + } + + /** + * Test getRecord. + * + * @return void + */ + public function testGetRecord() + { + $responseBody = $this->getFixture('proquestfsg/record.xml'); + $connector = $this->getConnector( + $this->getMockClient($responseBody) + ); + $searchResult = $connector->getRecord('2811962947'); + $this->assertEquals(1, $searchResult['offset']); + $this->assertEquals(1, $searchResult['total']); + $this->assertCount(2, $searchResult['facets']['Databases']); + $this->assertCount(1, $searchResult['docs']); + } + + /** + * Get a mock HTTP client. + * + * @param string $responseBody Response body returned by client. + * + * @return MockObject&Client + */ + protected function getMockClient($responseBody) + { + $client = $this->createMock(\Laminas\Http\Client::class); + $response = $this->createMock(\Laminas\Http\Response::class); + $response->expects($this->once())->method('isSuccess') + ->willReturn(true); + $response->expects($this->once())->method('getBody') + ->willReturn($responseBody); + $client->expects($this->once())->method('setMethod') + ->willReturn($client); + $client->expects($this->once())->method('send') + ->willReturn($response); + return $client; + } + + /** + * Get a connector. + * + * @param Client $client HTTP client + * + * @return Connector + */ + protected function getConnector($client) + { + $connector = new Connector($client); + return $connector; + } +} From f1c377653d4a6dfe477d9d2d157d0ab409c92645 Mon Sep 17 00:00:00 2001 From: Maccabee Levine <31278545+maccabeelevine@users.noreply.github.com> Date: Fri, 8 Nov 2024 11:27:15 -0500 Subject: [PATCH 30/34] Remove blank line Co-authored-by: Demian Katz --- config/vufind/ProQuestFSG.ini | 1 - 1 file changed, 1 deletion(-) diff --git a/config/vufind/ProQuestFSG.ini b/config/vufind/ProQuestFSG.ini index dcaa1c6025d..73e84f0db30 100644 --- a/config/vufind/ProQuestFSG.ini +++ b/config/vufind/ProQuestFSG.ini @@ -60,7 +60,6 @@ load_results_with_js = true ;[TopRecommendations] ; No search-specific settings by default -- add your own here. - ; The order of display is as shown below ; The name of the index field is on the left ; The display name of the field is on the right From e3824df1854252720c008b2ed91a26b6f2f0afa5 Mon Sep 17 00:00:00 2001 From: Maccabee Levine Date: Fri, 8 Nov 2024 16:34:53 +0000 Subject: [PATCH 31/34] Perform search if necessary before getting facet list. --- module/VuFind/src/VuFind/Search/ProQuestFSG/Results.php | 3 +++ 1 file changed, 3 insertions(+) diff --git a/module/VuFind/src/VuFind/Search/ProQuestFSG/Results.php b/module/VuFind/src/VuFind/Search/ProQuestFSG/Results.php index 8324d2beff0..a7c45f0c607 100644 --- a/module/VuFind/src/VuFind/Search/ProQuestFSG/Results.php +++ b/module/VuFind/src/VuFind/Search/ProQuestFSG/Results.php @@ -101,6 +101,9 @@ protected function performSearch() */ public function getFacetList($filter = null) { + if (null === $this->simplifiedResponseFacets) { + $this->performAndProcessSearch(); + } return $this->buildFacetList($this->simplifiedResponseFacets, $filter); } From 645eb829a11de6b3adf38d703e919498b6c0fb77 Mon Sep 17 00:00:00 2001 From: Maccabee Levine <31278545+maccabeelevine@users.noreply.github.com> Date: Fri, 8 Nov 2024 11:37:01 -0500 Subject: [PATCH 32/34] Simplify conditional ParamBag creation Co-authored-by: Demian Katz --- .../src/VuFindSearch/Backend/ProQuestFSG/Backend.php | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/module/VuFindSearch/src/VuFindSearch/Backend/ProQuestFSG/Backend.php b/module/VuFindSearch/src/VuFindSearch/Backend/ProQuestFSG/Backend.php index bb069a7a497..57ce83a4413 100644 --- a/module/VuFindSearch/src/VuFindSearch/Backend/ProQuestFSG/Backend.php +++ b/module/VuFindSearch/src/VuFindSearch/Backend/ProQuestFSG/Backend.php @@ -98,9 +98,7 @@ public function search( $limit, ParamBag $params = null ) { - if (null === $params) { - $params = new ParamBag(); - } + $params ??= new ParamBag(); $params->mergeWith($this->getQueryBuilder()->build($query)); $response = $this->connector->search($params, $offset, $limit); $collection = $this->createRecordCollection($response); From 6b9ce46b33f09be339d38942cbab672214bc05fc Mon Sep 17 00:00:00 2001 From: Maccabee Levine Date: Fri, 8 Nov 2024 16:38:53 +0000 Subject: [PATCH 33/34] Clean code. --- .../ProQuestFSG/Response/XML/RecordCollectionFactory.php | 1 - module/VuFindSearch/src/VuFindSearch/Backend/SRU/Connector.php | 2 -- 2 files changed, 3 deletions(-) diff --git a/module/VuFindSearch/src/VuFindSearch/Backend/ProQuestFSG/Response/XML/RecordCollectionFactory.php b/module/VuFindSearch/src/VuFindSearch/Backend/ProQuestFSG/Response/XML/RecordCollectionFactory.php index 2784c8b2d64..1f7685ffc2e 100644 --- a/module/VuFindSearch/src/VuFindSearch/Backend/ProQuestFSG/Response/XML/RecordCollectionFactory.php +++ b/module/VuFindSearch/src/VuFindSearch/Backend/ProQuestFSG/Response/XML/RecordCollectionFactory.php @@ -78,7 +78,6 @@ public function __construct($recordFactory = null, $collectionClass = null) { if (null === $recordFactory) { $recordFactory = function ($i) { - // return new Record(new MarcReader($i)); $reader = new MarcReader($i); $record = new Record($reader); return $record; diff --git a/module/VuFindSearch/src/VuFindSearch/Backend/SRU/Connector.php b/module/VuFindSearch/src/VuFindSearch/Backend/SRU/Connector.php index 46caf14a6b1..8512079f3ac 100644 --- a/module/VuFindSearch/src/VuFindSearch/Backend/SRU/Connector.php +++ b/module/VuFindSearch/src/VuFindSearch/Backend/SRU/Connector.php @@ -71,8 +71,6 @@ class Connector implements \Laminas\Log\LoggerAwareInterface */ protected $host; - protected $defaultPath = ''; - /** * The version to specify in the URL * From 2a4c875e84e2dab5c5c4de7c11f8940fae9d9379 Mon Sep 17 00:00:00 2001 From: Maccabee Levine Date: Fri, 8 Nov 2024 16:40:20 +0000 Subject: [PATCH 34/34] Protect missing docs in response --- .../ProQuestFSG/Response/XML/RecordCollectionFactory.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/module/VuFindSearch/src/VuFindSearch/Backend/ProQuestFSG/Response/XML/RecordCollectionFactory.php b/module/VuFindSearch/src/VuFindSearch/Backend/ProQuestFSG/Response/XML/RecordCollectionFactory.php index 1f7685ffc2e..7f69320abc8 100644 --- a/module/VuFindSearch/src/VuFindSearch/Backend/ProQuestFSG/Response/XML/RecordCollectionFactory.php +++ b/module/VuFindSearch/src/VuFindSearch/Backend/ProQuestFSG/Response/XML/RecordCollectionFactory.php @@ -107,7 +107,7 @@ public function factory($response) ); } $collection = new $this->collectionClass($response); - foreach ($response['docs'] as $doc) { + foreach ($response['docs'] ?? [] as $doc) { $collection->add(call_user_func($this->recordFactory, $doc), false); } return $collection;