From 3c8f812a16d0484c4fb32eb78cc3baf38fcfe898 Mon Sep 17 00:00:00 2001 From: johnnyq Date: Thu, 30 Jul 2026 00:46:15 -0400 Subject: [PATCH] Feature: On all export modals added Filter Tab and Selectable Columns tab with default selected, also you can now export to a PDF --- admin/modals/user/user_export.php | 53 +- admin/post/users.php | 79 +- admin/users.php | 2 +- agent/assets.php | 2 +- agent/certificates.php | 2 +- agent/clients.php | 2 +- agent/contacts.php | 2 +- agent/credentials.php | 2 +- agent/domains.php | 2 +- agent/expenses.php | 2 +- agent/invoices.php | 2 +- agent/locations.php | 2 +- agent/modals/asset/asset_export.php | 165 +++- agent/modals/asset/asset_interface_export.php | 7 +- .../modals/certificate/certificate_export.php | 95 ++- agent/modals/client/client_export.php | 164 +++- agent/modals/contact/contact_export.php | 126 ++- agent/modals/credential/credential_export.php | 99 ++- agent/modals/domain/domain_export.php | 95 ++- agent/modals/expense/expense_export.php | 91 +- agent/modals/income/income_export.php | 12 +- agent/modals/invoice/invoice_export.php | 90 +- agent/modals/location/location_export.php | 100 ++- agent/modals/network/network_export.php | 103 ++- agent/modals/product/product_export.php | 93 +- agent/modals/quote/quote_export.php | 56 +- .../recurring_invoice_export.php | 117 ++- agent/modals/software/software_export.php | 94 ++- agent/modals/ticket/ticket_export.php | 193 ++++- .../modals/transaction/transaction_export.php | 11 +- agent/modals/trip/trip_export.php | 47 +- agent/modals/vendor/vendor_export.php | 48 +- agent/networks.php | 2 +- agent/post/asset.php | 198 +++-- agent/post/certificate.php | 93 +- agent/post/client.php | 132 ++- agent/post/contact.php | 115 ++- agent/post/credential.php | 106 ++- agent/post/domain.php | 98 ++- agent/post/expense.php | 132 +-- agent/post/income.php | 31 +- agent/post/invoice.php | 122 ++- agent/post/location.php | 102 ++- agent/post/network.php | 91 +- agent/post/product.php | 97 ++- agent/post/quote.php | 81 +- agent/post/recurring_invoice.php | 92 +- agent/post/software.php | 152 ++-- agent/post/ticket.php | 192 ++++- agent/post/transaction.php | 44 +- agent/post/trip.php | 82 +- agent/post/vendor.php | 81 +- agent/products.php | 2 +- agent/quotes.php | 2 +- agent/recurring_invoices.php | 13 +- agent/software.php | 2 +- agent/tickets.php | 2 +- agent/trips.php | 2 +- agent/vendors.php | 2 +- functions.php | 1 + functions/export.php | 799 ++++++++++++++++++ 61 files changed, 3997 insertions(+), 829 deletions(-) create mode 100644 functions/export.php diff --git a/admin/modals/user/user_export.php b/admin/modals/user/user_export.php index 929a0837..21590878 100644 --- a/admin/modals/user/user_export.php +++ b/admin/modals/user/user_export.php @@ -1,25 +1,70 @@ + + +
+
diff --git a/admin/post/users.php b/admin/post/users.php index 3bfa7028..39b2f7a4 100644 --- a/admin/post/users.php +++ b/admin/post/users.php @@ -301,57 +301,68 @@ if (isset($_POST['restore_user'])) { } -if (isset($_POST['export_users_csv'])) { +if (isset($_POST['export_users'])) { validateCSRFToken(); - //get records from database - $sql = mysqli_query($mysqli, "SELECT * FROM users LEFT JOIN user_roles ON user_role_id = role_id ORDER BY user_name ASC"); + enforceAdminPermission(); - $count = mysqli_num_rows($sql); + $format = resolveExportFormat($_POST['export_users']); - if ($count > 0) { - $delimiter = ","; - $enclosure = '"'; - $escape = '\\'; // backslash - $filename = "Users-" . date('Y-m-d') . ".csv"; + // Filters inherited from the users page - mirrors admin/users.php + $filter_summary = []; - //create a file pointer - $f = fopen('php://memory', 'w'); + // Archived Filter + if (isset($_POST['archived']) && $_POST['archived'] == 1) { + $archive_query = "user_archived_at IS NOT NULL"; + $filter_summary['Archived'] = 'Archived only'; + } else { + $archive_query = "user_archived_at IS NULL"; + } - //set column headers - $fields = array('Name', 'Email', 'Role', 'Status', 'Creation Date'); - fputcsv($f, $fields, $delimiter, $enclosure, $escape); + // Search Filter + $q = escapeSql($_POST['q'] ?? ''); + if (!empty($q)) { + $filter_summary['Search'] = $_POST['q']; + } - //output each row of the data, format line as csv and write to file pointer - while($row = $sql->fetch_assoc()) { + $sql = mysqli_query( + $mysqli, + "SELECT * FROM users + LEFT JOIN user_roles ON user_role_id = role_id + WHERE (user_name LIKE '%$q%' OR user_email LIKE '%$q%') + AND user_type = 1 + AND $archive_query + ORDER BY user_name ASC" + ); + + $num_rows = mysqli_num_rows($sql); + + if ($num_rows > 0) { + + guardExportPdfRowCount($format, $num_rows); + + $export = beginExport('users', $format, "$session_company_name-Users", 'Users', summarizeExportFilters($filter_summary)); + + while ($row = mysqli_fetch_assoc($sql)) { $user_status = intval($row['user_status']); if ($user_status == 2) { - $user_status_display = "Invited"; + $row['user_status_display'] = "Invited"; } elseif ($user_status == 1) { - $user_status_display = "Active"; - } else{ - $user_status_display = "Disabled"; + $row['user_status_display'] = "Active"; + } else { + $row['user_status_display'] = "Disabled"; } - $lineData = array($row['user_name'], $row['user_email'], $row['role_name'], $user_status_display, $row['user_created_at']); - fputcsv($f, array_map('escapeCsvFormula', $lineData), $delimiter, $enclosure, $escape); + addExportRow($export, $row); } - //move back to beginning of file - fseek($f, 0); - - //set headers to download file rather than displayed - header('Content-Type: text/csv'); - header('Content-Disposition: attachment; filename="' . $filename . '";'); - - //output all remaining data on a file pointer - fpassthru($f); - - // Logging - logAudit("User", "Export", "$session_name exported $count user(s) to a CSV file"); + finishExport($export); } + + logAudit("User", "Export", "$session_name exported $num_rows user(s) to a " . strtoupper($format) . " file"); + exit; } diff --git a/admin/users.php b/admin/users.php index f96d1156..d29a050e 100644 --- a/admin/users.php +++ b/admin/users.php @@ -34,7 +34,7 @@ $num_rows = mysqli_fetch_row(mysqli_query($mysqli, "SELECT FOUND_ROWS()")); 1) { ?> + data-modal-url=""> Export diff --git a/agent/assets.php b/agent/assets.php index dd4d146d..32eb370c 100644 --- a/agent/assets.php +++ b/agent/assets.php @@ -225,7 +225,7 @@ $num_rows = mysqli_fetch_row(mysqli_query($mysqli, "SELECT FOUND_ROWS()")); 0) { ?> + data-modal-url=""> Export diff --git a/agent/certificates.php b/agent/certificates.php index 9bef2c8a..5b121986 100644 --- a/agent/certificates.php +++ b/agent/certificates.php @@ -85,7 +85,7 @@ $num_rows = mysqli_fetch_row(mysqli_query($mysqli, "SELECT FOUND_ROWS()")); diff --git a/agent/clients.php b/agent/clients.php index 6977ce9e..9c621dd7 100644 --- a/agent/clients.php +++ b/agent/clients.php @@ -98,7 +98,7 @@ $num_rows = mysqli_fetch_row(mysqli_query($mysqli, "SELECT FOUND_ROWS()")); + data-modal-url=" $dtf, 'dtt' => $dtt]) ?>"> Export diff --git a/agent/contacts.php b/agent/contacts.php index 484ffb88..e716fcf8 100644 --- a/agent/contacts.php +++ b/agent/contacts.php @@ -105,7 +105,7 @@ $num_rows = mysqli_fetch_row(mysqli_query($mysqli, "SELECT FOUND_ROWS()")); + data-modal-url=""> Export diff --git a/agent/credentials.php b/agent/credentials.php index 81079e97..cd59b4a6 100644 --- a/agent/credentials.php +++ b/agent/credentials.php @@ -120,7 +120,7 @@ $num_rows = mysqli_fetch_row(mysqli_query($mysqli, "SELECT FOUND_ROWS()")); 0) { ?> + data-modal-url=""> Export diff --git a/agent/domains.php b/agent/domains.php index 3c350932..3ab3d3bc 100644 --- a/agent/domains.php +++ b/agent/domains.php @@ -97,7 +97,7 @@ $num_rows = mysqli_fetch_row(mysqli_query($mysqli, "SELECT FOUND_ROWS()")); diff --git a/agent/expenses.php b/agent/expenses.php index 7cac0737..beb8bbac 100644 --- a/agent/expenses.php +++ b/agent/expenses.php @@ -69,7 +69,7 @@ $num_rows = mysqli_fetch_row(mysqli_query($mysqli, "SELECT FOUND_ROWS()")); diff --git a/agent/invoices.php b/agent/invoices.php index 42407b6a..7e5c7a51 100644 --- a/agent/invoices.php +++ b/agent/invoices.php @@ -171,7 +171,7 @@ $num_rows = mysqli_fetch_row(mysqli_query($mysqli, "SELECT FOUND_ROWS()")); diff --git a/agent/locations.php b/agent/locations.php index dd76fd1b..e041987a 100644 --- a/agent/locations.php +++ b/agent/locations.php @@ -91,7 +91,7 @@ $num_rows = mysqli_fetch_row(mysqli_query($mysqli, "SELECT FOUND_ROWS()")); 0) { ?> + data-modal-url=""> Export diff --git a/agent/modals/asset/asset_export.php b/agent/modals/asset/asset_export.php index f043e3d2..9cebfb7e 100644 --- a/agent/modals/asset/asset_export.php +++ b/agent/modals/asset/asset_export.php @@ -2,28 +2,187 @@ require_once '../../../includes/modal_header.php'; +enforceUserPermission('module_support'); + +// Pre-filled from the assets page's current filters. Everything here is editable - +// the export runs whatever this form posts, not whatever the page happened to show. $client_id = intval($_GET['client_id'] ?? 0); +if ($client_id) { + enforceClientAccess(); +} + +// Search Filter +$q_filter = $_GET['q'] ?? ''; + +// Type Filter +$type_filter = $_GET['type'] ?? ''; + +// Client Filter +$client_filter = intval($_GET['client'] ?? 0); + +// Location Filter +$location_filter = intval($_GET['location'] ?? 0); + +// Tags Filter +$tag_filter = (isset($_GET['tags']) && is_array($_GET['tags'])) ? array_map('intval', $_GET['tags']) : []; + +// Expiring In Filter +$expire_filter = $_GET['expire_days'] ?? ''; + +// Archived Filter +$archived_filter = (isset($_GET['archived']) && $_GET['archived'] == 1) ? 1 : 0; ob_start(); ?> + + +
diff --git a/agent/modals/asset/asset_interface_export.php b/agent/modals/asset/asset_interface_export.php index 4da21587..159bf5e4 100644 --- a/agent/modals/asset/asset_interface_export.php +++ b/agent/modals/asset/asset_interface_export.php @@ -2,7 +2,7 @@ @@ -73,46 +109,45 @@ ob_start();
- +
- +
- +
- +
+ + diff --git a/agent/modals/income/income_export.php b/agent/modals/income/income_export.php index 2cf2b3c5..8ef75c9a 100644 --- a/agent/modals/income/income_export.php +++ b/agent/modals/income/income_export.php @@ -53,17 +53,21 @@ ob_start(); ?> + +
diff --git a/agent/modals/invoice/invoice_export.php b/agent/modals/invoice/invoice_export.php index c465a7ee..2f4e0686 100644 --- a/agent/modals/invoice/invoice_export.php +++ b/agent/modals/invoice/invoice_export.php @@ -2,47 +2,121 @@ require_once '../../../includes/modal_header.php'; +enforceUserPermission('module_sales'); + +// Pre-filled from the invoices page's current filters. Everything here is editable - +// the export runs whatever this form posts, not whatever the page happened to show. $client_id = intval($_GET['client_id'] ?? 0); +if ($client_id) { + enforceClientAccess(); +} + +// Search Filter +$q_filter = $_GET['q'] ?? ''; + +// Status Filter +$status_filter = $_GET['status'] ?? ''; + +// Category Filter +$category_filter = intval($_GET['category'] ?? 0); + +// Date Filter - the all-time sentinels from filter_header.php leave the fields blank +$date_from_filter = (!empty($_GET['dtf']) && $_GET['dtf'] !== '1970-01-01') ? escapeHtml($_GET['dtf']) : ''; +$date_to_filter = (!empty($_GET['dtt']) && $_GET['dtt'] !== '2099-12-31') ? escapeHtml($_GET['dtt']) : ''; ob_start(); ?> + + +
+
diff --git a/agent/modals/location/location_export.php b/agent/modals/location/location_export.php index 95e07d88..6b711ade 100644 --- a/agent/modals/location/location_export.php +++ b/agent/modals/location/location_export.php @@ -2,27 +2,121 @@ require_once '../../../includes/modal_header.php'; +enforceUserPermission('module_client'); + +// Pre-filled from the locations page's current filters. Everything here is editable - +// the export runs whatever this form posts, not whatever the page happened to show. $client_id = intval($_GET['client_id'] ?? 0); +if ($client_id) { + enforceClientAccess(); +} + +// Search Filter +$q_filter = $_GET['q'] ?? ''; + +// Client Filter +$client_filter = intval($_GET['client'] ?? 0); + +// Tags Filter +$tag_filter = (isset($_GET['tags']) && is_array($_GET['tags'])) ? array_map('intval', $_GET['tags']) : []; + +// Archived Filter +$archived_filter = (isset($_GET['archived']) && $_GET['archived'] == 1) ? 1 : 0; ob_start(); ?> + + +
+
diff --git a/agent/modals/network/network_export.php b/agent/modals/network/network_export.php index e50ba88f..074bffc3 100644 --- a/agent/modals/network/network_export.php +++ b/agent/modals/network/network_export.php @@ -2,27 +2,124 @@ require_once '../../../includes/modal_header.php'; +enforceUserPermission('module_support'); + +// Pre-filled from the networks page's current filters. Everything here is editable - +// the export runs whatever this form posts, not whatever the page happened to show. $client_id = intval($_GET['client_id'] ?? 0); +if ($client_id) { + enforceClientAccess(); +} + +// Search Filter +$q_filter = $_GET['q'] ?? ''; + +// Client Filter +$client_filter = intval($_GET['client'] ?? 0); + +// Location Filter +$location_filter = intval($_GET['location'] ?? 0); + +// Archived Filter +$archived_filter = (isset($_GET['archived']) && $_GET['archived'] == 1) ? 1 : 0; ob_start(); ?> + + +
+
diff --git a/agent/modals/product/product_export.php b/agent/modals/product/product_export.php index ad8dfe58..3b4d68bb 100644 --- a/agent/modals/product/product_export.php +++ b/agent/modals/product/product_export.php @@ -2,24 +2,111 @@ require_once '../../../includes/modal_header.php'; +enforceUserPermission('module_sales'); + +// Pre-filled from the products page's current filters. Everything here is editable - +// the export runs whatever this form posts, not whatever the page happened to show. +$client_id = intval($_GET['client_id'] ?? 0); +if ($client_id) { + enforceClientAccess(); +} + +// Search Filter +$q_filter = $_GET['q'] ?? ''; + +// Type Filter +$type_filter = $_GET['type'] ?? ''; + +// Category Filter +$category_filter = intval($_GET['category'] ?? 0); + +// Archived Filter +$archived_filter = (isset($_GET['archived']) && $_GET['archived'] == 1) ? 1 : 0; + ob_start(); ?> + + +
+
diff --git a/agent/modals/quote/quote_export.php b/agent/modals/quote/quote_export.php index daec4dc0..9641aa25 100644 --- a/agent/modals/quote/quote_export.php +++ b/agent/modals/quote/quote_export.php @@ -2,28 +2,78 @@ require_once '../../../includes/modal_header.php'; +enforceUserPermission('module_sales'); + +// Pre-filled from the quotes page's current filters. Everything here is editable - +// the export runs whatever this form posts, not whatever the page happened to show. $client_id = intval($_GET['client_id'] ?? 0); +if ($client_id) { + enforceClientAccess(); +} + +// Search Filter +$q_filter = $_GET['q'] ?? ''; + +// Date Filter - the all-time sentinels from filter_header.php leave the fields blank +$date_from_filter = (!empty($_GET['dtf']) && $_GET['dtf'] !== '1970-01-01') ? escapeHtml($_GET['dtf']) : ''; +$date_to_filter = (!empty($_GET['dtt']) && $_GET['dtt'] !== '2099-12-31') ? escapeHtml($_GET['dtt']) : ''; ob_start(); ?> + + +
diff --git a/agent/modals/recurring_invoice/recurring_invoice_export.php b/agent/modals/recurring_invoice/recurring_invoice_export.php index 444b3660..d986ef39 100644 --- a/agent/modals/recurring_invoice/recurring_invoice_export.php +++ b/agent/modals/recurring_invoice/recurring_invoice_export.php @@ -1,23 +1,98 @@ -