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