From de20262d44f367833275df8a47437d04c8dae1b1 Mon Sep 17 00:00:00 2001 From: James Richie Date: Wed, 29 Jul 2026 20:12:26 -0400 Subject: [PATCH] added report for All Users Login Activity --- classes/Users.php | 13 +- js/selectReport.js | 396 +++++++++++++++------------- reports/Print_UserLoginActivity.php | 179 +++++++++++++ reports/Print_UserSummary.php | 4 +- xsl/searchPermitFacts.xsl | 5 +- 5 files changed, 397 insertions(+), 200 deletions(-) create mode 100644 reports/Print_UserLoginActivity.php diff --git a/classes/Users.php b/classes/Users.php index 09c3bf6..e9cdac2 100644 --- a/classes/Users.php +++ b/classes/Users.php @@ -292,13 +292,6 @@ class Users extends Base { public function getUserByUserName($user_name) { -// $SQL = "select view_users.* -// from view_users -// where user_id = '{$user_name}' -// or user_client_name = '{$user_name}'"; -// -// return $this->getTable("user", $SQL); - $SQL = "select view_users.* from view_users where user_id = ? @@ -326,7 +319,7 @@ class Users extends Base { public function getUsers() { - $SQL = "select view_users.* from view_users"; + $SQL = "select view_users.* from view_users order by view_users.user_name"; return $this->getTable("allusers", $SQL); } @@ -774,7 +767,7 @@ class Users extends Base { break; case "copy": - + $receiving_user_serial = filter_input(INPUT_POST, "receiving_user_serial", FILTER_SANITIZE_NUMBER_INT) ?: 0; $subscription_serials = filter_input(INPUT_POST, "subscriptions", FILTER_SANITIZE_NUMBER_INT, FILTER_REQUIRE_ARRAY) ?: array(); $subscription_start_dates = filter_input(INPUT_POST, "subscription_start_date", FILTER_DEFAULT, FILTER_REQUIRE_ARRAY) ?: array(); @@ -789,7 +782,7 @@ class Users extends Base { "usersubscription_end_date" => date("Y-m-d", strtotime($subscription_end_dates[$index] ?? "")) ); } - + // Add the Subscriptions to Receiving User $connection = $this->connect(); diff --git a/js/selectReport.js b/js/selectReport.js index c1c5f98..b5e5a87 100644 --- a/js/selectReport.js +++ b/js/selectReport.js @@ -3,227 +3,251 @@ // Select Report // ============= -$(document).ready(function() { +$(document).ready(function () { - var $application = $("#APPLICATION_MNEMONIC").val(), - $sessionStorage = JSON.parse(sessionStorage.getItem($application) || "{}"); - - // ----------- - // Find Button - // ----------- - - $(".btnFind").on("click", function() { - - $sessionStorage.action = "Reports.selectReport"; - $sessionStorage.pagination = "first"; - - sessionStorage.setItem($application, JSON.stringify($sessionStorage)); - - $("#spinner-dialog").modal("show"); - - formSubmit($sessionStorage); - - }); + var $application = $("#APPLICATION_MNEMONIC").val(), + $sessionStorage = JSON.parse(sessionStorage.getItem($application) || "{}"); - $("#select_report").on("keyup", function(e) { - if (e.key === "Enter") { - $(".btnFind").trigger("click"); - } - }); - - // ----------------- - // Clear Find Button - // ----------------- - - $(".btnClearFind").on("click", function() { - - $("#select_report").val("").trigger("change"); - - $sessionStorage.action = "Reports.selectReport"; - $sessionStorage.pagination = "first"; - - sessionStorage.setItem($application, JSON.stringify($sessionStorage)); - - $("#spinner-dialog").modal("show"); - - formSubmit($sessionStorage); - - }); + // ----------- + // Find Button + // ----------- - // -------------------- - // Show Per Page Change - // -------------------- + $(".btnFind").on("click", function () { - $("#reports_per_page").on("change", function() { - - $sessionStorage.alerts_per_page = $(this).val(); - $sessionStorage.action = "Reports.selectReport"; - $sessionStorage.pagination = "first"; - - sessionStorage.setItem($application, JSON.stringify($sessionStorage)); - - $("#spinner-dialog").modal("show"); - - formSubmit($sessionStorage); - - }); - - // ------------------ - // Pagination Buttons - // ------------------ - - $(".btnPagination").on("click", function() { - - $sessionStorage.action = "Reports.selectReport"; - $sessionStorage.pagination = $(this).data("pagination"); - - sessionStorage.setItem($application, JSON.stringify($sessionStorage)); - - $("#spinner-dialog").modal("show"); - - formSubmit($sessionStorage); - - delete $sessionStorage.pagination; - - sessionStorage.setItem($application, JSON.stringify($sessionStorage)); - - }); - - // ----------- - // Done Button - // ----------- - - $(".btnDone").on("click", function() { - - formSubmit({ action : "" }); - - }); - - // --------------------------- - // Process the selected Report - // --------------------------- - - $("#reports-table tbody").on("click touch", "tr", function(e) { - - e.preventDefault(); - - switch ($(this).data("report-type")) { - - case "Report" : - - $sessionStorage.action = $(this).data("report-class"); - $sessionStorage.printReturn = "Reports.selectReport"; + $sessionStorage.action = "Reports.selectReport"; + $sessionStorage.pagination = "first"; sessionStorage.setItem($application, JSON.stringify($sessionStorage)); - - var target = $(this).data("report-target").trim(); - formSubmit($sessionStorage, target); - - break; - - case "Download" : - - $sessionStorage.action = $(this).data("report-class"); - $sessionStorage.downloadReturn = "Reports.selectReport"; - - sessionStorage.setItem($application, JSON.stringify($sessionStorage)); + $("#spinner-dialog").modal("show"); formSubmit($sessionStorage); - - break; - - case "Email" : - - break; - - case "Graph" : - - $sessionStorage.action = $(this).data("report-class"); - $sessionStorage.graphReturn = "Reports.selectReport"; + + }); + + $("#select_report").on("keyup", function (e) { + if (e.key === "Enter") { + $(".btnFind").trigger("click"); + } + }); + + // ----------------- + // Clear Find Button + // ----------------- + + $(".btnClearFind").on("click", function () { + + $("#select_report").val("").trigger("change"); + + $sessionStorage.action = "Reports.selectReport"; + $sessionStorage.pagination = "first"; sessionStorage.setItem($application, JSON.stringify($sessionStorage)); + $("#spinner-dialog").modal("show"); + formSubmit($sessionStorage); - - break; - - case "Upload" : - - break; - - default : - - return false; - - break; - - } - }); + }); - // ------------------- - // Save Changed Inputs - // ------------------- + // -------------------- + // Show Per Page Change + // -------------------- - $(".autosave").on("change", function(e) { + $("#reports_per_page").on("change", function () { - switch (e.target.type) { + $sessionStorage.alerts_per_page = $(this).val(); + $sessionStorage.action = "Reports.selectReport"; + $sessionStorage.pagination = "first"; - case "text" : $sessionStorage[e.target.name] = $(this).val(); break; - case "radio" : $sessionStorage[e.target.name] = $(this).val(); break; - case "checkbox" : $sessionStorage[e.target.name] = $(this).prop("checked"); break; - case "select-one" : $sessionStorage[e.target.name] = $(this).val(); break; - case "hidden" : $sessionStorage[e.target.name] = $(this).val(); break; + sessionStorage.setItem($application, JSON.stringify($sessionStorage)); - default : $sessionStorage[e.target.name] = $(this).val(); break; + $("#spinner-dialog").modal("show"); - } + formSubmit($sessionStorage); - sessionStorage.setItem($application, JSON.stringify($sessionStorage)); + }); - }); + // ------------------ + // Pagination Buttons + // ------------------ - // ---------------- - // Initalize Inputs - // ---------------- + $(".btnPagination").on("click", function () { - $.each($sessionStorage, function(name, value) { + $sessionStorage.action = "Reports.selectReport"; + $sessionStorage.pagination = $(this).data("pagination"); - var $input = $(":input").filter("[name='" + name + "']"); + sessionStorage.setItem($application, JSON.stringify($sessionStorage)); - if ($input.length > 0) { + $("#spinner-dialog").modal("show"); - switch ($input.prop("type")) { + formSubmit($sessionStorage); - case "text" : $input.val(value); break; - case "radio" : $input.filter("[value=" + value + "]").prop("checked", true); break; - case "checkbox" : $input.prop("checked", value); break; - case "select-one" : $input.val(value); break; - case "hidden" : $input.val(value); break; + delete $sessionStorage.pagination; - default : $input.val(value); break; + sessionStorage.setItem($application, JSON.stringify($sessionStorage)); - } + }); - } + // ----------- + // Done Button + // ----------- - }); + $(".btnDone").on("click", function () { - // ------------------ - // Save preset Inputs - // ------------------ + formSubmit({action: ""}); - $("input[type=radio]:checked").trigger("change"); + }); - // ----------------- - // Per Page Dropdown - // ----------------- + // --------------------------- + // Process the selected Report + // --------------------------- - $("#reports_per_page").on("change", function() { + $("#reports-table tbody").on("click touch", "tr", function (e) { + + e.preventDefault(); + + switch ($(this).data("report-type")) { + + case "Report" : + + $sessionStorage.action = $(this).data("report-class"); + $sessionStorage.printReturn = "Reports.selectReport"; + + sessionStorage.setItem($application, JSON.stringify($sessionStorage)); + + var target = $(this).data("report-target").trim(); + + formSubmit($sessionStorage, target); + + break; + + case "Download" : + + $sessionStorage.action = $(this).data("report-class"); + $sessionStorage.downloadReturn = "Reports.selectReport"; + + sessionStorage.setItem($application, JSON.stringify($sessionStorage)); + + formSubmit($sessionStorage); + + break; + + case "Email" : + + break; + + case "Graph" : + + $sessionStorage.action = $(this).data("report-class"); + $sessionStorage.graphReturn = "Reports.selectReport"; + + sessionStorage.setItem($application, JSON.stringify($sessionStorage)); + + formSubmit($sessionStorage); + + break; + + case "Upload" : + + break; + + default : + + return false; + + break; + + } + + }); + + // ------------------- + // Save Changed Inputs + // ------------------- + + $(".autosave").on("change", function (e) { + + switch (e.target.type) { + + case "text" : + $sessionStorage[e.target.name] = $(this).val(); + break; + case "radio" : + $sessionStorage[e.target.name] = $(this).val(); + break; + case "checkbox" : + $sessionStorage[e.target.name] = $(this).prop("checked"); + break; + case "select-one" : + $sessionStorage[e.target.name] = $(this).val(); + break; + case "hidden" : + $sessionStorage[e.target.name] = $(this).val(); + break; + + default : + $sessionStorage[e.target.name] = $(this).val(); + break; + + } + + sessionStorage.setItem($application, JSON.stringify($sessionStorage)); + + }); + + // ---------------- + // Initalize Inputs + // ---------------- + + $.each($sessionStorage, function (name, value) { + + var $input = $(":input").filter("[name='" + name + "']"); + + if ($input.length > 0) { + + switch ($input.prop("type")) { + + case "text" : + $input.val(value); + break; + case "radio" : + $input.filter("[value=" + value + "]").prop("checked", true); + break; + case "checkbox" : + $input.prop("checked", value); + break; + case "select-one" : + $input.val(value); + break; + case "hidden" : + $input.val(value); + break; + + default : + $input.val(value); + break; + + } + + } + + }); + + // ------------------ + // Save preset Inputs + // ------------------ + + $("input[type=radio]:checked").trigger("change"); + + // ----------------- + // Per Page Dropdown + // ----------------- + + $("#reports_per_page").on("change", function () { + + $(".btnFind").trigger("click"); + + }); - $(".btnFind").trigger("click"); - - }); - }); \ No newline at end of file diff --git a/reports/Print_UserLoginActivity.php b/reports/Print_UserLoginActivity.php new file mode 100644 index 0000000..c5bc43b --- /dev/null +++ b/reports/Print_UserLoginActivity.php @@ -0,0 +1,179 @@ +output_type = $output_type; + + ob_clean(); + + if ($output_type == "string") { + return $report->render(); + } else { + $report->render(); + } + } +} + +// ========================== +// Class to Generate the .pdf +// ========================== + +class User_LoginActivity extends TCPDF { + + // Variables + + public $user_serial = 0; + public $first_page = true; + public $output_type = "normal"; + + // ================ + // Debug an Object. + // ================ + + public function debug($object = "") { + + echo "
";
+        print_r($object);
+        exit();
+    }
+
+    // =================
+    // Render the Report
+    // =================
+
+    public function render() {
+
+        set_time_limit(0);
+
+        // Get the data for the report
+
+        $users = (new Users())->getUsers();
+
+        // Set report defaults
+
+        $this->title = "All Users Login Activity";
+
+        $this->SetFont("Calibri");
+        $this->SetMargins(10, 30, 10);
+        $this->SetHeaderMargin(10);
+        $this->SetFooterMargin(10);
+        $this->setCellPaddings(0, 0, 0, 0);
+        $this->setCellMargins(2, 0, 0, 0);
+
+        $this->addPage("P", "LETTER");
+
+        // ------------------------
+        // Print the Users Activity
+        // ------------------------
+
+        $this->SetFont("Calibri", "B", 10);
+
+        $rowCount = 0;
+
+        foreach ($users as $user) {
+
+            $this->stripeLine($rowCount, 60);
+
+            $rowCount++;
+
+            $user_name = (string) $user->user_name;
+            $users_login = (string) $user->user_login_verbose ?: 'Never Logged In';
+
+            $this->Cell(20, 0, $user_name, 0, 0, "C", false, "", 0);
+            $this->Cell(20, 0, $users_login, 0, 0, "L", false, "", 0);
+            $this->Ln();
+        }
+
+        // --------------
+        // Return the pdf
+        // --------------
+
+        if ($this->output_type == "string") {
+            return $this->Output("UserLoginActivity.pdf", "S");
+        } else {
+            $this->Output("UserLoginActivity.pdf");
+        }
+    }
+
+    // ======
+    // Header
+    // ======
+
+    public function Header() {
+
+        $this->setCellPaddings(0, 0, 0, 0);
+        $this->setCellMargins(2, 0, 0, 0);
+
+        $this->Image('images/dec-international-logo.png', 10, 7, 25, 10);
+
+        $this->SetFont("Calibri", "B", 16);
+
+        $this->Cell(0, 6, "Users Login Activity", 0, 1, "C");
+
+        $this->Ln(5);
+
+        $this->SetFont("Calibri", "B", 12);
+
+        $this->Cell(20, 0, "User Name", "B", 0, "C", false, "", 3);
+        $this->Cell(50, 0, "Last Login", "B", 0, "L", false, "", 3);
+
+        $this->SetFont("Calibri", "B", 10);
+    }
+
+    // ======
+    // Footer
+    // ======
+
+    public function Footer() {
+
+        $this->SetFont("Calibri", "I", 8);
+
+        $X = $this->GetX();
+
+        $this->Cell(0, 10, "DEC-International, LLC", 0, false, "C");
+
+        $this->SetX($X);
+
+        $this->Cell(40, 10, "Page " . $this->getAliasNumPage() . "/" . $this->getAliasNbPages(), 0, false, "L");
+        $this->Cell(0, 10, date("Y-m-d g:i A"), 0, false, "R");
+    }
+
+    // =======================
+    // Stripe the printed line
+    // =======================
+
+    private function stripeLine($pRowCount = 0, $pRowWidth = 0) {
+
+        $this->SetFillColor(($pRowCount % 2) ? 220 : 255);
+        $X = $this->GetX();
+        $this->Cell($pRowWidth, 0, "", 0, 0, "L", true);
+        $this->SetX($X);
+    }
+}
+
+?>
diff --git a/reports/Print_UserSummary.php b/reports/Print_UserSummary.php
index 5e79444..9bb8c7e 100644
--- a/reports/Print_UserSummary.php
+++ b/reports/Print_UserSummary.php
@@ -2,9 +2,9 @@
 
 require_once ("tcpdf/tcpdf.php");
 
-// ============================
+// ==========================
 // Print a User Summary Sheet
-// ============================
+// ==========================
 
 class Print_UserSummary extends Base {
 
diff --git a/xsl/searchPermitFacts.xsl b/xsl/searchPermitFacts.xsl
index 03381fd..67ecb24 100644
--- a/xsl/searchPermitFacts.xsl
+++ b/xsl/searchPermitFacts.xsl
@@ -31,7 +31,8 @@
                     |
                     
                     
-                        Available Records:                     
+                        Available Records: 
+                        
                     
                    
         
@@ -185,7 +186,7 @@
                             
 
                         
-            
+