Ejemplo n.º 1
0
 /**
  * Place Hold
  *
  * This is responsible for both placing holds as well as placing recalls.
  *
  * @param   string  $recordId   The id of the bib record
  * @param   string  $patronId   The id of the patron
  * @param   string  $comment    Any comment regarding the hold or recall
  * @param   string  $type       Whether to place a hold or recall
  * @return  mixed               True if successful, false if unsuccessful
  *                              If an error occurs, return a PEAR_Error
  * @access  public
  */
 public function placeHold($recordId, $patronId, $comment, $type)
 {
     global $user;
     $hold_result = array();
     $hold_result['result'] = false;
     //Set pickup location
     if (isset($_REQUEST['campus'])) {
         $campus = trim($_REQUEST['campus']);
     } else {
         $campus = $user->homeLocationId;
         //Get the code for the location
         $locationLookup = new Location();
         $locationLookup->locationId = $campus;
         $locationLookup->find();
         if ($locationLookup->N > 0) {
             $locationLookup->fetch();
             $campus = $locationLookup->code;
         }
     }
     $campus = strtoupper($campus);
     //Get a specific item number to place a hold on even though we are placing a title level hold.
     //because.... Koha
     require_once ROOT_DIR . '/RecordDrivers/MarcRecord.php';
     $recordDriver = new MarcRecord($recordId);
     if (!$recordDriver->isValid()) {
         $hold_result['message'] = 'Unable to find a valid record for this title.  Please try your search again.';
         return $hold_result;
     }
     global $configArray;
     $marcRecord = $recordDriver->getMarcRecord();
     //Check to see if the title requires item level holds
     /** @var File_MARC_Data_Field[] $holdTypeFields */
     $itemLevelHoldAllowed = false;
     $itemLevelHoldOnly = false;
     $holdTypeFields = $marcRecord->getFields('942');
     foreach ($holdTypeFields as $holdTypeField) {
         if ($holdTypeField->getSubfield('r') != null) {
             if ($holdTypeField->getSubfield('r')->getData() == 'itemtitle') {
                 $itemLevelHoldAllowed = true;
             } else {
                 if ($holdTypeField->getSubfield('r')->getData() == 'item') {
                     $itemLevelHoldAllowed = true;
                     $itemLevelHoldOnly = true;
                 }
             }
         }
     }
     //Get the items the user can place a hold on
     $this->loginToKoha($user);
     $placeHoldPage = $this->getKohaPage($configArray['Catalog']['url'] . '/cgi-bin/koha/opac-reserve.pl?biblionumber=' . $recordId);
     preg_match_all('/<div class="dialog alert">(.*?)<\\/div>/s', $placeHoldPage, $matches);
     if (count($matches) > 0 && count($matches[1]) > 0) {
         $hold_result['title'] = $recordDriver->getTitle();
         $hold_result['result'] = false;
         $hold_result['message'] = '';
         foreach ($matches[1] as $errorMsg) {
             $hold_result['message'] .= $errorMsg . '<br/>';
         }
         return $hold_result;
     }
     if ($itemLevelHoldAllowed) {
         //Need to prompt for an item level hold
         $items = array();
         if (!$itemLevelHoldOnly) {
             //Add a first title returned
             $items[-1] = array('itemNumber' => -1, 'location' => 'Next available copy', 'callNumber' => '', 'status' => '');
         }
         //Get the item table from the page
         if (preg_match('/<table>\\s+<caption>Select a specific copy:<\\/caption>\\s+(.*?)<\\/table>/s', $placeHoldPage, $matches)) {
             $itemTable = $matches[1];
             //Get the header row labels
             $headerLabels = array();
             preg_match_all('/<th[^>]*>(.*?)<\\/th>/si', $itemTable, $tableHeaders, PREG_PATTERN_ORDER);
             foreach ($tableHeaders[1] as $col => $tableHeader) {
                 $headerLabels[$col] = trim(strip_tags(strtolower($tableHeader)));
             }
             //Grab each row within the table
             preg_match_all('/<tr[^>]*>\\s+(<td.*?)<\\/tr>/si', $itemTable, $tableData, PREG_PATTERN_ORDER);
             foreach ($tableData[1] as $tableRow) {
                 //Each row in the table represents a hold
                 $curItem = array();
                 $validItem = false;
                 //Go through each cell in the row
                 preg_match_all('/<td[^>]*>(.*?)<\\/td>/si', $tableRow, $tableCells, PREG_PATTERN_ORDER);
                 foreach ($tableCells[1] as $col => $tableCell) {
                     if ($headerLabels[$col] == 'copy') {
                         if (strpos($tableCell, 'disabled') === false) {
                             $validItem = true;
                             if (preg_match('/value="(\\d+)"/', $tableCell, $valueMatches)) {
                                 $curItem['itemNumber'] = $valueMatches[1];
                             }
                         }
                     } else {
                         if ($headerLabels[$col] == 'item type') {
                             $curItem['itemType'] = trim($tableCell);
                         } else {
                             if ($headerLabels[$col] == 'barcode') {
                                 $curItem['barcode'] = trim($tableCell);
                             } else {
                                 if ($headerLabels[$col] == 'home library') {
                                     $curItem['location'] = trim($tableCell);
                                 } else {
                                     if ($headerLabels[$col] == 'call number') {
                                         $curItem['callNumber'] = trim($tableCell);
                                     } else {
                                         if ($headerLabels[$col] == 'vol info') {
                                             $curItem['volInfo'] = trim($tableCell);
                                         } else {
                                             if ($headerLabels[$col] == 'information') {
                                                 $curItem['status'] = trim($tableCell);
                                             }
                                         }
                                     }
                                 }
                             }
                         }
                     }
                 }
                 if ($validItem) {
                     $items[$curItem['itemNumber']] = $curItem;
                 }
             }
         } elseif (preg_match('/<div class="dialog alert">(.*?)<\\/div>/s', $placeHoldPage, $matches)) {
             $items = array();
             $message = trim($matches[1]);
         }
         $hold_result['title'] = $recordDriver->getTitle();
         $hold_result['items'] = $items;
         if (count($items) > 0) {
             $message = 'This title allows item level holds, please select an item to place a hold on.';
         } else {
             if (!isset($message)) {
                 $message = 'There are no holdable items for this title.';
             }
         }
         $hold_result['result'] = false;
         $hold_result['message'] = $message;
         return $hold_result;
     } else {
         //Just a regular bib level hold
         $hold_result['title'] = $recordDriver->getTitle();
         //Post the hold to koha
         $placeHoldPage = $configArray['Catalog']['url'] . '/cgi-bin/koha/opac-reserve.pl';
         $holdParams = array('biblionumbers' => $recordId . '/', 'branch' => $campus, 'place_reserve' => 1, "reqtype_{$recordId}" => 'Any', 'reserve_mode' => 'multi', 'selecteditems' => "{$recordId}//{$campus}/", 'single_bib' => $recordId);
         $kohaHoldResult = $this->postToKohaPage($placeHoldPage, $holdParams);
         //If the hold is successful we go back to the account page and can see
         $hold_result['id'] = $recordId;
         if (preg_match('/<a href="#opac-user-holds">Holds<\\/a>/si', $kohaHoldResult)) {
             //We redirected to the holds page, everything seems to be good
             $holds = $this->getMyHolds($user, 1, -1, 'title', $kohaHoldResult);
             $hold_result['result'] = true;
             $hold_result['message'] = "Your hold was placed successfully.";
             //Find the correct hold (will be unavailable)
             foreach ($holds['holds']['unavailable'] as $holdInfo) {
                 if ($holdInfo['id'] == $recordId) {
                     if (isset($holdInfo['position'])) {
                         $hold_result['message'] .= "  You are number <b>" . $holdInfo['position'] . "</b> in the queue.";
                     }
                     break;
                 }
             }
         } else {
             $hold_result['result'] = false;
             //Look for an alert message
             if (preg_match('/<div class="dialog alert">(.*?)<\\/div>/', $kohaHoldResult, $matches)) {
                 $hold_result['message'] = 'Your hold could not be placed. ' . $matches[1];
             } else {
                 $hold_result['message'] = 'Your hold could not be placed. ';
             }
         }
         return $hold_result;
     }
 }