mirror of
https://github.com/itflow-org/itflow
synced 2026-03-11 08:14:52 +00:00
Compare commits
34 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
ff80a3db3f | ||
|
|
c7d00d7b0d | ||
|
|
1c6e74b08e | ||
|
|
f8d054f8aa | ||
|
|
e0dfaf2d22 | ||
|
|
757a62c35b | ||
|
|
52a62fc23c | ||
|
|
ad9e4b4fb4 | ||
|
|
4fdd5ae769 | ||
|
|
9f2b9e3b3e | ||
|
|
2c074e9dc4 | ||
|
|
0fad31d683 | ||
|
|
b154930a4c | ||
|
|
359b04e7d1 | ||
|
|
cc00e3bf75 | ||
|
|
0454685039 | ||
|
|
b5eb325c5e | ||
|
|
ed6276a3e4 | ||
|
|
5da1310e34 | ||
|
|
a69b09c9e6 | ||
|
|
8da3bb15e9 | ||
|
|
8488445bf4 | ||
|
|
546d21adac | ||
|
|
580f50b187 | ||
|
|
4744276f2a | ||
|
|
6106b8aebb | ||
|
|
dd2b203321 | ||
|
|
7994c9c7a8 | ||
|
|
ae59aa3326 | ||
|
|
0ab9a1c97d | ||
|
|
2908568e2a | ||
|
|
2b673a1b6c | ||
|
|
bece8abfe2 | ||
|
|
ac2b355399 |
67
CHANGELOG.md
67
CHANGELOG.md
@@ -2,6 +2,39 @@
|
|||||||
|
|
||||||
This file documents all notable changes made to ITFlow.
|
This file documents all notable changes made to ITFlow.
|
||||||
|
|
||||||
|
## [25.02.4]
|
||||||
|
|
||||||
|
### Fixed
|
||||||
|
- Resolved issue preventing the addition or editing of licenses when no vendor was selected.
|
||||||
|
- Fixed several undeclared variables in AJAX contact details.
|
||||||
|
- Corrected the contact ticket count display.
|
||||||
|
- Addressed an issue where clicking "More Details" in AJAX contact/asset details failed to include the `client_id` in the URL.
|
||||||
|
- Fixed an issue with recurring invoices in the client URL: clicking "Inactive" or "Active" would unexpectedly navigate away from the client section.
|
||||||
|
- Added new php function getFieldById() to return a record using just an id and sanitized as well.
|
||||||
|
|
||||||
|
## [25.02.3]
|
||||||
|
|
||||||
|
### Fixed
|
||||||
|
- Fixed notifications being reversed as dismissed notifications.
|
||||||
|
|
||||||
|
## [25.02.2]
|
||||||
|
|
||||||
|
### Fixed
|
||||||
|
- Corrected some edit modals not showing notes correctly.
|
||||||
|
- Bugfix: When exporting to CSV, the first asset wasn't being shown.
|
||||||
|
- Fix broken create / edit credentials.
|
||||||
|
- Fixed missing Notificatons link.
|
||||||
|
- Fixed a few dead links.
|
||||||
|
- Fixed Overdue count also counting Non-Billable Invoices.
|
||||||
|
- Fix Edit Client Notes.
|
||||||
|
|
||||||
|
### Added / Changed
|
||||||
|
- Implemented SSL certificate history tracking.
|
||||||
|
- Added Inactive / Active Filter to Recurring Invoices.
|
||||||
|
- Merged Dismissed notifications and notification in one.
|
||||||
|
- Added Link Button to addd / edit Document WYSIWYG.
|
||||||
|
- Added Physical location to the asset export / import.
|
||||||
|
|
||||||
## [25.02.1]
|
## [25.02.1]
|
||||||
### Fixed
|
### Fixed
|
||||||
- Resolved broken links in the client overview, project and client listings, and rack details.
|
- Resolved broken links in the client overview, project and client listings, and rack details.
|
||||||
@@ -24,33 +57,33 @@ This file documents all notable changes made to ITFlow.
|
|||||||
- Added a Vendor Quick Details Modal.
|
- Added a Vendor Quick Details Modal.
|
||||||
- Enabled vendor linking and added a License Purchase Reference in the Software Licenses section.
|
- Enabled vendor linking and added a License Purchase Reference in the Software Licenses section.
|
||||||
- Added download original, optimized and thumbnail option for images.
|
- Added download original, optimized and thumbnail option for images.
|
||||||
- Added Paid status to the top corner of Invoice PDFs
|
- Added Paid status to the top corner of Invoice PDFs.
|
||||||
|
|
||||||
## [25.02]
|
## [25.02]
|
||||||
### Fixed
|
### Fixed
|
||||||
- Migrated several reports to the new permissions/roles system
|
- Migrated several reports to the new permissions/roles system.
|
||||||
- Resolved issue with empty task box showing for closed/resolved tickets
|
- Resolved issue with empty task box showing for closed/resolved tickets.
|
||||||
- Corrected ticket priority sorting
|
- Corrected ticket priority sorting.
|
||||||
- Cloned asset interfaces when transferring assets between clients
|
- Cloned asset interfaces when transferring assets between clients.
|
||||||
|
|
||||||
### Added / Changed
|
### Added / Changed
|
||||||
- Restored max number of records per page option back to 500 since we dont have repeating modals.
|
- Restored max number of records per page option back to 500 since we dont have repeating modals.
|
||||||
- Bulk Categorize Tickets feature
|
- Bulk Categorize Tickets feature.
|
||||||
- Renamed "Interface port" to "Interface Description." "Interface Name" should now refer to port name and/or number
|
- Renamed "Interface port" to "Interface Description." "Interface Name" should now refer to port name and/or number.
|
||||||
- Changed "Transfer Asset to Client" from a single action to a bulk action
|
- Changed "Transfer Asset to Client" from a single action to a bulk action.
|
||||||
- Updated Filter Footer UI to show "Showing x to x of x records" instead of just the total records
|
- Updated Filter Footer UI to show "Showing x to x of x records" instead of just the total records.
|
||||||
- Added Client Overview section to view client assets, contacts, licenses, credentials, etc.
|
- Added Client Overview section to view client assets, contacts, licenses, credentials, etc.
|
||||||
- Introduced Quick Peek for asset details, contact information, and document viewing throughout the ITFlow App, all made possible by AJAX
|
- Introduced Quick Peek for asset details, contact information, and document viewing throughout the ITFlow App, all made possible by AJAX.
|
||||||
- Enabled Simple Drag-and-Drop Ordering for Invoices, Recurring Invoices, Quotes, Ticket Tasks, and Ticket Template Tasks
|
- Enabled Simple Drag-and-Drop Ordering for Invoices, Recurring Invoices, Quotes, Ticket Tasks, and Ticket Template Tasks.
|
||||||
- Added new Ticket View options: Kanban and Simple View
|
- Added new Ticket View options: Kanban and Simple View.
|
||||||
- Migrated all repeating modals to the new AJAX modal function for faster loading times and quicker development
|
- Migrated all repeating modals to the new AJAX modal function for faster loading times and quicker development.
|
||||||
- Allowed clients to upload PDF documents to accepted quotes
|
- Allowed clients to upload PDF documents to accepted quotes.
|
||||||
- Client Portal now shows ticket category
|
- Client Portal now shows ticket category.
|
||||||
- Custom links can now be added to the Client Portal navbar
|
- Custom links can now be added to the Client Portal navbar.
|
||||||
- Lots of little tweaks to UI, performance, bugs, etc.
|
- Lots of little tweaks to UI, performance, bugs, etc.
|
||||||
|
|
||||||
### Breaking Changes
|
### Breaking Changes
|
||||||
- Cron scripts have officially been moved to the /scripts folder and are no longer in the root directory; they must be updated to function properly
|
- Cron scripts have officially been moved to the /scripts folder and are no longer in the root directory; they must be updated to function properly.
|
||||||
|
|
||||||
## [25.01.3]
|
## [25.01.3]
|
||||||
### Fixed
|
### Fixed
|
||||||
|
|||||||
@@ -848,7 +848,7 @@ ob_start();
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="modal-footer bg-white">
|
<div class="modal-footer bg-white">
|
||||||
<a href="asset_details.php?<?php echo $client_url; ?>asset_id=<?php echo $asset_id; ?>" class="btn btn-primary text-bold"><span class="text-white"><i class="fas fa-info-circle mr-2"></i>More Details</span></a>
|
<a href="asset_details.php?client_id=<?php echo $client_id; ?>&asset_id=<?php echo $asset_id; ?>" class="btn btn-primary text-bold"><span class="text-white"><i class="fas fa-info-circle mr-2"></i>More Details</span></a>
|
||||||
<a href="#" class="btn btn-secondary"
|
<a href="#" class="btn btn-secondary"
|
||||||
data-toggle="ajax-modal" data-ajax-url="ajax/ajax_asset_edit.php" data-ajax-id="<?php echo $asset_id; ?>">
|
data-toggle="ajax-modal" data-ajax-url="ajax/ajax_asset_edit.php" data-ajax-id="<?php echo $asset_id; ?>">
|
||||||
<span class="text-white"><i class="fas fa-edit mr-2"></i>Edit</span>
|
<span class="text-white"><i class="fas fa-edit mr-2"></i>Edit</span>
|
||||||
|
|||||||
@@ -13,10 +13,13 @@ $certificate_domain = nullable_htmlentities($row['certificate_domain']);
|
|||||||
$certificate_domain_id = intval($row['certificate_domain_id']);
|
$certificate_domain_id = intval($row['certificate_domain_id']);
|
||||||
$certificate_issued_by = nullable_htmlentities($row['certificate_issued_by']);
|
$certificate_issued_by = nullable_htmlentities($row['certificate_issued_by']);
|
||||||
$certificate_public_key = nullable_htmlentities($row['certificate_public_key']);
|
$certificate_public_key = nullable_htmlentities($row['certificate_public_key']);
|
||||||
|
$certificate_notes = nullable_htmlentities($row['certificate_notes']);
|
||||||
$certificate_expire = nullable_htmlentities($row['certificate_expire']);
|
$certificate_expire = nullable_htmlentities($row['certificate_expire']);
|
||||||
$certificate_created_at = nullable_htmlentities($row['certificate_created_at']);
|
$certificate_created_at = nullable_htmlentities($row['certificate_created_at']);
|
||||||
$client_id = intval($row['certificate_client_id']);
|
$client_id = intval($row['certificate_client_id']);
|
||||||
|
|
||||||
|
$history_sql = mysqli_query($mysqli, "SELECT * FROM certificate_history WHERE certificate_history_certificate_id = $certificate_id");
|
||||||
|
|
||||||
// Generate the HTML form content using output buffering.
|
// Generate the HTML form content using output buffering.
|
||||||
ob_start();
|
ob_start();
|
||||||
?>
|
?>
|
||||||
@@ -42,6 +45,9 @@ ob_start();
|
|||||||
<li class="nav-item">
|
<li class="nav-item">
|
||||||
<a class="nav-link" data-toggle="pill" href="#pillsEditNotes<?php echo $certificate_id; ?>">Notes</a>
|
<a class="nav-link" data-toggle="pill" href="#pillsEditNotes<?php echo $certificate_id; ?>">Notes</a>
|
||||||
</li>
|
</li>
|
||||||
|
<li class="nav-item">
|
||||||
|
<a class="nav-link" data-toggle="pill" href="#pillsEditHistory<?php echo $certificate_id; ?>">History</a>
|
||||||
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
|
|
||||||
<hr>
|
<hr>
|
||||||
@@ -141,11 +147,40 @@ ob_start();
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="tab-pane fade" id="pillsEditNotes<?php echo $certificate_id; ?>">
|
<div class="tab-pane fade" id="pillsEditNotes<?php echo $certificate_id; ?>">
|
||||||
|
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<textarea class="form-control" name="notes" rows="12" placeholder="Enter some notes"><?php echo $certificate_notes; ?></textarea>
|
<textarea class="form-control" name="notes" rows="12" placeholder="Enter some notes"><?php echo $certificate_notes; ?></textarea>
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="tab-pane fade" id="pillsEditHistory<?php echo $certificate_id; ?>">
|
||||||
|
<div class="table-responsive">
|
||||||
|
<table class='table table-sm table-striped border table-hover'>
|
||||||
|
<thead class='thead-dark'>
|
||||||
|
<tr>
|
||||||
|
<th>Date</th>
|
||||||
|
<th>Field</th>
|
||||||
|
<th>Before</th>
|
||||||
|
<th>After</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
<?php
|
||||||
|
while ($row = mysqli_fetch_array($history_sql)) {
|
||||||
|
$certificate_modified_at = nullable_htmlentities($row['certificate_history_modified_at']);
|
||||||
|
$certificate_field = nullable_htmlentities($row['certificate_history_column']);
|
||||||
|
$certificate_before_value = nullable_htmlentities($row['certificate_history_old_value']);
|
||||||
|
$certificate_after_value = nullable_htmlentities($row['certificate_history_new_value']);
|
||||||
|
?>
|
||||||
|
<tr>
|
||||||
|
<td><?php echo $certificate_modified_at; ?></td>
|
||||||
|
<td><?php echo $certificate_field; ?></td>
|
||||||
|
<td><?php echo $certificate_before_value; ?></td>
|
||||||
|
<td><?php echo $certificate_after_value; ?></td>
|
||||||
|
</tr>
|
||||||
|
<?php } ?>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -251,9 +251,7 @@ ob_start();
|
|||||||
<div class="tab-pane fade" id="pills-client-notes<?php echo $client_id; ?>">
|
<div class="tab-pane fade" id="pills-client-notes<?php echo $client_id; ?>">
|
||||||
|
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<textarea class="form-control" rows="10" placeholder="Enter some notes"
|
<textarea class="form-control" rows="10" placeholder="Enter some notes" name="notes"><?php echo $client_notes; ?></textarea>
|
||||||
name="notes"><?php echo $client_notes; ?>
|
|
||||||
</textarea>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ $sql = mysqli_query($mysqli, "SELECT * FROM contacts
|
|||||||
LEFT JOIN locations ON location_id = contact_location_id
|
LEFT JOIN locations ON location_id = contact_location_id
|
||||||
LEFT JOIN users ON user_id = contact_user_id
|
LEFT JOIN users ON user_id = contact_user_id
|
||||||
WHERE contact_id = $contact_id
|
WHERE contact_id = $contact_id
|
||||||
$client_query
|
LIMIT 1
|
||||||
");
|
");
|
||||||
|
|
||||||
$row = mysqli_fetch_array($sql);
|
$row = mysqli_fetch_array($sql);
|
||||||
@@ -114,7 +114,7 @@ $sql_linked_services = mysqli_query($mysqli, "SELECT * FROM service_contacts, se
|
|||||||
AND service_contacts.service_id = services.service_id
|
AND service_contacts.service_id = services.service_id
|
||||||
ORDER BY service_name ASC"
|
ORDER BY service_name ASC"
|
||||||
);
|
);
|
||||||
$service_count = mysqli_num_rows($sql_linked_services);
|
$services_count = mysqli_num_rows($sql_linked_services);
|
||||||
|
|
||||||
$linked_services = array();
|
$linked_services = array();
|
||||||
|
|
||||||
@@ -846,7 +846,7 @@ ob_start();
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="modal-footer bg-white">
|
<div class="modal-footer bg-white">
|
||||||
<a href="contact_details.php?<?php echo $client_url; ?>contact_id=<?php echo $contact_id; ?>" class="btn btn-primary text-bold">
|
<a href="contact_details.php?client_id=<?php echo $client_id; ?>&contact_id=<?php echo $contact_id; ?>" class="btn btn-primary text-bold">
|
||||||
<span class="text-white"><i class="fas fa-info-circle mr-2"></i>More Details</span>
|
<span class="text-white"><i class="fas fa-info-circle mr-2"></i>More Details</span>
|
||||||
</a>
|
</a>
|
||||||
<a href="#" class="btn btn-secondary"
|
<a href="#" class="btn btn-secondary"
|
||||||
|
|||||||
@@ -66,13 +66,17 @@ ob_start();
|
|||||||
</div>
|
</div>
|
||||||
<div class="modal-footer bg-white justify-content-end">
|
<div class="modal-footer bg-white justify-content-end">
|
||||||
<?php if ($num_notifications) { ?>
|
<?php if ($num_notifications) { ?>
|
||||||
|
|
||||||
<a href="post.php?dismiss_all_notifications&csrf_token=<?php echo $_SESSION[
|
<a href="post.php?dismiss_all_notifications&csrf_token=<?php echo $_SESSION[
|
||||||
"csrf_token"
|
"csrf_token"
|
||||||
]; ?>" class="btn btn-primary">
|
]; ?>" class="btn btn-primary">
|
||||||
<span class="text-white text-bold"><i class="fas fa-check mr-2"></i>Dismiss all</span>
|
<span class="text-white text-bold"><i class="fas fa-check mr-2"></i>Dismiss all</span>
|
||||||
</a>
|
</a>
|
||||||
|
<a href="notifications.php" class="btn btn-secondary">
|
||||||
|
<span class="text-white">See all Notifications</span>
|
||||||
|
</a>
|
||||||
<?php } else { ?>
|
<?php } else { ?>
|
||||||
<a href="notifications_dismissed.php" class="btn btn-dark">
|
<a href="notifications.php?dismissed" class="btn btn-dark">
|
||||||
<span class="text-white text-bold">See Dismissed Notifications</span>
|
<span class="text-white text-bold">See Dismissed Notifications</span>
|
||||||
</a>
|
</a>
|
||||||
<?php } ?>
|
<?php } ?>
|
||||||
|
|||||||
@@ -385,7 +385,7 @@ $num_rows = mysqli_fetch_row(mysqli_query($mysqli, "SELECT FOUND_ROWS()"));
|
|||||||
if ($ticket_count) {
|
if ($ticket_count) {
|
||||||
$ticket_count_display = "<span class='mr-2 badge badge-pill badge-secondary p-2' title='$ticket_count Tickets'><i class='fas fa-fw fa-life-ring mr-2'></i>$ticket_count</span>";
|
$ticket_count_display = "<span class='mr-2 badge badge-pill badge-secondary p-2' title='$ticket_count Tickets'><i class='fas fa-fw fa-life-ring mr-2'></i>$ticket_count</span>";
|
||||||
} else {
|
} else {
|
||||||
$software_count_display = '';
|
$ticket_count_display = '';
|
||||||
}
|
}
|
||||||
|
|
||||||
// Related Documents Query
|
// Related Documents Query
|
||||||
|
|||||||
@@ -17,117 +17,6 @@ if (LATEST_DATABASE_VERSION > CURRENT_DATABASE_VERSION) {
|
|||||||
|
|
||||||
// We need updates!
|
// We need updates!
|
||||||
|
|
||||||
if (CURRENT_DATABASE_VERSION == '0.1.0') {
|
|
||||||
// Insert queries here required to update to DB version 0.1.1
|
|
||||||
// Logs don't get archived
|
|
||||||
mysqli_query($mysqli, "ALTER TABLE `logs` DROP `log_archived_at`");
|
|
||||||
|
|
||||||
// Assets will eventualy have file associatons which could include a receipt.
|
|
||||||
mysqli_query($mysqli, "ALTER TABLE `assets` DROP `asset_reciept`");
|
|
||||||
|
|
||||||
mysqli_query($mysqli, "ALTER TABLE `campaign_messages` DROP `message_updated_at`");
|
|
||||||
// This will be a seperate table eventually called contact_documents because contact can have several documents
|
|
||||||
mysqli_query($mysqli, "ALTER TABLE `documents` DROP `document_contact_id`");
|
|
||||||
|
|
||||||
mysqli_query($mysqli, "ALTER TABLE `expenses` DROP `expense_asset_id`");
|
|
||||||
mysqli_query($mysqli, "ALTER TABLE `files` DROP `file_contact_id`");
|
|
||||||
mysqli_query($mysqli, "ALTER TABLE `history` DROP `history_archived_at`");
|
|
||||||
|
|
||||||
// Then, update the database to the next sequential version
|
|
||||||
mysqli_query($mysqli, "UPDATE `settings` SET `config_current_database_version` = '0.1.1'");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (CURRENT_DATABASE_VERSION == '0.1.1') {
|
|
||||||
// Insert queries here required to update to DB version 0.1.2
|
|
||||||
// Create Many to Many Relationship tables for Assets, Contacts, Software and Vendors
|
|
||||||
|
|
||||||
mysqli_query($mysqli, "CREATE TABLE `asset_documents` (`asset_id` int(11) NOT NULL,`document_id` int(11) NOT NULL, PRIMARY KEY (`asset_id`,`document_id`))");
|
|
||||||
mysqli_query($mysqli, "CREATE TABLE `asset_logins` (`asset_id` int(11) NOT NULL,`login_id` int(11) NOT NULL, PRIMARY KEY (`asset_id`,`login_id`))");
|
|
||||||
mysqli_query($mysqli, "CREATE TABLE `asset_files` (`asset_id` int(11) NOT NULL,`file_id` int(11) NOT NULL, PRIMARY KEY (`asset_id`,`file_id`))");
|
|
||||||
|
|
||||||
mysqli_query($mysqli, "CREATE TABLE `contact_documents` (`contact_id` int(11) NOT NULL,`document_id` int(11) NOT NULL, PRIMARY KEY (`contact_id`,`document_id`))");
|
|
||||||
mysqli_query($mysqli, "CREATE TABLE `contact_logins` (`contact_id` int(11) NOT NULL,`login_id` int(11) NOT NULL, PRIMARY KEY (`contact_id`,`login_id`))");
|
|
||||||
mysqli_query($mysqli, "CREATE TABLE `contact_files` (`contact_id` int(11) NOT NULL,`file_id` int(11) NOT NULL, PRIMARY KEY (`contact_id`,`file_id`))");
|
|
||||||
|
|
||||||
mysqli_query($mysqli, "CREATE TABLE `software_documents` (`software_id` int(11) NOT NULL,`document_id` int(11) NOT NULL, PRIMARY KEY (`software_id`,`document_id`))");
|
|
||||||
mysqli_query($mysqli, "CREATE TABLE `software_logins` (`software_id` int(11) NOT NULL,`login_id` int(11) NOT NULL, PRIMARY KEY (`software_id`,`login_id`))");
|
|
||||||
mysqli_query($mysqli, "CREATE TABLE `software_files` (`software_id` int(11) NOT NULL,`file_id` int(11) NOT NULL, PRIMARY KEY (`software_id`,`file_id`))");
|
|
||||||
|
|
||||||
mysqli_query($mysqli, "CREATE TABLE `vendor_documents` (`vendor_id` int(11) NOT NULL,`document_id` int(11) NOT NULL, PRIMARY KEY (`vendor_id`,`document_id`))");
|
|
||||||
mysqli_query($mysqli, "CREATE TABLE `vendor_logins` (`vendor_id` int(11) NOT NULL,`login_id` int(11) NOT NULL, PRIMARY KEY (`vendor_id`,`login_id`))");
|
|
||||||
mysqli_query($mysqli, "CREATE TABLE `vendor_files` (`vendor_id` int(11) NOT NULL,`file_id` int(11) NOT NULL, PRIMARY KEY (`vendor_id`,`file_id`))");
|
|
||||||
|
|
||||||
// Then, update the database to the next sequential version
|
|
||||||
mysqli_query($mysqli, "UPDATE `settings` SET `config_current_database_version` = '0.1.2'");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (CURRENT_DATABASE_VERSION == '0.1.2') {
|
|
||||||
// Insert queries here required to update to DB version 0.1.3
|
|
||||||
mysqli_query($mysqli, "ALTER TABLE `logs` ADD `log_entity_id` INT NOT NULL DEFAULT '0' AFTER `log_user_id`");
|
|
||||||
|
|
||||||
// Then, update the database to the next sequential version
|
|
||||||
mysqli_query($mysqli, "UPDATE `settings` SET `config_current_database_version` = '0.1.3'");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (CURRENT_DATABASE_VERSION == '0.1.3') {
|
|
||||||
// Insert queries here required to update to DB version 0.1.4
|
|
||||||
mysqli_query($mysqli, "ALTER TABLE assets ADD asset_status VARCHAR(200) NULL AFTER asset_mac");
|
|
||||||
|
|
||||||
///Then, update the database to the next sequential version
|
|
||||||
mysqli_query($mysqli, "UPDATE `settings` SET `config_current_database_version` = '0.1.4'");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (CURRENT_DATABASE_VERSION == '0.1.4') {
|
|
||||||
// Insert queries here required to update to DB version 0.1.5
|
|
||||||
mysqli_query($mysqli, "ALTER TABLE `domains` ADD `domain_txt` TEXT NULL DEFAULT NULL AFTER `domain_mail_servers`");
|
|
||||||
|
|
||||||
// Then, update the database to the next sequential version
|
|
||||||
mysqli_query($mysqli, "UPDATE `settings` SET `config_current_database_version` = '0.1.5'");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (CURRENT_DATABASE_VERSION == '0.1.5') {
|
|
||||||
// Insert queries here required to update to DB version 0.1.6
|
|
||||||
// Remove Mailing List Tables
|
|
||||||
mysqli_query($mysqli, "DROP TABLE campaigns");
|
|
||||||
mysqli_query($mysqli, "DROP TABLE campaign_messages");
|
|
||||||
|
|
||||||
// Then, update the database to the next sequential version
|
|
||||||
mysqli_query($mysqli, "UPDATE `settings` SET `config_current_database_version` = '0.1.6'");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (CURRENT_DATABASE_VERSION == '0.1.6') {
|
|
||||||
// Insert queries here required to update to DB version 0.1.7
|
|
||||||
//Remove custom links
|
|
||||||
mysqli_query($mysqli, "DROP TABLE custom_links");
|
|
||||||
// Then, update the database to the next sequential version
|
|
||||||
mysqli_query($mysqli, "UPDATE `settings` SET `config_current_database_version` = '0.1.7'");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (CURRENT_DATABASE_VERSION == '0.1.7') {
|
|
||||||
// Insert queries here required to update to DB version 0.1.8
|
|
||||||
mysqli_query($mysqli, "ALTER TABLE `settings` DROP `config_backup_enable`");
|
|
||||||
mysqli_query($mysqli, "ALTER TABLE `settings` DROP `config_backup_path`");
|
|
||||||
|
|
||||||
// Then, update the database to the next sequential version
|
|
||||||
mysqli_query($mysqli, "UPDATE `settings` SET `config_current_database_version` = '0.1.8'");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (CURRENT_DATABASE_VERSION == '0.1.8') {
|
|
||||||
// Insert queries here required to update to DB version 0.1.9
|
|
||||||
mysqli_query($mysqli, "ALTER TABLE `settings` DROP `config_base_url`");
|
|
||||||
// Then, update the database to the next sequential version
|
|
||||||
mysqli_query($mysqli, "UPDATE `settings` SET `config_current_database_version` = '0.1.9'");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (CURRENT_DATABASE_VERSION == '0.1.9') {
|
|
||||||
// Insert queries here required to update to DB version 0.2.0
|
|
||||||
// Allow contacts to reset their portal password
|
|
||||||
mysqli_query($mysqli, "ALTER TABLE contacts ADD contact_password_reset_token VARCHAR(200) NULL DEFAULT NULL AFTER contact_password_hash");
|
|
||||||
|
|
||||||
// Then, update the database to the next sequential version
|
|
||||||
mysqli_query($mysqli, "UPDATE `settings` SET `config_current_database_version` = '0.2.0'");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (CURRENT_DATABASE_VERSION == '0.2.0') {
|
if (CURRENT_DATABASE_VERSION == '0.2.0') {
|
||||||
//Insert queries here required to update to DB version 0.2.1
|
//Insert queries here required to update to DB version 0.2.1
|
||||||
|
|
||||||
@@ -2520,10 +2409,24 @@ if (LATEST_DATABASE_VERSION > CURRENT_DATABASE_VERSION) {
|
|||||||
mysqli_query($mysqli, "UPDATE `settings` SET `config_current_database_version` = '1.8.6'");
|
mysqli_query($mysqli, "UPDATE `settings` SET `config_current_database_version` = '1.8.6'");
|
||||||
}
|
}
|
||||||
|
|
||||||
// if (CURRENT_DATABASE_VERSION == '1.8.6') {
|
if (CURRENT_DATABASE_VERSION == '1.8.6') {
|
||||||
// // Insert queries here required to update to DB version 1.8.7
|
mysqli_query($mysqli, "
|
||||||
|
CREATE TABLE `certificate_history` (`certificate_history_id` INT(11) NOT NULL AUTO_INCREMENT,
|
||||||
|
`certificate_history_column` VARCHAR(200) NOT NULL,
|
||||||
|
`certificate_history_old_value` TEXT NOT NULL,
|
||||||
|
`certificate_history_new_value` TEXT NOT NULL,
|
||||||
|
`certificate_history_certificate_id` INT(11) NOT NULL,
|
||||||
|
`certificate_history_modified_at` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||||
|
PRIMARY KEY (`certificate_history_id`)) ENGINE = InnoDB CHARSET=utf8mb4 COLLATE utf8mb4_unicode_ci;
|
||||||
|
");
|
||||||
|
|
||||||
|
mysqli_query($mysqli, "UPDATE `settings` SET `config_current_database_version` = '1.8.7'");
|
||||||
|
}
|
||||||
|
|
||||||
|
// if (CURRENT_DATABASE_VERSION == '1.8.7') {
|
||||||
|
// // Insert queries here required to update to DB version 1.8.8
|
||||||
// // Then, update the database to the next sequential version
|
// // Then, update the database to the next sequential version
|
||||||
// mysqli_query($mysqli, "UPDATE `settings` SET `config_current_database_version` = '1.8.7'");
|
// mysqli_query($mysqli, "UPDATE `settings` SET `config_current_database_version` = '1.8.8'");
|
||||||
// }
|
// }
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
18
db.sql
18
db.sql
@@ -321,6 +321,24 @@ CREATE TABLE `categories` (
|
|||||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci;
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci;
|
||||||
/*!40101 SET character_set_client = @saved_cs_client */;
|
/*!40101 SET character_set_client = @saved_cs_client */;
|
||||||
|
|
||||||
|
--
|
||||||
|
-- Table structure for table `certificate_history`
|
||||||
|
--
|
||||||
|
|
||||||
|
DROP TABLE IF EXISTS `certificate_history`;
|
||||||
|
/*!40101 SET @saved_cs_client = @@character_set_client */;
|
||||||
|
/*!40101 SET character_set_client = utf8 */;
|
||||||
|
CREATE TABLE `certificate_history` (
|
||||||
|
`certificate_history_id` int(11) NOT NULL AUTO_INCREMENT,
|
||||||
|
`certificate_history_column` varchar(200) NOT NULL,
|
||||||
|
`certificate_history_old_value` text NOT NULL,
|
||||||
|
`certificate_history_new_value` text NOT NULL,
|
||||||
|
`certificate_history_certificate_id` int(11) NOT NULL,
|
||||||
|
`certificate_history_modified_at` datetime NOT NULL DEFAULT current_timestamp(),
|
||||||
|
PRIMARY KEY (`certificate_history_id`)
|
||||||
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
||||||
|
/*!40101 SET character_set_client = @saved_cs_client */;
|
||||||
|
|
||||||
--
|
--
|
||||||
-- Table structure for table `certificates`
|
-- Table structure for table `certificates`
|
||||||
--
|
--
|
||||||
|
|||||||
@@ -1414,3 +1414,90 @@ function logAuth($status, $details) {
|
|||||||
function getFallback($data) {
|
function getFallback($data) {
|
||||||
return !empty($data) ? $data : '<span class="text-muted">N/A</span>';
|
return !empty($data) ? $data : '<span class="text-muted">N/A</span>';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieves a specified field's value from a table based on the record's id.
|
||||||
|
* It validates the table and field names, automatically determines the primary key (or uses the first column as fallback),
|
||||||
|
* and returns the field value with an appropriate escaping method.
|
||||||
|
*
|
||||||
|
* @param string $table The name of the table.
|
||||||
|
* @param int $id The record's id.
|
||||||
|
* @param string $field The field (column) to retrieve.
|
||||||
|
* @param string $escape_method The escape method: 'sql' (default, auto-detects int), 'html', 'json', or 'int'.
|
||||||
|
*
|
||||||
|
* @return mixed The escaped field value, or null if not found or invalid input.
|
||||||
|
*/
|
||||||
|
function getFieldById($table, $id, $field, $escape_method = 'sql') {
|
||||||
|
global $mysqli; // Use the global MySQLi connection
|
||||||
|
|
||||||
|
// Validate table and field names to allow only letters, numbers, and underscores
|
||||||
|
if (!preg_match('/^[a-zA-Z0-9_]+$/', $table) || !preg_match('/^[a-zA-Z0-9_]+$/', $field)) {
|
||||||
|
return null; // Invalid table or field name
|
||||||
|
}
|
||||||
|
|
||||||
|
// Sanitize id as an integer
|
||||||
|
$id = (int)$id;
|
||||||
|
|
||||||
|
// Get the list of columns and their details from the table
|
||||||
|
$columns_result = mysqli_query($mysqli, "SHOW COLUMNS FROM `$table`");
|
||||||
|
if (!$columns_result || mysqli_num_rows($columns_result) == 0) {
|
||||||
|
return null; // Table not found or has no columns
|
||||||
|
}
|
||||||
|
|
||||||
|
// Build an associative array with column details
|
||||||
|
$columns = [];
|
||||||
|
while ($row = mysqli_fetch_assoc($columns_result)) {
|
||||||
|
$columns[$row['Field']] = [
|
||||||
|
'type' => $row['Type'],
|
||||||
|
'key' => $row['Key']
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
// Find the primary key field if available
|
||||||
|
$id_field = null;
|
||||||
|
foreach ($columns as $col => $details) {
|
||||||
|
if ($details['key'] === 'PRI') {
|
||||||
|
$id_field = $col;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Fallback: if no primary key is found, use the first column
|
||||||
|
if (!$id_field) {
|
||||||
|
reset($columns);
|
||||||
|
$id_field = key($columns);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Ensure the requested field exists; if not, default to the id field
|
||||||
|
if (!array_key_exists($field, $columns)) {
|
||||||
|
$field = $id_field;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Build and execute the query to fetch the specified field value
|
||||||
|
$query = "SELECT `$field` FROM `$table` WHERE `$id_field` = $id";
|
||||||
|
$sql = mysqli_query($mysqli, $query);
|
||||||
|
|
||||||
|
if ($sql && mysqli_num_rows($sql) > 0) {
|
||||||
|
$row = mysqli_fetch_assoc($sql);
|
||||||
|
$value = $row[$field];
|
||||||
|
|
||||||
|
// Apply the desired escaping method or auto-detect integer type if using SQL escaping
|
||||||
|
switch ($escape_method) {
|
||||||
|
case 'html':
|
||||||
|
return htmlspecialchars($value, ENT_QUOTES, 'UTF-8'); // Escape for HTML
|
||||||
|
case 'json':
|
||||||
|
return json_encode($value); // Escape for JSON
|
||||||
|
case 'int':
|
||||||
|
return (int)$value; // Explicitly cast value to integer
|
||||||
|
case 'sql':
|
||||||
|
default:
|
||||||
|
// Auto-detect if the field type is integer
|
||||||
|
if (stripos($columns[$field]['type'], 'int') !== false) {
|
||||||
|
return (int)$value;
|
||||||
|
} else {
|
||||||
|
return sanitizeInput($value); // Escape for SQL using a custom function
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return null; // Return null if no record was found
|
||||||
|
}
|
||||||
@@ -5,4 +5,4 @@
|
|||||||
* Update this file each time we merge develop into master. Format is YY.MM (add a .v if there is more than one release a month.
|
* Update this file each time we merge develop into master. Format is YY.MM (add a .v if there is more than one release a month.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
DEFINE("APP_VERSION", "25.02.1");
|
DEFINE("APP_VERSION", "25.02.4");
|
||||||
|
|||||||
@@ -202,7 +202,7 @@
|
|||||||
|
|
||||||
<?php
|
<?php
|
||||||
if ($num_domains > 0) { ?>
|
if ($num_domains > 0) { ?>
|
||||||
<span class="right badge <?php if ($num_domains_expiring > 0) { ?> badge-warning text-dark<?php } ?> <?php if ($num_domains_expired > 0) { ?> badge-danger <?php } ?> text-white"><?php echo $num_domains; ?></span>
|
<span class="right badge <?php if (isset($num_domains_expiring)) { ?> badge-warning text-dark<?php } ?> <?php if (isset($num_domains_expired)) { ?> badge-danger <?php } ?> text-white"><?php echo $num_domains; ?></span>
|
||||||
<?php } ?>
|
<?php } ?>
|
||||||
</p>
|
</p>
|
||||||
</a>
|
</a>
|
||||||
|
|||||||
@@ -5,4 +5,4 @@
|
|||||||
* It is used in conjunction with database_updates.php
|
* It is used in conjunction with database_updates.php
|
||||||
*/
|
*/
|
||||||
|
|
||||||
DEFINE("LATEST_DATABASE_VERSION", "1.8.6");
|
DEFINE("LATEST_DATABASE_VERSION", "1.8.7");
|
||||||
|
|||||||
@@ -33,7 +33,7 @@ $draft_count = $row['num'];
|
|||||||
$row = mysqli_fetch_assoc(mysqli_query($mysqli, "SELECT COUNT('invoice_id') AS num FROM invoices WHERE invoice_status = 'Cancelled' $client_query"));
|
$row = mysqli_fetch_assoc(mysqli_query($mysqli, "SELECT COUNT('invoice_id') AS num FROM invoices WHERE invoice_status = 'Cancelled' $client_query"));
|
||||||
$cancelled_count = $row['num'];
|
$cancelled_count = $row['num'];
|
||||||
|
|
||||||
$row = mysqli_fetch_assoc(mysqli_query($mysqli, "SELECT COUNT('invoice_id') AS num FROM invoices WHERE invoice_status NOT LIKE 'Draft' AND invoice_status NOT LIKE 'Paid' AND invoice_status NOT LIKE 'Cancelled' AND invoice_due < CURDATE() $client_query"));
|
$row = mysqli_fetch_assoc(mysqli_query($mysqli, "SELECT COUNT('invoice_id') AS num FROM invoices WHERE invoice_status NOT LIKE 'Draft' AND invoice_status NOT LIKE 'Paid' AND invoice_status NOT LIKE 'Cancelled' AND invoice_status NOT LIKE 'Non-Billable' AND invoice_due < CURDATE() $client_query"));
|
||||||
$overdue_count = $row['num'];
|
$overdue_count = $row['num'];
|
||||||
|
|
||||||
$sql_total_draft_amount = mysqli_query($mysqli, "SELECT SUM(invoice_amount) AS total_draft_amount FROM invoices WHERE invoice_status = 'Draft' $client_query");
|
$sql_total_draft_amount = mysqli_query($mysqli, "SELECT SUM(invoice_amount) AS total_draft_amount FROM invoices WHERE invoice_status = 'Draft' $client_query");
|
||||||
|
|||||||
16
js/app.js
16
js/app.js
@@ -28,6 +28,7 @@ tinymce.init({
|
|||||||
toolbar: [
|
toolbar: [
|
||||||
{ name: 'styles', items: [ 'styles' ] },
|
{ name: 'styles', items: [ 'styles' ] },
|
||||||
{ name: 'formatting', items: [ 'bold', 'italic', 'forecolor' ] },
|
{ name: 'formatting', items: [ 'bold', 'italic', 'forecolor' ] },
|
||||||
|
{ name: 'link', items: [ 'link'] },
|
||||||
{ name: 'lists', items: [ 'bullist', 'numlist' ] },
|
{ name: 'lists', items: [ 'bullist', 'numlist' ] },
|
||||||
{ name: 'alignment', items: [ 'alignleft', 'aligncenter', 'alignright', 'alignjustify' ] },
|
{ name: 'alignment', items: [ 'alignleft', 'aligncenter', 'alignright', 'alignjustify' ] },
|
||||||
{ name: 'indentation', items: [ 'outdent', 'indent' ] },
|
{ name: 'indentation', items: [ 'outdent', 'indent' ] },
|
||||||
@@ -59,6 +60,7 @@ tinymce.init({
|
|||||||
toolbar: [
|
toolbar: [
|
||||||
{ name: 'styles', items: [ 'styles' ] },
|
{ name: 'styles', items: [ 'styles' ] },
|
||||||
{ name: 'formatting', items: [ 'bold', 'italic', 'forecolor' ] },
|
{ name: 'formatting', items: [ 'bold', 'italic', 'forecolor' ] },
|
||||||
|
{ name: 'link', items: [ 'link'] },
|
||||||
{ name: 'lists', items: [ 'bullist', 'numlist' ] },
|
{ name: 'lists', items: [ 'bullist', 'numlist' ] },
|
||||||
{ name: 'alignment', items: [ 'alignleft', 'aligncenter', 'alignright', 'alignjustify' ] },
|
{ name: 'alignment', items: [ 'alignleft', 'aligncenter', 'alignright', 'alignjustify' ] },
|
||||||
{ name: 'indentation', items: [ 'outdent', 'indent' ] },
|
{ name: 'indentation', items: [ 'outdent', 'indent' ] },
|
||||||
@@ -275,20 +277,6 @@ tinymce.init({
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
// Initialize TinyMCE
|
|
||||||
tinymce.init({
|
|
||||||
selector: '.tinymcePreview',
|
|
||||||
resize: false,
|
|
||||||
promotion: false,
|
|
||||||
branding: false,
|
|
||||||
menubar: false,
|
|
||||||
toolbar: false,
|
|
||||||
statusbar: false,
|
|
||||||
readonly: false,
|
|
||||||
plugins: 'autoresize',
|
|
||||||
license_key: 'gpl',
|
|
||||||
});
|
|
||||||
|
|
||||||
// DateTime
|
// DateTime
|
||||||
$('.datetimepicker').datetimepicker({
|
$('.datetimepicker').datetimepicker({
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -14,7 +14,7 @@
|
|||||||
<input type="hidden" name="client_id" value="<?php echo $client_id; ?>">
|
<input type="hidden" name="client_id" value="<?php echo $client_id; ?>">
|
||||||
<?php } ?>
|
<?php } ?>
|
||||||
<div class="modal-body bg-white">
|
<div class="modal-body bg-white">
|
||||||
<p><strong>Format csv file with headings & data:</strong><br>Name, Description, Type, Make, Model, Serial, OS, Assigned To, Location</p>
|
<p><strong>Format csv file with headings & data:</strong><br>Name, Description, Type, Make, Model, Serial, OS, Assigned To, Location, Physical Location</p>
|
||||||
<hr>
|
<hr>
|
||||||
<div class="form-group my-4">
|
<div class="form-group my-4">
|
||||||
<input type="file" class="form-control-file" name="file" accept=".csv" required>
|
<input type="file" class="form-control-file" name="file" accept=".csv" required>
|
||||||
|
|||||||
@@ -1,33 +1,123 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
|
// Default Column Sortby Filter
|
||||||
|
$sort = "notification_timestamp";
|
||||||
|
$order = "DESC";
|
||||||
|
|
||||||
require_once "includes/inc_all.php";
|
require_once "includes/inc_all.php";
|
||||||
|
|
||||||
|
// Dismissed Filter
|
||||||
|
if (isset($_GET['dismissed'])) {
|
||||||
|
$dismissed_query = 'AND notification_dismissed_at IS NOT NULL';
|
||||||
|
$dismissed_filter = 1;
|
||||||
|
} else {
|
||||||
|
// Default - any
|
||||||
|
$dismissed_query = 'AND notification_dismissed_at IS NULL';
|
||||||
|
$dismissed_filter = 0;
|
||||||
|
}
|
||||||
|
|
||||||
$sql = mysqli_query($mysqli, "SELECT * FROM notifications LEFT JOIN clients ON notification_client_id = client_id WHERE notification_dismissed_at IS NULL AND notification_user_id = $session_user_id ORDER BY notification_id DESC");
|
$sql = mysqli_query(
|
||||||
|
$mysqli,
|
||||||
|
"SELECT SQL_CALC_FOUND_ROWS * FROM notifications
|
||||||
|
LEFT JOIN clients ON notification_client_id = client_id
|
||||||
|
WHERE (notification_type LIKE '%$q%' OR notification LIKE '%$q%')
|
||||||
|
AND DATE(notification_timestamp) BETWEEN '$dtf' AND '$dtt'
|
||||||
|
AND notification_user_id = $session_user_id
|
||||||
|
$dismissed_query
|
||||||
|
ORDER BY $sort $order
|
||||||
|
LIMIT $record_from, $record_to
|
||||||
|
");
|
||||||
|
|
||||||
|
$num_rows = mysqli_fetch_row(mysqli_query($mysqli, "SELECT FOUND_ROWS()"));
|
||||||
|
|
||||||
?>
|
?>
|
||||||
|
|
||||||
<div class="card card-dark">
|
<div class="card card-dark">
|
||||||
<div class="card-header py-2">
|
<div class="card-header py-2">
|
||||||
<h3 class="card-title mt-2"><i class="fas fa-fw fa-bell mr-2"></i>Notifications</h3>
|
<h3 class="card-title mt-2">
|
||||||
|
<i class="fas fa-fw fa-bell mr-2"></i><?php if($dismissed_filter) { echo "Dismissed "; } ?>Notifications
|
||||||
|
</h3>
|
||||||
<div class="card-tools">
|
<div class="card-tools">
|
||||||
|
<?php if($dismissed_filter) { ?>
|
||||||
<?php if (mysqli_num_rows($sql) > 0) { ?><a href="post.php?dismiss_all_notifications" class="btn btn-primary"><i class="fas fa-fw fa-check mr-2"></i>Dismiss All</a><?php } ?>
|
<a href="notifications.php" class="btn btn-primary"><i class="fas fa-fw fa-history mr-2"></i>Dismissed</a>
|
||||||
<a href="notifications_dismissed.php" class="btn btn-secondary"><i class="fas fa-fw fa-history mr-2"></i>Dismissed</a>
|
<?php } else { ?>
|
||||||
|
<a href="notifications.php?dismissed" class="btn btn-outline-secondary"><i class="fas fa-fw fa-history mr-2"></i>Dismissed</a>
|
||||||
|
<?php } ?>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="card-body">
|
<div class="card-body">
|
||||||
<?php if (mysqli_num_rows($sql) > 0) { ?>
|
<form class="mb-4" autocomplete="off">
|
||||||
|
<?php if ($dismissed_filter) { ?>
|
||||||
|
<input type="hidden" name="dismissed" value="">
|
||||||
|
<?php } ?>
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-sm-4">
|
||||||
|
<div class="input-group">
|
||||||
|
<input type="search" class="form-control" name="q" value="<?php if (isset($q)) { echo stripslashes(nullable_htmlentities($q)); } ?>" placeholder="Search <?php if($dismissed_filter) { echo "Dismissed "; } ?>Notifications">
|
||||||
|
<div class="input-group-append">
|
||||||
|
<button class="btn btn-primary text-strong"><i class="fa fa-search"></i></button>
|
||||||
|
<button class="btn btn-secondary" type="button" data-toggle="collapse" data-target="#advancedFilter"><i class="fas fa-filter"></i></button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="col-sm-8">
|
||||||
|
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="collapse mt-3 <?php if (!empty($_GET['dtf'])) { echo "show"; } ?>" id="advancedFilter">
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-md-2">
|
||||||
|
<div class="form-group">
|
||||||
|
<label>Date From</label>
|
||||||
|
<input type="date" class="form-control" name="dtf" max="2999-12-31" value="<?php echo nullable_htmlentities($dtf); ?>">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="col-md-2">
|
||||||
|
<div class="form-group">
|
||||||
|
<label>Date To</label>
|
||||||
|
<input type="date" class="form-control" name="dtt" max="2999-12-31" value="<?php echo nullable_htmlentities($dtt); ?>">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
<div class="table-responsive-sm">
|
<div class="table-responsive-sm">
|
||||||
<table class="table table-striped table-borderless table-hover">
|
<table class="table table-hover">
|
||||||
<thead>
|
<thead class="<?php if ($num_rows[0] == 0) { echo "d-none"; } ?>">
|
||||||
<tr>
|
<tr>
|
||||||
<th>Timestamp</th>
|
<th>
|
||||||
<th>Type</th>
|
<a class="text-dark" href="?<?php echo $url_query_strings_sort; ?>&sort=notification_timestamp&order=<?php echo $disp; ?>">
|
||||||
<th>Notification</th>
|
Timestamp <?php if ($sort == 'notification_timestamp') { echo $order_icon; } ?>
|
||||||
<th>Client</th>
|
</a>
|
||||||
<th class="text-center">Dismiss</th>
|
</th>
|
||||||
|
<th>
|
||||||
|
<a class="text-dark" href="?<?php echo $url_query_strings_sort; ?>&sort=notification_type&order=<?php echo $disp; ?>">
|
||||||
|
Type <?php if ($sort == 'notification_type') { echo $order_icon; } ?>
|
||||||
|
</a>
|
||||||
|
</th>
|
||||||
|
<th>
|
||||||
|
<a class="text-dark" href="?<?php echo $url_query_strings_sort; ?>&sort=notification&order=<?php echo $disp; ?>">
|
||||||
|
Notification <?php if ($sort == 'notification') { echo $order_icon; } ?>
|
||||||
|
</a>
|
||||||
|
</th>
|
||||||
|
<?php if($dismissed_filter) { ?>
|
||||||
|
<th>
|
||||||
|
<a class="text-dark" href="?<?php echo $url_query_strings_sort; ?>&sort=notification_dismissed_at&order=<?php echo $disp; ?>">
|
||||||
|
Dismissed At <?php if ($sort == 'notification_dismissed_at') { echo $order_icon; } ?>
|
||||||
|
</a>
|
||||||
|
</th>
|
||||||
|
<?php } ?>
|
||||||
|
<?php if(!$dismissed_filter) { ?>
|
||||||
|
<th class="text-center p-0">
|
||||||
|
<?php if (mysqli_num_rows($sql) > 0) { ?>
|
||||||
|
<a href="post.php?dismiss_all_notifications&csrf_token=<?php echo $_SESSION["csrf_token"]; ?>"
|
||||||
|
class="btn btn-sm btn-dark mb-2" title="Dismiss All">
|
||||||
|
<i class="fas fa-fw fa-check-double"></i>
|
||||||
|
</a>
|
||||||
|
<?php } ?>
|
||||||
|
</th>
|
||||||
|
<?php } ?>
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
<tbody>
|
<tbody>
|
||||||
@@ -35,42 +125,35 @@ $sql = mysqli_query($mysqli, "SELECT * FROM notifications LEFT JOIN clients ON n
|
|||||||
|
|
||||||
while ($row = mysqli_fetch_array($sql)) {
|
while ($row = mysqli_fetch_array($sql)) {
|
||||||
$notification_id = intval($row['notification_id']);
|
$notification_id = intval($row['notification_id']);
|
||||||
|
$notification_timestamp = nullable_htmlentities($row['notification_timestamp']);
|
||||||
$notification_type = nullable_htmlentities($row['notification_type']);
|
$notification_type = nullable_htmlentities($row['notification_type']);
|
||||||
$notification = nullable_htmlentities($row['notification']);
|
$notification = nullable_htmlentities($row['notification']);
|
||||||
$notification_timestamp = nullable_htmlentities($row['notification_timestamp']);
|
$notification_dismissed_at = nullable_htmlentities($row['notification_dismissed_at']);
|
||||||
$client_name = nullable_htmlentities($row['client_name']);
|
$client_name = nullable_htmlentities($row['client_name']);
|
||||||
$client_id = intval($row['client_id']);
|
$client_id = intval($row['client_id']);
|
||||||
if (empty($client_name)) {
|
|
||||||
$client_name_display = "-";
|
|
||||||
} else {
|
|
||||||
$client_name_display = "<a href='client_overview.php?client_id=$client_id'>$client_name</a>";
|
|
||||||
}
|
|
||||||
|
|
||||||
?>
|
?>
|
||||||
<tr class="row-danger">
|
<tr>
|
||||||
<td><?php echo $notification_timestamp; ?></td>
|
<td><?php echo $notification_timestamp; ?></td>
|
||||||
<td><?php echo $notification_type; ?></td>
|
<td><?php echo $notification_type; ?></td>
|
||||||
<td><?php echo $notification; ?></td>
|
<td><?php echo $notification; ?></td>
|
||||||
<td><?php echo $client_name_display; ?></td>
|
<?php if($dismissed_filter) { ?>
|
||||||
<td class="text-center"><a class="btn btn-info btn-sm" href="post.php?dismiss_notification=<?php echo $notification_id; ?>"><i class="fas fa-check"></a></td>
|
<td><?php echo $notification_dismissed_at; ?></td>
|
||||||
|
<?php } ?>
|
||||||
|
<?php if(!$dismissed_filter) { ?>
|
||||||
|
<td class="text-center"><a class="btn btn-secondary btn-sm" href="post.php?dismiss_notification=<?php echo $notification_id; ?>" title="Dismiss"><i class="fas fa-check"></i></a></td>
|
||||||
|
<?php } ?>
|
||||||
</tr>
|
</tr>
|
||||||
|
|
||||||
<?php } ?>
|
<?php } ?>
|
||||||
|
|
||||||
|
|
||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
</div>
|
</div>
|
||||||
|
<?php require_once "includes/filter_footer.php"; ?>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<?php } else { ?>
|
|
||||||
<div class="my-5" style="text-align: center">
|
|
||||||
<i class='far fa-fw fa-6x fa-bell-slash text-secondary'></i><h3 class='text-secondary mt-3'>No Notifications</h3>
|
|
||||||
</div>
|
|
||||||
<?php } ?>
|
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<?php
|
<?php
|
||||||
require_once "includes/footer.php";
|
|
||||||
|
|
||||||
|
require_once "includes/footer.php";
|
||||||
|
|||||||
@@ -1,132 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
// Default Column Sortby Filter
|
|
||||||
$sort = "notification_timestamp";
|
|
||||||
$order = "DESC";
|
|
||||||
|
|
||||||
require_once "includes/inc_all.php";
|
|
||||||
|
|
||||||
//Rebuild URL
|
|
||||||
|
|
||||||
$url_query_strings_sort = http_build_query($get_copy);
|
|
||||||
|
|
||||||
$sql = mysqli_query(
|
|
||||||
$mysqli,
|
|
||||||
"SELECT SQL_CALC_FOUND_ROWS * FROM notifications
|
|
||||||
LEFT JOIN clients ON notification_client_id = client_id
|
|
||||||
WHERE (notification_type LIKE '%$q%' OR notification LIKE '%$q%' OR client_name LIKE '%$q%')
|
|
||||||
AND DATE(notification_timestamp) BETWEEN '$dtf' AND '$dtt'
|
|
||||||
AND notification_user_id = $session_user_id
|
|
||||||
AND notification_dismissed_at IS NOT NULL
|
|
||||||
ORDER BY $sort $order
|
|
||||||
LIMIT $record_from, $record_to
|
|
||||||
");
|
|
||||||
|
|
||||||
$num_rows = mysqli_fetch_row(mysqli_query($mysqli, "SELECT FOUND_ROWS()"));
|
|
||||||
|
|
||||||
?>
|
|
||||||
|
|
||||||
<div class="card card-dark">
|
|
||||||
<div class="card-header py-3">
|
|
||||||
<h3 class="card-title"><i class="fas fa-fw fa-bell mr-2"></i>Dismissed Notications</h3>
|
|
||||||
</div>
|
|
||||||
<div class="card-body">
|
|
||||||
<form class="mb-4" autocomplete="off">
|
|
||||||
<div class="row">
|
|
||||||
<div class="col-sm-4">
|
|
||||||
<div class="input-group">
|
|
||||||
<input type="search" class="form-control" name="q" value="<?php if (isset($q)) { echo stripslashes(nullable_htmlentities($q)); } ?>" placeholder="Search Dismissed Notifications">
|
|
||||||
<div class="input-group-append">
|
|
||||||
<button class="btn btn-primary"><i class="fa fa-search"></i></button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="col-sm-8">
|
|
||||||
<button class="btn btn-primary float-right" type="button" data-toggle="collapse" data-target="#advancedFilter"><i class="fas fa-filter"></i></button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="collapse mt-3 <?php if (!empty($_GET['dtf'])) { echo "show"; } ?>" id="advancedFilter">
|
|
||||||
<div class="row">
|
|
||||||
<div class="col-md-2">
|
|
||||||
<div class="form-group">
|
|
||||||
<label>Date From</label>
|
|
||||||
<input type="date" class="form-control" name="dtf" max="2999-12-31" value="<?php echo nullable_htmlentities($dtf); ?>">
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="col-md-2">
|
|
||||||
<div class="form-group">
|
|
||||||
<label>Date To</label>
|
|
||||||
<input type="date" class="form-control" name="dtt" max="2999-12-31" value="<?php echo nullable_htmlentities($dtt); ?>">
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</form>
|
|
||||||
<div class="table-responsive-sm">
|
|
||||||
<table class="table table-hover">
|
|
||||||
<thead class="<?php if ($num_rows[0] == 0) { echo "d-none"; } ?>">
|
|
||||||
<tr>
|
|
||||||
<th>
|
|
||||||
<a class="text-dark" href="?<?php echo $url_query_strings_sort; ?>&sort=notification_timestamp&order=<?php echo $disp; ?>">
|
|
||||||
Timestamp <?php if ($sort == 'notification_timestamp') { echo $order_icon; } ?>
|
|
||||||
</a>
|
|
||||||
</th>
|
|
||||||
<th>
|
|
||||||
<a class="text-dark" href="?<?php echo $url_query_strings_sort; ?>&sort=notification_type&order=<?php echo $disp; ?>">
|
|
||||||
Type <?php if ($sort == 'notification_type') { echo $order_icon; } ?>
|
|
||||||
</a>
|
|
||||||
</th>
|
|
||||||
<th>
|
|
||||||
<a class="text-dark" href="?<?php echo $url_query_strings_sort; ?>&sort=notification&order=<?php echo $disp; ?>">
|
|
||||||
Notification <?php if ($sort == 'notification') { echo $order_icon; } ?>
|
|
||||||
</a>
|
|
||||||
</th>
|
|
||||||
<th>
|
|
||||||
<a class="text-dark" href="?<?php echo $url_query_strings_sort; ?>&sort=client_name&order=<?php echo $disp; ?>">
|
|
||||||
Client <?php if ($sort == 'client_name') { echo $order_icon; } ?>
|
|
||||||
</a>
|
|
||||||
</th>
|
|
||||||
<th>
|
|
||||||
<a class="text-dark" href="?<?php echo $url_query_strings_sort; ?>&sort=notification_dismissed_at&order=<?php echo $disp; ?>">
|
|
||||||
Dismissed At <?php if ($sort == 'notification_dismissed_at') { echo $order_icon; } ?>
|
|
||||||
</a>
|
|
||||||
</th>
|
|
||||||
</tr>
|
|
||||||
</thead>
|
|
||||||
<tbody>
|
|
||||||
<?php
|
|
||||||
|
|
||||||
while ($row = mysqli_fetch_array($sql)) {
|
|
||||||
$notification_id = intval($row['notification_id']);
|
|
||||||
$notification_timestamp = nullable_htmlentities($row['notification_timestamp']);
|
|
||||||
$notification_type = nullable_htmlentities($row['notification_type']);
|
|
||||||
$notification = nullable_htmlentities($row['notification']);
|
|
||||||
$notification_dismissed_at = nullable_htmlentities($row['notification_dismissed_at']);
|
|
||||||
$client_name = nullable_htmlentities($row['client_name']);
|
|
||||||
$client_id = intval($row['client_id']);
|
|
||||||
if (empty($client_name)) {
|
|
||||||
$client_name_display = "-";
|
|
||||||
} else {
|
|
||||||
$client_name_display = "<a href='client_overview.php?client_id=$client_id'>$client_name</a>";
|
|
||||||
}
|
|
||||||
|
|
||||||
?>
|
|
||||||
<tr>
|
|
||||||
<td><?php echo $notification_timestamp; ?></td>
|
|
||||||
<td><?php echo $notification_type; ?></td>
|
|
||||||
<td><?php echo $notification; ?></td>
|
|
||||||
<td><?php echo $client_name_display; ?></td>
|
|
||||||
<td><?php echo $notification_dismissed_at; ?></td>
|
|
||||||
|
|
||||||
<?php } ?>
|
|
||||||
|
|
||||||
</tbody>
|
|
||||||
</table>
|
|
||||||
</div>
|
|
||||||
<?php require_once "includes/filter_footer.php"; ?>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<?php
|
|
||||||
|
|
||||||
require_once "includes/footer.php";
|
|
||||||
@@ -740,7 +740,6 @@ if (isset($_GET['unlink_asset_from_file'])) {
|
|||||||
if (isset($_POST["import_assets_csv"])) {
|
if (isset($_POST["import_assets_csv"])) {
|
||||||
|
|
||||||
enforceUserPermission('module_support', 2);
|
enforceUserPermission('module_support', 2);
|
||||||
|
|
||||||
validateCSRFToken($_POST['csrf_token']);
|
validateCSRFToken($_POST['csrf_token']);
|
||||||
|
|
||||||
$client_id = intval($_POST['client_id']);
|
$client_id = intval($_POST['client_id']);
|
||||||
@@ -774,9 +773,9 @@ if (isset($_POST["import_assets_csv"])) {
|
|||||||
//(Else)Check column count (name, desc, type, make, model, serial, os, assigned to, location)
|
//(Else)Check column count (name, desc, type, make, model, serial, os, assigned to, location)
|
||||||
$f = fopen($file_name, "r");
|
$f = fopen($file_name, "r");
|
||||||
$f_columns = fgetcsv($f, 1000, ",");
|
$f_columns = fgetcsv($f, 1000, ",");
|
||||||
if (!$error & count($f_columns) != 9) {
|
if (!$error & count($f_columns) != 10) {
|
||||||
$error = true;
|
$error = true;
|
||||||
$_SESSION['alert_message'] = "Bad column count.";
|
$_SESSION['alert_message'] = "Invalid column count.";
|
||||||
}
|
}
|
||||||
|
|
||||||
//Else, parse the file
|
//Else, parse the file
|
||||||
@@ -832,11 +831,14 @@ if (isset($_POST["import_assets_csv"])) {
|
|||||||
$location_id = intval($row['location_id']);
|
$location_id = intval($row['location_id']);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (!empty($column[9])) {
|
||||||
|
$physical_location = sanitizeInput($column[9]);
|
||||||
|
}
|
||||||
|
|
||||||
// Check if duplicate was detected
|
// Check if duplicate was detected
|
||||||
if ($duplicate_detect == 0) {
|
if ($duplicate_detect == 0) {
|
||||||
//Add
|
//Add
|
||||||
mysqli_query($mysqli,"INSERT INTO assets SET asset_name = '$name', asset_description = '$description', asset_type = '$type', asset_make = '$make', asset_model = '$model', asset_serial = '$serial', asset_os = '$os', asset_contact_id = $contact_id, asset_location_id = $location_id, asset_client_id = $client_id");
|
mysqli_query($mysqli,"INSERT INTO assets SET asset_name = '$name', asset_description = '$description', asset_type = '$type', asset_make = '$make', asset_model = '$model', asset_serial = '$serial', asset_os = '$os', asset_physical_location = '$physical_location', asset_contact_id = $contact_id, asset_location_id = $location_id, asset_client_id = $client_id");
|
||||||
|
|
||||||
$asset_id = mysqli_insert_id($mysqli);
|
$asset_id = mysqli_insert_id($mysqli);
|
||||||
|
|
||||||
@@ -864,7 +866,7 @@ if (isset($_POST["import_assets_csv"])) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (isset($_GET['download_assets_csv_template'])) {
|
if (isset($_GET['download_assets_csv_template'])) {
|
||||||
$client_id = intval($_GET['download_client_assets_csv_template']);
|
$client_id = intval($_GET['download_assets_csv_template']);
|
||||||
|
|
||||||
//get records from database
|
//get records from database
|
||||||
$sql = mysqli_query($mysqli,"SELECT client_name FROM clients WHERE client_id = $client_id");
|
$sql = mysqli_query($mysqli,"SELECT client_name FROM clients WHERE client_id = $client_id");
|
||||||
@@ -879,7 +881,7 @@ if (isset($_GET['download_assets_csv_template'])) {
|
|||||||
$f = fopen('php://memory', 'w');
|
$f = fopen('php://memory', 'w');
|
||||||
|
|
||||||
//set column headers
|
//set column headers
|
||||||
$fields = array('Name', 'Description', 'Type', 'Make', 'Model', 'Serial', 'OS', 'Assigned To', 'Location');
|
$fields = array('Name', 'Description', 'Type', 'Make', 'Model', 'Serial', 'OS', 'Assigned To', 'Location', 'Physical Location');
|
||||||
fputcsv($f, $fields, $delimiter);
|
fputcsv($f, $fields, $delimiter);
|
||||||
|
|
||||||
//move back to beginning of file
|
//move back to beginning of file
|
||||||
@@ -898,22 +900,22 @@ if (isset($_GET['download_assets_csv_template'])) {
|
|||||||
if (isset($_POST['export_assets_csv'])) {
|
if (isset($_POST['export_assets_csv'])) {
|
||||||
|
|
||||||
enforceUserPermission('module_support');
|
enforceUserPermission('module_support');
|
||||||
|
|
||||||
validateCSRFToken($_POST['csrf_token']);
|
validateCSRFToken($_POST['csrf_token']);
|
||||||
|
|
||||||
|
$client_name = 'All'; // default
|
||||||
|
|
||||||
if (isset($_POST['client_id'])) {
|
if (isset($_POST['client_id'])) {
|
||||||
$client_id = intval($_POST['client_id']);
|
$client_id = intval($_POST['client_id']);
|
||||||
$client_query = "AND asset_client_id = $client_id";
|
$client_query = "AND asset_client_id = $client_id";
|
||||||
|
|
||||||
|
$client_row = mysqli_fetch_array(mysqli_query($mysqli,"SELECT client_name FROM clients WHERE client_id = $client_id"));
|
||||||
|
$client_name = $client_row['client_name'];
|
||||||
} else {
|
} else {
|
||||||
$client_query = '';
|
$client_query = '';
|
||||||
}
|
}
|
||||||
|
|
||||||
//get records from database
|
// Get records from database
|
||||||
$sql = mysqli_query($mysqli,"SELECT * FROM assets LEFT JOIN contacts ON asset_contact_id = contact_id LEFT JOIN locations ON asset_location_id = location_id LEFT JOIN asset_interfaces ON interface_asset_id = asset_id AND interface_primary = 1 LEFT JOIN clients ON asset_client_id = client_id WHERE asset_archived_at IS NULL $client_query ORDER BY asset_name ASC");
|
$sql = mysqli_query($mysqli,"SELECT * FROM assets LEFT JOIN contacts ON asset_contact_id = contact_id LEFT JOIN locations ON asset_location_id = location_id LEFT JOIN asset_interfaces ON interface_asset_id = asset_id AND interface_primary = 1 LEFT JOIN clients ON asset_client_id = client_id WHERE asset_archived_at IS NULL $client_query ORDER BY asset_name ASC");
|
||||||
$row = mysqli_fetch_array($sql);
|
|
||||||
|
|
||||||
$client_name = $row['client_name'];
|
|
||||||
|
|
||||||
$num_rows = mysqli_num_rows($sql);
|
$num_rows = mysqli_num_rows($sql);
|
||||||
|
|
||||||
if ($num_rows > 0) {
|
if ($num_rows > 0) {
|
||||||
@@ -924,12 +926,12 @@ if (isset($_POST['export_assets_csv'])) {
|
|||||||
$f = fopen('php://memory', 'w');
|
$f = fopen('php://memory', 'w');
|
||||||
|
|
||||||
//set column headers
|
//set column headers
|
||||||
$fields = array('Name', 'Description', 'Type', 'Make', 'Model', 'Serial Number', 'Operating System', 'Purchase Date', 'Warranty Expire', 'Install Date', 'Assigned To', 'Location', 'Notes');
|
$fields = array('Name', 'Description', 'Type', 'Make', 'Model', 'Serial Number', 'Operating System', 'Purchase Date', 'Warranty Expire', 'Install Date', 'Assigned To', 'Location', 'Physical Location', 'Notes');
|
||||||
fputcsv($f, $fields, $delimiter);
|
fputcsv($f, $fields, $delimiter);
|
||||||
|
|
||||||
//output each row of the data, format line as csv and write to file pointer
|
//output each row of the data, format line as csv and write to file pointer
|
||||||
while ($row = mysqli_fetch_array($sql)) {
|
while ($row = mysqli_fetch_array($sql)) {
|
||||||
$lineData = array($row['asset_name'], $row['asset_description'], $row['asset_type'], $row['asset_make'], $row['asset_model'], $row['asset_serial'], $row['asset_os'], $row['asset_purchase_date'], $row['asset_warranty_expire'], $row['asset_install_date'], $row['contact_name'], $row['location_name'], $row['asset_notes']);
|
$lineData = array($row['asset_name'], $row['asset_description'], $row['asset_type'], $row['asset_make'], $row['asset_model'], $row['asset_serial'], $row['asset_os'], $row['asset_purchase_date'], $row['asset_warranty_expire'], $row['asset_install_date'], $row['contact_name'], $row['location_name'], $row['asset_physical_location'], $row['asset_notes']);
|
||||||
fputcsv($f, $lineData, $delimiter);
|
fputcsv($f, $lineData, $delimiter);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1188,7 +1190,6 @@ if (isset($_GET['delete_asset_interface'])) {
|
|||||||
if (isset($_POST["import_client_asset_interfaces_csv"])) {
|
if (isset($_POST["import_client_asset_interfaces_csv"])) {
|
||||||
|
|
||||||
enforceUserPermission('module_support', 2);
|
enforceUserPermission('module_support', 2);
|
||||||
|
|
||||||
validateCSRFToken($_POST['csrf_token']);
|
validateCSRFToken($_POST['csrf_token']);
|
||||||
|
|
||||||
$asset_id = intval($_POST['asset_id']);
|
$asset_id = intval($_POST['asset_id']);
|
||||||
@@ -1338,7 +1339,6 @@ if (isset($_GET['download_client_asset_interfaces_csv_template'])) {
|
|||||||
if (isset($_POST['export_client_asset_interfaces_csv'])) {
|
if (isset($_POST['export_client_asset_interfaces_csv'])) {
|
||||||
|
|
||||||
enforceUserPermission('module_support');
|
enforceUserPermission('module_support');
|
||||||
|
|
||||||
validateCSRFToken($_POST['csrf_token']);
|
validateCSRFToken($_POST['csrf_token']);
|
||||||
|
|
||||||
$asset_id = intval($_POST['asset_id']);
|
$asset_id = intval($_POST['asset_id']);
|
||||||
|
|||||||
@@ -64,8 +64,41 @@ if (isset($_POST['edit_certificate'])) {
|
|||||||
$expire = "'" . $expire . "'";
|
$expire = "'" . $expire . "'";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Get current certificate info
|
||||||
|
$original_certificate_info = mysqli_fetch_assoc(mysqli_query($mysqli,"
|
||||||
|
SELECT
|
||||||
|
certificates.*,
|
||||||
|
domains.domain_name
|
||||||
|
FROM certificates
|
||||||
|
LEFT JOIN domains ON certificate_domain_id = domain_id
|
||||||
|
WHERE certificate_id = $certificate_id
|
||||||
|
"));
|
||||||
|
|
||||||
|
// Update certificate
|
||||||
mysqli_query($mysqli,"UPDATE certificates SET certificate_name = '$name', certificate_description = '$description', certificate_domain = '$domain', certificate_issued_by = '$issued_by', certificate_expire = $expire, certificate_public_key = '$public_key', certificate_notes = '$notes', certificate_domain_id = '$domain_id' WHERE certificate_id = $certificate_id");
|
mysqli_query($mysqli,"UPDATE certificates SET certificate_name = '$name', certificate_description = '$description', certificate_domain = '$domain', certificate_issued_by = '$issued_by', certificate_expire = $expire, certificate_public_key = '$public_key', certificate_notes = '$notes', certificate_domain_id = '$domain_id' WHERE certificate_id = $certificate_id");
|
||||||
|
|
||||||
|
// Fetch the updated info
|
||||||
|
$new_certificate_info = mysqli_fetch_assoc(mysqli_query($mysqli,"
|
||||||
|
SELECT
|
||||||
|
certificates.*,
|
||||||
|
domains.domain_name
|
||||||
|
FROM certificates
|
||||||
|
LEFT JOIN domains ON certificate_domain_id = domain_id
|
||||||
|
WHERE certificate_id = $certificate_id
|
||||||
|
"));
|
||||||
|
|
||||||
|
// Compare/log changes between old/new info
|
||||||
|
$ignored_columns = ["certificate_public_key", "certificate_updated_at", "certificate_accessed_at", "certificate_domain_id"];
|
||||||
|
foreach ($original_certificate_info as $column => $old_value) {
|
||||||
|
$new_value = $new_certificate_info[$column];
|
||||||
|
if ($old_value != $new_value && !in_array($column, $ignored_columns)) {
|
||||||
|
$column = sanitizeInput($column);
|
||||||
|
$old_value = sanitizeInput($old_value);
|
||||||
|
$new_value = sanitizeInput($new_value);
|
||||||
|
mysqli_query($mysqli,"INSERT INTO certificate_history SET certificate_history_column = '$column', certificate_history_old_value = '$old_value', certificate_history_new_value = '$new_value', certificate_history_certificate_id = $certificate_id");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Logging
|
// Logging
|
||||||
logAction("Certificate", "Edit", "$session_name edited certificate $name", $client_id, $certificate_id);
|
logAction("Certificate", "Edit", "$session_name edited certificate $name", $client_id, $certificate_id);
|
||||||
|
|
||||||
|
|||||||
@@ -12,7 +12,7 @@ if (isset($_POST['add_login'])) {
|
|||||||
|
|
||||||
require_once 'post/user/credential_model.php';
|
require_once 'post/user/credential_model.php';
|
||||||
|
|
||||||
mysqli_query($mysqli,"INSERT INTO logins SET login_name = '$name', login_description = '$description', login_uri = '$uri', login_uri_2 = '$uri_2', login_username = '$username', login_password = '$password', login_otp_secret = '$otp_secret', login_note = '$note', login_important = $important, login_contact_id = $contact_id, login_vendor_id = $vendor_id, login_asset_id = $asset_id, login_software_id = $software_id, login_client_id = $client_id");
|
mysqli_query($mysqli,"INSERT INTO logins SET login_name = '$name', login_description = '$description', login_uri = '$uri', login_uri_2 = '$uri_2', login_username = '$username', login_password = '$password', login_otp_secret = '$otp_secret', login_note = '$note', login_important = $important, login_contact_id = $contact_id, login_asset_id = $asset_id, login_client_id = $client_id");
|
||||||
|
|
||||||
$login_id = mysqli_insert_id($mysqli);
|
$login_id = mysqli_insert_id($mysqli);
|
||||||
|
|
||||||
@@ -50,7 +50,7 @@ if (isset($_POST['edit_login'])) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Update the login entry with the new details
|
// Update the login entry with the new details
|
||||||
mysqli_query($mysqli,"UPDATE logins SET login_name = '$name', login_description = '$description', login_uri = '$uri', login_uri_2 = '$uri_2', login_username = '$username', login_password = '$password', login_otp_secret = '$otp_secret', login_note = '$note', login_important = $important, login_contact_id = $contact_id, login_vendor_id = $vendor_id, login_asset_id = $asset_id, login_software_id = $software_id WHERE login_id = $login_id");
|
mysqli_query($mysqli,"UPDATE logins SET login_name = '$name', login_description = '$description', login_uri = '$uri', login_uri_2 = '$uri_2', login_username = '$username', login_password = '$password', login_otp_secret = '$otp_secret', login_note = '$note', login_important = $important, login_contact_id = $contact_id, login_asset_id = $asset_id WHERE login_id = $login_id");
|
||||||
|
|
||||||
// Tags
|
// Tags
|
||||||
// Delete existing tags
|
// Delete existing tags
|
||||||
|
|||||||
@@ -66,7 +66,7 @@ if (isset($_POST['add_software'])) {
|
|||||||
$expire = "'" . $expire . "'";
|
$expire = "'" . $expire . "'";
|
||||||
}
|
}
|
||||||
$notes = sanitizeInput($_POST['notes']);
|
$notes = sanitizeInput($_POST['notes']);
|
||||||
$vendor = sanitizeInput($_POST['vendor'] ?? 0);
|
$vendor = intval($_POST['vendor'] ?? 0);
|
||||||
|
|
||||||
mysqli_query($mysqli,"INSERT INTO software SET software_name = '$name', software_version = '$version', software_description = '$description', software_type = '$type', software_key = '$key', software_license_type = '$license_type', software_seats = $seats, software_purchase_reference = '$purchase_reference', software_purchase = $purchase, software_expire = $expire, software_notes = '$notes', software_vendor_id = $vendor, software_client_id = $client_id");
|
mysqli_query($mysqli,"INSERT INTO software SET software_name = '$name', software_version = '$version', software_description = '$description', software_type = '$type', software_key = '$key', software_license_type = '$license_type', software_seats = $seats, software_purchase_reference = '$purchase_reference', software_purchase = $purchase, software_expire = $expire, software_notes = '$notes', software_vendor_id = $vendor, software_client_id = $client_id");
|
||||||
|
|
||||||
@@ -127,7 +127,7 @@ if (isset($_POST['edit_software'])) {
|
|||||||
$expire = "'" . $expire . "'";
|
$expire = "'" . $expire . "'";
|
||||||
}
|
}
|
||||||
$notes = sanitizeInput($_POST['notes']);
|
$notes = sanitizeInput($_POST['notes']);
|
||||||
$vendor = sanitizeInput($_POST['vendor'] ?? 0);
|
$vendor = intval($_POST['vendor'] ?? 0);
|
||||||
|
|
||||||
mysqli_query($mysqli,"UPDATE software SET software_name = '$name', software_version = '$version', software_description = '$description', software_type = '$type', software_key = '$key', software_license_type = '$license_type', software_seats = $seats, software_purchase_reference = '$purchase_reference', software_purchase = $purchase, software_expire = $expire, software_notes = '$notes', software_vendor_id = $vendor WHERE software_id = $software_id");
|
mysqli_query($mysqli,"UPDATE software SET software_name = '$name', software_version = '$version', software_description = '$description', software_type = '$type', software_key = '$key', software_license_type = '$license_type', software_seats = $seats, software_purchase_reference = '$purchase_reference', software_purchase = $purchase, software_expire = $expire, software_notes = '$notes', software_vendor_id = $vendor WHERE software_id = $software_id");
|
||||||
|
|
||||||
|
|||||||
@@ -18,8 +18,14 @@ if (isset($_GET['client_id'])) {
|
|||||||
// Perms
|
// Perms
|
||||||
enforceUserPermission('module_sales');
|
enforceUserPermission('module_sales');
|
||||||
|
|
||||||
//Rebuild URL
|
// Status Filter
|
||||||
$url_query_strings_sort = http_build_query($get_copy);
|
if (isset($_GET['status']) && $_GET['status'] == "inactive") {
|
||||||
|
$status_filter = "inactive";
|
||||||
|
$status_query = "AND recurring_status = 0";
|
||||||
|
} else {
|
||||||
|
$status_filter = "active";
|
||||||
|
$status_query = "AND recurring_status = 1";
|
||||||
|
}
|
||||||
|
|
||||||
$sql = mysqli_query(
|
$sql = mysqli_query(
|
||||||
$mysqli,
|
$mysqli,
|
||||||
@@ -29,6 +35,7 @@ $sql = mysqli_query(
|
|||||||
LEFT JOIN recurring_payments ON recurring_payment_recurring_invoice_id = recurring_id
|
LEFT JOIN recurring_payments ON recurring_payment_recurring_invoice_id = recurring_id
|
||||||
WHERE (CONCAT(recurring_prefix,recurring_number) LIKE '%$q%' OR recurring_frequency LIKE '%$q%' OR recurring_scope LIKE '%$q%' OR client_name LIKE '%$q%' OR category_name LIKE '%$q%')
|
WHERE (CONCAT(recurring_prefix,recurring_number) LIKE '%$q%' OR recurring_frequency LIKE '%$q%' OR recurring_scope LIKE '%$q%' OR client_name LIKE '%$q%' OR category_name LIKE '%$q%')
|
||||||
AND DATE(recurring_created_at) BETWEEN '$dtf' AND '$dtt'
|
AND DATE(recurring_created_at) BETWEEN '$dtf' AND '$dtt'
|
||||||
|
$status_query
|
||||||
$client_query
|
$client_query
|
||||||
ORDER BY $sort $order LIMIT $record_from, $record_to");
|
ORDER BY $sort $order LIMIT $record_from, $record_to");
|
||||||
|
|
||||||
@@ -49,6 +56,7 @@ $num_rows = mysqli_fetch_row(mysqli_query($mysqli, "SELECT FOUND_ROWS()"));
|
|||||||
<?php if ($client_url) { ?>
|
<?php if ($client_url) { ?>
|
||||||
<input type="hidden" name="client_id" value="<?php echo $client_id; ?>">
|
<input type="hidden" name="client_id" value="<?php echo $client_id; ?>">
|
||||||
<?php } ?>
|
<?php } ?>
|
||||||
|
<input type="hidden" name="status" value="<?php echo $status_filter; ?>">
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="col-sm-4">
|
<div class="col-sm-4">
|
||||||
<div class="input-group">
|
<div class="input-group">
|
||||||
@@ -60,7 +68,11 @@ $num_rows = mysqli_fetch_row(mysqli_query($mysqli, "SELECT FOUND_ROWS()"));
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="col-sm-8">
|
<div class="col-sm-8">
|
||||||
<div class="btn-group float-right">
|
<div class="btn-toolbar float-right">
|
||||||
|
<div class="btn-group mr-2">
|
||||||
|
<a href="?<?php echo $client_url; ?>status=active" class="btn btn-<?php if ($status_filter == "active"){ echo "primary"; } else { echo "default"; } ?>"><i class="fa fa-fw fa-check mr-2"></i>Active</a>
|
||||||
|
<a href="?<?php echo $client_url; ?>status=inactive" class="btn btn-<?php if ($status_filter == "inactive"){ echo "primary"; } else { echo "default"; } ?>"><i class="fa fa-fw fa-ban mr-2"></i>Inactive</a>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -66,7 +66,7 @@ enforceUserPermission('module_financial');
|
|||||||
?>
|
?>
|
||||||
|
|
||||||
<tr>
|
<tr>
|
||||||
<td><a href="client_invoices.php?client_id=<?php echo $client_id; ?>"><?php echo $client_name; ?></a></td>
|
<td><a href="invoices.php?client_id=<?php echo $client_id; ?>"><?php echo $client_name; ?></a></td>
|
||||||
<td class="text-right"><?php echo numfmt_format_currency($currency_format, $balance, $session_company_currency); ?></td>
|
<td class="text-right"><?php echo numfmt_format_currency($currency_format, $balance, $session_company_currency); ?></td>
|
||||||
</tr>
|
</tr>
|
||||||
<?php
|
<?php
|
||||||
|
|||||||
@@ -60,8 +60,42 @@ while ($row = mysqli_fetch_array($sql_certificates)) {
|
|||||||
echo "$public_key\n\n";
|
echo "$public_key\n\n";
|
||||||
|
|
||||||
$expire = "'" . $expire . "'";
|
$expire = "'" . $expire . "'";
|
||||||
|
|
||||||
|
// Get current certificate info
|
||||||
|
$original_certificate_info = mysqli_fetch_assoc(mysqli_query($mysqli,"
|
||||||
|
SELECT
|
||||||
|
certificates.*,
|
||||||
|
domains.domain_name
|
||||||
|
FROM certificates
|
||||||
|
LEFT JOIN domains ON certificate_domain_id = domain_id
|
||||||
|
WHERE certificate_id = $certificate_id
|
||||||
|
"));
|
||||||
|
|
||||||
|
// Update
|
||||||
mysqli_query($mysqli,"UPDATE certificates SET certificate_issued_by = '$issued_by', certificate_expire = $expire, certificate_public_key = '$public_key' WHERE certificate_id = $certificate_id");
|
mysqli_query($mysqli,"UPDATE certificates SET certificate_issued_by = '$issued_by', certificate_expire = $expire, certificate_public_key = '$public_key' WHERE certificate_id = $certificate_id");
|
||||||
|
|
||||||
|
// Fetch the updated info
|
||||||
|
$new_certificate_info = mysqli_fetch_assoc(mysqli_query($mysqli,"
|
||||||
|
SELECT
|
||||||
|
certificates.*,
|
||||||
|
domains.domain_name
|
||||||
|
FROM certificates
|
||||||
|
LEFT JOIN domains ON certificate_domain_id = domain_id
|
||||||
|
WHERE certificate_id = $certificate_id
|
||||||
|
"));
|
||||||
|
|
||||||
|
// Compare/log changes between old/new info
|
||||||
|
$ignored_columns = ["certificate_public_key", "certificate_updated_at", "certificate_accessed_at", "certificate_domain_id"];
|
||||||
|
foreach ($original_certificate_info as $column => $old_value) {
|
||||||
|
$new_value = $new_certificate_info[$column];
|
||||||
|
if ($old_value != $new_value && !in_array($column, $ignored_columns)) {
|
||||||
|
$column = sanitizeInput($column);
|
||||||
|
$old_value = sanitizeInput($old_value);
|
||||||
|
$new_value = sanitizeInput($new_value);
|
||||||
|
mysqli_query($mysqli,"INSERT INTO certificate_history SET certificate_history_column = '$column', certificate_history_old_value = '$old_value', certificate_history_new_value = '$new_value', certificate_history_certificate_id = $certificate_id");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
logApp("Cron-Certificate-Refresher", "error", "Cron Certificate Refresh - error updating Error updating $domain.");
|
logApp("Cron-Certificate-Refresher", "error", "Cron Certificate Refresh - error updating Error updating $domain.");
|
||||||
error_log("Certificate Cron Error - Error updating $domain");
|
error_log("Certificate Cron Error - Error updating $domain");
|
||||||
|
|||||||
Reference in New Issue
Block a user