diff --git a/code/web/interface/themes/responsive/Admin/usage-graph.tpl b/code/web/interface/themes/responsive/Admin/usage-graph.tpl index 2d121f5196..b4658b7645 100644 --- a/code/web/interface/themes/responsive/Admin/usage-graph.tpl +++ b/code/web/interface/themes/responsive/Admin/usage-graph.tpl @@ -28,6 +28,10 @@ +
+ {translate text='Export To CSV' isAdminFacing=true} +
{translate text="Exporting will retrieve the latest data. To see it on screen, refresh this page." isAdminFacing=true}
+
{/strip} {literal} diff --git a/code/web/release_notes/24.09.00.MD b/code/web/release_notes/24.09.00.MD index f926f44146..2512a7ce37 100644 --- a/code/web/release_notes/24.09.00.MD +++ b/code/web/release_notes/24.09.00.MD @@ -14,6 +14,8 @@ // alexander // chloe +### Other Updates +- Added an 'Export as CSV' feature for the raw data of the Usage Graphs accessed through the System Reports' usage dashboard. (*CZ*) // pedro diff --git a/code/web/services/Admin/AJAX.php b/code/web/services/Admin/AJAX.php index a1f7cf09ef..b1318c22f3 100644 --- a/code/web/services/Admin/AJAX.php +++ b/code/web/services/Admin/AJAX.php @@ -1610,4 +1610,11 @@ public function copyMenuLinks() { return $result; } + + public function exportUsageData() { + require_once ROOT_DIR . '/services/Admin/UsageGraphs.php'; + $aspenUsageGraph = new Admin_UsageGraphs(); + $aspenUsageGraph->buildCSV(); + // TODO: trigger page refresh + } } \ No newline at end of file diff --git a/code/web/services/Admin/UsageGraphs.php b/code/web/services/Admin/UsageGraphs.php index 9095f22224..3af727dfb1 100644 --- a/code/web/services/Admin/UsageGraphs.php +++ b/code/web/services/Admin/UsageGraphs.php @@ -6,15 +6,87 @@ class Admin_UsageGraphs extends Admin_Admin { function launch() { global $interface; - global $enabledModules; - global $library; + + $stat = $_REQUEST['stat']; + if (!empty($_REQUEST['instance'])) { + $instanceName = $_REQUEST['instance']; + } else { + $instanceName = ''; + } + $title = 'Aspen Usage Graph'; + $interface->assign('graphTitle', $title); + $this->assignGraphSpecificTitle($stat); + $this->getAndSetInterfaceDataSeries($stat, $instanceName); + $interface->assign('stat', $stat); + $title = $interface->getVariable('graphTitle'); + $this->display('usage-graph.tpl', $title); + } + function getBreadcrumbs(): array { + $breadcrumbs = []; + $breadcrumbs[] = new Breadcrumb('/Admin/Home', 'Administration Home'); + $breadcrumbs[] = new Breadcrumb('/Admin/Home#system_reports', 'System Reports'); + $breadcrumbs[] = new Breadcrumb('/Admin/UsageDashboard', 'Usage Dashboard'); + $breadcrumbs[] = new Breadcrumb('', 'Usage Graph'); + return $breadcrumbs; + } + + function getActiveAdminSection(): string { + return 'system_reports'; + } + + function canView(): bool { + return UserAccount::userHasPermission([ + 'View Dashboards', + 'View System Reports', + ]); + } + + public function buildCSV() { + global $interface; + $stat = $_REQUEST['stat']; if (!empty($_REQUEST['instance'])) { $instanceName = $_REQUEST['instance']; } else { $instanceName = ''; } + $this->getAndSetInterfaceDataSeries($stat, $instanceName); + $dataSeries = $interface->getVariable('dataSeries'); + + $filename = "ApsenUsageData_{$stat}.csv"; + header("Last-Modified: " . gmdate("D, d M Y H:i:s") . " GMT"); + header("Cache-Control: no-store, no-cache, must-revalidate"); + header("Cache-Control: post-check=0, pre-check=0", false); + header("Pragma: no-cache"); + header('Content-Type: text/csv; charset=utf-8'); + header("Content-Disposition: attachment;filename={$filename}"); + $fp = fopen('php://output', 'w'); + $graphTitles = array_keys($dataSeries); + $numGraphTitles = count($dataSeries); + + // builds the header for each section of the table in the CSV - column headers: Dates, and the title of the graph + for($i = 0; $i < $numGraphTitles; $i++) { + $dataSerie = $dataSeries[$graphTitles[$i]]; + $numRows = count($dataSerie['data']); + $dates = array_keys($dataSerie['data']); + $header = ['Dates', $graphTitles[$i]]; + fputcsv($fp, $header); + + // builds each subsequent data row - aka the column value + for($j = 0; $j < $numRows; $j++) { + $date = $dates[$j]; + $value = $dataSerie['data'][$date]; + $row = [$date, $value]; + fputcsv($fp, $row); + } + } + exit(); + } + private function getAndSetInterfaceDataSeries($stat, $instanceName) { + global $interface; + global $enabledModules; + global $library; $dataSeries = []; $columnLabels = []; @@ -28,72 +100,6 @@ function launch() { $userUsage->selectAdd('month'); $userUsage->orderBy('year, month'); - switch ($stat) { - case 'generalUsage': - $title .= ' - General Usage'; - break; - case 'pageViews': - $title .= ' - Pages Viewed'; - break; - case 'authenticatedPageViews': - $title .= ' - Authenticated Page Views'; - break; - case 'sessionsStarted': - $title = ' - Sessions Started'; - break; - case 'pageViewsByBots': - $title .= ' - Pages Viewed By Bots'; - break; - case 'asyncRequests': - $title .= ' - Asynchronous Requests'; - break; - case 'coversRequested': - $title .= ' - Covers Requested'; - break; - case 'searches': - $title .= ' - Searches'; - break; - case 'groupedWorksSearches': - $title .= ' - Grouped Work Searches'; - break; - case 'listSearches': - $title .= ' - List Searches'; - break; - case 'edsSearches': - $title .= ' - EBSCO EDS Searches'; - break; - case 'eventSearches': - $title .= ' - Event Searches'; - break; - case 'openArchivesSearches': - $title .= ' - Open Archives Searches'; - break; - case 'genealogySearches': - $title .= ' - Genealogy Searches'; - break; - case 'exceptionsReport': - $title .= ' - Exceptions'; - break; - case 'blockedPages': - $title .= ' - Blocked Pages'; - break; - case 'blockedApiRequests': - $title .= ' - Blocked API Requests'; - break; - case 'errors': - $title .= ' - Errors'; - break; - case 'emailSending': - $title .= ' - Email Sending'; - break; - case 'emailsSent': - $title .= ' - Emails Sent'; - break; - case 'failedEmails': - $title .= ' - Failed Emails'; - break; - } - //General Usage Stats if ($stat == 'pageViews' || $stat == 'generalUsage') { $dataSeries['Page Views'] = [ @@ -276,8 +282,6 @@ function launch() { $userUsage->selectAdd('SUM(emailsFailed) as sumFailedEmails'); } - - //Collect results $userUsage->find(); @@ -378,28 +382,77 @@ function launch() { $interface->assign('dataSeries', $dataSeries); $interface->assign('translateDataSeries', true); $interface->assign('translateColumnLabels', false); - - $interface->assign('graphTitle', $title); - $this->display('usage-graph.tpl', $title); - } - - function getBreadcrumbs(): array { - $breadcrumbs = []; - $breadcrumbs[] = new Breadcrumb('/Admin/Home', 'Administration Home'); - $breadcrumbs[] = new Breadcrumb('/Admin/Home#system_reports', 'System Reports'); - $breadcrumbs[] = new Breadcrumb('/Admin/UsageDashboard', 'Usage Dashboard'); - $breadcrumbs[] = new Breadcrumb('', 'Usage Graph'); - return $breadcrumbs; } - function getActiveAdminSection(): string { - return 'system_reports'; + private function assignGraphSpecificTitle($stat) { + global $interface; + $title = $interface->getVariable('graphTitle'); + switch ($stat) { + case 'generalUsage': + $title .= ' - General Usage'; + break; + case 'pageViews': + $title .= ' - Pages Viewed'; + break; + case 'authenticatedPageViews': + $title .= ' - Authenticated Page Views'; + break; + case 'sessionsStarted': + $title = ' - Sessions Started'; + break; + case 'pageViewsByBots': + $title .= ' - Pages Viewed By Bots'; + break; + case 'asyncRequests': + $title .= ' - Asynchronous Requests'; + break; + case 'coversRequested': + $title .= ' - Covers Requested'; + break; + case 'searches': + $title .= ' - Searches'; + break; + case 'groupedWorksSearches': + $title .= ' - Grouped Work Searches'; + break; + case 'listSearches': + $title .= ' - List Searches'; + break; + case 'edsSearches': + $title .= ' - EBSCO EDS Searches'; + break; + case 'eventSearches': + $title .= ' - Event Searches'; + break; + case 'openArchivesSearches': + $title .= ' - Open Archives Searches'; + break; + case 'genealogySearches': + $title .= ' - Genealogy Searches'; + break; + case 'exceptionsReport': + $title .= ' - Exceptions'; + break; + case 'blockedPages': + $title .= ' - Blocked Pages'; + break; + case 'blockedApiRequests': + $title .= ' - Blocked API Requests'; + break; + case 'errors': + $title .= ' - Errors'; + break; + case 'emailSending': + $title .= ' - Email Sending'; + break; + case 'emailsSent': + $title .= ' - Emails Sent'; + break; + case 'failedEmails': + $title .= ' - Failed Emails'; + break; + } + $interface->assign('graphTitle', $title); } - function canView(): bool { - return UserAccount::userHasPermission([ - 'View Dashboards', - 'View System Reports', - ]); - } } \ No newline at end of file