changeset 156:9e94166d5e0b

Add MultiVoyager.php db driver for multiple Voyager ILS and a few support patches
author Reuben Pasquini <rdp0004@auburn.edu>
date Sun, 31 Oct 2010 16:08:22 -0500
parents 8d88cd5b7d46
children 1092fa3351be
files web/Drivers/MultiVoyager.php web/Drivers/Voyager.php web/services/Record/Holdings.php web/services/Search/AJAX.php web/sys/SS360Link.php
diffstat 5 files changed, 317 insertions(+), 50 deletions(-) [+]
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/web/Drivers/MultiVoyager.php	Sun Oct 31 16:08:22 2010 -0500
@@ -0,0 +1,251 @@
+<?php
+/**
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2,
+ * as published by the Free Software Foundation.
+ *     http://www.gnu.org/licenses/gpl-2.0.html
+ */
+require_once 'Interface.php';
+require_once 'Voyager.php';
+require_once 'Log.php';
+
+# Set log mask once
+$log = &Log::singleton( 'display', '', 'MultiVoyager' );
+$log->setMask( Log::MAX( PEAR_LOG_WARN ) ); 
+
+/**
+ * Multiple voyager database driver.
+ * Assumes that each record has an ILS specific prefix, ex:
+ *     555, AUM555
+ * Solrmarc can setup the prefix at import time with a 
+ * marc.properties rule like this:
+ *     001 = script(custom.bsh),getCustomId
+ * where custom.bsh has a function
+ *     public String getCustomId( Record record ) {
+ *         return "Prefix" + ((ControlField) record.getVariableFiled( "001" )).getData();
+ *     }
+ * The conf/MultiVoyager.ini file species the Voyager connection
+ * data and id-prefix for each ILS.
+ * The ini also specifies a default driver to use for patron information.
+ */
+class MultiVoyager implements DriverInterface
+{
+    private $dbPrefixMap = array();
+    
+
+    function __construct()
+    {
+        $log = &Log::singleton( 'display', '', 'MultiVoyager' );
+        // Load Configuration for this Module
+        $this->config = parse_ini_file('conf/MultiVoyager.ini', true);
+        
+        // Define Database Name
+        $configList = explode( ',', $this->config['Catalog']['configList'] );
+        $this->defaultDriver = $this->config['Catalog']['default'];
+        foreach( $configList as $configName ) {
+            $log->debug( "Setting up config: " . $configName . " with host " . $this->config[$configName]['host'] ."\n" ); 
+	    $this->dbPrefixMap[$configName] = new Voyager( $this->config[$configName] );
+        }
+    }
+
+
+   /**
+    * Return the Voyager driver appropriate for the given id, or null 
+    * if no appropriate driver registered.
+    * Public for testing.
+    */
+   public function getDriver( $id ) {
+       return $this->dbPrefixMap[ $this->getPrefix( $id ) ];
+   }
+
+   /**
+    * Public for testing
+    */
+    public function getDefaultDriver() {
+        return $this->getDriver( $this->defaultDriver );
+    }
+
+   /**
+    * Internal utility function extracts prefix from given id,
+    * or returns "EMPTY" if no prefix.  Public for testing.
+    *
+    * @param id
+    * @return letter prefix of id or "EMPTY"
+    */
+   public function getPrefix( $id ) {
+       $matches = array();
+       if( preg_match( '/^([A-Z]+)\d+$/i', $id, &$matches ) > 0 ) {
+          return $matches[1];
+       } else {
+          return "EMPTY";
+       }
+   } 
+
+
+   /**
+    * Utility function calls a closure passing the appropriate driver
+    * and id as arguments
+    * 
+    * @param id
+    * @param function to call
+    * @param noDriverResult to return if no drive is available
+    * @return $function($driver,$id) or $noDriverResult
+    */
+   private function callWithDriver( $id, $function, $noDriverResult ) {
+        $idNumber = $id;
+        // Extract post-prefix numeric id
+        if( preg_match( '/^[A-Z]+(\d+)$/i', $id, &$matches ) > 0 ) {
+            $idNumber = $matches[1];
+        }
+        $driver = $this->getDriver( $id );
+        if ( $driver ) {
+            return $function( $driver, $idNumber );
+        } else {
+            return $noDriverResult;
+        }
+   }
+
+    public function getStatus($id)
+    {
+        return $this->callWithDriver( $id, 
+                  create_function( '$driver,$id', 'return $driver->getStatus($id);' ),
+                  array() );
+    }
+
+    public function getStatuses($idList)
+    {
+       $result = array();
+       foreach( $idList as $id ) {
+            $result[] = $this->getStatus( $id );
+       }
+       return $result;
+    }
+
+    public function getHolding($id)
+    {
+        $log = &Log::singleton( 'display', '', 'MultiVoyager' );
+        $log->debug( "getHolding $id\n" );
+        return $this->callWithDriver( $id, 
+                  create_function( '$driver,$id', 'return $driver->getHolding($id);' ),
+                  array() );
+    }
+
+
+    public function getPurchaseHistory($id)
+    {
+        return $this->callWithDriver( $id, 
+                  create_function( '$driver,$id', 'return $driver->getPurchaseHistory($id);' ),
+                  array() );
+    }
+
+    public function getHoldLink($id)
+    {
+        return $this->callWithDriver( $id, 
+                  create_function( '$driver,$id', 'return $driver->getHoldLink($id);' ),
+                  "" 
+           );
+    }
+
+    public function patronLogin($barcode, $lname)
+    {
+        return $this->getDefaultDriver()->patronLogin( $barcode, $lname );
+    }
+    
+    public function getMyTransactions($patron)
+    {
+        return $this->getDefaultDriver()->getMyTransaction( $patron );
+    }
+
+    public function getMyFines($patron)
+    {
+        return $this->getDefaultDriver()->getMyFines( $patron );
+    }
+
+    public function getMyHolds($patron)
+    {
+        return $this->getDefaultDriver()->getMyHolds( $patron );
+    }
+
+    public function getMyProfile($patron)
+    {
+        return $this->getDefaultDriver()->getMyProfile( $patron );
+    }
+
+
+    public function getNewItems($page, $limit, $daysOld, $departmentId = null)
+    {
+        return $this->getDefaultDriver()->getNewItems( $page, $limit, $daysOld, $departmentId );
+    }
+    
+    function getFunds()
+    {
+        return $this->getDefaultDriver()->getFunds();
+    }
+
+    function getDepartments($startDate = null)
+    {
+        return $this->getDefaultDriver()->getDepartments( $startDate );
+    }
+    
+    function getInstructors($startDate)
+    {
+        return $this->getDefaultDriver()->getInstructors( $startDate );
+    }
+    
+    function getCourses($startDate)
+    {
+        return $this->getDefaultDriver()->getCourses( $startDate );
+    }
+
+    function findReserves($course, $inst, $dept)
+    {
+        return $this->getDefaultDriver()->findReserves( $cours, $inst, $dept );
+    }
+
+    
+}
+
+require_once ( 'PHPUnit/Framework.php' );
+ 
+/**
+ * Test case.  May need to alter for your environment.
+ * Run with 'phpunit MultiTester MultiVoyager.php'
+ */
+class MultiTester extends PHPUnit_Framework_TestCase
+{
+    public function testGetPrefix()
+    {
+        $manager = new MultiVoyager();
+        $this->assertTrue( "AUB" == $manager->getPrefix( "AUB555" ),
+                           "Got right prefix for AUB555: " + $manager->getPrefix( "AUB555" )
+                           );
+    }
+
+    public function testGetDriver() {
+        $manager = new MultiVoyager();
+        $this->assertTrue( null != $manager->getDefaultDriver(),
+                           "Default driver exists"
+                         );
+    }
+
+    public function testGetHoldings() {
+        $manager = new MultiVoyager();
+        $info = $manager->getHolding( '555555' );
+        $this->assertTrue( count( $info ) > 0,
+                           "Got some holdings" );
+    }
+
+    public function testGetStatuses() {
+        $manager = new MultiVoyager();
+        $statusList = array( 'AUM363352' );
+        $info = $manager->getStatuses( $statusList );
+        $this->assertTrue( count( $info ) > 0,
+                           "Got some status" );
+    }
+}
+
+#$test = new MultiTester();
+#$test->testGetPrefix();
+#$test->testGetDriver();
+
+?>
--- a/web/Drivers/Voyager.php	Thu Oct 28 12:02:19 2010 -0500
+++ b/web/Drivers/Voyager.php	Sun Oct 31 16:08:22 2010 -0500
@@ -18,6 +18,12 @@
  *
  */
 require_once 'Interface.php';
+require_once( 'Log.php' );
+
+
+# Set log mask once
+$log = &Log::singleton( 'display', '', 'Voyager' );
+$log->setMask( Log::MAX( PEAR_LOG_WARN ) ); 
 
 class Voyager implements DriverInterface
 {
@@ -26,10 +32,14 @@
     private $config;
     private $statusRankings = false;        // used by pickStatus() method
     
-    function __construct()
+    function __construct( $config )
     {
-        // Load Configuration for this Module
-        $this->config = parse_ini_file('conf/Voyager.ini', true);
+        if( $config ) {
+            $this->config = array( 'Catalog' => $config );
+        } else {
+            // Load Configuration for this Module
+            $this->config = parse_ini_file('conf/Voyager.ini', true);
+        }
         
         // Define Database Name
         $this->dbName = $this->config['Catalog']['database'];
@@ -46,6 +56,8 @@
                    '(SID=' . $this->config['Catalog']['service'] . ')' .
                  ')' . 
                ')';
+        $log = &Log::singleton( 'display', '', 'Voyager' );
+        $log->debug( "Voyager tns: " . $tns );
         try {
             $this->db = new PDO("oci:dbname=$tns",
                                 $this->config['Catalog']['user'],
--- a/web/services/Record/Holdings.php	Thu Oct 28 12:02:19 2010 -0500
+++ b/web/services/Record/Holdings.php	Sun Oct 31 16:08:22 2010 -0500
@@ -48,8 +48,8 @@
         }
 
         // Get Holdings Data
-        if ($catalog->status 
-             && preg_match( "/^[0-9]+$/", $this->id ) ) {
+        if ($catalog->status ) {
+             // -- old pre-AUM check ... && preg_match( "/^[0-9]+$/", $this->id ) ) {
             $result = $catalog->getHolding($this->id);
             if (PEAR::isError($result)) {
                 PEAR::raiseError($result);
@@ -63,6 +63,7 @@
               }
             }
             $interface->assign('holdings', $holdings);
+            //print_r($holdings);
     
             // Get Acquisitions Data
             $result = $catalog->getPurchaseHistory($this->id);
--- a/web/services/Search/AJAX.php	Thu Oct 28 12:02:19 2010 -0500
+++ b/web/services/Search/AJAX.php	Sun Oct 31 16:08:22 2010 -0500
@@ -70,53 +70,55 @@
         
         $result = $catalog->getStatuses($_GET['id']);
         
-        foreach ($result as $record) {
-            $available = false;
-            $location = '';
-            foreach ($record as $info) {
-                // Find an available copy
-                if ($info['availability']) {
-                    $available = true;
-                }
-
-                // Has multiple locations?
-                if ($location != 'Multiple Locations') {
-                    if ($location != '') {
-                        if ($info['location'] != $location) {
-                            $location = 'Multiple Locations';
+        foreach ($_GET['id'] as $id) {
+            foreach ($result as $record) {
+                $available = false;
+                $location = '';
+                foreach ($record as $info) {
+                    // Find an available copy
+                    if ($info['availability']) {
+                        $available = true;
+                    }
+    
+                    // Has multiple locations?
+                    if ($location != 'Multiple Locations') {
+                        if ($location != '') {
+                            if ($info['location'] != $location) {
+                                $location = 'Multiple Locations';
+                            } else {
+                                $location = htmlentities($info['location']);
+                            }
                         } else {
                             $location = htmlentities($info['location']);
                         }
-                    } else {
-                        $location = htmlentities($info['location']);
                     }
                 }
+                
+                echo ' <item id="' . $id . '">';
+                echo '  <status>'.$record[0]['status'].'</status>';
+                if ($available) {
+                    echo '  <availability>true</availability>';
+                } else {
+                    echo '  <availability>false</availability>';
+    
+                    // Auburn addition written by Clint Bellanger
+                    // include a Recall link for this item if logged in
+                    global $user;
+                    if ($user->cat_username) {
+                      echo '  <recall>';
+                      echo 'http://aubiecat.auburn.edu/cgi-bin/Pwebrecon.cgi';
+                      echo '?BBID=' . $record[0]['id'];
+                      echo '&amp;BC=' . $user->cat_username;
+                      echo '&amp;LN=' . $user->cat_password;
+                      echo '&amp;AUACTION=request';
+                      echo '</recall>';
+                    }
+                }
+                echo '  <location>' . $location . '</location>';
+                echo '  <reserve>' . $record[0]['reserve'] . '</reserve>';
+                echo '  <callnumber>' . $record[0]['callnumber'] . '</callnumber>';
+                echo ' </item>';
             }
-            
-            echo ' <item id="' . $record[0]['id'] . '">';
-            echo '  <status>'.$record[0]['status'].'</status>';
-            if ($available) {
-                echo '  <availability>true</availability>';
-            } else {
-                echo '  <availability>false</availability>';
-
-                // Auburn addition written by Clint Bellanger
-                // include a Recall link for this item if logged in
-                global $user;
-                if ($user->cat_username) {
-                  echo '  <recall>';
-                  echo 'http://aubiecat.auburn.edu/cgi-bin/Pwebrecon.cgi';
-                  echo '?BBID=' . $record[0]['id'];
-                  echo '&amp;BC=' . $user->cat_username;
-                  echo '&amp;LN=' . $user->cat_password;
-                  echo '&amp;AUACTION=request';
-                  echo '</recall>';
-                }
-            }
-            echo '  <location>' . $location . '</location>';
-            echo '  <reserve>' . $record[0]['reserve'] . '</reserve>';
-            echo '  <callnumber>' . $record[0]['callnumber'] . '</callnumber>';
-            echo ' </item>';
         }
 
     }
--- a/web/sys/SS360Link.php	Thu Oct 28 12:02:19 2010 -0500
+++ b/web/sys/SS360Link.php	Sun Oct 31 16:08:22 2010 -0500
@@ -23,10 +23,11 @@
 require_once( 'Log.php' );
 require_once( 'sys/AuUtil.php' );
 
-$log = Log::singleton( 'console', '', 'Three60Link' );
-$log->setMask( Log::MAX( PEAR_LOG_INFO ) );
+class Data {}
 
-class Data {}
+# Set log mask once
+$log = &Log::singleton( 'display', '', 'Three60Link' );
+$log->setMask( Log::MAX( PEAR_LOG_WARN ) ); 
 
 /**
  * Little interface to Serial Solution's 360Link
@@ -40,7 +41,7 @@
      */
     function lookupByIssn( $sIssn, $id ) {
         //global $log;
-        $log = Log::singleton( 'console', '', 'Three60Link' );
+        $log = &Log::singleton( 'display', '', 'Three60Link' );
         $sUrl = "http://" . $this->sServer . "/openurlxml?version=1.0&issn=" .
             $sIssn;
         $log->debug( "URL: $sUrl" );