From 05436e6041301fcd54541097809dadb1cf863fb2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Chlo=C3=A9=20Zermatten?= Date: Tue, 13 Aug 2024 10:56:41 +0100 Subject: [PATCH 01/12] feat: basic form template --- .../interface/themes/responsive/ILL/Form.tpl | 39 +++++++++++++++++++ 1 file changed, 39 insertions(+) create mode 100644 code/web/interface/themes/responsive/ILL/Form.tpl diff --git a/code/web/interface/themes/responsive/ILL/Form.tpl b/code/web/interface/themes/responsive/ILL/Form.tpl new file mode 100644 index 0000000000..1c499f2216 --- /dev/null +++ b/code/web/interface/themes/responsive/ILL/Form.tpl @@ -0,0 +1,39 @@ +
+

ILL Request Form

+
+
+ +
+
+ +
+
+ +
+
+ +
+
+ +
+
+ +
+
+ +
+
+ +
+
+ +
+
+ +
+
+ +
+ +
+
\ No newline at end of file From fa02cdae2f2a44a777e8a4cdd3e3f1fb8c0452f1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Chlo=C3=A9=20Zermatten?= Date: Tue, 13 Aug 2024 10:57:23 +0100 Subject: [PATCH 02/12] feat: launch form template --- code/web/services/ILL/NewRequestForm.php | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) create mode 100644 code/web/services/ILL/NewRequestForm.php diff --git a/code/web/services/ILL/NewRequestForm.php b/code/web/services/ILL/NewRequestForm.php new file mode 100644 index 0000000000..961c487cfd --- /dev/null +++ b/code/web/services/ILL/NewRequestForm.php @@ -0,0 +1,19 @@ +assign('title', $title); + $this->display('Form.tpl', $title); + } + + function getBreadcrumbs(): array { + $breadcrumbs = []; + $breadcrumbs[] = new Breadcrumb('/Union/Search', 'Search Results'); + $breadcrumbs[] = new Breadcrumb('/ILL/RequestForm', 'ILL Request Form'); + return $breadcrumbs; + } +} \ No newline at end of file From 1a3d67e306974cf0b1f037edacd2fd0eb23299bf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Chlo=C3=A9=20Zermatten?= Date: Tue, 13 Aug 2024 12:04:04 +0100 Subject: [PATCH 03/12] feat: send ILL request to Koha Get the form data through the AJAX request, get the necessary active user details, format the request, send it to the Koha endpoint, then navigate back to the ILL request form --- code/web/services/ILL/AJAX.php | 73 ++++++++++++++++++++++++++++++++++ 1 file changed, 73 insertions(+) create mode 100644 code/web/services/ILL/AJAX.php diff --git a/code/web/services/ILL/AJAX.php b/code/web/services/ILL/AJAX.php new file mode 100644 index 0000000000..5f57827799 --- /dev/null +++ b/code/web/services/ILL/AJAX.php @@ -0,0 +1,73 @@ +$method(); + echo json_encode($result); + } else { + echo json_encode(['error' => 'invalid_method']); + } + } + + function postFormData() + { + $user = UserAccount::getActiveUserObj(); + + $reqBody = [ + "ill_backend_id" => "FreeForm", // temporarily hard-coded + "patron_id" => $user->id, + "library_id" => $user->_homeLibrary->subdomain, + "extended_attributes" => [ + ['type' => 'article_title', 'value' => $_POST['article_title']], + ['type' => 'associated_id', 'value' => $_POST['associated_id']], + ['type' => 'author', 'value' => $_POST['author']], + ['type' => 'issn', 'value' => $_POST['issn']], + ['type' => 'issue', 'value' => $_POST['issue']], + ['type' => 'pages', 'value' => $_POST['pages']], + ['type' => 'publisher', 'value' => $_POST['publisher']], + ['type' => 'pubmedid', 'value' => $_POST['pubmedid']], + ['type' => 'title', 'value' => $_POST['title']], + ['type' => 'volume', 'value' => $_POST['volume']], + ['type' => 'year', 'value' => $_POST['year']] + ] + ]; + + $reqUrl = 'http://localhost:8081/api/v1/ill/requests'; // might need to replace localhost with IP if curl err 7 encountered -> TODO: store the url elsewhere + $credentials = $user->ils_username . ':' . $user->ils_password; // $user->ils_password is likely to be null -> TODO: need to find a way to safely get and pass this credential + + $curl = curl_init($reqUrl); + curl_setopt($curl, CURLOPT_POST, 1); + curl_setopt($curl, CURLOPT_POSTFIELDS, json_encode($reqBody)); + curl_setopt($curl, CURLOPT_HEADER, 1); + curl_setopt($curl, CURLOPT_HTTPHEADER, ['Content-Type: multipart/form-data']); + curl_setopt($curl, CURLOPT_HTTPAUTH, CURLAUTH_BASIC); + curl_setopt($curl, CURLOPT_USERPWD, $credentials); + curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1); + $result = curl_exec($curl); + + $err = curl_error($curl); + if(!empty($err)) { + return new AspenError('an error occurred while sending your request: ' . $err ); + } + + header('Location: ' . 'http://localhost:8083/ILL/NewRequestForm'); // goes back to the new request form -> TODO: add a success message to display + } + + function getBreadcrumbs(): array + { + return []; + } +} From 3f062e82ab9c08ad780eef2824a15c07260eee5a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Chlo=C3=A9=20Zermatten?= Date: Tue, 13 Aug 2024 12:13:41 +0100 Subject: [PATCH 04/12] feat: can set library to send ILL request to Koha --- code/web/interface/themes/responsive/Search/list.tpl | 7 +++++++ code/web/sys/LibraryLocation/Library.php | 1 + 2 files changed, 8 insertions(+) diff --git a/code/web/interface/themes/responsive/Search/list.tpl b/code/web/interface/themes/responsive/Search/list.tpl index 227c160477..b5e7981b2f 100644 --- a/code/web/interface/themes/responsive/Search/list.tpl +++ b/code/web/interface/themes/responsive/Search/list.tpl @@ -122,6 +122,13 @@ {translate text="Can't find what you are looking for? Try our Materials Request Service." isPublicFacing=true} {translate text='Submit Request' isPublicFacing=true}

+ {elseif $materialRequestType == 4} + {/if} {/if} diff --git a/code/web/sys/LibraryLocation/Library.php b/code/web/sys/LibraryLocation/Library.php index 20100345df..96acbf9107 100644 --- a/code/web/sys/LibraryLocation/Library.php +++ b/code/web/sys/LibraryLocation/Library.php @@ -590,6 +590,7 @@ static function getObjectStructure($context = ''): array { 1 => 'Aspen Request System', 2 => 'ILS Request System', 3 => 'External Request Link', + 4 => 'ILL Request System - Koha' ]; $catalog = CatalogFactory::getCatalogConnectionInstance(); if ($catalog == null || !$catalog->hasMaterialsRequestSupport()) { From 040f8f72120de58ab262ed8d1d1f295c1eacc738 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Chlo=C3=A9=20Zermatten?= Date: Tue, 13 Aug 2024 16:06:10 +0100 Subject: [PATCH 05/12] feat: get koha api url from kohaSystemPreference --- code/web/Drivers/Koha.php | 4 ++++ code/web/services/ILL/AJAX.php | 8 ++++---- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/code/web/Drivers/Koha.php b/code/web/Drivers/Koha.php index cd91d203f2..c6092430dd 100644 --- a/code/web/Drivers/Koha.php +++ b/code/web/Drivers/Koha.php @@ -6977,6 +6977,10 @@ private function getKohaSystemPreference(string $preferenceName, $default = '') return $preference; } + public function getStaffClientBaseURL() { + return $this->getKohaSystemPreference('staffClientBaseURL'); + } + public function getPluginStatus(string $pluginName) { $this->initDatabaseConnection(); /** @noinspection SqlResolve */ diff --git a/code/web/services/ILL/AJAX.php b/code/web/services/ILL/AJAX.php index 5f57827799..fd8fc035f9 100644 --- a/code/web/services/ILL/AJAX.php +++ b/code/web/services/ILL/AJAX.php @@ -1,7 +1,7 @@ "FreeForm", // temporarily hard-coded "patron_id" => $user->id, @@ -45,7 +45,7 @@ function postFormData() ] ]; - $reqUrl = 'http://localhost:8081/api/v1/ill/requests'; // might need to replace localhost with IP if curl err 7 encountered -> TODO: store the url elsewhere + $reqUrl = $catalog->getStaffClientBaseURL() . '/api/v1/ill/requests'; $credentials = $user->ils_username . ':' . $user->ils_password; // $user->ils_password is likely to be null -> TODO: need to find a way to safely get and pass this credential $curl = curl_init($reqUrl); @@ -56,7 +56,7 @@ function postFormData() curl_setopt($curl, CURLOPT_HTTPAUTH, CURLAUTH_BASIC); curl_setopt($curl, CURLOPT_USERPWD, $credentials); curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1); - $result = curl_exec($curl); + curl_exec($curl); $err = curl_error($curl); if(!empty($err)) { From b28e214097d32eb5107cd99f8f9072eff17b1c96 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Chlo=C3=A9=20Zermatten?= Date: Wed, 14 Aug 2024 13:25:14 +0100 Subject: [PATCH 06/12] feat: temporary ILL requests view template --- .../themes/responsive/ILL/my-requests.tpl | 75 +++++++++++++++++++ 1 file changed, 75 insertions(+) create mode 100644 code/web/interface/themes/responsive/ILL/my-requests.tpl diff --git a/code/web/interface/themes/responsive/ILL/my-requests.tpl b/code/web/interface/themes/responsive/ILL/my-requests.tpl new file mode 100644 index 0000000000..b073b86b53 --- /dev/null +++ b/code/web/interface/themes/responsive/ILL/my-requests.tpl @@ -0,0 +1,75 @@ +{*is in essence a copy of myMaterialRequests.tpl, is intended for use as proof of concept only *} + +
+ {if !empty($profile->_web_note)} +
+
{$profile->_web_note}
+
+ {/if} + {if !empty($accountMessages)} + {include file='systemMessages.tpl' messages=$accountMessages} + {/if} + {if !empty($ilsMessages)} + {include file='ilsMessages.tpl' messages=$ilsMessages} + {/if} + +

{translate text='My Materials Requests' isPublicFacing=true}

+ + {* MDN 7/26/2019 Do not allow access for linked users *} + {* {include file="MyAccount/switch-linked-user-form.tpl" label="Viewing Requests for" actionPath="/MyAccount/ReadingHistory"}*} + + {if !empty($error)} +
{$error}
+ {else} + {if $user->canSuggestMaterials()} + {if !empty($ILLRequests)} + {if count($ILLRequests) > 0} +
+ + + + {if !empty($allowDeletingILSRequests)} + + {/if} + + + + + + + + {foreach from=$ILLRequests item=request} + + {if !empty($allowDeletingILSRequests)} + + {/if} + + + + + + {/foreach} + +
 {translate text="Summary" isPublicFacing=true}{translate text="Suggested On" isPublicFacing=true}{translate text="Staff Note" isPublicFacing=true}{translate text="Status" isPublicFacing=true}
+ + {$request.summary}{$request.requested_date}{$request.staff_note}{$request.status}
+ {if !empty($allowDeletingILSRequests)} + + {/if} +
+
+ {else} +
{translate text='There are no materials requests that meet your criteria.' isPublicFacing=true}
+ {/if} + {/if} + + {else} +
{translate text='You are not eligible to make Materials Requests at this time.' isPublicFacing=true}
+ {/if} + {/if} +
+ \ No newline at end of file From afcc84209be07a1057f0b5d847d30ef2979b8d86 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Chlo=C3=A9=20Zermatten?= Date: Wed, 14 Aug 2024 13:36:54 +0100 Subject: [PATCH 07/12] feat: ILL_MyRequests class --- code/web/services/ILL/MyRequests.php | 14 ++++++++++++++ 1 file changed, 14 insertions(+) create mode 100644 code/web/services/ILL/MyRequests.php diff --git a/code/web/services/ILL/MyRequests.php b/code/web/services/ILL/MyRequests.php new file mode 100644 index 0000000000..efebf92c26 --- /dev/null +++ b/code/web/services/ILL/MyRequests.php @@ -0,0 +1,14 @@ + Date: Wed, 14 Aug 2024 13:42:16 +0100 Subject: [PATCH 08/12] feat: GET ILL request list from Koha Consumes the Koha api to fetch a list of ILL requests made by a specific patron. --- code/web/services/ILL/MyRequests.php | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/code/web/services/ILL/MyRequests.php b/code/web/services/ILL/MyRequests.php index efebf92c26..597cbb33bc 100644 --- a/code/web/services/ILL/MyRequests.php +++ b/code/web/services/ILL/MyRequests.php @@ -4,6 +4,21 @@ class ILL_MyRequests extends MyAccount { function launch() { + } + + private function getRequestsBy($user) { + $catalog = CatalogFactory::getCatalogConnectionInstance(); + $reqUrl = $catalog->getStaffClientBaseURL() . '/api/v1/ill/requests' . "?q={\"patron_id\":" . ($user->unique_ils_id) . "}"; + + $credentials = $user->ils_username . ':' . $user->ils_password; // $user->ils_password is likely to be null -> TODO: need to find a way to safely get and pass this credential + + // fetch the ILL requests made by the user + $curl = curl_init($reqUrl); + curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1); + curl_setopt($curl, CURLOPT_HEADER, 1); + curl_setopt($curl, CURLOPT_HTTPAUTH, CURLAUTH_BASIC); + curl_setopt($curl, CURLOPT_USERPWD, $credentials); + $response = curl_exec($curl); } From fafddf2e9caf652a2ffe4a703d1617ce757f4bb2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Chlo=C3=A9=20Zermatten?= Date: Wed, 14 Aug 2024 13:43:21 +0100 Subject: [PATCH 09/12] feat: add any curl error to logs --- code/web/services/ILL/MyRequests.php | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/code/web/services/ILL/MyRequests.php b/code/web/services/ILL/MyRequests.php index 597cbb33bc..873a79c595 100644 --- a/code/web/services/ILL/MyRequests.php +++ b/code/web/services/ILL/MyRequests.php @@ -20,6 +20,12 @@ private function getRequestsBy($user) { curl_setopt($curl, CURLOPT_USERPWD, $credentials); $response = curl_exec($curl); + // handle any curl errors + $err = curl_error($curl); + if (!empty($err)) { + return new AspenError('an error occurred while sending your request: ' . $err); + } + } function getBreadcrumbs(): array { From f2c3299540938da41c488fca405180c7792afa57 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Chlo=C3=A9=20Zermatten?= Date: Wed, 14 Aug 2024 13:46:25 +0100 Subject: [PATCH 10/12] feat: get ILL request associative array parses the initial response retrieved from the Koha API and returns its body as an associative array, having closed the curl connexion. --- code/web/services/ILL/MyRequests.php | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/code/web/services/ILL/MyRequests.php b/code/web/services/ILL/MyRequests.php index 873a79c595..090230a4c7 100644 --- a/code/web/services/ILL/MyRequests.php +++ b/code/web/services/ILL/MyRequests.php @@ -26,6 +26,14 @@ private function getRequestsBy($user) { return new AspenError('an error occurred while sending your request: ' . $err); } + // extract the request body into an associative array + $headerSize = curl_getinfo($curl, CURLINFO_HEADER_SIZE); + $body = substr($response, $headerSize); + $requestList = json_decode($body, true); + + // shut down the connection + curl_close($curl); + return $requestList; } function getBreadcrumbs(): array { From 6062f112d22bca111889f7a771052a5e69a21927 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Chlo=C3=A9=20Zermatten?= Date: Wed, 14 Aug 2024 13:48:43 +0100 Subject: [PATCH 11/12] feat: get patron --- code/web/services/ILL/MyRequests.php | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/code/web/services/ILL/MyRequests.php b/code/web/services/ILL/MyRequests.php index 090230a4c7..342f377609 100644 --- a/code/web/services/ILL/MyRequests.php +++ b/code/web/services/ILL/MyRequests.php @@ -4,6 +4,27 @@ class ILL_MyRequests extends MyAccount { function launch() { + global $interface; + + if (UserAccount::isLoggedIn()) { + + // get the patron - uses logic from MaterialsRequest_MyRequests::launch() (should we?) + $user = UserAccount::getActiveUserObj(); + $linkedUsers = $user->getLinkedUsers(); + $patronId = empty($_REQUEST['patronId']) ? $user->id : $_REQUEST['patronId']; + $interface->assign('patronId', $patronId); + + $patron = $user->getUserReferredTo($patronId); + if (count($linkedUsers) > 0) { + array_unshift($linkedUsers, $user); + $interface->assign('linkedUsers', $linkedUsers); + } + $interface->assign('selectedUser', $patronId); // needs to be set even when there is only one user so that the patronId hidden input gets a value in the reading history form. + + } else { + header('Location: /MyAccount/Home?followupModule=MaterialsRequest&followupAction=MyRequests'); + exit; + } } private function getRequestsBy($user) { From 67c42e5a91d9f86d58566625aab1135fc7bc815f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Chlo=C3=A9=20Zermatten?= Date: Wed, 14 Aug 2024 13:49:33 +0100 Subject: [PATCH 12/12] feat: render ILL request list --- code/web/services/ILL/MyRequests.php | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/code/web/services/ILL/MyRequests.php b/code/web/services/ILL/MyRequests.php index 342f377609..a80e4faa40 100644 --- a/code/web/services/ILL/MyRequests.php +++ b/code/web/services/ILL/MyRequests.php @@ -21,6 +21,14 @@ function launch() { } $interface->assign('selectedUser', $patronId); // needs to be set even when there is only one user so that the patronId hidden input gets a value in the reading history form. + // get the list of requests for the patron + $requests = $this->getRequestsBy($patron); + $interface->assign('ILLRequests', $requests); + + $requestTemplate = 'my-requests.tpl'; // could get this from a catalogConnection (if set first) + $title = 'My Materials Requests'; + + $this->display($requestTemplate, $title); } else { header('Location: /MyAccount/Home?followupModule=MaterialsRequest&followupAction=MyRequests'); exit;