mirror of
https://github.com/itflow-org/itflow
synced 2026-03-10 15:54:51 +00:00
Compare commits
1 Commits
v25.01
...
Before-Mul
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
762bbecb63 |
2
.github/FUNDING.yml
vendored
2
.github/FUNDING.yml
vendored
@@ -1 +1 @@
|
|||||||
custom: ["https://donate.itflow.org"]
|
custom: ["https://www.paypal.com/donate/?business=QP4U384PMVBMU&no_recurring=0&item_name=Help+support+the+development+of+ITFlow¤cy_code=USD"]
|
||||||
|
|||||||
31
.github/ISSUE_TEMPLATE/bug_report.md
vendored
31
.github/ISSUE_TEMPLATE/bug_report.md
vendored
@@ -1,23 +1,32 @@
|
|||||||
---
|
---
|
||||||
name: Bug report
|
name: Bug report
|
||||||
about: Please report bugs on the Forum @ https://forum.itflow.org/t/bug
|
about: Something not working quite right? Create a report to help us improve!
|
||||||
title: 'Please report bugs on the Forum'
|
title: ''
|
||||||
labels: Support
|
labels: ''
|
||||||
assignees: ''
|
assignees: ''
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
We're now using GitHub Issues exclusively for development.
|
**Describe the bug**
|
||||||
-
|
A clear and concise description of what the bug is.
|
||||||
|
|
||||||
Going forward, GitHub Issues will be used to track confirmed bugs & planned features via Github Projects. This allows us to keep GitHub clean & tidy, whilst maintaining an active and relaxed community experience on the Forum.
|
**Can you reproduce this on the demo at demo.itflow.org**
|
||||||
|
Yes/No/NA
|
||||||
|
|
||||||
Please raise bugs on the forum @ https://forum.itflow.org/t/bug. Make sure to mention whether you can replicate the bug on demo.itflow.org.
|
**Are you on the latest available version of ITFlow, with an up-to-date database structure?**
|
||||||
|
Yes/No
|
||||||
|
|
||||||
Thanks,
|
**To Reproduce**
|
||||||
|
Steps to reproduce the behavior:
|
||||||
|
1. Go to '...'
|
||||||
|
2. Click on '....'
|
||||||
|
4. See error
|
||||||
|
|
||||||
The ITFlow team :)
|
**Expected behavior**
|
||||||
|
A clear and concise description of what you expected to happen, if not obvious.
|
||||||
|
|
||||||
--
|
**Screenshots**
|
||||||
|
If applicable, add screenshots to help explain your problem.
|
||||||
|
|
||||||
To privately discuss a security issue, please see https://github.com/itflow-org/itflow/security
|
**Additional context**
|
||||||
|
Add any other context about the problem here.
|
||||||
|
|||||||
19
.github/ISSUE_TEMPLATE/feature_request.md
vendored
19
.github/ISSUE_TEMPLATE/feature_request.md
vendored
@@ -1,25 +1,16 @@
|
|||||||
---
|
---
|
||||||
name: Feature request
|
name: Feature request
|
||||||
about: Please discuss new features on the Forum @ https://forum.itflow.org/t/features
|
about: Please discuss new features on the Forum @ https://forum.itflow.org/t/features
|
||||||
title: 'Please discuss new features on the Forum'
|
title: ''
|
||||||
labels: Support
|
labels: Support
|
||||||
assignees: ''
|
assignees: ''
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
We're now using GitHub Issues exclusively for development.
|
We're now using GitHub just to track features we're definitely planning to implement (and bugs!).
|
||||||
-
|
|
||||||
|
|
||||||
Going forward, GitHub Issues will be used to track confirmed bugs & planned features via Github Projects. This allows us to keep GitHub clean & tidy, whilst maintaining an active and relaxed community experience on the Forum.
|
Please discuss new feature requests on the forum @ https://forum.itflow.org/t/features. This allows us to gather interest & feedback on the features people feel are most important, whilst keeping GitHub cleaner and more about the code.
|
||||||
|
|
||||||
Please discuss new feature requests on the forum @ https://forum.itflow.org/t/features. When creating discussions, try to imagine how your proposed feature would also benefit other users.
|
New feature requests here will be closed.
|
||||||
|
|
||||||
All new feature requests raised here will be closed, unless agreed otherwise.
|
Thanks :)
|
||||||
|
|
||||||
Thanks,
|
|
||||||
|
|
||||||
The ITFlow team :)
|
|
||||||
|
|
||||||
--
|
|
||||||
|
|
||||||
To privately discuss a security issue, please see https://github.com/itflow-org/itflow/security
|
|
||||||
|
|||||||
19
.github/ISSUE_TEMPLATE/support.md
vendored
19
.github/ISSUE_TEMPLATE/support.md
vendored
@@ -1,25 +1,18 @@
|
|||||||
---
|
---
|
||||||
name: Support
|
name: Support
|
||||||
about: Please request support on the Forum @ https://forum.itflow.org/t/support
|
about: Please visit the Forum or Discord for support
|
||||||
title: 'Please visit the Forum for support'
|
title: ''
|
||||||
labels: Support
|
labels: Support
|
||||||
assignees: ''
|
assignees: ''
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
We're now using GitHub Issues exclusively for development.
|
Please visit the Forum or Discord for support
|
||||||
-
|
|
||||||
|
|
||||||
Going forward, GitHub Issues will be used to track confirmed bugs & planned features via Github Projects. This allows us to keep GitHub clean & tidy, whilst maintaining an active and relaxed community experience on the Forum.
|
Forum - https://forum.itflow.org/
|
||||||
|
|
||||||
Please use the forum for support queries/issues: https://forum.itflow.org/t/support
|
Discord - https://discord.gg/ZjCcBzTUDr
|
||||||
|
|
||||||
All new support requests raised here will be closed.
|
|
||||||
|
|
||||||
Thanks,
|
|
||||||
|
|
||||||
The ITFlow team :)
|
|
||||||
|
|
||||||
--
|
--
|
||||||
|
|
||||||
To privately discuss a security issue, please see https://github.com/itflow-org/itflow/security
|
To discuss a security issue, please see: https://i.imgur.com/P03o0Sy.png
|
||||||
|
|||||||
37
.github/workflows/dbsql-lint.yml
vendored
37
.github/workflows/dbsql-lint.yml
vendored
@@ -1,37 +0,0 @@
|
|||||||
name: SQL Syntax Check for db.sql
|
|
||||||
|
|
||||||
on:
|
|
||||||
pull_request:
|
|
||||||
paths:
|
|
||||||
- 'db.sql'
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
syntax_check:
|
|
||||||
name: Check db.sql SQL Syntax
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
|
|
||||||
services:
|
|
||||||
mariadb:
|
|
||||||
image: mariadb:latest
|
|
||||||
ports:
|
|
||||||
- "3306:3306"
|
|
||||||
env:
|
|
||||||
MYSQL_RANDOM_ROOT_PASSWORD: "yes"
|
|
||||||
MARIADB_USER: user
|
|
||||||
MARIADB_PASSWORD: password
|
|
||||||
MARIADB_DATABASE: itfsyntaxdb
|
|
||||||
options: >-
|
|
||||||
--health-cmd="healthcheck.sh --connect --innodb_initialized"
|
|
||||||
--health-interval=10s
|
|
||||||
--health-timeout=5s
|
|
||||||
--health-retries=3
|
|
||||||
|
|
||||||
steps:
|
|
||||||
- name: Checkout Repository
|
|
||||||
uses: actions/checkout@v3
|
|
||||||
|
|
||||||
- name: Import & Lint db.sql
|
|
||||||
run: mysql --host 127.0.0.1 -uuser -ppassword itfsyntaxdb < db.sql
|
|
||||||
|
|
||||||
- name: Show imported tables
|
|
||||||
run: mysql --host 127.0.0.1 -uuser -ppassword itfsyntaxdb -e "show tables;"
|
|
||||||
8
.github/workflows/first-interaction.yml
vendored
8
.github/workflows/first-interaction.yml
vendored
@@ -10,20 +10,18 @@ jobs:
|
|||||||
run:
|
run:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/first-interaction@v1.2.0
|
- uses: actions/first-interaction@v1.1.1
|
||||||
with:
|
with:
|
||||||
repo-token: ${{ secrets.GITHUB_TOKEN }}
|
repo-token: ${{ secrets.GITHUB_TOKEN }}
|
||||||
issue-message: |
|
issue-message: |
|
||||||
Hello & Welcome! :)
|
Hello & Welcome! :)
|
||||||
|
|
||||||
Thanks for taking the time to get in touch.
|
Thanks for taking the time to get in touch. We'll review this issue shortly.
|
||||||
|
|
||||||
We ask that all bugs/feature/support requests are raised via the [forum](https://forum.itflow.org). We'll be in touch shortly to confirm.
|
Whilst you're waiting, please feel free to check out the [forum](https://forum.itflow.org).
|
||||||
pr-message: |
|
pr-message: |
|
||||||
Hello & Welcome! :)
|
Hello & Welcome! :)
|
||||||
|
|
||||||
Thanks for taking the time to help improve ITFlow. We're excited to review your contributions - we'll review this PR as soon as we can!
|
Thanks for taking the time to help improve ITFlow. We're excited to review your contributions - we'll review this PR as soon as we can!
|
||||||
|
|
||||||
Whilst you're waiting, please feel free to check out the [forum](https://forum.itflow.org).
|
Whilst you're waiting, please feel free to check out the [forum](https://forum.itflow.org).
|
||||||
|
|
||||||
Just so you know, all contributions to ITFlow are licensed under the GNU GPL. By contributing you grant us a perpetual & irrevocable license to include your work in ITFlow.
|
|
||||||
|
|||||||
2
.github/workflows/php-lint.yml
vendored
2
.github/workflows/php-lint.yml
vendored
@@ -12,4 +12,4 @@ jobs:
|
|||||||
- uses: actions/checkout@v2
|
- uses: actions/checkout@v2
|
||||||
|
|
||||||
- name: Check PHP syntax errors
|
- name: Check PHP syntax errors
|
||||||
uses: overtrue/phplint@9.4.1
|
uses: overtrue/phplint@4.1.0
|
||||||
|
|||||||
19
.gitignore
vendored
19
.gitignore
vendored
@@ -1,7 +1,6 @@
|
|||||||
node_modules
|
node_modules
|
||||||
config.php
|
config.php
|
||||||
|
|
||||||
uploads/favicon.ico
|
|
||||||
uploads/clients/*
|
uploads/clients/*
|
||||||
!uploads/clients/index.php
|
!uploads/clients/index.php
|
||||||
uploads/expenses/*
|
uploads/expenses/*
|
||||||
@@ -12,17 +11,7 @@ uploads/users/*
|
|||||||
!uploads/users/index.php
|
!uploads/users/index.php
|
||||||
uploads/tmp/*
|
uploads/tmp/*
|
||||||
!uploads/tmp/index.php
|
!uploads/tmp/index.php
|
||||||
uploads/tickets/*
|
backups/*
|
||||||
!uploads/tickets/index.php
|
!backups/index.php
|
||||||
.idea/*
|
!backups/.htaccess
|
||||||
plugins/htmlpurifier/standalone/HTMLPurifier/DefinitionCache/Serializer/HTML/*
|
.idea/*
|
||||||
!plugins/htmlpurifier/standalone/HTMLPurifier/DefinitionCache/Serializer/HTML/.gitkeep
|
|
||||||
plugins/htmlpurifier/standalone/HTMLPurifier/DefinitionCache/Serializer/URI/*
|
|
||||||
!plugins/htmlpurifier/standalone/HTMLPurifier/DefinitionCache/Serializer/URI/.gitkeep
|
|
||||||
plugins/htmlpurifier/standalone/HTMLPurifier/DefinitionCache/Serializer/CSS/*
|
|
||||||
!plugins/htmlpurifier/standalone/HTMLPurifier/DefinitionCache/Serializer/CSS/.gitkeep
|
|
||||||
.vscode/settings.json
|
|
||||||
xcustom/*
|
|
||||||
!xcustom/readme.php
|
|
||||||
post/xcustom
|
|
||||||
!post/xcustom/readme.php
|
|
||||||
@@ -1,2 +0,0 @@
|
|||||||
# Prevent access to .git, .github, and config.php
|
|
||||||
RedirectMatch 404 ^/(\.git|\.github|config\.php)
|
|
||||||
82
CHANGELOG.md
82
CHANGELOG.md
@@ -1,82 +0,0 @@
|
|||||||
# Changelog
|
|
||||||
|
|
||||||
This file documents all notable changes made to ITFlow.
|
|
||||||
|
|
||||||
## [25.01.01]
|
|
||||||
|
|
||||||
### Added / Changed
|
|
||||||
- Redesigned the Multi-Factor Authentication (MFA) Setup and Enforcement Flow UI/UX for a more intuitive user experience.
|
|
||||||
- Added a "Member" column in the user roles listing for improved visibility.
|
|
||||||
- General UI/UX improvements, along with minor performance optimizations and cleanups.
|
|
||||||
|
|
||||||
### Fixed
|
|
||||||
- Fixed an issue where Stripe was not appearing as a recurring payment option.
|
|
||||||
- Corrected inaccurate Quarter 2 Expense results in the Profit & Loss Report.
|
|
||||||
- Resolved TOTP code not displaying correctly on hover in the Contact or Asset Details sections.
|
|
||||||
- Archived contacts no longer appear in the Bulk Mail section.
|
|
||||||
- Fixed an issue where the Ticket Assign Modal was showing both ITFlow and client users.
|
|
||||||
- Fixed issue with login key redirecting to legacy client portal page.
|
|
||||||
|
|
||||||
## [25.01]
|
|
||||||
|
|
||||||
### Added / Changed
|
|
||||||
- Added support for saving cards in Stripe for automatic invoice payments.
|
|
||||||
- Page titles now display detailed information (e.g., page name, client selection, company name, ticket and invoice info) for easier multi-tab navigation.
|
|
||||||
- Reintroduced the new admin role-check for admin pages.
|
|
||||||
- Admin roles can now be archived.
|
|
||||||
- Debug mode now shows the current Git branch.
|
|
||||||
- The auto-acknowledgment email for email-parsed tickets now includes a guest link.
|
|
||||||
- Recurring tickets no longer require a contact.
|
|
||||||
- Stripe online payment setup now prompts you to set the income/expense account.
|
|
||||||
- New cron/CLI scripts have been moved to the `/scripts` subfolder — remember to update your cron configurations!
|
|
||||||
- Moved modal includes to `/modals` to tidy up the root directory.
|
|
||||||
- Moved most include files to `/includes` to improve directory structure.
|
|
||||||
- Moved guest pages to `/guest` for better organization.
|
|
||||||
- Renamed the include file `pagination.php` to `filter_footer.php`, as it is used in conjunction with `filter_header.php` for page filtering.
|
|
||||||
- Guest ticket feedback now shows the ticket prefix and number, not just the ID.
|
|
||||||
- Individual POST handler logic pages are no longer directly accessible.
|
|
||||||
- Added the ability to delete payments on the Payments and Client Payments pages.
|
|
||||||
- Implemented domain history tracking.
|
|
||||||
- Added Asset Interface Linking/Connections to show what interface is connected to which interface port of another asset.
|
|
||||||
- Added Force Recurring Ticket option in more locations, not just for recurring tickets.
|
|
||||||
- Implemented row spanning and centered devices that occupy multiple units in a rack.
|
|
||||||
- Added tooltips to main navigation badge counts to clarify what is being counted.
|
|
||||||
- Reduced max records per page from 500 to 100 to prevent performance issues.
|
|
||||||
- Updated several plugins:
|
|
||||||
- `stripe-php` from 10.5.0 to 16.4.0
|
|
||||||
- `Inputmask` from 5.0.8 to 5.0.9
|
|
||||||
- `DataTables` from 2.1.8 to 2.2.1
|
|
||||||
- `pdfmake` from 0.2.8 to 0.2.18
|
|
||||||
- `php-mime-mail-parser` to 9.0.1
|
|
||||||
- `TinyMCE` from 7.5.1 to 7.6.1
|
|
||||||
- Removed unused libraries from the vendor folder and moved Stripe to the plugins folder, eliminating the vendor folder.
|
|
||||||
- Merged the MFA TOTP functionality files `base32static.php` and `rfc6238.php` into a single file (`totp`) and moved it to the plugins folder.
|
|
||||||
- No longer need to pass the DB connection (`$mysqli`) to the `addToMailQueue` function.
|
|
||||||
- Disabled HTML Purifier caching.
|
|
||||||
- Replaced the `nullable_htmlentities` function with `htmlspecialchars`.
|
|
||||||
- Updated filter variable naming.
|
|
||||||
- Implemented other minor UI updates, performance optimizations, and directory cleanups.
|
|
||||||
|
|
||||||
### Fixed
|
|
||||||
- Fixed an issue where the ticket edit modal didn't show multi-client or no-client projects.
|
|
||||||
- Fixed asset interface losing DHCP settings.
|
|
||||||
- Fixed a 500 error when creating or editing recurring expenses due to an incorrect variable name.
|
|
||||||
- Fixed tickets created via the portal/email not being marked as billable.
|
|
||||||
- Fixed issues with editing recurring expenses.
|
|
||||||
- Resolved a regression where the TinyMCE editor didn’t display when adding or editing ticket templates.
|
|
||||||
- Fixed a TinyMCE license issue.
|
|
||||||
|
|
||||||
### Removed / Deprecated
|
|
||||||
- Deprecated the cron scripts in the root directory. Cron jobs should now use the ones in the `/scripts` subfolder, which no longer require a cron key and must be run via CLI.
|
|
||||||
|
|
||||||
### BREAKING CHANGES
|
|
||||||
- The client portal has been moved from `/portal` to `/client`:
|
|
||||||
- Links in previous emails will be broken.
|
|
||||||
- The Azure Entra ID SSO Redirect URI needs to be updated to `/client`.
|
|
||||||
- You may need to update other links (e.g., website, support page).
|
|
||||||
- Guest links have been moved from `/` to `/guest`. Previous links will be broken.
|
|
||||||
|
|
||||||
## [24.12]
|
|
||||||
|
|
||||||
### Added / Changed
|
|
||||||
- Introduced versioned releases for the first time!
|
|
||||||
@@ -60,7 +60,7 @@ representative at an online or offline event.
|
|||||||
|
|
||||||
Instances of abusive, harassing, or otherwise unacceptable behavior may be
|
Instances of abusive, harassing, or otherwise unacceptable behavior may be
|
||||||
reported to the community leaders responsible for enforcement at
|
reported to the community leaders responsible for enforcement at
|
||||||
the forums.
|
the forums / Discord.
|
||||||
All complaints will be reviewed and investigated promptly and fairly.
|
All complaints will be reviewed and investigated promptly and fairly.
|
||||||
|
|
||||||
All community leaders are obligated to respect the privacy and security of the
|
All community leaders are obligated to respect the privacy and security of the
|
||||||
|
|||||||
97
README.md
97
README.md
@@ -3,10 +3,15 @@
|
|||||||
<!-- PROJECT SHIELDS -->
|
<!-- PROJECT SHIELDS -->
|
||||||
[![Contributors][contributors-shield]][contributors-url]
|
[![Contributors][contributors-shield]][contributors-url]
|
||||||
[![Stargazers][stars-shield]][stars-url]
|
[![Stargazers][stars-shield]][stars-url]
|
||||||
|
[![Issues][issues-shield]][issues-url]
|
||||||
[![Commits][commit-shield]][commit-url]
|
[![Commits][commit-shield]][commit-url]
|
||||||
[![GPL License][license-shield]][license-url]
|
[![GPL License][license-shield]][license-url]
|
||||||
|
|
||||||
|
<!-- PROJECT LOGO -->
|
||||||
<div align="center">
|
<div align="center">
|
||||||
|
<!-- <a href="https://github.com/itflow-org/itflow">
|
||||||
|
<img src="images/logo.png" alt="Logo" width="80" height="80">
|
||||||
|
</a> -->
|
||||||
|
|
||||||
<h3 align="center">ITFlow</h3>
|
<h3 align="center">ITFlow</h3>
|
||||||
|
|
||||||
@@ -19,17 +24,15 @@
|
|||||||
Username: <b>demo@demo</b> | Password: <b>demo</b>
|
Username: <b>demo@demo</b> | Password: <b>demo</b>
|
||||||
<br />
|
<br />
|
||||||
<br />
|
<br />
|
||||||
<a href="https://itflow.org/#about">About</a>
|
<a href="https://itflow.org/index.php?page=About">About</a>
|
||||||
·
|
·
|
||||||
<a href="https://docs.itflow.org">Docs</a>
|
<a href="https://itflow.org/docs.php">Docs</a>
|
||||||
·
|
·
|
||||||
<a href="https://forum.itflow.org/">Forum</a>
|
<a href="https://forum.itflow.org/">Forum</a>
|
||||||
·
|
·
|
||||||
<a href="https://forum.itflow.org/t/bug">Report Bug</a>
|
<a href="https://github.com/itflow-org/itflow/issues">Report Bug</a>
|
||||||
·
|
·
|
||||||
<a href="https://forum.itflow.org/t/features">Request Feature</a>
|
<a href="https://forum.itflow.org/t/features">Request Feature</a>
|
||||||
·
|
|
||||||
<a href="https://github.com/itflow-org/itflow/security/policy">Security</a>
|
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@@ -42,26 +45,58 @@
|
|||||||
|
|
||||||
|
|
||||||
### The Problem
|
### The Problem
|
||||||
- You're a small but busy managed service provider with 101 things to do. Information about your clients is unorganised, unstructured and outdated.
|
- You're a busy MSP with 101 things to do.
|
||||||
- For some work, you seem to spend longer looking for the relevant documentation than actually working on the issue/project.
|
- Information about your clients is unorganised and unstructured: scattered in random tickets or folders - when you do eventually find it, it's out of date.
|
||||||
|
- For some issues, you spend longer looking for the relevant documentation than actually working the ticket.
|
||||||
- On top of the technical day to day, you also have to take care of the financial side of the business - consistent pricing, quotes/invoicing, and accounting.
|
- On top of the technical day to day, you also have to take care of the financial side of the business - consistent pricing, quotes/invoicing, and accounting.
|
||||||
|
|
||||||
### The Solution: ITFlow
|
### The Solution: ITFlow
|
||||||
- ITFlow consolidates common MSP needs (documentation, ticketing and billing) into one unified system.
|
- ITFlow consolidates common MSP needs (documentation, ticketing, and accounting) into one system
|
||||||
|
|
||||||
|
### In Beta
|
||||||
|
* This project is in beta with many ongoing changes. Updates may unintentionally introduce bugs/security issues.
|
||||||
|
* Whilst we are confident the code is safe, nothing in life is 100% safe or risk-free. Use your best judgement before deciding to store highly confidential information in ITFlow.
|
||||||
|
* We are hoping to have a stable 1.0 release by April/May 2023.
|
||||||
|
|
||||||
|
<!-- BUILT WITH -->
|
||||||
|
### Built With
|
||||||
|
|
||||||
|
* Backend / PHP libs
|
||||||
|
* PHP
|
||||||
|
* MariaDB
|
||||||
|
* PHPMailer
|
||||||
|
* HTML Purifier
|
||||||
|
* PHP Mime Mail Parser
|
||||||
|
|
||||||
|
* CSS
|
||||||
|
* Bootstrap
|
||||||
|
* AdminLTE
|
||||||
|
* fontawesome
|
||||||
|
|
||||||
|
* JS Libraries
|
||||||
|
* chart.js
|
||||||
|
* moments.js
|
||||||
|
* jQuery
|
||||||
|
* pdfmake
|
||||||
|
* Select2
|
||||||
|
* SummerNote
|
||||||
|
* FullCalendar.io
|
||||||
|
|
||||||
<!-- GETTING STARTED -->
|
<!-- GETTING STARTED -->
|
||||||
## Getting Started
|
## Getting Started / Installation
|
||||||
|
|
||||||
### Self Hosting
|
ITFlow is self-hosted. There is a full installation guide in the [docs](https://wiki.itflow.org/doku.php?id=wiki:installation), but the main steps are:
|
||||||
- The best installation method is to use the [install script](https://docs.itflow.org/installation_script) on Ubuntu/Debian. A video walk through is available [here](https://www.youtube.com/watch?v=kKz9NOU_1XE).
|
|
||||||
```
|
|
||||||
wget -O itflow_install.sh https://github.com/itflow-org/itflow-install-script/raw/main/itflow_install.sh
|
|
||||||
bash itflow_install.sh
|
|
||||||
```
|
|
||||||
- Other manual installation methods are available in the [docs](https://docs.itflow.org/installation).
|
|
||||||
|
|
||||||
### Managed Hosting
|
1. Install a LAMP stack (Linux, Apache, MariaDB, PHP)
|
||||||
- If you'd prefer, we can [host ITFlow for you](https://services.itflow.org/hosting.php).
|
```sh
|
||||||
|
sudo apt install git apache2 php libapache2-mod-php php-intl php-imap php-mailparse php-mysqli php-curl mariadb-server
|
||||||
|
```
|
||||||
|
2. Clone the repo
|
||||||
|
```sh
|
||||||
|
git clone https://github.com/itflow-org/itflow.git /var/www/html
|
||||||
|
```
|
||||||
|
3. Create a MariaDB Database
|
||||||
|
4. Point your browser to your HTTPS web server to begin setup
|
||||||
|
|
||||||
<!-- FEATURES -->
|
<!-- FEATURES -->
|
||||||
## Key Features
|
## Key Features
|
||||||
@@ -73,34 +108,36 @@
|
|||||||
|
|
||||||
<!-- ROADMAP -->
|
<!-- ROADMAP -->
|
||||||
## Roadmap / Future to-do
|
## Roadmap / Future to-do
|
||||||
We track the implementation of confirmed features and bugs via [TaskFlow](https://tasks.dev.itflow.org/tasks.php). Use the [forum](https://forum.itflow.org) to request features or raise bug reports.
|
* Comprehensive API to allow custom third party integration
|
||||||
|
* CalDAV to integrate with 3rd party calendars
|
||||||
|
* CardDAV to integrate with 3rd party Address books
|
||||||
|
* Recent caller toast alerts to click and bring up the clients account right away
|
||||||
|
* FIDO2 WebAuthn Support for passwordless auth (TPM Fingerprint), (USB Hardware keys such as Yubikey)
|
||||||
|
|
||||||
|
See the [forum](https://forum.itflow.org/d/11-road-map) and the [open issues](https://github.com/itflow-org/itflow/issues) for a full list of proposed features & known issues.
|
||||||
|
|
||||||
|
|
||||||
<!-- CONTRIBUTING -->
|
<!-- CONTRIBUTING -->
|
||||||
## Support & Contributions
|
## Support & Contributions
|
||||||
|
|
||||||
### Forum
|
### Forum
|
||||||
For help using ITFlow, bugs, feature requests, and general ideas / discussions please use the community [forum](https://forum.itflow.org).
|
For help using ITFlow, feature requests, and general ideas / discussions please use the community [forum](https://forum.itflow.org).
|
||||||
|
For bugs, please raise an [issue](https://github.com/itflow-org/itflow/issues).
|
||||||
|
|
||||||
### Contributing
|
### Contributing
|
||||||
If you want to improve ITFlow, feel free to fork the repo and create a pull reques. Make sure to discuss significant changes or new features with fellow contributors on the forum first. This helps ensure that your contributions are aligned with project goals, and saves time for everyone. All contributions should follow our [code standards](https://docs.itflow.org/code_standards). See the [contributing guide](https://docs.itflow.org/contribute).
|
If you are able to make a contribution that would make ITFlow better, please fork the repo and create a pull request. Please make sure you're following our [code standards](https://wiki.itflow.org/doku.php?id=wiki:code_standards).
|
||||||
|
For large changes / new features, please discuss the issue with other contributors first.
|
||||||
|
|
||||||
#### Contributors
|
#### Contributors
|
||||||
<a href="https://github.com/itflow-org/itflow/graphs/contributors">
|
<a href="https://github.com/itflow-org/itflow/graphs/contributors">
|
||||||
<img src="https://contrib.rocks/image?repo=itflow-org/itflow" />
|
<img src="https://contrib.rocks/image?repo=itflow-org/itflow" />
|
||||||
</a>
|
</a>
|
||||||
|
|
||||||
### Supporters
|
<!-- LICENSE -->
|
||||||
We’re incredibly grateful to the organizations and individuals who support the project - a big thank you to:
|
|
||||||
- CompuMatter
|
|
||||||
- F1 for HELP
|
|
||||||
|
|
||||||
## License
|
## License
|
||||||
|
|
||||||
ITFlow is distributed "as is" under the GPL License, WITHOUT WARRANTY OF ANY KIND. See [`LICENSE`](https://github.com/itflow-org/itflow/blob/master/LICENSE) for details.
|
ITFlow is distributed "as is" under the GPL License, WITHOUT WARRANTY OF ANY KIND. See [`LICENSE`](https://github.com/itflow-org/itflow/blob/master/LICENSE) for details.
|
||||||
|
|
||||||
## Security
|
|
||||||
* As of 2025, we now have a stable release of the project.
|
|
||||||
* Whilst we are confident in the safety of the code, no system is risk-free. Nearly all software has bugs. Use your best judgement before storing highly confidential information in ITFlow.
|
|
||||||
* If you have a security concern, privately report it [here](https://github.com/itflow-org/itflow/security/policy).
|
|
||||||
|
|
||||||
<!-- MARKDOWN LINKS & IMAGES -->
|
<!-- MARKDOWN LINKS & IMAGES -->
|
||||||
<!-- https://www.markdownguide.org/basic-syntax/#reference-style-links -->
|
<!-- https://www.markdownguide.org/basic-syntax/#reference-style-links -->
|
||||||
|
|||||||
25
SECURITY.md
25
SECURITY.md
@@ -1,26 +1,23 @@
|
|||||||
# Security Policy
|
# Security Policy
|
||||||
|
|
||||||
## **Please do NOT report security concerns/vulnerabilities publicly (Issues/forum)**
|
## In Beta
|
||||||
|
|
||||||
**We take security seriously**
|
ITFlow is currently in beta and is a work in progress.
|
||||||
|
|
||||||
- Whilst we are confident in the safety of the code, no system is risk-free. Nearly all software has bugs. Use your best judgement before storing highly confidential information in ITFlow.
|
**We take security seriously.** Whilst we are confident the code is safe, nothing in life is 100% safe or risk-free. You should use your best judgment before entering confidential information into the app.
|
||||||
- We attempt to follow security best practices where possible, including [automated code scanning](https://sonarcloud.io/component_measures?id=itflow-org_itflow&metric=security_rating&view=list).
|
|
||||||
- [](https://sonarcloud.io/summary/new_code?id=itflow-org_itflow)
|
We attempt to follow security best practices where possible, including [automated code scanning](https://sonarcloud.io/component_measures?id=itflow-org_itflow&metric=security_rating&view=list).
|
||||||
|
|
||||||
## Supported Versions
|
## Supported Versions
|
||||||
We operate a rolling release model. Any bug fixes will be released into latest version of ITFlow, so you must stay up-to-date.
|
|
||||||
|
|
||||||
| Version | Supported |
|
| Version | Supported |
|
||||||
| ------- | ------------------ |
|
| ------- | ------------------ |
|
||||||
| Beta | :x: |
|
| Beta | :white_check_mark: |
|
||||||
| 24.12 | :white_check_mark: |
|
|
||||||
| 25.1 | :white_check_mark: (When released) |
|
|
||||||
|
|
||||||
## Reporting a Vulnerability via GitHub Security Advisories
|
## Reporting a Vulnerability
|
||||||
|
|
||||||
|
**<ins>Please do not report security vulnerabilities through public GitHub issues.</ins>**
|
||||||
|
|
||||||
|
If you have discovered a security issue, please [report it](https://github.com/itflow-org/itflow/security/advisories/new) to us in as much detail as possible, so we can fix it. You should expect to receive an initial acknowledgement within 72 hours.
|
||||||
|
|
||||||
**Security contact: [GitHub Security Advisories](https://github.com/itflow-org/itflow/security/advisories/new)**
|
**Security contact: [GitHub Security Advisories](https://github.com/itflow-org/itflow/security/advisories/new)**
|
||||||
|
|
||||||
If you have discovered a security issue, please **[report it](https://github.com/itflow-org/itflow/security/advisories/new)** to us in as much detail as possible, so we can fix it.
|
|
||||||
|
|
||||||
You should expect to receive an initial acknowledgement within 72 hours. If you don't receive any feedback, we may have missed the initial email from GitHub (we're human!). Please raise a forum discussion quoting ONLY the assigned GHSA ref.
|
|
||||||
|
|||||||
@@ -8,8 +8,6 @@
|
|||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
<form action="post.php" method="post" autocomplete="off">
|
<form action="post.php" method="post" autocomplete="off">
|
||||||
<input type="hidden" name="csrf_token" value="<?php echo $_SESSION['csrf_token'] ?>">
|
|
||||||
|
|
||||||
<div class="modal-body bg-white">
|
<div class="modal-body bg-white">
|
||||||
|
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
@@ -18,17 +16,18 @@
|
|||||||
<div class="input-group-prepend">
|
<div class="input-group-prepend">
|
||||||
<span class="input-group-text"><i class="fa fa-fw fa-piggy-bank"></i></span>
|
<span class="input-group-text"><i class="fa fa-fw fa-piggy-bank"></i></span>
|
||||||
</div>
|
</div>
|
||||||
<input type="text" class="form-control" name="name" placeholder="Account name" maxlength="200" required autofocus>
|
<input type="text" class="form-control" name="name" placeholder="Account name" required autofocus>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label>Opening Balance <strong class="text-danger">*</strong></label>
|
<label>Opening Balance</label>
|
||||||
<div class="input-group">
|
<div class="input-group">
|
||||||
<div class="input-group-prepend">
|
<div class="input-group-prepend">
|
||||||
<span class="input-group-text"><i class="fa fa-fw fa-dollar-sign"></i></span>
|
<span class="input-group-text"><i class="fa fa-fw fa-dollar-sign"></i></span>
|
||||||
</div>
|
</div>
|
||||||
<input type="text" class="form-control" inputmode="numeric" pattern="-?[0-9]*\.?[0-9]{0,2}" name="opening_balance" placeholder="0.00" required>
|
<input type="number" class="form-control" step="0.01" min="0" name="opening_balance" placeholder="Opening Balance" required>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
@@ -9,23 +9,23 @@
|
|||||||
</div>
|
</div>
|
||||||
<form action="post.php" method="post" autocomplete="off">
|
<form action="post.php" method="post" autocomplete="off">
|
||||||
<input type="hidden" name="account_id" value="<?php echo $account_id; ?>">
|
<input type="hidden" name="account_id" value="<?php echo $account_id; ?>">
|
||||||
<input type="hidden" name="csrf_token" value="<?php echo $_SESSION['csrf_token'] ?>">
|
|
||||||
<div class="modal-body bg-white">
|
<div class="modal-body bg-white">
|
||||||
|
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label>Account Name <strong class="text-danger">*</strong></label>
|
<label>Account Name <strong class="text-danger">*</strong></label>
|
||||||
<div class="input-group">
|
<div class="input-group">
|
||||||
<div class="input-group-prepend">
|
<div class="input-group-prepend">
|
||||||
<span class="input-group-text"><i class="fa fa-fw fa-piggy-bank"></i></span>
|
<span class="input-group-text"><i class="fa fa-fw fa-piggy-bank"></i></span>
|
||||||
</div>
|
</div>
|
||||||
<input type="text" class="form-control" name="name" maxlength="200" value="<?php echo $account_name; ?>" required>
|
<input type="text" class="form-control" name="name" value="<?php echo $account_name; ?>" placeholder="Account name" required>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label>Notes</label>
|
<label>Notes</label>
|
||||||
<textarea class="form-control" rows="5" placeholder="Enter some notes" name="notes"><?php echo $account_notes; ?></textarea>
|
<textarea class="form-control" rows="5" placeholder="Enter some notes" name="notes"><?php echo $account_notes; ?></textarea>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
<div class="modal-footer bg-white">
|
<div class="modal-footer bg-white">
|
||||||
<button type="submit" name="edit_account" class="btn btn-primary text-bold"><i class="fa fa-check mr-2"></i>Save</button>
|
<button type="submit" name="edit_account" class="btn btn-primary text-bold"><i class="fa fa-check mr-2"></i>Save</button>
|
||||||
50
accounts.php
50
accounts.php
@@ -1,23 +1,19 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
// Default Column Sortby Filter
|
// Default Column Sortby Filter
|
||||||
$sort = "account_name";
|
$sb = "account_name";
|
||||||
$order = "ASC";
|
$o = "ASC";
|
||||||
|
|
||||||
require_once "includes/inc_all.php";
|
require_once("inc_all.php");
|
||||||
|
|
||||||
// Perms
|
|
||||||
enforceUserPermission('module_financial');
|
|
||||||
|
|
||||||
//Rebuild URL
|
//Rebuild URL
|
||||||
$url_query_strings_sort = http_build_query($get_copy);
|
$url_query_strings_sb = http_build_query(array_merge($_GET, array('sb' => $sb, 'o' => $o)));
|
||||||
|
|
||||||
$sql = mysqli_query(
|
$sql = mysqli_query(
|
||||||
$mysqli,
|
$mysqli,
|
||||||
"SELECT SQL_CALC_FOUND_ROWS * FROM accounts
|
"SELECT SQL_CALC_FOUND_ROWS * FROM accounts
|
||||||
WHERE (account_name LIKE '%$q%')
|
WHERE account_name LIKE '%$q%' AND company_id = $session_company_id
|
||||||
AND account_archived_at IS NULL
|
ORDER BY $sb $o LIMIT $record_from, $record_to"
|
||||||
ORDER BY $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()"));
|
||||||
@@ -34,27 +30,19 @@ $num_rows = mysqli_fetch_row(mysqli_query($mysqli, "SELECT FOUND_ROWS()"));
|
|||||||
<div class="card-body">
|
<div class="card-body">
|
||||||
<form autocomplete="off">
|
<form autocomplete="off">
|
||||||
<div class="input-group">
|
<div class="input-group">
|
||||||
<input type="search" class="form-control col-md-4" name="q" value="<?php if (isset($q)) { echo stripslashes(nullable_htmlentities($q)); } ?>" placeholder="Search Accounts">
|
<input type="search" class="form-control col-md-4" name="q" value="<?php if (isset($q)) { echo stripslashes(htmlentities($q)); } ?>" placeholder="Search Accounts">
|
||||||
<div class="input-group-append">
|
<div class="input-group-append">
|
||||||
<button class="btn btn-primary"><i class="fa fa-search"></i></button>
|
<button class="btn btn-primary"><i class="fa fa-search"></i></button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
<hr>
|
<hr>
|
||||||
<div class="table-responsive-sm">
|
<div class="table-responsive">
|
||||||
<table class="table table-striped table-borderless table-hover">
|
<table class="table table-striped table-borderless table-hover">
|
||||||
<thead class="text-dark <?php if ($num_rows[0] == 0) { echo "d-none"; } ?>">
|
<thead class="text-dark <?php if ($num_rows[0] == 0) { echo "d-none"; } ?>">
|
||||||
<tr>
|
<tr>
|
||||||
<th>
|
<th><a class="text-dark" href="?<?php echo $url_query_strings_sb; ?>&sb=account_name&o=<?php echo $disp; ?>">Name</a></th>
|
||||||
<a class="text-dark" href="?<?php echo $url_query_strings_sort; ?>&sort=account_name&order=<?php echo $disp; ?>">
|
<th><a class="text-dark" href="?<?php echo $url_query_strings_sb; ?>&sb=account_currency_code&o=<?php echo $disp; ?>">Currency</a></th>
|
||||||
Name <?php if ($sort == 'account_name') { echo $order_icon; } ?>
|
|
||||||
</a>
|
|
||||||
</th>
|
|
||||||
<th>
|
|
||||||
<a class="text-dark" href="?<?php echo $url_query_strings_sort; ?>&sort=account_currency_code&order=<?php echo $disp; ?>">
|
|
||||||
Currency <?php if ($sort == 'account_currency_code') { echo $order_icon; } ?>
|
|
||||||
</a>
|
|
||||||
</th>
|
|
||||||
<th class="text-right">Balance</th>
|
<th class="text-right">Balance</th>
|
||||||
<th class="text-center">Action</th>
|
<th class="text-center">Action</th>
|
||||||
</tr>
|
</tr>
|
||||||
@@ -64,10 +52,10 @@ $num_rows = mysqli_fetch_row(mysqli_query($mysqli, "SELECT FOUND_ROWS()"));
|
|||||||
|
|
||||||
while ($row = mysqli_fetch_array($sql)) {
|
while ($row = mysqli_fetch_array($sql)) {
|
||||||
$account_id = intval($row['account_id']);
|
$account_id = intval($row['account_id']);
|
||||||
$account_name = nullable_htmlentities($row['account_name']);
|
$account_name = htmlentities($row['account_name']);
|
||||||
$opening_balance = floatval($row['opening_balance']);
|
$opening_balance = floatval($row['opening_balance']);
|
||||||
$account_currency_code = nullable_htmlentities($row['account_currency_code']);
|
$account_currency_code = htmlentities($row['account_currency_code']);
|
||||||
$account_notes = nullable_htmlentities($row['account_notes']);
|
$account_notes = 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_array($sql_payments);
|
||||||
@@ -97,9 +85,9 @@ $num_rows = mysqli_fetch_row(mysqli_query($mysqli, "SELECT FOUND_ROWS()"));
|
|||||||
<a class="dropdown-item" href="#" data-toggle="modal" data-target="#editAccountModal<?php echo $account_id; ?>">
|
<a class="dropdown-item" href="#" data-toggle="modal" data-target="#editAccountModal<?php echo $account_id; ?>">
|
||||||
<i class="fas fa-fw fa-edit mr-2"></i>Edit
|
<i class="fas fa-fw fa-edit mr-2"></i>Edit
|
||||||
</a>
|
</a>
|
||||||
<?php if ($balance == 0 && $account_id != $config_stripe_account) { //Cannot Archive an Account until it reaches 0 Balance and cant be selected as an online account ?>
|
<?php if ($balance == 0) { //Cannot Archive an Account until it reaches 0 Balance ?>
|
||||||
<div class="dropdown-divider"></div>
|
<div class="dropdown-divider"></div>
|
||||||
<a class="dropdown-item text-danger" href="post.php?archive_account=<?php echo $account_id; ?>&csrf_token=<?php echo $_SESSION['csrf_token'] ?>">
|
<a class="dropdown-item text-danger" href="post.php?archive_account=<?php echo $account_id; ?>">
|
||||||
<i class="fas fa-fw fa-archive mr-2"></i>Archive
|
<i class="fas fa-fw fa-archive mr-2"></i>Archive
|
||||||
</a>
|
</a>
|
||||||
<?php } ?>
|
<?php } ?>
|
||||||
@@ -109,18 +97,18 @@ $num_rows = mysqli_fetch_row(mysqli_query($mysqli, "SELECT FOUND_ROWS()"));
|
|||||||
</tr>
|
</tr>
|
||||||
|
|
||||||
<?php
|
<?php
|
||||||
require "modals/account_edit_modal.php";
|
include("account_edit_modal.php");
|
||||||
}
|
}
|
||||||
?>
|
?>
|
||||||
|
|
||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
</div>
|
</div>
|
||||||
<?php require_once "includes/filter_footer.php"; ?>
|
<?php require_once("pagination.php"); ?>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<?php
|
<?php
|
||||||
|
|
||||||
require_once "modals/account_add_modal.php";
|
require_once("account_add_modal.php");
|
||||||
require_once "includes/footer.php";
|
require_once("footer.php");
|
||||||
|
|||||||
180
admin_api.php
180
admin_api.php
@@ -1,180 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
// Default Column Sortby Filter
|
|
||||||
$sort = "api_key_name";
|
|
||||||
$order = "ASC";
|
|
||||||
|
|
||||||
require_once "includes/inc_all_admin.php";
|
|
||||||
|
|
||||||
|
|
||||||
//Rebuild URL
|
|
||||||
$url_query_strings_sort = http_build_query($get_copy);
|
|
||||||
|
|
||||||
$sql = mysqli_query(
|
|
||||||
$mysqli,
|
|
||||||
"SELECT SQL_CALC_FOUND_ROWS * FROM api_keys
|
|
||||||
LEFT JOIN clients on api_keys.api_key_client_id = clients.client_id
|
|
||||||
WHERE (api_key_name LIKE '%$q%')
|
|
||||||
ORDER BY $sort $order LIMIT $record_from, $record_to"
|
|
||||||
);
|
|
||||||
|
|
||||||
$num_rows = mysqli_fetch_row(mysqli_query($mysqli, "SELECT FOUND_ROWS()"));
|
|
||||||
|
|
||||||
?>
|
|
||||||
|
|
||||||
<div class="card card-dark">
|
|
||||||
<div class="card-header py-2">
|
|
||||||
<h3 class="card-title mt-2"><i class="fas fa-fw fa-key mr-2"></i>API Keys</h3>
|
|
||||||
<div class="card-tools">
|
|
||||||
<button type="button" class="btn btn-primary" data-toggle="modal" data-target="#addApiKeyModal"><i class="fas fa-plus mr-2"></i>Create</button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="card-body">
|
|
||||||
|
|
||||||
<form autocomplete="off">
|
|
||||||
<div class="row">
|
|
||||||
|
|
||||||
<div class="col-md-4">
|
|
||||||
<div class="input-group mb-3 mb-md-0">
|
|
||||||
<input type="search" class="form-control" name="q" value="<?php if (isset($q)) { echo stripslashes(nullable_htmlentities($q)); } ?>" placeholder="Search keys">
|
|
||||||
<div class="input-group-append">
|
|
||||||
<button class="btn btn-primary"><i class="fa fa-search"></i></button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="col-md-8">
|
|
||||||
<div class="btn-group float-right">
|
|
||||||
<div class="dropdown ml-2" id="bulkActionButton" hidden>
|
|
||||||
<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>)
|
|
||||||
</button>
|
|
||||||
<div class="dropdown-menu">
|
|
||||||
<button class="dropdown-item text-danger text-bold"
|
|
||||||
type="submit" form="bulkActions" name="bulk_delete_api_keys">
|
|
||||||
<i class="fas fa-fw fa-trash mr-2"></i>Revoke
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
</div>
|
|
||||||
|
|
||||||
</form>
|
|
||||||
<hr>
|
|
||||||
|
|
||||||
<div class="table-responsive-sm">
|
|
||||||
|
|
||||||
<form id="bulkActions" action="post.php" method="post">
|
|
||||||
<input type="hidden" name="csrf_token" value="<?php echo $_SESSION['csrf_token'] ?>">
|
|
||||||
|
|
||||||
<table class="table table-striped table-borderless table-hover">
|
|
||||||
<thead class="text-dark <?php if ($num_rows[0] == 0) { echo "d-none"; } ?>">
|
|
||||||
<tr>
|
|
||||||
<td class="pr-0">
|
|
||||||
<div class="form-check">
|
|
||||||
<input class="form-check-input" type="checkbox" onclick="checkAll(this)">
|
|
||||||
</div>
|
|
||||||
</td>
|
|
||||||
<th>
|
|
||||||
<a class="text-dark" href="?<?php echo $url_query_strings_sort; ?>&sort=api_key_name&order=<?php echo $disp; ?>">
|
|
||||||
Name <?php if ($sort == 'api_key_name') { echo $order_icon; } ?>
|
|
||||||
</a>
|
|
||||||
</th>
|
|
||||||
<th>
|
|
||||||
<a class="text-dark" href="?<?php echo $url_query_strings_sort; ?>&sort=api_key_client_id&order=<?php echo $disp; ?>">
|
|
||||||
Client <?php if ($sort == 'api_key_client_id') { echo $order_icon; } ?>
|
|
||||||
</a>
|
|
||||||
</th>
|
|
||||||
<th>
|
|
||||||
<a class="text-dark" href="?<?php echo $url_query_strings_sort; ?>&sort=api_key_secret&order=<?php echo $disp; ?>">
|
|
||||||
Secret <?php if ($sort == 'api_key_secret') { echo $order_icon; } ?>
|
|
||||||
</a>
|
|
||||||
</th>
|
|
||||||
<th>
|
|
||||||
<a class="text-dark" href="?<?php echo $url_query_strings_sort; ?>&sort=api_key_created_at&order=<?php echo $disp; ?>">
|
|
||||||
Created <?php if ($sort == 'api_key_created_at') { echo $order_icon; } ?>
|
|
||||||
</a>
|
|
||||||
</th>
|
|
||||||
<th>
|
|
||||||
<a class="text-dark" href="?<?php echo $url_query_strings_sort; ?>&sort=api_key_expire&order=<?php echo $disp; ?>">
|
|
||||||
Expires <?php if ($sort == 'api_key_expire') { echo $order_icon; } ?>
|
|
||||||
</a>
|
|
||||||
</th>
|
|
||||||
<th class="text-center">Action</th>
|
|
||||||
</tr>
|
|
||||||
</thead>
|
|
||||||
<tbody>
|
|
||||||
<?php
|
|
||||||
|
|
||||||
while ($row = mysqli_fetch_array($sql)) {
|
|
||||||
$api_key_id = intval($row['api_key_id']);
|
|
||||||
$api_key_name = nullable_htmlentities($row['api_key_name']);
|
|
||||||
$api_key_secret = nullable_htmlentities("************" . substr($row['api_key_secret'], -4));
|
|
||||||
$api_key_created_at = nullable_htmlentities($row['api_key_created_at']);
|
|
||||||
$api_key_expire = nullable_htmlentities($row['api_key_expire']);
|
|
||||||
if ($api_key_expire < date("Y-m-d H:i:s")) {
|
|
||||||
$api_key_expire = $api_key_expire . " (Expired)";
|
|
||||||
}
|
|
||||||
|
|
||||||
if ($row['api_key_client_id'] == 0) {
|
|
||||||
$api_key_client = "<i>All Clients</i>";
|
|
||||||
} else {
|
|
||||||
$api_key_client = nullable_htmlentities($row['client_name']);
|
|
||||||
}
|
|
||||||
|
|
||||||
?>
|
|
||||||
<tr>
|
|
||||||
<td class="pr-0">
|
|
||||||
<div class="form-check">
|
|
||||||
<input class="form-check-input bulk-select" type="checkbox" name="api_key_ids[]" value="<?php echo $api_key_id ?>">
|
|
||||||
</div>
|
|
||||||
</td>
|
|
||||||
|
|
||||||
<td class="text-bold"><?php echo $api_key_name; ?></td>
|
|
||||||
|
|
||||||
<td><?php echo $api_key_client; ?></td>
|
|
||||||
|
|
||||||
<td><?php echo $api_key_secret; ?></td>
|
|
||||||
|
|
||||||
<td><?php echo $api_key_created_at; ?></td>
|
|
||||||
|
|
||||||
<td><?php echo $api_key_expire; ?></td>
|
|
||||||
|
|
||||||
<td>
|
|
||||||
<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>
|
|
||||||
<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'] ?>">
|
|
||||||
<i class="fas fa-fw fa-times mr-2"></i>Revoke
|
|
||||||
</a>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
|
|
||||||
<?php } ?>
|
|
||||||
|
|
||||||
|
|
||||||
</tbody>
|
|
||||||
</table>
|
|
||||||
|
|
||||||
</form>
|
|
||||||
|
|
||||||
</div>
|
|
||||||
<?php require_once "includes/filter_footer.php";
|
|
||||||
?>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<script src="js/bulk_actions.js"></script>
|
|
||||||
|
|
||||||
<?php
|
|
||||||
require_once "modals/admin_api_key_add_modal.php";
|
|
||||||
|
|
||||||
require_once "includes/footer.php";
|
|
||||||
|
|
||||||
@@ -1,193 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
// Default Column Sortby Filter
|
|
||||||
$sort = "app_log_id";
|
|
||||||
$order = "DESC";
|
|
||||||
|
|
||||||
require_once "includes/inc_all_admin.php";
|
|
||||||
|
|
||||||
// Log Type Filter
|
|
||||||
if (isset($_GET['type']) & !empty($_GET['type'])) {
|
|
||||||
$log_type_query = "AND (app_log_type = '" . sanitizeInput($_GET['type']) . "')";
|
|
||||||
$type_filter = nullable_htmlentities($_GET['type']);
|
|
||||||
} else {
|
|
||||||
// Default - any
|
|
||||||
$log_type_query = '';
|
|
||||||
$type_filter = '';
|
|
||||||
}
|
|
||||||
|
|
||||||
// Log Category Filter
|
|
||||||
if (isset($_GET['category']) & !empty($_GET['catergory'])) {
|
|
||||||
$log_category_query = "AND (app_log_category = '" . sanitizeInput($_GET['category']) . "')";
|
|
||||||
$category_filter = nullable_htmlentities($_GET['category']);
|
|
||||||
} else {
|
|
||||||
// Default - any
|
|
||||||
$log_category_query = '';
|
|
||||||
$category_filter = '';
|
|
||||||
}
|
|
||||||
|
|
||||||
//Rebuild URL
|
|
||||||
$url_query_strings_sort = http_build_query($get_copy);
|
|
||||||
|
|
||||||
$sql = mysqli_query(
|
|
||||||
$mysqli,
|
|
||||||
"SELECT SQL_CALC_FOUND_ROWS * FROM app_logs
|
|
||||||
WHERE (app_log_type LIKE '%$q%' OR app_log_category LIKE '%$q%' OR app_log_details LIKE '%$q%')
|
|
||||||
AND DATE(app_log_created_at) BETWEEN '$dtf' AND '$dtt'
|
|
||||||
$log_type_query
|
|
||||||
$log_category_query
|
|
||||||
ORDER BY $sort $order LIMIT $record_from, $record_to"
|
|
||||||
);
|
|
||||||
|
|
||||||
$num_rows = mysqli_fetch_row(mysqli_query($mysqli, "SELECT FOUND_ROWS()"));
|
|
||||||
|
|
||||||
?>
|
|
||||||
|
|
||||||
<div class="card card-dark">
|
|
||||||
<div class="card-header py-3">
|
|
||||||
<h3 class="card-title"><i class="fas fa-fw fa-history mr-2"></i>App Logs</h3>
|
|
||||||
</div>
|
|
||||||
<div class="card-body">
|
|
||||||
<form class="mb-4" autocomplete="off">
|
|
||||||
<div class="row">
|
|
||||||
<div class="col-sm-4">
|
|
||||||
<div class="input-group">
|
|
||||||
<input type="search" class="form-control" name="q" value="<?php if (isset($q)) { echo stripslashes(nullable_htmlentities($q)); } ?>" placeholder="Search app logs">
|
|
||||||
<div class="input-group-append">
|
|
||||||
<button class="btn btn-secondary" type="button" data-toggle="collapse" data-target="#advancedFilter"><i class="fas fa-filter"></i></button>
|
|
||||||
<button class="btn btn-primary"><i class="fa fa-search"></i></button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="col-sm-2">
|
|
||||||
<div class="form-group">
|
|
||||||
<select class="form-control select2" name="type" onchange="this.form.submit()">
|
|
||||||
<option value="">- All Types -</option>
|
|
||||||
|
|
||||||
<?php
|
|
||||||
$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)) {
|
|
||||||
$log_type = nullable_htmlentities($row['app_log_type']);
|
|
||||||
?>
|
|
||||||
<option <?php if ($type_filter == $log_type) { echo "selected"; } ?>><?php echo $log_type; ?></option>
|
|
||||||
<?php
|
|
||||||
}
|
|
||||||
?>
|
|
||||||
|
|
||||||
</select>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="col-sm-2">
|
|
||||||
<div class="form-group">
|
|
||||||
<select class="form-control select2" name="category" onchange="this.form.submit()">
|
|
||||||
<option value="">- All Categories -</option>
|
|
||||||
|
|
||||||
<?php
|
|
||||||
$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)) {
|
|
||||||
$log_category = nullable_htmlentities($row['app_log_category']);
|
|
||||||
?>
|
|
||||||
<option <?php if ($category_filter == $log_category) { echo "selected"; } ?>><?php echo $log_category; ?></option>
|
|
||||||
<?php
|
|
||||||
}
|
|
||||||
?>
|
|
||||||
|
|
||||||
</select>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="collapse mt-3 <?php if (!empty($_GET['dtf']) || $_GET['canned_date'] !== "custom" ) { echo "show"; } ?>" id="advancedFilter">
|
|
||||||
<div class="row">
|
|
||||||
<div class="col-md-2">
|
|
||||||
<div class="form-group">
|
|
||||||
<label>Canned Date</label>
|
|
||||||
<select onchange="this.form.submit()" class="form-control select2" name="canned_date">
|
|
||||||
<option <?php if ($_GET['canned_date'] == "custom") { echo "selected"; } ?> value="">Custom</option>
|
|
||||||
<option <?php if ($_GET['canned_date'] == "today") { echo "selected"; } ?> value="today">Today</option>
|
|
||||||
<option <?php if ($_GET['canned_date'] == "yesterday") { echo "selected"; } ?> value="yesterday">Yesterday</option>
|
|
||||||
<option <?php if ($_GET['canned_date'] == "thisweek") { echo "selected"; } ?> value="thisweek">This Week</option>
|
|
||||||
<option <?php if ($_GET['canned_date'] == "lastweek") { echo "selected"; } ?> value="lastweek">Last Week</option>
|
|
||||||
<option <?php if ($_GET['canned_date'] == "thismonth") { echo "selected"; } ?> value="thismonth">This Month</option>
|
|
||||||
<option <?php if ($_GET['canned_date'] == "lastmonth") { echo "selected"; } ?> value="lastmonth">Last Month</option>
|
|
||||||
<option <?php if ($_GET['canned_date'] == "thisyear") { echo "selected"; } ?> value="thisyear">This Year</option>
|
|
||||||
<option <?php if ($_GET['canned_date'] == "lastyear") { echo "selected"; } ?> value="lastyear">Last Year</option>
|
|
||||||
</select>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="col-md-2">
|
|
||||||
<div class="form-group">
|
|
||||||
<label>Date From</label>
|
|
||||||
<input onchange="this.form.submit()" type="date" class="form-control" name="dtf" max="2999-12-31" value="<?php echo nullable_htmlentities($dtf); ?>">
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="col-md-2">
|
|
||||||
<div class="form-group">
|
|
||||||
<label>Date To</label>
|
|
||||||
<input onchange="this.form.submit()" type="date" class="form-control" name="dtt" max="2999-12-31" value="<?php echo nullable_htmlentities($dtt); ?>">
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</form>
|
|
||||||
<hr>
|
|
||||||
<div class="table-responsive-sm">
|
|
||||||
<table class="table table-sm table-striped table-borderless table-hover">
|
|
||||||
<thead class="text-dark <?php if ($num_rows[0] == 0) { echo "d-none"; } ?>">
|
|
||||||
<tr>
|
|
||||||
<th>
|
|
||||||
<a class="text-dark" href="?<?php echo $url_query_strings_sort; ?>&sort=app_log_created_at&order=<?php echo $disp; ?>">
|
|
||||||
Timestamp <?php if ($sort == 'app_log_created_at') { echo $order_icon; } ?>
|
|
||||||
</a>
|
|
||||||
</th>
|
|
||||||
<th>
|
|
||||||
<a class="text-dark" href="?<?php echo $url_query_strings_sort; ?>&sort=app_log_type&order=<?php echo $disp; ?>">
|
|
||||||
Type <?php if ($sort == 'app_log_type') { echo $order_icon; } ?>
|
|
||||||
</a>
|
|
||||||
</th>
|
|
||||||
<th>
|
|
||||||
<a class="text-dark" href="?<?php echo $url_query_strings_sort; ?>&sort=app_log_category&order=<?php echo $disp; ?>">
|
|
||||||
Category <?php if ($sort == 'app_log_category') { echo $order_icon; } ?>
|
|
||||||
</a>
|
|
||||||
</th>
|
|
||||||
<th>
|
|
||||||
<a class="text-dark" href="?<?php echo $url_query_strings_sort; ?>&sort=app_log_details&order=<?php echo $disp; ?>">
|
|
||||||
Details <?php if ($sort == 'app_log_details') { echo $order_icon; } ?>
|
|
||||||
</a>
|
|
||||||
</th>
|
|
||||||
</tr>
|
|
||||||
</thead>
|
|
||||||
<tbody>
|
|
||||||
<?php
|
|
||||||
|
|
||||||
while ($row = mysqli_fetch_array($sql)) {
|
|
||||||
$log_id = intval($row['app_log_id']);
|
|
||||||
$log_type = nullable_htmlentities($row['app_log_type']);
|
|
||||||
$log_category = nullable_htmlentities($row['app_log_category']);
|
|
||||||
$log_details = nullable_htmlentities($row['app_log_details']);
|
|
||||||
$log_created_at = nullable_htmlentities($row['app_log_created_at']);
|
|
||||||
|
|
||||||
?>
|
|
||||||
|
|
||||||
<tr>
|
|
||||||
<td><?php echo $log_created_at; ?></td>
|
|
||||||
<td><?php echo $log_type; ?></td>
|
|
||||||
<td><?php echo $log_category; ?></td>
|
|
||||||
<td><?php echo $log_details; ?></td>
|
|
||||||
</tr>
|
|
||||||
|
|
||||||
<?php
|
|
||||||
}
|
|
||||||
?>
|
|
||||||
|
|
||||||
</tbody>
|
|
||||||
</table>
|
|
||||||
</div>
|
|
||||||
<?php require_once "includes/filter_footer.php";
|
|
||||||
?>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<?php
|
|
||||||
require_once "includes/footer.php";
|
|
||||||
@@ -1,305 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
// Default Column Sortby Filter
|
|
||||||
$sort = "log_id";
|
|
||||||
$order = "DESC";
|
|
||||||
|
|
||||||
require_once "includes/inc_all_admin.php";
|
|
||||||
|
|
||||||
// User Filter
|
|
||||||
if (isset($_GET['user']) & !empty($_GET['user'])) {
|
|
||||||
$user_query = 'AND (log_user_id = ' . intval($_GET['user']) . ')';
|
|
||||||
$user_filter = intval($_GET['user']);
|
|
||||||
} else {
|
|
||||||
// Default - any
|
|
||||||
$user_query = '';
|
|
||||||
$user_filter = '';
|
|
||||||
}
|
|
||||||
|
|
||||||
// Client Filter
|
|
||||||
if (isset($_GET['client']) & !empty($_GET['client'])) {
|
|
||||||
$client_query = 'AND (log_client_id = ' . intval($_GET['client']) . ')';
|
|
||||||
$client_filter = intval($_GET['client']);
|
|
||||||
} else {
|
|
||||||
// Default - any
|
|
||||||
$client_query = '';
|
|
||||||
$client_filter = '';
|
|
||||||
}
|
|
||||||
|
|
||||||
// Log Type Filter
|
|
||||||
if (isset($_GET['type']) & !empty($_GET['type'])) {
|
|
||||||
$log_type_query = "AND (log_type = '" . sanitizeInput($_GET['type']) . "')";
|
|
||||||
$type_filter = nullable_htmlentities($_GET['type']);
|
|
||||||
} else {
|
|
||||||
// Default - any
|
|
||||||
$log_type_query = '';
|
|
||||||
$type_filter = '';
|
|
||||||
}
|
|
||||||
|
|
||||||
// Log Action Filter
|
|
||||||
if (isset($_GET['action']) & !empty($_GET['action'])) {
|
|
||||||
$log_action_query = "AND (log_action = '" . sanitizeInput($_GET['action']) . "')";
|
|
||||||
$action_filter = nullable_htmlentities($_GET['action']);
|
|
||||||
} else {
|
|
||||||
// Default - any
|
|
||||||
$log_action_query = '';
|
|
||||||
$action_filter = '';
|
|
||||||
}
|
|
||||||
|
|
||||||
//Rebuild URL
|
|
||||||
$url_query_strings_sort = http_build_query($get_copy);
|
|
||||||
|
|
||||||
$sql = mysqli_query(
|
|
||||||
$mysqli,
|
|
||||||
"SELECT SQL_CALC_FOUND_ROWS * FROM logs
|
|
||||||
LEFT JOIN users ON log_user_id = user_id
|
|
||||||
LEFT JOIN clients ON log_client_id = client_id
|
|
||||||
WHERE (log_type LIKE '%$q%' OR log_action LIKE '%$q%' OR log_description LIKE '%$q%' OR log_ip LIKE '%$q%' OR log_user_agent LIKE '%$q%' OR user_name LIKE '%$q%' OR client_name LIKE '%$q%')
|
|
||||||
AND DATE(log_created_at) BETWEEN '$dtf' AND '$dtt'
|
|
||||||
$user_query
|
|
||||||
$client_query
|
|
||||||
$log_type_query
|
|
||||||
$log_action_query
|
|
||||||
ORDER BY $sort $order LIMIT $record_from, $record_to"
|
|
||||||
);
|
|
||||||
|
|
||||||
$num_rows = mysqli_fetch_row(mysqli_query($mysqli, "SELECT FOUND_ROWS()"));
|
|
||||||
|
|
||||||
?>
|
|
||||||
|
|
||||||
<div class="card card-dark">
|
|
||||||
<div class="card-header py-3">
|
|
||||||
<h3 class="card-title"><i class="fas fa-fw fa-history mr-2"></i>Audit Logs</h3>
|
|
||||||
</div>
|
|
||||||
<div class="card-body">
|
|
||||||
<form class="mb-4" autocomplete="off">
|
|
||||||
<div class="row">
|
|
||||||
<div class="col-sm-4">
|
|
||||||
<div class="input-group">
|
|
||||||
<input type="search" class="form-control" name="q" value="<?php if (isset($q)) { echo stripslashes(nullable_htmlentities($q)); } ?>" placeholder="Search audit logs">
|
|
||||||
<div class="input-group-append">
|
|
||||||
<button class="btn btn-secondary" type="button" data-toggle="collapse" data-target="#advancedFilter"><i class="fas fa-filter"></i></button>
|
|
||||||
<button class="btn btn-primary"><i class="fa fa-search"></i></button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="col-sm-2">
|
|
||||||
<div class="form-group">
|
|
||||||
<select class="form-control select2" name="client" onchange="this.form.submit()">
|
|
||||||
<option value="">- All Clients -</option>
|
|
||||||
|
|
||||||
<?php
|
|
||||||
$sql_clients_filter = mysqli_query($mysqli, "SELECT * FROM clients ORDER BY client_name ASC");
|
|
||||||
while ($row = mysqli_fetch_array($sql_clients_filter)) {
|
|
||||||
$client_id = intval($row['client_id']);
|
|
||||||
$client_name = nullable_htmlentities($row['client_name']);
|
|
||||||
?>
|
|
||||||
<option <?php if ($client_filter == $client_id) { echo "selected"; } ?> value="<?php echo $client_id; ?>"><?php echo $client_name; ?></option>
|
|
||||||
<?php
|
|
||||||
}
|
|
||||||
?>
|
|
||||||
|
|
||||||
</select>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="col-sm-2">
|
|
||||||
<div class="form-group">
|
|
||||||
<select class="form-control select2" name="user" onchange="this.form.submit()">
|
|
||||||
<option value="">- All Users -</option>
|
|
||||||
|
|
||||||
<?php
|
|
||||||
$sql_users_filter = mysqli_query($mysqli, "SELECT * FROM users ORDER BY user_name ASC");
|
|
||||||
while ($row = mysqli_fetch_array($sql_users_filter)) {
|
|
||||||
$user_id = intval($row['user_id']);
|
|
||||||
$user_name = nullable_htmlentities($row['user_name']);
|
|
||||||
?>
|
|
||||||
<option <?php if ($user_filter == $user_id) { echo "selected"; } ?> value="<?php echo $user_id; ?>"><?php echo $user_name; ?></option>
|
|
||||||
<?php
|
|
||||||
}
|
|
||||||
?>
|
|
||||||
|
|
||||||
</select>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="col-sm-2">
|
|
||||||
<div class="form-group">
|
|
||||||
<select class="form-control select2" name="type" onchange="this.form.submit()">
|
|
||||||
<option value="">- All Types -</option>
|
|
||||||
|
|
||||||
<?php
|
|
||||||
$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)) {
|
|
||||||
$log_type = nullable_htmlentities($row['log_type']);
|
|
||||||
?>
|
|
||||||
<option <?php if ($type_filter == $log_type) { echo "selected"; } ?>><?php echo $log_type; ?></option>
|
|
||||||
<?php
|
|
||||||
}
|
|
||||||
?>
|
|
||||||
|
|
||||||
</select>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="col-sm-2">
|
|
||||||
<div class="form-group">
|
|
||||||
<select class="form-control select2" name="action" onchange="this.form.submit()">
|
|
||||||
<option value="">- All Actions -</option>
|
|
||||||
|
|
||||||
<?php
|
|
||||||
$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)) {
|
|
||||||
$log_action = nullable_htmlentities($row['log_action']);
|
|
||||||
?>
|
|
||||||
<option <?php if ($action_filter == $log_action) { echo "selected"; } ?>><?php echo $log_action; ?></option>
|
|
||||||
<?php
|
|
||||||
}
|
|
||||||
?>
|
|
||||||
|
|
||||||
</select>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="collapse mt-3 <?php if (!empty($_GET['dtf']) || $_GET['canned_date'] !== "custom" ) { echo "show"; } ?>" id="advancedFilter">
|
|
||||||
<div class="row">
|
|
||||||
<div class="col-md-2">
|
|
||||||
<div class="form-group">
|
|
||||||
<label>Canned Date</label>
|
|
||||||
<select onchange="this.form.submit()" class="form-control select2" name="canned_date">
|
|
||||||
<option <?php if ($_GET['canned_date'] == "custom") { echo "selected"; } ?> value="">Custom</option>
|
|
||||||
<option <?php if ($_GET['canned_date'] == "today") { echo "selected"; } ?> value="today">Today</option>
|
|
||||||
<option <?php if ($_GET['canned_date'] == "yesterday") { echo "selected"; } ?> value="yesterday">Yesterday</option>
|
|
||||||
<option <?php if ($_GET['canned_date'] == "thisweek") { echo "selected"; } ?> value="thisweek">This Week</option>
|
|
||||||
<option <?php if ($_GET['canned_date'] == "lastweek") { echo "selected"; } ?> value="lastweek">Last Week</option>
|
|
||||||
<option <?php if ($_GET['canned_date'] == "thismonth") { echo "selected"; } ?> value="thismonth">This Month</option>
|
|
||||||
<option <?php if ($_GET['canned_date'] == "lastmonth") { echo "selected"; } ?> value="lastmonth">Last Month</option>
|
|
||||||
<option <?php if ($_GET['canned_date'] == "thisyear") { echo "selected"; } ?> value="thisyear">This Year</option>
|
|
||||||
<option <?php if ($_GET['canned_date'] == "lastyear") { echo "selected"; } ?> value="lastyear">Last Year</option>
|
|
||||||
</select>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="col-md-2">
|
|
||||||
<div class="form-group">
|
|
||||||
<label>Date From</label>
|
|
||||||
<input onchange="this.form.submit()" type="date" class="form-control" name="dtf" max="2999-12-31" value="<?php echo nullable_htmlentities($dtf); ?>">
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="col-md-2">
|
|
||||||
<div class="form-group">
|
|
||||||
<label>Date To</label>
|
|
||||||
<input onchange="this.form.submit()" type="date" class="form-control" name="dtt" max="2999-12-31" value="<?php echo nullable_htmlentities($dtt); ?>">
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</form>
|
|
||||||
<hr>
|
|
||||||
<div class="table-responsive-sm">
|
|
||||||
<table class="table table-sm table-striped table-borderless table-hover">
|
|
||||||
<thead class="text-dark <?php if ($num_rows[0] == 0) { echo "d-none"; } ?>">
|
|
||||||
<tr>
|
|
||||||
<th>
|
|
||||||
<a class="text-dark" href="?<?php echo $url_query_strings_sort; ?>&sort=log_created_at&order=<?php echo $disp; ?>">
|
|
||||||
Timestamp <?php if ($sort == 'log_created_at') { echo $order_icon; } ?>
|
|
||||||
</a>
|
|
||||||
</th>
|
|
||||||
<th>
|
|
||||||
<a class="text-dark" href="?<?php echo $url_query_strings_sort; ?>&sort=user_name&order=<?php echo $disp; ?>">
|
|
||||||
User <?php if ($sort == 'user_name') { echo $order_icon; } ?>
|
|
||||||
</a>
|
|
||||||
</th>
|
|
||||||
<?php if (empty($client)) { ?>
|
|
||||||
<th>
|
|
||||||
<a class="text-dark" href="?<?php echo $url_query_strings_sort; ?>&sort=client_name&order=<?php echo $disp; ?>">
|
|
||||||
Client <?php if ($sort == 'client_name') { echo $order_icon; } ?>
|
|
||||||
</a>
|
|
||||||
</th>
|
|
||||||
<?php } ?>
|
|
||||||
<th>
|
|
||||||
<a class="text-dark" href="?<?php echo $url_query_strings_sort; ?>&sort=log_type&order=<?php echo $disp; ?>">
|
|
||||||
Type <?php if ($sort == 'log_type') { echo $order_icon; } ?>
|
|
||||||
</a>
|
|
||||||
</th>
|
|
||||||
<th>
|
|
||||||
<a class="text-dark" href="?<?php echo $url_query_strings_sort; ?>&sort=log_action&order=<?php echo $disp; ?>">
|
|
||||||
Action <?php if ($sort == 'log_action') { echo $order_icon; } ?>
|
|
||||||
</a>
|
|
||||||
</th>
|
|
||||||
<th>
|
|
||||||
<a class="text-dark" href="?<?php echo $url_query_strings_sort; ?>&sort=log_description&order=<?php echo $disp; ?>">
|
|
||||||
Description <?php if ($sort == 'log_description') { echo $order_icon; } ?>
|
|
||||||
</a>
|
|
||||||
</th>
|
|
||||||
<th>
|
|
||||||
<a class="text-dark" href="?<?php echo $url_query_strings_sort; ?>&sort=log_ip&order=<?php echo $disp; ?>">
|
|
||||||
IP Address <?php if ($sort == 'log_ip') { echo $order_icon; } ?>
|
|
||||||
</a>
|
|
||||||
</th>
|
|
||||||
<th>
|
|
||||||
<a class="text-dark" href="?<?php echo $url_query_strings_sort; ?>&sort=log_user_agent&order=<?php echo $disp; ?>">
|
|
||||||
User Agent <?php if ($sort == 'log_user_agent') { echo $order_icon; } ?>
|
|
||||||
</a>
|
|
||||||
</th>
|
|
||||||
</tr>
|
|
||||||
</thead>
|
|
||||||
<tbody>
|
|
||||||
<?php
|
|
||||||
|
|
||||||
while ($row = mysqli_fetch_array($sql)) {
|
|
||||||
$log_id = intval($row['log_id']);
|
|
||||||
$log_type = nullable_htmlentities($row['log_type']);
|
|
||||||
$log_action = nullable_htmlentities($row['log_action']);
|
|
||||||
$log_description = nullable_htmlentities($row['log_description']);
|
|
||||||
$log_ip = nullable_htmlentities($row['log_ip']);
|
|
||||||
$log_user_agent = nullable_htmlentities($row['log_user_agent']);
|
|
||||||
$log_user_os = getOS($log_user_agent);
|
|
||||||
$log_user_browser = getWebBrowser($log_user_agent);
|
|
||||||
$log_created_at = nullable_htmlentities($row['log_created_at']);
|
|
||||||
$user_id = intval($row['user_id']);
|
|
||||||
$user_name = nullable_htmlentities($row['user_name']);
|
|
||||||
if (empty($user_name)) {
|
|
||||||
$user_name_display = "-";
|
|
||||||
} else {
|
|
||||||
$user_name_display = $user_name;
|
|
||||||
}
|
|
||||||
$client_name = nullable_htmlentities($row['client_name']);
|
|
||||||
$client_id = intval($row['client_id']);
|
|
||||||
if (empty($client_name)) {
|
|
||||||
$client_name_display = "-";
|
|
||||||
} else {
|
|
||||||
$client_name_display = "<a href='client_overview.php?client_id=$client_id'>$client_name</a>";
|
|
||||||
}
|
|
||||||
$log_entity_id = intval($row['log_entity_id']);
|
|
||||||
|
|
||||||
?>
|
|
||||||
|
|
||||||
<tr>
|
|
||||||
<td><?php echo $log_created_at; ?></td>
|
|
||||||
<td><?php echo $user_name_display; ?></td>
|
|
||||||
<?php if(empty($client)) { ?>
|
|
||||||
<td><?php echo $client_name_display; ?></td>
|
|
||||||
<?php } ?>
|
|
||||||
<td><?php echo $log_type; ?></td>
|
|
||||||
<td><?php echo $log_action; ?></td>
|
|
||||||
<td><?php echo $log_description; ?></td>
|
|
||||||
<td><?php echo $log_ip; ?></td>
|
|
||||||
<td><?php echo "$log_user_os<div class='text-secondary'>$log_user_browser</div>"; ?></td>
|
|
||||||
</tr>
|
|
||||||
|
|
||||||
<?php
|
|
||||||
}
|
|
||||||
?>
|
|
||||||
|
|
||||||
</tbody>
|
|
||||||
</table>
|
|
||||||
</div>
|
|
||||||
<?php require_once "includes/filter_footer.php";
|
|
||||||
?>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<?php
|
|
||||||
require_once "includes/footer.php";
|
|
||||||
|
|
||||||
@@ -1,38 +0,0 @@
|
|||||||
<?php
|
|
||||||
require_once "includes/inc_all_admin.php";
|
|
||||||
?>
|
|
||||||
|
|
||||||
<div class="card card-dark mb-3">
|
|
||||||
<div class="card-header py-3">
|
|
||||||
<h3 class="card-title"><i class="fas fa-fw fa-database mr-2"></i>Download Database</h3>
|
|
||||||
</div>
|
|
||||||
<div class="card-body" style="text-align: center;">
|
|
||||||
<div class="alert alert-secondary">If you are unable to back up the entire VM, you'll need to back up the files & database individually. There is no built-in restore. See the <a href="https://docs.itflow.org/backups" target="_blank">docs here</a>.</div>
|
|
||||||
<a class="btn btn-primary btn-lg p-3" href="post.php?download_database&csrf_token=<?php echo $_SESSION['csrf_token'] ?>"><i class="fas fa-fw fa-4x fa-download"></i><br><br>Download database</a>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<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>Backup Master Encryption Key</h3>
|
|
||||||
</div>
|
|
||||||
<div class="card-body">
|
|
||||||
<div class="card-body">
|
|
||||||
<form action="post.php" method="POST">
|
|
||||||
<input type="hidden" name="csrf_token" value="<?php echo $_SESSION['csrf_token'] ?>">
|
|
||||||
<div class="row d-flex justify-content-center">
|
|
||||||
<div class="input-group col-4">
|
|
||||||
<div class="input-group-prepend">
|
|
||||||
<input type="password" class="form-control" placeholder="Enter your account password" name="password" autocomplete="new-password" required>
|
|
||||||
</div>
|
|
||||||
<button class="btn btn-primary" type="submit" name="backup_master_key"><i class="fas fa-fw fa-key mr-2"></i>Get Master Key</button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</form>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<?php
|
|
||||||
require_once "includes/footer.php";
|
|
||||||
|
|
||||||
@@ -1,153 +0,0 @@
|
|||||||
<?php
|
|
||||||
require_once "includes/inc_all_admin.php";
|
|
||||||
|
|
||||||
|
|
||||||
$sql = mysqli_query($mysqli, "SELECT * FROM contacts
|
|
||||||
LEFT JOIN clients ON client_id = contact_client_id
|
|
||||||
WHERE client_archived_at IS NULL
|
|
||||||
AND contact_archived_at IS NULL
|
|
||||||
AND contact_email != ''
|
|
||||||
AND (contact_primary = 1 OR
|
|
||||||
contact_important = 1 OR
|
|
||||||
contact_billing = 1 OR
|
|
||||||
contact_technical = 1)
|
|
||||||
ORDER BY client_name ASC, contact_primary DESC,
|
|
||||||
contact_important DESC"
|
|
||||||
);
|
|
||||||
|
|
||||||
?>
|
|
||||||
|
|
||||||
|
|
||||||
<div class="card">
|
|
||||||
<div class="card-header">
|
|
||||||
<h3 class="card-title mt-2 mb-2"><i class="fa fa-fw fa-envelope-open mr-2"></i>Bulk Mail</h3>
|
|
||||||
<div class="card-tools">
|
|
||||||
<button id="bulkActionButton" hidden class="btn btn-primary" type="submit" form='bulkActions' name="send_bulk_mail_now">
|
|
||||||
<i class="fas fa-fw fa-paper-plane mr-2"></i>Send (<span id="selectedCount">0</span>)
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="card-body">
|
|
||||||
<form id="bulkActions" action="post.php" method="post">
|
|
||||||
<input type="hidden" name="csrf_token" value="<?php echo $_SESSION['csrf_token'] ?>">
|
|
||||||
|
|
||||||
<div class="row">
|
|
||||||
|
|
||||||
<div class="col">
|
|
||||||
|
|
||||||
<h5>Email Message</h5>
|
|
||||||
|
|
||||||
<hr>
|
|
||||||
|
|
||||||
<div class="form-group">
|
|
||||||
<select type="text" class="form-control select2" name="mail_from">
|
|
||||||
<option value="<?php echo nullable_htmlentities($config_mail_from_email); ?>">
|
|
||||||
<?php echo nullable_htmlentities("$config_mail_from_name - $config_mail_from_email"); ?></option>
|
|
||||||
<option value="<?php echo nullable_htmlentities($config_invoice_from_email); ?>">
|
|
||||||
<?php echo nullable_htmlentities("$config_invoice_from_name - $config_invoice_from_email"); ?></option>
|
|
||||||
<option value="<?php echo nullable_htmlentities($config_quote_from_email); ?>">
|
|
||||||
<?php echo nullable_htmlentities("$config_quote_from_name - $config_quote_from_email"); ?></option>
|
|
||||||
<option value="<?php echo nullable_htmlentities($config_ticket_from_email); ?>">
|
|
||||||
<?php echo nullable_htmlentities("$config_ticket_from_name - $config_ticket_from_email"); ?></option>
|
|
||||||
</select>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="form-group">
|
|
||||||
<input type="text" class="form-control" name="mail_from_name" placeholder="From Name" value="<?php echo nullable_htmlentities($config_mail_from_name); ?>" required>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="form-group">
|
|
||||||
<input type="text" class="form-control" name="subject" placeholder="Subject" required>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="form-group">
|
|
||||||
<textarea class="form-control tinymce" name="body" placeholder="Type an email in here"></textarea>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="form-group">
|
|
||||||
<div class="input-group">
|
|
||||||
<div class="input-group-prepend">
|
|
||||||
<span class="input-group-text"><i class="fa fa-fw fa-calendar"></i></span>
|
|
||||||
</div>
|
|
||||||
<input type="datetime-local" class="form-control" name="queued_at">
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="col">
|
|
||||||
|
|
||||||
<h5>Select Contacts</h5>
|
|
||||||
<hr>
|
|
||||||
<div class="card">
|
|
||||||
<div class="table-responsive">
|
|
||||||
<table class="table">
|
|
||||||
<thead>
|
|
||||||
<tr>
|
|
||||||
<td>
|
|
||||||
<div class="form-check">
|
|
||||||
<input type="checkbox" class="form-check-input" id="selectAllCheckbox" onclick="checkAll(this)">
|
|
||||||
</div>
|
|
||||||
</td>
|
|
||||||
<th>Client</th>
|
|
||||||
<th>Name</th>
|
|
||||||
<th>Title</th>
|
|
||||||
<th>Email</th>
|
|
||||||
</tr>
|
|
||||||
</thead>
|
|
||||||
<tbody>
|
|
||||||
|
|
||||||
<?php
|
|
||||||
while ($row = mysqli_fetch_array($sql)) {
|
|
||||||
$contact_id = intval($row['contact_id']);
|
|
||||||
$contact_name = nullable_htmlentities($row['contact_name']);
|
|
||||||
$contact_title = nullable_htmlentities($row['contact_title']);
|
|
||||||
if (empty($contact_title)) {
|
|
||||||
$contact_title_display = "-";
|
|
||||||
} else {
|
|
||||||
$contact_title_display = "$contact_title";
|
|
||||||
}
|
|
||||||
$contact_email = nullable_htmlentities($row['contact_email']);
|
|
||||||
$contact_primary = intval($row['contact_primary']);
|
|
||||||
$contact_important = intval($row['contact_important']);
|
|
||||||
$contact_billing = intval($row['contact_billing']);
|
|
||||||
$contact_technical = intval($row['contact_technical']);
|
|
||||||
$contact_client_id = intval($row['contact_client_id']);
|
|
||||||
$client_name = nullable_htmlentities($row['client_name']);
|
|
||||||
?>
|
|
||||||
<tr>
|
|
||||||
<td>
|
|
||||||
<div class="form-check">
|
|
||||||
<input type="checkbox" class="form-check-input bulk-select" name="contact_ids[]" value="<?php echo $contact_id; ?>">
|
|
||||||
</div>
|
|
||||||
</td>
|
|
||||||
<td><?php echo $client_name; ?></td>
|
|
||||||
<td>
|
|
||||||
<a href="client_contact_details.php?client_id=<?php echo $contact_client_id; ?>&contact_id=<?php echo $contact_id; ?>" target="_blank">
|
|
||||||
<?php echo $contact_name; ?>
|
|
||||||
</a>
|
|
||||||
</td>
|
|
||||||
<td><?php echo $contact_title_display; ?></td>
|
|
||||||
<td><?php echo $contact_email; ?></td>
|
|
||||||
</tr>
|
|
||||||
<?php } ?>
|
|
||||||
</tbody>
|
|
||||||
</table>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
</div>
|
|
||||||
|
|
||||||
</div>
|
|
||||||
|
|
||||||
</div>
|
|
||||||
|
|
||||||
</form>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
|
|
||||||
<script src="js/bulk_actions.js"></script>
|
|
||||||
|
|
||||||
<?php
|
|
||||||
|
|
||||||
require_once "includes/footer.php";
|
|
||||||
@@ -1,197 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
// Default Column Sortby Filter
|
|
||||||
$sort = "category_name";
|
|
||||||
$order = "ASC";
|
|
||||||
|
|
||||||
require_once "includes/inc_all_admin.php";
|
|
||||||
|
|
||||||
|
|
||||||
if (isset($_GET['category'])) {
|
|
||||||
$category = sanitizeInput($_GET['category']);
|
|
||||||
} else {
|
|
||||||
$category = "Expense";
|
|
||||||
}
|
|
||||||
|
|
||||||
//Rebuild URL
|
|
||||||
$url_query_strings_sort = http_build_query($get_copy);
|
|
||||||
|
|
||||||
|
|
||||||
$sql = mysqli_query(
|
|
||||||
$mysqli,
|
|
||||||
"SELECT SQL_CALC_FOUND_ROWS * FROM categories
|
|
||||||
WHERE category_name LIKE '%$q%'
|
|
||||||
AND category_type = '$category'
|
|
||||||
AND category_$archive_query
|
|
||||||
ORDER BY $sort $order LIMIT $record_from, $record_to"
|
|
||||||
);
|
|
||||||
$num_rows = mysqli_fetch_row(mysqli_query($mysqli, "SELECT FOUND_ROWS()"));
|
|
||||||
|
|
||||||
if (isset($_GET['archived'])) {
|
|
||||||
$category = "Archived";
|
|
||||||
}
|
|
||||||
|
|
||||||
?>
|
|
||||||
|
|
||||||
|
|
||||||
<div class="card card-dark">
|
|
||||||
<div class="card-header py-2">
|
|
||||||
<h3 class="card-title mt-2"><i class="fa fa-fw fa-list-ul mr-2"></i>
|
|
||||||
<?php echo nullable_htmlentities($category); ?> Categories
|
|
||||||
</h3>
|
|
||||||
<?php
|
|
||||||
if (!isset($_GET['archived'])) {
|
|
||||||
?>
|
|
||||||
<div class="card-tools">
|
|
||||||
<button type="button" class="btn btn-primary" data-toggle="modal" data-target="#addCategoryModal"><i
|
|
||||||
class="fas fa-plus mr-2"></i>New <?php echo nullable_htmlentities($category); ?> Category</button>
|
|
||||||
</div>
|
|
||||||
<?php
|
|
||||||
}
|
|
||||||
?>
|
|
||||||
</div>
|
|
||||||
<div class="card-body">
|
|
||||||
<form autocomplete="off">
|
|
||||||
<input type="hidden" name="category" value="<?php echo nullable_htmlentities($category); ?>">
|
|
||||||
<div class="row">
|
|
||||||
<div class="col-sm-4 mb-2">
|
|
||||||
<div class="input-group">
|
|
||||||
<input type="search" class="form-control" name="q"
|
|
||||||
value="<?php if (isset($q)) {
|
|
||||||
echo stripslashes(nullable_htmlentities($q));
|
|
||||||
} ?>"
|
|
||||||
placeholder="Search <?php echo nullable_htmlentities($category); ?> Categories ">
|
|
||||||
<div class="input-group-append">
|
|
||||||
<button class="btn btn-primary"><i class="fa fa-search"></i></button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="col-sm-8">
|
|
||||||
<div class="btn-group float-right">
|
|
||||||
<a href="?category=Expense"
|
|
||||||
class="btn <?php if ($category == 'Expense') {
|
|
||||||
echo 'btn-primary';
|
|
||||||
} else {
|
|
||||||
echo 'btn-default';
|
|
||||||
} ?>">Expense</a>
|
|
||||||
<a href="?category=Income"
|
|
||||||
class="btn <?php if ($category == 'Income') {
|
|
||||||
echo 'btn-primary';
|
|
||||||
} else {
|
|
||||||
echo 'btn-default';
|
|
||||||
} ?>">Income</a>
|
|
||||||
<a href="?category=Referral"
|
|
||||||
class="btn <?php if ($category == 'Referral') {
|
|
||||||
echo 'btn-primary';
|
|
||||||
} else {
|
|
||||||
echo 'btn-default';
|
|
||||||
} ?>">Referral</a>
|
|
||||||
<a href="?category=Payment Method"
|
|
||||||
class="btn <?php if ($category == 'Payment Method') {
|
|
||||||
echo 'btn-primary';
|
|
||||||
} else {
|
|
||||||
echo 'btn-default';
|
|
||||||
} ?>">Payment
|
|
||||||
Method</a>
|
|
||||||
<a href="?category=Ticket"
|
|
||||||
class="btn <?php if ($category == 'Ticket') {
|
|
||||||
echo 'btn-primary';
|
|
||||||
} else {
|
|
||||||
echo 'btn-default';
|
|
||||||
} ?>">Ticket</a>
|
|
||||||
<a href="?archived=1"
|
|
||||||
class="btn <?php if (isset($_GET['archived'])) {
|
|
||||||
echo 'btn-primary';
|
|
||||||
} else {
|
|
||||||
echo 'btn-default';
|
|
||||||
} ?>"><i
|
|
||||||
class="fas fa-fw fa-archive mr-2"></i>Archived</a>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</form>
|
|
||||||
<hr>
|
|
||||||
<div class="table-responsive-sm">
|
|
||||||
<table class="table table-striped table-borderless table-hover">
|
|
||||||
<thead class="text-dark <?php if ($num_rows[0] == 0) { echo "d-none"; } ?>">
|
|
||||||
<tr>
|
|
||||||
<th>
|
|
||||||
<a class="text-dark" href="?<?php echo $url_query_strings_sort; ?>&sort=category_name&order=<?php echo $disp; ?>">
|
|
||||||
Name <?php if ($sort == 'category_name') { echo $order_icon; } ?>
|
|
||||||
</a>
|
|
||||||
</th>
|
|
||||||
<th>Color</th>
|
|
||||||
<th class="text-center">Action</th>
|
|
||||||
</tr>
|
|
||||||
</thead>
|
|
||||||
<tbody>
|
|
||||||
<?php
|
|
||||||
|
|
||||||
while ($row = mysqli_fetch_array($sql)) {
|
|
||||||
$category_id = intval($row['category_id']);
|
|
||||||
$category_name = nullable_htmlentities($row['category_name']);
|
|
||||||
$category_color = nullable_htmlentities($row['category_color']);
|
|
||||||
|
|
||||||
?>
|
|
||||||
<tr>
|
|
||||||
<td><a class="text-dark" href="#" data-toggle="modal"
|
|
||||||
data-target="#editCategoryModal<?php echo $category_id; ?>">
|
|
||||||
<?php echo $category_name; ?>
|
|
||||||
</a></td>
|
|
||||||
<td><i class="fa fa-3x fa-circle" style="color:<?php echo $category_color; ?>;"></i></td>
|
|
||||||
<td>
|
|
||||||
<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>
|
|
||||||
<div class="dropdown-menu">
|
|
||||||
<?php
|
|
||||||
if ($category == "Archived") {
|
|
||||||
?>
|
|
||||||
<a class="dropdown-item text-success confirm-link"
|
|
||||||
href="post.php?unarchive_category=<?php echo $category_id; ?>">
|
|
||||||
<i class="fas fa-fw fa-archive mr-2"></i>Unarchive
|
|
||||||
</a>
|
|
||||||
<a class="dropdown-item text-danger confirm-link"
|
|
||||||
href="post.php?delete_category=<?php echo $category_id; ?>">
|
|
||||||
<i class="fas fa-fw fa-trash mr-2"></i>Delete
|
|
||||||
</a>
|
|
||||||
<?php
|
|
||||||
} else {
|
|
||||||
?>
|
|
||||||
<a class="dropdown-item" href="#" data-toggle="modal"
|
|
||||||
data-target="#editCategoryModal<?php echo $category_id; ?>">
|
|
||||||
<i class="fas fa-fw fa-edit mr-2"></i>Edit
|
|
||||||
</a>
|
|
||||||
<a class="dropdown-item text-danger confirm-link"
|
|
||||||
href="post.php?archive_category=<?php echo $category_id; ?>">
|
|
||||||
<i class="fas fa-fw fa-archive mr-2"></i>Archive
|
|
||||||
</a>
|
|
||||||
<?php
|
|
||||||
}
|
|
||||||
?>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
|
|
||||||
<?php
|
|
||||||
|
|
||||||
require "modals/admin_category_edit_modal.php";
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
?>
|
|
||||||
|
|
||||||
</tbody>
|
|
||||||
</table>
|
|
||||||
</div>
|
|
||||||
<?php require_once "includes/filter_footer.php";
|
|
||||||
?>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<?php
|
|
||||||
require_once "modals/admin_category_add_modal.php";
|
|
||||||
|
|
||||||
require_once "includes/footer.php";
|
|
||||||
@@ -1,153 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
// Default Column Sortby Filter
|
|
||||||
$sort = "custom_link_name";
|
|
||||||
$order = "ASC";
|
|
||||||
|
|
||||||
require_once "includes/inc_all_admin.php";
|
|
||||||
|
|
||||||
|
|
||||||
//Rebuild URL
|
|
||||||
$url_query_strings_sort = http_build_query($get_copy);
|
|
||||||
|
|
||||||
$sql = mysqli_query(
|
|
||||||
$mysqli,
|
|
||||||
"SELECT SQL_CALC_FOUND_ROWS * FROM custom_links
|
|
||||||
WHERE custom_link_name LIKE '%$q%'
|
|
||||||
ORDER BY $sort $order LIMIT $record_from, $record_to"
|
|
||||||
);
|
|
||||||
|
|
||||||
$num_rows = mysqli_fetch_row(mysqli_query($mysqli, "SELECT FOUND_ROWS()"));
|
|
||||||
|
|
||||||
?>
|
|
||||||
|
|
||||||
<div class="card card-dark">
|
|
||||||
<div class="card-header py-2">
|
|
||||||
<h3 class="card-title mt-2"><i class="fas fa-fw fa-external-link-alt mr-2"></i>Custom Links</h3>
|
|
||||||
<div class="card-tools">
|
|
||||||
<button type="button" class="btn btn-primary" data-toggle="modal" data-target="#addLinkModal"><i class="fas fa-plus mr-2"></i>New Link</button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="card-body">
|
|
||||||
<div class="row">
|
|
||||||
<div class="col-sm-4 mb-2">
|
|
||||||
<form autocomplete="off">
|
|
||||||
<div class="input-group">
|
|
||||||
<input type="search" class="form-control" name="q" value="<?php if (isset($q)) { echo stripslashes(nullable_htmlentities($q)); } ?>" placeholder="Search Links">
|
|
||||||
<div class="input-group-append">
|
|
||||||
<button class="btn btn-primary"><i class="fa fa-search"></i></button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</form>
|
|
||||||
</div>
|
|
||||||
<div class="col-sm-8">
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<hr>
|
|
||||||
<div class="table-responsive-sm">
|
|
||||||
<table class="table table-striped table-borderless table-hover">
|
|
||||||
<thead class="text-dark <?php if ($num_rows[0] == 0) { echo "d-none"; } ?>">
|
|
||||||
<tr>
|
|
||||||
<th>
|
|
||||||
<a class="text-dark" href="?<?php echo $url_query_strings_sort; ?>&sort=custom_link_name&order=<?php echo $disp; ?>">
|
|
||||||
Name <?php if ($sort == 'custom_link_name') { echo $order_icon; } ?>
|
|
||||||
</a>
|
|
||||||
</th>
|
|
||||||
<th>
|
|
||||||
<a class="text-dark" href="?<?php echo $url_query_strings_sort; ?>&sort=custom_link_order&order=<?php echo $disp; ?>">
|
|
||||||
Order <?php if ($sort == 'custom_link_order') { echo $order_icon; } ?>
|
|
||||||
</a>
|
|
||||||
</th>
|
|
||||||
<th>
|
|
||||||
<a class="text-dark" href="?<?php echo $url_query_strings_sort; ?>&sort=custom_link_uri&order=<?php echo $disp; ?>">
|
|
||||||
URI / <span class="text-secondary">New Tab</span> <?php if ($sort == 'custom_link_uri') { echo $order_icon; } ?>
|
|
||||||
</a>
|
|
||||||
</th>
|
|
||||||
<th>
|
|
||||||
<a class="text-dark" href="?<?php echo $url_query_strings_sort; ?>&sort=custom_link_location&order=<?php echo $disp; ?>">
|
|
||||||
Location <?php if ($sort == 'custom_link_location') { echo $order_icon; } ?>
|
|
||||||
</a>
|
|
||||||
</th>
|
|
||||||
<th class="text-center">Action</th>
|
|
||||||
</tr>
|
|
||||||
</thead>
|
|
||||||
<tbody>
|
|
||||||
<?php
|
|
||||||
|
|
||||||
while ($row = mysqli_fetch_array($sql)) {
|
|
||||||
$custom_link_id = intval($row['custom_link_id']);
|
|
||||||
$custom_link_name = nullable_htmlentities($row['custom_link_name']);
|
|
||||||
$custom_link_uri = nullable_htmlentities($row['custom_link_uri']);
|
|
||||||
$custom_link_icon = nullable_htmlentities($row['custom_link_icon']);
|
|
||||||
$custom_link_new_tab = intval($row['custom_link_new_tab']);
|
|
||||||
if ($custom_link_new_tab == 1 ) {
|
|
||||||
$custom_link_new_tab_display = "<i class='fas fa-fw fa-checkmark'></i>";
|
|
||||||
} else {
|
|
||||||
$custom_link_new_tab_display = "";
|
|
||||||
}
|
|
||||||
$custom_link_order = intval($row['custom_link_order']);
|
|
||||||
if ($custom_link_order == 0 ) {
|
|
||||||
$custom_link_order_display = "-";
|
|
||||||
} else {
|
|
||||||
$custom_link_order_display = $custom_link_order;
|
|
||||||
}
|
|
||||||
$custom_link_location = intval($row['custom_link_location']);
|
|
||||||
if ($custom_link_location == 1) {
|
|
||||||
$custom_link_location_display = "Main Side Nav";
|
|
||||||
} else {
|
|
||||||
$custom_link_location_display = "Top Nav";
|
|
||||||
}
|
|
||||||
|
|
||||||
?>
|
|
||||||
<tr>
|
|
||||||
<td>
|
|
||||||
<a href="#" data-toggle="modal" data-target="#editLinkModal<?php echo $custom_link_id; ?>">
|
|
||||||
<i class="fa fa-fw fa-<?php echo $custom_link_icon; ?> mr-2"></i>
|
|
||||||
<?php echo $custom_link_name;?>
|
|
||||||
</a>
|
|
||||||
</td>
|
|
||||||
<td><?php echo $custom_link_order_display; ?></td>
|
|
||||||
<td><?php echo "$custom_link_uri $custom_link_new_tab_display"; ?></td>
|
|
||||||
<td><?php echo $custom_link_location_display; ?></td>
|
|
||||||
<td>
|
|
||||||
<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>
|
|
||||||
<div class="dropdown-menu">
|
|
||||||
<a class="dropdown-item" href="#" data-toggle="modal" data-target="#editLinkModal<?php echo $custom_link_id; ?>">
|
|
||||||
<i class="fas fa-fw fa-edit mr-2"></i>Edit
|
|
||||||
</a>
|
|
||||||
<div class="dropdown-divider"></div>
|
|
||||||
<a class="dropdown-item text-danger text-bold confirm-link" href="post.php?delete_custom_link=<?php echo $custom_link_id; ?>">
|
|
||||||
<i class="fas fa-fw fa-trash mr-2"></i>Delete
|
|
||||||
</a>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
|
|
||||||
<?php
|
|
||||||
|
|
||||||
require "modals/admin_custom_link_edit_modal.php";
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
?>
|
|
||||||
|
|
||||||
</tbody>
|
|
||||||
</table>
|
|
||||||
</div>
|
|
||||||
<?php require_once "includes/filter_footer.php";
|
|
||||||
?>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<?php
|
|
||||||
require_once "modals/admin_custom_link_add_modal.php";
|
|
||||||
|
|
||||||
require_once "includes/footer.php";
|
|
||||||
|
|
||||||
757
admin_debug.php
757
admin_debug.php
@@ -1,757 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
require_once "includes/inc_all_admin.php";
|
|
||||||
require_once "includes/database_version.php";
|
|
||||||
require_once "config.php";
|
|
||||||
|
|
||||||
$checks = [];
|
|
||||||
|
|
||||||
// Execute the git command to get the latest commit hash
|
|
||||||
$commitHash = shell_exec('git log -1 --format=%H');
|
|
||||||
|
|
||||||
// Get branch info
|
|
||||||
$gitBranch = shell_exec('git rev-parse --abbrev-ref HEAD');
|
|
||||||
|
|
||||||
// Section: System Information
|
|
||||||
$systemInfo = [];
|
|
||||||
|
|
||||||
// Operating System and Version
|
|
||||||
$os = php_uname();
|
|
||||||
$systemInfo[] = [
|
|
||||||
'name' => 'Operating System',
|
|
||||||
'value' => $os,
|
|
||||||
];
|
|
||||||
|
|
||||||
// Web Server and Version
|
|
||||||
$webServer = $_SERVER['SERVER_SOFTWARE'] ?? 'Unknown';
|
|
||||||
$systemInfo[] = [
|
|
||||||
'name' => 'Web Server',
|
|
||||||
'value' => $webServer,
|
|
||||||
];
|
|
||||||
|
|
||||||
// Kernel and Version
|
|
||||||
$kernelVersion = php_uname('r');
|
|
||||||
$systemInfo[] = [
|
|
||||||
'name' => 'Kernel Version',
|
|
||||||
'value' => $kernelVersion,
|
|
||||||
];
|
|
||||||
|
|
||||||
// Database and Version
|
|
||||||
$dbVersion = $mysqli->server_info;
|
|
||||||
$systemInfo[] = [
|
|
||||||
'name' => 'Database Version',
|
|
||||||
'value' => $dbVersion,
|
|
||||||
];
|
|
||||||
|
|
||||||
// Section: PHP Extensions
|
|
||||||
$phpExtensions = [];
|
|
||||||
$extensions = [
|
|
||||||
'php-mailparse' => 'mailparse',
|
|
||||||
'php-imap' => 'imap',
|
|
||||||
'php-mysqli' => 'mysqli',
|
|
||||||
'php-intl' => 'intl',
|
|
||||||
'php-curl' => 'curl',
|
|
||||||
'php-mbstring' => 'mbstring',
|
|
||||||
'php-gd' => 'gd',
|
|
||||||
];
|
|
||||||
|
|
||||||
foreach ($extensions as $name => $ext) {
|
|
||||||
$loaded = extension_loaded($ext);
|
|
||||||
$phpExtensions[] = [
|
|
||||||
'name' => "$name installed",
|
|
||||||
'passed' => $loaded,
|
|
||||||
'value' => $loaded ? 'Installed' : 'Not Installed',
|
|
||||||
];
|
|
||||||
}
|
|
||||||
|
|
||||||
// Section: PHP Configuration
|
|
||||||
$phpConfig = [];
|
|
||||||
|
|
||||||
// Check if shell_exec is enabled
|
|
||||||
$disabled_functions = explode(',', ini_get('disable_functions'));
|
|
||||||
$disabled_functions = array_map('trim', $disabled_functions);
|
|
||||||
$shell_exec_enabled = !in_array('shell_exec', $disabled_functions);
|
|
||||||
|
|
||||||
$phpConfig[] = [
|
|
||||||
'name' => 'shell_exec is enabled',
|
|
||||||
'passed' => $shell_exec_enabled,
|
|
||||||
'value' => $shell_exec_enabled ? 'Enabled' : 'Disabled',
|
|
||||||
];
|
|
||||||
|
|
||||||
// Check upload_max_filesize and post_max_size >= 500M
|
|
||||||
function return_bytes($val) {
|
|
||||||
$val = trim($val);
|
|
||||||
$unit = strtolower(substr($val, -1));
|
|
||||||
$num = (float)$val;
|
|
||||||
switch ($unit) {
|
|
||||||
case 'g':
|
|
||||||
$num *= 1024;
|
|
||||||
case 'm':
|
|
||||||
$num *= 1024;
|
|
||||||
case 'k':
|
|
||||||
$num *= 1024;
|
|
||||||
}
|
|
||||||
return $num;
|
|
||||||
}
|
|
||||||
|
|
||||||
$required_bytes = 500 * 1024 * 1024; // 500M in bytes
|
|
||||||
|
|
||||||
$upload_max_filesize = ini_get('upload_max_filesize');
|
|
||||||
$post_max_size = ini_get('post_max_size');
|
|
||||||
|
|
||||||
$upload_passed = return_bytes($upload_max_filesize) >= $required_bytes;
|
|
||||||
$post_passed = return_bytes($post_max_size) >= $required_bytes;
|
|
||||||
|
|
||||||
$phpConfig[] = [
|
|
||||||
'name' => 'upload_max_filesize >= 500M',
|
|
||||||
'passed' => $upload_passed,
|
|
||||||
'value' => $upload_max_filesize,
|
|
||||||
];
|
|
||||||
|
|
||||||
$phpConfig[] = [
|
|
||||||
'name' => 'post_max_size >= 500M',
|
|
||||||
'passed' => $post_passed,
|
|
||||||
'value' => $post_max_size,
|
|
||||||
];
|
|
||||||
|
|
||||||
// PHP Memory Limit >= 128M
|
|
||||||
$memoryLimit = ini_get('memory_limit');
|
|
||||||
$memoryLimitBytes = return_bytes($memoryLimit);
|
|
||||||
$memoryLimitPassed = $memoryLimitBytes >= (128 * 1024 * 1024);
|
|
||||||
$phpConfig[] = [
|
|
||||||
'name' => 'PHP Memory Limit >= 128M',
|
|
||||||
'passed' => $memoryLimitPassed,
|
|
||||||
'value' => $memoryLimit,
|
|
||||||
];
|
|
||||||
|
|
||||||
// Max Execution Time >= 300 seconds
|
|
||||||
$maxExecutionTime = ini_get('max_execution_time');
|
|
||||||
$maxExecutionTimePassed = $maxExecutionTime >= 300;
|
|
||||||
$phpConfig[] = [
|
|
||||||
'name' => 'Max Execution Time >= 300 seconds',
|
|
||||||
'passed' => $maxExecutionTimePassed,
|
|
||||||
'value' => $maxExecutionTime . ' seconds',
|
|
||||||
];
|
|
||||||
|
|
||||||
// Check PHP version >= 8.2.0
|
|
||||||
$php_version = PHP_VERSION;
|
|
||||||
$php_passed = version_compare($php_version, '8.2.0', '>=');
|
|
||||||
|
|
||||||
$phpConfig[] = [
|
|
||||||
'name' => 'PHP version >= 8.2.0',
|
|
||||||
'passed' => $php_passed,
|
|
||||||
'value' => $php_version,
|
|
||||||
];
|
|
||||||
|
|
||||||
// Section: Shell Commands
|
|
||||||
$shellCommands = [];
|
|
||||||
|
|
||||||
if ($shell_exec_enabled) {
|
|
||||||
$commands = ['whois', 'dig', 'git'];
|
|
||||||
|
|
||||||
foreach ($commands as $command) {
|
|
||||||
$which = trim(shell_exec("which $command 2>/dev/null"));
|
|
||||||
$exists = !empty($which);
|
|
||||||
$shellCommands[] = [
|
|
||||||
'name' => "Command '$command' available",
|
|
||||||
'passed' => $exists,
|
|
||||||
'value' => $exists ? $which : 'Not Found',
|
|
||||||
];
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
// If shell_exec is disabled, mark commands as unavailable
|
|
||||||
foreach (['whois', 'dig', 'git'] as $command) {
|
|
||||||
$shellCommands[] = [
|
|
||||||
'name' => "Command '$command' available",
|
|
||||||
'passed' => false,
|
|
||||||
'value' => 'shell_exec Disabled',
|
|
||||||
];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Section: SSL Checks
|
|
||||||
$sslChecks = [];
|
|
||||||
|
|
||||||
// Check if accessing via HTTPS
|
|
||||||
$https = (!empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] !== 'off') || $_SERVER['SERVER_PORT'] == 443;
|
|
||||||
$sslChecks[] = [
|
|
||||||
'name' => 'Accessing via HTTPS',
|
|
||||||
'passed' => $https,
|
|
||||||
'value' => $https ? 'Yes' : 'No',
|
|
||||||
];
|
|
||||||
|
|
||||||
// SSL Certificate Validity Check
|
|
||||||
if ($https) {
|
|
||||||
$streamContext = stream_context_create(["ssl" => ["capture_peer_cert" => true]]);
|
|
||||||
$socket = @stream_socket_client("ssl://{$_SERVER['HTTP_HOST']}:443", $errno, $errstr, 30, STREAM_CLIENT_CONNECT, $streamContext);
|
|
||||||
|
|
||||||
if ($socket) {
|
|
||||||
$params = stream_context_get_params($socket);
|
|
||||||
$cert = $params['options']['ssl']['peer_certificate'];
|
|
||||||
$certInfo = openssl_x509_parse($cert);
|
|
||||||
|
|
||||||
$validFrom = $certInfo['validFrom_time_t'];
|
|
||||||
$validTo = $certInfo['validTo_time_t'];
|
|
||||||
$currentTime = time();
|
|
||||||
|
|
||||||
$certValid = ($currentTime >= $validFrom && $currentTime <= $validTo);
|
|
||||||
|
|
||||||
$sslChecks[] = [
|
|
||||||
'name' => 'SSL Certificate is valid',
|
|
||||||
'passed' => $certValid,
|
|
||||||
'value' => $certValid ? 'Valid' : 'Invalid or Expired',
|
|
||||||
];
|
|
||||||
} else {
|
|
||||||
$sslChecks[] = [
|
|
||||||
'name' => 'SSL Certificate is valid',
|
|
||||||
'passed' => false,
|
|
||||||
'value' => 'Unable to retrieve certificate',
|
|
||||||
];
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
$sslChecks[] = [
|
|
||||||
'name' => 'SSL Certificate is valid',
|
|
||||||
'passed' => false,
|
|
||||||
'value' => 'Not using HTTPS',
|
|
||||||
];
|
|
||||||
}
|
|
||||||
|
|
||||||
// Section: Domain Checks
|
|
||||||
$domainChecks = [];
|
|
||||||
|
|
||||||
// Check if the site has a valid FQDN
|
|
||||||
$fqdn = $_SERVER['HTTP_HOST'];
|
|
||||||
$isValidFqdn = (bool) filter_var('http://' . $fqdn, FILTER_VALIDATE_URL) && preg_match('/^[a-z0-9.-]+\.[a-z]{2,}$/i', $fqdn);
|
|
||||||
|
|
||||||
$domainChecks[] = [
|
|
||||||
'name' => 'Site has a valid FQDN',
|
|
||||||
'passed' => $isValidFqdn,
|
|
||||||
'value' => $fqdn,
|
|
||||||
];
|
|
||||||
|
|
||||||
// Section: File Permissions
|
|
||||||
$filePermissions = [];
|
|
||||||
|
|
||||||
// Check if web user has write access to webroot directory
|
|
||||||
$webroot = $_SERVER['DOCUMENT_ROOT'];
|
|
||||||
$writable = is_writable($webroot);
|
|
||||||
$filePermissions[] = [
|
|
||||||
'name' => 'Web user has write access to webroot directory',
|
|
||||||
'passed' => $writable,
|
|
||||||
'value' => $webroot,
|
|
||||||
];
|
|
||||||
|
|
||||||
// Section: Uploads Directory Stats
|
|
||||||
$uploadsStats = [];
|
|
||||||
|
|
||||||
// Define the uploads directory path
|
|
||||||
$uploadsDir = __DIR__ . '/uploads'; // Adjust the path if needed
|
|
||||||
|
|
||||||
if (is_dir($uploadsDir)) {
|
|
||||||
// Function to recursively count files and calculate total size
|
|
||||||
function getDirStats($dir) {
|
|
||||||
$files = 0;
|
|
||||||
$size = 0;
|
|
||||||
|
|
||||||
$iterator = new RecursiveIteratorIterator(new RecursiveDirectoryIterator($dir));
|
|
||||||
foreach ($iterator as $file) {
|
|
||||||
if ($file->isFile()) {
|
|
||||||
$files++;
|
|
||||||
$size += $file->getSize();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return ['files' => $files, 'size' => $size];
|
|
||||||
}
|
|
||||||
|
|
||||||
$stats = getDirStats($uploadsDir);
|
|
||||||
$sizeInMB = round($stats['size'] / (1024 * 1024), 2);
|
|
||||||
|
|
||||||
$uploadsStats[] = [
|
|
||||||
'name' => 'Number of files in uploads directory',
|
|
||||||
'value' => $stats['files'],
|
|
||||||
];
|
|
||||||
|
|
||||||
$uploadsStats[] = [
|
|
||||||
'name' => 'Total size of uploads directory (MB)',
|
|
||||||
'value' => $sizeInMB . ' MB',
|
|
||||||
];
|
|
||||||
} else {
|
|
||||||
$uploadsStats[] = [
|
|
||||||
'name' => 'Uploads directory exists',
|
|
||||||
'value' => 'Directory not found',
|
|
||||||
];
|
|
||||||
}
|
|
||||||
|
|
||||||
// Section: Database Stats
|
|
||||||
$databaseStats = [];
|
|
||||||
|
|
||||||
// Get list of tables
|
|
||||||
$tablesResult = $mysqli->query("SHOW TABLE STATUS");
|
|
||||||
if ($tablesResult) {
|
|
||||||
$totalTables = 0;
|
|
||||||
$totalFields = 0;
|
|
||||||
$totalRows = 0;
|
|
||||||
$totalSize = 0;
|
|
||||||
$tableDetails = [];
|
|
||||||
|
|
||||||
while ($table = $tablesResult->fetch_assoc()) {
|
|
||||||
$tableName = $table['Name'];
|
|
||||||
$tableRows = $table['Rows'];
|
|
||||||
$dataLength = $table['Data_length'];
|
|
||||||
$indexLength = $table['Index_length'];
|
|
||||||
$tableSize = ($dataLength + $indexLength) / (1024 * 1024); // Size in MB
|
|
||||||
|
|
||||||
// Get number of fields
|
|
||||||
$fieldsResult = $mysqli->query("SHOW COLUMNS FROM `$tableName`");
|
|
||||||
$numFields = $fieldsResult->num_rows;
|
|
||||||
$fieldsResult->free();
|
|
||||||
|
|
||||||
$totalTables++;
|
|
||||||
$totalFields += $numFields;
|
|
||||||
$totalRows += $tableRows;
|
|
||||||
$totalSize += $tableSize;
|
|
||||||
|
|
||||||
$tableDetails[] = [
|
|
||||||
'name' => $tableName,
|
|
||||||
'fields' => $numFields,
|
|
||||||
'rows' => $tableRows,
|
|
||||||
'size' => round($tableSize, 2),
|
|
||||||
];
|
|
||||||
}
|
|
||||||
$tablesResult->free();
|
|
||||||
|
|
||||||
$databaseStats[] = [
|
|
||||||
'name' => 'Total number of tables',
|
|
||||||
'value' => $totalTables,
|
|
||||||
];
|
|
||||||
$databaseStats[] = [
|
|
||||||
'name' => 'Total number of fields',
|
|
||||||
'value' => $totalFields,
|
|
||||||
];
|
|
||||||
$databaseStats[] = [
|
|
||||||
'name' => 'Total number of rows',
|
|
||||||
'value' => $totalRows,
|
|
||||||
];
|
|
||||||
$databaseStats[] = [
|
|
||||||
'name' => 'Total database size (MB)',
|
|
||||||
'value' => round($totalSize, 2) . ' MB',
|
|
||||||
];
|
|
||||||
} else {
|
|
||||||
$databaseStats[] = [
|
|
||||||
'name' => 'Database connection error',
|
|
||||||
'value' => $mysqli->error,
|
|
||||||
];
|
|
||||||
}
|
|
||||||
|
|
||||||
// Section: Database Structure Comparison
|
|
||||||
$dbComparison = [];
|
|
||||||
|
|
||||||
// Path to the db.sql file
|
|
||||||
$dbSqlFile = __DIR__ . '/db.sql';
|
|
||||||
|
|
||||||
if (file_exists($dbSqlFile)) {
|
|
||||||
// Read the db.sql file
|
|
||||||
$sqlContent = file_get_contents($dbSqlFile);
|
|
||||||
|
|
||||||
// Remove comments and empty lines
|
|
||||||
$lines = explode("\n", $sqlContent);
|
|
||||||
$sqlStatements = [];
|
|
||||||
$statement = '';
|
|
||||||
|
|
||||||
foreach ($lines as $line) {
|
|
||||||
// Remove single-line comments
|
|
||||||
$line = preg_replace('/--.*$/', '', $line);
|
|
||||||
$line = preg_replace('/\/\*.*?\*\//', '', $line);
|
|
||||||
|
|
||||||
// Skip empty lines
|
|
||||||
if (trim($line) == '') {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Append line to the current statement
|
|
||||||
$statement .= $line . "\n";
|
|
||||||
|
|
||||||
// Check if the statement ends with a semicolon
|
|
||||||
if (preg_match('/;\s*$/', $line)) {
|
|
||||||
$sqlStatements[] = $statement;
|
|
||||||
$statement = '';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Parse the CREATE TABLE statements
|
|
||||||
$sqlTables = [];
|
|
||||||
|
|
||||||
foreach ($sqlStatements as $sql) {
|
|
||||||
if (preg_match('/CREATE TABLE\s+`?([^` ]+)`?\s*\((.*)\)(.*?);/msi', $sql, $match)) {
|
|
||||||
$tableName = $match[1];
|
|
||||||
$columnsDefinition = $match[2];
|
|
||||||
|
|
||||||
// Extract column names and data types
|
|
||||||
$columns = [];
|
|
||||||
$columnLines = explode("\n", $columnsDefinition);
|
|
||||||
foreach ($columnLines as $line) {
|
|
||||||
$line = trim($line);
|
|
||||||
// Skip empty lines and lines that do not define columns
|
|
||||||
if ($line == '' || strpos($line, 'PRIMARY KEY') !== false || strpos($line, 'UNIQUE KEY') !== false || strpos($line, 'KEY') === 0 || strpos($line, 'CONSTRAINT') === 0 || strpos($line, ')') === 0) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Remove trailing comma if present
|
|
||||||
$line = rtrim($line, ',');
|
|
||||||
|
|
||||||
// Match column definition
|
|
||||||
if (preg_match('/^`([^`]+)`\s+(.+)/', $line, $colMatch)) {
|
|
||||||
$colName = $colMatch[1];
|
|
||||||
$colDefinition = $colMatch[2];
|
|
||||||
|
|
||||||
// Extract the data type from the column definition
|
|
||||||
$tokens = preg_split('/\s+/', $colDefinition);
|
|
||||||
$colType = $tokens[0];
|
|
||||||
|
|
||||||
// Handle data types with parentheses (e.g., varchar(255), decimal(15,2))
|
|
||||||
if (preg_match('/^([a-zA-Z]+)\(([^)]+)\)/', $colType, $typeMatch)) {
|
|
||||||
$colType = $typeMatch[1] . '(' . $typeMatch[2] . ')';
|
|
||||||
}
|
|
||||||
|
|
||||||
$columns[$colName] = $colType;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
$sqlTables[$tableName] = $columns;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Get current database table structures
|
|
||||||
$dbTables = [];
|
|
||||||
$tablesResult = $mysqli->query("SHOW TABLES");
|
|
||||||
while ($row = $tablesResult->fetch_row()) {
|
|
||||||
$tableName = $row[0];
|
|
||||||
$columnsResult = $mysqli->query("SHOW COLUMNS FROM `$tableName`");
|
|
||||||
$columns = [];
|
|
||||||
while ($col = $columnsResult->fetch_assoc()) {
|
|
||||||
$columns[$col['Field']] = $col['Type'];
|
|
||||||
}
|
|
||||||
$columnsResult->free();
|
|
||||||
$dbTables[$tableName] = $columns;
|
|
||||||
}
|
|
||||||
$tablesResult->free();
|
|
||||||
|
|
||||||
// Compare the structures
|
|
||||||
foreach ($sqlTables as $tableName => $sqlColumns) {
|
|
||||||
if (!isset($dbTables[$tableName])) {
|
|
||||||
$dbComparison[] = [
|
|
||||||
'name' => "Table `$tableName` missing in database",
|
|
||||||
'status' => 'Missing Table',
|
|
||||||
];
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Compare columns
|
|
||||||
$dbColumns = $dbTables[$tableName];
|
|
||||||
foreach ($sqlColumns as $colName => $colType) {
|
|
||||||
if (!isset($dbColumns[$colName])) {
|
|
||||||
$dbComparison[] = [
|
|
||||||
'name' => "Column `$colName` missing in table `$tableName`",
|
|
||||||
'status' => 'Missing Column',
|
|
||||||
];
|
|
||||||
} else {
|
|
||||||
// Normalize data types for comparison
|
|
||||||
$sqlColType = strtolower($colType);
|
|
||||||
$dbColType = strtolower($dbColumns[$colName]);
|
|
||||||
|
|
||||||
// Remove attributes and constraints
|
|
||||||
$sqlColType = preg_replace('/\s+.*$/', '', $sqlColType);
|
|
||||||
$dbColType = preg_replace('/\s+.*$/', '', $dbColType);
|
|
||||||
|
|
||||||
// Remove additional attributes like unsigned, zerofill, etc.
|
|
||||||
$sqlColType = preg_replace('/\s+unsigned|\s+zerofill|\s+binary/', '', $sqlColType);
|
|
||||||
$dbColType = preg_replace('/\s+unsigned|\s+zerofill|\s+binary/', '', $dbColType);
|
|
||||||
|
|
||||||
if ($sqlColType != $dbColType) {
|
|
||||||
$dbComparison[] = [
|
|
||||||
'name' => "Data type mismatch for `$colName` in table `$tableName`",
|
|
||||||
'status' => "Expected: $colType, Found: {$dbColumns[$colName]}",
|
|
||||||
];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Check for extra columns in the database that are not in the SQL file
|
|
||||||
foreach ($dbColumns as $colName => $colType) {
|
|
||||||
if (!isset($sqlColumns[$colName])) {
|
|
||||||
$dbComparison[] = [
|
|
||||||
'name' => "Extra column `$colName` in table `$tableName` not present in db.sql",
|
|
||||||
'status' => 'Extra Column',
|
|
||||||
];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Check for tables in the database not present in the db.sql file
|
|
||||||
foreach ($dbTables as $tableName => $dbColumns) {
|
|
||||||
if (!isset($sqlTables[$tableName])) {
|
|
||||||
$dbComparison[] = [
|
|
||||||
'name' => "Extra table `$tableName` in database not present in db.sql",
|
|
||||||
'status' => 'Extra Table',
|
|
||||||
];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
$dbComparison[] = [
|
|
||||||
'name' => 'db.sql file not found',
|
|
||||||
'status' => 'File Missing',
|
|
||||||
];
|
|
||||||
}
|
|
||||||
|
|
||||||
$mysqli->close();
|
|
||||||
?>
|
|
||||||
|
|
||||||
<div class="card card-dark">
|
|
||||||
<div class="card-header py-3">
|
|
||||||
<h3 class="card-title"><i class="fas fa-fw fa-bug mr-2"></i>Debug</h3>
|
|
||||||
</div>
|
|
||||||
<div class="card-body">
|
|
||||||
|
|
||||||
<h2>Debugging</h2>
|
|
||||||
<ul>
|
|
||||||
<li>If you are experiencing a problem with ITFlow, this page should help you identify any configuration issues.</li>
|
|
||||||
<li>Note: You might also need to gather <a href="https://docs.itflow.org/gathering_logs#error_logs">error logs</a></li>
|
|
||||||
</ul>
|
|
||||||
<hr>
|
|
||||||
|
|
||||||
<table class="table table-bordered mb-3">
|
|
||||||
<tr>
|
|
||||||
<th>ITFlow release version</th>
|
|
||||||
<th><?php echo APP_VERSION; ?></th>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>Current DB Version</td>
|
|
||||||
<td><?php echo CURRENT_DATABASE_VERSION; ?></td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>Current Code Commit</td>
|
|
||||||
<td><?php echo $commitHash; ?></td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>Current Branch</td>
|
|
||||||
<td><?php echo $gitBranch; ?></td>
|
|
||||||
</tr>
|
|
||||||
</table>
|
|
||||||
|
|
||||||
<!-- System Information Table -->
|
|
||||||
<h3>System Information</h3>
|
|
||||||
<table class="table table-sm table-bordered">
|
|
||||||
<tbody>
|
|
||||||
<?php foreach ($systemInfo as $info): ?>
|
|
||||||
<tr>
|
|
||||||
<td><?= htmlspecialchars($info['name']); ?></td>
|
|
||||||
<td><?= htmlspecialchars($info['value']); ?></td>
|
|
||||||
</tr>
|
|
||||||
<?php endforeach; ?>
|
|
||||||
</tbody>
|
|
||||||
</table>
|
|
||||||
|
|
||||||
<!-- PHP Extensions and Configuration Table -->
|
|
||||||
<h3 class="mt-3">PHP Extensions and Configuration</h3>
|
|
||||||
<table class="table table-sm table-bordered">
|
|
||||||
<!-- PHP Extensions Section -->
|
|
||||||
<thead>
|
|
||||||
<tr class="table-secondary">
|
|
||||||
<th colspan="3">PHP Extensions</th>
|
|
||||||
</tr>
|
|
||||||
</thead>
|
|
||||||
<tbody>
|
|
||||||
<?php foreach ($phpExtensions as $check): ?>
|
|
||||||
<tr>
|
|
||||||
<td><?= htmlspecialchars($check['name']); ?></td>
|
|
||||||
<td class="text-center">
|
|
||||||
<?php if ($check['passed']): ?>
|
|
||||||
<i class="fas fa-check" style="color:green"></i>
|
|
||||||
<?php else: ?>
|
|
||||||
<i class="fas fa-times" style="color:red"></i>
|
|
||||||
<?php endif; ?>
|
|
||||||
</td>
|
|
||||||
<td><?= htmlspecialchars($check['value']); ?></td>
|
|
||||||
</tr>
|
|
||||||
<?php endforeach; ?>
|
|
||||||
</tbody>
|
|
||||||
<!-- PHP Configuration Section -->
|
|
||||||
<thead>
|
|
||||||
<tr class="table-secondary">
|
|
||||||
<th colspan="3">PHP Configuration</th>
|
|
||||||
</tr>
|
|
||||||
</thead>
|
|
||||||
<tbody>
|
|
||||||
<?php foreach ($phpConfig as $check): ?>
|
|
||||||
<tr>
|
|
||||||
<td><?= htmlspecialchars($check['name']); ?></td>
|
|
||||||
<td class="text-center">
|
|
||||||
<?php if ($check['passed']): ?>
|
|
||||||
<i class="fas fa-check" style="color:green"></i>
|
|
||||||
<?php else: ?>
|
|
||||||
<i class="fas fa-times" style="color:red"></i>
|
|
||||||
<?php endif; ?>
|
|
||||||
</td>
|
|
||||||
<td><?= htmlspecialchars($check['value']); ?></td>
|
|
||||||
</tr>
|
|
||||||
<?php endforeach; ?>
|
|
||||||
</tbody>
|
|
||||||
<thead>
|
|
||||||
<tr class="table-secondary">
|
|
||||||
<th colspan="3">Shell Commands</th>
|
|
||||||
</tr>
|
|
||||||
</thead>
|
|
||||||
<tbody>
|
|
||||||
<?php foreach ($shellCommands as $check): ?>
|
|
||||||
<tr>
|
|
||||||
<td><?= htmlspecialchars($check['name']); ?></td>
|
|
||||||
<td class="text-center">
|
|
||||||
<?php if ($check['passed']): ?>
|
|
||||||
<i class="fas fa-check" style="color:green"></i>
|
|
||||||
<?php else: ?>
|
|
||||||
<i class="fas fa-times" style="color:red"></i>
|
|
||||||
<?php endif; ?>
|
|
||||||
</td>
|
|
||||||
<td><?= htmlspecialchars($check['value']); ?></td>
|
|
||||||
</tr>
|
|
||||||
<?php endforeach; ?>
|
|
||||||
</tbody>
|
|
||||||
<thead>
|
|
||||||
<tr class="table-secondary">
|
|
||||||
<th colspan="3">SSL Checks</th>
|
|
||||||
</tr>
|
|
||||||
</thead>
|
|
||||||
<tbody>
|
|
||||||
<?php foreach ($sslChecks as $check): ?>
|
|
||||||
<tr>
|
|
||||||
<td><?= htmlspecialchars($check['name']); ?></td>
|
|
||||||
<td class="text-center">
|
|
||||||
<?php if ($check['passed']): ?>
|
|
||||||
<i class="fas fa-check" style="color:green"></i>
|
|
||||||
<?php else: ?>
|
|
||||||
<i class="fas fa-times" style="color:red"></i>
|
|
||||||
<?php endif; ?>
|
|
||||||
</td>
|
|
||||||
<td><?= htmlspecialchars($check['value']); ?></td>
|
|
||||||
</tr>
|
|
||||||
<?php endforeach; ?>
|
|
||||||
</tbody>
|
|
||||||
<thead>
|
|
||||||
<tr class="table-secondary">
|
|
||||||
<th colspan="3">Domain Checks</th>
|
|
||||||
</tr>
|
|
||||||
</thead>
|
|
||||||
<tbody>
|
|
||||||
<?php foreach ($domainChecks as $check): ?>
|
|
||||||
<tr>
|
|
||||||
<td><?= htmlspecialchars($check['name']); ?></td>
|
|
||||||
<td class="text-center">
|
|
||||||
<?php if ($check['passed']): ?>
|
|
||||||
<i class="fas fa-check" style="color:green"></i>
|
|
||||||
<?php else: ?>
|
|
||||||
<i class="fas fa-times" style="color:red"></i>
|
|
||||||
<?php endif; ?>
|
|
||||||
</td>
|
|
||||||
<td><?= htmlspecialchars($check['value']); ?></td>
|
|
||||||
</tr>
|
|
||||||
<?php endforeach; ?>
|
|
||||||
</tbody>
|
|
||||||
|
|
||||||
<!-- File Permissions Table -->
|
|
||||||
<thead>
|
|
||||||
<tr class="table-secondary">
|
|
||||||
<th colspan="3">File Permissions</th>
|
|
||||||
</tr>
|
|
||||||
</thead>
|
|
||||||
<tbody>
|
|
||||||
<?php foreach ($filePermissions as $check): ?>
|
|
||||||
<tr>
|
|
||||||
<td><?= htmlspecialchars($check['name']); ?></td>
|
|
||||||
<td class="text-center">
|
|
||||||
<?php if ($check['passed']): ?>
|
|
||||||
<i class="fas fa-check" style="color:green"></i>
|
|
||||||
<?php else: ?>
|
|
||||||
<i class="fas fa-times" style="color:red"></i>
|
|
||||||
<?php endif; ?>
|
|
||||||
</td>
|
|
||||||
<td><?= htmlspecialchars($check['value']); ?></td>
|
|
||||||
</tr>
|
|
||||||
<?php endforeach; ?>
|
|
||||||
</tbody>
|
|
||||||
</table>
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<!-- Database Structure Comparison Table -->
|
|
||||||
<h3 class="mt-3">Database Structure Comparison</h3>
|
|
||||||
<table class="table table-sm table-bordered">
|
|
||||||
<tbody>
|
|
||||||
<?php if (!empty($dbComparison)): ?>
|
|
||||||
<?php foreach ($dbComparison as $issue): ?>
|
|
||||||
<tr>
|
|
||||||
<td><?= htmlspecialchars($issue['name']); ?></td>
|
|
||||||
<td colspan="2"><?= htmlspecialchars($issue['status']); ?></td>
|
|
||||||
</tr>
|
|
||||||
<?php endforeach; ?>
|
|
||||||
<?php else: ?>
|
|
||||||
<tr>
|
|
||||||
<td colspan="3">No discrepancies found between the database and db.sql file.</td>
|
|
||||||
</tr>
|
|
||||||
<?php endif; ?>
|
|
||||||
</tbody>
|
|
||||||
</table>
|
|
||||||
|
|
||||||
<!-- Uploads Directory Stats Table -->
|
|
||||||
<h3 class="mt-3">Uploads Directory Stats</h3>
|
|
||||||
<table class="table table-sm table-bordered">
|
|
||||||
<tbody>
|
|
||||||
<?php foreach ($uploadsStats as $stat): ?>
|
|
||||||
<tr>
|
|
||||||
<td><?= htmlspecialchars($stat['name']); ?></td>
|
|
||||||
<td colspan="2"><?= htmlspecialchars($stat['value']); ?></td>
|
|
||||||
</tr>
|
|
||||||
<?php endforeach; ?>
|
|
||||||
</tbody>
|
|
||||||
</table>
|
|
||||||
|
|
||||||
<!-- Database Stats Table -->
|
|
||||||
<h3 class="mt-3">Database Stats</h3>
|
|
||||||
<table class="table table-sm table-bordered">
|
|
||||||
<tbody>
|
|
||||||
<?php foreach ($databaseStats as $stat): ?>
|
|
||||||
<tr>
|
|
||||||
<td><?= htmlspecialchars($stat['name']); ?></td>
|
|
||||||
<td colspan="2"><?= htmlspecialchars($stat['value']); ?></td>
|
|
||||||
</tr>
|
|
||||||
<?php endforeach; ?>
|
|
||||||
</tbody>
|
|
||||||
</table>
|
|
||||||
|
|
||||||
<!-- Table Stats Table -->
|
|
||||||
<h3 class="mt-3">Table Stats</h3>
|
|
||||||
<table class="table table-sm table-bordered">
|
|
||||||
<thead>
|
|
||||||
<tr>
|
|
||||||
<th>Table Name</th>
|
|
||||||
<th>Fields / Rows</th>
|
|
||||||
<th>Size (MB)</th>
|
|
||||||
</tr>
|
|
||||||
</thead>
|
|
||||||
<tbody>
|
|
||||||
<?php foreach ($tableDetails as $table): ?>
|
|
||||||
<tr>
|
|
||||||
<td><?= htmlspecialchars($table['name']); ?></td>
|
|
||||||
<td><?= htmlspecialchars("Fields: {$table['fields']}, Rows: {$table['rows']}"); ?></td>
|
|
||||||
<td><?= htmlspecialchars($table['size'] . ' MB'); ?></td>
|
|
||||||
</tr>
|
|
||||||
<?php endforeach; ?>
|
|
||||||
</tbody>
|
|
||||||
</table>
|
|
||||||
|
|
||||||
</div>
|
|
||||||
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<?php
|
|
||||||
|
|
||||||
require_once "includes/footer.php";
|
|
||||||
|
|
||||||
@@ -1,170 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
// Default Column Sort by Filter
|
|
||||||
$sort = "document_name";
|
|
||||||
$order = "ASC";
|
|
||||||
|
|
||||||
require_once "includes/inc_all_admin.php";
|
|
||||||
|
|
||||||
// Search query SQL snippet
|
|
||||||
if (!empty($q)) {
|
|
||||||
$query_snippet = "AND (MATCH(document_content_raw) AGAINST ('$q') OR document_name LIKE '%$q%')";
|
|
||||||
} else {
|
|
||||||
$query_snippet = ""; // empty
|
|
||||||
}
|
|
||||||
|
|
||||||
// Rebuild URL
|
|
||||||
$url_query_strings_sort = http_build_query($get_copy);
|
|
||||||
|
|
||||||
$sql = mysqli_query(
|
|
||||||
$mysqli,
|
|
||||||
"SELECT SQL_CALC_FOUND_ROWS * FROM documents
|
|
||||||
LEFT JOIN users ON document_created_by = user_id
|
|
||||||
WHERE document_template = 1
|
|
||||||
$query_snippet
|
|
||||||
ORDER BY $sort $order LIMIT $record_from, $record_to"
|
|
||||||
);
|
|
||||||
|
|
||||||
$num_rows = mysqli_fetch_row(mysqli_query($mysqli, "SELECT FOUND_ROWS()"));
|
|
||||||
|
|
||||||
?>
|
|
||||||
|
|
||||||
<div class="card card-dark">
|
|
||||||
<div class="card-header py-2">
|
|
||||||
<h3 class="card-title mt-2"><i class="fa fa-fw fa-file mr-2"></i>Document Templates</h3>
|
|
||||||
<div class="card-tools">
|
|
||||||
<button type="button" class="btn btn-primary" data-toggle="modal" data-target="#addDocumentTemplateModal">
|
|
||||||
<i class="fas fa-plus mr-2"></i>New Template
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="card-body">
|
|
||||||
|
|
||||||
<form autocomplete="off">
|
|
||||||
<div class="input-group">
|
|
||||||
<input type="search" class="form-control " name="q" value="<?php if (isset($q)) { echo stripslashes(nullable_htmlentities($q)); } ?>" placeholder="Search templates">
|
|
||||||
<div class="input-group-append">
|
|
||||||
<button class="btn btn-secondary"><i class="fa fa-search"></i></button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</form>
|
|
||||||
<hr>
|
|
||||||
|
|
||||||
<div class="table-responsive-sm">
|
|
||||||
<table class="table table-striped table-borderless table-hover">
|
|
||||||
<thead class="text-dark <?php if ($num_rows[0] == 0) { echo "d-none"; } ?>">
|
|
||||||
<tr>
|
|
||||||
<th>
|
|
||||||
<a class="text-secondary" href="?<?php echo $url_query_strings_sort; ?>&sort=document_name&order=<?php echo $disp; ?>">
|
|
||||||
Template Name <?php if ($sort == 'document_name') { echo $order_icon; } ?>
|
|
||||||
</a>
|
|
||||||
</th>
|
|
||||||
<th>
|
|
||||||
<a class="text-secondary" href="?<?php echo $url_query_strings_sort; ?>&sort=document_created_at&order=<?php echo $disp; ?>">
|
|
||||||
Created <?php if ($sort == 'document_created_at') { echo $order_icon; } ?>
|
|
||||||
</a>
|
|
||||||
</th>
|
|
||||||
<th>
|
|
||||||
<a class="text-secondary" href="?<?php echo $url_query_strings_sort; ?>&sort=document_updated_at&order=<?php echo $disp; ?>">
|
|
||||||
Updated <?php if ($sort == 'document_updated_at') { echo $order_icon; } ?>
|
|
||||||
</a>
|
|
||||||
</th>
|
|
||||||
<th class="text-center">
|
|
||||||
Action
|
|
||||||
</th>
|
|
||||||
</tr>
|
|
||||||
</thead>
|
|
||||||
<tbody>
|
|
||||||
<?php
|
|
||||||
|
|
||||||
while ($row = mysqli_fetch_array($sql)) {
|
|
||||||
$document_id = intval($row['document_id']);
|
|
||||||
$document_name = nullable_htmlentities($row['document_name']);
|
|
||||||
$document_description = nullable_htmlentities($row['document_description']);
|
|
||||||
$document_content = nullable_htmlentities($row['document_content']);
|
|
||||||
$document_created_by_name = nullable_htmlentities($row['user_name']);
|
|
||||||
$document_created_at = nullable_htmlentities($row['document_created_at']);
|
|
||||||
$document_updated_at = nullable_htmlentities($row['document_updated_at']);
|
|
||||||
$document_folder_id = intval($row['document_folder_id']);
|
|
||||||
|
|
||||||
?>
|
|
||||||
|
|
||||||
<tr>
|
|
||||||
<td>
|
|
||||||
<a class="text-bold" href="admin_document_template_details.php?document_id=<?php echo $document_id; ?>"><i class="fas fa-fw fa-file-alt text-dark"></i> <?php echo $document_name; ?></a>
|
|
||||||
<div class="mt-1 text-secondary"><?php echo $document_description; ?></div>
|
|
||||||
</td>
|
|
||||||
<td>
|
|
||||||
<?php echo $document_created_at; ?>
|
|
||||||
<div class="text-secondary"><?php echo $document_created_by_name; ?></div>
|
|
||||||
</td>
|
|
||||||
<td><?php echo $document_updated_at; ?></td>
|
|
||||||
<td>
|
|
||||||
<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>
|
|
||||||
<div class="dropdown-menu">
|
|
||||||
<a class="dropdown-item" href="#" data-toggle="modal" data-target="#editDocumentTemplateModal<?php echo $document_id; ?>">
|
|
||||||
<i class="fas fa-fw fa-edit mr-2"></i>Edit
|
|
||||||
</a>
|
|
||||||
<div class="dropdown-divider"></div>
|
|
||||||
<a class="dropdown-item text-danger text-bold" href="post.php?delete_document=<?php echo $document_id; ?>">
|
|
||||||
<i class="fas fa-fw fa-trash mr-2"></i>Delete
|
|
||||||
</a>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
|
|
||||||
<?php
|
|
||||||
|
|
||||||
require "modals/admin_document_template_edit_modal.php";
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
?>
|
|
||||||
|
|
||||||
</tbody>
|
|
||||||
</table>
|
|
||||||
<br>
|
|
||||||
</div>
|
|
||||||
<?php require_once "includes/filter_footer.php"; ?>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<?php require_once "modals/admin_document_template_add_modal.php"; ?>
|
|
||||||
<?php require_once "includes/footer.php"; ?>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
$(document).ready(function(){
|
|
||||||
|
|
||||||
$('#generateAIContent').on('click', function(){
|
|
||||||
var prompt = $('#aiPrompt').val().trim();
|
|
||||||
if(prompt === '') {
|
|
||||||
alert('Please enter a prompt.');
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
$('#generateAIContent').prop('disabled', true).html('<i class="fa fa-spinner fa-spin"></i> Generating...');
|
|
||||||
|
|
||||||
$.ajax({
|
|
||||||
url: 'post.php?ai_create_document_template', // The PHP script that calls the OpenAI API
|
|
||||||
method: 'POST',
|
|
||||||
data: { prompt: prompt },
|
|
||||||
dataType: 'html',
|
|
||||||
success: function(response) {
|
|
||||||
// Assuming you have exactly one TinyMCE instance on the page
|
|
||||||
// and it's targeting the .tinymce textarea:
|
|
||||||
tinymce.activeEditor.setContent(response);
|
|
||||||
},
|
|
||||||
error: function() {
|
|
||||||
alert('Error generating content. Please try again.');
|
|
||||||
},
|
|
||||||
complete: function() {
|
|
||||||
$('#generateAIContent').prop('disabled', false).html('<i class="fa fa-fw fa-magic mr-1"></i>Generate with AI');
|
|
||||||
}
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
</script>
|
|
||||||
@@ -1,66 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
require_once "includes/inc_all_admin.php";
|
|
||||||
|
|
||||||
|
|
||||||
//Initialize the HTML Purifier to prevent XSS
|
|
||||||
require "plugins/htmlpurifier/HTMLPurifier.standalone.php";
|
|
||||||
|
|
||||||
$purifier_config = HTMLPurifier_Config::createDefault();
|
|
||||||
$purifier_config->set('Cache.DefinitionImpl', null); // Disable cache by setting a non-existent directory or an invalid one
|
|
||||||
$purifier_config->set('URI.AllowedSchemes', ['data' => true, 'src' => true, 'http' => true, 'https' => true]);
|
|
||||||
$purifier = new HTMLPurifier($purifier_config);
|
|
||||||
|
|
||||||
if (isset($_GET['document_id'])) {
|
|
||||||
$document_id = intval($_GET['document_id']);
|
|
||||||
}
|
|
||||||
|
|
||||||
$sql_document = mysqli_query($mysqli, "SELECT * FROM documents WHERE document_template = 1 AND document_id = $document_id");
|
|
||||||
|
|
||||||
$row = mysqli_fetch_array($sql_document);
|
|
||||||
|
|
||||||
$document_name = nullable_htmlentities($row['document_name']);
|
|
||||||
$document_description = nullable_htmlentities($row['document_description']);
|
|
||||||
$document_content = $purifier->purify($row['document_content']);
|
|
||||||
$document_created_at = nullable_htmlentities($row['document_created_at']);
|
|
||||||
$document_updated_at = nullable_htmlentities($row['document_updated_at']);
|
|
||||||
|
|
||||||
?>
|
|
||||||
|
|
||||||
<ol class="breadcrumb d-print-none">
|
|
||||||
<li class="breadcrumb-item">
|
|
||||||
<a href="clients.php">Home</a>
|
|
||||||
</li>
|
|
||||||
<li class="breadcrumb-item">
|
|
||||||
<a href="admin_user.php">Admin</a>
|
|
||||||
</li>
|
|
||||||
<li class="breadcrumb-item">
|
|
||||||
<a href="admin_document_template.php">Document Templates</a>
|
|
||||||
</li>
|
|
||||||
<li class="breadcrumb-item active"><i class="fas fa-file mr-2"></i><?php echo $document_name; ?></li>
|
|
||||||
</ol>
|
|
||||||
|
|
||||||
<div class="card card-dark">
|
|
||||||
<div class="card-header">
|
|
||||||
|
|
||||||
<h3 class="card-title mt-2"><i class="fa fa-fw fa-file mr-2"></i><?php echo $document_name; ?></h3>
|
|
||||||
|
|
||||||
<div class="card-tools">
|
|
||||||
<button type="button" class="btn btn-primary" data-toggle="modal" data-target="#editDocumentTemplateModal<?php echo $document_id; ?>">
|
|
||||||
<i class="fas fa-edit mr-2"></i>Edit
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="card-body prettyContent">
|
|
||||||
<?php echo $document_content; ?>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<script src="js/pretty_content.js"></script>
|
|
||||||
|
|
||||||
<?php
|
|
||||||
|
|
||||||
require_once "modals/admin_document_template_edit_modal.php";
|
|
||||||
|
|
||||||
require_once "includes/footer.php";
|
|
||||||
|
|
||||||
@@ -1,213 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
// Default Column Sortby Filter
|
|
||||||
$sort = "email_id";
|
|
||||||
$order = "DESC";
|
|
||||||
|
|
||||||
require_once "includes/inc_all_admin.php";
|
|
||||||
|
|
||||||
//Rebuild URL
|
|
||||||
$url_query_strings_sort = http_build_query($get_copy);
|
|
||||||
|
|
||||||
$sql = mysqli_query(
|
|
||||||
$mysqli,
|
|
||||||
"SELECT SQL_CALC_FOUND_ROWS * FROM email_queue
|
|
||||||
WHERE (email_id LIKE '%$q%' OR email_from LIKE '%$q%' OR email_from_name LIKE '%$q%' OR email_recipient LIKE '%$q%' OR email_recipient_name LIKE '%$q%' OR email_subject LIKE '%$q%')
|
|
||||||
AND DATE(email_queued_at) BETWEEN '$dtf' AND '$dtt'
|
|
||||||
ORDER BY $sort $order LIMIT $record_from, $record_to"
|
|
||||||
);
|
|
||||||
|
|
||||||
$num_rows = mysqli_fetch_row(mysqli_query($mysqli, "SELECT FOUND_ROWS()"));
|
|
||||||
|
|
||||||
?>
|
|
||||||
|
|
||||||
<div class="card card-dark">
|
|
||||||
<div class="card-header py-3">
|
|
||||||
<h3 class="card-title"><i class="fas fa-fw fa-mail-bulk mr-2"></i>Email Queue</h3>
|
|
||||||
</div>
|
|
||||||
<div class="card-body">
|
|
||||||
<form class="mb-4" autocomplete="off">
|
|
||||||
<div class="row">
|
|
||||||
<div class="col-sm-4">
|
|
||||||
<div class="input-group">
|
|
||||||
<input type="search" class="form-control" name="q" value="<?php if (isset($q)) { echo stripslashes(nullable_htmlentities($q)); } ?>" placeholder="Search mail queue">
|
|
||||||
<div class="input-group-append">
|
|
||||||
<button class="btn btn-secondary" type="button" data-toggle="collapse" data-target="#advancedFilter"><i class="fas fa-filter"></i></button>
|
|
||||||
<button class="btn btn-primary"><i class="fa fa-search"></i></button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="col-sm-8">
|
|
||||||
<div class="dropdown float-right" id="bulkActionButton" hidden>
|
|
||||||
<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>)
|
|
||||||
</button>
|
|
||||||
<div class="dropdown-menu">
|
|
||||||
<button class="dropdown-item"
|
|
||||||
type="submit" form="bulkActions" name="bulk_cancel_emails">
|
|
||||||
<i class="fas fa-fw fa-ban mr-2"></i>Cancel
|
|
||||||
</button>
|
|
||||||
<div class="dropdown-divider"></div>
|
|
||||||
<button class="dropdown-item text-danger text-bold"
|
|
||||||
type="submit" form="bulkActions" name="bulk_delete_emails">
|
|
||||||
<i class="fas fa-fw fa-trash mr-2"></i>Delete
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="collapse mt-3 <?php if (!empty($_GET['dtf']) || $_GET['canned_date'] !== "custom" ) { echo "show"; } ?>" id="advancedFilter">
|
|
||||||
<div class="row">
|
|
||||||
<div class="col-md-2">
|
|
||||||
<div class="form-group">
|
|
||||||
<label>Canned Date</label>
|
|
||||||
<select onchange="this.form.submit()" class="form-control select2" name="canned_date">
|
|
||||||
<option <?php if ($_GET['canned_date'] == "custom") { echo "selected"; } ?> value="">Custom</option>
|
|
||||||
<option <?php if ($_GET['canned_date'] == "today") { echo "selected"; } ?> value="today">Today</option>
|
|
||||||
<option <?php if ($_GET['canned_date'] == "yesterday") { echo "selected"; } ?> value="yesterday">Yesterday</option>
|
|
||||||
<option <?php if ($_GET['canned_date'] == "thisweek") { echo "selected"; } ?> value="thisweek">This Week</option>
|
|
||||||
<option <?php if ($_GET['canned_date'] == "lastweek") { echo "selected"; } ?> value="lastweek">Last Week</option>
|
|
||||||
<option <?php if ($_GET['canned_date'] == "thismonth") { echo "selected"; } ?> value="thismonth">This Month</option>
|
|
||||||
<option <?php if ($_GET['canned_date'] == "lastmonth") { echo "selected"; } ?> value="lastmonth">Last Month</option>
|
|
||||||
<option <?php if ($_GET['canned_date'] == "thisyear") { echo "selected"; } ?> value="thisyear">This Year</option>
|
|
||||||
<option <?php if ($_GET['canned_date'] == "lastyear") { echo "selected"; } ?> value="lastyear">Last Year</option>
|
|
||||||
</select>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="col-md-2">
|
|
||||||
<div class="form-group">
|
|
||||||
<label>Date From</label>
|
|
||||||
<input onchange="this.form.submit()" type="date" class="form-control" name="dtf" max="2999-12-31" value="<?php echo nullable_htmlentities($dtf); ?>">
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="col-md-2">
|
|
||||||
<div class="form-group">
|
|
||||||
<label>Date To</label>
|
|
||||||
<input onchange="this.form.submit()" type="date" class="form-control" name="dtt" max="2999-12-31" value="<?php echo nullable_htmlentities($dtt); ?>">
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</form>
|
|
||||||
<hr>
|
|
||||||
<form id="bulkActions" action="post.php" method="post">
|
|
||||||
<input type="hidden" name="csrf_token" value="<?php echo $_SESSION['csrf_token'] ?>">
|
|
||||||
|
|
||||||
<div class="table-responsive-sm">
|
|
||||||
<table class="table table-sm table-striped table-borderless table-hover">
|
|
||||||
<thead class="text-dark <?php if ($num_rows[0] == 0) { echo "d-none"; } ?>">
|
|
||||||
<tr>
|
|
||||||
<td class="bg-light pr-0">
|
|
||||||
<div class="form-check">
|
|
||||||
<input class="form-check-input" id="selectAllCheckbox" type="checkbox" onclick="checkAll(this)">
|
|
||||||
</div>
|
|
||||||
</td>
|
|
||||||
<th>
|
|
||||||
<a class="text-dark" href="?<?php echo $url_query_strings_sort; ?>&sort=email_queued_at&order=<?php echo $disp; ?>">
|
|
||||||
Queued <?php if ($sort == 'email_queued_at') { echo $order_icon; } ?>
|
|
||||||
</a>
|
|
||||||
</th>
|
|
||||||
<th>
|
|
||||||
<a class="text-dark" href="?<?php echo $url_query_strings_sort; ?>&sort=email_from&order=<?php echo $disp; ?>">
|
|
||||||
From <?php if ($sort == 'email_from') { echo $order_icon; } ?>
|
|
||||||
</a>
|
|
||||||
</th>
|
|
||||||
<th>
|
|
||||||
<a class="text-dark" href="?<?php echo $url_query_strings_sort; ?>&sort=email_recipient&order=<?php echo $disp; ?>">
|
|
||||||
To <?php if ($sort == 'email_recipient') { echo $order_icon; } ?>
|
|
||||||
</a>
|
|
||||||
</th>
|
|
||||||
<th>
|
|
||||||
<a class="text-dark" href="?<?php echo $url_query_strings_sort; ?>&sort=email_subject&order=<?php echo $disp; ?>">
|
|
||||||
Subject <?php if ($sort == 'email_subject') { echo $order_icon; } ?>
|
|
||||||
</a>
|
|
||||||
</th>
|
|
||||||
<th>
|
|
||||||
<a class="text-dark" href="?<?php echo $url_query_strings_sort; ?>&sort=email_status&order=<?php echo $disp; ?>">
|
|
||||||
Status <?php if ($sort == 'email_status') { echo $order_icon; } ?>
|
|
||||||
</a>
|
|
||||||
</th>
|
|
||||||
<th>
|
|
||||||
<a class="text-dark" href="?<?php echo $url_query_strings_sort; ?>&sort=email_attempts&order=<?php echo $disp; ?>">
|
|
||||||
Attempts <?php if ($sort == 'email_attempts') { echo $order_icon; } ?>
|
|
||||||
</a>
|
|
||||||
</th>
|
|
||||||
<th class="text-center">Action</th>
|
|
||||||
</tr>
|
|
||||||
</thead>
|
|
||||||
<tbody>
|
|
||||||
<?php
|
|
||||||
|
|
||||||
while ($row = mysqli_fetch_array($sql)) {
|
|
||||||
$email_id = intval($row['email_id']);
|
|
||||||
$email_from = nullable_htmlentities($row['email_from']);
|
|
||||||
$email_from_name = nullable_htmlentities($row['email_from_name']);
|
|
||||||
$email_recipient = nullable_htmlentities($row['email_recipient']);
|
|
||||||
$email_recipient_name = nullable_htmlentities($row['email_recipient_name']);
|
|
||||||
$email_subject = nullable_htmlentities($row['email_subject']);
|
|
||||||
$email_attempts = intval($row['email_attempts']);
|
|
||||||
$email_queued_at = nullable_htmlentities($row['email_queued_at']);
|
|
||||||
$email_failed_at = nullable_htmlentities($row['email_failed_at']);
|
|
||||||
$email_sent_at = nullable_htmlentities($row['email_sent_at']);
|
|
||||||
$email_status = intval($row['email_status']);
|
|
||||||
if ($email_status == 0) {
|
|
||||||
$email_status_display = "<div class='text-primary'>Queued</div>";
|
|
||||||
} elseif($email_status == 1) {
|
|
||||||
$email_status_display = "<div class='text-warning'>Sending</div>";
|
|
||||||
} elseif($email_status == 2) {
|
|
||||||
$email_status_display = "<div class='text-danger'>Failed</div><small class='text-secondary'>$email_failed_at</small>";
|
|
||||||
} else {
|
|
||||||
$email_status_display = "<div class='text-success'>Sent</div><small class='text-secondary'>$email_sent_at</small>";
|
|
||||||
}
|
|
||||||
|
|
||||||
?>
|
|
||||||
|
|
||||||
<tr>
|
|
||||||
<td class="pr-0 bg-light">
|
|
||||||
<?php if ($email_status !== 3) { ?>
|
|
||||||
<div class="form-check">
|
|
||||||
<input class="form-check-input bulk-select" type="checkbox" name="email_ids[]" value="<?php echo $email_id ?>">
|
|
||||||
</div>
|
|
||||||
<?php } ?>
|
|
||||||
</td>
|
|
||||||
<td><?php echo $email_queued_at; ?></td>
|
|
||||||
<td><?php echo "$email_from<br><small class='text-secondary'>$email_from_name</small>"?></td>
|
|
||||||
<td><?php echo "$email_recipient<br><small class='text-secondary'>$email_recipient_name</small>"?></td>
|
|
||||||
<td><?php echo $email_subject; ?></td>
|
|
||||||
<td><?php echo $email_status_display; ?></td>
|
|
||||||
<td><?php echo $email_attempts; ?></td>
|
|
||||||
<td class="text-center">
|
|
||||||
<a class="btn btn-sm btn-secondary" href="admin_mail_queue_message_view.php?email_id=<?php echo $email_id; ?>">
|
|
||||||
<i class="fas fa-fw fa-eye"></i>
|
|
||||||
</a>
|
|
||||||
|
|
||||||
<!-- Show force resend if all retries have failed -->
|
|
||||||
<?php if ($email_status == 2 && $email_attempts > 3) { ?>
|
|
||||||
<a class="btn btn-sm btn-success" href="post.php?send_failed_mail=<?php echo $email_id; ?>"><i class="fas fa-fw fa-paper-plane"></i></a>
|
|
||||||
<?php } ?>
|
|
||||||
|
|
||||||
<!-- Allow cancelling a message if it hasn't yet been picked up (e.g. stuck/bugged) -->
|
|
||||||
<?php if ($email_status !== 3) { ?>
|
|
||||||
<a class="btn btn-sm btn-danger confirm-link" href="post.php?cancel_mail=<?php echo $email_id; ?>"><i class="fas fa-fw fa-trash"></i></a>
|
|
||||||
<?php } ?>
|
|
||||||
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
|
|
||||||
<?php
|
|
||||||
}
|
|
||||||
?>
|
|
||||||
|
|
||||||
</tbody>
|
|
||||||
</table>
|
|
||||||
</div>
|
|
||||||
</form>
|
|
||||||
|
|
||||||
<?php require_once "includes/filter_footer.php"; ?>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<script src="js/bulk_actions.js"></script>
|
|
||||||
|
|
||||||
<?php
|
|
||||||
require_once "includes/footer.php";
|
|
||||||
@@ -1,78 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
require_once "includes/inc_all_admin.php";
|
|
||||||
|
|
||||||
//Initialize the HTML Purifier to prevent XSS
|
|
||||||
require "plugins/htmlpurifier/HTMLPurifier.standalone.php";
|
|
||||||
|
|
||||||
$purifier_config = HTMLPurifier_Config::createDefault();
|
|
||||||
$purifier_config->set('Cache.DefinitionImpl', null); // Disable cache by setting a non-existent directory or an invalid one
|
|
||||||
$purifier_config->set('URI.AllowedSchemes', ['data' => true, 'src' => true, 'http' => true, 'https' => true]);
|
|
||||||
$purifier = new HTMLPurifier($purifier_config);
|
|
||||||
|
|
||||||
if (isset($_GET['email_id'])) {
|
|
||||||
$email_id = intval($_GET['email_id']);
|
|
||||||
} else {
|
|
||||||
echo "You dont belong here";
|
|
||||||
exit();
|
|
||||||
}
|
|
||||||
|
|
||||||
$sql = mysqli_query($mysqli, "SELECT * FROM email_queue WHERE email_id = $email_id");
|
|
||||||
|
|
||||||
$row = mysqli_fetch_array($sql);
|
|
||||||
|
|
||||||
$email_from = nullable_htmlentities($row['email_from']);
|
|
||||||
$email_from_name = nullable_htmlentities($row['email_from_name']);
|
|
||||||
$email_recipient = nullable_htmlentities($row['email_recipient']);
|
|
||||||
$email_recipient_name = nullable_htmlentities($row['email_recipient_name']);
|
|
||||||
$email_subject = nullable_htmlentities($row['email_subject']);
|
|
||||||
$email_content = $purifier->purify($row['email_content']);
|
|
||||||
$email_attempts = intval($row['email_attempts']);
|
|
||||||
$email_queued_at = nullable_htmlentities($row['email_queued_at']);
|
|
||||||
$email_failed_at = nullable_htmlentities($row['email_failed_at']);
|
|
||||||
$email_sent_at = nullable_htmlentities($row['email_sent_at']);
|
|
||||||
$email_status = intval($row['email_status']);
|
|
||||||
if ($email_status == 0) {
|
|
||||||
$email_status_display = "<div class='text-primary'>Queued</div>";
|
|
||||||
} elseif($email_status == 1) {
|
|
||||||
$email_status_display = "<div class='text-warning'>Sending</div>";
|
|
||||||
} elseif($email_status == 2) {
|
|
||||||
$email_status_display = "<div class='text-danger'>Failed</div><small class='text-secondary'>$email_failed_at</small>";
|
|
||||||
} else {
|
|
||||||
$email_status_display = "<div class='text-success'>Sent</div><small class='text-secondary'>$email_sent_at</small>";
|
|
||||||
}
|
|
||||||
|
|
||||||
?>
|
|
||||||
|
|
||||||
<ol class="breadcrumb d-print-none">
|
|
||||||
<li class="breadcrumb-item">
|
|
||||||
<a href="admin_user.php"><i class="fas fa-fw fa-user-shield mr-2"></i>Admin</a>
|
|
||||||
</li>
|
|
||||||
<li class="breadcrumb-item">
|
|
||||||
<a href="admin_mail_queue.php"><i class="fas fa-fw fa-mail-bulk mr-2"></i>Mail Queue</a>
|
|
||||||
</li>
|
|
||||||
<li class="breadcrumb-item active"><i class="fas fa-fw fa-envelope-open mr-2"></i><?php echo $email_subject; ?></li>
|
|
||||||
</ol>
|
|
||||||
|
|
||||||
<div class="row">
|
|
||||||
|
|
||||||
<div class="col-md-12">
|
|
||||||
<div class="card">
|
|
||||||
<div class="card-header bg-dark">
|
|
||||||
<div>From: <?php echo "$email_from_name <small>($email_from)</small>"; ?></div>
|
|
||||||
<div>To: <?php echo "$email_recipient_name <small>($email_recipient)</small>"; ?></div>
|
|
||||||
<div>Subject: <?php echo $email_subject; ?></div>
|
|
||||||
</div>
|
|
||||||
<div class="card-body prettyContent">
|
|
||||||
<?php echo $email_content; ?>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<script src="js/pretty_content.js"></script>
|
|
||||||
|
|
||||||
<?php
|
|
||||||
|
|
||||||
require_once "includes/footer.php";
|
|
||||||
@@ -1,149 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
// Default Column Sortby Filter
|
|
||||||
$sort = "project_template_name";
|
|
||||||
$order = "ASC";
|
|
||||||
|
|
||||||
require_once "includes/inc_all_admin.php";
|
|
||||||
|
|
||||||
|
|
||||||
//Rebuild URL
|
|
||||||
$url_query_strings_sort = http_build_query($get_copy);
|
|
||||||
|
|
||||||
$sql = mysqli_query(
|
|
||||||
$mysqli,
|
|
||||||
"SELECT SQL_CALC_FOUND_ROWS * FROM project_templates
|
|
||||||
WHERE (project_template_name LIKE '%$q%' OR project_template_description LIKE '%$q%')
|
|
||||||
AND project_template_archived_at IS NULL
|
|
||||||
ORDER BY $sort $order LIMIT $record_from, $record_to"
|
|
||||||
);
|
|
||||||
|
|
||||||
$num_rows = mysqli_fetch_row(mysqli_query($mysqli, "SELECT FOUND_ROWS()"));
|
|
||||||
|
|
||||||
?>
|
|
||||||
|
|
||||||
<div class="card card-dark">
|
|
||||||
<div class="card-header py-2">
|
|
||||||
<h3 class="card-title mt-2"><i class="fas fa-fw fa-project-diagram mr-2"></i>Project Templates</h3>
|
|
||||||
<div class="card-tools">
|
|
||||||
<button type="button" class="btn btn-primary" data-toggle="modal" data-target="#addProjectTemplateModal"><i class="fas fa-plus mr-2"></i>New Project Template</button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="card-body">
|
|
||||||
<form autocomplete="off">
|
|
||||||
<div class="row">
|
|
||||||
|
|
||||||
<div class="col-md-4">
|
|
||||||
<div class="input-group mb-3 mb-md-0">
|
|
||||||
<input type="search" class="form-control" name="q" value="<?php if(isset($q)){ echo stripslashes(nullable_htmlentities($q)); } ?>" placeholder="Search Project Templates">
|
|
||||||
<div class="input-group-append">
|
|
||||||
<button class="btn btn-dark"><i class="fa fa-search"></i></button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="col-md-8">
|
|
||||||
</div>
|
|
||||||
|
|
||||||
</div>
|
|
||||||
</form>
|
|
||||||
<hr>
|
|
||||||
<div class="table-responsive-sm">
|
|
||||||
<table class="table table-striped table-borderless table-hover">
|
|
||||||
<thead class="text-dark <?php if($num_rows[0] == 0){ echo "d-none"; } ?>">
|
|
||||||
<tr>
|
|
||||||
<th>
|
|
||||||
<a class="text-secondary" href="?<?php echo $url_query_strings_sort; ?>&sort=project_template_name&order=<?php echo $disp; ?>">
|
|
||||||
Template <?php if ($sort == 'project_template_name') { echo $order_icon; } ?>
|
|
||||||
</a>
|
|
||||||
</th>
|
|
||||||
<th>Tickets</th>
|
|
||||||
<th>Tasks</th>
|
|
||||||
<th class="text-center">Action</th>
|
|
||||||
</tr>
|
|
||||||
</thead>
|
|
||||||
<tbody>
|
|
||||||
<?php
|
|
||||||
|
|
||||||
while($row = mysqli_fetch_array($sql)){
|
|
||||||
$project_template_id = intval($row['project_template_id']);
|
|
||||||
$project_template_name = nullable_htmlentities($row['project_template_name']);
|
|
||||||
$project_template_description = nullable_htmlentities($row['project_template_description']);
|
|
||||||
$project_template_created_at = nullable_htmlentities($row['project_template_created_at']);
|
|
||||||
|
|
||||||
// Get Ticket Template Count
|
|
||||||
$sql_ticket_templates = mysqli_query($mysqli, "SELECT * FROM ticket_templates, project_template_ticket_templates
|
|
||||||
WHERE ticket_templates.ticket_template_id = project_template_ticket_templates.ticket_template_id
|
|
||||||
AND project_template_ticket_templates.project_template_id = $project_template_id
|
|
||||||
ORDER BY ticket_template_order ASC, ticket_template_name ASC");
|
|
||||||
$ticket_template_count = mysqli_num_rows($sql_ticket_templates);
|
|
||||||
|
|
||||||
// Get Tasks Template Count
|
|
||||||
$sql_task_templates = mysqli_query($mysqli,
|
|
||||||
"SELECT * FROM ticket_templates, task_templates, project_template_ticket_templates
|
|
||||||
WHERE ticket_templates.ticket_template_id = project_template_ticket_templates.ticket_template_id
|
|
||||||
AND project_template_ticket_templates.project_template_id = $project_template_id
|
|
||||||
AND ticket_templates.ticket_template_id = task_template_ticket_template_id
|
|
||||||
ORDER BY task_template_created_at ASC"
|
|
||||||
);
|
|
||||||
$task_template_count = mysqli_num_rows($sql_task_templates);
|
|
||||||
|
|
||||||
?>
|
|
||||||
<tr>
|
|
||||||
<td>
|
|
||||||
<a class="text-dark" href="#" data-toggle="modal" data-target="#editProjectTemplateModal<?php echo $project_template_id; ?>">
|
|
||||||
<div class="media">
|
|
||||||
<i class="fa fa-fw fa-2x fa-project-diagram mr-3"></i>
|
|
||||||
<div class="media-body">
|
|
||||||
<div>
|
|
||||||
<a href="admin_project_template_details.php?project_template_id=<?php echo $project_template_id; ?>">
|
|
||||||
<?php echo $project_template_name; ?>
|
|
||||||
</a>
|
|
||||||
</div>
|
|
||||||
<div><small class="text-secondary"><?php echo $project_template_description; ?></small></div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</a>
|
|
||||||
</td>
|
|
||||||
<td><?php echo $ticket_template_count; ?></td>
|
|
||||||
<td><?php echo $task_template_count; ?></td>
|
|
||||||
<td>
|
|
||||||
<div class="dropdown dropleft text-center">
|
|
||||||
<button class="btn btn-secondary btn-sm" data-toggle="dropdown">
|
|
||||||
<i class="fas fa-ellipsis-h"></i>
|
|
||||||
</button>
|
|
||||||
<div class="dropdown-menu">
|
|
||||||
<a class="dropdown-item" href="#" data-toggle="modal" data-target="#editProjectTemplateModal<?php echo $project_template_id; ?>">
|
|
||||||
<i class="fas fa-fw fa-edit mr-2"></i>Edit
|
|
||||||
</a>
|
|
||||||
<?php if($session_user_role == 3) { ?>
|
|
||||||
<div class="dropdown-divider"></div>
|
|
||||||
<a class="dropdown-item text-danger text-bold confirm-link" href="post.php?delete_project_template=<?php echo $project_template_id; ?>">
|
|
||||||
<i class="fas fa-fw fa-trash mr-2"></i>Delete
|
|
||||||
</a>
|
|
||||||
<?php } ?>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
|
|
||||||
<?php
|
|
||||||
|
|
||||||
require "modals/admin_project_template_edit_modal.php";
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
?>
|
|
||||||
|
|
||||||
</tbody>
|
|
||||||
</table>
|
|
||||||
</div>
|
|
||||||
<?php require_once "includes/filter_footer.php";
|
|
||||||
?>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<?php
|
|
||||||
require_once "modals/admin_project_template_add_modal.php";
|
|
||||||
|
|
||||||
require_once "includes/footer.php";
|
|
||||||
@@ -1,234 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
require_once "includes/inc_all_admin.php";
|
|
||||||
|
|
||||||
|
|
||||||
if (isset($_GET['project_template_id'])) {
|
|
||||||
$project_template_id = intval($_GET['project_template_id']);
|
|
||||||
|
|
||||||
$sql_project_templates = mysqli_query(
|
|
||||||
$mysqli,
|
|
||||||
"SELECT * FROM project_templates
|
|
||||||
WHERE project_template_id = $project_template_id LIMIT 1"
|
|
||||||
);
|
|
||||||
|
|
||||||
if (mysqli_num_rows($sql_project_templates) == 0) {
|
|
||||||
echo "<center><h1 class='text-secondary mt-5'>Nothing to see here</h1><a class='btn btn-lg btn-secondary mt-3' href='admin_project_template.php'><i class='fa fa-fw fa-arrow-left'></i> Go Back</a></center>";
|
|
||||||
|
|
||||||
include_once "footer.php";
|
|
||||||
exit;
|
|
||||||
}
|
|
||||||
|
|
||||||
$row = mysqli_fetch_array($sql_project_templates);
|
|
||||||
|
|
||||||
$project_template_name = nullable_htmlentities($row['project_template_name']);
|
|
||||||
$project_template_description = nullable_htmlentities($row['project_template_description']);
|
|
||||||
$project_template_created_at = date("Y-m-d", strtotime($row['project_template_created_at']));
|
|
||||||
$project_template_updated_at = nullable_htmlentities($row['project_template_updated_at']);
|
|
||||||
|
|
||||||
// Get Associated Ticket Templates
|
|
||||||
$sql_ticket_templates = mysqli_query($mysqli, "SELECT * FROM ticket_templates, project_template_ticket_templates
|
|
||||||
WHERE ticket_templates.ticket_template_id = project_template_ticket_templates.ticket_template_id
|
|
||||||
AND project_template_ticket_templates.project_template_id = $project_template_id
|
|
||||||
ORDER BY ticket_template_order ASC, ticket_template_name ASC");
|
|
||||||
$ticket_template_count = mysqli_num_rows($sql_ticket_templates);
|
|
||||||
|
|
||||||
// Get All Task Templates
|
|
||||||
$sql_task_templates = mysqli_query($mysqli,
|
|
||||||
"SELECT * FROM ticket_templates, task_templates, project_template_ticket_templates
|
|
||||||
WHERE ticket_templates.ticket_template_id = project_template_ticket_templates.ticket_template_id
|
|
||||||
AND project_template_ticket_templates.project_template_id = $project_template_id
|
|
||||||
AND ticket_templates.ticket_template_id = task_template_ticket_template_id
|
|
||||||
ORDER BY task_template_created_at ASC"
|
|
||||||
);
|
|
||||||
$task_template_count = mysqli_num_rows($sql_task_templates);
|
|
||||||
|
|
||||||
?>
|
|
||||||
|
|
||||||
<!-- Breadcrumbs-->
|
|
||||||
<ol class="breadcrumb d-print-none">
|
|
||||||
<li class="breadcrumb-item">
|
|
||||||
<a href="admin_user.php">Admin</a>
|
|
||||||
</li>
|
|
||||||
<li class="breadcrumb-item">
|
|
||||||
<a href="admin_project_template.php">Project Templates</a>
|
|
||||||
</li>
|
|
||||||
<li class="breadcrumb-item active">Project Template Details</li>
|
|
||||||
</ol>
|
|
||||||
|
|
||||||
<!-- Project Header -->
|
|
||||||
<div class="card card-body">
|
|
||||||
<div class="row">
|
|
||||||
<div class="col-sm-4">
|
|
||||||
<div class="media">
|
|
||||||
<i class="fa fa-fw fa-2x fa-project-diagram text-secondary mr-3"></i>
|
|
||||||
<div class="media-body">
|
|
||||||
<h3 class="mb-0"><?php echo $project_template_name; ?><span class='badge badge-pill badge-info ml-2'>Template</span></h3>
|
|
||||||
<div><small class="text-secondary"><?php echo $project_template_description; ?></small></div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="col-sm-3">
|
|
||||||
<div class="media">
|
|
||||||
<i class="fa fa-fw fa-2x fa-life-ring text-secondary mr-3"></i>
|
|
||||||
<div class="media-body">
|
|
||||||
<div>Ticket Templates</div>
|
|
||||||
<h3 class="mb-0"><?php echo $ticket_template_count; ?></h3>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="col-sm-3">
|
|
||||||
<div class="media">
|
|
||||||
<i class="fa fa-fw fa-2x fa-tasks text-secondary mr-3"></i>
|
|
||||||
<div class="media-body">
|
|
||||||
<div>Task Templates</div>
|
|
||||||
<h3 class="mb-0"><?php echo $task_template_count; ?></h3>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="col-sm-2">
|
|
||||||
<div class="btn-group float-right">
|
|
||||||
<button type="button" class="btn btn-primary btn-sm" href="#" data-toggle="modal" data-target="#addProjectTemplateTicketTemplateModal">
|
|
||||||
<i class="fas fa-fw fa-plus mr-2"></i>Add Ticket Template
|
|
||||||
</button>
|
|
||||||
<div class="dropdown dropleft text-center ml-3">
|
|
||||||
<button class="btn btn-secondary btn-sm" type="button" id="dropdownMenuButton" data-toggle="dropdown">
|
|
||||||
<i class="fas fa-fw fa-ellipsis-v"></i>
|
|
||||||
</button>
|
|
||||||
<div class="dropdown-menu" aria-labelledby="dropdownMenuButton">
|
|
||||||
<a class="dropdown-item" href="#" data-toggle="modal" data-target="#editProjectTemplateModal<?php echo $project_template_id; ?>">
|
|
||||||
<i class="fas fa-fw fa-edit mr-2"></i>Edit Template
|
|
||||||
</a>
|
|
||||||
<?php if ($session_user_role == 3) { ?>
|
|
||||||
<div class="dropdown-divider"></div>
|
|
||||||
<a class="dropdown-item text-danger text-bold confirm-link" href="post.php?archive_project_template=<?php echo $project_template_id; ?>">
|
|
||||||
<i class="fas fa-fw fa-archive mr-2"></i>Archive (not yet implemented)
|
|
||||||
</a>
|
|
||||||
<?php } ?>
|
|
||||||
<?php if ($session_user_role == 3) { ?>
|
|
||||||
<div class="dropdown-divider"></div>
|
|
||||||
<a class="dropdown-item text-danger confirm-link" href="post.php?delete_project_template=<?php echo $project_template_id; ?>">
|
|
||||||
<i class="fas fa-fw fa-trash mr-2"></i>Delete
|
|
||||||
</a>
|
|
||||||
<?php } ?>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="row">
|
|
||||||
<div class="col-md-8">
|
|
||||||
|
|
||||||
<!-- Tickets card -->
|
|
||||||
<?php if (mysqli_num_rows($sql_ticket_templates) > 0) { ?>
|
|
||||||
<div class="card card-body card-outline card-dark mb-3">
|
|
||||||
|
|
||||||
<h5 class="text-secondary"><i class="fa fa-fw fa-life-ring mr-2"></i>Project Ticket Templates</h5>
|
|
||||||
<div class="table-responsive-sm">
|
|
||||||
<table class="table table-striped table-borderless table-hover">
|
|
||||||
<thead class="text-dark">
|
|
||||||
<tr>
|
|
||||||
<th>Order</th>
|
|
||||||
<th>Template Name</th>
|
|
||||||
<th>Description</th>
|
|
||||||
<th>Ticket Subject</th>
|
|
||||||
<th>Action</th>
|
|
||||||
</tr>
|
|
||||||
</thead>
|
|
||||||
<tbody>
|
|
||||||
<?php
|
|
||||||
|
|
||||||
while ($row = mysqli_fetch_array($sql_ticket_templates)) {
|
|
||||||
$ticket_template_id = intval($row['ticket_template_id']);
|
|
||||||
$ticket_template_order = intval($row['ticket_template_order']);
|
|
||||||
$ticket_template_name = nullable_htmlentities($row['ticket_template_name']);
|
|
||||||
$ticket_template_description = nullable_htmlentities($row['ticket_template_description']);
|
|
||||||
$ticket_template_subject = nullable_htmlentities($row['ticket_template_subject']);
|
|
||||||
$ticket_template_created_at = nullable_htmlentities($row['ticket_template_created_at']);
|
|
||||||
$ticket_template_updated_at = nullable_htmlentities($row['ticket_template_updated_at']);
|
|
||||||
|
|
||||||
?>
|
|
||||||
|
|
||||||
<tr>
|
|
||||||
<td class="pr-0">
|
|
||||||
<form action="post.php" method="post" autocomplete="off">
|
|
||||||
<input type="hidden" name="edit_ticket_template_order">
|
|
||||||
<input type="hidden" name="project_template_id" value="<?php echo $project_template_id; ?>">
|
|
||||||
<input type="hidden" name="ticket_template_id" value="<?php echo $ticket_template_id; ?>">
|
|
||||||
<input type="text" class="form-control pr-0" onchange="this.form.submit()" name="order" value="<?php echo $ticket_template_order; ?>">
|
|
||||||
</form>
|
|
||||||
</td>
|
|
||||||
<td>
|
|
||||||
<a href="admin_ticket_template_details.php?ticket_template_id=<?php echo $ticket_template_id; ?>">
|
|
||||||
<?php echo $ticket_template_name; ?>
|
|
||||||
</a>
|
|
||||||
</td>
|
|
||||||
<td><?php echo $ticket_template_description; ?></td>
|
|
||||||
<td><?php echo $ticket_template_subject; ?></td>
|
|
||||||
<td>
|
|
||||||
<form action="post.php" method="post" autocomplete="off">
|
|
||||||
<input type="hidden" name="project_template_id" value="<?php echo $project_template_id; ?>">
|
|
||||||
<input type="hidden" name="ticket_template_id" value="<?php echo $ticket_template_id; ?>">
|
|
||||||
<button type="submit" class="btn btn-default btn-sm confirm-link"
|
|
||||||
name="remove_ticket_template_from_project_template">
|
|
||||||
<i class="fa fa-fw fa-times"></i>
|
|
||||||
</button>
|
|
||||||
</form>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
|
|
||||||
<?php } ?>
|
|
||||||
|
|
||||||
</tbody>
|
|
||||||
</table>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<?php } ?>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="col-md-4">
|
|
||||||
|
|
||||||
<!-- Task Templates Card -->
|
|
||||||
<?php if (mysqli_num_rows($sql_task_templates) > 0) { ?>
|
|
||||||
<div class="card card-body card-outline card-dark">
|
|
||||||
<h5 class="text-secondary"><i class="fas fa-fw fa-tasks mr-2"></i>Project Task Templates</h5>
|
|
||||||
<table class="table">
|
|
||||||
<?php
|
|
||||||
while($row = mysqli_fetch_array($sql_task_templates)){
|
|
||||||
$task_template_id = intval($row['task_template_id']);
|
|
||||||
$task_template_name = nullable_htmlentities($row['task_template_name']);
|
|
||||||
$task_template_description = nullable_htmlentities($row['task_template_description']);
|
|
||||||
?>
|
|
||||||
<tr>
|
|
||||||
<td>
|
|
||||||
<i class="far fa-fw fa-check-square text-primary mr-3"></i>
|
|
||||||
<?php echo $task_template_name; ?>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
<?php } ?>
|
|
||||||
</table>
|
|
||||||
</div>
|
|
||||||
<?php } ?>
|
|
||||||
<!-- End Task TemplatesCard -->
|
|
||||||
|
|
||||||
</div> <!-- End col-3 -->
|
|
||||||
|
|
||||||
</div> <!-- End row -->
|
|
||||||
|
|
||||||
<?php
|
|
||||||
|
|
||||||
require_once "modals/admin_project_template_edit_modal.php";
|
|
||||||
require_once "modals/admin_project_template_ticket_template_add_modal.php";
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
require_once "includes/footer.php";
|
|
||||||
|
|
||||||
?>
|
|
||||||
|
|
||||||
<script src="js/pretty_content.js"></script>
|
|
||||||
156
admin_role.php
156
admin_role.php
@@ -1,156 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
// Default Column Sortby Filter
|
|
||||||
$sort = "user_role_is_admin";
|
|
||||||
$order = "DESC";
|
|
||||||
|
|
||||||
require_once "includes/inc_all_admin.php";
|
|
||||||
|
|
||||||
|
|
||||||
//Rebuild URL
|
|
||||||
$url_query_strings_sort = http_build_query($get_copy);
|
|
||||||
|
|
||||||
$sql = mysqli_query(
|
|
||||||
$mysqli,
|
|
||||||
"SELECT SQL_CALC_FOUND_ROWS * FROM user_roles
|
|
||||||
WHERE (user_roles.user_role_name LIKE '%$q%' OR user_roles.user_role_description LIKE '%$q%')
|
|
||||||
AND user_roles.user_role_archived_at IS NULL
|
|
||||||
ORDER BY $sort $order LIMIT $record_from, $record_to"
|
|
||||||
);
|
|
||||||
|
|
||||||
$num_rows = mysqli_fetch_row(mysqli_query($mysqli, "SELECT FOUND_ROWS()"));
|
|
||||||
|
|
||||||
?>
|
|
||||||
<div class="alert alert-info text-center"><strong>Roles are still in development. Permissions may not be fully enforced.</strong></div>
|
|
||||||
|
|
||||||
<div class="card card-dark">
|
|
||||||
<div class="card-header py-2">
|
|
||||||
<h3 class="card-title mt-2"><i class="fas fa-fw fa-user-shield mr-2"></i>Roles</h3>
|
|
||||||
<div class="card-tools">
|
|
||||||
<div class="btn-group">
|
|
||||||
<button type="button" class="btn btn-primary" data-toggle="modal" data-target="#addRoleModal">
|
|
||||||
<i class="fas fa-fw fa-user-plus mr-2"></i>New Role
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="card-body">
|
|
||||||
<form class="mb-4" autocomplete="off">
|
|
||||||
<div class="row">
|
|
||||||
<div class="col-md-4">
|
|
||||||
<div class="input-group">
|
|
||||||
<input type="search" class="form-control" name="q" value="<?php if (isset($q)) {echo stripslashes(nullable_htmlentities($q));} ?>" placeholder="Search Roles">
|
|
||||||
<div class="input-group-append">
|
|
||||||
<button class="btn btn-primary"><i class="fa fa-search"></i></button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</form>
|
|
||||||
<hr>
|
|
||||||
<div class="table-responsive-sm">
|
|
||||||
<table class="table table-striped table-borderless table-hover">
|
|
||||||
<thead class="text-dark <?php if ($num_rows[0] == 0) { echo "d-none"; } ?>">
|
|
||||||
<tr>
|
|
||||||
<th>
|
|
||||||
<a class="text-dark" href="?<?php echo $url_query_strings_sort; ?>&sort=user_role_name&order=<?php echo $disp; ?>">
|
|
||||||
Role <?php if ($sort == 'user_role_name') { echo $order_icon; } ?>
|
|
||||||
</a>
|
|
||||||
</th>
|
|
||||||
<th>Members</th>
|
|
||||||
<th>
|
|
||||||
<a class="text-dark" href="?<?php echo $url_query_strings_sort; ?>&sort=user_role_is_admin&order=<?php echo $disp; ?>">
|
|
||||||
Admin <?php if ($sort == 'user_role_is_admin') { echo $order_icon; } ?>
|
|
||||||
</a>
|
|
||||||
</th>
|
|
||||||
<th class="text-center">Action</th>
|
|
||||||
</tr>
|
|
||||||
</thead>
|
|
||||||
<tbody>
|
|
||||||
<?php
|
|
||||||
|
|
||||||
while ($row = mysqli_fetch_array($sql)) {
|
|
||||||
$role_id = intval($row['user_role_id']);
|
|
||||||
$role_name = nullable_htmlentities($row['user_role_name']);
|
|
||||||
$role_description = nullable_htmlentities($row['user_role_description']);
|
|
||||||
$role_admin = intval($row['user_role_is_admin']);
|
|
||||||
$role_archived_at = nullable_htmlentities($row['user_role_archived_at']);
|
|
||||||
|
|
||||||
// Count number of users that have each role
|
|
||||||
$sql_role_user_count = mysqli_query($mysqli, "SELECT COUNT(users.user_id) FROM users LEFT JOIN user_settings on users.user_id = user_settings.user_id WHERE user_role = $role_id AND user_archived_at IS NULL");
|
|
||||||
$role_user_count = mysqli_fetch_row($sql_role_user_count)[0];
|
|
||||||
|
|
||||||
$sql_users = mysqli_query($mysqli, "SELECT * FROM users LEFT JOIN user_settings on users.user_id = user_settings.user_id WHERE user_role = $role_id AND user_archived_at IS NULL");
|
|
||||||
// Initialize an empty array to hold user names
|
|
||||||
$user_names = [];
|
|
||||||
|
|
||||||
// Fetch each row and store the user_name in the array
|
|
||||||
while($row = mysqli_fetch_assoc($sql_users)) {
|
|
||||||
$user_names[] = nullable_htmlentities($row['user_name']);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Convert the array of user names to a comma-separated string
|
|
||||||
$user_names_string = implode(",", $user_names) ;
|
|
||||||
|
|
||||||
if (empty($user_names_string)) {
|
|
||||||
$user_names_string = "-";
|
|
||||||
}
|
|
||||||
|
|
||||||
?>
|
|
||||||
<tr>
|
|
||||||
<td>
|
|
||||||
<a class="text-dark text-bold" href="#" data-toggle="modal" data-target="#editRoleModal<?php echo $role_id; ?>">
|
|
||||||
<?php echo $role_name; ?>
|
|
||||||
</a>
|
|
||||||
<div class="text-secondary"><?php echo $role_description; ?></div>
|
|
||||||
</td>
|
|
||||||
<td><?php echo $user_names_string; ?></td>
|
|
||||||
<td><?php echo $role_admin ? 'Yes' : 'No' ; ?></td>
|
|
||||||
<td>
|
|
||||||
<?php if ($role_id !== 3) { ?>
|
|
||||||
<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>
|
|
||||||
<div class="dropdown-menu">
|
|
||||||
|
|
||||||
<a class="dropdown-item" href="#" data-toggle="modal" data-target="#editRoleModal<?php echo $role_id; ?>">
|
|
||||||
<i class="fas fa-fw fa-user-edit mr-2"></i>Edit
|
|
||||||
</a>
|
|
||||||
|
|
||||||
<?php if (empty($role_archived_at) && $role_user_count == 0) { ?>
|
|
||||||
<div class="dropdown-divider"></div>
|
|
||||||
<a class="dropdown-item text-danger confirm-link" href="post.php?archive_role=<?php echo $role_id; ?>&csrf_token=<?php echo $_SESSION['csrf_token'] ?>">
|
|
||||||
<i class="fas fa-fw fa-archive mr-2"></i>Archive
|
|
||||||
</a>
|
|
||||||
<?php } ?>
|
|
||||||
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<?php } ?>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
|
|
||||||
<?php
|
|
||||||
|
|
||||||
require "modals/admin_role_edit_modal.php";
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
?>
|
|
||||||
|
|
||||||
</tbody>
|
|
||||||
</table>
|
|
||||||
</div>
|
|
||||||
<?php require_once "includes/filter_footer.php";
|
|
||||||
?>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<?php
|
|
||||||
|
|
||||||
require_once "modals/admin_role_add_modal.php";
|
|
||||||
|
|
||||||
require_once "includes/footer.php";
|
|
||||||
|
|
||||||
@@ -1,77 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
require_once "includes/inc_all_admin.php";
|
|
||||||
?>
|
|
||||||
|
|
||||||
<div class="card card-dark">
|
|
||||||
<div class="card-header py-3">
|
|
||||||
<h3 class="card-title"><i class="fas fa-fw fa-robot mr-2"></i>AI</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'] ?>">
|
|
||||||
|
|
||||||
<div class="form-group">
|
|
||||||
<label>AI Provider</label>
|
|
||||||
<div class="input-group">
|
|
||||||
<div class="input-group-prepend">
|
|
||||||
<span class="input-group-text"><i class="fa fa-fw fa-robot"></i></span>
|
|
||||||
</div>
|
|
||||||
<select class="form-control select2" name="provider">
|
|
||||||
<option value="" <?php if($config_ai_enable == 0) { echo "selected"; } ?> >Disabled</option>
|
|
||||||
<option <?php if($config_ai_provider == "Ollama") { echo "selected"; } ?> >Ollama</option>
|
|
||||||
<option <?php if($config_ai_provider == "OpenAI") { echo "selected"; } ?> >OpenAI</option>
|
|
||||||
<option <?php if($config_ai_provider == "LocalAI") { echo "selected"; } ?> >LocalAI</option>
|
|
||||||
</select>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="form-group">
|
|
||||||
<label>AI Model</label>
|
|
||||||
<div class="input-group">
|
|
||||||
<div class="input-group-prepend">
|
|
||||||
<span class="input-group-text"><i class="fa fa-fw fa-robot"></i></span>
|
|
||||||
</div>
|
|
||||||
<input type="text" class="form-control" name="model" value="<?php echo nullable_htmlentities($config_ai_model); ?>" placeholder="ex gpt-4">
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="form-group">
|
|
||||||
<label>URL</label>
|
|
||||||
<div class="input-group">
|
|
||||||
<div class="input-group-prepend">
|
|
||||||
<span class="input-group-text"><i class="fa fa-fw fa-globe"></i></span>
|
|
||||||
</div>
|
|
||||||
<input type="url" class="form-control" name="url" value="<?php echo nullable_htmlentities($config_ai_url); ?>" placeholder="ex https://ai.company.ext/api">
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="form-group">
|
|
||||||
<label>API Key</label>
|
|
||||||
<div class="input-group">
|
|
||||||
<div class="input-group-prepend">
|
|
||||||
<span class="input-group-text"><i class="fa fa-fw fa-key"></i></span>
|
|
||||||
</div>
|
|
||||||
<input type="text" class="form-control" name="api_key" value="<?php echo nullable_htmlentities($config_ai_api_key); ?>" placeholder="Enter API key here">
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<hr>
|
|
||||||
|
|
||||||
<button type="submit" name="edit_ai_settings" class="btn btn-primary text-bold"><i class="fa fa-check mr-2"></i>Save</button>
|
|
||||||
|
|
||||||
</form>
|
|
||||||
|
|
||||||
<div class="mt-5">
|
|
||||||
<h5>Test AI Rewording</h5>
|
|
||||||
<textarea id="textInput" class="form-control tinymceAI mb-3" rows="10"></textarea>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<script src="js/ai_reword.js"></script>
|
|
||||||
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<?php
|
|
||||||
require_once "includes/footer.php";
|
|
||||||
|
|
||||||
@@ -1,124 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
// Default Column Sortby Filter
|
|
||||||
$sort = "custom_field_label";
|
|
||||||
$order = "ASC";
|
|
||||||
|
|
||||||
require_once "includes/inc_all_admin.php";
|
|
||||||
|
|
||||||
|
|
||||||
if (isset($_GET['table'])) {
|
|
||||||
$table = sanitizeInput($_GET['table']);
|
|
||||||
} else {
|
|
||||||
$table = "client_assets";
|
|
||||||
}
|
|
||||||
|
|
||||||
//Rebuild URL
|
|
||||||
$url_query_strings_sort = http_build_query($get_copy);
|
|
||||||
|
|
||||||
$sql = mysqli_query(
|
|
||||||
$mysqli,
|
|
||||||
"SELECT SQL_CALC_FOUND_ROWS * FROM custom_fields
|
|
||||||
WHERE custom_field_label LIKE '%$q%'
|
|
||||||
AND custom_field_table = '$table'
|
|
||||||
ORDER BY $sort $order LIMIT $record_from, $record_to"
|
|
||||||
);
|
|
||||||
|
|
||||||
$num_rows = mysqli_fetch_row(mysqli_query($mysqli, "SELECT FOUND_ROWS()"));
|
|
||||||
|
|
||||||
?>
|
|
||||||
|
|
||||||
|
|
||||||
<div class="card card-dark">
|
|
||||||
<div class="card-header py-2">
|
|
||||||
<h3 class="card-title mt-2"><i class="fa fa-fw fa-th-list mr-2"></i><?php echo nullable_htmlentities($table); ?> Fields</h3>
|
|
||||||
<div class="card-tools">
|
|
||||||
<button type="button" class="btn btn-primary" data-toggle="modal" data-target="#createCustomFieldModal"><i class="fas fa-plus mr-2"></i>Create</button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="card-body">
|
|
||||||
<form autocomplete="off">
|
|
||||||
<input type="hidden" name="table" value="<?php echo nullable_htmlentities($table); ?>">
|
|
||||||
<div class="row">
|
|
||||||
<div class="col-sm-4 mb-2">
|
|
||||||
<div class="input-group">
|
|
||||||
<input type="search" class="form-control" name="q" value="<?php if (isset($q)) { echo stripslashes(nullable_htmlentities($q)); } ?>" placeholder="Search">
|
|
||||||
<div class="input-group-append">
|
|
||||||
<button class="btn btn-primary"><i class="fa fa-search"></i></button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="col-sm-8">
|
|
||||||
<div class="btn-group float-right">
|
|
||||||
<a href="?table=client_assets" class="btn <?php if ($table == 'client_assets') { echo 'btn-primary'; } else { echo 'btn-default'; } ?>">Assets</a>
|
|
||||||
<a href="?table=clients" class="btn <?php if ($table == 'clients') { echo 'btn-primary'; } else { echo 'btn-default'; } ?>">Clients</a>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</form>
|
|
||||||
<hr>
|
|
||||||
<div class="table-responsive-sm">
|
|
||||||
<table class="table table-striped table-borderless table-hover">
|
|
||||||
<thead class="text-dark <?php if ($num_rows[0] == 0) { echo "d-none"; } ?>">
|
|
||||||
<tr>
|
|
||||||
<th><a class="text-dark" href="?<?php echo $url_query_strings_sort; ?>&sort=custom_field_label&order=<?php echo $disp; ?>">Label</a></th>
|
|
||||||
<th><a class="text-dark" href="?<?php echo $url_query_strings_sort; ?>&sort=custom_field_type&order=<?php echo $disp; ?>">Type</a></th>
|
|
||||||
<th class="text-center">Action</th>
|
|
||||||
</tr>
|
|
||||||
</thead>
|
|
||||||
<tbody>
|
|
||||||
<?php
|
|
||||||
|
|
||||||
while ($row = mysqli_fetch_array($sql)) {
|
|
||||||
$custom_field_id = intval($row['custom_field_id']);
|
|
||||||
$custom_field_label = nullable_htmlentities($row['custom_field_label']);
|
|
||||||
$custom_field_type = nullable_htmlentities($row['custom_field_type']);
|
|
||||||
$custom_field_location = intval($row['custom_field_location']);
|
|
||||||
$custom_field_order = intval($row['custom_field_order']);
|
|
||||||
|
|
||||||
?>
|
|
||||||
<tr>
|
|
||||||
<td><a class="text-dark" href="#" data-toggle="modal" data-target="#editCustomFieldModal<?php echo $custom_field_id; ?>"><?php echo $custom_field_label; ?></a></td>
|
|
||||||
<td><?php echo $custom_field_type; ?></td>
|
|
||||||
<td>
|
|
||||||
<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>
|
|
||||||
<div class="dropdown-menu">
|
|
||||||
<a class="dropdown-item" href="#" data-toggle="modal" data-target="#editCustomFieldModal<?php echo $custom_field_id; ?>">
|
|
||||||
<i class="fas fa-fw fa-edit mr-2"></i>Edit
|
|
||||||
</a>
|
|
||||||
<div class="dropdown-divider"></div>
|
|
||||||
<a class="dropdown-item text-danger text-bold confirm-link" href="post.php?delete_custom_field=<?php echo $custom_field_id; ?>">
|
|
||||||
<i class="fas fa-fw fa-trash mr-2"></i>Delete
|
|
||||||
</a>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
|
|
||||||
<?php
|
|
||||||
|
|
||||||
//$colors_diff = array_diff($colors_array,$colors_used_array);
|
|
||||||
|
|
||||||
include "custom_field_edit_modal.php";
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
?>
|
|
||||||
|
|
||||||
</tbody>
|
|
||||||
</table>
|
|
||||||
</div>
|
|
||||||
<?php require_once "includes/filter_footer.php";
|
|
||||||
?>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<?php
|
|
||||||
require_once "custom_field_create_modal.php";
|
|
||||||
|
|
||||||
require_once "includes/footer.php";
|
|
||||||
|
|
||||||
@@ -1,252 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
require_once "includes/inc_all_admin.php";
|
|
||||||
?>
|
|
||||||
|
|
||||||
<div class="card card-dark">
|
|
||||||
<div class="card-header py-3">
|
|
||||||
<h3 class="card-title"><i class="fas fa-fw fa-cogs mr-2"></i>Defaults</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'] ?>">
|
|
||||||
|
|
||||||
<div class="form-group">
|
|
||||||
<label>Start Page</label>
|
|
||||||
<div class="input-group">
|
|
||||||
<div class="input-group-prepend">
|
|
||||||
<span class="input-group-text"><i class="fa fa-fw fa-home"></i></span>
|
|
||||||
</div>
|
|
||||||
<select class="form-control select2" name="start_page" data-tags="true" required>
|
|
||||||
<?php if (!in_array($config_start_page, array_keys($start_page_select_array))) { ?>
|
|
||||||
<option selected> <?php echo nullable_htmlentities($config_start_page); ?></option>
|
|
||||||
<?php } ?>
|
|
||||||
<?php foreach ($start_page_select_array as $start_page_value => $start_page_name) { ?>
|
|
||||||
<option <?php if ($start_page_value == $config_start_page) { echo "selected"; } ?>
|
|
||||||
value="<?php echo nullable_htmlentities($start_page_value); ?>">
|
|
||||||
<?php echo nullable_htmlentities($start_page_name); ?>
|
|
||||||
</option>
|
|
||||||
<?php }?>
|
|
||||||
</select>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="form-group">
|
|
||||||
<label>Calendar</label>
|
|
||||||
<div class="input-group">
|
|
||||||
<div class="input-group-prepend">
|
|
||||||
<span class="input-group-text"><i class="fa fa-fw fa-calendar"></i></span>
|
|
||||||
</div>
|
|
||||||
<select class="form-control select2" name="calendar">
|
|
||||||
<option value="0">- None -</option>
|
|
||||||
<?php
|
|
||||||
|
|
||||||
$sql = mysqli_query($mysqli, "SELECT * FROM calendars ORDER BY calendar_name ASC");
|
|
||||||
while ($row = mysqli_fetch_array($sql)) {
|
|
||||||
$calendar_id = intval($row['calendar_id']);
|
|
||||||
$calendar_name = nullable_htmlentities($row['calendar_name']); ?>
|
|
||||||
<option <?php if ($config_default_calendar == $calendar_id) {
|
|
||||||
echo "selected";
|
|
||||||
} ?> value="<?php echo $calendar_id; ?>"><?php echo $calendar_name; ?></option>
|
|
||||||
<?php } ?>
|
|
||||||
|
|
||||||
</select>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="form-group">
|
|
||||||
<label>Transfer From Account</label>
|
|
||||||
<div class="input-group">
|
|
||||||
<div class="input-group-prepend">
|
|
||||||
<span class="input-group-text"><i class="fa fa-fw fa-exchange-alt"></i></span>
|
|
||||||
</div>
|
|
||||||
<select class="form-control select2" name="transfer_from_account">
|
|
||||||
<option value="0">- None -</option>
|
|
||||||
<?php
|
|
||||||
|
|
||||||
$sql = mysqli_query($mysqli, "SELECT * FROM accounts WHERE account_archived_at IS NULL ORDER BY account_name ASC");
|
|
||||||
while ($row = mysqli_fetch_array($sql)) {
|
|
||||||
$account_id = intval($row['account_id']);
|
|
||||||
$account_name = nullable_htmlentities($row['account_name']); ?>
|
|
||||||
<option <?php if ($config_default_transfer_from_account == $account_id) {
|
|
||||||
echo "selected";
|
|
||||||
} ?> value="<?php echo $account_id; ?>"><?php echo $account_name; ?></option>
|
|
||||||
<?php } ?>
|
|
||||||
|
|
||||||
</select>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="form-group">
|
|
||||||
<label>Transfer To Account</label>
|
|
||||||
<div class="input-group">
|
|
||||||
<div class="input-group-prepend">
|
|
||||||
<span class="input-group-text"><i class="fa fa-fw fa-exchange-alt"></i></span>
|
|
||||||
</div>
|
|
||||||
<select class="form-control select2" name="transfer_to_account">
|
|
||||||
<option value="0">- None -</option>
|
|
||||||
<?php
|
|
||||||
|
|
||||||
$sql = mysqli_query($mysqli, "SELECT * FROM accounts WHERE account_archived_at IS NULL ORDER BY account_name ASC");
|
|
||||||
while ($row = mysqli_fetch_array($sql)) {
|
|
||||||
$account_id = intval($row['account_id']);
|
|
||||||
$account_name = nullable_htmlentities($row['account_name']); ?>
|
|
||||||
<option <?php if ($config_default_transfer_to_account == $account_id) {
|
|
||||||
echo "selected";
|
|
||||||
} ?> value="<?php echo $account_id; ?>"><?php echo $account_name; ?></option>
|
|
||||||
<?php } ?>
|
|
||||||
|
|
||||||
</select>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="form-group">
|
|
||||||
<label>Payment Account</label>
|
|
||||||
<div class="input-group">
|
|
||||||
<div class="input-group-prepend">
|
|
||||||
<span class="input-group-text"><i class="fa fa-fw fa-credit-card"></i></span>
|
|
||||||
</div>
|
|
||||||
<select class="form-control select2" name="payment_account">
|
|
||||||
<option value="0">- None -</option>
|
|
||||||
<?php
|
|
||||||
|
|
||||||
$sql = mysqli_query($mysqli, "SELECT * FROM accounts WHERE account_archived_at IS NULL ORDER BY account_name ASC");
|
|
||||||
while ($row = mysqli_fetch_array($sql)) {
|
|
||||||
$account_id = intval($row['account_id']);
|
|
||||||
$account_name = nullable_htmlentities($row['account_name']); ?>
|
|
||||||
<option <?php if ($config_default_payment_account == $account_id) {
|
|
||||||
echo "selected";
|
|
||||||
} ?> value="<?php echo $account_id; ?>"><?php echo $account_name; ?></option>
|
|
||||||
<?php
|
|
||||||
}
|
|
||||||
?>
|
|
||||||
|
|
||||||
</select>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="form-group">
|
|
||||||
<label>Expense Account</label>
|
|
||||||
<div class="input-group">
|
|
||||||
<div class="input-group-prepend">
|
|
||||||
<span class="input-group-text"><i class="fa fa-fw fa-shopping-cart"></i></span>
|
|
||||||
</div>
|
|
||||||
<select class="form-control select2" name="expense_account">
|
|
||||||
<option value="0">- None -</option>
|
|
||||||
<?php
|
|
||||||
|
|
||||||
$sql = mysqli_query($mysqli, "SELECT * FROM accounts WHERE account_archived_at IS NULL ORDER BY account_name ASC");
|
|
||||||
while ($row = mysqli_fetch_array($sql)) {
|
|
||||||
$account_id = intval($row['account_id']);
|
|
||||||
$account_name = nullable_htmlentities($row['account_name']); ?>
|
|
||||||
<option <?php if ($config_default_expense_account == $account_id) {
|
|
||||||
echo "selected";
|
|
||||||
} ?> value="<?php echo $account_id; ?>"><?php echo $account_name; ?></option>
|
|
||||||
<?php } ?>
|
|
||||||
|
|
||||||
</select>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="form-group">
|
|
||||||
<label>Payment Method</label>
|
|
||||||
<div class="input-group">
|
|
||||||
<div class="input-group-prepend">
|
|
||||||
<span class="input-group-text"><i class="fa fa-fw fa-credit-card"></i></span>
|
|
||||||
</div>
|
|
||||||
<select class="form-control select2" name="payment_method">
|
|
||||||
<option value="">- None -</option>
|
|
||||||
<?php
|
|
||||||
|
|
||||||
$sql = mysqli_query($mysqli, "SELECT * FROM categories WHERE category_type = 'Payment Method' ORDER BY category_name ASC");
|
|
||||||
while ($row = mysqli_fetch_array($sql)) {
|
|
||||||
$payment_method = nullable_htmlentities($row['category_name']); ?>
|
|
||||||
<option <?php if ($config_default_payment_method == $payment_method) {
|
|
||||||
echo "selected";
|
|
||||||
} ?>><?php echo $payment_method; ?></option>
|
|
||||||
<?php } ?>
|
|
||||||
|
|
||||||
</select>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="form-group">
|
|
||||||
<label>Expense Payment Method</label>
|
|
||||||
<div class="input-group">
|
|
||||||
<div class="input-group-prepend">
|
|
||||||
<span class="input-group-text"><i class="fa fa-fw fa-credit-card"></i></span>
|
|
||||||
</div>
|
|
||||||
<select class="form-control select2" name="expense_payment_method">
|
|
||||||
<option value="">- None -</option>
|
|
||||||
<?php
|
|
||||||
|
|
||||||
$sql = mysqli_query($mysqli, "SELECT * FROM categories WHERE category_type = 'Payment Method' ORDER BY category_name ASC");
|
|
||||||
while ($row = mysqli_fetch_array($sql)) {
|
|
||||||
$payment_method = nullable_htmlentities($row['category_name']); ?>
|
|
||||||
<option <?php if ($config_default_expense_payment_method == $payment_method) {
|
|
||||||
echo "selected";
|
|
||||||
} ?>><?php echo $payment_method; ?></option>
|
|
||||||
<?php } ?>
|
|
||||||
|
|
||||||
</select>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="form-group">
|
|
||||||
<label>Net Terms</label>
|
|
||||||
<div class="input-group">
|
|
||||||
<div class="input-group-prepend">
|
|
||||||
<span class="input-group-text"><i class="fa fa-fw fa-calendar"></i></span>
|
|
||||||
</div>
|
|
||||||
<select class="form-control select2" name="net_terms">
|
|
||||||
<?php foreach ($net_terms_array as $net_term_value => $net_term_name) { ?>
|
|
||||||
<option <?php if ($config_default_net_terms == $net_term_value) {
|
|
||||||
echo "selected";
|
|
||||||
} ?> value="<?php echo $net_term_value; ?>"><?php echo $net_term_name; ?></option>
|
|
||||||
<?php } ?>
|
|
||||||
</select>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="form-group">
|
|
||||||
<label>Client Hourly Rate</label>
|
|
||||||
<div class="input-group">
|
|
||||||
<div class="input-group-prepend">
|
|
||||||
<span class="input-group-text"><i class="fa fa-fw fa-clock"></i></span>
|
|
||||||
</div>
|
|
||||||
<input type="text" class="form-control" inputmode="numeric" pattern="[0-9]*\.?[0-9]{0,2}" name="hourly_rate" value="<?php echo number_format($config_default_hourly_rate, 2, '.', ''); ?>" placeholder="0.00" required>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="form-group">
|
|
||||||
<label>Phone Mask</label>
|
|
||||||
<div class="input-group">
|
|
||||||
<div class="input-group-prepend">
|
|
||||||
<span class="input-group-text"><i class="fa fa-phone"></i></span>
|
|
||||||
</div>
|
|
||||||
<select class="form-control select2" name="phone_mask">
|
|
||||||
<?php
|
|
||||||
$sql = mysqli_query($mysqli, "SELECT config_phone_mask FROM settings WHERE company_id = 1");
|
|
||||||
while ($row = mysqli_fetch_array($sql)) {
|
|
||||||
$phone_mask = intval($row['config_phone_mask']);
|
|
||||||
} ?>
|
|
||||||
<option <?php if ($phone_mask == 1) { echo "selected"; }?> value=1>
|
|
||||||
US Format - e.g. (412) 888-9999
|
|
||||||
</option>
|
|
||||||
<option <?php if ($phone_mask == 0) { echo "selected"; }?> value=0>
|
|
||||||
Non-US Format - e.g. 4128889999
|
|
||||||
</option>
|
|
||||||
</select>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<hr>
|
|
||||||
|
|
||||||
<button type="submit" name="edit_default_settings" class="btn btn-primary text-bold"><i class="fa fa-check mr-2"></i>Save</button>
|
|
||||||
|
|
||||||
</form>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<?php
|
|
||||||
require_once "includes/footer.php";
|
|
||||||
@@ -1,43 +0,0 @@
|
|||||||
<?php
|
|
||||||
require_once "includes/inc_all_admin.php";
|
|
||||||
?>
|
|
||||||
|
|
||||||
<div class="card card-dark">
|
|
||||||
<div class="card-header py-3">
|
|
||||||
<h3 class="card-title"><i class="fas fa-fw fa-plug mr-2"></i>Integration Settings</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'] ?>">
|
|
||||||
|
|
||||||
<h4>Client Portal SSO via Microsoft Entra</h4>
|
|
||||||
<div class="form-group">
|
|
||||||
<label>MS Entra OAuth App (Client) ID</label>
|
|
||||||
<div class="input-group">
|
|
||||||
<div class="input-group-prepend">
|
|
||||||
<span class="input-group-text"><i class="fa fa-fw fa-user"></i></span>
|
|
||||||
</div>
|
|
||||||
<input type="text" class="form-control" name="azure_client_id" placeholder="e721e3b6-01d6-50e8-7f22-c84d951a52e7" value="<?php echo nullable_htmlentities($config_azure_client_id); ?>">
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="form-group">
|
|
||||||
<label>MS Entra OAuth Secret</label>
|
|
||||||
<div class="input-group">
|
|
||||||
<div class="input-group-prepend">
|
|
||||||
<span class="input-group-text"><i class="fa fa-fw fa-key"></i></span>
|
|
||||||
</div>
|
|
||||||
<input type="password" class="form-control" name="azure_client_secret" placeholder="Auto-generated from App Registration" value="<?php echo nullable_htmlentities($config_azure_client_secret); ?>" autocomplete="new-password">
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<hr>
|
|
||||||
|
|
||||||
<button type="submit" name="edit_integrations_settings" class="btn btn-primary text-bold"><i class="fa fa-check mr-2"></i>Save</button>
|
|
||||||
|
|
||||||
</form>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<?php require_once "includes/footer.php";
|
|
||||||
|
|
||||||
@@ -1,79 +0,0 @@
|
|||||||
<?php
|
|
||||||
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");
|
|
||||||
|
|
||||||
$row = mysqli_fetch_array($sql);
|
|
||||||
$company_locale = nullable_htmlentities($row['company_locale']);
|
|
||||||
$company_currency = nullable_htmlentities($row['company_currency']);
|
|
||||||
|
|
||||||
// Get a list of all available timezones
|
|
||||||
$timezones = DateTimeZone::listIdentifiers();
|
|
||||||
|
|
||||||
?>
|
|
||||||
|
|
||||||
<div class="card card-dark">
|
|
||||||
<div class="card-header py-3">
|
|
||||||
<h3 class="card-title"><i class="fas fa-fw fa-globe mr-2"></i>Localization</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'] ?>">
|
|
||||||
|
|
||||||
<div class="form-group">
|
|
||||||
<label>Language <strong class="text-danger">*</strong></label>
|
|
||||||
<div class="input-group">
|
|
||||||
<div class="input-group-prepend">
|
|
||||||
<span class="input-group-text"><i class="fa fa-fw fa-language"></i></span>
|
|
||||||
</div>
|
|
||||||
<select class="form-control select2" name="locale" required>
|
|
||||||
<option value="">- Select a Locale -</option>
|
|
||||||
<?php foreach($locales_array as $locale_code => $locale_name) { ?>
|
|
||||||
<option <?php if ($company_locale == $locale_code) { echo "selected"; } ?> value="<?php echo $locale_code; ?>"><?php echo $locale_name; ?></option>
|
|
||||||
<?php } ?>
|
|
||||||
</select>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="form-group">
|
|
||||||
<label>Currency <strong class="text-danger">*</strong></label>
|
|
||||||
<div class="input-group">
|
|
||||||
<div class="input-group-prepend">
|
|
||||||
<span class="input-group-text"><i class="fa fa-fw fa-money-bill"></i></span>
|
|
||||||
</div>
|
|
||||||
<select class="form-control select2" name="currency_code" required>
|
|
||||||
<option value="">- Currency -</option>
|
|
||||||
<?php foreach($currencies_array as $currency_code => $currency_name) { ?>
|
|
||||||
<option <?php if ($company_currency == $currency_code) { echo "selected"; } ?> value="<?php echo $currency_code; ?>"><?php echo "$currency_code - $currency_name"; ?></option>
|
|
||||||
<?php } ?>
|
|
||||||
</select>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="form-group">
|
|
||||||
<label>Timezone <strong class="text-danger">*</strong></label>
|
|
||||||
<div class="input-group">
|
|
||||||
<div class="input-group-prepend">
|
|
||||||
<span class="input-group-text"><i class="fa fa-fw fa-business-time"></i></span>
|
|
||||||
</div>
|
|
||||||
<select class="form-control select2" name="timezone" required>
|
|
||||||
<option value="">- Select a Timezone -</option>
|
|
||||||
<?php foreach ($timezones as $tz) { ?>
|
|
||||||
<option <?php if ($config_timezone == $tz) { echo "selected"; } ?> value="<?php echo $tz; ?>"><?php echo $tz; ?></option>
|
|
||||||
<?php } ?>
|
|
||||||
</select>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<hr>
|
|
||||||
|
|
||||||
<button type="submit" name="edit_localization" class="btn btn-primary text-bold"><i class="fas fa-check mr-2"></i>Save</button>
|
|
||||||
|
|
||||||
</form>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<?php
|
|
||||||
require_once "includes/footer.php";
|
|
||||||
|
|
||||||
@@ -1,331 +0,0 @@
|
|||||||
<?php
|
|
||||||
require_once "includes/inc_all_admin.php";
|
|
||||||
?>
|
|
||||||
|
|
||||||
<div class="card card-dark">
|
|
||||||
<div class="card-header py-3">
|
|
||||||
<h3 class="card-title"><i class="fas fa-fw fa-envelope mr-2"></i>SMTP Mail Settings <small>(For Sending Email)</small></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'] ?>">
|
|
||||||
|
|
||||||
<div class="form-group">
|
|
||||||
<label>SMTP Host</label>
|
|
||||||
<div class="input-group">
|
|
||||||
<div class="input-group-prepend">
|
|
||||||
<span class="input-group-text"><i class="fa fa-fw fa-server"></i></span>
|
|
||||||
</div>
|
|
||||||
<input type="text" class="form-control" name="config_smtp_host" placeholder="Mail Server Address" value="<?php echo nullable_htmlentities($config_smtp_host); ?>" required>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="form-group">
|
|
||||||
<label>SMTP Port</label>
|
|
||||||
<div class="input-group">
|
|
||||||
<div class="input-group-prepend">
|
|
||||||
<span class="input-group-text"><i class="fa fa-fw fa-plug"></i></span>
|
|
||||||
</div>
|
|
||||||
<input type="number" min="0" class="form-control" name="config_smtp_port" placeholder="Mail Server Port Number" value="<?php echo intval($config_smtp_port); ?>" required>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="form-group">
|
|
||||||
<label>Encryption</label>
|
|
||||||
<div class="input-group">
|
|
||||||
<div class="input-group-prepend">
|
|
||||||
<span class="input-group-text"><i class="fa fa-fw fa-lock"></i></span>
|
|
||||||
</div>
|
|
||||||
<select class="form-control" name="config_smtp_encryption">
|
|
||||||
<option value=''>None</option>
|
|
||||||
<option <?php if ($config_smtp_encryption == 'tls') { echo "selected"; } ?> value="tls">TLS</option>
|
|
||||||
<option <?php if ($config_smtp_encryption == 'ssl') { echo "selected"; } ?> value="ssl">SSL</option>
|
|
||||||
</select>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="form-group">
|
|
||||||
<label>SMTP Username</label>
|
|
||||||
<div class="input-group">
|
|
||||||
<div class="input-group-prepend">
|
|
||||||
<span class="input-group-text"><i class="fa fa-fw fa-user"></i></span>
|
|
||||||
</div>
|
|
||||||
<input type="text" class="form-control" name="config_smtp_username" placeholder="Username (Leave blank if no auth is required)" value="<?php echo nullable_htmlentities($config_smtp_username); ?>">
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="form-group">
|
|
||||||
<label>SMTP Password</label>
|
|
||||||
<div class="input-group">
|
|
||||||
<div class="input-group-prepend">
|
|
||||||
<span class="input-group-text"><i class="fa fa-fw fa-key"></i></span>
|
|
||||||
</div>
|
|
||||||
<input type="password" class="form-control" data-toggle="password" name="config_smtp_password" placeholder="Password (Leave blank if no auth is required)" value="<?php echo nullable_htmlentities($config_smtp_password); ?>" autocomplete="new-password">
|
|
||||||
<div class="input-group-append">
|
|
||||||
<span class="input-group-text"><i class="fa fa-fw fa-eye"></i></span>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<hr>
|
|
||||||
|
|
||||||
<button type="submit" name="edit_mail_smtp_settings" class="btn btn-primary text-bold"><i class="fas fa-check mr-2"></i>Save</button>
|
|
||||||
|
|
||||||
</form>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="card card-dark">
|
|
||||||
<div class="card-header py-3">
|
|
||||||
<h3 class="card-title"><i class="fas fa-fw fa-envelope mr-2"></i>IMAP Mail Settings <small>(For Monitoring Ticket Inbox)</small></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'] ?>">
|
|
||||||
|
|
||||||
<div class="form-group">
|
|
||||||
<label>IMAP Host</label>
|
|
||||||
<div class="input-group">
|
|
||||||
<div class="input-group-prepend">
|
|
||||||
<span class="input-group-text"><i class="fa fa-fw fa-server"></i></span>
|
|
||||||
</div>
|
|
||||||
<input type="text" class="form-control" name="config_imap_host" placeholder="Incoming Mail Server Address (for email to ticket parsing)" value="<?php echo nullable_htmlentities($config_imap_host); ?>">
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="form-group">
|
|
||||||
<label>IMAP Port</label>
|
|
||||||
<div class="input-group">
|
|
||||||
<div class="input-group-prepend">
|
|
||||||
<span class="input-group-text"><i class="fa fa-fw fa-plug"></i></span>
|
|
||||||
</div>
|
|
||||||
<input type="number" min="0" class="form-control" name="config_imap_port" placeholder="Incoming Mail Server Port Number (993)" value="<?php echo intval($config_imap_port); ?>">
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="form-group">
|
|
||||||
<label>IMAP Encryption</label>
|
|
||||||
<div class="input-group">
|
|
||||||
<div class="input-group-prepend">
|
|
||||||
<span class="input-group-text"><i class="fa fa-fw fa-lock"></i></span>
|
|
||||||
</div>
|
|
||||||
<select class="form-control" name="config_imap_encryption">
|
|
||||||
<option value=''>None</option>
|
|
||||||
<option <?php if ($config_imap_encryption == 'tls') { echo "selected"; } ?> value="tls">TLS</option>
|
|
||||||
<option <?php if ($config_imap_encryption == 'ssl') { echo "selected"; } ?> value="ssl">SSL</option>
|
|
||||||
</select>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class='form-group'>
|
|
||||||
<label>IMAP Username</label>
|
|
||||||
<div class='input-group'>
|
|
||||||
<div class='input-group-prepend'>
|
|
||||||
<span class='input-group-text'><i class='fa fa-fw fa-user'></i></span>
|
|
||||||
</div>
|
|
||||||
<input type='text' class='form-control' name='config_imap_username' placeholder='Username' value="<?php
|
|
||||||
echo nullable_htmlentities($config_imap_username); ?>" required>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class='form-group'>
|
|
||||||
<label>IMAP Password</label>
|
|
||||||
<div class='input-group'>
|
|
||||||
<div class='input-group-prepend'>
|
|
||||||
<span class='input-group-text'><i class='fa fa-fw fa-key'></i></span>
|
|
||||||
</div>
|
|
||||||
<input type='password' class='form-control' data-toggle='password' name='config_imap_password' placeholder='Password' value="<?php
|
|
||||||
echo nullable_htmlentities($config_imap_password); ?>" autocomplete='new-password' required>
|
|
||||||
<div class='input-group-append'>
|
|
||||||
<span class='input-group-text'><i class='fa fa-fw fa-eye'></i></span>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<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>
|
|
||||||
|
|
||||||
</form>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="card card-dark">
|
|
||||||
<div class="card-header py-3">
|
|
||||||
<h3 class="card-title"><i class="fas fa-fw fa-paper-plane mr-2"></i>Mail From Configuration</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'] ?>">
|
|
||||||
|
|
||||||
<p>Each of the "From Email" Addresses need to be able to send email on behalf of the SMTP user configured above
|
|
||||||
<h5>System Default</h5>
|
|
||||||
<p class="text-secondary">(used for system tasks such as sending share links)</p>
|
|
||||||
<div class="form-group">
|
|
||||||
<label>From Email</label>
|
|
||||||
<div class="input-group">
|
|
||||||
<div class="input-group-prepend">
|
|
||||||
<span class="input-group-text"><i class="fa fa-fw fa-envelope"></i></span>
|
|
||||||
</div>
|
|
||||||
<input type="email" class="form-control" name="config_mail_from_email" placeholder="Email Address (ex noreply@yourcompany.com)" value="<?php echo nullable_htmlentities($config_mail_from_email); ?>">
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="form-group">
|
|
||||||
<label>From Name</label>
|
|
||||||
<div class="input-group">
|
|
||||||
<div class="input-group-prepend">
|
|
||||||
<span class="input-group-text"><i class="fa fa-fw fa-tag"></i></span>
|
|
||||||
</div>
|
|
||||||
<input type="text" class="form-control" name="config_mail_from_name" placeholder="Name (ex YourCompany)" value="<?php echo nullable_htmlentities($config_mail_from_name); ?>">
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<h5>Invoices</h5>
|
|
||||||
<p class="text-secondary">(used for when invoice emails are sent)</p>
|
|
||||||
|
|
||||||
<div class="form-group">
|
|
||||||
<label>From Email</label>
|
|
||||||
<div class="input-group">
|
|
||||||
<div class="input-group-prepend">
|
|
||||||
<span class="input-group-text"><i class="fa fa-fw fa-envelope"></i></span>
|
|
||||||
</div>
|
|
||||||
<input type="email" class="form-control" name="config_invoice_from_email" placeholder="Email (ex billing@yourcompany.com)" value="<?php echo nullable_htmlentities($config_invoice_from_email); ?>">
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="form-group">
|
|
||||||
<label>From Name</label>
|
|
||||||
<div class="input-group">
|
|
||||||
<div class="input-group-prepend">
|
|
||||||
<span class="input-group-text"><i class="fa fa-fw fa-tag"></i></span>
|
|
||||||
</div>
|
|
||||||
<input type="text" class="form-control" name="config_invoice_from_name" placeholder="Name (ex CompanyName Billing)" value="<?php echo nullable_htmlentities($config_invoice_from_name); ?>">
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<h5>Quotes</h5>
|
|
||||||
<p class="text-secondary">(used for when quote emails are sent)</p>
|
|
||||||
|
|
||||||
<div class="form-group">
|
|
||||||
<label>From Email</label>
|
|
||||||
<div class="input-group">
|
|
||||||
<div class="input-group-prepend">
|
|
||||||
<span class="input-group-text"><i class="fa fa-fw fa-envelope"></i></span>
|
|
||||||
</div>
|
|
||||||
<input type="email" class="form-control" name="config_quote_from_email" placeholder="Email (ex sales@yourcompany.com)" value="<?php echo nullable_htmlentities($config_quote_from_email); ?>">
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="form-group">
|
|
||||||
<label>From Name</label>
|
|
||||||
<div class="input-group">
|
|
||||||
<div class="input-group-prepend">
|
|
||||||
<span class="input-group-text"><i class="fa fa-fw fa-tag"></i></span>
|
|
||||||
</div>
|
|
||||||
<input type="text" class="form-control" name="config_quote_from_name" placeholder="Name (ex YourCompany Sales)" value="<?php echo nullable_htmlentities($config_quote_from_name); ?>">
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<h5>Tickets</h5>
|
|
||||||
<p class="text-secondary">(used for when tickets are created and emailed to a client)</p>
|
|
||||||
|
|
||||||
<div class="form-group">
|
|
||||||
<label>From Email</label>
|
|
||||||
<div class="input-group">
|
|
||||||
<div class="input-group-prepend">
|
|
||||||
<span class="input-group-text"><i class="fa fa-fw fa-envelope"></i></span>
|
|
||||||
</div>
|
|
||||||
<input type="email" class="form-control" name="config_ticket_from_email" placeholder="Email (ex support@yourcompany.com)" value="<?php echo nullable_htmlentities($config_ticket_from_email); ?>">
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="form-group">
|
|
||||||
<label>From Name</label>
|
|
||||||
<div class="input-group">
|
|
||||||
<div class="input-group-prepend">
|
|
||||||
<span class="input-group-text"><i class="fa fa-fw fa-tag"></i></span>
|
|
||||||
</div>
|
|
||||||
<input type="text" class="form-control" name="config_ticket_from_name" placeholder="Name (ex YourCompany Support)" value="<?php echo nullable_htmlentities($config_ticket_from_name); ?>">
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<hr>
|
|
||||||
|
|
||||||
<button type="submit" name="edit_mail_from_settings" class="btn btn-primary text-bold"><i class="fas fa-check mr-2"></i>Save</button>
|
|
||||||
|
|
||||||
</form>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<?php if (!empty($config_smtp_host) && !empty($config_smtp_port) && !empty($config_mail_from_email) && !empty($config_mail_from_name)) { ?>
|
|
||||||
|
|
||||||
<div class="card card-dark">
|
|
||||||
<div class="card-header py-3">
|
|
||||||
<h3 class="card-title"><i class="fas fa-fw fa-paper-plane mr-2"></i>Test Email Sending</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'] ?>">
|
|
||||||
|
|
||||||
<div class="input-group">
|
|
||||||
<select class="form-control select2" name="test_email" required>
|
|
||||||
<option value="">- Select an Email Address to send from -</option>
|
|
||||||
<?php
|
|
||||||
if ($config_mail_from_email) {
|
|
||||||
?>
|
|
||||||
<option value="1"><?php echo nullable_htmlentities($config_mail_from_name); ?> (<?php echo nullable_htmlentities($config_mail_from_email); ?>)</option>
|
|
||||||
<?php } ?>
|
|
||||||
|
|
||||||
<?php
|
|
||||||
if ($config_invoice_from_email) {
|
|
||||||
?>
|
|
||||||
<option value="2"><?php echo nullable_htmlentities($config_invoice_from_name); ?> (<?php echo nullable_htmlentities($config_invoice_from_email); ?>)</option>
|
|
||||||
<?php } ?>
|
|
||||||
|
|
||||||
<?php
|
|
||||||
if ($config_quote_from_email) {
|
|
||||||
?>
|
|
||||||
<option value="3"><?php echo nullable_htmlentities($config_quote_from_name); ?> (<?php echo nullable_htmlentities($config_quote_from_email); ?>)</option>
|
|
||||||
<?php } ?>
|
|
||||||
|
|
||||||
<?php
|
|
||||||
if ($config_ticket_from_email) {
|
|
||||||
?>
|
|
||||||
<option value="4"><?php echo nullable_htmlentities($config_ticket_from_name); ?> (<?php echo nullable_htmlentities($config_ticket_from_email); ?>)</option>
|
|
||||||
<?php } ?>
|
|
||||||
|
|
||||||
|
|
||||||
</select>
|
|
||||||
<input type="email" class="form-control " name="email_to" placeholder="Email address to send to">
|
|
||||||
<div class="input-group-append">
|
|
||||||
<button type="submit" name="test_email_smtp" class="btn btn-success"><i class="fas fa-fw fa-paper-plane mr-2"></i>Send</button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</form>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<?php } ?>
|
|
||||||
|
|
||||||
<?php if (!empty($config_imap_username) && !empty($config_imap_password) && !empty($config_imap_host) && !empty($config_imap_port)) { ?>
|
|
||||||
|
|
||||||
<div class="card card-dark">
|
|
||||||
<div class="card-header py-3">
|
|
||||||
<h3 class="card-title"><i class="fas fa-fw fa-plug mr-2"></i>Test IMAP Connection</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'] ?>">
|
|
||||||
|
|
||||||
<div class="input-group-append">
|
|
||||||
<button type="submit" name="test_email_imap" class="btn btn-success"><i class="fas fa-fw fa-inbox mr-2"></i>Test</button>
|
|
||||||
</div>
|
|
||||||
</form>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<?php } ?>
|
|
||||||
|
|
||||||
<?php require_once "includes/footer.php";
|
|
||||||
|
|
||||||
@@ -1,82 +0,0 @@
|
|||||||
<?php
|
|
||||||
require_once "includes/inc_all_admin.php";
|
|
||||||
?>
|
|
||||||
|
|
||||||
<div class="card card-dark">
|
|
||||||
<div class="card-header py-3">
|
|
||||||
<h3 class="card-title"><i class="fas fa-fw fa-cube mr-2"></i>Modules</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'] ?>">
|
|
||||||
|
|
||||||
<div class="form-group">
|
|
||||||
<div class="custom-control custom-switch">
|
|
||||||
<input type="checkbox" class="custom-control-input" name="config_module_enable_itdoc" <?php if ($config_module_enable_itdoc == 1) { echo "checked"; } ?> value="1" id="customSwitch1">
|
|
||||||
<label class="custom-control-label" for="customSwitch1">Show IT Documentation</label>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="form-group">
|
|
||||||
<div class="custom-control custom-switch">
|
|
||||||
<input type="checkbox" class="custom-control-input" name="config_module_enable_ticketing" <?php if ($config_module_enable_ticketing == 1) { echo "checked"; } ?> value="1" id="customSwitch2">
|
|
||||||
<label class="custom-control-label" for="customSwitch2">Show Ticketing</label>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="form-group">
|
|
||||||
<div class="custom-control custom-switch">
|
|
||||||
<input type="checkbox" class="custom-control-input" name="config_module_enable_accounting" <?php if ($config_module_enable_accounting == 1) { echo "checked"; } ?> value="1" id="customSwitch3">
|
|
||||||
<label class="custom-control-label" for="customSwitch3">Show Invoicing / Accounting</label>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="form-group">
|
|
||||||
<div class="custom-control custom-switch">
|
|
||||||
<input type="checkbox" class="custom-control-input" name="config_client_portal_enable" <?php if ($config_client_portal_enable == 1) { echo "checked"; } ?> value="1" id="customSwitch4">
|
|
||||||
<label class="custom-control-label" for="customSwitch4">Enable Client Portal</label>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<hr>
|
|
||||||
|
|
||||||
<div class="form-group">
|
|
||||||
<div class="custom-control custom-switch">
|
|
||||||
<input type="checkbox" disabled class="custom-control-input" name="config_whitelabel_enabled" <?php if ($config_whitelabel_enabled == 1) { echo "checked"; } ?> value="1" id="customSwitch5">
|
|
||||||
<label class="custom-control-label" for="customSwitch5">White-label <small class="text-secondary">(Hides 'Powered by ITFlow' banner)</small></label>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="form-group">
|
|
||||||
<label>White-label key</label>
|
|
||||||
<textarea class="form-control" name="config_whitelabel_key" rows="2" placeholder="Enter a key to enable white-labelling the client portal"><?php echo nullable_htmlentities($config_whitelabel_key); ?></textarea>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<?php if ($config_whitelabel_enabled == 1 && validateWhitelabelKey($config_whitelabel_key)) {
|
|
||||||
$key_info = validateWhitelabelKey($config_whitelabel_key);
|
|
||||||
$key_desc = $key_info["description"];
|
|
||||||
$key_org = $key_info["organisation"];
|
|
||||||
$key_expires = $key_info["expires"];
|
|
||||||
?>
|
|
||||||
<div class="form-group">
|
|
||||||
<p>White-labelling is active - thank you for your support! :)</p>
|
|
||||||
<ul>
|
|
||||||
<li>Key: <?php echo $key_desc ?></li>
|
|
||||||
<li>Org: <?php echo $key_org ?></li>
|
|
||||||
<li>Expires: <?php echo $key_expires; if ($key_expires < date('Y-m-d H:i:s')) { echo " (expiring) "; } ?></li>
|
|
||||||
</ul>
|
|
||||||
|
|
||||||
</div>
|
|
||||||
<?php } ?>
|
|
||||||
|
|
||||||
<hr>
|
|
||||||
|
|
||||||
<button type="submit" name="edit_module_settings" class="btn btn-primary text-bold"><i class="fas fa-check mr-2"></i>Save</button>
|
|
||||||
|
|
||||||
</form>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<?php
|
|
||||||
require_once "includes/footer.php";
|
|
||||||
|
|
||||||
@@ -1,183 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
require_once "includes/inc_all_admin.php";
|
|
||||||
|
|
||||||
?>
|
|
||||||
|
|
||||||
<div class="card card-dark">
|
|
||||||
<div class="card-header py-3">
|
|
||||||
<h3 class="card-title"><i class="fas fa-fw fa-bell mr-2"></i>Notifications</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'] ?>">
|
|
||||||
|
|
||||||
<div class="form-group">
|
|
||||||
<div class="custom-control custom-switch">
|
|
||||||
<input type="checkbox" class="custom-control-input" name="config_enable_cron" <?php if ($config_enable_cron == 1) { echo "checked"; } ?> value="1" id="enableCronSwitch">
|
|
||||||
<label class="custom-control-label" for="enableCronSwitch">Enable Cron (recommended) <small>(several cron scripts must also be added to cron with correct schedules, <a href="https://docs.itflow.org/cron">docs</a>)</small></label>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<table class="table table-bordered">
|
|
||||||
<thead class="thead-dark">
|
|
||||||
<tr>
|
|
||||||
<th>Notification</th>
|
|
||||||
<th>App Notify</th>
|
|
||||||
<th>Tech Email Notify</th>
|
|
||||||
<th>Client Email Notify</th>
|
|
||||||
<th>Create Ticket</th>
|
|
||||||
</tr>
|
|
||||||
</thead>
|
|
||||||
<tbody>
|
|
||||||
<tr>
|
|
||||||
<th colspan=5>Expirations</th>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<th>
|
|
||||||
<div><i class="fas fa-fw fa-globe mr-2"></i>Domain Expiration Notice</div>
|
|
||||||
<small class="text-muted">
|
|
||||||
(This setting triggers a notification when a domain is approaching its expiration date, specifically at 1, 7, 14, 30 and 90 days prior to expiry.)
|
|
||||||
</small>
|
|
||||||
</th>
|
|
||||||
<td>
|
|
||||||
<div class="custom-control custom-checkbox text-center">
|
|
||||||
<input type="checkbox" class="custom-control-input" name="config_enable_alert_domain_expire" id="customCheck1" <?php if ($config_enable_alert_domain_expire == 1) { echo "checked"; } ?> value="1">
|
|
||||||
<label class="custom-control-label" for="customCheck1"></label>
|
|
||||||
</div>
|
|
||||||
</td>
|
|
||||||
<td></td>
|
|
||||||
<td></td>
|
|
||||||
<td></td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<th>
|
|
||||||
<div><i class="fas fa-fw fa-lock mr-2"></i>Certificate Expiration Notice</div>
|
|
||||||
<small class="text-muted">
|
|
||||||
(This setting triggers a notification when a certificate is approaching its expiration date, specifically at 1, 7, 14, 30 and 90 days prior to expiry.)
|
|
||||||
</small>
|
|
||||||
</th>
|
|
||||||
<td>
|
|
||||||
</td>
|
|
||||||
<td></td>
|
|
||||||
<td></td>
|
|
||||||
<td></td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<th>
|
|
||||||
<div><i class="fas fa-fw fa-desktop mr-2"></i>Asset Warranty Expiration Notice</div>
|
|
||||||
<small class="text-muted">
|
|
||||||
(This setting triggers a notification when an asset is approaching its expiration date, specifically at 1, 7, 14, 30 and 90 days prior to expiry.)
|
|
||||||
</small>
|
|
||||||
</th>
|
|
||||||
<td>
|
|
||||||
</td>
|
|
||||||
<td></td>
|
|
||||||
<td></td>
|
|
||||||
<td></td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<th colspan=5>Billing</th>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<th>
|
|
||||||
<div><i class="fas fa-fw fa-file-invoice mr-2"></i>Invoice Reminders</div>
|
|
||||||
<small class="text-muted">
|
|
||||||
(This will automatically dispatch a reminder email for the invoice to the primary contact's email every 30 days following the invoice's due date.)
|
|
||||||
</small>
|
|
||||||
</th>
|
|
||||||
<td>
|
|
||||||
|
|
||||||
</td>
|
|
||||||
<td></td>
|
|
||||||
<td>
|
|
||||||
<div class="custom-control custom-checkbox text-center">
|
|
||||||
<input type="checkbox" class="custom-control-input" name="config_send_invoice_reminders" <?php if ($config_send_invoice_reminders == 1) { echo "checked"; } ?> value="1" id="sendInvoiceRemindersSwitch">
|
|
||||||
<label class="custom-control-label" for="sendInvoiceRemindersSwitch"></label>
|
|
||||||
</div>
|
|
||||||
</td>
|
|
||||||
<td></td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<th>
|
|
||||||
<div><i class="fas fa-fw fa-redo-alt mr-2"></i>Send Recurring Invoice</div>
|
|
||||||
<small class="text-muted">
|
|
||||||
(This will notify all primary and billing contacts of a client that a new invoice was generated from recurring invoices)
|
|
||||||
</small>
|
|
||||||
</th>
|
|
||||||
<td>
|
|
||||||
|
|
||||||
</td>
|
|
||||||
<td></td>
|
|
||||||
<td>
|
|
||||||
<div class="custom-control custom-checkbox text-center">
|
|
||||||
<input type="checkbox" class="custom-control-input" name="config_recurring_auto_send_invoice" <?php if ($config_recurring_auto_send_invoice == 1) { echo "checked"; } ?> value="1" id="sendRecurringSwitch">
|
|
||||||
<label class="custom-control-label" for="sendRecurringSwitch"></label>
|
|
||||||
</div>
|
|
||||||
</td>
|
|
||||||
<td></td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<th colspan=5>Operational</th>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<th>
|
|
||||||
<div><i class="fas fa-fw fa-bell mr-2"></i>Send clients general notification emails</div>
|
|
||||||
<small class="text-secondary">(Should clients receive automatic emails when tickets are raised/closed?)</small>
|
|
||||||
</th>
|
|
||||||
<td></td>
|
|
||||||
<td></td>
|
|
||||||
<td>
|
|
||||||
<div class="custom-control custom-checkbox text-center">
|
|
||||||
<input type="checkbox" class="custom-control-input" name="config_ticket_client_general_notifications" <?php if($config_ticket_client_general_notifications == 1){ echo "checked"; } ?> value="1" id="ticketNotificationSwitch">
|
|
||||||
<label class="custom-control-label" for="ticketNotificationSwitch"></label>
|
|
||||||
</div>
|
|
||||||
</td>
|
|
||||||
<td></td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<th>
|
|
||||||
<div><i class="fas fa-fw fa-link mr-2"></i>Shared Item View</div>
|
|
||||||
<small class="text-secondary">(Notify when Shared items are viewed)</small>
|
|
||||||
</th>
|
|
||||||
<td></td>
|
|
||||||
<td></td>
|
|
||||||
<td>
|
|
||||||
</td>
|
|
||||||
<td></td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<th>
|
|
||||||
<div><i class="fas fa-fw fa-clock mr-2"></i>Cron Execution</div>
|
|
||||||
<small class="text-secondary">(Notify when the nightly cron job ran)</small>
|
|
||||||
</th>
|
|
||||||
<td></td>
|
|
||||||
<td></td>
|
|
||||||
<td>
|
|
||||||
</td>
|
|
||||||
<td></td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<th>
|
|
||||||
<div><i class="fas fa-fw fa-download mr-2"></i>ITFlow Updates</div>
|
|
||||||
<small class="text-secondary">(Notify when ITFlow has an update)</small>
|
|
||||||
</th>
|
|
||||||
<td></td>
|
|
||||||
<td></td>
|
|
||||||
<td>
|
|
||||||
</td>
|
|
||||||
<td></td>
|
|
||||||
</tr>
|
|
||||||
</tbody>
|
|
||||||
</table>
|
|
||||||
|
|
||||||
<hr>
|
|
||||||
|
|
||||||
<button type="submit" name="edit_notification_settings" class="btn btn-primary text-bold"><i class="fa fa-check mr-2"></i>Save</button>
|
|
||||||
|
|
||||||
</form>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<?php
|
|
||||||
require_once "includes/footer.php";
|
|
||||||
@@ -1,154 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
require_once "includes/inc_all_admin.php";
|
|
||||||
|
|
||||||
?>
|
|
||||||
|
|
||||||
<div class="card card-dark">
|
|
||||||
<div class="card-header py-3">
|
|
||||||
<h3 class="card-title"><i class="fas fa-fw fa-credit-card mr-2"></i>Online Payment</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'] ?>">
|
|
||||||
|
|
||||||
<div class="form-group">
|
|
||||||
<div class="custom-control custom-switch">
|
|
||||||
<input type="checkbox" class="custom-control-input" name="config_stripe_enable" <?php if ($config_stripe_enable == 1) { echo "checked"; } ?> value="1" id="enableStripeSwitch">
|
|
||||||
<label class="custom-control-label" for="enableStripeSwitch">Enable Stripe</label>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="<?php if ($config_stripe_enable == 0) { echo "d-none"; } ?>">
|
|
||||||
|
|
||||||
<div class="form-group">
|
|
||||||
<label>Publishable key <strong class="text-danger">*</strong></label>
|
|
||||||
<div class="input-group">
|
|
||||||
<div class="input-group-prepend">
|
|
||||||
<span class="input-group-text"><i class="fa fa-fw fa-eye"></i></span>
|
|
||||||
</div>
|
|
||||||
<input type="text" class="form-control" name="config_stripe_publishable" placeholder="Stripe Publishable API Key (pk_...)" value="<?php echo nullable_htmlentities($config_stripe_publishable); ?>">
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="form-group">
|
|
||||||
<label>Secret key <strong class="text-danger">*</strong></label>
|
|
||||||
<div class="input-group">
|
|
||||||
<div class="input-group-prepend">
|
|
||||||
<span class="input-group-text"><i class="fa fa-fw fa-key"></i></span>
|
|
||||||
</div>
|
|
||||||
<input type="text" class="form-control" name="config_stripe_secret" placeholder="Stripe Secret API Key (sk_...)" value="<?php echo nullable_htmlentities($config_stripe_secret); ?>">
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="form-group">
|
|
||||||
<label>Account <strong class="text-danger">*</strong></label>
|
|
||||||
<div class="input-group">
|
|
||||||
<div class="input-group-prepend">
|
|
||||||
<span class="input-group-text"><i class="fas fa-fw fa-piggy-bank"></i></span>
|
|
||||||
</div>
|
|
||||||
<select class="form-control select2" name="config_stripe_account">
|
|
||||||
<option value="">- Account -</option>
|
|
||||||
<?php
|
|
||||||
$sql_accounts = mysqli_query($mysqli, "SELECT * FROM accounts WHERE account_archived_at IS NULL ORDER BY account_name ASC");
|
|
||||||
while ($row = mysqli_fetch_array($sql_accounts)) {
|
|
||||||
$account_id = intval($row['account_id']);
|
|
||||||
$account_name = nullable_htmlentities($row['account_name']);
|
|
||||||
?>
|
|
||||||
|
|
||||||
<option value="<?php echo $account_id ?>" <?php if ($account_id == $config_stripe_account) { echo "selected"; } ?>><?php echo $account_name ?></option>
|
|
||||||
<?php
|
|
||||||
}
|
|
||||||
?>
|
|
||||||
</select>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<hr>
|
|
||||||
|
|
||||||
<div class="form-group">
|
|
||||||
<label>Expense Vendor</label>
|
|
||||||
<div class="input-group">
|
|
||||||
<div class="input-group-prepend">
|
|
||||||
<span class="input-group-text"><i class="fa fa-fw fa-building"></i></span>
|
|
||||||
</div>
|
|
||||||
<select class="form-control select2" name="config_stripe_expense_vendor">
|
|
||||||
<option value="">- Do not expense Stripe fees -</option>
|
|
||||||
<?php
|
|
||||||
|
|
||||||
$sql_select = mysqli_query($mysqli, "SELECT vendor_id, vendor_name FROM vendors WHERE vendor_client_id = 0 AND vendor_template = 0 AND vendor_archived_at IS NULL ORDER BY vendor_name ASC");
|
|
||||||
while ($row = mysqli_fetch_array($sql_select)) {
|
|
||||||
$vendor_id = intval($row['vendor_id']);
|
|
||||||
$vendor_name = nullable_htmlentities($row['vendor_name']);
|
|
||||||
?>
|
|
||||||
<option <?php if ($config_stripe_expense_vendor == $vendor_id) { ?> selected <?php } ?> value="<?php echo $vendor_id; ?>"><?php echo $vendor_name; ?></option>
|
|
||||||
<?php
|
|
||||||
}
|
|
||||||
?>
|
|
||||||
</select>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="form-group">
|
|
||||||
<label>Expense Category</label>
|
|
||||||
<div class="input-group">
|
|
||||||
<div class="input-group-prepend">
|
|
||||||
<span class="input-group-text"><i class="fa fa-fw fa-list"></i></span>
|
|
||||||
</div>
|
|
||||||
<select class="form-control select2" name="config_stripe_expense_category">
|
|
||||||
<option value="">- Do not expense Stripe fees -</option>
|
|
||||||
<?php
|
|
||||||
|
|
||||||
$sql_select = 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_select)) {
|
|
||||||
$category_id = intval($row['category_id']);
|
|
||||||
$category_name = nullable_htmlentities($row['category_name']);
|
|
||||||
?>
|
|
||||||
<option <?php if ($config_stripe_expense_category == $category_id) { ?> selected <?php } ?> value="<?php echo $category_id; ?>"><?php echo $category_name; ?></option>
|
|
||||||
<?php
|
|
||||||
}
|
|
||||||
|
|
||||||
?>
|
|
||||||
</select>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="form-group">
|
|
||||||
<label>Percentage Fee to expense</label>
|
|
||||||
<div class="input-group">
|
|
||||||
<div class="input-group-prepend">
|
|
||||||
<span class="input-group-text"><i class="fa fa-fw fa-percent"></i></span>
|
|
||||||
</div>
|
|
||||||
<input type="text" class="form-control" inputmode="numeric" pattern="[0-9]*\.?[0-9]{0,2}" name="config_stripe_percentage_fee" placeholder="Enter Percentage" value="<?php echo $config_stripe_percentage_fee * 100; ?>">
|
|
||||||
</div>
|
|
||||||
<small class="form-text text-muted">See <a href="https://stripe.com/pricing" target="_blank">here <i class="fas fa-fw fa-external-link-alt"></i></a> for the latest Stripe Fees.</small>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="form-group">
|
|
||||||
<label>Flat Fee to expense</label>
|
|
||||||
<div class="input-group">
|
|
||||||
<div class="input-group-prepend">
|
|
||||||
<span class="input-group-text"><i class="fa fa-fw fa-shopping-cart"></i></span>
|
|
||||||
</div>
|
|
||||||
<input type="text" class="form-control" inputmode="numeric" pattern="[0-9]*\.?[0-9]{0,2}" name="config_stripe_flat_fee" placeholder="0.030" value="<?php echo number_format($config_stripe_flat_fee, 2, '.', ''); ?>">
|
|
||||||
</div>
|
|
||||||
<small class="form-text text-muted">See <a href="https://stripe.com/pricing" target="_blank">here <i class="fas fa-fw fa-external-link-alt"></i></a> for the latest Stripe Fees.</small>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="alert alert-secondary">Currently, we only integrate with Stripe. Please see <a href="https://forum.itflow.org/d/439-payment-integrations-megathread" target="_blank">this forum post</a>.</div>
|
|
||||||
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<hr>
|
|
||||||
|
|
||||||
<button type="submit" name="edit_online_payment_settings" class="btn btn-primary text-bold"><i class="fas fa-check mr-2"></i>Save</button>
|
|
||||||
|
|
||||||
</form>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<?php
|
|
||||||
require_once "includes/footer.php";
|
|
||||||
|
|
||||||
@@ -1,70 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
require_once "includes/inc_all_admin.php";
|
|
||||||
|
|
||||||
$stripe_clients_sql = mysqli_query($mysqli, "SELECT * FROM client_stripe LEFT JOIN clients ON client_stripe.client_id = clients.client_id");
|
|
||||||
?>
|
|
||||||
|
|
||||||
<div class="card card-dark">
|
|
||||||
<div class="card-header py-3">
|
|
||||||
<h3 class="card-title"><i class="fas fa-fw fa-credit-card mr-2"></i>Online Payment - Client info</h3>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="card-body">
|
|
||||||
|
|
||||||
<table class="table border border-dark">
|
|
||||||
<thead class="thead-dark">
|
|
||||||
<tr>
|
|
||||||
<th>Client</th>
|
|
||||||
<th>Stripe Customer ID</th>
|
|
||||||
<th>Stripe Payment ID</th>
|
|
||||||
<th class="text-center">Action</th>
|
|
||||||
</tr>
|
|
||||||
</thead>
|
|
||||||
<tbody>
|
|
||||||
|
|
||||||
<?php
|
|
||||||
while ($row = mysqli_fetch_array($stripe_clients_sql)) {
|
|
||||||
$client_id = intval($row['client_id']);
|
|
||||||
$client_name = nullable_htmlentities($row['client_name']);
|
|
||||||
$stripe_id = nullable_htmlentities($row['stripe_id']);
|
|
||||||
$stripe_pm = nullable_htmlentities($row['stripe_pm']);
|
|
||||||
|
|
||||||
?>
|
|
||||||
|
|
||||||
<tr>
|
|
||||||
<td><?php echo "$client_name ($client_id)" ?></td>
|
|
||||||
<td><?php echo $stripe_id; ?></td>
|
|
||||||
<td><?php echo $stripe_pm ?></td>
|
|
||||||
<td>
|
|
||||||
<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>
|
|
||||||
<div class="dropdown-menu">
|
|
||||||
<?php if (!empty($stripe_pm)) { ?>
|
|
||||||
<a class="dropdown-item text-danger confirm-link" href="post.php?stripe_remove_pm&client_id=<?php echo $client_id ?>&pm=<?php echo $stripe_pm ?>&csrf_token=<?php echo $_SESSION['csrf_token'] ?>">
|
|
||||||
<i class="fas fa-fw fa-credit-card mr-2"></i>Delete payment method
|
|
||||||
</a>
|
|
||||||
<?php } else { ?>
|
|
||||||
<a data-toggle="tooltip" data-placement="left" title="May result in duplicate customer records in Stripe" class="dropdown-item text-danger confirm-link" href="post.php?stripe_reset_customer&client_id=<?php echo $client_id ?>&csrf_token=<?php echo $_SESSION['csrf_token'] ?>">
|
|
||||||
<i class="fas fa-fw fa-trash mr-2"></i>Reset Stripe
|
|
||||||
</a>
|
|
||||||
<?php } ?>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</td>
|
|
||||||
|
|
||||||
</tr>
|
|
||||||
|
|
||||||
<?php } ?>
|
|
||||||
|
|
||||||
</tbody>
|
|
||||||
</table>
|
|
||||||
|
|
||||||
</div>
|
|
||||||
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<?php
|
|
||||||
require_once "includes/footer.php";
|
|
||||||
@@ -1,44 +0,0 @@
|
|||||||
<?php
|
|
||||||
require_once "includes/inc_all_admin.php";
|
|
||||||
?>
|
|
||||||
|
|
||||||
<div class="card card-dark">
|
|
||||||
<div class="card-header py-3">
|
|
||||||
<h3 class="card-title"><i class="fas fa-fw fa-project-diagram mr-2"></i>Project Settings</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'] ?>">
|
|
||||||
|
|
||||||
<h4>Project</h4>
|
|
||||||
|
|
||||||
<div class="form-group">
|
|
||||||
<label>Project Prefix</label>
|
|
||||||
<div class="input-group">
|
|
||||||
<div class="input-group-prepend">
|
|
||||||
<span class="input-group-text"><i class="fa fa-fw fa-barcode"></i></span>
|
|
||||||
</div>
|
|
||||||
<input type="text" class="form-control" name="config_project_prefix" placeholder="Project Prefix" value="<?php echo nullable_htmlentities($config_project_prefix); ?>" required>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="form-group">
|
|
||||||
<label>Next Number</label>
|
|
||||||
<div class="input-group">
|
|
||||||
<div class="input-group-prepend">
|
|
||||||
<span class="input-group-text"><i class="fa fa-fw fa-barcode"></i></span>
|
|
||||||
</div>
|
|
||||||
<input type="number" min="0" class="form-control" name="config_project_next_number" placeholder="Next Project Number" value="<?php echo intval($config_project_next_number); ?>" required>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<hr>
|
|
||||||
|
|
||||||
<button type="submit" name="edit_project_settings" class="btn btn-primary text-bold"><i class="fas fa-check mr-2"></i>Save</button>
|
|
||||||
|
|
||||||
</form>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<?php
|
|
||||||
require_once "includes/footer.php";
|
|
||||||
@@ -1,66 +0,0 @@
|
|||||||
<?php
|
|
||||||
require_once "includes/inc_all_admin.php";
|
|
||||||
|
|
||||||
?>
|
|
||||||
|
|
||||||
<div class="card card-dark">
|
|
||||||
<div class="card-header py-3">
|
|
||||||
<h3 class="card-title"><i class="fas fa-fw fa-shield-alt mr-2"></i>Security</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'] ?>">
|
|
||||||
|
|
||||||
<div class="form-group">
|
|
||||||
<label>Login Message</label>
|
|
||||||
<textarea class="form-control" name="config_login_message" rows="5" placeholder="Enter a message to be displayed on the login screen"><?php echo nullable_htmlentities($config_login_message); ?></textarea>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="form-group">
|
|
||||||
<div class="custom-control custom-switch">
|
|
||||||
<input type="checkbox" class="custom-control-input" name="config_login_key_required" <?php if ($config_login_key_required == 1) { echo "checked"; } ?> value="1" id="customSwitch1">
|
|
||||||
<label class="custom-control-label" for="customSwitch1">Require a login key to access the technician login page?</label>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="form-group">
|
|
||||||
<label>Login key secret value <small class="text-secondary">(This must be provided in the URL as /login.php?key=<?php echo nullable_htmlentities($config_login_key_secret)?>)</small></label>
|
|
||||||
<div class="input-group">
|
|
||||||
<div class="input-group-prepend">
|
|
||||||
<span class="input-group-text"><i class="fa fa-fw fa-key"></i></span>
|
|
||||||
</div>
|
|
||||||
<input type="text" class="form-control" name="config_login_key_secret" pattern="\w{3,99}" placeholder="Something really easy for techs to remember: e.g. MYSECRET" value="<?php echo nullable_htmlentities($config_login_key_secret); ?>">
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="form-group">
|
|
||||||
<label>2FA Remember Me Expire <small class="text-secondary">(The amount of days before a device 2FA remember me token will expire)</small></label>
|
|
||||||
<div class="input-group">
|
|
||||||
<div class="input-group-prepend">
|
|
||||||
<span class="input-group-text"><i class="fa fa-fw fa-clock"></i></span>
|
|
||||||
</div>
|
|
||||||
<input type="number" class="form-control" name="config_login_remember_me_expire" placeholder="Enter Days to Expire" value="<?php echo intval($config_login_remember_me_expire); ?>">
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="form-group">
|
|
||||||
<label>Log retention <small class="text-secondary">(The amount of days before app/audit/auth logs are deleted during nightly cron)</small></label>
|
|
||||||
<div class="input-group">
|
|
||||||
<div class="input-group-prepend">
|
|
||||||
<span class="input-group-text"><i class="fa fa-fw fa-clock"></i></span>
|
|
||||||
</div>
|
|
||||||
<input type="number" class="form-control" name="config_log_retention" placeholder="Enter days to retain" value="<?php echo intval($config_log_retention); ?>">
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<hr>
|
|
||||||
|
|
||||||
<button type="submit" name="edit_security_settings" class="btn btn-primary text-bold"><i class="fas fa-check mr-2"></i>Save</button>
|
|
||||||
|
|
||||||
</form>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<?php
|
|
||||||
require_once "includes/footer.php";
|
|
||||||
|
|
||||||
@@ -1,67 +0,0 @@
|
|||||||
<?php
|
|
||||||
require_once "includes/inc_all_admin.php";
|
|
||||||
?>
|
|
||||||
|
|
||||||
<div class="card card-dark">
|
|
||||||
<div class="card-header py-3">
|
|
||||||
<h3 class="card-title"><i class="fas fa-fw fa-paint-brush mr-2"></i>Theme</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'] ?>">
|
|
||||||
|
|
||||||
<label>Select a Theme</label>
|
|
||||||
<div class="form-row">
|
|
||||||
|
|
||||||
<?php
|
|
||||||
|
|
||||||
foreach ($theme_colors_array as $theme_color) {
|
|
||||||
|
|
||||||
?>
|
|
||||||
|
|
||||||
<div class="col-3 text-center mb-3">
|
|
||||||
<div class="form-group">
|
|
||||||
<div class="custom-control custom-radio">
|
|
||||||
<input class="custom-control-input" type="radio" onchange="this.form.submit()" id="customRadio<?php echo $theme_color; ?>" name="edit_theme_settings" value="<?php echo $theme_color; ?>" <?php if ($config_theme == $theme_color) { echo "checked"; } ?>>
|
|
||||||
<label for="customRadio<?php echo $theme_color; ?>" class="custom-control-label">
|
|
||||||
<i class="fa fa-fw fa-6x fa-circle text-<?php echo $theme_color; ?>"></i>
|
|
||||||
<br>
|
|
||||||
<?php echo $theme_color; ?>
|
|
||||||
</label>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<?php } ?>
|
|
||||||
|
|
||||||
</div>
|
|
||||||
|
|
||||||
</form>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="card card-dark">
|
|
||||||
<div class="card-header py-3">
|
|
||||||
<h3 class="card-title"><i class="fas fa-fw fa-image mr-2"></i>Favicon</h3>
|
|
||||||
</div>
|
|
||||||
<div class="card-body">
|
|
||||||
<form action="post.php" method="post" enctype="multipart/form-data" autocomplete="off">
|
|
||||||
<input type="hidden" name="csrf_token" value="<?php echo $_SESSION['csrf_token'] ?>">
|
|
||||||
|
|
||||||
<img class="mb-3" src="<?php if(file_exists("uploads/favicon.ico")) { echo "uploads/favicon.ico"; } else { echo "favicon.ico"; } ?>">
|
|
||||||
|
|
||||||
<div class="form-group">
|
|
||||||
<input type="file" class="form-control-file" name="file" accept=".ico">
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<hr>
|
|
||||||
|
|
||||||
<button type="submit" name="edit_favicon_settings" class="btn btn-primary text-bold"><i class="fa fa-check mr-2"></i>Upload Icon</button>
|
|
||||||
|
|
||||||
</form>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<?php
|
|
||||||
require_once "includes/footer.php";
|
|
||||||
|
|
||||||
@@ -1,135 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
// Default Column Sortby Filter
|
|
||||||
$sort = "ticket_status_name";
|
|
||||||
$order = "ASC";
|
|
||||||
|
|
||||||
require_once "includes/inc_all_admin.php";
|
|
||||||
|
|
||||||
|
|
||||||
//Rebuild URL
|
|
||||||
$url_query_strings_sort = http_build_query($get_copy);
|
|
||||||
|
|
||||||
$sql = mysqli_query(
|
|
||||||
$mysqli,
|
|
||||||
"SELECT SQL_CALC_FOUND_ROWS * FROM ticket_statuses
|
|
||||||
WHERE ticket_status_name LIKE '%$q%'
|
|
||||||
ORDER BY $sort $order LIMIT $record_from, $record_to"
|
|
||||||
);
|
|
||||||
|
|
||||||
$num_rows = mysqli_fetch_row(mysqli_query($mysqli, "SELECT FOUND_ROWS()"));
|
|
||||||
|
|
||||||
?>
|
|
||||||
|
|
||||||
<div class="card card-dark">
|
|
||||||
<div class="card-header py-2">
|
|
||||||
<h3 class="card-title mt-2"><i class="fas fa-fw fa-info-circle mr-2"></i>Tickets Statuses</h3>
|
|
||||||
<div class="card-tools">
|
|
||||||
<button type="button" class="btn btn-primary" data-toggle="modal" data-target="#addTicketStatusModal"><i class="fas fa-plus mr-2"></i>New Ticket Status</button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="card-body">
|
|
||||||
<div class="row">
|
|
||||||
<div class="col-sm-4 mb-2">
|
|
||||||
<form autocomplete="off">
|
|
||||||
<div class="input-group">
|
|
||||||
<input type="search" class="form-control" name="q" value="<?php if (isset($q)) { echo stripslashes(nullable_htmlentities($q)); } ?>" placeholder="Search Ticket Statuses">
|
|
||||||
<div class="input-group-append">
|
|
||||||
<button class="btn btn-primary"><i class="fa fa-search"></i></button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</form>
|
|
||||||
</div>
|
|
||||||
<div class="col-sm-8">
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<hr>
|
|
||||||
<div class="table-responsive-sm">
|
|
||||||
<table class="table table-striped table-borderless table-hover">
|
|
||||||
<thead class="text-dark <?php if ($num_rows[0] == 0) { echo "d-none"; } ?>">
|
|
||||||
<tr>
|
|
||||||
<th>
|
|
||||||
<a class="text-dark" href="?<?php echo $url_query_strings_sort; ?>&sort=ticket_status_name&order=<?php echo $disp; ?>">
|
|
||||||
Name <?php if ($sort == 'ticket_status_name') { echo $order_icon; } ?>
|
|
||||||
</a>
|
|
||||||
</th>
|
|
||||||
<th>
|
|
||||||
<a class="text-dark" href="?<?php echo $url_query_strings_sort; ?>&sort=ticket_status_color&order=<?php echo $disp; ?>">
|
|
||||||
Color <?php if ($sort == 'ticket_status_color') { echo $order_icon; } ?>
|
|
||||||
</a>
|
|
||||||
</th>
|
|
||||||
<th>
|
|
||||||
<a class="text-dark" href="?<?php echo $url_query_strings_sort; ?>&sort=ticket_status_active&order=<?php echo $disp; ?>">
|
|
||||||
Status <?php if ($sort == 'ticket_status_active') { echo $order_icon; } ?>
|
|
||||||
</a>
|
|
||||||
</th>
|
|
||||||
<th class="text-center">Action</th>
|
|
||||||
</tr>
|
|
||||||
</thead>
|
|
||||||
<tbody>
|
|
||||||
<?php
|
|
||||||
|
|
||||||
while ($row = mysqli_fetch_array($sql)) {
|
|
||||||
$ticket_status_id = intval($row['ticket_status_id']);
|
|
||||||
$ticket_status_name = nullable_htmlentities($row['ticket_status_name']);
|
|
||||||
$ticket_status_color = nullable_htmlentities($row['ticket_status_color']);
|
|
||||||
$ticket_status_active = intval($row['ticket_status_active']);
|
|
||||||
if ($ticket_status_active) {
|
|
||||||
$ticket_status_display = "<div class='text-success text-bold'>Active</div>";
|
|
||||||
} else {
|
|
||||||
$ticket_status_display = "<div class='text-secondary'>Disabled</div>";
|
|
||||||
}
|
|
||||||
|
|
||||||
?>
|
|
||||||
<tr>
|
|
||||||
<td>
|
|
||||||
<a href="#" data-toggle="modal" data-target="#editTicketStatusModal<?php echo $ticket_status_id; ?>">
|
|
||||||
<?php echo $ticket_status_name; ?>
|
|
||||||
</a>
|
|
||||||
</td>
|
|
||||||
<td>
|
|
||||||
<span class='badge badge-pill text-light p-2' style="background-color: <?php echo $ticket_status_color; ?>"><?php echo $ticket_status_name; ?></span>
|
|
||||||
<td><?php echo $ticket_status_display; ?></td>
|
|
||||||
<td>
|
|
||||||
<?php if ( $ticket_status_id > 5 ) { ?>
|
|
||||||
<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>
|
|
||||||
<div class="dropdown-menu">
|
|
||||||
<a class="dropdown-item" href="#" data-toggle="modal" data-target="#editTicketStatusModal<?php echo $ticket_status_id; ?>">
|
|
||||||
<i class="fas fa-fw fa-edit mr-2"></i>Edit
|
|
||||||
</a>
|
|
||||||
<div class="dropdown-divider"></div>
|
|
||||||
<a class="dropdown-item text-danger text-bold confirm-link" href="post.php?delete_ticket_status=<?php echo $ticket_status_id; ?>">
|
|
||||||
<i class="fas fa-fw fa-trash mr-2"></i>Delete
|
|
||||||
</a>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<?php } ?>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
|
|
||||||
<?php
|
|
||||||
if ( $ticket_status_id > 5 ) {
|
|
||||||
require "modals/admin_ticket_status_edit_modal.php";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
?>
|
|
||||||
|
|
||||||
</tbody>
|
|
||||||
</table>
|
|
||||||
</div>
|
|
||||||
<?php require_once "includes/filter_footer.php";
|
|
||||||
?>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<?php
|
|
||||||
require_once "modals/admin_ticket_status_add_modal.php";
|
|
||||||
|
|
||||||
require_once "includes/footer.php";
|
|
||||||
|
|
||||||
@@ -1,119 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
// Default Column Sortby Filter
|
|
||||||
$sort = "ticket_template_name";
|
|
||||||
$order = "ASC";
|
|
||||||
|
|
||||||
require_once "includes/inc_all_admin.php";
|
|
||||||
|
|
||||||
|
|
||||||
//Rebuild URL
|
|
||||||
$url_query_strings_sort = http_build_query($get_copy);
|
|
||||||
|
|
||||||
$sql = mysqli_query(
|
|
||||||
$mysqli,
|
|
||||||
"SELECT SQL_CALC_FOUND_ROWS * FROM ticket_templates
|
|
||||||
WHERE (ticket_template_name LIKE '%$q%' OR ticket_template_description LIKE '%$q%')
|
|
||||||
AND ticket_template_archived_at IS NULL
|
|
||||||
ORDER BY $sort $order LIMIT $record_from, $record_to"
|
|
||||||
);
|
|
||||||
|
|
||||||
$num_rows = mysqli_fetch_row(mysqli_query($mysqli, "SELECT FOUND_ROWS()"));
|
|
||||||
|
|
||||||
?>
|
|
||||||
|
|
||||||
<div class="card card-dark">
|
|
||||||
<div class="card-header py-2">
|
|
||||||
<h3 class="card-title mt-2"><i class="fas fa-fw fa-life-ring mr-2"></i>Ticket Templates</h3>
|
|
||||||
<div class="card-tools">
|
|
||||||
<button type="button" class="btn btn-primary" data-toggle="modal" data-target="#addTicketTemplateModal"><i class="fas fa-plus mr-2"></i>New Ticket Template</button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="card-body">
|
|
||||||
<form autocomplete="off">
|
|
||||||
<div class="row">
|
|
||||||
|
|
||||||
<div class="col-md-4">
|
|
||||||
<div class="input-group mb-3 mb-md-0">
|
|
||||||
<input type="search" class="form-control" name="q" value="<?php if(isset($q)){ echo stripslashes(nullable_htmlentities($q)); } ?>" placeholder="Search Ticket Templates">
|
|
||||||
<div class="input-group-append">
|
|
||||||
<button class="btn btn-dark"><i class="fa fa-search"></i></button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="col-md-8">
|
|
||||||
</div>
|
|
||||||
|
|
||||||
</div>
|
|
||||||
</form>
|
|
||||||
<hr>
|
|
||||||
<div class="table-responsive-sm">
|
|
||||||
<table class="table table-striped table-borderless table-hover">
|
|
||||||
<thead class="text-dark <?php if($num_rows[0] == 0){ echo "d-none"; } ?>">
|
|
||||||
<tr>
|
|
||||||
<th>
|
|
||||||
<a class="text-secondary" href="?<?php echo $url_query_strings_sort; ?>&sort=ticket_template_name&order=<?php echo $disp; ?>">
|
|
||||||
Template <?php if ($sort == 'ticket_template_name') { echo $order_icon; } ?>
|
|
||||||
</a>
|
|
||||||
</th>
|
|
||||||
<th>Tasks</th>
|
|
||||||
<th class="text-center">Action</th>
|
|
||||||
</tr>
|
|
||||||
</thead>
|
|
||||||
<tbody>
|
|
||||||
<?php
|
|
||||||
|
|
||||||
while($row = mysqli_fetch_array($sql)){
|
|
||||||
$ticket_template_id = intval($row['ticket_template_id']);
|
|
||||||
$ticket_template_name = nullable_htmlentities($row['ticket_template_name']);
|
|
||||||
$ticket_template_description = nullable_htmlentities($row['ticket_template_description']);
|
|
||||||
$ticket_template_subject = nullable_htmlentities($row['ticket_template_subject']);
|
|
||||||
$ticket_template_created_at = nullable_htmlentities($row['ticket_template_created_at']);
|
|
||||||
|
|
||||||
?>
|
|
||||||
<tr>
|
|
||||||
<td>
|
|
||||||
<a class="text-dark">
|
|
||||||
<div class="media">
|
|
||||||
<i class="fa fa-fw fa-2x fa-life-ring mr-3"></i>
|
|
||||||
<div class="media-body">
|
|
||||||
<div>
|
|
||||||
<a href="admin_ticket_template_details.php?ticket_template_id=<?php echo $ticket_template_id; ?>">
|
|
||||||
<?php echo $ticket_template_name; ?>
|
|
||||||
</a>
|
|
||||||
</div>
|
|
||||||
<div><small class="text-secondary"><?php echo $ticket_template_description; ?></small></div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</a>
|
|
||||||
</td>
|
|
||||||
<td>0</td>
|
|
||||||
<td>
|
|
||||||
<div class="dropdown dropleft text-center">
|
|
||||||
<button class="btn btn-secondary btn-sm" data-toggle="dropdown">
|
|
||||||
<i class="fas fa-ellipsis-h"></i>
|
|
||||||
</button>
|
|
||||||
<div class="dropdown-menu">
|
|
||||||
<a class="dropdown-item text-danger text-bold confirm-link" href="post.php?delete_ticket_template=<?php echo $ticket_template_id; ?>">
|
|
||||||
<i class="fas fa-fw fa-trash mr-2"></i>Delete
|
|
||||||
</a>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
|
|
||||||
<?php } ?>
|
|
||||||
|
|
||||||
</tbody>
|
|
||||||
</table>
|
|
||||||
</div>
|
|
||||||
<?php require_once "includes/filter_footer.php";
|
|
||||||
?>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<?php
|
|
||||||
require_once "modals/admin_ticket_template_add_modal.php";
|
|
||||||
require_once "includes/footer.php";
|
|
||||||
|
|
||||||
@@ -1,144 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
require_once "includes/inc_all_admin.php";
|
|
||||||
|
|
||||||
|
|
||||||
//Initialize the HTML Purifier to prevent XSS
|
|
||||||
require "plugins/htmlpurifier/HTMLPurifier.standalone.php";
|
|
||||||
|
|
||||||
$purifier_config = HTMLPurifier_Config::createDefault();
|
|
||||||
$purifier_config->set('Cache.DefinitionImpl', null); // Disable cache by setting a non-existent directory or an invalid one
|
|
||||||
$purifier_config->set('URI.AllowedSchemes', ['data' => true, 'src' => true, 'http' => true, 'https' => true]);
|
|
||||||
$purifier = new HTMLPurifier($purifier_config);
|
|
||||||
|
|
||||||
if (isset($_GET['ticket_template_id'])) {
|
|
||||||
$ticket_template_id = intval($_GET['ticket_template_id']);
|
|
||||||
}
|
|
||||||
|
|
||||||
$sql_ticket_templates = mysqli_query($mysqli, "SELECT * FROM ticket_templates WHERE ticket_template_id = $ticket_template_id");
|
|
||||||
|
|
||||||
$row = mysqli_fetch_array($sql_ticket_templates);
|
|
||||||
|
|
||||||
$ticket_template_name = nullable_htmlentities($row['ticket_template_name']);
|
|
||||||
$ticket_template_description = nullable_htmlentities($row['ticket_template_description']);
|
|
||||||
$ticket_template_subject = nullable_htmlentities($row['ticket_template_subject']);
|
|
||||||
$ticket_template_details = $purifier->purify($row['ticket_template_details']);
|
|
||||||
$ticket_template_created_at = nullable_htmlentities($row['ticket_template_created_at']);
|
|
||||||
$ticket_template_updated_at = nullable_htmlentities($row['ticket_template_updated_at']);
|
|
||||||
|
|
||||||
// Get Task Templates
|
|
||||||
$sql_task_templates = mysqli_query($mysqli, "SELECT * FROM task_templates WHERE task_template_ticket_template_id = $ticket_template_id ORDER BY task_template_order ASC, task_template_id ASC");
|
|
||||||
|
|
||||||
?>
|
|
||||||
|
|
||||||
<ol class="breadcrumb d-print-none">
|
|
||||||
<li class="breadcrumb-item">
|
|
||||||
<a href="clients.php">Home</a>
|
|
||||||
</li>
|
|
||||||
<li class="breadcrumb-item">
|
|
||||||
<a href="admin_user.php">Admin</a>
|
|
||||||
</li>
|
|
||||||
<li class="breadcrumb-item">
|
|
||||||
<a href="admin_ticket_template.php">Ticket Templates</a>
|
|
||||||
</li>
|
|
||||||
<li class="breadcrumb-item active"><i class="fas fa-life-ring mr-2"></i><?php echo $ticket_template_name; ?></li>
|
|
||||||
</ol>
|
|
||||||
|
|
||||||
<div class="row">
|
|
||||||
<div class="col-8">
|
|
||||||
|
|
||||||
<div class="card card-dark">
|
|
||||||
<div class="card-header">
|
|
||||||
<h3 class="card-title mt-2">
|
|
||||||
<div class="media">
|
|
||||||
<i class="fa fa-fw fa-2x fa-life-ring mr-3"></i>
|
|
||||||
<div class="media-body">
|
|
||||||
<h3 class="mb-0"><?php echo $ticket_template_name; ?></h3>
|
|
||||||
<div><small class="text-secondary"><?php echo $ticket_template_description; ?></small></div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</h3>
|
|
||||||
<div class="card-tools">
|
|
||||||
<button type="button" class="btn btn-default btn-sm" data-toggle="modal" data-target="#editTicketTemplateModal">
|
|
||||||
<i class="fas fa-edit"></i>
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<h5><?php echo $ticket_template_subject; ?></h5>
|
|
||||||
<div class="card-body prettyContent">
|
|
||||||
<?php echo $ticket_template_details; ?>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="col-4">
|
|
||||||
|
|
||||||
<div class="card card-dark">
|
|
||||||
<div class="card-header">
|
|
||||||
<h5 class="card-title"><i class="fa fa-fw fa-tasks mr-2"></i>Tasks</h5>
|
|
||||||
</div>
|
|
||||||
<div class="card-body">
|
|
||||||
<form action="post.php" method="post" autocomplete="off">
|
|
||||||
<input type="hidden" name="ticket_template_id" value="<?php echo $ticket_template_id; ?>">
|
|
||||||
<div class="form-group">
|
|
||||||
<div class="input-group">
|
|
||||||
<div class="input-group-prepend">
|
|
||||||
<span class="input-group-text"><i class="fa fa-fw fa-tasks"></i></span>
|
|
||||||
</div>
|
|
||||||
<input type="text" class="form-control" name="task_name" placeholder="Create a task" required>
|
|
||||||
<div class="input-group-append">
|
|
||||||
<button type="submit" name="add_ticket_template_task" class="btn btn-primary"><i class="fas fa-fw fa-check"></i></button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</form>
|
|
||||||
<table class="table table-striped table-sm">
|
|
||||||
<?php
|
|
||||||
while($row = mysqli_fetch_array($sql_task_templates)){
|
|
||||||
$task_id = intval($row['task_template_id']);
|
|
||||||
$task_name = nullable_htmlentities($row['task_template_name']);
|
|
||||||
$task_order = intval($row['task_template_order']);
|
|
||||||
$task_completion_estimate = intval($row['task_template_completion_estimate']);
|
|
||||||
$task_description = nullable_htmlentities($row['task_template_description']);
|
|
||||||
?>
|
|
||||||
<tr>
|
|
||||||
<td><i class="far fa-fw fa-square text-secondary"></i></td>
|
|
||||||
<td><span class="text-secondary"><?php echo $task_completion_estimate; ?>m</span> - <?php echo $task_name; ?></td>
|
|
||||||
<td class="text-right">
|
|
||||||
<div class="float-right">
|
|
||||||
<div class="dropdown dropleft text-center">
|
|
||||||
<button class="btn btn-link text-secondary btn-sm" type="button" data-toggle="dropdown">
|
|
||||||
<i class="fas fa-fw fa-ellipsis-v"></i>
|
|
||||||
</button>
|
|
||||||
<div class="dropdown-menu">
|
|
||||||
<a class="dropdown-item" href="#" data-toggle="modal" data-target="#editTaskModal<?php echo $task_id; ?>">
|
|
||||||
<i class="fas fa-fw fa-edit mr-2"></i>Edit
|
|
||||||
</a>
|
|
||||||
<div class="dropdown-divider"></div>
|
|
||||||
<a class="dropdown-item text-danger confirm-link" href="post.php?delete_task_template=<?php echo $task_id; ?>&csrf_token=<?php echo $_SESSION['csrf_token'] ?>">
|
|
||||||
<i class="fas fa-fw fa-trash-alt mr-2"></i>Delete
|
|
||||||
</a>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
<?php
|
|
||||||
require "modals/task_edit_modal.php";
|
|
||||||
}
|
|
||||||
?>
|
|
||||||
</table>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
</div>
|
|
||||||
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<script src="js/pretty_content.js"></script>
|
|
||||||
|
|
||||||
<?php
|
|
||||||
|
|
||||||
require_once "modals/admin_ticket_template_edit_modal.php";
|
|
||||||
require_once "includes/footer.php";
|
|
||||||
@@ -1,88 +0,0 @@
|
|||||||
<?php
|
|
||||||
require_once "includes/inc_all_admin.php";
|
|
||||||
|
|
||||||
require_once "includes/database_version.php";
|
|
||||||
|
|
||||||
$updates = fetchUpdates();
|
|
||||||
|
|
||||||
$latest_version = $updates->latest_version;
|
|
||||||
$current_version = $updates->current_version;
|
|
||||||
$result = $updates->result;
|
|
||||||
|
|
||||||
$git_log = shell_exec("git log $repo_branch..origin/$repo_branch --pretty=format:'<tr><td>%h</td><td>%ar</td><td>%s</td></tr>'");
|
|
||||||
|
|
||||||
?>
|
|
||||||
|
|
||||||
<div class="card card-dark">
|
|
||||||
<div class="card-header py-3">
|
|
||||||
<h3 class="card-title"><i class="fas fa-fw fa-download mr-2"></i>Update</h3>
|
|
||||||
</div>
|
|
||||||
<div class="card-body" style="text-align: center;">
|
|
||||||
|
|
||||||
<!-- Check if git fetch result was successful (0), if not show a warning -->
|
|
||||||
<?php if ($result !== 0) { ?>
|
|
||||||
<div class="alert alert-danger">
|
|
||||||
<strong>WARNING: Could not find execute 'git fetch'.</strong>
|
|
||||||
<br><br>
|
|
||||||
<i>Error details:- <?php echo shell_exec("git fetch 2>&1"); ?></i>
|
|
||||||
<br>
|
|
||||||
<br>Things to check: Is Git installed? Is the Git origin/remote correct? Are web server file permissions too strict?
|
|
||||||
<br>Seek support on the <a href="https://forum.itflow.org">Forum</a> if required - include relevant PHP error logs & ITFlow debug output
|
|
||||||
</div>
|
|
||||||
<?php } ?>
|
|
||||||
|
|
||||||
<?php if (LATEST_DATABASE_VERSION > CURRENT_DATABASE_VERSION) { ?>
|
|
||||||
<div class="alert alert-warning">
|
|
||||||
<strong>Ensure you have a current <a href="https://docs.itflow.org/backups">app & database backup</a> before updating!</strong>
|
|
||||||
</div>
|
|
||||||
<br>
|
|
||||||
<a class="btn btn-dark btn-lg my-4" href="post.php?update_db"><i class="fas fa-fw fa-4x fa-download mb-1"></i><h5>Update Database</h5></a>
|
|
||||||
<br>
|
|
||||||
<small class="text-secondary">Current DB Version: <?php echo CURRENT_DATABASE_VERSION; ?></small>
|
|
||||||
<br>
|
|
||||||
<small class="text-secondary">Latest DB Version: <?php echo LATEST_DATABASE_VERSION; ?></small>
|
|
||||||
<br>
|
|
||||||
<hr>
|
|
||||||
|
|
||||||
<?php } else {
|
|
||||||
if (!empty($git_log)) { ?>
|
|
||||||
|
|
||||||
<a class="btn btn-primary btn-lg my-4" href="post.php?update"><i class="fas fa-fw fa-4x fa-download mb-1"></i><h5>Update App</h5></a>
|
|
||||||
<a class="btn btn-danger btn-lg" href="post.php?update&force_update=1"><i class="fas fa-fw fa-4x fa-hammer mb-1"></i><h5>FORCE Update App</h5></a>
|
|
||||||
|
|
||||||
<?php } else { ?>
|
|
||||||
<p><strong>Application Release Version:<br><strong class="text-dark"><?php echo APP_VERSION; ?></strong></p>
|
|
||||||
<p class="text-secondary">Database Version:<br><strong class="text-dark"><?php echo CURRENT_DATABASE_VERSION; ?></strong></p>
|
|
||||||
<p class="text-secondary">Code Commit:<br><strong class="text-dark"><?php echo $current_version; ?></strong></p>
|
|
||||||
<p class="text-muted">You are up to date!<br>Everything is going to be alright</p>
|
|
||||||
<i class="far fa-3x text-dark fa-smile-wink"></i><br>
|
|
||||||
<?php }
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!empty($git_log)) { ?>
|
|
||||||
<table class="table ">
|
|
||||||
<thead>
|
|
||||||
<tr>
|
|
||||||
<th>Commit</th>
|
|
||||||
<th>When</th>
|
|
||||||
<th>Description</th>
|
|
||||||
</tr>
|
|
||||||
</thead>
|
|
||||||
<tbody>
|
|
||||||
<?php
|
|
||||||
echo $git_log;
|
|
||||||
?>
|
|
||||||
</tbody>
|
|
||||||
</table>
|
|
||||||
<?php
|
|
||||||
}
|
|
||||||
|
|
||||||
?>
|
|
||||||
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<?php
|
|
||||||
|
|
||||||
require_once "includes/footer.php";
|
|
||||||
|
|
||||||
243
admin_user.php
243
admin_user.php
@@ -1,243 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
// Default Column Sortby Filter
|
|
||||||
$sort = "user_name";
|
|
||||||
$order = "ASC";
|
|
||||||
|
|
||||||
require_once "includes/inc_all_admin.php";
|
|
||||||
|
|
||||||
|
|
||||||
//Rebuild URL
|
|
||||||
$url_query_strings_sort = http_build_query($get_copy);
|
|
||||||
|
|
||||||
$sql = mysqli_query(
|
|
||||||
$mysqli,
|
|
||||||
"SELECT SQL_CALC_FOUND_ROWS * FROM users, user_settings, user_roles
|
|
||||||
WHERE users.user_id = user_settings.user_id
|
|
||||||
AND user_settings.user_role = user_roles.user_role_id
|
|
||||||
AND (user_name LIKE '%$q%' OR user_email LIKE '%$q%')
|
|
||||||
AND user_archived_at IS NULL
|
|
||||||
ORDER BY $sort $order LIMIT $record_from, $record_to"
|
|
||||||
);
|
|
||||||
|
|
||||||
$num_rows = mysqli_fetch_row(mysqli_query($mysqli, "SELECT FOUND_ROWS()"));
|
|
||||||
|
|
||||||
?>
|
|
||||||
|
|
||||||
<div class="card card-dark">
|
|
||||||
<div class="card-header py-2">
|
|
||||||
<h3 class="card-title mt-2"><i class="fas fa-fw fa-users mr-2"></i>Users</h3>
|
|
||||||
<div class="card-tools">
|
|
||||||
<div class="btn-group">
|
|
||||||
<button type="button" class="btn btn-primary" data-toggle="modal" data-target="#addUserModal">
|
|
||||||
<i class="fas fa-fw fa-user-plus mr-2"></i>New User
|
|
||||||
</button>
|
|
||||||
<button type="button" class="btn btn-primary dropdown-toggle dropdown-toggle-split" data-toggle="dropdown"></button>
|
|
||||||
<div class="dropdown-menu">
|
|
||||||
<!--<a class="dropdown-item text-dark" href="#" data-toggle="modal" data-target="#userInviteModal"><i class="fas fa-paper-plane mr-2"></i>Invite User</a>-->
|
|
||||||
<?php if ($num_rows[0] > 1) { ?>
|
|
||||||
<div class="dropdown-divider"></div>
|
|
||||||
<a class="dropdown-item text-danger" href="#" data-toggle="modal" data-target="#resetAllUserPassModal"><i class="fas fa-skull-crossbones mr-2"></i>IR</a>
|
|
||||||
<?php } ?>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="card-body">
|
|
||||||
<form class="mb-4" autocomplete="off">
|
|
||||||
<div class="row">
|
|
||||||
<div class="col-md-4">
|
|
||||||
<div class="input-group">
|
|
||||||
<input type="search" class="form-control" name="q" value="<?php if (isset($q)) {echo stripslashes(nullable_htmlentities($q));} ?>" placeholder="Search Users">
|
|
||||||
<div class="input-group-append">
|
|
||||||
<button class="btn btn-primary"><i class="fa fa-search"></i></button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="col-md-8">
|
|
||||||
<div class="float-right">
|
|
||||||
<button type="button" class="btn btn-default" data-toggle="modal" data-target="#exportUserModal"><i class="fa fa-fw fa-download mr-2"></i>Export</button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</form>
|
|
||||||
<hr>
|
|
||||||
<div class="table-responsive-sm">
|
|
||||||
<table class="table table-striped table-borderless table-hover">
|
|
||||||
<thead class="text-dark <?php if ($num_rows[0] == 0) { echo "d-none"; } ?>">
|
|
||||||
<tr>
|
|
||||||
<th class="text-center">
|
|
||||||
<a class="text-dark" href="?<?php echo $url_query_strings_sort; ?>&sort=user_name&order=<?php echo $disp; ?>">
|
|
||||||
Name <?php if ($sort == 'user_name') { echo $order_icon; } ?>
|
|
||||||
</a>
|
|
||||||
</th>
|
|
||||||
<th>
|
|
||||||
<a class="text-dark" href="?<?php echo $url_query_strings_sort; ?>&sort=user_email&order=<?php echo $disp; ?>">
|
|
||||||
Email <?php if ($sort == 'user_email') { echo $order_icon; } ?>
|
|
||||||
</a>
|
|
||||||
</th>
|
|
||||||
<th>
|
|
||||||
<a class="text-dark" href="?<?php echo $url_query_strings_sort; ?>&sort=user_role&order=<?php echo $disp; ?>">
|
|
||||||
Role <?php if ($sort == 'user_role') { echo $order_icon; } ?>
|
|
||||||
</a>
|
|
||||||
</th>
|
|
||||||
<th>
|
|
||||||
<a class="text-dark" href="?<?php echo $url_query_strings_sort; ?>&sort=user_status&order=<?php echo $disp; ?>">
|
|
||||||
Status <?php if ($sort == 'user_status') { echo $order_icon; } ?>
|
|
||||||
</a>
|
|
||||||
</th>
|
|
||||||
<th class="text-center">MFA</th>
|
|
||||||
<th>
|
|
||||||
Last Login
|
|
||||||
</th>
|
|
||||||
<th class="text-center">Action</th>
|
|
||||||
</tr>
|
|
||||||
</thead>
|
|
||||||
<tbody>
|
|
||||||
<?php
|
|
||||||
|
|
||||||
while ($row = mysqli_fetch_array($sql)) {
|
|
||||||
$user_id = intval($row['user_id']);
|
|
||||||
$user_name = nullable_htmlentities($row['user_name']);
|
|
||||||
$user_email = nullable_htmlentities($row['user_email']);
|
|
||||||
$user_status = intval($row['user_status']);
|
|
||||||
if ($user_status == 2) {
|
|
||||||
$user_status_display = "<span class='text-info'>Invited</span>";
|
|
||||||
} elseif ($user_status == 1) {
|
|
||||||
$user_status_display = "<span class='text-success'>Active</span>";
|
|
||||||
} else{
|
|
||||||
$user_status_display = "<span class='text-danger'>Disabled</span>";
|
|
||||||
}
|
|
||||||
$user_avatar = nullable_htmlentities($row['user_avatar']);
|
|
||||||
$user_token = nullable_htmlentities($row['user_token']);
|
|
||||||
if(empty($user_token)) {
|
|
||||||
$mfa_status_display = "<i class='fas fa-fw fa-unlock text-danger'></i>";
|
|
||||||
} else {
|
|
||||||
$mfa_status_display = "<i class='fas fa-fw fa-lock text-success'></i>";
|
|
||||||
}
|
|
||||||
$user_config_force_mfa = intval($row['user_config_force_mfa']);
|
|
||||||
$user_role = $row['user_role'];
|
|
||||||
$user_role_display = nullable_htmlentities($row['user_role_name']);
|
|
||||||
$user_initials = nullable_htmlentities(initials($user_name));
|
|
||||||
|
|
||||||
$sql_last_login = mysqli_query(
|
|
||||||
$mysqli,
|
|
||||||
"SELECT * FROM logs
|
|
||||||
WHERE log_user_id = $user_id AND log_type = 'Login'
|
|
||||||
ORDER BY log_id DESC LIMIT 1"
|
|
||||||
);
|
|
||||||
if (mysqli_num_rows($sql_last_login) == 0) {
|
|
||||||
$last_login = "<span class='text-bold'>Never logged in</span>";
|
|
||||||
} else {
|
|
||||||
$row = mysqli_fetch_array($sql_last_login);
|
|
||||||
$log_created_at = nullable_htmlentities($row['log_created_at']);
|
|
||||||
$log_ip = nullable_htmlentities($row['log_ip']);
|
|
||||||
$log_user_agent = nullable_htmlentities($row['log_user_agent']);
|
|
||||||
$log_user_os = getOS($log_user_agent);
|
|
||||||
$log_user_browser = getWebBrowser($log_user_agent);
|
|
||||||
$last_login = "$log_created_at<small class='text-secondary'><div class='mt-1'>$log_user_os</div><div class='mt-1'>$log_user_browser</div><div class='mt-1'><i class='fa fa-fw fa-globe'></i> $log_ip</div></small>";
|
|
||||||
}
|
|
||||||
|
|
||||||
// Get User Client Access Permissions
|
|
||||||
$user_client_access_sql = mysqli_query($mysqli,"SELECT client_id FROM user_permissions WHERE user_id = $user_id");
|
|
||||||
$client_access_array = [];
|
|
||||||
while ($row = mysqli_fetch_assoc($user_client_access_sql)) {
|
|
||||||
$client_access_array[] = intval($row['client_id']);
|
|
||||||
}
|
|
||||||
|
|
||||||
$sql_remember_tokens = mysqli_query($mysqli, "SELECT * FROM remember_tokens WHERE remember_token_user_id = $user_id");
|
|
||||||
$remember_token_count = mysqli_num_rows($sql_remember_tokens);
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
?>
|
|
||||||
<tr>
|
|
||||||
<td class="text-center">
|
|
||||||
<a class="text-dark" href="#" <?php if ($user_id !== $session_user_id) { // Prevent modifying self ?> data-toggle="modal" data-target="#editUserModal<?php echo $user_id; ?>" <?php } ?>>
|
|
||||||
<?php if (!empty($user_avatar)) { ?>
|
|
||||||
<img class="img-size-50 img-circle" src="<?php echo "uploads/users/$user_id/$user_avatar"; ?>">
|
|
||||||
<?php } else { ?>
|
|
||||||
<span class="fa-stack fa-2x">
|
|
||||||
<i class="fa fa-circle fa-stack-2x text-secondary"></i>
|
|
||||||
<span class="fa fa-stack-1x text-white"><?php echo $user_initials; ?></span>
|
|
||||||
</span>
|
|
||||||
<br>
|
|
||||||
<?php } ?>
|
|
||||||
|
|
||||||
<div class="text-secondary"><?php echo $user_name; ?></div>
|
|
||||||
</a>
|
|
||||||
</td>
|
|
||||||
<td><a href="mailto:<?php echo $user_email; ?>"><?php echo $user_email; ?></a></td>
|
|
||||||
<td><?php echo $user_role_display; ?></td>
|
|
||||||
<td><?php echo $user_status_display; ?></td>
|
|
||||||
<td class="text-center"><?php echo $mfa_status_display; ?></td>
|
|
||||||
<td><?php echo $last_login; ?></td>
|
|
||||||
<td>
|
|
||||||
<?php if ($user_id !== $session_user_id) { // Prevent modifying self ?>
|
|
||||||
<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>
|
|
||||||
<div class="dropdown-menu">
|
|
||||||
<a class="dropdown-item" href="#" data-toggle="modal" data-target="#editUserModal<?php echo $user_id; ?>">
|
|
||||||
<i class="fas fa-fw fa-user-edit mr-2"></i>Edit
|
|
||||||
</a>
|
|
||||||
<?php if ($remember_token_count > 0) { ?>
|
|
||||||
<a class="dropdown-item" href="post.php?revoke_remember_me=<?php echo $user_id; ?>&csrf_token=<?php echo $_SESSION['csrf_token'] ?>"><i class="fas fa-fw fa-ban mr-2"></i>Revoke <?php echo $remember_token_count; ?> Remember Tokens
|
|
||||||
</a>
|
|
||||||
<?php } ?>
|
|
||||||
<?php if ($user_status == 0) { ?>
|
|
||||||
<a class="dropdown-item text-success" href="post.php?activate_user=<?php echo $user_id; ?>&csrf_token=<?php echo $_SESSION['csrf_token'] ?>">
|
|
||||||
<i class="fas fa-fw fa-user-check mr-2"></i>Activate
|
|
||||||
</a>
|
|
||||||
<?php }elseif ($user_status == 1) { ?>
|
|
||||||
<a class="dropdown-item text-danger" href="post.php?disable_user=<?php echo $user_id; ?>&csrf_token=<?php echo $_SESSION['csrf_token'] ?>">
|
|
||||||
<i class="fas fa-fw fa-user-slash mr-2"></i>Disable
|
|
||||||
</a>
|
|
||||||
<?php } ?>
|
|
||||||
<div class="dropdown-divider"></div>
|
|
||||||
<a class="dropdown-item text-danger" href="#" data-toggle="modal" data-target="#archiveUserModal<?php echo $user_id; ?>">
|
|
||||||
<i class="fas fa-fw fa-archive mr-2"></i>Archive
|
|
||||||
</a>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<?php } ?>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
|
|
||||||
<?php
|
|
||||||
|
|
||||||
require "modals/admin_user_edit_modal.php";
|
|
||||||
|
|
||||||
require "modals/admin_user_archive_modal.php";
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
?>
|
|
||||||
|
|
||||||
</tbody>
|
|
||||||
</table>
|
|
||||||
</div>
|
|
||||||
<?php require_once "includes/filter_footer.php";
|
|
||||||
?>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<script>
|
|
||||||
function generatePassword() {
|
|
||||||
document.getElementById("password").value = "<?php echo randomString() ?>"
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<?php
|
|
||||||
|
|
||||||
require_once "modals/admin_user_add_modal.php";
|
|
||||||
|
|
||||||
require_once "modals/admin_user_invite_modal.php";
|
|
||||||
|
|
||||||
require_once "modals/admin_user_export_modal.php";
|
|
||||||
|
|
||||||
require_once "modals/admin_user_all_reset_password_modal.php";
|
|
||||||
|
|
||||||
require_once "includes/footer.php";
|
|
||||||
|
|
||||||
326
ajax.php
326
ajax.php
@@ -6,31 +6,46 @@
|
|||||||
* Always returns data in JSON format, unless otherwise specified
|
* Always returns data in JSON format, unless otherwise specified
|
||||||
*/
|
*/
|
||||||
|
|
||||||
require_once "config.php";
|
require_once("config.php");
|
||||||
require_once "functions.php";
|
require_once("functions.php");
|
||||||
require_once "check_login.php";
|
require_once("check_login.php");
|
||||||
require_once "plugins/totp/totp.php";
|
require_once("rfc6238.php");
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Fetches SSL certificates from remote hosts & returns the relevant info (issuer, expiry, public key)
|
* Fetches SSL certificates from remote hosts & returns the relevant info (issuer, expiry, public key)
|
||||||
*/
|
*/
|
||||||
if (isset($_GET['certificate_fetch_parse_json_details'])) {
|
if (isset($_GET['certificate_fetch_parse_json_details'])) {
|
||||||
|
|
||||||
// PHP doesn't appreciate attempting SSL sockets to non-existent domains
|
// PHP doesn't appreciate attempting SSL sockets to non-existent domains
|
||||||
if (empty($_GET['domain'])) {
|
if (empty($_GET['domain'])) {
|
||||||
exit();
|
exit();
|
||||||
}
|
}
|
||||||
|
$domain = $_GET['domain'];
|
||||||
|
|
||||||
$name = $_GET['domain'];
|
// FQDNs in database shouldn't have a URL scheme, adding one
|
||||||
|
$domain = "https://".$domain;
|
||||||
|
|
||||||
// Get SSL cert for domain (if exists)
|
// Parse host and port
|
||||||
$certificate = getSSL($name);
|
$url = parse_url($domain, PHP_URL_HOST);
|
||||||
|
$port = parse_url($domain, PHP_URL_PORT);
|
||||||
|
// Default port
|
||||||
|
if (!$port) {
|
||||||
|
$port = "443";
|
||||||
|
}
|
||||||
|
|
||||||
if ($certificate['success'] == "TRUE") {
|
// Get certificate (using verify peer false to allow for self-signed certs)
|
||||||
|
$socket = "ssl://$url:$port";
|
||||||
|
$get = stream_context_create(array("ssl" => array("capture_peer_cert" => true, "verify_peer" => false,)));
|
||||||
|
$read = stream_socket_client($socket, $errno, $errstr, 30, STREAM_CLIENT_CONNECT, $get);
|
||||||
|
$cert = stream_context_get_params($read);
|
||||||
|
$cert_public_key_obj = openssl_x509_parse($cert['options']['ssl']['peer_certificate']);
|
||||||
|
openssl_x509_export($cert['options']['ssl']['peer_certificate'], $export);
|
||||||
|
|
||||||
|
// Process data
|
||||||
|
if ($cert_public_key_obj) {
|
||||||
$response['success'] = "TRUE";
|
$response['success'] = "TRUE";
|
||||||
$response['expire'] = $certificate['expire'];
|
$response['expire'] = date('Y-m-d', $cert_public_key_obj['validTo_time_t']);
|
||||||
$response['issued_by'] = $certificate['issued_by'];
|
$response['issued_by'] = strip_tags($cert_public_key_obj['issuer']['O']);
|
||||||
$response['public_key'] = $certificate['public_key'];
|
$response['public_key'] = $export; //nl2br
|
||||||
} else {
|
} else {
|
||||||
$response['success'] = "FALSE";
|
$response['success'] = "FALSE";
|
||||||
}
|
}
|
||||||
@@ -55,7 +70,7 @@ if (isset($_GET['certificate_get_json_details'])) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Get all domains for this client that could be linked to this certificate
|
// Get all domains for this client that could be linked to this certificate
|
||||||
$domains_sql = mysqli_query($mysqli, "SELECT domain_id, domain_name FROM domains WHERE domain_client_id = $client_id");
|
$domains_sql = mysqli_query($mysqli, "SELECT domain_id, domain_name FROM domains WHERE domain_client_id = '$client_id' AND company_id = '$session_company_id'");
|
||||||
while ($row = mysqli_fetch_array($domains_sql)) {
|
while ($row = mysqli_fetch_array($domains_sql)) {
|
||||||
$response['domains'][] = $row;
|
$response['domains'][] = $row;
|
||||||
}
|
}
|
||||||
@@ -67,7 +82,7 @@ if (isset($_GET['certificate_get_json_details'])) {
|
|||||||
* Looks up info for a given domain ID from the database, used to dynamically populate modal fields
|
* Looks up info for a given domain ID from the database, used to dynamically populate modal fields
|
||||||
*/
|
*/
|
||||||
if (isset($_GET['domain_get_json_details'])) {
|
if (isset($_GET['domain_get_json_details'])) {
|
||||||
enforceUserPermission('module_support');
|
validateTechRole();
|
||||||
|
|
||||||
$domain_id = intval($_GET['domain_id']);
|
$domain_id = intval($_GET['domain_id']);
|
||||||
$client_id = intval($_GET['client_id']);
|
$client_id = intval($_GET['client_id']);
|
||||||
@@ -79,29 +94,11 @@ if (isset($_GET['domain_get_json_details'])) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Get all registrars/webhosts (vendors) for this client that could be linked to this domain
|
// Get all registrars/webhosts (vendors) for this client that could be linked to this domain
|
||||||
$vendor_sql = mysqli_query($mysqli, "SELECT vendor_id, vendor_name FROM vendors WHERE vendor_client_id = $client_id AND vendor_archived_at IS NULL ORDER BY vendor_name ASC");
|
$vendor_sql = mysqli_query($mysqli, "SELECT vendor_id, vendor_name FROM vendors WHERE vendor_client_id = $client_id");
|
||||||
while ($row = mysqli_fetch_array($vendor_sql)) {
|
while ($row = mysqli_fetch_array($vendor_sql)) {
|
||||||
$response['vendors'][] = $row;
|
$response['vendors'][] = $row;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get domain history
|
|
||||||
$history_sql = mysqli_query($mysqli, "SELECT * FROM domain_history WHERE domain_history_domain_id = $domain_id");
|
|
||||||
$history_html = "<table class='table table-sm table-striped border table-hover'>";
|
|
||||||
$history_html .= "<thead class='thead-dark'><tr><th>Date</th><th>Field</th><th>Before</th><th>After</th></tr></thead><tbody>";
|
|
||||||
while ($row = mysqli_fetch_array($history_sql)) {
|
|
||||||
// Fetch data from the query and create table rows
|
|
||||||
$history_html .= "<tr>";
|
|
||||||
$history_html .= "<td>" . htmlspecialchars(date('Y-m-d', strtotime($row['domain_history_modified_at']))) . "</td>";
|
|
||||||
$history_html .= "<td>" . htmlspecialchars($row['domain_history_column']) . "</td>";
|
|
||||||
$history_html .= "<td>" . htmlspecialchars($row['domain_history_old_value']) . "</td>";
|
|
||||||
$history_html .= "<td>" . htmlspecialchars($row['domain_history_new_value']) . "</td>";
|
|
||||||
$history_html .= "</tr>";
|
|
||||||
}
|
|
||||||
$history_html .= "</tbody></table>";
|
|
||||||
|
|
||||||
// Return the HTML content to JavaScript
|
|
||||||
$response['history'] = $history_html;
|
|
||||||
|
|
||||||
echo json_encode($response);
|
echo json_encode($response);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -113,19 +110,17 @@ if (isset($_GET['merge_ticket_get_json_details'])) {
|
|||||||
|
|
||||||
$merge_into_ticket_number = intval($_GET['merge_into_ticket_number']);
|
$merge_into_ticket_number = intval($_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
|
$sql = mysqli_query($mysqli, "SELECT ticket_id, ticket_number, ticket_prefix, ticket_subject, ticket_priority, ticket_status, client_name, contact_name FROM tickets
|
||||||
LEFT JOIN clients ON ticket_client_id = client_id
|
LEFT JOIN clients ON ticket_client_id = client_id
|
||||||
LEFT JOIN contacts ON ticket_contact_id = contact_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' AND tickets.company_id = '$session_company_id'");
|
||||||
WHERE ticket_number = $merge_into_ticket_number");
|
|
||||||
|
|
||||||
if (mysqli_num_rows($sql) == 0) {
|
if (mysqli_num_rows($sql) == 0) {
|
||||||
//Do nothing.
|
//Do nothing.
|
||||||
echo "No ticket found!";
|
|
||||||
} else {
|
} else {
|
||||||
//Return ticket, client and contact details for the given ticket number
|
//Return ticket, client and contact details for the given ticket number
|
||||||
$response = mysqli_fetch_array($sql);
|
$response = mysqli_fetch_array($sql);
|
||||||
|
$response = array_map('htmlentities', $response);
|
||||||
echo json_encode($response);
|
echo json_encode($response);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -148,8 +143,8 @@ if (isset($_GET['network_get_json_details'])) {
|
|||||||
// Lookup all client locations, as networks can be associated with any client location
|
// Lookup all client locations, as networks can be associated with any client location
|
||||||
$locations_sql = mysqli_query(
|
$locations_sql = mysqli_query(
|
||||||
$mysqli,
|
$mysqli,
|
||||||
"SELECT location_id, location_name FROM locations
|
"SELECT location_id, location_name FROM locations
|
||||||
WHERE location_client_id = '$client_id'"
|
WHERE location_client_id = '$client_id' AND company_id = '$session_company_id'"
|
||||||
);
|
);
|
||||||
while ($row = mysqli_fetch_array($locations_sql)) {
|
while ($row = mysqli_fetch_array($locations_sql)) {
|
||||||
$response['locations'][] = $row;
|
$response['locations'][] = $row;
|
||||||
@@ -163,10 +158,10 @@ if (isset($_POST['client_set_notes'])) {
|
|||||||
$notes = sanitizeInput($_POST['notes']);
|
$notes = sanitizeInput($_POST['notes']);
|
||||||
|
|
||||||
// Update notes
|
// Update notes
|
||||||
mysqli_query($mysqli, "UPDATE clients SET client_notes = '$notes' WHERE client_id = $client_id");
|
mysqli_query($mysqli, "UPDATE clients SET client_notes = '$notes' WHERE client_id = '$client_id'");
|
||||||
|
|
||||||
// Logging
|
// Logging
|
||||||
logAction("Client", "Edit", "$session_name edited client notes", $client_id);
|
mysqli_query($mysqli, "INSERT INTO logs SET log_type = 'Client', log_action = 'Modify', log_description = '$session_name modified client notes', log_ip = '$session_ip', log_user_agent = '$session_user_agent', log_created_at = NOW(), log_client_id = $client_id, log_user_id = $session_user_id, company_id = $session_company_id");
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -174,39 +169,11 @@ if (isset($_POST['contact_set_notes'])) {
|
|||||||
$contact_id = intval($_POST['contact_id']);
|
$contact_id = intval($_POST['contact_id']);
|
||||||
$notes = sanitizeInput($_POST['notes']);
|
$notes = sanitizeInput($_POST['notes']);
|
||||||
|
|
||||||
// Get Contact Details and Client ID for Logging
|
|
||||||
$sql = mysqli_query($mysqli,"SELECT contact_name, contact_client_id
|
|
||||||
FROM contacts WHERE contact_id = $contact_id"
|
|
||||||
);
|
|
||||||
$row = mysqli_fetch_array($sql);
|
|
||||||
$contact_name = sanitizeInput($row['contact_name']);
|
|
||||||
$client_id = intval($row['contact_client_id']);
|
|
||||||
|
|
||||||
// Update notes
|
// Update notes
|
||||||
mysqli_query($mysqli, "UPDATE contacts SET contact_notes = '$notes' WHERE contact_id = $contact_id");
|
mysqli_query($mysqli, "UPDATE contacts SET contact_notes = '$notes' WHERE contact_id = $contact_id");
|
||||||
|
|
||||||
// Logging
|
// Logging
|
||||||
logAction("Contact", "Edit", "$session_name edited contact notes for $contact_name", $client_id, $contact_id);
|
mysqli_query($mysqli, "INSERT INTO logs SET log_type = 'Contact', log_action = 'Modify', log_description = '$session_name modified contact notes', log_ip = '$session_ip', log_user_agent = '$session_user_agent', log_user_id = $session_user_id, company_id = $session_company_id");
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
if (isset($_POST['asset_set_notes'])) {
|
|
||||||
$asset_id = intval($_POST['asset_id']);
|
|
||||||
$notes = sanitizeInput($_POST['notes']);
|
|
||||||
|
|
||||||
// Get Asset Details and Client ID for Logging
|
|
||||||
$sql = mysqli_query($mysqli,"SELECT asset_name, asset_client_id
|
|
||||||
FROM assets WHERE asset_id = $asset_id"
|
|
||||||
);
|
|
||||||
$row = mysqli_fetch_array($sql);
|
|
||||||
$asset_name = sanitizeInput($row['asset_name']);
|
|
||||||
$client_id = intval($row['asset_client_id']);
|
|
||||||
|
|
||||||
// Update notes
|
|
||||||
mysqli_query($mysqli, "UPDATE assets SET asset_notes = '$notes' WHERE asset_id = $asset_id");
|
|
||||||
|
|
||||||
// Logging
|
|
||||||
logAction("Asset", "Edit", "$session_name edited asset notes for $asset_name", $client_id, $asset_id);
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -218,7 +185,7 @@ if (isset($_POST['asset_set_notes'])) {
|
|||||||
if (isset($_GET['ticket_add_view'])) {
|
if (isset($_GET['ticket_add_view'])) {
|
||||||
$ticket_id = intval($_GET['ticket_id']);
|
$ticket_id = intval($_GET['ticket_id']);
|
||||||
|
|
||||||
mysqli_query($mysqli, "INSERT INTO ticket_views SET view_ticket_id = $ticket_id, view_user_id = $session_user_id, view_timestamp = NOW()");
|
mysqli_query($mysqli, "INSERT INTO ticket_views SET view_ticket_id = '$ticket_id', view_user_id = '$session_user_id', view_timestamp = NOW()");
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -229,7 +196,7 @@ if (isset($_GET['ticket_add_view'])) {
|
|||||||
if (isset($_GET['ticket_query_views'])) {
|
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_array($query)) {
|
||||||
$users[] = $row['user_name'];
|
$users[] = $row['user_name'];
|
||||||
}
|
}
|
||||||
@@ -238,10 +205,10 @@ if (isset($_GET['ticket_query_views'])) {
|
|||||||
$users = array_unique($users);
|
$users = array_unique($users);
|
||||||
if (count($users) > 1) {
|
if (count($users) > 1) {
|
||||||
// Multiple viewers
|
// Multiple viewers
|
||||||
$response['message'] = "<i class='fas fa-fw fa-eye mr-2'></i>" . nullable_htmlentities(implode(", ", $users) . " are viewing this ticket.");
|
$response['message'] = htmlentities(implode(", ", $users) . " are viewing this ticket.");
|
||||||
} else {
|
} else {
|
||||||
// Single viewer
|
// Single viewer
|
||||||
$response['message'] = "<i class='fas fa-fw fa-eye mr-2'></i>" . nullable_htmlentities(implode("", $users) . " is viewing this ticket.");
|
$response['message'] = htmlentities(implode("", $users) . " is viewing this ticket.");
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// No viewers
|
// No viewers
|
||||||
@@ -263,39 +230,23 @@ if (isset($_GET['share_generate_link'])) {
|
|||||||
$client_id = intval($_GET['client_id']);
|
$client_id = intval($_GET['client_id']);
|
||||||
$item_type = sanitizeInput($_GET['type']);
|
$item_type = sanitizeInput($_GET['type']);
|
||||||
$item_id = intval($_GET['id']);
|
$item_id = intval($_GET['id']);
|
||||||
$item_email = sanitizeInput($_GET['contact_email']);
|
|
||||||
$item_note = sanitizeInput($_GET['note']);
|
$item_note = sanitizeInput($_GET['note']);
|
||||||
$item_view_limit = intval($_GET['views']);
|
$item_view_limit = intval($_GET['views']);
|
||||||
$item_view_limit_wording = "";
|
|
||||||
if ($item_view_limit == 1) {
|
|
||||||
$item_view_limit_wording = " and may only be viewed <strong>once</strong>, before the link is destroyed.";
|
|
||||||
}
|
|
||||||
$item_expires = sanitizeInput($_GET['expires']);
|
$item_expires = sanitizeInput($_GET['expires']);
|
||||||
$item_expires_friendly = "never"; // default never
|
|
||||||
if ($item_expires == "1 HOUR") {
|
|
||||||
$item_expires_friendly = "1 hour";
|
|
||||||
} elseif ($item_expires == "24 HOUR") {
|
|
||||||
$item_expires_friendly = "1 day";
|
|
||||||
} elseif ($item_expires == "168 HOUR") {
|
|
||||||
$item_expires_friendly = "1 week";
|
|
||||||
} elseif ($item_expires == "730 HOUR") {
|
|
||||||
$item_expires_friendly = "1 month";
|
|
||||||
}
|
|
||||||
|
|
||||||
$item_key = randomString(156);
|
$item_key = randomString(156);
|
||||||
|
|
||||||
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_array(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_array(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 == "Login") {
|
if ($item_type == "Login") {
|
||||||
$login = mysqli_query($mysqli, "SELECT login_name, login_username, login_password FROM logins WHERE login_id = $item_id AND login_client_id = $client_id LIMIT 1");
|
$login = mysqli_query($mysqli, "SELECT login_name, login_username, login_password FROM logins WHERE login_id = '$item_id' AND login_client_id = '$client_id' LIMIT 1");
|
||||||
$row = mysqli_fetch_array($login);
|
$row = mysqli_fetch_array($login);
|
||||||
|
|
||||||
$item_name = sanitizeInput($row['login_name']);
|
$item_name = sanitizeInput($row['login_name']);
|
||||||
@@ -315,82 +266,32 @@ if (isset($_GET['share_generate_link'])) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Insert entry into DB
|
// Insert entry into DB
|
||||||
$sql = mysqli_query($mysqli, "INSERT INTO shared_items SET item_active = 1, item_key = '$item_key', item_type = '$item_type', item_related_id = $item_id, item_encrypted_username = '$item_encrypted_username', item_encrypted_credential = '$item_encrypted_credential', item_note = '$item_note', item_recipient = '$item_email', item_views = 0, item_view_limit = $item_view_limit, item_expire_at = NOW() + INTERVAL + $item_expires, item_client_id = $client_id");
|
$sql = mysqli_query($mysqli, "INSERT INTO shared_items SET item_active = '1', item_key = '$item_key', item_type = '$item_type', item_related_id = '$item_id', item_encrypted_username = '$item_encrypted_username', item_encrypted_credential = '$item_encrypted_credential', item_note = '$item_note', item_views = 0, item_view_limit = '$item_view_limit', item_created_at = NOW(), item_expire_at = '$item_expires', item_client_id = '$client_id'");
|
||||||
$share_id = $mysqli->insert_id;
|
$share_id = $mysqli->insert_id;
|
||||||
|
|
||||||
// Return URL
|
// Return URL
|
||||||
if ($item_type == "Login") {
|
if ($item_type == "Login") {
|
||||||
$url = "https://$config_base_url/guest/guest_view_item.php?id=$share_id&key=$item_key&ek=$login_encryption_key";
|
$url = "$config_base_url/guest_view_item.php?id=$share_id&key=$item_key&ek=$login_encryption_key";
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
$url = "https://$config_base_url/guest/guest_view_item.php?id=$share_id&key=$item_key";
|
$url = "$config_base_url/guest_view_item.php?id=$share_id&key=$item_key";
|
||||||
}
|
}
|
||||||
|
|
||||||
$sql = mysqli_query($mysqli,"SELECT * FROM companies WHERE company_id = 1");
|
|
||||||
$row = mysqli_fetch_array($sql);
|
|
||||||
$company_name = sanitizeInput($row['company_name']);
|
|
||||||
$company_phone = sanitizeInput(formatPhoneNumber($row['company_phone']));
|
|
||||||
|
|
||||||
// Sanitize Config vars from get_settings.php
|
|
||||||
$config_ticket_from_name = sanitizeInput($config_ticket_from_name);
|
|
||||||
$config_ticket_from_email = sanitizeInput($config_ticket_from_email);
|
|
||||||
$config_mail_from_name = sanitizeInput($config_mail_from_name);
|
|
||||||
$config_mail_from_email = sanitizeInput($config_mail_from_email);
|
|
||||||
|
|
||||||
// Send user e-mail, if specified
|
|
||||||
if(!empty($config_smtp_host) && filter_var($item_email, FILTER_VALIDATE_EMAIL)){
|
|
||||||
|
|
||||||
$subject = "Time sensitive - $company_name secure link enclosed";
|
|
||||||
if ($item_expires_friendly == "never") {
|
|
||||||
$subject = "$company_name secure link enclosed";
|
|
||||||
}
|
|
||||||
$body = "Hello,<br><br>$session_name from $company_name sent you a time sensitive secure link regarding \"$item_name\".<br><br>The link will expire in <strong>$item_expires_friendly</strong>$item_view_limit_wording.<br><br><strong><a href=\'$url\'>Click here to access your secure content</a></strong><br><br>--<br>$company_name - Support<br>$config_ticket_from_email<br>$company_phone";
|
|
||||||
|
|
||||||
// Add the intended recipient disclosure
|
|
||||||
$body .= "<br><br><em>This email and any attachments are confidential and intended for the specified recipient(s) only. If you are not the intended recipient, please notify the sender and delete this email. Unauthorized use, disclosure, or distribution is prohibited.</em>";
|
|
||||||
|
|
||||||
$data = [
|
|
||||||
[
|
|
||||||
'from' => $config_mail_from_email,
|
|
||||||
'from_name' => $config_mail_from_name,
|
|
||||||
'recipient' => $item_email,
|
|
||||||
'recipient_name' => $item_email,
|
|
||||||
'subject' => $subject,
|
|
||||||
'body' => $body
|
|
||||||
]
|
|
||||||
];
|
|
||||||
|
|
||||||
addToMailQueue($data);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
echo json_encode($url);
|
echo json_encode($url);
|
||||||
|
|
||||||
// Logging
|
// Logging
|
||||||
logAction("Share", "Create", "$session_name created shared link for $item_type - $item_name", $client_id, $item_id);
|
mysqli_query($mysqli, "INSERT INTO logs SET log_type = 'Sharing', log_action = 'Create', log_description = '$session_name created shared link for $item_type - $item_name', log_client_id = '$client_id', log_ip = '$session_ip', log_user_agent = '$session_user_agent', log_user_id = $session_user_id, company_id = $session_company_id");
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Looks up info for a given recurring (was scheduled) ticket ID from the database, used to dynamically populate modal edit fields
|
* Looks up info for a given scheduled ticket ID from the database, used to dynamically populate modal edit fields
|
||||||
*/
|
*/
|
||||||
if (isset($_GET['recurring_ticket_get_json_details'])) {
|
if (isset($_GET['scheduled_ticket_get_json_details'])) {
|
||||||
validateTechRole();
|
validateTechRole();
|
||||||
|
|
||||||
$client_id = intval($_GET['client_id']);
|
$client_id = intval($_GET['client_id']);
|
||||||
$ticket_id = intval($_GET['ticket_id']);
|
$ticket_id = intval($_GET['ticket_id']);
|
||||||
|
|
||||||
// Get all contacts, to allow tickets to be raised under a specific contact
|
|
||||||
$contact_sql = mysqli_query($mysqli, "SELECT contact_id, contact_name FROM contacts
|
|
||||||
WHERE contact_client_id = $client_id
|
|
||||||
AND contact_archived_at IS NULL
|
|
||||||
ORDER BY contact_primary DESC, contact_technical DESC, contact_name ASC"
|
|
||||||
);
|
|
||||||
while ($row = mysqli_fetch_array($contact_sql)) {
|
|
||||||
$response['contacts'][] = $row;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Get ticket details
|
|
||||||
$ticket_sql = mysqli_query($mysqli, "SELECT * FROM scheduled_tickets
|
$ticket_sql = mysqli_query($mysqli, "SELECT * FROM scheduled_tickets
|
||||||
WHERE scheduled_ticket_id = $ticket_id
|
WHERE scheduled_ticket_id = $ticket_id
|
||||||
AND scheduled_ticket_client_id = $client_id LIMIT 1");
|
AND scheduled_ticket_client_id = $client_id LIMIT 1");
|
||||||
@@ -398,134 +299,21 @@ if (isset($_GET['recurring_ticket_get_json_details'])) {
|
|||||||
$response['ticket'][] = $row;
|
$response['ticket'][] = $row;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get assets
|
|
||||||
$asset_sql = mysqli_query($mysqli, "SELECT asset_id, asset_name FROM assets WHERE asset_client_id = $client_id AND asset_archived_at IS NULL");
|
$asset_sql = mysqli_query($mysqli, "SELECT asset_id, asset_name FROM assets WHERE asset_client_id = $client_id AND asset_archived_at IS NULL");
|
||||||
while ($row = mysqli_fetch_array($asset_sql)) {
|
while ($row = mysqli_fetch_array($asset_sql)) {
|
||||||
$response['assets'][] = $row;
|
$response['assets'][] = $row;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get technicians to auto assign the ticket to
|
|
||||||
$sql_agents = mysqli_query(
|
|
||||||
$mysqli,
|
|
||||||
"SELECT users.user_id, user_name FROM users
|
|
||||||
LEFT JOIN user_settings on users.user_id = user_settings.user_id
|
|
||||||
WHERE user_role > 1
|
|
||||||
AND user_status = 1
|
|
||||||
AND user_archived_at IS NULL
|
|
||||||
ORDER BY user_name ASC"
|
|
||||||
);
|
|
||||||
while ($row = mysqli_fetch_array($sql_agents)) {
|
|
||||||
$response['agents'][] = $row;
|
|
||||||
}
|
|
||||||
|
|
||||||
echo json_encode($response);
|
echo json_encode($response);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Looks up info for a given quote ID from the database, used to dynamically populate modal fields
|
* Dynamic TOTP for client login page
|
||||||
|
* When provided with a TOTP secret, returns a 6-digit code
|
||||||
*/
|
*/
|
||||||
if (isset($_GET['quote_get_json_details'])) {
|
if (isset($_GET['get_totp_token'])) {
|
||||||
$quote_id = intval($_GET['quote_id']);
|
$otp = TokenAuth6238::getTokenCode($_GET['totp_secret']);
|
||||||
|
|
||||||
// Get quote details
|
|
||||||
$quote_sql = mysqli_query(
|
|
||||||
$mysqli,
|
|
||||||
"SELECT * FROM quotes
|
|
||||||
LEFT JOIN clients ON quote_client_id = client_id
|
|
||||||
WHERE quote_id = $quote_id LIMIT 1"
|
|
||||||
);
|
|
||||||
|
|
||||||
while ($row = mysqli_fetch_array($quote_sql)) {
|
|
||||||
$response['quote'][] = $row;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// Get all income-related categories for quoting
|
|
||||||
$quote_created_at = $response['quote'][0]['quote_created_at'];
|
|
||||||
$category_sql = mysqli_query(
|
|
||||||
$mysqli,
|
|
||||||
"SELECT category_id, category_name FROM categories
|
|
||||||
WHERE category_type = 'Income' AND (category_archived_at > '$quote_created_at' OR category_archived_at IS NULL)
|
|
||||||
ORDER BY category_name"
|
|
||||||
);
|
|
||||||
|
|
||||||
while ($row = mysqli_fetch_array($category_sql)) {
|
|
||||||
$response['categories'][] = $row;
|
|
||||||
}
|
|
||||||
|
|
||||||
echo json_encode($response);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Returns sorted list of active clients
|
|
||||||
*/
|
|
||||||
if (isset($_GET['get_active_clients'])) {
|
|
||||||
|
|
||||||
$client_sql = mysqli_query(
|
|
||||||
$mysqli,
|
|
||||||
"SELECT client_id, client_name FROM clients
|
|
||||||
WHERE client_archived_at IS NULL
|
|
||||||
ORDER BY client_accessed_at DESC"
|
|
||||||
);
|
|
||||||
|
|
||||||
while ($row = mysqli_fetch_array($client_sql)) {
|
|
||||||
$response['clients'][] = $row;
|
|
||||||
}
|
|
||||||
|
|
||||||
echo json_encode($response);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Returns ordered list of active contacts for a specified client
|
|
||||||
*/
|
|
||||||
if (isset($_GET['get_client_contacts'])) {
|
|
||||||
$client_id = intval($_GET['client_id']);
|
|
||||||
|
|
||||||
$contact_sql = mysqli_query(
|
|
||||||
$mysqli,
|
|
||||||
"SELECT contact_id, contact_name, contact_primary, contact_important, contact_technical FROM contacts
|
|
||||||
WHERE contacts.contact_archived_at IS NULL AND contact_client_id = $client_id
|
|
||||||
ORDER BY contact_primary DESC, contact_technical DESC, contact_important DESC, contact_name"
|
|
||||||
);
|
|
||||||
|
|
||||||
while ($row = mysqli_fetch_array($contact_sql)) {
|
|
||||||
$response['contacts'][] = $row;
|
|
||||||
}
|
|
||||||
|
|
||||||
echo json_encode($response);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* NEW TOTP getter for client login/passwords page
|
|
||||||
* When provided with a login ID, checks permissions and returns the 6-digit code
|
|
||||||
*/
|
|
||||||
if (isset($_GET['get_totp_token_via_id'])) {
|
|
||||||
validateTechRole();
|
|
||||||
|
|
||||||
$login_id = intval($_GET['login_id']);
|
|
||||||
|
|
||||||
$sql = mysqli_fetch_assoc(mysqli_query($mysqli, "SELECT login_name, login_otp_secret, login_client_id FROM logins WHERE login_id = $login_id"));
|
|
||||||
$name = sanitizeInput($sql['login_name']);
|
|
||||||
$totp_secret = $sql['login_otp_secret'];
|
|
||||||
$client_id = intval($sql['login_client_id']);
|
|
||||||
|
|
||||||
$otp = TokenAuth6238::getTokenCode(strtoupper($totp_secret));
|
|
||||||
echo json_encode($otp);
|
echo json_encode($otp);
|
||||||
|
|
||||||
// Logging
|
|
||||||
// Only log the TOTP view if the user hasn't already viewed this specific login entry recently, this prevents logs filling if a user hovers across an entry a few times
|
|
||||||
$check_recent_totp_view_logged_sql = mysqli_fetch_assoc(mysqli_query($mysqli, "SELECT COUNT(log_id) AS recent_totp_view FROM logs WHERE log_type = 'Login' AND log_action = 'View TOTP' AND log_user_id = $session_user_id AND log_entity_id = $login_id AND log_client_id = $client_id AND log_created_at > (NOW() - INTERVAL 5 MINUTE)"));
|
|
||||||
$recent_totp_view_logged_count = intval($check_recent_totp_view_logged_sql['recent_totp_view']);
|
|
||||||
|
|
||||||
if ($recent_totp_view_logged_count == 0) {
|
|
||||||
// Logging
|
|
||||||
logAction("Credential", "View TOTP", "$session_name viewed credential TOTP code for $name", $client_id, $login_id);
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (isset($_GET['get_readable_pass'])) {
|
|
||||||
echo json_encode(GenerateReadablePassword(4));
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,23 +2,15 @@
|
|||||||
|
|
||||||
// Variable assignment from POST (or: blank/from DB is updating)
|
// Variable assignment from POST (or: blank/from DB is updating)
|
||||||
if (isset($_POST['asset_name'])) {
|
if (isset($_POST['asset_name'])) {
|
||||||
$name = sanitizeInput($_POST['asset_name']);
|
$name = trim(strip_tags(mysqli_real_escape_string($mysqli, $_POST['asset_name'])));
|
||||||
} elseif (isset($asset_row) && isset($asset_row['asset_name'])) {
|
} elseif (isset($asset_row) && isset($asset_row['asset_name'])) {
|
||||||
$name = $asset_row['asset_name'];
|
$name = $asset_row['asset_name'];
|
||||||
} else {
|
} else {
|
||||||
$name = '';
|
$name = '';
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isset($_POST['asset_description'])) {
|
|
||||||
$description = sanitizeInput($_POST['asset_description']);
|
|
||||||
} elseif (isset($asset_row) && isset($asset_row['asset_description'])) {
|
|
||||||
$description = $asset_row['asset_description'];
|
|
||||||
} else {
|
|
||||||
$description = '';
|
|
||||||
}
|
|
||||||
|
|
||||||
if (isset($_POST['asset_type'])) {
|
if (isset($_POST['asset_type'])) {
|
||||||
$type = sanitizeInput($_POST['asset_type']);
|
$type = trim(strip_tags(mysqli_real_escape_string($mysqli, $_POST['asset_type'])));
|
||||||
} elseif (isset($asset_row) && isset($asset_row['asset_type'])) {
|
} elseif (isset($asset_row) && isset($asset_row['asset_type'])) {
|
||||||
$type = $asset_row['asset_type'];
|
$type = $asset_row['asset_type'];
|
||||||
} else {
|
} else {
|
||||||
@@ -26,14 +18,14 @@ if (isset($_POST['asset_type'])) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (isset($_POST['asset_make'])) {
|
if (isset($_POST['asset_make'])) {
|
||||||
$make = sanitizeInput($_POST['asset_make']);
|
$make = trim(strip_tags(mysqli_real_escape_string($mysqli, $_POST['asset_make'])));
|
||||||
} elseif (isset($asset_row) && isset($asset_row['asset_make'])) {
|
} elseif (isset($asset_row) && isset($asset_row['asset_make'])) {
|
||||||
$make = $asset_row['asset_make'];
|
$make = $asset_row['asset_make'];
|
||||||
} else {
|
} else {
|
||||||
$make = '';
|
$make = '';
|
||||||
}
|
}
|
||||||
if (isset($_POST['asset_model'])) {
|
if (isset($_POST['asset_model'])) {
|
||||||
$model = sanitizeInput($_POST['asset_model']);
|
$model = trim(strip_tags(mysqli_real_escape_string($mysqli, $_POST['asset_model'])));
|
||||||
} elseif (isset($asset_row) && isset($asset_row['asset_model'])) {
|
} elseif (isset($asset_row) && isset($asset_row['asset_model'])) {
|
||||||
$model = $asset_row['asset_model'];
|
$model = $asset_row['asset_model'];
|
||||||
} else {
|
} else {
|
||||||
@@ -41,7 +33,7 @@ if (isset($_POST['asset_model'])) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (isset($_POST['asset_serial'])) {
|
if (isset($_POST['asset_serial'])) {
|
||||||
$serial = sanitizeInput($_POST['asset_serial']);
|
$serial = trim(strip_tags(mysqli_real_escape_string($mysqli, $_POST['asset_serial'])));
|
||||||
} elseif (isset($asset_row) && isset($asset_row['asset_serial'])) {
|
} elseif (isset($asset_row) && isset($asset_row['asset_serial'])) {
|
||||||
$serial = $asset_row['asset_serial'];
|
$serial = $asset_row['asset_serial'];
|
||||||
} else {
|
} else {
|
||||||
@@ -49,7 +41,7 @@ if (isset($_POST['asset_serial'])) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (isset($_POST['asset_os'])) {
|
if (isset($_POST['asset_os'])) {
|
||||||
$os = sanitizeInput($_POST['asset_os']);
|
$os = trim(strip_tags(mysqli_real_escape_string($mysqli, $_POST['asset_os'])));
|
||||||
} elseif (isset($asset_row) && isset($asset_row['asset_os'])) {
|
} elseif (isset($asset_row) && isset($asset_row['asset_os'])) {
|
||||||
$os = $asset_row['asset_os'];
|
$os = $asset_row['asset_os'];
|
||||||
} else {
|
} else {
|
||||||
@@ -57,31 +49,23 @@ if (isset($_POST['asset_os'])) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (isset($_POST['asset_ip'])) {
|
if (isset($_POST['asset_ip'])) {
|
||||||
$ip = sanitizeInput($_POST['asset_ip']);
|
$aip = trim(strip_tags(mysqli_real_escape_string($mysqli, $_POST['asset_ip'])));
|
||||||
} elseif (isset($asset_row) && isset($asset_row['interface_ip'])) {
|
} elseif (isset($asset_row) && isset($asset_row['asset_ip'])) {
|
||||||
$ip = $asset_row['interface_ip'];
|
$aip = $asset_row['asset_ip'];
|
||||||
} else {
|
} else {
|
||||||
$ip = '';
|
$aip = '';
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isset($_POST['asset_mac'])) {
|
if (isset($_POST['asset_mac'])) {
|
||||||
$mac = sanitizeInput($_POST['asset_mac']);
|
$mac = trim(strip_tags(mysqli_real_escape_string($mysqli, $_POST['asset_mac'])));
|
||||||
} elseif (isset($asset_row) && isset($asset_row['interface_mac'])) {
|
} elseif (isset($asset_row) && isset($asset_row['asset_mac'])) {
|
||||||
$mac = $asset_row['interface_mac'];
|
$mac = $asset_row['asset_mac'];
|
||||||
} else {
|
} else {
|
||||||
$mac = '';
|
$mac = '';
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isset($_POST['asset_uri'])) {
|
|
||||||
$uri = sanitizeInput($_POST['asset_uri']);
|
|
||||||
} elseif (isset($asset_row) && isset($asset_row['asset_uri'])) {
|
|
||||||
$uri = $asset_row['asset_uri'];
|
|
||||||
} else {
|
|
||||||
$uri = '';
|
|
||||||
}
|
|
||||||
|
|
||||||
if (isset($_POST['asset_status'])) {
|
if (isset($_POST['asset_status'])) {
|
||||||
$status = sanitizeInput($_POST['asset_status']);
|
$status = trim(strip_tags(mysqli_real_escape_string($mysqli, $_POST['asset_status'])));
|
||||||
} elseif (isset($asset_row) && isset($asset_row['asset_status'])) {
|
} elseif (isset($asset_row) && isset($asset_row['asset_status'])) {
|
||||||
$status = $asset_row['asset_status'];
|
$status = $asset_row['asset_status'];
|
||||||
} else {
|
} else {
|
||||||
@@ -89,31 +73,31 @@ if (isset($_POST['asset_status'])) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (isset($_POST['asset_purchase_date']) && !empty($_POST['asset_purchase_date'])) {
|
if (isset($_POST['asset_purchase_date']) && !empty($_POST['asset_purchase_date'])) {
|
||||||
$purchase_date = "'" . sanitizeInput($_POST['asset_purchase_date']) . "'";
|
$purchase_date = trim(strip_tags(mysqli_real_escape_string($mysqli, $_POST['asset_purchase_date'])));
|
||||||
} elseif (isset($asset_row) && isset($asset_row['asset_purchase_date'])) {
|
} elseif (isset($asset_row) && isset($asset_row['asset_purchase_date'])) {
|
||||||
$purchase_date = "'" . $asset_row['asset_purchase_date'] . "'";
|
$purchase_date = $asset_row['asset_purchase_date'];
|
||||||
} else {
|
} else {
|
||||||
$purchase_date = "NULL";
|
$purchase_date = "0000-00-00";
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isset($_POST['asset_warranty_expire']) && !empty($_POST['asset_warranty_expire'])) {
|
if (isset($_POST['asset_warranty_expire']) && !empty($_POST['asset_warranty_expire'])) {
|
||||||
$warranty_expire = "'" . sanitizeInput($_POST['asset_warranty_expire']) . "'";
|
$warranty_expire = trim(strip_tags(mysqli_real_escape_string($mysqli, $_POST['asset_warranty_expire'])));
|
||||||
} elseif (isset($asset_row) && isset($asset_row['asset_warranty_expire'])) {
|
} elseif (isset($asset_row) && isset($asset_row['asset_warranty_expire'])) {
|
||||||
$warranty_expire = "'" . $asset_row['asset_warranty_expire'] . "'";
|
$warranty_expire = $asset_row['asset_warranty_expire'];
|
||||||
} else {
|
} else {
|
||||||
$warranty_expire = "NULL";
|
$warranty_expire = "0000-00-00";
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isset($_POST['asset_install_date']) && !empty($_POST['asset_install_date'])) {
|
if (isset($_POST['asset_install_date']) && !empty($_POST['asset_install_date'])) {
|
||||||
$install_date = "'" . sanitizeInput($_POST['asset_install_date']) . "'";
|
$install_date = trim(strip_tags(mysqli_real_escape_string($mysqli, $_POST['asset_install_date'])));
|
||||||
} elseif (isset($asset_row) && isset($asset_row['asset_install_date'])) {
|
} elseif (isset($asset_row) && isset($asset_row['asset_install_date'])) {
|
||||||
$install_date = "'" . $asset_row['asset_install_date'] . "'";
|
$install_date = $asset_row['asset_install_date'];
|
||||||
} else {
|
} else {
|
||||||
$install_date = "NULL";
|
$install_date = "0000-00-00";
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isset($_POST['asset_notes'])) {
|
if (isset($_POST['asset_notes'])) {
|
||||||
$notes = sanitizeInput($_POST['asset_notes']);
|
$notes = trim(strip_tags(mysqli_real_escape_string($mysqli, $_POST['asset_notes'])));
|
||||||
} elseif (isset($asset_row) && isset($asset_row['asset_notes'])) {
|
} elseif (isset($asset_row) && isset($asset_row['asset_notes'])) {
|
||||||
$notes = $asset_row['asset_notes'];
|
$notes = $asset_row['asset_notes'];
|
||||||
} else {
|
} else {
|
||||||
@@ -146,8 +130,8 @@ if (isset($_POST['asset_contact_id'])) {
|
|||||||
|
|
||||||
if (isset($_POST['asset_network_id'])) {
|
if (isset($_POST['asset_network_id'])) {
|
||||||
$network = intval($_POST['asset_network_id']);
|
$network = intval($_POST['asset_network_id']);
|
||||||
} elseif (isset($asset_row) && isset($asset_row['interface_network_id'])) {
|
} elseif (isset($asset_row) && isset($asset_row['asset_network_id'])) {
|
||||||
$network = $asset_row['interface_network_id'];
|
$network = $asset_row['asset_network_id'];
|
||||||
} else {
|
} else {
|
||||||
$network = '0';
|
$network = '0';
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,33 +1,26 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
require_once '../validate_api_key.php';
|
require_once('../validate_api_key.php');
|
||||||
|
require_once('../require_post_method.php');
|
||||||
require_once '../require_post_method.php';
|
|
||||||
|
|
||||||
|
|
||||||
// Parse POST info
|
// Parse POST info
|
||||||
require_once 'asset_model.php';
|
require_once('asset_model.php');
|
||||||
|
|
||||||
|
|
||||||
// Default
|
// Default
|
||||||
$insert_id = false;
|
$insert_id = false;
|
||||||
|
|
||||||
if (!empty($name) && !empty($client_id)) {
|
if (!empty($name) && !empty($client_id)) {
|
||||||
// Insert into Database
|
// Insert into Database
|
||||||
$insert_sql = mysqli_query($mysqli, "INSERT INTO assets SET asset_name = '$name', asset_description = '$description', asset_type = '$type', asset_make = '$make', asset_model = '$model', asset_serial = '$serial', asset_os = '$os', asset_uri = '$uri', asset_status = '$status', asset_location_id = $location, asset_vendor_id = $vendor, asset_contact_id = $contact, asset_purchase_date = $purchase_date, asset_warranty_expire = $warranty_expire, asset_install_date = $install_date, asset_notes = '$notes', asset_client_id = $client_id");
|
$insert_sql = mysqli_query($mysqli, "INSERT INTO assets SET asset_name = '$name', asset_type = '$type', asset_make = '$make', asset_model = '$model', asset_serial = '$serial', asset_os = '$os', asset_ip = '$aip', asset_mac = '$mac', asset_status = '$status', asset_location_id = $location, asset_vendor_id = $vendor, asset_contact_id = $contact, asset_purchase_date = '$purchase_date', asset_warranty_expire = '$warranty_expire', asset_install_date = '$install_date', asset_notes = '$notes', asset_created_at = NOW(), asset_network_id = $network, asset_client_id = $client_id, company_id = '$company_id'");
|
||||||
|
|
||||||
if ($insert_sql) {
|
if ($insert_sql) {
|
||||||
$insert_id = mysqli_insert_id($mysqli);
|
$insert_id = mysqli_insert_id($mysqli);
|
||||||
|
|
||||||
// Add Primary Interface
|
//Logging
|
||||||
mysqli_query($mysqli,"INSERT INTO asset_interfaces SET interface_name = 'Primary', interface_mac = '$mac', interface_ip = '$ip', interface_port = 'eth0', interface_primary = 1, interface_network_id = $network, interface_asset_id = $insert_id");
|
mysqli_query($mysqli, "INSERT INTO logs SET log_type = 'Asset', log_action = 'Created', log_description = '$name via API ($api_key_name)', log_ip = '$ip', log_user_agent = '$user_agent', log_created_at = NOW(), log_client_id = '$client_id', company_id = $company_id");
|
||||||
|
mysqli_query($mysqli, "INSERT INTO logs SET log_type = 'API', log_action = 'Success', log_description = 'Created asset $name via API ($api_key_name)', log_ip = '$ip', log_user_agent = '$user_agent', log_created_at = NOW(), log_client_id = '$client_id', company_id = $company_id");
|
||||||
// Logging
|
|
||||||
logAction("Asset", "Create", "$name via API ($api_key_name)", $client_id, $insert_id);
|
|
||||||
logAction("API", "Success", "Created asset $name via API ($api_key_name)", $client_id);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Output
|
// Output
|
||||||
require_once '../create_output.php';
|
require_once('../create_output.php');
|
||||||
|
|
||||||
|
|||||||
@@ -1,9 +1,7 @@
|
|||||||
<?php
|
<?php
|
||||||
require_once '../validate_api_key.php';
|
require_once('../validate_api_key.php');
|
||||||
|
|
||||||
|
|
||||||
require_once '../require_post_method.php';
|
|
||||||
|
|
||||||
|
require_once('../require_post_method.php');
|
||||||
|
|
||||||
// Parse ID
|
// Parse ID
|
||||||
$asset_id = intval($_POST['asset_id']);
|
$asset_id = intval($_POST['asset_id']);
|
||||||
@@ -12,23 +10,19 @@ $asset_id = intval($_POST['asset_id']);
|
|||||||
$delete_count = false;
|
$delete_count = false;
|
||||||
|
|
||||||
if (!empty($asset_id)) {
|
if (!empty($asset_id)) {
|
||||||
$row = mysqli_fetch_assoc(mysqli_query($mysqli, "SELECT * FROM assets WHERE asset_id = $asset_id AND asset_client_id = $client_id LIMIT 1"));
|
$row = mysqli_fetch_assoc(mysqli_query($mysqli, "SELECT * FROM assets WHERE asset_id = $asset_id AND asset_client_id = $client_id AND company_id = '$company_id' LIMIT 1"));
|
||||||
$asset_name = $row['asset_name'];
|
$asset_name = $row['asset_name'];
|
||||||
|
|
||||||
$delete_sql = mysqli_query($mysqli, "DELETE FROM assets WHERE asset_id = $asset_id AND asset_client_id = $client_id LIMIT 1");
|
$delete_sql = mysqli_query($mysqli, "DELETE FROM assets WHERE asset_id = $asset_id AND asset_client_id = $client_id AND company_id = '$company_id' LIMIT 1");
|
||||||
|
|
||||||
// Delete Interfaces
|
|
||||||
mysqli_query($mysqli,"DELETE FROM asset_interfaces WHERE interface_asset_id = $asset_id");
|
|
||||||
|
|
||||||
// Check delete & get affected rows
|
// Check delete & get affected rows
|
||||||
if ($delete_sql && !empty($asset_name)) {
|
if ($delete_sql && !empty($asset_name)) {
|
||||||
$delete_count = mysqli_affected_rows($mysqli);
|
$delete_count = mysqli_affected_rows($mysqli);
|
||||||
|
|
||||||
// Logging
|
//Logging
|
||||||
logAction("Asset", "Delete", "$asset_name via API ($api_key_name)", $client_id);
|
mysqli_query($mysqli, "INSERT INTO logs SET log_type = 'Asset', log_action = 'Deleted', log_description = '$asset_name via API ($api_key_name)', log_ip = '$ip', log_user_agent = '$user_agent', log_client_id = $client_id, company_id = $company_id");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Output
|
// Output
|
||||||
require_once '../delete_output.php';
|
require_once('../delete_output.php');
|
||||||
|
|
||||||
|
|||||||
@@ -1,49 +1,41 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
require_once '../validate_api_key.php';
|
require_once('../validate_api_key.php');
|
||||||
|
require_once('../require_get_method.php');
|
||||||
require_once '../require_get_method.php';
|
|
||||||
|
|
||||||
|
|
||||||
// Asset via ID (single)
|
// Asset via ID (single)
|
||||||
if (isset($_GET['asset_id'])) {
|
if (isset($_GET['asset_id'])) {
|
||||||
$id = intval($_GET['asset_id']);
|
$id = intval($_GET['asset_id']);
|
||||||
$sql = mysqli_query($mysqli, "SELECT * FROM assets WHERE asset_id = $id AND asset_client_id LIKE '$client_id'");
|
$sql = mysqli_query($mysqli, "SELECT * FROM assets WHERE asset_id = '$id' AND asset_client_id LIKE '$client_id' AND company_id = '$company_id'");
|
||||||
|
|
||||||
} elseif (isset($_GET['asset_type'])) {
|
} elseif (isset($_GET['asset_type'])) {
|
||||||
// Asset query via type
|
// Asset query via type
|
||||||
|
|
||||||
$type = mysqli_real_escape_string($mysqli, ucfirst($_GET['asset_type']));
|
$type = mysqli_real_escape_string($mysqli, ucfirst($_GET['asset_type']));
|
||||||
$sql = mysqli_query($mysqli, "SELECT * FROM assets WHERE asset_type = '$type' AND asset_client_id LIKE '$client_id' ORDER BY asset_id LIMIT $limit OFFSET $offset");
|
$sql = mysqli_query($mysqli, "SELECT * FROM assets WHERE asset_type = '$type' AND asset_client_id LIKE '$client_id' AND company_id = '$company_id' ORDER BY asset_id LIMIT $limit OFFSET $offset");
|
||||||
|
|
||||||
} elseif (isset($_GET['asset_name'])) {
|
} elseif (isset($_GET['asset_name'])) {
|
||||||
// Asset query via name
|
// Asset query via name
|
||||||
|
|
||||||
$name = mysqli_real_escape_string($mysqli, $_GET['asset_name']);
|
$name = mysqli_real_escape_string($mysqli, $_GET['asset_name']);
|
||||||
$sql = mysqli_query($mysqli, "SELECT * FROM assets WHERE asset_name = '$name' AND asset_client_id LIKE '$client_id' ORDER BY asset_id LIMIT $limit OFFSET $offset");
|
$sql = mysqli_query($mysqli, "SELECT * FROM assets WHERE asset_name = '$name' AND asset_client_id LIKE '$client_id' AND company_id = '$company_id' ORDER BY asset_id LIMIT $limit OFFSET $offset");
|
||||||
|
|
||||||
} elseif (isset($_GET['asset_serial'])) {
|
} elseif (isset($_GET['asset_serial'])) {
|
||||||
// Asset query via serial
|
// Asset query via serial
|
||||||
|
|
||||||
$serial = mysqli_real_escape_string($mysqli, $_GET['asset_serial']);
|
$serial = mysqli_real_escape_string($mysqli, $_GET['asset_serial']);
|
||||||
$sql = mysqli_query($mysqli, "SELECT * FROM assets WHERE asset_serial = '$serial' AND asset_client_id LIKE '$client_id' ORDER BY asset_id LIMIT $limit OFFSET $offset");
|
$sql = mysqli_query($mysqli, "SELECT * FROM assets WHERE asset_serial = '$serial' AND asset_client_id LIKE '$client_id' AND company_id = '$company_id' ORDER BY asset_id LIMIT $limit OFFSET $offset");
|
||||||
|
|
||||||
} elseif (isset($_GET['asset_mac'])) {
|
} elseif (isset($_GET['client_id'])) {
|
||||||
// Asset query via mac
|
// Asset query via client ID
|
||||||
$mac = mysqli_real_escape_string($mysqli, $_GET['asset_mac']);
|
|
||||||
$sql = mysqli_query($mysqli, "SELECT * FROM assets LEFT JOIN asset_interfaces ON interface_asset_id = asset_id AND interface_primary = 1 WHERE interface_mac = '$mac' AND asset_client_id LIKE '$client_id' ORDER BY asset_id LIMIT $limit OFFSET $offset");
|
|
||||||
|
|
||||||
} elseif (isset($_GET['asset_uri'])) {
|
$sql = mysqli_query($mysqli, "SELECT * FROM assets WHERE asset_client_id LIKE '$client_id' AND company_id = '$company_id' ORDER BY asset_id LIMIT $limit OFFSET $offset");
|
||||||
// Asset query via uri
|
}
|
||||||
$uri = mysqli_real_escape_string($mysqli, $_GET['asset_uri']);
|
|
||||||
$sql = mysqli_query($mysqli, "SELECT * FROM assets WHERE asset_uri = '$uri' AND asset_client_id LIKE '$client_id' ORDER BY asset_id LIMIT $limit OFFSET $offset");
|
|
||||||
|
|
||||||
} elseif (isset($_GET['asset_uri_2'])) {
|
// All assets
|
||||||
// Asset query via uri2
|
else {
|
||||||
$uri2 = mysqli_real_escape_string($mysqli, $_GET['asset_uri']);
|
$sql = mysqli_query($mysqli, "SELECT * FROM assets WHERE asset_client_id LIKE '$client_id' AND company_id = '$company_id' ORDER BY asset_id LIMIT $limit OFFSET $offset");
|
||||||
$sql = mysqli_query($mysqli, "SELECT * FROM assets WHERE asset_uri_2 = '$uri2' AND asset_client_id LIKE '$client_id' ORDER BY asset_id LIMIT $limit OFFSET $offset");
|
|
||||||
|
|
||||||
}else {
|
|
||||||
// All assets (by client ID or all in general if key permits)
|
|
||||||
$sql = mysqli_query($mysqli, "SELECT * FROM assets LEFT JOIN asset_interfaces ON interface_asset_id = asset_id AND interface_primary = 1 WHERE asset_client_id LIKE '$client_id' ORDER BY asset_id LIMIT $limit OFFSET $offset");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Output
|
// Output
|
||||||
require_once "../read_output.php";
|
require_once("../read_output.php");
|
||||||
|
|||||||
@@ -1,9 +1,7 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
require_once '../validate_api_key.php';
|
require_once('../validate_api_key.php');
|
||||||
|
require_once('../require_post_method.php');
|
||||||
require_once '../require_post_method.php';
|
|
||||||
|
|
||||||
|
|
||||||
// Parse ID
|
// Parse ID
|
||||||
$asset_id = intval($_POST['asset_id']);
|
$asset_id = intval($_POST['asset_id']);
|
||||||
@@ -13,27 +11,22 @@ $update_count = false;
|
|||||||
|
|
||||||
if (!empty($asset_id)) {
|
if (!empty($asset_id)) {
|
||||||
|
|
||||||
$asset_row = mysqli_fetch_assoc(mysqli_query($mysqli, "SELECT * FROM assets WHERE asset_id = '$asset_id' AND asset_client_id = $client_id LIMIT 1"));
|
$asset_row = mysqli_fetch_assoc(mysqli_query($mysqli, "SELECT * FROM assets WHERE asset_id = '$asset_id' AND asset_client_id = $client_id AND company_id = '$company_id' LIMIT 1"));
|
||||||
|
|
||||||
// Variable assignment from POST - assigning the current database value if a value is not provided
|
// Variable assignment from POST - assigning the current database value if a value is not provided
|
||||||
require_once 'asset_model.php';
|
require_once('asset_model.php');
|
||||||
|
|
||||||
|
$update_sql = mysqli_query($mysqli, "UPDATE assets SET asset_name = '$name', asset_type = '$type', asset_make = '$make', asset_model = '$model', asset_serial = '$serial', asset_os = '$os', asset_ip = '$aip', asset_mac = '$mac', asset_status = '$status', asset_location_id = $location, asset_vendor_id = $vendor, asset_contact_id = $contact, asset_purchase_date = '$purchase_date', asset_warranty_expire = '$warranty_expire', asset_install_date = '$install_date', asset_notes = '$notes', asset_updated_at = NOW(), asset_network_id = $network WHERE asset_id = $asset_id AND asset_client_id = $client_id AND company_id = '$company_id' LIMIT 1");
|
||||||
$update_sql = mysqli_query($mysqli, "UPDATE assets SET asset_name = '$name', asset_description = '$description', asset_type = '$type', asset_make = '$make', asset_model = '$model', asset_serial = '$serial', asset_os = '$os', asset_uri = '$uri', asset_status = '$status', asset_location_id = $location, asset_vendor_id = $vendor, asset_contact_id = $contact, asset_purchase_date = $purchase_date, asset_warranty_expire = $warranty_expire, asset_install_date = $install_date, asset_notes = '$notes' WHERE asset_id = $asset_id AND asset_client_id = $client_id LIMIT 1");
|
|
||||||
|
|
||||||
// Check insert & get insert ID
|
// Check insert & get insert ID
|
||||||
if ($update_sql) {
|
if ($update_sql) {
|
||||||
$update_count = mysqli_affected_rows($mysqli);
|
$update_count = mysqli_affected_rows($mysqli);
|
||||||
|
|
||||||
// Update Primary Interface
|
//Logging
|
||||||
mysqli_query($mysqli,"UPDATE asset_interfaces SET interface_mac = '$mac', interface_ip = '$ip', interface_network_id = $network WHERE interface_asset_id = $asset_id AND interface_primary = 1");
|
mysqli_query($mysqli, "INSERT INTO logs SET log_type = 'Asset', log_action = 'Updated', log_description = '$name via API ($api_key_name)', log_ip = '$ip', log_user_agent = '$user_agent', log_client_id = $client_id, company_id = $company_id");
|
||||||
|
mysqli_query($mysqli, "INSERT INTO logs SET log_type = 'API', log_action = 'Success', log_description = 'Updated asset $name via API ($api_key_name)', log_ip = '$ip', log_user_agent = '$user_agent', log_client_id = $client_id, company_id = $company_id");
|
||||||
// Logging
|
|
||||||
logAction("Asset", "Edit", "$name via API ($api_key_name)", $client_id);
|
|
||||||
logAction("API", "Success", "Edited asset $name via API ($api_key_name)", $client_id);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Output
|
// Output
|
||||||
require_once '../update_output.php';
|
require_once('../update_output.php');
|
||||||
|
|
||||||
|
|||||||
@@ -1,25 +1,29 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
require_once '../validate_api_key.php';
|
require_once('../validate_api_key.php');
|
||||||
|
require_once('../require_get_method.php');
|
||||||
require_once '../require_get_method.php';
|
|
||||||
|
|
||||||
|
|
||||||
// Specific certificate via ID (single)
|
// Specific certificate via ID (single)
|
||||||
if (isset($_GET['certificate_id'])) {
|
if (isset($_GET['certificate_id'])) {
|
||||||
$id = intval($_GET['certificate_id']);
|
$id = intval($_GET['certificate_id']);
|
||||||
$sql = mysqli_query($mysqli, "SELECT * FROM certificates WHERE certificate_id = '$id' AND certificate_client_id LIKE '$client_id'");
|
$sql = mysqli_query($mysqli, "SELECT * FROM certificates WHERE certificate_id = '$id' AND certificate_client_id LIKE '$client_id' AND company_id = '$company_id'");
|
||||||
|
|
||||||
} elseif (isset($_GET['certificate_name'])) {
|
} elseif (isset($_GET['certificate_name'])) {
|
||||||
// Certificate by name
|
// Certificate by name
|
||||||
|
|
||||||
$name = mysqli_real_escape_string($mysqli, $_GET['certificate_name']);
|
$name = mysqli_real_escape_string($mysqli, $_GET['certificate_name']);
|
||||||
$sql = mysqli_query($mysqli, "SELECT * FROM certificates WHERE certificate_name = '$name' AND certificate_client_id LIKE '$client_id' ORDER BY certificate_id LIMIT $limit OFFSET $offset");
|
$sql = mysqli_query($mysqli, "SELECT * FROM certificates WHERE certificate_name = '$name' AND certificate_client_id LIKE '$client_id' AND company_id = '$company_id' ORDER BY certificate_id LIMIT $limit OFFSET $offset");
|
||||||
|
|
||||||
|
} elseif (isset($_GET['client_id'])) {
|
||||||
|
// Certificate via client ID
|
||||||
|
|
||||||
|
$sql = mysqli_query($mysqli, "SELECT * FROM certificates WHERE certificate_client_id = '$client_id' AND company_id = '$company_id' ORDER BY certificate_id LIMIT $limit OFFSET $offset");
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
// All certificates (by client ID or all in general if key permits)
|
// All certificates
|
||||||
$sql = mysqli_query($mysqli, "SELECT * FROM certificates WHERE certificate_client_id LIKE '$client_id' ORDER BY certificate_id LIMIT $limit OFFSET $offset");
|
|
||||||
|
$sql = mysqli_query($mysqli, "SELECT * FROM certificates WHERE certificate_client_id LIKE '$client_id' AND company_id = '$company_id' ORDER BY certificate_id LIMIT $limit OFFSET $offset");
|
||||||
}
|
}
|
||||||
|
|
||||||
// Output
|
// Output
|
||||||
require_once "../read_output.php";
|
require_once("../read_output.php");
|
||||||
|
|
||||||
|
|||||||
@@ -1,83 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
// Variable assignment from POST (or: blank/from DB is updating)
|
|
||||||
|
|
||||||
if (isset($_POST['client_name'])) {
|
|
||||||
$name = sanitizeInput($_POST['client_name']);
|
|
||||||
} elseif ($client_row) {
|
|
||||||
$name = $client_row['client_name'];
|
|
||||||
} else {
|
|
||||||
$name = '';
|
|
||||||
}
|
|
||||||
|
|
||||||
if (isset($_POST['client_type'])) {
|
|
||||||
$type = sanitizeInput($_POST['client_type']);
|
|
||||||
} elseif ($client_row) {
|
|
||||||
$type = $client_row['client_type'];
|
|
||||||
} else {
|
|
||||||
$type = '';
|
|
||||||
}
|
|
||||||
|
|
||||||
if (isset($_POST['client_website'])) {
|
|
||||||
$website = preg_replace("(^https?://)", "", sanitizeInput($_POST['client_website']));
|
|
||||||
} elseif ($client_row) {
|
|
||||||
$website = $client_row['client_website'];
|
|
||||||
} else {
|
|
||||||
$website = '';
|
|
||||||
}
|
|
||||||
|
|
||||||
if (isset($_POST['client_referral'])) {
|
|
||||||
$referral = sanitizeInput($_POST['client_referral']);
|
|
||||||
} elseif ($client_row) {
|
|
||||||
$referral = $client_row['client_referral'];
|
|
||||||
} else {
|
|
||||||
$referral = '';
|
|
||||||
}
|
|
||||||
|
|
||||||
if (isset($_POST['client_rate'])) {
|
|
||||||
$rate = floatval($_POST['client_rate']);
|
|
||||||
} elseif ($client_row) {
|
|
||||||
$rate = $client_row['client_rate'];
|
|
||||||
} else {
|
|
||||||
$rate = '';
|
|
||||||
}
|
|
||||||
|
|
||||||
if (isset($_POST['client_currency_code'])) {
|
|
||||||
$currency_code = sanitizeInput($_POST['client_currency_code']);
|
|
||||||
} elseif ($client_row) {
|
|
||||||
$currency_code = $client_row['client_currency_code'];
|
|
||||||
} else {
|
|
||||||
$currency_code = '';
|
|
||||||
}
|
|
||||||
|
|
||||||
if (isset($_POST['client_net_terms'])) {
|
|
||||||
$net_terms = intval($_POST['client_net_terms']);
|
|
||||||
} elseif ($client_row) {
|
|
||||||
$net_terms = $client_row['client_net_terms'];
|
|
||||||
} else {
|
|
||||||
$net_terms = '';
|
|
||||||
}
|
|
||||||
|
|
||||||
if (isset($_POST['client_tax_id_number'])) {
|
|
||||||
$tax_id_number = sanitizeInput($_POST['client_tax_id_number']);
|
|
||||||
} elseif ($client_row) {
|
|
||||||
$tax_id_number = $client_row['client_tax_id_number'];
|
|
||||||
} else {
|
|
||||||
$tax_id_number = '';
|
|
||||||
}
|
|
||||||
|
|
||||||
if (isset($_POST['client_is_lead'])) {
|
|
||||||
$lead = intval($_POST['client_is_lead']);
|
|
||||||
} elseif ($client_row) {
|
|
||||||
$lead = $client_row['client_is_lead'];
|
|
||||||
} else {
|
|
||||||
$lead = 0; // Default: Not a lead
|
|
||||||
}
|
|
||||||
|
|
||||||
if (isset($_POST['client_notes'])) {
|
|
||||||
$notes = sanitizeInput($_POST['client_notes']);
|
|
||||||
} elseif ($client_row) {
|
|
||||||
$notes = $client_row['client_notes'];
|
|
||||||
} else {
|
|
||||||
$notes = '';
|
|
||||||
}
|
|
||||||
@@ -1,32 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
require_once '../validate_api_key.php';
|
|
||||||
|
|
||||||
require_once '../require_post_method.php';
|
|
||||||
|
|
||||||
// Parse Info
|
|
||||||
require_once 'client_model.php';
|
|
||||||
|
|
||||||
|
|
||||||
// Default
|
|
||||||
$insert_id = false;
|
|
||||||
|
|
||||||
// To add a client, we just need a name and an "ANY CLIENT" API key
|
|
||||||
if (!empty($name) && $client_id == 0) {
|
|
||||||
|
|
||||||
// Insert client
|
|
||||||
$insert_sql = mysqli_query($mysqli, "INSERT INTO clients SET client_name = '$name', client_type = '$type', client_website = '$website', client_referral = '$referral', client_rate = $rate, client_currency_code = '$currency_code', client_net_terms = $net_terms, client_tax_id_number = '$tax_id_number', client_lead = $lead, client_notes = '$notes', client_accessed_at = NOW()");
|
|
||||||
|
|
||||||
// Check insert & get insert ID
|
|
||||||
if ($insert_sql) {
|
|
||||||
$insert_id = mysqli_insert_id($mysqli);
|
|
||||||
|
|
||||||
// Logging
|
|
||||||
logAction("Client", "Create", "$name via API ($api_key_name)", $insert_id);
|
|
||||||
logAction("API", "Success", "Created client $name via API ($api_key_name)", $insert_id);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
// Output
|
|
||||||
require_once '../create_output.php';
|
|
||||||
@@ -1,19 +1,24 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
require_once '../validate_api_key.php';
|
require_once('../validate_api_key.php');
|
||||||
|
require_once('../require_get_method.php');
|
||||||
|
|
||||||
require_once '../require_get_method.php';
|
// Specific client via ID (single)
|
||||||
|
if (isset($_GET['client_id'])) {
|
||||||
|
$id = intval($_GET['client_id']);
|
||||||
|
$sql = mysqli_query($mysqli, "SELECT * FROM clients WHERE client_id = '$id' AND client_id LIKE '$client_id' AND company_id = '$company_id'");
|
||||||
|
|
||||||
|
} elseif (isset($_GET['client_name'])) {
|
||||||
|
// Specific client via name (single)
|
||||||
|
|
||||||
// Specific client via name (single)
|
|
||||||
if (isset($_GET['client_name'])) {
|
|
||||||
$name = mysqli_real_escape_string($mysqli, $_GET['client_name']);
|
$name = mysqli_real_escape_string($mysqli, $_GET['client_name']);
|
||||||
$sql = mysqli_query($mysqli, "SELECT * FROM clients WHERE client_name = '$name' AND client_id LIKE '$client_id'");
|
$sql = mysqli_query($mysqli, "SELECT * FROM clients WHERE client_name = '$name' AND client_id LIKE '$client_id' AND company_id = '$company_id'");
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
// All clients (by client ID if given, or all in general if key permits)
|
// All clients
|
||||||
$sql = mysqli_query($mysqli, "SELECT * FROM clients WHERE client_id LIKE '$client_id' ORDER BY client_id LIMIT $limit OFFSET $offset");
|
|
||||||
|
$sql = mysqli_query($mysqli, "SELECT * FROM clients WHERE client_id LIKE '$client_id' AND company_id = '$company_id' ORDER BY client_id LIMIT $limit OFFSET $offset");
|
||||||
}
|
}
|
||||||
|
|
||||||
// Output
|
// Output
|
||||||
require_once "../read_output.php";
|
require_once("../read_output.php");
|
||||||
|
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ define('number_regex', '/[^0-9]/');
|
|||||||
|
|
||||||
// Variable assignment from POST (or: blank/from DB is updating)
|
// Variable assignment from POST (or: blank/from DB is updating)
|
||||||
if (isset($_POST['contact_name'])) {
|
if (isset($_POST['contact_name'])) {
|
||||||
$name = sanitizeInput($_POST['contact_name']);
|
$name = trim(strip_tags(mysqli_real_escape_string($mysqli, $_POST['contact_name'])));
|
||||||
} elseif ($contact_row) {
|
} elseif ($contact_row) {
|
||||||
$name = $contact_row['contact_name'];
|
$name = $contact_row['contact_name'];
|
||||||
} else {
|
} else {
|
||||||
@@ -11,7 +11,7 @@ if (isset($_POST['contact_name'])) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (isset($_POST['contact_title'])) {
|
if (isset($_POST['contact_title'])) {
|
||||||
$title = sanitizeInput($_POST['contact_title']);
|
$title = trim(strip_tags(mysqli_real_escape_string($mysqli, $_POST['contact_title'])));
|
||||||
} elseif ($contact_row) {
|
} elseif ($contact_row) {
|
||||||
$title = $contact_row['contact_title'];
|
$title = $contact_row['contact_title'];
|
||||||
} else {
|
} else {
|
||||||
@@ -19,7 +19,7 @@ if (isset($_POST['contact_title'])) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (isset($_POST['contact_department'])) {
|
if (isset($_POST['contact_department'])) {
|
||||||
$department = sanitizeInput($_POST['contact_department']);
|
$department = trim(strip_tags(mysqli_real_escape_string($mysqli, $_POST['contact_department'])));
|
||||||
} elseif ($contact_row) {
|
} elseif ($contact_row) {
|
||||||
$department = $contact_row['contact_department'];
|
$department = $contact_row['contact_department'];
|
||||||
} else {
|
} else {
|
||||||
@@ -27,7 +27,7 @@ if (isset($_POST['contact_department'])) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (isset($_POST['contact_email'])) {
|
if (isset($_POST['contact_email'])) {
|
||||||
$email = sanitizeInput($_POST['contact_email']);
|
$email = trim(strip_tags(mysqli_real_escape_string($mysqli, $_POST['contact_email'])));
|
||||||
} elseif ($contact_row) {
|
} elseif ($contact_row) {
|
||||||
$email = $contact_row['contact_email'];
|
$email = $contact_row['contact_email'];
|
||||||
} else {
|
} else {
|
||||||
@@ -59,19 +59,19 @@ if (isset($_POST['contact_mobile'])) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (isset($_POST['contact_notes'])) {
|
if (isset($_POST['contact_notes'])) {
|
||||||
$notes = sanitizeInput($_POST['contact_notes']);
|
$notes = trim(strip_tags(mysqli_real_escape_string($mysqli, $_POST['contact_notes'])));
|
||||||
} elseif ($contact_row) {
|
} elseif ($contact_row) {
|
||||||
$notes = $contact_row['contact_notes'];
|
$notes = $contact_row['contact_notes'];
|
||||||
} else {
|
} else {
|
||||||
$notes = '';
|
$notes = '';
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isset($_POST['contact_primary'])) {
|
if (isset($_POST['contact_auth_method'])) {
|
||||||
$primary = intval($_POST['contact_primary']);
|
$auth_method = trim(strip_tags(mysqli_real_escape_string($mysqli, $_POST['contact_auth_method'])));
|
||||||
} elseif ($contact_row) {
|
} elseif ($contact_row) {
|
||||||
$primary = $contact_row['contact_primary'];
|
$auth_method = $contact_row['contact_auth_method'];
|
||||||
} else {
|
} else {
|
||||||
$primary = '0';
|
$auth_method = '';
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isset($_POST['contact_important'])) {
|
if (isset($_POST['contact_important'])) {
|
||||||
|
|||||||
@@ -1,13 +1,10 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
require_once '../validate_api_key.php';
|
require_once('../validate_api_key.php');
|
||||||
|
require_once('../require_post_method.php');
|
||||||
require_once '../require_post_method.php';
|
|
||||||
|
|
||||||
|
|
||||||
// Parse Info
|
// Parse Info
|
||||||
require_once 'contact_model.php';
|
require_once('contact_model.php');
|
||||||
|
|
||||||
|
|
||||||
// Default
|
// Default
|
||||||
$insert_id = false;
|
$insert_id = false;
|
||||||
@@ -20,20 +17,18 @@ if (!empty($name) && !empty($email) && !empty($client_id)) {
|
|||||||
if (mysqli_num_rows($email_duplication_sql) == 0) {
|
if (mysqli_num_rows($email_duplication_sql) == 0) {
|
||||||
|
|
||||||
// Insert contact
|
// Insert contact
|
||||||
$insert_sql = mysqli_query($mysqli, "INSERT INTO contacts SET contact_name = '$name', contact_title = '$title', contact_department = '$department', contact_email = '$email', contact_phone = '$phone', contact_extension = '$extension', contact_mobile = '$mobile', contact_notes = '$notes', contact_primary = '$primary', contact_important = '$important', contact_billing = '$billing', contact_technical = '$technical', contact_location_id = $location_id, contact_client_id = $client_id");
|
$insert_sql = mysqli_query($mysqli, "INSERT INTO contacts SET contact_name = '$name', contact_title = '$title', contact_department = '$department', contact_email = '$email', contact_phone = '$phone', contact_extension = '$extension', contact_mobile = '$mobile', contact_notes = '$notes', contact_auth_method = '$auth_method', contact_important = '$important', contact_billing = '$billing', contact_technical = '$technical', contact_created_at = NOW(), contact_location_id = $location_id, contact_client_id = $client_id, company_id = $company_id");
|
||||||
|
|
||||||
// Check insert & get insert ID
|
// Check insert & get insert ID
|
||||||
if ($insert_sql) {
|
if ($insert_sql) {
|
||||||
$insert_id = mysqli_insert_id($mysqli);
|
$insert_id = mysqli_insert_id($mysqli);
|
||||||
|
//Logging
|
||||||
// Logging
|
mysqli_query($mysqli, "INSERT INTO logs SET log_type = 'Contact', log_action = 'Created', log_description = '$name via API ($api_key_name)', log_ip = '$ip', log_user_agent = '$user_agent', log_created_at = NOW(), log_client_id = $client_id, company_id = $company_id");
|
||||||
logAction("Contact", "Create", "$name via API ($api_key_name)", $client_id, $insert_id);
|
mysqli_query($mysqli, "INSERT INTO logs SET log_type = 'API', log_action = 'Success', log_description = 'Created contact $name via API ($api_key_name)', log_ip = '$ip', log_user_agent = '$user_agent', log_created_at = NOW(), log_client_id = $client_id, company_id = $company_id");
|
||||||
logAction("API", "Success", "Created contact $name via API ($api_key_name)", $client_id);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Output
|
// Output
|
||||||
require_once '../create_output.php';
|
require_once('../create_output.php');
|
||||||
|
|
||||||
|
|||||||
@@ -1,9 +1,7 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
require_once '../validate_api_key.php';
|
require_once('../validate_api_key.php');
|
||||||
|
require_once('../require_post_method.php');
|
||||||
require_once '../require_post_method.php';
|
|
||||||
|
|
||||||
|
|
||||||
// Parse ID
|
// Parse ID
|
||||||
$contact_id = intval($_POST['contact_id']);
|
$contact_id = intval($_POST['contact_id']);
|
||||||
@@ -12,20 +10,19 @@ $contact_id = intval($_POST['contact_id']);
|
|||||||
$delete_count = false;
|
$delete_count = false;
|
||||||
|
|
||||||
if (!empty($contact_id)) {
|
if (!empty($contact_id)) {
|
||||||
$row = mysqli_fetch_assoc(mysqli_query($mysqli, "SELECT * FROM contacts WHERE contact_id = $contact_id AND contact_client_id = $client_id LIMIT 1"));
|
$row = mysqli_fetch_assoc(mysqli_query($mysqli, "SELECT * FROM contacts WHERE contact_id = $contact_id AND contact_client_id = $client_id AND company_id = '$company_id' LIMIT 1"));
|
||||||
$contact_name = $row['contact_name'];
|
$contact_name = $row['contact_name'];
|
||||||
|
|
||||||
$delete_sql = mysqli_query($mysqli, "DELETE FROM contacts WHERE contact_id = $contact_id AND contact_client_id = $client_id LIMIT 1");
|
$delete_sql = mysqli_query($mysqli, "DELETE FROM contacts WHERE contact_id = $contact_id AND contact_client_id = $client_id AND company_id = '$company_id' LIMIT 1");
|
||||||
|
|
||||||
// Check delete & get affected rows
|
// Check delete & get affected rows
|
||||||
if ($delete_sql && !empty($contact_name)) {
|
if ($delete_sql && !empty($contact_name)) {
|
||||||
$delete_count = mysqli_affected_rows($mysqli);
|
$delete_count = mysqli_affected_rows($mysqli);
|
||||||
|
|
||||||
// Logging
|
//Logging
|
||||||
logAction("Contact", "Delete", "$contact_name via API ($api_key_name)", $client_id);
|
mysqli_query($mysqli, "INSERT INTO logs SET log_type = 'Contact', log_action = 'Deleted', log_description = '$contact_name via API ($api_key_name)', log_ip = '$ip', log_user_agent = '$user_agent', log_client_id = $client_id, company_id = $company_id");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Output
|
// Output
|
||||||
require_once '../delete_output.php';
|
require_once('../delete_output.php');
|
||||||
|
|
||||||
|
|||||||
@@ -1,30 +1,24 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
require_once '../validate_api_key.php';
|
require_once('../validate_api_key.php');
|
||||||
|
require_once('../require_get_method.php');
|
||||||
require_once '../require_get_method.php';
|
|
||||||
|
|
||||||
|
|
||||||
// Specific contact via ID (single)
|
// Specific contact via ID (single)
|
||||||
if (isset($_GET['contact_id'])) {
|
if (isset($_GET['contact_id'])) {
|
||||||
$id = intval($_GET['contact_id']);
|
$id = intval($_GET['contact_id']);
|
||||||
$sql = mysqli_query($mysqli, "SELECT * FROM contacts WHERE contact_id = '$id' AND contact_client_id LIKE '$client_id'");
|
$sql = mysqli_query($mysqli, "SELECT * FROM contacts WHERE contact_id = '$id' AND contact_client_id LIKE '$client_id' AND company_id = '$company_id'");
|
||||||
|
|
||||||
} elseif (isset($_GET['contact_email'])) {
|
} elseif (isset($_GET['contact_email'])) {
|
||||||
// Specific contact via email (single)
|
// Specific contact via email (single)
|
||||||
$email = mysqli_real_escape_string($mysqli, $_GET['contact_email']);
|
|
||||||
$sql = mysqli_query($mysqli, "SELECT * FROM contacts WHERE contact_email = '$email' AND contact_client_id LIKE '$client_id'");
|
|
||||||
|
|
||||||
} elseif (isset($_GET['contact_phone_or_mobile'])) {
|
$email = mysqli_real_escape_string($mysqli, $_GET['contact_email']);
|
||||||
// Specific contact via phone number or mobile (single)
|
$sql = mysqli_query($mysqli, "SELECT * FROM contacts WHERE contact_email = '$email' AND contact_client_id LIKE '$client_id' AND company_id = '$company_id'");
|
||||||
$phone_or_mob = mysqli_real_escape_string($mysqli, $_GET['contact_phone_or_mobile']);
|
|
||||||
$sql = mysqli_query($mysqli, "SELECT * FROM contacts WHERE contact_mobile = '$phone_or_mob' OR contact_phone = '$phone_or_mob' AND contact_client_id LIKE '$client_id' LIMIT 1");
|
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
// All contacts (by client ID, or all in general if key permits)
|
// All contacts
|
||||||
$sql = mysqli_query($mysqli, "SELECT * FROM contacts WHERE contact_client_id LIKE '$client_id' ORDER BY contact_id LIMIT $limit OFFSET $offset");
|
|
||||||
|
$sql = mysqli_query($mysqli, "SELECT * FROM contacts WHERE contact_client_id LIKE '$client_id' AND company_id = '$company_id' ORDER BY contact_id LIMIT $limit OFFSET $offset");
|
||||||
}
|
}
|
||||||
|
|
||||||
// Output
|
// Output
|
||||||
require_once "../read_output.php";
|
require_once("../read_output.php");
|
||||||
|
|
||||||
|
|||||||
@@ -1,9 +1,7 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
require_once '../validate_api_key.php';
|
require_once('../validate_api_key.php');
|
||||||
|
require_once('../require_post_method.php');
|
||||||
require_once '../require_post_method.php';
|
|
||||||
|
|
||||||
|
|
||||||
// Parse Info
|
// Parse Info
|
||||||
$contact_id = intval($_POST['contact_id']);
|
$contact_id = intval($_POST['contact_id']);
|
||||||
@@ -13,23 +11,22 @@ $update_count = false;
|
|||||||
|
|
||||||
if (!empty($contact_id)) {
|
if (!empty($contact_id)) {
|
||||||
|
|
||||||
$contact_row = mysqli_fetch_assoc(mysqli_query($mysqli, "SELECT * FROM contacts WHERE contact_id = '$contact_id' AND contact_client_id = $client_id LIMIT 1"));
|
$contact_row = mysqli_fetch_assoc(mysqli_query($mysqli, "SELECT * FROM contacts WHERE contact_id = '$contact_id' AND contact_client_id = $client_id AND company_id = '$company_id' LIMIT 1"));
|
||||||
|
|
||||||
// Variable assignment from POST - assigning the current database value if a value is not provided
|
// Variable assignment from POST - assigning the current database value if a value is not provided
|
||||||
require_once 'contact_model.php';
|
require_once('contact_model.php');
|
||||||
|
|
||||||
|
$update_sql = mysqli_query($mysqli, "UPDATE contacts SET contact_name = '$name', contact_title = '$title', contact_department = '$department', contact_email = '$email', contact_phone = '$phone', contact_extension = '$extension', contact_mobile = '$mobile', contact_notes = '$notes', contact_auth_method = '$auth_method', contact_important = '$important', contact_billing = '$billing', contact_technical = '$technical', contact_updated_at = NOW(), contact_location_id = $location_id, contact_client_id = $client_id, company_id = $company_id WHERE contact_id = $contact_id LIMIT 1");
|
||||||
$update_sql = mysqli_query($mysqli, "UPDATE contacts SET contact_name = '$name', contact_title = '$title', contact_department = '$department', contact_email = '$email', contact_phone = '$phone', contact_extension = '$extension', contact_mobile = '$mobile', contact_notes = '$notes', contact_primary = '$primary', contact_important = '$important', contact_billing = '$billing', contact_technical = '$technical', contact_location_id = $location_id, contact_client_id = $client_id WHERE contact_id = $contact_id LIMIT 1");
|
|
||||||
|
|
||||||
// Check insert & get insert ID
|
// Check insert & get insert ID
|
||||||
if ($update_sql) {
|
if ($update_sql) {
|
||||||
$update_count = mysqli_affected_rows($mysqli);
|
$update_count = mysqli_affected_rows($mysqli);
|
||||||
|
|
||||||
// Logging
|
//Logging
|
||||||
logAction("Contact", "Edit", "$name via API ($api_key_name)", $client_id, $contact_id);
|
mysqli_query($mysqli, "INSERT INTO logs SET log_type = 'Contact', log_action = 'Updated', log_description = '$name via API ($api_key_name)', log_ip = '$ip', log_user_agent = '$user_agent', log_created_at = NOW(), log_client_id = $client_id, company_id = $company_id");
|
||||||
logAction("API", "Success", "Edited contact $name via API ($api_key_name)", $client_id);
|
mysqli_query($mysqli, "INSERT INTO logs SET log_type = 'API', log_action = 'Success', log_description = 'Updated contact $name via API ($api_key_name)', log_ip = '$ip', log_user_agent = '$user_agent', log_created_at = NOW(), log_client_id = $client_id, company_id = $company_id");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Output
|
// Output
|
||||||
require_once '../update_output.php';
|
require_once('../update_output.php');
|
||||||
|
|||||||
@@ -1,30 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
require_once '../validate_api_key.php';
|
|
||||||
|
|
||||||
require_once '../require_post_method.php';
|
|
||||||
|
|
||||||
// Parse info
|
|
||||||
require_once 'credential_model.php';
|
|
||||||
|
|
||||||
// Default
|
|
||||||
$insert_id = false;
|
|
||||||
|
|
||||||
if (!empty($api_key_decrypt_password) && !empty($name) && !(empty($password))) {
|
|
||||||
|
|
||||||
// Add credential
|
|
||||||
$insert_sql = mysqli_query($mysqli,"INSERT INTO logins SET login_name = '$name', login_description = '$description', login_uri = '$uri', login_uri_2 = '$uri_2', login_username = '$username', login_password = '$password', login_otp_secret = '$otp_secret', login_note = '$note', login_important = $important, login_contact_id = $contact_id, login_vendor_id = $vendor_id, login_asset_id = $asset_id, login_software_id = $software_id, login_client_id = $client_id");
|
|
||||||
|
|
||||||
// Check insert & get insert ID
|
|
||||||
if ($insert_sql) {
|
|
||||||
$insert_id = mysqli_insert_id($mysqli);
|
|
||||||
|
|
||||||
// Logging
|
|
||||||
logAction("Credential", "Create", "$name via API ($api_key_name)", $client_id, $insert_id);
|
|
||||||
logAction("API", "Success", "Created credential $name via API ($api_key_name)", $client_id);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
// Output
|
|
||||||
require_once '../create_output.php';
|
|
||||||
@@ -1,120 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
|
|
||||||
// Variable assignment from POST (or: blank/from DB is updating)
|
|
||||||
|
|
||||||
$api_key_decrypt_password = '';
|
|
||||||
if (isset($_POST['api_key_decrypt_password'])) {
|
|
||||||
$api_key_decrypt_password = $_POST['api_key_decrypt_password']; // No sanitization
|
|
||||||
}
|
|
||||||
|
|
||||||
if (isset($_POST['login_name'])) {
|
|
||||||
$name = sanitizeInput($_POST['login_name']);
|
|
||||||
} elseif (isset($credential_row) && isset($credential_row['login_name'])) {
|
|
||||||
$name = $credential_row['login_name'];
|
|
||||||
} else {
|
|
||||||
$name = '';
|
|
||||||
}
|
|
||||||
|
|
||||||
if (isset($_POST['login_description'])) {
|
|
||||||
$description = sanitizeInput($_POST['login_description']);
|
|
||||||
} elseif (isset($credential_row) && isset($credential_row['login_description'])) {
|
|
||||||
$description = $credential_row['login_description'];
|
|
||||||
} else {
|
|
||||||
$description = '';
|
|
||||||
}
|
|
||||||
|
|
||||||
if (isset($_POST['login_uri'])) {
|
|
||||||
$uri = sanitizeInput($_POST['login_uri']);
|
|
||||||
} elseif (isset($credential_row) && isset($credential_row['login_uri'])) {
|
|
||||||
$uri = $credential_row['login_uri'];
|
|
||||||
} else {
|
|
||||||
$uri = '';
|
|
||||||
}
|
|
||||||
|
|
||||||
if (isset($_POST['login_uri_2'])) {
|
|
||||||
$uri_2 = sanitizeInput($_POST['login_uri_2']);
|
|
||||||
} elseif (isset($credential_row) && isset($credential_row['login_uri_2'])) {
|
|
||||||
$uri_2 = $credential_row['login_uri_2'];
|
|
||||||
} else {
|
|
||||||
$uri_2 = '';
|
|
||||||
}
|
|
||||||
|
|
||||||
if (isset($_POST['login_username'])) {
|
|
||||||
$username = $_POST['login_username'];
|
|
||||||
$username = apiEncryptLoginEntry($username, $api_key_decrypt_hash, $api_key_decrypt_password);
|
|
||||||
} elseif (isset($credential_row) && isset($credential_row['login_username'])) {
|
|
||||||
$username = $credential_row['login_username'];
|
|
||||||
} else {
|
|
||||||
$username = '';
|
|
||||||
}
|
|
||||||
|
|
||||||
if (isset($_POST['login_password'])) {
|
|
||||||
$password = $_POST['login_password'];
|
|
||||||
$password = apiEncryptLoginEntry($password, $api_key_decrypt_hash, $api_key_decrypt_password);
|
|
||||||
$password_changed = true;
|
|
||||||
} elseif (isset($credential_row) && isset($credential_row['login_password'])) {
|
|
||||||
$password = $credential_row['login_password'];
|
|
||||||
$password_changed = false;
|
|
||||||
} else {
|
|
||||||
$password = '';
|
|
||||||
$password_changed = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
if (isset($_POST['login_otp_secret'])) {
|
|
||||||
$otp_secret = sanitizeInput($_POST['login_otp_secret']);
|
|
||||||
} elseif (isset($credential_row) && isset($credential_row['login_otp_secret'])) {
|
|
||||||
$otp_secret = $credential_row['login_otp_secret'];
|
|
||||||
} else {
|
|
||||||
$otp_secret = '';
|
|
||||||
}
|
|
||||||
|
|
||||||
if (isset($_POST['login_note'])) {
|
|
||||||
$note = sanitizeInput($_POST['login_note']);
|
|
||||||
} elseif (isset($credential_row) && isset($credential_row['login_note'])) {
|
|
||||||
$note = $credential_row['login_note'];
|
|
||||||
} else {
|
|
||||||
$note = '';
|
|
||||||
}
|
|
||||||
|
|
||||||
if (isset($_POST['login_important'])) {
|
|
||||||
$important = intval($_POST['login_important']);
|
|
||||||
} elseif (isset($credential_row) && isset($credential_row['login_important'])) {
|
|
||||||
$important = $credential_row['login_important'];
|
|
||||||
} else {
|
|
||||||
$important = '';
|
|
||||||
}
|
|
||||||
|
|
||||||
if (isset($_POST['login_contact_id'])) {
|
|
||||||
$contact_id = intval($_POST['login_contact_id']);
|
|
||||||
} elseif (isset($credential_row) && isset($credential_row['login_contact_id'])) {
|
|
||||||
$contact_id = $credential_row['login_contact_id'];
|
|
||||||
} else {
|
|
||||||
$contact_id = '';
|
|
||||||
}
|
|
||||||
|
|
||||||
if (isset($_POST['login_vendor_id'])) {
|
|
||||||
$vendor_id = intval($_POST['login_vendor_id']);
|
|
||||||
} elseif (isset($credential_row) && isset($credential_row['login_vendor_id'])) {
|
|
||||||
$vendor_id = $credential_row['login_vendor_id'];
|
|
||||||
} else {
|
|
||||||
$vendor_id = '';
|
|
||||||
}
|
|
||||||
|
|
||||||
if (isset($_POST['login_asset_id'])) {
|
|
||||||
$asset_id = intval($_POST['login_asset_id']);
|
|
||||||
} elseif (isset($credential_row) && isset($credential_row['login_asset_id'])) {
|
|
||||||
$asset_id = $credential_row['login_asset_id'];
|
|
||||||
} else {
|
|
||||||
$asset_id = '';
|
|
||||||
}
|
|
||||||
|
|
||||||
if (isset($_POST['login_software_id'])) {
|
|
||||||
$software_id = intval($_POST['login_software_id']);
|
|
||||||
} elseif (isset($credential_row) && isset($credential_row['login_software_id'])) {
|
|
||||||
$software_id = $credential_row['login_software_id'];
|
|
||||||
} else {
|
|
||||||
$software_id = '';
|
|
||||||
}
|
|
||||||
@@ -1,59 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
require_once '../validate_api_key.php';
|
|
||||||
|
|
||||||
require_once '../require_get_method.php';
|
|
||||||
|
|
||||||
// Defaults
|
|
||||||
$sql = false;
|
|
||||||
|
|
||||||
$api_key_decrypt_password = '';
|
|
||||||
if (isset($_GET['api_key_decrypt_password'])) {
|
|
||||||
$api_key_decrypt_password = $_GET['api_key_decrypt_password']; // No sanitization
|
|
||||||
}
|
|
||||||
|
|
||||||
// Specific credential/login via ID (single)
|
|
||||||
if (isset($_GET['login_id']) && !empty($api_key_decrypt_password)) {
|
|
||||||
|
|
||||||
$id = intval($_GET['login_id']);
|
|
||||||
|
|
||||||
$sql = mysqli_query($mysqli, "SELECT * FROM logins WHERE login_id = '$id' AND login_client_id LIKE '$client_id' LIMIT 1");
|
|
||||||
|
|
||||||
|
|
||||||
} elseif (!empty($api_key_decrypt_password)) {
|
|
||||||
// All credentials ("logins")
|
|
||||||
|
|
||||||
$sql = mysqli_query($mysqli, "SELECT * FROM logins WHERE login_client_id LIKE '$client_id' ORDER BY login_id LIMIT $limit OFFSET $offset");
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
// Output - Not using the standard API read_output.php
|
|
||||||
// Usually we just output what is in the database, but credentials need to be decrypted first.
|
|
||||||
|
|
||||||
if ($sql && mysqli_num_rows($sql) > 0) {
|
|
||||||
|
|
||||||
$return_arr['success'] = "True";
|
|
||||||
$return_arr['count'] = mysqli_num_rows($sql);
|
|
||||||
|
|
||||||
$row = array();
|
|
||||||
while ($row = mysqli_fetch_array($sql)) {
|
|
||||||
$row['login_username'] = apiDecryptLoginEntry($row['login_username'], $api_key_decrypt_hash, $api_key_decrypt_password);
|
|
||||||
$row['login_password'] = apiDecryptLoginEntry($row['login_password'], $api_key_decrypt_hash, $api_key_decrypt_password);
|
|
||||||
$return_arr['data'][] = $row;
|
|
||||||
}
|
|
||||||
|
|
||||||
echo json_encode($return_arr);
|
|
||||||
exit();
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
$return_arr['success'] = "False";
|
|
||||||
$return_arr['message'] = "No resource (for this client and company) with the specified parameter(s).";
|
|
||||||
|
|
||||||
// Log any database/schema related errors to the PHP Error log
|
|
||||||
if (mysqli_error($mysqli)) {
|
|
||||||
error_log("API Database Error: " . mysqli_error($mysqli));
|
|
||||||
}
|
|
||||||
|
|
||||||
echo json_encode($return_arr);
|
|
||||||
exit();
|
|
||||||
}
|
|
||||||
@@ -1,38 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
require_once '../validate_api_key.php';
|
|
||||||
|
|
||||||
require_once '../require_post_method.php';
|
|
||||||
|
|
||||||
// Parse ID
|
|
||||||
$login_id = intval($_POST['login_id']);
|
|
||||||
|
|
||||||
// Default
|
|
||||||
$update_count = false;
|
|
||||||
|
|
||||||
if (!empty($_POST['api_key_decrypt_password']) && !empty($login_id)) {
|
|
||||||
|
|
||||||
$credential_row = mysqli_fetch_assoc(mysqli_query($mysqli, "SELECT * FROM logins WHERE login_id = '$login_id' AND login_client_id = $client_id LIMIT 1"));
|
|
||||||
|
|
||||||
// Variable assignment from POST - assigning the current database value if a value is not provided
|
|
||||||
require_once 'credential_model.php';
|
|
||||||
|
|
||||||
$update_sql = mysqli_query($mysqli,"UPDATE logins SET login_name = '$name', login_description = '$description', login_uri = '$uri', login_uri_2 = '$uri_2', login_username = '$username', login_password = '$password', login_otp_secret = '$otp_secret', login_note = '$note', login_important = $important, login_contact_id = $contact_id, login_vendor_id = $vendor_id, login_asset_id = $asset_id, login_software_id = $software_id, login_client_id = $client_id WHERE login_id = '$login_id' AND login_client_id = $client_id LIMIT 1");
|
|
||||||
|
|
||||||
// Check insert & get insert ID
|
|
||||||
if ($update_sql) {
|
|
||||||
$update_count = mysqli_affected_rows($mysqli);
|
|
||||||
|
|
||||||
if ($password_changed) {
|
|
||||||
mysqli_query($mysqli, "UPDATE logins SET login_password_changed_at = NOW() WHERE login_id = $login_id LIMIT 1");
|
|
||||||
}
|
|
||||||
|
|
||||||
// Logging
|
|
||||||
logAction("Credential", "Edit", "$name via API ($api_key_name)", $client_id, $login_id);
|
|
||||||
logAction("API", "Success", "Updated credential $name via API ($api_key_name)", $client_id);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
// Output
|
|
||||||
require_once '../update_output.php';
|
|
||||||
@@ -1,33 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
require_once '../validate_api_key.php';
|
|
||||||
|
|
||||||
require_once '../require_post_method.php';
|
|
||||||
|
|
||||||
// Parse info
|
|
||||||
require_once 'document_model.php';
|
|
||||||
|
|
||||||
// Default
|
|
||||||
$insert_id = false;
|
|
||||||
|
|
||||||
if (!empty($name) && !(empty($content))) {
|
|
||||||
|
|
||||||
// Create document
|
|
||||||
$insert_sql = mysqli_query($mysqli,"INSERT INTO documents SET document_name = '$name', document_description = '$description', document_content = '$content', document_content_raw = '$content_raw', document_template = 0, document_folder_id = $folder, document_created_by = 0, document_client_id = $client_id");
|
|
||||||
|
|
||||||
// Check insert & get insert ID
|
|
||||||
if ($insert_sql) {
|
|
||||||
$insert_id = mysqli_insert_id($mysqli);
|
|
||||||
|
|
||||||
// Update field document_parent to be the same id as document ID as this is the only version of the document.
|
|
||||||
mysqli_query($mysqli,"UPDATE documents SET document_parent = $insert_id WHERE document_id = $insert_id");
|
|
||||||
|
|
||||||
// Logging
|
|
||||||
logAction("Document", "Create", "$name via API ($api_key_name)", $client_id, $insert_id);
|
|
||||||
logAction("API", "Success", "Created document $name via API ($api_key_name)", $client_id);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
// Output
|
|
||||||
require_once '../create_output.php';
|
|
||||||
@@ -1,43 +0,0 @@
|
|||||||
<?php
|
|
||||||
// Variable assignment from POST (or: blank/from DB is updating)
|
|
||||||
|
|
||||||
if (isset($_POST['document_name'])) {
|
|
||||||
$name = sanitizeInput($_POST['document_name']);
|
|
||||||
} elseif (isset($document_row) && isset($document_row['document_name'])) {
|
|
||||||
$name = $document_row['document_name'];
|
|
||||||
} else {
|
|
||||||
$name = '';
|
|
||||||
}
|
|
||||||
|
|
||||||
if (isset($_POST['document_description'])) {
|
|
||||||
$description = sanitizeInput($_POST['document_description']);
|
|
||||||
} elseif (isset($document_row) && isset($document_row['document_description'])) {
|
|
||||||
$description = $document_row['document_description'];
|
|
||||||
} else {
|
|
||||||
$description = '';
|
|
||||||
}
|
|
||||||
|
|
||||||
if (isset($_POST['document_content'])) {
|
|
||||||
$content = mysqli_real_escape_string($mysqli, $_POST['document_content']);
|
|
||||||
} elseif (isset($document_row) && isset($document_row['document_content'])) {
|
|
||||||
$content = $document_row['document_content'];
|
|
||||||
} else {
|
|
||||||
$content = '';
|
|
||||||
}
|
|
||||||
|
|
||||||
// Raw content (used for FULL INDEX searching)
|
|
||||||
if (isset($_POST['document_content'])) {
|
|
||||||
$content_raw = sanitizeInput($_POST['document_name'] . $_POST['document_description'] . " " . str_replace("<", " <", $_POST['document_content']));
|
|
||||||
} elseif (isset($document_row) && isset($document_row['document_content_raw'])) {
|
|
||||||
$content_raw = $document_row['document_content_raw'];
|
|
||||||
} else {
|
|
||||||
$content_raw = '';
|
|
||||||
}
|
|
||||||
|
|
||||||
if (isset($_POST['document_folder_id'])) {
|
|
||||||
$folder = intval($_POST['document_content']);
|
|
||||||
} elseif (isset($document_row) && isset($document_row['document_folder_id'])) {
|
|
||||||
$folder = intval($document_row['document_folder_id']);
|
|
||||||
} else {
|
|
||||||
$folder = 0;
|
|
||||||
}
|
|
||||||
@@ -1,20 +1,19 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
require_once '../validate_api_key.php';
|
require_once('../validate_api_key.php');
|
||||||
|
require_once('../require_get_method.php');
|
||||||
require_once '../require_get_method.php';
|
|
||||||
|
|
||||||
|
|
||||||
if (isset($_GET['document_id'])) {
|
if (isset($_GET['document_id'])) {
|
||||||
// Document via ID (single)
|
// Document via ID (single)
|
||||||
|
|
||||||
$id = intval($_GET['document_id']);
|
$id = intval($_GET['document_id']);
|
||||||
$sql = mysqli_query($mysqli, "SELECT * FROM documents WHERE document_id = '$id' AND document_client_id LIKE '$client_id'");
|
$sql = mysqli_query($mysqli, "SELECT * FROM documents WHERE document_id = '$id' AND document_client_id LIKE '$client_id' AND company_id = '$company_id'");
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
// All documents (by client ID if given, or all in general if key permits)
|
// All documents
|
||||||
$sql = mysqli_query($mysqli, "SELECT * FROM documents WHERE document_client_id LIKE '$client_id' ORDER BY document_id LIMIT $limit OFFSET $offset");
|
|
||||||
|
$sql = mysqli_query($mysqli, "SELECT * FROM documents WHERE document_client_id LIKE '$client_id' AND company_id = '$company_id' ORDER BY document_id LIMIT $limit OFFSET $offset");
|
||||||
}
|
}
|
||||||
|
|
||||||
// Output
|
// Output
|
||||||
require_once "../read_output.php";
|
require_once("../read_output.php");
|
||||||
|
|
||||||
|
|||||||
@@ -1,60 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
require_once '../validate_api_key.php';
|
|
||||||
|
|
||||||
require_once '../require_post_method.php';
|
|
||||||
|
|
||||||
// Parse ID
|
|
||||||
$document_id = intval($_POST['document_id']);
|
|
||||||
|
|
||||||
// Default
|
|
||||||
$update_count = false;
|
|
||||||
|
|
||||||
if (!empty($document_id)) {
|
|
||||||
|
|
||||||
$document_row = mysqli_fetch_assoc(mysqli_query($mysqli, "SELECT * FROM documents WHERE document_id = '$document_id' AND document_client_id = $client_id LIMIT 1"));
|
|
||||||
|
|
||||||
// Variable assignment from POST - assigning the current database value if a value is not provided
|
|
||||||
require_once 'document_model.php';
|
|
||||||
|
|
||||||
// Documents are a little weird as we update them by *inserting* a new document row
|
|
||||||
$update_insert_sql = mysqli_query($mysqli,"INSERT INTO documents SET document_name = '$name', document_description = '$description', document_content = '$content', document_content_raw = '$content_raw', document_template = 0, document_folder_id = $folder, document_created_by = 0, document_client_id = $client_id");
|
|
||||||
|
|
||||||
// Check insert & get insert ID
|
|
||||||
if ($update_insert_sql) {
|
|
||||||
$insert_id = $new_document_id = mysqli_insert_id($mysqli);
|
|
||||||
|
|
||||||
// Update the parent ID of the new document to match its new document ID
|
|
||||||
mysqli_query($mysqli,"UPDATE documents SET document_parent = $new_document_id WHERE document_id = $new_document_id");
|
|
||||||
|
|
||||||
// Link all existing links with old document with new document
|
|
||||||
mysqli_query($mysqli,"UPDATE documents SET document_parent = $new_document_id, document_archived_at = NOW() WHERE document_parent = $document_id");
|
|
||||||
|
|
||||||
// Update Links to the new parent document:-
|
|
||||||
// Document files
|
|
||||||
mysqli_query($mysqli,"UPDATE document_files SET document_id = $new_document_id WHERE document_id = $document_id");
|
|
||||||
|
|
||||||
// Contact documents
|
|
||||||
mysqli_query($mysqli,"UPDATE contact_documents SET document_id = $new_document_id WHERE document_id = $document_id");
|
|
||||||
|
|
||||||
// Asset documents
|
|
||||||
mysqli_query($mysqli,"UPDATE asset_documents SET document_id = $new_document_id WHERE document_id = $document_id");
|
|
||||||
|
|
||||||
// Software documents
|
|
||||||
mysqli_query($mysqli,"UPDATE software_documents SET document_id = $new_document_id WHERE document_id = $document_id");
|
|
||||||
|
|
||||||
// Vendor documents
|
|
||||||
mysqli_query($mysqli,"UPDATE vendor_documents SET document_id = $new_document_id WHERE document_id = $document_id");
|
|
||||||
|
|
||||||
// Logging
|
|
||||||
logAction("Document", "Edit", "$name via API ($api_key_name) previous version kept", $client_id, $insert_id);
|
|
||||||
logAction("API", "Success", "Edited document $name via API ($api_key_name)", $client_id);
|
|
||||||
|
|
||||||
// Override update count to 1 for API to report a success (as we inserted a document, not "updated" an existing row)
|
|
||||||
$update_count = 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
// Output
|
|
||||||
require_once '../update_output.php';
|
|
||||||
@@ -1,25 +1,29 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
require_once '../validate_api_key.php';
|
require_once('../validate_api_key.php');
|
||||||
|
require_once('../require_get_method.php');
|
||||||
require_once '../require_get_method.php';
|
|
||||||
|
|
||||||
|
|
||||||
// Specific domain via ID (single)
|
// Specific domain via ID (single)
|
||||||
if (isset($_GET['domain_id'])) {
|
if (isset($_GET['domain_id'])) {
|
||||||
$id = intval($_GET['domain_id']);
|
$id = intval($_GET['domain_id']);
|
||||||
$sql = mysqli_query($mysqli, "SELECT * FROM domains WHERE domain_id = '$id' AND domain_client_id LIKE '$client_id'");
|
$sql = mysqli_query($mysqli, "SELECT * FROM domains WHERE domain_id = '$id' AND domain_client_id LIKE '$client_id' AND company_id = '$company_id'");
|
||||||
|
|
||||||
} elseif (isset($_GET['domain_name'])) {
|
} elseif (isset($_GET['domain_name'])) {
|
||||||
// Domain by name
|
// Domain by name
|
||||||
|
|
||||||
$name = mysqli_real_escape_string($mysqli, $_GET['domain_name']);
|
$name = mysqli_real_escape_string($mysqli, $_GET['domain_name']);
|
||||||
$sql = mysqli_query($mysqli, "SELECT * FROM domains WHERE domain_name = '$name' AND domain_client_id LIKE '$client_id' ORDER BY asset_id LIMIT $limit OFFSET $offset");
|
$sql = mysqli_query($mysqli, "SELECT * FROM domains WHERE domain_name = '$name' AND domain_client_id LIKE '$client_id' AND company_id = '$company_id' ORDER BY asset_id LIMIT $limit OFFSET $offset");
|
||||||
|
|
||||||
|
} elseif (isset($_GET['client_id'])) {
|
||||||
|
// Domain via client ID
|
||||||
|
|
||||||
|
$sql = mysqli_query($mysqli, "SELECT * FROM domains WHERE domain_client_id LIKE '$client_id' AND company_id = '$company_id' ORDER BY domain_id LIMIT $limit OFFSET $offset");
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
// All domains (by client ID or all in general if key permits)
|
// All domains
|
||||||
$sql = mysqli_query($mysqli, "SELECT * FROM domains WHERE domain_client_id LIKE '$client_id' ORDER BY domain_id LIMIT $limit OFFSET $offset");
|
|
||||||
|
$sql = mysqli_query($mysqli, "SELECT * FROM domains WHERE domain_client_id LIKE '$client_id' AND company_id = '$company_id' ORDER BY domain_id LIMIT $limit OFFSET $offset");
|
||||||
}
|
}
|
||||||
|
|
||||||
// Output
|
// Output
|
||||||
require_once "../read_output.php";
|
require_once("../read_output.php");
|
||||||
|
|
||||||
|
|||||||
@@ -1,9 +1,7 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
require_once '../validate_api_key.php';
|
require_once('../validate_api_key.php');
|
||||||
|
require_once('../require_get_method.php');
|
||||||
require_once '../require_get_method.php';
|
|
||||||
|
|
||||||
|
|
||||||
// Expenses aren't stored against client IDs, so we instead validate the API key is for All Clients
|
// Expenses aren't stored against client IDs, so we instead validate the API key is for All Clients
|
||||||
|
|
||||||
@@ -11,14 +9,13 @@ if (isset($_GET['expense_id']) && $client_id == "%") {
|
|||||||
// Expense via ID (single)
|
// Expense via ID (single)
|
||||||
|
|
||||||
$id = intval($_GET['expense_id']);
|
$id = intval($_GET['expense_id']);
|
||||||
$sql = mysqli_query($mysqli, "SELECT * FROM expenses WHERE expense_id = '$id'");
|
$sql = mysqli_query($mysqli, "SELECT * FROM expenses WHERE expense_id = '$id' AND company_id = '$company_id'");
|
||||||
|
|
||||||
} elseif ($client_id == "%") {
|
} elseif ($client_id == "%") {
|
||||||
// All expenses
|
// All expenses
|
||||||
|
|
||||||
$sql = mysqli_query($mysqli, "SELECT * FROM expenses ORDER BY expense_id LIMIT $limit OFFSET $offset");
|
$sql = mysqli_query($mysqli, "SELECT * FROM expenses WHERE company_id = '$company_id' ORDER BY expense_id LIMIT $limit OFFSET $offset");
|
||||||
}
|
}
|
||||||
|
|
||||||
// Output
|
// Output
|
||||||
require_once "../read_output.php";
|
require_once("../read_output.php");
|
||||||
|
|
||||||
|
|||||||
@@ -1,20 +1,19 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
require_once '../validate_api_key.php';
|
require_once('../validate_api_key.php');
|
||||||
|
require_once('../require_get_method.php');
|
||||||
require_once '../require_get_method.php';
|
|
||||||
|
|
||||||
|
|
||||||
if (isset($_GET['invoice_id'])) {
|
if (isset($_GET['invoice_id'])) {
|
||||||
// Invoice via ID (single)
|
// Invoice via ID (single)
|
||||||
|
|
||||||
$id = intval($_GET['invoice_id']);
|
$id = intval($_GET['invoice_id']);
|
||||||
$sql = mysqli_query($mysqli, "SELECT * FROM invoices WHERE invoice_id = '$id' AND invoice_client_id LIKE '$client_id'");
|
$sql = mysqli_query($mysqli, "SELECT * FROM invoices WHERE invoice_id = '$id' AND invoice_client_id LIKE '$client_id' AND company_id = '$company_id'");
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
// All invoices (by client ID if given, or all in general if key permits)
|
// All invoices
|
||||||
$sql = mysqli_query($mysqli, "SELECT * FROM invoices WHERE invoice_client_id LIKE '$client_id' ORDER BY invoice_id LIMIT $limit OFFSET $offset");
|
|
||||||
|
$sql = mysqli_query($mysqli, "SELECT * FROM invoices WHERE invoice_client_id LIKE '$client_id' AND company_id = '$company_id' ORDER BY invoice_id LIMIT $limit OFFSET $offset");
|
||||||
}
|
}
|
||||||
|
|
||||||
// Output
|
// Output
|
||||||
require_once "../read_output.php";
|
require_once("../read_output.php");
|
||||||
|
|
||||||
|
|||||||
@@ -1,20 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
require_once '../validate_api_key.php';
|
|
||||||
|
|
||||||
require_once '../require_get_method.php';
|
|
||||||
|
|
||||||
|
|
||||||
if (isset($_GET['location_id'])) {
|
|
||||||
// Location via ID (single)
|
|
||||||
$id = intval($_GET['location_id']);
|
|
||||||
$sql = mysqli_query($mysqli, "SELECT * FROM locations WHERE location_id = '$id' AND location_client_id LIKE '$client_id'");
|
|
||||||
|
|
||||||
} else {
|
|
||||||
// All locations (by client ID if given, or all in general if key permits)
|
|
||||||
$sql = mysqli_query($mysqli, "SELECT * FROM locations WHERE location_client_id LIKE '$client_id' ORDER BY location_id LIMIT $limit OFFSET $offset");
|
|
||||||
}
|
|
||||||
|
|
||||||
// Output
|
|
||||||
require_once "../read_output.php";
|
|
||||||
|
|
||||||
@@ -1,25 +1,29 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
require_once '../validate_api_key.php';
|
require_once('../validate_api_key.php');
|
||||||
|
require_once('../require_get_method.php');
|
||||||
require_once '../require_get_method.php';
|
|
||||||
|
|
||||||
|
|
||||||
// Specific network via ID (single)
|
// Specific network via ID (single)
|
||||||
if (isset($_GET['network_id'])) {
|
if (isset($_GET['network_id'])) {
|
||||||
$id = intval($_GET['network_id']);
|
$id = intval($_GET['network_id']);
|
||||||
$sql = mysqli_query($mysqli, "SELECT * FROM networks WHERE network_id = '$id' AND network_client_id LIKE '$client_id'");
|
$sql = mysqli_query($mysqli, "SELECT * FROM networks WHERE network_id = '$id' AND network_client_id LIKE '$client_id' AND company_id = '$company_id'");
|
||||||
|
|
||||||
} elseif (isset($_GET['network_name'])) {
|
} elseif (isset($_GET['network_name'])) {
|
||||||
// Network by name
|
// Network by name
|
||||||
|
|
||||||
$name = mysqli_real_escape_string($mysqli, $_GET['network_name']);
|
$name = mysqli_real_escape_string($mysqli, $_GET['network_name']);
|
||||||
$sql = mysqli_query($mysqli, "SELECT * FROM networks WHERE network_name = '$name' AND network_client_id LIKE '$client_id' ORDER BY network_id LIMIT $limit OFFSET $offset");
|
$sql = mysqli_query($mysqli, "SELECT * FROM networks WHERE network_name = '$name' AND network_client_id LIKE '$client_id' AND company_id = '$company_id' ORDER BY network_id LIMIT $limit OFFSET $offset");
|
||||||
|
|
||||||
|
} elseif (isset($_GET['client_id'])) {
|
||||||
|
// Network via client ID
|
||||||
|
|
||||||
|
$sql = mysqli_query($mysqli, "SELECT * FROM networks WHERE network_client_id LIKE '$client_id' AND company_id = '$company_id' ORDER BY network_id LIMIT $limit OFFSET $offset");
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
// All networks (by client ID or all in general if key permits)
|
// All networks
|
||||||
$sql = mysqli_query($mysqli, "SELECT * FROM networks WHERE network_client_id LIKE '$client_id' ORDER BY network_id LIMIT $limit OFFSET $offset");
|
|
||||||
|
$sql = mysqli_query($mysqli, "SELECT * FROM networks WHERE network_client_id LIKE '$client_id' AND company_id = '$company_id' ORDER BY network_id LIMIT $limit OFFSET $offset");
|
||||||
}
|
}
|
||||||
|
|
||||||
// Output
|
// Output
|
||||||
require_once "../read_output.php";
|
require_once("../read_output.php");
|
||||||
|
|
||||||
|
|||||||
@@ -1,9 +1,7 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
require_once '../validate_api_key.php';
|
require_once('../validate_api_key.php');
|
||||||
|
require_once('../require_get_method.php');
|
||||||
require_once '../require_get_method.php';
|
|
||||||
|
|
||||||
|
|
||||||
// Payments aren't stored against client IDs, so we instead validate the API key is for All Clients
|
// Payments aren't stored against client IDs, so we instead validate the API key is for All Clients
|
||||||
|
|
||||||
@@ -12,20 +10,19 @@ if (isset($_GET['payment_id']) && $client_id == "%") {
|
|||||||
// Payment via ID (single)
|
// Payment via ID (single)
|
||||||
|
|
||||||
$id = intval($_GET['payment_id']);
|
$id = intval($_GET['payment_id']);
|
||||||
$sql = mysqli_query($mysqli, "SELECT * FROM payments WHERE payment_id = '$id'");
|
$sql = mysqli_query($mysqli, "SELECT * FROM payments WHERE payment_id = '$id' AND company_id = '$company_id'");
|
||||||
|
|
||||||
} elseif (isset($_GET['payment_invoice_id']) && $client_id == "%") {
|
} elseif (isset($_GET['payment_invoice_id']) && $client_id == "%") {
|
||||||
// Payments for an invoice
|
// Payments for an invoice
|
||||||
|
|
||||||
$id = intval($_GET['payment_invoice_id']);
|
$id = intval($_GET['payment_invoice_id']);
|
||||||
$sql = mysqli_query($mysqli, "SELECT * FROM payments WHERE payment_invoice_id = '$id'");
|
$sql = mysqli_query($mysqli, "SELECT * FROM payments WHERE payment_invoice_id = '$id' AND company_id = '$company_id'");
|
||||||
|
|
||||||
} elseif ($client_id == "%") {
|
} elseif ($client_id == "%") {
|
||||||
// All payments
|
// All payments
|
||||||
|
|
||||||
$sql = mysqli_query($mysqli, "SELECT * FROM payments ORDER BY payment_id LIMIT $limit OFFSET $offset");
|
$sql = mysqli_query($mysqli, "SELECT * FROM payments WHERE company_id = '$company_id' ORDER BY payment_id LIMIT $limit OFFSET $offset");
|
||||||
}
|
}
|
||||||
|
|
||||||
// Output
|
// Output
|
||||||
require_once "../read_output.php";
|
require_once("../read_output.php");
|
||||||
|
|
||||||
|
|||||||
@@ -1,22 +1,21 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
require_once '../validate_api_key.php';
|
require_once('../validate_api_key.php');
|
||||||
|
require_once('../require_get_method.php');
|
||||||
require_once '../require_get_method.php';
|
|
||||||
|
|
||||||
|
|
||||||
// Products aren't stored against client IDs, so we instead validate the API key is for All Clients
|
// Products aren't stored against client IDs, so we instead validate the API key is for All Clients
|
||||||
|
|
||||||
if (isset($_GET['product_id']) && $client_id == "%") {
|
if (isset($_GET['product_id']) && $client_id == "%") {
|
||||||
// product via ID (single)
|
// product via ID (single)
|
||||||
|
|
||||||
$id = intval($_GET['product_id']);
|
$id = intval($_GET['product_id']);
|
||||||
$sql = mysqli_query($mysqli, "SELECT * FROM products WHERE product_id = '$id'");
|
$sql = mysqli_query($mysqli, "SELECT * FROM products WHERE product_id = '$id' AND company_id = '$company_id'");
|
||||||
|
|
||||||
} elseif ($client_id == "%") {
|
} elseif ($client_id == "%") {
|
||||||
// All products
|
// All products
|
||||||
$sql = mysqli_query($mysqli, "SELECT * FROM products ORDER BY product_id LIMIT $limit OFFSET $offset");
|
|
||||||
|
$sql = mysqli_query($mysqli, "SELECT * FROM products WHERE company_id = '$company_id' ORDER BY product_id LIMIT $limit OFFSET $offset");
|
||||||
}
|
}
|
||||||
|
|
||||||
// Output
|
// Output
|
||||||
require_once "../read_output.php";
|
require_once("../read_output.php");
|
||||||
|
|
||||||
|
|||||||
@@ -1,20 +1,19 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
require_once '../validate_api_key.php';
|
require_once('../validate_api_key.php');
|
||||||
|
require_once('../require_get_method.php');
|
||||||
require_once '../require_get_method.php';
|
|
||||||
|
|
||||||
|
|
||||||
if (isset($_GET['quote_id'])) {
|
if (isset($_GET['quote_id'])) {
|
||||||
// quote via ID (single)
|
// quote via ID (single)
|
||||||
|
|
||||||
$id = intval($_GET['quote_id']);
|
$id = intval($_GET['quote_id']);
|
||||||
$sql = mysqli_query($mysqli, "SELECT * FROM quotes WHERE quote_id LIKE '$id' AND quote_client_id = '$client_id'");
|
$sql = mysqli_query($mysqli, "SELECT * FROM quotes WHERE quote_id LIKE '$id' AND quote_client_id = '$client_id' AND company_id = '$company_id'");
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
// All quotes (by client ID if given, or all in general if key permits)
|
// All quotes
|
||||||
$sql = mysqli_query($mysqli, "SELECT * FROM quotes WHERE quote_client_id LIKE '$client_id' ORDER BY quote_id LIMIT $limit OFFSET $offset");
|
|
||||||
|
$sql = mysqli_query($mysqli, "SELECT * FROM quotes WHERE quote_client_id LIKE '$client_id' AND company_id = '$company_id' ORDER BY quote_id LIMIT $limit OFFSET $offset");
|
||||||
}
|
}
|
||||||
|
|
||||||
// Output
|
// Output
|
||||||
require_once "../read_output.php";
|
require_once("../read_output.php");
|
||||||
|
|
||||||
|
|||||||
@@ -9,6 +9,6 @@ if ($_SERVER['REQUEST_METHOD'] !== "POST") {
|
|||||||
|
|
||||||
// Client ID must be specific for INSERT/UPDATE/DELETE queries
|
// Client ID must be specific for INSERT/UPDATE/DELETE queries
|
||||||
// If this API key allows any client, set $client_id to the one specified, else leave it
|
// If this API key allows any client, set $client_id to the one specified, else leave it
|
||||||
if ($client_id == 0 && isset($_POST['client_id'])) {
|
if ($client_id == 0) {
|
||||||
$client_id = intval($_POST['client_id']);
|
$client_id = intval($_POST['client_id']);
|
||||||
}
|
}
|
||||||
@@ -1,35 +1,41 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
require_once '../validate_api_key.php';
|
require_once('../validate_api_key.php');
|
||||||
|
require_once('../require_get_method.php');
|
||||||
require_once '../require_get_method.php';
|
|
||||||
|
|
||||||
|
|
||||||
// Specific software via ID (single)
|
// Specific software via ID (single)
|
||||||
if (isset($_GET['software_id'])) {
|
if (isset($_GET['software_id'])) {
|
||||||
$id = intval($_GET['software_id']);
|
$id = intval($_GET['software_id']);
|
||||||
$sql = mysqli_query($mysqli, "SELECT * FROM software WHERE software_id = '$id' AND software_client_id LIKE '$client_id'");
|
$sql = mysqli_query($mysqli, "SELECT * FROM software WHERE software_id = '$id' AND software_client_id LIKE '$client_id' AND company_id = '$company_id'");
|
||||||
|
|
||||||
} elseif (isset($_GET['software_key'])) {
|
} elseif (isset($_GET['software_key'])) {
|
||||||
// Specific software via key
|
// Specific software via key
|
||||||
|
|
||||||
$key = mysqli_real_escape_string($mysqli, $_GET['software_license']);
|
$key = mysqli_real_escape_string($mysqli, $_GET['software_license']);
|
||||||
$sql = mysqli_query($mysqli, "SELECT * FROM software WHERE software_key = '$key' AND software_client_id LIKE '$client_id' ORDER BY software_id LIMIT $limit OFFSET $offset");
|
$sql = mysqli_query($mysqli, "SELECT * FROM software WHERE software_key = '$key' AND software_client_id LIKE '$client_id' AND company_id = '$company_id' ORDER BY software_id LIMIT $limit OFFSET $offset");
|
||||||
|
|
||||||
} elseif (isset($_GET['software_name'])) {
|
} elseif (isset($_GET['software_name'])) {
|
||||||
// Software by name
|
// Software by name
|
||||||
|
|
||||||
$name = mysqli_real_escape_string($mysqli, $_GET['software_name']);
|
$name = mysqli_real_escape_string($mysqli, $_GET['software_name']);
|
||||||
$sql = mysqli_query($mysqli, "SELECT * FROM software WHERE software_name = '$name' AND software_client_id LIKE '$client_id' ORDER BY asset_id LIMIT $limit OFFSET $offset");
|
$sql = mysqli_query($mysqli, "SELECT * FROM software WHERE software_name = '$name' AND software_client_id LIKE '$client_id' AND company_id = '$company_id' ORDER BY asset_id LIMIT $limit OFFSET $offset");
|
||||||
|
|
||||||
} elseif (isset($_GET['software_type'])) {
|
} elseif (isset($_GET['software_type'])) {
|
||||||
// Software via type
|
// Software via type
|
||||||
|
|
||||||
$type = intval($_GET['software_type']);
|
$type = intval($_GET['software_type']);
|
||||||
$sql = mysqli_query($mysqli, "SELECT * FROM software WHERE software_type = '$type' AND software_client_id LIKE '$client_id' ORDER BY software_id LIMIT $limit OFFSET $offset");
|
$sql = mysqli_query($mysqli, "SELECT * FROM software WHERE software_type = '$type' AND software_client_id LIKE '$client_id' AND company_id = '$company_id' ORDER BY software_id LIMIT $limit OFFSET $offset");
|
||||||
|
|
||||||
|
} elseif (isset($_GET['client_id'])) {
|
||||||
|
// Software via client ID
|
||||||
|
|
||||||
|
$sql = mysqli_query($mysqli, "SELECT * FROM software WHERE software_client_id LIKE '$client_id' AND company_id = '$company_id' ORDER BY software_id LIMIT $limit OFFSET $offset");
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
// All software(s) (by client ID if given, or all in general if key permits)
|
// All software(s)
|
||||||
$sql = mysqli_query($mysqli, "SELECT * FROM software WHERE software_client_id LIKE '$client_id' ORDER BY software_id LIMIT $limit OFFSET $offset");
|
|
||||||
|
$sql = mysqli_query($mysqli, "SELECT * FROM software WHERE software_client_id LIKE '$client_id' AND company_id = '$company_id' ORDER BY software_id LIMIT $limit OFFSET $offset");
|
||||||
}
|
}
|
||||||
|
|
||||||
// Output
|
// Output
|
||||||
require_once "../read_output.php";
|
require_once("../read_output.php");
|
||||||
|
|
||||||
|
|||||||
@@ -1,56 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
require_once '../validate_api_key.php';
|
|
||||||
|
|
||||||
require_once '../require_post_method.php';
|
|
||||||
|
|
||||||
// Ticket-related settings
|
|
||||||
require_once "../../../get_settings.php";
|
|
||||||
|
|
||||||
$sql = mysqli_query($mysqli, "SELECT company_name, company_phone FROM companies WHERE company_id = 1");
|
|
||||||
$row = mysqli_fetch_array($sql);
|
|
||||||
$company_name = $row['company_name'];
|
|
||||||
$company_phone = formatPhoneNumber($row['company_phone']);
|
|
||||||
|
|
||||||
// Parse Info
|
|
||||||
$ticket_row = false; // Creation, not an update
|
|
||||||
require_once 'ticket_model.php';
|
|
||||||
|
|
||||||
// Default
|
|
||||||
$insert_id = false;
|
|
||||||
|
|
||||||
if (!empty($subject)) {
|
|
||||||
|
|
||||||
if (!is_int($client_id)) {
|
|
||||||
$client_id = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
// If no contact is selected automatically choose the primary contact for the client (if client set)
|
|
||||||
if ($contact == 0 && $client_id != 0) {
|
|
||||||
$sql = mysqli_query($mysqli,"SELECT contact_id FROM contacts WHERE contact_client_id = $client_id AND contact_primary = 1");
|
|
||||||
$row = mysqli_fetch_array($sql);
|
|
||||||
$contact = intval($row['contact_id']);
|
|
||||||
}
|
|
||||||
|
|
||||||
//Get the next Ticket Number and add 1 for the new ticket number
|
|
||||||
$ticket_number = $config_ticket_next_number;
|
|
||||||
$new_config_ticket_next_number = $config_ticket_next_number + 1;
|
|
||||||
mysqli_query($mysqli,"UPDATE settings SET config_ticket_next_number = $new_config_ticket_next_number WHERE company_id = 1");
|
|
||||||
|
|
||||||
// Insert ticket
|
|
||||||
$url_key = randomString(156);
|
|
||||||
$insert_sql = mysqli_query($mysqli,"INSERT INTO tickets SET ticket_prefix = '$config_ticket_prefix', ticket_number = $ticket_number, ticket_subject = '$subject', ticket_details = '$details', ticket_priority = '$priority', ticket_status = 1, ticket_vendor_ticket_number = '$vendor_ticket_number', ticket_vendor_id = $vendor_id, ticket_created_by = 0, ticket_assigned_to = $assigned_to, ticket_contact_id = $contact, ticket_url_key = '$url_key', ticket_client_id = $client_id");
|
|
||||||
|
|
||||||
// Check insert & get insert ID
|
|
||||||
if ($insert_sql) {
|
|
||||||
$insert_id = mysqli_insert_id($mysqli);
|
|
||||||
|
|
||||||
// Logging
|
|
||||||
logAction("Ticket", "Create", "Created ticket $config_ticket_prefix$ticket_number $subject via API ($api_key_name)", $client_id, $insert_id);
|
|
||||||
logAction("API", "Success", "Created ticket $config_ticket_prefix$ticket_number $subject via API ($api_key_name)", $client_id);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
// Output
|
|
||||||
require_once '../create_output.php';
|
|
||||||
@@ -1,25 +1,18 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
require_once '../validate_api_key.php';
|
require_once('../validate_api_key.php');
|
||||||
|
require_once('../require_get_method.php');
|
||||||
require_once '../require_get_method.php';
|
|
||||||
|
|
||||||
|
|
||||||
// Specific ticket via ID (single)
|
// Specific ticket via ID (single)
|
||||||
if (isset($_GET['ticket_id'])) {
|
if (isset($_GET['ticket_id'])) {
|
||||||
$id = intval($_GET['ticket_id']);
|
$id = intval($_GET['ticket_id']);
|
||||||
$sql = mysqli_query(
|
$sql = mysqli_query($mysqli, "SELECT * FROM tickets WHERE ticket_id = '$id' AND ticket_client_id LIKE '$client_id' AND company_id = '$company_id'");
|
||||||
$mysqli,
|
|
||||||
"SELECT * FROM tickets
|
|
||||||
LEFT JOIN ticket_statuses ON ticket_status = ticket_status_id
|
|
||||||
WHERE ticket_id = '$id' AND ticket_client_id LIKE '$client_id'"
|
|
||||||
);
|
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
// All tickets (by client ID if given, or all in general if key permits)
|
// All tickets
|
||||||
$sql = mysqli_query($mysqli, "SELECT * FROM tickets WHERE ticket_client_id LIKE '$client_id' ORDER BY ticket_id LIMIT $limit OFFSET $offset");
|
|
||||||
|
$sql = mysqli_query($mysqli, "SELECT * FROM tickets WHERE ticket_client_id LIKE '$client_id' AND company_id = '$company_id' ORDER BY ticket_id LIMIT $limit OFFSET $offset");
|
||||||
}
|
}
|
||||||
|
|
||||||
// Output
|
// Output
|
||||||
require_once "../read_output.php";
|
require_once("../read_output.php");
|
||||||
|
|
||||||
|
|||||||
@@ -1,61 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
// Variable assignment from POST (or: blank/from DB is updating)
|
|
||||||
|
|
||||||
if (isset($_POST['ticket_contact_id'])) {
|
|
||||||
$contact = intval($_POST['ticket_contact_id']);
|
|
||||||
} elseif ($ticket_row) {
|
|
||||||
$contact = $ticket_row['ticket_contact_id'];
|
|
||||||
} else {
|
|
||||||
$contact = '0';
|
|
||||||
}
|
|
||||||
|
|
||||||
if (isset($_POST['ticket_subject'])) {
|
|
||||||
$subject = sanitizeInput($_POST['ticket_subject']);
|
|
||||||
} elseif ($ticket_row) {
|
|
||||||
$subject = $ticket_row['ticket_subject'];
|
|
||||||
} else {
|
|
||||||
$subject = '';
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
if (isset($_POST['ticket_priority'])) {
|
|
||||||
$priority = sanitizeInput($_POST['ticket_priority']);
|
|
||||||
} elseif ($ticket_row) {
|
|
||||||
$priority = $ticket_row['ticket_priority'];
|
|
||||||
} else {
|
|
||||||
$priority = 'Low';
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
if (isset($_POST['ticket_details'])) {
|
|
||||||
$details = sanitizeInput($_POST['ticket_details']) . "<br>";
|
|
||||||
} elseif ($ticket_row) {
|
|
||||||
$details = $ticket_row['ticket_details'];
|
|
||||||
} else {
|
|
||||||
$details = '< blank ><br>';
|
|
||||||
}
|
|
||||||
|
|
||||||
if (isset($_POST['ticket_vendor_id'])) {
|
|
||||||
$vendor_id = intval($_POST['ticket_vendor_id']);
|
|
||||||
} elseif ($ticket_row) {
|
|
||||||
$vendor_id = $ticket_row['ticket_vendor_id'];
|
|
||||||
} else {
|
|
||||||
$vendor_id = '0';
|
|
||||||
}
|
|
||||||
|
|
||||||
if (isset($_POST['ticket_vendor_ticket_id'])) {
|
|
||||||
$vendor_ticket_number = intval($_POST['ticket_vendor_ticket_id']);
|
|
||||||
} elseif ($ticket_row) {
|
|
||||||
$vendor_ticket_number = $ticket_row['ticket_vendor_ticket_id'];
|
|
||||||
} else {
|
|
||||||
$vendor_ticket_number = '0';
|
|
||||||
}
|
|
||||||
|
|
||||||
if (isset($_POST['ticket_assigned_to'])) {
|
|
||||||
$assigned_to = intval($_POST['ticket_assigned_to']);
|
|
||||||
} elseif ($ticket_row) {
|
|
||||||
$assigned_to = $ticket_row['ticket_assigned_to'];
|
|
||||||
} else {
|
|
||||||
$assigned_to = '0';
|
|
||||||
}
|
|
||||||
@@ -7,8 +7,8 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
// Includes
|
// Includes
|
||||||
require_once __DIR__ . '../../../functions.php';
|
require_once(__DIR__ . '../../../functions.php');
|
||||||
require_once __DIR__ . "../../../config.php";
|
require_once(__DIR__ . "../../../config.php");
|
||||||
|
|
||||||
// JSON header
|
// JSON header
|
||||||
header('Content-Type: application/json');
|
header('Content-Type: application/json');
|
||||||
@@ -17,12 +17,8 @@ header('Content-Type: application/json');
|
|||||||
$_POST = json_decode(file_get_contents('php://input'), true);
|
$_POST = json_decode(file_get_contents('php://input'), true);
|
||||||
|
|
||||||
// Get IP & UA
|
// Get IP & UA
|
||||||
$ip = sanitizeInput(getIP());
|
$ip = strip_tags(mysqli_real_escape_string($mysqli, getIP()));
|
||||||
$user_agent = sanitizeInput($_SERVER['HTTP_USER_AGENT']);
|
$user_agent = strip_tags(mysqli_real_escape_string($mysqli, $_SERVER['HTTP_USER_AGENT']));
|
||||||
|
|
||||||
// Temp Added this to work with the new logAction function
|
|
||||||
$session_ip = $ip;
|
|
||||||
$session_user_agent = $user_agent;
|
|
||||||
|
|
||||||
// Setup return array
|
// Setup return array
|
||||||
$return_arr = array();
|
$return_arr = array();
|
||||||
@@ -60,15 +56,15 @@ if (!isset($_GET['api_key']) && !isset($_POST['api_key'])) {
|
|||||||
|
|
||||||
// Set API key variable
|
// Set API key variable
|
||||||
if (isset($_GET['api_key'])) {
|
if (isset($_GET['api_key'])) {
|
||||||
$api_key = sanitizeInput($_GET['api_key']);
|
$api_key = $_GET['api_key'];
|
||||||
}
|
}
|
||||||
if (isset($_POST['api_key'])) {
|
if (isset($_POST['api_key'])) {
|
||||||
$api_key = sanitizeInput($_POST['api_key']);
|
$api_key = $_POST['api_key'];
|
||||||
}
|
}
|
||||||
|
|
||||||
// Validate API key
|
// Validate API key
|
||||||
if (isset($api_key)) {
|
if (isset($api_key)) {
|
||||||
$api_key = sanitizeInput($api_key);
|
$api_key = mysqli_real_escape_string($mysqli, $api_key);
|
||||||
|
|
||||||
$sql = mysqli_query($mysqli, "SELECT * FROM api_keys WHERE api_key_secret = '$api_key' AND api_key_expire > NOW() LIMIT 1");
|
$sql = mysqli_query($mysqli, "SELECT * FROM api_keys WHERE api_key_secret = '$api_key' AND api_key_expire > NOW() LIMIT 1");
|
||||||
|
|
||||||
@@ -76,7 +72,7 @@ if (isset($api_key)) {
|
|||||||
if (mysqli_num_rows($sql) !== 1) {
|
if (mysqli_num_rows($sql) !== 1) {
|
||||||
// Invalid Key
|
// Invalid Key
|
||||||
header(WORDING_UNAUTHORIZED);
|
header(WORDING_UNAUTHORIZED);
|
||||||
mysqli_query($mysqli, "INSERT INTO logs SET log_type = 'API', log_action = 'Failed', log_description = 'Incorrect or expired key', log_ip = '$ip', log_user_agent = '$user_agent'");
|
mysqli_query($mysqli, "INSERT INTO logs SET log_type = 'API', log_action = 'Failed', log_description = 'Incorrect or expired key', log_ip = '$ip', log_user_agent = '$user_agent', log_created_at = NOW()");
|
||||||
|
|
||||||
$return_arr['success'] = "False";
|
$return_arr['success'] = "False";
|
||||||
$return_arr['message'] = "Authentication failed. API key is invalid or has expired.";
|
$return_arr['message'] = "Authentication failed. API key is invalid or has expired.";
|
||||||
@@ -92,8 +88,8 @@ if (isset($api_key)) {
|
|||||||
// Set client ID, company ID & key name
|
// Set client ID, company ID & key name
|
||||||
$row = mysqli_fetch_array($sql);
|
$row = mysqli_fetch_array($sql);
|
||||||
$api_key_name = htmlentities($row['api_key_name']);
|
$api_key_name = htmlentities($row['api_key_name']);
|
||||||
$api_key_decrypt_hash = $row['api_key_decrypt_hash']; // No sanitization
|
$client_id = $row['api_key_client_id'];
|
||||||
$client_id = intval($row['api_key_client_id']);
|
$company_id = $row['company_id'];
|
||||||
|
|
||||||
// Set limit & offset for queries
|
// Set limit & offset for queries
|
||||||
if (isset($_GET['limit'])) {
|
if (isset($_GET['limit'])) {
|
||||||
|
|||||||
19
api/v1/vendors/read.php
vendored
19
api/v1/vendors/read.php
vendored
@@ -1,19 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
require_once '../validate_api_key.php';
|
|
||||||
|
|
||||||
require_once '../require_get_method.php';
|
|
||||||
|
|
||||||
// Specific vendor via their ID (single)
|
|
||||||
if (isset($_GET['vendor_id'])) {
|
|
||||||
$id = intval($_GET['vendor_id']);
|
|
||||||
$sql = mysqli_query($mysqli, "SELECT * FROM vendors WHERE vendor_id = '$id' AND vendor_client_id LIKE '$client_id'");
|
|
||||||
|
|
||||||
} else {
|
|
||||||
// All Vendors (by client ID or all in general if key permits)
|
|
||||||
$sql = mysqli_query($mysqli, "SELECT * FROM vendors WHERE vendor_client_id LIKE '$client_id' ORDER BY vendor_id LIMIT $limit OFFSET $offset");
|
|
||||||
}
|
|
||||||
|
|
||||||
// Output
|
|
||||||
require_once "../read_output.php";
|
|
||||||
|
|
||||||
@@ -1,76 +1,79 @@
|
|||||||
<script src="js/quote_edit_modal.js"></script>
|
<?php
|
||||||
<div class="modal" id="editQuoteModal" tabindex="-1">
|
$key = randomString(156);
|
||||||
|
?>
|
||||||
|
<div class="modal" id="addApiKeyModal" tabindex="-1">
|
||||||
<div class="modal-dialog">
|
<div class="modal-dialog">
|
||||||
<div class="modal-content bg-dark">
|
<div class="modal-content bg-dark">
|
||||||
<div class="modal-header">
|
<div class="modal-header">
|
||||||
<h5 class="modal-title text-white"><i class="fas fa-fw fa-comment-dollar mr-2"></i>Editing quote: <span class="text-bold" id="editQuoteHeaderID"></span> - <span class="text" id="editQuoteHeaderClient"></span></h5>
|
<h5 class="modal-title"><i class="fas fa-fw fa-key mr-2"></i>New Key</h5>
|
||||||
<button type="button" class="close text-white" data-dismiss="modal">
|
<button type="button" class="close text-white" data-dismiss="modal">
|
||||||
<span>×</span>
|
<span>×</span>
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
<form action="post.php" method="post" autocomplete="off">
|
<form action="post.php" method="post" autocomplete="off">
|
||||||
<input type="hidden" name="quote_id" id="editQuoteID" value="">
|
<div class="modal-body bg-white">
|
||||||
|
|
||||||
<div class="modal-body bg-white" <?php if (lookupUserPermission('module_sales') <= 1) { echo 'inert'; } ?>>
|
<input type="hidden" name="csrf_token" value="<?php echo $_SESSION['csrf_token'] ?>">
|
||||||
|
<input type="hidden" name="key" value="<?php echo $key ?>">
|
||||||
|
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label>Quote Date</label>
|
<label>API Key <strong class="text-danger">*</strong></label>
|
||||||
<div class="input-group">
|
<div class="input-group">
|
||||||
<div class="input-group-prepend">
|
<div class="input-group-prepend">
|
||||||
<span class="input-group-text"><i class="fa fa-fw fa-calendar"></i></span>
|
<span class="input-group-text"><i class="fa fa-fw fa-key"></i></span>
|
||||||
</div>
|
</div>
|
||||||
<input type="date" class="form-control" name="date" id="editQuoteDate" max="2999-12-31" value="" required>
|
<input type="text" class="form-control" value="<?php echo $key ?>" required disabled>
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="form-group">
|
|
||||||
<label>Expire <strong class="text-danger">*</strong></label>
|
|
||||||
<div class="input-group">
|
|
||||||
<div class="input-group-prepend">
|
|
||||||
<span class="input-group-text"><i class="fa fa-fw fa-calendar"></i></span>
|
|
||||||
</div>
|
|
||||||
<input type="date" class="form-control" name="expire" id="editQuoteExpire" max="2999-12-31" value="" required>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="form-group">
|
|
||||||
<label>Income Category</label>
|
|
||||||
<div class="input-group">
|
|
||||||
<div class="input-group-prepend">
|
|
||||||
<span class="input-group-text"><i class="fa fa-fw fa-tag"></i></span>
|
|
||||||
</div>
|
|
||||||
<select class="form-control select2" name="category" id="editQuoteCategory" required>
|
|
||||||
</select>
|
|
||||||
<div class="input-group-append">
|
<div class="input-group-append">
|
||||||
<a class="btn btn-secondary" href="admin_category.php?category=Income" target="_blank"><i class="fas fa-fw fa-plus"></i></a>
|
<button class="btn btn-default clipboardjs" type="button" data-clipboard-text="<?php echo $key; ?>"><i class="fa fa-fw fa-copy"></i></button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<hr>
|
||||||
|
|
||||||
<div class='form-group'>
|
<div class="form-group">
|
||||||
<label>Discount Amount</label>
|
<label>Name <strong class="text-danger">*</strong></label>
|
||||||
<div class='input-group'>
|
<div class="input-group">
|
||||||
<div class='input-group-prepend'>
|
<div class="input-group-prepend">
|
||||||
<span class='input-group-text'><i class='fa fa-fw fa-dollar-sign'></i></span>
|
<span class="input-group-text"><i class="fa fa-fw fa-sticky-note"></i></span>
|
||||||
</div>
|
</div>
|
||||||
<input type='text' class='form-control' inputmode="numeric" pattern="-?[0-9]*\.?[0-9]{0,2}" name='quote_discount' placeholder='0.00' value="<?php echo number_format($quote_discount, 2, '.', ''); ?>">
|
<input type="text" class="form-control" name="name" placeholder="Key Name" required autofocus>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label>Scope</label>
|
<label>Expiration Date <strong class="text-danger">*</strong></label>
|
||||||
<div class="input-group">
|
<div class="input-group">
|
||||||
<div class="input-group-prepend">
|
<div class="input-group-prepend">
|
||||||
<span class="input-group-text"><i class="fa fa-fw fa-comment"></i></span>
|
<span class="input-group-text"><i class="fa fa-fw fa-calendar"></i></span>
|
||||||
</div>
|
</div>
|
||||||
<input type="text" class="form-control" name="scope" id="editQuoteScope" placeholder="Quick description" value="" maxlength="255">
|
<input type="date" class="form-control" name="expire" max="2999-12-31" required>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="form-group">
|
||||||
|
<label>Client <strong class="text-danger">*</strong></label>
|
||||||
|
<div class="input-group">
|
||||||
|
<div class="input-group-prepend">
|
||||||
|
<span class="input-group-text"><i class="fa fa-fw fa-user"></i></span>
|
||||||
|
</div>
|
||||||
|
<select class="form-control select2" name="client" required>
|
||||||
|
<option value="">- Client -</option>
|
||||||
|
<option value="0"> ALL CLIENTS </option>
|
||||||
|
<?php
|
||||||
|
$sql = mysqli_query($mysqli, "SELECT * FROM clients WHERE company_id = $session_company_id ORDER BY client_name ASC");
|
||||||
|
while ($row = mysqli_fetch_array($sql)) {
|
||||||
|
$client_id = intval($row['client_id']);
|
||||||
|
$client_name = htmlentities($row['client_name']); ?>
|
||||||
|
<option value="<?php echo $client_id; ?>"><?php echo "$client_name (Client ID: $client_id)"; ?></option>
|
||||||
|
<?php } ?>
|
||||||
|
</select>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
<div class="modal-footer bg-white">
|
<div class="modal-footer bg-white">
|
||||||
<button type="submit" name="edit_quote" class="btn btn-primary text-bold"><i class="fas fa-check mr-2"></i>Save</button>
|
<button type="submit" name="add_api_key" class="btn btn-primary text-bold"><i class="fa 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>
|
<button type="button" class="btn btn-light" data-dismiss="modal"><i class="fas fa-times mr-2"></i>Cancel</button>
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
96
base32static.php
Normal file
96
base32static.php
Normal file
@@ -0,0 +1,96 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* Encode in Base32 based on RFC 4648.
|
||||||
|
* Requires 20% more space than base64
|
||||||
|
* Great for case-insensitive filesystems like Windows and URL's (except for = char which can be excluded using the pad option for urls)
|
||||||
|
*
|
||||||
|
* @package default
|
||||||
|
* @author Bryan Ruiz
|
||||||
|
**/
|
||||||
|
class Base32Static {
|
||||||
|
private static $map = array(
|
||||||
|
'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', // 7
|
||||||
|
'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', // 15
|
||||||
|
'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', // 23
|
||||||
|
'Y', 'Z', '2', '3', '4', '5', '6', '7', // 31
|
||||||
|
'=' // padding character
|
||||||
|
);
|
||||||
|
|
||||||
|
private static $flippedMap = array(
|
||||||
|
'A'=>'0', 'B'=>'1', 'C'=>'2', 'D'=>'3', 'E'=>'4', 'F'=>'5', 'G'=>'6', 'H'=>'7',
|
||||||
|
'I'=>'8', 'J'=>'9', 'K'=>'10', 'L'=>'11', 'M'=>'12', 'N'=>'13', 'O'=>'14', 'P'=>'15',
|
||||||
|
'Q'=>'16', 'R'=>'17', 'S'=>'18', 'T'=>'19', 'U'=>'20', 'V'=>'21', 'W'=>'22', 'X'=>'23',
|
||||||
|
'Y'=>'24', 'Z'=>'25', '2'=>'26', '3'=>'27', '4'=>'28', '5'=>'29', '6'=>'30', '7'=>'31'
|
||||||
|
);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Use padding false when encoding for urls
|
||||||
|
*
|
||||||
|
* @return base32 encoded string
|
||||||
|
* @author Bryan Ruiz
|
||||||
|
**/
|
||||||
|
public static function encode($input, $padding = true) {
|
||||||
|
if (empty($input)) return "";
|
||||||
|
|
||||||
|
$input = str_split($input);
|
||||||
|
$binaryString = "";
|
||||||
|
|
||||||
|
for ($i = 0; $i < count($input); $i++) {
|
||||||
|
$binaryString .= str_pad(base_convert(ord($input[$i]), 10, 2), 8, '0', STR_PAD_LEFT);
|
||||||
|
}
|
||||||
|
|
||||||
|
$fiveBitBinaryArray = str_split($binaryString, 5);
|
||||||
|
$base32 = "";
|
||||||
|
$i=0;
|
||||||
|
|
||||||
|
while($i < count($fiveBitBinaryArray)) {
|
||||||
|
$base32 .= self::$map[base_convert(str_pad($fiveBitBinaryArray[$i], 5, '0'), 2, 10)];
|
||||||
|
$i++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($padding && ($x = strlen($binaryString) % 40) != 0) {
|
||||||
|
if ($x == 8) $base32 .= str_repeat(self::$map[32], 6);
|
||||||
|
else if ($x == 16) $base32 .= str_repeat(self::$map[32], 4);
|
||||||
|
else if ($x == 24) $base32 .= str_repeat(self::$map[32], 3);
|
||||||
|
else if ($x == 32) $base32 .= self::$map[32];
|
||||||
|
}
|
||||||
|
|
||||||
|
return $base32;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function decode($input) {
|
||||||
|
if (empty($input)) return;
|
||||||
|
|
||||||
|
$paddingCharCount = substr_count($input, self::$map[32]);
|
||||||
|
$allowedValues = array(6,4,3,1,0);
|
||||||
|
|
||||||
|
if (!in_array($paddingCharCount, $allowedValues)) return false;
|
||||||
|
|
||||||
|
for ($i=0; $i<4; $i++){
|
||||||
|
if ($paddingCharCount == $allowedValues[$i] &&
|
||||||
|
substr($input, -($allowedValues[$i])) != str_repeat(self::$map[32], $allowedValues[$i])) return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
$input = str_replace('=', '', $input);
|
||||||
|
$input = str_split($input);
|
||||||
|
$binaryString = "";
|
||||||
|
|
||||||
|
for ($i=0; $i < count($input); $i = $i+8) {
|
||||||
|
$x = "";
|
||||||
|
|
||||||
|
if (!in_array($input[$i], self::$map)) return false;
|
||||||
|
|
||||||
|
for ($j=0; $j < 8; $j++) {
|
||||||
|
$x .= str_pad(base_convert(@self::$flippedMap[@$input[$i + $j]], 10, 2), 5, '0', STR_PAD_LEFT);
|
||||||
|
}
|
||||||
|
|
||||||
|
$eightBits = str_split($x, 8);
|
||||||
|
|
||||||
|
for ($z = 0; $z < count($eightBits); $z++) {
|
||||||
|
$binaryString .= (($y = chr(base_convert($eightBits[$z], 2, 10))) || ord($y) == 48) ? $y:"";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return $binaryString;
|
||||||
|
}
|
||||||
|
}
|
||||||
72
blank.php
72
blank.php
@@ -1,55 +1,35 @@
|
|||||||
<?php require_once "includes/inc_all.php"; ?>
|
<?php require_once("inc_all.php"); ?>
|
||||||
|
|
||||||
<!-- Breadcrumbs-->
|
<!-- Breadcrumbs-->
|
||||||
<ol class="breadcrumb">
|
<ol class="breadcrumb">
|
||||||
<li class="breadcrumb-item">
|
<li class="breadcrumb-item">
|
||||||
<a href="index.html">Dashboard</a>
|
<a href="index.html">Dashboard</a>
|
||||||
</li>
|
</li>
|
||||||
<li class="breadcrumb-item active">Blank Page</li>
|
<li class="breadcrumb-item active">Blank Page</li>
|
||||||
</ol>
|
</ol>
|
||||||
|
|
||||||
<!-- Page Content -->
|
<!-- Page Content -->
|
||||||
<h1>Blank Page</h1>
|
<h1>Blank Page</h1>
|
||||||
<hr>
|
<hr>
|
||||||
<p>This is a great starting point for new custom pages.</p>
|
<p>This is a great starting point for new custom pages.</p>
|
||||||
|
|
||||||
|
<?php echo CURRENT_DATABASE_VERSION; ?>
|
||||||
|
<br>
|
||||||
|
|
||||||
|
<?php echo randomString(100); ?>
|
||||||
|
<br>
|
||||||
|
<form>
|
||||||
<?php
|
<?php
|
||||||
|
$timezones = DateTimeZone::listIdentifiers();
|
||||||
$start_date = date('Y') . "-10-10";
|
echo '<select name="timezone">';
|
||||||
|
foreach ($timezones as $timezone) {
|
||||||
echo "<H1>$start_date</H1>";
|
echo '<option value="' . $timezone . '">' . $timezone . '</option>';
|
||||||
|
}
|
||||||
echo "<H2>User Agent</H2>";
|
echo '</select>';
|
||||||
echo getUserAgent();
|
|
||||||
|
|
||||||
|
|
||||||
?>
|
?>
|
||||||
<br>
|
</form>
|
||||||
|
|
||||||
<dl>
|
|
||||||
<dt>Requester</dt>
|
|
||||||
<dd>Sam Adams</dd>
|
|
||||||
|
|
||||||
<dt>Created</dt>
|
|
||||||
<dd><time datetime="2024-04-11T17:52:30+00:00" title="2024-04-11 13:52" data-datetime="calendar">Today at 13:52</time></dd>
|
|
||||||
|
|
||||||
<dt>Last activity</dt>
|
|
||||||
<dd><time datetime="2024-04-11T18:08:55+00:00" title="2024-04-11 14:08" data-datetime="calendar">Today at 14:08</time></dd>
|
|
||||||
</dl>
|
|
||||||
|
|
||||||
<?php echo randomString(100); ?>
|
|
||||||
<br>
|
|
||||||
<textarea class="tinymceTest"></textarea>
|
|
||||||
|
|
||||||
<textarea class="tinymce"></textarea>
|
|
||||||
|
|
||||||
<textarea class="tinymceTicket"></textarea>
|
|
||||||
<?php
|
|
||||||
// show the current Date and Time
|
|
||||||
$date_time = date('Y-m-d H:i:s');
|
|
||||||
echo "Current Date and Time: <strong>$date_time</strong>";
|
|
||||||
?>
|
|
||||||
|
|
||||||
<script>toastr.success('Have Fun Wozz!!')</script>
|
<script>toastr.success('Have Fun Wozz!!')</script>
|
||||||
|
|
||||||
<?php require_once "includes/footer.php";
|
<?php require_once("footer.php"); ?>
|
||||||
|
|||||||
113
budget.php
113
budget.php
@@ -1,113 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
require_once "includes/inc_all.php";
|
|
||||||
|
|
||||||
// Perms
|
|
||||||
enforceUserPermission('module_financial');
|
|
||||||
|
|
||||||
// Fetch categories
|
|
||||||
$query = "SELECT category_id, category_name FROM categories WHERE category_type ='Expense' AND category_archived_at IS NULL";
|
|
||||||
$result = mysqli_query($mysqli, $query);
|
|
||||||
$categories = [];
|
|
||||||
while($row = mysqli_fetch_assoc($result)) {
|
|
||||||
$categories[] = $row;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Fetch years with budget
|
|
||||||
$query = "SELECT DISTINCT budget_year FROM budget ORDER BY budget_year ASC";
|
|
||||||
$result = mysqli_query($mysqli, $query);
|
|
||||||
$years = [];
|
|
||||||
while ($row = mysqli_fetch_assoc($result)) {
|
|
||||||
$years[] = $row['budget_year'];
|
|
||||||
}
|
|
||||||
|
|
||||||
// Fetch current year budgets
|
|
||||||
$currentYear = date("Y");
|
|
||||||
if (isset($_GET['year'])) {
|
|
||||||
$currentYear = intval($_GET['year']);
|
|
||||||
}
|
|
||||||
|
|
||||||
$query = "SELECT * FROM budget WHERE budget_year = $currentYear";
|
|
||||||
$result = mysqli_query($mysqli, $query);
|
|
||||||
$budgets = [];
|
|
||||||
while ($row = mysqli_fetch_assoc($result)) {
|
|
||||||
$budgets[] = $row;
|
|
||||||
}
|
|
||||||
|
|
||||||
$months = ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"];
|
|
||||||
$columnTotals = array_fill(0, 12, 0);
|
|
||||||
$grandTotal = 0;
|
|
||||||
|
|
||||||
?>
|
|
||||||
<div class="card card-dark">
|
|
||||||
<div class="card-header py-2">
|
|
||||||
<h3 class="card-title mt-2"><i class="fas fa-fw fa-balance-scale mr-2"></i>Budget for <span id="currentYear"><?php echo $currentYear; ?></span></h3>
|
|
||||||
<div class="card-tools">
|
|
||||||
<a href="budget_edit.php" class="btn btn-primary">
|
|
||||||
<i class="fas fa-edit mr-2"></i>Edit Budget
|
|
||||||
</a>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="card-body">
|
|
||||||
<form id="yearForm" method="GET" action="budget.php">
|
|
||||||
<div class="form-group">
|
|
||||||
<select class="form-control" name="year" id="yearSelect" onchange="submit();">
|
|
||||||
<?php foreach ($years as $year): ?>
|
|
||||||
<option value="<?php echo $year; ?>" <?php if ($year == $currentYear) { echo 'selected'; } ?>><?php echo $year; ?></option>
|
|
||||||
<?php endforeach; ?>
|
|
||||||
</select>
|
|
||||||
</div>
|
|
||||||
</form>
|
|
||||||
<table class="table table-bordered table-striped">
|
|
||||||
<thead>
|
|
||||||
<tr>
|
|
||||||
<th>Expense</th>
|
|
||||||
<?php foreach ($months as $month): ?>
|
|
||||||
<th><?php echo $month; ?></th>
|
|
||||||
<?php endforeach; ?>
|
|
||||||
<th>Total</th>
|
|
||||||
</tr>
|
|
||||||
</thead>
|
|
||||||
<tbody>
|
|
||||||
<?php foreach ($categories as $category): ?>
|
|
||||||
<tr>
|
|
||||||
<td><?php echo nullable_htmlentities($category['category_name']); ?></td>
|
|
||||||
<?php
|
|
||||||
$rowTotal = 0;
|
|
||||||
foreach ($months as $index => $month):
|
|
||||||
$amount = getBudgetAmount($budgets, $category['category_id'], $index + 1);
|
|
||||||
$rowTotal += $amount;
|
|
||||||
$columnTotals[$index] += $amount;
|
|
||||||
?>
|
|
||||||
<td><?php echo $amount; ?></td>
|
|
||||||
<?php endforeach; ?>
|
|
||||||
<td><?php echo $rowTotal; ?></td>
|
|
||||||
</tr>
|
|
||||||
<?php
|
|
||||||
$grandTotal += $rowTotal;
|
|
||||||
endforeach; ?>
|
|
||||||
</tbody>
|
|
||||||
<tfoot>
|
|
||||||
<tr>
|
|
||||||
<th>Total</th>
|
|
||||||
<?php foreach ($columnTotals as $total): ?>
|
|
||||||
<th><?php echo $total; ?></th>
|
|
||||||
<?php endforeach; ?>
|
|
||||||
<th><?php echo $grandTotal; ?></th>
|
|
||||||
</tr>
|
|
||||||
</tfoot>
|
|
||||||
</table>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<?php
|
|
||||||
function getBudgetAmount($budgets, $categoryId, $month) {
|
|
||||||
foreach ($budgets as $budget) {
|
|
||||||
if ($budget['budget_category_id'] == $categoryId && $budget['budget_month'] == $month) {
|
|
||||||
return intval($budget['budget_amount']);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
require_once "includes/footer.php";
|
|
||||||
?>
|
|
||||||
114
budget_edit.php
114
budget_edit.php
@@ -1,114 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
require_once "includes/inc_all.php";
|
|
||||||
|
|
||||||
enforceUserPermission('module_financial', 2);
|
|
||||||
|
|
||||||
// Fetch categories
|
|
||||||
$query = "SELECT category_id, category_name FROM categories WHERE category_type ='Expense' AND category_archived_at IS NULL";
|
|
||||||
$result = mysqli_query($mysqli, $query);
|
|
||||||
$categories = [];
|
|
||||||
while($row = mysqli_fetch_assoc($result)) {
|
|
||||||
$categories[] = $row;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Fetch current year budgets
|
|
||||||
$currentYear = date("Y");
|
|
||||||
if(isset($_GET['year'])) {
|
|
||||||
$currentYear = intval($_GET['year']);
|
|
||||||
}
|
|
||||||
|
|
||||||
$query = "SELECT * FROM budget WHERE budget_year = $currentYear";
|
|
||||||
$result = mysqli_query($mysqli, $query);
|
|
||||||
$budgets = [];
|
|
||||||
while($row = mysqli_fetch_assoc($result)) {
|
|
||||||
$budgets[] = $row;
|
|
||||||
}
|
|
||||||
|
|
||||||
$months = ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"];
|
|
||||||
$columnTotals = array_fill(0, 12, 0);
|
|
||||||
$grandTotal = 0;
|
|
||||||
|
|
||||||
?>
|
|
||||||
<div class="card card-dark">
|
|
||||||
<div class="card-header py-2">
|
|
||||||
<h3 class="card-title mt-2"><i class="fas fa-fw fa-balance-scale mr-2"></i>Editing Budget for <span id="currentYear"><?php echo $currentYear; ?></span></h3>
|
|
||||||
<div class="card-tools">
|
|
||||||
<a href="budget.php" class="btn btn-default text-dark">
|
|
||||||
<i class="fas fa-eye mr-2"></i>View Budget
|
|
||||||
</a>
|
|
||||||
<button type="submit" name="save_budget" form="budgetForm" class="btn btn-primary"><i class="fas fa-fw fa-check mr-2"></i>Save Budget</button>
|
|
||||||
<button type="submit" name="delete_budget" form="budgetForm" class="btn btn-danger"><i class="fas fa-fw fa-trash mr-2"></i>Delete Budget</button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="card-body">
|
|
||||||
|
|
||||||
<form id="yearForm" method="GET" action="budget.php">
|
|
||||||
<div class="form-group">
|
|
||||||
<select class="form-control" name="year" id="yearSelect" onchange="submit();">
|
|
||||||
<?php for ($i = $currentYear - 10; $i <= $currentYear + 5; $i++): ?>
|
|
||||||
<option value="<?php echo $i; ?>" <?php if ($i == $currentYear) echo 'selected'; ?>><?php echo $i; ?></option>
|
|
||||||
<?php endfor; ?>
|
|
||||||
</select>
|
|
||||||
</div>
|
|
||||||
</form>
|
|
||||||
<form id="budgetForm" method="POST" action="post.php">
|
|
||||||
<input type="hidden" name="year" value="<?php echo $currentYear; ?>">
|
|
||||||
<input type="hidden" name="csrf_token" value="<?php echo $_SESSION['csrf_token'] ?>">
|
|
||||||
|
|
||||||
<table class="table table-bordered table-striped">
|
|
||||||
<thead>
|
|
||||||
<tr>
|
|
||||||
<th>Expense</th>
|
|
||||||
<?php foreach ($months as $month): ?>
|
|
||||||
<th><?php echo $month; ?></th>
|
|
||||||
<?php endforeach; ?>
|
|
||||||
<th>Total</th>
|
|
||||||
</tr>
|
|
||||||
</thead>
|
|
||||||
<tbody>
|
|
||||||
<?php foreach ($categories as $category): ?>
|
|
||||||
<tr>
|
|
||||||
<td><?php echo nullable_htmlentities($category['category_name']); ?></td>
|
|
||||||
<?php
|
|
||||||
$rowTotal = 0;
|
|
||||||
foreach ($months as $index => $month):
|
|
||||||
$amount = getBudgetAmount($budgets, $category['category_id'], $index + 1);
|
|
||||||
$rowTotal += $amount;
|
|
||||||
$columnTotals[$index] += $amount;
|
|
||||||
?>
|
|
||||||
<td><input type='text' inputmode='numeric' pattern='[0-9]*' class="form-control" name="budget[<?php echo intval($category['category_id']); ?>][<?php echo $index + 1; ?>]" value="<?php echo $amount; ?>"></td>
|
|
||||||
<?php endforeach; ?>
|
|
||||||
<td><?php echo $rowTotal; ?></td>
|
|
||||||
</tr>
|
|
||||||
<?php
|
|
||||||
$grandTotal += $rowTotal;
|
|
||||||
endforeach; ?>
|
|
||||||
</tbody>
|
|
||||||
<tfoot>
|
|
||||||
<tr>
|
|
||||||
<th>Total</th>
|
|
||||||
<?php foreach ($columnTotals as $total): ?>
|
|
||||||
<th><?php echo $total; ?></th>
|
|
||||||
<?php endforeach; ?>
|
|
||||||
<th><?php echo $grandTotal; ?></th>
|
|
||||||
</tr>
|
|
||||||
</tfoot>
|
|
||||||
</table>
|
|
||||||
</form>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<?php
|
|
||||||
function getBudgetAmount($budgets, $categoryId, $month) {
|
|
||||||
foreach ($budgets as $budget) {
|
|
||||||
if ($budget['budget_category_id'] == $categoryId && $budget['budget_month'] == $month) {
|
|
||||||
return intval($budget['budget_amount']);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
require_once "includes/footer.php";
|
|
||||||
?>
|
|
||||||
@@ -16,17 +16,17 @@
|
|||||||
<div class="input-group-prepend">
|
<div class="input-group-prepend">
|
||||||
<span class="input-group-text"><i class="fa fa-fw fa-calendar"></i></span>
|
<span class="input-group-text"><i class="fa fa-fw fa-calendar"></i></span>
|
||||||
</div>
|
</div>
|
||||||
<input type="text" class="form-control" name="name" placeholder="Name your calendar" maxlength="200" required autofocus>
|
<input type="text" class="form-control" name="name" placeholder="Name your calendar" required autofocus>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label>Color <strong class="text-danger">*</strong></label>
|
<label>Color</label>
|
||||||
<div class="input-group">
|
<div class="input-group">
|
||||||
<div class="input-group-prepend">
|
<div class="input-group-prepend">
|
||||||
<span class="input-group-text"><i class="fa fa-fw fa-paint-brush"></i></span>
|
<span class="input-group-text"><i class="fa fa-fw fa-palette"></i></span>
|
||||||
</div>
|
</div>
|
||||||
<input type="color" class="form-control col-3" name="color" required>
|
<input type="color" class="form-control" name="color" required>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@@ -15,7 +15,7 @@
|
|||||||
<a class="nav-link active" data-toggle="pill" href="#pills-event"><i class="fa fa-fw fa-calendar mr-2"></i>Event</a>
|
<a class="nav-link active" data-toggle="pill" href="#pills-event"><i class="fa fa-fw fa-calendar mr-2"></i>Event</a>
|
||||||
</li>
|
</li>
|
||||||
<li class="nav-item">
|
<li class="nav-item">
|
||||||
<a class="nav-link" data-toggle="pill" href="#pills-details"><i class="fa fa-fw fa-info-circle mr-2"></i>Details</a>
|
<a class="nav-link" data-toggle="pill" href="#pills-more"><i class="fa fa-fw fa-info-circle mr-2"></i>More</a>
|
||||||
</li>
|
</li>
|
||||||
<li class="nav-item">
|
<li class="nav-item">
|
||||||
<a class="nav-link" data-toggle="pill" href="#pills-attendees"><i class="fa fa-fw fa-users mr-2"></i>Attendees</a>
|
<a class="nav-link" data-toggle="pill" href="#pills-attendees"><i class="fa fa-fw fa-users mr-2"></i>Attendees</a>
|
||||||
@@ -34,7 +34,7 @@
|
|||||||
<div class="input-group-prepend">
|
<div class="input-group-prepend">
|
||||||
<span class="input-group-text"><i class="fa fa-fw fa-calendar-day"></i></span>
|
<span class="input-group-text"><i class="fa fa-fw fa-calendar-day"></i></span>
|
||||||
</div>
|
</div>
|
||||||
<input type="text" class="form-control" name="title" placeholder="Title of the event" maxlength="200" required autofocus>
|
<input type="text" class="form-control" name="title" placeholder="Title of the event" required autofocus>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@@ -48,37 +48,40 @@
|
|||||||
<option value="">- Calendar -</option>
|
<option value="">- Calendar -</option>
|
||||||
<?php
|
<?php
|
||||||
|
|
||||||
$sql = mysqli_query($mysqli, "SELECT * FROM calendars ORDER BY calendar_name ASC");
|
$sql = mysqli_query($mysqli, "SELECT * FROM calendars WHERE company_id = $session_company_id ORDER BY calendar_name ASC");
|
||||||
while ($row = mysqli_fetch_array($sql)) {
|
while ($row = mysqli_fetch_array($sql)) {
|
||||||
$calendar_id = intval($row['calendar_id']);
|
$calendar_id = intval($row['calendar_id']);
|
||||||
$calendar_name = nullable_htmlentities($row['calendar_name']);
|
$calendar_name = htmlentities($row['calendar_name']);
|
||||||
$calendar_color = nullable_htmlentities($row['calendar_color']);
|
$calendar_color = htmlentities($row['calendar_color']);
|
||||||
?>
|
?>
|
||||||
<option <?php if ($config_default_calendar == $calendar_id) { echo "selected"; } ?> data-content="<i class='fa fa-circle mr-2' style='color:<?php echo $calendar_color; ?>;'></i> <?php echo $calendar_name; ?>" value="<?php echo $calendar_id; ?>"><?php echo $calendar_name; ?></option>
|
<option <?php if ($config_default_calendar == $calendar_id) { echo "selected"; } ?> data-content="<i class='fa fa-circle mr-2' style='color:<?php echo $calendar_color; ?>;'></i> <?php echo $calendar_name; ?>" value="<?php echo $calendar_id; ?>"><?php echo $calendar_name; ?></option>
|
||||||
<?php } ?>
|
<?php } ?>
|
||||||
|
|
||||||
</select>
|
</select>
|
||||||
|
<div class="input-group-append">
|
||||||
|
<button type="button" class="btn btn-dark" data-toggle="modal" data-target="#addQuickCalendarModal"><i class="fas fa-fw fa-plus"></i></button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<label>Start / End <strong class="text-danger">*</strong></label>
|
||||||
|
<div class="form-row">
|
||||||
|
<div class="col-md-6 mb-3">
|
||||||
|
<input type="datetime-local" class="form-control form-control-sm" id="event_add_start" name="start" required onblur="updateIncrementEndTime()">
|
||||||
|
</div>
|
||||||
|
<div class="col-md-6 mb-3">
|
||||||
|
<input type="datetime-local" class="form-control form-control-sm" id="event_add_end" name="end" required>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label>Start / End <strong class="text-danger">*</strong></label>
|
<label>Description</label>
|
||||||
<div class="input-group">
|
<textarea class="form-control" rows="4" name="description" placeholder="Enter a description"></textarea>
|
||||||
<div class="input-group-prepend">
|
|
||||||
<span class="input-group-text"><i class="fa fa-fw fa-calendar-check"></i></span>
|
|
||||||
</div>
|
|
||||||
<input type="datetime-local" class="form-control" id="event_add_start" name="start" required onblur="updateIncrementEndTime()">
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="form-group">
|
</div>
|
||||||
<div class="input-group">
|
|
||||||
<div class="input-group-prepend">
|
<div class="tab-pane fade" id="pills-more">
|
||||||
<span class="input-group-text"><i class="fa fa-fw fa-calendar"></i></span>
|
|
||||||
</div>
|
|
||||||
<input type="datetime-local" class="form-control" id="event_add_end" name="end" required>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label>Repeat</label>
|
<label>Repeat</label>
|
||||||
@@ -86,7 +89,7 @@
|
|||||||
<div class="input-group-prepend">
|
<div class="input-group-prepend">
|
||||||
<span class="input-group-text"><i class="fa fa-fw fa-recycle"></i></span>
|
<span class="input-group-text"><i class="fa fa-fw fa-recycle"></i></span>
|
||||||
</div>
|
</div>
|
||||||
<select class="form-control select2" name="repeat" disabled>
|
<select class="form-control select2" name="repeat">
|
||||||
<option value="">Never</option>
|
<option value="">Never</option>
|
||||||
<option>Day</option>
|
<option>Day</option>
|
||||||
<option>Week</option>
|
<option>Week</option>
|
||||||
@@ -98,24 +101,6 @@
|
|||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="tab-pane fade" id="pills-details">
|
|
||||||
|
|
||||||
<div class="form-group">
|
|
||||||
<label>Location</label>
|
|
||||||
<div class="input-group">
|
|
||||||
<div class="input-group-prepend">
|
|
||||||
<span class="input-group-text"><i class="fa fa-fw fa-map-marker-alt"></i></span>
|
|
||||||
</div>
|
|
||||||
<input type="text" class="form-control" name="location" placeholder="Location of the event">
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="form-group">
|
|
||||||
<textarea class="form-control" rows="8" name="description" placeholder="Enter a description"></textarea>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="tab-pane fade" id="pills-attendees">
|
<div class="tab-pane fade" id="pills-attendees">
|
||||||
|
|
||||||
<?php if (isset($client_id)) { ?>
|
<?php if (isset($client_id)) { ?>
|
||||||
@@ -132,11 +117,11 @@
|
|||||||
<option value="">- Client -</option>
|
<option value="">- Client -</option>
|
||||||
<?php
|
<?php
|
||||||
|
|
||||||
$sql = mysqli_query($mysqli, "SELECT * FROM clients LEFT JOIN contacts ON clients.client_id = contacts.contact_client_id AND contact_primary = 1 ORDER BY client_name ASC");
|
$sql = mysqli_query($mysqli, "SELECT * FROM clients LEFT JOIN contacts ON primary_contact = contact_id WHERE clients.company_id = $session_company_id ORDER BY client_name ASC");
|
||||||
while ($row = mysqli_fetch_array($sql)) {
|
while ($row = mysqli_fetch_array($sql)) {
|
||||||
$client_id = intval($row['client_id']);
|
$client_id = intval($row['client_id']);
|
||||||
$client_name = nullable_htmlentities($row['client_name']);
|
$client_name = htmlentities($row['client_name']);
|
||||||
$contact_email = nullable_htmlentities($row['contact_email']);
|
$contact_email = htmlentities($row['contact_email']);
|
||||||
?>
|
?>
|
||||||
<option value="<?php echo $client_id; ?>"><?php echo $client_name; ?></option>
|
<option value="<?php echo $client_id; ?>"><?php echo $client_name; ?></option>
|
||||||
|
|
||||||
@@ -18,7 +18,7 @@
|
|||||||
<a class="nav-link active" data-toggle="pill" href="#pills-event<?php echo $event_id; ?>"><i class="fa fa-fw fa-calendar mr-2"></i>Event</a>
|
<a class="nav-link active" data-toggle="pill" href="#pills-event<?php echo $event_id; ?>"><i class="fa fa-fw fa-calendar mr-2"></i>Event</a>
|
||||||
</li>
|
</li>
|
||||||
<li class="nav-item">
|
<li class="nav-item">
|
||||||
<a class="nav-link" data-toggle="pill" href="#pills-details<?php echo $event_id; ?>"><i class="fa fa-fw fa-info-circle mr-2"></i>Details</a>
|
<a class="nav-link" data-toggle="pill" href="#pills-more<?php echo $event_id; ?>"><i class="fa fa-fw fa-info-circle mr-2"></i>More</a>
|
||||||
</li>
|
</li>
|
||||||
<li class="nav-item">
|
<li class="nav-item">
|
||||||
<a class="nav-link" data-toggle="pill" href="#pills-attendees<?php echo $event_id; ?>"><i class="fa fa-fw fa-users mr-2"></i>Attendees</a>
|
<a class="nav-link" data-toggle="pill" href="#pills-attendees<?php echo $event_id; ?>"><i class="fa fa-fw fa-users mr-2"></i>Attendees</a>
|
||||||
@@ -37,7 +37,7 @@
|
|||||||
<div class="input-group-prepend">
|
<div class="input-group-prepend">
|
||||||
<span class="input-group-text"><i class="fa fa-fw fa-calendar-day"></i></span>
|
<span class="input-group-text"><i class="fa fa-fw fa-calendar-day"></i></span>
|
||||||
</div>
|
</div>
|
||||||
<input type="text" class="form-control" name="title" maxlength="200" value="<?php echo $event_title; ?>" placeholder="Title of the event" required>
|
<input type="text" class="form-control" name="title" value="<?php echo $event_title; ?>" placeholder="Title of the event" required>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@@ -50,11 +50,11 @@
|
|||||||
<select class="form-control select2" name="calendar" required>
|
<select class="form-control select2" name="calendar" required>
|
||||||
<?php
|
<?php
|
||||||
|
|
||||||
$sql_calendars_select = mysqli_query($mysqli, "SELECT * FROM calendars ORDER BY calendar_name ASC");
|
$sql_calendars_select = mysqli_query($mysqli, "SELECT * FROM calendars WHERE company_id = $session_company_id ORDER BY calendar_name ASC");
|
||||||
while ($row = mysqli_fetch_array($sql_calendars_select)) {
|
while ($row = mysqli_fetch_array($sql_calendars_select)) {
|
||||||
$calendar_id_select = intval($row['calendar_id']);
|
$calendar_id_select = intval($row['calendar_id']);
|
||||||
$calendar_name_select = nullable_htmlentities($row['calendar_name']);
|
$calendar_name_select = htmlentities($row['calendar_name']);
|
||||||
$calendar_color_select = nullable_htmlentities($row['calendar_color']);
|
$calendar_color_select = htmlentities($row['calendar_color']);
|
||||||
?>
|
?>
|
||||||
<option data-content="<i class='fa fa-circle mr-2' style='color:<?php echo $calendar_color_select; ?>;'></i> <?php echo $calendar_name_select; ?>"<?php if ($calendar_id == $calendar_id_select) { echo "selected"; } ?> value="<?php echo $calendar_id_select; ?>"><?php echo $calendar_name_select; ?></option>
|
<option data-content="<i class='fa fa-circle mr-2' style='color:<?php echo $calendar_color_select; ?>;'></i> <?php echo $calendar_name_select; ?>"<?php if ($calendar_id == $calendar_id_select) { echo "selected"; } ?> value="<?php echo $calendar_id_select; ?>"><?php echo $calendar_name_select; ?></option>
|
||||||
|
|
||||||
@@ -63,32 +63,32 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="form-group">
|
<label>Start / End <strong class="text-danger">*</strong></label>
|
||||||
<label>Start / End <strong class="text-danger">*</strong></label>
|
<div class="form-row">
|
||||||
<div class="input-group">
|
<div class="col-md-6 mb-3">
|
||||||
<div class="input-group-prepend">
|
<input type="datetime-local" class="form-control form-control-sm" name="start" value="<?php echo date('Y-m-d\TH:i:s', strtotime($event_start)); ?>" required>
|
||||||
<span class="input-group-text"><i class="fa fa-fw fa-calendar-check"></i></span>
|
</div>
|
||||||
</div>
|
<div class="col-md-6 mb-3">
|
||||||
<input type="datetime-local" class="form-control" name="start" value="<?php echo date('Y-m-d\TH:i:s', strtotime($event_start)); ?>" required>
|
<input type="datetime-local" class="form-control form-control-sm" name="end" value="<?php echo date('Y-m-d\TH:i:s', strtotime($event_end)); ?>"required>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<div class="input-group">
|
<label>Description</label>
|
||||||
<div class="input-group-prepend">
|
<textarea class="form-control" rows="4" name="description" placeholder="Enter a description"><?php echo $event_description; ?></textarea>
|
||||||
<span class="input-group-text"><i class="fa fa-fw fa-calendar-day"></i></span>
|
|
||||||
</div>
|
|
||||||
<input type="datetime-local" class="form-control" name="end" value="<?php echo date('Y-m-d\TH:i:s', strtotime($event_end)); ?>"required>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="tab-pane fade" id="pills-more<?php echo $event_id; ?>">
|
||||||
|
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label>Repeat</label>
|
<label>Repeat</label>
|
||||||
<div class="input-group">
|
<div class="input-group">
|
||||||
<div class="input-group-prepend">
|
<div class="input-group-prepend">
|
||||||
<span class="input-group-text"><i class="fa fa-fw fa-recycle"></i></span>
|
<span class="input-group-text"><i class="fa fa-fw fa-recycle"></i></span>
|
||||||
</div>
|
</div>
|
||||||
<select class="form-control select2" name="repeat" disabled>
|
<select class="form-control select2" name="repeat">
|
||||||
<option <?php if (empty($event_repeat)) { echo "selected"; } ?> value="">Never</option>
|
<option <?php if (empty($event_repeat)) { echo "selected"; } ?> value="">Never</option>
|
||||||
<option <?php if ($event_repeat == "Day") { echo "selected"; } ?>>Day</option>
|
<option <?php if ($event_repeat == "Day") { echo "selected"; } ?>>Day</option>
|
||||||
<option <?php if ($event_repeat == "Week") { echo "selected"; } ?>>Week</option>
|
<option <?php if ($event_repeat == "Week") { echo "selected"; } ?>>Week</option>
|
||||||
@@ -100,25 +100,6 @@
|
|||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="tab-pane fade" id="pills-details<?php echo $event_id; ?>">
|
|
||||||
<div class="form-group">
|
|
||||||
<label>Location</label>
|
|
||||||
<div class="input-group">
|
|
||||||
<div class="input-group-prepend">
|
|
||||||
<span class="input-group-text"><i class="fa fa-fw fa-map-marker-alt"></i></span>
|
|
||||||
</div>
|
|
||||||
<input type="text" class="form-control" name="location" value="<?php echo $event_location; ?>" placeholder="Location of the event">
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="form-group">
|
|
||||||
<label>Description</label>
|
|
||||||
<textarea class="form-control" rows="8" name="description" placeholder="Enter a description"><?php echo $event_description; ?></textarea>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="tab-pane fade" id="pills-attendees<?php echo $event_id; ?>">
|
<div class="tab-pane fade" id="pills-attendees<?php echo $event_id; ?>">
|
||||||
|
|
||||||
<?php if (isset($_GET['client_id'])) { ?>
|
<?php if (isset($_GET['client_id'])) { ?>
|
||||||
@@ -135,11 +116,11 @@
|
|||||||
<option value="">- Client -</option>
|
<option value="">- Client -</option>
|
||||||
<?php
|
<?php
|
||||||
|
|
||||||
$sql_clients = mysqli_query($mysqli, "SELECT * FROM clients LEFT JOIN contacts ON clients.client_id = contacts.contact_client_id AND contact_primary = 1 ORDER BY client_name ASC");
|
$sql_clients = mysqli_query($mysqli, "SELECT * FROM clients LEFT JOIN contacts ON primary_contact = contact_id WHERE clients.company_id = $session_company_id ORDER BY client_name ASC");
|
||||||
while ($row = mysqli_fetch_array($sql_clients)) {
|
while ($row = mysqli_fetch_array($sql_clients)) {
|
||||||
$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 = htmlentities($row['client_name']);
|
||||||
$contact_email_select = nullable_htmlentities($row['contact_email']);
|
$contact_email_select = htmlentities($row['contact_email']);
|
||||||
?>
|
?>
|
||||||
<option <?php if ($client_id == $client_id_select) { echo "selected"; } ?> value="<?php echo $client_id_select; ?>"><?php echo $client_name_select; ?></option>
|
<option <?php if ($client_id == $client_id_select) { echo "selected"; } ?> value="<?php echo $client_id_select; ?>"><?php echo $client_name_select; ?></option>
|
||||||
|
|
||||||
@@ -164,7 +145,7 @@
|
|||||||
|
|
||||||
</div>
|
</div>
|
||||||
<div class="modal-footer bg-white">
|
<div class="modal-footer bg-white">
|
||||||
<a class="btn btn-default text-danger mr-auto" href="post.php?delete_event=<?php echo $event_id; ?>"><i class="fa fa-calendar-times mr-2"></i>Delete</a>
|
<a class="btn text-danger mr-auto" href="post.php?delete_event=<?php echo $event_id; ?>"><i class="fa fa-calendar-times mr-2"></i>Delete</a>
|
||||||
<button type="submit" name="edit_event" class="btn btn-primary text-bold"><i class="fa fa-check mr-2"></i>Save</button>
|
<button type="submit" name="edit_event" class="btn btn-primary text-bold"><i class="fa fa-check mr-2"></i>Save</button>
|
||||||
<button type="button" class="btn btn-light" data-dismiss="modal"><i class="fa fa-times mr-2"></i>Cancel</button>
|
<button type="button" class="btn btn-light" data-dismiss="modal"><i class="fa fa-times mr-2"></i>Cancel</button>
|
||||||
</div>
|
</div>
|
||||||
@@ -1,105 +1,48 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
require_once "includes/inc_all.php";
|
require_once("inc_all.php");
|
||||||
|
|
||||||
|
|
||||||
if (isset($_GET['calendar_id'])) {
|
if (isset($_GET['calendar_id'])) {
|
||||||
$calendar_selected_id = intval($_GET['calendar_id']);
|
$calendar_selected_id = intval($_GET['calendar_id']);
|
||||||
}
|
}
|
||||||
|
|
||||||
?>
|
?>
|
||||||
|
<link href='plugins/fullcalendar/main.min.css' rel='stylesheet' />
|
||||||
|
|
||||||
<!-- So that when hovering over a created event it turns into a hand instead of cursor -->
|
<div id='calendar'></div>
|
||||||
<style>
|
|
||||||
.fc-event {
|
|
||||||
cursor: pointer;
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
|
|
||||||
<div class="row">
|
|
||||||
|
|
||||||
<div class="col-md-3">
|
|
||||||
<div class="card">
|
|
||||||
<div class="card-header py-2">
|
|
||||||
<h3 class="card-title mt-1">Calendars</h3>
|
|
||||||
<div class="card-tools">
|
|
||||||
<button type="button" class="btn btn-dark btn-sm" data-toggle="modal" data-target="#addCalendarModal"><i class="fas fa-plus"></i></button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="card-body">
|
|
||||||
|
|
||||||
<form>
|
|
||||||
<?php
|
|
||||||
$sql = mysqli_query($mysqli, "SELECT * FROM calendars");
|
|
||||||
while ($row = mysqli_fetch_array($sql)) {
|
|
||||||
$calendar_id = intval($row['calendar_id']);
|
|
||||||
$calendar_name = nullable_htmlentities($row['calendar_name']);
|
|
||||||
$calendar_color = nullable_htmlentities($row['calendar_color']);
|
|
||||||
?>
|
|
||||||
<div class="form-group">
|
|
||||||
<i class="fas fa-fw fa-circle mr-2" style="color:<?php echo $calendar_color; ?>;"></i><?php echo $calendar_name; ?>
|
|
||||||
<button type="button" class="btn btn-link btn-sm float-right" data-toggle="modal" data-target="#editCalendarModal<?php echo $calendar_id; ?>"><i class="fas fa-fw fa-pencil-alt text-secondary"></i></button>
|
|
||||||
</div>
|
|
||||||
<?php
|
|
||||||
require "modals/calendar_edit_modal.php";
|
|
||||||
}
|
|
||||||
?>
|
|
||||||
</form>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="card">
|
|
||||||
<div class="card-header py-2">
|
|
||||||
<h3 class="card-title mt-1">System Calendars</h3>
|
|
||||||
<div class="card-tools">
|
|
||||||
<button type="button" class="btn btn-dark btn-sm"><i class="fas fa-eye"></i></button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="card-body">
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="col-md-9">
|
|
||||||
<div class="card">
|
|
||||||
<div id='calendar'></div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<?php
|
<?php
|
||||||
|
|
||||||
require_once "modals/calendar_event_add_modal.php";
|
require_once("calendar_event_add_modal.php");
|
||||||
|
require_once("calendar_add_modal.php");
|
||||||
require_once "modals/calendar_add_modal.php";
|
require_once("category_quick_add_modal.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 events LEFT JOIN calendars ON event_calendar_id = calendar_id");
|
$sql = mysqli_query($mysqli, "SELECT * FROM events LEFT JOIN calendars ON event_calendar_id = calendar_id WHERE calendars.company_id = $session_company_id");
|
||||||
while ($row = mysqli_fetch_array($sql)) {
|
while ($row = mysqli_fetch_array($sql)) {
|
||||||
$event_id = intval($row['event_id']);
|
$event_id = $row['event_id'];
|
||||||
$event_title = nullable_htmlentities($row['event_title']);
|
$event_title = htmlentities($row['event_title']);
|
||||||
$event_description = nullable_htmlentities($row['event_description']);
|
$event_description = htmlentities($row['event_description']);
|
||||||
$event_location = nullable_htmlentities($row['event_location']);
|
$event_start = htmlentities($row['event_start']);
|
||||||
$event_start = nullable_htmlentities($row['event_start']);
|
$event_end = htmlentities($row['event_end']);
|
||||||
$event_end = nullable_htmlentities($row['event_end']);
|
$event_repeat = htmlentities($row['event_repeat']);
|
||||||
$event_repeat = nullable_htmlentities($row['event_repeat']);
|
$calendar_id = $row['calendar_id'];
|
||||||
$calendar_id = intval($row['calendar_id']);
|
$calendar_name = htmlentities($row['calendar_name']);
|
||||||
$calendar_name = nullable_htmlentities($row['calendar_name']);
|
$calendar_color = htmlentities($row['calendar_color']);
|
||||||
$calendar_color = nullable_htmlentities($row['calendar_color']);
|
$client_id = $row['event_client_id'];
|
||||||
$client_id = intval($row['event_client_id']);
|
|
||||||
|
require("calendar_event_edit_modal.php");
|
||||||
|
|
||||||
require "modals/calendar_event_edit_modal.php";
|
|
||||||
}
|
}
|
||||||
|
|
||||||
?>
|
?>
|
||||||
|
|
||||||
<?php require_once "includes/footer.php";
|
<?php require_once("footer.php"); ?>
|
||||||
?>
|
|
||||||
|
|
||||||
<script src='plugins/fullcalendar/dist/index.global.js'></script>
|
<script src='plugins/fullcalendar/main.min.js'></script>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
|
|
||||||
document.addEventListener('DOMContentLoaded', function() {
|
document.addEventListener('DOMContentLoaded', function() {
|
||||||
var calendarEl = document.getElementById('calendar');
|
var calendarEl = document.getElementById('calendar');
|
||||||
|
|
||||||
@@ -107,217 +50,107 @@ while ($row = mysqli_fetch_array($sql)) {
|
|||||||
themeSystem: 'bootstrap',
|
themeSystem: 'bootstrap',
|
||||||
defaultView: 'dayGridMonth',
|
defaultView: 'dayGridMonth',
|
||||||
customButtons: {
|
customButtons: {
|
||||||
newEvent: {
|
addEvent: {
|
||||||
text: 'New Event',
|
bootstrapFontAwesome: 'fa fa-plus',
|
||||||
bootstrapFontAwesome: 'fas fa-plus',
|
|
||||||
click: function() {
|
click: function() {
|
||||||
$("#addCalendarEventModal").modal();
|
$("#addCalendarEventModal").modal();
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
addCalendar: {
|
||||||
|
bootstrapFontAwesome: 'fa fa-calendar-plus',
|
||||||
|
click: function() {
|
||||||
|
$("#addCalendarModal").modal();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
headerToolbar: {
|
headerToolbar: {
|
||||||
left: 'prev,next today',
|
left: 'prev,next today',
|
||||||
center: 'title',
|
center: 'title',
|
||||||
right: 'dayGridMonth,timeGridWeek,timeGridDay,listMonth newEvent'
|
right: 'dayGridMonth,timeGridWeek,timeGridDay,listMonth addEvent addCalendar'
|
||||||
},
|
},
|
||||||
<?php if (!$session_mobile) {
|
events: [
|
||||||
?>aspectRatio: 2.5,
|
<?php
|
||||||
<?php } else { ?>
|
$sql = mysqli_query($mysqli, "SELECT * FROM events LEFT JOIN calendars ON event_calendar_id = calendar_id WHERE calendars.company_id = $session_company_id");
|
||||||
aspectRatio: 0.7,
|
while ($row = mysqli_fetch_array($sql)) {
|
||||||
<?php } ?>
|
$event_id = intval($row['event_id']);
|
||||||
navLinks: true, // can click day/week names to navigate views
|
$event_title = json_encode($row['event_title']);
|
||||||
selectable: true,
|
$event_start = json_encode($row['event_start']);
|
||||||
height: '90vh',
|
$event_end = json_encode($row['event_end']);
|
||||||
|
$calendar_id = intval($row['calendar_id']);
|
||||||
|
$calendar_name = json_encode($row['calendar_name']);
|
||||||
|
$calendar_color = json_encode($row['calendar_color']);
|
||||||
|
|
||||||
selectMirror: true,
|
echo "{ id: $event_id, title: $event_title, start: $event_start, end: $event_end, color: $calendar_color },";
|
||||||
eventClick: function(editEvent) {
|
|
||||||
$('#editEventModal' + editEvent.event.id).modal();
|
|
||||||
},
|
|
||||||
dayMaxEvents: true, // allow "more" link when too many events
|
|
||||||
views: {
|
|
||||||
timeGrid: {
|
|
||||||
dayMaxEventRows: 3, // adjust to 6 only for timeGridWeek/timeGridDay
|
|
||||||
expandRows: true,
|
|
||||||
nowIndicator: true,
|
|
||||||
eventMaxStack: 1,
|
|
||||||
},
|
|
||||||
dayGrid: {
|
|
||||||
dayMaxEvents: 3, // adjust to 6 only for timeGridWeek/timeGridDay
|
|
||||||
expandRows: true,
|
|
||||||
},
|
|
||||||
|
|
||||||
},
|
|
||||||
events: [
|
|
||||||
<?php
|
|
||||||
$sql = mysqli_query($mysqli, "SELECT * FROM events LEFT JOIN calendars ON event_calendar_id = calendar_id");
|
|
||||||
while ($row = mysqli_fetch_array($sql)) {
|
|
||||||
$event_id = intval($row['event_id']);
|
|
||||||
$event_title = json_encode($row['event_title']);
|
|
||||||
$event_start = json_encode($row['event_start']);
|
|
||||||
$event_end = json_encode($row['event_end']);
|
|
||||||
$calendar_id = intval($row['calendar_id']);
|
|
||||||
$calendar_name = json_encode($row['calendar_name']);
|
|
||||||
$calendar_color = json_encode($row['calendar_color']);
|
|
||||||
|
|
||||||
echo "{ id: $event_id, title: $event_title, start: $event_start, end: $event_end, color: $calendar_color },";
|
|
||||||
}
|
|
||||||
|
|
||||||
//Invoices Created
|
|
||||||
$sql = mysqli_query($mysqli, "SELECT * FROM clients LEFT JOIN invoices ON client_id = invoice_client_id");
|
|
||||||
while ($row = mysqli_fetch_array($sql)) {
|
|
||||||
$event_id = intval($row['invoice_id']);
|
|
||||||
$scope = strval($row['invoice_scope']);
|
|
||||||
if (empty($scope)) {
|
|
||||||
$scope = "Not Set";
|
|
||||||
}
|
|
||||||
$event_title = json_encode($row['invoice_prefix'] . $row['invoice_number'] . " created -scope: " . $scope);
|
|
||||||
$event_start = json_encode($row['invoice_date']);
|
|
||||||
|
|
||||||
|
|
||||||
echo "{ id: $event_id, title: $event_title, start: $event_start, display: 'list-item', color: 'blue', url: 'invoice.php?invoice_id=$event_id' },";
|
|
||||||
}
|
|
||||||
|
|
||||||
//Quotes Created
|
|
||||||
$sql = mysqli_query($mysqli, "SELECT * FROM clients LEFT JOIN quotes ON client_id = quote_client_id");
|
|
||||||
while ($row = mysqli_fetch_array($sql)) {
|
|
||||||
$event_id = intval($row['quote_id']);
|
|
||||||
$event_title = json_encode($row['quote_prefix'] . $row['quote_number'] . " " . $row['quote_scope']);
|
|
||||||
$event_start = json_encode($row['quote_date']);
|
|
||||||
|
|
||||||
echo "{ id: $event_id, title: $event_title, start: $event_start, display: 'list-item', color: 'purple', url: 'quote.php?quote_id=$event_id' },";
|
|
||||||
}
|
|
||||||
|
|
||||||
//Tickets Created
|
|
||||||
$sql = mysqli_query($mysqli, "SELECT * FROM clients
|
|
||||||
LEFT JOIN tickets ON client_id = ticket_client_id
|
|
||||||
LEFT JOIN ticket_statuses ON ticket_status = ticket_status_id
|
|
||||||
LEFT JOIN users ON ticket_assigned_to = user_id"
|
|
||||||
);
|
|
||||||
while ($row = mysqli_fetch_array($sql)) {
|
|
||||||
$event_id = intval($row['ticket_id']);
|
|
||||||
$ticket_status = intval($row['ticket_status']);
|
|
||||||
$ticket_status_name = strval($row['ticket_status_name']);
|
|
||||||
$username = $row['user_name'];
|
|
||||||
if (empty($username)) {
|
|
||||||
$username = "";
|
|
||||||
} else {
|
|
||||||
//Limit to characters and add ...
|
|
||||||
$username = "[". substr($row['user_name'], 0, 9) . "...]";
|
|
||||||
}
|
}
|
||||||
|
|
||||||
$event_title = json_encode($row['ticket_prefix'] . $row['ticket_number'] . " created - " . $row['ticket_subject'] . " " . $username . "{" . $ticket_status_name . "}");
|
//Invoices Created
|
||||||
$event_start = json_encode($row['ticket_created_at']);
|
$sql = mysqli_query($mysqli, "SELECT * FROM clients LEFT JOIN invoices ON client_id = invoice_client_id WHERE clients.company_id = $session_company_id");
|
||||||
|
while ($row = mysqli_fetch_array($sql)) {
|
||||||
|
$event_id = intval($row['invoice_id']);
|
||||||
|
$event_title = json_encode($row['invoice_prefix'] . $row['invoice_number'] . " " . $row['invoice_scope']);
|
||||||
|
$event_start = json_encode($row['invoice_date']);
|
||||||
|
|
||||||
if ($ticket_status == 1) {
|
echo "{ id: $event_id, title: $event_title, start: $event_start, color: 'blue', url: 'invoice.php?invoice_id=$event_id' },";
|
||||||
$event_color = "red";
|
|
||||||
} elseif ($ticket_status == 2) {
|
|
||||||
$event_color = "blue";
|
|
||||||
} elseif ($ticket_status == 3) {
|
|
||||||
$event_color = "grey";
|
|
||||||
} else {
|
|
||||||
$event_color = "black";
|
|
||||||
}
|
}
|
||||||
|
|
||||||
echo "{ id: $event_id, title: $event_title, start: $event_start, color: '$event_color', url: 'ticket.php?ticket_id=$event_id' },";
|
//Quotes Created
|
||||||
}
|
$sql = mysqli_query($mysqli, "SELECT * FROM clients LEFT JOIN quotes ON client_id = quote_client_id WHERE clients.company_id = $session_company_id");
|
||||||
|
while ($row = mysqli_fetch_array($sql)) {
|
||||||
|
$event_id = intval($row['quote_id']);
|
||||||
|
$event_title = json_encode($row['quote_prefix'] . $row['quote_number'] . " " . $row['quote_scope']);
|
||||||
|
$event_start = json_encode($row['quote_date']);
|
||||||
|
|
||||||
// Recurring Tickets
|
echo "{ id: $event_id, title: $event_title, start: $event_start, color: 'purple', url: 'quote.php?quote_id=$event_id' },";
|
||||||
$sql = mysqli_query($mysqli, "SELECT * FROM clients
|
|
||||||
LEFT JOIN scheduled_tickets ON client_id = scheduled_ticket_client_id
|
|
||||||
LEFT JOIN users ON scheduled_ticket_assigned_to = user_id"
|
|
||||||
);
|
|
||||||
while ($row = mysqli_fetch_array($sql)) {
|
|
||||||
$event_id = intval($row['scheduled_ticket_id']);
|
|
||||||
$client_id = intval($row['client_id']);
|
|
||||||
$username = $row['user_name'];
|
|
||||||
$frequency = $row['scheduled_ticket_frequency'];
|
|
||||||
if (empty($username)) {
|
|
||||||
$username = "";
|
|
||||||
} else {
|
|
||||||
//Limit to characters and add ...
|
|
||||||
$username = "[". substr($row['user_name'], 0, 9) . "...]";
|
|
||||||
}
|
}
|
||||||
|
|
||||||
$event_title = json_encode("R Ticket ($frequency) - " . $row['scheduled_ticket_subject'] . " " . $username);
|
//Tickets Created
|
||||||
$event_start = json_encode($row['scheduled_ticket_next_run']);
|
$sql = mysqli_query($mysqli, "SELECT * FROM clients LEFT JOIN tickets ON client_id = ticket_client_id WHERE clients.company_id = $session_company_id");
|
||||||
|
while ($row = mysqli_fetch_array($sql)) {
|
||||||
|
$event_id = intval($row['ticket_id']);
|
||||||
|
$event_title = json_encode($row['ticket_prefix'] . $row['ticket_number'] . " " . $row['ticket_subject']);
|
||||||
|
$event_start = json_encode($row['ticket_created_at']);
|
||||||
|
|
||||||
echo "{ id: $event_id, title: $event_title, start: $event_start, color: '$event_color', url: 'client_recurring_tickets.php?client_id=$client_id' },";
|
echo "{ id: $event_id, title: $event_title, start: $event_start, color: 'orange', url: 'ticket.php?ticket_id=$event_id' },";
|
||||||
}
|
|
||||||
|
|
||||||
//Tickets Scheduled
|
|
||||||
$sql = mysqli_query($mysqli, "SELECT * FROM clients
|
|
||||||
LEFT JOIN tickets ON client_id = ticket_client_id
|
|
||||||
LEFT JOIN ticket_statuses ON ticket_status = ticket_status_id
|
|
||||||
LEFT JOIN users ON ticket_assigned_to = user_id
|
|
||||||
WHERE ticket_schedule IS NOT NULL"
|
|
||||||
);
|
|
||||||
while ($row = mysqli_fetch_array($sql)) {
|
|
||||||
$event_id = intval($row['ticket_id']);
|
|
||||||
$username = $row['user_name'];
|
|
||||||
if (empty($username)) {
|
|
||||||
$username = "";
|
|
||||||
} else {
|
|
||||||
//Limit to characters and add ...
|
|
||||||
$username = substr($row['user_name'], 0, 9) . "...";
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (strtotime($row['ticket_schedule']) < time()) {
|
//Vendors Added Created
|
||||||
if (!empty($row['ticket_schedule'])) {
|
$sql = mysqli_query($mysqli, "SELECT * FROM clients LEFT JOIN vendors ON client_id = vendor_client_id WHERE vendor_template = 0 AND clients.company_id = $session_company_id");
|
||||||
$event_color = "red";
|
while ($row = mysqli_fetch_array($sql)) {
|
||||||
} else {
|
$event_id = intval($row['vendor_id']);
|
||||||
$event_color = "green";
|
$client_id = intval($row['client_id']);
|
||||||
}
|
$event_title = json_encode($row['vendor_name']);
|
||||||
} else {
|
$event_start = json_encode($row['vendor_created_at']);
|
||||||
$event_color = "grey";
|
|
||||||
|
echo "{ id: $event_id, title: $event_title, start: $event_start, color: 'brown', url: 'client_vendors.php?client_id=$client_id' },";
|
||||||
}
|
}
|
||||||
|
|
||||||
$ticket_status = strval($row['ticket_status_name']);
|
//Clients Added
|
||||||
$event_title = json_encode($row['ticket_prefix'] . $row['ticket_number'] . " scheduled - " . $row['ticket_subject'] . " [" . $username . "]{" . $ticket_status . "}");
|
$sql = mysqli_query($mysqli, "SELECT * FROM clients WHERE clients.company_id = $session_company_id");
|
||||||
$event_start = json_encode($row['ticket_schedule']);
|
while ($row = mysqli_fetch_array($sql)) {
|
||||||
|
$event_id = intval($row['client_id']);
|
||||||
|
$event_title = json_encode($row['client_name']);
|
||||||
|
$event_start = json_encode($row['client_created_at']);
|
||||||
|
|
||||||
|
echo "{ id: $event_id, title: $event_title, start: $event_start, color: 'green', url: 'client_overview.php?client_id=$event_id' },";
|
||||||
|
}
|
||||||
|
?>
|
||||||
|
|
||||||
|
|
||||||
echo "{ id: $event_id, title: $event_title, start: $event_start, color: '$event_color', url: 'ticket.php?ticket_id=$event_id' },";
|
],
|
||||||
|
eventClick: function(editEvent) {
|
||||||
|
$('#editEventModal'+editEvent.event.id).modal();
|
||||||
}
|
}
|
||||||
|
|
||||||
//Vendors Added Created
|
|
||||||
$sql = mysqli_query($mysqli, "SELECT * FROM clients LEFT JOIN vendors ON client_id = vendor_client_id WHERE vendor_template = 0");
|
|
||||||
while ($row = mysqli_fetch_array($sql)) {
|
|
||||||
$event_id = intval($row['vendor_id']);
|
|
||||||
$client_id = intval($row['client_id']);
|
|
||||||
$event_title = json_encode("Vendor : '" . $row['vendor_name'] . "' created");
|
|
||||||
$event_start = json_encode($row['vendor_created_at']);
|
|
||||||
|
|
||||||
echo "{ id: $event_id, title: $event_title, start: $event_start, color: 'brown', url: 'client_vendors.php?client_id=$client_id' },";
|
|
||||||
}
|
|
||||||
|
|
||||||
//Clients Added
|
|
||||||
$sql = mysqli_query($mysqli, "SELECT * FROM clients");
|
|
||||||
while ($row = mysqli_fetch_array($sql)) {
|
|
||||||
$event_id = intval($row['client_id']);
|
|
||||||
$event_title = json_encode("Client: '" . $row['client_name'] . "' created");
|
|
||||||
$event_start = json_encode($row['client_created_at']);
|
|
||||||
|
|
||||||
echo "{ id: $event_id, title: $event_title, start: $event_start, color: 'brown', url: 'client_overview.php?client_id=$event_id' },";
|
|
||||||
}
|
|
||||||
?>
|
|
||||||
],
|
|
||||||
eventOrder: 'allDay,start,-duration,title',
|
|
||||||
|
|
||||||
<?php
|
|
||||||
// User preference for Calendar start day (Sunday/Monday)
|
|
||||||
// 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"));
|
|
||||||
$user_config_calendar_first_day = intval($row['user_config_calendar_first_day']);
|
|
||||||
?>
|
|
||||||
firstDay: <?php echo $user_config_calendar_first_day ?>,
|
|
||||||
});
|
});
|
||||||
|
|
||||||
calendar.render();
|
calendar.render();
|
||||||
});
|
});
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<!-- Automatically set new event end date to 1 hr after start date -->
|
<!-- Automatically set new event end date to 1 hr after start date -->
|
||||||
<script>
|
<script>
|
||||||
|
|
||||||
// Function - called when user leaves field (onblur)
|
// Function - called when user leaves field (onblur)
|
||||||
function updateIncrementEndTime() {
|
function updateIncrementEndTime() {
|
||||||
|
|
||||||
@@ -327,19 +160,15 @@ while ($row = mysqli_fetch_array($sql)) {
|
|||||||
// Create a date object
|
// Create a date object
|
||||||
let new_end = new Date(start);
|
let new_end = new Date(start);
|
||||||
|
|
||||||
// Get the time zone offset in minutes, convert it to milliseconds
|
|
||||||
let offsetInMilliseconds = new_end.getTimezoneOffset() * 60 * 1000;
|
|
||||||
|
|
||||||
// Adjust the date by the time zone offset before adding an hour
|
|
||||||
new_end = new Date(new_end.getTime() - offsetInMilliseconds);
|
|
||||||
|
|
||||||
// Set the end date to 1 hr in the future
|
// Set the end date to 1 hr in the future
|
||||||
new_end.setHours(new_end.getHours() + 1);
|
new_end.setHours(new_end.getHours() + 1)
|
||||||
|
|
||||||
// Get the date back as a string, with the milliseconds trimmed off
|
// Get the date back as a string, with the milliseconds trimmed off
|
||||||
new_end = new_end.toISOString().replace(/.\d+Z$/g, "");
|
new_end = new_end.toISOString().replace(/.\d+Z$/g, "");
|
||||||
|
|
||||||
// Update the end date field
|
// Update the end date field
|
||||||
document.getElementById("event_add_end").value = new_end;
|
document.getElementById("event_add_end").value = new_end;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
138
categories.php
Normal file
138
categories.php
Normal file
@@ -0,0 +1,138 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
// Default Column Sortby Filter
|
||||||
|
$sb = "category_name";
|
||||||
|
$o = "ASC";
|
||||||
|
|
||||||
|
require_once("inc_all_settings.php");
|
||||||
|
|
||||||
|
if (isset($_GET['category'])) {
|
||||||
|
$category = sanitizeInput($_GET['category']);
|
||||||
|
} else {
|
||||||
|
$category = "Expense";
|
||||||
|
}
|
||||||
|
|
||||||
|
//Rebuild URL
|
||||||
|
$url_query_strings_sb = http_build_query(array_merge($_GET, array('sb' => $sb, 'o' => $o)));
|
||||||
|
|
||||||
|
$sql = mysqli_query(
|
||||||
|
$mysqli,
|
||||||
|
"SELECT SQL_CALC_FOUND_ROWS * FROM categories
|
||||||
|
WHERE category_name LIKE '%$q%'
|
||||||
|
AND category_type = '$category'
|
||||||
|
AND category_archived_at IS NULL
|
||||||
|
AND company_id = $session_company_id
|
||||||
|
ORDER BY $sb $o LIMIT $record_from, $record_to"
|
||||||
|
);
|
||||||
|
|
||||||
|
$num_rows = mysqli_fetch_row(mysqli_query($mysqli, "SELECT FOUND_ROWS()"));
|
||||||
|
|
||||||
|
$colors_used_array = [];
|
||||||
|
|
||||||
|
//Colors Used
|
||||||
|
$sql_colors_used = mysqli_query(
|
||||||
|
$mysqli,
|
||||||
|
"SELECT category_color FROM categories
|
||||||
|
WHERE category_type = '$category'
|
||||||
|
AND category_archived_at IS NULL
|
||||||
|
AND company_id = $session_company_id"
|
||||||
|
);
|
||||||
|
|
||||||
|
while ($color_used_row = mysqli_fetch_array($sql_colors_used)) {
|
||||||
|
$colors_used_array[] = $color_used_row['category_color'];
|
||||||
|
}
|
||||||
|
$colors_diff = array_diff($colors_array, $colors_used_array);
|
||||||
|
|
||||||
|
?>
|
||||||
|
|
||||||
|
|
||||||
|
<div class="card card-dark">
|
||||||
|
<div class="card-header py-2">
|
||||||
|
<h3 class="card-title mt-2"><i class="fa fa-fw fa-list mr-2"></i><?php echo htmlentities($category); ?> Categories</h3>
|
||||||
|
<div class="card-tools">
|
||||||
|
<button type="button" class="btn btn-primary" data-toggle="modal" data-target="#addCategoryModal"><i class="fas fa-plus mr-2"></i>New</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="card-body">
|
||||||
|
<form autocomplete="off">
|
||||||
|
<input type="hidden" name="category" value="<?php echo htmlentities($category); ?>">
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-sm-4 mb-2">
|
||||||
|
<div class="input-group">
|
||||||
|
<input type="search" class="form-control" name="q" value="<?php if (isset($q)) { echo stripslashes(htmlentities($q)); } ?>" placeholder="Search Categories">
|
||||||
|
<div class="input-group-append">
|
||||||
|
<button class="btn btn-primary"><i class="fa fa-search"></i></button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="col-sm-8">
|
||||||
|
<div class="btn-group float-right">
|
||||||
|
<a href="?category=Expense" class="btn <?php if ($category == 'Expense') { echo 'btn-primary'; } else { echo 'btn-default'; } ?>">Expense</a>
|
||||||
|
<a href="?category=Income" class="btn <?php if ($category == 'Income') { echo 'btn-primary'; } else { echo 'btn-default'; } ?>">Income</a>
|
||||||
|
<a href="?category=Referral" class="btn <?php if ($category == 'Referral') { echo 'btn-primary'; } else { echo 'btn-default'; } ?>">Referral</a>
|
||||||
|
<a href="?category=Payment Method" class="btn <?php if ($category == 'Payment Method') { echo 'btn-primary'; } else { echo 'btn-default'; } ?>">Payment Method</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
<hr>
|
||||||
|
<div class="table-responsive">
|
||||||
|
<table class="table table-striped table-borderless table-hover">
|
||||||
|
<thead class="text-dark <?php if ($num_rows[0] == 0) { echo "d-none"; } ?>">
|
||||||
|
<tr>
|
||||||
|
<th><a class="text-dark" href="?<?php echo $url_query_strings_sb; ?>&sb=category_name&o=<?php echo $disp; ?>">Name</a></th>
|
||||||
|
<th>Color</th>
|
||||||
|
<th class="text-center">Action</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
<?php
|
||||||
|
|
||||||
|
while ($row = mysqli_fetch_array($sql)) {
|
||||||
|
$category_id = intval($row['category_id']);
|
||||||
|
$category_name = htmlentities($row['category_name']);
|
||||||
|
$category_color = htmlentities($row['category_color']);
|
||||||
|
//$colors_used_array[] = $row['category_color'];
|
||||||
|
|
||||||
|
?>
|
||||||
|
<tr>
|
||||||
|
<td><a class="text-dark" href="#" data-toggle="modal" data-target="#editCategoryModal<?php echo $category_id; ?>"><?php echo $category_name; ?></a></td>
|
||||||
|
<td><i class="fa fa-3x fa-circle" style="color:<?php echo $category_color; ?>;"></i></td>
|
||||||
|
<td>
|
||||||
|
<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>
|
||||||
|
<div class="dropdown-menu">
|
||||||
|
<a class="dropdown-item" href="#" data-toggle="modal" data-target="#editCategoryModal<?php echo $category_id; ?>">
|
||||||
|
<i class="fas fa-fw fa-edit mr-2"></i>Edit
|
||||||
|
</a>
|
||||||
|
<div class="dropdown-divider"></div>
|
||||||
|
<a class="dropdown-item text-danger" href="post.php?archive_category=<?php echo $category_id; ?>">
|
||||||
|
<i class="fas fa-fw fa-archive mr-2"></i>Archive
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
|
||||||
|
<?php
|
||||||
|
|
||||||
|
//$colors_diff = array_diff($colors_array,$colors_used_array);
|
||||||
|
|
||||||
|
include("category_edit_modal.php");
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
?>
|
||||||
|
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
<?php require_once("pagination.php"); ?>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<?php
|
||||||
|
require_once("category_add_modal.php");
|
||||||
|
require_once("footer.php");
|
||||||
@@ -2,34 +2,38 @@
|
|||||||
<div class="modal-dialog">
|
<div class="modal-dialog">
|
||||||
<div class="modal-content bg-dark">
|
<div class="modal-content bg-dark">
|
||||||
<div class="modal-header">
|
<div class="modal-header">
|
||||||
<h5 class="modal-title"><i class="fa fa-fw fa-list-ul mr-2"></i>New <?php echo nullable_htmlentities($category); ?> Category</h5>
|
<h5 class="modal-title"><i class="fa fa-fw fa-list mr-2"></i>New <?php echo htmlentities($category); ?> Category</h5>
|
||||||
<button type="button" class="close text-white" data-dismiss="modal">
|
<button type="button" class="close text-white" data-dismiss="modal">
|
||||||
<span>×</span>
|
<span>×</span>
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
<form action="post.php" method="post" autocomplete="off">
|
<form action="post.php" method="post" autocomplete="off">
|
||||||
<input type="hidden" name="type" value="<?php echo nullable_htmlentities($category); ?>">
|
<input type="hidden" name="type" value="<?php echo htmlentities($category); ?>">
|
||||||
|
|
||||||
<div class="modal-body bg-white">
|
<div class="modal-body bg-white">
|
||||||
|
|
||||||
<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">
|
<input type="text" class="form-control" name="name" placeholder="Category name" required autofocus>
|
||||||
<div class="input-group-prepend">
|
|
||||||
<span class="input-group-text"><i class="fa fa-fw fa-list-ul"></i></span>
|
|
||||||
</div>
|
|
||||||
<input type="text" class="form-control" name="name" placeholder="Category name" maxlength="200" required autofocus>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="form-group">
|
<label>Color <strong class="text-danger">*</strong></label>
|
||||||
<label>Color <strong class="text-danger">*</strong></label>
|
<div class="form-row">
|
||||||
<div class="input-group">
|
|
||||||
<div class="input-group-prepend">
|
<?php
|
||||||
<span class="input-group-text"><i class="fa fa-fw fa-paint-brush"></i></span>
|
|
||||||
|
foreach ($colors_diff as $color) { ?>
|
||||||
|
|
||||||
|
<div class="col-3 mb-3">
|
||||||
|
<div class="form-check">
|
||||||
|
<input class="form-check-input" type="radio" name="color" value="<?php echo $color; ?>">
|
||||||
|
<label class="form-check-label">
|
||||||
|
<i class="fa fa-fw fa-3x fa-circle" style="color:<?php echo $color; ?>"></i>
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<input type="color" class="form-control col-3" name="color" required>
|
<?php } ?>
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
54
category_edit_modal.php
Normal file
54
category_edit_modal.php
Normal file
@@ -0,0 +1,54 @@
|
|||||||
|
<div class="modal" id="editCategoryModal<?php echo $category_id; ?>" tabindex="-1">
|
||||||
|
<div class="modal-dialog">
|
||||||
|
<div class="modal-content bg-dark">
|
||||||
|
<div class="modal-header">
|
||||||
|
<h5 class="modal-title"><i class="fa fa-fw fa-list mr-2"></i>Editing category: <strong><?php echo $category_name; ?></strong></h5>
|
||||||
|
<button type="button" class="close text-white" data-dismiss="modal">
|
||||||
|
<span>×</span>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
<form action="post.php" method="post" autocomplete="off">
|
||||||
|
<input type="hidden" name="category_id" value="<?php echo $category_id; ?>">
|
||||||
|
<input type="hidden" name="type" value="<?php echo htmlentities($category); ?>">
|
||||||
|
<div class="modal-body bg-white">
|
||||||
|
|
||||||
|
<div class="form-group">
|
||||||
|
<label>Name <strong class="text-danger">*</strong></label>
|
||||||
|
<input type="text" class="form-control" name="name" value="<?php echo $category_name; ?>" required>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<label>Color <strong class="text-danger">*</strong></label>
|
||||||
|
<div class="mb-3">
|
||||||
|
<div class="form-check">
|
||||||
|
<input class="form-check-input" type="radio" name="color" value="<?php echo $category_color; ?>" checked>
|
||||||
|
<label class="form-check-label">
|
||||||
|
<i class="fa fa-fw fa-4x fa-circle" style="color:<?php echo $category_color; ?>"></i>
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="form-row">
|
||||||
|
|
||||||
|
<?php
|
||||||
|
|
||||||
|
foreach($colors_diff as $color) { ?>
|
||||||
|
<div class="col-3 mb-3">
|
||||||
|
<div class="form-check">
|
||||||
|
<input class="form-check-input" type="radio" name="color" value="<?php echo $color; ?>">
|
||||||
|
<label class="form-check-label">
|
||||||
|
<i class="fa fa-fw fa-3x fa-circle" style="color:<?php echo $color; ?>"></i>
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<?php } ?>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
<div class="modal-footer bg-white">
|
||||||
|
<button type="submit" name="edit_category" class="btn btn-primary text-bold"><i class="fa fa-check mr-2"></i>Save</button>
|
||||||
|
<button type="button" class="btn btn-light" data-dismiss="modal"><i class="fa fa-times mr-2"></i>Cancel</button>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
96
category_quick_add_modal.php
Normal file
96
category_quick_add_modal.php
Normal file
@@ -0,0 +1,96 @@
|
|||||||
|
<div class="modal" id="addQuickCategoryExpenseModal" tabindex="-1">
|
||||||
|
<div class="modal-dialog modal-sm">
|
||||||
|
<div class="modal-content bg-light">
|
||||||
|
<div class="modal-body">
|
||||||
|
<form action="post.php" method="post" autocomplete="off">
|
||||||
|
<input type="hidden" name="type" value="Expense">
|
||||||
|
<input type="hidden" name="color" value="#000000">
|
||||||
|
<div class="input-group">
|
||||||
|
<input type="text" class="form-control" name="name" placeholder="Category name" required autofocus>
|
||||||
|
<div class="input-group-append">
|
||||||
|
<button type="button" class="btn btn-secondary" data-dismiss="modal"><i class="fa fa-fw fa-times"></i></button>
|
||||||
|
<button type="submit" name="add_category" class="btn btn-primary"><i class="fa fa-fw fa-check"></i></button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="modal" id="addQuickCategoryIncomeModal" tabindex="-1">
|
||||||
|
<div class="modal-dialog modal-sm">
|
||||||
|
<div class="modal-content bg-light">
|
||||||
|
<div class="modal-body">
|
||||||
|
<form action="post.php" method="post" autocomplete="off">
|
||||||
|
<input type="hidden" name="type" value="Income">
|
||||||
|
<input type="hidden" name="color" value="#000000">
|
||||||
|
<div class="input-group">
|
||||||
|
<input type="text" class="form-control" name="name" placeholder="Category name" required autofocus>
|
||||||
|
<div class="input-group-append">
|
||||||
|
<button type="button" class="btn btn-secondary" data-dismiss="modal"><i class="fa fa-fw fa-times"></i></button>
|
||||||
|
<button type="submit" name="add_category" class="btn btn-primary"><i class="fa fa-fw fa-check"></i></button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="modal" id="addQuickVendorModal" tabindex="-1">
|
||||||
|
<div class="modal-dialog modal-sm">
|
||||||
|
<div class="modal-content bg-light">
|
||||||
|
<div class="modal-body">
|
||||||
|
<form action="post.php" method="post" autocomplete="off">
|
||||||
|
<div class="input-group">
|
||||||
|
<input type="text" class="form-control" name="name" placeholder="Vendor name" required autofocus>
|
||||||
|
<div class="input-group-append">
|
||||||
|
<button type="button" class="btn btn-secondary" data-dismiss="modal"><i class="fa fa-fw fa-times"></i></button>
|
||||||
|
<button type="submit" name="add_vendor" class="btn btn-primary"><i class="fa fa-fw fa-check"></i></button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="modal" id="addQuickReferralModal" tabindex="-1">
|
||||||
|
<div class="modal-dialog modal-sm">
|
||||||
|
<div class="modal-content bg-light">
|
||||||
|
<div class="modal-body">
|
||||||
|
<form action="post.php" method="post" autocomplete="off">
|
||||||
|
<input type="hidden" name="type" value="Referral">
|
||||||
|
<input type="hidden" name="color" value="#000000">
|
||||||
|
<div class="input-group">
|
||||||
|
<input type="text" class="form-control" name="name" placeholder="Referral name" required autofocus>
|
||||||
|
<div class="input-group-append">
|
||||||
|
<button type="button" class="btn btn-secondary" data-dismiss="modal"><i class="fa fa-fw fa-times"></i></button>
|
||||||
|
<button type="submit" name="add_category" class="btn btn-primary"><i class="fa fa-fw fa-check"></i></button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="modal" id="addQuickCalendarModal" tabindex="-1">
|
||||||
|
<div class="modal-dialog modal-sm">
|
||||||
|
<div class="modal-content bg-light">
|
||||||
|
<div class="modal-body">
|
||||||
|
<form action="post.php" method="post" autocomplete="off">
|
||||||
|
<input type="hidden" name="color" value="#000000">
|
||||||
|
<div class="input-group">
|
||||||
|
<input type="text" class="form-control" name="name" placeholder="Calendar name" required autofocus>
|
||||||
|
<div class="input-group-append">
|
||||||
|
<button type="button" class="btn btn-secondary" data-dismiss="modal"><i class="fa fa-fw fa-times"></i></button>
|
||||||
|
<button type="submit" name="add_calendar" class="btn btn-primary"><i class="fa fa-fw fa-check"></i></button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user