Compare commits
No commits in common. '7f33504b029fe7acc31d23f81c645bda20f9941f' and 'a6b47a11735f19b5fbe07d79a4c1d062c88cbf8a' have entirely different histories.
7f33504b02
...
a6b47a1173
6 changed files with 92 additions and 277 deletions
@ -1,197 +0,0 @@ |
|||||||
<?php |
|
||||||
|
|
||||||
/** |
|
||||||
* @file |
|
||||||
* Contains the SharePointRequestHandler class for submitting ILL requests |
|
||||||
* to a SharePoint list via a Power Automate webhook. |
|
||||||
*/ |
|
||||||
|
|
||||||
use Drupal\Core\Form\FormStateInterface; |
|
||||||
|
|
||||||
/** |
|
||||||
* Handles building and submitting ILL requests to SharePoint via Power Automate. |
|
||||||
* |
|
||||||
* Usage (from the form submit handler): |
|
||||||
* @code |
|
||||||
* \Drupal::moduleHandler()->loadInclude('upei_roblib_ill', 'inc', 'includes/sharepoint'); |
|
||||||
* $handler = new SharePointRequestHandler(); |
|
||||||
* $payload = $handler->buildPayload($form_state); |
|
||||||
* $response = $handler->submitRequest($payload); |
|
||||||
* @endcode |
|
||||||
*/ |
|
||||||
class SharePointRequestHandler |
|
||||||
{ |
|
||||||
|
|
||||||
/** |
|
||||||
* Drupal config object for upei_roblib_ill.settings. |
|
||||||
* |
|
||||||
* @var \Drupal\Core\Config\ImmutableConfig |
|
||||||
*/ |
|
||||||
protected $config; |
|
||||||
|
|
||||||
/** |
|
||||||
* Constructs a new SharePointRequestHandler. |
|
||||||
*/ |
|
||||||
public function __construct() |
|
||||||
{ |
|
||||||
$this->config = \Drupal::config('upei_roblib_ill.settings'); |
|
||||||
} |
|
||||||
|
|
||||||
/** |
|
||||||
* Builds the webhook payload 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 array |
|
||||||
* An associative array matching the Power Automate webhook payload schema. |
|
||||||
*/ |
|
||||||
public function buildPayload(FormStateInterface $form_state): array |
|
||||||
{ |
|
||||||
$storage = $form_state->getStorage(); |
|
||||||
$biblio = $storage['request'] ?? []; |
|
||||||
$patron = $form_state->getValues(); |
|
||||||
|
|
||||||
$genre = $biblio['Genre'] ?? 'article'; |
|
||||||
|
|
||||||
// Determine the author: 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']; |
|
||||||
} |
|
||||||
|
|
||||||
// Combine DOI and ISBN into a single field. |
|
||||||
$doi_isbn_parts = []; |
|
||||||
if (!empty($biblio['doi'])) { |
|
||||||
$doi_isbn_parts[] = $biblio['doi']; |
|
||||||
} |
|
||||||
if (!empty($biblio['ISBN'])) { |
|
||||||
$doi_isbn_parts[] = $biblio['ISBN']; |
|
||||||
} |
|
||||||
if (!empty($biblio['ISSN'])) { |
|
||||||
$doi_isbn_parts[] = $biblio['ISSN']; |
|
||||||
} |
|
||||||
$doi_isbn = implode('; ', $doi_isbn_parts); |
|
||||||
|
|
||||||
// Build patron full name. |
|
||||||
$first_name = $patron['FirstName'] ?? ''; |
|
||||||
$surname = $patron['Surname'] ?? ''; |
|
||||||
$patron_name = trim("$first_name $surname"); |
|
||||||
|
|
||||||
// Build notes — pack all extra info that doesn't have its own schema field. |
|
||||||
$notes_parts = []; |
|
||||||
if (!empty($biblio['ArticleTitle'])) { |
|
||||||
$notes_parts[] = 'Article/Chapter: ' . $biblio['ArticleTitle']; |
|
||||||
} |
|
||||||
if (!empty($biblio['Volume'])) { |
|
||||||
$notes_parts[] = 'Vol: ' . $biblio['Volume']; |
|
||||||
} |
|
||||||
if (!empty($biblio['Issue'])) { |
|
||||||
$notes_parts[] = 'Issue: ' . $biblio['Issue']; |
|
||||||
} |
|
||||||
if (!empty($biblio['PagesRequested'])) { |
|
||||||
$notes_parts[] = 'Pages: ' . $biblio['PagesRequested']; |
|
||||||
} |
|
||||||
if (!empty($patron['patron_type'])) { |
|
||||||
$notes_parts[] = 'Patron Type: ' . $patron['patron_type']; |
|
||||||
} |
|
||||||
if (!empty($patron['Department'])) { |
|
||||||
$notes_parts[] = 'Dept: ' . $patron['Department']; |
|
||||||
} |
|
||||||
if (!empty($patron['notes'])) { |
|
||||||
$notes_parts[] = $patron['notes']; |
|
||||||
} |
|
||||||
|
|
||||||
// All values MUST be strings — Power Automate rejects the request |
|
||||||
// if any value type does not match the trigger's JSON schema. |
|
||||||
return [ |
|
||||||
'title' => (string)($biblio['Title'] ?? ''), |
|
||||||
'author' => (string)$author, |
|
||||||
'year' => (string)($biblio['Date'] ?? ''), |
|
||||||
'doi_isbn' => (string)$doi_isbn, |
|
||||||
'format' => (string)$genre, |
|
||||||
'patronName' => (string)$patron_name, |
|
||||||
'patronEmail' => (string)($patron['DeliveryAddress'] ?? ''), |
|
||||||
'patronBarcode' => (string)($patron['campus_id'] ?? ''), |
|
||||||
'notes' => (string)implode(' | ', $notes_parts), |
|
||||||
'submittedAt' => (string)gmdate('Y-m-d\TH:i:s') . '.000Z', |
|
||||||
]; |
|
||||||
} |
|
||||||
|
|
||||||
/** |
|
||||||
* Submits the payload to the configured Power Automate webhook. |
|
||||||
* |
|
||||||
* @param array $payload |
|
||||||
* The payload array as built by buildPayload(). |
|
||||||
* |
|
||||||
* @return array |
|
||||||
* An associative array with at least a 'ConfirmMessage' key, and |
|
||||||
* optionally a 'RequestNumber' key on success. |
|
||||||
*/ |
|
||||||
public function submitRequest(array $payload): array |
|
||||||
{ |
|
||||||
\Drupal::moduleHandler()->loadInclude('upei_roblib_ill', 'inc', 'includes/db'); |
|
||||||
|
|
||||||
$webhook_url = $this->config->get('sharepoint_webhook_url'); |
|
||||||
if (empty($webhook_url)) { |
|
||||||
\Drupal::logger('upei_roblib_ill')->error( |
|
||||||
'SharePoint webhook URL is not configured. Please set it in the ILL settings.' |
|
||||||
); |
|
||||||
$error_response = [ |
|
||||||
'ConfirmMessage' => 'SharePoint integration is not configured. Please contact the library.', |
|
||||||
]; |
|
||||||
upei_roblib_ill_log_request($payload, $error_response); |
|
||||||
return $error_response; |
|
||||||
} |
|
||||||
|
|
||||||
// Log the outgoing payload for debugging. |
|
||||||
\Drupal::logger('upei_roblib_ill')->notice( |
|
||||||
'Submitting ILL request to SharePoint webhook. Payload: @payload', |
|
||||||
['@payload' => json_encode($payload)] |
|
||||||
); |
|
||||||
|
|
||||||
try { |
|
||||||
// Use 'json' option which handles JSON encoding and Content-Type automatically. |
|
||||||
$response = \Drupal::httpClient()->post($webhook_url, [ |
|
||||||
'json' => $payload, |
|
||||||
'timeout' => 30, |
|
||||||
]); |
|
||||||
|
|
||||||
$status_code = $response->getStatusCode(); |
|
||||||
$body = (string)$response->getBody(); |
|
||||||
$response_data = json_decode($body, TRUE) ?: []; |
|
||||||
|
|
||||||
if ($status_code >= 200 && $status_code < 300) { |
|
||||||
$result = [ |
|
||||||
'RequestNumber' => $response_data['requestId'] ?? date('YmdHis'), |
|
||||||
'ConfirmMessage' => 'Your Interlibrary Loan request has been successfully submitted.', |
|
||||||
]; |
|
||||||
} |
|
||||||
else { |
|
||||||
$message = $response_data['error'] ?? 'Unexpected response from SharePoint (HTTP ' . $status_code . ').'; |
|
||||||
$result = [ |
|
||||||
'ConfirmMessage' => 'SharePoint could not process your request: ' . $message, |
|
||||||
]; |
|
||||||
} |
|
||||||
} |
|
||||||
catch (\Exception $e) { |
|
||||||
\Drupal::logger('upei_roblib_ill')->error( |
|
||||||
'SharePoint webhook request failed: @message', |
|
||||||
['@message' => $e->getMessage()] |
|
||||||
); |
|
||||||
$result = [ |
|
||||||
'ConfirmMessage' => 'Error communicating with SharePoint: ' . $e->getMessage(), |
|
||||||
]; |
|
||||||
} |
|
||||||
|
|
||||||
upei_roblib_ill_log_request($payload, $result); |
|
||||||
return $result; |
|
||||||
} |
|
||||||
|
|
||||||
} |
|
||||||
Loading…
Reference in new issue