Skip to content

Commit

Permalink
Add ISSN support to BrowZine link handler.
Browse files Browse the repository at this point in the history
  • Loading branch information
demiankatz committed Dec 19, 2024
1 parent 03c1054 commit 31c6874
Show file tree
Hide file tree
Showing 7 changed files with 197 additions and 103 deletions.
18 changes: 12 additions & 6 deletions config/vufind/BrowZine.ini
Original file line number Diff line number Diff line change
Expand Up @@ -30,17 +30,18 @@ load_results_with_js = true
; full Full pagination alike to the one at the bottom of results
;top_paginator = simple

; This section controls the behavior of the BrowZine DOI handler; see also
; the [DOI] section of config.ini to activate the handler.
[DOI]
; This section controls the behavior of the BrowZine identifier link handler; see also
; the [IdentifierLinks] section of config.ini to activate the handler.
[IdentifierLinks]
; Can be set to "include" to include only the options listed in the "filter"
; setting, or to "exclude" to filter out the options listed in the "filter"
; setting. The default is "none," which performs no filtering.
;filterType = exclude
; This repeatable section can be used to filter based on link type; legal
; options are the keys defined in DOIServices section.
; options are the keys defined in DOIServices and ISSNServices sections.
; Note that this setting is available for convenience and compatibility with previous
; versions. You can get the same results by changing the DOIServices section.
; versions. You can get the same results by changing the DOIServices and/or
; ISSNServices sections.
;filter[] = "browzineWebLink"
;filter[] = "fullTextFile"

Expand All @@ -49,7 +50,7 @@ load_results_with_js = true
; used. Default is false.
local_icons = false

; This section defines the services to display from BrowZine and their display order.
; This section defines the DOI services to display from BrowZine and their display order.
; Each key is a service name (see https://thirdiron.atlassian.net/wiki/x/WIDqAw for
; more information) and value contains translation key, local icon and Third Iron's
; icon asset (optional) separated by a pipe character.
Expand All @@ -58,6 +59,11 @@ browzineWebLink = "View Complete Issue|browzine-issue|https://assets.thirdiron.c
fullTextFile = "PDF Full Text|browzine-pdf|https://assets.thirdiron.com/images/integrations/browzine-pdf-download-icon.svg"
retractionNoticeUrl = "View Retraction Notice|browzine-retraction"

; This section defines the ISSN services to display from BrowZine and their display order.
; The format is the same as [DOIServices] above.
[ISSNServices]
browzineWebLink = "Browse Available Issues|browzine-issue|https://assets.thirdiron.com/images/integrations/browzine-open-book-icon.svg"

; This section defines the view options available on standard search results.
; If only one view is required, set default_view under [General] above, and
; leave this section commented out.
Expand Down
1 change: 1 addition & 0 deletions languages/en.ini
Original file line number Diff line number Diff line change
Expand Up @@ -145,6 +145,7 @@ Breadcrumbs = "Breadcrumbs"
Brief View = "Brief View"
Browse = "Browse"
Browse Alphabetically = "Browse Alphabetically"
Browse Available Issues = "Browse Available Issues"
Browse for Authors = "Browse for Authors"
Browse Home = "Browse Home"
Browse the Catalog = "Browse the Catalog"
Expand Down
145 changes: 91 additions & 54 deletions module/VuFind/src/VuFind/IdentifierLinker/BrowZine.php
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,10 @@

namespace VuFind\IdentifierLinker;

use Exception;
use VuFind\I18n\Translator\TranslatorAwareInterface;
use VuFindSearch\Backend\BrowZine\Command\LookupDoiCommand;
use VuFindSearch\Backend\BrowZine\Command\LookupIssnsCommand;
use VuFindSearch\Service;

use function in_array;
Expand All @@ -48,42 +50,20 @@ class BrowZine implements IdentifierLinkerInterface, TranslatorAwareInterface
{
use \VuFind\I18n\Translator\TranslatorAwareTrait;

/**
* Search service
*
* @var Service
*/
protected $searchService;

/**
* Configuration options
*
* @var array
*/
protected $config;

/**
* Configured DOI services
*
* @var array
*/
protected $doiServices;

/**
* Constructor
*
* @param Service $searchService Search service
* @param array $config Configuration settings
* @param array $doiServices Configured DOI services
* @param array $issnServices Configured ISSN services
*/
public function __construct(
Service $searchService,
array $config = [],
array $doiServices = []
protected Service $searchService,
protected array $config = [],
protected array $doiServices = [],
protected array $issnServices = []
) {
$this->searchService = $searchService;
$this->config = $config;
$this->doiServices = $doiServices;
}

/**
Expand All @@ -110,6 +90,32 @@ protected function arrayKeyAvailable(string $key, ?array $data): bool
return true;
}

/**
* Format a single service link.
*
* @param array $data Raw API response data
* @param string $serviceKey Key being extracted from response
* @param array $config Service-specific configuration settings
*
* @return array{link: string, label: string, data: array, localIcon: ?string, icon: ?string}
* @throws Exception
*/
protected function processServiceLink(array $data, string $serviceKey, array $config): array
{
$result = [
'link' => $data[$serviceKey],
'label' => $this->translate($config['linkText']),
'data' => $data,
];
$localIcons = !empty($this->config['local_icons']);
if (!$localIcons && !empty($config['icon'])) {
$result['icon'] = $config['icon'];
} else {
$result['localIcon'] = $config['localIcon'];
}
return $result;
}

/**
* Given an array of identifier arrays, perform a lookup and return an associative array
* of arrays, matching the keys of the input array. Each output array contains one or more
Expand All @@ -124,33 +130,53 @@ protected function arrayKeyAvailable(string $key, ?array $data): bool
public function getLinks(array $idArray): array
{
$response = [];
$localIcons = !empty($this->config['local_icons']);
foreach ($idArray as $idKey => $ids) {
if (!isset($ids['doi'])) {
continue;
}
$command = new LookupDoiCommand('BrowZine', $ids['doi']);
$result = $this->searchService->invoke($command)->getResult();
$data = $result['data'] ?? null;
foreach ($this->getDoiServices() as $serviceKey => $config) {
if ($this->arrayKeyAvailable($serviceKey, $data)) {
$result = [
'link' => $data[$serviceKey],
'label' => $this->translate($config['linkText']),
'data' => $data,
];
if (!$localIcons && !empty($config['icon'])) {
$result['icon'] = $config['icon'];
} else {
$result['localIcon'] = $config['localIcon'];
// If we have a DOI, that gets priority because it is more specific; otherwise we'll
// fall back and attempt the ISSN:
if (isset($ids['doi'])) {
$command = new LookupDoiCommand('BrowZine', $ids['doi']);
$result = $this->searchService->invoke($command)->getResult();
$data = $result['data'] ?? null;
foreach ($this->getDoiServices() as $serviceKey => $config) {
if ($this->arrayKeyAvailable($serviceKey, $data)) {
$response[$idKey][] = $this->processServiceLink($data, $serviceKey, $config);
}
}
} elseif (isset($ids['issn'])) {
$command = new LookupIssnsCommand('BrowZine', $ids['issn']);
$result = $this->searchService->invoke($command)->getResult();
$data = $result['data'][0] ?? null;
foreach ($this->getIssnServices() as $serviceKey => $config) {
if ($this->arrayKeyAvailable($serviceKey, $data)) {
$response[$idKey][] = $this->processServiceLink($data, $serviceKey, $config);
}
$response[$idKey][] = $result;
}
}
}
return $response;
}

/**
* Unpack service configuration into more useful array format.
*
* @param array $config Raw (pipe-delimited) configuration from BrowZine.ini
*
* @return array
*/
protected function unpackServiceConfig(array $config): array
{
$result = [];
foreach ($config as $key => $config) {
$parts = explode('|', $config);
$result[$key] = [
'linkText' => $parts[0],
'localIcon' => $parts[1],
'icon' => $parts[2] ?? null,
];
}
return $result;
}

/**
* Get an array of DOI services and their configuration
*
Expand All @@ -173,15 +199,26 @@ protected function getDoiServices(): array
],
];
}
$result = [];
foreach ($this->doiServices as $key => $config) {
$parts = explode('|', $config);
$result[$key] = [
'linkText' => $parts[0],
'localIcon' => $parts[1],
'icon' => $parts[2] ?? null,
return $this->unpackServiceConfig($this->doiServices);
}

/**
* Get an array of ISSN services and their configuration
*
* @return array
*/
protected function getIssnServices(): array
{
if (empty($this->issnServices)) {
$baseIconUrl = 'https://assets.thirdiron.com/images/integrations/';
return [
'browzineWebLink' => [
'linkText' => 'Browse Available Issues',
'localIcon' => 'browzine-issue',
'icon' => $baseIconUrl . 'browzine-open-book-icon.svg',
],
];
}
return $result;
return $this->unpackServiceConfig($this->issnServices);
}
}
16 changes: 9 additions & 7 deletions module/VuFind/src/VuFind/IdentifierLinker/BrowZineFactory.php
Original file line number Diff line number Diff line change
Expand Up @@ -70,12 +70,14 @@ public function __invoke(
throw new \Exception('Unexpected options passed to factory.');
}
$search = $container->get(\VuFindSearch\Service::class);
$fullConfig = $container->get(\VuFind\Config\PluginManager::class)
->get('BrowZine');
$config = isset($fullConfig->DOI) ? $fullConfig->DOI->toArray() : [];
$doiServices = isset($fullConfig->DOIServices)
? $fullConfig->DOIServices->toArray()
: [];
return new $requestedName($search, $config, $doiServices);
$fullConfig = $container->get(\VuFind\Config\PluginManager::class)->get('BrowZine')->toArray();
// DOI config section is supported as a fallback for back-compatibility:
$config = $fullConfig['IdentifierLinks'] ?? $fullConfig['DOI'] ?? [];
return new $requestedName(
$search,
$config,
$fullConfig['DOIServices'] ?? [],
$fullConfig['ISSNServices'] ?? []
);
}
}
1 change: 1 addition & 0 deletions module/VuFind/tests/fixtures/browzine/issn.json
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{"data":[{"id":5006,"type":"journals","title":"Biochemical Pharmacology","issn":"00062952","sjrValue":1.365,"coverImageUrl":"https://coverurl","browzineEnabled":true,"browzineWebLink":"https://weblink"}]}
Loading

0 comments on commit 31c6874

Please sign in to comment.