diff --git a/module/VuFind/src/VuFind/ILS/Driver/Horizon.php b/module/VuFind/src/VuFind/ILS/Driver/Horizon.php index ec275a31f27821c386a48620f27a1b7fafbc8c32..cd2711314044feadef838c17dca662beeb646d3d 100644 --- a/module/VuFind/src/VuFind/ILS/Driver/Horizon.php +++ b/module/VuFind/src/VuFind/ILS/Driver/Horizon.php @@ -2,7 +2,7 @@ /** * Horizon ILS Driver * - * PHP version 5 + * PHP version 7 * * Copyright (C) Villanova University 2007. * @@ -27,8 +27,10 @@ * @link https://vufind.org/wiki/development:plugins:ils_drivers Wiki */ namespace VuFind\ILS\Driver; - -use VuFind\Exception\ILS as ILSException; +use PDO, PDOException, + VuFind\Exception\ILS as ILSException, + Zend\Log\LoggerAwareInterface, + VuFind\Log\LoggerAwareTrait; /** * Horizon ILS Driver @@ -40,8 +42,10 @@ use VuFind\Exception\ILS as ILSException; * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License * @link https://vufind.org/wiki/development:plugins:ils_drivers Wiki */ -class Horizon extends AbstractBase +class Horizon extends AbstractBase implements LoggerAwareInterface { + use LoggerAwareTrait; + /** * Date converter object * @@ -80,17 +84,24 @@ class Horizon extends AbstractBase if (empty($this->config)) { throw new ILSException('Configuration needs to be set.'); } - + // Connect to database - $this->db = mssql_pconnect( - $this->config['Catalog']['host'] . ':' - . $this->config['Catalog']['port'], - $this->config['Catalog']['username'], - $this->config['Catalog']['password'] - ); - - // Select the databse - mssql_select_db($this->config['Catalog']['database']); + try { + $this->db = new PDO( + 'dblib:host=' . $this->config['Catalog']['host'] . + ':' . $this->config['Catalog']['port'] . + ';dbname=' . $this->config['Catalog']['database'], + $this->config['Catalog']['username'], + $this->config['Catalog']['password'] + ); + + // throw an exception instead of false on sql errors + $this->db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); + + } catch (\Exception $e) { + $this->logError($e->getMessage()); + throw new ILSException('ILS Configuration problem : ' . $e->getMessage()); + } } /** @@ -335,12 +346,16 @@ class Horizon extends AbstractBase try { $holding = []; - $sqlStmt = mssql_query($sql); - while ($row = mssql_fetch_assoc($sqlStmt)) { + $sqlStmt = $this->db->query($sql); + foreach ($sqlStmt as $row) { $holding[] = $this->processHoldingRow($id, $row, $patron); } + + $this->debug(json_encode($holding)); + return $holding; } catch (\Exception $e) { + $this->logError($e->getMessage()); throw new ILSException($e->getMessage()); } } @@ -358,12 +373,14 @@ class Horizon extends AbstractBase $item_status = $row['STATUS_CODE']; //get the item status code $statusValues = $this->parseStatus($item_status); - $status = ['id' => $id, - 'availability' => $statusValues['available'], - 'status' => $row['STATUS'], - 'location' => $row['LOCATION'], - 'reserve' => $statusValues['reserve'], - 'callnumber' => $row['CALLNUMBER']]; + $status = [ + 'id' => $id, + 'availability' => $statusValues['available'], + 'status' => $row['STATUS'], + 'location' => $row['LOCATION'], + 'reserve' => $statusValues['reserve'], + 'callnumber' => $row['CALLNUMBER'] + ]; return $status; } @@ -418,10 +435,13 @@ class Horizon extends AbstractBase $sqlWhere = ["i.bib# in (" . $bibIDs . ")", "i.staff_only = 0"]; - $sqlArray = ['expressions' => $sqlExpressions, - 'from' => $sqlFrom, - 'innerJoin' => $sqlInnerJoin, - 'where' => $sqlWhere]; + $sqlArray = [ + 'expressions' => $sqlExpressions, + 'from' => $sqlFrom, + 'innerJoin' => $sqlInnerJoin, + 'where' => $sqlWhere + ]; + return $sqlArray; } @@ -455,13 +475,14 @@ class Horizon extends AbstractBase try { $status = []; - $sqlStmt = mssql_query($sql); - while ($row = mssql_fetch_assoc($sqlStmt)) { + $sqlStmt = $this->db->query($sql); + foreach ($sqlStmt as $row) { $id = $row['ID']; $status[$id][] = $this->processStatusRow($id, $row); } return $status; } catch (\Exception $e) { + $this->logError($e->getMessage()); throw new ILSException($e->getMessage()); } } @@ -492,39 +513,48 @@ class Horizon extends AbstractBase * * @throws ILSException * @return mixed Associative array of patron info on successful login, - * null on unsuccessful login. + * ILSException on unsuccessful login. */ public function patronLogin($username, $password) { $sql = "select name_reconstructed as FULLNAME, " . - "email_address as EMAIL from borrower " . + "email_address as EMAIL " . + "from borrower " . "left outer join borrower_address on " . - "borrower_address.borrower#=borrower.borrower# " . + "borrower_address.borrower# = borrower.borrower# " . "inner join borrower_barcode on " . - "borrower.borrower#=borrower_barcode.borrower# " . - "where borrower_barcode.bbarcode=\"" . addslashes($username) . - "\" and pin# = \"" . addslashes($password) . "\""; - + "borrower.borrower# = borrower_barcode.borrower# " . + "where borrower_barcode.bbarcode = " . + "'" . addslashes($username) . "' " . + "and pin# = '" . addslashes($password) . "'"; + try { $user = []; - $sqlStmt = mssql_query($sql); - $row = mssql_fetch_assoc($sqlStmt); - if ($row) { - list($lastname, $firstname) = explode(', ', $row['FULLNAME']); - $user = ['id' => $username, - 'firstname' => $firstname, - 'lastname' => $lastname, - 'cat_username' => $username, - 'cat_password' => $password, - 'email' => $row['EMAIL'], - 'major' => null, - 'college' => null]; - + + $sqlStmt = $this->db->query($sql); + foreach ($sqlStmt as $row) { + list($lastname,$firstname) = explode(', ', $row['FULLNAME']); + $user = [ + 'id' => $username, + 'firstname' => $firstname, + 'lastname' => $lastname, + 'cat_username' => $username, + 'cat_password' => $password, + 'email' => $row['EMAIL'], + 'major' => null, + 'college' => null + ]; + + $this->debug(json_encode($user)); + return $user; - } else { - return null; } + + throw new ILSException( + 'Unable to login patron ' . $patron['id'] + ); } catch (\Exception $e) { + $this->logError($e->getMessage()); throw new ILSException($e->getMessage()); } } @@ -578,8 +608,7 @@ class Horizon extends AbstractBase // Where $sqlWhere = [ - "bb.bbarcode=\"" . addslashes($patron['id']) . - "\"" + "bb.bbarcode='" . addslashes($patron['id']) . "'" ]; $sqlOrder = [ @@ -672,16 +701,19 @@ class Horizon extends AbstractBase $sql = $this->buildSqlFromArray($sqlArray); try { - $sqlStmt = mssql_query($sql); - - while ($row = mssql_fetch_assoc($sqlStmt)) { + $sqlStmt = $this->db->query($sql); + foreach ($sqlStmt as $row) { $hold = $this->processHoldsRow($row); if ($hold) { $holdList[] = $hold; } } + + $this->debug(json_encode($holdList)); + return $holdList; } catch (\Exception $e) { + $this->logError($e->getMessage()); throw new ILSException($e->getMessage()); } } @@ -750,7 +782,7 @@ class Horizon extends AbstractBase " on bu4.reference# = bu.reference# " . " and bu4.ord = 0 " . " and bu4.block in ('l', 'LostPro','fine','he') " . - " where bb.bbarcode = \"" . addslashes($patron['id']) . "\" " . + " where bb.bbarcode = '" . addslashes($patron['id']) . "' " . " and bu.ord = 0 " . " and bl.pac_display = 1 " . " order by FEEBLOCK desc " . @@ -760,20 +792,26 @@ class Horizon extends AbstractBase " , bu.date"; try { - $sqlStmt = mssql_query($sql); - - while ($row = mssql_fetch_assoc($sqlStmt)) { - $fineList[] = ['amount' => $row['AMOUNT'], - 'checkout' => $row['CHECKOUT'], - 'fine' => $row['FINE'], - 'balance' => $row['BALANCE'], - 'createdate' => $row['CREATEDATE'], - 'duedate' => $row['DUEDATE'], - 'id' => $row['ID'], - 'title' => $row['TITLE']]; + $sqlStmt = $this->db->query($sql); + $fineList = []; + foreach ($sqlStmt as $row) { + $fineList[] = [ + 'amount' => $row['AMOUNT'], + 'checkout' => $row['CHECKOUT'], + 'fine' => $row['FINE'], + 'balance' => $row['BALANCE'], + 'createdate' => $row['CREATEDATE'], + 'duedate' => $row['DUEDATE'], + 'id' => $row['ID'], + 'title' => $row['TITLE'] + ]; } + + $this->debug(json_encode($fineList)); + return $fineList; } catch (\Exception $e) { + $this->logError($e->getMessage()); throw new ILSException($e->getMessage()); } } @@ -786,7 +824,8 @@ class Horizon extends AbstractBase * @param array $patron The patron array * * @throws ILSException - * @return array Array of the patron's profile data on success. + * @return array Array of the patron's profile data on success, + * throw ILSException if none found */ public function getMyProfile($patron) { @@ -794,32 +833,38 @@ class Horizon extends AbstractBase "city_st.descr as ADDRESS2, postal_code as ZIP, phone_no as PHONE " . "from borrower " . "left outer join borrower_phone on " . - "borrower_phone.borrower#=borrower.borrower# " . + "borrower_phone.borrower#=borrower.borrower# " . "inner join borrower_address on " . - "borrower_address.borrower#=borrower.borrower# " . + "borrower_address.borrower#=borrower.borrower# " . "inner join city_st on city_st.city_st=borrower_address.city_st " . "inner join borrower_barcode on " . - "borrower_barcode.borrower#=borrower.borrower# " . - "where borrower_barcode.bbarcode=\"" . addslashes($patron['id']) . "\""; - + "borrower_barcode.borrower# = borrower.borrower# " . + "where borrower_barcode.bbarcode = '" . addslashes($patron['id']) . "'"; + try { - $sqlStmt = mssql_query($sql); - - $row = mssql_fetch_assoc($sqlStmt); - if ($row) { - list($lastname, $firstname) = explode(', ', $row['FULLNAME']); - $profile = ['lastname' => $lastname, - 'firstname' => $firstname, - 'address1' => $row['ADDRESS1'], - 'address2' => $row['ADDRESS2'], - 'zip' => $row['ZIP'], - 'phone' => $row['PHONE'], - 'group' => null]; + $sqlStmt = $this->db->query($sql); + foreach ($sqlStmt as $row) { + list($lastname,$firstname) = explode(', ', $row['FULLNAME']); + $profile = [ + 'lastname' => $lastname, + 'firstname' => $firstname, + 'address1' => $row['ADDRESS1'], + 'address2' => $row['ADDRESS2'], + 'zip' => $row['ZIP'], + 'phone' => $row['PHONE'], + 'group' => null + ]; + + $this->debug(json_encode($profile)); + return $profile; - } else { - return null; } + + throw new ILSException( + 'Unable to retrieve profile for patron ' . $patron['id'] + ); } catch (\Exception $e) { + $this->logError($e->getMessage()); throw new ILSException($e->getMessage()); } } @@ -866,7 +911,7 @@ class Horizon extends AbstractBase // Where $sqlWhere = [ - "bb.bbarcode=\"" . addslashes($patron['id']) . "\""]; + "bb.bbarcode='" . addslashes($patron['id']) . "'"]; // Order by $sqlOrder = [ @@ -917,15 +962,15 @@ class Horizon extends AbstractBase return [ 'id' => $row['BIB_NUM'], - 'item_id' => $row['ITEM_NUM'], - 'duedate' => $dueDate, - 'barcode' => $row['ITEM_BARCODE'], - 'renew' => $row['RENEW'], - 'request' => $row['REQUEST'], - 'dueStatus' => $dueStatus, - 'volume' => $row['VOLUME'], - 'publication_year' => $row['PUBLICATION_YEAR'], - 'title' => $row['TITLE'] + 'item_id' => $row['ITEM_NUM'], + 'duedate' => $dueDate, + 'barcode' => $row['ITEM_BARCODE'], + 'renew' => $row['RENEW'], + 'request' => $row['REQUEST'], + 'dueStatus' => $dueStatus, + 'volume' => $row['VOLUME'], + 'publication_year' => $row['PUBLICATION_YEAR'], + 'title' => $row['TITLE'] ]; } @@ -948,12 +993,16 @@ class Horizon extends AbstractBase $sql = $this->buildSqlFromArray($sqlArray); try { - $sqlStmt = mssql_query($sql); - while ($row = mssql_fetch_assoc($sqlStmt)) { + $sqlStmt = $this->db->query($sql); + foreach ($sqlStmt as $row) { $transList[] = $this->processTransactionsRow($row); } + + $this->debug(json_encode($transList)); + return $transList; } catch (\Exception $e) { + $this->logError($e->getMessage()); throw new ILSException($e->getMessage()); } } @@ -1002,6 +1051,7 @@ class Horizon extends AbstractBase // Set the Sybase or MSSQL rowcount limit (TODO: account for $page) $limitsql = "set rowcount {$limit}"; + // for Sybase ASE 12.5 : "set rowcount $limit" // This is the actual query for IDs. $newsql = " select nb.bib# " @@ -1016,19 +1066,25 @@ class Horizon extends AbstractBase $results = []; // Set the rowcount limit before executing the query for IDs - mssql_query($limitsql); + $this->db->query($limitsql); // Actual query for IDs - $sqlStmt = mssql_query($newsql); - while ($row = mssql_fetch_assoc($sqlStmt)) { - $results[] = $row['bib#']; - } + try { + $sqlStmt = $this->db->query($newsql); + foreach ($sqlStmt as $row) { + $results[] = $row['bib#']; + } + + $retVal = ['count' => count($results), 'results' => []]; + foreach ($results as $result) { + $retVal['results'][] = ['id' => $result]; + } - $retVal = ['count' => count($results), 'results' => []]; - foreach ($results as $result) { - $retVal['results'][] = ['id' => $result]; + return $retVal; + } catch (\Exception $e) { + $this->logError($e->getMessage()); + throw new ILSException($e->getMessage()); } - return $retVal; } else { return ['count' => 0, 'results' => []]; } @@ -1048,9 +1104,14 @@ class Horizon extends AbstractBase { $checkHzVersionSQL = "select database_revision from matham"; - $versionResult = mssql_query($checkHzVersionSQL); - while ($row = mssql_fetch_assoc($versionResult)) { - $hzVersionFound = $row['database_revision']; + try { + $versionResult = $this->db->query($checkHzVersionSQL); + foreach ($versionResult as $row) { + $hzVersionFound = $row['database_revision']; + } + } catch (\Exception $e) { + $this->logError($e->getMessage()); + throw new ILSException($e->getMessage()); } /* The Horizon database version is made up of 4 numbers separated by periods. @@ -1095,11 +1156,12 @@ class Horizon extends AbstractBase " from bib_control bc" . " where bc.staff_only = 1"; try { - $sqlStmt = mssql_query($sql); - while ($row = mssql_fetch_assoc($sqlStmt)) { + $sqlStmt = $this->db->query($sql); + foreach ($sqlStmt as $row) { $list[] = $row['bib#']; } } catch (\Exception $e) { + $this->logError($e->getMessage()); throw new ILSException($e->getMessage()); }