From 6de273b2910139f80160b28ec234827f06f50cc6 Mon Sep 17 00:00:00 2001
From: Demian Katz <demian.katz@villanova.edu>
Date: Tue, 19 Mar 2019 08:53:29 -0400
Subject: [PATCH] Add support for fetching call numbers from Sierra bibs.
 (#1346)

- Includes renaming of getHoldingFields support method to extractFieldsFromApiData for clarity.
---
 config/vufind/SierraRest.ini                  |  6 +++
 .../src/VuFind/ILS/Driver/SierraRest.php      | 43 ++++++++++++++-----
 2 files changed, 38 insertions(+), 11 deletions(-)

diff --git a/config/vufind/SierraRest.ini b/config/vufind/SierraRest.ini
index ead3b1f5080..53ecb7b1278 100644
--- a/config/vufind/SierraRest.ini
+++ b/config/vufind/SierraRest.ini
@@ -124,6 +124,12 @@ title_hold_bib_levels = a:b:m:d
 ; By default the loan history is disabled. Uncomment the following line to enable it.
 ;enabled = true
 
+[CallNumber]
+; By default, the driver will only look in the item record for a call number; if your
+; institution relies on bib-level call numbers, uncomment this setting and indicate
+; which bib fields to use when the item-level call number is not populated.
+;bib_fields = 099ab:090ab:050ab
+
 ; Both MARC field+subfields and Sierra field tags may be used to specify which fields
 ; are included as textual information from holdings records. Note that Sierra does
 ; not use MARC tags for all holdings information, and e.g. 'h' may cover several
diff --git a/module/VuFind/src/VuFind/ILS/Driver/SierraRest.php b/module/VuFind/src/VuFind/ILS/Driver/SierraRest.php
index 94d7e8ab2ab..583b7fe5f55 100644
--- a/module/VuFind/src/VuFind/ILS/Driver/SierraRest.php
+++ b/module/VuFind/src/VuFind/ILS/Driver/SierraRest.php
@@ -1620,6 +1620,23 @@ class SierraRest extends AbstractBase implements TranslatorAwareInterface,
         return 'SierraRest-' . md5($this->config['Catalog']['host'] . "|$key");
     }
 
+    /**
+     * Extract a bib call number from a bib record (if configured to do so).
+     *
+     * @param array $bib Bib record
+     *
+     * @return string
+     */
+    protected function getBibCallNumber($bib)
+    {
+        $result = empty($this->config['CallNumber']['bib_fields'])
+            ? '' : $this->extractFieldsFromApiData(
+                [$bib], // wrap $bib in array to conform to expected format
+                $this->config['CallNumber']['bib_fields']
+            );
+        return is_array($result) ? reset($result) : $result;
+    }
+
     /**
      * Get Item Statuses
      *
@@ -1633,7 +1650,10 @@ class SierraRest extends AbstractBase implements TranslatorAwareInterface,
      */
     protected function getItemStatusesForBib($id)
     {
-        $bib = $this->getBibRecord($id, 'bibLevel');
+        // If we need to look at bib call numbers, retrieve varFields:
+        $bibFields = empty($this->config['CallNumber']['bib_fields'])
+            ? 'bibLevel' : 'bibLevel,varFields';
+        $bib = $this->getBibRecord($id, $bibFields);
         $holdingsData = [];
         if ($this->apiVersion >= 5.1) {
             $holdingsResult = $this->makeRequest(
@@ -1721,7 +1741,8 @@ class SierraRest extends AbstractBase implements TranslatorAwareInterface,
                     'status' => $status,
                     'reserve' => 'N',
                     'callnumber' => isset($item['callNumber'])
-                        ? preg_replace('/^\|a/', '', $item['callNumber']) : '',
+                        ? preg_replace('/^\|a/', '', $item['callNumber'])
+                        : $this->getBibCallNumber($bib),
                     'duedate' => $duedate,
                     'number' => $volume,
                     'barcode' => $item['barcode'],
@@ -1798,7 +1819,7 @@ class SierraRest extends AbstractBase implements TranslatorAwareInterface,
         $result = [];
         // Get Notes
         if (isset($this->config['Holdings']['notes'])) {
-            $data = $this->getHoldingFields(
+            $data = $this->extractFieldsFromApiData(
                 $holdings,
                 $this->config['Holdings']['notes']
             );
@@ -1808,7 +1829,7 @@ class SierraRest extends AbstractBase implements TranslatorAwareInterface,
         }
 
         // Get Summary (may be multiple lines)
-        $data = $this->getHoldingFields(
+        $data = $this->extractFieldsFromApiData(
             $holdings,
             isset($this->config['Holdings']['summary'])
             ? $this->config['Holdings']['summary']
@@ -1820,7 +1841,7 @@ class SierraRest extends AbstractBase implements TranslatorAwareInterface,
 
         // Get Supplements
         if (isset($this->config['Holdings']['supplements'])) {
-            $data = $this->getHoldingFields(
+            $data = $this->extractFieldsFromApiData(
                 $holdings,
                 $this->config['Holdings']['supplements']
             );
@@ -1831,7 +1852,7 @@ class SierraRest extends AbstractBase implements TranslatorAwareInterface,
 
         // Get Indexes
         if (isset($this->config['Holdings']['indexes'])) {
-            $data = $this->getHoldingFields(
+            $data = $this->extractFieldsFromApiData(
                 $holdings,
                 $this->config['Holdings']['indexes']
             );
@@ -1843,26 +1864,26 @@ class SierraRest extends AbstractBase implements TranslatorAwareInterface,
     }
 
     /**
-     * Get fields from holdings according to the field spec.
+     * Get fields from holdings or bib API response according to the field spec.
      *
-     * @param array        $holdings   Holdings records
+     * @param array        $response   API response data
      * @param array|string $fieldSpecs Array or colon-separated list of
      * field/subfield specifications (3 chars for field code and then subfields,
      * e.g. 866az)
      *
      * @return string|string[] Results as a string if single, array if multiple
      */
-    protected function getHoldingFields($holdings, $fieldSpecs)
+    protected function extractFieldsFromApiData($response, $fieldSpecs)
     {
         if (!is_array($fieldSpecs)) {
             $fieldSpecs = explode(':', $fieldSpecs);
         }
         $result = [];
-        foreach ($holdings as $holding) {
+        foreach ($response as $row) {
             foreach ($fieldSpecs as $fieldSpec) {
                 $fieldCode = substr($fieldSpec, 0, 3);
                 $subfieldCodes = substr($fieldSpec, 3);
-                $fields = $holding['varFields'] ?? [];
+                $fields = $row['varFields'] ?? [];
                 foreach ($fields as $field) {
                     if (($field['marcTag'] ?? '') !== $fieldCode
                         && ($field['fieldTag'] ?? '') !== $fieldCode
-- 
GitLab