2 changed files with 315 additions and 0 deletions
@ -0,0 +1,270 @@ |
|||||||
|
<?php |
||||||
|
|
||||||
|
/** |
||||||
|
* @file |
||||||
|
* Contains the RapidIllRequestHandler class for submitting ILL requests |
||||||
|
* to RapidILL using the roblib/rapidillrequest package. |
||||||
|
*/ |
||||||
|
|
||||||
|
use Drupal\Core\Form\FormStateInterface; |
||||||
|
use RapidIll\InsertRequest; |
||||||
|
use RapidIll\InsertResponse; |
||||||
|
use RapidIll\RapidIllClient; |
||||||
|
use RapidIll\RapidIllException; |
||||||
|
use RapidIll\RequestType; |
||||||
|
|
||||||
|
/** |
||||||
|
* Handles building and submitting RapidILL requests from the ILL loan form. |
||||||
|
* |
||||||
|
* Usage (from the form submit handler): |
||||||
|
* @code |
||||||
|
* module_load_include('inc', 'upei_roblib_ill', 'includes/rapidill'); |
||||||
|
* $handler = new RapidIllRequestHandler(); |
||||||
|
* $response = $handler->submitRequest($form_state); |
||||||
|
* @endcode |
||||||
|
*/ |
||||||
|
class RapidIllRequestHandler { |
||||||
|
|
||||||
|
/** |
||||||
|
* Drupal config object for upei_roblib_ill.settings. |
||||||
|
* |
||||||
|
* @var \Drupal\Core\Config\ImmutableConfig |
||||||
|
*/ |
||||||
|
protected $config; |
||||||
|
|
||||||
|
/** |
||||||
|
* Constructs a new RapidIllRequestHandler. |
||||||
|
*/ |
||||||
|
public function __construct() { |
||||||
|
$this->config = \Drupal::config('upei_roblib_ill.settings'); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Maps a form Genre value to a RapidILL RequestType enum. |
||||||
|
* |
||||||
|
* @param string $genre |
||||||
|
* The genre value from the ILL form ('article', 'book', or 'chapter'). |
||||||
|
* |
||||||
|
* @return \RapidIll\RequestType |
||||||
|
* The corresponding RequestType enum value. |
||||||
|
*/ |
||||||
|
public function getRequestType(string $genre): RequestType { |
||||||
|
return match ($genre) { |
||||||
|
'book' => RequestType::Book, |
||||||
|
'chapter' => RequestType::BookChapter, |
||||||
|
default => RequestType::Article, |
||||||
|
}; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Builds a RapidILL InsertRequest from the Drupal form state. |
||||||
|
* |
||||||
|
* Reads bibliographic data from form storage (step 1) and patron data |
||||||
|
* from the current form values (step 2). |
||||||
|
* |
||||||
|
* @param \Drupal\Core\Form\FormStateInterface $form_state |
||||||
|
* The current form state containing both steps of the ILL form. |
||||||
|
* |
||||||
|
* @return \RapidIll\InsertRequest |
||||||
|
* A populated InsertRequest ready to be submitted. |
||||||
|
*/ |
||||||
|
public function buildInsertRequest(FormStateInterface $form_state): InsertRequest { |
||||||
|
$storage = $form_state->getStorage(); |
||||||
|
$biblio = $storage['request'] ?? []; |
||||||
|
$patron = $form_state->getValues(); |
||||||
|
|
||||||
|
$genre = $biblio['Genre'] ?? 'article'; |
||||||
|
$request = new InsertRequest(); |
||||||
|
$request->setRequestType($this->getRequestType($genre)); |
||||||
|
|
||||||
|
// -- Bibliographic fields -- |
||||||
|
if (!empty($biblio['Title'])) { |
||||||
|
$request->setJournalTitle($biblio['Title']); |
||||||
|
} |
||||||
|
|
||||||
|
if (!empty($biblio['ArticleTitle'])) { |
||||||
|
$request->setArticleTitle($biblio['ArticleTitle']); |
||||||
|
} |
||||||
|
|
||||||
|
// Use ArticleAuthor for articles/chapters, Author for books. |
||||||
|
$author = ''; |
||||||
|
if ($genre !== 'book' && !empty($biblio['ArticleAuthor'])) { |
||||||
|
$author = $biblio['ArticleAuthor']; |
||||||
|
} |
||||||
|
elseif (!empty($biblio['Author'])) { |
||||||
|
$author = $biblio['Author']; |
||||||
|
} |
||||||
|
if (!empty($author)) { |
||||||
|
$request->setArticleAuthor($author); |
||||||
|
} |
||||||
|
|
||||||
|
if (!empty($biblio['ISSN'])) { |
||||||
|
$issn = is_array($biblio['ISSN']) ? reset($biblio['ISSN']) : $biblio['ISSN']; |
||||||
|
if (!empty($issn)) { |
||||||
|
$request->addIssn($issn); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
if (!empty($biblio['ISBN'])) { |
||||||
|
$isbn = is_array($biblio['ISBN']) ? reset($biblio['ISBN']) : $biblio['ISBN']; |
||||||
|
if (!empty($isbn)) { |
||||||
|
$request->addIsbn($isbn); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
if (!empty($biblio['Volume'])) { |
||||||
|
$request->setJournalVolume($biblio['Volume']); |
||||||
|
} |
||||||
|
|
||||||
|
if (!empty($biblio['Issue'])) { |
||||||
|
$request->setJournalIssue($biblio['Issue']); |
||||||
|
} |
||||||
|
|
||||||
|
if (!empty($biblio['PagesRequested'])) { |
||||||
|
$request->setArticlePages($biblio['PagesRequested']); |
||||||
|
} |
||||||
|
|
||||||
|
if (!empty($biblio['Date'])) { |
||||||
|
$request->setJournalYear($biblio['Date']); |
||||||
|
} |
||||||
|
|
||||||
|
// -- Patron fields -- |
||||||
|
if (!empty($patron['campus_id'])) { |
||||||
|
$request->setPatronId($patron['campus_id']); |
||||||
|
} |
||||||
|
|
||||||
|
$first_name = $patron['FirstName'] ?? ''; |
||||||
|
$surname = $patron['Surname'] ?? ''; |
||||||
|
$full_name = trim("$first_name $surname"); |
||||||
|
if (!empty($full_name)) { |
||||||
|
$request->setPatronName($full_name); |
||||||
|
} |
||||||
|
|
||||||
|
if (!empty($patron['DeliveryAddress'])) { |
||||||
|
$request->setPatronEmail($patron['DeliveryAddress']); |
||||||
|
} |
||||||
|
|
||||||
|
if (!empty($patron['Department'])) { |
||||||
|
$request->setPatronDepartment($patron['Department']); |
||||||
|
} |
||||||
|
|
||||||
|
// Combine user notes and DOI (if present) into patron notes. |
||||||
|
$notes_parts = []; |
||||||
|
if (!empty($patron['notes'])) { |
||||||
|
$notes_parts[] = $patron['notes']; |
||||||
|
} |
||||||
|
if (!empty($biblio['doi'])) { |
||||||
|
$notes_parts[] = 'DOI: ' . $biblio['doi']; |
||||||
|
} |
||||||
|
if (!empty($notes_parts)) { |
||||||
|
$request->setPatronNotes(implode(' | ', $notes_parts)); |
||||||
|
} |
||||||
|
|
||||||
|
return $request; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Creates a RapidIllClient from the module's Drupal configuration. |
||||||
|
* |
||||||
|
* Reads the following config keys from 'upei_roblib_ill.settings': |
||||||
|
* - rapid_ill_username |
||||||
|
* - rapid_ill_password |
||||||
|
* - rapid_ill_code |
||||||
|
* - rapid_ill_branch_name |
||||||
|
* |
||||||
|
* @return \RapidIll\RapidIllClient |
||||||
|
* A configured RapidILL client. |
||||||
|
* |
||||||
|
* @throws \RuntimeException |
||||||
|
* If any required configuration value is missing. |
||||||
|
*/ |
||||||
|
protected function createClient(): RapidIllClient { |
||||||
|
$username = $this->config->get('rapid_ill_username'); |
||||||
|
$password = $this->config->get('rapid_ill_password'); |
||||||
|
$rapid_code = $this->config->get('rapid_ill_code'); |
||||||
|
$branch_name = $this->config->get('rapid_ill_branch_name'); |
||||||
|
|
||||||
|
if (empty($username) || empty($password) || empty($rapid_code) || empty($branch_name)) { |
||||||
|
\Drupal::logger('upei_roblib_ill')->error( |
||||||
|
'RapidILL configuration is incomplete. Please set rapid_ill_username, rapid_ill_password, rapid_ill_code, and rapid_ill_branch_name in the ILL settings.' |
||||||
|
); |
||||||
|
throw new \RuntimeException('RapidILL configuration is incomplete.'); |
||||||
|
} |
||||||
|
|
||||||
|
return new RapidIllClient( |
||||||
|
username: $username, |
||||||
|
password: $password, |
||||||
|
rapidCode: $rapid_code, |
||||||
|
branchName: $branch_name, |
||||||
|
); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Builds and submits a RapidILL request from the ILL loan form. |
||||||
|
* |
||||||
|
* This method mirrors the behaviour of upei_roblib_ill_add_request() in |
||||||
|
* relais.inc, returning a response array with the same shape so the form's |
||||||
|
* existing redirect logic can consume it directly. |
||||||
|
* |
||||||
|
* @param \Drupal\Core\Form\FormStateInterface $form_state |
||||||
|
* The current form state. |
||||||
|
* |
||||||
|
* @return array |
||||||
|
* An associative array with at least a 'ConfirmMessage' key, and |
||||||
|
* optionally a 'RequestNumber' key on success. |
||||||
|
*/ |
||||||
|
public function submitRequest(FormStateInterface $form_state): array { |
||||||
|
module_load_include('inc', 'upei_roblib_ill', 'includes/db'); |
||||||
|
module_load_include('inc', 'upei_roblib_ill', 'includes/utilities'); |
||||||
|
|
||||||
|
// Build the Relais-style array for logging purposes. |
||||||
|
$relais_arr = upei_roblib_ill_build_relais_arr($form_state); |
||||||
|
|
||||||
|
try { |
||||||
|
$client = $this->createClient(); |
||||||
|
} |
||||||
|
catch (\RuntimeException $e) { |
||||||
|
$error_response = [ |
||||||
|
'ConfirmMessage' => 'RapidILL is not configured. Please contact the library.', |
||||||
|
]; |
||||||
|
upei_roblib_ill_log_request($relais_arr, $error_response); |
||||||
|
return $error_response; |
||||||
|
} |
||||||
|
|
||||||
|
$insert_request = $this->buildInsertRequest($form_state); |
||||||
|
|
||||||
|
try { |
||||||
|
/** @var \RapidIll\InsertResponse $response */ |
||||||
|
$response = $client->insertRequest($insert_request); |
||||||
|
} |
||||||
|
catch (RapidIllException $e) { |
||||||
|
\Drupal::logger('upei_roblib_ill')->error( |
||||||
|
'RapidILL request failed: @message', |
||||||
|
['@message' => $e->getMessage()] |
||||||
|
); |
||||||
|
$error_response = [ |
||||||
|
'ConfirmMessage' => 'Error communicating with RapidILL: ' . $e->getMessage(), |
||||||
|
]; |
||||||
|
upei_roblib_ill_log_request($relais_arr, $error_response); |
||||||
|
return $error_response; |
||||||
|
} |
||||||
|
|
||||||
|
// Build a response array compatible with the existing form redirect. |
||||||
|
if ($response->isSuccessful) { |
||||||
|
$result = [ |
||||||
|
'RequestNumber' => $response->rapidRequestId, |
||||||
|
'ConfirmMessage' => 'Your Interlibrary Loan request has been successfully submitted to RapidILL. Your Rapid Request ID is: ' . $response->rapidRequestId, |
||||||
|
]; |
||||||
|
} |
||||||
|
else { |
||||||
|
$message = $response->verificationNote ?? 'Unknown error from RapidILL.'; |
||||||
|
$result = [ |
||||||
|
'ConfirmMessage' => 'RapidILL could not process your request: ' . $message, |
||||||
|
]; |
||||||
|
} |
||||||
|
|
||||||
|
upei_roblib_ill_log_request($relais_arr, $result); |
||||||
|
return $result; |
||||||
|
} |
||||||
|
|
||||||
|
} |
||||||
Loading…
Reference in new issue