From 3c602e06db6bd169cf659afe2591e69f5ed6d2aa Mon Sep 17 00:00:00 2001
From: Juha Luoma <33253757+LuomaJuha@users.noreply.github.com>
Date: Tue, 5 Nov 2024 13:29:08 +0200
Subject: [PATCH 2/7] Adjusted loan history to show form to download
---
local/languages/finna/en-gb.ini | 12 +-
local/languages/finna/fi.ini | 12 +-
local/languages/finna/sv.ini | 12 +-
.../Finna/Controller/MyResearchController.php | 222 +++++++++++-------
.../templates/checkouts/downloadhistory.phtml | 25 ++
5 files changed, 188 insertions(+), 95 deletions(-)
create mode 100644 themes/finna2/templates/checkouts/downloadhistory.phtml
diff --git a/local/languages/finna/en-gb.ini b/local/languages/finna/en-gb.ini
index 4ac27d2f4fc..c9d0cf9525b 100644
--- a/local/languages/finna/en-gb.ini
+++ b/local/languages/finna/en-gb.ini
@@ -599,10 +599,14 @@ list_order_saved = "Sort order saved"
list-tags-info = "Add a new keyword"
Loading = "Loading"
Loan Details = "Loan Details"
-loan_history_download = "Export all in page"
-loan_history_download_csv = "Export CSV"
-loan_history_download_ods = "Export OpenOffice (ods)"
-loan_history_download_xlsx = "Export Excel (xlsx)"
+loan_history_download = "Download loan history"
+loan_history_download_csv = "CSV"
+loan_history_download_ods = "OpenOffice (ods)"
+loan_history_download_xlsx = "Excel (xlsx)"
+loan_history_info = "Select starting page for downloading loan history. Download starts from the first page and 9 following pages."
+loan_history_pages = "Pages available to download: %%total%%"
+loan_history_append_file = "Choose a file where to append loan history"
+loan_history_create_new_file = "Or create a new file"
loan_history_purge = "Purge History"
loan_history_purge_prompt_html = "Are you sure you will purge the loan history? Cleared loan history cannot be retrieved anymore."
loan_history_purge_selected = "Purge Selected"
diff --git a/local/languages/finna/fi.ini b/local/languages/finna/fi.ini
index 66e17185bfb..9e86a9a3483 100644
--- a/local/languages/finna/fi.ini
+++ b/local/languages/finna/fi.ini
@@ -589,10 +589,14 @@ list_order_saved = "Järjestys tallennettu"
list-tags-info = "Lisää uusi avainsana"
Loading = "Ladataan"
Loan Details = "Lainan tiedot"
-loan_history_download = "Vie kaikki sivulta"
-loan_history_download_csv = "Vie CSV"
-loan_history_download_ods = "Vie OpenOffice (ods)"
-loan_history_download_xlsx = "Vie Excel (xlsx)"
+loan_history_download = "Lataa lainahistoria"
+loan_history_download_csv = "CSV"
+loan_history_download_ods = "OpenOffice (ods)"
+loan_history_download_xlsx = "Excel (xlsx)"
+loan_history_info = "Valitse aloitussivu lainahistorian lataamiselle. Sivuja ladataan ensimmäinen valittu sivu ja 9 seuraavaa."
+loan_history_pages = "Sivuja ladattavana: %%total%%"
+loan_history_append_file = "Valitse tiedosto, mihin lainahistoriaa jatketaan"
+loan_history_create_new_file = "Tai luo uusi tiedosto"
loan_history_purge = "Tyhjennä historia"
loan_history_purge_prompt_html = "Oletko varma, että haluat tyhjentää lainaushistoriasi? Tyhjennettyä historiaa ei saa takaisin."
loan_history_purge_selected = "Poista valitut"
diff --git a/local/languages/finna/sv.ini b/local/languages/finna/sv.ini
index e3e84c7b4a9..31d8dde5488 100644
--- a/local/languages/finna/sv.ini
+++ b/local/languages/finna/sv.ini
@@ -587,10 +587,14 @@ list_order_saved = "Sortering sparad"
list-tags-info = "Lägg till nytt nyckelord"
Loading = "Laddar"
Loan Details = "Information om lånet"
-loan_history_download = "Exportera alla på sidan"
-loan_history_download_csv = "Exportera CSV"
-loan_history_download_ods = "Exportera OpenOffice (ods)"
-loan_history_download_xlsx = "Exportera Excel (xlsx)"
+loan_history_download = "Ladda lånehistorik"
+loan_history_download_csv = "CSV"
+loan_history_download_ods = "OpenOffice (ods)"
+loan_history_download_xlsx = "Excel (xlsx)"
+loan_history_info = "Välja första sidan att ladda lånehistorik. Laddning börjar från första sidan och innehåller nästa 9 sidorna."
+loan_history_pages = "Sidorna tillgänglig för laddning: %%total%%"
+loan_history_append_file = "Välj filen för att fortsätta nedladdningen"
+loan_history_create_new_file = "Eller skapa en ny fil"
loan_history_purge = "Rensa historiken"
loan_history_purge_prompt_html = "Är du säker på att du vill rensa din utlåningshistorik? Raderad historik kan inte återskapas."
loan_history_purge_selected = "Radera valda"
diff --git a/module/Finna/src/Finna/Controller/MyResearchController.php b/module/Finna/src/Finna/Controller/MyResearchController.php
index 9be2eb547c9..ce5d363b455 100644
--- a/module/Finna/src/Finna/Controller/MyResearchController.php
+++ b/module/Finna/src/Finna/Controller/MyResearchController.php
@@ -1347,114 +1347,170 @@ public function downloadLoanHistoryAction()
'getMyTransactionHistory',
$patron
);
+
if (false === $functionConfig) {
$this->flashMessenger()->addErrorMessage('ils_action_unavailable');
return $this->redirect()->toRoute('checkouts-history');
}
- $fileFormat = $this->params()->fromQuery('format', '');
- if (!in_array($fileFormat, ['ods', 'csv', 'xlsx'])) {
+ $allowedFileFormats = ['csv', 'ods', 'xlsx'];
+ if (!$this->formWasSubmitted('submitLoanHistoryRequest')) {
+ $pageOptions = $this->getPaginationHelper()->getOptions(
+ 1,
+ null,
+ $config->Catalog->historic_loan_page_size ?? 50,
+ $functionConfig
+ );
+ // Get checked out item details:
+ $result = $catalog->getMyTransactionHistory($patron, $pageOptions['ilsParams']);
+ $paginator = $this->getPaginationHelper()->getPaginator(
+ $pageOptions,
+ $result['count'],
+ $result['transactions']
+ );
+ $view = $this->createViewModel([
+ 'paginator' => $paginator,
+ 'fileFormats' => $allowedFileFormats,
+ 'params' => $pageOptions['ilsParams'],
+ ]);
+ $view->setTemplate('checkouts/downloadhistory.phtml');
+ return $view;
+ }
+
+ $request = $this->getRequest();
+ if (!$request->isPost()) {
throw new \Exception('Invalid parameters.');
}
+ $requestCombined = array_merge_recursive(
+ $request->getPost()->toArray(),
+ $request->getFiles()->toArray()
+ );
+ $fileFormat = $requestCombined['history_file_format'] ?? '';
+ if (!in_array($fileFormat, $allowedFileFormats)) {
+ throw new \Exception('Should be not here.');
+ }
+
+ $startPage = (int)$requestCombined['startIndex'];
+ $lastPage = (int)($requestCombined['lastIndex'] ?? $startPage);
+ $alternativeLimit = $startPage + 9;
+ if ($lastPage > $startPage + 9) {
+ $lastPage = $alternativeLimit;
+ }
- $page = (int)$this->params()->fromQuery('page', 1);
- $sort = $this->params()->fromQuery('sort', '');
$recordLoader = $this->serviceLocator->get(\VuFind\Record\Loader::class);
$config = $this->getConfig();
- try {
- $tmp = fopen('php://temp/maxmemory:' . (5 * 1024 * 1024), 'r+');
- $header = [
- $this->translate('Title'),
- $this->translate('Format'),
- $this->translate('Author'),
- $this->translate('Publication Year'),
- $this->translate('Institution'),
- $this->translate('Borrowing Location'),
- $this->translate('Checkout Date'),
- $this->translate('Return Date'),
- $this->translate('Due Date'),
+
+ $tmp = fopen('php://temp/maxmemory:' . (5 * 1024 * 1024), 'r+');
+ $header = [
+ $this->translate('Title'),
+ $this->translate('Format'),
+ $this->translate('Author'),
+ $this->translate('Publication Year'),
+ $this->translate('Institution'),
+ $this->translate('Borrowing Location'),
+ $this->translate('Checkout Date'),
+ $this->translate('Return Date'),
+ $this->translate('Due Date'),
+ ];
+
+ if ($file = $requestCombined['append_file']['tmp_name'] ?? null) {
+ $fileFormatLimit = [
+ \PhpOffice\PhpSpreadsheet\IOFactory::READER_CSV,
+ \PhpOffice\PhpSpreadsheet\IOFactory::READER_ODS,
+ \PhpOffice\PhpSpreadsheet\IOFactory::READER_XLSX,
];
+ try {
+ $spreadsheet = \PhpOffice\PhpSpreadsheet\IOFactory::load($file, 0, $fileFormatLimit);
+ } catch (\Exception $e) {
+ throw new \Exception('Invalid format');
+ }
+ $worksheet = $spreadsheet->getActiveSheet();
+ } else {
$spreadsheet = new Spreadsheet();
$worksheet = $spreadsheet->getActiveSheet();
$worksheet->fromArray($header);
- if ('xlsx' === $fileFormat) {
- Cell::setValueBinder(new AdvancedValueBinder());
- }
+ }
+
+ if ('xlsx' === $fileFormat) {
+ Cell::setValueBinder(new AdvancedValueBinder());
+ }
+ $transactions = [];
+ for ($i = $startPage; $i <= $lastPage; $i++) {
$pageOptions = $this->getPaginationHelper()->getOptions(
- $page,
- $sort,
+ $i,
+ null,
$config->Catalog->historic_loan_page_size ?? 50,
$functionConfig
);
$result = $catalog->getMyTransactionHistory($patron, $pageOptions['ilsParams']);
-
if (isset($result['success']) && !$result['success']) {
$this->flashMessenger()->addErrorMessage($result['status']);
return $this->redirect()->toRoute('checkouts-history');
}
-
- $ids = [];
- foreach ($result['transactions'] as $current) {
- $id = $current['id'] ?? '';
- $source = $current['source'] ?? DEFAULT_SEARCH_BACKEND;
- $ids[] = compact('id', 'source');
- }
- $records = $recordLoader->loadBatch($ids, true);
- foreach ($result['transactions'] as $i => $current) {
- $driver = $records[$i];
- $format = $driver->getFormats();
- $format = end($format);
- $author = $driver->tryMethod('getNonPresenterAuthors');
-
- $loan = [];
- $loan[] = $current['title'] ?? $driver->getTitle() ?? '';
- $loan[] = $this->translate($format);
- $loan[] = $author[0]['name'] ?? '';
- $loan[] = $current['publication_year'] ?? '';
- $loan[] = empty($current['institution_name'])
- ? ''
- : $this->translateWithPrefix('location_', $current['institution_name']);
- $loan[] = empty($current['borrowingLocation'])
- ? ''
- : $this->translateWithPrefix('location_', $current['borrowingLocation']);
- $loan[] = $current['checkoutDate'] ?? '';
- $loan[] = $current['returnDate'] ?? '';
- $loan[] = $current['dueDate'] ?? '';
-
- $nextRow = $worksheet->getHighestRow() + 1;
- $worksheet->fromArray($loan, null, 'A' . (string)$nextRow);
- }
- if ('xlsx' === $fileFormat) {
- $worksheet->getStyle('G2:I' . $worksheet->getHighestRow())
- ->getNumberFormat()
- ->setFormatCode('dd.mm.yyyy');
- foreach (['G', 'H', 'I'] as $col) {
- $worksheet->getColumnDimension($col)->setAutoSize(true);
- }
+ $tempPaginator = $this->getPaginationHelper()->getPaginator(
+ $pageOptions,
+ $result['count'],
+ $result['transactions']
+ );
+ $transactions = array_merge($transactions, $result['transactions']);
+ }
+ $ids = [];
+ foreach ($transactions as $current) {
+ $id = $current['id'] ?? '';
+ $source = $current['source'] ?? DEFAULT_SEARCH_BACKEND;
+ $ids[] = compact('id', 'source');
+ }
+ $records = $recordLoader->loadBatch($ids, true);
+ foreach ($transactions as $i => $current) {
+ $driver = $records[$i];
+ $format = $driver->getFormats();
+ $format = end($format);
+ $author = $driver->tryMethod('getNonPresenterAuthors');
+
+ $loan = [];
+ $loan[] = $current['title'] ?? $driver->getTitle() ?? '';
+ $loan[] = $this->translate($format);
+ $loan[] = $author[0]['name'] ?? '';
+ $loan[] = $current['publication_year'] ?? '';
+ $loan[] = empty($current['institution_name'])
+ ? ''
+ : $this->translateWithPrefix('location_', $current['institution_name']);
+ $loan[] = empty($current['borrowingLocation'])
+ ? ''
+ : $this->translateWithPrefix('location_', $current['borrowingLocation']);
+ $loan[] = $current['checkoutDate'] ?? '';
+ $loan[] = $current['returnDate'] ?? '';
+ $loan[] = $current['dueDate'] ?? '';
+
+ $nextRow = $worksheet->getHighestRow() + 1;
+ $worksheet->fromArray($loan, null, 'A' . (string)$nextRow);
+ }
+ if ('xlsx' === $fileFormat) {
+ $worksheet->getStyle('G2:I' . $worksheet->getHighestRow())
+ ->getNumberFormat()
+ ->setFormatCode('dd.mm.yyyy');
+ foreach (['G', 'H', 'I'] as $col) {
+ $worksheet->getColumnDimension($col)->setAutoSize(true);
}
- $response = $this->getResponse();
- $response->getHeaders()
- ->addHeaderLine(
- 'Content-Type',
- $this->exportFormats[$fileFormat]['mediaType']
- );
- $writer = new $this->exportFormats[$fileFormat]['writer']($spreadsheet);
- $writer->save($tmp);
- $fileName = implode('-', ['finna-loan-history-page', $page, $sort,]);
- $fileName = str_replace(' ', '-', $fileName) . '.' . $fileFormat;
- $response->getHeaders()
- ->addHeaderLine(
- 'Content-Disposition',
- 'attachment; filename="' . $fileName . '"'
- );
-
- rewind($tmp);
-
- $response->setContent(stream_get_contents($tmp));
- } catch (\Exception $e) {
- $this->flashMessenger()->addErrorMessage('An error has occurred');
- return $this->redirect()->toRoute('checkouts-history');
}
+ $response = $this->getResponse();
+ $response->getHeaders()
+ ->addHeaderLine(
+ 'Content-Type',
+ $this->exportFormats[$fileFormat]['mediaType']
+ );
+ $writer = new $this->exportFormats[$fileFormat]['writer']($spreadsheet);
+ $writer->save($tmp);
+ $fileName = implode('-', ['finna-loan-history-pages', $startPage, $lastPage]);
+ $fileName .= ".$fileFormat";
+ $response->getHeaders()
+ ->addHeaderLine(
+ 'Content-Disposition',
+ 'attachment; filename="' . $fileName . '"'
+ );
+
+ rewind($tmp);
+ $response->setContent(stream_get_contents($tmp));
return $response;
}
diff --git a/themes/finna2/templates/checkouts/downloadhistory.phtml b/themes/finna2/templates/checkouts/downloadhistory.phtml
new file mode 100644
index 00000000000..c3995b7933b
--- /dev/null
+++ b/themes/finna2/templates/checkouts/downloadhistory.phtml
@@ -0,0 +1,25 @@
+
From 9a549d9acca35f965b4974b6dea89a22092a4cac Mon Sep 17 00:00:00 2001
From: Juha Luoma <33253757+LuomaJuha@users.noreply.github.com>
Date: Tue, 5 Nov 2024 13:36:04 +0200
Subject: [PATCH 3/7] Added csrf
---
local/languages/finna/fi.ini | 2 +-
.../Finna/Controller/MyResearchController.php | 8 +++++-
.../templates/checkouts/downloadhistory.phtml | 3 ++-
.../finna2/templates/checkouts/history.phtml | 26 +------------------
4 files changed, 11 insertions(+), 28 deletions(-)
diff --git a/local/languages/finna/fi.ini b/local/languages/finna/fi.ini
index 9e86a9a3483..2a0e6763341 100644
--- a/local/languages/finna/fi.ini
+++ b/local/languages/finna/fi.ini
@@ -589,7 +589,7 @@ list_order_saved = "Järjestys tallennettu"
list-tags-info = "Lisää uusi avainsana"
Loading = "Ladataan"
Loan Details = "Lainan tiedot"
-loan_history_download = "Lataa lainahistoria"
+loan_history_download = "Lataa lainaushistoria"
loan_history_download_csv = "CSV"
loan_history_download_ods = "OpenOffice (ods)"
loan_history_download_xlsx = "Excel (xlsx)"
diff --git a/module/Finna/src/Finna/Controller/MyResearchController.php b/module/Finna/src/Finna/Controller/MyResearchController.php
index ce5d363b455..15920c1e164 100644
--- a/module/Finna/src/Finna/Controller/MyResearchController.php
+++ b/module/Finna/src/Finna/Controller/MyResearchController.php
@@ -1378,12 +1378,18 @@ public function downloadLoanHistoryAction()
$request = $this->getRequest();
if (!$request->isPost()) {
- throw new \Exception('Invalid parameters.');
+ throw new \Exception('Invalid method.');
}
+
$requestCombined = array_merge_recursive(
$request->getPost()->toArray(),
$request->getFiles()->toArray()
);
+ // Do CSRF check
+ $csrf = $this->serviceLocator->get(\VuFind\Validator\CsrfInterface::class);
+ if (!$csrf->isValid($requestCombined['csrf'])) {
+ throw new \VuFind\Exception\BadRequest('error_inconsistent_parameters');
+ }
$fileFormat = $requestCombined['history_file_format'] ?? '';
if (!in_array($fileFormat, $allowedFileFormats)) {
throw new \Exception('Should be not here.');
diff --git a/themes/finna2/templates/checkouts/downloadhistory.phtml b/themes/finna2/templates/checkouts/downloadhistory.phtml
index c3995b7933b..c2ac6442826 100644
--- a/themes/finna2/templates/checkouts/downloadhistory.phtml
+++ b/themes/finna2/templates/checkouts/downloadhistory.phtml
@@ -1,5 +1,6 @@
+
=$this->transEsc('loan_history_download')?>