Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Email the service desk after a hold is placed #3955

Draft
wants to merge 4 commits into
base: dev
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions config/vufind/config.ini
Original file line number Diff line number Diff line change
Expand Up @@ -375,6 +375,10 @@ renewals_enabled = false
; if available, but not supported by all drivers)
title_level_holds_mode = "disabled"

; Email submitted request notifications to and from these addresses
;holds_email_to = "[email protected]"
;holds_email_from = "[email protected]"

; Determines how holdings are grouped in the record display, using fields from
; the item information provided by the ILS driver.
;
Expand Down
4 changes: 4 additions & 0 deletions languages/en.ini
Original file line number Diff line number Diff line change
Expand Up @@ -732,6 +732,7 @@ Item Description = "Item Description"
Item Notes = "Notes"
Item removed from favorites = "Item removed from saved items"
Item removed from list = "Item removed from list"
item_barcode = "Item Barcode"
Items = "Items"
items = "items"
items_added_to_bookbag = "%%count%% item(s) added to your Book Bag"
Expand Down Expand Up @@ -1066,6 +1067,7 @@ password_only_numeric = "Numbers only"
Passwords do not match = "Passwords do not match"
past_days = "{range, plural, =1 {Yesterday} =7 {Past Week} other {Past # Days}}"
patron_account_expires = "Expires"
patron_barcode = "Patron Barcode"
patron_status_address_missing = "Your address is missing."
patron_status_card_blocked = "This library card is blocked from borrowing."
patron_status_card_expired = "Your library card has expired."
Expand Down Expand Up @@ -1221,6 +1223,8 @@ renew_success = "Renewal Successful"
renew_success_summary = "Successfully renewed {count, plural, =1 {1 item} other {# items}}."
Renewed = "Renewed"
Request full text = "Request full text"
request_email_item_message = "A request was placed for item: %%id%%"
request_email_subject = "Request Placed for item: %%id%%"
request_in_transit = "In Transit to Pickup Location"
request_place_text = "Place a Request"
request_submit_text = "Submit Request"
Expand Down
54 changes: 54 additions & 0 deletions module/VuFind/src/VuFind/Controller/HoldsTrait.php
Original file line number Diff line number Diff line change
Expand Up @@ -195,6 +195,7 @@ public function holdAction()

// Success: Go to Display Holds
if (isset($results['success']) && $results['success'] == true) {
$this->emailRequestPlaced($holdDetails);
$msg = [
'html' => true,
'msg' => empty($gatheredDetails['proxiedUser'])
Expand Down Expand Up @@ -282,4 +283,57 @@ public function holdAction()
$view->setTemplate('record/hold');
return $view;
}

/**
* Email the successful request to staff as a notification.
*
* @param array $holdDetails Details about the successful hold request
*
* @return void
*/
protected function emailRequestPlaced($holdDetails)
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

VuFind calls these user actions both holds (too specific) and requests (maybe too general). I use requests where possible but holds where the term is already used i.e. in that config section.

{
$config = $this->getConfig();
$to = $this->getEmailRecipient($holdDetails);
$from = $config->Catalog->holds_email_from ?? null;
if (!$to || !$from) {
return;
}

$renderer = $this->getViewRenderer();
$message = $renderer->render(
'Email/request-placed.phtml',
['hold_details' => $holdDetails]
);

$subject = $this->translate('request_email_subject', [
'%%id%%' => $holdDetails['id'] ?? '',
'%%barcode%%' => $holdDetails['barcode'] ?? '',
]);
try {
$mailer = $this->getService(\VuFind\Mailer\Mailer::class);
$mailer->send(
$to,
$from,
$subject,
$message
);
} catch (\VuFind\Exception\Mail $e) {
return;
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't want to throw an exception, after all the hold succeeded. Might be helpful to log the error but I wasn't sure if it was worth using LoggerAwareTrait for the one message.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You could also use error_log as a last resort.

}
}

/**
* Get the appropriate staff email recipient for a hold request. This falls back
* on a configured default but may be overridden to vary based on the hold details.
*
* @param array $holdDetails Details about the successful hold request
*
* @return string The email address
*/
protected function getEmailRecipient($holdDetails)
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The logic I'll be implementing locally is to look at the pickup location and do a mapping from that to a particular email address. Not sure if that is generic enough to share.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could that be generalized to something like a prioritized list of $holdDetails properties mapped to email addresses? This is pretty ugly, but something like:

[EmailNotificationMap]
property_name[value] = "[email protected]"
other_property_name[value2] = "[email protected]"
default = "[email protected]"

(Obviously this would lend itself better to YAML or JSON configuration, but if we have to use .ini, it might work).

{
$config = $this->getConfig();
return $config->Catalog->holds_email_to ?? null;
}
}
19 changes: 19 additions & 0 deletions themes/root/templates/Email/request-placed.phtml
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
<?php // This is a text-only email template; do not include HTML! ?>
<?=$this->translate('request_email_item_message', ['%%id%%' => $hold_details['id']])?>


-----

<?=$this->translate('patron_barcode')?>: <?=$hold_details['patron']['cat_username'] ?? ''?>

<?=$this->translate('item_barcode')?>: <?=$hold_details['barcode'] ?? ''?>

<?=$this->translate('Title')?>: <?=$hold_details['itemTitle'] ?? ''?>

<?=$this->translate('Call Number')?>: <?=$hold_details['callNo'] ?? ''?>

<?=$this->translate('Location')?>: <?=$hold_details['homeLocation'] ?? ''?>

<?=$this->translate('Comments')?>: <?=$hold_details['comment'] ?? ''?>

<?php /* Request Group: <?=$this->translate('request_group')?>: <?=$hold_details['requestGroupId'] ?? ''?> */ ?>
Copy link
Member Author

@maccabeelevine maccabeelevine Sep 20, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'll finish using requestGroup after #3930.

Loading