vufind

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 Oct 31 16:08:22 2010 -0500 (2010-10-31)
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
line diff
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/web/Drivers/MultiVoyager.php	Sun Oct 31 16:08:22 2010 -0500
     1.3 @@ -0,0 +1,251 @@
     1.4 +<?php
     1.5 +/**
     1.6 + * This program is free software; you can redistribute it and/or modify
     1.7 + * it under the terms of the GNU General Public License version 2,
     1.8 + * as published by the Free Software Foundation.
     1.9 + *     http://www.gnu.org/licenses/gpl-2.0.html
    1.10 + */
    1.11 +require_once 'Interface.php';
    1.12 +require_once 'Voyager.php';
    1.13 +require_once 'Log.php';
    1.14 +
    1.15 +# Set log mask once
    1.16 +$log = &Log::singleton( 'display', '', 'MultiVoyager' );
    1.17 +$log->setMask( Log::MAX( PEAR_LOG_WARN ) ); 
    1.18 +
    1.19 +/**
    1.20 + * Multiple voyager database driver.
    1.21 + * Assumes that each record has an ILS specific prefix, ex:
    1.22 + *     555, AUM555
    1.23 + * Solrmarc can setup the prefix at import time with a 
    1.24 + * marc.properties rule like this:
    1.25 + *     001 = script(custom.bsh),getCustomId
    1.26 + * where custom.bsh has a function
    1.27 + *     public String getCustomId( Record record ) {
    1.28 + *         return "Prefix" + ((ControlField) record.getVariableFiled( "001" )).getData();
    1.29 + *     }
    1.30 + * The conf/MultiVoyager.ini file species the Voyager connection
    1.31 + * data and id-prefix for each ILS.
    1.32 + * The ini also specifies a default driver to use for patron information.
    1.33 + */
    1.34 +class MultiVoyager implements DriverInterface
    1.35 +{
    1.36 +    private $dbPrefixMap = array();
    1.37 +    
    1.38 +
    1.39 +    function __construct()
    1.40 +    {
    1.41 +        $log = &Log::singleton( 'display', '', 'MultiVoyager' );
    1.42 +        // Load Configuration for this Module
    1.43 +        $this->config = parse_ini_file('conf/MultiVoyager.ini', true);
    1.44 +        
    1.45 +        // Define Database Name
    1.46 +        $configList = explode( ',', $this->config['Catalog']['configList'] );
    1.47 +        $this->defaultDriver = $this->config['Catalog']['default'];
    1.48 +        foreach( $configList as $configName ) {
    1.49 +            $log->debug( "Setting up config: " . $configName . " with host " . $this->config[$configName]['host'] ."\n" ); 
    1.50 +	    $this->dbPrefixMap[$configName] = new Voyager( $this->config[$configName] );
    1.51 +        }
    1.52 +    }
    1.53 +
    1.54 +
    1.55 +   /**
    1.56 +    * Return the Voyager driver appropriate for the given id, or null 
    1.57 +    * if no appropriate driver registered.
    1.58 +    * Public for testing.
    1.59 +    */
    1.60 +   public function getDriver( $id ) {
    1.61 +       return $this->dbPrefixMap[ $this->getPrefix( $id ) ];
    1.62 +   }
    1.63 +
    1.64 +   /**
    1.65 +    * Public for testing
    1.66 +    */
    1.67 +    public function getDefaultDriver() {
    1.68 +        return $this->getDriver( $this->defaultDriver );
    1.69 +    }
    1.70 +
    1.71 +   /**
    1.72 +    * Internal utility function extracts prefix from given id,
    1.73 +    * or returns "EMPTY" if no prefix.  Public for testing.
    1.74 +    *
    1.75 +    * @param id
    1.76 +    * @return letter prefix of id or "EMPTY"
    1.77 +    */
    1.78 +   public function getPrefix( $id ) {
    1.79 +       $matches = array();
    1.80 +       if( preg_match( '/^([A-Z]+)\d+$/i', $id, &$matches ) > 0 ) {
    1.81 +          return $matches[1];
    1.82 +       } else {
    1.83 +          return "EMPTY";
    1.84 +       }
    1.85 +   } 
    1.86 +
    1.87 +
    1.88 +   /**
    1.89 +    * Utility function calls a closure passing the appropriate driver
    1.90 +    * and id as arguments
    1.91 +    * 
    1.92 +    * @param id
    1.93 +    * @param function to call
    1.94 +    * @param noDriverResult to return if no drive is available
    1.95 +    * @return $function($driver,$id) or $noDriverResult
    1.96 +    */
    1.97 +   private function callWithDriver( $id, $function, $noDriverResult ) {
    1.98 +        $idNumber = $id;
    1.99 +        // Extract post-prefix numeric id
   1.100 +        if( preg_match( '/^[A-Z]+(\d+)$/i', $id, &$matches ) > 0 ) {
   1.101 +            $idNumber = $matches[1];
   1.102 +        }
   1.103 +        $driver = $this->getDriver( $id );
   1.104 +        if ( $driver ) {
   1.105 +            return $function( $driver, $idNumber );
   1.106 +        } else {
   1.107 +            return $noDriverResult;
   1.108 +        }
   1.109 +   }
   1.110 +
   1.111 +    public function getStatus($id)
   1.112 +    {
   1.113 +        return $this->callWithDriver( $id, 
   1.114 +                  create_function( '$driver,$id', 'return $driver->getStatus($id);' ),
   1.115 +                  array() );
   1.116 +    }
   1.117 +
   1.118 +    public function getStatuses($idList)
   1.119 +    {
   1.120 +       $result = array();
   1.121 +       foreach( $idList as $id ) {
   1.122 +            $result[] = $this->getStatus( $id );
   1.123 +       }
   1.124 +       return $result;
   1.125 +    }
   1.126 +
   1.127 +    public function getHolding($id)
   1.128 +    {
   1.129 +        $log = &Log::singleton( 'display', '', 'MultiVoyager' );
   1.130 +        $log->debug( "getHolding $id\n" );
   1.131 +        return $this->callWithDriver( $id, 
   1.132 +                  create_function( '$driver,$id', 'return $driver->getHolding($id);' ),
   1.133 +                  array() );
   1.134 +    }
   1.135 +
   1.136 +
   1.137 +    public function getPurchaseHistory($id)
   1.138 +    {
   1.139 +        return $this->callWithDriver( $id, 
   1.140 +                  create_function( '$driver,$id', 'return $driver->getPurchaseHistory($id);' ),
   1.141 +                  array() );
   1.142 +    }
   1.143 +
   1.144 +    public function getHoldLink($id)
   1.145 +    {
   1.146 +        return $this->callWithDriver( $id, 
   1.147 +                  create_function( '$driver,$id', 'return $driver->getHoldLink($id);' ),
   1.148 +                  "" 
   1.149 +           );
   1.150 +    }
   1.151 +
   1.152 +    public function patronLogin($barcode, $lname)
   1.153 +    {
   1.154 +        return $this->getDefaultDriver()->patronLogin( $barcode, $lname );
   1.155 +    }
   1.156 +    
   1.157 +    public function getMyTransactions($patron)
   1.158 +    {
   1.159 +        return $this->getDefaultDriver()->getMyTransaction( $patron );
   1.160 +    }
   1.161 +
   1.162 +    public function getMyFines($patron)
   1.163 +    {
   1.164 +        return $this->getDefaultDriver()->getMyFines( $patron );
   1.165 +    }
   1.166 +
   1.167 +    public function getMyHolds($patron)
   1.168 +    {
   1.169 +        return $this->getDefaultDriver()->getMyHolds( $patron );
   1.170 +    }
   1.171 +
   1.172 +    public function getMyProfile($patron)
   1.173 +    {
   1.174 +        return $this->getDefaultDriver()->getMyProfile( $patron );
   1.175 +    }
   1.176 +
   1.177 +
   1.178 +    public function getNewItems($page, $limit, $daysOld, $departmentId = null)
   1.179 +    {
   1.180 +        return $this->getDefaultDriver()->getNewItems( $page, $limit, $daysOld, $departmentId );
   1.181 +    }
   1.182 +    
   1.183 +    function getFunds()
   1.184 +    {
   1.185 +        return $this->getDefaultDriver()->getFunds();
   1.186 +    }
   1.187 +
   1.188 +    function getDepartments($startDate = null)
   1.189 +    {
   1.190 +        return $this->getDefaultDriver()->getDepartments( $startDate );
   1.191 +    }
   1.192 +    
   1.193 +    function getInstructors($startDate)
   1.194 +    {
   1.195 +        return $this->getDefaultDriver()->getInstructors( $startDate );
   1.196 +    }
   1.197 +    
   1.198 +    function getCourses($startDate)
   1.199 +    {
   1.200 +        return $this->getDefaultDriver()->getCourses( $startDate );
   1.201 +    }
   1.202 +
   1.203 +    function findReserves($course, $inst, $dept)
   1.204 +    {
   1.205 +        return $this->getDefaultDriver()->findReserves( $cours, $inst, $dept );
   1.206 +    }
   1.207 +
   1.208 +    
   1.209 +}
   1.210 +
   1.211 +require_once ( 'PHPUnit/Framework.php' );
   1.212 + 
   1.213 +/**
   1.214 + * Test case.  May need to alter for your environment.
   1.215 + * Run with 'phpunit MultiTester MultiVoyager.php'
   1.216 + */
   1.217 +class MultiTester extends PHPUnit_Framework_TestCase
   1.218 +{
   1.219 +    public function testGetPrefix()
   1.220 +    {
   1.221 +        $manager = new MultiVoyager();
   1.222 +        $this->assertTrue( "AUB" == $manager->getPrefix( "AUB555" ),
   1.223 +                           "Got right prefix for AUB555: " + $manager->getPrefix( "AUB555" )
   1.224 +                           );
   1.225 +    }
   1.226 +
   1.227 +    public function testGetDriver() {
   1.228 +        $manager = new MultiVoyager();
   1.229 +        $this->assertTrue( null != $manager->getDefaultDriver(),
   1.230 +                           "Default driver exists"
   1.231 +                         );
   1.232 +    }
   1.233 +
   1.234 +    public function testGetHoldings() {
   1.235 +        $manager = new MultiVoyager();
   1.236 +        $info = $manager->getHolding( '555555' );
   1.237 +        $this->assertTrue( count( $info ) > 0,
   1.238 +                           "Got some holdings" );
   1.239 +    }
   1.240 +
   1.241 +    public function testGetStatuses() {
   1.242 +        $manager = new MultiVoyager();
   1.243 +        $statusList = array( 'AUM363352' );
   1.244 +        $info = $manager->getStatuses( $statusList );
   1.245 +        $this->assertTrue( count( $info ) > 0,
   1.246 +                           "Got some status" );
   1.247 +    }
   1.248 +}
   1.249 +
   1.250 +#$test = new MultiTester();
   1.251 +#$test->testGetPrefix();
   1.252 +#$test->testGetDriver();
   1.253 +
   1.254 +?>
     2.1 --- a/web/Drivers/Voyager.php	Thu Oct 28 12:02:19 2010 -0500
     2.2 +++ b/web/Drivers/Voyager.php	Sun Oct 31 16:08:22 2010 -0500
     2.3 @@ -18,6 +18,12 @@
     2.4   *
     2.5   */
     2.6  require_once 'Interface.php';
     2.7 +require_once( 'Log.php' );
     2.8 +
     2.9 +
    2.10 +# Set log mask once
    2.11 +$log = &Log::singleton( 'display', '', 'Voyager' );
    2.12 +$log->setMask( Log::MAX( PEAR_LOG_WARN ) ); 
    2.13  
    2.14  class Voyager implements DriverInterface
    2.15  {
    2.16 @@ -26,10 +32,14 @@
    2.17      private $config;
    2.18      private $statusRankings = false;        // used by pickStatus() method
    2.19      
    2.20 -    function __construct()
    2.21 +    function __construct( $config )
    2.22      {
    2.23 -        // Load Configuration for this Module
    2.24 -        $this->config = parse_ini_file('conf/Voyager.ini', true);
    2.25 +        if( $config ) {
    2.26 +            $this->config = array( 'Catalog' => $config );
    2.27 +        } else {
    2.28 +            // Load Configuration for this Module
    2.29 +            $this->config = parse_ini_file('conf/Voyager.ini', true);
    2.30 +        }
    2.31          
    2.32          // Define Database Name
    2.33          $this->dbName = $this->config['Catalog']['database'];
    2.34 @@ -46,6 +56,8 @@
    2.35                     '(SID=' . $this->config['Catalog']['service'] . ')' .
    2.36                   ')' . 
    2.37                 ')';
    2.38 +        $log = &Log::singleton( 'display', '', 'Voyager' );
    2.39 +        $log->debug( "Voyager tns: " . $tns );
    2.40          try {
    2.41              $this->db = new PDO("oci:dbname=$tns",
    2.42                                  $this->config['Catalog']['user'],
     3.1 --- a/web/services/Record/Holdings.php	Thu Oct 28 12:02:19 2010 -0500
     3.2 +++ b/web/services/Record/Holdings.php	Sun Oct 31 16:08:22 2010 -0500
     3.3 @@ -48,8 +48,8 @@
     3.4          }
     3.5  
     3.6          // Get Holdings Data
     3.7 -        if ($catalog->status 
     3.8 -             && preg_match( "/^[0-9]+$/", $this->id ) ) {
     3.9 +        if ($catalog->status ) {
    3.10 +             // -- old pre-AUM check ... && preg_match( "/^[0-9]+$/", $this->id ) ) {
    3.11              $result = $catalog->getHolding($this->id);
    3.12              if (PEAR::isError($result)) {
    3.13                  PEAR::raiseError($result);
    3.14 @@ -63,6 +63,7 @@
    3.15                }
    3.16              }
    3.17              $interface->assign('holdings', $holdings);
    3.18 +            //print_r($holdings);
    3.19      
    3.20              // Get Acquisitions Data
    3.21              $result = $catalog->getPurchaseHistory($this->id);
     4.1 --- a/web/services/Search/AJAX.php	Thu Oct 28 12:02:19 2010 -0500
     4.2 +++ b/web/services/Search/AJAX.php	Sun Oct 31 16:08:22 2010 -0500
     4.3 @@ -70,53 +70,55 @@
     4.4          
     4.5          $result = $catalog->getStatuses($_GET['id']);
     4.6          
     4.7 -        foreach ($result as $record) {
     4.8 -            $available = false;
     4.9 -            $location = '';
    4.10 -            foreach ($record as $info) {
    4.11 -                // Find an available copy
    4.12 -                if ($info['availability']) {
    4.13 -                    $available = true;
    4.14 -                }
    4.15 -
    4.16 -                // Has multiple locations?
    4.17 -                if ($location != 'Multiple Locations') {
    4.18 -                    if ($location != '') {
    4.19 -                        if ($info['location'] != $location) {
    4.20 -                            $location = 'Multiple Locations';
    4.21 +        foreach ($_GET['id'] as $id) {
    4.22 +            foreach ($result as $record) {
    4.23 +                $available = false;
    4.24 +                $location = '';
    4.25 +                foreach ($record as $info) {
    4.26 +                    // Find an available copy
    4.27 +                    if ($info['availability']) {
    4.28 +                        $available = true;
    4.29 +                    }
    4.30 +    
    4.31 +                    // Has multiple locations?
    4.32 +                    if ($location != 'Multiple Locations') {
    4.33 +                        if ($location != '') {
    4.34 +                            if ($info['location'] != $location) {
    4.35 +                                $location = 'Multiple Locations';
    4.36 +                            } else {
    4.37 +                                $location = htmlentities($info['location']);
    4.38 +                            }
    4.39                          } else {
    4.40                              $location = htmlentities($info['location']);
    4.41                          }
    4.42 -                    } else {
    4.43 -                        $location = htmlentities($info['location']);
    4.44                      }
    4.45                  }
    4.46 +                
    4.47 +                echo ' <item id="' . $id . '">';
    4.48 +                echo '  <status>'.$record[0]['status'].'</status>';
    4.49 +                if ($available) {
    4.50 +                    echo '  <availability>true</availability>';
    4.51 +                } else {
    4.52 +                    echo '  <availability>false</availability>';
    4.53 +    
    4.54 +                    // Auburn addition written by Clint Bellanger
    4.55 +                    // include a Recall link for this item if logged in
    4.56 +                    global $user;
    4.57 +                    if ($user->cat_username) {
    4.58 +                      echo '  <recall>';
    4.59 +                      echo 'http://aubiecat.auburn.edu/cgi-bin/Pwebrecon.cgi';
    4.60 +                      echo '?BBID=' . $record[0]['id'];
    4.61 +                      echo '&amp;BC=' . $user->cat_username;
    4.62 +                      echo '&amp;LN=' . $user->cat_password;
    4.63 +                      echo '&amp;AUACTION=request';
    4.64 +                      echo '</recall>';
    4.65 +                    }
    4.66 +                }
    4.67 +                echo '  <location>' . $location . '</location>';
    4.68 +                echo '  <reserve>' . $record[0]['reserve'] . '</reserve>';
    4.69 +                echo '  <callnumber>' . $record[0]['callnumber'] . '</callnumber>';
    4.70 +                echo ' </item>';
    4.71              }
    4.72 -            
    4.73 -            echo ' <item id="' . $record[0]['id'] . '">';
    4.74 -            echo '  <status>'.$record[0]['status'].'</status>';
    4.75 -            if ($available) {
    4.76 -                echo '  <availability>true</availability>';
    4.77 -            } else {
    4.78 -                echo '  <availability>false</availability>';
    4.79 -
    4.80 -                // Auburn addition written by Clint Bellanger
    4.81 -                // include a Recall link for this item if logged in
    4.82 -                global $user;
    4.83 -                if ($user->cat_username) {
    4.84 -                  echo '  <recall>';
    4.85 -                  echo 'http://aubiecat.auburn.edu/cgi-bin/Pwebrecon.cgi';
    4.86 -                  echo '?BBID=' . $record[0]['id'];
    4.87 -                  echo '&amp;BC=' . $user->cat_username;
    4.88 -                  echo '&amp;LN=' . $user->cat_password;
    4.89 -                  echo '&amp;AUACTION=request';
    4.90 -                  echo '</recall>';
    4.91 -                }
    4.92 -            }
    4.93 -            echo '  <location>' . $location . '</location>';
    4.94 -            echo '  <reserve>' . $record[0]['reserve'] . '</reserve>';
    4.95 -            echo '  <callnumber>' . $record[0]['callnumber'] . '</callnumber>';
    4.96 -            echo ' </item>';
    4.97          }
    4.98  
    4.99      }
     5.1 --- a/web/sys/SS360Link.php	Thu Oct 28 12:02:19 2010 -0500
     5.2 +++ b/web/sys/SS360Link.php	Sun Oct 31 16:08:22 2010 -0500
     5.3 @@ -23,10 +23,11 @@
     5.4  require_once( 'Log.php' );
     5.5  require_once( 'sys/AuUtil.php' );
     5.6  
     5.7 -$log = Log::singleton( 'console', '', 'Three60Link' );
     5.8 -$log->setMask( Log::MAX( PEAR_LOG_INFO ) );
     5.9 +class Data {}
    5.10  
    5.11 -class Data {}
    5.12 +# Set log mask once
    5.13 +$log = &Log::singleton( 'display', '', 'Three60Link' );
    5.14 +$log->setMask( Log::MAX( PEAR_LOG_WARN ) ); 
    5.15  
    5.16  /**
    5.17   * Little interface to Serial Solution's 360Link
    5.18 @@ -40,7 +41,7 @@
    5.19       */
    5.20      function lookupByIssn( $sIssn, $id ) {
    5.21          //global $log;
    5.22 -        $log = Log::singleton( 'console', '', 'Three60Link' );
    5.23 +        $log = &Log::singleton( 'display', '', 'Three60Link' );
    5.24          $sUrl = "http://" . $this->sServer . "/openurlxml?version=1.0&issn=" .
    5.25              $sIssn;
    5.26          $log->debug( "URL: $sUrl" );