137 Commits

Author SHA1 Message Date
Johnny
20e2f22a27 Merge pull request #1268 from itflow-org/develop
Develop to Master for 26.02.1 Maint Release
2026-02-14 15:54:13 -05:00
johnnyq
12b3775041 Update Changelog 2026-02-14 15:50:27 -05:00
johnnyq
52b509fdc5 Update Changelog 2026-02-14 15:49:40 -05:00
johnnyq
f9d0a8bf43 Ticket: Dont display Updated at if null, Move Subject from top ticket bar to header in ticket details, add additional comments about the client_permission_overide 2026-02-14 15:48:40 -05:00
johnnyq
2349ef33d1 Remove 0 in access_permission_query 2026-02-14 15:07:42 -05:00
johnnyq
ccaf15268c Add a 0 IN ticket_client_id for no client tickets so agents that are restricted to certain clients and still view no clients in tickets list by using a , also restrict change clients on tickets for restricted agents 2026-02-14 15:06:17 -05:00
johnnyq
616635f951 client edit modal: Restrict Access to client restricted agents 2026-02-14 13:17:15 -05:00
johnnyq
ce7daaf1cf ticket edit modal: Restrict Access to client restricted agents 2026-02-14 12:55:34 -05:00
johnnyq
fb9f5d986d ticket Details: Restrict Access to ticket details by restricted agents 2026-02-14 12:51:58 -05:00
johnnyq
3148906cfe ticket Details: Restrict Access to ticket details by restricted Agents 2026-02-14 12:30:49 -05:00
johnnyq
6c057f4fd0 Restrict Tickets presented in ticket listing to client restricted Agents 2026-02-14 12:16:22 -05:00
johnnyq
3014bba66d Update Changelog, Bump App Release 2026-02-14 12:01:49 -05:00
johnnyq
97958d5e22 Missing Generate Password js code in Create Credential modal 2026-02-13 14:43:34 -05:00
johnnyq
1a7452cc27 Restrict Agents that are restricted to view certain clients from calendar events. 2026-02-13 14:28:45 -05:00
johnnyq
34ba5d0570 Properly get the new ticket number for logging in ticket merge 2026-02-13 14:14:01 -05:00
johnnyq
c0fe9813dc Fix Ticket Merging regressed from ticket select now use ticket_id instead of ticket_number 2026-02-13 14:09:05 -05:00
johnnyq
fd29eb7c15 Fix Transfer Asset to client due to field change from asset_important to asset_favorite 2026-02-13 13:39:41 -05:00
johnnyq
1bee085b33 Add Report for Client Detail Time Auditing 2026-02-13 13:35:02 -05:00
johnnyq
1d06e6d9c8 Revert to old ajax-modal js code for now, Fix Assets not lising in create ticket. 2026-02-11 13:33:28 -05:00
wrongecho
bdf8038148 Merge pull request #1265 from MydsiIversen/Time-API
feat: Add API endpoint to retrieve time worked by technicians
2026-02-09 14:23:02 +00:00
Mads Iversen
62fb2c91a1 feat: Add API endpoint to retrieve time worked by technicians on tickets with filtering by date and technician. 2026-02-09 12:09:56 +00:00
Johnny
376285ef62 Merge pull request #1263 from itflow-org/develop
Develop to Master for 26.02 Release Take 2
2026-02-08 12:02:43 -05:00
johnnyq
d1eeba67fc Add bulk Fav / unfav creds and added fav creds to the client overview page 2026-02-07 18:42:53 -05:00
johnnyq
2ca8112daf Revert Git change test to ticket_email_parser.php 2026-02-06 15:14:37 -05:00
johnnyq
546f10bc82 Testing Git changes on ticket_email_parser.php 2026-02-06 15:13:54 -05:00
johnnyq
ec7f1d561d Fix Version 2026-02-06 13:12:34 -05:00
johnnyq
8d54bc3a2f Another change 2026-02-06 13:03:07 -05:00
johnnyq
1d8f77f799 Update Changelog for 26.2 Release 2026-02-06 13:01:37 -05:00
johnnyq
1c6795dd55 Bump app version 2026-02-06 12:09:32 -05:00
Johnny
4d895a56e4 Merge pull request #1261 from cs2000/develop
Add full Microsoft 365 and Google OAuth mail support
2026-02-05 14:04:22 -05:00
johnnyq
bdd56c91f7 Update Credential Important to Favorite 2026-02-05 12:24:21 -05:00
johnnyq
be172b5bd9 Add star-toggle class to add asset 2026-02-05 12:15:41 -05:00
johnnyq
d224d71f59 Bump Datatables from 2.3.4 to 2.3.7 2026-02-05 11:50:33 -05:00
johnnyq
065630b975 Bump PHPMailer from 7.0.1 to 7.0.2 2026-02-05 11:46:28 -05:00
johnnyq
decea604ab Bump TinyMCE 8.2.2 to 8.3.2 2026-02-05 11:38:22 -05:00
johnnyq
004b3b2bdc Draft of ticket_by_client report v2 not yet in the side menu of reports 2026-02-05 11:31:40 -05:00
cs2000
dca0cc34e9 Revert to original file from dev branch
Accidentally comitted an older file.
2026-02-05 16:08:04 +00:00
cs2000
9afb165fc4 SonarCube Suggestion
Remove duplicates of https://login.microsoftonline.com/ and make them use a constant.
2026-02-05 10:26:51 +00:00
cs2000
6a6eb4a714 SonarCube Suggestion
Define a constant "MICROSOFT_OAUTH_BASE_URL" instead of duplicating "https://login.microsoftonline.com/" multiple times in the same file.
2026-02-05 10:22:06 +00:00
cs2000
629f4e0c81 SonarCube Suggestion
Defined a constant $settings_mail_path at the top of the file instead of duplicating "/admin/settings_mail.php" in the code multiple times.
2026-02-05 10:19:13 +00:00
cs2000
7cbe9bf7fc SonarCube Suggestion
Removed two instances of unecessary double parentheses.
2026-02-05 10:17:28 +00:00
cs2000
fc33312e79 SonarCube Suggestion
Rename multiple functions to conform to project naming rules (^[a-z][a-zA-Z0-9]*$). This is a non-functional refactor for style/CI compliance and consistency.
2026-02-05 10:15:52 +00:00
cs2000
563c0ea9c4 Changes for M365 oAuth using dev code
My bad, my changes were made previously using my installed version and not the latest changes in the dev branch, i have pulled the dev branch and merged my changes with the latest codebase.
2026-02-05 09:38:09 +00:00
cs2000
10d1a902d9 Changes for M365 oAuth now using latest dev code
My bad, my changes were made previously using my installed version and not the latest changes in the dev branch, i have pulled the dev branch and merged my changes with the latest codebase.
2026-02-05 09:37:22 +00:00
johnnyq
4079257739 Update UI/UX for Adding and editing roles, Permissions can be set upon role add nice blocker style radios buttons instead of select boxes 2026-02-04 13:12:24 -05:00
johnnyq
91aba13c0d Fix Empty col in client overview if no fabvorite assets, fix creds page rename var from important to favorite 2026-02-04 11:11:12 -05:00
cs2000
2cca4f2f0e Changes for M365 oAuth
- Added null-safe guard around folder path logging during message move failure to prevent property_exists() fatal when folder object is null.
2026-02-04 13:26:52 +00:00
cs2000
d2e8dc1439 Changes for M365 oAuth
- Fixed email queue gating for OAuth SMTP setups by treating configured config_smtp_provider as mail-enabled, even when config_smtp_host is blank.
- Restores queueing for public ticket reply emails (including “Public Comment & Email”) and related ticket notification paths.
2026-02-04 13:26:17 +00:00
cs2000
f3f9d0dd71 Changes for M365 oAuth
- Added OAuth token lifecycle helpers (expiry check, refresh, persistence).
- Updated SMTP XOAUTH2 send path to automatically refresh expired/missing access tokens for Microsoft/Google providers before sending queued mail.
2026-02-04 13:25:32 +00:00
cs2000
f6845a046f Changes for M365 oAuth
- New callback endpoint to complete Microsoft OAuth web flow.
- Validates admin session + OAuth state, exchanges authorization code for tokens, stores refresh/access tokens and expiry, and redirects with success/error feedback.
2026-02-04 13:24:50 +00:00
cs2000
a50a4f274f Changes for M365 oAuth
- Added handler to start Microsoft OAuth Authorization Code flow (oauth_connect_microsoft_mail) with state generation/validation prep.
- Added handler to test OAuth token refresh from admin UI and persist refreshed tokens/expiry.
- Updated IMAP test handler to support OAuth token refresh + XOAUTH2 authentication (in addition to legacy LOGIN).
2026-02-04 13:23:53 +00:00
cs2000
6b6d847756 Changes for M365 oAuth
- Added web-based Microsoft OAuth onboarding UI in Mail settings, including a Connect Microsoft 365 button and auto-generated callback URI display.
- Added Test OAuth Token Refresh UI section.
- Updated visibility logic so Test Email Sending and Test IMAP Connection show correctly for OAuth-based configs (not only host/password configs).
2026-02-04 13:23:03 +00:00
johnnyq
65d1f59e9b Feature: Favorites added to assets, Bulk Fav/unfav, adds favs to client overview 2026-02-03 22:23:20 -05:00
johnnyq
f39e6ccbc9 Remove old ticket merge code, rename kanban_v2 to to just kanban 2026-02-03 17:20:19 -05:00
johnnyq
747b62d78c Remove extra double quote 2026-02-03 17:09:07 -05:00
johnnyq
af0f3ac25f Update ticket Merge bulk with a dropdown select box to select a ticket instead of entering a number manually 2026-02-03 16:35:20 -05:00
johnnyq
6aefe99c2f Update ticket Merge with a dropdown select box to select a ticket instead of entering a number manually 2026-02-03 16:08:33 -05:00
johnnyq
61c5595a68 Fix Get type on add asset 2026-02-02 16:05:38 -05:00
johnnyq
3d11611699 Attempt to Fix duplicate data entries by fast clicking submit in modals using ajax_modal.js include 2026-01-31 15:14:01 -05:00
johnnyq
38b4ed4b96 Tidy check_login for client portal 2026-01-30 14:24:34 -05:00
johnnyq
34308a5f9a check if archived and active for client login as well along with loading extended client user session vars in /client/includes/check_login.php 2026-01-30 14:10:59 -05:00
johnnyq
118cc10804 During load user session check if user is archived and active, prevents users from making further actions if they are disabled or archived but are still logged in 2026-01-30 13:36:18 -05:00
johnnyq
ae3386f2d5 Fix Vendor phone formatting in Ticket details 2026-01-29 16:36:10 -05:00
johnnyq
bf1ccc62f5 Fix Collected Tax Report, was not adding totals OCT-Dec was misaligned and Grand Total wasnt displaying 2026-01-29 14:02:50 -05:00
johnnyq
1ce4dd932e Updated PL report - changed Gross Profit to Gross Revenue as is more accurate for taxation 2026-01-29 13:55:09 -05:00
johnnyq
ff0bb49926 Tidy up Ticket to Invoice Description 2026-01-29 13:13:24 -05:00
johnnyq
018642cbb8 Fix Ticket View / filtering 2026-01-28 23:33:12 -05:00
johnnyq
bf1d0655c4 Update Ticket list ui smaller badge for ticket and smaller task progress bar and more natural dates 2026-01-28 22:52:56 -05:00
johnnyq
874b07f4d7 More UI/UX updated to ticket details shrink padding on right cards, update wordings, changed header paddings, made unassigned a clickable badge no longer red, swapped trash cans for times icons, much cleaner overall 2026-01-28 22:06:50 -05:00
johnnyq
19fa210743 Merge branch 'develop' of github.com:itflow-org/itflow into develop 2026-01-28 18:16:54 -05:00
johnnyq
c8a6513d1c Fix new times on new date time displays in ticket details 2026-01-28 18:16:38 -05:00
wrongecho
01288c8452 Merge branch 'develop' of https://github.com/itflow-org/itflow into develop 2026-01-28 23:10:54 +00:00
johnnyq
a60d3bb3a0 More Ticket Details UI/UX Sprucing better label naming etc 2026-01-28 17:41:14 -05:00
johnnyq
0470159c55 Added function formatDuration to format times like worked etc, updated Time worked in Ticket details to use the new function and some other minor ui/ux cleanups in ticket details 2026-01-28 16:08:39 -05:00
wrongecho
e1a93035fd Undo client scoping uses = instead of LIKE in tickets resolve.php --- see forum thread 2667 2026-01-28 14:57:28 +00:00
wrongecho
c0b7a26905 API bugfixes before release:
- apiEncryptLoginEntry should be apiEncryptCredentialEntry
- Client scoping uses = instead of LIKE in tickets resolve.php
2026-01-28 14:48:41 +00:00
johnnyq
704d770ec2 Fix Icon to Chevron down if Expand all folders is clicked 2026-01-27 16:32:17 -05:00
johnnyq
d42d2d99b1 Remember folders expanded by Passing folders_expanded var in breadcrumb links and search in files 2026-01-27 16:27:04 -05:00
johnnyq
ebfcc15927 Feature: File Folders are collapsed by default with a global option to exapand all folders or expand individual folder by click 2026-01-27 16:15:18 -05:00
johnnyq
4693aa3c93 Render root in display_folders function in files instead of it being seperate 2026-01-27 15:25:20 -05:00
wrongecho
07df657848 Bugfix: newline char showing in parsed emails 2026-01-27 17:25:53 +00:00
wrongecho
ef9436a1fb Bugfix: Ticket edit modal not setting assigned agent 2026-01-27 12:32:41 +00:00
johnnyq
9318f42ce0 Remove Folder option in edit document modal as this is reserved for move to folder modal 2026-01-24 01:37:00 -05:00
johnnyq
85c37d78a8 Do not update document_updated_at field if document is moved, toggle visibity, renamed, archived or restored same with bulk 2026-01-24 01:27:50 -05:00
johnnyq
ff02ab0cea Show Document Updated at instead of created at. This fixes where it should show the initial document creation date instead of the most updated date, also renamed uploaded column to updated 2026-01-23 13:06:06 -05:00
johnnyq
bd8bf026f0 Allow svg email attachemment for mail parser 2026-01-23 11:24:26 -05:00
johnnyq
644dc95380 Merge branch 'develop' of github.com:itflow-org/itflow into develop 2026-01-21 12:40:43 -05:00
johnnyq
f4935efed3 Remove deprecated quick adds to the client overview 2026-01-21 12:40:30 -05:00
wrongecho
1712d34846 Kanban - move to v2 (rewritten style) 2026-01-21 13:15:23 +00:00
johnnyq
f0f1134be6 Fix phone number formatting is both asset details page and modal 2026-01-19 17:26:40 -05:00
johnnyq
e0f7460e08 If not client_id then do not include &client_id= in ticket uris as this would cause ticket viewing to break if client_id is 0. 2026-01-19 17:01:38 -05:00
johnnyq
ae1d71dcd7 append client_id to the uri for agent ticket links so that the when clicked will take them to the client section and show client header along with the bread crumbs link of client tickets 2026-01-19 16:24:31 -05:00
johnnyq
3cfe38c948 updated UI for contact details so menu is on the left instead of top. Also load the first tab based off the count 2026-01-17 17:35:05 -05:00
johnnyq
c1f0b63101 Fix login not passing master key if agent is client and agent and if MFA is enabled 2026-01-17 17:07:22 -05:00
johnnyq
0a658d7cab Fix Document Update API 2026-01-17 13:17:17 -05:00
johnnyq
3ed2582a9b Remove TaxID from packing slip 2026-01-15 14:09:03 -05:00
johnnyq
2ea68776f6 Merge branch 'develop' of github.com:itflow-org/itflow into develop 2026-01-15 13:13:25 -05:00
johnnyq
c1ff22298f Remove xcustom from .gitignore as its been superceded by custom 2026-01-15 13:13:15 -05:00
wrongecho
e94d2f93ea Merge branch 'develop' of https://github.com/itflow-org/itflow into develop 2026-01-15 17:35:35 +00:00
wrongecho
e7f6f8a4c7 Mail Parser - NDR Parsing 2026-01-15 17:35:13 +00:00
johnnyq
4ffe75683b Merge branch 'develop' of github.com:itflow-org/itflow into develop 2026-01-15 12:28:34 -05:00
johnnyq
687920743d Fix user_id not being set in audit logs for agent and client logins, also fix issie where user_id wasnt being set in client portal. 2026-01-15 12:28:20 -05:00
wrongecho
1a93149643 Basic asset history tracking (transfers) - See https://tasks.dev.itflow.org/task_details.php?task_id=19 2026-01-15 14:58:23 +00:00
wrongecho
11d6654763 Basic asset history tracking - See https://tasks.dev.itflow.org/task_details.php?task_id=19 2026-01-15 14:49:41 +00:00
wrongecho
512d65c17a Keep asset PO/ref when copying 2026-01-15 14:22:22 +00:00
wrongecho
5a274061f3 Invoice - add a basic picking/packaging slip 2026-01-15 13:58:53 +00:00
wrongecho
a398ac7a8d Mail Parser - Support flowed text 2026-01-15 11:54:37 +00:00
wrongecho
41df4c4b9f API Keys - Revoke then Delete 2026-01-15 11:37:17 +00:00
wrongecho
7e7909cec1 Mail Parser - Do not automatically send new ticket notifications to noreply/donotreply addresses 2026-01-15 10:38:25 +00:00
wrongecho
7322bd66df Invoices - Show agent names in history 2026-01-15 10:19:56 +00:00
wrongecho
39affa5528 Show trips on main nav for everyone if accounting enabled 2026-01-15 10:04:48 +00:00
wrongecho
374111c88d Add digiBandit as sponsor 2026-01-15 09:28:52 +00:00
wrongecho
72fc0015bf Add digiBandit as sponsor 2026-01-15 09:28:03 +00:00
johnnyq
7ab406b3f5 Convert mysqli_fetch_assoc to mysqli_fetch_row in setup for table import 2026-01-14 18:02:11 -05:00
johnnyq
df280cd574 Fix missing isset in view in tickets.php 2026-01-14 17:36:06 -05:00
johnnyq
0a30300bde replace all instances of mysqli_fetch_array with mysqli_fetch_assoc for better performance and memory usage 2026-01-14 17:30:23 -05:00
johnnyq
cb8b99d6ae up the permissions to added edit Payment 2026-01-12 18:12:20 -05:00
johnnyq
1d3f29d385 added edit Payment 2026-01-12 18:11:41 -05:00
johnnyq
c154113474 Do not add Signature on ticket comment if Public only when reply is emailed 2026-01-12 15:18:22 -05:00
johnnyq
e02a6fc5e6 Use mysqli_fetch_assoc in login 2026-01-12 12:30:12 -05:00
johnnyq
78040573d1 Fix Remove Powered by ITFlow on Login Screen when WhiteLabel is enabled 2026-01-12 12:27:44 -05:00
wrongecho
981f9ace04 TinyMCE - add all options to mobile (we may regret this) 2026-01-12 16:12:06 +00:00
wrongecho
208f7ac8f0 Tickets Kanban
- Keep the selected view (kanban/list) when applying other filters
- Allow filtering tickets by project (main and kanban v2)
2026-01-12 16:11:36 +00:00
wrongecho
661f8db10b Tickets Kanban
- Keep the selected view (kanban/list) when applying other filters
- Allow filtering tickets by project (main and kanban v2)
2026-01-12 16:04:02 +00:00
wrongecho
b48168ffec Rewrite kanban in more procedural code to match existing codebase (as a v2, delete old and rename once we're happy) 2026-01-12 15:36:06 +00:00
wrongecho
908ebb46d9 Merge pull request #1258 from itflow-org/ticket-task-approvals
Ticket task approvals
2026-01-12 12:27:24 +00:00
johnnyq
1de023f9df Fix Role Archiving, Roles can only be archived if no users are assigned to the role 2026-01-11 16:46:53 -05:00
johnnyq
5815ef2f75 Added bulk delete, archive and restore and invidual file/document restore functions to files 2026-01-10 20:38:04 -05:00
johnnyq
e5dab8b1ca Update files to use mysqli_fetch_assoc for better performance and memory optimization. Add title for List View and Grid View 2026-01-10 19:12:22 -05:00
johnnyq
56c4b7fbe6 Add show archived logic to files 2026-01-10 19:03:28 -05:00
johnnyq
365b65e5b2 fix Bulk Delete Documents and Files 2026-01-10 16:27:12 -05:00
johnnyq
2193cd8d3e switched from mysqli_fetch_array to mysqli_fetch_assoc in client modals 2026-01-10 16:09:03 -05:00
johnnyq
8b221bc055 switched from mysqli_fetch_array to mysqli_fetch_assoc in clients listing page. This will have a major query speed and memory optimization impact 2026-01-10 15:54:19 -05:00
Johnny
163aa3062e Merge pull request #1254 from itflow-org/develop
Develop to Master for 25.12.1 Maint Release
2025-12-14 14:03:56 -05:00
Johnny
03570ecd04 Merge pull request #1250 from itflow-org/develop
Develop to Master for 25.12 release
2025-12-06 14:36:09 -05:00
Johnny
c7ef3627ce Merge pull request #1247 from itflow-org/develop
Merge Develop into Master for v25.11.1 release
2025-11-17 12:22:24 -05:00
Johnny
d1dcc5fb7e Merge pull request #1246 from itflow-org/develop
Develop to Master for Release
2025-11-08 13:47:43 -05:00
431 changed files with 10976 additions and 8074 deletions

6
.gitignore vendored
View File

@@ -32,10 +32,6 @@ plugins/htmlpurifier/standalone/HTMLPurifier/DefinitionCache/Serializer/URI/*
plugins/htmlpurifier/standalone/HTMLPurifier/DefinitionCache/Serializer/CSS/* plugins/htmlpurifier/standalone/HTMLPurifier/DefinitionCache/Serializer/CSS/*
!plugins/htmlpurifier/standalone/HTMLPurifier/DefinitionCache/Serializer/CSS/.gitkeep !plugins/htmlpurifier/standalone/HTMLPurifier/DefinitionCache/Serializer/CSS/.gitkeep
.vscode/settings.json .vscode/settings.json
xcustom/*
!xcustom/readme.php
post/xcustom
!post/xcustom/readme.php
admin/custom/* admin/custom/*
!admin/custom/readme.php !admin/custom/readme.php
agent/custom/* agent/custom/*
@@ -53,5 +49,3 @@ setup/custom/*
api/v1/custom/* api/v1/custom/*
!api/v1/custom/readme.php !api/v1/custom/readme.php
.zed .zed

View File

@@ -2,6 +2,73 @@
This file documents all notable changes made to ITFlow. This file documents all notable changes made to ITFlow.
## [26.02.1] Maint Release
### Bug Fixes
- Credentials: Fix Password Generator.
- Calendar: Restrict Events for client restricted agents.
- Ticket Merge: Fix.
- Asset Transfer: Fix.
- Ticket Listing: Restrict Tickets presented in ticket list view from client restricted agents.
- Ticket Details: Deny access to client restricted agents to view tickets without client_id in uri.
- Tickets: Allow agents with restricted client access to view and edit tickets without a client.
- Ticket Change client: Limit selection for agents with restricted client access.
- Ticket Details: Don't display Updated at when null.
### New Features & Updates
- Report: Added Client Detail Auditing.
- API: Added Endpoint to retrieve time worked by agent.
- ajax-modal: Revert to previous JS implementation before 26.02 release.
- Ticket: Move Subject from Ticket main ticket header to ticket details card header.
## [26.02] Stable Release
### Bug Fixes
- Mail Parser - Do not automatically send new ticket notifications to noreply/donotreply addresses.
- Ticket: removed newline \n on Parsed emails.
- Show Trips for everyone if accounting module is enabled.
- Fix Invoice Exporting.
- Fix Billable Column not sorting correctly in tickets.
- Fix Login flow where user agent and client user exists and agent has MFA but will not let them continue.
- Fix passing missing user_id var in client portal.
- Fix Ticket Templates not auto filling when selected.
- Fix Invoices not being sent to all billings contacts when manaully sent.
- Fix Documents and Files not able to be bulk deleted.
- Fix Role Archiving, can be archived as long as no users are assigned to the role.
- Fix showing Powered By ITFlow visibility on the login screen when Whitelabel is enabled.
- Missing username in audit log on successful login due to missing passed user_id to logging.
- API: Fix updating all documents instead of the intended document.
- Documents: Fix Document created at not showing the correct creation date of the master document.
- Ticket: Fixed Using edit ticket modal agent was not able to be set.
- Always check if a user is archived and or disabled instead of just during login.
- Report: Fix Collected tax report not totalling all tax categories.
### New Features & Updates
- Task Approval System for ticket tasks: Once an approval is requested, the task cannot be marked as complete until approved. Internal Approvals Any other technician, or Specific technician, Client Approvals Anyone (usually the requestor) Tech contacts Billing contacts.
- Printable Invoice Packing Slips now available.
- Drastic Performance Bump: Up to 50% faster queries accross the board and reduced server memory usage by 40% by switching Database Query method from mysqli_fetch_array to mysqli_fetch_assoc.
- Added Connect to Microsoft 365 Button to mail settings.
- OAUTH2 support for Microsoft 365 and Google Workspaces is now considered stable and working.
- Favorites: Assets and Credentials now can be favorited singly or by Bulk action. Favorited items appear in the client overview now.
- Files/Documents: Collapsable folders feature, collapsed by default with a button to expand all.
- URL Keys and such are now set to a more manageable 32 Characters by default.
- Various UI/UX Updates throughout the app, with focus oin ticket details, contact details modal etc.
- Added Show Archived files and documents to the files section.
- Added Bulk Archive and restore options to files and documents.
- Rewrite of the Kanban Ticket view to match our procedural style of coding.
- All options are available in TinyMCE now in Mobile mode.
- Agent names appear now in Invoice History section.
- Mail Parser: Support flowed text.
- Assets: Keep Purchase reference when copying.
- Assets: Add basic tracking history: Archiving, restoring, name changes, transferimg to new clients.
- Mail Parser: NDR Parsing.
- Allow SVG files in mail attachments.
- Tickets: Use a more friendly time worked instead of 02:41:00 translates to 2h 41m.
- Update wording on ticket to invoice item details.
- Merge Tickets: Now wth a ticket merge dropdown list of tickets instead of a text field.
- Role Permissions can now be set during role creation, update Permission UI to use radio buttons instead of select boxes.
- Bump TinyMCE 8.2.2 to 8.3.2.
- Bump PHPMailer from 7.0.1 to 7.0.2.
- Bump Datatables from 2.3.4 to 2.3.7.
## [25.12.1] Maint Release ## [25.12.1] Maint Release
### Major Changes ### Major Changes

View File

@@ -93,6 +93,7 @@ If you want to improve ITFlow, feel free to fork the repo and create a pull requ
Were incredibly grateful to the organizations and individuals who support the project - a big thank you to: Were incredibly grateful to the organizations and individuals who support the project - a big thank you to:
- CompuMatter - CompuMatter
- F1 for HELP - F1 for HELP
- digiBandit
- JetBrains (PhpStorm) - JetBrains (PhpStorm)
## License ## License

View File

@@ -58,7 +58,7 @@ $num_rows = mysqli_num_rows($sql);
<tbody> <tbody>
<?php <?php
while ($row = mysqli_fetch_array($sql)) { while ($row = mysqli_fetch_assoc($sql)) {
$provider_id = intval($row['ai_provider_id']); $provider_id = intval($row['ai_provider_id']);
$provider_name = nullable_htmlentities($row['ai_provider_name']); $provider_name = nullable_htmlentities($row['ai_provider_name']);
$model_id = intval($row['ai_model_id']); $model_id = intval($row['ai_model_id']);

View File

@@ -48,7 +48,7 @@ $num_rows = mysqli_num_rows($sql);
<tbody> <tbody>
<?php <?php
while ($row = mysqli_fetch_array($sql)) { while ($row = mysqli_fetch_assoc($sql)) {
$provider_id = intval($row['ai_provider_id']); $provider_id = intval($row['ai_provider_id']);
$provider_name = nullable_htmlentities($row['ai_provider_name']); $provider_name = nullable_htmlentities($row['ai_provider_name']);
$url = nullable_htmlentities($row['ai_provider_api_url']); $url = nullable_htmlentities($row['ai_provider_api_url']);

View File

@@ -49,7 +49,7 @@ $num_rows = mysqli_fetch_row(mysqli_query($mysqli, "SELECT FOUND_ROWS()"));
<div class="dropdown-menu"> <div class="dropdown-menu">
<button class="dropdown-item text-danger text-bold" <button class="dropdown-item text-danger text-bold"
type="submit" form="bulkActions" name="bulk_delete_api_keys"> type="submit" form="bulkActions" name="bulk_delete_api_keys">
<i class="fas fa-fw fa-trash mr-2"></i>Revoke <i class="fas fa-fw fa-trash mr-2"></i>Delete
</button> </button>
</div> </div>
</div> </div>
@@ -105,7 +105,7 @@ $num_rows = mysqli_fetch_row(mysqli_query($mysqli, "SELECT FOUND_ROWS()"));
<tbody> <tbody>
<?php <?php
while ($row = mysqli_fetch_array($sql)) { while ($row = mysqli_fetch_assoc($sql)) {
$api_key_id = intval($row['api_key_id']); $api_key_id = intval($row['api_key_id']);
$api_key_name = nullable_htmlentities($row['api_key_name']); $api_key_name = nullable_htmlentities($row['api_key_name']);
$api_key_secret = nullable_htmlentities("************" . substr($row['api_key_secret'], -4)); $api_key_secret = nullable_htmlentities("************" . substr($row['api_key_secret'], -4));
@@ -139,9 +139,16 @@ $num_rows = mysqli_fetch_row(mysqli_query($mysqli, "SELECT FOUND_ROWS()"));
<i class="fas fa-ellipsis-h"></i> <i class="fas fa-ellipsis-h"></i>
</button> </button>
<div class="dropdown-menu"> <div class="dropdown-menu">
<a class="dropdown-item text-danger text-bold confirm-link" href="post.php?delete_api_key=<?php echo $api_key_id; ?>&csrf_token=<?php echo $_SESSION['csrf_token'] ?>"> <?php if ($api_key_expire > date("Y-m-d H:i:s")) { ?>
<a class="dropdown-item text-danger text-bold confirm-link" href="post.php?revoke_api_key=<?php echo $api_key_id; ?>&csrf_token=<?php echo $_SESSION['csrf_token'] ?>">
<i class="fas fa-fw fa-times mr-2"></i>Revoke <i class="fas fa-fw fa-times mr-2"></i>Revoke
</a> </a>
<?php } ?>
<?php if ($api_key_expire < date("Y-m-d H:i:s")) { ?>
<a class="dropdown-item text-danger text-bold confirm-link" href="post.php?delete_api_key=<?php echo $api_key_id; ?>&csrf_token=<?php echo $_SESSION['csrf_token'] ?>">
<i class="fas fa-fw fa-times mr-2"></i>Delete
</a>
<?php } ?>
</div> </div>
</div> </div>
</td> </td>
@@ -164,4 +171,3 @@ $num_rows = mysqli_fetch_row(mysqli_query($mysqli, "SELECT FOUND_ROWS()"));
<?php <?php
require_once "../includes/footer.php"; require_once "../includes/footer.php";

View File

@@ -66,7 +66,7 @@ $num_rows = mysqli_fetch_row(mysqli_query($mysqli, "SELECT FOUND_ROWS()"));
<?php <?php
$sql_types_filter = mysqli_query($mysqli, "SELECT DISTINCT app_log_type FROM app_logs ORDER BY app_log_type ASC"); $sql_types_filter = mysqli_query($mysqli, "SELECT DISTINCT app_log_type FROM app_logs ORDER BY app_log_type ASC");
while ($row = mysqli_fetch_array($sql_types_filter)) { while ($row = mysqli_fetch_assoc($sql_types_filter)) {
$log_type = nullable_htmlentities($row['app_log_type']); $log_type = nullable_htmlentities($row['app_log_type']);
?> ?>
<option <?php if ($type_filter == $log_type) { echo "selected"; } ?>><?php echo $log_type; ?></option> <option <?php if ($type_filter == $log_type) { echo "selected"; } ?>><?php echo $log_type; ?></option>
@@ -85,7 +85,7 @@ $num_rows = mysqli_fetch_row(mysqli_query($mysqli, "SELECT FOUND_ROWS()"));
<?php <?php
$sql_categories_filter = mysqli_query($mysqli, "SELECT DISTINCT app_log_category FROM app_logs ORDER BY app_log_category ASC"); $sql_categories_filter = mysqli_query($mysqli, "SELECT DISTINCT app_log_category FROM app_logs ORDER BY app_log_category ASC");
while ($row = mysqli_fetch_array($sql_categories_filter)) { while ($row = mysqli_fetch_assoc($sql_categories_filter)) {
$log_category = nullable_htmlentities($row['app_log_category']); $log_category = nullable_htmlentities($row['app_log_category']);
?> ?>
<option <?php if ($category_filter == $log_category) { echo "selected"; } ?>><?php echo $log_category; ?></option> <option <?php if ($category_filter == $log_category) { echo "selected"; } ?>><?php echo $log_category; ?></option>
@@ -141,7 +141,7 @@ $num_rows = mysqli_fetch_row(mysqli_query($mysqli, "SELECT FOUND_ROWS()"));
<tbody> <tbody>
<?php <?php
while ($row = mysqli_fetch_array($sql)) { while ($row = mysqli_fetch_assoc($sql)) {
$log_id = intval($row['app_log_id']); $log_id = intval($row['app_log_id']);
$log_type = nullable_htmlentities($row['app_log_type']); $log_type = nullable_htmlentities($row['app_log_type']);
$log_category = nullable_htmlentities($row['app_log_category']); $log_category = nullable_htmlentities($row['app_log_category']);

View File

@@ -88,7 +88,7 @@ $num_rows = mysqli_fetch_row(mysqli_query($mysqli, "SELECT FOUND_ROWS()"));
<?php <?php
$sql_clients_filter = mysqli_query($mysqli, "SELECT * FROM clients ORDER BY client_name ASC"); $sql_clients_filter = mysqli_query($mysqli, "SELECT * FROM clients ORDER BY client_name ASC");
while ($row = mysqli_fetch_array($sql_clients_filter)) { while ($row = mysqli_fetch_assoc($sql_clients_filter)) {
$client_id = intval($row['client_id']); $client_id = intval($row['client_id']);
$client_name = nullable_htmlentities($row['client_name']); $client_name = nullable_htmlentities($row['client_name']);
?> ?>
@@ -108,7 +108,7 @@ $num_rows = mysqli_fetch_row(mysqli_query($mysqli, "SELECT FOUND_ROWS()"));
<?php <?php
$sql_users_filter = mysqli_query($mysqli, "SELECT * FROM users ORDER BY user_name ASC"); $sql_users_filter = mysqli_query($mysqli, "SELECT * FROM users ORDER BY user_name ASC");
while ($row = mysqli_fetch_array($sql_users_filter)) { while ($row = mysqli_fetch_assoc($sql_users_filter)) {
$user_id = intval($row['user_id']); $user_id = intval($row['user_id']);
$user_name = nullable_htmlentities($row['user_name']); $user_name = nullable_htmlentities($row['user_name']);
?> ?>
@@ -128,7 +128,7 @@ $num_rows = mysqli_fetch_row(mysqli_query($mysqli, "SELECT FOUND_ROWS()"));
<?php <?php
$sql_types_filter = mysqli_query($mysqli, "SELECT DISTINCT log_type FROM logs ORDER BY log_type ASC"); $sql_types_filter = mysqli_query($mysqli, "SELECT DISTINCT log_type FROM logs ORDER BY log_type ASC");
while ($row = mysqli_fetch_array($sql_types_filter)) { while ($row = mysqli_fetch_assoc($sql_types_filter)) {
$log_type = nullable_htmlentities($row['log_type']); $log_type = nullable_htmlentities($row['log_type']);
?> ?>
<option <?php if ($type_filter == $log_type) { echo "selected"; } ?>><?php echo $log_type; ?></option> <option <?php if ($type_filter == $log_type) { echo "selected"; } ?>><?php echo $log_type; ?></option>
@@ -147,7 +147,7 @@ $num_rows = mysqli_fetch_row(mysqli_query($mysqli, "SELECT FOUND_ROWS()"));
<?php <?php
$sql_actions_filter = mysqli_query($mysqli, "SELECT DISTINCT log_action FROM logs ORDER BY log_action ASC"); $sql_actions_filter = mysqli_query($mysqli, "SELECT DISTINCT log_action FROM logs ORDER BY log_action ASC");
while ($row = mysqli_fetch_array($sql_actions_filter)) { while ($row = mysqli_fetch_assoc($sql_actions_filter)) {
$log_action = nullable_htmlentities($row['log_action']); $log_action = nullable_htmlentities($row['log_action']);
?> ?>
<option <?php if ($action_filter == $log_action) { echo "selected"; } ?>><?php echo $log_action; ?></option> <option <?php if ($action_filter == $log_action) { echo "selected"; } ?>><?php echo $log_action; ?></option>
@@ -225,7 +225,7 @@ $num_rows = mysqli_fetch_row(mysqli_query($mysqli, "SELECT FOUND_ROWS()"));
<tbody> <tbody>
<?php <?php
while ($row = mysqli_fetch_array($sql)) { while ($row = mysqli_fetch_assoc($sql)) {
$log_id = intval($row['log_id']); $log_id = intval($row['log_id']);
$log_type = nullable_htmlentities($row['log_type']); $log_type = nullable_htmlentities($row['log_type']);
$log_action = nullable_htmlentities($row['log_action']); $log_action = nullable_htmlentities($row['log_action']);
@@ -280,4 +280,3 @@ $num_rows = mysqli_fetch_row(mysqli_query($mysqli, "SELECT FOUND_ROWS()"));
<?php <?php
require_once "../includes/footer.php"; require_once "../includes/footer.php";

View File

@@ -111,7 +111,7 @@ $num_rows = mysqli_fetch_row(mysqli_query($mysqli, "SELECT FOUND_ROWS()"));
<tbody> <tbody>
<?php <?php
while ($row = mysqli_fetch_array($sql)) { while ($row = mysqli_fetch_assoc($sql)) {
$category_id = intval($row['category_id']); $category_id = intval($row['category_id']);
$category_name = nullable_htmlentities($row['category_name']); $category_name = nullable_htmlentities($row['category_name']);
$category_color = nullable_htmlentities($row['category_color']); $category_color = nullable_htmlentities($row['category_color']);

View File

@@ -59,7 +59,7 @@ $num_rows = mysqli_fetch_row(mysqli_query($mysqli, "SELECT FOUND_ROWS()"));
</thead> </thead>
<tbody> <tbody>
<?php <?php
while ($row = mysqli_fetch_array($sql)) { while ($row = mysqli_fetch_assoc($sql)) {
$id = intval($row['contract_template_id']); $id = intval($row['contract_template_id']);
$name = nullable_htmlentities($row['contract_template_name']); $name = nullable_htmlentities($row['contract_template_name']);
$type = nullable_htmlentities($row['contract_template_type']); $type = nullable_htmlentities($row['contract_template_type']);

View File

@@ -72,7 +72,7 @@ $num_rows = mysqli_fetch_row(mysqli_query($mysqli, "SELECT FOUND_ROWS()"));
<tbody> <tbody>
<?php <?php
while ($row = mysqli_fetch_array($sql)) { while ($row = mysqli_fetch_assoc($sql)) {
$custom_link_id = intval($row['custom_link_id']); $custom_link_id = intval($row['custom_link_id']);
$custom_link_name = nullable_htmlentities($row['custom_link_name']); $custom_link_name = nullable_htmlentities($row['custom_link_name']);
$custom_link_uri = nullable_htmlentities($row['custom_link_uri']); $custom_link_uri = nullable_htmlentities($row['custom_link_uri']);

View File

@@ -791,7 +791,7 @@ if (LATEST_DATABASE_VERSION > CURRENT_DATABASE_VERSION) {
// Copy primary_location and primary_contact to their new vars in their own respecting tables // Copy primary_location and primary_contact to their new vars in their own respecting tables
$sql = mysqli_query($mysqli, "SELECT * FROM clients"); $sql = mysqli_query($mysqli, "SELECT * FROM clients");
while($row = mysqli_fetch_array($sql)) { while($row = mysqli_fetch_assoc($sql)) {
$primary_contact = $row['primary_contact']; $primary_contact = $row['primary_contact'];
$primary_location = $row['primary_location']; $primary_location = $row['primary_location'];
@@ -1666,7 +1666,7 @@ if (LATEST_DATABASE_VERSION > CURRENT_DATABASE_VERSION) {
if (CURRENT_DATABASE_VERSION == '1.3.9') { if (CURRENT_DATABASE_VERSION == '1.3.9') {
// Migrate all Network Info from Assets to Interface Table and make it primary interface // Migrate all Network Info from Assets to Interface Table and make it primary interface
$sql = mysqli_query($mysqli, "SELECT * FROM assets"); $sql = mysqli_query($mysqli, "SELECT * FROM assets");
while ($row = mysqli_fetch_array($sql)) { while ($row = mysqli_fetch_assoc($sql)) {
$asset_id = intval($row['asset_id']); $asset_id = intval($row['asset_id']);
$mac = sanitizeInput($row['asset_mac']); $mac = sanitizeInput($row['asset_mac']);
$ip = sanitizeInput($row['asset_ip']); $ip = sanitizeInput($row['asset_ip']);
@@ -1945,7 +1945,7 @@ if (LATEST_DATABASE_VERSION > CURRENT_DATABASE_VERSION) {
if (CURRENT_DATABASE_VERSION == '1.5.7') { if (CURRENT_DATABASE_VERSION == '1.5.7') {
// Create Users for contacts that have logins enabled and that are not archived // Create Users for contacts that have logins enabled and that are not archived
$contacts_sql = mysqli_query($mysqli, "SELECT * FROM `contacts` WHERE contact_archived_at IS NULL AND (contact_auth_method = 'local' OR contact_auth_method = 'azure')"); $contacts_sql = mysqli_query($mysqli, "SELECT * FROM `contacts` WHERE contact_archived_at IS NULL AND (contact_auth_method = 'local' OR contact_auth_method = 'azure')");
while($row = mysqli_fetch_array($contacts_sql)) { while($row = mysqli_fetch_assoc($contacts_sql)) {
$contact_id = intval($row['contact_id']); $contact_id = intval($row['contact_id']);
$contact_name = mysqli_real_escape_string($mysqli, $row['contact_name']); $contact_name = mysqli_real_escape_string($mysqli, $row['contact_name']);
$contact_email = mysqli_real_escape_string($mysqli, $row['contact_email']); $contact_email = mysqli_real_escape_string($mysqli, $row['contact_email']);
@@ -3853,7 +3853,7 @@ if (LATEST_DATABASE_VERSION > CURRENT_DATABASE_VERSION) {
// Get Current Stripe Settings // Get Current Stripe Settings
$sql_stripe_settings = mysqli_query($mysqli, "SELECT * FROM settings WHERE company_id = 1"); $sql_stripe_settings = mysqli_query($mysqli, "SELECT * FROM settings WHERE company_id = 1");
$row = mysqli_fetch_array($sql_stripe_settings); $row = mysqli_fetch_assoc($sql_stripe_settings);
$config_stripe_enable = intval($row['config_stripe_enable']); $config_stripe_enable = intval($row['config_stripe_enable']);
if ($config_stripe_enable === 1) { if ($config_stripe_enable === 1) {
$config_stripe_publishable = mysqli_real_escape_string($mysqli, $row['config_stripe_publishable']); $config_stripe_publishable = mysqli_real_escape_string($mysqli, $row['config_stripe_publishable']);
@@ -3879,7 +3879,7 @@ if (LATEST_DATABASE_VERSION > CURRENT_DATABASE_VERSION) {
// Migrate Clients and Payment Method over // Migrate Clients and Payment Method over
$sql_stripe_clients = mysqli_query($mysqli, "SELECT * FROM client_stripe WHERE stripe_pm IS NOT NULL AND stripe_pm != ''"); $sql_stripe_clients = mysqli_query($mysqli, "SELECT * FROM client_stripe WHERE stripe_pm IS NOT NULL AND stripe_pm != ''");
while ($row = mysqli_fetch_array($sql_stripe_clients)) { while ($row = mysqli_fetch_assoc($sql_stripe_clients)) {
$client_id = intval($row['client_id']); $client_id = intval($row['client_id']);
$stripe_id = mysqli_real_escape_string($mysqli, $row['stripe_id']); $stripe_id = mysqli_real_escape_string($mysqli, $row['stripe_id']);
$stripe_pm = mysqli_real_escape_string($mysqli, $row['stripe_pm']); $stripe_pm = mysqli_real_escape_string($mysqli, $row['stripe_pm']);
@@ -3932,7 +3932,7 @@ if (LATEST_DATABASE_VERSION > CURRENT_DATABASE_VERSION) {
// Migrate Payment Methods from Categories Table to new payment_methods table // Migrate Payment Methods from Categories Table to new payment_methods table
$sql_categories = mysqli_query($mysqli, "SELECT * FROM categories WHERE category_type = 'Payment Method' AND category_name != 'Stripe' AND category_archived_at IS NULL"); $sql_categories = mysqli_query($mysqli, "SELECT * FROM categories WHERE category_type = 'Payment Method' AND category_name != 'Stripe' AND category_archived_at IS NULL");
while ($row = mysqli_fetch_array($sql_categories)) { while ($row = mysqli_fetch_assoc($sql_categories)) {
$category_name = sanitizeInput($row['category_name']); $category_name = sanitizeInput($row['category_name']);
mysqli_query($mysqli,"INSERT INTO payment_methods SET payment_method_name = '$category_name'"); mysqli_query($mysqli,"INSERT INTO payment_methods SET payment_method_name = '$category_name'");
@@ -4154,10 +4154,49 @@ if (LATEST_DATABASE_VERSION > CURRENT_DATABASE_VERSION) {
mysqli_query($mysqli, "UPDATE `settings` SET `config_current_database_version` = '2.3.9'"); mysqli_query($mysqli, "UPDATE `settings` SET `config_current_database_version` = '2.3.9'");
} }
// if (CURRENT_DATABASE_VERSION == '2.3.9') { if (CURRENT_DATABASE_VERSION == '2.3.9') {
// // Insert queries here required to update to DB version 2.4.0 mysqli_query($mysqli, "ALTER TABLE `clients` ADD `client_favorite` TINYINT(1) NOT NULL DEFAULT '0' AFTER `client_notes`");
mysqli_query($mysqli, "ALTER TABLE `locations` ADD `location_favorite` TINYINT(1) NOT NULL DEFAULT '0' AFTER `location_notes`");
mysqli_query($mysqli, "ALTER TABLE `vendors` ADD `vendor_favorite` TINYINT(1) NOT NULL DEFAULT '0' AFTER `vendor_notes`");
mysqli_query($mysqli, "ALTER TABLE `software` ADD `software_favorite` TINYINT(1) NOT NULL DEFAULT '0' AFTER `software_notes`");
mysqli_query(
$mysqli,
"ALTER TABLE `credentials`
CHANGE `credential_important` `credential_favorite`
TINYINT(1) NOT NULL DEFAULT 0
AFTER `credential_note`"
);
mysqli_query($mysqli, "ALTER TABLE `assets` DROP `asset_important`");
mysqli_query($mysqli, "ALTER TABLE `assets` ADD `asset_favorite` TINYINT(1) NOT NULL DEFAULT '0' AFTER `asset_notes`");
mysqli_query($mysqli, "ALTER TABLE `documents` DROP `document_important`");
mysqli_query($mysqli, "ALTER TABLE `documents` ADD `document_favorite` TINYINT(1) NOT NULL DEFAULT '0' AFTER `document_client_visible`");
mysqli_query($mysqli, "ALTER TABLE `racks` ADD `rack_favorite` TINYINT(1) NOT NULL DEFAULT '0' AFTER `rack_notes`");
mysqli_query($mysqli, "ALTER TABLE `files` DROP `file_important`");
mysqli_query($mysqli, "ALTER TABLE `files` ADD `file_favorite` TINYINT(1) NOT NULL DEFAULT '0' AFTER `file_mime_type`");
mysqli_query($mysqli, "ALTER TABLE `networks` ADD `network_favorite` TINYINT(1) NOT NULL DEFAULT '0' AFTER `network_notes`");
mysqli_query($mysqli, "ALTER TABLE `domains` ADD `domain_favorite` TINYINT(1) NOT NULL DEFAULT '0' AFTER `domain_notes`");
mysqli_query($mysqli, "ALTER TABLE `certificates` ADD `certificate_favorite` TINYINT(1) NOT NULL DEFAULT '0' AFTER `certificate_notes`");
mysqli_query($mysqli, "ALTER TABLE `services` ADD `service_favorite` TINYINT(1) NOT NULL DEFAULT '0' AFTER `service_notes`");
mysqli_query($mysqli, "UPDATE `settings` SET `config_current_database_version` = '2.4.0'");
}
// if (CURRENT_DATABASE_VERSION == '2.4.0') {
// // Insert queries here required to update to DB version 2.4.1
// // 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` = '2.4.0'"); // mysqli_query($mysqli, "UPDATE `settings` SET `config_current_database_version` = '2.4.1'");
// } // }
} else { } else {

View File

@@ -66,7 +66,7 @@
<tbody> <tbody>
<?php <?php
while ($row = mysqli_fetch_array($sql)) { while ($row = mysqli_fetch_assoc($sql)) {
$document_template_id = intval($row['document_template_id']); $document_template_id = intval($row['document_template_id']);
$document_template_name = nullable_htmlentities($row['document_template_name']); $document_template_name = nullable_htmlentities($row['document_template_name']);
$document_template_description = nullable_htmlentities($row['document_template_description']); $document_template_description = nullable_htmlentities($row['document_template_description']);

View File

@@ -23,7 +23,7 @@ if (mysqli_num_rows($sql_document) == 0) {
exit(); exit();
} }
$row = mysqli_fetch_array($sql_document); $row = mysqli_fetch_assoc($sql_document);
$document_template_name = nullable_htmlentities($row['document_template_name']); $document_template_name = nullable_htmlentities($row['document_template_name']);
$document_template_description = nullable_htmlentities($row['document_template_description']); $document_template_description = nullable_htmlentities($row['document_template_description']);

View File

@@ -293,7 +293,7 @@
ORDER BY custom_link_order ASC, custom_link_name ASC" ORDER BY custom_link_order ASC, custom_link_name ASC"
); );
while ($row = mysqli_fetch_array($sql_custom_links)) { while ($row = mysqli_fetch_assoc($sql_custom_links)) {
$custom_link_name = nullable_htmlentities($row['custom_link_name']); $custom_link_name = nullable_htmlentities($row['custom_link_name']);
$custom_link_uri = sanitize_url($row['custom_link_uri']); $custom_link_uri = sanitize_url($row['custom_link_uri']);
$custom_link_icon = nullable_htmlentities($row['custom_link_icon']); $custom_link_icon = nullable_htmlentities($row['custom_link_icon']);

View File

@@ -116,7 +116,7 @@ $num_rows = mysqli_fetch_row(mysqli_query($mysqli, "SELECT FOUND_ROWS()"));
<tbody> <tbody>
<?php <?php
while ($row = mysqli_fetch_array($sql)) { while ($row = mysqli_fetch_assoc($sql)) {
$email_id = intval($row['email_id']); $email_id = intval($row['email_id']);
$email_from = nullable_htmlentities($row['email_from']); $email_from = nullable_htmlentities($row['email_from']);
$email_from_name = nullable_htmlentities($row['email_from_name']); $email_from_name = nullable_htmlentities($row['email_from_name']);

View File

@@ -27,7 +27,7 @@ ob_start();
<option value="">- Select an AI Provider -</option> <option value="">- Select an AI Provider -</option>
<?php <?php
$sql_ai_providers = mysqli_query($mysqli, "SELECT * FROM ai_providers"); $sql_ai_providers = mysqli_query($mysqli, "SELECT * FROM ai_providers");
while ($row = mysqli_fetch_array($sql_ai_providers)) { while ($row = mysqli_fetch_assoc($sql_ai_providers)) {
$ai_provider_id = intval($row['ai_provider_id']); $ai_provider_id = intval($row['ai_provider_id']);
$ai_provider_name = nullable_htmlentities($row['ai_provider_name']); $ai_provider_name = nullable_htmlentities($row['ai_provider_name']);

View File

@@ -6,7 +6,7 @@ $model_id = intval($_GET['id']);
$sql = mysqli_query($mysqli, "SELECT * FROM ai_models WHERE ai_model_id = $model_id LIMIT 1"); $sql = mysqli_query($mysqli, "SELECT * FROM ai_models WHERE ai_model_id = $model_id LIMIT 1");
$row = mysqli_fetch_array($sql); $row = mysqli_fetch_assoc($sql);
$ai_model_ai_provider_id = intval($row['ai_model_ai_provider_id']); $ai_model_ai_provider_id = intval($row['ai_model_ai_provider_id']);
$model_id = intval($row['ai_model_id']); $model_id = intval($row['ai_model_id']);
$model_name = nullable_htmlentities($row['ai_model_name']); $model_name = nullable_htmlentities($row['ai_model_name']);
@@ -39,7 +39,7 @@ ob_start();
<option value="">- Select an AI Provider -</option> <option value="">- Select an AI Provider -</option>
<?php <?php
$sql_ai_providers = mysqli_query($mysqli, "SELECT * FROM ai_providers"); $sql_ai_providers = mysqli_query($mysqli, "SELECT * FROM ai_providers");
while ($row = mysqli_fetch_array($sql_ai_providers)) { while ($row = mysqli_fetch_assoc($sql_ai_providers)) {
$ai_provider_id = intval($row['ai_provider_id']); $ai_provider_id = intval($row['ai_provider_id']);
$ai_provider_name = nullable_htmlentities($row['ai_provider_name']); $ai_provider_name = nullable_htmlentities($row['ai_provider_name']);

View File

@@ -6,7 +6,7 @@ $provider_id = intval($_GET['id']);
$sql = mysqli_query($mysqli, "SELECT * FROM ai_providers WHERE ai_provider_id = $provider_id LIMIT 1"); $sql = mysqli_query($mysqli, "SELECT * FROM ai_providers WHERE ai_provider_id = $provider_id LIMIT 1");
$row = mysqli_fetch_array($sql); $row = mysqli_fetch_assoc($sql);
$provider_name = nullable_htmlentities($row['ai_provider_name']); $provider_name = nullable_htmlentities($row['ai_provider_name']);
$url = nullable_htmlentities($row['ai_provider_api_url']); $url = nullable_htmlentities($row['ai_provider_api_url']);
$key = nullable_htmlentities($row['ai_provider_api_key']); $key = nullable_htmlentities($row['ai_provider_api_key']);

View File

@@ -64,7 +64,7 @@ ob_start();
<option value="0"> ALL CLIENTS </option> <option value="0"> ALL CLIENTS </option>
<?php <?php
$sql = mysqli_query($mysqli, "SELECT client_id, client_name FROM clients WHERE client_archived_at IS NULL ORDER BY client_name ASC"); $sql = mysqli_query($mysqli, "SELECT client_id, client_name FROM clients WHERE client_archived_at IS NULL ORDER BY client_name ASC");
while ($row = mysqli_fetch_array($sql)) { while ($row = mysqli_fetch_assoc($sql)) {
$client_id = intval($row['client_id']); $client_id = intval($row['client_id']);
$client_name = nullable_htmlentities($row['client_name']); ?> $client_name = nullable_htmlentities($row['client_name']); ?>
<option value="<?php echo $client_id; ?>"><?php echo "$client_name (Client ID: $client_id)"; ?></option> <option value="<?php echo $client_id; ?>"><?php echo "$client_name (Client ID: $client_id)"; ?></option>

View File

@@ -6,7 +6,7 @@ $category_id = intval($_GET['id']);
$sql = mysqli_query($mysqli, "SELECT * FROM categories WHERE category_id = $category_id LIMIT 1"); $sql = mysqli_query($mysqli, "SELECT * FROM categories WHERE category_id = $category_id LIMIT 1");
$row = mysqli_fetch_array($sql); $row = mysqli_fetch_assoc($sql);
$category_name = nullable_htmlentities($row['category_name']); $category_name = nullable_htmlentities($row['category_name']);
$category_color = nullable_htmlentities($row['category_color']); $category_color = nullable_htmlentities($row['category_color']);
$category_type = nullable_htmlentities($row['category_type']); $category_type = nullable_htmlentities($row['category_type']);

View File

@@ -8,7 +8,7 @@ $update_frequency_array = ['Manual', 'Annually', '2 Year', '3 Year', '5 Year', '
// Fetch existing template // Fetch existing template
$sql = mysqli_query($mysqli, "SELECT * FROM contract_templates WHERE contract_template_id = $contract_template_id LIMIT 1"); $sql = mysqli_query($mysqli, "SELECT * FROM contract_templates WHERE contract_template_id = $contract_template_id LIMIT 1");
$row = mysqli_fetch_array($sql); $row = mysqli_fetch_assoc($sql);
// Assign locals // Assign locals
$name = nullable_htmlentities($row['contract_template_name']); $name = nullable_htmlentities($row['contract_template_name']);

View File

@@ -5,7 +5,7 @@ require_once '../../../includes/modal_header.php';
$custom_link_id = intval($_GET['id']); $custom_link_id = intval($_GET['id']);
$sql = mysqli_query($mysqli, "SELECT * FROM custom_links WHERE custom_link_id = $custom_link_id LIMIT 1"); $sql = mysqli_query($mysqli, "SELECT * FROM custom_links WHERE custom_link_id = $custom_link_id LIMIT 1");
$row = mysqli_fetch_array($sql); $row = mysqli_fetch_assoc($sql);
$custom_link_name = nullable_htmlentities($row['custom_link_name']); $custom_link_name = nullable_htmlentities($row['custom_link_name']);
$custom_link_uri = nullable_htmlentities($row['custom_link_uri']); $custom_link_uri = nullable_htmlentities($row['custom_link_uri']);
$custom_link_icon = nullable_htmlentities($row['custom_link_icon']); $custom_link_icon = nullable_htmlentities($row['custom_link_icon']);

View File

@@ -5,7 +5,7 @@ require_once '../../../includes/modal_header.php';
$document_template_id = intval($_GET['id']); $document_template_id = intval($_GET['id']);
$sql = mysqli_query($mysqli, "SELECT * FROM document_templates WHERE document_template_id = $document_template_id LIMIT 1"); $sql = mysqli_query($mysqli, "SELECT * FROM document_templates WHERE document_template_id = $document_template_id LIMIT 1");
$row = mysqli_fetch_array($sql); $row = mysqli_fetch_assoc($sql);
$document_template_name = nullable_htmlentities($row['document_template_name']); $document_template_name = nullable_htmlentities($row['document_template_name']);
$document_template_description = nullable_htmlentities($row['document_template_description']); $document_template_description = nullable_htmlentities($row['document_template_description']);
$document_template_content = nullable_htmlentities($row['document_template_content']); $document_template_content = nullable_htmlentities($row['document_template_content']);

View File

@@ -17,7 +17,7 @@ $purifier_config->set('URI.AllowedSchemes', ['data' => true, 'src' => true, 'htt
$purifier = new HTMLPurifier($purifier_config); $purifier = new HTMLPurifier($purifier_config);
$sql = mysqli_query($mysqli, "SELECT * FROM email_queue WHERE email_id = $email_id LIMIT 1"); $sql = mysqli_query($mysqli, "SELECT * FROM email_queue WHERE email_id = $email_id LIMIT 1");
$row = mysqli_fetch_array($sql); $row = mysqli_fetch_assoc($sql);
$email_from = nullable_htmlentities($row['email_from']); $email_from = nullable_htmlentities($row['email_from']);
$email_from_name = nullable_htmlentities($row['email_from_name']); $email_from_name = nullable_htmlentities($row['email_from_name']);

View File

@@ -6,7 +6,7 @@ $payment_method_id = intval($_GET['id']);
$sql = mysqli_query($mysqli, "SELECT * FROM payment_methods WHERE payment_method_id = $payment_method_id LIMIT 1"); $sql = mysqli_query($mysqli, "SELECT * FROM payment_methods WHERE payment_method_id = $payment_method_id LIMIT 1");
$row = mysqli_fetch_array($sql); $row = mysqli_fetch_assoc($sql);
$payment_method_id = intval($row['payment_method_id']); $payment_method_id = intval($row['payment_method_id']);
$payment_method_name = nullable_htmlentities($row['payment_method_name']); $payment_method_name = nullable_htmlentities($row['payment_method_name']);
$payment_method_description = nullable_htmlentities($row['payment_method_description']); $payment_method_description = nullable_htmlentities($row['payment_method_description']);

View File

@@ -79,7 +79,7 @@ ob_start();
<?php <?php
$sql = mysqli_query($mysqli, "SELECT account_id, account_name FROM accounts WHERE account_archived_at IS NULL ORDER BY account_name ASC"); $sql = mysqli_query($mysqli, "SELECT account_id, account_name FROM accounts WHERE account_archived_at IS NULL ORDER BY account_name ASC");
while ($row = mysqli_fetch_array($sql)) { while ($row = mysqli_fetch_assoc($sql)) {
$account_id = intval($row['account_id']); $account_id = intval($row['account_id']);
$account_name = nullable_htmlentities($row['account_name']); $account_name = nullable_htmlentities($row['account_name']);
?> ?>
@@ -125,7 +125,7 @@ ob_start();
<?php <?php
$sql = mysqli_query($mysqli, "SELECT vendor_id, vendor_name FROM vendors WHERE vendor_client_id = 0 AND vendor_archived_at IS NULL ORDER BY vendor_name ASC"); $sql = mysqli_query($mysqli, "SELECT vendor_id, vendor_name FROM vendors WHERE vendor_client_id = 0 AND vendor_archived_at IS NULL ORDER BY vendor_name ASC");
while ($row = mysqli_fetch_array($sql)) { while ($row = mysqli_fetch_assoc($sql)) {
$vendor_id = intval($row['vendor_id']); $vendor_id = intval($row['vendor_id']);
$vendor_name = nullable_htmlentities($row['vendor_name']); $vendor_name = nullable_htmlentities($row['vendor_name']);
?> ?>
@@ -149,7 +149,7 @@ ob_start();
<?php <?php
$sql = mysqli_query($mysqli, "SELECT category_id, category_name FROM categories WHERE category_type = 'Expense' AND category_archived_at IS NULL ORDER BY category_name ASC"); $sql = mysqli_query($mysqli, "SELECT category_id, category_name FROM categories WHERE category_type = 'Expense' AND category_archived_at IS NULL ORDER BY category_name ASC");
while ($row = mysqli_fetch_array($sql)) { while ($row = mysqli_fetch_assoc($sql)) {
$category_id = intval($row['category_id']); $category_id = intval($row['category_id']);
$category_name = nullable_htmlentities($row['category_name']); $category_name = nullable_htmlentities($row['category_name']);
?> ?>

View File

@@ -6,7 +6,7 @@ $provider_id = intval($_GET['id']);
$sql = mysqli_query($mysqli, "SELECT * FROM payment_providers WHERE payment_provider_id = $provider_id LIMIT 1"); $sql = mysqli_query($mysqli, "SELECT * FROM payment_providers WHERE payment_provider_id = $provider_id LIMIT 1");
$row = mysqli_fetch_array($sql); $row = mysqli_fetch_assoc($sql);
$provider_name = nullable_htmlentities($row['payment_provider_name']); $provider_name = nullable_htmlentities($row['payment_provider_name']);
$public_key = nullable_htmlentities($row['payment_provider_public_key']); $public_key = nullable_htmlentities($row['payment_provider_public_key']);
$private_key = nullable_htmlentities($row['payment_provider_private_key']); $private_key = nullable_htmlentities($row['payment_provider_private_key']);
@@ -78,7 +78,7 @@ ob_start();
<?php <?php
$sql = mysqli_query($mysqli, "SELECT account_id, account_name FROM accounts WHERE account_archived_at IS NULL ORDER BY account_name ASC"); $sql = mysqli_query($mysqli, "SELECT account_id, account_name FROM accounts WHERE account_archived_at IS NULL ORDER BY account_name ASC");
while ($row = mysqli_fetch_array($sql)) { while ($row = mysqli_fetch_assoc($sql)) {
$account_id_select = intval($row['account_id']); $account_id_select = intval($row['account_id']);
$account_name = nullable_htmlentities($row['account_name']); $account_name = nullable_htmlentities($row['account_name']);
?> ?>
@@ -117,7 +117,7 @@ ob_start();
<?php <?php
$sql = mysqli_query($mysqli, "SELECT vendor_id, vendor_name FROM vendors WHERE vendor_client_id = 0 AND vendor_archived_at IS NULL ORDER BY vendor_name ASC"); $sql = mysqli_query($mysqli, "SELECT vendor_id, vendor_name FROM vendors WHERE vendor_client_id = 0 AND vendor_archived_at IS NULL ORDER BY vendor_name ASC");
while ($row = mysqli_fetch_array($sql)) { while ($row = mysqli_fetch_assoc($sql)) {
$vendor_id_select = intval($row['vendor_id']); $vendor_id_select = intval($row['vendor_id']);
$vendor_name = nullable_htmlentities($row['vendor_name']); $vendor_name = nullable_htmlentities($row['vendor_name']);
?> ?>
@@ -143,7 +143,7 @@ ob_start();
<?php <?php
$sql_category = mysqli_query($mysqli, "SELECT category_id, category_name FROM categories WHERE category_type = 'Expense' AND category_archived_at IS NULL ORDER BY category_name ASC"); $sql_category = mysqli_query($mysqli, "SELECT category_id, category_name FROM categories WHERE category_type = 'Expense' AND category_archived_at IS NULL ORDER BY category_name ASC");
while ($row = mysqli_fetch_array($sql_category)) { while ($row = mysqli_fetch_assoc($sql_category)) {
$category_id_select = intval($row['category_id']); $category_id_select = intval($row['category_id']);
$category_name = nullable_htmlentities($row['category_name']); $category_name = nullable_htmlentities($row['category_name']);
?> ?>

View File

@@ -5,7 +5,7 @@ require_once '../../../includes/modal_header.php';
$project_template_id = intval($_GET['project_template_id']); $project_template_id = intval($_GET['project_template_id']);
$sql = mysqli_query($mysqli, "SELECT * FROM project_templates WHERE project_template_id = $project_template_id LIMIT 1"); $sql = mysqli_query($mysqli, "SELECT * FROM project_templates WHERE project_template_id = $project_template_id LIMIT 1");
$row = mysqli_fetch_array($sql); $row = mysqli_fetch_assoc($sql);
$project_template_name = nullable_htmlentities($row['project_template_name']); $project_template_name = nullable_htmlentities($row['project_template_name']);
$project_template_description = nullable_htmlentities($row['project_template_description']); $project_template_description = nullable_htmlentities($row['project_template_description']);

View File

@@ -36,7 +36,7 @@ ob_start();
AND ticket_template_archived_at IS NULL AND ticket_template_archived_at IS NULL
ORDER BY ticket_template_name ASC" ORDER BY ticket_template_name ASC"
); );
while ($row = mysqli_fetch_array($sql_ticket_templates_select)) { while ($row = mysqli_fetch_assoc($sql_ticket_templates_select)) {
$ticket_template_id_select = intval($row['ticket_template_id']); $ticket_template_id_select = intval($row['ticket_template_id']);
$ticket_template_name_select = nullable_htmlentities($row['ticket_template_name']); $ticket_template_name_select = nullable_htmlentities($row['ticket_template_name']);
?> ?>

View File

@@ -11,11 +11,28 @@ ob_start();
<span>&times;</span> <span>&times;</span>
</button> </button>
</div> </div>
<form action="post.php" method="post" enctype="multipart/form-data" autocomplete="off"> <form action="post.php" method="post" enctype="multipart/form-data" autocomplete="off">
<input type="hidden" name="csrf_token" value="<?php echo $_SESSION['csrf_token'] ?>"> <input type="hidden" name="csrf_token" value="<?= $_SESSION['csrf_token'] ?>">
<div class="modal-body"> <div class="modal-body">
<ul class="nav nav-pills nav-justified mb-3">
<li class="nav-item">
<a class="nav-link active" data-toggle="pill" href="#pills-role-details">Details</a>
</li>
<li class="nav-item">
<a class="nav-link" data-toggle="pill" href="#pills-role-permissions">Permissions</a>
</li>
</ul>
<hr>
<div class="tab-content"> <div class="tab-content">
<!-- DETAILS TAB -->
<div class="tab-pane fade show active" id="pills-role-details">
<div class="form-group"> <div class="form-group">
<label>Name <strong class="text-danger">*</strong></label> <label>Name <strong class="text-danger">*</strong></label>
<div class="input-group"> <div class="input-group">
@@ -38,25 +55,159 @@ ob_start();
<div class="form-group"> <div class="form-group">
<label>Admin Access <strong class="text-danger">*</strong></label> <label>Admin Access <strong class="text-danger">*</strong></label>
<div class="input-group">
<div class="input-group-prepend"> <div class="custom-control custom-radio mb-2">
<span class="input-group-text"><i class="fa fa-fw fa-tools"></i></span> <input type="radio" class="custom-control-input" id="admin_no" name="role_is_admin" value="0" checked required>
</div> <label class="custom-control-label" for="admin_no">
<select class="form-control select2" name="role_is_admin" required> No - use permissions on the next tab
<option value="0">No - edit after creation to set permissions</option> </label>
<option value="1">Yes - this role should have full admin access</option>
</select>
</div> </div>
<div class="custom-control custom-radio">
<input type="radio" class="custom-control-input" id="admin_yes" name="role_is_admin" value="1" required>
<label class="custom-control-label" for="admin_yes">
Yes - this role should have full admin access
</label>
</div> </div>
</div> </div>
</div> </div>
<!-- PERMISSIONS TAB -->
<div class="tab-pane fade" id="pills-role-permissions">
<?php
// Enumerate modules
$sql_modules = mysqli_query($mysqli, "SELECT * FROM modules");
while ($row_modules = mysqli_fetch_assoc($sql_modules)) {
$module_id = intval($row_modules['module_id']);
// raw for name, escaped for display
$module_name_raw = $row_modules['module_name'];
$module_name_display = ucfirst(str_replace("module_", "", $module_name_raw));
$module_name_display_safe = nullable_htmlentities($module_name_display);
$module_description = nullable_htmlentities($row_modules['module_description']);
// default for new role
$module_permission = 0;
$field_name = $module_id . "##" . $module_name_raw;
$group_id = "perm_group_$module_id";
?>
<div class="form-group">
<label><?= $module_name_display_safe ?> <strong class="text-danger">*</strong></label>
<div class="btn-group btn-group-toggle btn-block" data-toggle="buttons" role="group"
aria-label="Permissions for <?= $module_name_display_safe ?>">
<label class="btn btn-outline-secondary btn-sm active" title="No Access">
<input
type="radio"
name="<?= $field_name ?>"
id="<?= $group_id ?>_0"
value="0"
autocomplete="off"
checked
required
>
None
</label>
<label class="btn btn-outline-primary btn-sm" title="Viewing Only">
<input
type="radio"
name="<?= $field_name ?>"
id="<?= $group_id ?>_1"
value="1"
autocomplete="off"
>
<i class="fas fa-fw fa-eye mr-1"></i>Read
</label>
<label class="btn btn-outline-warning btn-sm" title="Read, Edit, Archive">
<input
type="radio"
name="<?= $field_name ?>"
id="<?= $group_id ?>_2"
value="2"
autocomplete="off"
>
<i class="fas fa-fw fa-edit mr-1"></i>Modify
</label>
<label class="btn btn-outline-danger btn-sm" title="Read, Edit, Archive, Delete">
<input
type="radio"
name="<?= $field_name ?>"
id="<?= $group_id ?>_3"
value="3"
autocomplete="off"
>
<i class="fas fa-fw fa-trash mr-1"></i>Full
</label>
</div>
<small class="form-text text-muted mt-2"><?= $module_description ?></small>
</div>
<?php } // end while ?>
</div>
</div>
</div>
<div class="modal-footer"> <div class="modal-footer">
<button type="submit" name="add_role" class="btn btn-primary text-bold"><i class="fas fa-check mr-2"></i>Save</button> <button type="submit" name="add_role" class="btn btn-primary text-bold">
<button type="button" class="btn btn-light" data-dismiss="modal"><i class="fas fa-times mr-2"></i>Cancel</button> <i class="fas fa-check mr-2"></i>Create
</button>
<button type="button" class="btn btn-light" data-dismiss="modal">
<i class="fas fa-times mr-2"></i>Cancel
</button>
</div> </div>
</form> </form>
<script>
// Optional: when Admin Yes is selected, disable permission radios + switch to Details tab
(function () {
function setPermissionsEnabled(enabled) {
const permsTab = document.getElementById('pills-role-permissions');
if (!permsTab) return;
permsTab.querySelectorAll('input[type="radio"]').forEach(function (el) {
el.disabled = !enabled;
});
// also visually dim the tab content
permsTab.style.opacity = enabled ? '1' : '0.5';
}
const adminYes = document.getElementById('admin_yes');
const adminNo = document.getElementById('admin_no');
function refresh() {
const isAdmin = adminYes && adminYes.checked;
setPermissionsEnabled(!isAdmin);
if (isAdmin) {
// move user back to Details tab (avoids confusion)
const detailsTab = document.querySelector('a[href="#pills-role-details"]');
if (detailsTab) detailsTab.click();
}
}
if (adminYes && adminNo) {
adminYes.addEventListener('change', refresh);
adminNo.addEventListener('change', refresh);
refresh();
}
})();
</script>
<?php <?php
require_once '../../../includes/modal_footer.php'; require_once '../../../includes/modal_footer.php';

View File

@@ -6,7 +6,7 @@ $role_id = intval($_GET['id']);
$sql = mysqli_query($mysqli, "SELECT * FROM user_roles WHERE role_id = $role_id LIMIT 1"); $sql = mysqli_query($mysqli, "SELECT * FROM user_roles WHERE role_id = $role_id LIMIT 1");
$row = mysqli_fetch_array($sql); $row = mysqli_fetch_assoc($sql);
$role_name = nullable_htmlentities($row['role_name']); $role_name = nullable_htmlentities($row['role_name']);
$role_description = nullable_htmlentities($row['role_description']); $role_description = nullable_htmlentities($row['role_description']);
$role_admin = intval($row['role_is_admin']); $role_admin = intval($row['role_is_admin']);
@@ -31,36 +31,36 @@ if (empty($user_names_string)) {
$user_names_string = "-"; $user_names_string = "-";
} }
// Generate the HTML form content using output buffering.
ob_start(); ob_start();
?> ?>
<div class="modal-header bg-dark"> <div class="modal-header bg-dark">
<h5 class="modal-title"><i class="fas fa-fw fa-user-shield mr-2"></i>Editing role: <h5 class="modal-title"><i class="fas fa-fw fa-user-shield mr-2"></i>Editing role:
<strong><?php echo $role_name; ?></strong></h5> <strong><?= $role_name ?></strong></h5>
<button type="button" class="close text-white" data-dismiss="modal"> <button type="button" class="close text-white" data-dismiss="modal">
<span>&times;</span> <span>&times;</span>
</button> </button>
</div> </div>
<form action="post.php" method="post" enctype="multipart/form-data" autocomplete="off"> <form action="post.php" method="post" enctype="multipart/form-data" autocomplete="off">
<input type="hidden" name="csrf_token" value="<?php echo $_SESSION['csrf_token'] ?>"> <input type="hidden" name="csrf_token" value="<?= $_SESSION['csrf_token'] ?>">
<input type="hidden" name="role_id" value="<?php echo $role_id; ?>"> <input type="hidden" name="role_id" value="<?= $role_id ?>">
<div class="modal-body"> <div class="modal-body">
<ul class="nav nav-pills nav-justified mb-3"> <ul class="nav nav-pills nav-justified mb-3">
<li class="nav-item"> <li class="nav-item">
<a class="nav-link active" data-toggle="pill" href="#pills-role-details<?php echo $role_id; ?>">Details</a> <a class="nav-link active" data-toggle="pill" href="#pills-role-details">Details</a>
</li> </li>
<?php if (!$role_admin) { ?>
<li class="nav-item"> <li class="nav-item">
<a class="nav-link" data-toggle="pill" href="#pills-role-access<?php echo $role_id; ?>">Access</a> <a class="nav-link" data-toggle="pill" href="#pills-role-permissions">Permissions</a>
</li> </li>
<?php } ?>
</ul> </ul>
<hr> <hr>
<div class="tab-content"> <div class="tab-content">
<div class="tab-pane fade show active" id="pills-role-details<?php echo $role_id; ?>"> <div class="tab-pane fade show active" id="pills-role-details">
<div class="form-group"> <div class="form-group">
<label>Name <strong class="text-danger">*</strong></label> <label>Name <strong class="text-danger">*</strong></label>
@@ -68,7 +68,7 @@ ob_start();
<div class="input-group-prepend"> <div class="input-group-prepend">
<span class="input-group-text"><i class="fa fa-fw fa-user-shield"></i></span> <span class="input-group-text"><i class="fa fa-fw fa-user-shield"></i></span>
</div> </div>
<input type="text" class="form-control" name="role_name" placeholder="Role Name" maxlength="200" value="<?php echo $role_name; ?>" required> <input type="text" class="form-control" name="role_name" placeholder="Role Name" maxlength="200" value="<?= $role_name ?>" required>
</div> </div>
</div> </div>
@@ -78,27 +78,33 @@ ob_start();
<div class="input-group-prepend"> <div class="input-group-prepend">
<span class="input-group-text"><i class="fa fa-fw fa-chevron-right"></i></span> <span class="input-group-text"><i class="fa fa-fw fa-chevron-right"></i></span>
</div> </div>
<input type="text" class="form-control" name="role_description" placeholder="Role Description" maxlength="200" value="<?php echo $role_description; ?>" required> <input type="text" class="form-control" name="role_description" placeholder="Role Description" maxlength="200" value="<?= $role_description ?>" required>
</div> </div>
</div> </div>
<div class="form-group"> <div class="form-group">
<label>Admin Access <strong class="text-danger">*</strong></label> <label>Admin Access <strong class="text-danger">*</strong></label>
<div class="input-group"> <div class="custom-control custom-radio mb-2">
<div class="input-group-prepend"> <input type="radio" class="custom-control-input" id="admin_yes" name="role_is_admin" value="1"
<span class="input-group-text"><i class="fa fa-fw fa-tools"></i></span> <?php if ($role_admin) { echo 'checked'; } ?> required>
<label class="custom-control-label" for="admin_yes">
Yes - this role should have full admin access
</label>
</div> </div>
<select class="form-control select2" name="role_is_admin" required>
<option value="1" <?php if ($role_admin) { echo 'selected'; } ?> >Yes - this role should have full admin access</option> <div class="custom-control custom-radio">
<option value="0" <?php if (!$role_admin) { echo 'selected'; } ?>>No - use permissions on the next tab</option> <input type="radio" class="custom-control-input" id="admin_no" name="role_is_admin" value="0"
</select> <?php if (!$role_admin) { echo 'checked'; } ?> required>
<label class="custom-control-label" for="admin_no">
No - use permissions on the next tab
</label>
</div> </div>
</div> </div>
</div> </div>
<?php if (!$role_admin) { ?>
<div class="tab-pane fade" id="pills-role-access<?php echo $role_id; ?>"> <div class="tab-pane fade" id="pills-role-permissions">
<?php if ($role_admin) { ?> <?php if ($role_admin) { ?>
<div class="alert alert-warning"><strong>Module permissions do not apply to Admins.</strong></div> <div class="alert alert-warning"><strong>Module permissions do not apply to Admins.</strong></div>
@@ -108,14 +114,14 @@ ob_start();
// Enumerate modules // Enumerate modules
$sql_modules = mysqli_query($mysqli, "SELECT * FROM modules"); $sql_modules = mysqli_query($mysqli, "SELECT * FROM modules");
while ($row_modules = mysqli_fetch_array($sql_modules)) { while ($row_modules = mysqli_fetch_assoc($sql_modules)) {
$module_id = intval($row_modules['module_id']); $module_id = intval($row_modules['module_id']);
$module_name = nullable_htmlentities($row_modules['module_name']); $module_name = nullable_htmlentities($row_modules['module_name']);
$module_name_display = ucfirst(str_replace("module_","",$module_name)); $module_name_display = ucfirst(str_replace("module_","",$module_name));
$module_description = nullable_htmlentities($row_modules['module_description']); $module_description = nullable_htmlentities($row_modules['module_description']);
// Get permission level for module // Get permission level for module
$module_permission_row = mysqli_fetch_array(mysqli_query($mysqli, "SELECT user_role_permission_level FROM user_role_permissions WHERE module_id = $module_id AND user_role_id = $role_id LIMIT 1")); $module_permission_row = mysqli_fetch_assoc(mysqli_query($mysqli, "SELECT user_role_permission_level FROM user_role_permissions WHERE module_id = $module_id AND user_role_id = $role_id LIMIT 1"));
$module_permission = 0; $module_permission = 0;
if ($module_permission_row) { if ($module_permission_row) {
$module_permission = $module_permission_row['user_role_permission_level']; $module_permission = $module_permission_row['user_role_permission_level'];
@@ -123,22 +129,73 @@ ob_start();
?> ?>
<div class="form-group"> <div class="form-group">
<label> <?php echo $module_name_display ?> <strong class="text-danger">*</strong></label> <label> <?= $module_name_display ?> <strong class="text-danger">*</strong></label>
<div class="input-group"> <?php
<select class="form-control select2" name="<?php echo "$module_id##$module_name" ?>" required> $field_name = "$module_id##$module_name";
<option value="0" <?php if ($module_permission == 0) { echo 'selected'; } ?> >None</option> $group_id = "perm_group_$module_id";
<option value="1" <?php if ($module_permission == 1) { echo 'selected'; } ?> >Read</option> ?>
<option value="2" <?php if ($module_permission == 2) { echo 'selected'; } ?>>Modify (Read, Edit, Archive)</option>
<option value="3" <?php if ($module_permission == 3) { echo 'selected'; } ?>>Full (Read, Edit, Archive, Delete)</option> <div class="btn-group btn-group-toggle btn-block" data-toggle="buttons" role="group" aria-label="Permissions for <?= $module_name_display ?>">
</select>
<label class="btn btn-outline-secondary btn-sm <?php if ($module_permission == 0) { echo 'active'; } ?>" title="No Access">
<input
type="radio"
name="<?= $field_name ?>"
id="<?= $group_id ?>_0"
value="0"
autocomplete="off"
<?php if ($module_permission == 0) { echo 'checked'; } ?>
required
>
None
</label>
<label class="btn btn-outline-primary btn-sm <?php if ($module_permission == 1) { echo 'active'; } ?>" title="Viewing Only">
<input
type="radio"
name="<?= $field_name ?>"
id="<?= $group_id ?>_1"
value="1"
autocomplete="off"
<?php if ($module_permission == 1) { echo 'checked'; } ?>
>
<i class="fas fa-fw fa-eye mr-1"></i>Read
</label>
<label class="btn btn-outline-warning btn-sm <?php if ($module_permission == 2) { echo 'active'; } ?>" title="Read, Edit, Archive">
<input
type="radio"
name="<?= $field_name ?>"
id="<?= $group_id ?>_2"
value="2"
autocomplete="off"
<?php if ($module_permission == 2) { echo 'checked'; } ?>
>
<i class="fas fa-fw fa-edit mr-1"></i>Modify
</label>
<label class="btn btn-outline-danger btn-sm <?php if ($module_permission == 3) { echo 'active'; } ?>" title="Read, Edit, Archive, Delete">
<input
type="radio"
name="<?= $field_name ?>"
id="<?= $group_id ?>_3"
value="3"
autocomplete="off"
<?php if ($module_permission == 3) { echo 'checked'; } ?>
>
<i class="fas fa-fw fa-trash mr-1"></i>Full
</label>
</div> </div>
<small class="form-text text-muted"><?php echo $module_description ?></small>
<small class="form-text text-muted mt-2"><?= $module_description ?></small>
</div> </div>
<?php } // End while ?> <?php } // End while ?>
</div> </div>
<?php } ?>
</div> </div>

View File

@@ -5,7 +5,7 @@ require_once '../../../includes/modal_header.php';
$software_template_id = intval($_GET['id']); $software_template_id = intval($_GET['id']);
$sql = mysqli_query($mysqli, "SELECT * FROM software_templates WHERE software_template_id = $software_template_id LIMIT 1"); $sql = mysqli_query($mysqli, "SELECT * FROM software_templates WHERE software_template_id = $software_template_id LIMIT 1");
$row = mysqli_fetch_array($sql); $row = mysqli_fetch_assoc($sql);
$software_name = nullable_htmlentities($row['software_template_name']); $software_name = nullable_htmlentities($row['software_template_name']);
$software_version = nullable_htmlentities($row['software_template_version']); $software_version = nullable_htmlentities($row['software_template_version']);
$software_description = nullable_htmlentities($row['software_template_description']); $software_description = nullable_htmlentities($row['software_template_description']);

View File

@@ -6,7 +6,7 @@ $tag_id = intval($_GET['id']);
$sql = mysqli_query($mysqli, "SELECT * FROM tags WHERE tag_id = $tag_id LIMIT 1"); $sql = mysqli_query($mysqli, "SELECT * FROM tags WHERE tag_id = $tag_id LIMIT 1");
$row = mysqli_fetch_array($sql); $row = mysqli_fetch_assoc($sql);
$tag_name = nullable_htmlentities($row['tag_name']); $tag_name = nullable_htmlentities($row['tag_name']);
$tag_type = intval($row['tag_type']); $tag_type = intval($row['tag_type']);
$tag_color = nullable_htmlentities($row['tag_color']); $tag_color = nullable_htmlentities($row['tag_color']);

View File

@@ -5,7 +5,7 @@ require_once '../../../includes/modal_header.php';
$tax_id = intval($_GET['id']); $tax_id = intval($_GET['id']);
$sql = mysqli_query($mysqli, "SELECT * FROM taxes WHERE tax_id = $tax_id LIMIT 1"); $sql = mysqli_query($mysqli, "SELECT * FROM taxes WHERE tax_id = $tax_id LIMIT 1");
$row = mysqli_fetch_array($sql); $row = mysqli_fetch_assoc($sql);
$tax_name = nullable_htmlentities($row['tax_name']); $tax_name = nullable_htmlentities($row['tax_name']);
$tax_percent = floatval($row['tax_percent']); $tax_percent = floatval($row['tax_percent']);

View File

@@ -5,7 +5,7 @@ require_once '../../../includes/modal_header.php';
$ticket_status_id = intval($_GET['id']); $ticket_status_id = intval($_GET['id']);
$sql = mysqli_query($mysqli, "SELECT * FROM ticket_statuses WHERE ticket_status_id = $ticket_status_id LIMIT 1"); $sql = mysqli_query($mysqli, "SELECT * FROM ticket_statuses WHERE ticket_status_id = $ticket_status_id LIMIT 1");
$row = mysqli_fetch_array($sql); $row = mysqli_fetch_assoc($sql);
$ticket_status_name = nullable_htmlentities($row['ticket_status_name']); $ticket_status_name = nullable_htmlentities($row['ticket_status_name']);
$ticket_status_color = nullable_htmlentities($row['ticket_status_color']); $ticket_status_color = nullable_htmlentities($row['ticket_status_color']);
$ticket_status_order = intval($row['ticket_status_order']); $ticket_status_order = intval($row['ticket_status_order']);

View File

@@ -59,7 +59,7 @@ ob_start();
<?php <?php
$sql_project_templates = mysqli_query($mysqli, "SELECT * FROM project_templates WHERE project_template_archived_at IS NULL ORDER BY project_template_name ASC"); $sql_project_templates = mysqli_query($mysqli, "SELECT * FROM project_templates WHERE project_template_archived_at IS NULL ORDER BY project_template_name ASC");
while ($row = mysqli_fetch_array($sql_project_templates)) { while ($row = mysqli_fetch_assoc($sql_project_templates)) {
$project_template_id_select = intval($row['project_template_id']); $project_template_id_select = intval($row['project_template_id']);
$project_template_name_select = nullable_htmlentities($row['project_template_name']); ?> $project_template_name_select = nullable_htmlentities($row['project_template_name']); ?>
<option value="<?php echo $project_template_id_select; ?>"><?php echo $project_template_name_select; ?></option> <option value="<?php echo $project_template_id_select; ?>"><?php echo $project_template_name_select; ?></option>

View File

@@ -6,7 +6,7 @@ $task_template_id = intval($_GET['id']);
$sql = mysqli_query($mysqli, "SELECT * FROM task_templates WHERE task_template_id = $task_template_id LIMIT 1"); $sql = mysqli_query($mysqli, "SELECT * FROM task_templates WHERE task_template_id = $task_template_id LIMIT 1");
$row = mysqli_fetch_array($sql); $row = mysqli_fetch_assoc($sql);
$task_template_name = nullable_htmlentities($row['task_template_name']); $task_template_name = nullable_htmlentities($row['task_template_name']);
$task_template_order = intval($row['task_template_order']); $task_template_order = intval($row['task_template_order']);
$task_template_completion_estimate = intval($row['task_template_completion_estimate']); $task_template_completion_estimate = intval($row['task_template_completion_estimate']);

View File

@@ -76,7 +76,7 @@ ob_start();
<option value="">- Role -</option> <option value="">- Role -</option>
<?php <?php
$sql_user_roles = mysqli_query($mysqli, "SELECT * FROM user_roles WHERE role_archived_at IS NULL"); $sql_user_roles = mysqli_query($mysqli, "SELECT * FROM user_roles WHERE role_archived_at IS NULL");
while ($row = mysqli_fetch_array($sql_user_roles)) { while ($row = mysqli_fetch_assoc($sql_user_roles)) {
$role_id = intval($row['role_id']); $role_id = intval($row['role_id']);
$role_name = nullable_htmlentities($row['role_name']); $role_name = nullable_htmlentities($row['role_name']);
@@ -129,7 +129,7 @@ ob_start();
<?php <?php
$sql_client_select = mysqli_query($mysqli, "SELECT * FROM clients WHERE client_archived_at IS NULL ORDER BY client_name ASC"); $sql_client_select = mysqli_query($mysqli, "SELECT * FROM clients WHERE client_archived_at IS NULL ORDER BY client_name ASC");
while ($row = mysqli_fetch_array($sql_client_select)) { while ($row = mysqli_fetch_assoc($sql_client_select)) {
$client_id = intval($row['client_id']); $client_id = intval($row['client_id']);
$client_name = nullable_htmlentities($row['client_name']); $client_name = nullable_htmlentities($row['client_name']);

View File

@@ -6,7 +6,7 @@ $user_id = intval($_GET['id']);
$sql = mysqli_query($mysqli, "SELECT * FROM users WHERE users.user_id = $user_id LIMIT 1"); $sql = mysqli_query($mysqli, "SELECT * FROM users WHERE users.user_id = $user_id LIMIT 1");
$row = mysqli_fetch_array($sql); $row = mysqli_fetch_assoc($sql);
$user_name = nullable_htmlentities($row['user_name']); $user_name = nullable_htmlentities($row['user_name']);
$user_email = nullable_htmlentities($row['user_email']); $user_email = nullable_htmlentities($row['user_email']);
$user_avatar = nullable_htmlentities($row['user_avatar']); $user_avatar = nullable_htmlentities($row['user_avatar']);
@@ -60,7 +60,7 @@ ob_start();
<option value="0">No one</option> <option value="0">No one</option>
<?php <?php
$sql_users = mysqli_query($mysqli, "SELECT * FROM users WHERE user_type = 1 AND user_archived_at IS NULL"); $sql_users = mysqli_query($mysqli, "SELECT * FROM users WHERE user_type = 1 AND user_archived_at IS NULL");
while ($row = mysqli_fetch_array($sql_users)) { while ($row = mysqli_fetch_assoc($sql_users)) {
$user_id_select = intval($row['user_id']); $user_id_select = intval($row['user_id']);
$user_name_select = nullable_htmlentities($row['user_name']); $user_name_select = nullable_htmlentities($row['user_name']);

View File

@@ -9,7 +9,7 @@ $sql = mysqli_query($mysqli, "SELECT * FROM users
WHERE users.user_id = $user_id LIMIT 1" WHERE users.user_id = $user_id LIMIT 1"
); );
$row = mysqli_fetch_array($sql); $row = mysqli_fetch_assoc($sql);
$user_name = nullable_htmlentities($row['user_name']); $user_name = nullable_htmlentities($row['user_name']);
$user_email = nullable_htmlentities($row['user_email']); $user_email = nullable_htmlentities($row['user_email']);
$user_avatar = nullable_htmlentities($row['user_avatar']); $user_avatar = nullable_htmlentities($row['user_avatar']);
@@ -114,7 +114,7 @@ ob_start();
<select class="form-control select2" name="role" required> <select class="form-control select2" name="role" required>
<?php <?php
$sql_user_roles = mysqli_query($mysqli, "SELECT * FROM user_roles WHERE role_archived_at IS NULL"); $sql_user_roles = mysqli_query($mysqli, "SELECT * FROM user_roles WHERE role_archived_at IS NULL");
while ($row = mysqli_fetch_array($sql_user_roles)) { while ($row = mysqli_fetch_assoc($sql_user_roles)) {
$role_id = intval($row['role_id']); $role_id = intval($row['role_id']);
$role_name = nullable_htmlentities($row['role_name']); $role_name = nullable_htmlentities($row['role_name']);
@@ -175,7 +175,7 @@ ob_start();
<?php <?php
$sql_client_select = mysqli_query($mysqli, "SELECT * FROM clients WHERE client_archived_at IS NULL ORDER BY client_name ASC"); $sql_client_select = mysqli_query($mysqli, "SELECT * FROM clients WHERE client_archived_at IS NULL ORDER BY client_name ASC");
while ($row = mysqli_fetch_array($sql_client_select)) { while ($row = mysqli_fetch_assoc($sql_client_select)) {
$client_id_select = intval($row['client_id']); $client_id_select = intval($row['client_id']);
$client_name_select = nullable_htmlentities($row['client_name']); $client_name_select = nullable_htmlentities($row['client_name']);

View File

@@ -6,7 +6,7 @@ $user_id = intval($_GET['id']);
$sql = mysqli_query($mysqli, "SELECT * FROM users WHERE user_id = $user_id AND user_archived_at IS NOT NULL LIMIT 1"); $sql = mysqli_query($mysqli, "SELECT * FROM users WHERE user_id = $user_id AND user_archived_at IS NOT NULL LIMIT 1");
$row = mysqli_fetch_array($sql); $row = mysqli_fetch_assoc($sql);
$user_name = str_replace(" (archived)", "", $row['user_name']); //Removed (archived) from user_name $user_name = str_replace(" (archived)", "", $row['user_name']); //Removed (archived) from user_name
$user_name = nullable_htmlentities($user_name); $user_name = nullable_htmlentities($user_name);
$user_email = nullable_htmlentities($row['user_email']); $user_email = nullable_htmlentities($row['user_email']);
@@ -64,7 +64,7 @@ ob_start();
<select class="form-control select2" name="role" required> <select class="form-control select2" name="role" required>
<?php <?php
$sql_user_roles = mysqli_query($mysqli, "SELECT * FROM user_roles WHERE role_archived_at IS NULL"); $sql_user_roles = mysqli_query($mysqli, "SELECT * FROM user_roles WHERE role_archived_at IS NULL");
while ($row = mysqli_fetch_array($sql_user_roles)) { while ($row = mysqli_fetch_assoc($sql_user_roles)) {
$role_id = intval($row['role_id']); $role_id = intval($row['role_id']);
$role_name = nullable_htmlentities($row['role_name']); $role_name = nullable_htmlentities($row['role_name']);

View File

@@ -5,7 +5,7 @@ require_once '../../../includes/modal_header.php';
$vendor_template_id = intval($_GET['id']); $vendor_template_id = intval($_GET['id']);
$sql = mysqli_query($mysqli, "SELECT * FROM vendor_templates WHERE vendor_template_id = $vendor_template_id LIMIT 1"); $sql = mysqli_query($mysqli, "SELECT * FROM vendor_templates WHERE vendor_template_id = $vendor_template_id LIMIT 1");
$row = mysqli_fetch_array($sql); $row = mysqli_fetch_assoc($sql);
$vendor_name = nullable_htmlentities($row['vendor_template_name']); $vendor_name = nullable_htmlentities($row['vendor_template_name']);
$vendor_description = nullable_htmlentities($row['vendor_template_description']); $vendor_description = nullable_htmlentities($row['vendor_template_description']);
$vendor_account_number = nullable_htmlentities($row['vendor_template_account_number']); $vendor_account_number = nullable_htmlentities($row['vendor_template_account_number']);

View File

@@ -57,7 +57,7 @@ $num_rows = mysqli_fetch_row(mysqli_query($mysqli, "SELECT FOUND_ROWS()"));
<tbody> <tbody>
<?php <?php
while ($row = mysqli_fetch_array($sql)) { while ($row = mysqli_fetch_assoc($sql)) {
$module_id = intval($row['module_id']); $module_id = intval($row['module_id']);
$module_name = nullable_htmlentities($row['module_name']); $module_name = nullable_htmlentities($row['module_name']);
$module_description = nullable_htmlentities($row['module_description']); $module_description = nullable_htmlentities($row['module_description']);

View File

@@ -0,0 +1,103 @@
<?php
require_once "../config.php";
require_once "../functions.php";
require_once "../includes/check_login.php";
$settings_mail_path = '/admin/settings_mail.php';
if (!isset($session_is_admin) || !$session_is_admin) {
flash_alert("Admin access required.", 'error');
redirect($settings_mail_path);
}
$state = sanitizeInput($_GET['state'] ?? '');
$code = $_GET['code'] ?? '';
$error = sanitizeInput($_GET['error'] ?? '');
$error_description = sanitizeInput($_GET['error_description'] ?? '');
$session_state = $_SESSION['mail_oauth_state'] ?? '';
$session_state_expires = intval($_SESSION['mail_oauth_state_expires_at'] ?? 0);
unset($_SESSION['mail_oauth_state'], $_SESSION['mail_oauth_state_expires_at']);
if (!empty($error)) {
$msg = "Microsoft OAuth authorization failed: $error";
if (!empty($error_description)) {
$msg .= " ($error_description)";
}
flash_alert($msg, 'error');
redirect($settings_mail_path);
}
if (empty($state) || empty($code) || empty($session_state) || !hash_equals($session_state, $state) || time() > $session_state_expires) {
flash_alert("Microsoft OAuth callback validation failed. Please try connecting again.", 'error');
redirect($settings_mail_path);
}
if (empty($config_mail_oauth_client_id) || empty($config_mail_oauth_client_secret) || empty($config_mail_oauth_tenant_id)) {
flash_alert("Microsoft OAuth settings are incomplete. Please fill Client ID, Client Secret, and Tenant ID.", 'error');
redirect($settings_mail_path);
}
if (defined('BASE_URL') && !empty(BASE_URL)) {
$base_url = rtrim((string) BASE_URL, '/');
} else {
$base_url = 'https://' . rtrim((string) $config_base_url, '/');
}
$redirect_uri = $base_url . '/admin/oauth_microsoft_mail_callback.php';
$token_url = 'https://login.microsoftonline.com/' . rawurlencode($config_mail_oauth_tenant_id) . '/oauth2/v2.0/token';
$scope = 'offline_access openid profile https://outlook.office.com/IMAP.AccessAsUser.All https://outlook.office.com/SMTP.Send';
$ch = curl_init($token_url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query([
'client_id' => $config_mail_oauth_client_id,
'client_secret' => $config_mail_oauth_client_secret,
'grant_type' => 'authorization_code',
'code' => $code,
'redirect_uri' => $redirect_uri,
'scope' => $scope,
], '', '&'));
curl_setopt($ch, CURLOPT_TIMEOUT, 20);
$raw_body = curl_exec($ch);
$curl_err = curl_error($ch);
$http_code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
if ($raw_body === false || $http_code < 200 || $http_code >= 300) {
$reason = !empty($curl_err) ? $curl_err : "HTTP $http_code";
flash_alert("Microsoft OAuth token exchange failed: $reason", 'error');
redirect($settings_mail_path);
}
$json = json_decode($raw_body, true);
if (!is_array($json) || empty($json['refresh_token']) || empty($json['access_token'])) {
flash_alert("Microsoft OAuth token exchange failed: refresh token or access token missing.", 'error');
redirect($settings_mail_path);
}
$refresh_token = (string) $json['refresh_token'];
$access_token = (string) $json['access_token'];
$expires_at = date('Y-m-d H:i:s', time() + (int)($json['expires_in'] ?? 3600));
$refresh_token_esc = mysqli_real_escape_string($mysqli, $refresh_token);
$access_token_esc = mysqli_real_escape_string($mysqli, $access_token);
$expires_at_esc = mysqli_real_escape_string($mysqli, $expires_at);
mysqli_query($mysqli, "UPDATE settings SET
config_imap_provider = 'microsoft_oauth',
config_smtp_provider = 'microsoft_oauth',
config_mail_oauth_refresh_token = '$refresh_token_esc',
config_mail_oauth_access_token = '$access_token_esc',
config_mail_oauth_access_token_expires_at = '$expires_at_esc'
WHERE company_id = 1
");
logAction("Settings", "Edit", "$session_name completed Microsoft OAuth connect flow for mail settings");
flash_alert("Microsoft OAuth connected successfully. Token expires at $expires_at.");
redirect($settings_mail_path);

View File

@@ -45,7 +45,7 @@ $num_rows = mysqli_num_rows($sql);
<tbody> <tbody>
<?php <?php
while ($row = mysqli_fetch_array($sql)) { while ($row = mysqli_fetch_assoc($sql)) {
$payment_method_id = intval($row['payment_method_id']); $payment_method_id = intval($row['payment_method_id']);
$payment_method_name = nullable_htmlentities($row['payment_method_name']); $payment_method_name = nullable_htmlentities($row['payment_method_name']);
$payment_method_description = nullable_htmlentities($row['payment_method_description']); $payment_method_description = nullable_htmlentities($row['payment_method_description']);

View File

@@ -66,7 +66,7 @@ $num_rows = mysqli_num_rows($sql);
<tbody> <tbody>
<?php <?php
while ($row = mysqli_fetch_array($sql)) { while ($row = mysqli_fetch_assoc($sql)) {
$provider_id = intval($row['payment_provider_id']); $provider_id = intval($row['payment_provider_id']);
$provider_name = nullable_htmlentities($row['payment_provider_name']); $provider_name = nullable_htmlentities($row['payment_provider_name']);
$provider_description = nullable_htmlentities($row['payment_provider_description']); $provider_description = nullable_htmlentities($row['payment_provider_description']);

View File

@@ -31,6 +31,27 @@ if (isset($_POST['add_api_key'])) {
} }
if (isset($_GET['revoke_api_key'])) {
validateCSRFToken($_GET['csrf_token']);
$api_key_id = intval($_GET['revoke_api_key']);
// Get API Key Name
$row = mysqli_fetch_assoc(mysqli_query($mysqli,"SELECT api_key_name, api_key_client_id FROM api_keys WHERE api_key_id = $api_key_id"));
$api_key_name = sanitizeInput($row['api_key_name']);
$client_id = intval($row['api_key_client_id']);
mysqli_query($mysqli,"UPDATE api_keys SET api_key_expire = NOW() WHERE api_key_id = $api_key_id");
logAction("API Key", "Revoke", "$session_name revoked API key $name", $client_id);
flash_alert("API Key <strong>$name</strong> revoked", 'error');
redirect();
}
if (isset($_GET['delete_api_key'])) { if (isset($_GET['delete_api_key'])) {
validateCSRFToken($_GET['csrf_token']); validateCSRFToken($_GET['csrf_token']);
@@ -38,7 +59,7 @@ if (isset($_GET['delete_api_key'])) {
$api_key_id = intval($_GET['delete_api_key']); $api_key_id = intval($_GET['delete_api_key']);
// Get API Key Name // Get API Key Name
$row = mysqli_fetch_array(mysqli_query($mysqli,"SELECT api_key_name, api_key_client_id FROM api_keys WHERE api_key_id = $api_key_id")); $row = mysqli_fetch_assoc(mysqli_query($mysqli,"SELECT api_key_name, api_key_client_id FROM api_keys WHERE api_key_id = $api_key_id"));
$api_key_name = sanitizeInput($row['api_key_name']); $api_key_name = sanitizeInput($row['api_key_name']);
$client_id = intval($row['api_key_client_id']); $client_id = intval($row['api_key_client_id']);
@@ -66,7 +87,7 @@ if (isset($_POST['bulk_delete_api_keys'])) {
$api_key_id = intval($api_key_id); $api_key_id = intval($api_key_id);
// Get API Key Name // Get API Key Name
$row = mysqli_fetch_array(mysqli_query($mysqli,"SELECT api_key_name, api_key_client_id FROM api_keys WHERE api_key_id = $api_key_id")); $row = mysqli_fetch_assoc(mysqli_query($mysqli,"SELECT api_key_name, api_key_client_id FROM api_keys WHERE api_key_id = $api_key_id"));
$api_key_name = sanitizeInput($row['api_key_name']); $api_key_name = sanitizeInput($row['api_key_name']);
$client_id = intval($row['api_key_client_id']); $client_id = intval($row['api_key_client_id']);

View File

@@ -307,7 +307,7 @@ if (isset($_POST['backup_master_key'])) {
$password = $_POST['password']; $password = $_POST['password'];
$sql = mysqli_query($mysqli, "SELECT * FROM users WHERE user_id = $session_user_id"); $sql = mysqli_query($mysqli, "SELECT * FROM users WHERE user_id = $session_user_id");
$row = mysqli_fetch_array($sql); $row = mysqli_fetch_assoc($sql);
if (password_verify($password, $row['user_password'])) { if (password_verify($password, $row['user_password'])) {
$site_encryption_master_key = decryptUserSpecificKey($row['user_specific_encryption_ciphertext'], $password); $site_encryption_master_key = decryptUserSpecificKey($row['user_specific_encryption_ciphertext'], $password);
@@ -329,4 +329,3 @@ if (isset($_POST['backup_master_key'])) {
redirect(); redirect();
} }
} }

View File

@@ -44,7 +44,7 @@ if (isset($_GET['archive_category'])) {
// Get Category Name and Type for logging // Get Category Name and Type for logging
$sql = mysqli_query($mysqli,"SELECT category_name, category_type FROM categories WHERE category_id = $category_id"); $sql = mysqli_query($mysqli,"SELECT category_name, category_type FROM categories WHERE category_id = $category_id");
$row = mysqli_fetch_array($sql); $row = mysqli_fetch_assoc($sql);
$category_name = sanitizeInput($row['category_name']); $category_name = sanitizeInput($row['category_name']);
$category_type = sanitizeInput($row['category_type']); $category_type = sanitizeInput($row['category_type']);
@@ -64,7 +64,7 @@ if (isset($_GET['unarchive_category'])) {
// Get Category Name and Type for logging // Get Category Name and Type for logging
$sql = mysqli_query($mysqli,"SELECT category_name, category_type FROM categories WHERE category_id = $category_id"); $sql = mysqli_query($mysqli,"SELECT category_name, category_type FROM categories WHERE category_id = $category_id");
$row = mysqli_fetch_array($sql); $row = mysqli_fetch_assoc($sql);
$category_name = sanitizeInput($row['category_name']); $category_name = sanitizeInput($row['category_name']);
$category_type = sanitizeInput($row['category_type']); $category_type = sanitizeInput($row['category_type']);
@@ -84,7 +84,7 @@ if (isset($_GET['delete_category'])) {
// Get Category Name and Type for logging // Get Category Name and Type for logging
$sql = mysqli_query($mysqli,"SELECT category_name, category_type FROM categories WHERE category_id = $category_id"); $sql = mysqli_query($mysqli,"SELECT category_name, category_type FROM categories WHERE category_id = $category_id");
$row = mysqli_fetch_array($sql); $row = mysqli_fetch_assoc($sql);
$category_name = sanitizeInput($row['category_name']); $category_name = sanitizeInput($row['category_name']);
$category_type = sanitizeInput($row['category_type']); $category_type = sanitizeInput($row['category_type']);

View File

@@ -53,7 +53,7 @@ if (isset($_GET['delete_custom_link'])) {
// Get Custom Link name and uri for logging // Get Custom Link name and uri for logging
$sql = mysqli_query($mysqli,"SELECT custom_link_name, custom_link_uri FROM custom_links WHERE custom_link_id = $custom_link_id"); $sql = mysqli_query($mysqli,"SELECT custom_link_name, custom_link_uri FROM custom_links WHERE custom_link_id = $custom_link_id");
$row = mysqli_fetch_array($sql); $row = mysqli_fetch_assoc($sql);
$custom_link_name = sanitizeInput($row['custom_link_name']); $custom_link_name = sanitizeInput($row['custom_link_name']);
$custom_link_uri = sanitizeInput($row['custom_link_uri']); $custom_link_uri = sanitizeInput($row['custom_link_uri']);

View File

@@ -18,9 +18,23 @@ if (isset($_POST['add_role'])) {
$role_id = mysqli_insert_id($mysqli); $role_id = mysqli_insert_id($mysqli);
// Insert role permissions (only if not admin)
if ($admin == 0) {
foreach ($_POST as $key => $value) {
if (str_contains($key, '##module_')) {
$module_id = intval(explode('##', $key)[0]);
$access_level = intval($value);
if ($access_level > 0) {
mysqli_query($mysqli, "INSERT INTO user_role_permissions SET user_role_id = $role_id, module_id = $module_id, user_role_permission_level = $access_level");
}
}
}
}
logAction("User Role", "Create", "$session_name created user role $name", 0, $role_id); logAction("User Role", "Create", "$session_name created user role $name", 0, $role_id);
flash_alert("User Role <strong$name</strong> created"); flash_alert("User Role <strong>$name</strong> created");
redirect(); redirect();
@@ -76,7 +90,7 @@ if (isset($_GET['archive_role'])) {
mysqli_query($mysqli, "UPDATE user_roles SET role_archived_at = NOW() WHERE role_id = $role_id"); mysqli_query($mysqli, "UPDATE user_roles SET role_archived_at = NOW() WHERE role_id = $role_id");
$role_name = sanitizeInput(getFieldById('roles', $role_id, 'role_name')); $role_name = sanitizeInput(getFieldById('user_roles', $role_id, 'role_name'));
logAction("User Role", "Archive", "$session_name archived user role $role_name", 0, $role_id); logAction("User Role", "Archive", "$session_name archived user role $role_name", 0, $role_id);

View File

@@ -27,7 +27,7 @@ if (isset($_GET['delete_saved_payment'])) {
WHERE client_saved_payment_methods.saved_payment_id = $saved_payment_id" WHERE client_saved_payment_methods.saved_payment_id = $saved_payment_id"
); );
$row = mysqli_fetch_array($sql); $row = mysqli_fetch_assoc($sql);
$client_id = intval($row['saved_payment_client_id']); $client_id = intval($row['saved_payment_client_id']);
$provider_id = intval($row['saved_payment_provider_id']); $provider_id = intval($row['saved_payment_provider_id']);
$payment_provider_name = nullable_htmlentities($row['payment_provider_name']); $payment_provider_name = nullable_htmlentities($row['payment_provider_name']);

View File

@@ -19,7 +19,7 @@ if (isset($_POST['edit_company'])) {
$tax_id = sanitizeInput($_POST['tax_id']); $tax_id = sanitizeInput($_POST['tax_id']);
$sql = mysqli_query($mysqli,"SELECT company_logo FROM companies WHERE company_id = 1"); $sql = mysqli_query($mysqli,"SELECT company_logo FROM companies WHERE company_id = 1");
$row = mysqli_fetch_array($sql); $row = mysqli_fetch_assoc($sql);
$existing_file_name = sanitizeInput($row['company_logo']); $existing_file_name = sanitizeInput($row['company_logo']);
// Company logo // Company logo
@@ -55,7 +55,7 @@ if (isset($_POST['edit_company'])) {
if (isset($_GET['remove_company_logo'])) { if (isset($_GET['remove_company_logo'])) {
$sql = mysqli_query($mysqli,"SELECT company_logo FROM companies"); $sql = mysqli_query($mysqli,"SELECT company_logo FROM companies");
$row = mysqli_fetch_array($sql); $row = mysqli_fetch_assoc($sql);
$company_logo = $row['company_logo']; // FileSystem Operation Logo is already sanitized $company_logo = $row['company_logo']; // FileSystem Operation Logo is already sanitized
unlink("../uploads/settings/$company_logo"); unlink("../uploads/settings/$company_logo");

View File

@@ -2,6 +2,79 @@
defined('FROM_POST_HANDLER') || die("Direct file access is not allowed"); defined('FROM_POST_HANDLER') || die("Direct file access is not allowed");
if (!defined('MICROSOFT_OAUTH_BASE_URL')) {
define('MICROSOFT_OAUTH_BASE_URL', 'https://login.microsoftonline.com/');
}
if (isset($_POST['oauth_connect_microsoft_mail'])) {
validateCSRFToken($_POST['csrf_token']);
// Save current IMAP/OAuth form values first so auth flow always uses latest inputs.
$config_imap_provider = sanitizeInput($_POST['config_imap_provider'] ?? '');
$config_imap_username = sanitizeInput($_POST['config_imap_username'] ?? '');
$config_mail_oauth_client_id = sanitizeInput($_POST['config_mail_oauth_client_id'] ?? '');
$config_mail_oauth_client_secret = sanitizeInput($_POST['config_mail_oauth_client_secret'] ?? '');
$config_mail_oauth_tenant_id = sanitizeInput($_POST['config_mail_oauth_tenant_id'] ?? '');
$config_mail_oauth_refresh_token = sanitizeInput($_POST['config_mail_oauth_refresh_token'] ?? '');
$config_mail_oauth_access_token = sanitizeInput($_POST['config_mail_oauth_access_token'] ?? '');
mysqli_query($mysqli, "UPDATE settings SET
config_imap_provider = '$config_imap_provider',
config_imap_username = '$config_imap_username',
config_mail_oauth_client_id = '$config_mail_oauth_client_id',
config_mail_oauth_client_secret = '$config_mail_oauth_client_secret',
config_mail_oauth_tenant_id = '$config_mail_oauth_tenant_id',
config_mail_oauth_refresh_token = '$config_mail_oauth_refresh_token',
config_mail_oauth_access_token = '$config_mail_oauth_access_token'
WHERE company_id = 1
");
if ($config_imap_provider !== 'microsoft_oauth') {
flash_alert("Please set IMAP Provider to Microsoft 365 (OAuth) before connecting.", 'error');
redirect();
}
if (empty($config_mail_oauth_client_id) || empty($config_mail_oauth_client_secret) || empty($config_mail_oauth_tenant_id)) {
flash_alert("Missing Microsoft OAuth settings. Please provide Client ID, Client Secret, and Tenant ID first.", 'error');
redirect();
}
if (defined('BASE_URL') && !empty(BASE_URL)) {
$base_url = rtrim((string) BASE_URL, '/');
} else {
$base_url = 'https://' . rtrim((string) $config_base_url, '/');
}
$redirect_uri = $base_url . '/admin/oauth_microsoft_mail_callback.php';
try {
$state = bin2hex(random_bytes(32));
} catch (Throwable $e) {
$state = sha1(uniqid((string) mt_rand(), true));
}
$_SESSION['mail_oauth_state'] = $state;
$_SESSION['mail_oauth_state_expires_at'] = time() + 600;
$scope = 'offline_access openid profile https://outlook.office.com/IMAP.AccessAsUser.All https://outlook.office.com/SMTP.Send';
$authorize_url = MICROSOFT_OAUTH_BASE_URL . rawurlencode($config_mail_oauth_tenant_id) . '/oauth2/v2.0/authorize?'
. http_build_query([
'client_id' => $config_mail_oauth_client_id,
'response_type' => 'code',
'redirect_uri' => $redirect_uri,
'response_mode' => 'query',
'scope' => $scope,
'state' => $state,
'prompt' => 'consent',
], '', '&', PHP_QUERY_RFC3986);
logAction("Settings", "Edit", "$session_name started Microsoft OAuth connect flow for mail settings");
redirect($authorize_url);
}
if (isset($_POST['edit_mail_smtp_settings'])) { if (isset($_POST['edit_mail_smtp_settings'])) {
validateCSRFToken($_POST['csrf_token']); validateCSRFToken($_POST['csrf_token']);
@@ -163,12 +236,145 @@ if (isset($_POST['test_email_imap'])) {
validateCSRFToken($_POST['csrf_token']); validateCSRFToken($_POST['csrf_token']);
$provider = sanitizeInput($config_imap_provider ?? '');
$host = $config_imap_host; $host = $config_imap_host;
$port = (int) $config_imap_port; $port = (int) $config_imap_port;
$encryption = strtolower(trim($config_imap_encryption)); // e.g. "ssl", "tls", "none" $encryption = strtolower(trim($config_imap_encryption)); // e.g. "ssl", "tls", "none"
$username = $config_imap_username; $username = $config_imap_username;
$password = $config_imap_password; $password = $config_imap_password;
// Shared OAuth fields
$config_mail_oauth_client_id = $config_mail_oauth_client_id ?? '';
$config_mail_oauth_client_secret = $config_mail_oauth_client_secret ?? '';
$config_mail_oauth_tenant_id = $config_mail_oauth_tenant_id ?? '';
$config_mail_oauth_refresh_token = $config_mail_oauth_refresh_token ?? '';
$config_mail_oauth_access_token = $config_mail_oauth_access_token ?? '';
$config_mail_oauth_access_token_expires_at = $config_mail_oauth_access_token_expires_at ?? '';
$is_oauth = ($provider === 'google_oauth' || $provider === 'microsoft_oauth');
if ($provider === 'google_oauth') {
if (empty($host)) {
$host = 'imap.gmail.com';
}
if (empty($port)) {
$port = 993;
}
if (empty($encryption)) {
$encryption = 'ssl';
}
} elseif ($provider === 'microsoft_oauth') {
if (empty($host)) {
$host = 'outlook.office365.com';
}
if (empty($port)) {
$port = 993;
}
if (empty($encryption)) {
$encryption = 'ssl';
}
}
if (empty($host) || empty($port) || empty($username)) {
flash_alert("<strong>IMAP connection failed:</strong> Missing host, port, or username.", 'error');
redirect();
}
$token_is_expired = function (?string $expires_at): bool {
if (empty($expires_at)) {
return true;
}
$ts = strtotime($expires_at);
if ($ts === false) {
return true;
}
return ($ts - 60) <= time();
};
$http_form_post = function (string $url, array $fields): array {
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($fields, '', '&'));
curl_setopt($ch, CURLOPT_TIMEOUT, 20);
$raw = curl_exec($ch);
$err = curl_error($ch);
$code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
return [
'ok' => ($raw !== false && $code >= 200 && $code < 300),
'body' => $raw,
'code' => $code,
'err' => $err,
];
};
if ($is_oauth) {
if (!empty($config_mail_oauth_access_token) && !$token_is_expired($config_mail_oauth_access_token_expires_at)) {
$password = $config_mail_oauth_access_token;
} else {
if (empty($config_mail_oauth_client_id) || empty($config_mail_oauth_client_secret) || empty($config_mail_oauth_refresh_token)) {
flash_alert("<strong>IMAP OAuth failed:</strong> Missing OAuth client credentials or refresh token.", 'error');
redirect();
}
if ($provider === 'google_oauth') {
$response = $http_form_post('https://oauth2.googleapis.com/token', [
'client_id' => $config_mail_oauth_client_id,
'client_secret' => $config_mail_oauth_client_secret,
'refresh_token' => $config_mail_oauth_refresh_token,
'grant_type' => 'refresh_token',
]);
} else {
if (empty($config_mail_oauth_tenant_id)) {
flash_alert("<strong>IMAP OAuth failed:</strong> Microsoft tenant ID is required.", 'error');
redirect();
}
$token_url = MICROSOFT_OAUTH_BASE_URL . rawurlencode($config_mail_oauth_tenant_id) . "/oauth2/v2.0/token";
$response = $http_form_post($token_url, [
'client_id' => $config_mail_oauth_client_id,
'client_secret' => $config_mail_oauth_client_secret,
'refresh_token' => $config_mail_oauth_refresh_token,
'grant_type' => 'refresh_token',
]);
}
if (!$response['ok']) {
flash_alert("<strong>IMAP OAuth failed:</strong> Could not refresh access token.", 'error');
redirect();
}
$json = json_decode($response['body'], true);
if (!is_array($json) || empty($json['access_token'])) {
flash_alert("<strong>IMAP OAuth failed:</strong> Token response did not include an access token.", 'error');
redirect();
}
$password = $json['access_token'];
$expires_at = date('Y-m-d H:i:s', time() + (int)($json['expires_in'] ?? 3600));
$refresh_token_to_save = $json['refresh_token'] ?? null;
$token_esc = mysqli_real_escape_string($mysqli, $password);
$expires_at_esc = mysqli_real_escape_string($mysqli, $expires_at);
$refresh_sql = '';
if (!empty($refresh_token_to_save)) {
$refresh_token_esc = mysqli_real_escape_string($mysqli, $refresh_token_to_save);
$refresh_sql = ", config_mail_oauth_refresh_token = '{$refresh_token_esc}'";
}
mysqli_query($mysqli, "UPDATE settings SET config_mail_oauth_access_token = '{$token_esc}', config_mail_oauth_access_token_expires_at = '{$expires_at_esc}'{$refresh_sql} WHERE company_id = 1");
}
}
// Build remote socket (implicit SSL vs plain TCP) // Build remote socket (implicit SSL vs plain TCP)
$transport = 'tcp'; $transport = 'tcp';
if ($encryption === 'ssl') { if ($encryption === 'ssl') {
@@ -178,16 +384,16 @@ if (isset($_POST['test_email_imap'])) {
$remote_socket = $transport . '://' . $host . ':' . $port; $remote_socket = $transport . '://' . $host . ':' . $port;
// Stream context (you can tighten these if you want strict validation) // Stream context (you can tighten these if you want strict validation)
$contextOptions = []; $context_options = [];
if (in_array($encryption, ['ssl', 'tls'], true)) { if (in_array($encryption, ['ssl', 'tls'], true)) {
$contextOptions['ssl'] = [ $context_options['ssl'] = [
'verify_peer' => false, 'verify_peer' => false,
'verify_peer_name' => false, 'verify_peer_name' => false,
'allow_self_signed' => true, 'allow_self_signed' => true,
]; ];
} }
$context = stream_context_create($contextOptions); $context = stream_context_create($context_options);
try { try {
$errno = 0; $errno = 0;
@@ -215,10 +421,8 @@ if (isset($_POST['test_email_imap'])) {
fclose($fp); fclose($fp);
throw new Exception("Invalid IMAP greeting: " . trim((string) $greeting)); throw new Exception("Invalid IMAP greeting: " . trim((string) $greeting));
} }
// If you really want STARTTLS for "tls" (port 143), you can do it here // If you really want STARTTLS for "tls" (port 143), you can do it here
if ($encryption === 'tls' && stripos($greeting, 'STARTTLS') !== false) { if ($encryption === 'tls' && stripos($greeting, 'STARTTLS') !== false) {
// Request STARTTLS
fwrite($fp, "A0001 STARTTLS\r\n"); fwrite($fp, "A0001 STARTTLS\r\n");
$line = fgets($fp, 1024); $line = fgets($fp, 1024);
if ($line === false || stripos($line, 'A0001 OK') !== 0) { if ($line === false || stripos($line, 'A0001 OK') !== 0) {
@@ -226,28 +430,31 @@ if (isset($_POST['test_email_imap'])) {
throw new Exception("STARTTLS failed: " . trim((string) $line)); throw new Exception("STARTTLS failed: " . trim((string) $line));
} }
// Enable crypto on the stream
if (!stream_socket_enable_crypto($fp, true, STREAM_CRYPTO_METHOD_TLS_CLIENT)) { if (!stream_socket_enable_crypto($fp, true, STREAM_CRYPTO_METHOD_TLS_CLIENT)) {
fclose($fp); fclose($fp);
throw new Exception("Unable to enable TLS encryption on IMAP connection."); throw new Exception("Unable to enable TLS encryption on IMAP connection.");
} }
} }
// --- Do LOGIN command ---
$tag = 'A0002'; $tag = 'A0002';
// Simple quoting; this may fail with some special chars in username/password. if ($is_oauth) {
$loginCmd = sprintf( $oauth_b64 = base64_encode("user={$username}\x01auth=Bearer {$password}\x01\x01");
$auth_cmd = sprintf("%s AUTHENTICATE XOAUTH2 %s\r\n", $tag, $oauth_b64);
fwrite($fp, $auth_cmd);
} else {
$login_cmd = sprintf(
"%s LOGIN \"%s\" \"%s\"\r\n", "%s LOGIN \"%s\" \"%s\"\r\n",
$tag, $tag,
addcslashes($username, "\\\""), addcslashes($username, "\\\""),
addcslashes($password, "\\\"") addcslashes($password, "\\\"")
); );
fwrite($fp, $loginCmd); fwrite($fp, $login_cmd);
}
$success = false; $success = false;
$errorLine = ''; $error_line = '';
while (!feof($fp)) { while (!feof($fp)) {
$line = fgets($fp, 2048); $line = fgets($fp, 2048);
@@ -255,12 +462,11 @@ if (isset($_POST['test_email_imap'])) {
break; break;
} }
// Look for tagged response for our LOGIN
if (strpos($line, $tag . ' ') === 0) { if (strpos($line, $tag . ' ') === 0) {
if (stripos($line, $tag . ' OK') === 0) { if (stripos($line, $tag . ' OK') === 0) {
$success = true; $success = true;
} else { } else {
$errorLine = trim($line); $error_line = trim($line);
} }
break; break;
} }
@@ -271,12 +477,16 @@ if (isset($_POST['test_email_imap'])) {
fclose($fp); fclose($fp);
if ($success) { if ($success) {
flash_alert("Connected successfully"); if ($is_oauth) {
flash_alert("Connected successfully using OAuth");
} else { } else {
if (!$errorLine) { flash_alert("Connected successfully");
$errorLine = 'Unknown IMAP authentication error';
} }
throw new Exception($errorLine); } else {
if (!$error_line) {
$error_line = 'Unknown IMAP authentication error';
}
throw new Exception($error_line);
} }
} catch (Exception $e) { } catch (Exception $e) {
@@ -285,3 +495,88 @@ if (isset($_POST['test_email_imap'])) {
redirect(); redirect();
} }
if (isset($_POST['test_oauth_token_refresh'])) {
validateCSRFToken($_POST['csrf_token']);
$provider = sanitizeInput($_POST['oauth_provider'] ?? '');
if ($provider !== 'google_oauth' && $provider !== 'microsoft_oauth') {
flash_alert("OAuth token test failed: unsupported provider.", 'error');
redirect();
}
$oauth_client_id = sanitizeInput($config_mail_oauth_client_id ?? '');
$oauth_client_secret = sanitizeInput($config_mail_oauth_client_secret ?? '');
$oauth_tenant_id = sanitizeInput($config_mail_oauth_tenant_id ?? '');
$oauth_refresh_token = sanitizeInput($config_mail_oauth_refresh_token ?? '');
if (empty($oauth_client_id) || empty($oauth_client_secret) || empty($oauth_refresh_token)) {
flash_alert("OAuth token test failed: missing client ID, client secret, or refresh token.", 'error');
redirect();
}
if ($provider === 'microsoft_oauth' && empty($oauth_tenant_id)) {
flash_alert("OAuth token test failed: Microsoft tenant ID is required.", 'error');
redirect();
}
$token_url = 'https://oauth2.googleapis.com/token';
if ($provider === 'microsoft_oauth') {
$token_url = MICROSOFT_OAUTH_BASE_URL . rawurlencode($oauth_tenant_id) . "/oauth2/v2.0/token";
}
$post_fields = http_build_query([
'client_id' => $oauth_client_id,
'client_secret' => $oauth_client_secret,
'refresh_token' => $oauth_refresh_token,
'grant_type' => 'refresh_token',
]);
$ch = curl_init($token_url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, $post_fields);
curl_setopt($ch, CURLOPT_TIMEOUT, 20);
$raw_body = curl_exec($ch);
$curl_err = curl_error($ch);
$http_code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
if ($raw_body === false || $http_code < 200 || $http_code >= 300) {
$err_msg = !empty($curl_err) ? $curl_err : "HTTP $http_code";
flash_alert("OAuth token test failed: $err_msg", 'error');
redirect();
}
$json = json_decode($raw_body, true);
if (!is_array($json) || empty($json['access_token'])) {
flash_alert("OAuth token test failed: access token missing in provider response.", 'error');
redirect();
}
$new_access_token = sanitizeInput($json['access_token']);
$new_expires_at = date('Y-m-d H:i:s', time() + (int)($json['expires_in'] ?? 3600));
$new_refresh_token = !empty($json['refresh_token']) ? sanitizeInput($json['refresh_token']) : '';
$new_access_token_esc = mysqli_real_escape_string($mysqli, $new_access_token);
$new_expires_at_esc = mysqli_real_escape_string($mysqli, $new_expires_at);
$refresh_sql = '';
if (!empty($new_refresh_token)) {
$new_refresh_token_esc = mysqli_real_escape_string($mysqli, $new_refresh_token);
$refresh_sql = ", config_mail_oauth_refresh_token = '$new_refresh_token_esc'";
}
mysqli_query($mysqli, "UPDATE settings SET config_mail_oauth_access_token = '$new_access_token_esc', config_mail_oauth_access_token_expires_at = '$new_expires_at_esc'$refresh_sql WHERE company_id = 1");
$provider_label = $provider === 'microsoft_oauth' ? 'Microsoft 365' : 'Google Workspace';
logAction("Settings", "Edit", "$session_name tested OAuth token refresh for $provider_label mail settings");
flash_alert("OAuth token refresh successful for $provider_label. Access token expires at $new_expires_at.");
redirect();
}

View File

@@ -34,7 +34,7 @@ if (isset($_GET['stripe_remove_pm'])) {
// Remove Auto Pay on recurring invoices that are stripe // Remove Auto Pay on recurring invoices that are stripe
$sql_recurring_invoices = mysqli_query($mysqli, "SELECT recurring_invoice_id FROM recurring_invoices WHERE recurring_invoice_client_id = $client_id"); $sql_recurring_invoices = mysqli_query($mysqli, "SELECT recurring_invoice_id FROM recurring_invoices WHERE recurring_invoice_client_id = $client_id");
while ($row = mysqli_fetch_array($sql_recurring_invoices)) { while ($row = mysqli_fetch_assoc($sql_recurring_invoices)) {
$recurring_invoice_id = intval($row['recurring_invoice_id']); $recurring_invoice_id = intval($row['recurring_invoice_id']);
mysqli_query($mysqli, "DELETE FROM recurring_payments WHERE recurring_payment_method = 'Stripe' AND recurring_payment_recurring_invoice_id = $recurring_invoice_id"); mysqli_query($mysqli, "DELETE FROM recurring_payments WHERE recurring_payment_method = 'Stripe' AND recurring_payment_recurring_invoice_id = $recurring_invoice_id");
} }
@@ -59,7 +59,7 @@ if (isset($_GET['stripe_reset_customer'])) {
// Remove Auto Pay on recurring invoices that are stripe // Remove Auto Pay on recurring invoices that are stripe
$sql_recurring_invoices = mysqli_query($mysqli, "SELECT recurring_invoice_id FROM recurring_invoices WHERE recurring_invoice_client_id = $client_id"); $sql_recurring_invoices = mysqli_query($mysqli, "SELECT recurring_invoice_id FROM recurring_invoices WHERE recurring_invoice_client_id = $client_id");
while ($row = mysqli_fetch_array($sql_recurring_invoices)) { while ($row = mysqli_fetch_assoc($sql_recurring_invoices)) {
$recurring_invoice_id = intval($row['recurring_invoice_id']); $recurring_invoice_id = intval($row['recurring_invoice_id']);
mysqli_query($mysqli, "DELETE FROM recurring_payments WHERE recurring_payment_method = 'Stripe' AND recurring_payment_recurring_invoice_id = $recurring_invoice_id"); mysqli_query($mysqli, "DELETE FROM recurring_payments WHERE recurring_payment_method = 'Stripe' AND recurring_payment_recurring_invoice_id = $recurring_invoice_id");
} }

View File

@@ -51,7 +51,7 @@ if (isset($_GET['delete_software_template'])) {
// Get Software Template Name for logging and alert message // Get Software Template Name for logging and alert message
$sql = mysqli_query($mysqli,"SELECT software_template_name FROM software_templates WHERE software_template_id = $software_template_id"); $sql = mysqli_query($mysqli,"SELECT software_template_name FROM software_templates WHERE software_template_id = $software_template_id");
$row = mysqli_fetch_array($sql); $row = mysqli_fetch_assoc($sql);
$software_template_name = sanitizeInput($row['software_template_name']); $software_template_name = sanitizeInput($row['software_template_name']);
mysqli_query($mysqli,"DELETE FROM software_templates WHERE software_template_id = $software_template_id"); mysqli_query($mysqli,"DELETE FROM software_templates WHERE software_template_id = $software_template_id");

View File

@@ -21,7 +21,7 @@ if (isset($_GET['update'])) {
if ($config_telemetry > 0 OR $config_telemetry = 2) { if ($config_telemetry > 0 OR $config_telemetry = 2) {
$sql = mysqli_query($mysqli,"SELECT * FROM companies WHERE company_id = 1"); $sql = mysqli_query($mysqli,"SELECT * FROM companies WHERE company_id = 1");
$row = mysqli_fetch_array($sql); $row = mysqli_fetch_assoc($sql);
$company_name = sanitizeInput($row['company_name']); $company_name = sanitizeInput($row['company_name']);
$website = sanitizeInput($row['company_website']); $website = sanitizeInput($row['company_website']);

View File

@@ -53,7 +53,7 @@ if (isset($_POST['add_user'])) {
mysqli_query($mysqli, "INSERT INTO user_settings SET user_id = $user_id, user_config_force_mfa = $force_mfa"); mysqli_query($mysqli, "INSERT INTO user_settings SET user_id = $user_id, user_config_force_mfa = $force_mfa");
$sql = mysqli_query($mysqli,"SELECT * FROM companies WHERE company_id = 1"); $sql = mysqli_query($mysqli,"SELECT * FROM companies WHERE company_id = 1");
$row = mysqli_fetch_array($sql); $row = mysqli_fetch_assoc($sql);
$company_name = sanitizeInput($row['company_name']); $company_name = sanitizeInput($row['company_name']);
// Sanitize Config vars from load_global_settings.php // Sanitize Config vars from load_global_settings.php
@@ -118,7 +118,7 @@ if (isset($_POST['edit_user'])) {
// Get current Avatar // Get current Avatar
$sql = mysqli_query($mysqli, "SELECT user_avatar FROM users WHERE user_id = $user_id"); $sql = mysqli_query($mysqli, "SELECT user_avatar FROM users WHERE user_id = $user_id");
$row = mysqli_fetch_array($sql); $row = mysqli_fetch_assoc($sql);
$existing_file_name = sanitizeInput($row['user_avatar']); $existing_file_name = sanitizeInput($row['user_avatar']);
$extended_log_description = ''; $extended_log_description = '';
@@ -353,7 +353,7 @@ if (isset($_POST['ir_reset_user_password'])) {
// Confirm logged-in user password, for security // Confirm logged-in user password, for security
$admin_password = $_POST['admin_password']; $admin_password = $_POST['admin_password'];
$sql = mysqli_query($mysqli, "SELECT * FROM users WHERE user_id = $session_user_id"); $sql = mysqli_query($mysqli, "SELECT * FROM users WHERE user_id = $session_user_id");
$userRow = mysqli_fetch_array($sql); $userRow = mysqli_fetch_assoc($sql);
if (!password_verify($admin_password, $userRow['user_password'])) { if (!password_verify($admin_password, $userRow['user_password'])) {
flash_alert("Incorrect password.", 'error'); flash_alert("Incorrect password.", 'error');
@@ -364,7 +364,7 @@ if (isset($_POST['ir_reset_user_password'])) {
$sql_users = mysqli_query($mysqli, "SELECT * FROM users WHERE (user_archived_at IS NULL AND user_id != $session_user_id)"); $sql_users = mysqli_query($mysqli, "SELECT * FROM users WHERE (user_archived_at IS NULL AND user_id != $session_user_id)");
// Reset passwords // Reset passwords
while ($row = mysqli_fetch_array($sql_users)) { while ($row = mysqli_fetch_assoc($sql_users)) {
$user_id = intval($row['user_id']); $user_id = intval($row['user_id']);
$user_email = sanitizeInput($row['user_email']); $user_email = sanitizeInput($row['user_email']);
$new_password = randomString(); $new_password = randomString();

View File

@@ -61,7 +61,7 @@ $num_rows = mysqli_fetch_row(mysqli_query($mysqli, "SELECT FOUND_ROWS()"));
<tbody> <tbody>
<?php <?php
while($row = mysqli_fetch_array($sql)){ while($row = mysqli_fetch_assoc($sql)){
$project_template_id = intval($row['project_template_id']); $project_template_id = intval($row['project_template_id']);
$project_template_name = nullable_htmlentities($row['project_template_name']); $project_template_name = nullable_htmlentities($row['project_template_name']);
$project_template_description = nullable_htmlentities($row['project_template_description']); $project_template_description = nullable_htmlentities($row['project_template_description']);

View File

@@ -19,7 +19,7 @@ if (isset($_GET['project_template_id'])) {
exit; exit;
} }
$row = mysqli_fetch_array($sql_project_templates); $row = mysqli_fetch_assoc($sql_project_templates);
$project_template_name = nullable_htmlentities($row['project_template_name']); $project_template_name = nullable_htmlentities($row['project_template_name']);
$project_template_description = nullable_htmlentities($row['project_template_description']); $project_template_description = nullable_htmlentities($row['project_template_description']);
@@ -143,7 +143,7 @@ if (isset($_GET['project_template_id'])) {
<tbody> <tbody>
<?php <?php
while ($row = mysqli_fetch_array($sql_ticket_templates)) { while ($row = mysqli_fetch_assoc($sql_ticket_templates)) {
$ticket_template_id = intval($row['ticket_template_id']); $ticket_template_id = intval($row['ticket_template_id']);
$ticket_template_order = intval($row['ticket_template_order']); $ticket_template_order = intval($row['ticket_template_order']);
$ticket_template_name = nullable_htmlentities($row['ticket_template_name']); $ticket_template_name = nullable_htmlentities($row['ticket_template_name']);
@@ -199,7 +199,7 @@ if (isset($_GET['project_template_id'])) {
<h5 class="text-secondary"><i class="fas fa-fw fa-tasks mr-2"></i>Project Task Templates</h5> <h5 class="text-secondary"><i class="fas fa-fw fa-tasks mr-2"></i>Project Task Templates</h5>
<table class="table"> <table class="table">
<?php <?php
while($row = mysqli_fetch_array($sql_task_templates)){ while($row = mysqli_fetch_assoc($sql_task_templates)){
$task_template_id = intval($row['task_template_id']); $task_template_id = intval($row['task_template_id']);
$task_template_name = nullable_htmlentities($row['task_template_name']); $task_template_name = nullable_htmlentities($row['task_template_name']);
?> ?>

View File

@@ -65,7 +65,7 @@ $num_rows = mysqli_fetch_row(mysqli_query($mysqli, "SELECT FOUND_ROWS()"));
<tbody> <tbody>
<?php <?php
while ($row = mysqli_fetch_array($sql)) { while ($row = mysqli_fetch_assoc($sql)) {
$role_id = intval($row['role_id']); $role_id = intval($row['role_id']);
$role_name = nullable_htmlentities($row['role_name']); $role_name = nullable_htmlentities($row['role_name']);
$role_description = nullable_htmlentities($row['role_description']); $role_description = nullable_htmlentities($row['role_description']);

View File

@@ -104,7 +104,7 @@ $num_rows = mysqli_fetch_row(mysqli_query($mysqli, "SELECT FOUND_ROWS()"));
<tbody> <tbody>
<?php <?php
while ($row = mysqli_fetch_array($sql)) { while ($row = mysqli_fetch_assoc($sql)) {
$saved_payment_id = intval($row['saved_payment_id']); $saved_payment_id = intval($row['saved_payment_id']);
$client_id = intval($row['saved_payment_client_id']); $client_id = intval($row['saved_payment_client_id']);
$client_name = nullable_htmlentities($row['client_name']); $client_name = nullable_htmlentities($row['client_name']);

View File

@@ -4,7 +4,7 @@ require_once "includes/inc_all_admin.php";
$sql = mysqli_query($mysqli,"SELECT * FROM companies, settings WHERE companies.company_id = settings.company_id AND companies.company_id = 1"); $sql = mysqli_query($mysqli,"SELECT * FROM companies, settings WHERE companies.company_id = settings.company_id AND companies.company_id = 1");
$row = mysqli_fetch_array($sql); $row = mysqli_fetch_assoc($sql);
$company_id = intval($row['company_id']); $company_id = intval($row['company_id']);
$company_name = nullable_htmlentities($row['company_name']); $company_name = nullable_htmlentities($row['company_name']);
$company_country = nullable_htmlentities($row['company_country']); $company_country = nullable_htmlentities($row['company_country']);

View File

@@ -66,7 +66,7 @@ $num_rows = mysqli_fetch_row(mysqli_query($mysqli, "SELECT FOUND_ROWS()"));
<tbody> <tbody>
<?php <?php
while ($row = mysqli_fetch_array($sql)) { while ($row = mysqli_fetch_assoc($sql)) {
$custom_field_id = intval($row['custom_field_id']); $custom_field_id = intval($row['custom_field_id']);
$custom_field_label = nullable_htmlentities($row['custom_field_label']); $custom_field_label = nullable_htmlentities($row['custom_field_label']);
$custom_field_type = nullable_htmlentities($row['custom_field_type']); $custom_field_type = nullable_htmlentities($row['custom_field_type']);
@@ -118,4 +118,3 @@ $num_rows = mysqli_fetch_row(mysqli_query($mysqli, "SELECT FOUND_ROWS()"));
require_once "custom_field_create_modal.php"; require_once "custom_field_create_modal.php";
require_once "../includes/footer.php"; require_once "../includes/footer.php";

View File

@@ -42,7 +42,7 @@ require_once "includes/inc_all_admin.php";
<?php <?php
$sql = mysqli_query($mysqli, "SELECT * FROM calendars ORDER BY calendar_name ASC"); $sql = mysqli_query($mysqli, "SELECT * FROM calendars ORDER BY calendar_name ASC");
while ($row = mysqli_fetch_array($sql)) { while ($row = mysqli_fetch_assoc($sql)) {
$calendar_id = intval($row['calendar_id']); $calendar_id = intval($row['calendar_id']);
$calendar_name = nullable_htmlentities($row['calendar_name']); ?> $calendar_name = nullable_htmlentities($row['calendar_name']); ?>
<option <?php if ($config_default_calendar == $calendar_id) { <option <?php if ($config_default_calendar == $calendar_id) {
@@ -65,7 +65,7 @@ require_once "includes/inc_all_admin.php";
<?php <?php
$sql = mysqli_query($mysqli, "SELECT * FROM accounts WHERE account_archived_at IS NULL ORDER BY account_name ASC"); $sql = mysqli_query($mysqli, "SELECT * FROM accounts WHERE account_archived_at IS NULL ORDER BY account_name ASC");
while ($row = mysqli_fetch_array($sql)) { while ($row = mysqli_fetch_assoc($sql)) {
$account_id = intval($row['account_id']); $account_id = intval($row['account_id']);
$account_name = nullable_htmlentities($row['account_name']); ?> $account_name = nullable_htmlentities($row['account_name']); ?>
<option <?php if ($config_default_transfer_from_account == $account_id) { <option <?php if ($config_default_transfer_from_account == $account_id) {
@@ -88,7 +88,7 @@ require_once "includes/inc_all_admin.php";
<?php <?php
$sql = mysqli_query($mysqli, "SELECT * FROM accounts WHERE account_archived_at IS NULL ORDER BY account_name ASC"); $sql = mysqli_query($mysqli, "SELECT * FROM accounts WHERE account_archived_at IS NULL ORDER BY account_name ASC");
while ($row = mysqli_fetch_array($sql)) { while ($row = mysqli_fetch_assoc($sql)) {
$account_id = intval($row['account_id']); $account_id = intval($row['account_id']);
$account_name = nullable_htmlentities($row['account_name']); ?> $account_name = nullable_htmlentities($row['account_name']); ?>
<option <?php if ($config_default_transfer_to_account == $account_id) { <option <?php if ($config_default_transfer_to_account == $account_id) {
@@ -111,7 +111,7 @@ require_once "includes/inc_all_admin.php";
<?php <?php
$sql = mysqli_query($mysqli, "SELECT * FROM accounts WHERE account_archived_at IS NULL ORDER BY account_name ASC"); $sql = mysqli_query($mysqli, "SELECT * FROM accounts WHERE account_archived_at IS NULL ORDER BY account_name ASC");
while ($row = mysqli_fetch_array($sql)) { while ($row = mysqli_fetch_assoc($sql)) {
$account_id = intval($row['account_id']); $account_id = intval($row['account_id']);
$account_name = nullable_htmlentities($row['account_name']); ?> $account_name = nullable_htmlentities($row['account_name']); ?>
<option <?php if ($config_default_payment_account == $account_id) { <option <?php if ($config_default_payment_account == $account_id) {
@@ -136,7 +136,7 @@ require_once "includes/inc_all_admin.php";
<?php <?php
$sql = mysqli_query($mysqli, "SELECT * FROM accounts WHERE account_archived_at IS NULL ORDER BY account_name ASC"); $sql = mysqli_query($mysqli, "SELECT * FROM accounts WHERE account_archived_at IS NULL ORDER BY account_name ASC");
while ($row = mysqli_fetch_array($sql)) { while ($row = mysqli_fetch_assoc($sql)) {
$account_id = intval($row['account_id']); $account_id = intval($row['account_id']);
$account_name = nullable_htmlentities($row['account_name']); ?> $account_name = nullable_htmlentities($row['account_name']); ?>
<option <?php if ($config_default_expense_account == $account_id) { <option <?php if ($config_default_expense_account == $account_id) {
@@ -159,7 +159,7 @@ require_once "includes/inc_all_admin.php";
<?php <?php
$sql = mysqli_query($mysqli, "SELECT * FROM categories WHERE category_type = 'Payment Method' ORDER BY category_name ASC"); $sql = mysqli_query($mysqli, "SELECT * FROM categories WHERE category_type = 'Payment Method' ORDER BY category_name ASC");
while ($row = mysqli_fetch_array($sql)) { while ($row = mysqli_fetch_assoc($sql)) {
$payment_method = nullable_htmlentities($row['category_name']); ?> $payment_method = nullable_htmlentities($row['category_name']); ?>
<option <?php if ($config_default_payment_method == $payment_method) { <option <?php if ($config_default_payment_method == $payment_method) {
echo "selected"; echo "selected";
@@ -181,7 +181,7 @@ require_once "includes/inc_all_admin.php";
<?php <?php
$sql = mysqli_query($mysqli, "SELECT * FROM categories WHERE category_type = 'Payment Method' ORDER BY category_name ASC"); $sql = mysqli_query($mysqli, "SELECT * FROM categories WHERE category_type = 'Payment Method' ORDER BY category_name ASC");
while ($row = mysqli_fetch_array($sql)) { while ($row = mysqli_fetch_assoc($sql)) {
$payment_method = nullable_htmlentities($row['category_name']); ?> $payment_method = nullable_htmlentities($row['category_name']); ?>
<option <?php if ($config_default_expense_payment_method == $payment_method) { <option <?php if ($config_default_expense_payment_method == $payment_method) {
echo "selected"; echo "selected";

View File

@@ -4,7 +4,7 @@ require_once "includes/inc_all_admin.php";
$sql = mysqli_query($mysqli,"SELECT * FROM companies, settings WHERE companies.company_id = settings.company_id AND companies.company_id = 1"); $sql = mysqli_query($mysqli,"SELECT * FROM companies, settings WHERE companies.company_id = settings.company_id AND companies.company_id = 1");
$row = mysqli_fetch_array($sql); $row = mysqli_fetch_assoc($sql);
$company_locale = nullable_htmlentities($row['company_locale']); $company_locale = nullable_htmlentities($row['company_locale']);
$company_currency = nullable_htmlentities($row['company_currency']); $company_currency = nullable_htmlentities($row['company_currency']);
@@ -76,4 +76,3 @@ $timezones = DateTimeZone::listIdentifiers();
<?php <?php
require_once "../includes/footer.php"; require_once "../includes/footer.php";

View File

@@ -243,6 +243,32 @@ require_once "includes/inc_all_admin.php";
</div> </div>
</div> </div>
<?php
if (defined('BASE_URL') && !empty(BASE_URL)) {
$mail_oauth_callback_uri = rtrim((string) BASE_URL, '/') . '/admin/oauth_microsoft_mail_callback.php';
} else {
$mail_oauth_callback_uri = 'https://' . rtrim((string) $config_base_url, '/') . '/admin/oauth_microsoft_mail_callback.php';
}
?>
<div class="form-group">
<label>Microsoft OAuth Connect (Web)</label>
<div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text"><i class="fa fa-fw fa-link"></i></span>
</div>
<input type="text" class="form-control" readonly value="<?php echo htmlspecialchars($mail_oauth_callback_uri); ?>">
<div class="input-group-append">
<button type="submit" name="oauth_connect_microsoft_mail" class="btn btn-outline-primary">
<i class="fas fa-fw fa-sign-in-alt mr-2"></i>Connect Microsoft 365
</button>
</div>
</div>
<small class="text-secondary">
Add this callback URI in Entra App Registration, then click Connect to authorize and store refresh token automatically.
</small>
</div>
<hr> <hr>
<button type="submit" name="edit_mail_imap_settings" class="btn btn-primary text-bold"><i class="fas fa-check mr-2"></i>Save</button> <button type="submit" name="edit_mail_imap_settings" class="btn btn-primary text-bold"><i class="fas fa-check mr-2"></i>Save</button>
@@ -359,7 +385,22 @@ require_once "includes/inc_all_admin.php";
</div> </div>
</div> </div>
<?php if (!empty($config_smtp_host) && !empty($config_smtp_port) && !empty($config_mail_from_email) && !empty($config_mail_from_name)) { ?> <?php
$smtp_standard_ready = !empty($config_smtp_host)
&& !empty($config_smtp_port)
&& !empty($config_mail_from_email)
&& !empty($config_mail_from_name);
$smtp_oauth_ready = ($config_smtp_provider === 'google_oauth' || $config_smtp_provider === 'microsoft_oauth')
&& !empty($config_mail_from_email)
&& !empty($config_mail_from_name)
&& !empty($config_mail_oauth_client_id)
&& !empty($config_mail_oauth_client_secret)
&& !empty($config_mail_oauth_refresh_token)
&& ($config_smtp_provider !== 'microsoft_oauth' || !empty($config_mail_oauth_tenant_id));
?>
<?php if ($smtp_standard_ready || $smtp_oauth_ready) { ?>
<div class="card card-dark"> <div class="card card-dark">
<div class="card-header py-3"> <div class="card-header py-3">
@@ -409,7 +450,21 @@ require_once "includes/inc_all_admin.php";
<?php } ?> <?php } ?>
<?php if (!empty($config_imap_username) && !empty($config_imap_password) && !empty($config_imap_host) && !empty($config_imap_port)) { ?> <?php
$imap_standard_ready = !empty($config_imap_username)
&& !empty($config_imap_password)
&& !empty($config_imap_host)
&& !empty($config_imap_port);
$imap_oauth_ready = ($config_imap_provider === 'google_oauth' || $config_imap_provider === 'microsoft_oauth')
&& !empty($config_imap_username)
&& !empty($config_mail_oauth_client_id)
&& !empty($config_mail_oauth_client_secret)
&& !empty($config_mail_oauth_refresh_token)
&& ($config_imap_provider !== 'microsoft_oauth' || !empty($config_mail_oauth_tenant_id));
?>
<?php if ($imap_standard_ready || $imap_oauth_ready) { ?>
<div class="card card-dark"> <div class="card card-dark">
<div class="card-header py-3"> <div class="card-header py-3">
@@ -428,6 +483,46 @@ require_once "includes/inc_all_admin.php";
<?php } ?> <?php } ?>
<?php
$oauth_provider_for_test = '';
if ($config_imap_provider === 'google_oauth' || $config_imap_provider === 'microsoft_oauth') {
$oauth_provider_for_test = $config_imap_provider;
} elseif ($config_smtp_provider === 'google_oauth' || $config_smtp_provider === 'microsoft_oauth') {
$oauth_provider_for_test = $config_smtp_provider;
}
$oauth_has_required_fields = !empty($oauth_provider_for_test)
&& !empty($config_mail_oauth_client_id)
&& !empty($config_mail_oauth_client_secret)
&& !empty($config_mail_oauth_refresh_token)
&& ($oauth_provider_for_test !== 'microsoft_oauth' || !empty($config_mail_oauth_tenant_id));
?>
<?php if ($oauth_has_required_fields) { ?>
<div class="card card-dark">
<div class="card-header py-3">
<h3 class="card-title"><i class="fas fa-fw fa-key mr-2"></i>Test OAuth Token Refresh</h3>
</div>
<div class="card-body">
<form action="post.php" method="post" autocomplete="off">
<input type="hidden" name="csrf_token" value="<?php echo $_SESSION['csrf_token'] ?>">
<input type="hidden" name="oauth_provider" value="<?php echo htmlspecialchars($oauth_provider_for_test); ?>">
<p class="text-secondary mb-3">
This validates your refresh token and stores a new access token for
<?php echo $oauth_provider_for_test === 'microsoft_oauth' ? 'Microsoft 365' : 'Google Workspace'; ?>.
</p>
<button type="submit" name="test_oauth_token_refresh" class="btn btn-success">
<i class="fas fa-fw fa-sync-alt mr-2"></i>Test OAuth Token Refresh
</button>
</form>
</div>
</div>
<?php } ?>
<script> <script>
(function(){ (function(){
function setDisabled(container, disabled){ function setDisabled(container, disabled){

View File

@@ -97,7 +97,7 @@ require_once "includes/inc_all_admin.php";
<label>Kanban Settings</label> <label>Kanban Settings</label>
<div class="custom-control custom-switch"> <div class="custom-control custom-switch">
<input type="checkbox" class="custom-control-input" name="config_ticket_ordering" <?php if ($config_ticket_ordering == 1) { echo "checked"; } ?> value="1" id="ticketOrderingSwitch"> <input type="checkbox" class="custom-control-input" name="config_ticket_ordering" <?php if ($config_ticket_ordering == 1) { echo "checked"; } ?> value="1" id="ticketOrderingSwitch">
<label class="custom-control-label" for="ticketOrderingSwitch">Allow ticket ordering within its column<small class="text-secondary">(uncheked will result in ordering it by priority and id)</small></label> <label class="custom-control-label" for="ticketOrderingSwitch">Allow ticket ordering within its column<small class="text-secondary"> (unchecked = order by priority and id)</small></label>
</div> </div>
<div class="custom-control custom-switch"> <div class="custom-control custom-switch">
<input type="checkbox" class="custom-control-input" name="config_ticket_moving_columns" <?php if ($config_ticket_moving_columns == 1) { echo "checked"; } ?> value="1" id="ticketMovingColumnsSwitch"> <input type="checkbox" class="custom-control-input" name="config_ticket_moving_columns" <?php if ($config_ticket_moving_columns == 1) { echo "checked"; } ?> value="1" id="ticketMovingColumnsSwitch">

View File

@@ -68,7 +68,7 @@ $num_rows = mysqli_fetch_row(mysqli_query($mysqli, "SELECT FOUND_ROWS()"));
<tbody> <tbody>
<?php <?php
while($row = mysqli_fetch_array($sql)){ while($row = mysqli_fetch_assoc($sql)){
$software_template_id = intval($row['software_template_id']); $software_template_id = intval($row['software_template_id']);
$software_template_name = nullable_htmlentities($row['software_template_name']); $software_template_name = nullable_htmlentities($row['software_template_name']);
$software_template_version = nullable_htmlentities($row['software_template_version']); $software_template_version = nullable_htmlentities($row['software_template_version']);

View File

@@ -117,7 +117,7 @@ $num_rows = mysqli_fetch_row(mysqli_query($mysqli, "SELECT FOUND_ROWS()"));
<tbody> <tbody>
<?php <?php
while ($row = mysqli_fetch_array($sql)) { while ($row = mysqli_fetch_assoc($sql)) {
$tag_id = intval($row['tag_id']); $tag_id = intval($row['tag_id']);
$tag_name = nullable_htmlentities($row['tag_name']); $tag_name = nullable_htmlentities($row['tag_name']);
$tag_color = nullable_htmlentities($row['tag_color']); $tag_color = nullable_htmlentities($row['tag_color']);

View File

@@ -45,7 +45,7 @@ $num_rows = mysqli_num_rows($sql);
<tbody> <tbody>
<?php <?php
while ($row = mysqli_fetch_array($sql)) { while ($row = mysqli_fetch_assoc($sql)) {
$tax_id = intval($row['tax_id']); $tax_id = intval($row['tax_id']);
$tax_name = nullable_htmlentities($row['tax_name']); $tax_name = nullable_htmlentities($row['tax_name']);
$tax_percent = floatval($row['tax_percent']); $tax_percent = floatval($row['tax_percent']);

View File

@@ -67,7 +67,7 @@ $num_rows = mysqli_fetch_row(mysqli_query($mysqli, "SELECT FOUND_ROWS()"));
<tbody> <tbody>
<?php <?php
while ($row = mysqli_fetch_array($sql)) { while ($row = mysqli_fetch_assoc($sql)) {
$ticket_status_id = intval($row['ticket_status_id']); $ticket_status_id = intval($row['ticket_status_id']);
$ticket_status_name = nullable_htmlentities($row['ticket_status_name']); $ticket_status_name = nullable_htmlentities($row['ticket_status_name']);
$ticket_status_color = nullable_htmlentities($row['ticket_status_color']); $ticket_status_color = nullable_htmlentities($row['ticket_status_color']);

View File

@@ -69,7 +69,7 @@ $num_rows = mysqli_fetch_row(mysqli_query($mysqli, "SELECT FOUND_ROWS()"));
<tbody> <tbody>
<?php <?php
while($row = mysqli_fetch_array($sql)){ while($row = mysqli_fetch_assoc($sql)){
$ticket_template_id = intval($row['ticket_template_id']); $ticket_template_id = intval($row['ticket_template_id']);
$ticket_template_name = nullable_htmlentities($row['ticket_template_name']); $ticket_template_name = nullable_htmlentities($row['ticket_template_name']);
$ticket_template_description = nullable_htmlentities($row['ticket_template_description']); $ticket_template_description = nullable_htmlentities($row['ticket_template_description']);

View File

@@ -23,7 +23,7 @@ if (mysqli_num_rows($sql_ticket_template) == 0) {
exit(); exit();
} }
$row = mysqli_fetch_array($sql_ticket_template); $row = mysqli_fetch_assoc($sql_ticket_template);
$ticket_template_name = nullable_htmlentities($row['ticket_template_name']); $ticket_template_name = nullable_htmlentities($row['ticket_template_name']);
$ticket_template_description = nullable_htmlentities($row['ticket_template_description']); $ticket_template_description = nullable_htmlentities($row['ticket_template_description']);
@@ -98,7 +98,7 @@ $sql_task_templates = mysqli_query($mysqli, "SELECT * FROM task_templates WHERE
</form> </form>
<table class="table table-sm" id="tasks"> <table class="table table-sm" id="tasks">
<?php <?php
while($row = mysqli_fetch_array($sql_task_templates)){ while($row = mysqli_fetch_assoc($sql_task_templates)){
$task_id = intval($row['task_template_id']); $task_id = intval($row['task_template_id']);
$task_name = nullable_htmlentities($row['task_template_name']); $task_name = nullable_htmlentities($row['task_template_name']);
$task_completion_estimate = intval($row['task_template_completion_estimate']); $task_completion_estimate = intval($row['task_template_completion_estimate']);

View File

@@ -104,7 +104,7 @@ $num_rows = mysqli_fetch_row(mysqli_query($mysqli, "SELECT FOUND_ROWS()"));
<tbody> <tbody>
<?php <?php
while ($row = mysqli_fetch_array($sql)) { while ($row = mysqli_fetch_assoc($sql)) {
$user_id = intval($row['user_id']); $user_id = intval($row['user_id']);
$user_name = nullable_htmlentities($row['user_name']); $user_name = nullable_htmlentities($row['user_name']);
$user_email = nullable_htmlentities($row['user_email']); $user_email = nullable_htmlentities($row['user_email']);
@@ -139,7 +139,7 @@ $num_rows = mysqli_fetch_row(mysqli_query($mysqli, "SELECT FOUND_ROWS()"));
if (mysqli_num_rows($sql_last_login) == 0) { if (mysqli_num_rows($sql_last_login) == 0) {
$last_login = "<span class='text-bold'>Never logged in</span>"; $last_login = "<span class='text-bold'>Never logged in</span>";
} else { } else {
$row = mysqli_fetch_array($sql_last_login); $row = mysqli_fetch_assoc($sql_last_login);
$log_created_at = nullable_htmlentities($row['log_created_at']); $log_created_at = nullable_htmlentities($row['log_created_at']);
$log_ip = nullable_htmlentities($row['log_ip']); $log_ip = nullable_htmlentities($row['log_ip']);
$log_user_agent = nullable_htmlentities($row['log_user_agent']); $log_user_agent = nullable_htmlentities($row['log_user_agent']);

View File

@@ -64,7 +64,7 @@ $num_rows = mysqli_fetch_row(mysqli_query($mysqli, "SELECT FOUND_ROWS()"));
<tbody> <tbody>
<?php <?php
while ($row = mysqli_fetch_array($sql)) { while ($row = mysqli_fetch_assoc($sql)) {
$vendor_template_id = intval($row['vendor_template_id']); $vendor_template_id = intval($row['vendor_template_id']);
$vendor_template_name = nullable_htmlentities($row['vendor_template_name']); $vendor_template_name = nullable_htmlentities($row['vendor_template_name']);
$vendor_template_description = nullable_htmlentities($row['vendor_template_description']); $vendor_template_description = nullable_htmlentities($row['vendor_template_description']);

View File

@@ -59,7 +59,7 @@ $num_rows = mysqli_fetch_row(mysqli_query($mysqli, "SELECT FOUND_ROWS()"));
<tbody> <tbody>
<?php <?php
while ($row = mysqli_fetch_array($sql)) { while ($row = mysqli_fetch_assoc($sql)) {
$account_id = intval($row['account_id']); $account_id = intval($row['account_id']);
$account_name = nullable_htmlentities($row['account_name']); $account_name = nullable_htmlentities($row['account_name']);
$opening_balance = floatval($row['opening_balance']); $opening_balance = floatval($row['opening_balance']);
@@ -67,15 +67,15 @@ $num_rows = mysqli_fetch_row(mysqli_query($mysqli, "SELECT FOUND_ROWS()"));
$account_notes = nullable_htmlentities($row['account_notes']); $account_notes = nullable_htmlentities($row['account_notes']);
$sql_payments = mysqli_query($mysqli, "SELECT SUM(payment_amount) AS total_payments FROM payments WHERE payment_account_id = $account_id"); $sql_payments = mysqli_query($mysqli, "SELECT SUM(payment_amount) AS total_payments FROM payments WHERE payment_account_id = $account_id");
$row = mysqli_fetch_array($sql_payments); $row = mysqli_fetch_assoc($sql_payments);
$total_payments = floatval($row['total_payments']); $total_payments = floatval($row['total_payments']);
$sql_revenues = mysqli_query($mysqli, "SELECT SUM(revenue_amount) AS total_revenues FROM revenues WHERE revenue_account_id = $account_id"); $sql_revenues = mysqli_query($mysqli, "SELECT SUM(revenue_amount) AS total_revenues FROM revenues WHERE revenue_account_id = $account_id");
$row = mysqli_fetch_array($sql_revenues); $row = mysqli_fetch_assoc($sql_revenues);
$total_revenues = floatval($row['total_revenues']); $total_revenues = floatval($row['total_revenues']);
$sql_expenses = mysqli_query($mysqli, "SELECT SUM(expense_amount) AS total_expenses FROM expenses WHERE expense_account_id = $account_id"); $sql_expenses = mysqli_query($mysqli, "SELECT SUM(expense_amount) AS total_expenses FROM expenses WHERE expense_account_id = $account_id");
$row = mysqli_fetch_array($sql_expenses); $row = mysqli_fetch_assoc($sql_expenses);
$total_expenses = floatval($row['total_expenses']); $total_expenses = floatval($row['total_expenses']);
$balance = $opening_balance + $total_payments + $total_revenues - $total_expenses; $balance = $opening_balance + $total_payments + $total_revenues - $total_expenses;

View File

@@ -40,31 +40,6 @@ if (isset($_GET['certificate_fetch_parse_json_details'])) {
} }
/*
* Looks up info on the ticket number provided, used to populate the ticket merge modal
*/
if (isset($_GET['merge_ticket_get_json_details'])) {
enforceUserPermission('module_support');
$merge_into_ticket_number = intval(preg_replace('/[^0-9]/', '', $_GET['merge_into_ticket_number']));
$sql = mysqli_query($mysqli, "SELECT ticket_id, ticket_number, ticket_prefix, ticket_subject, ticket_priority, ticket_status, ticket_status_name, client_name, contact_name FROM tickets
LEFT JOIN clients ON ticket_client_id = client_id
LEFT JOIN contacts ON ticket_contact_id = contact_id
LEFT JOIN ticket_statuses ON ticket_status = ticket_status_id
WHERE ticket_number = $merge_into_ticket_number");
if (mysqli_num_rows($sql) == 0) {
//Do nothing.
echo "No ticket found!";
} else {
//Return ticket, client and contact details for the given ticket number
$response = mysqli_fetch_array($sql);
echo json_encode($response);
}
}
if (isset($_POST['client_set_notes'])) { if (isset($_POST['client_set_notes'])) {
enforceUserPermission('module_client', 2); enforceUserPermission('module_client', 2);
@@ -89,7 +64,7 @@ if (isset($_POST['contact_set_notes'])) {
$sql = mysqli_query($mysqli,"SELECT contact_name, contact_client_id $sql = mysqli_query($mysqli,"SELECT contact_name, contact_client_id
FROM contacts WHERE contact_id = $contact_id" FROM contacts WHERE contact_id = $contact_id"
); );
$row = mysqli_fetch_array($sql); $row = mysqli_fetch_assoc($sql);
$contact_name = sanitizeInput($row['contact_name']); $contact_name = sanitizeInput($row['contact_name']);
$client_id = intval($row['contact_client_id']); $client_id = intval($row['contact_client_id']);
@@ -111,7 +86,7 @@ if (isset($_POST['asset_set_notes'])) {
$sql = mysqli_query($mysqli,"SELECT asset_name, asset_client_id $sql = mysqli_query($mysqli,"SELECT asset_name, asset_client_id
FROM assets WHERE asset_id = $asset_id" FROM assets WHERE asset_id = $asset_id"
); );
$row = mysqli_fetch_array($sql); $row = mysqli_fetch_assoc($sql);
$asset_name = sanitizeInput($row['asset_name']); $asset_name = sanitizeInput($row['asset_name']);
$client_id = intval($row['asset_client_id']); $client_id = intval($row['asset_client_id']);
@@ -143,7 +118,7 @@ if (isset($_GET['ticket_query_views'])) {
$ticket_id = intval($_GET['ticket_id']); $ticket_id = intval($_GET['ticket_id']);
$query = mysqli_query($mysqli, "SELECT user_name FROM ticket_views LEFT JOIN users ON view_user_id = user_id WHERE view_ticket_id = $ticket_id AND view_user_id != $session_user_id AND view_timestamp > DATE_SUB(NOW(), INTERVAL 2 MINUTE)"); $query = mysqli_query($mysqli, "SELECT user_name FROM ticket_views LEFT JOIN users ON view_user_id = user_id WHERE view_ticket_id = $ticket_id AND view_user_id != $session_user_id AND view_timestamp > DATE_SUB(NOW(), INTERVAL 2 MINUTE)");
while ($row = mysqli_fetch_array($query)) { while ($row = mysqli_fetch_assoc($query)) {
$users[] = $row['user_name']; $users[] = $row['user_name'];
} }
@@ -198,18 +173,18 @@ if (isset($_GET['share_generate_link'])) {
$item_key = randomString(32); $item_key = randomString(32);
if ($item_type == "Document") { if ($item_type == "Document") {
$row = mysqli_fetch_array(mysqli_query($mysqli, "SELECT document_name FROM documents WHERE document_id = $item_id AND document_client_id = $client_id LIMIT 1")); $row = mysqli_fetch_assoc(mysqli_query($mysqli, "SELECT document_name FROM documents WHERE document_id = $item_id AND document_client_id = $client_id LIMIT 1"));
$item_name = sanitizeInput($row['document_name']); $item_name = sanitizeInput($row['document_name']);
} }
if ($item_type == "File") { if ($item_type == "File") {
$row = mysqli_fetch_array(mysqli_query($mysqli, "SELECT file_name FROM files WHERE file_id = $item_id AND file_client_id = $client_id LIMIT 1")); $row = mysqli_fetch_assoc(mysqli_query($mysqli, "SELECT file_name FROM files WHERE file_id = $item_id AND file_client_id = $client_id LIMIT 1"));
$item_name = sanitizeInput($row['file_name']); $item_name = sanitizeInput($row['file_name']);
} }
if ($item_type == "Credential") { if ($item_type == "Credential") {
$credential = mysqli_query($mysqli, "SELECT credential_name, credential_username, credential_password FROM credentials WHERE credential_id = $item_id AND credential_client_id = $client_id LIMIT 1"); $credential = mysqli_query($mysqli, "SELECT credential_name, credential_username, credential_password FROM credentials WHERE credential_id = $item_id AND credential_client_id = $client_id LIMIT 1");
$row = mysqli_fetch_array($credential); $row = mysqli_fetch_assoc($credential);
$item_name = sanitizeInput($row['credential_name']); $item_name = sanitizeInput($row['credential_name']);
@@ -240,7 +215,7 @@ if (isset($_GET['share_generate_link'])) {
} }
$sql = mysqli_query($mysqli,"SELECT * FROM companies WHERE company_id = 1"); $sql = mysqli_query($mysqli,"SELECT * FROM companies WHERE company_id = 1");
$row = mysqli_fetch_array($sql); $row = mysqli_fetch_assoc($sql);
$company_name = sanitizeInput($row['company_name']); $company_name = sanitizeInput($row['company_name']);
$company_phone = sanitizeInput(formatPhoneNumber($row['company_phone'], $row['company_phone_country_code'])); $company_phone = sanitizeInput(formatPhoneNumber($row['company_phone'], $row['company_phone_country_code']));
@@ -298,7 +273,7 @@ if (isset($_GET['get_active_clients'])) {
ORDER BY client_accessed_at DESC" ORDER BY client_accessed_at DESC"
); );
while ($row = mysqli_fetch_array($client_sql)) { while ($row = mysqli_fetch_assoc($client_sql)) {
$response['clients'][] = $row; $response['clients'][] = $row;
} }
@@ -322,7 +297,7 @@ if (isset($_GET['get_client_contacts'])) {
ORDER BY contact_primary DESC, contact_technical DESC, contact_important DESC, contact_name" ORDER BY contact_primary DESC, contact_technical DESC, contact_important DESC, contact_name"
); );
while ($row = mysqli_fetch_array($contact_sql)) { while ($row = mysqli_fetch_assoc($contact_sql)) {
$response['contacts'][] = $row; $response['contacts'][] = $row;
} }
@@ -344,10 +319,10 @@ if (isset($_GET['get_client_assets'])) {
LEFT JOIN contacts ON contact_id = asset_contact_id LEFT JOIN contacts ON contact_id = asset_contact_id
WHERE assets.asset_archived_at IS NULL AND asset_client_id = $client_id WHERE assets.asset_archived_at IS NULL AND asset_client_id = $client_id
$access_permission_query $access_permission_query
ORDER BY asset_important DESC, asset_name" ORDER BY asset_favorite DESC, asset_name"
); );
while ($row = mysqli_fetch_array($asset_sql)) { while ($row = mysqli_fetch_assoc($asset_sql)) {
$response['assets'][] = $row; $response['assets'][] = $row;
} }
@@ -371,7 +346,7 @@ if (isset($_GET['get_client_locations'])) {
ORDER BY location_primary DESC, location_name ASC" ORDER BY location_primary DESC, location_name ASC"
); );
while ($row = mysqli_fetch_array($locations_sql)) { while ($row = mysqli_fetch_assoc($locations_sql)) {
$response['locations'][] = $row; $response['locations'][] = $row;
} }
@@ -395,7 +370,7 @@ if (isset($_GET['get_client_vendors'])) {
ORDER BY vendor_name ASC" ORDER BY vendor_name ASC"
); );
while ($row = mysqli_fetch_array($vendors_sql)) { while ($row = mysqli_fetch_assoc($vendors_sql)) {
$response['vendors'][] = $row; $response['vendors'][] = $row;
} }
@@ -502,7 +477,7 @@ if (isset($_POST['update_kanban_ticket'])) {
LEFT JOIN ticket_statuses ON ticket_status = ticket_status_id LEFT JOIN ticket_statuses ON ticket_status = ticket_status_id
WHERE ticket_id = $ticket_id WHERE ticket_id = $ticket_id
"); ");
$row = mysqli_fetch_array($ticket_sql); $row = mysqli_fetch_assoc($ticket_sql);
$contact_name = sanitizeInput($row['contact_name']); $contact_name = sanitizeInput($row['contact_name']);
$contact_email = sanitizeInput($row['contact_email']); $contact_email = sanitizeInput($row['contact_email']);
@@ -521,7 +496,7 @@ if (isset($_POST['update_kanban_ticket'])) {
// Get Company Info // Get Company Info
$sql = mysqli_query($mysqli, "SELECT company_name, company_phone, company_phone_country_code FROM companies WHERE company_id = 1"); $sql = mysqli_query($mysqli, "SELECT company_name, company_phone, company_phone_country_code FROM companies WHERE company_id = 1");
$row = mysqli_fetch_array($sql); $row = mysqli_fetch_assoc($sql);
$company_name = sanitizeInput($row['company_name']); $company_name = sanitizeInput($row['company_name']);
$company_phone = sanitizeInput(formatPhoneNumber($row['company_phone'], $row['company_phone_country_code'])); $company_phone = sanitizeInput(formatPhoneNumber($row['company_phone'], $row['company_phone_country_code']));
@@ -550,7 +525,7 @@ if (isset($_POST['update_kanban_ticket'])) {
// Also Email all the watchers // Also Email all the watchers
$sql_watchers = mysqli_query($mysqli, "SELECT watcher_email FROM ticket_watchers WHERE watcher_ticket_id = $ticket_id"); $sql_watchers = mysqli_query($mysqli, "SELECT watcher_email FROM ticket_watchers WHERE watcher_ticket_id = $ticket_id");
$body .= "<br><br>----------------------------------------<br>YOU ARE A COLLABORATOR ON THIS TICKET"; $body .= "<br><br>----------------------------------------<br>YOU ARE A COLLABORATOR ON THIS TICKET";
while ($row = mysqli_fetch_array($sql_watchers)) { while ($row = mysqli_fetch_assoc($sql_watchers)) {
$watcher_email = sanitizeInput($row['watcher_email']); $watcher_email = sanitizeInput($row['watcher_email']);
// Queue Mail // Queue Mail
@@ -691,7 +666,7 @@ if (isset($_GET['client_duplicate_check'])) {
); );
if (mysqli_num_rows($sql_clients) > 0) { if (mysqli_num_rows($sql_clients) > 0) {
while ($row = mysqli_fetch_array($sql_clients)) { while ($row = mysqli_fetch_assoc($sql_clients)) {
$response['message'] = "<i class='fas fa-fw fa-copy mr-2'></i> Potential duplicate: <i>" . nullable_htmlentities($row['client_name']) . "</i> already exists."; $response['message'] = "<i class='fas fa-fw fa-copy mr-2'></i> Potential duplicate: <i>" . nullable_htmlentities($row['client_name']) . "</i> already exists.";
} }
} }
@@ -713,7 +688,7 @@ if (isset($_GET['contact_email_check'])) {
// 1. Duplicate check // 1. Duplicate check
$sql_contacts = mysqli_query($mysqli, "SELECT contact_email FROM contacts WHERE contact_email = '$email' LIMIT 1"); $sql_contacts = mysqli_query($mysqli, "SELECT contact_email FROM contacts WHERE contact_email = '$email' LIMIT 1");
if (mysqli_num_rows($sql_contacts) > 0) { if (mysqli_num_rows($sql_contacts) > 0) {
while ($row = mysqli_fetch_array($sql_contacts)) { while ($row = mysqli_fetch_assoc($sql_contacts)) {
$response['message'] = "<i class='fas fa-fw fa-copy mr-2'></i> Potential duplicate: <i>" . nullable_htmlentities($row['contact_email']) . "</i> already exists."; $response['message'] = "<i class='fas fa-fw fa-copy mr-2'></i> Potential duplicate: <i>" . nullable_htmlentities($row['contact_email']) . "</i> already exists.";
} }
} }
@@ -734,7 +709,7 @@ if (isset($_GET['ai_reword'])) {
$sql = mysqli_query($mysqli, "SELECT * FROM ai_models LEFT JOIN ai_providers ON ai_model_ai_provider_id = ai_provider_id WHERE ai_model_use_case = 'General' LIMIT 1"); $sql = mysqli_query($mysqli, "SELECT * FROM ai_models LEFT JOIN ai_providers ON ai_model_ai_provider_id = ai_provider_id WHERE ai_model_use_case = 'General' LIMIT 1");
$row = mysqli_fetch_array($sql); $row = mysqli_fetch_assoc($sql);
$model_name = $row['ai_model_name']; $model_name = $row['ai_model_name'];
$promptText = $row['ai_model_prompt']; $promptText = $row['ai_model_prompt'];
$url = $row['ai_provider_api_url']; $url = $row['ai_provider_api_url'];
@@ -805,7 +780,7 @@ if (isset($_GET['ai_create_document_template'])) {
$sql = mysqli_query($mysqli, "SELECT * FROM ai_models LEFT JOIN ai_providers ON ai_model_ai_provider_id = ai_provider_id WHERE ai_model_use_case = 'General' LIMIT 1"); $sql = mysqli_query($mysqli, "SELECT * FROM ai_models LEFT JOIN ai_providers ON ai_model_ai_provider_id = ai_provider_id WHERE ai_model_use_case = 'General' LIMIT 1");
$row = mysqli_fetch_array($sql); $row = mysqli_fetch_assoc($sql);
$model_name = $row['ai_model_name']; $model_name = $row['ai_model_name'];
$url = $row['ai_provider_api_url']; $url = $row['ai_provider_api_url'];
$key = $row['ai_provider_api_key']; $key = $row['ai_provider_api_key'];
@@ -861,7 +836,7 @@ if (isset($_GET['ai_ticket_summary'])) {
$sql = mysqli_query($mysqli, "SELECT * FROM ai_models LEFT JOIN ai_providers ON ai_model_ai_provider_id = ai_provider_id WHERE ai_model_use_case = 'General' LIMIT 1"); $sql = mysqli_query($mysqli, "SELECT * FROM ai_models LEFT JOIN ai_providers ON ai_model_ai_provider_id = ai_provider_id WHERE ai_model_use_case = 'General' LIMIT 1");
$row = mysqli_fetch_array($sql); $row = mysqli_fetch_assoc($sql);
$model_name = $row['ai_model_name']; $model_name = $row['ai_model_name'];
$url = $row['ai_provider_api_url']; $url = $row['ai_provider_api_url'];
$key = $row['ai_provider_api_key']; $key = $row['ai_provider_api_key'];

View File

@@ -29,7 +29,7 @@ if (isset($_GET['asset_id'])) {
} else { } else {
$row = mysqli_fetch_array($sql); $row = mysqli_fetch_assoc($sql);
$client_id = intval($row['client_id']); $client_id = intval($row['client_id']);
$client_name = nullable_htmlentities($row['client_name']); $client_name = nullable_htmlentities($row['client_name']);
$asset_id = intval($row['asset_id']); $asset_id = intval($row['asset_id']);
@@ -51,6 +51,7 @@ if (isset($_GET['asset_id'])) {
$asset_photo = nullable_htmlentities($row['asset_photo']); $asset_photo = nullable_htmlentities($row['asset_photo']);
$asset_physical_location = nullable_htmlentities($row['asset_physical_location']); $asset_physical_location = nullable_htmlentities($row['asset_physical_location']);
$asset_notes = nullable_htmlentities($row['asset_notes']); $asset_notes = nullable_htmlentities($row['asset_notes']);
$asset_favorite = intval($row['asset_favorite']);
$asset_created_at = nullable_htmlentities($row['asset_created_at']); $asset_created_at = nullable_htmlentities($row['asset_created_at']);
$asset_vendor_id = intval($row['asset_vendor_id']); $asset_vendor_id = intval($row['asset_vendor_id']);
$asset_location_id = intval($row['asset_location_id']); $asset_location_id = intval($row['asset_location_id']);
@@ -66,8 +67,11 @@ if (isset($_GET['asset_id'])) {
$contact_name = nullable_htmlentities($row['contact_name']); $contact_name = nullable_htmlentities($row['contact_name']);
$contact_email = nullable_htmlentities($row['contact_email']); $contact_email = nullable_htmlentities($row['contact_email']);
$contact_phone = nullable_htmlentities($row['contact_phone']); $contact_phone_country_code = nullable_htmlentities($row['contact_phone_country_code']);
$contact_mobile = nullable_htmlentities($row['contact_mobile']); $contact_phone = nullable_htmlentities(formatPhoneNumber($row['contact_phone'], $contact_phone_country_code));
$contact_extension = nullable_htmlentities($row['contact_extension']);
$contact_mobile_country_code = nullable_htmlentities($row['contact_mobile_country_code']);
$contact_mobile = nullable_htmlentities(formatPhoneNumber($row['contact_mobile'], $contact_mobile_country_code));
$contact_archived_at = nullable_htmlentities($row['contact_archived_at']); $contact_archived_at = nullable_htmlentities($row['contact_archived_at']);
if ($contact_archived_at) { if ($contact_archived_at) {
$contact_name_display = "<span class='text-danger' title='Archived'><s>$contact_name</s></span>"; $contact_name_display = "<span class='text-danger' title='Archived'><s>$contact_name</s></span>";
@@ -122,7 +126,7 @@ if (isset($_GET['asset_id'])) {
$asset_tag_name_display_array = array(); $asset_tag_name_display_array = array();
$asset_tag_id_array = array(); $asset_tag_id_array = array();
$sql_asset_tags = mysqli_query($mysqli, "SELECT * FROM asset_tags LEFT JOIN tags ON asset_tag_tag_id = tag_id WHERE asset_tag_asset_id = $asset_id ORDER BY tag_name ASC"); $sql_asset_tags = mysqli_query($mysqli, "SELECT * FROM asset_tags LEFT JOIN tags ON asset_tag_tag_id = tag_id WHERE asset_tag_asset_id = $asset_id ORDER BY tag_name ASC");
while ($row = mysqli_fetch_array($sql_asset_tags)) { while ($row = mysqli_fetch_assoc($sql_asset_tags)) {
$asset_tag_id = intval($row['tag_id']); $asset_tag_id = intval($row['tag_id']);
$asset_tag_name = nullable_htmlentities($row['tag_name']); $asset_tag_name = nullable_htmlentities($row['tag_name']);
@@ -223,7 +227,7 @@ if (isset($_GET['asset_id'])) {
credentials.credential_password, credentials.credential_password,
credentials.credential_otp_secret, credentials.credential_otp_secret,
credentials.credential_note, credentials.credential_note,
credentials.credential_important, credentials.credential_favorite,
credentials.credential_contact_id, credentials.credential_contact_id,
credentials.credential_asset_id credentials.credential_asset_id
FROM credentials FROM credentials
@@ -270,7 +274,9 @@ if (isset($_GET['asset_id'])) {
data-modal-url="modals/asset/asset_edit.php?id=<?= $asset_id ?>"> data-modal-url="modals/asset/asset_edit.php?id=<?= $asset_id ?>">
<i class="fas fa-fw fa-edit"></i> <i class="fas fa-fw fa-edit"></i>
</button> </button>
<h4 class="text-bold"><i class="fa fa-fw text-secondary fa-<?= $device_icon; ?> mr-3"></i><?= $asset_name; ?></h4> <h4 class="text-bold"><i class="fa fa-fw text-secondary fa-<?= $device_icon; ?> mr-2"></i><?= $asset_name; ?>
<?php if ($asset_favorite) { ?><i class="fas fa-fw text-warning fa-star" title="Favorite"></i><?php } ?>
</h4>
<?php if ($asset_photo) { ?> <?php if ($asset_photo) { ?>
<img class="img-fluid img-circle p-3" alt="asset_photo" src="<?= "../uploads/clients/$client_id/$asset_photo"; ?>"> <img class="img-fluid img-circle p-3" alt="asset_photo" src="<?= "../uploads/clients/$client_id/$asset_photo"; ?>">
<?php } ?> <?php } ?>
@@ -285,25 +291,25 @@ if (isset($_GET['asset_id'])) {
</div> </div>
<?php } ?> <?php } ?>
<?php if ($asset_type) { ?> <?php if ($asset_type) { ?>
<div class="mt-1"><i class="fa fa-fw fa-tag text-secondary mr-3"></i><?= $asset_type; ?></div> <div class="mt-1"><i class="fa fa-fw fa-tag text-secondary mr-2"></i><?= $asset_type; ?></div>
<?php } <?php }
if ($asset_make) { ?> if ($asset_make) { ?>
<div class="mt-2"><i class="fa fa-fw fa-circle text-secondary mr-3"></i><?= "$asset_make $asset_model"; ?></div> <div class="mt-2"><i class="fa fa-fw fa-circle text-secondary mr-2"></i><?= "$asset_make $asset_model"; ?></div>
<?php } <?php }
if ($asset_os) { ?> if ($asset_os) { ?>
<div class="mt-2"><i class="fab fa-fw fa-windows text-secondary mr-3"></i><?= "$asset_os"; ?></div> <div class="mt-2"><i class="fab fa-fw fa-windows text-secondary mr-2"></i><?= "$asset_os"; ?></div>
<?php } <?php }
if ($asset_serial) { ?> if ($asset_serial) { ?>
<div class="mt-2"><i class="fa fa-fw fa-barcode text-secondary mr-3"></i><?= $asset_serial; ?></div> <div class="mt-2"><i class="fa fa-fw fa-barcode text-secondary mr-2"></i><?= $asset_serial; ?></div>
<?php } <?php }
if ($asset_purchase_date) { ?> if ($asset_purchase_date) { ?>
<div class="mt-2"><i class="fa fa-fw fa-shopping-cart text-secondary mr-3"></i><?= date('Y-m-d', strtotime($asset_purchase_date)); ?></div> <div class="mt-2"><i class="fa fa-fw fa-shopping-cart text-secondary mr-2"></i><?= date('Y-m-d', strtotime($asset_purchase_date)); ?></div>
<?php } <?php }
if ($asset_install_date) { ?> if ($asset_install_date) { ?>
<div class="mt-2"><i class="fa fa-fw fa-calendar-check text-secondary mr-3"></i><?= date('Y-m-d', strtotime($asset_install_date)); ?></div> <div class="mt-2"><i class="fa fa-fw fa-calendar-check text-secondary mr-2"></i><?= date('Y-m-d', strtotime($asset_install_date)); ?></div>
<?php } <?php }
if ($asset_warranty_expire) { ?> if ($asset_warranty_expire) { ?>
<div class="mt-2"><i class="fa fa-fw fa-exclamation-triangle text-secondary mr-3"></i><?= date('Y-m-d', strtotime($asset_warranty_expire)); ?></div> <div class="mt-2"><i class="fa fa-fw fa-exclamation-triangle text-secondary mr-2"></i><?= date('Y-m-d', strtotime($asset_warranty_expire)); ?></div>
<?php } ?> <?php } ?>
</div> </div>
</div> </div>
@@ -351,10 +357,13 @@ if (isset($_GET['asset_id'])) {
<div class="mt-2"><i class="fa fa-fw fa-envelope text-secondary mr-2"></i><a href='mailto:<?= $contact_email; ?>'><?= $contact_email; ?></a><button class='btn btn-sm clipboardjs' data-clipboard-text='<?= $contact_email; ?>'><i class='far fa-copy text-secondary'></i></button></div> <div class="mt-2"><i class="fa fa-fw fa-envelope text-secondary mr-2"></i><a href='mailto:<?= $contact_email; ?>'><?= $contact_email; ?></a><button class='btn btn-sm clipboardjs' data-clipboard-text='<?= $contact_email; ?>'><i class='far fa-copy text-secondary'></i></button></div>
<?php } <?php }
if ($contact_phone) { ?> if ($contact_phone) { ?>
<div class="mt-2"><i class="fa fa-fw fa-phone text-secondary mr-2"></i><?= formatPhoneNumber($contact_phone); echo " $contact_extension"; ?></div> <div class="mt-2"><i class="fa fa-fw fa-phone text-secondary mr-2"></i><?= $contact_phone ?></div>
<?php }
if ($contact_extension) { ?>
<div class="mt-1"><i class="fa fa-fw text-secondary mr-2"></i><?= "ext. $contact_extension" ?></div>
<?php } <?php }
if ($contact_mobile) { ?> if ($contact_mobile) { ?>
<div class="mt-2"><i class="fa fa-fw fa-mobile-alt text-secondary mr-2"></i><?= formatPhoneNumber($contact_mobile); ?></div> <div class="mt-2"><i class="fa fa-fw fa-mobile-alt text-secondary mr-2"></i><?= $contact_mobile ?></div>
<?php } ?> <?php } ?>
</div> </div>
@@ -517,7 +526,7 @@ if (isset($_GET['asset_id'])) {
</tr> </tr>
</thead> </thead>
<tbody> <tbody>
<?php while ($row = mysqli_fetch_array($sql_related_interfaces)) { ?> <?php while ($row = mysqli_fetch_assoc($sql_related_interfaces)) { ?>
<?php <?php
$interface_id = intval($row['interface_id']); $interface_id = intval($row['interface_id']);
$interface_name = nullable_htmlentities($row['interface_name']); $interface_name = nullable_htmlentities($row['interface_name']);
@@ -626,7 +635,7 @@ if (isset($_GET['asset_id'])) {
<tbody> <tbody>
<?php <?php
while ($row = mysqli_fetch_array($sql_related_credentials)) { while ($row = mysqli_fetch_assoc($sql_related_credentials)) {
$credential_id = intval($row['credential_id']); $credential_id = intval($row['credential_id']);
$credential_name = nullable_htmlentities($row['credential_name']); $credential_name = nullable_htmlentities($row['credential_name']);
$credential_description = nullable_htmlentities($row['credential_description']); $credential_description = nullable_htmlentities($row['credential_description']);
@@ -651,7 +660,7 @@ if (isset($_GET['asset_id'])) {
$otp_display = "<span onmouseenter='showOTPViaCredentialID($credential_id)'><i class='far fa-clock'></i> <span id='otp_$credential_id'><i>Hover..</i></span></span>"; $otp_display = "<span onmouseenter='showOTPViaCredentialID($credential_id)'><i class='far fa-clock'></i> <span id='otp_$credential_id'><i>Hover..</i></span></span>";
} }
$credential_note = nullable_htmlentities($row['credential_note']); $credential_note = nullable_htmlentities($row['credential_note']);
$credential_important = intval($row['credential_important']); $credential_favorite = intval($row['credential_favorite']);
$credential_contact_id = intval($row['credential_contact_id']); $credential_contact_id = intval($row['credential_contact_id']);
$credential_asset_id = intval($row['credential_asset_id']); $credential_asset_id = intval($row['credential_asset_id']);
@@ -659,7 +668,7 @@ if (isset($_GET['asset_id'])) {
$credential_tag_name_display_array = array(); $credential_tag_name_display_array = array();
$credential_tag_id_array = array(); $credential_tag_id_array = array();
$sql_credential_tags = mysqli_query($mysqli, "SELECT * FROM credential_tags LEFT JOIN tags ON credential_tags.tag_id = tags.tag_id WHERE credential_id = $credential_id ORDER BY tag_name ASC"); $sql_credential_tags = mysqli_query($mysqli, "SELECT * FROM credential_tags LEFT JOIN tags ON credential_tags.tag_id = tags.tag_id WHERE credential_id = $credential_id ORDER BY tag_name ASC");
while ($row = mysqli_fetch_array($sql_credential_tags)) { while ($row = mysqli_fetch_assoc($sql_credential_tags)) {
$credential_tag_id = intval($row['tag_id']); $credential_tag_id = intval($row['tag_id']);
$credential_tag_name = nullable_htmlentities($row['tag_name']); $credential_tag_name = nullable_htmlentities($row['tag_name']);
@@ -758,7 +767,7 @@ if (isset($_GET['asset_id'])) {
<tbody> <tbody>
<?php <?php
while ($row = mysqli_fetch_array($sql_related_software)) { while ($row = mysqli_fetch_assoc($sql_related_software)) {
$software_id = intval($row['software_id']); $software_id = intval($row['software_id']);
$software_name = nullable_htmlentities($row['software_name']); $software_name = nullable_htmlentities($row['software_name']);
$software_version = nullable_htmlentities($row['software_version']); $software_version = nullable_htmlentities($row['software_version']);
@@ -775,7 +784,7 @@ if (isset($_GET['asset_id'])) {
// Asset Licenses // Asset Licenses
$asset_licenses_sql = mysqli_query($mysqli, "SELECT asset_id FROM software_assets WHERE software_id = $software_id"); $asset_licenses_sql = mysqli_query($mysqli, "SELECT asset_id FROM software_assets WHERE software_id = $software_id");
$asset_licenses_array = array(); $asset_licenses_array = array();
while ($row = mysqli_fetch_array($asset_licenses_sql)) { while ($row = mysqli_fetch_assoc($asset_licenses_sql)) {
$asset_licenses_array[] = intval($row['asset_id']); $asset_licenses_array[] = intval($row['asset_id']);
$seat_count = $seat_count + 1; $seat_count = $seat_count + 1;
} }
@@ -784,7 +793,7 @@ if (isset($_GET['asset_id'])) {
// Contact Licenses // Contact Licenses
$contact_licenses_sql = mysqli_query($mysqli, "SELECT contact_id FROM software_contacts WHERE software_id = $software_id"); $contact_licenses_sql = mysqli_query($mysqli, "SELECT contact_id FROM software_contacts WHERE software_id = $software_id");
$contact_licenses_array = array(); $contact_licenses_array = array();
while ($row = mysqli_fetch_array($contact_licenses_sql)) { while ($row = mysqli_fetch_assoc($contact_licenses_sql)) {
$contact_licenses_array[] = intval($row['contact_id']); $contact_licenses_array[] = intval($row['contact_id']);
$seat_count = $seat_count + 1; $seat_count = $seat_count + 1;
} }
@@ -844,7 +853,7 @@ if (isset($_GET['asset_id'])) {
<tbody> <tbody>
<?php <?php
while ($row = mysqli_fetch_array($sql_related_documents)) { while ($row = mysqli_fetch_assoc($sql_related_documents)) {
$document_id = intval($row['document_id']); $document_id = intval($row['document_id']);
$document_name = nullable_htmlentities($row['document_name']); $document_name = nullable_htmlentities($row['document_name']);
$document_description = nullable_htmlentities($row['document_description']); $document_description = nullable_htmlentities($row['document_description']);
@@ -923,7 +932,7 @@ if (isset($_GET['asset_id'])) {
<tbody> <tbody>
<?php <?php
while ($row = mysqli_fetch_array($sql_related_files)) { while ($row = mysqli_fetch_assoc($sql_related_files)) {
$file_id = intval($row['file_id']); $file_id = intval($row['file_id']);
$file_name = nullable_htmlentities($row['file_name']); $file_name = nullable_htmlentities($row['file_name']);
$file_description = nullable_htmlentities($row['file_description']); $file_description = nullable_htmlentities($row['file_description']);
@@ -995,7 +1004,7 @@ if (isset($_GET['asset_id'])) {
<tbody> <tbody>
<?php <?php
while ($row = mysqli_fetch_array($sql_related_recurring_tickets)) { while ($row = mysqli_fetch_assoc($sql_related_recurring_tickets)) {
$recurring_ticket_id = intval($row['recurring_ticket_id']); $recurring_ticket_id = intval($row['recurring_ticket_id']);
$recurring_ticket_subject = nullable_htmlentities($row['recurring_ticket_subject']); $recurring_ticket_subject = nullable_htmlentities($row['recurring_ticket_subject']);
$recurring_ticket_priority = nullable_htmlentities($row['recurring_ticket_priority']); $recurring_ticket_priority = nullable_htmlentities($row['recurring_ticket_priority']);
@@ -1074,7 +1083,7 @@ if (isset($_GET['asset_id'])) {
<tbody> <tbody>
<?php <?php
while ($row = mysqli_fetch_array($sql_related_tickets)) { while ($row = mysqli_fetch_assoc($sql_related_tickets)) {
$ticket_id = intval($row['ticket_id']); $ticket_id = intval($row['ticket_id']);
$ticket_prefix = nullable_htmlentities($row['ticket_prefix']); $ticket_prefix = nullable_htmlentities($row['ticket_prefix']);
$ticket_number = intval($row['ticket_number']); $ticket_number = intval($row['ticket_number']);
@@ -1165,7 +1174,7 @@ if (isset($_GET['asset_id'])) {
<tbody> <tbody>
<?php <?php
while ($row = mysqli_fetch_array($sql_linked_services)) { while ($row = mysqli_fetch_assoc($sql_linked_services)) {
$service_id = intval($row['service_id']); $service_id = intval($row['service_id']);
$service_name = nullable_htmlentities($row['service_name']); $service_name = nullable_htmlentities($row['service_name']);
$service_description = nullable_htmlentities($row['service_description']); $service_description = nullable_htmlentities($row['service_description']);

View File

@@ -248,7 +248,7 @@ $num_rows = mysqli_fetch_row(mysqli_query($mysqli, "SELECT FOUND_ROWS()"));
AND ( EXISTS (SELECT 1 FROM assets WHERE asset_location_id = location_id AND $archive_query) OR location_id = $location_filter) AND ( EXISTS (SELECT 1 FROM assets WHERE asset_location_id = location_id AND $archive_query) OR location_id = $location_filter)
ORDER BY location_name ASC ORDER BY location_name ASC
"); ");
while ($row = mysqli_fetch_array($sql_locations_filter)) { while ($row = mysqli_fetch_assoc($sql_locations_filter)) {
$location_id = intval($row['location_id']); $location_id = intval($row['location_id']);
$location_name = nullable_htmlentities($row['location_name']); $location_name = nullable_htmlentities($row['location_name']);
?> ?>
@@ -275,7 +275,7 @@ $num_rows = mysqli_fetch_row(mysqli_query($mysqli, "SELECT FOUND_ROWS()"));
$access_permission_query $access_permission_query
ORDER BY client_name ASC ORDER BY client_name ASC
"); ");
while ($row = mysqli_fetch_array($sql_clients_filter)) { while ($row = mysqli_fetch_assoc($sql_clients_filter)) {
$client_id = intval($row['client_id']); $client_id = intval($row['client_id']);
$client_name = nullable_htmlentities($row['client_name']); $client_name = nullable_htmlentities($row['client_name']);
?> ?>
@@ -303,7 +303,7 @@ $num_rows = mysqli_fetch_row(mysqli_query($mysqli, "SELECT FOUND_ROWS()"));
GROUP BY tag_id GROUP BY tag_id
HAVING COUNT(asset_tag_asset_id) > 0 OR tag_id IN ($tag_filter) HAVING COUNT(asset_tag_asset_id) > 0 OR tag_id IN ($tag_filter)
"); ");
while ($row = mysqli_fetch_array($sql_tags_filter)) { while ($row = mysqli_fetch_assoc($sql_tags_filter)) {
$tag_id = intval($row['tag_id']); $tag_id = intval($row['tag_id']);
$tag_name = nullable_htmlentities($row['tag_name']); ?> $tag_name = nullable_htmlentities($row['tag_name']); ?>
@@ -345,6 +345,16 @@ $num_rows = mysqli_fetch_row(mysqli_query($mysqli, "SELECT FOUND_ROWS()"));
<i class="fas fa-fw fa-layer-group mr-2"></i>Bulk Action (<span id="selectedCount"></span>) <i class="fas fa-fw fa-layer-group mr-2"></i>Bulk Action (<span id="selectedCount"></span>)
</button> </button>
<div class="dropdown-menu"> <div class="dropdown-menu">
<button class="dropdown-item"
type="submit" form="bulkActions" name="bulk_favorite_assets">
<i class="fas fa-fw fa-star text-warning mr-2"></i>Favorite
</button>
<div class="dropdown-divider"></div>
<button class="dropdown-item"
type="submit" form="bulkActions" name="bulk_unfavorite_assets">
<i class="far fa-fw fa-star mr-2"></i>Unfavorite
</button>
<div class="dropdown-divider"></div>
<?php if ($client_url) { ?> <?php if ($client_url) { ?>
<a class="dropdown-item ajax-modal" href="#" <a class="dropdown-item ajax-modal" href="#"
data-modal-url="modals/asset/asset_bulk_assign_contact.php?<?= $client_url ?>" data-modal-url="modals/asset/asset_bulk_assign_contact.php?<?= $client_url ?>"
@@ -524,7 +534,7 @@ $num_rows = mysqli_fetch_row(mysqli_query($mysqli, "SELECT FOUND_ROWS()"));
<tbody> <tbody>
<?php <?php
while ($row = mysqli_fetch_array($sql)) { while ($row = mysqli_fetch_assoc($sql)) {
$client_id = intval($row['client_id']); $client_id = intval($row['client_id']);
$client_name = nullable_htmlentities($row['client_name']); $client_name = nullable_htmlentities($row['client_name']);
$asset_id = intval($row['asset_id']); $asset_id = intval($row['asset_id']);
@@ -590,6 +600,7 @@ $num_rows = mysqli_fetch_row(mysqli_query($mysqli, "SELECT FOUND_ROWS()"));
$asset_physical_location_display = ""; $asset_physical_location_display = "";
} }
$asset_notes = nullable_htmlentities($row['asset_notes']); $asset_notes = nullable_htmlentities($row['asset_notes']);
$asset_favorite = intval($row['asset_favorite']);
$asset_created_at = nullable_htmlentities($row['asset_created_at']); $asset_created_at = nullable_htmlentities($row['asset_created_at']);
$asset_archived_at = nullable_htmlentities($row['asset_archived_at']); $asset_archived_at = nullable_htmlentities($row['asset_archived_at']);
$asset_vendor_id = intval($row['asset_vendor_id']); $asset_vendor_id = intval($row['asset_vendor_id']);
@@ -630,7 +641,7 @@ $num_rows = mysqli_fetch_row(mysqli_query($mysqli, "SELECT FOUND_ROWS()"));
$asset_tag_name_display_array = array(); $asset_tag_name_display_array = array();
$asset_tag_id_array = array(); $asset_tag_id_array = array();
$sql_asset_tags = mysqli_query($mysqli, "SELECT * FROM asset_tags LEFT JOIN tags ON asset_tag_tag_id = tag_id WHERE asset_tag_asset_id = $asset_id ORDER BY tag_name ASC"); $sql_asset_tags = mysqli_query($mysqli, "SELECT * FROM asset_tags LEFT JOIN tags ON asset_tag_tag_id = tag_id WHERE asset_tag_asset_id = $asset_id ORDER BY tag_name ASC");
while ($row = mysqli_fetch_array($sql_asset_tags)) { while ($row = mysqli_fetch_assoc($sql_asset_tags)) {
$asset_tag_id = intval($row['tag_id']); $asset_tag_id = intval($row['tag_id']);
$asset_tag_name = nullable_htmlentities($row['tag_name']); $asset_tag_name = nullable_htmlentities($row['tag_name']);
@@ -660,7 +671,7 @@ $num_rows = mysqli_fetch_row(mysqli_query($mysqli, "SELECT FOUND_ROWS()"));
<div class="media"> <div class="media">
<i class="fa fa-fw fa-2x fa-<?= $device_icon ?> mr-3 mt-1"></i> <i class="fa fa-fw fa-2x fa-<?= $device_icon ?> mr-3 mt-1"></i>
<div class="media-body"> <div class="media-body">
<div><?= $asset_name ?></div> <div><?= $asset_name ?> <?php if ($asset_favorite) { echo "<i class='fas fa-fw fa-star text-warning' title='Favorite'></i>"; } ?></div>
<div><small class="text-secondary"><?= $asset_description ?></small></div> <div><small class="text-secondary"><?= $asset_description ?></small></div>
<?php <?php
if ($asset_tags_display) { ?> if ($asset_tags_display) { ?>

View File

@@ -41,7 +41,7 @@ if (isset($_GET['calendar_id'])) {
<form> <form>
<?php <?php
$sql = mysqli_query($mysqli, "SELECT * FROM calendars"); $sql = mysqli_query($mysqli, "SELECT * FROM calendars");
while ($row = mysqli_fetch_array($sql)) { while ($row = mysqli_fetch_assoc($sql)) {
$calendar_id = intval($row['calendar_id']); $calendar_id = intval($row['calendar_id']);
$calendar_name = nullable_htmlentities($row['calendar_name']); $calendar_name = nullable_htmlentities($row['calendar_name']);
$calendar_color = nullable_htmlentities($row['calendar_color']); $calendar_color = nullable_htmlentities($row['calendar_color']);
@@ -85,7 +85,7 @@ require_once "modals/calendar/calendar_event_add.php";
//loop through IDs and create a modal for each //loop through IDs and create a modal for each
$sql = mysqli_query($mysqli, "SELECT * FROM calendar_events LEFT JOIN calendars ON event_calendar_id = calendar_id $client_event_query"); $sql = mysqli_query($mysqli, "SELECT * FROM calendar_events LEFT JOIN calendars ON event_calendar_id = calendar_id $client_event_query");
while ($row = mysqli_fetch_array($sql)) { while ($row = mysqli_fetch_assoc($sql)) {
$event_id = intval($row['event_id']); $event_id = intval($row['event_id']);
$event_title = nullable_htmlentities($row['event_title']); $event_title = nullable_htmlentities($row['event_title']);
$event_description = nullable_htmlentities($row['event_description']); $event_description = nullable_htmlentities($row['event_description']);
@@ -166,7 +166,7 @@ while ($row = mysqli_fetch_array($sql)) {
events: [ events: [
<?php <?php
$sql = mysqli_query($mysqli, "SELECT * FROM calendar_events LEFT JOIN calendars ON event_calendar_id = calendar_id $client_event_query"); $sql = mysqli_query($mysqli, "SELECT * FROM calendar_events LEFT JOIN calendars ON event_calendar_id = calendar_id $client_event_query");
while ($row = mysqli_fetch_array($sql)) { while ($row = mysqli_fetch_assoc($sql)) {
$event_id = intval($row['event_id']); $event_id = intval($row['event_id']);
$event_title = json_encode($row['event_title']); $event_title = json_encode($row['event_title']);
$event_start = json_encode($row['event_start']); $event_start = json_encode($row['event_start']);
@@ -179,8 +179,8 @@ while ($row = mysqli_fetch_array($sql)) {
} }
// Invoices Created // Invoices Created
$sql = mysqli_query($mysqli, "SELECT * FROM clients LEFT JOIN invoices ON client_id = invoice_client_id $client_query"); $sql = mysqli_query($mysqli, "SELECT * FROM clients LEFT JOIN invoices ON client_id = invoice_client_id $client_query $access_permission_query");
while ($row = mysqli_fetch_array($sql)) { while ($row = mysqli_fetch_assoc($sql)) {
$event_id = intval($row['invoice_id']); $event_id = intval($row['invoice_id']);
$scope = strval($row['invoice_scope']); $scope = strval($row['invoice_scope']);
if (empty($scope)) { if (empty($scope)) {
@@ -194,8 +194,8 @@ while ($row = mysqli_fetch_array($sql)) {
} }
// Quotes Created // Quotes Created
$sql = mysqli_query($mysqli, "SELECT * FROM clients LEFT JOIN quotes ON client_id = quote_client_id $client_query"); $sql = mysqli_query($mysqli, "SELECT * FROM clients LEFT JOIN quotes ON client_id = quote_client_id $client_query $access_permission_query");
while ($row = mysqli_fetch_array($sql)) { while ($row = mysqli_fetch_assoc($sql)) {
$event_id = intval($row['quote_id']); $event_id = intval($row['quote_id']);
$event_title = json_encode($row['quote_prefix'] . $row['quote_number'] . " " . $row['quote_scope']); $event_title = json_encode($row['quote_prefix'] . $row['quote_number'] . " " . $row['quote_scope']);
$event_start = json_encode($row['quote_date']); $event_start = json_encode($row['quote_date']);
@@ -208,9 +208,9 @@ while ($row = mysqli_fetch_array($sql)) {
LEFT JOIN tickets ON client_id = ticket_client_id LEFT JOIN tickets ON client_id = ticket_client_id
LEFT JOIN ticket_statuses ON ticket_status = ticket_status_id LEFT JOIN ticket_statuses ON ticket_status = ticket_status_id
LEFT JOIN users ON ticket_assigned_to = user_id LEFT JOIN users ON ticket_assigned_to = user_id
$client_query" $client_query $access_permission_query"
); );
while ($row = mysqli_fetch_array($sql)) { while ($row = mysqli_fetch_assoc($sql)) {
$event_id = intval($row['ticket_id']); $event_id = intval($row['ticket_id']);
$ticket_status = intval($row['ticket_status']); $ticket_status = intval($row['ticket_status']);
$ticket_status_name = strval($row['ticket_status_name']); $ticket_status_name = strval($row['ticket_status_name']);
@@ -242,9 +242,9 @@ while ($row = mysqli_fetch_array($sql)) {
$sql = mysqli_query($mysqli, "SELECT * FROM clients $sql = mysqli_query($mysqli, "SELECT * FROM clients
LEFT JOIN recurring_tickets ON client_id = recurring_ticket_client_id LEFT JOIN recurring_tickets ON client_id = recurring_ticket_client_id
LEFT JOIN users ON recurring_ticket_assigned_to = user_id LEFT JOIN users ON recurring_ticket_assigned_to = user_id
$client_query" $client_query $access_permission_query"
); );
while ($row = mysqli_fetch_array($sql)) { while ($row = mysqli_fetch_assoc($sql)) {
$event_id = intval($row['recurring_ticket_id']); $event_id = intval($row['recurring_ticket_id']);
$client_id = intval($row['client_id']); $client_id = intval($row['client_id']);
$username = $row['user_name']; $username = $row['user_name'];
@@ -267,9 +267,9 @@ while ($row = mysqli_fetch_array($sql)) {
LEFT JOIN tickets ON client_id = ticket_client_id LEFT JOIN tickets ON client_id = ticket_client_id
LEFT JOIN ticket_statuses ON ticket_status = ticket_status_id LEFT JOIN ticket_statuses ON ticket_status = ticket_status_id
LEFT JOIN users ON ticket_assigned_to = user_id LEFT JOIN users ON ticket_assigned_to = user_id
$client_query AND ticket_schedule IS NOT NULL" $client_query $access_permission_query AND ticket_schedule IS NOT NULL"
); );
while ($row = mysqli_fetch_array($sql)) { while ($row = mysqli_fetch_assoc($sql)) {
$event_id = intval($row['ticket_id']); $event_id = intval($row['ticket_id']);
$username = $row['user_name']; $username = $row['user_name'];
if (empty($username)) { if (empty($username)) {
@@ -298,8 +298,8 @@ while ($row = mysqli_fetch_array($sql)) {
} }
// Vendors Added Created // Vendors Added Created
$sql = mysqli_query($mysqli, "SELECT * FROM clients LEFT JOIN vendors ON client_id = vendor_client_id $client_query"); $sql = mysqli_query($mysqli, "SELECT * FROM clients LEFT JOIN vendors ON client_id = vendor_client_id $client_query $access_permission_query");
while ($row = mysqli_fetch_array($sql)) { while ($row = mysqli_fetch_assoc($sql)) {
$event_id = intval($row['vendor_id']); $event_id = intval($row['vendor_id']);
$client_id = intval($row['client_id']); $client_id = intval($row['client_id']);
$event_title = json_encode("Vendor : '" . $row['vendor_name'] . "' created"); $event_title = json_encode("Vendor : '" . $row['vendor_name'] . "' created");
@@ -311,7 +311,7 @@ while ($row = mysqli_fetch_array($sql)) {
if (!isset($_GET['client_id'])) { if (!isset($_GET['client_id'])) {
//Clients Added //Clients Added
$sql = mysqli_query($mysqli, "SELECT * FROM clients"); $sql = mysqli_query($mysqli, "SELECT * FROM clients");
while ($row = mysqli_fetch_array($sql)) { while ($row = mysqli_fetch_assoc($sql)) {
$event_id = intval($row['client_id']); $event_id = intval($row['client_id']);
$event_title = json_encode("Client: '" . $row['client_name'] . "' created"); $event_title = json_encode("Client: '" . $row['client_name'] . "' created");
$event_start = json_encode($row['client_created_at']); $event_start = json_encode($row['client_created_at']);
@@ -326,7 +326,7 @@ while ($row = mysqli_fetch_array($sql)) {
<?php <?php
// User preference for Calendar start day (Sunday/Monday) // User preference for Calendar start day (Sunday/Monday)
// Fetch User Dashboard Settings // Fetch User Dashboard Settings
$row = mysqli_fetch_array(mysqli_query($mysqli, "SELECT user_config_calendar_first_day FROM user_settings WHERE user_id = $session_user_id")); $row = mysqli_fetch_assoc(mysqli_query($mysqli, "SELECT user_config_calendar_first_day FROM user_settings WHERE user_id = $session_user_id"));
$user_config_calendar_first_day = intval($row['user_config_calendar_first_day']); $user_config_calendar_first_day = intval($row['user_config_calendar_first_day']);
?> ?>
firstDay: <?php echo $user_config_calendar_first_day ?>, firstDay: <?php echo $user_config_calendar_first_day ?>,

View File

@@ -111,7 +111,7 @@ $num_rows = mysqli_fetch_row(mysqli_query($mysqli, "SELECT FOUND_ROWS()"));
$access_permission_query $access_permission_query
ORDER BY client_name ASC ORDER BY client_name ASC
"); ");
while ($row = mysqli_fetch_array($sql_clients_filter)) { while ($row = mysqli_fetch_assoc($sql_clients_filter)) {
$client_id = intval($row['client_id']); $client_id = intval($row['client_id']);
$client_name = nullable_htmlentities($row['client_name']); $client_name = nullable_htmlentities($row['client_name']);
?> ?>
@@ -194,7 +194,7 @@ $num_rows = mysqli_fetch_row(mysqli_query($mysqli, "SELECT FOUND_ROWS()"));
<tbody> <tbody>
<?php <?php
while ($row = mysqli_fetch_array($sql)) { while ($row = mysqli_fetch_assoc($sql)) {
$client_id = intval($row['client_id']); $client_id = intval($row['client_id']);
$client_name = nullable_htmlentities($row['client_name']); $client_name = nullable_htmlentities($row['client_name']);
$certificate_id = intval($row['certificate_id']); $certificate_id = intval($row['certificate_id']);

View File

@@ -9,13 +9,13 @@ enforceUserPermission('module_sales');
require_once 'plugins/stripe-php/init.php'; require_once 'plugins/stripe-php/init.php';
// Get Stripe vars // Get Stripe vars
$stripe_vars = mysqli_fetch_array(mysqli_query($mysqli, "SELECT config_stripe_enable, config_stripe_publishable, config_stripe_secret FROM settings WHERE company_id = 1")); $stripe_vars = mysqli_fetch_assoc(mysqli_query($mysqli, "SELECT config_stripe_enable, config_stripe_publishable, config_stripe_secret FROM settings WHERE company_id = 1"));
$config_stripe_enable = intval($stripe_vars['config_stripe_enable']); $config_stripe_enable = intval($stripe_vars['config_stripe_enable']);
$config_stripe_publishable = nullable_htmlentities($stripe_vars['config_stripe_publishable']); $config_stripe_publishable = nullable_htmlentities($stripe_vars['config_stripe_publishable']);
$config_stripe_secret = nullable_htmlentities($stripe_vars['config_stripe_secret']); $config_stripe_secret = nullable_htmlentities($stripe_vars['config_stripe_secret']);
// Get client's StripeID from database // Get client's StripeID from database
$stripe_client_details = mysqli_fetch_array(mysqli_query($mysqli, "SELECT * FROM client_stripe WHERE client_id = $client_id LIMIT 1")); $stripe_client_details = mysqli_fetch_assoc(mysqli_query($mysqli, "SELECT * FROM client_stripe WHERE client_id = $client_id LIMIT 1"));
if ($stripe_client_details) { if ($stripe_client_details) {
$stripe_id = sanitizeInput($stripe_client_details['stripe_id']); $stripe_id = sanitizeInput($stripe_client_details['stripe_id']);
$stripe_pm = sanitizeInput($stripe_client_details['stripe_pm']); $stripe_pm = sanitizeInput($stripe_client_details['stripe_pm']);

View File

@@ -23,6 +23,24 @@ $sql_important_contacts = mysqli_query(
ORDER BY contact_primary DESC, contact_name DESC LIMIT 5" ORDER BY contact_primary DESC, contact_name DESC LIMIT 5"
); );
$sql_favorite_assets = mysqli_query(
$mysqli,
"SELECT * FROM assets
WHERE asset_client_id = $client_id
AND asset_favorite = 1
AND asset_archived_at IS NULL
ORDER BY asset_type ASC, asset_name ASC"
);
$sql_favorite_credentials = mysqli_query(
$mysqli,
"SELECT * FROM credentials
WHERE credential_client_id = $client_id
AND credential_favorite = 1
AND credential_archived_at IS NULL
ORDER BY credential_name ASC"
);
$sql_recent_tickets = mysqli_query( $sql_recent_tickets = mysqli_query(
$mysqli, $mysqli,
"SELECT * FROM tickets "SELECT * FROM tickets
@@ -215,7 +233,7 @@ $sql_asset_retired = mysqli_query(
<table class="table table-borderless table-sm"> <table class="table table-borderless table-sm">
<?php <?php
while ($row = mysqli_fetch_array($sql_important_contacts)) { while ($row = mysqli_fetch_assoc($sql_important_contacts)) {
$contact_id = intval($row['contact_id']); $contact_id = intval($row['contact_id']);
$contact_name = nullable_htmlentities($row['contact_name']); $contact_name = nullable_htmlentities($row['contact_name']);
$contact_title = nullable_htmlentities($row['contact_title']); $contact_title = nullable_htmlentities($row['contact_title']);
@@ -288,6 +306,111 @@ $sql_asset_retired = mysqli_query(
</div> </div>
<?php if (mysqli_num_rows($sql_favorite_assets) > 0) { ?>
<div class="col-md-4">
<div class="card card-dark mb-3">
<div class="card-header">
<h5 class="card-title"><i class="fas fa-fw fa-star mr-2"></i>Favorite Assets</h5>
</div>
<div class="card-body p-2">
<table class="table table-borderless table-sm">
<?php
while ($row = mysqli_fetch_assoc($sql_favorite_assets)) {
$asset_id = intval($row['asset_id']);
$asset_name = nullable_htmlentities($row['asset_name']);
$asset_type = nullable_htmlentities($row['asset_type']);
$asset_icon = getAssetIcon($asset_type);
?>
<tr>
<td>
<a href="#" class="ajax-modal"
data-modal-size="lg"
data-modal-url="modals/asset/asset_details.php?id=<?= $asset_id ?>">
<i class="fas fa-fw fa-<?= $asset_icon ?> text-muted mr-2"></i><?= $asset_name ?>
</a>
</td>
</tr>
<?php
}
?>
</table>
</div>
</div>
</div>
<?php } ?>
<?php if (mysqli_num_rows($sql_favorite_credentials) > 0) { ?>
<div class="col-md-4">
<div class="card card-dark mb-3">
<div class="card-header">
<h5 class="card-title"><i class="fas fa-fw fa-star mr-2"></i>Favorite Credentials</h5>
</div>
<div class="card-body p-2">
<table class="table table-borderless table-sm">
<?php
while ($row = mysqli_fetch_assoc($sql_favorite_credentials)) {
$credential_id = intval($row['credential_id']);
$credential_name = nullable_htmlentities($row['credential_name']);
$credential_description = nullable_htmlentities($row['credential_description']);
$credential_uri = sanitize_url($row['credential_uri']);
if (empty($credential_uri)) {
$credential_uri_display = "-";
} else {
$credential_uri_display = "<a href='$credential_uri'>" . truncate($credential_uri,40) . "</a><button class='btn btn-sm clipboardjs' type='button' title='$credential_uri' data-clipboard-text='$credential_uri'><i class='far fa-copy text-secondary'></i></button>";
}
$credential_uri_2 = sanitize_url($row['credential_uri_2']);
$credential_username = nullable_htmlentities(decryptCredentialEntry($row['credential_username']));
if (empty($credential_username)) {
$credential_username_display = "-";
} else {
$credential_username_display = "$credential_username<button class='btn btn-sm clipboardjs' type='button' data-clipboard-text='$credential_username'><i class='far fa-copy text-secondary'></i></button>";
}
$credential_password = nullable_htmlentities(decryptCredentialEntry($row['credential_password']));
$credential_otp_secret = nullable_htmlentities($row['credential_otp_secret']);
$credential_id_with_secret = '"' . $row['credential_id'] . '","' . $row['credential_otp_secret'] . '"';
if (empty($credential_otp_secret)) {
$otp_display = "-";
} else {
$otp_display = "<span onmouseenter='showOTPViaCredentialID($credential_id)'><i class='far fa-clock'></i> <span id='otp_$credential_id'><i>Hover..</i></span></span>";
}
?>
<tr>
<td>
<a href="#" class="ajax-modal"
data-modal-url="modals/credential/credential_edit.php?id=<?= $credential_id ?>">
<i class="fas fa-fw fa-key text-muted mr-2"></i><?= $credential_name ?>
</a>
</td>
<td><?= $credential_username_display ?></td>
<td class="text-nowrap">
<button class="btn p-0" type="button" data-toggle="popover" data-trigger="focus" data-placement="top" data-content="<?php echo $credential_password; ?>"><i class="fas fa-2x fa-ellipsis-h text-secondary"></i><i class="fas fa-2x fa-ellipsis-h text-secondary"></i></button><button class="btn btn-sm clipboardjs" type="button" data-clipboard-text="<?php echo $credential_password; ?>"><i class="far fa-copy text-secondary"></i></button>
</td>
<td><?= $otp_display ?></td>
</tr>
<?php
}
?>
</table>
</div>
</div>
</div>
<?php } ?>
<?php if (mysqli_num_rows($sql_shared_items) > 0) { ?> <?php if (mysqli_num_rows($sql_shared_items) > 0) { ?>
<div class="col-md-4"> <div class="col-md-4">
@@ -301,7 +424,7 @@ $sql_asset_retired = mysqli_query(
<tbody> <tbody>
<?php <?php
while ($row = mysqli_fetch_array($sql_shared_items)) { while ($row = mysqli_fetch_assoc($sql_shared_items)) {
$item_id = intval($row['item_id']); $item_id = intval($row['item_id']);
$item_active = nullable_htmlentities($row['item_active']); $item_active = nullable_htmlentities($row['item_active']);
$item_key = nullable_htmlentities($row['item_key']); $item_key = nullable_htmlentities($row['item_key']);
@@ -317,17 +440,17 @@ $sql_asset_retired = mysqli_query(
if ($item_type == 'Credential') { if ($item_type == 'Credential') {
$share_item_sql = mysqli_query($mysqli, "SELECT credential_name FROM credentials WHERE credential_id = $item_related_id AND credential_client_id = $client_id"); $share_item_sql = mysqli_query($mysqli, "SELECT credential_name FROM credentials WHERE credential_id = $item_related_id AND credential_client_id = $client_id");
$share_item = mysqli_fetch_array($share_item_sql); $share_item = mysqli_fetch_assoc($share_item_sql);
$item_name = nullable_htmlentities($share_item['credential_name']); $item_name = nullable_htmlentities($share_item['credential_name']);
$item_icon = "fas fa-key"; $item_icon = "fas fa-key";
} elseif ($item_type == 'Document') { } elseif ($item_type == 'Document') {
$share_item_sql = mysqli_query($mysqli, "SELECT document_name FROM documents WHERE document_id = $item_related_id AND document_client_id = $client_id"); $share_item_sql = mysqli_query($mysqli, "SELECT document_name FROM documents WHERE document_id = $item_related_id AND document_client_id = $client_id");
$share_item = mysqli_fetch_array($share_item_sql); $share_item = mysqli_fetch_assoc($share_item_sql);
$item_name = nullable_htmlentities($share_item['document_name']); $item_name = nullable_htmlentities($share_item['document_name']);
$item_icon = "fas fa-folder"; $item_icon = "fas fa-folder";
} elseif ($item_type == 'File') { } elseif ($item_type == 'File') {
$share_item_sql = mysqli_query($mysqli, "SELECT file_name FROM files WHERE file_id = $item_related_id AND file_client_id = $client_id"); $share_item_sql = mysqli_query($mysqli, "SELECT file_name FROM files WHERE file_id = $item_related_id AND file_client_id = $client_id");
$share_item = mysqli_fetch_array($share_item_sql); $share_item = mysqli_fetch_assoc($share_item_sql);
$item_name = nullable_htmlentities($share_item['file_name']); $item_name = nullable_htmlentities($share_item['file_name']);
$item_icon = "fas fa-paperclip"; $item_icon = "fas fa-paperclip";
} }
@@ -377,7 +500,7 @@ $sql_asset_retired = mysqli_query(
<?php <?php
while ($row = mysqli_fetch_array($sql_domains_expiring)) { while ($row = mysqli_fetch_assoc($sql_domains_expiring)) {
$domain_id = intval($row['domain_id']); $domain_id = intval($row['domain_id']);
$domain_name = nullable_htmlentities($row['domain_name']); $domain_name = nullable_htmlentities($row['domain_name']);
$domain_expire = nullable_htmlentities($row['domain_expire']); $domain_expire = nullable_htmlentities($row['domain_expire']);
@@ -395,7 +518,7 @@ $sql_asset_retired = mysqli_query(
<?php <?php
while ($row = mysqli_fetch_array($sql_certificates_expiring)) { while ($row = mysqli_fetch_assoc($sql_certificates_expiring)) {
$certificate_id = intval($row['certificate_id']); $certificate_id = intval($row['certificate_id']);
$certificate_name = nullable_htmlentities($row['certificate_name']); $certificate_name = nullable_htmlentities($row['certificate_name']);
$certificate_expire = nullable_htmlentities($row['certificate_expire']); $certificate_expire = nullable_htmlentities($row['certificate_expire']);
@@ -413,7 +536,7 @@ $sql_asset_retired = mysqli_query(
<?php <?php
while ($row = mysqli_fetch_array($sql_asset_warranties_expiring)) { while ($row = mysqli_fetch_assoc($sql_asset_warranties_expiring)) {
$asset_id = intval($row['asset_id']); $asset_id = intval($row['asset_id']);
$asset_name = nullable_htmlentities($row['asset_name']); $asset_name = nullable_htmlentities($row['asset_name']);
$asset_warranty_expire = nullable_htmlentities($row['asset_warranty_expire']); $asset_warranty_expire = nullable_htmlentities($row['asset_warranty_expire']);
@@ -433,7 +556,7 @@ $sql_asset_retired = mysqli_query(
<?php <?php
while ($row = mysqli_fetch_array($sql_asset_retire)) { while ($row = mysqli_fetch_assoc($sql_asset_retire)) {
$asset_id = intval($row['asset_id']); $asset_id = intval($row['asset_id']);
$asset_name = nullable_htmlentities($row['asset_name']); $asset_name = nullable_htmlentities($row['asset_name']);
$asset_install_date = nullable_htmlentities($row['asset_install_date']); $asset_install_date = nullable_htmlentities($row['asset_install_date']);
@@ -452,7 +575,7 @@ $sql_asset_retired = mysqli_query(
<?php <?php
while ($row = mysqli_fetch_array($sql_licenses_expiring)) { while ($row = mysqli_fetch_assoc($sql_licenses_expiring)) {
$software_id = intval($row['software_id']); $software_id = intval($row['software_id']);
$software_name = nullable_htmlentities($row['software_name']); $software_name = nullable_htmlentities($row['software_name']);
$software_expire = nullable_htmlentities($row['software_expire']); $software_expire = nullable_htmlentities($row['software_expire']);
@@ -495,7 +618,7 @@ $sql_asset_retired = mysqli_query(
<?php <?php
while ($row = mysqli_fetch_array($sql_domains_expired)) { while ($row = mysqli_fetch_assoc($sql_domains_expired)) {
$domain_id = intval($row['domain_id']); $domain_id = intval($row['domain_id']);
$domain_name = nullable_htmlentities($row['domain_name']); $domain_name = nullable_htmlentities($row['domain_name']);
$domain_expire = nullable_htmlentities($row['domain_expire']); $domain_expire = nullable_htmlentities($row['domain_expire']);
@@ -513,7 +636,7 @@ $sql_asset_retired = mysqli_query(
<?php <?php
while ($row = mysqli_fetch_array($sql_certificates_expired)) { while ($row = mysqli_fetch_assoc($sql_certificates_expired)) {
$certificate_id = intval($row['certificate_id']); $certificate_id = intval($row['certificate_id']);
$certificate_name = nullable_htmlentities($row['certificate_name']); $certificate_name = nullable_htmlentities($row['certificate_name']);
$certificate_expire = nullable_htmlentities($row['certificate_expire']); $certificate_expire = nullable_htmlentities($row['certificate_expire']);
@@ -531,7 +654,7 @@ $sql_asset_retired = mysqli_query(
<?php <?php
while ($row = mysqli_fetch_array($sql_asset_warranties_expired)) { while ($row = mysqli_fetch_assoc($sql_asset_warranties_expired)) {
$asset_id = intval($row['asset_id']); $asset_id = intval($row['asset_id']);
$asset_name = nullable_htmlentities($row['asset_name']); $asset_name = nullable_htmlentities($row['asset_name']);
$asset_warranty_expire = nullable_htmlentities($row['asset_warranty_expire']); $asset_warranty_expire = nullable_htmlentities($row['asset_warranty_expire']);
@@ -551,7 +674,7 @@ $sql_asset_retired = mysqli_query(
<?php <?php
while ($row = mysqli_fetch_array($sql_asset_retired)) { while ($row = mysqli_fetch_assoc($sql_asset_retired)) {
$asset_id = intval($row['asset_id']); $asset_id = intval($row['asset_id']);
$asset_name = nullable_htmlentities($row['asset_name']); $asset_name = nullable_htmlentities($row['asset_name']);
$asset_install_date = nullable_htmlentities($row['asset_install_date']); $asset_install_date = nullable_htmlentities($row['asset_install_date']);
@@ -570,7 +693,7 @@ $sql_asset_retired = mysqli_query(
<?php <?php
while ($row = mysqli_fetch_array($sql_licenses_expired)) { while ($row = mysqli_fetch_assoc($sql_licenses_expired)) {
$software_id = intval($row['software_id']); $software_id = intval($row['software_id']);
$software_name = nullable_htmlentities($row['software_name']); $software_name = nullable_htmlentities($row['software_name']);
$software_expire = nullable_htmlentities($row['software_expire']); $software_expire = nullable_htmlentities($row['software_expire']);
@@ -609,7 +732,7 @@ $sql_asset_retired = mysqli_query(
<tbody> <tbody>
<?php <?php
while ($row = mysqli_fetch_array($sql_stale_tickets)) { while ($row = mysqli_fetch_assoc($sql_stale_tickets)) {
$ticket_id = intval($row['ticket_id']); $ticket_id = intval($row['ticket_id']);
$ticket_prefix = nullable_htmlentities($row['ticket_prefix']); $ticket_prefix = nullable_htmlentities($row['ticket_prefix']);
$ticket_number = intval($row['ticket_number']); $ticket_number = intval($row['ticket_number']);
@@ -652,7 +775,7 @@ $sql_asset_retired = mysqli_query(
<tbody> <tbody>
<?php <?php
while ($row = mysqli_fetch_array($sql_recent_activities)) { while ($row = mysqli_fetch_assoc($sql_recent_activities)) {
$log_created_at_time_ago = timeAgo($row['log_created_at']); $log_created_at_time_ago = timeAgo($row['log_created_at']);
$log_description = nullable_htmlentities($row['log_description']); $log_description = nullable_htmlentities($row['log_description']);
@@ -681,6 +804,9 @@ $sql_asset_retired = mysqli_query(
</div> </div>
<!-- Include script to get TOTP code via the login ID -->
<script src="js/credential_show_otp_via_id.js"></script>
<script> <script>
function updateClientNotes(client_id) { function updateClientNotes(client_id) {
var notes = document.getElementById("clientNotes").value; var notes = document.getElementById("clientNotes").value;

View File

@@ -231,7 +231,7 @@ $num_rows = mysqli_fetch_row(mysqli_query($mysqli, "SELECT FOUND_ROWS()"));
GROUP BY tags.tag_id GROUP BY tags.tag_id
HAVING COUNT(client_tags.client_id) > 0 OR tags.tag_id IN ($tag_filter) HAVING COUNT(client_tags.client_id) > 0 OR tags.tag_id IN ($tag_filter)
"); ");
while ($row = mysqli_fetch_array($sql_tags_filter)) { while ($row = mysqli_fetch_assoc($sql_tags_filter)) {
$tag_id = intval($row['tag_id']); $tag_id = intval($row['tag_id']);
$tag_name = nullable_htmlentities($row['tag_name']); ?> $tag_name = nullable_htmlentities($row['tag_name']); ?>
@@ -249,7 +249,7 @@ $num_rows = mysqli_fetch_row(mysqli_query($mysqli, "SELECT FOUND_ROWS()"));
<?php <?php
$sql_industries_filter = mysqli_query($mysqli, "SELECT DISTINCT client_type FROM clients WHERE 1 = 1 AND client_$archive_query AND client_type != '' $leads_query ORDER BY client_type ASC"); $sql_industries_filter = mysqli_query($mysqli, "SELECT DISTINCT client_type FROM clients WHERE 1 = 1 AND client_$archive_query AND client_type != '' $leads_query ORDER BY client_type ASC");
while ($row = mysqli_fetch_array($sql_industries_filter)) { while ($row = mysqli_fetch_assoc($sql_industries_filter)) {
$industry_name = nullable_htmlentities($row['client_type']); $industry_name = nullable_htmlentities($row['client_type']);
?> ?>
<option <?php if ($industry_name == $industry_filter) { echo "selected"; } ?>><?php echo $industry_name; ?></option> <option <?php if ($industry_name == $industry_filter) { echo "selected"; } ?>><?php echo $industry_name; ?></option>
@@ -268,7 +268,7 @@ $num_rows = mysqli_fetch_row(mysqli_query($mysqli, "SELECT FOUND_ROWS()"));
<?php <?php
$sql_referrals_filter = mysqli_query($mysqli, "SELECT DISTINCT client_referral FROM clients WHERE 1 = 1 AND client_$archive_query AND client_referral != '' $leads_query ORDER BY client_referral ASC"); $sql_referrals_filter = mysqli_query($mysqli, "SELECT DISTINCT client_referral FROM clients WHERE 1 = 1 AND client_$archive_query AND client_referral != '' $leads_query ORDER BY client_referral ASC");
while ($row = mysqli_fetch_array($sql_referrals_filter)) { while ($row = mysqli_fetch_assoc($sql_referrals_filter)) {
$referral_name = nullable_htmlentities($row['client_referral']); $referral_name = nullable_htmlentities($row['client_referral']);
?> ?>
<option <?php if ($referral_name == $referral_filter) { echo "selected"; } ?>><?php echo $referral_name; ?></option> <option <?php if ($referral_name == $referral_filter) { echo "selected"; } ?>><?php echo $referral_name; ?></option>
@@ -323,7 +323,7 @@ $num_rows = mysqli_fetch_row(mysqli_query($mysqli, "SELECT FOUND_ROWS()"));
<tbody> <tbody>
<?php <?php
while ($row = mysqli_fetch_array($sql)) { while ($row = mysqli_fetch_assoc($sql)) {
$client_id = intval($row['client_id']); $client_id = intval($row['client_id']);
$client_name = nullable_htmlentities($row['client_name']); $client_name = nullable_htmlentities($row['client_name']);
$client_type = nullable_htmlentities($row['client_type']); $client_type = nullable_htmlentities($row['client_type']);
@@ -426,7 +426,7 @@ $num_rows = mysqli_fetch_row(mysqli_query($mysqli, "SELECT FOUND_ROWS()"));
$client_tag_name_display_array = array(); $client_tag_name_display_array = array();
$client_tag_id_array = array(); $client_tag_id_array = array();
$sql_client_tags = mysqli_query($mysqli, "SELECT * FROM client_tags LEFT JOIN tags ON client_tags.tag_id = tags.tag_id WHERE client_id = $client_id ORDER BY tag_name ASC"); $sql_client_tags = mysqli_query($mysqli, "SELECT * FROM client_tags LEFT JOIN tags ON client_tags.tag_id = tags.tag_id WHERE client_id = $client_id ORDER BY tag_name ASC");
while ($row = mysqli_fetch_array($sql_client_tags)) { while ($row = mysqli_fetch_assoc($sql_client_tags)) {
$client_tag_id = intval($row['tag_id']); $client_tag_id = intval($row['tag_id']);
$client_tag_name = nullable_htmlentities($row['tag_name']); $client_tag_name = nullable_htmlentities($row['tag_name']);
@@ -446,12 +446,12 @@ $num_rows = mysqli_fetch_row(mysqli_query($mysqli, "SELECT FOUND_ROWS()"));
//Add up all the payments for the invoice and get the total amount paid to the invoice //Add up all the payments for the invoice and get the total amount paid to the invoice
$sql_invoice_amounts = mysqli_query($mysqli, "SELECT SUM(invoice_amount) AS invoice_amounts FROM invoices WHERE invoice_client_id = $client_id AND invoice_status != 'Draft' AND invoice_status != 'Cancelled' AND invoice_status != 'Non-Billable' "); $sql_invoice_amounts = mysqli_query($mysqli, "SELECT SUM(invoice_amount) AS invoice_amounts FROM invoices WHERE invoice_client_id = $client_id AND invoice_status != 'Draft' AND invoice_status != 'Cancelled' AND invoice_status != 'Non-Billable' ");
$row = mysqli_fetch_array($sql_invoice_amounts); $row = mysqli_fetch_assoc($sql_invoice_amounts);
$invoice_amounts = floatval($row['invoice_amounts']); $invoice_amounts = floatval($row['invoice_amounts']);
$sql_amount_paid = mysqli_query($mysqli, "SELECT SUM(payment_amount) AS amount_paid FROM payments, invoices WHERE payment_invoice_id = invoice_id AND invoice_client_id = $client_id"); $sql_amount_paid = mysqli_query($mysqli, "SELECT SUM(payment_amount) AS amount_paid FROM payments, invoices WHERE payment_invoice_id = invoice_id AND invoice_client_id = $client_id");
$row = mysqli_fetch_array($sql_amount_paid); $row = mysqli_fetch_assoc($sql_amount_paid);
$amount_paid = floatval($row['amount_paid']); $amount_paid = floatval($row['amount_paid']);
@@ -465,19 +465,19 @@ $num_rows = mysqli_fetch_row(mysqli_query($mysqli, "SELECT FOUND_ROWS()"));
// Get Credit Balance // Get Credit Balance
$sql_credit_balance = mysqli_query($mysqli, "SELECT SUM(credit_amount) AS credit_balance FROM credits WHERE credit_client_id = $client_id"); $sql_credit_balance = mysqli_query($mysqli, "SELECT SUM(credit_amount) AS credit_balance FROM credits WHERE credit_client_id = $client_id");
$row = mysqli_fetch_array($sql_credit_balance); $row = mysqli_fetch_assoc($sql_credit_balance);
$credit_balance = floatval($row['credit_balance']); $credit_balance = floatval($row['credit_balance']);
//Get Monthly Recurring Total //Get Monthly Recurring Total
$sql_recurring_monthly_total = mysqli_query($mysqli, "SELECT SUM(recurring_invoice_amount) AS recurring_monthly_total FROM recurring_invoices WHERE recurring_invoice_status = 1 AND recurring_invoice_frequency = 'month' AND recurring_invoice_client_id = $client_id"); $sql_recurring_monthly_total = mysqli_query($mysqli, "SELECT SUM(recurring_invoice_amount) AS recurring_monthly_total FROM recurring_invoices WHERE recurring_invoice_status = 1 AND recurring_invoice_frequency = 'month' AND recurring_invoice_client_id = $client_id");
$row = mysqli_fetch_array($sql_recurring_monthly_total); $row = mysqli_fetch_assoc($sql_recurring_monthly_total);
$recurring_monthly_total = floatval($row['recurring_monthly_total']); $recurring_monthly_total = floatval($row['recurring_monthly_total']);
//Get Yearly Recurring Total //Get Yearly Recurring Total
$sql_recurring_yearly_total = mysqli_query($mysqli, "SELECT SUM(recurring_invoice_amount) AS recurring_yearly_total FROM recurring_invoices WHERE recurring_invoice_status = 1 AND recurring_invoice_frequency = 'year' AND recurring_invoice_client_id = $client_id"); $sql_recurring_yearly_total = mysqli_query($mysqli, "SELECT SUM(recurring_invoice_amount) AS recurring_yearly_total FROM recurring_invoices WHERE recurring_invoice_status = 1 AND recurring_invoice_frequency = 'year' AND recurring_invoice_client_id = $client_id");
$row = mysqli_fetch_array($sql_recurring_yearly_total); $row = mysqli_fetch_assoc($sql_recurring_yearly_total);
$recurring_yearly_total = floatval($row['recurring_yearly_total']) / 12; $recurring_yearly_total = floatval($row['recurring_yearly_total']) / 12;

View File

@@ -29,7 +29,7 @@ if (isset($_GET['contact_id'])) {
exit(); exit();
} }
$row = mysqli_fetch_array($sql); $row = mysqli_fetch_assoc($sql);
$client_id = intval($row['client_id']); $client_id = intval($row['client_id']);
$client_name = nullable_htmlentities($row['client_name']); $client_name = nullable_htmlentities($row['client_name']);
$contact_name = nullable_htmlentities($row['contact_name']); $contact_name = nullable_htmlentities($row['contact_name']);
@@ -120,7 +120,7 @@ if (isset($_GET['contact_id'])) {
$contact_tag_name_display_array = array(); $contact_tag_name_display_array = array();
$contact_tag_id_array = array(); $contact_tag_id_array = array();
$sql_contact_tags = mysqli_query($mysqli, "SELECT * FROM contact_tags LEFT JOIN tags ON contact_tags.tag_id = tags.tag_id WHERE contact_id = $contact_id ORDER BY tag_name ASC"); $sql_contact_tags = mysqli_query($mysqli, "SELECT * FROM contact_tags LEFT JOIN tags ON contact_tags.tag_id = tags.tag_id WHERE contact_id = $contact_id ORDER BY tag_name ASC");
while ($row = mysqli_fetch_array($sql_contact_tags)) { while ($row = mysqli_fetch_assoc($sql_contact_tags)) {
$contact_tag_id = intval($row['tag_id']); $contact_tag_id = intval($row['tag_id']);
$contact_tag_name = nullable_htmlentities($row['tag_name']); $contact_tag_name = nullable_htmlentities($row['tag_name']);
@@ -363,7 +363,7 @@ if (isset($_GET['contact_id'])) {
<tbody> <tbody>
<?php <?php
while ($row = mysqli_fetch_array($sql_related_assets)) { while ($row = mysqli_fetch_assoc($sql_related_assets)) {
$asset_id = intval($row['asset_id']); $asset_id = intval($row['asset_id']);
$asset_type = nullable_htmlentities($row['asset_type']); $asset_type = nullable_htmlentities($row['asset_type']);
$asset_name = nullable_htmlentities($row['asset_name']); $asset_name = nullable_htmlentities($row['asset_name']);
@@ -371,10 +371,10 @@ if (isset($_GET['contact_id'])) {
$asset_make = nullable_htmlentities($row['asset_make']); $asset_make = nullable_htmlentities($row['asset_make']);
$asset_model = nullable_htmlentities($row['asset_model']); $asset_model = nullable_htmlentities($row['asset_model']);
$asset_serial = nullable_htmlentities($row['asset_serial']); $asset_serial = nullable_htmlentities($row['asset_serial']);
if (empty($asset_serial)) { if ($asset_serial) {
$asset_serial_display = "-";
} else {
$asset_serial_display = $asset_serial; $asset_serial_display = $asset_serial;
} else {
$asset_serial_display = "-";
} }
$asset_os = nullable_htmlentities($row['asset_os']); $asset_os = nullable_htmlentities($row['asset_os']);
if (empty($asset_os)) { if (empty($asset_os)) {
@@ -405,6 +405,7 @@ if (isset($_GET['contact_id'])) {
$asset_photo = nullable_htmlentities($row['asset_photo']); $asset_photo = nullable_htmlentities($row['asset_photo']);
$asset_physical_location = nullable_htmlentities($row['asset_physical_location']); $asset_physical_location = nullable_htmlentities($row['asset_physical_location']);
$asset_notes = nullable_htmlentities($row['asset_notes']); $asset_notes = nullable_htmlentities($row['asset_notes']);
$asset_favorite = intval($row['asset_favorite']);
$asset_created_at = nullable_htmlentities($row['asset_created_at']); $asset_created_at = nullable_htmlentities($row['asset_created_at']);
$device_icon = getAssetIcon($asset_type); $device_icon = getAssetIcon($asset_type);
@@ -412,7 +413,7 @@ if (isset($_GET['contact_id'])) {
$asset_tag_name_display_array = array(); $asset_tag_name_display_array = array();
$asset_tag_id_array = array(); $asset_tag_id_array = array();
$sql_asset_tags = mysqli_query($mysqli, "SELECT * FROM asset_tags LEFT JOIN tags ON asset_tag_tag_id = tag_id WHERE asset_tag_asset_id = $asset_id ORDER BY tag_name ASC"); $sql_asset_tags = mysqli_query($mysqli, "SELECT * FROM asset_tags LEFT JOIN tags ON asset_tag_tag_id = tag_id WHERE asset_tag_asset_id = $asset_id ORDER BY tag_name ASC");
while ($row = mysqli_fetch_array($sql_asset_tags)) { while ($row = mysqli_fetch_assoc($sql_asset_tags)) {
$asset_tag_id = intval($row['tag_id']); $asset_tag_id = intval($row['tag_id']);
$asset_tag_name = nullable_htmlentities($row['tag_name']); $asset_tag_name = nullable_htmlentities($row['tag_name']);
@@ -433,14 +434,15 @@ if (isset($_GET['contact_id'])) {
?> ?>
<tr> <tr>
<th> <th>
<i class="fa fa-fw text-secondary fa-<?php echo $device_icon; ?> mr-2"></i> <i class="fa fa-fw text-secondary fa-<?= $device_icon ?> mr-1"></i>
<a class="text-secondary ajax-modal" href="#" <a class="text-secondary ajax-modal" href="#"
data-modal-size="lg" data-modal-size="lg"
data-modal-url="modals/asset/asset_details.php?id=<?= $asset_id ?>"> data-modal-url="modals/asset/asset_details.php?id=<?= $asset_id ?>">
<?php echo $asset_name; ?> <?= $asset_name ?>
<?php if ($asset_favorite) { echo "<i class='fas fa-fw fa-star text-warning' title='Favorite'></i>"; } ?>
</a> </a>
<div class="mt-0"> <div class="mt-0">
<small class="text-muted"><?php echo $asset_description; ?></small> <small class="text-muted"><?= $asset_description ?></small>
</div> </div>
<?php <?php
if ($asset_tags_display) { ?> if ($asset_tags_display) { ?>
@@ -449,17 +451,17 @@ if (isset($_GET['contact_id'])) {
</div> </div>
<?php } ?> <?php } ?>
</th> </th>
<td><?php echo $asset_type; ?></td> <td><?= $asset_type ?></td>
<td> <td>
<?php echo $asset_make; ?> <?= $asset_make ?>
<div class="mt-0"> <div class="mt-0">
<small class="text-muted"><?php echo $asset_model; ?></small> <small class="text-muted"><?= $asset_model ?></small>
</div> </div>
</td> </td>
<td><?php echo $asset_serial_display; ?></td> <td><?= $asset_serial_display ?></td>
<td><?php echo $asset_install_date_display; ?></td> <td><?= $asset_install_date_display ?></td>
<td><?php echo $asset_status; ?></td> <td><?= $asset_status ?></td>
<td> <td>
<div class="dropdown dropleft text-center"> <div class="dropdown dropleft text-center">
<button class="btn btn-secondary btn-sm" type="button" data-toggle="dropdown"><i class="fas fa-ellipsis-h"></i></button> <button class="btn btn-secondary btn-sm" type="button" data-toggle="dropdown"><i class="fas fa-ellipsis-h"></i></button>
@@ -474,16 +476,16 @@ if (isset($_GET['contact_id'])) {
</a> </a>
<div class="dropdown-divider"></div> <div class="dropdown-divider"></div>
<a class="dropdown-item" <a class="dropdown-item"
href="post.php?unlink_asset_from_contact&contact_id=<?php echo $contact_id; ?>&asset_id=<?php echo $asset_id; ?>" href="post.php?unlink_asset_from_contact&contact_id=<?= $contact_id ?>&asset_id=<?= $asset_id ?>"
class="btn btn-secondary btn-sm" title="Unlink"> class="btn btn-secondary btn-sm" title="Unlink">
<i class="fas fa-fw fa-unlink mr-2"></i>Unlink <i class="fas fa-fw fa-unlink mr-2"></i>Unlink
</a> </a>
<?php if ($session_user_role == 3) { ?> <?php if ($session_user_role == 3) { ?>
<div class="dropdown-divider"></div> <div class="dropdown-divider"></div>
<a class="dropdown-item text-danger" href="post.php?archive_asset=<?php echo $asset_id; ?>&csrf_token=<?php echo $_SESSION['csrf_token'] ?>"> <a class="dropdown-item text-danger" href="post.php?archive_asset=<?= $asset_id ?>&csrf_token=<?php echo $_SESSION['csrf_token'] ?>">
<i class="fas fa-fw fa-archive mr-2"></i>Archive <i class="fas fa-fw fa-archive mr-2"></i>Archive
</a> </a>
<a class="dropdown-item text-danger text-bold" href="post.php?delete_asset=<?php echo $asset_id; ?>&csrf_token=<?php echo $_SESSION['csrf_token'] ?>"> <a class="dropdown-item text-danger text-bold" href="post.php?delete_asset=<?= $asset_id ?>&csrf_token=<?= $_SESSION['csrf_token'] ?>">
<i class="fas fa-fw fa-trash mr-2"></i>Delete <i class="fas fa-fw fa-trash mr-2"></i>Delete
</a> </a>
<?php } ?> <?php } ?>
@@ -531,7 +533,7 @@ if (isset($_GET['contact_id'])) {
<tbody> <tbody>
<?php <?php
while ($row = mysqli_fetch_array($sql_related_credentials)) { while ($row = mysqli_fetch_assoc($sql_related_credentials)) {
$credential_id = intval($row['credentials_credential_id']); $credential_id = intval($row['credentials_credential_id']);
$credential_name = nullable_htmlentities($row['credential_name']); $credential_name = nullable_htmlentities($row['credential_name']);
$credential_description = nullable_htmlentities($row['credential_description']); $credential_description = nullable_htmlentities($row['credential_description']);
@@ -557,7 +559,7 @@ if (isset($_GET['contact_id'])) {
$otp_display = "<span onmouseenter='showOTPViaCredentialID($credential_id)'><i class='far fa-clock'></i> <span id='otp_$credential_id'><i>Hover..</i></span></span>"; $otp_display = "<span onmouseenter='showOTPViaCredentialID($credential_id)'><i class='far fa-clock'></i> <span id='otp_$credential_id'><i>Hover..</i></span></span>";
} }
$credential_note = nullable_htmlentities($row['credential_note']); $credential_note = nullable_htmlentities($row['credential_note']);
$credential_important = intval($row['credential_important']); $credential_favorite = intval($row['credential_favorite']);
$credential_contact_id = intval($row['credential_contact_id']); $credential_contact_id = intval($row['credential_contact_id']);
$credential_asset_id = intval($row['credential_asset_id']); $credential_asset_id = intval($row['credential_asset_id']);
@@ -565,7 +567,7 @@ if (isset($_GET['contact_id'])) {
$credential_tag_name_display_array = array(); $credential_tag_name_display_array = array();
$credential_tag_id_array = array(); $credential_tag_id_array = array();
$sql_credential_tags = mysqli_query($mysqli, "SELECT * FROM credential_tags LEFT JOIN tags ON credential_tags.tag_id = tags.tag_id WHERE credential_id = $credential_id ORDER BY tag_name ASC"); $sql_credential_tags = mysqli_query($mysqli, "SELECT * FROM credential_tags LEFT JOIN tags ON credential_tags.tag_id = tags.tag_id WHERE credential_id = $credential_id ORDER BY tag_name ASC");
while ($row = mysqli_fetch_array($sql_credential_tags)) { while ($row = mysqli_fetch_assoc($sql_credential_tags)) {
$credential_tag_id = intval($row['tag_id']); $credential_tag_id = intval($row['tag_id']);
$credential_tag_name = nullable_htmlentities($row['tag_name']); $credential_tag_name = nullable_htmlentities($row['tag_name']);
@@ -666,7 +668,7 @@ if (isset($_GET['contact_id'])) {
<tbody> <tbody>
<?php <?php
while ($row = mysqli_fetch_array($sql_linked_software)) { while ($row = mysqli_fetch_assoc($sql_linked_software)) {
$software_id = intval($row['software_id']); $software_id = intval($row['software_id']);
$software_name = nullable_htmlentities($row['software_name']); $software_name = nullable_htmlentities($row['software_name']);
$software_version = nullable_htmlentities($row['software_version']); $software_version = nullable_htmlentities($row['software_version']);
@@ -683,7 +685,7 @@ if (isset($_GET['contact_id'])) {
// Asset Licenses // Asset Licenses
$asset_licenses_sql = mysqli_query($mysqli, "SELECT asset_id FROM software_assets WHERE software_id = $software_id"); $asset_licenses_sql = mysqli_query($mysqli, "SELECT asset_id FROM software_assets WHERE software_id = $software_id");
$asset_licenses_array = array(); $asset_licenses_array = array();
while ($row = mysqli_fetch_array($asset_licenses_sql)) { while ($row = mysqli_fetch_assoc($asset_licenses_sql)) {
$asset_licenses_array[] = intval($row['asset_id']); $asset_licenses_array[] = intval($row['asset_id']);
$seat_count = $seat_count + 1; $seat_count = $seat_count + 1;
} }
@@ -692,7 +694,7 @@ if (isset($_GET['contact_id'])) {
// Contact Licenses // Contact Licenses
$contact_licenses_sql = mysqli_query($mysqli, "SELECT contact_id FROM software_contacts WHERE software_id = $software_id"); $contact_licenses_sql = mysqli_query($mysqli, "SELECT contact_id FROM software_contacts WHERE software_id = $software_id");
$contact_licenses_array = array(); $contact_licenses_array = array();
while ($row = mysqli_fetch_array($contact_licenses_sql)) { while ($row = mysqli_fetch_assoc($contact_licenses_sql)) {
$contact_licenses_array[] = intval($row['contact_id']); $contact_licenses_array[] = intval($row['contact_id']);
$seat_count = $seat_count + 1; $seat_count = $seat_count + 1;
} }
@@ -741,7 +743,7 @@ if (isset($_GET['contact_id'])) {
<tbody> <tbody>
<?php <?php
while ($row = mysqli_fetch_array($sql_related_recurring_tickets)) { while ($row = mysqli_fetch_assoc($sql_related_recurring_tickets)) {
$recurring_ticket_id = intval($row['recurring_ticket_id']); $recurring_ticket_id = intval($row['recurring_ticket_id']);
$recurring_ticket_subject = nullable_htmlentities($row['recurring_ticket_subject']); $recurring_ticket_subject = nullable_htmlentities($row['recurring_ticket_subject']);
$recurring_ticket_priority = nullable_htmlentities($row['recurring_ticket_priority']); $recurring_ticket_priority = nullable_htmlentities($row['recurring_ticket_priority']);
@@ -821,7 +823,7 @@ if (isset($_GET['contact_id'])) {
<tbody> <tbody>
<?php <?php
while ($row = mysqli_fetch_array($sql_related_tickets)) { while ($row = mysqli_fetch_assoc($sql_related_tickets)) {
$ticket_id = intval($row['ticket_id']); $ticket_id = intval($row['ticket_id']);
$ticket_prefix = nullable_htmlentities($row['ticket_prefix']); $ticket_prefix = nullable_htmlentities($row['ticket_prefix']);
$ticket_number = intval($row['ticket_number']); $ticket_number = intval($row['ticket_number']);
@@ -910,7 +912,7 @@ if (isset($_GET['contact_id'])) {
<tbody> <tbody>
<?php <?php
while ($row = mysqli_fetch_array($sql_linked_services)) { while ($row = mysqli_fetch_assoc($sql_linked_services)) {
$service_id = intval($row['service_id']); $service_id = intval($row['service_id']);
$service_name = nullable_htmlentities($row['service_name']); $service_name = nullable_htmlentities($row['service_name']);
$service_description = nullable_htmlentities($row['service_description']); $service_description = nullable_htmlentities($row['service_description']);
@@ -969,7 +971,7 @@ if (isset($_GET['contact_id'])) {
<tbody> <tbody>
<?php <?php
while ($row = mysqli_fetch_array($sql_linked_documents)) { while ($row = mysqli_fetch_assoc($sql_linked_documents)) {
$document_id = intval($row['document_id']); $document_id = intval($row['document_id']);
$document_name = nullable_htmlentities($row['document_name']); $document_name = nullable_htmlentities($row['document_name']);
$document_description = nullable_htmlentities($row['document_description']); $document_description = nullable_htmlentities($row['document_description']);
@@ -1035,7 +1037,7 @@ if (isset($_GET['contact_id'])) {
<tbody> <tbody>
<?php <?php
while ($row = mysqli_fetch_array($sql_linked_files)) { while ($row = mysqli_fetch_assoc($sql_linked_files)) {
$file_id = intval($row['file_id']); $file_id = intval($row['file_id']);
$file_name = nullable_htmlentities($row['file_name']); $file_name = nullable_htmlentities($row['file_name']);
$file_description = nullable_htmlentities($row['file_description']); $file_description = nullable_htmlentities($row['file_description']);
@@ -1099,7 +1101,7 @@ if (isset($_GET['contact_id'])) {
<tbody> <tbody>
<?php <?php
while ($row = mysqli_fetch_array($sql_related_notes)) { while ($row = mysqli_fetch_assoc($sql_related_notes)) {
$contact_note_id = intval($row['contact_note_id']); $contact_note_id = intval($row['contact_note_id']);
$contact_note_type = nullable_htmlentities($row['contact_note_type']); $contact_note_type = nullable_htmlentities($row['contact_note_type']);
$contact_note = nl2br(nullable_htmlentities($row['contact_note'])); $contact_note = nl2br(nullable_htmlentities($row['contact_note']));

View File

@@ -144,7 +144,7 @@ $num_rows = mysqli_fetch_row(mysqli_query($mysqli, "SELECT FOUND_ROWS()"));
GROUP BY tags.tag_id GROUP BY tags.tag_id
HAVING COUNT(contact_tags.contact_id) > 0 OR tags.tag_id IN ($tag_filter) HAVING COUNT(contact_tags.contact_id) > 0 OR tags.tag_id IN ($tag_filter)
"); ");
while ($row = mysqli_fetch_array($sql_tags_filter)) { while ($row = mysqli_fetch_assoc($sql_tags_filter)) {
$tag_id = intval($row['tag_id']); $tag_id = intval($row['tag_id']);
$tag_name = nullable_htmlentities($row['tag_name']); ?> $tag_name = nullable_htmlentities($row['tag_name']); ?>
@@ -169,7 +169,7 @@ $num_rows = mysqli_fetch_row(mysqli_query($mysqli, "SELECT FOUND_ROWS()"));
AND ( EXISTS (SELECT 1 FROM contacts WHERE contact_location_id = location_id AND $archive_query) OR location_id = $location_filter) AND ( EXISTS (SELECT 1 FROM contacts WHERE contact_location_id = location_id AND $archive_query) OR location_id = $location_filter)
ORDER BY location_name ASC ORDER BY location_name ASC
"); ");
while ($row = mysqli_fetch_array($sql_locations_filter)) { while ($row = mysqli_fetch_assoc($sql_locations_filter)) {
$location_id = intval($row['location_id']); $location_id = intval($row['location_id']);
$location_name = nullable_htmlentities($row['location_name']); $location_name = nullable_htmlentities($row['location_name']);
?> ?>
@@ -196,7 +196,7 @@ $num_rows = mysqli_fetch_row(mysqli_query($mysqli, "SELECT FOUND_ROWS()"));
$access_permission_query $access_permission_query
ORDER BY client_name ASC ORDER BY client_name ASC
"); ");
while ($row = mysqli_fetch_array($sql_clients_filter)) { while ($row = mysqli_fetch_assoc($sql_clients_filter)) {
$client_id = intval($row['client_id']); $client_id = intval($row['client_id']);
$client_name = nullable_htmlentities($row['client_name']); $client_name = nullable_htmlentities($row['client_name']);
?> ?>
@@ -327,7 +327,7 @@ $num_rows = mysqli_fetch_row(mysqli_query($mysqli, "SELECT FOUND_ROWS()"));
<tbody> <tbody>
<?php <?php
while ($row = mysqli_fetch_array($sql)) { while ($row = mysqli_fetch_assoc($sql)) {
$client_id = intval($row['client_id']); $client_id = intval($row['client_id']);
$client_name = nullable_htmlentities($row['client_name']); $client_name = nullable_htmlentities($row['client_name']);
$contact_id = intval($row['contact_id']); $contact_id = intval($row['contact_id']);
@@ -445,7 +445,7 @@ $num_rows = mysqli_fetch_row(mysqli_query($mysqli, "SELECT FOUND_ROWS()"));
$contact_tag_name_display_array = array(); $contact_tag_name_display_array = array();
$contact_tag_id_array = array(); $contact_tag_id_array = array();
$sql_contact_tags = mysqli_query($mysqli, "SELECT * FROM contact_tags LEFT JOIN tags ON contact_tags.tag_id = tags.tag_id WHERE contact_id = $contact_id ORDER BY tag_name ASC"); $sql_contact_tags = mysqli_query($mysqli, "SELECT * FROM contact_tags LEFT JOIN tags ON contact_tags.tag_id = tags.tag_id WHERE contact_id = $contact_id ORDER BY tag_name ASC");
while ($row = mysqli_fetch_array($sql_contact_tags)) { while ($row = mysqli_fetch_assoc($sql_contact_tags)) {
$contact_tag_id = intval($row['tag_id']); $contact_tag_id = intval($row['tag_id']);
$contact_tag_name = nullable_htmlentities($row['tag_name']); $contact_tag_name = nullable_htmlentities($row['tag_name']);

View File

@@ -93,7 +93,7 @@ $sql = mysqli_query(
$access_permission_query $access_permission_query
$client_query $client_query
GROUP BY c.credential_id GROUP BY c.credential_id
ORDER BY c.credential_important DESC, $sort $order LIMIT $record_from, $record_to" ORDER BY c.credential_favorite DESC, $sort $order LIMIT $record_from, $record_to"
); );
$num_rows = mysqli_fetch_row(mysqli_query($mysqli, "SELECT FOUND_ROWS()")); $num_rows = mysqli_fetch_row(mysqli_query($mysqli, "SELECT FOUND_ROWS()"));
@@ -161,7 +161,7 @@ $num_rows = mysqli_fetch_row(mysqli_query($mysqli, "SELECT FOUND_ROWS()"));
GROUP BY tags.tag_id GROUP BY tags.tag_id
HAVING COUNT(credential_tags.credential_id) > 0 OR tags.tag_id IN ($tag_filter) HAVING COUNT(credential_tags.credential_id) > 0 OR tags.tag_id IN ($tag_filter)
"); ");
while ($row = mysqli_fetch_array($sql_tags_filter)) { while ($row = mysqli_fetch_assoc($sql_tags_filter)) {
$tag_id = intval($row['tag_id']); $tag_id = intval($row['tag_id']);
$tag_name = nullable_htmlentities($row['tag_name']); ?> $tag_name = nullable_htmlentities($row['tag_name']); ?>
@@ -180,7 +180,7 @@ $num_rows = mysqli_fetch_row(mysqli_query($mysqli, "SELECT FOUND_ROWS()"));
<?php <?php
$sql_locations_filter = mysqli_query($mysqli, "SELECT * FROM locations WHERE location_client_id = $client_id AND location_archived_at IS NULL ORDER BY location_name ASC"); $sql_locations_filter = mysqli_query($mysqli, "SELECT * FROM locations WHERE location_client_id = $client_id AND location_archived_at IS NULL ORDER BY location_name ASC");
while ($row = mysqli_fetch_array($sql_locations_filter)) { while ($row = mysqli_fetch_assoc($sql_locations_filter)) {
$location_id = intval($row['location_id']); $location_id = intval($row['location_id']);
$location_name = nullable_htmlentities($row['location_name']); $location_name = nullable_htmlentities($row['location_name']);
?> ?>
@@ -207,7 +207,7 @@ $num_rows = mysqli_fetch_row(mysqli_query($mysqli, "SELECT FOUND_ROWS()"));
$access_permission_query $access_permission_query
ORDER BY client_name ASC ORDER BY client_name ASC
"); ");
while ($row = mysqli_fetch_array($sql_clients_filter)) { while ($row = mysqli_fetch_assoc($sql_clients_filter)) {
$client_id = intval($row['client_id']); $client_id = intval($row['client_id']);
$client_name = nullable_htmlentities($row['client_name']); $client_name = nullable_htmlentities($row['client_name']);
?> ?>
@@ -232,7 +232,17 @@ $num_rows = mysqli_fetch_row(mysqli_query($mysqli, "SELECT FOUND_ROWS()"));
<i class="fas fa-fw fa-layer-group mr-2"></i>Bulk Action (<span id="selectedCount">0</span>) <i class="fas fa-fw fa-layer-group mr-2"></i>Bulk Action (<span id="selectedCount">0</span>)
</button> </button>
<div class="dropdown-menu"> <div class="dropdown-menu">
<button class="dropdown-item"
type="submit" form="bulkActions" name="bulk_favorite_credentials">
<i class="fas fa-fw fa-star text-warning mr-2"></i>Favorite
</button>
<div class="dropdown-divider"></div>
<button class="dropdown-item"
type="submit" form="bulkActions" name="bulk_unfavorite_credentials">
<i class="far fa-fw fa-star mr-2"></i>Unfavorite
</button>
<?php if ($archived) { ?> <?php if ($archived) { ?>
<div class="dropdown-divider"></div>
<button class="dropdown-item text-info" <button class="dropdown-item text-info"
type="submit" form="bulkActions" name="bulk_unarchive_credentials"> type="submit" form="bulkActions" name="bulk_unarchive_credentials">
<i class="fas fa-fw fa-redo mr-2"></i>Unarchive <i class="fas fa-fw fa-redo mr-2"></i>Unarchive
@@ -243,6 +253,7 @@ $num_rows = mysqli_fetch_row(mysqli_query($mysqli, "SELECT FOUND_ROWS()"));
<i class="fas fa-fw fa-trash mr-2"></i>Delete <i class="fas fa-fw fa-trash mr-2"></i>Delete
</button> </button>
<?php } else { ?> <?php } else { ?>
<div class="dropdown-divider"></div>
<a class="dropdown-item ajax-modal" href="#" <a class="dropdown-item ajax-modal" href="#"
data-modal-url="modals/credential/credential_bulk_assign_tags.php" data-modal-url="modals/credential/credential_bulk_assign_tags.php"
data-bulk="true"> data-bulk="true">
@@ -301,7 +312,7 @@ $num_rows = mysqli_fetch_row(mysqli_query($mysqli, "SELECT FOUND_ROWS()"));
<tbody> <tbody>
<?php <?php
while ($row = mysqli_fetch_array($sql)) { while ($row = mysqli_fetch_assoc($sql)) {
$client_id = intval($row['client_id']); $client_id = intval($row['client_id']);
$client_name = nullable_htmlentities($row['client_name']); $client_name = nullable_htmlentities($row['client_name']);
$credential_id = intval($row['c_credential_id']); $credential_id = intval($row['c_credential_id']);
@@ -331,7 +342,7 @@ $num_rows = mysqli_fetch_row(mysqli_query($mysqli, "SELECT FOUND_ROWS()"));
$credential_note = nullable_htmlentities($row['credential_note']); $credential_note = nullable_htmlentities($row['credential_note']);
$credential_created_at = nullable_htmlentities($row['credential_created_at']); $credential_created_at = nullable_htmlentities($row['credential_created_at']);
$credential_archived_at = nullable_htmlentities($row['credential_archived_at']); $credential_archived_at = nullable_htmlentities($row['credential_archived_at']);
$credential_important = intval($row['credential_important']); $credential_favorite = intval($row['credential_favorite']);
$credential_contact_id = intval($row['credential_contact_id']); $credential_contact_id = intval($row['credential_contact_id']);
$contact_name = nullable_htmlentities($row['contact_name']); $contact_name = nullable_htmlentities($row['contact_name']);
$credential_asset_id = intval($row['credential_asset_id']); $credential_asset_id = intval($row['credential_asset_id']);
@@ -341,7 +352,7 @@ $num_rows = mysqli_fetch_row(mysqli_query($mysqli, "SELECT FOUND_ROWS()"));
$credential_tag_name_display_array = array(); $credential_tag_name_display_array = array();
$credential_tag_id_array = array(); $credential_tag_id_array = array();
$sql_credential_tags = mysqli_query($mysqli, "SELECT * FROM credential_tags LEFT JOIN tags ON credential_tags.tag_id = tags.tag_id WHERE credential_id = $credential_id ORDER BY tag_name ASC"); $sql_credential_tags = mysqli_query($mysqli, "SELECT * FROM credential_tags LEFT JOIN tags ON credential_tags.tag_id = tags.tag_id WHERE credential_id = $credential_id ORDER BY tag_name ASC");
while ($row = mysqli_fetch_array($sql_credential_tags)) { while ($row = mysqli_fetch_assoc($sql_credential_tags)) {
$credential_tag_id = intval($row['tag_id']); $credential_tag_id = intval($row['tag_id']);
$credential_tag_name = nullable_htmlentities($row['tag_name']); $credential_tag_name = nullable_htmlentities($row['tag_name']);
@@ -390,7 +401,7 @@ $num_rows = mysqli_fetch_row(mysqli_query($mysqli, "SELECT FOUND_ROWS()"));
LIMIT 1" LIMIT 1"
); );
if (mysqli_num_rows($sql_shared) > 0) { if (mysqli_num_rows($sql_shared) > 0) {
$row = mysqli_fetch_array($sql_shared); $row = mysqli_fetch_assoc($sql_shared);
$item_id = intval($row['item_id']); $item_id = intval($row['item_id']);
$item_active = nullable_htmlentities($row['item_active']); $item_active = nullable_htmlentities($row['item_active']);
$item_key = nullable_htmlentities($row['item_key']); $item_key = nullable_htmlentities($row['item_key']);
@@ -407,7 +418,7 @@ $num_rows = mysqli_fetch_row(mysqli_query($mysqli, "SELECT FOUND_ROWS()"));
?> ?>
<tr class="<?php if (!empty($credential_important)) { echo "text-bold"; } ?>"> <tr class="<?php if ($credential_favorite) { echo "text-bold"; } ?>">
<td class="pr-0"> <td class="pr-0">
<div class="form-check"> <div class="form-check">
<input class="form-check-input bulk-select" type="checkbox" name="credential_ids[]" value="<?php echo $credential_id ?>"> <input class="form-check-input bulk-select" type="checkbox" name="credential_ids[]" value="<?php echo $credential_id ?>">
@@ -419,7 +430,7 @@ $num_rows = mysqli_fetch_row(mysqli_query($mysqli, "SELECT FOUND_ROWS()"));
<div class="media"> <div class="media">
<i class="fa fa-fw fa-2x fa-key mr-3"></i> <i class="fa fa-fw fa-2x fa-key mr-3"></i>
<div class="media-body"> <div class="media-body">
<div><?php echo $credential_name; ?></div> <div><?php echo $credential_name; ?> <?php if ($credential_favorite) { echo "<i class='fas fa-fw fa-star text-warning' title='Favorite'></i>"; } ?></div>
<div><small class="text-secondary"><?php echo $credential_description; ?></small></div> <div><small class="text-secondary"><?php echo $credential_description; ?></small></div>
<?php <?php
if (!empty($credential_tags_display)) { ?> if (!empty($credential_tags_display)) { ?>

View File

@@ -17,7 +17,7 @@ if (isset($_GET['enable_technical'])) {
// Fetch User Dashboard Settings // Fetch User Dashboard Settings
$sql_user_dashboard_settings = mysqli_query($mysqli, "SELECT * FROM user_settings WHERE user_id = $session_user_id"); $sql_user_dashboard_settings = mysqli_query($mysqli, "SELECT * FROM user_settings WHERE user_id = $session_user_id");
$row = mysqli_fetch_array($sql_user_dashboard_settings); $row = mysqli_fetch_assoc($sql_user_dashboard_settings);
$user_config_dashboard_financial_enable = intval($row['user_config_dashboard_financial_enable']); $user_config_dashboard_financial_enable = intval($row['user_config_dashboard_financial_enable']);
$user_config_dashboard_technical_enable = intval($row['user_config_dashboard_technical_enable']); $user_config_dashboard_technical_enable = intval($row['user_config_dashboard_technical_enable']);
@@ -52,7 +52,7 @@ $sql_years_select = mysqli_query($mysqli, "
<label for="year" class="mr-sm-2">Select Year:</label> <label for="year" class="mr-sm-2">Select Year:</label>
<select id="year" onchange="this.form.submit()" class="form-control mr-sm-3 col-sm-2 mb-3 mb-sm-0" name="year"> <select id="year" onchange="this.form.submit()" class="form-control mr-sm-3 col-sm-2 mb-3 mb-sm-0" name="year">
<?php while ($row = mysqli_fetch_array($sql_years_select)) { <?php while ($row = mysqli_fetch_assoc($sql_years_select)) {
$year_select = $row['all_years']; $year_select = $row['all_years'];
if (empty($year_select)) { if (empty($year_select)) {
$year_select = date('Y'); $year_select = date('Y');
@@ -88,29 +88,29 @@ if ($user_config_dashboard_financial_enable == 1) {
$largest_income_month = 0; $largest_income_month = 0;
$sql_total_payments_to_invoices = mysqli_query($mysqli, "SELECT SUM(payment_amount) AS total_payments_to_invoices FROM payments WHERE YEAR(payment_date) = $year"); $sql_total_payments_to_invoices = mysqli_query($mysqli, "SELECT SUM(payment_amount) AS total_payments_to_invoices FROM payments WHERE YEAR(payment_date) = $year");
$row = mysqli_fetch_array($sql_total_payments_to_invoices); $row = mysqli_fetch_assoc($sql_total_payments_to_invoices);
$total_payments_to_invoices = floatval($row['total_payments_to_invoices']); $total_payments_to_invoices = floatval($row['total_payments_to_invoices']);
$sql_total_revenues = mysqli_query($mysqli, "SELECT SUM(revenue_amount) AS total_revenues FROM revenues WHERE YEAR(revenue_date) = $year AND revenue_category_id > 0"); $sql_total_revenues = mysqli_query($mysqli, "SELECT SUM(revenue_amount) AS total_revenues FROM revenues WHERE YEAR(revenue_date) = $year AND revenue_category_id > 0");
$row = mysqli_fetch_array($sql_total_revenues); $row = mysqli_fetch_assoc($sql_total_revenues);
$total_revenues = floatval($row['total_revenues']); $total_revenues = floatval($row['total_revenues']);
$total_income = $total_payments_to_invoices + $total_revenues; $total_income = $total_payments_to_invoices + $total_revenues;
$sql_total_expenses = mysqli_query($mysqli, "SELECT SUM(expense_amount) AS total_expenses FROM expenses WHERE expense_vendor_id > 0 AND YEAR(expense_date) = $year"); $sql_total_expenses = mysqli_query($mysqli, "SELECT SUM(expense_amount) AS total_expenses FROM expenses WHERE expense_vendor_id > 0 AND YEAR(expense_date) = $year");
$row = mysqli_fetch_array($sql_total_expenses); $row = mysqli_fetch_assoc($sql_total_expenses);
$total_expenses = floatval($row['total_expenses']); $total_expenses = floatval($row['total_expenses']);
$sql_invoice_totals = mysqli_query($mysqli, "SELECT SUM(invoice_amount) AS invoice_totals FROM invoices WHERE invoice_status != 'Draft' AND invoice_status != 'Cancelled' AND invoice_status != 'Non-Billable' AND YEAR(invoice_date) = $year"); $sql_invoice_totals = mysqli_query($mysqli, "SELECT SUM(invoice_amount) AS invoice_totals FROM invoices WHERE invoice_status != 'Draft' AND invoice_status != 'Cancelled' AND invoice_status != 'Non-Billable' AND YEAR(invoice_date) = $year");
$row = mysqli_fetch_array($sql_invoice_totals); $row = mysqli_fetch_assoc($sql_invoice_totals);
$invoice_totals = floatval($row['invoice_totals']); $invoice_totals = floatval($row['invoice_totals']);
$sql_total_payments_to_invoices_all_years = mysqli_query($mysqli, "SELECT SUM(payment_amount) AS total_payments_to_invoices_all_years FROM payments"); $sql_total_payments_to_invoices_all_years = mysqli_query($mysqli, "SELECT SUM(payment_amount) AS total_payments_to_invoices_all_years FROM payments");
$row = mysqli_fetch_array($sql_total_payments_to_invoices_all_years); $row = mysqli_fetch_assoc($sql_total_payments_to_invoices_all_years);
$total_payments_to_invoices_all_years = floatval($row['total_payments_to_invoices_all_years']); $total_payments_to_invoices_all_years = floatval($row['total_payments_to_invoices_all_years']);
$sql_invoice_totals_all_years = mysqli_query($mysqli, "SELECT SUM(invoice_amount) AS invoice_totals_all_years FROM invoices WHERE invoice_status != 'Draft' AND invoice_status != 'Cancelled' AND invoice_status != 'Non-Billable'"); $sql_invoice_totals_all_years = mysqli_query($mysqli, "SELECT SUM(invoice_amount) AS invoice_totals_all_years FROM invoices WHERE invoice_status != 'Draft' AND invoice_status != 'Cancelled' AND invoice_status != 'Non-Billable'");
$row = mysqli_fetch_array($sql_invoice_totals_all_years); $row = mysqli_fetch_assoc($sql_invoice_totals_all_years);
$invoice_totals_all_years = floatval($row['invoice_totals_all_years']); $invoice_totals_all_years = floatval($row['invoice_totals_all_years']);
$receivables = $invoice_totals_all_years - $total_payments_to_invoices_all_years; $receivables = $invoice_totals_all_years - $total_payments_to_invoices_all_years;
@@ -135,30 +135,30 @@ if ($user_config_dashboard_financial_enable == 1) {
// Get recurring invoice totals // Get recurring invoice totals
$sql_recurring_yearly_total = mysqli_query($mysqli, "SELECT SUM(recurring_invoice_amount) AS recurring_yearly_total FROM recurring_invoices WHERE recurring_invoice_status = 1 AND recurring_invoice_frequency = 'year' AND YEAR(recurring_invoice_created_at) <= $year"); $sql_recurring_yearly_total = mysqli_query($mysqli, "SELECT SUM(recurring_invoice_amount) AS recurring_yearly_total FROM recurring_invoices WHERE recurring_invoice_status = 1 AND recurring_invoice_frequency = 'year' AND YEAR(recurring_invoice_created_at) <= $year");
$row = mysqli_fetch_array($sql_recurring_yearly_total); $row = mysqli_fetch_assoc($sql_recurring_yearly_total);
$recurring_yearly_total = floatval($row['recurring_yearly_total']); $recurring_yearly_total = floatval($row['recurring_yearly_total']);
$sql_recurring_monthly_total = mysqli_query($mysqli, "SELECT SUM(recurring_invoice_amount) AS recurring_monthly_total FROM recurring_invoices WHERE recurring_invoice_status = 1 AND recurring_invoice_frequency = 'month' AND YEAR(recurring_invoice_created_at) <= $year"); $sql_recurring_monthly_total = mysqli_query($mysqli, "SELECT SUM(recurring_invoice_amount) AS recurring_monthly_total FROM recurring_invoices WHERE recurring_invoice_status = 1 AND recurring_invoice_frequency = 'month' AND YEAR(recurring_invoice_created_at) <= $year");
$row = mysqli_fetch_array($sql_recurring_monthly_total); $row = mysqli_fetch_assoc($sql_recurring_monthly_total);
$recurring_monthly_total = floatval($row['recurring_monthly_total']) + ($recurring_yearly_total / 12); $recurring_monthly_total = floatval($row['recurring_monthly_total']) + ($recurring_yearly_total / 12);
// Recurring expenses totals // Recurring expenses totals
$sql_recurring_expense_yearly_total = mysqli_query($mysqli, "SELECT SUM(recurring_expense_amount) AS recurring_expense_yearly_total FROM recurring_expenses WHERE recurring_expense_status = 1 AND recurring_expense_frequency = 2 AND YEAR(recurring_expense_created_at) <= $year"); $sql_recurring_expense_yearly_total = mysqli_query($mysqli, "SELECT SUM(recurring_expense_amount) AS recurring_expense_yearly_total FROM recurring_expenses WHERE recurring_expense_status = 1 AND recurring_expense_frequency = 2 AND YEAR(recurring_expense_created_at) <= $year");
$row = mysqli_fetch_array($sql_recurring_expense_yearly_total); $row = mysqli_fetch_assoc($sql_recurring_expense_yearly_total);
$recurring_expense_yearly_total = floatval($row['recurring_expense_yearly_total']); $recurring_expense_yearly_total = floatval($row['recurring_expense_yearly_total']);
$sql_recurring_expense_monthly_total = mysqli_query($mysqli, "SELECT SUM(recurring_expense_amount) AS recurring_expense_monthly_total FROM recurring_expenses WHERE recurring_expense_status = 1 AND recurring_expense_frequency = 1 AND YEAR(recurring_expense_created_at) <= $year"); $sql_recurring_expense_monthly_total = mysqli_query($mysqli, "SELECT SUM(recurring_expense_amount) AS recurring_expense_monthly_total FROM recurring_expenses WHERE recurring_expense_status = 1 AND recurring_expense_frequency = 1 AND YEAR(recurring_expense_created_at) <= $year");
$row = mysqli_fetch_array($sql_recurring_expense_monthly_total); $row = mysqli_fetch_assoc($sql_recurring_expense_monthly_total);
$recurring_expense_monthly_total = floatval($row['recurring_expense_monthly_total']) + ($recurring_expense_yearly_total / 12); $recurring_expense_monthly_total = floatval($row['recurring_expense_monthly_total']) + ($recurring_expense_yearly_total / 12);
// Get miles driven // Get miles driven
$sql_miles_driven = mysqli_query($mysqli, "SELECT SUM(trip_miles) AS total_miles FROM trips WHERE YEAR(trip_date) = $year"); $sql_miles_driven = mysqli_query($mysqli, "SELECT SUM(trip_miles) AS total_miles FROM trips WHERE YEAR(trip_date) = $year");
$row = mysqli_fetch_array($sql_miles_driven); $row = mysqli_fetch_assoc($sql_miles_driven);
$total_miles = floatval($row['total_miles']); $total_miles = floatval($row['total_miles']);
if ($config_module_enable_ticketing && $config_module_enable_accounting) { if ($config_module_enable_ticketing && $config_module_enable_accounting) {
$sql_unbilled_tickets = mysqli_query($mysqli, "SELECT COUNT(ticket_id) AS unbilled_tickets FROM tickets WHERE ticket_closed_at IS NOT NULL AND ticket_billable = 1 AND ticket_invoice_id = 0 AND YEAR(ticket_created_at) = $year"); $sql_unbilled_tickets = mysqli_query($mysqli, "SELECT COUNT(ticket_id) AS unbilled_tickets FROM tickets WHERE ticket_closed_at IS NOT NULL AND ticket_billable = 1 AND ticket_invoice_id = 0 AND YEAR(ticket_created_at) = $year");
$row = mysqli_fetch_array($sql_unbilled_tickets); $row = mysqli_fetch_assoc($sql_unbilled_tickets);
$unbilled_tickets = intval($row['unbilled_tickets']); $unbilled_tickets = intval($row['unbilled_tickets']);
} else { } else {
$row = mysqli_fetch_assoc(mysqli_query($mysqli, "SELECT COUNT(recurring_invoice_id) AS recurring_invoices_added FROM recurring_invoices WHERE YEAR(recurring_invoice_created_at) = $year")); $row = mysqli_fetch_assoc(mysqli_query($mysqli, "SELECT COUNT(recurring_invoice_id) AS recurring_invoices_added FROM recurring_invoices WHERE YEAR(recurring_invoice_created_at) = $year"));
@@ -421,7 +421,7 @@ if ($user_config_dashboard_financial_enable == 1) {
<div class="table-responsive"> <div class="table-responsive">
<table class="table"> <table class="table">
<tbody> <tbody>
<?php while ($row = mysqli_fetch_array($sql_accounts)) { <?php while ($row = mysqli_fetch_assoc($sql_accounts)) {
$account_id = intval($row['account_id']); $account_id = intval($row['account_id']);
$account_name = nullable_htmlentities($row['account_name']); $account_name = nullable_htmlentities($row['account_name']);
$opening_balance = floatval($row['opening_balance']); $opening_balance = floatval($row['opening_balance']);
@@ -430,15 +430,15 @@ if ($user_config_dashboard_financial_enable == 1) {
<td><?php echo $account_name; ?></td> <td><?php echo $account_name; ?></td>
<?php <?php
$sql_payments = mysqli_query($mysqli, "SELECT SUM(payment_amount) AS total_payments FROM payments WHERE payment_account_id = $account_id"); $sql_payments = mysqli_query($mysqli, "SELECT SUM(payment_amount) AS total_payments FROM payments WHERE payment_account_id = $account_id");
$row = mysqli_fetch_array($sql_payments); $row = mysqli_fetch_assoc($sql_payments);
$total_payments = floatval($row['total_payments']); $total_payments = floatval($row['total_payments']);
$sql_revenues = mysqli_query($mysqli, "SELECT SUM(revenue_amount) AS total_revenues FROM revenues WHERE revenue_account_id = $account_id"); $sql_revenues = mysqli_query($mysqli, "SELECT SUM(revenue_amount) AS total_revenues FROM revenues WHERE revenue_account_id = $account_id");
$row = mysqli_fetch_array($sql_revenues); $row = mysqli_fetch_assoc($sql_revenues);
$total_revenues = floatval($row['total_revenues']); $total_revenues = floatval($row['total_revenues']);
$sql_expenses = mysqli_query($mysqli, "SELECT SUM(expense_amount) AS total_expenses FROM expenses WHERE expense_account_id = $account_id"); $sql_expenses = mysqli_query($mysqli, "SELECT SUM(expense_amount) AS total_expenses FROM expenses WHERE expense_account_id = $account_id");
$row = mysqli_fetch_array($sql_expenses); $row = mysqli_fetch_assoc($sql_expenses);
$total_expenses = floatval($row['total_expenses']); $total_expenses = floatval($row['total_expenses']);
$balance = $opening_balance + $total_payments + $total_revenues - $total_expenses; $balance = $opening_balance + $total_payments + $total_revenues - $total_expenses;
@@ -477,7 +477,7 @@ if ($user_config_dashboard_financial_enable == 1) {
</tr> </tr>
</thead> </thead>
<tbody> <tbody>
<?php while ($row = mysqli_fetch_array($sql_latest_invoice_payments)) { <?php while ($row = mysqli_fetch_assoc($sql_latest_invoice_payments)) {
$payment_date = nullable_htmlentities($row['payment_date']); $payment_date = nullable_htmlentities($row['payment_date']);
$payment_amount = floatval($row['payment_amount']); $payment_amount = floatval($row['payment_amount']);
$invoice_prefix = nullable_htmlentities($row['invoice_prefix']); $invoice_prefix = nullable_htmlentities($row['invoice_prefix']);
@@ -518,7 +518,7 @@ if ($user_config_dashboard_financial_enable == 1) {
</tr> </tr>
</thead> </thead>
<tbody> <tbody>
<?php while ($row = mysqli_fetch_array($sql_latest_expenses)) { <?php while ($row = mysqli_fetch_assoc($sql_latest_expenses)) {
$expense_date = nullable_htmlentities($row['expense_date']); $expense_date = nullable_htmlentities($row['expense_date']);
$expense_amount = floatval($row['expense_amount']); $expense_amount = floatval($row['expense_amount']);
$vendor_name = nullable_htmlentities($row['vendor_name']); $vendor_name = nullable_htmlentities($row['vendor_name']);
@@ -709,7 +709,7 @@ if ($user_config_dashboard_technical_enable == 1) {
</tr> </tr>
</thead> </thead>
<tbody> <tbody>
<?php while ($row = mysqli_fetch_array($sql_your_tickets)) { <?php while ($row = mysqli_fetch_assoc($sql_your_tickets)) {
$ticket_id = intval($row['ticket_id']); $ticket_id = intval($row['ticket_id']);
$ticket_prefix = nullable_htmlentities($row['ticket_prefix']); $ticket_prefix = nullable_htmlentities($row['ticket_prefix']);
$ticket_number = intval($row['ticket_number']); $ticket_number = intval($row['ticket_number']);
@@ -795,11 +795,11 @@ if ($user_config_dashboard_technical_enable == 1) {
<?php <?php
for ($month = 1; $month <= 12; $month++) { for ($month = 1; $month <= 12; $month++) {
$sql_payments = mysqli_query($mysqli, "SELECT SUM(payment_amount) AS payment_amount_for_month FROM payments, invoices WHERE payment_invoice_id = invoice_id AND YEAR(payment_date) = $year AND MONTH(payment_date) = $month"); $sql_payments = mysqli_query($mysqli, "SELECT SUM(payment_amount) AS payment_amount_for_month FROM payments, invoices WHERE payment_invoice_id = invoice_id AND YEAR(payment_date) = $year AND MONTH(payment_date) = $month");
$row = mysqli_fetch_array($sql_payments); $row = mysqli_fetch_assoc($sql_payments);
$payments_for_month = floatval($row['payment_amount_for_month']); $payments_for_month = floatval($row['payment_amount_for_month']);
$sql_revenues = mysqli_query($mysqli, "SELECT SUM(revenue_amount) AS revenue_amount_for_month FROM revenues WHERE revenue_category_id > 0 AND YEAR(revenue_date) = $year AND MONTH(revenue_date) = $month"); $sql_revenues = mysqli_query($mysqli, "SELECT SUM(revenue_amount) AS revenue_amount_for_month FROM revenues WHERE revenue_category_id > 0 AND YEAR(revenue_date) = $year AND MONTH(revenue_date) = $month");
$row = mysqli_fetch_array($sql_revenues); $row = mysqli_fetch_assoc($sql_revenues);
$revenues_for_month = floatval($row['revenue_amount_for_month']); $revenues_for_month = floatval($row['revenue_amount_for_month']);
$income_for_month = $payments_for_month + $revenues_for_month; $income_for_month = $payments_for_month + $revenues_for_month;
@@ -825,11 +825,11 @@ if ($user_config_dashboard_technical_enable == 1) {
<?php <?php
for ($month = 1; $month <= 12; $month++) { for ($month = 1; $month <= 12; $month++) {
$sql_payments = mysqli_query($mysqli, "SELECT SUM(payment_amount) AS payment_amount_for_month FROM payments, invoices WHERE payment_invoice_id = invoice_id AND YEAR(payment_date) = $year-1 AND MONTH(payment_date) = $month"); $sql_payments = mysqli_query($mysqli, "SELECT SUM(payment_amount) AS payment_amount_for_month FROM payments, invoices WHERE payment_invoice_id = invoice_id AND YEAR(payment_date) = $year-1 AND MONTH(payment_date) = $month");
$row = mysqli_fetch_array($sql_payments); $row = mysqli_fetch_assoc($sql_payments);
$payments_for_month = floatval($row['payment_amount_for_month']); $payments_for_month = floatval($row['payment_amount_for_month']);
$sql_revenues = mysqli_query($mysqli, "SELECT SUM(revenue_amount) AS revenue_amount_for_month FROM revenues WHERE revenue_category_id > 0 AND YEAR(revenue_date) = $year-1 AND MONTH(revenue_date) = $month"); $sql_revenues = mysqli_query($mysqli, "SELECT SUM(revenue_amount) AS revenue_amount_for_month FROM revenues WHERE revenue_category_id > 0 AND YEAR(revenue_date) = $year-1 AND MONTH(revenue_date) = $month");
$row = mysqli_fetch_array($sql_revenues); $row = mysqli_fetch_assoc($sql_revenues);
$revenues_for_month = floatval($row['revenue_amount_for_month']); $revenues_for_month = floatval($row['revenue_amount_for_month']);
$income_for_month = $payments_for_month + $revenues_for_month; $income_for_month = $payments_for_month + $revenues_for_month;
@@ -856,7 +856,7 @@ if ($user_config_dashboard_technical_enable == 1) {
$largest_invoice_month = 0; $largest_invoice_month = 0;
for ($month = 1; $month <= 12; $month++) { for ($month = 1; $month <= 12; $month++) {
$sql_projected = mysqli_query($mysqli, "SELECT SUM(invoice_amount) AS invoice_amount_for_month FROM invoices WHERE YEAR(invoice_due) = $year AND MONTH(invoice_due) = $month AND invoice_status != 'Cancelled' AND invoice_status != 'Draft' AND invoice_status != 'Non-Billable'"); $sql_projected = mysqli_query($mysqli, "SELECT SUM(invoice_amount) AS invoice_amount_for_month FROM invoices WHERE YEAR(invoice_due) = $year AND MONTH(invoice_due) = $month AND invoice_status != 'Cancelled' AND invoice_status != 'Draft' AND invoice_status != 'Non-Billable'");
$row = mysqli_fetch_array($sql_projected); $row = mysqli_fetch_assoc($sql_projected);
$invoice_for_month = floatval($row['invoice_amount_for_month']); $invoice_for_month = floatval($row['invoice_amount_for_month']);
if ($invoice_for_month > 0 && $invoice_for_month > $largest_invoice_month) { if ($invoice_for_month > 0 && $invoice_for_month > $largest_invoice_month) {
@@ -882,7 +882,7 @@ if ($user_config_dashboard_technical_enable == 1) {
$largest_expense_month = 0; $largest_expense_month = 0;
for ($month = 1; $month <= 12; $month++) { for ($month = 1; $month <= 12; $month++) {
$sql_expenses = mysqli_query($mysqli, "SELECT SUM(expense_amount) AS expense_amount_for_month FROM expenses WHERE YEAR(expense_date) = $year AND MONTH(expense_date) = $month AND expense_vendor_id > 0"); $sql_expenses = mysqli_query($mysqli, "SELECT SUM(expense_amount) AS expense_amount_for_month FROM expenses WHERE YEAR(expense_date) = $year AND MONTH(expense_date) = $month AND expense_vendor_id > 0");
$row = mysqli_fetch_array($sql_expenses); $row = mysqli_fetch_assoc($sql_expenses);
$expenses_for_month = floatval($row['expense_amount_for_month']); $expenses_for_month = floatval($row['expense_amount_for_month']);
if ($expenses_for_month > 0 && $expenses_for_month > $largest_expense_month) { if ($expenses_for_month > 0 && $expenses_for_month > $largest_expense_month) {
@@ -944,7 +944,7 @@ if ($user_config_dashboard_technical_enable == 1) {
$largest_trip_miles_month = 0; $largest_trip_miles_month = 0;
for ($month = 1; $month <= 12; $month++) { for ($month = 1; $month <= 12; $month++) {
$sql_trips = mysqli_query($mysqli, "SELECT SUM(trip_miles) AS trip_miles_for_month FROM trips WHERE YEAR(trip_date) = $year AND MONTH(trip_date) = $month"); $sql_trips = mysqli_query($mysqli, "SELECT SUM(trip_miles) AS trip_miles_for_month FROM trips WHERE YEAR(trip_date) = $year AND MONTH(trip_date) = $month");
$row = mysqli_fetch_array($sql_trips); $row = mysqli_fetch_assoc($sql_trips);
$trip_miles_for_month = floatval($row['trip_miles_for_month']); $trip_miles_for_month = floatval($row['trip_miles_for_month']);
if ($trip_miles_for_month > 0 && $trip_miles_for_month > $largest_trip_miles_month) { if ($trip_miles_for_month > 0 && $trip_miles_for_month > $largest_trip_miles_month) {
@@ -991,13 +991,13 @@ if ($user_config_dashboard_technical_enable == 1) {
<?php <?php
mysqli_query($mysqli, "CREATE TEMPORARY TABLE TopCategories SELECT category_name, category_id, SUM(invoice_amount) AS total_income FROM categories, invoices WHERE invoice_category_id = category_id AND invoice_status = 'Paid' AND YEAR(invoice_date) = $year GROUP BY category_name, category_id ORDER BY total_income DESC LIMIT 5"); mysqli_query($mysqli, "CREATE TEMPORARY TABLE TopCategories SELECT category_name, category_id, SUM(invoice_amount) AS total_income FROM categories, invoices WHERE invoice_category_id = category_id AND invoice_status = 'Paid' AND YEAR(invoice_date) = $year GROUP BY category_name, category_id ORDER BY total_income DESC LIMIT 5");
$sql_categories = mysqli_query($mysqli, "SELECT category_name FROM TopCategories"); $sql_categories = mysqli_query($mysqli, "SELECT category_name FROM TopCategories");
while ($row = mysqli_fetch_array($sql_categories)) { while ($row = mysqli_fetch_assoc($sql_categories)) {
$category_name = json_encode($row['category_name']); $category_name = json_encode($row['category_name']);
echo "$category_name,"; echo "$category_name,";
} }
$sql_other_categories = mysqli_query($mysqli, "SELECT SUM(invoices.invoice_amount) AS other_income FROM categories LEFT JOIN TopCategories ON categories.category_id = TopCategories.category_id INNER JOIN invoices ON categories.category_id = invoices.invoice_category_id WHERE TopCategories.category_id IS NULL AND invoice_status = 'Paid' AND YEAR(invoice_date) = $year"); $sql_other_categories = mysqli_query($mysqli, "SELECT SUM(invoices.invoice_amount) AS other_income FROM categories LEFT JOIN TopCategories ON categories.category_id = TopCategories.category_id INNER JOIN invoices ON categories.category_id = invoices.invoice_category_id WHERE TopCategories.category_id IS NULL AND invoice_status = 'Paid' AND YEAR(invoice_date) = $year");
$row = mysqli_fetch_array($sql_other_categories); $row = mysqli_fetch_assoc($sql_other_categories);
$other_income = floatval($row['other_income']); $other_income = floatval($row['other_income']);
if ($other_income > 0) { if ($other_income > 0) {
echo "'Others',"; echo "'Others',";
@@ -1008,7 +1008,7 @@ if ($user_config_dashboard_technical_enable == 1) {
data: [ data: [
<?php <?php
$sql_categories = mysqli_query($mysqli, "SELECT total_income FROM TopCategories"); $sql_categories = mysqli_query($mysqli, "SELECT total_income FROM TopCategories");
while ($row = mysqli_fetch_array($sql_categories)) { while ($row = mysqli_fetch_assoc($sql_categories)) {
$total_income = floatval($row['total_income']); $total_income = floatval($row['total_income']);
echo "$total_income,"; echo "$total_income,";
} }
@@ -1020,7 +1020,7 @@ if ($user_config_dashboard_technical_enable == 1) {
backgroundColor: [ backgroundColor: [
<?php <?php
$sql_categories = mysqli_query($mysqli, "SELECT category_color FROM TopCategories JOIN categories ON TopCategories.category_id = categories.category_id"); $sql_categories = mysqli_query($mysqli, "SELECT category_color FROM TopCategories JOIN categories ON TopCategories.category_id = categories.category_id");
while ($row = mysqli_fetch_array($sql_categories)) { while ($row = mysqli_fetch_assoc($sql_categories)) {
$category_color = json_encode($row['category_color']); $category_color = json_encode($row['category_color']);
echo "$category_color,"; echo "$category_color,";
} }
@@ -1056,13 +1056,13 @@ if ($user_config_dashboard_technical_enable == 1) {
<?php <?php
mysqli_query($mysqli, "CREATE TEMPORARY TABLE TopExpenseCategories SELECT category_name, category_id, SUM(expense_amount) AS total_expense FROM categories, expenses WHERE expense_category_id = category_id AND expense_vendor_id > 0 AND YEAR(expense_date) = $year GROUP BY category_name, category_id ORDER BY total_expense DESC LIMIT 5"); mysqli_query($mysqli, "CREATE TEMPORARY TABLE TopExpenseCategories SELECT category_name, category_id, SUM(expense_amount) AS total_expense FROM categories, expenses WHERE expense_category_id = category_id AND expense_vendor_id > 0 AND YEAR(expense_date) = $year GROUP BY category_name, category_id ORDER BY total_expense DESC LIMIT 5");
$sql_categories = mysqli_query($mysqli, "SELECT category_name FROM TopExpenseCategories"); $sql_categories = mysqli_query($mysqli, "SELECT category_name FROM TopExpenseCategories");
while ($row = mysqli_fetch_array($sql_categories)) { while ($row = mysqli_fetch_assoc($sql_categories)) {
$category_name = json_encode($row['category_name']); $category_name = json_encode($row['category_name']);
echo "$category_name,"; echo "$category_name,";
} }
$sql_other_categories = mysqli_query($mysqli, "SELECT SUM(expenses.expense_amount) AS other_expense FROM categories LEFT JOIN TopExpenseCategories ON categories.category_id = TopExpenseCategories.category_id INNER JOIN expenses ON categories.category_id = expenses.expense_category_id WHERE TopExpenseCategories.category_id IS NULL AND expense_vendor_id > 0 AND YEAR(expense_date) = $year"); $sql_other_categories = mysqli_query($mysqli, "SELECT SUM(expenses.expense_amount) AS other_expense FROM categories LEFT JOIN TopExpenseCategories ON categories.category_id = TopExpenseCategories.category_id INNER JOIN expenses ON categories.category_id = expenses.expense_category_id WHERE TopExpenseCategories.category_id IS NULL AND expense_vendor_id > 0 AND YEAR(expense_date) = $year");
$row = mysqli_fetch_array($sql_other_categories); $row = mysqli_fetch_assoc($sql_other_categories);
$other_expense = floatval($row['other_expense']); $other_expense = floatval($row['other_expense']);
if ($other_expense > 0) { if ($other_expense > 0) {
echo "'Others',"; echo "'Others',";
@@ -1073,7 +1073,7 @@ if ($user_config_dashboard_technical_enable == 1) {
data: [ data: [
<?php <?php
$sql_categories = mysqli_query($mysqli, "SELECT total_expense FROM TopExpenseCategories"); $sql_categories = mysqli_query($mysqli, "SELECT total_expense FROM TopExpenseCategories");
while ($row = mysqli_fetch_array($sql_categories)) { while ($row = mysqli_fetch_assoc($sql_categories)) {
$total_expense = floatval($row['total_expense']); $total_expense = floatval($row['total_expense']);
echo "$total_expense,"; echo "$total_expense,";
} }
@@ -1085,7 +1085,7 @@ if ($user_config_dashboard_technical_enable == 1) {
backgroundColor: [ backgroundColor: [
<?php <?php
$sql_categories = mysqli_query($mysqli, "SELECT category_color FROM TopExpenseCategories JOIN categories ON TopExpenseCategories.category_id = categories.category_id"); $sql_categories = mysqli_query($mysqli, "SELECT category_color FROM TopExpenseCategories JOIN categories ON TopExpenseCategories.category_id = categories.category_id");
while ($row = mysqli_fetch_array($sql_categories)) { while ($row = mysqli_fetch_assoc($sql_categories)) {
$category_color = json_encode($row['category_color']); $category_color = json_encode($row['category_color']);
echo "$category_color,"; echo "$category_color,";
} }
@@ -1121,13 +1121,13 @@ if ($user_config_dashboard_technical_enable == 1) {
<?php <?php
mysqli_query($mysqli, "CREATE TEMPORARY TABLE TopVendors SELECT vendor_name, vendor_id, SUM(expense_amount) AS total_expense FROM vendors, expenses WHERE expense_vendor_id = vendor_id AND YEAR(expense_date) = $year GROUP BY vendor_name, vendor_id ORDER BY total_expense DESC LIMIT 5"); mysqli_query($mysqli, "CREATE TEMPORARY TABLE TopVendors SELECT vendor_name, vendor_id, SUM(expense_amount) AS total_expense FROM vendors, expenses WHERE expense_vendor_id = vendor_id AND YEAR(expense_date) = $year GROUP BY vendor_name, vendor_id ORDER BY total_expense DESC LIMIT 5");
$sql_vendors = mysqli_query($mysqli, "SELECT vendor_name FROM TopVendors"); $sql_vendors = mysqli_query($mysqli, "SELECT vendor_name FROM TopVendors");
while ($row = mysqli_fetch_array($sql_vendors)) { while ($row = mysqli_fetch_assoc($sql_vendors)) {
$vendor_name = json_encode($row['vendor_name']); $vendor_name = json_encode($row['vendor_name']);
echo "$vendor_name,"; echo "$vendor_name,";
} }
$sql_other_vendors = mysqli_query($mysqli, "SELECT SUM(expenses.expense_amount) AS other_expense FROM vendors LEFT JOIN TopVendors ON vendors.vendor_id = TopVendors.vendor_id INNER JOIN expenses ON vendors.vendor_id = expenses.expense_vendor_id WHERE TopVendors.vendor_id IS NULL AND YEAR(expense_date) = $year"); $sql_other_vendors = mysqli_query($mysqli, "SELECT SUM(expenses.expense_amount) AS other_expense FROM vendors LEFT JOIN TopVendors ON vendors.vendor_id = TopVendors.vendor_id INNER JOIN expenses ON vendors.vendor_id = expenses.expense_vendor_id WHERE TopVendors.vendor_id IS NULL AND YEAR(expense_date) = $year");
$row = mysqli_fetch_array($sql_other_vendors); $row = mysqli_fetch_assoc($sql_other_vendors);
$other_expense = floatval($row['other_expense']); $other_expense = floatval($row['other_expense']);
if ($other_expense > 0) { if ($other_expense > 0) {
echo "'Others',"; echo "'Others',";
@@ -1138,7 +1138,7 @@ if ($user_config_dashboard_technical_enable == 1) {
data: [ data: [
<?php <?php
$sql_vendors = mysqli_query($mysqli, "SELECT total_expense FROM TopVendors"); $sql_vendors = mysqli_query($mysqli, "SELECT total_expense FROM TopVendors");
while ($row = mysqli_fetch_array($sql_vendors)) { while ($row = mysqli_fetch_assoc($sql_vendors)) {
$total_expense = floatval($row['total_expense']); $total_expense = floatval($row['total_expense']);
echo "$total_expense,"; echo "$total_expense,";
} }
@@ -1150,7 +1150,7 @@ if ($user_config_dashboard_technical_enable == 1) {
backgroundColor: [ backgroundColor: [
<?php <?php
$sql_vendors = mysqli_query($mysqli, "SELECT vendor_id FROM TopVendors"); $sql_vendors = mysqli_query($mysqli, "SELECT vendor_id FROM TopVendors");
while ($row = mysqli_fetch_array($sql_vendors)) { while ($row = mysqli_fetch_assoc($sql_vendors)) {
// Generate random color for each vendor // Generate random color for each vendor
echo "'#" . substr(md5(rand()), 0, 6) . "',"; echo "'#" . substr(md5(rand()), 0, 6) . "',";
} }

View File

@@ -30,7 +30,7 @@ if (mysqli_num_rows($sql_document) == 0) {
exit(); exit();
} }
$row = mysqli_fetch_array($sql_document); $row = mysqli_fetch_assoc($sql_document);
$folder_name = nullable_htmlentities($row['folder_name']); $folder_name = nullable_htmlentities($row['folder_name']);
$document_name = nullable_htmlentities($row['document_name']); $document_name = nullable_htmlentities($row['document_name']);
@@ -115,7 +115,7 @@ $page_title = $row['document_name'];
<div class="float-right"> <div class="float-right">
<div> <div>
Date: Date:
<strong><?= date('Y-m-d', strtotime($document_created_at)); ?></strong> <strong><?= date('Y-m-d', strtotime($document_updated_at)); ?></strong>
</div> </div>
<?php if($document_created_by_name) { ?> <?php if($document_created_by_name) { ?>
<div> <div>
@@ -150,7 +150,7 @@ $page_title = $row['document_name'];
$document_version_count = 1; // Initialize the document version counter $document_version_count = 1; // Initialize the document version counter
while ($row = mysqli_fetch_array($sql_document_versions)) { while ($row = mysqli_fetch_assoc($sql_document_versions)) {
$document_version_id = intval($row['document_version_id']); $document_version_id = intval($row['document_version_id']);
$document_version_name = nullable_htmlentities($row['document_version_name']); $document_version_name = nullable_htmlentities($row['document_version_name']);
$document_version_description = nullable_htmlentities($row['document_version_description']); $document_version_description = nullable_htmlentities($row['document_version_description']);
@@ -216,7 +216,7 @@ $page_title = $row['document_name'];
$linked_files = array(); $linked_files = array();
while ($row = mysqli_fetch_array($sql_files)) { while ($row = mysqli_fetch_assoc($sql_files)) {
$file_id = intval($row['file_id']); $file_id = intval($row['file_id']);
$folder_id = intval($row['file_folder_id']); $folder_id = intval($row['file_folder_id']);
$file_name = nullable_htmlentities($row['file_name']); $file_name = nullable_htmlentities($row['file_name']);
@@ -249,7 +249,7 @@ $page_title = $row['document_name'];
$linked_contacts = array(); $linked_contacts = array();
while ($row = mysqli_fetch_array($sql_contacts)) { while ($row = mysqli_fetch_assoc($sql_contacts)) {
$contact_id = intval($row['contact_id']); $contact_id = intval($row['contact_id']);
$contact_name = nullable_htmlentities($row['contact_name']); $contact_name = nullable_htmlentities($row['contact_name']);
@@ -283,7 +283,7 @@ $page_title = $row['document_name'];
$linked_assets = array(); $linked_assets = array();
while ($row = mysqli_fetch_array($sql_assets)) { while ($row = mysqli_fetch_assoc($sql_assets)) {
$asset_id = intval($row['asset_id']); $asset_id = intval($row['asset_id']);
$asset_name = nullable_htmlentities($row['asset_name']); $asset_name = nullable_htmlentities($row['asset_name']);
@@ -319,7 +319,7 @@ $page_title = $row['document_name'];
$linked_software = array(); $linked_software = array();
while ($row = mysqli_fetch_array($sql_software)) { while ($row = mysqli_fetch_assoc($sql_software)) {
$software_id = intval($row['software_id']); $software_id = intval($row['software_id']);
$software_name = nullable_htmlentities($row['software_name']); $software_name = nullable_htmlentities($row['software_name']);
@@ -351,7 +351,7 @@ $page_title = $row['document_name'];
$associated_vendors = array(); $associated_vendors = array();
while ($row = mysqli_fetch_array($sql_vendors)) { while ($row = mysqli_fetch_assoc($sql_vendors)) {
$vendor_id = intval($row['vendor_id']); $vendor_id = intval($row['vendor_id']);
$vendor_name = nullable_htmlentities($row['vendor_name']); $vendor_name = nullable_htmlentities($row['vendor_name']);
@@ -400,7 +400,7 @@ $page_title = $row['document_name'];
ORDER BY document_version_created_at DESC" ORDER BY document_version_created_at DESC"
); );
while ($row = mysqli_fetch_array($sql_document_versions)) { while ($row = mysqli_fetch_assoc($sql_document_versions)) {
$document_version_id = intval($row['document_version_id']); $document_version_id = intval($row['document_version_id']);
$document_version_name = nullable_htmlentities($row['document_version_name']); $document_version_name = nullable_htmlentities($row['document_version_name']);
$document_version_description = nullable_htmlentities($row['document_version_description']); $document_version_description = nullable_htmlentities($row['document_version_description']);

View File

@@ -123,7 +123,7 @@ $num_rows = mysqli_fetch_row(mysqli_query($mysqli, "SELECT FOUND_ROWS()"));
$access_permission_query $access_permission_query
ORDER BY client_name ASC ORDER BY client_name ASC
"); ");
while ($row = mysqli_fetch_array($sql_clients_filter)) { while ($row = mysqli_fetch_assoc($sql_clients_filter)) {
$client_id = intval($row['client_id']); $client_id = intval($row['client_id']);
$client_name = nullable_htmlentities($row['client_name']); $client_name = nullable_htmlentities($row['client_name']);
?> ?>
@@ -230,7 +230,7 @@ $num_rows = mysqli_fetch_row(mysqli_query($mysqli, "SELECT FOUND_ROWS()"));
<tbody> <tbody>
<?php <?php
while ($row = mysqli_fetch_array($sql)) { while ($row = mysqli_fetch_assoc($sql)) {
$domain_id = intval($row['domain_id']); $domain_id = intval($row['domain_id']);
$domain_name = nullable_htmlentities($row['domain_name']); $domain_name = nullable_htmlentities($row['domain_name']);
$domain_description = nullable_htmlentities($row['domain_description']); $domain_description = nullable_htmlentities($row['domain_description']);

View File

@@ -145,7 +145,7 @@ $num_rows = mysqli_fetch_row(mysqli_query($mysqli, "SELECT FOUND_ROWS()"));
<?php <?php
$sql_vendors_filter = mysqli_query($mysqli, "SELECT vendor_id, vendor_name FROM vendors WHERE EXISTS (SELECT 1 FROM expenses WHERE expense_vendor_id = vendor_id) ORDER BY vendor_name ASC"); $sql_vendors_filter = mysqli_query($mysqli, "SELECT vendor_id, vendor_name FROM vendors WHERE EXISTS (SELECT 1 FROM expenses WHERE expense_vendor_id = vendor_id) ORDER BY vendor_name ASC");
while ($row = mysqli_fetch_array($sql_vendors_filter)) { while ($row = mysqli_fetch_assoc($sql_vendors_filter)) {
$vendor_id = intval($row['vendor_id']); $vendor_id = intval($row['vendor_id']);
$vendor_name = nullable_htmlentities($row['vendor_name']); $vendor_name = nullable_htmlentities($row['vendor_name']);
?> ?>
@@ -165,7 +165,7 @@ $num_rows = mysqli_fetch_row(mysqli_query($mysqli, "SELECT FOUND_ROWS()"));
<?php <?php
$sql_categories_filter = mysqli_query($mysqli, "SELECT category_id, category_name FROM categories WHERE category_type = 'Expense' AND EXISTS (SELECT 1 FROM expenses WHERE expense_category_id = category_id) ORDER BY category_name ASC"); $sql_categories_filter = mysqli_query($mysqli, "SELECT category_id, category_name FROM categories WHERE category_type = 'Expense' AND EXISTS (SELECT 1 FROM expenses WHERE expense_category_id = category_id) ORDER BY category_name ASC");
while ($row = mysqli_fetch_array($sql_categories_filter)) { while ($row = mysqli_fetch_assoc($sql_categories_filter)) {
$category_id = intval($row['category_id']); $category_id = intval($row['category_id']);
$category_name = nullable_htmlentities($row['category_name']); $category_name = nullable_htmlentities($row['category_name']);
?> ?>
@@ -185,7 +185,7 @@ $num_rows = mysqli_fetch_row(mysqli_query($mysqli, "SELECT FOUND_ROWS()"));
<?php <?php
$sql_accounts_filter = mysqli_query($mysqli, "SELECT account_id, account_name FROM accounts WHERE EXISTS (SELECT 1 FROM expenses WHERE expense_account_id = account_id) ORDER BY account_name ASC"); $sql_accounts_filter = mysqli_query($mysqli, "SELECT account_id, account_name FROM accounts WHERE EXISTS (SELECT 1 FROM expenses WHERE expense_account_id = account_id) ORDER BY account_name ASC");
while ($row = mysqli_fetch_array($sql_accounts_filter)) { while ($row = mysqli_fetch_assoc($sql_accounts_filter)) {
$account_id = intval($row['account_id']); $account_id = intval($row['account_id']);
$account_name = nullable_htmlentities($row['account_name']); $account_name = nullable_htmlentities($row['account_name']);
?> ?>
@@ -251,7 +251,7 @@ $num_rows = mysqli_fetch_row(mysqli_query($mysqli, "SELECT FOUND_ROWS()"));
<tbody> <tbody>
<?php <?php
while ($row = mysqli_fetch_array($sql)) { while ($row = mysqli_fetch_assoc($sql)) {
$expense_id = intval($row['expense_id']); $expense_id = intval($row['expense_id']);
$expense_date = nullable_htmlentities($row['expense_date']); $expense_date = nullable_htmlentities($row['expense_date']);
$expense_amount = floatval($row['expense_amount']); $expense_amount = floatval($row['expense_amount']);

View File

@@ -23,6 +23,13 @@ if (!empty($_GET['view'])) {
$view = 0; $view = 0;
} }
// Folder tree expanded state: 1 = expand all, 0 = collapsed (default)
if (isset($_GET['folders_expanded'])) {
$folders_expanded = intval($_GET['folders_expanded']);
} else {
$folders_expanded = 0;
}
if (!isset($q)) { if (!isset($q)) {
$q = ''; $q = '';
} }
@@ -72,38 +79,83 @@ function is_ancestor_folder($folder_id, $current_folder_id, $client_id) {
} }
} }
function display_folders($parent_folder_id, $client_id, $indent = 0) { function display_folders($parent_folder_id, $client_id, $indent = 0, $render_root = false) {
global $mysqli, $get_folder_id, $session_user_role; global $mysqli, $get_folder_id, $session_user_role, $archive_query, $archived, $num_root_items, $folders_expanded;
$sql_folders = mysqli_query($mysqli, "SELECT * FROM folders WHERE parent_folder = $parent_folder_id AND folder_client_id = $client_id ORDER BY folder_name ASC"); // Always render root (only once)
while ($row = mysqli_fetch_array($sql_folders)) { if ($parent_folder_id == 0 && $indent == 0) {
echo '<li class="nav-item">';
echo '<a class="nav-link ' . ($get_folder_id == 0 ? 'active' : '') . '"';
echo ' href="?client_id=' . $client_id . '&folder_id=0&archived=' . $archived . '&folders_expanded=' . $folders_expanded . '">';
echo '/';
if ($num_root_items > 0) {
echo "<span class='badge badge-pill badge-dark float-right mt-1'>$num_root_items</span>";
}
echo '</a>';
echo '</li>';
}
$sql_folders = mysqli_query(
$mysqli,
"SELECT * FROM folders
WHERE parent_folder = $parent_folder_id
AND folder_client_id = $client_id
ORDER BY folder_name ASC"
);
while ($row = mysqli_fetch_assoc($sql_folders)) {
$folder_id = intval($row['folder_id']); $folder_id = intval($row['folder_id']);
$folder_name = nullable_htmlentities($row['folder_name']); $folder_name = nullable_htmlentities($row['folder_name']);
// Count files in folder $row_files = mysqli_fetch_assoc(mysqli_query(
$row_files = mysqli_fetch_assoc(mysqli_query($mysqli, "SELECT COUNT('file_id') AS num FROM files WHERE file_folder_id = $folder_id AND file_client_id = $client_id AND file_archived_at IS NULL")); $mysqli,
"SELECT COUNT('file_id') AS num
FROM files
WHERE file_folder_id = $folder_id
AND file_client_id = $client_id
AND file_$archive_query"
));
$num_files = intval($row_files['num']); $num_files = intval($row_files['num']);
// Count documents in folder $row_docs = mysqli_fetch_assoc(mysqli_query(
$row_docs = mysqli_fetch_assoc(mysqli_query($mysqli, "SELECT COUNT('document_id') AS num FROM documents WHERE document_folder_id = $folder_id AND document_client_id = $client_id AND document_archived_at IS NULL")); $mysqli,
"SELECT COUNT('document_id') AS num
FROM documents
WHERE document_folder_id = $folder_id
AND document_client_id = $client_id
AND document_$archive_query"
));
$num_docs = intval($row_docs['num']); $num_docs = intval($row_docs['num']);
$num_total = $num_files + $num_docs; $num_total = $num_files + $num_docs;
// Count subfolders $subfolder_result = mysqli_query(
$subfolder_result = mysqli_query($mysqli, "SELECT COUNT(*) AS count FROM folders WHERE parent_folder = $folder_id AND folder_client_id = $client_id"); $mysqli,
"SELECT COUNT(*) AS count
FROM folders
WHERE parent_folder = $folder_id
AND folder_client_id = $client_id"
);
$subfolder_count = intval(mysqli_fetch_assoc($subfolder_result)['count']); $subfolder_count = intval(mysqli_fetch_assoc($subfolder_result)['count']);
// Active or ancestor of active folder = on active path
$on_active_path = ($get_folder_id == $folder_id) || is_ancestor_folder($folder_id, $get_folder_id, $client_id);
// Option C: indent with padding (no AdminLTE sidebar CSS required)
// Tune these numbers if you want tighter/looser indent
$indent_px = 12 * $indent; // 12px per level
echo '<li class="nav-item">'; echo '<li class="nav-item">';
echo '<div class="row">'; echo '<div class="row">';
echo '<div class="col-10">'; echo '<div class="col-10">';
echo '<a class="nav-link ';
if ($get_folder_id == $folder_id) { echo "active"; }
echo '" href="?client_id=' . $client_id . '&folder_id=' . $folder_id . '">';
echo str_repeat('&nbsp;', $indent * 4); echo '<a class="nav-link ' . ($get_folder_id == $folder_id ? 'active' : '') . '"';
echo ' style="padding-left: ' . (12 + $indent_px) . 'px;"';
echo ' href="?client_id=' . $client_id . '&folder_id=' . $folder_id . '&archived=' . $archived . '&folders_expanded=' . $folders_expanded . '">';
if ($get_folder_id == $folder_id || is_ancestor_folder($folder_id, $get_folder_id, $client_id)) { if ($on_active_path) {
echo '<i class="fas fa-fw fa-folder-open"></i>'; echo '<i class="fas fa-fw fa-folder-open"></i>';
} else { } else {
echo '<i class="fas fa-fw fa-folder"></i>'; echo '<i class="fas fa-fw fa-folder"></i>';
@@ -111,12 +163,19 @@ function display_folders($parent_folder_id, $client_id, $indent = 0) {
echo ' ' . $folder_name; echo ' ' . $folder_name;
if ($subfolder_count > 0) {
$is_expanded = $folders_expanded || $on_active_path;
echo '<i class="fas fa-chevron-' . ($is_expanded ? 'down' : 'right') . ' text-muted ml-2"></i>';
}
if ($num_total > 0) { if ($num_total > 0) {
echo "<span class='badge badge-pill badge-dark float-right mt-1'>$num_total</span>"; echo "<span class='badge badge-pill badge-dark float-right mt-1'>$num_total</span>";
} }
echo '</a>'; echo '</a>';
echo '</div>'; echo '</div>'; // col-10
echo '<div class="col-2">'; echo '<div class="col-2">';
?> ?>
<div class="dropdown"> <div class="dropdown">
@@ -128,9 +187,7 @@ function display_folders($parent_folder_id, $client_id, $indent = 0) {
data-modal-url="modals/folder/folder_rename.php?id=<?= $folder_id ?>"> data-modal-url="modals/folder/folder_rename.php?id=<?= $folder_id ?>">
<i class="fas fa-fw fa-edit mr-2"></i>Rename <i class="fas fa-fw fa-edit mr-2"></i>Rename
</a> </a>
<?php <?php if ($session_user_role == 3 && $num_total == 0 && $subfolder_count == 0) { ?>
// Only show delete if admin and no contents and no subfolders
if ($session_user_role == 3 && $num_total == 0 && $subfolder_count == 0) { ?>
<div class="dropdown-divider"></div> <div class="dropdown-divider"></div>
<a class="dropdown-item text-danger text-bold confirm-link" href="post.php?delete_folder=<?php echo $folder_id; ?>"> <a class="dropdown-item text-danger text-bold confirm-link" href="post.php?delete_folder=<?php echo $folder_id; ?>">
<i class="fas fa-fw fa-trash mr-2"></i>Delete <i class="fas fa-fw fa-trash mr-2"></i>Delete
@@ -139,10 +196,11 @@ function display_folders($parent_folder_id, $client_id, $indent = 0) {
</div> </div>
</div> </div>
<?php <?php
echo '</div>'; echo '</div>'; // col-2
echo '</div>'; echo '</div>'; // row
if ($subfolder_count > 0) { // Collapsed by default: ONLY render children if folder is on active path
if ($subfolder_count > 0 && ($folders_expanded || $on_active_path)) {
echo '<ul class="nav nav-pills flex-column bg-light">'; echo '<ul class="nav nav-pills flex-column bg-light">';
display_folders($folder_id, $client_id, $indent + 1); display_folders($folder_id, $client_id, $indent + 1);
echo '</ul>'; echo '</ul>';
@@ -152,6 +210,7 @@ function display_folders($parent_folder_id, $client_id, $indent = 0) {
} }
} }
// --------------------------------------------- // ---------------------------------------------
// DATA LOAD // DATA LOAD
// view=1 (thumbs) uses original files-only query // view=1 (thumbs) uses original files-only query
@@ -172,7 +231,7 @@ if ($view == 1) {
"SELECT SQL_CALC_FOUND_ROWS * FROM files "SELECT SQL_CALC_FOUND_ROWS * FROM files
LEFT JOIN users ON file_created_by = user_id LEFT JOIN users ON file_created_by = user_id
WHERE file_client_id = $client_id WHERE file_client_id = $client_id
AND file_archived_at IS NULL AND file_$archive_query
AND (file_name LIKE '%$q%' OR file_ext LIKE '%$q%' OR file_description LIKE '%$q%') AND (file_name LIKE '%$q%' OR file_ext LIKE '%$q%' OR file_description LIKE '%$q%')
$query_images $query_images
ORDER BY file_name ASC ORDER BY file_name ASC
@@ -185,7 +244,7 @@ if ($view == 1) {
LEFT JOIN users ON file_created_by = user_id LEFT JOIN users ON file_created_by = user_id
WHERE file_client_id = $client_id WHERE file_client_id = $client_id
AND file_folder_id = $folder_id AND file_folder_id = $folder_id
AND file_archived_at IS NULL AND file_$archive_query
AND (file_name LIKE '%$q%' OR file_ext LIKE '%$q%' OR file_description LIKE '%$q%') AND (file_name LIKE '%$q%' OR file_ext LIKE '%$q%' OR file_description LIKE '%$q%')
$query_images $query_images
ORDER BY file_name ASC ORDER BY file_name ASC
@@ -228,7 +287,7 @@ if ($view == 1) {
FROM files FROM files
LEFT JOIN users ON file_created_by = user_id LEFT JOIN users ON file_created_by = user_id
WHERE file_client_id = $client_id WHERE file_client_id = $client_id
AND file_archived_at IS NULL AND file_$archive_query
$file_folder_snippet $file_folder_snippet
$file_search_snippet" $file_search_snippet"
); );
@@ -240,7 +299,7 @@ if ($view == 1) {
FROM documents FROM documents
LEFT JOIN users ON document_created_by = user_id LEFT JOIN users ON document_created_by = user_id
WHERE document_client_id = $client_id WHERE document_client_id = $client_id
AND document_archived_at IS NULL AND document_$archive_query
$doc_folder_snippet $doc_folder_snippet
$doc_search_snippet" $doc_search_snippet"
); );
@@ -256,6 +315,7 @@ if ($view == 1) {
$file_mime_type = nullable_htmlentities($row['file_mime_type']); $file_mime_type = nullable_htmlentities($row['file_mime_type']);
$file_uploaded_by = nullable_htmlentities($row['user_name']); $file_uploaded_by = nullable_htmlentities($row['user_name']);
$file_created_at = nullable_htmlentities($row['file_created_at']); $file_created_at = nullable_htmlentities($row['file_created_at']);
$file_archived_at = $row['file_archived_at'];
// determine icon // determine icon
if ($file_ext == 'pdf') { if ($file_ext == 'pdf') {
@@ -293,6 +353,7 @@ if ($view == 1) {
'size' => $file_size, 'size' => $file_size,
'created_at' => $file_created_at, 'created_at' => $file_created_at,
'created_by' => $file_uploaded_by, 'created_by' => $file_uploaded_by,
'archived_at' => $file_archived_at,
]; ];
} }
@@ -303,6 +364,8 @@ if ($view == 1) {
$document_description = nullable_htmlentities($row['document_description']); $document_description = nullable_htmlentities($row['document_description']);
$document_created_by_name = nullable_htmlentities($row['user_name']); $document_created_by_name = nullable_htmlentities($row['user_name']);
$document_created_at = $row['document_created_at']; $document_created_at = $row['document_created_at'];
$document_updated_at = $row['document_updated_at'];
$document_archived_at = $row['document_archived_at'];
$items[] = [ $items[] = [
'kind' => 'document', 'kind' => 'document',
@@ -311,8 +374,9 @@ if ($view == 1) {
'description' => $document_description, 'description' => $document_description,
'mime' => 'Document', 'mime' => 'Document',
'size' => null, 'size' => null,
'created_at' => $document_created_at, 'updated_at' => $document_updated_at,
'created_by' => $document_created_by_name, 'created_by' => $document_created_by_name,
'archived_at' => $document_archived_at,
]; ];
} }
@@ -356,8 +420,8 @@ if ($view == 1) {
// --------------------------------------------- // ---------------------------------------------
// Root folder count (for "/" badge) // Root folder count (for "/" badge)
// --------------------------------------------- // ---------------------------------------------
$row_root_files = mysqli_fetch_assoc(mysqli_query($mysqli, "SELECT COUNT('file_id') AS num FROM files WHERE file_folder_id = 0 AND file_client_id = $client_id AND file_archived_at IS NULL")); $row_root_files = mysqli_fetch_assoc(mysqli_query($mysqli, "SELECT COUNT('file_id') AS num FROM files WHERE file_folder_id = 0 AND file_client_id = $client_id AND file_$archive_query"));
$row_root_docs = mysqli_fetch_assoc(mysqli_query($mysqli, "SELECT COUNT('document_id') AS num FROM documents WHERE document_folder_id = 0 AND document_client_id = $client_id AND document_archived_at IS NULL")); $row_root_docs = mysqli_fetch_assoc(mysqli_query($mysqli, "SELECT COUNT('document_id') AS num FROM documents WHERE document_folder_id = 0 AND document_client_id = $client_id AND document_$archive_query"));
$num_root_items = intval($row_root_files['num']) + intval($row_root_docs['num']); $num_root_items = intval($row_root_files['num']) + intval($row_root_docs['num']);
?> ?>
@@ -403,15 +467,26 @@ $num_root_items = intval($row_root_files['num']) + intval($row_root_docs['num'])
<!-- Folders --> <!-- Folders -->
<div class="col-md-3 border-right mb-3"> <div class="col-md-3 border-right mb-3">
<h4>Folders</h4> <div class="d-flex align-items-center justify-content-between">
<h4 class="mb-0">Folders</h4>
<?php
$toggle_value = $folders_expanded ? 0 : 1;
$toggle_title = $folders_expanded
? 'Collapse all folders'
: 'Expand all folders';
?>
<a href="?<?= http_build_query(array_merge($_GET, ['folders_expanded' => $toggle_value])) ?>"
class="btn btn-tool"
title="<?= $toggle_title ?>"
aria-label="<?= $toggle_title ?>">
<i class="fas <?= $folders_expanded ? 'fa-chevron-down' : 'fa-chevron-right' ?>"></i>
</a>
</div>
<hr> <hr>
<ul class="nav nav-pills flex-column bg-light"> <ul class="nav nav-pills flex-column bg-light">
<li class="nav-item">
<a class="nav-link <?php if ($get_folder_id == 0) { echo "active"; } ?>"
href="?client_id=<?php echo $client_id; ?>&folder_id=0">
/ <?php if ($num_root_items > 0) { echo "<span class='badge badge-pill badge-dark float-right mt-1'>$num_root_items</span>"; } ?>
</a>
</li>
<?php <?php
// Start folder tree from root // Start folder tree from root
display_folders(0, $client_id); display_folders(0, $client_id);
@@ -424,9 +499,11 @@ $num_root_items = intval($row_root_files['num']) + intval($row_root_docs['num'])
<!-- Search + view toggle --> <!-- Search + view toggle -->
<form autocomplete="off"> <form autocomplete="off">
<input type="hidden" name="client_id" value="<?php echo $client_id; ?>"> <input type="hidden" name="client_id" value="<?= $client_id ?>">
<input type="hidden" name="view" value="<?php echo $view; ?>"> <input type="hidden" name="view" value="<?= $view ?>">
<input type="hidden" name="folder_id" value="<?php echo $get_folder_id; ?>"> <input type="hidden" name="folder_id" value="<?= $get_folder_id ?>">
<input type="hidden" name="archived" value="<?= $archived ?>">
<input type="hidden" name="folders_expanded" value="<?= $folders_expanded ?>">
<div class="row"> <div class="row">
<div class="col-md-5"> <div class="col-md-5">
<div class="input-group mb-3 mb-md-0"> <div class="input-group mb-3 mb-md-0">
@@ -439,10 +516,18 @@ $num_root_items = intval($row_root_files['num']) + intval($row_root_docs['num'])
</div> </div>
</div> </div>
<div class="col-md-7"> <div class="col-md-7">
<div class="btn-group float-right"> <div class="float-right">
<a href="?<?php echo $url_query_strings_sort; ?>&view=0&folder_id=<?php echo $get_folder_id; ?>" class="btn <?php if($view == 0){ echo "btn-primary"; } else { echo "btn-outline-secondary"; } ?>"><i class="fas fa-list-ul"></i></a> <div class="btn-group">
<a href="?<?php echo $url_query_strings_sort; ?>&view=1&folder_id=<?php echo $get_folder_id; ?>" class="btn <?php if($view == 1){ echo "btn-primary"; } else { echo "btn-outline-secondary"; } ?>"><i class="fas fa-th-large"></i></a> <a href="?<?php echo $url_query_strings_sort; ?>&view=0&folder_id=<?php echo $get_folder_id; ?>" class="btn <?php if($view == 0){ echo "btn-primary"; } else { echo "btn-outline-secondary"; } ?>" title="List View"><i class="fas fa-list-ul"></i></a>
<a href="?<?php echo $url_query_strings_sort; ?>&view=1&folder_id=<?php echo $get_folder_id; ?>" class="btn <?php if($view == 1){ echo "btn-primary"; } else { echo "btn-outline-secondary"; } ?>" title="Grid View"><i class="fas fa-th-large"></i></a>
</div>
<div class="btn-group">
<a href="?<?php echo $url_query_strings_sort; ?>&archived=<?php if($archived == 1){ echo 0; } else { echo 1; } ?>"
class="btn btn-<?php if($archived == 1){ echo "primary"; } else { echo "default"; } ?>">
<i class="fa fa-fw fa-archive mr-2"></i>Archived
</a>
</div>
<div class="btn-group">
<div class="dropdown ml-2" id="bulkActionButton" hidden> <div class="dropdown ml-2" id="bulkActionButton" hidden>
<button class="btn btn-secondary dropdown-toggle" type="button" data-toggle="dropdown"> <button class="btn btn-secondary dropdown-toggle" type="button" data-toggle="dropdown">
<i class="fas fa-fw fa-layer-group mr-2"></i>Bulk Action (<span id="selectedCount">0</span>) <i class="fas fa-fw fa-layer-group mr-2"></i>Bulk Action (<span id="selectedCount">0</span>)
@@ -453,14 +538,27 @@ $num_root_items = intval($row_root_files['num']) + intval($row_root_docs['num'])
data-bulk="true"> data-bulk="true">
<i class="fas fa-fw fa-exchange-alt mr-2"></i>Move Files <i class="fas fa-fw fa-exchange-alt mr-2"></i>Move Files
</a> </a>
<?php if ($archived) { ?>
<div class="dropdown-divider"></div>
<button class="dropdown-item text-info"
type="submit" form="bulkActions" name="bulk_restore_files">
<i class="fas fa-fw fa-redo mr-2"></i>Restore Files
</button>
<div class="dropdown-divider"></div> <div class="dropdown-divider"></div>
<button class="dropdown-item text-danger text-bold" <button class="dropdown-item text-danger text-bold"
type="submit" form="bulkActions" name="bulk_delete_files"> type="submit" form="bulkActions" name="bulk_delete_files">
<i class="fas fa-fw fa-trash mr-2"></i>Delete Files <i class="fas fa-fw fa-trash mr-2"></i>Delete Files
</button> </button>
<?php } else { ?>
<div class="dropdown-divider"></div>
<button class="dropdown-item text-danger"
type="submit" form="bulkActions" name="bulk_archive_files">
<i class="fas fa-fw fa-archive mr-2"></i>Archive Files
</button>
<?php } ?>
</div>
</div> </div>
</div> </div>
</div> </div>
</div> </div>
</div> </div>
@@ -470,7 +568,7 @@ $num_root_items = intval($row_root_files['num']) + intval($row_root_docs['num'])
<nav class="mt-3"> <nav class="mt-3">
<ol class="breadcrumb"> <ol class="breadcrumb">
<li class="breadcrumb-item"> <li class="breadcrumb-item">
<a href="?client_id=<?php echo $client_id; ?>&folder_id=0"> <a href="?client_id=<?php echo $client_id; ?>&folder_id=0&archived=<?= $archived ?>">
<i class="fas fa-fw fa-folder mr-2"></i>Root <i class="fas fa-fw fa-folder mr-2"></i>Root
</a> </a>
</li> </li>
@@ -478,7 +576,7 @@ $num_root_items = intval($row_root_files['num']) + intval($row_root_docs['num'])
$bread_crumb_folder_id = $folder['folder_id']; $bread_crumb_folder_id = $folder['folder_id'];
$bread_crumb_folder_name = $folder['folder_name']; ?> $bread_crumb_folder_name = $folder['folder_name']; ?>
<li class="breadcrumb-item"> <li class="breadcrumb-item">
<a href="?client_id=<?php echo $client_id; ?>&folder_id=<?php echo $bread_crumb_folder_id; ?>"> <a href="?client_id=<?= $client_id ?>&folder_id=<?= $bread_crumb_folder_id ?>&archived=<?= $archived ?>&folders_expanded=<?= $folders_expanded ?>">
<i class="fas fa-fw fa-folder-open mr-2"></i><?php echo $bread_crumb_folder_name; ?> <i class="fas fa-fw fa-folder-open mr-2"></i><?php echo $bread_crumb_folder_name; ?>
</a> </a>
</li> </li>
@@ -494,7 +592,7 @@ $num_root_items = intval($row_root_files['num']) + intval($row_root_docs['num'])
<div class="row"> <div class="row">
<?php <?php
$files = []; $files = [];
while ($row = mysqli_fetch_array($sql)) { while ($row = mysqli_fetch_assoc($sql)) {
$file_id = intval($row['file_id']); $file_id = intval($row['file_id']);
$file_name = nullable_htmlentities($row['file_name']); $file_name = nullable_htmlentities($row['file_name']);
$file_reference_name= nullable_htmlentities($row['file_reference_name']); $file_reference_name= nullable_htmlentities($row['file_reference_name']);
@@ -503,6 +601,7 @@ $num_root_items = intval($row_root_files['num']) + intval($row_root_docs['num'])
$file_size_KB = number_format($file_size / 1024); $file_size_KB = number_format($file_size / 1024);
$file_mime_type = nullable_htmlentities($row['file_mime_type']); $file_mime_type = nullable_htmlentities($row['file_mime_type']);
$file_uploaded_by = nullable_htmlentities($row['user_name']); $file_uploaded_by = nullable_htmlentities($row['user_name']);
$file_archived_at = nullable_htmlentities($row['file_archived_at']);
$files[] = [ $files[] = [
'id' => $file_id, 'id' => $file_id,
@@ -538,11 +637,12 @@ $num_root_items = intval($row_root_files['num']) + intval($row_root_docs['num'])
<i class="fas fa-fw fa-exchange-alt mr-2"></i>Move <i class="fas fa-fw fa-exchange-alt mr-2"></i>Move
</a> </a>
<a class="dropdown-item" href="#" data-toggle="modal" data-target="#linkAssetToFileModal<?php echo $file_id; ?>"> <a class="dropdown-item" href="#" data-toggle="modal" data-target="#linkAssetToFileModal<?php echo $file_id; ?>">
<i class="fas fa-fw fa-desktop mr-2"></i>Asset <i class="fas fa-fw fa-desktop mr-2"></i>Link Asset
</a> </a>
<?php if ($file_archived_at) { ?>
<div class="dropdown-divider"></div> <div class="dropdown-divider"></div>
<a class="dropdown-item text-danger confirm-link" href="post.php?archive_file=<?php echo $file_id; ?>"> <a class="dropdown-item text-info" href="post.php?restore_file=<?= $file_id ?>">
<i class="fas fa-fw fa-archive mr-2"></i>Archive <i class="fas fa-fw fa-redo mr-2"></i>Restore
</a> </a>
<?php if ($session_user_role == 3) { ?> <?php if ($session_user_role == 3) { ?>
<div class="dropdown-divider"></div> <div class="dropdown-divider"></div>
@@ -550,6 +650,12 @@ $num_root_items = intval($row_root_files['num']) + intval($row_root_docs['num'])
<i class="fas fa-fw fa-trash mr-2"></i>Delete <i class="fas fa-fw fa-trash mr-2"></i>Delete
</a> </a>
<?php } ?> <?php } ?>
<?php } else { ?>
<div class="dropdown-divider"></div>
<a class="dropdown-item text-danger confirm-link" href="post.php?archive_file=<?= $file_id ?>">
<i class="fas fa-fw fa-archive mr-2"></i>Archive
</a>
<?php } ?>
</div> </div>
</div> </div>
<small class="text-secondary"><?php echo $file_name; ?></small> <small class="text-secondary"><?php echo $file_name; ?></small>
@@ -571,7 +677,6 @@ $num_root_items = intval($row_root_files['num']) + intval($row_root_docs['num'])
<!-- LIST VIEW: unified Files + Documents --> <!-- LIST VIEW: unified Files + Documents -->
<form id="bulkActions" action="post.php" method="post"> <form id="bulkActions" action="post.php" method="post">
<input type="hidden" name="csrf_token" value="<?php echo $_SESSION['csrf_token'] ?>"> <input type="hidden" name="csrf_token" value="<?php echo $_SESSION['csrf_token'] ?>">
<div class="table-responsive-sm"> <div class="table-responsive-sm">
<table class="table border"> <table class="table border">
<thead class="thead-light <?php if ($num_rows[0] == 0) { echo "d-none"; } ?>"> <thead class="thead-light <?php if ($num_rows[0] == 0) { echo "d-none"; } ?>">
@@ -598,7 +703,7 @@ $num_root_items = intval($row_root_files['num']) + intval($row_root_docs['num'])
</th> </th>
<th> <th>
<a class="text-secondary" href="?<?php echo $url_query_strings_sort; ?>&sort=created&order=<?php echo $disp; ?>"> <a class="text-secondary" href="?<?php echo $url_query_strings_sort; ?>&sort=created&order=<?php echo $disp; ?>">
Uploaded <?php if ($sort == 'created') { echo $order_icon; } ?> Updated <?php if ($sort == 'created') { echo $order_icon; } ?>
</a> </a>
</th> </th>
<th></th> <th></th>
@@ -621,6 +726,7 @@ $num_root_items = intval($row_root_files['num']) + intval($row_root_docs['num'])
$file_mime_type = $item['mime']; $file_mime_type = $item['mime'];
$file_uploaded_by = $item['created_by']; $file_uploaded_by = $item['created_by'];
$file_created_at = $item['created_at']; $file_created_at = $item['created_at'];
$file_archived_at = $item['archived_at'];
// Shared? // Shared?
$sql_shared = mysqli_query( $sql_shared = mysqli_query(
@@ -636,7 +742,7 @@ $num_root_items = intval($row_root_files['num']) + intval($row_root_docs['num'])
); );
$file_shared = (mysqli_num_rows($sql_shared) > 0); $file_shared = (mysqli_num_rows($sql_shared) > 0);
if ($file_shared) { if ($file_shared) {
$row_shared = mysqli_fetch_array($sql_shared); $row_shared = mysqli_fetch_assoc($sql_shared);
$item_recipient = nullable_htmlentities($row_shared['item_recipient']); $item_recipient = nullable_htmlentities($row_shared['item_recipient']);
$item_expire_at_human = timeAgo($row_shared['item_expire_at']); $item_expire_at_human = timeAgo($row_shared['item_expire_at']);
} }
@@ -699,11 +805,12 @@ $num_root_items = intval($row_root_files['num']) + intval($row_root_docs['num'])
<i class="fas fa-fw fa-exchange-alt mr-2"></i>Move <i class="fas fa-fw fa-exchange-alt mr-2"></i>Move
</a> </a>
<a class="dropdown-item" href="#" data-toggle="modal" data-target="#linkAssetToFileModal<?php echo $file_id; ?>"> <a class="dropdown-item" href="#" data-toggle="modal" data-target="#linkAssetToFileModal<?php echo $file_id; ?>">
<i class="fas fa-fw fa-desktop mr-2"></i>Asset <i class="fas fa-fw fa-desktop mr-2"></i>Link Asset
</a> </a>
<?php if ($file_archived_at) { ?>
<div class="dropdown-divider"></div> <div class="dropdown-divider"></div>
<a class="dropdown-item text-danger confirm-link" href="post.php?archive_file=<?php echo $file_id; ?>"> <a class="dropdown-item text-info" href="post.php?restore_file=<?= $file_id ?>">
<i class="fas fa-fw fa-archive mr-2"></i>Archive <i class="fas fa-fw fa-redo mr-2"></i>Restore
</a> </a>
<?php if ($session_user_role == 3) { ?> <?php if ($session_user_role == 3) { ?>
<div class="dropdown-divider"></div> <div class="dropdown-divider"></div>
@@ -711,6 +818,12 @@ $num_root_items = intval($row_root_files['num']) + intval($row_root_docs['num'])
<i class="fas fa-fw fa-trash mr-2"></i>Delete <i class="fas fa-fw fa-trash mr-2"></i>Delete
</a> </a>
<?php } ?> <?php } ?>
<?php } else { ?>
<div class="dropdown-divider"></div>
<a class="dropdown-item text-danger confirm-link" href="post.php?archive_file=<?= $file_id ?>">
<i class="fas fa-fw fa-archive mr-2"></i>Archive
</a>
<?php } ?>
</div> </div>
</div> </div>
</td> </td>
@@ -724,7 +837,9 @@ $num_root_items = intval($row_root_files['num']) + intval($row_root_docs['num'])
$document_name = $item['name']; $document_name = $item['name'];
$document_description = $item['description']; $document_description = $item['description'];
$document_created_by_name = $item['created_by']; $document_created_by_name = $item['created_by'];
$document_created_at = date("m/d/Y", strtotime($item['created_at'])); $document_created_at = date("m/d/Y", strtotime($item['updated_at']));
//$document_updated_at = date("m/d/Y", strtotime($item['updated_at']));
$document_archived_at = $item['archived_at'];
$sql_shared = mysqli_query( $sql_shared = mysqli_query(
$mysqli, $mysqli,
@@ -739,7 +854,7 @@ $num_root_items = intval($row_root_files['num']) + intval($row_root_docs['num'])
); );
$doc_shared = (mysqli_num_rows($sql_shared) > 0); $doc_shared = (mysqli_num_rows($sql_shared) > 0);
if ($doc_shared) { if ($doc_shared) {
$row_shared = mysqli_fetch_array($sql_shared); $row_shared = mysqli_fetch_assoc($sql_shared);
$item_recipient = nullable_htmlentities($row_shared['item_recipient']); $item_recipient = nullable_htmlentities($row_shared['item_recipient']);
$item_expire_at_human = timeAgo($row_shared['item_expire_at']); $item_expire_at_human = timeAgo($row_shared['item_expire_at']);
} }
@@ -811,16 +926,23 @@ $num_root_items = intval($row_root_files['num']) + intval($row_root_docs['num'])
data-modal-url="modals/document/document_move.php?id=<?= $document_id ?>"> data-modal-url="modals/document/document_move.php?id=<?= $document_id ?>">
<i class="fas fa-fw fa-exchange-alt mr-2"></i>Move <i class="fas fa-fw fa-exchange-alt mr-2"></i>Move
</a> </a>
<?php if ($document_archived_at) { ?>
<div class="dropdown-divider"></div>
<a class="dropdown-item text-info" href="post.php?restore_document=<?= $document_id ?>">
<i class="fas fa-fw fa-redo mr-2"></i>Restore
</a>
<?php if ($session_user_role == 3) { ?> <?php if ($session_user_role == 3) { ?>
<div class="dropdown-divider"></div> <div class="dropdown-divider"></div>
<a class="dropdown-item text-danger confirm-link" href="post.php?archive_document=<?php echo $document_id; ?>"> <a class="dropdown-item text-danger text-bold" href="post.php?delete_document=<?= $document_id ?>">
<i class="fas fa-fw fa-archive mr-2"></i>Archive
</a>
<div class="dropdown-divider"></div>
<a class="dropdown-item text-danger text-bold confirm-link" href="post.php?delete_document=<?php echo $document_id; ?>">
<i class="fas fa-fw fa-trash mr-2"></i>Delete <i class="fas fa-fw fa-trash mr-2"></i>Delete
</a> </a>
<?php } ?> <?php } ?>
<?php } else { ?>
<div class="dropdown-divider"></div>
<a class="dropdown-item text-danger" href="post.php?archive_document=<?= $document_id ?>">
<i class="fas fa-fw fa-archive mr-2"></i>Archive
</a>
<?php } ?>
</div> </div>
</div> </div>
</td> </td>

View File

@@ -148,7 +148,7 @@ while ($folder_id > 0) {
global $mysqli, $get_folder_id, $session_user_role; global $mysqli, $get_folder_id, $session_user_role;
$sql_folders = mysqli_query($mysqli, "SELECT * FROM folders WHERE parent_folder = $parent_folder_id AND folder_location = 1 AND folder_client_id = $client_id ORDER BY folder_name ASC"); $sql_folders = mysqli_query($mysqli, "SELECT * FROM folders WHERE parent_folder = $parent_folder_id AND folder_location = 1 AND folder_client_id = $client_id ORDER BY folder_name ASC");
while ($row = mysqli_fetch_array($sql_folders)) { while ($row = mysqli_fetch_assoc($sql_folders)) {
$folder_id = intval($row['folder_id']); $folder_id = intval($row['folder_id']);
$folder_name = nullable_htmlentities($row['folder_name']); $folder_name = nullable_htmlentities($row['folder_name']);
@@ -309,7 +309,7 @@ while ($folder_id > 0) {
<?php <?php
$files = []; $files = [];
while ($row = mysqli_fetch_array($sql)) { while ($row = mysqli_fetch_assoc($sql)) {
$file_id = intval($row['file_id']); $file_id = intval($row['file_id']);
$file_name = nullable_htmlentities($row['file_name']); $file_name = nullable_htmlentities($row['file_name']);
$file_reference_name = nullable_htmlentities($row['file_reference_name']); $file_reference_name = nullable_htmlentities($row['file_reference_name']);
@@ -429,7 +429,7 @@ while ($folder_id > 0) {
<tbody> <tbody>
<?php <?php
while ($row = mysqli_fetch_array($sql)) { while ($row = mysqli_fetch_assoc($sql)) {
$file_id = intval($row['file_id']); $file_id = intval($row['file_id']);
$file_name = nullable_htmlentities($row['file_name']); $file_name = nullable_htmlentities($row['file_name']);
$file_description = nullable_htmlentities($row['file_description']); $file_description = nullable_htmlentities($row['file_description']);
@@ -480,7 +480,7 @@ while ($folder_id > 0) {
); );
$file_shared = (mysqli_num_rows($sql_shared) > 0) ? true : false; $file_shared = (mysqli_num_rows($sql_shared) > 0) ? true : false;
if ($file_shared) { if ($file_shared) {
$row = mysqli_fetch_array($sql_shared); $row = mysqli_fetch_assoc($sql_shared);
$item_id = intval($row['item_id']); $item_id = intval($row['item_id']);
$item_active = nullable_htmlentities($row['item_active']); $item_active = nullable_htmlentities($row['item_active']);
$item_key = nullable_htmlentities($row['item_key']); $item_key = nullable_htmlentities($row['item_key']);

View File

@@ -179,7 +179,7 @@ if (isset($_GET['query'])) {
<tbody> <tbody>
<?php <?php
while ($row = mysqli_fetch_array($sql_clients)) { while ($row = mysqli_fetch_assoc($sql_clients)) {
$client_id = intval($row['client_id']); $client_id = intval($row['client_id']);
$client_name = nullable_htmlentities($row['client_name']); $client_name = nullable_htmlentities($row['client_name']);
$location_phone_country_code = nullable_htmlentities($row['location_phone_country_code']); $location_phone_country_code = nullable_htmlentities($row['location_phone_country_code']);
@@ -225,7 +225,7 @@ if (isset($_GET['query'])) {
<tbody> <tbody>
<?php <?php
while ($row = mysqli_fetch_array($sql_contacts)) { while ($row = mysqli_fetch_assoc($sql_contacts)) {
$contact_id = intval($row['contact_id']); $contact_id = intval($row['contact_id']);
$contact_name = nullable_htmlentities($row['contact_name']); $contact_name = nullable_htmlentities($row['contact_name']);
$contact_title = nullable_htmlentities($row['contact_title']); $contact_title = nullable_htmlentities($row['contact_title']);
@@ -282,7 +282,7 @@ if (isset($_GET['query'])) {
<tbody> <tbody>
<?php <?php
while ($row = mysqli_fetch_array($sql_vendors)) { while ($row = mysqli_fetch_assoc($sql_vendors)) {
$vendor_name = nullable_htmlentities($row['vendor_name']); $vendor_name = nullable_htmlentities($row['vendor_name']);
$vendor_description = nullable_htmlentities($row['vendor_description']); $vendor_description = nullable_htmlentities($row['vendor_description']);
$vendor_phone_country_code = nullable_htmlentities($row['vendor_phone_country_code']); $vendor_phone_country_code = nullable_htmlentities($row['vendor_phone_country_code']);
@@ -329,7 +329,7 @@ if (isset($_GET['query'])) {
<tbody> <tbody>
<?php <?php
while ($row = mysqli_fetch_array($sql_domains)) { while ($row = mysqli_fetch_assoc($sql_domains)) {
$domain_name = nullable_htmlentities($row['domain_name']); $domain_name = nullable_htmlentities($row['domain_name']);
$domain_expiry = nullable_htmlentities($row['domain_expire']); $domain_expiry = nullable_htmlentities($row['domain_expire']);
$domain_id = intval($row['domain_id']); $domain_id = intval($row['domain_id']);
@@ -372,7 +372,7 @@ if (isset($_GET['query'])) {
<tbody> <tbody>
<?php <?php
while ($row = mysqli_fetch_array($sql_products)) { while ($row = mysqli_fetch_assoc($sql_products)) {
$product_name = nullable_htmlentities($row['product_name']); $product_name = nullable_htmlentities($row['product_name']);
$product_description = nullable_htmlentities($row['product_description']); $product_description = nullable_htmlentities($row['product_description']);
?> ?>
@@ -411,7 +411,7 @@ if (isset($_GET['query'])) {
<tbody> <tbody>
<?php <?php
while ($row = mysqli_fetch_array($sql_documents)) { while ($row = mysqli_fetch_assoc($sql_documents)) {
$document_id = intval($row['document_id']); $document_id = intval($row['document_id']);
$document_name = nullable_htmlentities($row['document_name']); $document_name = nullable_htmlentities($row['document_name']);
$client_id = intval($row['document_client_id']); $client_id = intval($row['document_client_id']);
@@ -456,7 +456,7 @@ if (isset($_GET['query'])) {
<tbody> <tbody>
<?php <?php
while ($row = mysqli_fetch_array($sql_files)) { while ($row = mysqli_fetch_assoc($sql_files)) {
$file_id = intval($row['file_id']); $file_id = intval($row['file_id']);
$file_name = nullable_htmlentities($row['file_name']); $file_name = nullable_htmlentities($row['file_name']);
$file_reference_name = nullable_htmlentities($row['file_reference_name']); $file_reference_name = nullable_htmlentities($row['file_reference_name']);
@@ -507,7 +507,7 @@ if (isset($_GET['query'])) {
<tbody> <tbody>
<?php <?php
while ($row = mysqli_fetch_array($sql_tickets)) { while ($row = mysqli_fetch_assoc($sql_tickets)) {
$ticket_id = intval($row['ticket_id']); $ticket_id = intval($row['ticket_id']);
$ticket_prefix = nullable_htmlentities($row['ticket_prefix']); $ticket_prefix = nullable_htmlentities($row['ticket_prefix']);
$ticket_number = intval($row['ticket_number']); $ticket_number = intval($row['ticket_number']);
@@ -557,7 +557,7 @@ if (isset($_GET['query'])) {
<tbody> <tbody>
<?php <?php
while ($row = mysqli_fetch_array($sql_recurring_tickets)) { while ($row = mysqli_fetch_assoc($sql_recurring_tickets)) {
$recurring_ticket_id = intval($row['recurring_ticket_id']); $recurring_ticket_id = intval($row['recurring_ticket_id']);
$recurring_ticket_subject = nullable_htmlentities($row['recurring_ticket_subject']); $recurring_ticket_subject = nullable_htmlentities($row['recurring_ticket_subject']);
$recurring_ticket_frequency = nullable_htmlentities($row['recurring_ticket_frequency']); $recurring_ticket_frequency = nullable_htmlentities($row['recurring_ticket_frequency']);
@@ -607,7 +607,7 @@ if (isset($_GET['query'])) {
<tbody> <tbody>
<?php <?php
while ($row = mysqli_fetch_array($sql_credentials)) { while ($row = mysqli_fetch_assoc($sql_credentials)) {
$credential_name = nullable_htmlentities($row['credential_name']); $credential_name = nullable_htmlentities($row['credential_name']);
$credential_description = nullable_htmlentities($row['credential_description']); $credential_description = nullable_htmlentities($row['credential_description']);
$credential_client_id = intval($row['credential_client_id']); $credential_client_id = intval($row['credential_client_id']);
@@ -659,7 +659,7 @@ if (isset($_GET['query'])) {
<tbody> <tbody>
<?php <?php
while ($row = mysqli_fetch_array($sql_quotes)) { while ($row = mysqli_fetch_assoc($sql_quotes)) {
$quote_id = intval($row['quote_id']); $quote_id = intval($row['quote_id']);
$quote_prefix = nullable_htmlentities($row['quote_prefix']); $quote_prefix = nullable_htmlentities($row['quote_prefix']);
$quote_number = intval($row['quote_number']); $quote_number = intval($row['quote_number']);
@@ -710,7 +710,7 @@ if (isset($_GET['query'])) {
<tbody> <tbody>
<?php <?php
while ($row = mysqli_fetch_array($sql_invoices)) { while ($row = mysqli_fetch_assoc($sql_invoices)) {
$invoice_id = intval($row['invoice_id']); $invoice_id = intval($row['invoice_id']);
$invoice_prefix = nullable_htmlentities($row['invoice_prefix']); $invoice_prefix = nullable_htmlentities($row['invoice_prefix']);
$invoice_number = intval($row['invoice_number']); $invoice_number = intval($row['invoice_number']);
@@ -762,7 +762,7 @@ if (isset($_GET['query'])) {
<tbody> <tbody>
<?php <?php
while ($row = mysqli_fetch_array($sql_assets)) { while ($row = mysqli_fetch_assoc($sql_assets)) {
$client_id = intval($row['asset_client_id']); $client_id = intval($row['asset_client_id']);
$client_name = nullable_htmlentities($row['client_name']); $client_name = nullable_htmlentities($row['client_name']);
$asset_id = intval($row['asset_id']); $asset_id = intval($row['asset_id']);
@@ -843,7 +843,7 @@ if (isset($_GET['query'])) {
<?php <?php
$last_ticket_id = null; // Track the last ticket ID processed $last_ticket_id = null; // Track the last ticket ID processed
while ($row = mysqli_fetch_array($sql_ticket_replies)) { while ($row = mysqli_fetch_assoc($sql_ticket_replies)) {
$ticket_id = intval($row['ticket_id']); $ticket_id = intval($row['ticket_id']);
// Only output the ticket header if we're at a new ticket // Only output the ticket header if we're at a new ticket

View File

@@ -53,7 +53,6 @@ $num_software = $row['num'];
<i class="nav-icon fas fa-address-book"></i> <i class="nav-icon fas fa-address-book"></i>
<p> <p>
Contacts Contacts
<span href="#" class="fas fa-plus-circle right ajax-modal" data-modal-url="/agent/modals/contact/contact_add.php"></span>
<?php <?php
if ($num_contacts > 0) { ?> if ($num_contacts > 0) { ?>
<span class="right badge text-light"><?php echo $num_contacts; ?></span> <span class="right badge text-light"><?php echo $num_contacts; ?></span>
@@ -66,7 +65,6 @@ $num_software = $row['num'];
<i class="nav-icon fas fa-map-marker-alt"></i> <i class="nav-icon fas fa-map-marker-alt"></i>
<p> <p>
Locations Locations
<span href="#" class="fas fa-plus-circle right ajax-modal" data-modal-url="/agent/modals/location/location_add.php"></span>
<?php <?php
if ($num_locations > 0) { ?> if ($num_locations > 0) { ?>
<span class="right badge text-light"><?php echo $num_locations; ?></span> <span class="right badge text-light"><?php echo $num_locations; ?></span>
@@ -79,7 +77,6 @@ $num_software = $row['num'];
<i class="nav-icon fas fa-desktop"></i> <i class="nav-icon fas fa-desktop"></i>
<p> <p>
Assets Assets
<span href="#" class="fas fa-plus-circle right ajax-modal" data-modal-url="/agent/modals/asset/asset_add.php"></span>
<?php <?php
if ($num_assets > 0) { ?> if ($num_assets > 0) { ?>
<span class="right badge text-light"><?php echo $num_assets; ?></span> <span class="right badge text-light"><?php echo $num_assets; ?></span>
@@ -92,7 +89,6 @@ $num_software = $row['num'];
<i class="nav-icon fas fa-cube"></i> <i class="nav-icon fas fa-cube"></i>
<p> <p>
Licenses Licenses
<span href="#" class="fas fa-plus-circle right ajax-modal" data-modal-url="/agent/modals/software/software_add.php"></span>
<?php <?php
if ($num_software > 0) { ?> if ($num_software > 0) { ?>
<span class="right badge text-light"><?php echo $num_software; ?></span> <span class="right badge text-light"><?php echo $num_software; ?></span>
@@ -105,7 +101,6 @@ $num_software = $row['num'];
<i class="nav-icon fas fa-key"></i> <i class="nav-icon fas fa-key"></i>
<p> <p>
Credentials Credentials
<span href="#" class="fas fa-plus-circle right ajax-modal" data-modal-url="/agent/modals/credential/credential_add.php"></span>
<?php <?php
if ($num_credentials > 0) { ?> if ($num_credentials > 0) { ?>
<span class="right badge text-light"><?php echo $num_credentials; ?></span> <span class="right badge text-light"><?php echo $num_credentials; ?></span>
@@ -118,7 +113,6 @@ $num_software = $row['num'];
<i class="nav-icon fas fa-network-wired"></i> <i class="nav-icon fas fa-network-wired"></i>
<p> <p>
Networks Networks
<span href="#" class="fas fa-plus-circle right ajax-modal" data-modal-url="/agent/modals/network/network_add.php"></span>
<?php <?php
if ($num_networks > 0) { ?> if ($num_networks > 0) { ?>
<span class="right badge text-light"><?php echo $num_networks; ?></span> <span class="right badge text-light"><?php echo $num_networks; ?></span>
@@ -131,7 +125,6 @@ $num_software = $row['num'];
<i class="nav-icon fas fa-lock"></i> <i class="nav-icon fas fa-lock"></i>
<p> <p>
Certificates Certificates
<span href="#" class="fas fa-plus-circle right ajax-modal" data-modal-url="/agent/modals/certificate/certificate_add.php"></span>
<?php <?php
if ($num_certificates > 0) { ?> if ($num_certificates > 0) { ?>
<span class="right badge text-light"><?php echo $num_certificates; ?></span> <span class="right badge text-light"><?php echo $num_certificates; ?></span>
@@ -144,7 +137,6 @@ $num_software = $row['num'];
<i class="nav-icon fas fa-globe"></i> <i class="nav-icon fas fa-globe"></i>
<p> <p>
Domains Domains
<span href="#" class="fas fa-plus-circle right ajax-modal" data-modal-url="/agent/modals/domain/domain_add.php"></span>
<?php <?php
if ($num_domains > 0) { ?> if ($num_domains > 0) { ?>
<span class="right badge text-light"><?php echo $num_domains; ?></span> <span class="right badge text-light"><?php echo $num_domains; ?></span>
@@ -157,7 +149,6 @@ $num_software = $row['num'];
<i class="nav-icon fas fa-stream"></i> <i class="nav-icon fas fa-stream"></i>
<p> <p>
Services Services
<span href="#" class="fas fa-plus-circle right ajax-modal" data-modal-url="/agent/modals/service/service_add.php"></span>
<?php <?php
if ($num_services > 0) { ?> if ($num_services > 0) { ?>
<span class="right badge text-light"><?php echo $num_services; ?></span> <span class="right badge text-light"><?php echo $num_services; ?></span>

View File

@@ -41,7 +41,7 @@ if (isset($_GET['client_id'])) {
exit; exit;
} else { } else {
$row = mysqli_fetch_array($sql); $row = mysqli_fetch_assoc($sql);
$client_name = nullable_htmlentities($row['client_name']); $client_name = nullable_htmlentities($row['client_name']);
$client_is_lead = intval($row['client_lead']); $client_is_lead = intval($row['client_lead']);
$client_type = nullable_htmlentities($row['client_type']); $client_type = nullable_htmlentities($row['client_type']);
@@ -84,7 +84,7 @@ if (isset($_GET['client_id'])) {
$client_tag_name_display_array = array(); $client_tag_name_display_array = array();
$client_tag_id_array = array(); $client_tag_id_array = array();
$sql_client_tags = mysqli_query($mysqli, "SELECT * FROM client_tags LEFT JOIN tags ON client_tags.tag_id = tags.tag_id WHERE client_id = $client_id ORDER BY tag_name ASC"); $sql_client_tags = mysqli_query($mysqli, "SELECT * FROM client_tags LEFT JOIN tags ON client_tags.tag_id = tags.tag_id WHERE client_id = $client_id ORDER BY tag_name ASC");
while ($row = mysqli_fetch_array($sql_client_tags)) { while ($row = mysqli_fetch_assoc($sql_client_tags)) {
$client_tag_id = intval($row['tag_id']); $client_tag_id = intval($row['tag_id']);
$client_tag_name = nullable_htmlentities($row['tag_name']); $client_tag_name = nullable_htmlentities($row['tag_name']);
@@ -104,12 +104,12 @@ if (isset($_GET['client_id'])) {
//Add up all the payments for the invoice and get the total amount paid to the invoice //Add up all the payments for the invoice and get the total amount paid to the invoice
$sql_invoice_amounts = mysqli_query($mysqli, "SELECT SUM(invoice_amount) AS invoice_amounts FROM invoices WHERE invoice_client_id = $client_id AND invoice_status != 'Draft' AND invoice_status != 'Cancelled' AND invoice_status != 'Non-Billable'"); $sql_invoice_amounts = mysqli_query($mysqli, "SELECT SUM(invoice_amount) AS invoice_amounts FROM invoices WHERE invoice_client_id = $client_id AND invoice_status != 'Draft' AND invoice_status != 'Cancelled' AND invoice_status != 'Non-Billable'");
$row = mysqli_fetch_array($sql_invoice_amounts); $row = mysqli_fetch_assoc($sql_invoice_amounts);
$invoice_amounts = floatval($row['invoice_amounts']); $invoice_amounts = floatval($row['invoice_amounts']);
$sql_amount_paid = mysqli_query($mysqli, "SELECT SUM(payment_amount) AS amount_paid FROM payments, invoices WHERE payment_invoice_id = invoice_id AND invoice_client_id = $client_id"); $sql_amount_paid = mysqli_query($mysqli, "SELECT SUM(payment_amount) AS amount_paid FROM payments, invoices WHERE payment_invoice_id = invoice_id AND invoice_client_id = $client_id");
$row = mysqli_fetch_array($sql_amount_paid); $row = mysqli_fetch_assoc($sql_amount_paid);
$amount_paid = floatval($row['amount_paid']); $amount_paid = floatval($row['amount_paid']);
@@ -117,13 +117,13 @@ if (isset($_GET['client_id'])) {
//Get Monthly Recurring Total //Get Monthly Recurring Total
$sql_recurring_monthly_total = mysqli_query($mysqli, "SELECT SUM(recurring_invoice_amount) AS recurring_monthly_total FROM recurring_invoices WHERE recurring_invoice_status = 1 AND recurring_invoice_frequency = 'month' AND recurring_invoice_client_id = $client_id"); $sql_recurring_monthly_total = mysqli_query($mysqli, "SELECT SUM(recurring_invoice_amount) AS recurring_monthly_total FROM recurring_invoices WHERE recurring_invoice_status = 1 AND recurring_invoice_frequency = 'month' AND recurring_invoice_client_id = $client_id");
$row = mysqli_fetch_array($sql_recurring_monthly_total); $row = mysqli_fetch_assoc($sql_recurring_monthly_total);
$recurring_monthly_total = floatval($row['recurring_monthly_total']); $recurring_monthly_total = floatval($row['recurring_monthly_total']);
//Get Yearly Recurring Total //Get Yearly Recurring Total
$sql_recurring_yearly_total = mysqli_query($mysqli, "SELECT SUM(recurring_invoice_amount) AS recurring_yearly_total FROM recurring_invoices WHERE recurring_invoice_status = 1 AND recurring_invoice_frequency = 'year' AND recurring_invoice_client_id = $client_id"); $sql_recurring_yearly_total = mysqli_query($mysqli, "SELECT SUM(recurring_invoice_amount) AS recurring_yearly_total FROM recurring_invoices WHERE recurring_invoice_status = 1 AND recurring_invoice_frequency = 'year' AND recurring_invoice_client_id = $client_id");
$row = mysqli_fetch_array($sql_recurring_yearly_total); $row = mysqli_fetch_assoc($sql_recurring_yearly_total);
$recurring_yearly_total = floatval($row['recurring_yearly_total']) / 12; $recurring_yearly_total = floatval($row['recurring_yearly_total']) / 12;
@@ -131,7 +131,7 @@ if (isset($_GET['client_id'])) {
// Get Credit Balance // Get Credit Balance
$sql_credit_balance = mysqli_query($mysqli, "SELECT SUM(credit_amount) AS credit_balance FROM credits WHERE credit_client_id = $client_id"); $sql_credit_balance = mysqli_query($mysqli, "SELECT SUM(credit_amount) AS credit_balance FROM credits WHERE credit_client_id = $client_id");
$row = mysqli_fetch_array($sql_credit_balance); $row = mysqli_fetch_assoc($sql_credit_balance);
$credit_balance = floatval($row['credit_balance']); $credit_balance = floatval($row['credit_balance']);

View File

@@ -125,8 +125,10 @@
</a> </a>
</li> </li>
<?php } ?> <?php } ?>
<?php if ($config_module_enable_accounting == 1 && lookupUserPermission("module_financial") >= 1) { ?>
<?php if ($config_module_enable_accounting == 1) { ?>
<li class="nav-header mt-3">FINANCE</li> <li class="nav-header mt-3">FINANCE</li>
<?php if (lookupUserPermission("module_financial") >= 1) { ?>
<li class="nav-item"> <li class="nav-item">
<a href="/agent/payments.php" class="nav-link <?php if (basename($_SERVER["PHP_SELF"]) == "payments.php") { echo "active"; } ?>"> <a href="/agent/payments.php" class="nav-link <?php if (basename($_SERVER["PHP_SELF"]) == "payments.php") { echo "active"; } ?>">
<i class="nav-icon fas fa-credit-card"></i> <i class="nav-icon fas fa-credit-card"></i>
@@ -168,6 +170,7 @@
<p>Transfers</p> <p>Transfers</p>
</a> </a>
</li> </li>
<?php } ?>
<li class="nav-item"> <li class="nav-item">
<a href="/agent/trips.php" class="nav-link <?php if (basename($_SERVER["PHP_SELF"]) == "trips.php") { echo "active"; } ?>"> <a href="/agent/trips.php" class="nav-link <?php if (basename($_SERVER["PHP_SELF"]) == "trips.php") { echo "active"; } ?>">
<i class="nav-icon fas fa-route"></i> <i class="nav-icon fas fa-route"></i>
@@ -201,7 +204,7 @@
ORDER BY custom_link_order ASC, custom_link_name ASC" ORDER BY custom_link_order ASC, custom_link_name ASC"
); );
while ($row = mysqli_fetch_array($sql_custom_links)) { while ($row = mysqli_fetch_assoc($sql_custom_links)) {
$custom_link_name = nullable_htmlentities($row['custom_link_name']); $custom_link_name = nullable_htmlentities($row['custom_link_name']);
$custom_link_uri = sanitize_url($row['custom_link_uri']); $custom_link_uri = sanitize_url($row['custom_link_uri']);
$custom_link_icon = nullable_htmlentities($row['custom_link_icon']); $custom_link_icon = nullable_htmlentities($row['custom_link_icon']);

View File

@@ -37,7 +37,7 @@ if (isset($_GET['invoice_id'])) {
exit(); exit();
} }
$row = mysqli_fetch_array($sql); $row = mysqli_fetch_assoc($sql);
$invoice_id = intval($row['invoice_id']); $invoice_id = intval($row['invoice_id']);
$invoice_prefix = nullable_htmlentities($row['invoice_prefix']); $invoice_prefix = nullable_htmlentities($row['invoice_prefix']);
$invoice_number = intval($row['invoice_number']); $invoice_number = intval($row['invoice_number']);
@@ -78,7 +78,7 @@ if (isset($_GET['invoice_id'])) {
$page_title = "{$row['invoice_prefix']}{$row['invoice_number']}"; $page_title = "{$row['invoice_prefix']}{$row['invoice_number']}";
$sql = mysqli_query($mysqli, "SELECT * FROM companies WHERE company_id = 1"); $sql = mysqli_query($mysqli, "SELECT * FROM companies WHERE company_id = 1");
$row = mysqli_fetch_array($sql); $row = mysqli_fetch_assoc($sql);
$company_id = intval($row['company_id']); $company_id = intval($row['company_id']);
$company_name = nullable_htmlentities($row['company_name']); $company_name = nullable_htmlentities($row['company_name']);
$company_country = nullable_htmlentities($row['company_country']); $company_country = nullable_htmlentities($row['company_country']);
@@ -138,14 +138,14 @@ if (isset($_GET['invoice_id'])) {
//Add up all the payments for the invoice and get the total amount paid to the invoice //Add up all the payments for the invoice and get the total amount paid to the invoice
$sql_amount_paid = mysqli_query($mysqli, "SELECT SUM(payment_amount) AS amount_paid FROM payments WHERE payment_invoice_id = $invoice_id"); $sql_amount_paid = mysqli_query($mysqli, "SELECT SUM(payment_amount) AS amount_paid FROM payments WHERE payment_invoice_id = $invoice_id");
$row = mysqli_fetch_array($sql_amount_paid); $row = mysqli_fetch_assoc($sql_amount_paid);
$amount_paid = floatval($row['amount_paid']); $amount_paid = floatval($row['amount_paid']);
$balance = $invoice_amount - $amount_paid; $balance = $invoice_amount - $amount_paid;
// Get Credit Balance // Get Credit Balance
$sql_credit_balance = mysqli_query($mysqli, "SELECT SUM(credit_amount) AS credit_balance FROM credits WHERE credit_client_id = $client_id"); $sql_credit_balance = mysqli_query($mysqli, "SELECT SUM(credit_amount) AS credit_balance FROM credits WHERE credit_client_id = $client_id");
$row = mysqli_fetch_array($sql_credit_balance); $row = mysqli_fetch_assoc($sql_credit_balance);
$credit_balance = floatval($row['credit_balance']); $credit_balance = floatval($row['credit_balance']);
@@ -181,7 +181,7 @@ if (isset($_GET['invoice_id'])) {
"); ");
if (mysqli_num_rows($products_sql) > 0) { if (mysqli_num_rows($products_sql) > 0) {
while ($row = mysqli_fetch_array($products_sql)) { while ($row = mysqli_fetch_assoc($products_sql)) {
$products[] = $row; $products[] = $row;
} }
$json_products = json_encode($products); $json_products = json_encode($products);
@@ -288,6 +288,9 @@ if (isset($_GET['invoice_id'])) {
<a class="dropdown-item" href="post.php?export_invoice_pdf=<?php echo $invoice_id; ?>" target="_blank"> <a class="dropdown-item" href="post.php?export_invoice_pdf=<?php echo $invoice_id; ?>" target="_blank">
<i class="fa fa-fw fa-download text-secondary mr-2"></i>Download PDF <i class="fa fa-fw fa-download text-secondary mr-2"></i>Download PDF
</a> </a>
<a class="dropdown-item" href="post.php?export_invoice_packing_slip=<?php echo $invoice_id; ?>" target="_blank">
<i class="fa fa-fw fa-box-open text-secondary mr-2"></i>Packing Slip
</a>
<?php if (!empty($config_smtp_host) && !empty($contact_email)) { ?> <?php if (!empty($config_smtp_host) && !empty($contact_email)) { ?>
<a class="dropdown-item" href="post.php?email_invoice=<?php echo $invoice_id; ?>"> <a class="dropdown-item" href="post.php?email_invoice=<?php echo $invoice_id; ?>">
<i class="fa fa-fw fa-paper-plane text-secondary mr-2"></i>Send Email <i class="fa fa-fw fa-paper-plane text-secondary mr-2"></i>Send Email
@@ -394,7 +397,7 @@ if (isset($_GET['invoice_id'])) {
$total_tax = 0.00; $total_tax = 0.00;
$sub_total = 0.00; $sub_total = 0.00;
while ($row = mysqli_fetch_array($sql_invoice_items)) { while ($row = mysqli_fetch_assoc($sql_invoice_items)) {
$item_id = intval($row['item_id']); $item_id = intval($row['item_id']);
$item_name = nullable_htmlentities($row['item_name']); $item_name = nullable_htmlentities($row['item_name']);
$item_description = nullable_htmlentities($row['item_description']); $item_description = nullable_htmlentities($row['item_description']);
@@ -467,7 +470,7 @@ if (isset($_GET['invoice_id'])) {
<option value="0">No Tax</option> <option value="0">No Tax</option>
<?php <?php
$taxes_sql = mysqli_query($mysqli, "SELECT * FROM taxes WHERE tax_archived_at IS NULL ORDER BY tax_name ASC"); $taxes_sql = mysqli_query($mysqli, "SELECT * FROM taxes WHERE tax_archived_at IS NULL ORDER BY tax_name ASC");
while ($row = mysqli_fetch_array($taxes_sql)) { while ($row = mysqli_fetch_assoc($taxes_sql)) {
$tax_id = intval($row['tax_id']); $tax_id = intval($row['tax_id']);
$tax_name = nullable_htmlentities($row['tax_name']); $tax_name = nullable_htmlentities($row['tax_name']);
$tax_percent = floatval($row['tax_percent']); $tax_percent = floatval($row['tax_percent']);
@@ -591,7 +594,7 @@ if (isset($_GET['invoice_id'])) {
<tbody> <tbody>
<?php <?php
while ($row = mysqli_fetch_array($sql_history)) { while ($row = mysqli_fetch_assoc($sql_history)) {
$history_created_at = $row['history_created_at']; $history_created_at = $row['history_created_at'];
$history_status = nullable_htmlentities($row['history_status']); $history_status = nullable_htmlentities($row['history_status']);
$history_description = nullable_htmlentities($row['history_description']); $history_description = nullable_htmlentities($row['history_description']);
@@ -639,7 +642,7 @@ if (isset($_GET['invoice_id'])) {
<tbody> <tbody>
<?php <?php
while ($row = mysqli_fetch_array($sql_payments)) { while ($row = mysqli_fetch_assoc($sql_payments)) {
$payment_id = intval($row['payment_id']); $payment_id = intval($row['payment_id']);
$payment_date = nullable_htmlentities($row['payment_date']); $payment_date = nullable_htmlentities($row['payment_date']);
$payment_amount = floatval($row['payment_amount']); $payment_amount = floatval($row['payment_amount']);
@@ -703,7 +706,7 @@ if (isset($_GET['invoice_id'])) {
<tbody> <tbody>
<?php <?php
while ($row = mysqli_fetch_array($sql_tickets)) { while ($row = mysqli_fetch_assoc($sql_tickets)) {
$ticket_id = intval($row['ticket_id']); $ticket_id = intval($row['ticket_id']);
$ticket_created_at = nullable_htmlentities($row['ticket_created_at']); $ticket_created_at = nullable_htmlentities($row['ticket_created_at']);
$ticket_subject = nullable_htmlentities($row['ticket_subject']); $ticket_subject = nullable_htmlentities($row['ticket_subject']);

Some files were not shown because too many files have changed in this diff Show More