diff --git a/config/vufind/RecordTabs.ini b/config/vufind/RecordTabs.ini index 1f0ab31c9be..12918bcd5ab 100644 --- a/config/vufind/RecordTabs.ini +++ b/config/vufind/RecordTabs.ini @@ -133,16 +133,6 @@ tabs[Preview] = preview tabs[Details] = StaffViewArray defaultTab = null -[VuFind\RecordDriver\WorldCat] -tabs[Holdings] = HoldingsWorldCat -tabs[Description] = Description -tabs[TOC] = TOC -tabs[UserComments] = UserComments -tabs[Reviews] = Reviews -tabs[Excerpt] = Excerpt -tabs[Details] = StaffViewMARC -defaultTab = null - [VuFind\RecordDriver\WorldCat2] tabs[Holdings] = HoldingsWorldCat2 tabs[Description] = Description diff --git a/config/vufind/WorldCat.ini b/config/vufind/WorldCat.ini deleted file mode 100644 index f17612e6b3f..00000000000 --- a/config/vufind/WorldCat.ini +++ /dev/null @@ -1,89 +0,0 @@ -; This section contains global settings affecting search behavior. -[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 - -;default_noresults_recommend[] = SwitchTab - -; This section shows which search types will display in the basic search box at -; the top of WorldCat pages. The name of each setting below corresponds with one -; or more indices defined in the WorldCat API (multiple values are separated by -; colons). 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. -; -; For a complete list of legal values, see the SRU Explain page here: -; http://worldcat.org/webservices/catalog/ -[Basic_Searches] -srw.kw = "All Fields" -srw.ti:srw.se = Title -srw.au = Author -srw.su = Subject -srw.dd:srw.lc = "Call Number" -srw.bn:srw.in = "ISBN/ISSN" - -; 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] -srw.kw = adv_search_all -srw.ti:srw.se = adv_search_title -srw.au = adv_search_author -srw.su = adv_search_subject -srw.dd:srw.lc = adv_search_callnumber -srw.bn:srw.in = adv_search_isn -srw.pb = adv_search_publisher -srw.se = adv_search_series -srw.yr = adv_search_year - -; This section defines the sort options available on WorldCat search results. -; Values on the left of the equal sign are WorldCat API sort values. Values -; on the right of the equal sign are text that will be run through the -; translation module and displayed on screen. -[Sorting] -relevance = sort_relevance -Date,,0 = sort_year -Date = sort_year_asc -Author = sort_author -Title = sort_title - -; This section allows you to specify hidden sorting options. They can be used to create a -; whitelist of sort values using regular expressions. If you want to do this add regexes to -; the pattern[] array. All sort values that match at least one of these pattern are allowed -; in searches. But they will not be shown in the sort selection in the result list. -[HiddenSorting] -;pattern[] = .* ; E.g. uncomment this line to allow any value - -; This section controls the behavior of the WorldCatRecord module. See the -; [Record] section of the main config.ini for more detailed documentation. -[Record] -; Because the WorldCat database changes frequently, this feature sometimes -; behaves unpredictably; it is recommended that you leave it disabled: -next_prev_navigation = false - -related[] = "WorldCatSimilar" - -; 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 contains additional settings to pass to the WorldCat connector -; code. -[Connector] -; Set this to the latitude,longitude position of your library to ensure that -; custom holding locations are retrieved from your region first. -;latLon = "40.0373881,-75.3442107" - -; When looking up holdings at other libraries, should we retrieve holdings for -; any record matching the FRBR group (true) or only for exact matches (false)? -;useFrbrGroupingForHoldings = false diff --git a/config/vufind/combined.ini b/config/vufind/combined.ini index b074ebb7ca2..2731d258d40 100644 --- a/config/vufind/combined.ini +++ b/config/vufind/combined.ini @@ -1,5 +1,5 @@ ; This file controls the "combined search" module. Each section is named for a -; search backend (e.g. "Solr", "Summon", "WorldCat", etc.). If you want to create +; search backend (e.g. "Solr", "Summon", "WorldCat2", etc.). If you want to create ; multiple columns using the same backend but different settings, you may add a ; colon and a suffix (e.g. "Solr:filter1", "Solr:filter2") to differentiate the ; sections. diff --git a/config/vufind/config.ini b/config/vufind/config.ini index 81fe7ce275c..0d2d33fa780 100644 --- a/config/vufind/config.ini +++ b/config/vufind/config.ini @@ -1377,15 +1377,6 @@ url = "https://api.booksite.com" ;apiId = myAccessId ;apiKey = mySecretKey -; This section must be filled in if you plan to use the optional WorldCat -; search module. Otherwise, it may be ignored. -;[WorldCat] -;Your WorldCat search API key -;apiKey = "long-search-api-key-goes-here" -;Your holdings symbol (usually a three-letter code) - used for excluding your -; institution's holdings from the search results. -;OCLCCode = MYCODE - ; This section must be filled in to use Relais functionality. When ; activated, this function will allow users to place ILL requests on unavailable ; items through the record holdings tab. @@ -2127,7 +2118,6 @@ hide_holdings[] = "World Wide Web" ; MoreByAuthorSolr - Display books from the Solr index matching the current ; record's primary author. ; Similar - Similarity based on Solr lookup -; WorldCatSimilar - Similarity based on WorldCat lookup ; WorldCat2Similar - Similarity based on WorldCat v2 lookup related[] = "Similar" ;related[] = "MoreByAuthorSolr" @@ -2590,7 +2580,7 @@ max_tag_length = 64 case_sensitive_tags = false ; If this setting is set to false, users will not be presented with a search ; drop-down or advanced search link when searching/viewing tags. This is recommended -; when using a multi-backend system (e.g. Solr + Summon + WorldCat). If set to +; when using a multi-backend system (e.g. Solr + Summon + WorldCat2). If set to ; true, the standard Solr search options and advanced search link will be shown ; in the tag screens; this is recommended when using a Solr-only configuration. show_solr_options_in_tag_search = false diff --git a/languages/ILSMessages/es.ini b/languages/ILSMessages/es.ini index c746610e8c8..453ade9f89b 100644 --- a/languages/ILSMessages/es.ini +++ b/languages/ILSMessages/es.ini @@ -2,7 +2,7 @@ available_for_pickup_notification = "Tiene material disponible para recoger" checkout_block = "No puedes retirar más tems" electronic_resources_block = "No puede acceder a recursos electrónicos" hold_wrong_user_institution = "No puede reservar material de la biblioteca solicitada." -ill_item_renewal_limit = "Devolución en la fecha de vencimiento." +ill_item_renewal_limit = "Devolución en la fecha de vencimiento (máx. de renovaciones alcanzado)." ill_renewal_too_soon = "El ítem se renovará automáticamente (a menos que otros lo soliciten)" lost_card = "Su tarjeta ha sido reportada como perdida" message_from_library = "Tiene un mensaje de su biblioteca" diff --git a/module/VuFind/config/module.config.php b/module/VuFind/config/module.config.php index 440949ecdb9..283abde9f58 100644 --- a/module/VuFind/config/module.config.php +++ b/module/VuFind/config/module.config.php @@ -225,7 +225,6 @@ 'VuFind\Controller\UpgradeController' => 'VuFind\Controller\UpgradeControllerFactory', 'VuFind\Controller\WebController' => 'VuFind\Controller\AbstractBaseFactory', 'VuFind\Controller\WorldcatController' => 'VuFind\Controller\AbstractBaseFactory', - 'VuFind\Controller\WorldcatrecordController' => 'VuFind\Controller\AbstractBaseFactory', 'VuFind\Controller\Worldcat2Controller' => 'VuFind\Controller\AbstractBaseFactory', 'VuFind\Controller\Worldcat2recordController' => 'VuFind\Controller\AbstractBaseFactory', ], @@ -353,8 +352,9 @@ 'web' => 'VuFind\Controller\WebController', 'Worldcat' => 'VuFind\Controller\WorldcatController', 'worldcat' => 'VuFind\Controller\WorldcatController', - 'WorldcatRecord' => 'VuFind\Controller\WorldcatrecordController', - 'worldcatrecord' => 'VuFind\Controller\WorldcatrecordController', + // Remap legacy WorldcatRecord action to point to Worldcat2recordController + 'WorldcatRecord' => 'VuFind\Controller\Worldcat2recordController', + 'worldcatrecord' => 'VuFind\Controller\Worldcat2recordController', 'Worldcat2' => 'VuFind\Controller\Worldcat2Controller', 'worldcat2' => 'VuFind\Controller\Worldcat2Controller', 'Worldcat2Record' => 'VuFind\Controller\Worldcat2recordController', diff --git a/module/VuFind/src/VuFind/Config/Feature/IniReaderTrait.php b/module/VuFind/src/VuFind/Config/Feature/IniReaderTrait.php index d41561b4131..ffab6575d86 100644 --- a/module/VuFind/src/VuFind/Config/Feature/IniReaderTrait.php +++ b/module/VuFind/src/VuFind/Config/Feature/IniReaderTrait.php @@ -59,9 +59,8 @@ trait IniReaderTrait protected function getIniReader() { if (null == $this->iniReader) { - // Use ASCII 0 as a nest separator; otherwise some of the unusual key names - // we have (i.e. in WorldCat.ini search options) will get parsed in - // unexpected ways. + // Use ASCII 0 as a nest separator; otherwise some of our unusual key names + // (e.g. strings containing . characters) will get parsed in unexpected ways. $this->iniReader = new IniReader(); $this->iniReader->setNestSeparator(chr(0)); } diff --git a/module/VuFind/src/VuFind/Config/Upgrade.php b/module/VuFind/src/VuFind/Config/Upgrade.php index 6f4ad3ac749..afc3cc7be97 100644 --- a/module/VuFind/src/VuFind/Config/Upgrade.php +++ b/module/VuFind/src/VuFind/Config/Upgrade.php @@ -168,7 +168,6 @@ public function run() $this->upgradeSms(); $this->upgradeSummon(); $this->upgradePrimo(); - $this->upgradeWorldCat(); // The previous upgrade routines may have added values to permissions.ini, // so we should save it last. It doesn't have its own upgrade routine. @@ -621,24 +620,13 @@ protected function upgradeConfig() } // Warn the user about deprecated WorldCat settings: - if (isset($newConfig['WorldCat']['LimitCodes'])) { - unset($newConfig['WorldCat']['LimitCodes']); + if (isset($newConfig['WorldCat'])) { + unset($newConfig['WorldCat']); $this->addWarning( - 'The [WorldCat] LimitCodes setting never had any effect and has been' - . ' removed.' + 'The [WorldCat] section of config.ini has been removed following' + . ' the shutdown of the v1 WorldCat search API; use WorldCat2.ini instead.' ); } - $badKeys - = ['id', 'xISBN_token', 'xISBN_secret', 'xISSN_token', 'xISSN_secret']; - foreach ($badKeys as $key) { - if (isset($newConfig['WorldCat'][$key])) { - unset($newConfig['WorldCat'][$key]); - $this->addWarning( - 'The [WorldCat] ' . $key . ' setting is no longer used and' - . ' has been removed.' - ); - } - } if ( isset($newConfig['Record']['related']) && in_array('Editions', $newConfig['Record']['related']) @@ -1232,59 +1220,6 @@ protected function upgradePrimoServerSettings() } } - /** - * Upgrade WorldCat.ini. - * - * @throws FileAccessException - * @return void - */ - protected function upgradeWorldCat() - { - // If WorldCat is disabled in our current configuration, we don't need to - // load any WorldCat-specific settings: - if (!isset($this->newConfigs['config.ini']['WorldCat']['apiKey'])) { - return; - } - - // we want to retain the old installation's search settings exactly as-is - $groups = [ - 'Basic_Searches', 'Advanced_Searches', 'Sorting', - ]; - $this->applyOldSettings('WorldCat.ini', $groups); - - // we need to fix an obsolete search setting for authors - foreach (['Basic_Searches', 'Advanced_Searches'] as $section) { - $new = []; - foreach ($this->newConfigs['WorldCat.ini'][$section] as $k => $v) { - if ($k == 'srw.au:srw.pn:srw.cn') { - $k = 'srw.au'; - } - $new[$k] = $v; - } - $this->newConfigs['WorldCat.ini'][$section] = $new; - } - - // Deal with deprecated related record module. - $newConfig = & $this->newConfigs['WorldCat.ini']; - if ( - isset($newConfig['Record']['related']) - && in_array('WorldCatEditions', $newConfig['Record']['related']) - ) { - $newConfig['Record']['related'] = array_diff( - $newConfig['Record']['related'], - ['WorldCatEditions'] - ); - $this->addWarning( - 'The WorldCatEditions related record module is no longer ' - . 'supported due to OCLC\'s xID API shutdown.' - . ' It has been removed from your settings.' - ); - } - - // save the file - $this->saveModifiedConfig('WorldCat.ini'); - } - /** * Does the specified properties file contain any meaningful * (non-empty/non-comment) lines? diff --git a/module/VuFind/src/VuFind/Controller/WorldcatController.php b/module/VuFind/src/VuFind/Controller/WorldcatController.php index 8a2725a4f23..b3e931d1854 100644 --- a/module/VuFind/src/VuFind/Controller/WorldcatController.php +++ b/module/VuFind/src/VuFind/Controller/WorldcatController.php @@ -1,11 +1,11 @@ searchClassId = 'WorldCat'; - parent::__construct($sm); + return $this->redirect()->toRoute('worldcat2-home'); } /** - * Is the result scroller active? + * Advanced search action -- redirect to WorldCat v2. * - * @return bool + * @return mixed */ - protected function resultScrollerActive() + public function advancedAction() { - $config = $this->getService(\VuFind\Config\PluginManager::class)->get('WorldCat'); - return $config->Record->next_prev_navigation ?? false; + return $this->redirect()->toRoute('worldcat2-advanced'); } /** - * Search action -- call standard results action + * Search action -- transform search and redirect to WorldCat v2. * * @return mixed */ public function searchAction() { - return $this->resultsAction(); + $params = $this->params()->fromQuery(); + // v1 types are prefixed with "srw." but v2 types are not; convert! + foreach ($params as $key => $value) { + if (str_starts_with($key, 'type')) { + $params[$key] = str_replace('srw.', '', $value); + } + } + return $this->redirect()->toRoute('worldcat2-search', options: ['query' => $params]); } } diff --git a/module/VuFind/src/VuFind/Controller/WorldcatrecordController.php b/module/VuFind/src/VuFind/Controller/WorldcatrecordController.php deleted file mode 100644 index 8ec083c1b4e..00000000000 --- a/module/VuFind/src/VuFind/Controller/WorldcatrecordController.php +++ /dev/null @@ -1,69 +0,0 @@ - - * @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; - -/** - * WorldCat Record Controller - * - * @category VuFind - * @package Controller - * @author Demian Katz - * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License - * @link https://vufind.org Main Site - */ -class WorldcatrecordController extends AbstractRecord -{ - /** - * Constructor - * - * @param ServiceLocatorInterface $sm Service locator - */ - public function __construct(ServiceLocatorInterface $sm) - { - // Override some defaults: - $this->sourceId = 'WorldCat'; - - // 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('WorldCat'); - 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 4910287b0b2..c35c4c4ce46 100644 --- a/module/VuFind/src/VuFind/RecordDriver/PluginManager.php +++ b/module/VuFind/src/VuFind/RecordDriver/PluginManager.php @@ -71,7 +71,6 @@ class PluginManager extends \VuFind\ServiceManager\AbstractPluginManager 'solrreserves' => SolrReserves::class, 'solrweb' => SolrWeb::class, 'summon' => Summon::class, - 'worldcat' => WorldCat::class, 'worldcat2' => WorldCat2::class, ]; @@ -111,7 +110,6 @@ class PluginManager extends \VuFind\ServiceManager\AbstractPluginManager SolrReserves::class => SolrDefaultWithoutSearchServiceFactory::class, SolrWeb::class => SolrWebFactory::class, Summon::class => SummonFactory::class, - WorldCat::class => NameBasedConfigFactory::class, WorldCat2::class => NameBasedConfigFactory::class, ]; diff --git a/module/VuFind/src/VuFind/RecordDriver/WorldCat.php b/module/VuFind/src/VuFind/RecordDriver/WorldCat.php deleted file mode 100644 index e766970a397..00000000000 --- a/module/VuFind/src/VuFind/RecordDriver/WorldCat.php +++ /dev/null @@ -1,83 +0,0 @@ - - * @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 WorldCat. - * - * @category VuFind - * @package RecordDrivers - * @author Demian Katz - * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License - * @link https://vufind.org/wiki/development:plugins:record_drivers Wiki - */ -class WorldCat 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/RecordTab/HoldingsWorldCat.php b/module/VuFind/src/VuFind/RecordTab/HoldingsWorldCat.php deleted file mode 100644 index 1561756e1fb..00000000000 --- a/module/VuFind/src/VuFind/RecordTab/HoldingsWorldCat.php +++ /dev/null @@ -1,108 +0,0 @@ - - * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License - * @link https://vufind.org/wiki/development:plugins:record_tabs Wiki - */ - -namespace VuFind\RecordTab; - -use VuFindSearch\Backend\WorldCat\Command\GetHoldingsCommand; -use VuFindSearch\Service; - -/** - * Holdings (WorldCat) tab - * - * @category VuFind - * @package RecordTabs - * @author Demian Katz - * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License - * @link https://vufind.org/wiki/development:plugins:record_tabs Wiki - */ -class HoldingsWorldCat extends AbstractBase -{ - /** - * Search service - * - * @var Service - */ - protected $searchService; - - /** - * Constructor - * - * @param Service $searchService Search service - */ - public function __construct(Service $searchService) - { - $this->searchService = $searchService; - } - - /** - * Get the on-screen description for this tab. - * - * @return string - */ - public function getDescription() - { - return 'Holdings'; - } - - /** - * Get holdings information from WorldCat (false if none available). - * - * @return \SimpleXMLElement|bool - */ - public function getHoldings() - { - $id = $this->getOCLCNum(); - if (empty($id)) { - return false; - } - $command = new GetHoldingsCommand('WorldCat', $id); - return $this->searchService->invoke($command)->getResult(); - } - - /** - * Is this tab active? - * - * @return bool - */ - public function isActive() - { - $id = $this->getOCLCNum(); - return !empty($id); - } - - /** - * Get the OCLC number from the active record driver. - * - * @return string - */ - protected function getOCLCNum() - { - return $this->getRecordDriver()->tryMethod('getCleanOCLCNum'); - } -} diff --git a/module/VuFind/src/VuFind/RecordTab/HoldingsWorldCatFactory.php b/module/VuFind/src/VuFind/RecordTab/HoldingsWorldCatFactory.php deleted file mode 100644 index 8d1748cd0cd..00000000000 --- a/module/VuFind/src/VuFind/RecordTab/HoldingsWorldCatFactory.php +++ /dev/null @@ -1,74 +0,0 @@ - - * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License - * @link https://vufind.org/wiki/development Wiki - */ - -namespace VuFind\RecordTab; - -use Laminas\ServiceManager\Exception\ServiceNotCreatedException; -use Laminas\ServiceManager\Exception\ServiceNotFoundException; -use Psr\Container\ContainerExceptionInterface as ContainerException; -use Psr\Container\ContainerInterface; - -/** - * Factory for building the HoldingsWorldCat tab. - * - * @category VuFind - * @package RecordTabs - * @author Demian Katz - * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License - * @link https://vufind.org/wiki/development Wiki - */ -class HoldingsWorldCatFactory implements \Laminas\ServiceManager\Factory\FactoryInterface -{ - /** - * Create an object - * - * @param ContainerInterface $container Service manager - * @param string $requestedName Service being created - * @param null|array $options Extra options (optional) - * - * @return object - * - * @throws ServiceNotFoundException if unable to resolve the service. - * @throws ServiceNotCreatedException if an exception is raised when - * creating a service. - * @throws ContainerException&\Throwable if any other error occurs - * - * @SuppressWarnings(PHPMD.UnusedFormalParameter) - */ - public function __invoke( - ContainerInterface $container, - $requestedName, - array $options = null - ) { - if (!empty($options)) { - throw new \Exception('Unexpected options passed to factory.'); - } - return new $requestedName($container->get(\VuFindSearch\Service::class)); - } -} diff --git a/module/VuFind/src/VuFind/RecordTab/PluginManager.php b/module/VuFind/src/VuFind/RecordTab/PluginManager.php index 2ee0f812017..6bb011e1b2c 100644 --- a/module/VuFind/src/VuFind/RecordTab/PluginManager.php +++ b/module/VuFind/src/VuFind/RecordTab/PluginManager.php @@ -56,7 +56,6 @@ class PluginManager extends \VuFind\ServiceManager\AbstractPluginManager 'formats' => Formats::class, 'hierarchytree' => HierarchyTree::class, 'holdingsils' => HoldingsILS::class, - 'holdingsworldcat' => HoldingsWorldCat::class, 'holdingsworldcat2' => HoldingsWorldCat2::class, 'map' => Map::class, 'preview' => Preview::class, @@ -85,7 +84,6 @@ class PluginManager extends \VuFind\ServiceManager\AbstractPluginManager Formats::class => InvokableFactory::class, HierarchyTree::class => HierarchyTreeFactory::class, HoldingsILS::class => HoldingsILSFactory::class, - HoldingsWorldCat::class => HoldingsWorldCatFactory::class, HoldingsWorldCat2::class => HoldingsWorldCat2Factory::class, Map::class => MapFactory::class, OverdriveHoldings::class => InvokableFactory::class, diff --git a/module/VuFind/src/VuFind/Related/PluginManager.php b/module/VuFind/src/VuFind/Related/PluginManager.php index 5662b854b7f..0332afdaaee 100644 --- a/module/VuFind/src/VuFind/Related/PluginManager.php +++ b/module/VuFind/src/VuFind/Related/PluginManager.php @@ -54,7 +54,6 @@ class PluginManager extends \VuFind\ServiceManager\AbstractPluginManager 'morebyauthorsolr' => MoreByAuthorSolr::class, 'similar' => Similar::class, 'worldcateditions' => Deprecated::class, - 'worldcatsimilar' => WorldCatSimilar::class, 'worldcat2similar' => WorldCat2Similar::class, ]; @@ -69,7 +68,6 @@ class PluginManager extends \VuFind\ServiceManager\AbstractPluginManager Deprecated::class => InvokableFactory::class, MoreByAuthorSolr::class => SimilarFactory::class, Similar::class => SimilarFactory::class, - WorldCatSimilar::class => SimilarFactory::class, WorldCat2Similar::class => WorldCat2SimilarFactory::class, ]; diff --git a/module/VuFind/src/VuFind/Related/WorldCatSimilar.php b/module/VuFind/src/VuFind/Related/WorldCatSimilar.php deleted file mode 100644 index 8091cc14e0b..00000000000 --- a/module/VuFind/src/VuFind/Related/WorldCatSimilar.php +++ /dev/null @@ -1,101 +0,0 @@ - - * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License - * @link https://vufind.org/wiki/development:plugins:related_records_modules Wiki - */ - -namespace VuFind\Related; - -use VuFindSearch\Command\SearchCommand; - -/** - * Related Records: WorldCat-based similarity - * - * @category VuFind - * @package Related_Records - * @author Demian Katz - * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License - * @link https://vufind.org/wiki/development:plugins:related_records_modules Wiki - */ -class WorldCatSimilar extends Similar -{ - /** - * Establishes base settings for making recommendations. - * - * @param string $settings Settings from config.ini - * @param \VuFind\RecordDriver\AbstractBase $driver Record driver object - * - * @return void - */ - public function init($settings, $driver) - { - // Create array of query parts: - $parts = []; - - // Add Dewey class to query - $deweyClass = $driver->tryMethod('getDeweyCallNumber'); - if (!empty($deweyClass)) { - // Skip "English Fiction" Dewey class -- this won't give us useful - // matches because there's too much of it and it's too broad. - if (!str_starts_with($deweyClass, '823')) { - $parts[] = 'srw.dd any "' . $deweyClass . '"'; - } - } - - // Add author to query - $author = $driver->getPrimaryAuthor(); - if (!empty($author)) { - $parts[] = 'srw.au all "' . $author . '"'; - } - - // Add subjects to query - $subjects = $driver->getAllSubjectHeadings(); - foreach ($subjects as $current) { - $parts[] = 'srw.su all "' . implode(' ', $current) . '"'; - } - - // Add title to query - $title = $driver->getTitle(); - if (!empty($title)) { - $parts[] = 'srw.ti any "' . str_replace('"', '', $title) . '"'; - } - - // Build basic query: - $query = '(' . implode(' or ', $parts) . ')'; - - // Not current record ID if this is already a WorldCat record: - if ($driver->getSourceIdentifier() == 'WorldCat') { - $id = $driver->getUniqueId(); - $query .= " not srw.no all \"$id\""; - } - - // Perform the search and save results: - $queryObj = new \VuFindSearch\Query\Query($query); - $command = new SearchCommand('WorldCat', $queryObj, 0, 5); - $result = $this->searchService->invoke($command)->getResult(); - $this->results = $result->getRecords(); - } -} diff --git a/module/VuFind/src/VuFind/Search/BackendRegistry.php b/module/VuFind/src/VuFind/Search/BackendRegistry.php index deb514c4586..02d531a0978 100644 --- a/module/VuFind/src/VuFind/Search/BackendRegistry.php +++ b/module/VuFind/src/VuFind/Search/BackendRegistry.php @@ -52,6 +52,7 @@ class BackendRegistry extends \VuFind\ServiceManager\AbstractPluginManager 'reserves' => 'SolrReserves', // Legacy: 'VuFind' => 'Solr', + 'WorldCat' => 'WorldCat2', ]; /** @@ -76,7 +77,6 @@ class BackendRegistry extends \VuFind\ServiceManager\AbstractPluginManager 'SolrReserves' => Factory\SolrReservesBackendFactory::class, 'SolrWeb' => Factory\SolrWebBackendFactory::class, 'Summon' => Factory\SummonBackendFactory::class, - 'WorldCat' => Factory\WorldCatBackendFactory::class, 'WorldCat2' => Factory\WorldCat2BackendFactory::class, ]; diff --git a/module/VuFind/src/VuFind/Search/Factory/WorldCatBackendFactory.php b/module/VuFind/src/VuFind/Search/Factory/WorldCatBackendFactory.php deleted file mode 100644 index 2b18022edcb..00000000000 --- a/module/VuFind/src/VuFind/Search/Factory/WorldCatBackendFactory.php +++ /dev/null @@ -1,154 +0,0 @@ - - * @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\WorldCat\Backend; -use VuFindSearch\Backend\WorldCat\Connector; -use VuFindSearch\Backend\WorldCat\QueryBuilder; -use VuFindSearch\Backend\WorldCat\Response\XML\RecordCollectionFactory; - -/** - * Factory for WorldCat backends. - * - * @category VuFind - * @package Search - * @author David Maus - * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License - * @link https://vufind.org Main Site - */ -class WorldCatBackendFactory 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('WorldCat'); - $driver->setRawData($data); - return $driver; - }; - return new RecordCollectionFactory($callback); - } -} diff --git a/module/VuFind/src/VuFind/Search/WorldCat/Options.php b/module/VuFind/src/VuFind/Search/WorldCat/Options.php index 88823603627..d528f093d25 100644 --- a/module/VuFind/src/VuFind/Search/WorldCat/Options.php +++ b/module/VuFind/src/VuFind/Search/WorldCat/Options.php @@ -1,7 +1,8 @@ searchIni = $this->facetsIni = 'WorldCat'; - - // 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. * diff --git a/module/VuFind/src/VuFind/Search/WorldCat/Params.php b/module/VuFind/src/VuFind/Search/WorldCat/Params.php index 2d2ff441175..15836ccce61 100644 --- a/module/VuFind/src/VuFind/Search/WorldCat/Params.php +++ b/module/VuFind/src/VuFind/Search/WorldCat/Params.php @@ -1,7 +1,8 @@ getSort(); - $backendParams->set('sortKeys', empty($sort) ? 'relevance' : $sort); - - return $backendParams; - } } diff --git a/module/VuFind/src/VuFind/Search/WorldCat/Results.php b/module/VuFind/src/VuFind/Search/WorldCat/Results.php index c30455b7f66..8df13b425d1 100644 --- a/module/VuFind/src/VuFind/Search/WorldCat/Results.php +++ b/module/VuFind/src/VuFind/Search/WorldCat/Results.php @@ -1,7 +1,8 @@ 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(); + throw new \Exception('WorldCat v1 API no longer supported.'); } /** @@ -85,7 +70,6 @@ protected function performSearch() */ public function getFacetList($filter = null) { - // No facets in WorldCat: - return []; + throw new \Exception('WorldCat v1 API no longer supported.'); } } diff --git a/module/VuFind/tests/unit-tests/src/VuFindTest/RecordDriver/WorldCatTest.php b/module/VuFind/src/VuFindTest/RecordDriver/MarcBasicTraitTestHarness.php similarity index 56% rename from module/VuFind/tests/unit-tests/src/VuFindTest/RecordDriver/WorldCatTest.php rename to module/VuFind/src/VuFindTest/RecordDriver/MarcBasicTraitTestHarness.php index 52c22de223a..dc78033e20a 100644 --- a/module/VuFind/tests/unit-tests/src/VuFindTest/RecordDriver/WorldCatTest.php +++ b/module/VuFind/src/VuFindTest/RecordDriver/MarcBasicTraitTestHarness.php @@ -1,11 +1,11 @@ * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License * @link https://vufind.org/wiki/development:testing:unit_tests Wiki @@ -29,34 +29,21 @@ namespace VuFindTest\RecordDriver; +use VuFind\RecordDriver\DefaultRecord; +use VuFind\RecordDriver\Feature\MarcBasicTrait; +use VuFind\RecordDriver\Feature\MarcReaderTrait; + /** - * WorldCat Record Driver Test Class + * Test harness for simulating MARC record drivers (ignore outside of test suite!) * * @category VuFind - * @package Tests + * @package RecordDrivers * @author Demian Katz * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License * @link https://vufind.org/wiki/development:testing:unit_tests Wiki */ -class WorldCatTest extends \PHPUnit\Framework\TestCase +class MarcBasicTraitTestHarness extends DefaultRecord { - use \VuFindTest\Feature\FixtureTrait; - - /** - * Test that we can setRawData() with getRawData() without breaking anything. - * - * @return void - */ - public function testSetRawData() - { - $marc = $this->getFixture('marc/marctraits.xml'); - $driver = new \VuFind\RecordDriver\WorldCat(); - $driver->setRawData($marc); - // Test that we can pull data from MARC... - $this->assertEquals('The Foo:', $driver->getShortTitle()); - // Now reassign the raw data... - $driver->setRawData($driver->getRawData()); - // Now confirm that we still get the same result... - $this->assertEquals('The Foo:', $driver->getShortTitle()); - } + use MarcReaderTrait; + use MarcBasicTrait; } diff --git a/module/VuFind/tests/unit-tests/src/VuFindTest/Config/UpgradeTest.php b/module/VuFind/tests/unit-tests/src/VuFindTest/Config/UpgradeTest.php index 714fb59a223..34423a36645 100644 --- a/module/VuFind/tests/unit-tests/src/VuFindTest/Config/UpgradeTest.php +++ b/module/VuFind/tests/unit-tests/src/VuFindTest/Config/UpgradeTest.php @@ -62,7 +62,7 @@ class UpgradeTest extends \PHPUnit\Framework\TestCase * * @return Upgrade */ - protected function getUpgrader($version) + protected function getUpgrader(string $version): Upgrade { $oldDir = realpath($this->getFixtureDir() . 'configs/' . $version); $rawDir = realpath(__DIR__ . '/../../../../../../../config/vufind'); @@ -78,7 +78,7 @@ protected function getUpgrader($version) * * @return array */ - protected function checkVersion($version) + protected function checkVersion(string $version): array { $upgrader = $this->getUpgrader($version); $upgrader->run(); @@ -204,7 +204,7 @@ protected function checkVersion($version) * * @return void */ - public function testUpgrade11() + public function testUpgrade11(): void { $this->checkVersion('1.1'); } @@ -214,7 +214,7 @@ public function testUpgrade11() * * @return void */ - public function testUpgrade12() + public function testUpgrade12(): void { $this->checkVersion('1.2'); } @@ -224,7 +224,7 @@ public function testUpgrade12() * * @return void */ - public function testUpgrade13() + public function testUpgrade13(): void { $this->checkVersion('1.3'); } @@ -234,7 +234,7 @@ public function testUpgrade13() * * @return void */ - public function testUpgrade14() + public function testUpgrade14(): void { $this->checkVersion('1.4'); } @@ -244,7 +244,7 @@ public function testUpgrade14() * * @return void */ - public function testDefaultGenerator() + public function testDefaultGenerator(): void { // We expect the upgrader to switch default values: $upgrader = $this->getUpgrader('defaultgenerator'); @@ -270,7 +270,7 @@ public function testDefaultGenerator() * * @return void */ - public function testSpelling() + public function testSpelling(): void { $upgrader = $this->getUpgrader('spelling'); $upgrader->run(); @@ -286,7 +286,7 @@ public function testSpelling() * * @return void */ - public function testSyndetics() + public function testSyndetics(): void { // Test upgrading an SSL URL $upgrader = $this->getUpgrader('syndeticsurlssl'); @@ -312,7 +312,7 @@ public function testSyndetics() * * @return void */ - public function testGooglePreviewUpgrade() + public function testGooglePreviewUpgrade(): void { $upgrader = $this->getUpgrader('googlepreview'); $upgrader->run(); @@ -323,45 +323,12 @@ public function testGooglePreviewUpgrade() ); } - /** - * Test removal of xID settings - * - * @return void - */ - public function testXidDeprecation() - { - $upgrader = $this->getUpgrader('xid'); - $upgrader->run(); - $results = $upgrader->getNewConfigs(); - $this->assertEquals( - ['Similar'], - $results['config.ini']['Record']['related'] - ); - $this->assertEquals( - ['WorldCatSimilar'], - $results['WorldCat.ini']['Record']['related'] - ); - $this->assertEquals(['apiKey' => 'foo'], $results['config.ini']['WorldCat']); - $expectedWarnings = [ - 'The [WorldCat] id setting is no longer used and has been removed.', - 'The [WorldCat] xISBN_token setting is no longer used and has been removed.', - 'The [WorldCat] xISBN_secret setting is no longer used and has been removed.', - 'The [WorldCat] xISSN_token setting is no longer used and has been removed.', - 'The [WorldCat] xISSN_secret setting is no longer used and has been removed.', - 'The Editions related record module is no longer supported due to OCLC\'s xID ' - . 'API shutdown. It has been removed from your settings.', - 'The WorldCatEditions related record module is no longer supported due to OCLC\'s ' - . 'xID API shutdown. It has been removed from your settings.', - ]; - $this->assertEquals($expectedWarnings, $upgrader->getWarnings()); - } - /** * Test permission upgrade * * @return void */ - public function testPermissionUpgrade() + public function testPermissionUpgrade(): void { $upgrader = $this->getUpgrader('permissions'); $upgrader->run(); @@ -429,7 +396,7 @@ public function testPermissionUpgrade() * * @return void */ - public function testGoogleWarnings() + public function testGoogleWarnings(): void { $upgrader = $this->getUpgrader('googlewarnings'); $upgrader->run(); @@ -467,46 +434,26 @@ public function testGoogleWarnings() * * @return void */ - public function testWorldCatWarnings() + public function testWorldCatWarnings(): void { $upgrader = $this->getUpgrader('worldcatwarnings'); $upgrader->run(); $warnings = $upgrader->getWarnings(); $this->assertTrue( in_array( - 'The [WorldCat] LimitCodes setting never had any effect and has been' - . ' removed.', + 'The [WorldCat] section of config.ini has been removed following' + . ' the shutdown of the v1 WorldCat search API; use WorldCat2.ini instead.', $warnings ) ); } - /** - * Test WorldCat-specific upgrades. - * - * @return void - */ - public function testWorldCatUpgrades() - { - $upgrader = $this->getUpgrader('worldcatupgrades'); - $upgrader->run(); - $results = $upgrader->getNewConfigs(); - $this->assertEquals( - 'Author', - $results['WorldCat.ini']['Basic_Searches']['srw.au'] - ); - $this->assertEquals( - 'adv_search_author', - $results['WorldCat.ini']['Advanced_Searches']['srw.au'] - ); - } - /** * Test "meaningful line" detection in SolrMarc properties files. * * @return void */ - public function testMeaningfulLineDetection() + public function testMeaningfulLineDetection(): void { $upgrader = $this->getUpgrader('1.4'); $meaningless = realpath( @@ -536,7 +483,7 @@ public function testMeaningfulLineDetection() * * @return void */ - public function testCommentExtraction() + public function testCommentExtraction(): void { $upgrader = $this->getUpgrader('comments'); $config = $this->getFixtureDir() . 'configs/comments/config.ini'; @@ -574,7 +521,7 @@ public function testCommentExtraction() * * @return void */ - public function testPrimoUpgrade() + public function testPrimoUpgrade(): void { $upgrader = $this->getUpgrader('primo'); $upgrader->run(); @@ -591,7 +538,7 @@ public function testPrimoUpgrade() * * @return void */ - public function testAmazonCoverWarning() + public function testAmazonCoverWarning(): void { $upgrader = $this->getUpgrader('amazoncover'); $upgrader->run(); @@ -610,7 +557,7 @@ public function testAmazonCoverWarning() * * @return void */ - public function testAmazonReviewWarning() + public function testAmazonReviewWarning(): void { $upgrader = $this->getUpgrader('amazonreview'); $upgrader->run(); @@ -629,7 +576,7 @@ public function testAmazonReviewWarning() * * @return void */ - public function testReCaptcha() + public function testReCaptcha(): void { $upgrader = $this->getUpgrader('recaptcha'); $upgrader->run(); diff --git a/module/VuFind/tests/unit-tests/src/VuFindTest/RecordDriver/Feature/MarcBasicTraitTest.php b/module/VuFind/tests/unit-tests/src/VuFindTest/RecordDriver/Feature/MarcBasicTraitTest.php index e9d2121cc29..d0111481482 100644 --- a/module/VuFind/tests/unit-tests/src/VuFindTest/RecordDriver/Feature/MarcBasicTraitTest.php +++ b/module/VuFind/tests/unit-tests/src/VuFindTest/RecordDriver/Feature/MarcBasicTraitTest.php @@ -29,7 +29,8 @@ namespace VuFindTest\RecordDriver\Feature; -use VuFind\RecordDriver\WorldCat; +use PHPUnit\Framework\MockObject\MockObject; +use VuFindTest\RecordDriver\MarcBasicTraitTestHarness; /** * Record Driver Marc Traits Test Class @@ -110,17 +111,17 @@ public function testMarcBasicTraitMissingFields() * * @param string $fixture Record metadata fixture * - * @return MockObjec&WorldCat + * @return MarcBasicTraitTestHarness&MockObject */ - protected function createMockRecord(string $fixture): WorldCat + protected function createMockRecord(string $fixture): MarcBasicTraitTestHarness&MockObject { $xml = $this->getFixture("marc/$fixture"); $record = new \VuFind\Marc\MarcReader($xml); - $obj = $this->getMockBuilder(WorldCat::class) + $obj = $this->getMockBuilder(MarcBasicTraitTestHarness::class) ->onlyMethods(['getMarcReader'])->getMock(); $obj->expects($this->any()) ->method('getMarcReader') - ->will($this->returnValue($record)); + ->willReturn($record); return $obj; } } diff --git a/module/VuFind/tests/unit-tests/src/VuFindTest/RecordTab/HoldingsWorldCatTest.php b/module/VuFind/tests/unit-tests/src/VuFindTest/RecordTab/HoldingsWorldCatTest.php deleted file mode 100644 index 5297122b821..00000000000 --- a/module/VuFind/tests/unit-tests/src/VuFindTest/RecordTab/HoldingsWorldCatTest.php +++ /dev/null @@ -1,140 +0,0 @@ - - * @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\RecordTab; - -use VuFind\RecordTab\HoldingsWorldCat; -use VuFindSearch\Service; - -/** - * HoldingsWorldCat Test Class - * - * @category VuFind - * @package Tests - * @author Sudharma Kellampalli - * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License - * @link https://vufind.org/wiki/development:testing:unit_tests Wiki - */ -class HoldingsWorldCatTest extends \PHPUnit\Framework\TestCase -{ - /** - * Test getting Description. - * - * @return void - */ - public function testGetDescription(): void - { - $searchObj = $this->getService(); - $obj = new HoldingsWorldCat($searchObj); - $expected = 'Holdings'; - - $this->assertSame($expected, $obj->getDescription()); - } - - /** - * Data provider for testIsActive. - * - * @return array - */ - public static function isActiveProvider(): array - { - return ['Enabled' => ['foo', true], 'Not Enabled' => ['', false]]; - } - - /** - * Test if the tab is active. - * - * @param string $oclcnum OCLCNum - * @param bool $expectedResult Expected return value from isActive - * - * @return void - * - * @dataProvider isActiveProvider - */ - public function testIsActive(string $oclcnum, bool $expectedResult): void - { - $searchObj = $this->getService(); - $obj = new HoldingsWorldCat($searchObj); - $recordDriver = $this->getMockBuilder(\VuFind\RecordDriver\WorldCat::class) - ->disableOriginalConstructor() - ->getMock(); - $recordDriver->expects($this->once())->method('tryMethod') - ->with($this->equalTo('getCleanOCLCNum')) - ->will($this->returnValue($oclcnum)); - $obj->setRecordDriver($recordDriver); - $this->assertSame($expectedResult, $obj->isActive()); - } - - /** - * Test getting holdings information. - * - * @return void - */ - public function testGetHoldings(): void - { - $searchObj = $this->getMockBuilder(\VuFindSearch\Service::class) - ->disableOriginalConstructor() - ->getMock(); - $obj = new HoldingsWorldCat($searchObj); - $recordDriver = $this->getMockBuilder(\VuFind\RecordDriver\WorldCat::class) - ->disableOriginalConstructor() - ->getMock(); - $recordDriver->expects($this->once())->method('tryMethod') - ->with($this->equalTo('getCleanOCLCNum')) - ->will($this->returnValue('bar')); - $obj->setRecordDriver($recordDriver); - $commandObj = $this->getMockBuilder(\VuFindSearch\Command\AbstractBase::class) - ->disableOriginalConstructor() - ->getMock(); - $commandObj->expects($this->any())->method('getResult') - ->will($this->returnValue(true)); - $checkCommand = function ($command) { - return $command::class === \VuFindSearch\Backend\WorldCat\Command\GetHoldingsCommand::class - && $command->getArguments()[0] === 'bar' - && $command->getTargetIdentifier() === 'WorldCat'; - }; - $searchObj->expects($this->any())->method('invoke') - ->with($this->callback($checkCommand)) - ->will($this->returnValue($commandObj)); - $this->assertTrue($obj->getHoldings()); - } - - /** - * Get a Service object - * - * @return Service - */ - public function getService() - { - $searchObj = $this->getMockBuilder(\VuFindSearch\Service::class) - ->disableOriginalConstructor() - ->getMock(); - return $searchObj; - } -} diff --git a/module/VuFind/tests/unit-tests/src/VuFindTest/Related/WorldCatSimilarTest.php b/module/VuFind/tests/unit-tests/src/VuFindTest/Related/WorldCatSimilarTest.php deleted file mode 100644 index b0343d7fc0f..00000000000 --- a/module/VuFind/tests/unit-tests/src/VuFindTest/Related/WorldCatSimilarTest.php +++ /dev/null @@ -1,117 +0,0 @@ - - * @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\Related; - -use VuFind\Related\WorldCatSimilar; - -/** - * WorldCat Similar Related Items Test Class - * - * @category VuFind - * @package Tests - * @author Demian Katz - * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License - * @link https://vufind.org/wiki/development:testing:unit_tests Wiki - */ -class WorldCatSimilarTest extends \PHPUnit\Framework\TestCase -{ - /** - * Test results. - * - * @return void - */ - public function testGetResults() - { - $driver = $this->getMockBuilder(\VuFind\RecordDriver\WorldCat::class) - ->onlyMethods( - [ - 'tryMethod', - 'getPrimaryAuthor', - 'getAllSubjectHeadings', - 'getTitle', - 'getUniqueId', - 'getSourceIdentifier', - ] - )->getMock(); - $driver->expects($this->once()) - ->method('tryMethod') - ->with($this->equalTo('getDeweyCallNumber')) - ->will($this->returnValue('fakedc')); - $driver->expects($this->once()) - ->method('getPrimaryAuthor') - ->will($this->returnValue('fakepa')); - $driver->expects($this->once()) - ->method('getAllSubjectHeadings') - ->will($this->returnValue([['fakesh1a', 'fakesh1b'], ['fakesh2']])); - $driver->expects($this->once()) - ->method('getTitle') - ->will($this->returnValue('faketitle')); - $driver->expects($this->once()) - ->method('getUniqueId') - ->will($this->returnValue('fakeid')); - $driver->expects($this->once()) - ->method('getSourceIdentifier') - ->will($this->returnValue('WorldCat')); - $service = $this->getMockBuilder(\VuFindSearch\Service::class) - ->disableOriginalConstructor() - ->getMock(); - $response = $this->getMockBuilder(\VuFindSearch\Backend\WorldCat\Response\XML\RecordCollection::class) - ->onlyMethods(['getRecords']) - ->setConstructorArgs([['offset' => 0, 'total' => 0]]) - ->getMock(); - $response->expects($this->once()) - ->method('getRecords') - ->will($this->returnValue(['fakeresponse'])); - - $commandObj = $this->getMockBuilder(\VuFindSearch\Command\AbstractBase::class) - ->disableOriginalConstructor() - ->getMock(); - $commandObj->expects($this->once())->method('getResult') - ->will($this->returnValue($response)); - - $checkCommand = function ($command) { - $expectedTerms = '(srw.dd any "fakedc" or srw.au all "fakepa" or ' - . 'srw.su all "fakesh1a fakesh1b" or srw.su all "fakesh2" or ' - . 'srw.ti any "faketitle") not srw.no all "fakeid"'; - return $command::class === \VuFindSearch\Command\SearchCommand::class - && $command->getTargetIdentifier() === 'WorldCat' - && $command->getArguments()[0]->getAllTerms() === $expectedTerms - && $command->getArguments()[1] === 0 - && $command->getArguments()[2] === 5; - }; - $service->expects($this->once())->method('invoke') - ->with($this->callback($checkCommand)) - ->will($this->returnValue($commandObj)); - - $similar = new WorldCatSimilar($service); - $similar->init('', $driver); - $this->assertEquals(['fakeresponse'], $similar->getResults()); - } -} diff --git a/module/VuFindSearch/src/VuFindSearch/Backend/WorldCat/Backend.php b/module/VuFindSearch/src/VuFindSearch/Backend/WorldCat/Backend.php deleted file mode 100644 index 1c65e5028b5..00000000000 --- a/module/VuFindSearch/src/VuFindSearch/Backend/WorldCat/Backend.php +++ /dev/null @@ -1,203 +0,0 @@ - - * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License - * @link https://vufind.org - */ - -namespace VuFindSearch\Backend\WorldCat; - -use VuFindSearch\Backend\AbstractBackend; -use VuFindSearch\ParamBag; -use VuFindSearch\Query\AbstractQuery; -use VuFindSearch\Response\RecordCollectionFactoryInterface; -use VuFindSearch\Response\RecordCollectionInterface; - -/** - * WorldCat backend. - * - * @category VuFind - * @package Search - * @author David Maus - * @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 = null; - } - - /** - * 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/WorldCat/Command/GetHoldingsCommand.php b/module/VuFindSearch/src/VuFindSearch/Backend/WorldCat/Command/GetHoldingsCommand.php deleted file mode 100644 index fb42e918bea..00000000000 --- a/module/VuFindSearch/src/VuFindSearch/Backend/WorldCat/Command/GetHoldingsCommand.php +++ /dev/null @@ -1,72 +0,0 @@ - - * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License - * @link https://vufind.org - */ - -namespace VuFindSearch\Backend\WorldCat\Command; - -use VuFindSearch\Command\Feature\RecordIdentifierTrait; - -/** - * Command to fetch holdings from the WorldCat backend. - * - * @category VuFind - * @package Search - * @author Demian Katz - * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License - * @link https://vufind.org - */ -class GetHoldingsCommand extends \VuFindSearch\Command\CallMethodCommand -{ - use RecordIdentifierTrait; - - /** - * Constructor - * - * @param string $backendId Search backend identifier - * @param string $id WorldCat record identifier - */ - public function __construct(string $backendId, string $id) - { - $this->id = $id; - parent::__construct( - $backendId, - \VuFindSearch\Backend\WorldCat\Backend::class, - 'getHoldings' - ); - } - - /** - * Return search backend interface method arguments. - * - * @return array - */ - public function getArguments(): array - { - return [$this->getRecordIdentifier()]; - } -} diff --git a/module/VuFindSearch/src/VuFindSearch/Backend/WorldCat/Connector.php b/module/VuFindSearch/src/VuFindSearch/Backend/WorldCat/Connector.php deleted file mode 100644 index 7255eb6e4ee..00000000000 --- a/module/VuFindSearch/src/VuFindSearch/Backend/WorldCat/Connector.php +++ /dev/null @@ -1,175 +0,0 @@ - - * @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\WorldCat; - -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; - - /** - * 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( - 'http://www.worldcat.org/webservices/catalog/search/sru', - $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, - ]; - } - - /** - * 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); - - $xml = simplexml_load_string($response); - $docs = $xml->records->record ?? []; - $finalDocs = []; - foreach ($docs as $doc) { - $finalDocs[] = $doc->recordData->asXML(); - } - return [ - 'docs' => $finalDocs, - 'offset' => $offset, - 'total' => (int)($xml->numberOfRecords ?? 0), - ]; - } -} diff --git a/module/VuFindSearch/src/VuFindSearch/Backend/WorldCat/QueryBuilder.php b/module/VuFindSearch/src/VuFindSearch/Backend/WorldCat/QueryBuilder.php deleted file mode 100644 index 5175347a0c1..00000000000 --- a/module/VuFindSearch/src/VuFindSearch/Backend/WorldCat/QueryBuilder.php +++ /dev/null @@ -1,191 +0,0 @@ - - * @author David Maus - * @author Demian Katz - * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License - * @link https://vufind.org - */ - -namespace VuFindSearch\Backend\WorldCat; - -use VuFindSearch\ParamBag; -use VuFindSearch\Query\AbstractQuery; -use VuFindSearch\Query\Query; -use VuFindSearch\Query\QueryGroup; - -use function count; - -/** - * WorldCat QueryBuilder. - * - * @category VuFind - * @package Search - * @author Andrew S. Nagy - * @author David Maus - * @author Demian Katz - * @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/WorldCat/Response/XML/Record.php b/module/VuFindSearch/src/VuFindSearch/Backend/WorldCat/Response/XML/Record.php deleted file mode 100644 index c15a9d11a7b..00000000000 --- a/module/VuFindSearch/src/VuFindSearch/Backend/WorldCat/Response/XML/Record.php +++ /dev/null @@ -1,77 +0,0 @@ - - * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License - * @link https://vufind.org - */ - -namespace VuFindSearch\Backend\WorldCat\Response\XML; - -use VuFind\Marc\MarcReader; -use VuFindSearch\Response\RecordInterface; - -/** - * Simple WorldCat record. - * - * @category VuFind - * @package Search - * @author David Maus - * @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('WorldCat'); - } - - /** - * Get MARC record - * - * @return MarcReader - */ - public function getMarc(): MarcReader - { - return $this->marc; - } -} diff --git a/module/VuFindSearch/src/VuFindSearch/Backend/WorldCat/Response/XML/RecordCollection.php b/module/VuFindSearch/src/VuFindSearch/Backend/WorldCat/Response/XML/RecordCollection.php deleted file mode 100644 index 90a1a9ab3aa..00000000000 --- a/module/VuFindSearch/src/VuFindSearch/Backend/WorldCat/Response/XML/RecordCollection.php +++ /dev/null @@ -1,85 +0,0 @@ - - * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License - * @link https://vufind.org - */ - -namespace VuFindSearch\Backend\WorldCat\Response\XML; - -use VuFindSearch\Response\AbstractRecordCollection; - -/** - * WorldCat record collection. - * - * @category VuFind - * @package Search - * @author David Maus - * @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/WorldCat/Response/XML/RecordCollectionFactory.php b/module/VuFindSearch/src/VuFindSearch/Backend/WorldCat/Response/XML/RecordCollectionFactory.php deleted file mode 100644 index 4a2e9fd6664..00000000000 --- a/module/VuFindSearch/src/VuFindSearch/Backend/WorldCat/Response/XML/RecordCollectionFactory.php +++ /dev/null @@ -1,111 +0,0 @@ - - * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License - * @link https://vufind.org - */ - -namespace VuFindSearch\Backend\WorldCat\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 - * @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)); - }; - } 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/tests/unit-tests/src/VuFindTest/Backend/WorldCat/BackendTest.php b/module/VuFindSearch/tests/unit-tests/src/VuFindTest/Backend/WorldCat/BackendTest.php deleted file mode 100644 index ceec54cfda4..00000000000 --- a/module/VuFindSearch/tests/unit-tests/src/VuFindTest/Backend/WorldCat/BackendTest.php +++ /dev/null @@ -1,159 +0,0 @@ - - * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License - * @link https://vufind.org - */ - -namespace VuFindTest\Backend\WorldCat; - -use InvalidArgumentException; -use PHPUnit\Framework\TestCase; -use VuFindSearch\Backend\WorldCat\Backend; -use VuFindSearch\Query\Query; - -/** - * Unit tests for WorldCat backend. - * - * @category VuFind - * @package Search - * @author David Maus - * @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 retrieving a record. - * - * @return void - */ - public function testRetrieve() - { - $conn = $this->getConnectorMock(['getRecord']); - $conn->expects($this->once()) - ->method('getRecord') - ->will($this->returnValue($this->loadResponse('single-record'))); - - $back = new Backend($conn); - $back->setIdentifier('test'); - $coll = $back->retrieve('foobar'); - $this->assertCount(1, $coll); - $this->assertEquals('test', $coll->getSourceIdentifier()); - $rec = $coll->first(); - $this->assertEquals('test', $rec->getSourceIdentifier()); - $this->assertEquals('690250223', $rec->getMarc()->getField('001')); - } - - /** - * Test performing a search. - * - * @return void - */ - public function testSearch() - { - $conn = $this->getConnectorMock(['search']); - $conn->expects($this->once()) - ->method('search') - ->will($this->returnValue($this->loadResponse('search'))); - - $back = new Backend($conn); - $back->setIdentifier('test'); - $coll = $back->search(new Query('foobar'), 0, 3); - $this->assertCount(3, $coll); - $this->assertEquals('test', $coll->getSourceIdentifier()); - $rec = $coll->first(); - $this->assertEquals('test', $rec->getSourceIdentifier()); - $this->assertEquals('793503125', $rec->getMarc()->getField('001')); - $recs = $coll->getRecords(); - $this->assertEquals('test', $recs[1]->getSourceIdentifier()); - $this->assertEquals('798169104', $recs[1]->getMarc()->getField('001')); - $this->assertEquals('test', $recs[2]->getSourceIdentifier()); - $this->assertEquals('44310183', $recs[2]->getMarc()->getField('001')); - } - - /** - * Test setting a query builder. - * - * @return void - */ - public function testSetQueryBuilder() - { - $qb = new \VuFindSearch\Backend\WorldCat\QueryBuilder(); - $back = new Backend($this->getConnectorMock()); - $back->setQueryBuilder($qb); - $this->assertEquals($qb, $back->getQueryBuilder()); - } - - /** - * Test setting a custom record collection factory. - * - * @return void - */ - public function testConstructorSetters() - { - $fact = $this->createMock(\VuFindSearch\Response\RecordCollectionFactoryInterface::class); - $conn = $this->getConnectorMock(); - $back = new Backend($conn, $fact); - $this->assertEquals($fact, $back->getRecordCollectionFactory()); - $this->assertEquals($conn, $back->getConnector()); - } - - /// Internal API - - /** - * Load a WorldCat response as fixture. - * - * @param string $fixture Fixture file - * - * @return mixed - * - * @throws InvalidArgumentException Fixture files does not exist - */ - protected function loadResponse($fixture) - { - return unserialize( - $this->getFixture("worldcat/response/$fixture", 'VuFindSearch') - ); - } - - /** - * Return connector mock. - * - * @param array $mock Functions to mock - * - * @return array - */ - protected function getConnectorMock(array $mock = []) - { - $client = $this->createMock(\Laminas\Http\Client::class); - return $this->getMockBuilder(\VuFindSearch\Backend\WorldCat\Connector::class) - ->onlyMethods($mock) - ->setConstructorArgs(['fake', $client]) - ->getMock(); - } -} diff --git a/module/VuFindSearch/tests/unit-tests/src/VuFindTest/Backend/WorldCat/Command/GetHoldingsCommandTest.php b/module/VuFindSearch/tests/unit-tests/src/VuFindTest/Backend/WorldCat/Command/GetHoldingsCommandTest.php deleted file mode 100644 index af58c3f2879..00000000000 --- a/module/VuFindSearch/tests/unit-tests/src/VuFindTest/Backend/WorldCat/Command/GetHoldingsCommandTest.php +++ /dev/null @@ -1,81 +0,0 @@ - - * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License - * @link https://vufind.org - */ - -namespace VuFindTest\Backend\WorldCat\Command; - -use PHPUnit\Framework\TestCase; -use VuFindSearch\Backend\WorldCat\Command\GetHoldingsCommand; - -/** - * Unit tests for GetHoldingsCommand. - * - * @category VuFind - * @package Search - * @author Demian Katz - * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License - * @link https://vufind.org - */ -class GetHoldingsCommandTest extends TestCase -{ - /** - * Test that an error is thrown for unsupported backends. - * - * @return void - */ - public function testUnsupportedBackend(): void - { - $command = new GetHoldingsCommand('foo', 'id'); - $backend = $this - ->getMockBuilder(\VuFindSearch\Backend\BrowZine\Backend::class) - ->disableOriginalConstructor()->getMock(); - $backend->expects($this->once())->method('getIdentifier') - ->will($this->returnValue('foo')); - $this->expectExceptionMessage('foo does not support getHoldings()'); - $command->execute($backend); - } - - /** - * Test that a supported backend behaves as expected. - * - * @return void - */ - public function testSupportedBackend(): void - { - $backend = $this - ->getMockBuilder(\VuFindSearch\Backend\WorldCat\Backend::class) - ->disableOriginalConstructor()->getMock(); - $backend->expects($this->once())->method('getIdentifier') - ->will($this->returnValue('WorldCat')); - $backend->expects($this->once())->method('getHoldings') - ->with($this->equalTo('id')) - ->will($this->returnValue('foo')); - $command = new GetHoldingsCommand('WorldCat', 'id'); - $this->assertEquals('foo', $command->execute($backend)->getResult()); - } -} diff --git a/module/VuFindSearch/tests/unit-tests/src/VuFindTest/Backend/WorldCat/ConnectorTest.php b/module/VuFindSearch/tests/unit-tests/src/VuFindTest/Backend/WorldCat/ConnectorTest.php deleted file mode 100644 index 12487c0d51c..00000000000 --- a/module/VuFindSearch/tests/unit-tests/src/VuFindTest/Backend/WorldCat/ConnectorTest.php +++ /dev/null @@ -1,155 +0,0 @@ - - * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License - * @link https://vufind.org - */ - -namespace VuFindTest\Backend\WorldCat; - -use VuFindSearch\Backend\WorldCat\Connector; -use VuFindSearch\ParamBag; - -/** - * Unit tests for WorldCat backend. - * - * @category VuFind - * @package Search - * @author David Maus - * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License - * @link https://vufind.org - */ -class ConnectorTest extends \PHPUnit\Framework\TestCase -{ - /** - * Get a connector with a mock HTTP client. - * - * @param string $expectedUri URI expected by client. - * @param string $body Response body returned by client. - * - * @return Connector - */ - protected function getConnectorWithMockClient($expectedUri, $body = 'bar'): Connector - { - $client = $this->createMock(\Laminas\Http\Client::class); - $connector = new Connector('key', $client); - $client->expects($this->once())->method('setMethod') - ->with($this->equalTo('POST')) - ->will($this->returnValue($client)); - $client->expects($this->once())->method('setUri') - ->with($this->equalTo($expectedUri)); - $response = $this->createMock(\Laminas\Http\Response::class); - $response->expects($this->once())->method('getBody') - ->will($this->returnValue($body)); - $response->expects($this->any())->method('isSuccess') - ->will($this->returnValue(true)); - $client->expects($this->once())->method('send') - ->will($this->returnValue($response)); - return $connector; - } - - /** - * Test "get holdings" - * - * @return void - */ - public function testGetHoldings() - { - $expectedUri = 'http://www.worldcat.org/webservices/catalog/content/libraries/baz' - . '?wskey=key&servicelevel=full&frbrGrouping=on'; - $connector = $this->getConnectorWithMockClient($expectedUri); - $final = $connector->getHoldings('baz'); - $this->assertEquals('bar', (string)$final); - } - - /** - * Test "get holdings" HTTP failure - * - * @return void - */ - public function testGetHoldingsHttpFailure() - { - $this->expectException(\VuFindSearch\Backend\Exception\RequestErrorException::class); - - $client = $this->createMock(\Laminas\Http\Client::class); - $connector = new Connector('key', $client); - $client->expects($this->once())->method('setMethod') - ->with($this->equalTo('POST')) - ->will($this->returnValue($client)); - $response = $this->createMock(\Laminas\Http\Response::class); - $response->expects($this->any())->method('isSuccess') - ->will($this->returnValue(false)); - $response->expects($this->once())->method('getStatusCode') - ->will($this->returnValue(418)); - $client->expects($this->once())->method('send') - ->will($this->returnValue($response)); - $connector->getHoldings('baz'); - } - - /** - * Test "get record" - * - * @return void - */ - public function testGetRecord() - { - $expectedUri = 'http://www.worldcat.org/webservices/catalog/content/baz?servicelevel=full&wskey=key'; - $body = 'bar'; - $connector = $this->getConnectorWithMockClient($expectedUri, $body); - $final = $connector->getRecord('baz'); - $this->assertEquals($body, $final['docs'][0]); - } - - /** - * Test "get record" with error - * - * @return void - */ - public function testGetRecordWithError() - { - $expectedUri = 'http://www.worldcat.org/webservices/catalog/content/baz?servicelevel=full&wskey=key'; - $body = 'bad'; - $connector = $this->getConnectorWithMockClient($expectedUri, $body); - $final = $connector->getRecord('baz'); - $this->assertEquals([], $final['docs']); - } - - /** - * Test search - * - * @return void - */ - public function testSearch() - { - $expectedUri = 'http://www.worldcat.org/webservices/catalog/search/sru?version=1.1&x=y' - . '&startRecord=0&maximumRecords=20&servicelevel=full&wskey=key'; - $body = ',1bar' - . ''; - $connector = $this->getConnectorWithMockClient($expectedUri, $body); - $final = $connector->search(new ParamBag(['x' => 'y']), 0, 20); - $this->assertEquals('bar', $final['docs'][0]); - $this->assertEquals(1, $final['total']); - } -} diff --git a/module/VuFindSearch/tests/unit-tests/src/VuFindTest/Backend/WorldCat/QueryBuilderTest.php b/module/VuFindSearch/tests/unit-tests/src/VuFindTest/Backend/WorldCat/QueryBuilderTest.php deleted file mode 100644 index 21a3c652972..00000000000 --- a/module/VuFindSearch/tests/unit-tests/src/VuFindTest/Backend/WorldCat/QueryBuilderTest.php +++ /dev/null @@ -1,95 +0,0 @@ - - * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License - * @link https://vufind.org - */ - -namespace VuFindTest\Backend\WorldCat; - -use PHPUnit\Framework\TestCase; -use VuFindSearch\Backend\WorldCat\QueryBuilder; - -/** - * Unit tests for WorldCat query builder - * - * @category VuFind - * @package Search - * @author David Maus - * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License - * @link https://vufind.org - */ -class QueryBuilderTest extends TestCase -{ - use \VuFindTest\Feature\FixtureTrait; - - /** - * Test query parsing. - * - * @return void - */ - public function testParsing() - { - // Set up an array of expected inputs (serialized objects) and outputs - // (queries): - $tests = [ - ['basic', '(srw.au all "john smith" OR srw.pn all "john smith" OR srw.cn all "john smith")'], - [ - 'advanced', - '((srw.ti all "bananas" OR srw.se all "bananas")) AND ((srw.su all "oranges") OR (srw.su all "apples"))' - . ' NOT (((srw.se all "pears")))', - ], - ]; - - $qb = new QueryBuilder(); - foreach ($tests as $test) { - [$input, $output] = $test; - $q = unserialize( - $this->getFixture("worldcat/query/$input", 'VuFindSearch') - ); - $response = $qb->build($q); - $processedQ = $response->get('query'); - $this->assertEquals($output, $processedQ[0]); - } - } - - /** - * Test the "exclude code" feature. - * - * @return void - */ - public function testExclude() - { - $qb = new QueryBuilder('TEST'); - $q = unserialize( - $this->getFixture('worldcat/query/basic', 'VuFindSearch') - ); - $response = $qb->build($q); - $processedQ = $response->get('query'); - $output = '(srw.au all "john smith" OR srw.pn all "john smith"' - . ' OR srw.cn all "john smith") not srw.li all "TEST"'; - $this->assertEquals($output, $processedQ[0]); - } -} diff --git a/module/VuFindSearch/tests/unit-tests/src/VuFindTest/Backend/WorldCat/Response/XML/RecordCollectionFactoryTest.php b/module/VuFindSearch/tests/unit-tests/src/VuFindTest/Backend/WorldCat/Response/XML/RecordCollectionFactoryTest.php deleted file mode 100644 index d6882e01955..00000000000 --- a/module/VuFindSearch/tests/unit-tests/src/VuFindTest/Backend/WorldCat/Response/XML/RecordCollectionFactoryTest.php +++ /dev/null @@ -1,71 +0,0 @@ - - * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License - * @link https://vufind.org - */ - -namespace VuFindTest\Backend\WorldCat\Response\XML; - -use VuFindSearch\Backend\WorldCat\Response\XML\RecordCollectionFactory; - -/** - * Unit tests for WorldCat backend. - * - * @category VuFind - * @package Search - * @author David Maus - * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License - * @link https://vufind.org - */ -class RecordCollectionFactoryTest extends \PHPUnit\Framework\TestCase -{ - /** - * Test bad callback. - * - * @return void - */ - public function testBadCallback() - { - $this->expectException(\VuFindSearch\Exception\InvalidArgumentException::class); - $this->expectExceptionMessage('Record factory must be callable.'); - - new RecordCollectionFactory('bad'); - } - - /** - * Test bad factory input. - * - * @return void - */ - public function testBadFactoryInput() - { - $this->expectException(\VuFindSearch\Exception\InvalidArgumentException::class); - $this->expectExceptionMessage('Unexpected type of value: Expected array, got string'); - - $x = new RecordCollectionFactory(); - $x->factory('bad'); - } -} diff --git a/themes/bootstrap3/templates/RecordTab/holdingsworldcat.phtml b/themes/bootstrap3/templates/RecordTab/holdingsworldcat.phtml deleted file mode 100644 index e25df3d8d0f..00000000000 --- a/themes/bootstrap3/templates/RecordTab/holdingsworldcat.phtml +++ /dev/null @@ -1,31 +0,0 @@ -tab->getHoldings(); ?> -diagnostic->message)): ?> -

escapeHtml($holdings->diagnostic->message)?>

- 0): ?> -

transEsc('Holdings at Other Libraries')?>

- - - - - - physicalAddress->text)): ?> - - - - - - holdingSimple->copiesSummary->copiesCount)): ?> - - - - - - -
- electronicAddress->text) && !empty($holding->electronicAddress->text)): ?> - escapeHtml($holding->physicalLocation)?> - - escapeHtml($holding->physicalLocation)?> - -
transEsc('Address')?>: escapeHtml($holding->physicalAddress->text)?>
transEsc('Copies')?>: escapeHtml($holding->holdingSimple->copiesSummary->copiesCount)?>
- diff --git a/themes/bootstrap3/templates/worldcat/advanced.phtml b/themes/bootstrap3/templates/worldcat/advanced.phtml deleted file mode 100644 index fad2fe7b408..00000000000 --- a/themes/bootstrap3/templates/worldcat/advanced.phtml +++ /dev/null @@ -1,4 +0,0 @@ -render('search/advanced/layout.phtml'); diff --git a/themes/bootstrap3/templates/worldcat/home.phtml b/themes/bootstrap3/templates/worldcat/home.phtml deleted file mode 100644 index 2b84165e5e2..00000000000 --- a/themes/bootstrap3/templates/worldcat/home.phtml +++ /dev/null @@ -1 +0,0 @@ -render('search/home.phtml'); diff --git a/themes/bootstrap3/templates/worldcat/search.phtml b/themes/bootstrap3/templates/worldcat/search.phtml deleted file mode 100644 index 220a3051137..00000000000 --- a/themes/bootstrap3/templates/worldcat/search.phtml +++ /dev/null @@ -1,3 +0,0 @@ -render('search/results.phtml'); diff --git a/themes/bootstrap5/templates/RecordTab/holdingsworldcat.phtml b/themes/bootstrap5/templates/RecordTab/holdingsworldcat.phtml deleted file mode 100644 index e25df3d8d0f..00000000000 --- a/themes/bootstrap5/templates/RecordTab/holdingsworldcat.phtml +++ /dev/null @@ -1,31 +0,0 @@ -tab->getHoldings(); ?> -diagnostic->message)): ?> -

escapeHtml($holdings->diagnostic->message)?>

- 0): ?> -

transEsc('Holdings at Other Libraries')?>

- - - - - - physicalAddress->text)): ?> - - - - - - holdingSimple->copiesSummary->copiesCount)): ?> - - - - - - -
- electronicAddress->text) && !empty($holding->electronicAddress->text)): ?> - escapeHtml($holding->physicalLocation)?> - - escapeHtml($holding->physicalLocation)?> - -
transEsc('Address')?>: escapeHtml($holding->physicalAddress->text)?>
transEsc('Copies')?>: escapeHtml($holding->holdingSimple->copiesSummary->copiesCount)?>
- diff --git a/themes/bootstrap5/templates/worldcat/advanced.phtml b/themes/bootstrap5/templates/worldcat/advanced.phtml deleted file mode 100644 index fad2fe7b408..00000000000 --- a/themes/bootstrap5/templates/worldcat/advanced.phtml +++ /dev/null @@ -1,4 +0,0 @@ -render('search/advanced/layout.phtml'); diff --git a/themes/bootstrap5/templates/worldcat/home.phtml b/themes/bootstrap5/templates/worldcat/home.phtml deleted file mode 100644 index 2b84165e5e2..00000000000 --- a/themes/bootstrap5/templates/worldcat/home.phtml +++ /dev/null @@ -1 +0,0 @@ -render('search/home.phtml'); diff --git a/themes/bootstrap5/templates/worldcat/search.phtml b/themes/bootstrap5/templates/worldcat/search.phtml deleted file mode 100644 index 220a3051137..00000000000 --- a/themes/bootstrap5/templates/worldcat/search.phtml +++ /dev/null @@ -1,3 +0,0 @@ -render('search/results.phtml');