Merge branch 'master' into stage
# Conflicts: # guest/guest_post.php
This commit is contained in:
108
admin/ai_model.php
Normal file
108
admin/ai_model.php
Normal file
@@ -0,0 +1,108 @@
|
||||
<?php
|
||||
|
||||
// Default Column Sortby Filter
|
||||
$sort = "ai_model_name";
|
||||
$order = "ASC";
|
||||
|
||||
require_once "includes/inc_all_admin.php";
|
||||
|
||||
$sql = mysqli_query($mysqli, "SELECT * FROM ai_models LEFT JOIN ai_providers ON ai_model_ai_provider_id = ai_provider_id ORDER BY $sort $order");
|
||||
|
||||
$num_rows = mysqli_num_rows($sql);
|
||||
|
||||
?>
|
||||
|
||||
<div class="card card-dark">
|
||||
<div class="card-header py-2">
|
||||
<h3 class="card-title mt-2"><i class="fas fa-fw fa-robot mr-2"></i>AI Models</h3>
|
||||
<div class="card-tools">
|
||||
<button type="button" class="btn btn-primary" data-toggle="modal" data-target="#addAIModelModal"><i class="fas fa-plus mr-2"></i>Add Model</button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<div class="table-responsive-sm">
|
||||
<table class="table table-striped table-borderless table-hover">
|
||||
<thead class="text-dark <?php if ($num_rows == 0) { echo "d-none"; } ?>">
|
||||
<tr>
|
||||
<th>
|
||||
<a class="text-dark" href="?<?php echo $url_query_strings_sort; ?>&sort=ai_model_name&order=<?php echo $disp; ?>">
|
||||
Model <?php if ($sort == 'ai_model_name') { echo $order_icon; } ?>
|
||||
</a>
|
||||
</th>
|
||||
<th>
|
||||
<a class="text-dark" href="?<?php echo $url_query_strings_sort; ?>&sort=ai_provider_name&order=<?php echo $disp; ?>">
|
||||
Provider <?php if ($sort == 'ai_provider_name') { echo $order_icon; } ?>
|
||||
</a>
|
||||
</th>
|
||||
<th>
|
||||
<a class="text-dark" href="?<?php echo $url_query_strings_sort; ?>&sort=ai_model_use_case&order=<?php echo $disp; ?>">
|
||||
Use Case<?php if ($sort == 'ai_model_use_case') { echo $order_icon; } ?>
|
||||
</a>
|
||||
</th>
|
||||
<th>
|
||||
<a class="text-dark">Prompt</a>
|
||||
</th>
|
||||
<th class="text-center">Action</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<?php
|
||||
|
||||
while ($row = mysqli_fetch_array($sql)) {
|
||||
$provider_id = intval($row['ai_provider_id']);
|
||||
$provider_name = nullable_htmlentities($row['ai_provider_name']);
|
||||
$model_id = intval($row['ai_model_id']);
|
||||
$model_name = nullable_htmlentities($row['ai_model_name']);
|
||||
$use_case = nullable_htmlentities($row['ai_model_use_case']);
|
||||
$prompt = nl2br(nullable_htmlentities($row['ai_model_prompt']));
|
||||
|
||||
?>
|
||||
<tr>
|
||||
<td>
|
||||
<a class="text-dark text-bold ajax-modal" href="#"
|
||||
data-modal-url="modals/ai/ai_model_edit.php?id=<?= $model_id ?>">
|
||||
<?php echo $model_name; ?>
|
||||
</a>
|
||||
</td>
|
||||
<td><?php echo $provider_name; ?></td>
|
||||
<td><?php echo $use_case; ?></td>
|
||||
<td><?php echo $prompt; ?></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 ajax-modal" href="#"
|
||||
data-modal-url="modals/ai/ai_model_edit.php?id=<?= $model_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_ai_model=<?php echo $model_id; ?>&csrf_token=<?php echo $_SESSION['csrf_token'] ?>">
|
||||
<i class="fas fa-fw fa-trash mr-2"></i>Delete
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<?php
|
||||
|
||||
}
|
||||
|
||||
if ($num_rows == 0) {
|
||||
echo "<h3 class='text-secondary mt-3' style='text-align: center'>No Records Here</h3>";
|
||||
}
|
||||
|
||||
?>
|
||||
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<?php
|
||||
require_once "modals/ai/ai_model_add.php";
|
||||
require_once "../includes/footer.php";
|
||||
109
admin/ai_provider.php
Normal file
109
admin/ai_provider.php
Normal file
@@ -0,0 +1,109 @@
|
||||
<?php
|
||||
|
||||
// Default Column Sortby Filter
|
||||
$sort = "ai_provider_name";
|
||||
$order = "ASC";
|
||||
|
||||
require_once "includes/inc_all_admin.php";
|
||||
|
||||
$sql = mysqli_query($mysqli, "SELECT * FROM ai_providers ORDER BY $sort $order");
|
||||
|
||||
$num_rows = mysqli_num_rows($sql);
|
||||
|
||||
?>
|
||||
|
||||
<div class="card card-dark">
|
||||
<div class="card-header py-2">
|
||||
<h3 class="card-title mt-2"><i class="fas fa-fw fa-robot mr-2"></i>AI Providers</h3>
|
||||
<div class="card-tools">
|
||||
<button type="button" class="btn btn-primary" data-toggle="modal" data-target="#addAIProviderModal"><i class="fas fa-plus mr-2"></i>Add Provider</button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<div class="table-responsive-sm">
|
||||
<table class="table table-striped table-borderless table-hover">
|
||||
<thead class="text-dark <?php if ($num_rows == 0) { echo "d-none"; } ?>">
|
||||
<tr>
|
||||
<th>
|
||||
<a class="text-dark" href="?<?php echo $url_query_strings_sort; ?>&sort=ai_provider_name&order=<?php echo $disp; ?>">
|
||||
Provider <?php if ($sort == 'ai_provider_name') { echo $order_icon; } ?>
|
||||
</a>
|
||||
</th>
|
||||
<th>
|
||||
<a class="text-dark" href="?<?php echo $url_query_strings_sort; ?>&sort=ai_provider_api_url&order=<?php echo $disp; ?>">
|
||||
URL <?php if ($sort == 'ai_provider_api_url') { echo $order_icon; } ?>
|
||||
</a>
|
||||
</th>
|
||||
<th>
|
||||
<a class="text-dark" href="?<?php echo $url_query_strings_sort; ?>&sort=ai_provider_api_key&order=<?php echo $disp; ?>">
|
||||
Key <?php if ($sort == 'ai_provider_api_key') { echo $order_icon; } ?>
|
||||
</a>
|
||||
</th>
|
||||
<th>
|
||||
<a class="text-dark">Models</a>
|
||||
</th>
|
||||
<th class="text-center">Action</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<?php
|
||||
|
||||
while ($row = mysqli_fetch_array($sql)) {
|
||||
$provider_id = intval($row['ai_provider_id']);
|
||||
$provider_name = nullable_htmlentities($row['ai_provider_name']);
|
||||
$url = nullable_htmlentities($row['ai_provider_api_url']);
|
||||
$key = nullable_htmlentities($row['ai_provider_api_key']);
|
||||
|
||||
$row = mysqli_fetch_assoc(mysqli_query($mysqli, "SELECT COUNT('ai_model_id') AS ai_model_count FROM ai_models WHERE ai_model_ai_provider_id = $provider_id"));
|
||||
$ai_model_count = intval($row['ai_model_count']);
|
||||
|
||||
?>
|
||||
<tr>
|
||||
<td>
|
||||
<a class="text-dark text-bold ajax-modal" href="#"
|
||||
data-modal-url="modals/ai/ai_provider_edit.php?id=<?= $provider_id ?>">
|
||||
<?php echo $provider_name; ?>
|
||||
</a>
|
||||
</td>
|
||||
<td><?php echo $url; ?></td>
|
||||
<td><?php echo $key; ?></td>
|
||||
<td><?php echo $ai_model_count; ?></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 ajax-modal" href="#"
|
||||
data-modal-url="modals/ai/ai_provider_edit.php?id=<?= $provider_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_ai_provider=<?php echo $provider_id; ?>&csrf_token=<?php echo $_SESSION['csrf_token'] ?>">
|
||||
<i class="fas fa-fw fa-trash mr-2"></i>Delete
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<?php
|
||||
|
||||
}
|
||||
|
||||
if ($num_rows == 0) {
|
||||
echo "<h3 class='text-secondary mt-3' style='text-align: center'>No Records Here</h3>";
|
||||
}
|
||||
|
||||
?>
|
||||
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<?php
|
||||
require_once "modals/ai/ai_provider_add.php";
|
||||
require_once "../includes/footer.php";
|
||||
176
admin/api_keys.php
Normal file
176
admin/api_keys.php
Normal file
@@ -0,0 +1,176 @@
|
||||
<?php
|
||||
|
||||
// Default Column Sortby Filter
|
||||
$sort = "api_key_name";
|
||||
$order = "ASC";
|
||||
|
||||
require_once "includes/inc_all_admin.php";
|
||||
|
||||
$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/api/api_key_add.php";
|
||||
|
||||
require_once "../includes/footer.php";
|
||||
|
||||
192
admin/app_log.php
Normal file
192
admin/app_log.php
Normal file
@@ -0,0 +1,192 @@
|
||||
<?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 = '';
|
||||
}
|
||||
|
||||
$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 autocomplete="off">
|
||||
<div class="row">
|
||||
<div class="col-sm-4">
|
||||
<div class="form-group">
|
||||
<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>
|
||||
|
||||
<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";
|
||||
302
admin/audit_log.php
Normal file
302
admin/audit_log.php
Normal file
@@ -0,0 +1,302 @@
|
||||
<?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 = '';
|
||||
}
|
||||
|
||||
$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 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 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="input-group mb-3 mb-md-0">
|
||||
<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="input-group mb-3 mb-md-0">
|
||||
<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="input-group mb-3 mb-md-0">
|
||||
<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="input-group mb-3 mb-md-0">
|
||||
<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"; } ?> text-nowrap">
|
||||
<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='../agent/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";
|
||||
|
||||
38
admin/backup.php
Normal file
38
admin/backup.php
Normal file
@@ -0,0 +1,38 @@
|
||||
<?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_backup&csrf_token=<?php echo $_SESSION['csrf_token'] ?>"><i class="fas fa-fw fa-4x fa-download"></i><br><br>Download Backup</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="d-flex justify-content-center">
|
||||
<div class="input-group col-sm-4">
|
||||
<input type="password" class="form-control" placeholder="Enter your account password" name="password" autocomplete="new-password" required>
|
||||
<div class="input-group-append">
|
||||
<button class="btn btn-primary" type="submit" name="backup_master_key"><i class="fas fa-key"></i></button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<?php
|
||||
require_once "../includes/footer.php";
|
||||
|
||||
179
admin/category.php
Normal file
179
admin/category.php
Normal file
@@ -0,0 +1,179 @@
|
||||
<?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";
|
||||
}
|
||||
|
||||
$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()"));
|
||||
|
||||
?>
|
||||
|
||||
<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 ajax-modal" data-modal-url="modals/category/category_add.php?category=<?= nullable_htmlentities($category) ?>"><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=Ticket"
|
||||
class="btn <?php if ($category == 'Ticket') {
|
||||
echo 'btn-primary';
|
||||
} else {
|
||||
echo 'btn-default';
|
||||
} ?>">Ticket</a>
|
||||
<a href="?<?php echo $url_query_strings_sort ?>&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 ajax-modal" href="#"
|
||||
data-modal-url="modals/category/category_edit.php?id=<?= $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 ($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 ajax-modal" href="#"
|
||||
data-modal-url="modals/category/category_edit.php?id=<?= $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
|
||||
|
||||
}
|
||||
|
||||
?>
|
||||
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<?php require_once "../includes/filter_footer.php";
|
||||
?>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<?php
|
||||
require_once "../includes/footer.php";
|
||||
8
admin/custom/readme.php
Normal file
8
admin/custom/readme.php
Normal file
@@ -0,0 +1,8 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
|
||||
- Custom Pages -
|
||||
If you wish to add custom pages to ITFlow, add them to this directory"
|
||||
Link to Documentation for File Directory Structure and examples
|
||||
*/
|
||||
149
admin/custom_link.php
Normal file
149
admin/custom_link.php
Normal file
@@ -0,0 +1,149 @@
|
||||
<?php
|
||||
|
||||
// Default Column Sortby Filter
|
||||
$sort = "custom_link_name";
|
||||
$order = "ASC";
|
||||
|
||||
require_once "includes/inc_all_admin.php";
|
||||
|
||||
$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";
|
||||
} elseif ($custom_link_location == 2) {
|
||||
$custom_link_location_display = "Top Nav";
|
||||
} elseif ($custom_link_location == 3) {
|
||||
$custom_link_location_display = "Client Portal Nav";
|
||||
} elseif ($custom_link_location == 4) {
|
||||
$custom_link_location_display = "Admin Nav";
|
||||
} elseif ($custom_link_location == 5) {
|
||||
$custom_link_location_display = "Reports Nav";
|
||||
}
|
||||
|
||||
?>
|
||||
<tr>
|
||||
<td>
|
||||
<a class="ajax-modal" href="#"
|
||||
data-modal-url="modals/custom_link/custom_link_edit.php?id=<?= $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 ajax-modal" href="#" data-modal-url="modals/custom_link/custom_link_edit.php?id=<?= $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
|
||||
}
|
||||
|
||||
?>
|
||||
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<?php require_once "../includes/filter_footer.php";
|
||||
?>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<?php
|
||||
require_once "modals/custom_link/custom_link_add.php";
|
||||
require_once "../includes/footer.php";
|
||||
4044
admin/database_updates.php
Normal file
4044
admin/database_updates.php
Normal file
File diff suppressed because it is too large
Load Diff
770
admin/debug.php
Normal file
770
admin/debug.php
Normal file
@@ -0,0 +1,770 @@
|
||||
<?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',
|
||||
'php-zip' => 'zip',
|
||||
];
|
||||
|
||||
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'];
|
||||
|
||||
// Accurate row count
|
||||
$countResult = $mysqli->query("SELECT COUNT(*) AS cnt FROM `$tableName`");
|
||||
$countRow = $countResult->fetch_assoc();
|
||||
$tableRows = $countRow['cnt'];
|
||||
$countResult->free();
|
||||
|
||||
$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',
|
||||
];
|
||||
}
|
||||
|
||||
// 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>
|
||||
|
||||
<div class="table-responsive">
|
||||
<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>
|
||||
</div>
|
||||
|
||||
<!-- 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>
|
||||
<div class="table-responsive">
|
||||
<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>
|
||||
</div>
|
||||
|
||||
|
||||
<!-- Database Structure Comparison Table -->
|
||||
<h3 class="mt-3">Database Structure Comparison</h3>
|
||||
<div class="table-responsive">
|
||||
<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>
|
||||
</div>
|
||||
|
||||
<!-- Uploads Directory Stats Table -->
|
||||
<h3 class="mt-3">Uploads Directory Stats</h3>
|
||||
<div class="table-responsive">
|
||||
<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>
|
||||
</div>
|
||||
|
||||
<!-- Database Stats Table -->
|
||||
<h3 class="mt-3">Database Stats</h3>
|
||||
<div class="table-responsive">
|
||||
<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>
|
||||
</div>
|
||||
|
||||
<!-- Table Stats Table -->
|
||||
<h3 class="mt-3">Table Stats</h3>
|
||||
<div class="table-responsive">
|
||||
<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>
|
||||
|
||||
</div>
|
||||
|
||||
<?php
|
||||
|
||||
require_once "../includes/footer.php";
|
||||
|
||||
158
admin/document_template.php
Normal file
158
admin/document_template.php
Normal file
@@ -0,0 +1,158 @@
|
||||
<?php
|
||||
|
||||
// Default Column Sort by Filter
|
||||
$sort = "document_template_name";
|
||||
$order = "ASC";
|
||||
|
||||
require_once "includes/inc_all_admin.php";
|
||||
|
||||
$sql = mysqli_query(
|
||||
$mysqli,
|
||||
"SELECT SQL_CALC_FOUND_ROWS * FROM document_templates
|
||||
LEFT JOIN users ON document_template_created_by = user_id
|
||||
WHERE user_name LIKE '%$q%' OR document_template_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="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_template_name&order=<?php echo $disp; ?>">
|
||||
Template Name <?php if ($sort == 'document_template_name') { echo $order_icon; } ?>
|
||||
</a>
|
||||
</th>
|
||||
<th>
|
||||
<a class="text-secondary" href="?<?php echo $url_query_strings_sort; ?>&sort=document_template_created_at&order=<?php echo $disp; ?>">
|
||||
Created <?php if ($sort == 'document_template_created_at') { echo $order_icon; } ?>
|
||||
</a>
|
||||
</th>
|
||||
<th>
|
||||
<a class="text-secondary" href="?<?php echo $url_query_strings_sort; ?>&sort=document_template_updated_at&order=<?php echo $disp; ?>">
|
||||
Updated <?php if ($sort == 'document_template_updated_at') { echo $order_icon; } ?>
|
||||
</a>
|
||||
</th>
|
||||
<th class="text-center">
|
||||
Action
|
||||
</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<?php
|
||||
|
||||
while ($row = mysqli_fetch_array($sql)) {
|
||||
$document_template_id = intval($row['document_template_id']);
|
||||
$document_template_name = nullable_htmlentities($row['document_template_name']);
|
||||
$document_template_description = nullable_htmlentities($row['document_template_description']);
|
||||
$document_template_content = nullable_htmlentities($row['document_template_content']);
|
||||
$document_template_created_by_name = nullable_htmlentities($row['user_name']);
|
||||
$document_template_created_at = nullable_htmlentities($row['document_template_created_at']);
|
||||
$document_template_updated_at = nullable_htmlentities($row['document_template_updated_at']);
|
||||
|
||||
?>
|
||||
|
||||
<tr>
|
||||
<td>
|
||||
<a class="text-bold" href="document_template_details.php?document_template_id=<?php echo $document_template_id; ?>"><i class="fas fa-fw fa-file-alt text-dark"></i> <?php echo $document_template_name; ?></a>
|
||||
<div class="mt-1 text-secondary"><?php echo $document_template_description; ?></div>
|
||||
</td>
|
||||
<td>
|
||||
<?php echo $document_template_created_at; ?>
|
||||
<div class="text-secondary"><?php echo $document_template_created_by_name; ?></div>
|
||||
</td>
|
||||
<td><?php echo $document_template_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 ajax-modal" href="#"
|
||||
data-modal-size="xl"
|
||||
data-modal-url="modals/document_template/document_template_edit.php?id=<?= $document_template_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_template=<?php echo $document_template_id; ?>">
|
||||
<i class="fas fa-fw fa-trash mr-2"></i>Delete
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<?php
|
||||
|
||||
}
|
||||
|
||||
?>
|
||||
|
||||
</tbody>
|
||||
</table>
|
||||
<br>
|
||||
</div>
|
||||
<?php require_once "../includes/filter_footer.php"; ?>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<?php require_once "modals/document_template/document_template_add.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>
|
||||
64
admin/document_template_details.php
Normal file
64
admin/document_template_details.php
Normal file
@@ -0,0 +1,64 @@
|
||||
<?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_template_id'])) {
|
||||
$document_template_id = intval($_GET['document_template_id']);
|
||||
}
|
||||
|
||||
$sql_document = mysqli_query($mysqli, "SELECT * FROM document_templates WHERE document_template_id = $document_template_id");
|
||||
|
||||
$row = mysqli_fetch_array($sql_document);
|
||||
|
||||
$document_template_name = nullable_htmlentities($row['document_template_name']);
|
||||
$document_template_description = nullable_htmlentities($row['document_template_description']);
|
||||
$document_template_content = $purifier->purify($row['document_template_content']);
|
||||
$document_template_created_at = nullable_htmlentities($row['document_template_created_at']);
|
||||
$document_template_updated_at = nullable_htmlentities($row['document_template_updated_at']);
|
||||
|
||||
?>
|
||||
|
||||
<ol class="breadcrumb d-print-none">
|
||||
<li class="breadcrumb-item">
|
||||
<a href="../">Home</a>
|
||||
</li>
|
||||
<li class="breadcrumb-item">
|
||||
<a href="users.php">Admin</a>
|
||||
</li>
|
||||
<li class="breadcrumb-item">
|
||||
<a href="document_template.php">Document Templates</a>
|
||||
</li>
|
||||
<li class="breadcrumb-item active"><i class="fas fa-file mr-2"></i><?php echo $document_template_name; ?></li>
|
||||
</ol>
|
||||
|
||||
<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><?php echo $document_template_name; ?></h3>
|
||||
|
||||
<div class="card-tools">
|
||||
<button type="button" class="btn btn-primary ajax-modal"
|
||||
data-modal-size="xl"
|
||||
data-modal-url="modals/document_template/document_template_edit.php?id=<?= $document_template_id ?>">
|
||||
<i class="fas fa-edit mr-2"></i>Edit
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="card-body prettyContent">
|
||||
<?php echo $document_template_content; ?>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script src="../js/pretty_content.js"></script>
|
||||
|
||||
<?php
|
||||
require_once "../includes/footer.php";
|
||||
58
admin/identity_provider.php
Normal file
58
admin/identity_provider.php
Normal file
@@ -0,0 +1,58 @@
|
||||
<?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-fingerprint mr-2"></i>Identity Providers</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>Identity Provider <small class='text-secondary'>(Currently only works with Microsoft Entra ID/AAD)</small></label>
|
||||
<div class="input-group">
|
||||
<div class="input-group-prepend">
|
||||
<span class="input-group-text"><i class="fa fa-fw fa-fingerprint"></i></span>
|
||||
</div>
|
||||
<select class="form-control select2" readonly>
|
||||
<option <?php if (empty($config_azure_client_id)) { echo "selected"; } ?>>Disabled</option>
|
||||
<option <?php if ($config_azure_client_id) { echo "selected"; } ?>>Microsoft Entra</option>
|
||||
<option>Google (WIP)</option>
|
||||
<option>Custom SSO (WIP)</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<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_identity_provider" 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";
|
||||
16
admin/includes/inc_all_admin.php
Normal file
16
admin/includes/inc_all_admin.php
Normal file
@@ -0,0 +1,16 @@
|
||||
<?php
|
||||
|
||||
require_once $_SERVER['DOCUMENT_ROOT'] . '/config.php';
|
||||
require_once $_SERVER['DOCUMENT_ROOT'] . '/functions.php';
|
||||
require_once $_SERVER['DOCUMENT_ROOT'] . '/includes/check_login.php';
|
||||
require_once $_SERVER['DOCUMENT_ROOT'] . '/includes/page_title.php';
|
||||
if (!isset($session_is_admin) || !$session_is_admin) {
|
||||
exit(WORDING_ROLECHECK_FAILED . "<br>Tell your admin: Your role does not have admin access.");
|
||||
}
|
||||
require_once $_SERVER['DOCUMENT_ROOT'] . '/includes/header.php';
|
||||
require_once $_SERVER['DOCUMENT_ROOT'] . '/includes/top_nav.php';
|
||||
require_once 'includes/side_nav.php';
|
||||
require_once $_SERVER['DOCUMENT_ROOT'] . '/includes/inc_wrapper.php';
|
||||
require_once $_SERVER['DOCUMENT_ROOT'] . '/includes/inc_alert_feedback.php';
|
||||
require_once $_SERVER['DOCUMENT_ROOT'] . '/includes/filter_header.php';
|
||||
require_once $_SERVER['DOCUMENT_ROOT'] . '/includes/app_version.php';
|
||||
316
admin/includes/side_nav.php
Normal file
316
admin/includes/side_nav.php
Normal file
@@ -0,0 +1,316 @@
|
||||
<!-- Main Sidebar Container -->
|
||||
<aside class="main-sidebar sidebar-dark-<?php echo nullable_htmlentities($config_theme); ?> d-print-none">
|
||||
<a class="brand-link pb-1 mt-1" href="/agent/<?php echo $config_start_page ?>">
|
||||
<p class="h6">
|
||||
<i class="nav-icon fas fa-arrow-left ml-3 mr-2"></i>
|
||||
<span class="brand-text">
|
||||
Back | <strong>Administration</strong>
|
||||
</span>
|
||||
</p>
|
||||
</a>
|
||||
|
||||
<!-- Sidebar -->
|
||||
<div class="sidebar">
|
||||
<!-- Sidebar Menu -->
|
||||
<nav>
|
||||
<ul class="nav nav-pills nav-sidebar flex-column mt-2" data-widget="treeview" data-accordion="false">
|
||||
<!-- ACCESS Section -->
|
||||
<li class="nav-item">
|
||||
<a href="users.php" class="nav-link <?php if (basename($_SERVER["PHP_SELF"]) == "users.php") {echo "active";} ?>">
|
||||
<i class="nav-icon fas fa-users"></i>
|
||||
<p>Users</p>
|
||||
</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a href="roles.php" class="nav-link <?php if (basename($_SERVER["PHP_SELF"]) == "roles.php") {echo "active";} ?>">
|
||||
<i class="nav-icon fas fa-user-shield"></i>
|
||||
<p>Roles</p>
|
||||
</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a href="api_keys.php" class="nav-link <?php if (basename($_SERVER["PHP_SELF"]) == "api_keys.php") {echo "active";} ?>">
|
||||
<i class="nav-icon fas fa-key"></i>
|
||||
<p>API Keys</p>
|
||||
</a>
|
||||
</li>
|
||||
<li class="nav-header">TAGS & CATEGORIES</li>
|
||||
|
||||
<li class="nav-item">
|
||||
<a href="tag.php" class="nav-link <?php echo (basename($_SERVER['PHP_SELF']) == 'tag.php' ? 'active' : ''); ?>">
|
||||
<i class="nav-icon fas fa-tags"></i>
|
||||
<p>Tags</p>
|
||||
</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a href="category.php" class="nav-link <?php echo (basename($_SERVER['PHP_SELF']) == 'category.php' ? 'active' : ''); ?>">
|
||||
<i class="nav-icon fas fa-list-ul"></i>
|
||||
<p>Categories</p>
|
||||
</a>
|
||||
</li>
|
||||
<?php if ($config_module_enable_accounting) { ?>
|
||||
<li class="nav-item">
|
||||
<a href="tax.php" class="nav-link <?php echo (basename($_SERVER['PHP_SELF']) == 'tax.php' ? 'active' : ''); ?>">
|
||||
<i class="nav-icon fas fa-balance-scale"></i>
|
||||
<p>Taxes</p>
|
||||
</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a href="payment_method.php" class="nav-link <?php echo (basename($_SERVER['PHP_SELF']) == 'payment_method.php' ? 'active' : ''); ?>">
|
||||
<i class="nav-icon fas fa-hand-holding-usd"></i>
|
||||
<p>Payment Methods</p>
|
||||
</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a href="payment_provider.php" class="nav-link <?php echo (basename($_SERVER['PHP_SELF']) == 'payment_provider.php' ? 'active' : ''); ?>">
|
||||
<i class="nav-icon far fa-credit-card"></i>
|
||||
<p>Payment Providers</p>
|
||||
</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a href="saved_payment_method.php" class="nav-link <?php echo (basename($_SERVER['PHP_SELF']) == 'saved_payment_method.php' ? 'active' : ''); ?>">
|
||||
<i class="nav-icon far fa-credit-card"></i>
|
||||
<p>Saved Payments</p>
|
||||
</a>
|
||||
</li>
|
||||
<?php } ?>
|
||||
<li class="nav-item">
|
||||
<a href="ai_provider.php" class="nav-link <?php echo (basename($_SERVER['PHP_SELF']) == 'ai_provider.php' ? 'active' : ''); ?>">
|
||||
<i class="nav-icon fas fa-robot"></i>
|
||||
<p>AI Providers</p>
|
||||
</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a href="ai_model.php" class="nav-link <?php echo (basename($_SERVER['PHP_SELF']) == 'ai_model.php' ? 'active' : ''); ?>">
|
||||
<i class="nav-icon fas fa-robot"></i>
|
||||
<p>AI Models</p>
|
||||
</a>
|
||||
</li>
|
||||
|
||||
<?php if ($config_module_enable_ticketing) { ?>
|
||||
<li class="nav-item">
|
||||
<a href="ticket_status.php" class="nav-link <?php echo (basename($_SERVER['PHP_SELF']) == 'ticket_status.php' ? 'active' : ''); ?>">
|
||||
<i class="nav-icon fas fa-info-circle"></i>
|
||||
<p>Ticket Statuses</p>
|
||||
</a>
|
||||
</li>
|
||||
<?php } ?>
|
||||
<li class="nav-item">
|
||||
<a href="custom_link.php" class="nav-link <?php echo (basename($_SERVER['PHP_SELF']) == 'custom_link.php' ? 'active' : ''); ?>">
|
||||
<i class="nav-icon fas fa-external-link-alt"></i>
|
||||
<p>Custom Links</p>
|
||||
</a>
|
||||
</li>
|
||||
|
||||
<?php if ($config_module_enable_itdoc) { ?>
|
||||
<li class="nav-header">TEMPLATES</li>
|
||||
|
||||
<li class="nav-item">
|
||||
<a href="project_template.php" class="nav-link <?php echo (in_array(basename($_SERVER['PHP_SELF']), ['project_template.php', 'project_template_details.php']) ? 'active' : ''); ?>">
|
||||
<i class="nav-icon fas fa-project-diagram"></i>
|
||||
<p>Project Templates</p>
|
||||
</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a href="ticket_template.php" class="nav-link <?php echo (in_array(basename($_SERVER['PHP_SELF']), ['ticket_template.php', 'ticket_template_details.php']) ? 'active' : ''); ?>">
|
||||
<i class="nav-icon fas fa-life-ring"></i>
|
||||
<p>Ticket Templates</p>
|
||||
</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a href="vendor_template.php" class="nav-link <?php echo (basename($_SERVER['PHP_SELF']) == 'vendor_template.php' ? 'active' : ''); ?>">
|
||||
<i class="nav-icon fas fa-building"></i>
|
||||
<p>Vendor Templates</p>
|
||||
</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a href="software_template.php" class="nav-link <?php echo (basename($_SERVER['PHP_SELF']) == 'software_template.php' ? 'active' : ''); ?>">
|
||||
<i class="nav-icon fas fa-rocket"></i>
|
||||
<p>License Templates</p>
|
||||
</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a href="document_template.php" class="nav-link <?php echo (in_array(basename($_SERVER['PHP_SELF']), ['document_template.php', 'document_template_details.php']) ? 'active' : ''); ?>">
|
||||
<i class="nav-icon fas fa-file"></i>
|
||||
<p>Document Templates</p>
|
||||
</a>
|
||||
</li>
|
||||
<?php } ?>
|
||||
|
||||
<li class="nav-header">MAINTENANCE</li>
|
||||
|
||||
<li class="nav-item">
|
||||
<a href="mail_queue.php" class="nav-link <?php echo (basename($_SERVER['PHP_SELF']) == 'mail_queue.php' ? 'active' : ''); ?>">
|
||||
<i class="nav-icon fas fa-mail-bulk"></i>
|
||||
<p>Mail Queue</p>
|
||||
</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a href="audit_log.php" class="nav-link <?php echo (basename($_SERVER['PHP_SELF']) == 'audit_log.php' ? 'active' : ''); ?>">
|
||||
<i class="nav-icon fas fa-history"></i>
|
||||
<p>Audit Logs</p>
|
||||
</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a href="app_log.php" class="nav-link <?php echo (basename($_SERVER['PHP_SELF']) == 'app_log.php' ? 'active' : ''); ?>">
|
||||
<i class="nav-icon fas fa-history"></i>
|
||||
<p>App Logs</p>
|
||||
</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a href="backup.php" class="nav-link <?php echo (basename($_SERVER['PHP_SELF']) == 'backup.php' ? 'active' : ''); ?>">
|
||||
<i class="nav-icon fas fa-cloud-upload-alt"></i>
|
||||
<p>Backup</p>
|
||||
</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a href="debug.php" class="nav-link <?php echo (basename($_SERVER['PHP_SELF']) == 'debug.php' ? 'active' : ''); ?>">
|
||||
<i class="nav-icon fas fa-bug"></i>
|
||||
<p>Debug</p>
|
||||
</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a href="update.php" class="nav-link <?php echo (basename($_SERVER['PHP_SELF']) == 'update.php' ? 'active' : ''); ?>">
|
||||
<i class="nav-icon fas fa-download"></i>
|
||||
<p>Update</p>
|
||||
</a>
|
||||
</li>
|
||||
|
||||
<!-- SETTINGS Section -->
|
||||
<li class="nav-item has-treeview mt-2 <?php echo (in_array(basename($_SERVER['PHP_SELF']), ['settings_company.php', 'settings_localization.php', 'settings_theme.php', 'settings_security.php', 'settings_mail.php', 'settings_notification.php', 'settings_default.php', 'settings_invoice.php', 'settings_quote.php', 'settings_online_payment.php', 'settings_online_payment_clients.php', 'settings_project.php', 'settings_ticket.php', 'settings_ai.php', 'identity_provider.php', 'settings_telemetry.php', 'settings_module.php']) ? 'menu-open' : ''); ?>">
|
||||
<a href="#" class="nav-link">
|
||||
<p>
|
||||
SETTINGS
|
||||
<i class="right fas fa-angle-left"></i>
|
||||
</p>
|
||||
</a>
|
||||
<ul class="nav nav-treeview">
|
||||
<li class="nav-item">
|
||||
<a href="settings_company.php" class="nav-link <?php echo (basename($_SERVER['PHP_SELF']) == 'settings_company.php' ? 'active' : ''); ?>">
|
||||
<i class="nav-icon fa fa-briefcase"></i>
|
||||
<p>Company Details</p>
|
||||
</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a href="settings_localization.php" class="nav-link <?php echo (basename($_SERVER['PHP_SELF']) == 'settings_localization.php' ? 'active' : ''); ?>">
|
||||
<i class="nav-icon fa fa-globe"></i>
|
||||
<p>Localization</p>
|
||||
</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a href="settings_theme.php" class="nav-link <?php echo (basename($_SERVER['PHP_SELF']) == 'settings_theme.php' ? 'active' : ''); ?>">
|
||||
<i class="nav-icon fa fa-paint-brush"></i>
|
||||
<p>Theme</p>
|
||||
</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a href="settings_security.php" class="nav-link <?php echo (basename($_SERVER['PHP_SELF']) == 'settings_security.php' ? 'active' : ''); ?>">
|
||||
<i class="nav-icon fas fa-shield-alt"></i>
|
||||
<p>Security</p>
|
||||
</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a href="settings_mail.php" class="nav-link <?php echo (basename($_SERVER['PHP_SELF']) == 'settings_mail.php' ? 'active' : ''); ?>">
|
||||
<i class="nav-icon far fa-envelope"></i>
|
||||
<p>Mail</p>
|
||||
</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a href="settings_notification.php" class="nav-link <?php echo (basename($_SERVER['PHP_SELF']) == 'settings_notification.php' ? 'active' : ''); ?>">
|
||||
<i class="nav-icon far fa-bell"></i>
|
||||
<p>Notifications</p>
|
||||
</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a href="settings_default.php" class="nav-link <?php echo (basename($_SERVER['PHP_SELF']) == 'settings_default.php' ? 'active' : ''); ?>">
|
||||
<i class="nav-icon fas fa-cogs"></i>
|
||||
<p>Defaults</p>
|
||||
</a>
|
||||
</li>
|
||||
<?php if ($config_module_enable_accounting) { ?>
|
||||
<li class="nav-item">
|
||||
<a href="settings_invoice.php" class="nav-link <?php echo (basename($_SERVER['PHP_SELF']) == 'settings_invoice.php' ? 'active' : ''); ?>">
|
||||
<i class="nav-icon fas fa-file-invoice"></i>
|
||||
<p>Invoice</p>
|
||||
</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a href="settings_quote.php" class="nav-link <?php echo (basename($_SERVER['PHP_SELF']) == 'settings_quote.php' ? 'active' : ''); ?>">
|
||||
<i class="nav-icon fas fa-comment-dollar"></i>
|
||||
<p>Quote</p>
|
||||
</a>
|
||||
</li>
|
||||
<?php } ?>
|
||||
<?php if ($config_module_enable_ticketing) { ?>
|
||||
<li class="nav-item">
|
||||
<a href="settings_project.php" class="nav-link <?php echo (basename($_SERVER['PHP_SELF']) == 'settings_project.php' ? 'active' : ''); ?>">
|
||||
<i class="nav-icon fas fa-project-diagram"></i>
|
||||
<p>Project</p>
|
||||
</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a href="settings_ticket.php" class="nav-link <?php echo (basename($_SERVER['PHP_SELF']) == 'settings_ticket.php' ? 'active' : ''); ?>">
|
||||
<i class="nav-icon fas fa-life-ring"></i>
|
||||
<p>Ticket</p>
|
||||
</a>
|
||||
</li>
|
||||
<?php } ?>
|
||||
<!-- Currently the only integration is the client portal SSO -->
|
||||
<?php if ($config_client_portal_enable) { ?>
|
||||
<li class="nav-item">
|
||||
<a href="identity_provider.php" class="nav-link <?php echo (basename($_SERVER['PHP_SELF']) == 'identity_provider.php' ? 'active' : ''); ?>">
|
||||
<i class="nav-icon fas fa-fingerprint"></i>
|
||||
<p>Identity Provider</p>
|
||||
</a>
|
||||
</li>
|
||||
<?php } ?>
|
||||
<li class="nav-item">
|
||||
<a href="settings_telemetry.php" class="nav-link <?php echo (basename($_SERVER['PHP_SELF']) == 'settings_telemetry.php' ? 'active' : ''); ?>">
|
||||
<i class="nav-icon fas fa-satellite-dish"></i>
|
||||
<p>Telemetry</p>
|
||||
</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a href="settings_module.php" class="nav-link <?php echo (basename($_SERVER['PHP_SELF']) == 'settings_module.php' ? 'active' : ''); ?>">
|
||||
<i class="nav-icon fas fa-cube"></i>
|
||||
<p>Modules</p>
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
</li>
|
||||
|
||||
<?php
|
||||
$sql_custom_links = mysqli_query($mysqli, "SELECT * FROM custom_links
|
||||
WHERE custom_link_location = 4 AND custom_link_archived_at IS NULL
|
||||
ORDER BY custom_link_order ASC, custom_link_name ASC"
|
||||
);
|
||||
|
||||
while ($row = mysqli_fetch_array($sql_custom_links)) {
|
||||
$custom_link_name = nullable_htmlentities($row['custom_link_name']);
|
||||
$custom_link_uri = sanitize_url($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) {
|
||||
$target = "target='_blank' rel='noopener noreferrer'";
|
||||
} else {
|
||||
$target = "";
|
||||
}
|
||||
|
||||
?>
|
||||
|
||||
<li class="nav-item">
|
||||
<a href="<?php echo $custom_link_uri; ?>" <?php echo $target; ?> class="nav-link <?php if (basename($_SERVER["PHP_SELF"]) == basename($custom_link_uri)) { echo "active"; } ?>">
|
||||
<i class="fas fa-<?php echo $custom_link_icon; ?> nav-icon"></i>
|
||||
<p><?php echo $custom_link_name; ?></p>
|
||||
<i class="fas fa-angle-right nav-icon float-right"></i>
|
||||
</a>
|
||||
</li>
|
||||
|
||||
<?php } ?>
|
||||
|
||||
</ul>
|
||||
</nav>
|
||||
<!-- /.sidebar-menu -->
|
||||
<div class="mb-3"></div>
|
||||
</div>
|
||||
<!-- /.sidebar -->
|
||||
</aside>
|
||||
4
admin/index.php
Normal file
4
admin/index.php
Normal file
@@ -0,0 +1,4 @@
|
||||
<?php
|
||||
|
||||
header('Location: users.php');
|
||||
|
||||
212
admin/mail_queue.php
Normal file
212
admin/mail_queue.php
Normal file
@@ -0,0 +1,212 @@
|
||||
<?php
|
||||
|
||||
// Default Column Sortby Filter
|
||||
$sort = "email_id";
|
||||
$order = "DESC";
|
||||
|
||||
require_once "includes/inc_all_admin.php";
|
||||
|
||||
$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 ajax-modal" href="#"
|
||||
data-modal-size="lg"
|
||||
data-modal-url="modals/mail_queue/mail_queue_message_view.php?id=<?= $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";
|
||||
73
admin/modals/ai/ai_model_add.php
Normal file
73
admin/modals/ai/ai_model_add.php
Normal file
@@ -0,0 +1,73 @@
|
||||
<div class="form-group">
|
||||
<div class="modal" id="addAIModelModal" tabindex="-1">
|
||||
<div class="modal-dialog">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header bg-dark">
|
||||
<h5 class="modal-title"><i class="fa fa-fw fa-robot mr-2"></i>Add AI Model</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="csrf_token" value="<?php echo $_SESSION['csrf_token'] ?>">
|
||||
|
||||
<div class="modal-body">
|
||||
|
||||
<div class="form-group">
|
||||
<label>Provider <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-robot"></i></span>
|
||||
</div>
|
||||
<select class="form-control select2" name="provider" required>
|
||||
<option value="">- Select an AI Provider -</option>
|
||||
<?php
|
||||
$sql_ai_providers = mysqli_query($mysqli, "SELECT * FROM ai_providers");
|
||||
while ($row = mysqli_fetch_array($sql_ai_providers)) {
|
||||
$ai_provider_id = intval($row['ai_provider_id']);
|
||||
$ai_provider_name = nullable_htmlentities($row['ai_provider_name']);
|
||||
|
||||
?>
|
||||
<option value="<?php echo $ai_provider_id; ?>"><?php echo $ai_provider_name; ?></option>
|
||||
<?php } ?>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label>Model Name <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-robot"></i></span>
|
||||
</div>
|
||||
<input type="text" class="form-control" name="model" placeholder="ex gpt-4">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label>Use Case <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-th-list"></i></span>
|
||||
</div>
|
||||
<select class="form-control select2" name="use_case">
|
||||
<option>General</option>
|
||||
<option>Tickets</option>
|
||||
<option>Documentation</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<textarea class="form-control" rows="8" name="prompt" placeholder="Enter a model prompt:"></textarea>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button type="submit" name="add_ai_model" 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="fa fa-times mr-2"></i>Cancel</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
90
admin/modals/ai/ai_model_edit.php
Normal file
90
admin/modals/ai/ai_model_edit.php
Normal file
@@ -0,0 +1,90 @@
|
||||
<?php
|
||||
|
||||
require_once '../../../includes/modal_header.php';
|
||||
|
||||
$model_id = intval($_GET['id']);
|
||||
|
||||
$sql = mysqli_query($mysqli, "SELECT * FROM ai_models WHERE ai_model_id = $model_id LIMIT 1");
|
||||
|
||||
$row = mysqli_fetch_array($sql);
|
||||
$ai_model_ai_provider_id = intval($row['ai_model_ai_provider_id']);
|
||||
$model_id = intval($row['ai_model_id']);
|
||||
$model_name = nullable_htmlentities($row['ai_model_name']);
|
||||
$use_case = nullable_htmlentities($row['ai_model_use_case']);
|
||||
$prompt = nullable_htmlentities($row['ai_model_prompt']);
|
||||
|
||||
// Generate the HTML form content using output buffering.
|
||||
ob_start();
|
||||
?>
|
||||
|
||||
<div class="modal-header bg-dark">
|
||||
<h5 class="modal-title"><i class="fa fa-fw fa-robot mr-2"></i>Editing: <strong><?php echo $model_name; ?></strong></h5>
|
||||
<button type="button" class="close text-light" data-dismiss="modal">
|
||||
<span>×</span>
|
||||
</button>
|
||||
</div>
|
||||
<form action="post.php" method="post" autocomplete="off">
|
||||
<input type="hidden" name="csrf_token" value="<?php echo $_SESSION['csrf_token'] ?>">
|
||||
<input type="hidden" name="model_id" value="<?php echo $model_id; ?>">
|
||||
|
||||
<div class="modal-body">
|
||||
|
||||
<div class="form-group">
|
||||
<label>Provider <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-robot"></i></span>
|
||||
</div>
|
||||
<select class="form-control select2" name="provider" required>
|
||||
<option value="">- Select an AI Provider -</option>
|
||||
<?php
|
||||
$sql_ai_providers = mysqli_query($mysqli, "SELECT * FROM ai_providers");
|
||||
while ($row = mysqli_fetch_array($sql_ai_providers)) {
|
||||
$ai_provider_id = intval($row['ai_provider_id']);
|
||||
$ai_provider_name = nullable_htmlentities($row['ai_provider_name']);
|
||||
|
||||
?>
|
||||
<option <?php if ($ai_provider_id = $ai_model_ai_provider_id) { echo "selected"; } ?> value="<?php echo $ai_provider_id; ?>"><?php echo $ai_provider_name; ?></option>
|
||||
<?php } ?>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label>Model Name <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-robot"></i></span>
|
||||
</div>
|
||||
<input type="text" class="form-control" name="model" value="<?php echo $model_name; ?>" placeholder="ex gpt-4">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label>Use Case <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-th-list"></i></span>
|
||||
</div>
|
||||
<select class="form-control select2" name="use_case">
|
||||
<option <?php if ($use_case == 'General') { echo "selected"; } ?>>General</option>
|
||||
<option <?php if ($use_case == 'Tickets') { echo "selected"; } ?>>Tickets</option>
|
||||
<option <?php if ($use_case == 'Documentation') { echo "selected"; } ?>>Documentation</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<textarea class="form-control" rows="8" name="prompt" placeholder="Enter a model prompt:"><?php echo $prompt; ?></textarea>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button type="submit" name="edit_ai_model" 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>
|
||||
|
||||
<?php
|
||||
|
||||
require_once '../../../includes/modal_footer.php';
|
||||
54
admin/modals/ai/ai_provider_add.php
Normal file
54
admin/modals/ai/ai_provider_add.php
Normal file
@@ -0,0 +1,54 @@
|
||||
<div class="form-group">
|
||||
<div class="modal" id="addAIProviderModal" tabindex="-1">
|
||||
<div class="modal-dialog">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header bg-dark">
|
||||
<h5 class="modal-title"><i class="fa fa-fw fa-robot mr-2"></i>New AI Provider</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="csrf_token" value="<?php echo $_SESSION['csrf_token'] ?>">
|
||||
|
||||
<div class="modal-body">
|
||||
|
||||
<div class="form-group">
|
||||
<label>Provider Name <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-robot"></i></span>
|
||||
</div>
|
||||
<input type="text" class="form-control" name="provider" placeholder="ex OpenAI">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label>URL <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-globe"></i></span>
|
||||
</div>
|
||||
<input type="url" class="form-control" name="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" placeholder="Enter API key here">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button type="submit" name="add_ai_provider" 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="fa fa-times mr-2"></i>Cancel</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
69
admin/modals/ai/ai_provider_edit.php
Normal file
69
admin/modals/ai/ai_provider_edit.php
Normal file
@@ -0,0 +1,69 @@
|
||||
<?php
|
||||
|
||||
require_once '../../../includes/modal_header.php';
|
||||
|
||||
$provider_id = intval($_GET['id']);
|
||||
|
||||
$sql = mysqli_query($mysqli, "SELECT * FROM ai_providers WHERE ai_provider_id = $provider_id LIMIT 1");
|
||||
|
||||
$row = mysqli_fetch_array($sql);
|
||||
$provider_name = nullable_htmlentities($row['ai_provider_name']);
|
||||
$url = nullable_htmlentities($row['ai_provider_api_url']);
|
||||
$key = nullable_htmlentities($row['ai_provider_api_key']);
|
||||
|
||||
// Generate the HTML form content using output buffering.
|
||||
ob_start();
|
||||
?>
|
||||
|
||||
<div class="modal-header bg-dark">
|
||||
<h5 class="modal-title"><i class="fa fa-fw fa-robot mr-2"></i>Editing: <strong><?php echo $provider_name; ?></strong></h5>
|
||||
<button type="button" class="close text-light" data-dismiss="modal">
|
||||
<span>×</span>
|
||||
</button>
|
||||
</div>
|
||||
<form action="post.php" method="post" autocomplete="off">
|
||||
<input type="hidden" name="csrf_token" value="<?php echo $_SESSION['csrf_token'] ?>">
|
||||
<input type="hidden" name="provider_id" value="<?php echo $provider_id; ?>">
|
||||
|
||||
<div class="modal-body">
|
||||
|
||||
<div class="form-group">
|
||||
<label>Provider Name <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-robot"></i></span>
|
||||
</div>
|
||||
<input type="text" class="form-control" name="provider" value="<?php echo $provider_name; ?>" placeholder="ex OpenAI">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label>URL <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-globe"></i></span>
|
||||
</div>
|
||||
<input type="url" class="form-control" name="url" value="<?php echo $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 $key; ?>" placeholder="Enter API key here">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button type="submit" name="edit_ai_provider" 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>
|
||||
|
||||
<?php
|
||||
|
||||
require_once '../../../includes/modal_footer.php';
|
||||
121
admin/modals/api/api_key_add.php
Normal file
121
admin/modals/api/api_key_add.php
Normal file
@@ -0,0 +1,121 @@
|
||||
<?php
|
||||
$key = randomString(156);
|
||||
$decryptPW = randomString(160);
|
||||
?>
|
||||
<div class="modal" id="addApiKeyModal" tabindex="-1">
|
||||
<div class="modal-dialog">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header bg-dark">
|
||||
<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">
|
||||
<span>×</span>
|
||||
</button>
|
||||
</div>
|
||||
<form action="post.php" method="post" autocomplete="off">
|
||||
<div class="modal-body">
|
||||
|
||||
<ul class="nav nav-pills nav-justified mb-3">
|
||||
<li class="nav-item">
|
||||
<a class="nav-link active" data-toggle="pill" href="#pills-api-details">Details</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" data-toggle="pill" href="#pills-api-keys">Keys</a>
|
||||
</li>
|
||||
</ul>
|
||||
<hr>
|
||||
|
||||
<div class="tab-content">
|
||||
|
||||
<div class="tab-pane fade show active" id="pills-api-details">
|
||||
<input type="hidden" name="csrf_token" value="<?php echo $_SESSION['csrf_token'] ?>">
|
||||
<input type="hidden" name="key" value="<?php echo $key ?>">
|
||||
<input type="hidden" name="password" value="<?php echo $decryptPW ?>">
|
||||
|
||||
<div class="form-group">
|
||||
<label>Name <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-sticky-note"></i></span>
|
||||
</div>
|
||||
<input type="text" class="form-control" name="name" placeholder="Key Name" maxlength="255" required autofocus>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label>Expiration Date <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" min="<?php echo date('Y-m-d')?>" max="2999-12-31" required>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label>Client Access <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="0"> ALL CLIENTS </option>
|
||||
<?php
|
||||
$sql = mysqli_query($mysqli, "SELECT client_id, client_name FROM clients WHERE client_archived_at IS NULL ORDER BY client_name ASC");
|
||||
while ($row = mysqli_fetch_array($sql)) {
|
||||
$client_id = intval($row['client_id']);
|
||||
$client_name = nullable_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 class="tab-pane fade" id="pills-api-keys">
|
||||
<div class="form-group">
|
||||
<label>API 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" value="<?php echo $key ?>" required disabled>
|
||||
<div class="input-group-append">
|
||||
<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 class="form-group">
|
||||
<label>Login credential decryption password <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-unlock-alt"></i></span>
|
||||
</div>
|
||||
<input type="text" class="form-control" value="<?php echo $decryptPW ?>" required disabled>
|
||||
<div class="input-group-append">
|
||||
<button class="btn btn-default clipboardjs" type="button" data-clipboard-text="<?php echo $decryptPW; ?>"><i class="fa fa-fw fa-copy"></i></button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<br>
|
||||
<div class="form-group">
|
||||
<label>I have made a copy of the key(s)<strong class="text-danger">*</strong></label>
|
||||
<div class="input-group">
|
||||
<div class="input-group-prepend">
|
||||
<input type="checkbox" name="ack" value="1" required>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<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>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
48
admin/modals/category/category_add.php
Normal file
48
admin/modals/category/category_add.php
Normal file
@@ -0,0 +1,48 @@
|
||||
<?php
|
||||
|
||||
require_once '../../../includes/modal_header.php';
|
||||
|
||||
$category = nullable_htmlentities($_GET['category']);
|
||||
|
||||
?>
|
||||
|
||||
<div class="modal-header bg-dark">
|
||||
<h5 class="modal-title"><i class="fa fa-fw fa-list-ul mr-2"></i>New <strong><?= nullable_htmlentities($category) ?></strong> Category</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="type" value="<?php echo ($category); ?>">
|
||||
|
||||
<div class="modal-body">
|
||||
|
||||
<div class="form-group">
|
||||
<label>Name <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-list-ul"></i></span>
|
||||
</div>
|
||||
<input type="text" class="form-control" name="name" placeholder="Category name" maxlength="200" required autofocus>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label>Color <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-paint-brush"></i></span>
|
||||
</div>
|
||||
<input type="color" class="form-control col-3" name="color" required>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button type="submit" name="add_category" 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="fa fa-times mr-2"></i>Cancel</button>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
<?php
|
||||
require_once '../../../includes/modal_footer.php';
|
||||
56
admin/modals/category/category_edit.php
Normal file
56
admin/modals/category/category_edit.php
Normal file
@@ -0,0 +1,56 @@
|
||||
<?php
|
||||
|
||||
require_once '../../../includes/modal_header.php';
|
||||
|
||||
$category_id = intval($_GET['id']);
|
||||
|
||||
$sql = mysqli_query($mysqli, "SELECT * FROM categories WHERE category_id = $category_id LIMIT 1");
|
||||
|
||||
$row = mysqli_fetch_array($sql);
|
||||
$category_name = nullable_htmlentities($row['category_name']);
|
||||
$category_color = nullable_htmlentities($row['category_color']);
|
||||
$category_type = nullable_htmlentities($row['category_type']);
|
||||
|
||||
// Generate the HTML form content using output buffering.
|
||||
ob_start();
|
||||
?>
|
||||
<div class="modal-header bg-dark">
|
||||
<h5 class="modal-title"><i class="fa fa-fw fa-list-ul 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 $category_type; ?>">
|
||||
<div class="modal-body">
|
||||
|
||||
<div class="form-group">
|
||||
<label>Name <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-list-ul"></i></span>
|
||||
</div>
|
||||
<input type="text" class="form-control" name="name" maxlength="200" value="<?php echo $category_name; ?>" required>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label>Color <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-paint-brush"></i></span>
|
||||
</div>
|
||||
<input type="color" class="form-control col-3" name="color" value="<?php echo $category_color; ?>" required>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<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>
|
||||
|
||||
<?php
|
||||
require_once '../../../includes/modal_footer.php';
|
||||
41
admin/modals/custom_field/custom_field_create.php
Normal file
41
admin/modals/custom_field/custom_field_create.php
Normal file
@@ -0,0 +1,41 @@
|
||||
<div class="modal" id="createCustomFieldModal" tabindex="-1">
|
||||
<div class="modal-dialog">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header bg-dark">
|
||||
<h5 class="modal-title"><i class="fa fa-fw fa-th-list mr-2"></i>Create <?php echo nullable_htmlentities($table); ?> field</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="table" value="<?php echo nullable_htmlentities($table); ?>">
|
||||
|
||||
<div class="modal-body">
|
||||
|
||||
<div class="form-group">
|
||||
<label>Label <strong class="text-danger">*</strong></label>
|
||||
<input type="text" class="form-control" name="label" placeholder="Enter a custom field label" maxlength="255" required autofocus>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label>Type <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-th"></i></span>
|
||||
</div>
|
||||
<select class="form-control select2" name="type" required>
|
||||
<option value="">- Select a field type -</option>
|
||||
<option>Text</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button type="submit" name="create_custom_field" 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="fa fa-times mr-2"></i>Cancel</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
40
admin/modals/custom_field/custom_field_edit.php
Normal file
40
admin/modals/custom_field/custom_field_edit.php
Normal file
@@ -0,0 +1,40 @@
|
||||
<div class="modal" id="editCustomFieldModal<?php echo $custom_field_id; ?>" tabindex="-1">
|
||||
<div class="modal-dialog">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header bg-dark">
|
||||
<h5 class="modal-title"><i class="fa fa-fw fa-th-list mr-2"></i>Editing custom field: <strong><?php echo $custom_field_label; ?></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="custom_field_id" value="<?php echo $custom_field_id; ?>">
|
||||
<div class="modal-body">
|
||||
|
||||
<div class="form-group">
|
||||
<label>Label <strong class="text-danger">*</strong></label>
|
||||
<input type="text" class="form-control" name="label" maxlength="255" value="<?php echo $custom_field_label; ?>" required>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label>Type <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-th"></i></span>
|
||||
</div>
|
||||
<select class="form-control select2" name="type" required>
|
||||
<option value="">- Select a field type -</option>
|
||||
<option <?php if ($custom_field_type == 'text') { echo "selected"; } ?> value="text">Text</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button type="submit" name="edit_custom_field" 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>
|
||||
83
admin/modals/custom_link/custom_link_add.php
Normal file
83
admin/modals/custom_link/custom_link_add.php
Normal file
@@ -0,0 +1,83 @@
|
||||
<div class="modal" id="addLinkModal" tabindex="-1">
|
||||
<div class="modal-dialog">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header bg-dark">
|
||||
<h5 class="modal-title"><i class="fas fa-fw fa-external-link-alt mr-2"></i>New Custom Link</h5>
|
||||
<button type="button" class="close text-white" data-dismiss="modal">
|
||||
<span>×</span>
|
||||
</button>
|
||||
</div>
|
||||
<form action="post.php" method="post" autocomplete="off">
|
||||
|
||||
<div class="modal-body">
|
||||
|
||||
<div class="form-group">
|
||||
<label>Name <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-list-ul"></i></span>
|
||||
</div>
|
||||
<input type="text" class="form-control" name="name" placeholder="Link name" maxlength="200" required autofocus>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label>Order</label>
|
||||
<div class="input-group">
|
||||
<div class="input-group-prepend">
|
||||
<span class="input-group-text"><i class="fa fa-fw fa-sort-numeric-down"></i></span>
|
||||
</div>
|
||||
<input type="number" class="form-control" name="order" placeholder="Leave blank for no order">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label>URI <strong class="text-danger">*</strong></label> / <span class="text-secondary">Open New Tab</span>
|
||||
<div class="input-group">
|
||||
<div class="input-group-prepend">
|
||||
<span class="input-group-text"><i class="fa fa-fw fa-external-link-alt"></i></span>
|
||||
</div>
|
||||
<input type="text" class="form-control" name="uri" placeholder="Enter Link" maxlength="500" required>
|
||||
<div class="input-group-append">
|
||||
<div class="input-group-text">
|
||||
<input type="checkbox" name="new_tab" value="1">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label>Icon</label>
|
||||
<div class="input-group">
|
||||
<div class="input-group-prepend">
|
||||
<span class="input-group-text"><i class="fa fa-fw fa-image"></i></span>
|
||||
</div>
|
||||
<input type="text" class="form-control" name="icon" placeholder="Icon ex handshake" maxlength="200">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label>Location <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-home"></i></span>
|
||||
</div>
|
||||
<select class="form-control select2" name="location" required>
|
||||
<option value="1">Main Side Nav</option>
|
||||
<option value="2">Top Nav (Icon Required)</option>
|
||||
<option value="3">Client Portal Nav</option>
|
||||
<option value="4">Admin Nav</option>
|
||||
<option value="5">Reports Nav</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button type="submit" name="add_custom_link" class="btn btn-primary text-bold"><i class="fas fa-check mr-2"></i>Create</button>
|
||||
<button type="button" class="btn btn-light" data-dismiss="modal"><i class="fas fa-times mr-2"></i>Cancel</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
101
admin/modals/custom_link/custom_link_edit.php
Normal file
101
admin/modals/custom_link/custom_link_edit.php
Normal file
@@ -0,0 +1,101 @@
|
||||
<?php
|
||||
|
||||
require_once '../../../includes/modal_header.php';
|
||||
|
||||
$custom_link_id = intval($_GET['id']);
|
||||
|
||||
$sql = mysqli_query($mysqli, "SELECT * FROM custom_links WHERE custom_link_id = $custom_link_id LIMIT 1");
|
||||
$row = mysqli_fetch_array($sql);
|
||||
$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']);
|
||||
$custom_link_order = intval($row['custom_link_order']);
|
||||
$custom_link_location = intval($row['custom_link_location']);
|
||||
|
||||
// Generate the HTML form content using output buffering.
|
||||
ob_start();
|
||||
?>
|
||||
|
||||
<div class="modal-header bg-dark">
|
||||
<h5 class="modal-title"><i class="fas fa-fw fa-external-link-alt mr-2"></i>Editing link: <strong><?php echo $custom_link_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="custom_link_id" value="<?php echo $custom_link_id; ?>">
|
||||
|
||||
<div class="modal-body">
|
||||
|
||||
<div class="form-group">
|
||||
<label>Name <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-list-ul"></i></span>
|
||||
</div>
|
||||
<input type="text" class="form-control" name="name" value="<?php echo $custom_link_name; ?>" maxlength="200" required>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label>Order</label>
|
||||
<div class="input-group">
|
||||
<div class="input-group-prepend">
|
||||
<span class="input-group-text"><i class="fa fa-fw fa-sort-numeric-down"></i></span>
|
||||
</div>
|
||||
<input type="number" class="form-control" name="order" placeholder="Leave blank for no order" value="<?php echo $custom_link_order; ?>">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label>URI <strong class="text-danger">*</strong></label> / <span class="text-secondary">Open New Tab</span>
|
||||
<div class="input-group">
|
||||
<div class="input-group-prepend">
|
||||
<span class="input-group-text"><i class="fa fa-fw fa-external-link-alt"></i></span>
|
||||
</div>
|
||||
<input type="text" class="form-control" name="uri" placeholder="Enter Link" maxlength="500" value="<?php echo $custom_link_uri; ?>" required>
|
||||
<div class="input-group-append">
|
||||
<div class="input-group-text">
|
||||
<input type="checkbox" name="new_tab" value="1" <?php if ($custom_link_new_tab == 1) { echo "checked"; } ?>>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label>Icon</label>
|
||||
<div class="input-group">
|
||||
<div class="input-group-prepend">
|
||||
<span class="input-group-text"><i class="fa fa-fw fa-image"></i></span>
|
||||
</div>
|
||||
<input type="text" class="form-control" name="icon" placeholder="Icon ex handshake" maxlength="200" value="<?php echo $custom_link_icon; ?>">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label>Location <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-home"></i></span>
|
||||
</div>
|
||||
<select class="form-control select2" name="location" required>
|
||||
<option value="1" <?php if ($custom_link_location === 1) { echo "selected"; } ?> >Main Side Nav</option>
|
||||
<option value="2" <?php if ($custom_link_location === 2) { echo "selected"; } ?> >Top Nav (Icon Required)</option>
|
||||
<option value="3" <?php if ($custom_link_location === 3) { echo "selected"; } ?> >Client Portal Nav</option>
|
||||
<option value="4" <?php if ($custom_link_location === 4) { echo "selected"; } ?> >Admin Nav</option>
|
||||
<option value="5" <?php if ($custom_link_location === 5) { echo "selected"; } ?> >Reports Nav</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button type="submit" name="edit_custom_link" class="btn btn-primary text-bold"><i class="fas fa-check mr-2"></i>Save</button>
|
||||
<button type="button" class="btn btn-light" data-dismiss="modal"><i class="fas fa-times mr-2"></i>Cancel</button>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
<?php
|
||||
require_once '../../../includes/modal_footer.php';
|
||||
49
admin/modals/document_template/document_template_add.php
Normal file
49
admin/modals/document_template/document_template_add.php
Normal file
@@ -0,0 +1,49 @@
|
||||
<div class="modal" id="addDocumentTemplateModal" tabindex="-1">
|
||||
<div class="modal-dialog modal-xl">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header bg-dark">
|
||||
<h5 class="modal-title"><i class="fa fa-fw fa-file-alt mr-2"></i>Creating Document Template</h5>
|
||||
<button type="button" class="close text-white" data-dismiss="modal">
|
||||
<span>×</span>
|
||||
</button>
|
||||
</div>
|
||||
<form action="post.php" method="post" autocomplete="off">
|
||||
<div class="modal-body">
|
||||
|
||||
<div class="form-group">
|
||||
<input type="text" class="form-control" name="name" placeholder="Template name" maxlength="200">
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label>Enter a prompt for the type of IT documentation you want to generate:</label>
|
||||
<div class="input-group mb-3">
|
||||
<input type="text" class="form-control" id="aiPrompt" placeholder="e.g. 'A network troubleshooting guide for junior technicians'">
|
||||
<div class="input-group-append">
|
||||
<button class="btn btn-info" type="button" id="generateAIContent">
|
||||
<i class="fa fa-fw fa-magic mr-1"></i>Generate with AI
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- TinyMCE Content -->
|
||||
<div class="form-group">
|
||||
<textarea class="form-control tinymce" name="content"></textarea>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<input type="text" class="form-control" name="description" placeholder="Enter a short summary">
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="modal-footer">
|
||||
|
||||
<button type="submit" name="add_document_template" 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="fa fa-times mr-2"></i>Cancel</button>
|
||||
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
47
admin/modals/document_template/document_template_edit.php
Normal file
47
admin/modals/document_template/document_template_edit.php
Normal file
@@ -0,0 +1,47 @@
|
||||
<?php
|
||||
|
||||
require_once '../../../includes/modal_header.php';
|
||||
|
||||
$document_template_id = intval($_GET['id']);
|
||||
|
||||
$sql = mysqli_query($mysqli, "SELECT * FROM document_templates WHERE document_template_id = $document_template_id LIMIT 1");
|
||||
$row = mysqli_fetch_array($sql);
|
||||
$document_template_name = nullable_htmlentities($row['document_template_name']);
|
||||
$document_template_description = nullable_htmlentities($row['document_template_description']);
|
||||
$document_template_content = nullable_htmlentities($row['document_template_content']);
|
||||
|
||||
// Generate the HTML form content using output buffering.
|
||||
ob_start();
|
||||
?>
|
||||
|
||||
<div class="modal-header bg-dark">
|
||||
<h5 class="modal-title"><i class="fa fa-fw fa-file-alt mr-2"></i>Editing template: <strong><?php echo $document_template_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="document_template_id" value="<?php echo $document_template_id; ?>">
|
||||
<div class="modal-body">
|
||||
|
||||
<div class="form-group">
|
||||
<input type="text" class="form-control" name="name" maxlength="200" value="<?php echo $document_template_name; ?>" placeholder="Name" required>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<textarea class="form-control tinymce" name="content"><?php echo $document_template_content; ?></textarea>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<input type="text" class="form-control" name="description" value="<?php echo $document_template_description; ?>" placeholder="Short summary">
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button type="submit" name="edit_document_template" 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>
|
||||
|
||||
<?php
|
||||
require_once '../../../includes/modal_footer.php';
|
||||
79
admin/modals/mail_queue/mail_queue_message_view.php
Normal file
79
admin/modals/mail_queue/mail_queue_message_view.php
Normal file
@@ -0,0 +1,79 @@
|
||||
<?php
|
||||
|
||||
require_once '../../../includes/modal_header.php';
|
||||
|
||||
if (!isset($session_is_admin) || !$session_is_admin) {
|
||||
exit(WORDING_ROLECHECK_FAILED . "<br>Tell your admin: Your role does not have admin access.");
|
||||
}
|
||||
|
||||
$email_id = intval($_GET['id']);
|
||||
|
||||
//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);
|
||||
|
||||
$sql = mysqli_query($mysqli, "SELECT * FROM email_queue WHERE email_id = $email_id LIMIT 1");
|
||||
$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>";
|
||||
}
|
||||
|
||||
// Generate the HTML form content using output buffering.
|
||||
ob_start();
|
||||
?>
|
||||
<div class="modal-header bg-dark">
|
||||
<h5 class="modal-title"><i class='fas fa-fw fa-envelope-open mr-2'></i><strong><?php echo $email_subject; ?></strong></h5>
|
||||
<button type="button" class="close text-light" data-dismiss="modal">
|
||||
<span>×</span>
|
||||
</button>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<div class="row">
|
||||
<div class="col-md-1">
|
||||
<span class="text-secondary">From:</span>
|
||||
</div>
|
||||
<div class="col-md-10">
|
||||
<?php echo "<strong>$email_from_name</strong> ($email_from)"; ?>
|
||||
</div>
|
||||
</div>
|
||||
<hr class="my-2">
|
||||
<div class="row">
|
||||
<div class="col-md-1">
|
||||
<span class="text-secondary">To:</span>
|
||||
</div>
|
||||
<div class="col-md-10">
|
||||
<?php echo "<strong>$email_recipient_name</strong> ($email_recipient)"; ?>
|
||||
</div>
|
||||
</div>
|
||||
<hr class="my-2">
|
||||
<div class="prettyContent">
|
||||
<?php echo $email_content; ?>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script src="../../js/pretty_content.js"></script>
|
||||
|
||||
<?php
|
||||
require_once '../../../includes/modal_footer.php';
|
||||
37
admin/modals/payment_method/payment_method_add.php
Normal file
37
admin/modals/payment_method/payment_method_add.php
Normal file
@@ -0,0 +1,37 @@
|
||||
<div class="modal" id="addPaymentMethodModal" tabindex="-1">
|
||||
<div class="modal-dialog">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header bg-dark">
|
||||
<h5 class="modal-title"><i class="fa fa-fw fa-credit-card mr-2"></i>Creating: <strong>Payment Method</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="csrf_token" value="<?php echo $_SESSION['csrf_token'] ?>">
|
||||
|
||||
<div class="modal-body">
|
||||
|
||||
<div class="form-group">
|
||||
<label>Name <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-credit-card"></i></span>
|
||||
</div>
|
||||
<input type="text" class="form-control" name="name" placeholder="Payment method name" maxlength="200" required autofocus>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<textarea class="form-control" rows="3" name="description" placeholder="Enter a description..."></textarea>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button type="submit" name="add_payment_method" 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="fa fa-times mr-2"></i>Cancel</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
51
admin/modals/payment_method/payment_method_edit.php
Normal file
51
admin/modals/payment_method/payment_method_edit.php
Normal file
@@ -0,0 +1,51 @@
|
||||
<?php
|
||||
|
||||
require_once '../../../includes/modal_header.php';
|
||||
|
||||
$payment_method_id = intval($_GET['id']);
|
||||
|
||||
$sql = mysqli_query($mysqli, "SELECT * FROM payment_methods WHERE payment_method_id = $payment_method_id LIMIT 1");
|
||||
|
||||
$row = mysqli_fetch_array($sql);
|
||||
$payment_method_id = intval($row['payment_method_id']);
|
||||
$payment_method_name = nullable_htmlentities($row['payment_method_name']);
|
||||
$payment_method_description = nullable_htmlentities($row['payment_method_description']);
|
||||
|
||||
// Generate the HTML form content using output buffering.
|
||||
ob_start();
|
||||
?>
|
||||
<div class="modal-header bg-dark">
|
||||
<h5 class="modal-title"><i class="fa fa-fw fa-credit-card mr-2"></i>Editing: <strong><?php echo $payment_method_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="csrf_token" value="<?php echo $_SESSION['csrf_token'] ?>">
|
||||
|
||||
<div class="modal-body">
|
||||
|
||||
<div class="form-group">
|
||||
<label>Name <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-credit-card"></i></span>
|
||||
</div>
|
||||
<input type="text" class="form-control" name="name" value="<?php echo $payment_method_name; ?>" placeholder="Payment method name" maxlength="200" required autofocus>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<textarea class="form-control" rows="3" name="description" placeholder="Enter a description..."><?php echo $payment_method_description; ?></textarea>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button type="submit" name="edit_payment_method" 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>
|
||||
|
||||
<?php
|
||||
|
||||
require_once '../../../includes/modal_footer.php';
|
||||
103
admin/modals/payment_provider/payment_provider_add.php
Normal file
103
admin/modals/payment_provider/payment_provider_add.php
Normal file
@@ -0,0 +1,103 @@
|
||||
<div class="form-group">
|
||||
<div class="modal" id="addPaymentProviderModal" tabindex="-1">
|
||||
<div class="modal-dialog">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header bg-dark">
|
||||
<h5 class="modal-title"><i class="fa fa-fw fa-credit-card mr-2"></i>Add Payment Provider</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="csrf_token" value="<?php echo $_SESSION['csrf_token'] ?>">
|
||||
|
||||
<div class="modal-body">
|
||||
|
||||
<div class="alert alert-info">
|
||||
An income account named after the provider will always be created and used for income of paid invoices.<br>
|
||||
If "Enable Expense" option is enabled, a matching vendor will also be automatically created for expense tracking. Additionally, an expense category named "Payment Processing" will be created.
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label>Provider <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-credit-card"></i></span>
|
||||
</div>
|
||||
<select class="form-control select2" name="provider">
|
||||
<option>Stripe</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<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="public_key" placeholder="Publishable API Key (pk_...)">
|
||||
</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="private_key" placeholder="Secret API Key (sk_...)">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label>Threshold</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="threshold" placeholder="1000.00">
|
||||
</div>
|
||||
<small class="form-text text-muted">Will not show as an option at Checkout if invoice amount is above this number, 0 disables the threshold check.</small>
|
||||
</div>
|
||||
|
||||
<hr>
|
||||
|
||||
<div class="form-group">
|
||||
<div class="custom-control custom-switch">
|
||||
<input type="checkbox" class="custom-control-input" name="enable_expense" checked value="1" id="enableExpenseSwitch">
|
||||
<label class="custom-control-label" for="enableExpenseSwitch">Enable Expense</label>
|
||||
</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="percentage_fee" placeholder="Enter Percentage">
|
||||
</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,3}" name="flat_fee" placeholder="0.030">
|
||||
</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="modal-footer">
|
||||
<button type="submit" name="add_payment_provider" class="btn btn-primary text-bold"><i class="fa fa-check mr-2"></i>Add</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>
|
||||
107
admin/modals/payment_provider/payment_provider_edit.php
Normal file
107
admin/modals/payment_provider/payment_provider_edit.php
Normal file
@@ -0,0 +1,107 @@
|
||||
<?php
|
||||
|
||||
require_once '../../../includes/modal_header.php';
|
||||
|
||||
$provider_id = intval($_GET['id']);
|
||||
|
||||
$sql = mysqli_query($mysqli, "SELECT * FROM payment_providers WHERE payment_provider_id = $provider_id LIMIT 1");
|
||||
|
||||
$row = mysqli_fetch_array($sql);
|
||||
$provider_name = nullable_htmlentities($row['payment_provider_name']);
|
||||
$public_key = nullable_htmlentities($row['payment_provider_public_key']);
|
||||
$private_key = nullable_htmlentities($row['payment_provider_private_key']);
|
||||
$account_id = nullable_htmlentities($row['payment_provider_account']);
|
||||
$threshold = floatval($row['payment_provider_threshold']);
|
||||
$vendor_id = nullable_htmlentities($row['payment_provider_expense_vendor']);
|
||||
$category_id = nullable_htmlentities($row['payment_provider_expense_category']);
|
||||
$percent_fee = floatval($row['payment_provider_expense_percentage_fee']) * 100;
|
||||
$flat_fee = floatval($row['payment_provider_expense_flat_fee']);
|
||||
|
||||
// Generate the HTML form content using output buffering.
|
||||
ob_start();
|
||||
?>
|
||||
<div class="modal-header bg-dark">
|
||||
<h5 class="modal-title"><i class="fa fa-fw fa-credit-card mr-2"></i>Editing: <strong><?php echo $provider_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="csrf_token" value="<?php echo $_SESSION['csrf_token'] ?>">
|
||||
<input type="hidden" name="provider_id" value="<?php echo $provider_id; ?>">
|
||||
|
||||
<div class="modal-body">
|
||||
|
||||
<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="public_key" placeholder="Publishable API Key (pk_...)" value="<?php echo $public_key; ?>">
|
||||
</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="private_key" placeholder="Secret API Key (sk_...)" value="<?php echo $private_key; ?>">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label>Threshold</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="threshold" placeholder="1000.00" value="<?php echo $threshold; ?>">
|
||||
</div>
|
||||
<small class="form-text text-muted">Will not show as an option at Checkout if above this number</small>
|
||||
</div>
|
||||
|
||||
<hr>
|
||||
|
||||
<div class="form-group">
|
||||
<div class="custom-control custom-switch">
|
||||
<input type="checkbox" class="custom-control-input" name="enable_expense" <?php if ($vendor_id) { echo "checked"; } ?> value="1" id="enableEditExpenseSwitch">
|
||||
<label class="custom-control-label" for="enableEditExpenseSwitch">Enable Expense</label>
|
||||
</div>
|
||||
<small>(Category: Payment Processing -- Vendor: <?php echo $provider_name; ?></small>
|
||||
</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="percentage_fee" value="<?php echo $percent_fee; ?>" placeholder="Enter Percentage">
|
||||
</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,3}" name="flat_fee" value="<?php echo $flat_fee; ?>" placeholder="0.030">
|
||||
</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="modal-footer">
|
||||
<button type="submit" name="edit_payment_provider" 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>
|
||||
|
||||
<?php
|
||||
|
||||
require_once '../../../includes/modal_footer.php';
|
||||
41
admin/modals/project_template/project_template_add.php
Normal file
41
admin/modals/project_template/project_template_add.php
Normal file
@@ -0,0 +1,41 @@
|
||||
<div class="modal" id="addProjectTemplateModal" tabindex="-1">
|
||||
<div class="modal-dialog">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header bg-dark">
|
||||
<h5 class="modal-title"><i class="fas fa-fw fa-project-diagram mr-2"></i>Creating Project Template</h5>
|
||||
<button type="button" class="close text-white" data-dismiss="modal">
|
||||
<span>×</span>
|
||||
</button>
|
||||
</div>
|
||||
<form action="post.php" method="post" autocomplete="off">
|
||||
|
||||
<div class="modal-body">
|
||||
<div class="form-group">
|
||||
<label>Project Template Name <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-project-diagram"></i></span>
|
||||
</div>
|
||||
<input type="text" class="form-control" name="name" placeholder="Project Template Name" maxlength="255" required autofocus>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label>Description</label>
|
||||
<div class="input-group">
|
||||
<div class="input-group-prepend">
|
||||
<span class="input-group-text"><i class="fa fa-fw fa-angle-right"></i></span>
|
||||
</div>
|
||||
<input type="text" class="form-control" name="description" placeholder="Description">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button type="submit" name="add_project_template" class="btn btn-primary text-bold"><i class="fas fa-check mr-2"></i>Create</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>
|
||||
44
admin/modals/project_template/project_template_edit.php
Normal file
44
admin/modals/project_template/project_template_edit.php
Normal file
@@ -0,0 +1,44 @@
|
||||
<div class="modal" id="editProjectTemplateModal<?php echo $project_template_id; ?>" tabindex="-1">
|
||||
<div class="modal-dialog">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header bg-dark">
|
||||
<h5 class="modal-title"><i class="fas fa-fw fa-project-diagram mr-2"></i>Editing Project Template: <strong><?php echo $project_template_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="project_template_id" value="<?php echo $project_template_id; ?>">
|
||||
|
||||
<div class="modal-body">
|
||||
<div class="form-group">
|
||||
<label>Project Template Name <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-project-diagram"></i></span>
|
||||
</div>
|
||||
<input type="text" class="form-control" name="name" placeholder="Project Template Name" maxlength="255" value="<?php echo $project_template_name; ?>" required autofocus>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label>Description</label>
|
||||
<div class="input-group">
|
||||
<div class="input-group-prepend">
|
||||
<span class="input-group-text"><i class="fa fa-fw fa-angle-right"></i></span>
|
||||
</div>
|
||||
<input type="text" class="form-control" name="description" placeholder="Description" value="<?php echo $project_template_description; ?>">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="modal-footer">
|
||||
<button type="submit" name="edit_project_template" class="btn btn-primary text-bold"><i class="fas fa-check mr-2"></i>Create</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>
|
||||
@@ -0,0 +1,64 @@
|
||||
<div class="modal" id="addProjectTemplateTicketTemplateModal" tabindex="-1">
|
||||
<div class="modal-dialog">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header bg-dark">
|
||||
<h5 class="modal-title"><i class="fas fa-fw fa-life-ring mr-2"></i>Adding Ticket Template</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="project_template_id" value="<?php echo $project_template_id; ?>">
|
||||
<div class="modal-body">
|
||||
|
||||
<div class="form-group">
|
||||
<label>Ticket Template <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-life-ring"></i></span>
|
||||
</div>
|
||||
<select class="form-control select2" name="ticket_template_id" required>
|
||||
<option value="">- Select a Ticket Template -</option>
|
||||
<?php
|
||||
|
||||
$sql_ticket_templates_select = mysqli_query($mysqli, "SELECT ticket_template_id, ticket_template_name FROM ticket_templates
|
||||
WHERE ticket_template_id NOT IN (
|
||||
SELECT ticket_template_id FROM project_template_ticket_templates
|
||||
WHERE project_template_id = $project_template_id
|
||||
)
|
||||
AND ticket_template_archived_at IS NULL
|
||||
ORDER BY ticket_template_name ASC"
|
||||
);
|
||||
while ($row = mysqli_fetch_array($sql_ticket_templates_select)) {
|
||||
$ticket_template_id_select = intval($row['ticket_template_id']);
|
||||
$ticket_template_name_select = nullable_htmlentities($row['ticket_template_name']);
|
||||
?>
|
||||
<option value="<?php echo $ticket_template_id_select; ?>"><?php echo $ticket_template_name_select; ?></option>
|
||||
<?php
|
||||
}
|
||||
|
||||
?>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label>Order</label>
|
||||
<div class="input-group">
|
||||
<div class="input-group-prepend">
|
||||
<span class="input-group-text"><i class="fa fa-fw fa-sort-numeric-down"></i></span>
|
||||
</div>
|
||||
<input type="text" class="form-control" name="order" value="1">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="modal-footer">
|
||||
<button type="submit" name="add_ticket_template_to_project_template" class="btn btn-primary text-bold"><i class="fas fa-check mr-2"></i>Add</button>
|
||||
<button type="button" class="btn btn-light" data-dismiss="modal"><i class="fas fa-times mr-2"></i>Cancel</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
58
admin/modals/role/role_add.php
Normal file
58
admin/modals/role/role_add.php
Normal file
@@ -0,0 +1,58 @@
|
||||
<div class="modal" id="addRoleModal" tabindex="-1">
|
||||
<div class="modal-dialog">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header bg-dark">
|
||||
<h5 class="modal-title"><i class="fas fa-fw fa-user-shield mr-2"></i>Add new role</h5>
|
||||
<button type="button" class="close text-white" data-dismiss="modal">
|
||||
<span>×</span>
|
||||
</button>
|
||||
</div>
|
||||
<form action="post.php" method="post" enctype="multipart/form-data" autocomplete="off">
|
||||
<input type="hidden" name="csrf_token" value="<?php echo $_SESSION['csrf_token'] ?>">
|
||||
<div class="modal-body">
|
||||
<div class="tab-content">
|
||||
|
||||
<div class="form-group">
|
||||
<label>Name <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-shield"></i></span>
|
||||
</div>
|
||||
<input type="text" class="form-control" name="role_name" placeholder="Role Name" maxlength="200" required>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label>Description <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-chevron-right"></i></span>
|
||||
</div>
|
||||
<input type="text" class="form-control" name="role_description" placeholder="Role Description" maxlength="200" required>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label>Admin Access <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-tools"></i></span>
|
||||
</div>
|
||||
<select class="form-control select2" name="role_is_admin" required>
|
||||
<option value="0">No - edit after creation to set permissions</option>
|
||||
<option value="1">Yes - this role should have full admin access</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button type="submit" name="add_role" class="btn btn-primary text-bold"><i class="fas fa-check mr-2"></i>Save</button>
|
||||
<button type="button" class="btn btn-light" data-dismiss="modal"><i class="fas fa-times mr-2"></i>Cancel</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
153
admin/modals/role/role_edit.php
Normal file
153
admin/modals/role/role_edit.php
Normal file
@@ -0,0 +1,153 @@
|
||||
<?php
|
||||
|
||||
require_once '../../../includes/modal_header.php';
|
||||
|
||||
$role_id = intval($_GET['id']);
|
||||
|
||||
$sql = mysqli_query($mysqli, "SELECT * FROM user_roles WHERE role_id = $role_id LIMIT 1");
|
||||
|
||||
$row = mysqli_fetch_array($sql);
|
||||
$role_name = nullable_htmlentities($row['role_name']);
|
||||
$role_description = nullable_htmlentities($row['role_description']);
|
||||
$role_admin = intval($row['role_is_admin']);
|
||||
|
||||
// Count number of users that have each role
|
||||
$sql_role_user_count = mysqli_query($mysqli, "SELECT COUNT(user_id) FROM users WHERE user_role_id = $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 WHERE user_role_id = $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 = "-";
|
||||
}
|
||||
|
||||
|
||||
// Generate the HTML form content using output buffering.
|
||||
ob_start();
|
||||
?>
|
||||
<div class="modal-header bg-dark">
|
||||
<h5 class="modal-title"><i class="fas fa-fw fa-user-shield mr-2"></i>Editing role:
|
||||
<strong><?php echo $role_name; ?></strong></h5>
|
||||
<button type="button" class="close text-white" data-dismiss="modal">
|
||||
<span>×</span>
|
||||
</button>
|
||||
</div>
|
||||
<form action="post.php" method="post" enctype="multipart/form-data" autocomplete="off">
|
||||
<input type="hidden" name="csrf_token" value="<?php echo $_SESSION['csrf_token'] ?>">
|
||||
<input type="hidden" name="role_id" value="<?php echo $role_id; ?>">
|
||||
<div class="modal-body">
|
||||
|
||||
<ul class="nav nav-pills nav-justified mb-3">
|
||||
<li class="nav-item">
|
||||
<a class="nav-link active" data-toggle="pill" href="#pills-role-details<?php echo $role_id; ?>">Details</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" data-toggle="pill" href="#pills-role-access<?php echo $role_id; ?>">Access</a>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<hr>
|
||||
|
||||
<div class="tab-content">
|
||||
|
||||
<div class="tab-pane fade show active" id="pills-role-details<?php echo $role_id; ?>">
|
||||
|
||||
<div class="form-group">
|
||||
<label>Name <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-shield"></i></span>
|
||||
</div>
|
||||
<input type="text" class="form-control" name="role_name" placeholder="Role Name" maxlength="200" value="<?php echo $role_name; ?>" required>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label>Description <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-chevron-right"></i></span>
|
||||
</div>
|
||||
<input type="text" class="form-control" name="role_description" placeholder="Role Description" maxlength="200" value="<?php echo $role_description; ?>" required>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<div class="form-group">
|
||||
<label>Admin Access <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-tools"></i></span>
|
||||
</div>
|
||||
<select class="form-control select2" name="role_is_admin" required>
|
||||
<option value="1" <?php if ($role_admin) { echo 'selected'; } ?> >Yes - this role should have full admin access</option>
|
||||
<option value="0" <?php if (!$role_admin) { echo 'selected'; } ?>>No - use permissions on the next tab</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="tab-pane fade" id="pills-role-access<?php echo $role_id; ?>">
|
||||
|
||||
<?php if ($role_admin) { ?>
|
||||
<div class="alert alert-warning"><strong>Module permissions do not apply to Admins.</strong></div>
|
||||
<?php } ?>
|
||||
|
||||
<?php
|
||||
|
||||
// Enumerate modules
|
||||
$sql_modules = mysqli_query($mysqli, "SELECT * FROM modules");
|
||||
while ($row_modules = mysqli_fetch_array($sql_modules)) {
|
||||
$module_id = intval($row_modules['module_id']);
|
||||
$module_name = nullable_htmlentities($row_modules['module_name']);
|
||||
$module_name_display = ucfirst(str_replace("module_","",$module_name));
|
||||
$module_description = nullable_htmlentities($row_modules['module_description']);
|
||||
|
||||
// Get permission level for module
|
||||
$module_permission_row = mysqli_fetch_array(mysqli_query($mysqli, "SELECT user_role_permission_level FROM user_role_permissions WHERE module_id = $module_id AND user_role_id = $role_id LIMIT 1"));
|
||||
$module_permission = 0;
|
||||
if ($module_permission_row) {
|
||||
$module_permission = $module_permission_row['user_role_permission_level'];
|
||||
}
|
||||
?>
|
||||
|
||||
<div class="form-group">
|
||||
<label> <?php echo $module_name_display ?> <strong class="text-danger">*</strong></label>
|
||||
<div class="input-group">
|
||||
<select class="form-control select2" name="<?php echo "$module_id##$module_name" ?>" required>
|
||||
<option value="0" <?php if ($module_permission == 0) { echo 'selected'; } ?> >None</option>
|
||||
<option value="1" <?php if ($module_permission == 1) { echo 'selected'; } ?> >Read</option>
|
||||
<option value="2" <?php if ($module_permission == 2) { echo 'selected'; } ?>>Modify (Read, Edit, Archive)</option>
|
||||
<option value="3" <?php if ($module_permission == 3) { echo 'selected'; } ?>>Full (Read, Edit, Archive, Delete)</option>
|
||||
</select>
|
||||
</div>
|
||||
<small class="form-text text-muted"><?php echo $module_description ?></small>
|
||||
|
||||
</div>
|
||||
|
||||
<?php } // End while ?>
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button type="submit" name="edit_role" class="btn btn-primary text-bold"><i class="fas fa-check mr-2"></i>Save</button>
|
||||
<button type="button" class="btn btn-light" data-dismiss="modal"><i class="fas fa-times mr-2"></i>Cancel</button>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
<?php
|
||||
require_once '../../../includes/modal_footer.php';
|
||||
83
admin/modals/software_template/software_template_add.php
Normal file
83
admin/modals/software_template/software_template_add.php
Normal file
@@ -0,0 +1,83 @@
|
||||
<div class="modal" id="addSoftwareTemplateModal" tabindex="-1">
|
||||
<div class="modal-dialog">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header bg-dark">
|
||||
<h5 class="modal-title"><i class="fa fa-fw fa-cube mr-2"></i>New License Template</h5>
|
||||
<button type="button" class="close text-white" data-dismiss="modal">
|
||||
<span>×</span>
|
||||
</button>
|
||||
</div>
|
||||
<form action="post.php" method="post" autocomplete="off">
|
||||
<div class="modal-body">
|
||||
|
||||
<div class="form-group">
|
||||
<label>Template Name <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-cube"></i></span>
|
||||
</div>
|
||||
<input type="text" class="form-control" name="name" placeholder="Software name" maxlength="200" required autofocus>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label>Version</label>
|
||||
<div class="input-group">
|
||||
<div class="input-group-prepend">
|
||||
<span class="input-group-text"><i class="fa fa-fw fa-cube"></i></span>
|
||||
</div>
|
||||
<input type="text" class="form-control" name="version" placeholder="Software version" maxlength="200">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label>Description</label>
|
||||
<div class="input-group">
|
||||
<div class="input-group-prepend">
|
||||
<span class="input-group-text"><i class="fa fa-fw fa-angle-right"></i></span>
|
||||
</div>
|
||||
<input type="text" class="form-control" name="description" placeholder="Short description">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label>Type <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-tag"></i></span>
|
||||
</div>
|
||||
<select class="form-control select2" name="type" required>
|
||||
<option value="">- Type -</option>
|
||||
<?php foreach($software_types_array as $software_type) { ?>
|
||||
<option><?php echo $software_type; ?></option>
|
||||
<?php } ?>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label>License Type</label>
|
||||
<div class="input-group">
|
||||
<div class="input-group-prepend">
|
||||
<span class="input-group-text"><i class="fa fa-fw fa-cube"></i></span>
|
||||
</div>
|
||||
<select class="form-control select2" name="license_type">
|
||||
<option value="">- Select a License Type -</option>
|
||||
<?php foreach($license_types_array as $license_type) { ?>
|
||||
<option><?php echo $license_type; ?></option>
|
||||
<?php } ?>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<textarea class="form-control" rows="8" placeholder="Enter some notes" name="notes"></textarea>
|
||||
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button type="submit" name="add_software_template" 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="fa fa-times mr-2"></i>Cancel</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
99
admin/modals/software_template/software_template_edit.php
Normal file
99
admin/modals/software_template/software_template_edit.php
Normal file
@@ -0,0 +1,99 @@
|
||||
<?php
|
||||
|
||||
require_once '../../../includes/modal_header.php';
|
||||
|
||||
$software_template_id = intval($_GET['id']);
|
||||
|
||||
$sql = mysqli_query($mysqli, "SELECT * FROM software_templates WHERE software_template_id = $software_template_id LIMIT 1");
|
||||
$row = mysqli_fetch_array($sql);
|
||||
$software_name = nullable_htmlentities($row['software_template_name']);
|
||||
$software_version = nullable_htmlentities($row['software_template_version']);
|
||||
$software_description = nullable_htmlentities($row['software_template_description']);
|
||||
$software_type = nullable_htmlentities($row['software_template_type']);
|
||||
$software_license_type = nullable_htmlentities($row['software_template_license_type']);
|
||||
$software_notes = nullable_htmlentities($row['software_template_notes']);
|
||||
|
||||
// Generate the HTML form content using output buffering.
|
||||
ob_start();
|
||||
?>
|
||||
|
||||
<div class="modal-header bg-dark">
|
||||
<h5 class="modal-title"><i class="fa fa-fw fa-cube mr-2"></i>Editing template: <strong><?php echo $software_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="software_template_id" value="<?php echo $software_template_id; ?>">
|
||||
<div class="modal-body">
|
||||
|
||||
<div class="form-group">
|
||||
<label>Template Name <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-cube"></i></span>
|
||||
</div>
|
||||
<input type="text" class="form-control" name="name" placeholder="Software name" maxlength="200" value="<?php echo $software_name; ?>" required>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label>Version</label>
|
||||
<div class="input-group">
|
||||
<div class="input-group-prepend">
|
||||
<span class="input-group-text"><i class="fa fa-fw fa-cube"></i></span>
|
||||
</div>
|
||||
<input type="text" class="form-control" name="version" placeholder="Software version" maxlength="200" value="<?php echo $software_version; ?>">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label>Description</label>
|
||||
<div class="input-group">
|
||||
<div class="input-group-prepend">
|
||||
<span class="input-group-text"><i class="fa fa-fw fa-angle-right"></i></span>
|
||||
</div>
|
||||
<input type="text" class="form-control" name="description" placeholder="Short description" value="<?php echo $software_description; ?>">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label>Type <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-tag"></i></span>
|
||||
</div>
|
||||
<select class="form-control select2" name="type" required>
|
||||
<?php foreach($software_types_array as $software_type_select) { ?>
|
||||
<option <?php if($software_type == $software_type_select) { echo "selected"; } ?>><?php echo $software_type_select; ?></option>
|
||||
<?php } ?>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label>License Type</label>
|
||||
<div class="input-group">
|
||||
<div class="input-group-prepend">
|
||||
<span class="input-group-text"><i class="fa fa-fw fa-cube"></i></span>
|
||||
</div>
|
||||
<select class="form-control select2" name="license_type">
|
||||
<option value="">- Select a License Type -</option>
|
||||
<?php foreach($license_types_array as $license_type_select) { ?>
|
||||
<option <?php if($license_type_select == $software_license_type){ echo "selected"; } ?>><?php echo $license_type_select; ?></option>
|
||||
<?php } ?>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<textarea class="form-control" rows="8" placeholder="Enter some notes" name="notes"><?php echo $software_notes; ?></textarea>
|
||||
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button type="submit" name="edit_software_template" 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>
|
||||
|
||||
<?php
|
||||
require_once '../../../includes/modal_footer.php';
|
||||
94
admin/modals/tag/tag_add.php
Normal file
94
admin/modals/tag/tag_add.php
Normal file
@@ -0,0 +1,94 @@
|
||||
<?php
|
||||
|
||||
require_once '../../../includes/modal_header.php';
|
||||
|
||||
$type_display = '';
|
||||
|
||||
if (isset($_GET['type'])) {
|
||||
$type = intval($_GET['type']);
|
||||
|
||||
if ($type === 1) {
|
||||
$type_display = "Client";
|
||||
} elseif($type === 2) {
|
||||
$type_display = "Location";
|
||||
} elseif ($type === 3) {
|
||||
$type_display = "Contact";
|
||||
} elseif ($type === 4) {
|
||||
$type_display = "Credential";
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
||||
|
||||
<div class="modal-header bg-dark">
|
||||
<h5 class="modal-title"><i class="fas fa-fw fa-tag mr-2"></i>New <strong><?= $type_display ?></strong> Tag</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="type" value="<?php echo $type; ?>">
|
||||
<div class="modal-body">
|
||||
<div class="form-group">
|
||||
<label>Name <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-tag"></i></span>
|
||||
</div>
|
||||
<input type="text" class="form-control" name="name" placeholder="Tag name" maxlength="200" required autofocus>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<?php if (isset($_GET['type'])) { ?>
|
||||
|
||||
<input type="hidden" name="type" value="<?= $type ?>">
|
||||
|
||||
<?php } else { ?>
|
||||
|
||||
<div class="form-group">
|
||||
<label>Type <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-th"></i></span>
|
||||
</div>
|
||||
<select class="form-control select2" name="type" required>
|
||||
<option value="">- Type -</option>
|
||||
<option value="1">Client Tag</option>
|
||||
<option value="2">Location Tag</option>
|
||||
<option value="3">Contact Tag</option>
|
||||
<option value="4">Credential Tag</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<?php } ?>
|
||||
|
||||
<div class="form-group">
|
||||
<label>Color <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-paint-brush"></i></span>
|
||||
</div>
|
||||
<input type="color" class="form-control col-3" name="color" required>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label>Icon</label>
|
||||
<div class="input-group">
|
||||
<div class="input-group-prepend">
|
||||
<span class="input-group-text"><i class="fa fa-fw fa-image"></i></span>
|
||||
</div>
|
||||
<input type="text" class="form-control" name="icon" placeholder="Icon ex handshake">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button type="submit" name="add_tag" class="btn btn-primary text-bold"><i class="fas fa-check mr-2"></i>Create</button>
|
||||
<button type="button" class="btn btn-light" data-dismiss="modal"><i class="fas fa-times mr-2"></i>Cancel</button>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
<?php
|
||||
require_once '../../../includes/modal_footer.php';
|
||||
82
admin/modals/tag/tag_edit.php
Normal file
82
admin/modals/tag/tag_edit.php
Normal file
@@ -0,0 +1,82 @@
|
||||
<?php
|
||||
|
||||
require_once '../../../includes/modal_header.php';
|
||||
|
||||
$tag_id = intval($_GET['id']);
|
||||
|
||||
$sql = mysqli_query($mysqli, "SELECT * FROM tags WHERE tag_id = $tag_id LIMIT 1");
|
||||
|
||||
$row = mysqli_fetch_array($sql);
|
||||
$tag_name = nullable_htmlentities($row['tag_name']);
|
||||
$tag_type = intval($row['tag_type']);
|
||||
$tag_color = nullable_htmlentities($row['tag_color']);
|
||||
$tag_icon = nullable_htmlentities($row['tag_icon']);
|
||||
|
||||
// Generate the HTML form content using output buffering.
|
||||
ob_start();
|
||||
?>
|
||||
<div class="modal-header bg-dark">
|
||||
<h5 class="modal-title"><i class="fas fa-fw fa-tag mr-2"></i>Editing tag: <strong><?php echo $tag_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="tag_id" value="<?php echo $tag_id; ?>">
|
||||
<div class="modal-body">
|
||||
|
||||
<div class="form-group">
|
||||
<label>Name <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-tag"></i></span>
|
||||
</div>
|
||||
<input type="text" class="form-control" name="name" maxlength="200" value="<?php echo $tag_name; ?>" required>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label>Type <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-th"></i></span>
|
||||
</div>
|
||||
<select class="form-control select2" name="type" required>
|
||||
<option value="">- Type -</option>
|
||||
<option value="1" <?php if ($tag_type == 1) { echo "selected"; } ?>>Client Tag</option>
|
||||
<option value="2" <?php if ($tag_type == 2) { echo "selected"; } ?>>Location Tag</option>
|
||||
<option value="3" <?php if ($tag_type == 3) { echo "selected"; } ?>>Contact Tag</option>
|
||||
<option value="4" <?php if ($tag_type == 4) { echo "selected"; } ?>>Credential Tag</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label>Color <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-paint-brush"></i></span>
|
||||
</div>
|
||||
<input type="color" class="form-control col-3" name="color" value="<?php echo $tag_color; ?>" required>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label>Icon</label>
|
||||
<div class="input-group">
|
||||
<div class="input-group-prepend">
|
||||
<span class="input-group-text"><i class="fa fa-fw fa-image"></i></span>
|
||||
</div>
|
||||
<input type="text" class="form-control" name="icon" placeholder="Icon ex handshake" value="<?php echo $tag_icon; ?>">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button type="submit" name="edit_tag" class="btn btn-primary text-bold"><i class="fas fa-check mr-2"></i>Save</button>
|
||||
<button type="button" class="btn btn-light" data-dismiss="modal"><i class="fas fa-times mr-2"></i>Cancel</button>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
<?php
|
||||
require_once '../../../includes/modal_footer.php';
|
||||
30
admin/modals/tax/tax_add.php
Normal file
30
admin/modals/tax/tax_add.php
Normal file
@@ -0,0 +1,30 @@
|
||||
<div class="modal" id="addTaxModal" tabindex="-1">
|
||||
<div class="modal-dialog">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header bg-dark">
|
||||
<h5 class="modal-title"><i class="fas fa-fw fa-balance-scale mr-2"></i>New Tax</h5>
|
||||
<button type="button" class="close text-white" data-dismiss="modal">
|
||||
<span aria-hidden="true">×</span>
|
||||
</button>
|
||||
</div>
|
||||
<form action="post.php" method="post" autocomplete="off">
|
||||
<input type="hidden" name="csrf_token" value="<?php echo $_SESSION['csrf_token'] ?>">
|
||||
|
||||
<div class="modal-body">
|
||||
<div class="form-group">
|
||||
<label>Name <strong class="text-danger">*</strong></label>
|
||||
<input type="text" class="form-control" name="name" placeholder="Tax name" maxlength="200" required autofocus>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label>Percent <strong class="text-danger">*</strong></label>
|
||||
<input type="number" min="0" step="any" class="form-control col-md-4" name="percent">
|
||||
</div>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button type="submit" name="add_tax" 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>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
46
admin/modals/tax/tax_edit.php
Normal file
46
admin/modals/tax/tax_edit.php
Normal file
@@ -0,0 +1,46 @@
|
||||
<?php
|
||||
|
||||
require_once '../../../includes/modal_header.php';
|
||||
|
||||
$tax_id = intval($_GET['id']);
|
||||
|
||||
$sql = mysqli_query($mysqli, "SELECT * FROM taxes WHERE tax_id = $tax_id LIMIT 1");
|
||||
$row = mysqli_fetch_array($sql);
|
||||
$tax_name = nullable_htmlentities($row['tax_name']);
|
||||
$tax_percent = floatval($row['tax_percent']);
|
||||
|
||||
// Generate the HTML form content using output buffering.
|
||||
ob_start();
|
||||
?>
|
||||
|
||||
<div class="modal-header bg-dark">
|
||||
<h5 class="modal-title"><i class="fas fa-fw fa-balance-scale mr-2"></i>Editing tax: <strong><?php echo $tax_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="csrf_token" value="<?php echo $_SESSION['csrf_token'] ?>">
|
||||
<input type="hidden" name="tax_id" value="<?php echo $tax_id; ?>">
|
||||
|
||||
<div class="modal-body">
|
||||
|
||||
<div class="form-group">
|
||||
<label>Name <strong class="text-danger">*</strong></label>
|
||||
<input type="text" class="form-control" name="name" maxlength="200" value="<?php echo $tax_name; ?>" required>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label>Percent <strong class="text-danger">*</strong></label>
|
||||
<input type="number" min="0" step="any" class="form-control col-md-4" name="percent" value="<?php echo $tax_percent; ?>">
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button type="submit" name="edit_tax" class="btn btn-primary text-bold"><i class="fas fa-check mr-2"></i>Save</button>
|
||||
<button type="button" class="btn btn-light" data-dismiss="modal"><i class="fas fa-times mr-2"></i>Cancel</button>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
<?php
|
||||
require_once '../../../includes/modal_footer.php';
|
||||
42
admin/modals/ticket_status/ticket_status_add.php
Normal file
42
admin/modals/ticket_status/ticket_status_add.php
Normal file
@@ -0,0 +1,42 @@
|
||||
<div class="modal" id="addTicketStatusModal" tabindex="-1">
|
||||
<div class="modal-dialog">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header bg-dark">
|
||||
<h5 class="modal-title"><i class="fas fa-fw fa-info-circle mr-2"></i>New Ticket Status</h5>
|
||||
<button type="button" class="close text-white" data-dismiss="modal">
|
||||
<span>×</span>
|
||||
</button>
|
||||
</div>
|
||||
<form action="post.php" method="post" autocomplete="off">
|
||||
|
||||
<div class="modal-body">
|
||||
|
||||
<div class="form-group">
|
||||
<label>Name <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-info-circle"></i></span>
|
||||
</div>
|
||||
<input type="text" class="form-control" name="name" placeholder="Ticket Status name" maxlength="200" required autofocus>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label>Color <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-paint-brush"></i></span>
|
||||
</div>
|
||||
<input type="color" class="form-control col-3" name="color" required>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button type="submit" name="add_ticket_status" class="btn btn-primary text-bold"><i class="fas fa-check mr-2"></i>Create</button>
|
||||
<button type="button" class="btn btn-light" data-dismiss="modal"><i class="fas fa-times mr-2"></i>Cancel</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
79
admin/modals/ticket_status/ticket_status_edit.php
Normal file
79
admin/modals/ticket_status/ticket_status_edit.php
Normal file
@@ -0,0 +1,79 @@
|
||||
<?php
|
||||
|
||||
require_once '../../../includes/modal_header.php';
|
||||
|
||||
$ticket_status_id = intval($_GET['id']);
|
||||
|
||||
$sql = mysqli_query($mysqli, "SELECT * FROM ticket_statuses WHERE ticket_status_id = $ticket_status_id LIMIT 1");
|
||||
$row = mysqli_fetch_array($sql);
|
||||
$ticket_status_name = nullable_htmlentities($row['ticket_status_name']);
|
||||
$ticket_status_color = nullable_htmlentities($row['ticket_status_color']);
|
||||
$ticket_status_order = intval($row['ticket_status_order']);
|
||||
$ticket_status_active = intval($row['ticket_status_active']);
|
||||
|
||||
// Generate the HTML form content using output buffering.
|
||||
ob_start();
|
||||
?>
|
||||
|
||||
<div class="modal-header bg-dark">
|
||||
<h5 class="modal-title"><i class="fas fa-fw fa-info-circle mr-2"></i>Editing Ticket Status: <strong><?php echo $ticket_status_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="ticket_status_id" value="<?php echo $ticket_status_id; ?>">
|
||||
<div class="modal-body">
|
||||
|
||||
<div class="form-group">
|
||||
<label>Name <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-tag"></i></span>
|
||||
</div>
|
||||
<input type="text" class="form-control" name="name" maxlength="200" value="<?php echo $ticket_status_name; ?>" required <?php if ($ticket_status_id <= 5) { echo "readonly"; } ?>>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label>Color <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-paint-brush"></i></span>
|
||||
</div>
|
||||
<input type="color" class="form-control col-3" name="color" value="<?php echo $ticket_status_color; ?>" required>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label>Order</label>
|
||||
<div class="input-group">
|
||||
<div class="input-group-prepend">
|
||||
<span class="input-group-text"><i class="fa fa-fw fa-sort-numeric-down"></i></span>
|
||||
</div>
|
||||
<input type="number" class="form-control" name="order" placeholder="Leave blank for no order" value="<?php echo $ticket_status_order; ?>">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label>Status <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-info-circle"></i></span>
|
||||
</div>
|
||||
<select class="form-control select2" name="status" required>
|
||||
<option <?php if ($ticket_status_active == 1) { echo "selected"; } ?> value="1">Active</option>
|
||||
<option <?php if ($ticket_status_active == 0) { echo "selected"; } ?> value="0" <?php if ($ticket_status_id <= 5) { echo "disabled"; } ?>>Inactive</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button type="submit" name="edit_ticket_status" class="btn btn-primary text-bold"><i class="fas fa-check mr-2"></i>Save</button>
|
||||
<button type="button" class="btn btn-light" data-dismiss="modal"><i class="fas fa-times mr-2"></i>Cancel</button>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
<?php
|
||||
require_once '../../../includes/modal_footer.php';
|
||||
75
admin/modals/ticket_template/ticket_template_add.php
Normal file
75
admin/modals/ticket_template/ticket_template_add.php
Normal file
@@ -0,0 +1,75 @@
|
||||
<div class="modal" id="addTicketTemplateModal" tabindex="-1">
|
||||
<div class="modal-dialog modal-lg">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header bg-dark">
|
||||
<h5 class="modal-title"><i class="fa fa-fw fa-life-ring mr-2"></i>Creating Ticket Template</h5>
|
||||
<button type="button" class="close text-white" data-dismiss="modal">
|
||||
<span>×</span>
|
||||
</button>
|
||||
</div>
|
||||
<form action="post.php" method="post" autocomplete="off">
|
||||
<div class="modal-body">
|
||||
|
||||
<div class="form-group">
|
||||
<label>Template Name <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-life-ring"></i></span>
|
||||
</div>
|
||||
<input type="text" class="form-control" name="name" placeholder="Template name" maxlength="200" required autofocus>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label>Subject</label>
|
||||
<div class="input-group">
|
||||
<div class="input-group-prepend">
|
||||
<span class="input-group-text"><i class="fa fa-fw fa-angle-right"></i></span>
|
||||
</div>
|
||||
<input type="text" class="form-control" name="subject" placeholder="Subject" maxlength="500">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<textarea class="form-control tinymceTicket" name="details"></textarea>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label>Description</label>
|
||||
<div class="input-group">
|
||||
<div class="input-group-prepend">
|
||||
<span class="input-group-text"><i class="fa fa-fw fa-angle-right"></i></span>
|
||||
</div>
|
||||
<input type="text" class="form-control" name="description" placeholder="Short description">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label>Add it to a Project Template?</label>
|
||||
<div class="input-group">
|
||||
<div class="input-group-prepend">
|
||||
<span class="input-group-text"><i class="fa fa-fw fa-project-diagram"></i></span>
|
||||
</div>
|
||||
<select class="form-control select2" name="project_template">
|
||||
<option value="0">- No -</option>
|
||||
<?php
|
||||
|
||||
$sql_project_templates = mysqli_query($mysqli, "SELECT * FROM project_templates WHERE project_template_archived_at IS NULL ORDER BY project_template_name ASC");
|
||||
while ($row = mysqli_fetch_array($sql_project_templates)) {
|
||||
$project_template_id_select = intval($row['project_template_id']);
|
||||
$project_template_name_select = nullable_htmlentities($row['project_template_name']); ?>
|
||||
<option value="<?php echo $project_template_id_select; ?>"><?php echo $project_template_name_select; ?></option>
|
||||
|
||||
<?php } ?>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button type="submit" name="add_ticket_template" 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="fa fa-times mr-2"></i>Cancel</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
57
admin/modals/ticket_template/ticket_template_edit.php
Normal file
57
admin/modals/ticket_template/ticket_template_edit.php
Normal file
@@ -0,0 +1,57 @@
|
||||
<div class="modal" id="editTicketTemplateModal" tabindex="-1">
|
||||
|
||||
<div class="modal-dialog modal-lg">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header bg-dark">
|
||||
<h5 class="modal-title"><i class="fa fa-fw fa-life-ring mr-2"></i>Editing Ticket Template: <?php echo $ticket_template_name; ?></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="ticket_template_id" value="<?php echo $ticket_template_id; ?>">
|
||||
<div class="modal-body">
|
||||
|
||||
<div class="form-group">
|
||||
<label>Template Name <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-life-ring"></i></span>
|
||||
</div>
|
||||
<input type="text" class="form-control" name="name" maxlength="200" value="<?php echo $ticket_template_name; ?>" placeholder="Template name" required autofocus>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label>Subject</label>
|
||||
<div class="input-group">
|
||||
<div class="input-group-prepend">
|
||||
<span class="input-group-text"><i class="fa fa-fw fa-angle-right"></i></span>
|
||||
</div>
|
||||
<input type="text" class="form-control" name="subject" maxlength="500" value="<?php echo $ticket_template_subject; ?>" placeholder="Subject">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<textarea class="form-control tinymceTicket" name="details"><?php echo $ticket_template_details; ?></textarea>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label>Description</label>
|
||||
<div class="input-group">
|
||||
<div class="input-group-prepend">
|
||||
<span class="input-group-text"><i class="fa fa-fw fa-angle-right"></i></span>
|
||||
</div>
|
||||
<input type="text" class="form-control" name="description" value="<?php echo $ticket_template_description; ?>" placeholder="Short description">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button type="submit" name="edit_ticket_template" 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>
|
||||
62
admin/modals/ticket_template/ticket_template_task_edit.php
Normal file
62
admin/modals/ticket_template/ticket_template_task_edit.php
Normal file
@@ -0,0 +1,62 @@
|
||||
<?php
|
||||
|
||||
require_once '../../../includes/modal_header.php';
|
||||
|
||||
$task_template_id = intval($_GET['id']);
|
||||
|
||||
$sql = mysqli_query($mysqli, "SELECT * FROM task_templates WHERE task_template_id = $task_template_id LIMIT 1");
|
||||
|
||||
$row = mysqli_fetch_array($sql);
|
||||
$task_template_name = nullable_htmlentities($row['task_template_name']);
|
||||
$task_template_order = intval($row['task_template_order']);
|
||||
$task_template_completion_estimate = intval($row['task_template_completion_estimate']);
|
||||
//$task_template_description = nullable_htmlentities($row['task_template_description']);
|
||||
|
||||
// Generate the HTML form content using output buffering.
|
||||
ob_start();
|
||||
|
||||
?>
|
||||
|
||||
<div class="modal-header bg-dark">
|
||||
<h5 class="modal-title"><i class="fa fa-fw fa-tasks mr-2"></i>Editing task</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="task_template_id" value="<?php echo $task_template_id; ?>">
|
||||
|
||||
<div class="modal-body">
|
||||
|
||||
<div class="form-group">
|
||||
<label>Name <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-tag"></i></span>
|
||||
</div>
|
||||
<input type="text" class="form-control" name="name" placeholder="Name the task" maxlength="255" value="<?php echo $task_template_name; ?>" required autofocus>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label>Estimated Completion Time <span class="text-secondary">(Minutes)</span></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="completion_estimate" placeholder="Estimated time to complete task in mins" value="<?php echo $task_template_completion_estimate; ?>">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="modal-footer">
|
||||
<button type="submit" name="edit_ticket_template_task" 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>
|
||||
|
||||
<?php
|
||||
|
||||
require_once '../../../includes/modal_footer.php';
|
||||
156
admin/modals/user/user_add.php
Normal file
156
admin/modals/user/user_add.php
Normal file
@@ -0,0 +1,156 @@
|
||||
<div class="modal" id="addUserModal" tabindex="-1">
|
||||
<div class="modal-dialog">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header bg-dark">
|
||||
<h5 class="modal-title"><i class="fas fa-fw fa-user-plus mr-2"></i>New User</h5>
|
||||
<button type="button" class="close text-white" data-dismiss="modal">
|
||||
<span>×</span>
|
||||
</button>
|
||||
</div>
|
||||
<form action="post.php" method="post" enctype="multipart/form-data" autocomplete="off">
|
||||
<input type="hidden" name="csrf_token" value="<?php echo $_SESSION['csrf_token'] ?>">
|
||||
<div class="modal-body">
|
||||
|
||||
<ul class="nav nav-pills nav-justified mb-3">
|
||||
<li class="nav-item">
|
||||
<a class="nav-link active" data-toggle="pill" href="#pills-user-details">Details</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" data-toggle="pill" href="#pills-user-access">Restrict Access</a>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<hr>
|
||||
|
||||
<div class="tab-content">
|
||||
|
||||
<div class="tab-pane fade show active" id="pills-user-details">
|
||||
|
||||
<div class="form-group">
|
||||
<label>Name <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>
|
||||
<input type="text" class="form-control" name="name" placeholder="Full Name" maxlength="200" required autofocus>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label>Email <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-envelope"></i></span>
|
||||
</div>
|
||||
<input type="email" class="form-control" name="email" placeholder="Email Address" maxlength="200" required>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label>Password <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-lock"></i></span>
|
||||
</div>
|
||||
<input type="password" class="form-control" data-toggle="password" name="password" id="password" placeholder="Enter a Password" autocomplete="new-password" minlength="8" required>
|
||||
<div class="input-group-append">
|
||||
<span class="input-group-text"><i class="fa fa-fw fa-eye"></i></span>
|
||||
</div>
|
||||
<div class="input-group-append">
|
||||
<span class="btn btn-default"><i class="fa fa-fw fa-question" onclick="generatePassword()"></i></span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label>Role <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-shield"></i></span>
|
||||
</div>
|
||||
<select class="form-control select2" name="role" required>
|
||||
<option value="">- Role -</option>
|
||||
<?php
|
||||
$sql_user_roles = mysqli_query($mysqli, "SELECT * FROM user_roles WHERE role_archived_at IS NULL");
|
||||
while ($row = mysqli_fetch_array($sql_user_roles)) {
|
||||
$role_id = intval($row['role_id']);
|
||||
$role_name = nullable_htmlentities($row['role_name']);
|
||||
|
||||
?>
|
||||
<option value="<?php echo $role_id; ?>"><?php echo $role_name; ?></option>
|
||||
<?php } ?>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label>Avatar</label>
|
||||
<input type="file" class="form-control-file" accept="image/*" name="file">
|
||||
</div>
|
||||
|
||||
<div class="form-group" <?php if(empty($config_smtp_host)) { echo "hidden"; } ?>>
|
||||
<div class="custom-control custom-checkbox">
|
||||
<input class="custom-control-input" type="checkbox" id="sendEmailCheckBox" name="send_email" value="" checked>
|
||||
<label for="sendEmailCheckBox" class="custom-control-label">
|
||||
Send user e-mail with login details?
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<div class="custom-control custom-checkbox">
|
||||
<input class="custom-control-input" type="checkbox" id="forceMFACheckBox" name="force_mfa" value=1>
|
||||
<label for="forceMFACheckBox" class="custom-control-label">
|
||||
Force MFA
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="tab-pane fade" id="pills-user-access">
|
||||
|
||||
<div class="alert alert-info">
|
||||
Check boxes to authorize user client access. No boxes grant full client access. Admin users are unaffected.
|
||||
</div>
|
||||
|
||||
<ul class="list-group">
|
||||
<li class="list-group-item bg-dark">
|
||||
<div class="form-check">
|
||||
<input type="checkbox" class="form-check-input" onclick="this.closest('.tab-pane').querySelectorAll('.client-checkbox').forEach(checkbox => checkbox.checked = this.checked);">
|
||||
<label class="form-check-label ml-3"><strong>Restrict Access to Clients</strong></label>
|
||||
</div>
|
||||
</li>
|
||||
|
||||
<?php
|
||||
|
||||
$sql_client_select = mysqli_query($mysqli, "SELECT * FROM clients WHERE client_archived_at IS NULL ORDER BY client_name ASC");
|
||||
while ($row = mysqli_fetch_array($sql_client_select)) {
|
||||
$client_id = intval($row['client_id']);
|
||||
$client_name = nullable_htmlentities($row['client_name']);
|
||||
|
||||
?>
|
||||
<li class="list-group-item">
|
||||
<div class="form-check">
|
||||
<input type="checkbox" class="form-check-input client-checkbox" name="clients[]" value="<?php echo $client_id; ?>">
|
||||
<label class="form-check-label ml-3"><?php echo $client_name; ?></label>
|
||||
</div>
|
||||
</li>
|
||||
|
||||
<?php } ?>
|
||||
|
||||
</ul>
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button type="submit" name="add_user" class="btn btn-primary text-bold"><i class="fas fa-check mr-2"></i>Create</button>
|
||||
<button type="button" class="btn btn-light" data-dismiss="modal"><i class="fas fa-times mr-2"></i>Cancel</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
31
admin/modals/user/user_all_reset_password.php
Normal file
31
admin/modals/user/user_all_reset_password.php
Normal file
@@ -0,0 +1,31 @@
|
||||
<div class="modal" id="resetAllUserPassModal" tabindex="-1">
|
||||
<div class="modal-dialog modal-lg">
|
||||
<div class="modal-content">
|
||||
<div class="modal-body">
|
||||
<div class="mb-4" style="text-align: center;">
|
||||
<i class="far fas fa-10x fa-skull-crossbones text-danger mb-3 mt-3"></i>
|
||||
<h2>Incident Response: Agent Password Reset</h2>
|
||||
<br>
|
||||
<div class="alert alert-danger" role="alert">
|
||||
<b>This is a potentially destructive function.<br>It is intended to be used as part of a potential security incident.</b>
|
||||
</div>
|
||||
<h6 class="mb-4 text-secondary"><b>All ITFlow agent passwords will be reset and shown to you </b><i>(except yours - change yours first!)</i>.<br/><br/>You should communicate temporary passwords to agents out of band (e.g. via a phone call) and require they are changed ASAP.</h6>
|
||||
<form action="post.php" method="POST">
|
||||
<input type="hidden" name="csrf_token" value="<?php echo $_SESSION['csrf_token'] ?>">
|
||||
<div class="row col-7 offset-4">
|
||||
<div class="input-group">
|
||||
<div class="input-group-prepend">
|
||||
<input type="password" class="form-control" placeholder="Enter your account password to continue" name="admin_password" required>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<br>
|
||||
<button class="btn btn-danger" type="submit" name="ir_reset_user_password"><i class="fas fa-fw fa-key mr-2"></i>Reset passwords</button>
|
||||
</form>
|
||||
</div>
|
||||
<button type="button" class="btn btn-outline-secondary btn-lg px-5 mr-4" data-dismiss="modal">Cancel</button>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
83
admin/modals/user/user_archive.php
Normal file
83
admin/modals/user/user_archive.php
Normal file
@@ -0,0 +1,83 @@
|
||||
<?php
|
||||
|
||||
require_once '../../../includes/modal_header.php';
|
||||
|
||||
$user_id = intval($_GET['id']);
|
||||
|
||||
$sql = mysqli_query($mysqli, "SELECT * FROM users WHERE users.user_id = $user_id LIMIT 1");
|
||||
|
||||
$row = mysqli_fetch_array($sql);
|
||||
$user_name = nullable_htmlentities($row['user_name']);
|
||||
$user_email = nullable_htmlentities($row['user_email']);
|
||||
$user_avatar = nullable_htmlentities($row['user_avatar']);
|
||||
$user_initials = nullable_htmlentities(initials($user_name));
|
||||
|
||||
$sql_related_tickets = mysqli_query($mysqli, "SELECT * FROM tickets
|
||||
WHERE ticket_assigned_to = $user_id AND ticket_resolved_at IS NULL AND ticket_closed_at IS NULL");
|
||||
|
||||
$ticket_count = mysqli_num_rows($sql_related_tickets);
|
||||
|
||||
// Related Recurring Tickets Query
|
||||
$sql_related_recurring_tickets = mysqli_query($mysqli, "SELECT * FROM recurring_tickets WHERE recurring_ticket_assigned_to = $user_id");
|
||||
|
||||
$recurring_ticket_count = mysqli_num_rows($sql_related_recurring_tickets);
|
||||
|
||||
// Generate the HTML form content using output buffering.
|
||||
ob_start();
|
||||
?>
|
||||
<div class="modal-header bg-dark">
|
||||
<h5 class="modal-title"><i class="fas fa-fw fa-user-slash mr-2"></i>Archiving user:
|
||||
<strong><?php echo $user_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="csrf_token" value="<?php echo $_SESSION['csrf_token'] ?>">
|
||||
<input type="hidden" name="user_id" value="<?php echo $user_id; ?>">
|
||||
<div class="modal-body">
|
||||
|
||||
|
||||
<center class="mb-3">
|
||||
<?php if (!empty($user_avatar)) { ?>
|
||||
<img class="img-fluid" src="<?php echo "../uploads/users/$user_id/$user_avatar"; ?>">
|
||||
<?php } else { ?>
|
||||
<span class="fa-stack fa-4x">
|
||||
<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>
|
||||
<?php } ?>
|
||||
</center>
|
||||
|
||||
|
||||
<div class="form-group">
|
||||
<label>Reassign <?= $ticket_count ?> Open Tickets and <?= $recurring_ticket_count ?> Recurring Tickets To:</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="ticket_assign" required>
|
||||
<option value="0">No one</option>
|
||||
<?php
|
||||
$sql_users = mysqli_query($mysqli, "SELECT * FROM users WHERE user_type = 1 AND user_archived_at IS NULL");
|
||||
while ($row = mysqli_fetch_array($sql_users)) {
|
||||
$user_id_select = intval($row['user_id']);
|
||||
$user_name_select = nullable_htmlentities($row['user_name']);
|
||||
|
||||
?>
|
||||
<option value="<?= $user_id_select ?>"><?= $user_name_select ?></option>
|
||||
<?php } ?>
|
||||
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button type="submit" name="archive_user" class="btn btn-danger text-bold"><i class="fas fa-archive mr-2"></i>Archive</button>
|
||||
<button type="button" class="btn btn-light" data-dismiss="modal"><i class="fas fa-times mr-2"></i>Cancel</button>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
<?php
|
||||
require_once "../../../includes/modal_footer.php";
|
||||
204
admin/modals/user/user_edit.php
Normal file
204
admin/modals/user/user_edit.php
Normal file
@@ -0,0 +1,204 @@
|
||||
<?php
|
||||
|
||||
require_once '../../../includes/modal_header.php';
|
||||
|
||||
$user_id = intval($_GET['id']);
|
||||
|
||||
$sql = mysqli_query($mysqli, "SELECT * FROM users
|
||||
LEFT JOIN user_settings ON users.user_id = user_settings.user_id
|
||||
WHERE users.user_id = $user_id LIMIT 1"
|
||||
);
|
||||
|
||||
$row = mysqli_fetch_array($sql);
|
||||
$user_name = nullable_htmlentities($row['user_name']);
|
||||
$user_email = nullable_htmlentities($row['user_email']);
|
||||
$user_avatar = nullable_htmlentities($row['user_avatar']);
|
||||
$user_token = nullable_htmlentities($row['user_token']);
|
||||
$user_config_force_mfa = intval($row['user_config_force_mfa']);
|
||||
$user_role_id = intval($row['user_role_id']);
|
||||
$user_initials = nullable_htmlentities(initials($user_name));
|
||||
|
||||
// Get User Client Access Permissions
|
||||
$user_client_access_sql = mysqli_query($mysqli,"SELECT client_id FROM user_client_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']);
|
||||
}
|
||||
|
||||
// Generate the HTML form content using output buffering.
|
||||
ob_start();
|
||||
?>
|
||||
<div class="modal-header bg-dark">
|
||||
<h5 class="modal-title"><i class="fas fa-fw fa-user-edit mr-2"></i>Editing user:
|
||||
<strong><?php echo $user_name; ?></strong></h5>
|
||||
<button type="button" class="close text-white" data-dismiss="modal">
|
||||
<span>×</span>
|
||||
</button>
|
||||
</div>
|
||||
<form action="post.php" method="post" enctype="multipart/form-data" autocomplete="off">
|
||||
<input type="hidden" name="csrf_token" value="<?php echo $_SESSION['csrf_token'] ?>">
|
||||
<input type="hidden" name="user_id" value="<?php echo $user_id; ?>">
|
||||
<div class="modal-body">
|
||||
|
||||
<ul class="nav nav-pills nav-justified mb-3">
|
||||
<li class="nav-item">
|
||||
<a class="nav-link active" data-toggle="pill" href="#pills-user-details<?php echo $user_id; ?>">Details</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" data-toggle="pill" href="#pills-user-access<?php echo $user_id; ?>">Restrict Access</a>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<hr>
|
||||
|
||||
<div class="tab-content">
|
||||
|
||||
<div class="tab-pane fade show active" id="pills-user-details<?php echo $user_id; ?>">
|
||||
|
||||
<center class="mb-3">
|
||||
<?php if (!empty($user_avatar)) { ?>
|
||||
<img class="img-fluid" src="<?php echo "../uploads/users/$user_id/$user_avatar"; ?>">
|
||||
<?php } else { ?>
|
||||
<span class="fa-stack fa-4x">
|
||||
<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>
|
||||
<?php } ?>
|
||||
</center>
|
||||
|
||||
<div class="form-group">
|
||||
<label>Name <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>
|
||||
<input type="text" class="form-control" name="name" placeholder="Full Name" maxlength="200"
|
||||
value="<?php echo $user_name; ?>" required>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label>Email <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-envelope"></i></span>
|
||||
</div>
|
||||
<input type="email" class="form-control" name="email" placeholder="Email Address" maxlength="200"
|
||||
value="<?php echo $user_email; ?>" required>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label>New Password</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>
|
||||
<input type="password" class="form-control" data-toggle="password" name="new_password"
|
||||
placeholder="Leave Blank For No Password Change" 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>
|
||||
|
||||
<div class="form-group">
|
||||
<label>Role <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-shield"></i></span>
|
||||
</div>
|
||||
<select class="form-control select2" name="role" required>
|
||||
<?php
|
||||
$sql_user_roles = mysqli_query($mysqli, "SELECT * FROM user_roles WHERE role_archived_at IS NULL");
|
||||
while ($row = mysqli_fetch_array($sql_user_roles)) {
|
||||
$role_id = intval($row['role_id']);
|
||||
$role_name = nullable_htmlentities($row['role_name']);
|
||||
|
||||
?>
|
||||
<option <?php if ($role_id == $user_role_id) {echo "selected";} ?> value="<?php echo $role_id; ?>"><?php echo $role_name; ?></option>
|
||||
<?php } ?>
|
||||
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label>Avatar</label>
|
||||
<input type="file" class="form-control-file" accept="image/*" name="file">
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<div class="custom-control custom-checkbox">
|
||||
<input class="custom-control-input" type="checkbox" id="forceMFACheckBox<?php echo $user_id; ?>" name="force_mfa" value="1" <?php if($user_config_force_mfa == 1){ echo "checked"; } ?>>
|
||||
<label for="forceMFACheckBox<?php echo $user_id; ?>" class="custom-control-label">
|
||||
Force MFA
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<?php if (!empty($user_token)) { ?>
|
||||
|
||||
<div class="form-group">
|
||||
<label>2FA</label>
|
||||
<div class="input-group">
|
||||
<div class="input-group-prepend">
|
||||
<span class="input-group-text"><i class="fa fa-fw fa-id-card"></i></span>
|
||||
</div>
|
||||
<select class="form-control" name="2fa">
|
||||
<option value="">Keep enabled</option>
|
||||
<option value="disable">Disable</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<?php } ?>
|
||||
</div>
|
||||
|
||||
<div class="tab-pane fade" id="pills-user-access<?php echo $user_id; ?>">
|
||||
|
||||
<div class="alert alert-info">
|
||||
Check boxes to authorize user client access. No boxes grant full client access. Admin users are unaffected.
|
||||
</div>
|
||||
|
||||
<ul class="list-group">
|
||||
<li class="list-group-item bg-dark">
|
||||
<div class="form-check">
|
||||
<input type="checkbox" class="form-check-input" onclick="this.closest('.tab-pane').querySelectorAll('.client-checkbox').forEach(checkbox => checkbox.checked = this.checked);">
|
||||
<label class="form-check-label ml-3"><strong>Restrict Access to Clients</strong></label>
|
||||
</div>
|
||||
</li>
|
||||
|
||||
<?php
|
||||
|
||||
$sql_client_select = mysqli_query($mysqli, "SELECT * FROM clients WHERE client_archived_at IS NULL ORDER BY client_name ASC");
|
||||
while ($row = mysqli_fetch_array($sql_client_select)) {
|
||||
$client_id_select = intval($row['client_id']);
|
||||
$client_name_select = nullable_htmlentities($row['client_name']);
|
||||
|
||||
?>
|
||||
|
||||
<li class="list-group-item">
|
||||
<div class="form-check">
|
||||
<input type="checkbox" class="form-check-input client-checkbox" name="clients[]" value="<?php echo $client_id_select; ?>" <?php if (in_array($client_id_select, $client_access_array)) { echo "checked"; } ?>>
|
||||
<label class="form-check-label ml-2"><?php echo $client_name_select; ?></label>
|
||||
</div>
|
||||
</li>
|
||||
|
||||
<?php } ?>
|
||||
|
||||
</ul>
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button type="submit" name="edit_user" class="btn btn-primary text-bold"><i class="fas fa-check mr-2"></i>Save</button>
|
||||
<button type="button" class="btn btn-light" data-dismiss="modal"><i class="fas fa-times mr-2"></i>Cancel</button>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
<?php
|
||||
require_once "../../../includes/modal_footer.php";
|
||||
21
admin/modals/user/user_export.php
Normal file
21
admin/modals/user/user_export.php
Normal file
@@ -0,0 +1,21 @@
|
||||
<div class="modal" id="exportUserModal" tabindex="-1">
|
||||
<div class="modal-dialog">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header bg-dark">
|
||||
<h5 class="modal-title"><i class="fas fa-fw fa-download mr-2"></i>Export Users to CSV</h5>
|
||||
<button type="button" class="close text-white" data-dismiss="modal">
|
||||
<span>×</span>
|
||||
</button>
|
||||
</div>
|
||||
<form action="post.php" method="post" autocomplete="off">
|
||||
<div class="modal-body">
|
||||
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button type="submit" name="export_users_csv" class="btn btn-primary text-bold"><i class="fas fa-fw fa-download mr-2"></i>Download CSV</button>
|
||||
<button type="button" class="btn btn-light" data-dismiss="modal"><i class="fas fa-times mr-2"></i>Cancel</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
45
admin/modals/user/user_invite.php
Normal file
45
admin/modals/user/user_invite.php
Normal file
@@ -0,0 +1,45 @@
|
||||
<div class="modal" id="userInviteModal" tabindex="-1">
|
||||
<div class="modal-dialog">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header bg-dark">
|
||||
<h5 class="modal-title"><i class="fas fa-fw fa-user-plus"></i>Invite User</h5>
|
||||
<button type="button" class="close text-white" data-dismiss="modal">
|
||||
<span>×</span>
|
||||
</button>
|
||||
</div>
|
||||
<form action="post.php" method="post" enctype="multipart/form-data" autocomplete="off">
|
||||
<input type="hidden" name="csrf_token" value="<?php echo $_SESSION['csrf_token'] ?>">
|
||||
<div class="modal-body">
|
||||
|
||||
<div class="form-group">
|
||||
<label>Email <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-envelope"></i></span>
|
||||
</div>
|
||||
<input type="email" class="form-control" name="email" placeholder="Email Address" maxlength="200" required>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label>Role <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-shield"></i></span>
|
||||
</div>
|
||||
<select class="form-control select2" name="role" required>
|
||||
<option value="">- Role -</option>
|
||||
<!-- //TODO: Pull from roles -->
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button type="submit" name="invite_user" class="btn btn-primary text-bold"><i class="fas fa-paper-plane mr-2"></i>Send Invite</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>
|
||||
87
admin/modals/user/user_restore.php
Normal file
87
admin/modals/user/user_restore.php
Normal file
@@ -0,0 +1,87 @@
|
||||
<?php
|
||||
|
||||
require_once '../../../includes/modal_header.php';
|
||||
|
||||
$user_id = intval($_GET['id']);
|
||||
|
||||
$sql = mysqli_query($mysqli, "SELECT * FROM users WHERE user_id = $user_id AND user_archived_at IS NOT NULL LIMIT 1");
|
||||
|
||||
$row = mysqli_fetch_array($sql);
|
||||
$user_name = str_replace(" (archived)", "", $row['user_name']); //Removed (archived) from user_name
|
||||
$user_name = nullable_htmlentities($user_name);
|
||||
$user_email = nullable_htmlentities($row['user_email']);
|
||||
$user_avatar = nullable_htmlentities($row['user_avatar']);
|
||||
$user_initials = initials($user_name);
|
||||
$user_role_id = intval($row['user_role_id']);
|
||||
|
||||
// Generate the HTML form content using output buffering.
|
||||
ob_start();
|
||||
?>
|
||||
<div class="modal-header bg-dark">
|
||||
<h5 class="modal-title"><i class="fas fa-fw fa-redo-alt mr-2"></i>Restoring user:
|
||||
<strong><?php echo $user_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="csrf_token" value="<?php echo $_SESSION['csrf_token'] ?>">
|
||||
<input type="hidden" name="user_id" value="<?php echo $user_id; ?>">
|
||||
<div class="modal-body">
|
||||
|
||||
|
||||
<center class="mb-3">
|
||||
<?php if (!empty($user_avatar)) { ?>
|
||||
<img class="img-fluid" src="<?php echo "../uploads/users/$user_id/$user_avatar"; ?>">
|
||||
<?php } else { ?>
|
||||
<span class="fa-stack fa-4x">
|
||||
<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>
|
||||
<?php } ?>
|
||||
</center>
|
||||
|
||||
<div class="form-group">
|
||||
<label>Set a New Password</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>
|
||||
<input type="password" class="form-control" data-toggle="password" name="new_password"
|
||||
placeholder="Enter a new 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>
|
||||
|
||||
<div class="form-group">
|
||||
<label>Role <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-shield"></i></span>
|
||||
</div>
|
||||
<select class="form-control select2" name="role" required>
|
||||
<?php
|
||||
$sql_user_roles = mysqli_query($mysqli, "SELECT * FROM user_roles WHERE role_archived_at IS NULL");
|
||||
while ($row = mysqli_fetch_array($sql_user_roles)) {
|
||||
$role_id = intval($row['role_id']);
|
||||
$role_name = nullable_htmlentities($row['role_name']);
|
||||
|
||||
?>
|
||||
<option <?php if ($role_id == $user_role_id) {echo "selected";} ?> value="<?php echo $role_id; ?>"><?php echo $role_name; ?></option>
|
||||
<?php } ?>
|
||||
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button type="submit" name="restore_user" class="btn btn-primary text-bold"><i class="fas fa-check mr-2"></i>Restore</button>
|
||||
<button type="button" class="btn btn-light" data-dismiss="modal"><i class="fas fa-times mr-2"></i>Cancel</button>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
<?php
|
||||
require_once "../../../includes/modal_footer.php";
|
||||
168
admin/modals/vendor_template/vendor_template_add.php
Normal file
168
admin/modals/vendor_template/vendor_template_add.php
Normal file
@@ -0,0 +1,168 @@
|
||||
<div class="modal" id="addVendorTemplateModal" tabindex="-1">
|
||||
<div class="modal-dialog">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header bg-dark">
|
||||
<h5 class="modal-title"><i class="fas fa-fw fa-building mr-2"></i>New Vendor Template</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="client_id" value="<?php if (isset($_GET['client_id'])) { echo $client_id; } else { echo 0; } ?>">
|
||||
|
||||
<div class="modal-body">
|
||||
|
||||
<ul class="nav nav-pills nav-justified mb-3">
|
||||
<li class="nav-item">
|
||||
<a class="nav-link active" data-toggle="pill" href="#pills-details">Details</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" data-toggle="pill" href="#pills-support">Support</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" data-toggle="pill" href="#pills-notes">Notes</a>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<hr>
|
||||
|
||||
<div class="tab-content">
|
||||
|
||||
<div class="tab-pane fade show active" id="pills-details">
|
||||
|
||||
<div class="form-group">
|
||||
<label>Vendor Name <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-building"></i></span>
|
||||
</div>
|
||||
<input type="text" class="form-control" name="name" placeholder="Vendor Name" maxlength="200" required autofocus>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label>Description</label>
|
||||
<div class="input-group">
|
||||
<div class="input-group-prepend">
|
||||
<span class="input-group-text"><i class="fa fa-fw fa-angle-right"></i></span>
|
||||
</div>
|
||||
<input type="text" class="form-control" name="description" placeholder="Description" maxlength="200">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label>Account Number</label>
|
||||
<div class="input-group">
|
||||
<div class="input-group-prepend">
|
||||
<span class="input-group-text"><i class="fa fa-fw fa-fingerprint"></i></span>
|
||||
</div>
|
||||
<input type="text" class="form-control" name="account_number" placeholder="Account number" maxlength="200">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label>Account Manager</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="contact_name" placeholder="Account manager's name" maxlength="200">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="tab-pane fade" id="pills-support">
|
||||
|
||||
<label>Support Phone / <span class="text-secondary">Extension</span></label>
|
||||
<div class="form-row">
|
||||
<div class="col-9">
|
||||
<div class="form-group">
|
||||
<div class="input-group">
|
||||
<div class="input-group-prepend">
|
||||
<span class="input-group-text"><i class="fa fa-fw fa-phone"></i></span>
|
||||
</div>
|
||||
<input type="tel" class="form-control col-2" name="phone_country_code" placeholder="+" maxlength="4">
|
||||
<input type="tel" class="form-control" name="phone" placeholder="Phone Number" maxlength="200">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-3">
|
||||
<div class="form-group">
|
||||
<input type="text" class="form-control" name="extension" placeholder="ext." maxlength="200">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label>Support Hours</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="text" class="form-control" name="hours" placeholder="Support Hours" maxlength="200">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label>Support 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="email" placeholder="Support Email" maxlength="200">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label>Support Website 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="text" class="form-control" name="website" placeholder="Do not include http(s)://" maxlength="200">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label>Pin/Code</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="code" placeholder="Access Code or Pin" maxlength="200">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label>SLA</label>
|
||||
<div class="input-group">
|
||||
<div class="input-group-prepend">
|
||||
<span class="input-group-text"><i class="fa fa-fw fa-handshake"></i></span>
|
||||
</div>
|
||||
<input type="text" class="form-control" name="sla" placeholder="SLA Response Time" maxlength="200">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="tab-pane fade" id="pills-notes">
|
||||
|
||||
<div class="form-group">
|
||||
<textarea class="form-control" rows="8" placeholder="Enter some notes" name="notes"></textarea>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button type="submit" name="add_vendor_template" class="btn btn-primary text-bold"><i class="fa fa-check mr-2"></i>Create Template</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>
|
||||
254
admin/modals/vendor_template/vendor_template_edit.php
Normal file
254
admin/modals/vendor_template/vendor_template_edit.php
Normal file
@@ -0,0 +1,254 @@
|
||||
<?php
|
||||
|
||||
require_once '../../../includes/modal_header.php';
|
||||
|
||||
$vendor_template_id = intval($_GET['id']);
|
||||
|
||||
$sql = mysqli_query($mysqli, "SELECT * FROM vendor_templates WHERE vendor_template_id = $vendor_template_id LIMIT 1");
|
||||
$row = mysqli_fetch_array($sql);
|
||||
$vendor_name = nullable_htmlentities($row['vendor_template_name']);
|
||||
$vendor_description = nullable_htmlentities($row['vendor_template_description']);
|
||||
$vendor_account_number = nullable_htmlentities($row['vendor_template_account_number']);
|
||||
$vendor_contact_name = nullable_htmlentities($row['vendor_template_contact_name']);
|
||||
$vendor_phone_country_code = intval($row['vendor_template_phone_country_code']);
|
||||
$vendor_phone = formatPhoneNumber($row['vendor_template_phone'], $vendor_phone_country_code);
|
||||
$vendor_extension = nullable_htmlentities($row['vendor_template_extension']);
|
||||
$vendor_email = nullable_htmlentities($row['vendor_template_email']);
|
||||
$vendor_website = nullable_htmlentities($row['vendor_template_website']);
|
||||
$vendor_hours = nullable_htmlentities($row['vendor_template_hours']);
|
||||
$vendor_sla = nullable_htmlentities($row['vendor_template_sla']);
|
||||
$vendor_code = nullable_htmlentities($row['vendor_template_code']);
|
||||
$vendor_notes = nullable_htmlentities($row['vendor_template_notes']);
|
||||
|
||||
// Generate the HTML form content using output buffering.
|
||||
ob_start();
|
||||
?>
|
||||
|
||||
<div class="modal-header bg-dark">
|
||||
<h5 class="modal-title"><i class="fas fa-fw fa-building mr-2"></i>Editing vendor template: <strong><?php echo $vendor_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="vendor_template_id" value="<?php echo $vendor_template_id; ?>">
|
||||
<div class="modal-body">
|
||||
|
||||
<ul class="nav nav-pills nav-justified mb-3">
|
||||
<li class="nav-item">
|
||||
<a class="nav-link active" data-toggle="pill" href="#pills-details<?php echo $vendor_template_id; ?>">Details</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" data-toggle="pill" href="#pills-support<?php echo $vendor_template_id; ?>">Support</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" data-toggle="pill" href="#pills-notes<?php echo $vendor_template_id; ?>">Notes</a>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<hr>
|
||||
|
||||
<div class="alert alert-info">Check the fields you would like to update globally</div>
|
||||
|
||||
<div class="tab-content">
|
||||
|
||||
<div class="tab-pane fade show active" id="pills-details<?php echo $vendor_template_id; ?>">
|
||||
|
||||
|
||||
<div class="form-group">
|
||||
<label>Vendor Name <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-building"></i></span>
|
||||
</div>
|
||||
<input type="text" class="form-control" name="name" placeholder="Vendor Name" maxlength="200" value="<?php echo "$vendor_name"; ?>" required>
|
||||
<div class="input-group-append">
|
||||
<div class="input-group-text">
|
||||
<input type="checkbox" name="global_update_vendor_name" value="1">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label>Description</label>
|
||||
<div class="input-group">
|
||||
<div class="input-group-prepend">
|
||||
<span class="input-group-text"><i class="fa fa-fw fa-angle-right"></i></span>
|
||||
</div>
|
||||
<input type="text" class="form-control" name="description" placeholder="Description" maxlength="200" value="<?php echo $vendor_description; ?>">
|
||||
<div class="input-group-append">
|
||||
<div class="input-group-text">
|
||||
<input type="checkbox" name="global_update_vendor_description" value="1">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label>Account Number</label>
|
||||
<div class="input-group">
|
||||
<div class="input-group-prepend">
|
||||
<span class="input-group-text"><i class="fa fa-fw fa-fingerprint"></i></span>
|
||||
</div>
|
||||
<input type="text" class="form-control" name="account_number" placeholder="Account number" maxlength="200" value="<?php echo $vendor_account_number; ?>">
|
||||
<div class="input-group-append">
|
||||
<div class="input-group-text">
|
||||
<input type="checkbox" name="global_update_vendor_account_number" value="1">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label>Account Manager</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="contact_name" maxlength="200" value="<?php echo $vendor_contact_name; ?>" placeholder="Vendor contact name">
|
||||
<div class="input-group-append">
|
||||
<div class="input-group-text">
|
||||
<input type="checkbox" name="global_update_vendor_contact_name" value="1">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<div class="custom-control custom-checkbox">
|
||||
<input type="checkbox" class="custom-control-input" id="updateVendorsCheckbox<?php echo $vendor_template_id; ?>" name="update_base_vendors" value="1" >
|
||||
<label class="custom-control-label" for="updateVendorsCheckbox<?php echo $vendor_template_id; ?>">Update All Base Vendors</label>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="tab-pane fade" id="pills-support<?php echo $vendor_template_id; ?>">
|
||||
|
||||
<label>Support Phone</label>
|
||||
<div class="form-row">
|
||||
<div class="col-8">
|
||||
<div class="form-group">
|
||||
<div class="input-group">
|
||||
<div class="input-group-prepend">
|
||||
<span class="input-group-text"><i class="fa fa-fw fa-phone"></i></span>
|
||||
</div>
|
||||
<input type="tel" class="form-control col-2" name="phone_country_code" placeholder="+" maxlength="4" value="<?php echo $vendor_phone_country_code; ?>">
|
||||
<input type="tel" class="form-control" name="phone" value="<?php echo $vendor_phone; ?>">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-4">
|
||||
<div class="input-group">
|
||||
<input type="text" class="form-control" name="extension" placeholder="Prompts" maxlength="200" value="<?php echo $vendor_extension; ?>">
|
||||
<div class="input-group-append">
|
||||
<div class="input-group-text">
|
||||
<input type="checkbox" name="global_update_vendor_phone" value="1">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label>Support Hours</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="text" class="form-control" name="hours" placeholder="Support Hours" maxlength="200" value="<?php echo $vendor_hours; ?>">
|
||||
<div class="input-group-append">
|
||||
<div class="input-group-text">
|
||||
<input type="checkbox" name="global_update_vendor_hours" value="1">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label>Support 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="email" placeholder="Support Email" maxlength="200" value="<?php echo $vendor_email; ?>">
|
||||
<div class="input-group-append">
|
||||
<div class="input-group-text">
|
||||
<input type="checkbox" name="global_update_vendor_email" value="1">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label>Support Website 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="text" class="form-control" name="website" placeholder="Do not include http(s)://" maxlength="200" value="<?php echo $vendor_website; ?>">
|
||||
<div class="input-group-append">
|
||||
<div class="input-group-text">
|
||||
<input type="checkbox" name="global_update_vendor_website" value="1">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label>SLA</label>
|
||||
<div class="input-group">
|
||||
<div class="input-group-prepend">
|
||||
<span class="input-group-text"><i class="fa fa-fw fa-handshake"></i></span>
|
||||
</div>
|
||||
<input type="text" class="form-control" name="sla" placeholder="SLA Response Time" maxlength="200" value="<?php echo $vendor_sla; ?>">
|
||||
<div class="input-group-append">
|
||||
<div class="input-group-text">
|
||||
<input type="checkbox" name="global_update_vendor_sla" value="1">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label>Pin/Code</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="code" placeholder="Access Code or Pin" maxlength="200" value="<?php echo $vendor_code; ?>">
|
||||
<div class="input-group-append">
|
||||
<div class="input-group-text">
|
||||
<input type="checkbox" name="global_update_vendor_code" value="1">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="tab-pane fade" id="pills-notes<?php echo $vendor_template_id; ?>">
|
||||
|
||||
<div class="form-group">
|
||||
<textarea class="form-control" rows="8" placeholder="Enter some notes" name="notes"><?php echo $vendor_notes; ?></textarea>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label>Update Notes Globally?</label>
|
||||
<input type="checkbox" name="global_update_vendor_notes" value="1">
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button type="submit" class="btn btn-primary text-bold" name="edit_vendor_template"><i class="fa fa-check mr-2"></i>Update Template</button>
|
||||
<button type="button" class="btn btn-light" data-dismiss="modal"><i class="fa fa-times mr-2"></i>Cancel</button>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
<?php
|
||||
require_once '../../../includes/modal_footer.php';
|
||||
102
admin/payment_method.php
Normal file
102
admin/payment_method.php
Normal file
@@ -0,0 +1,102 @@
|
||||
<?php
|
||||
|
||||
// Default Column Sortby Filter
|
||||
$sort = "payment_method_name";
|
||||
$order = "ASC";
|
||||
|
||||
require_once "includes/inc_all_admin.php";
|
||||
|
||||
$sql = mysqli_query($mysqli, "SELECT * FROM payment_methods ORDER BY $sort $order");
|
||||
|
||||
$num_rows = mysqli_num_rows($sql);
|
||||
|
||||
?>
|
||||
|
||||
<div class="card card-dark">
|
||||
<div class="card-header py-2">
|
||||
<h3 class="card-title mt-2"><i class="fas fa-fw fa-credit-card mr-2"></i>Payment Methods</h3>
|
||||
<div class="card-tools">
|
||||
<button type="button" class="btn btn-primary" data-toggle="modal" data-target="#addPaymentMethodModal"><i class="fas fa-plus mr-2"></i>Add Payment Method</button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<div class="table-responsive-sm">
|
||||
<table class="table table-striped table-borderless table-hover">
|
||||
<thead class="text-dark <?php if ($num_rows == 0) { echo "d-none"; } ?>">
|
||||
<tr>
|
||||
<th>
|
||||
<a class="text-dark" href="?<?php echo $url_query_strings_sort; ?>&sort=payment_method_name&order=<?php echo $disp; ?>">
|
||||
Method <?php if ($sort == 'payment_method_name') { echo $order_icon; } ?>
|
||||
</a>
|
||||
</th>
|
||||
<th>
|
||||
<a class="text-dark" href="?<?php echo $url_query_strings_sort; ?>&sort=payment_method_description&order=<?php echo $disp; ?>">
|
||||
Description <?php if ($sort == 'payment_method_description') { echo $order_icon; } ?>
|
||||
</a>
|
||||
</th>
|
||||
<th>
|
||||
<a class="text-dark" href="?<?php echo $url_query_strings_sort; ?>&sort=payment_method_created_at&order=<?php echo $disp; ?>">
|
||||
Created at <?php if ($sort == 'payment_method_created_at') { echo $order_icon; } ?>
|
||||
</a>
|
||||
</th>
|
||||
<th class="text-center">Action</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<?php
|
||||
|
||||
while ($row = mysqli_fetch_array($sql)) {
|
||||
$payment_method_id = intval($row['payment_method_id']);
|
||||
$payment_method_name = nullable_htmlentities($row['payment_method_name']);
|
||||
$payment_method_description = nullable_htmlentities($row['payment_method_description']);
|
||||
$payment_method_created_at = nullable_htmlentities($row['payment_method_created_at']);
|
||||
|
||||
?>
|
||||
<tr>
|
||||
<td>
|
||||
<a class="text-dark text-bold ajax-modal" href="#"
|
||||
data-modal-url="modals/payment_method/payment_method_edit.php?id=<?= $payment_method_id ?>">
|
||||
<?php echo $payment_method_name; ?>
|
||||
</a>
|
||||
</td>
|
||||
<td><?php echo $payment_method_description; ?></td>
|
||||
<td><?php echo $payment_method_created_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 ajax-modal" href="#"
|
||||
data-modal-url="modals/payment_method/payment_method_edit.php?id=<?= $payment_method_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_payment_method=<?php echo $payment_method_id; ?>&csrf_token=<?php echo $_SESSION['csrf_token'] ?>">
|
||||
<i class="fas fa-fw fa-trash mr-2"></i>Delete
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<?php
|
||||
|
||||
}
|
||||
|
||||
if ($num_rows == 0) {
|
||||
echo "<h3 class='text-secondary mt-3' style='text-align: center'>No Records Here</h3>";
|
||||
}
|
||||
|
||||
?>
|
||||
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<?php
|
||||
require_once "modals/payment_method/payment_method_add.php";
|
||||
require_once "../includes/footer.php";
|
||||
139
admin/payment_provider.php
Normal file
139
admin/payment_provider.php
Normal file
@@ -0,0 +1,139 @@
|
||||
<?php
|
||||
|
||||
// Default Column Sortby Filter
|
||||
$sort = "payment_provider_name";
|
||||
$order = "ASC";
|
||||
|
||||
require_once "includes/inc_all_admin.php";
|
||||
|
||||
$sql = mysqli_query($mysqli, "SELECT * FROM payment_providers
|
||||
LEFT JOIN accounts ON payment_provider_account = account_id
|
||||
LEFT JOIN vendors ON payment_provider_expense_vendor = vendor_id
|
||||
LEFT JOIN categories ON payment_provider_expense_category = category_id
|
||||
ORDER BY $sort $order"
|
||||
);
|
||||
|
||||
$num_rows = mysqli_num_rows($sql);
|
||||
|
||||
?>
|
||||
|
||||
<div class="card card-dark">
|
||||
<div class="card-header py-2">
|
||||
<h3 class="card-title mt-2"><i class="fas fa-fw fa-credit-card mr-2"></i>Payment Providers</h3>
|
||||
<div class="card-tools">
|
||||
<button type="button" class="btn btn-primary" data-toggle="modal" data-target="#addPaymentProviderModal"><i class="fas fa-plus mr-2"></i>Add Provider</button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<div class="table-responsive-sm">
|
||||
<table class="table table-striped table-borderless table-hover">
|
||||
<thead class="text-dark <?php if ($num_rows == 0) { echo "d-none"; } ?>">
|
||||
<tr>
|
||||
<th>
|
||||
<a class="text-dark" href="?<?php echo $url_query_strings_sort; ?>&sort=payment_provider_name&order=<?php echo $disp; ?>">
|
||||
Provider <?php if ($sort == 'payment_provider_name') { echo $order_icon; } ?>
|
||||
</a>
|
||||
</th>
|
||||
<th>
|
||||
<a class="text-dark" href="?<?php echo $url_query_strings_sort; ?>&sort=account_name&order=<?php echo $disp; ?>">
|
||||
Expense / Income Account <?php if ($sort == 'account_name') { echo $order_icon; } ?>
|
||||
</a>
|
||||
</th>
|
||||
<th>
|
||||
<a class="text-dark" href="?<?php echo $url_query_strings_sort; ?>&sort=payment_provider_threshold&order=<?php echo $disp; ?>">
|
||||
Threshold <?php if ($sort == 'payment_provider_threshold') { echo $order_icon; } ?>
|
||||
</a>
|
||||
</th>
|
||||
<th>
|
||||
<a class="text-dark" href="?<?php echo $url_query_strings_sort; ?>&sort=vendor_name&order=<?php echo $disp; ?>">
|
||||
Expense Vendor <?php if ($sort == 'vendor_name') { echo $order_icon; } ?>
|
||||
</a>
|
||||
</th>
|
||||
<th>
|
||||
<a class="text-dark" href="?<?php echo $url_query_strings_sort; ?>&sort=category_name&order=<?php echo $disp; ?>">
|
||||
Expense Category <?php if ($sort == 'category_name') { echo $order_icon; } ?>
|
||||
</a>
|
||||
</th>
|
||||
<th>
|
||||
<a class="text-dark">Expensed Fee</a>
|
||||
</th>
|
||||
<th>
|
||||
<a class="text-dark">Saved Payment Methods</a>
|
||||
</th>
|
||||
<th class="text-center">Action</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<?php
|
||||
|
||||
while ($row = mysqli_fetch_array($sql)) {
|
||||
$provider_id = intval($row['payment_provider_id']);
|
||||
$provider_name = nullable_htmlentities($row['payment_provider_name']);
|
||||
$provider_description = nullable_htmlentities($row['payment_provider_description']);
|
||||
$account_name = nullable_htmlentities($row['account_name']);
|
||||
$threshold = floatval($row['payment_provider_threshold']);
|
||||
$vendor_name = nullable_htmlentities($row['vendor_name']);
|
||||
$category = nullable_htmlentities($row['category_name']);
|
||||
$percent_fee = floatval($row['payment_provider_expense_percentage_fee']) * 100;
|
||||
$flat_fee = floatval($row['payment_provider_expense_flat_fee']);
|
||||
|
||||
$row = mysqli_fetch_assoc(mysqli_query($mysqli, "SELECT COUNT('saved_payment_id') AS saved_payment_count FROM client_saved_payment_methods WHERE saved_payment_provider_id = $provider_id"));
|
||||
$saved_payment_count = intval($row['saved_payment_count']);
|
||||
|
||||
?>
|
||||
<tr>
|
||||
<td>
|
||||
<a class="text-dark text-bold ajax-modal" href="#"
|
||||
data-modal-url="modals/payment_provider/payment_provider_edit.php?id=<?= $provider_id ?>">
|
||||
<?php echo $provider_name; ?>
|
||||
</a>
|
||||
<span class="text-secondary"><?php echo $provider_description; ?></span>
|
||||
</td>
|
||||
<td><?php echo $account_name; ?></td>
|
||||
<td><?php echo numfmt_format_currency($currency_format, $threshold, $session_company_currency); ?></td>
|
||||
<td><?php echo $vendor_name; ?></td>
|
||||
<td><?php echo $category; ?></td>
|
||||
<td><?php echo $percent_fee; ?>% + <?php echo numfmt_format_currency($currency_format, $flat_fee, $session_company_currency); ?></td>
|
||||
<td><?php echo $saved_payment_count; ?></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 ajax-modal" href="#"
|
||||
data-modal-url="modals/payment_provider/payment_provider_edit.php?id=<?= $provider_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?disable_payment_provider=--><?php //echo $provider_id; ?><!--&csrf_token=--><?php //echo $_SESSION['csrf_token'] ?><!--">-->
|
||||
<!-- <i class="fas fa-fw fa-thumbs-down mr-2"></i>Disable-->
|
||||
<!-- </a>-->
|
||||
<!-- <a class="dropdown-item text-danger confirm-link" href="post.php?delete_payment_provider=--><?php //echo $provider_id; ?><!--&csrf_token=--><?php //echo $_SESSION['csrf_token'] ?><!--">-->
|
||||
<!-- <i class="fas fa-fw fa-trash mr-2"></i>Delete-->
|
||||
<!-- </a>-->
|
||||
</div>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<?php
|
||||
|
||||
}
|
||||
|
||||
if ($num_rows == 0) {
|
||||
echo "<h3 class='text-secondary mt-3' style='text-align: center'>No Records Here</h3>";
|
||||
}
|
||||
|
||||
?>
|
||||
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<?php
|
||||
require_once "modals/payment_provider/payment_provider_add.php";
|
||||
require_once "../includes/footer.php";
|
||||
42
admin/post.php
Normal file
42
admin/post.php
Normal file
@@ -0,0 +1,42 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* ITFlow - Admin GET/POST request handler
|
||||
*/
|
||||
|
||||
require_once "../config.php";
|
||||
require_once "../functions.php";
|
||||
require_once "../includes/check_login.php";
|
||||
|
||||
// Define a variable that we can use to only allow running post files via inclusion (prevents people/bots poking them)
|
||||
define('FROM_POST_HANDLER', true);
|
||||
|
||||
// Determine which files we should load
|
||||
|
||||
// Parse URL & get the path
|
||||
$path = parse_url($_SERVER['HTTP_REFERER'], PHP_URL_PATH);
|
||||
|
||||
// Get the base name (the page name)
|
||||
$module = explode(".", basename($path))[0];
|
||||
|
||||
// Strip off any _details bits
|
||||
$module = str_ireplace('_details', '', $module);
|
||||
|
||||
// Dynamically load admin-related module POST logic
|
||||
if (isset($session_is_admin) && $session_is_admin) {
|
||||
// As (almost) every admin setting is only changed from 1 page, we can dynamically load the relevant logic inside this single admin check IF statement
|
||||
// To add a new admin POST request handler, add a file named after the admin page
|
||||
// e.g. changes made on the page http://itflow/admin_ticket_statues.php will load the page admin/post/admin_ticket_statues.php to handle the changes
|
||||
|
||||
include_once "post/$module.php";
|
||||
|
||||
}
|
||||
|
||||
// Logout is the same for user and admin
|
||||
require_once "../post/logout.php";
|
||||
|
||||
// TODO: Find a home for these
|
||||
|
||||
require_once "../post/ai.php";
|
||||
require_once "../post/misc.php";
|
||||
|
||||
65
admin/post/ai_model.php
Normal file
65
admin/post/ai_model.php
Normal file
@@ -0,0 +1,65 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* ITFlow - GET/POST request handler for AI Models ('ai_model')
|
||||
*/
|
||||
|
||||
defined('FROM_POST_HANDLER') || die("Direct file access is not allowed");
|
||||
|
||||
if (isset($_POST['add_ai_model'])) {
|
||||
|
||||
validateCSRFToken($_POST['csrf_token']);
|
||||
|
||||
$provider_id = intval($_POST['provider']);
|
||||
$model = sanitizeInput($_POST['model']);
|
||||
$prompt = sanitizeInput($_POST['prompt']);
|
||||
$use_case = sanitizeInput($_POST['use_case']);
|
||||
|
||||
mysqli_query($mysqli,"INSERT INTO ai_models SET ai_model_name = '$model', ai_model_prompt = '$prompt', ai_model_use_case = '$use_case', ai_model_ai_provider_id = $provider_id");
|
||||
|
||||
$ai_model_id = mysqli_insert_id($mysqli);
|
||||
|
||||
logAction("AI Model", "Create", "$session_name created AI Model $model");
|
||||
|
||||
flash_alert("AI Model <strong>$model</strong> created");
|
||||
|
||||
redirect();
|
||||
|
||||
}
|
||||
|
||||
if (isset($_POST['edit_ai_model'])) {
|
||||
|
||||
validateCSRFToken($_POST['csrf_token']);
|
||||
|
||||
$model_id = intval($_POST['model_id']);
|
||||
$model = sanitizeInput($_POST['model']);
|
||||
$prompt = sanitizeInput($_POST['prompt']);
|
||||
$use_case = sanitizeInput($_POST['use_case']);
|
||||
|
||||
mysqli_query($mysqli,"UPDATE ai_models SET ai_model_name = '$model', ai_model_prompt = '$prompt', ai_model_use_case = '$use_case' WHERE ai_model_id = $model_id");
|
||||
|
||||
logAction("AI Model", "Edit", "$session_name edited AI Model $model");
|
||||
|
||||
flash_alert("AI Model <strong>$model</strong> edited");
|
||||
|
||||
redirect();
|
||||
|
||||
}
|
||||
|
||||
if (isset($_GET['delete_ai_model'])) {
|
||||
|
||||
validateCSRFToken($_GET['csrf_token']);
|
||||
|
||||
$model_id = intval($_GET['delete_ai_model']);
|
||||
|
||||
$model_name = sanitizeInput(getFieldById('ai_models', $model_id, 'ai_model_name'));
|
||||
|
||||
mysqli_query($mysqli,"DELETE FROM ai_models WHERE ai_model_id = $model_id");
|
||||
|
||||
logAction("AI Model", "Delete", "$session_name deleted AI Model $model_name");
|
||||
|
||||
flash_alert("AI Model <strong>$model_name</strong> deleted", 'error');
|
||||
|
||||
redirect();
|
||||
|
||||
}
|
||||
65
admin/post/ai_provider.php
Normal file
65
admin/post/ai_provider.php
Normal file
@@ -0,0 +1,65 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* ITFlow - GET/POST request handler for AI Providers ('ai_provider')
|
||||
*/
|
||||
|
||||
defined('FROM_POST_HANDLER') || die("Direct file access is not allowed");
|
||||
|
||||
if (isset($_POST['add_ai_provider'])) {
|
||||
|
||||
validateCSRFToken($_POST['csrf_token']);
|
||||
|
||||
$provider = sanitizeInput($_POST['provider']);
|
||||
$url = sanitizeInput($_POST['url']);
|
||||
$model = sanitizeInput($_POST['model']);
|
||||
$api_key = sanitizeInput($_POST['api_key']);
|
||||
|
||||
mysqli_query($mysqli,"INSERT INTO ai_providers SET ai_provider_name = '$provider', ai_provider_api_url = '$url', ai_provider_api_key = '$api_key'");
|
||||
|
||||
$ai_provider_id = mysqli_insert_id($mysqli);
|
||||
|
||||
logAction("AI Provider", "Create", "$session_name created AI Provider $provider");
|
||||
|
||||
flash_alert("AI Model <strong>$provider</strong> created");
|
||||
|
||||
redirect();
|
||||
|
||||
}
|
||||
|
||||
if (isset($_POST['edit_ai_provider'])) {
|
||||
|
||||
validateCSRFToken($_POST['csrf_token']);
|
||||
|
||||
$provider_id = intval($_POST['provider_id']);
|
||||
$provider = sanitizeInput($_POST['provider']);
|
||||
$url = sanitizeInput($_POST['url']);
|
||||
$api_key = sanitizeInput($_POST['api_key']);
|
||||
|
||||
mysqli_query($mysqli,"UPDATE ai_providers SET ai_provider_name = '$provider', ai_provider_api_url = '$url', ai_provider_api_key = '$api_key' WHERE ai_provider_id = $provider_id");
|
||||
|
||||
logAction("AI Provider", "Edit", "$session_name edited AI Provider $provider");
|
||||
|
||||
flash_alert("AI Model <strong>$provider</strong> edited");
|
||||
|
||||
redirect();
|
||||
|
||||
}
|
||||
|
||||
if (isset($_GET['delete_ai_provider'])) {
|
||||
|
||||
validateCSRFToken($_GET['csrf_token']);
|
||||
|
||||
$provider_id = intval($_GET['delete_ai_provider']);
|
||||
|
||||
$provider_name = sanitizeInput(getFieldById('ai_providers', $provider_id, 'ai_provider_name'));
|
||||
|
||||
mysqli_query($mysqli,"DELETE FROM ai_providers WHERE ai_provider_id = $provider_id");
|
||||
|
||||
logAction("AI Provider", "Delete", "$session_name deleted AI Provider $provider_name", 'error');
|
||||
|
||||
flash_alert("AI Provider <strong>$provider_name</strong> deleted", 'error');
|
||||
|
||||
redirect();
|
||||
|
||||
}
|
||||
87
admin/post/api_keys.php
Normal file
87
admin/post/api_keys.php
Normal file
@@ -0,0 +1,87 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* ITFlow - GET/POST request handler for API settings
|
||||
*/
|
||||
|
||||
defined('FROM_POST_HANDLER') || die("Direct file access is not allowed");
|
||||
|
||||
if (isset($_POST['add_api_key'])) {
|
||||
|
||||
validateCSRFToken($_POST['csrf_token']);
|
||||
|
||||
$name = sanitizeInput($_POST['name']);
|
||||
$expire = sanitizeInput($_POST['expire']);
|
||||
$client_id = intval($_POST['client']);
|
||||
$secret = sanitizeInput($_POST['key']); // API Key
|
||||
|
||||
// Credential decryption password
|
||||
$password = password_hash(trim($_POST['password']), PASSWORD_DEFAULT);
|
||||
$apikey_specific_encryption_ciphertext = encryptUserSpecificKey(trim($_POST['password']));
|
||||
|
||||
mysqli_query($mysqli,"INSERT INTO api_keys SET api_key_name = '$name', api_key_secret = '$secret', api_key_decrypt_hash = '$apikey_specific_encryption_ciphertext', api_key_expire = '$expire', api_key_client_id = $client_id");
|
||||
|
||||
$api_key_id = mysqli_insert_id($mysqli);
|
||||
|
||||
logAction("API Key", "Create", "$session_name created API key $name set to expire on $expire", $client_id, $api_key_id);
|
||||
|
||||
flash_alert("API Key <strong>$name</strong> created");
|
||||
|
||||
redirect();
|
||||
|
||||
}
|
||||
|
||||
if (isset($_GET['delete_api_key'])) {
|
||||
|
||||
validateCSRFToken($_GET['csrf_token']);
|
||||
|
||||
$api_key_id = intval($_GET['delete_api_key']);
|
||||
|
||||
// Get API Key Name
|
||||
$row = mysqli_fetch_array(mysqli_query($mysqli,"SELECT api_key_name, api_key_client_id FROM api_keys WHERE api_key_id = $api_key_id"));
|
||||
$api_key_name = sanitizeInput($row['api_key_name']);
|
||||
$client_id = intval($row['api_key_client_id']);
|
||||
|
||||
mysqli_query($mysqli,"DELETE FROM api_keys WHERE api_key_id = $api_key_id");
|
||||
|
||||
logAction("API Key", "Delete", "$session_name deleted API key $name", $client_id);
|
||||
|
||||
flash_alert("API Key <strong>$name</strong> deleted", 'error');
|
||||
|
||||
redirect();
|
||||
|
||||
}
|
||||
|
||||
if (isset($_POST['bulk_delete_api_keys'])) {
|
||||
|
||||
validateCSRFToken($_POST['csrf_token']);
|
||||
|
||||
if (isset($_POST['api_key_ids'])) {
|
||||
|
||||
$count = count($_POST['api_key_ids']);
|
||||
|
||||
// Cycle through array and delete each record
|
||||
foreach ($_POST['api_key_ids'] as $api_key_id) {
|
||||
|
||||
$api_key_id = intval($api_key_id);
|
||||
|
||||
// Get API Key Name
|
||||
$row = mysqli_fetch_array(mysqli_query($mysqli,"SELECT api_key_name, api_key_client_id FROM api_keys WHERE api_key_id = $api_key_id"));
|
||||
$api_key_name = sanitizeInput($row['api_key_name']);
|
||||
$client_id = intval($row['api_key_client_id']);
|
||||
|
||||
mysqli_query($mysqli, "DELETE FROM api_keys WHERE api_key_id = $api_key_id");
|
||||
|
||||
logAction("API Key", "Delete", "$session_name deleted API key $name", $client_id);
|
||||
|
||||
}
|
||||
|
||||
logAction("API Key", "Bulk Delete", "$session_name deleted $count API key(s)");
|
||||
|
||||
flash_alert("Deleted <strong>$count</strong> API keys(s)", 'error');
|
||||
|
||||
}
|
||||
|
||||
redirect();
|
||||
|
||||
}
|
||||
213
admin/post/backup.php
Normal file
213
admin/post/backup.php
Normal file
@@ -0,0 +1,213 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* ITFlow - GET/POST request handler for DB / master key backup
|
||||
*/
|
||||
|
||||
defined('FROM_POST_HANDLER') || die("Direct file access is not allowed");
|
||||
|
||||
require_once "../includes/app_version.php";
|
||||
|
||||
if (isset($_GET['download_backup'])) {
|
||||
|
||||
validateCSRFToken($_GET['csrf_token']);
|
||||
|
||||
$timestamp = date('YmdHis');
|
||||
$baseName = "itflow_$timestamp";
|
||||
|
||||
// === 0. Scoped cleanup ===
|
||||
$cleanupFiles = [];
|
||||
|
||||
$registerTempFileForCleanup = function ($file) use (&$cleanupFiles) {
|
||||
$cleanupFiles[] = $file;
|
||||
};
|
||||
|
||||
register_shutdown_function(function () use (&$cleanupFiles) {
|
||||
foreach ($cleanupFiles as $file) {
|
||||
if (is_file($file)) {
|
||||
@unlink($file);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
// === 1. Local helper function: zipFolder
|
||||
$zipFolder = function ($folderPath, $zipFilePath) {
|
||||
$zip = new ZipArchive();
|
||||
if ($zip->open($zipFilePath, ZipArchive::CREATE | ZipArchive::OVERWRITE) !== TRUE) {
|
||||
error_log("Failed to open zip file: $zipFilePath");
|
||||
http_response_code(500);
|
||||
exit("Internal Server Error: Cannot open zip archive.");
|
||||
}
|
||||
|
||||
$folderPath = realpath($folderPath);
|
||||
if (!$folderPath) {
|
||||
error_log("Invalid folder path: $folderPath");
|
||||
http_response_code(500);
|
||||
exit("Internal Server Error: Invalid folder path.");
|
||||
}
|
||||
|
||||
$files = new RecursiveIteratorIterator(
|
||||
new RecursiveDirectoryIterator($folderPath),
|
||||
RecursiveIteratorIterator::LEAVES_ONLY
|
||||
);
|
||||
|
||||
foreach ($files as $file) {
|
||||
if (!$file->isDir()) {
|
||||
$filePath = $file->getRealPath();
|
||||
$relativePath = substr($filePath, strlen($folderPath) + 1);
|
||||
$zip->addFile($filePath, $relativePath);
|
||||
}
|
||||
}
|
||||
|
||||
$zip->close();
|
||||
};
|
||||
|
||||
// === 2. Create all temp files
|
||||
$sqlFile = tempnam(sys_get_temp_dir(), $baseName . "_sql_");
|
||||
$uploadsZip = tempnam(sys_get_temp_dir(), $baseName . "_uploads_");
|
||||
$versionFile = tempnam(sys_get_temp_dir(), $baseName . "_version_");
|
||||
$finalZip = tempnam(sys_get_temp_dir(), $baseName . "_backup_");
|
||||
|
||||
foreach ([$sqlFile, $uploadsZip, $versionFile, $finalZip] as $f) {
|
||||
$registerTempFileForCleanup($f);
|
||||
chmod($f, 0600);
|
||||
}
|
||||
|
||||
// === 3. Generate SQL Dump
|
||||
$sqlContent = "-- UTF-8 + Foreign Key Safe Dump\n";
|
||||
$sqlContent .= "SET NAMES 'utf8mb4';\n";
|
||||
$sqlContent .= "SET foreign_key_checks = 0;\n\n";
|
||||
|
||||
$tables = [];
|
||||
$res = $mysqli->query("SHOW TABLES");
|
||||
if (!$res) {
|
||||
error_log("MySQL Error: " . $mysqli->error);
|
||||
exit("Error retrieving tables.");
|
||||
}
|
||||
|
||||
while ($row = $res->fetch_row()) {
|
||||
$tables[] = $row[0];
|
||||
}
|
||||
|
||||
foreach ($tables as $table) {
|
||||
$createRes = $mysqli->query("SHOW CREATE TABLE `$table`");
|
||||
if (!$createRes) {
|
||||
error_log("MySQL Error: " . $mysqli->error);
|
||||
continue;
|
||||
}
|
||||
|
||||
$createRow = $createRes->fetch_assoc();
|
||||
$createSQL = array_values($createRow)[1];
|
||||
|
||||
$sqlContent .= "\n-- ----------------------------\n";
|
||||
$sqlContent .= "-- Table structure for `$table`\n";
|
||||
$sqlContent .= "-- ----------------------------\n";
|
||||
$sqlContent .= "DROP TABLE IF EXISTS `$table`;\n";
|
||||
$sqlContent .= $createSQL . ";\n\n";
|
||||
|
||||
$dataRes = $mysqli->query("SELECT * FROM `$table`");
|
||||
if ($dataRes && $dataRes->num_rows > 0) {
|
||||
$sqlContent .= "-- Dumping data for table `$table`\n";
|
||||
while ($row = $dataRes->fetch_assoc()) {
|
||||
$columns = array_map(fn($col) => '`' . $mysqli->real_escape_string($col) . '`', array_keys($row));
|
||||
$values = array_map(function ($val) use ($mysqli) {
|
||||
return is_null($val) ? "NULL" : "'" . $mysqli->real_escape_string($val) . "'";
|
||||
}, array_values($row));
|
||||
$sqlContent .= "INSERT INTO `$table` (" . implode(", ", $columns) . ") VALUES (" . implode(", ", $values) . ");\n";
|
||||
}
|
||||
$sqlContent .= "\n";
|
||||
}
|
||||
}
|
||||
|
||||
$sqlContent .= "SET foreign_key_checks = 1;\n";
|
||||
file_put_contents($sqlFile, $sqlContent);
|
||||
|
||||
// === 4. Zip the uploads folder
|
||||
$zipFolder("../uploads", $uploadsZip);
|
||||
|
||||
// === 5. Create version.txt
|
||||
$commitHash = trim(shell_exec('git log -1 --format=%H')) ?: 'N/A';
|
||||
$gitBranch = trim(shell_exec('git rev-parse --abbrev-ref HEAD')) ?: 'N/A';
|
||||
|
||||
$versionContent = "ITFlow Backup Metadata\n";
|
||||
$versionContent .= "-----------------------------\n";
|
||||
$versionContent .= "Generated: " . date('Y-m-d H:i:s') . "\n";
|
||||
$versionContent .= "Backup File: " . basename($finalZip) . "\n";
|
||||
$versionContent .= "Generated By: $session_name\n";
|
||||
$versionContent .= "Host: " . gethostname() . "\n";
|
||||
$versionContent .= "Git Branch: $gitBranch\n";
|
||||
$versionContent .= "Git Commit: $commitHash\n";
|
||||
$versionContent .= "ITFlow Version: " . (defined('APP_VERSION') ? APP_VERSION : 'Unknown') . "\n";
|
||||
$versionContent .= "Database Version: " . (defined('CURRENT_DATABASE_VERSION') ? CURRENT_DATABASE_VERSION : 'Unknown') . "\n";
|
||||
$versionContent .= "Checksum (SHA256): \n";
|
||||
|
||||
file_put_contents($versionFile, $versionContent);
|
||||
|
||||
// === 6. Build final ZIP
|
||||
$final = new ZipArchive();
|
||||
if ($final->open($finalZip, ZipArchive::CREATE | ZipArchive::OVERWRITE) !== TRUE) {
|
||||
error_log("Failed to create final zip: $finalZip");
|
||||
http_response_code(500);
|
||||
exit("Internal Server Error: Unable to create backup archive.");
|
||||
}
|
||||
|
||||
$final->addFile($sqlFile, "db.sql");
|
||||
$final->addFile($uploadsZip, "uploads.zip");
|
||||
$final->addFile($versionFile, "version.txt");
|
||||
$final->close();
|
||||
|
||||
chmod($finalZip, 0600);
|
||||
|
||||
$checksum = hash_file('sha256', $finalZip);
|
||||
file_put_contents($versionFile, $versionContent . "$checksum\n");
|
||||
|
||||
// === 7. Serve final ZIP
|
||||
header('Content-Type: application/zip');
|
||||
header('Content-Disposition: attachment; filename="' . basename($finalZip) . '"');
|
||||
header('Content-Length: ' . filesize($finalZip));
|
||||
header('Pragma: public');
|
||||
header('Expires: 0');
|
||||
header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
|
||||
header('Content-Transfer-Encoding: binary');
|
||||
|
||||
flush();
|
||||
$fp = fopen($finalZip, 'rb');
|
||||
fpassthru($fp);
|
||||
fclose($fp);
|
||||
|
||||
logAction("System", "Backup Download", "$session_name downloaded full backup.");
|
||||
flash_alert("Full backup downloaded.");
|
||||
exit;
|
||||
}
|
||||
|
||||
|
||||
if (isset($_POST['backup_master_key'])) {
|
||||
|
||||
validateCSRFToken($_POST['csrf_token']);
|
||||
|
||||
$password = $_POST['password'];
|
||||
|
||||
$sql = mysqli_query($mysqli, "SELECT * FROM users WHERE user_id = $session_user_id");
|
||||
$row = mysqli_fetch_array($sql);
|
||||
|
||||
if (password_verify($password, $row['user_password'])) {
|
||||
$site_encryption_master_key = decryptUserSpecificKey($row['user_specific_encryption_ciphertext'], $password);
|
||||
|
||||
logAction("Master Key", "Download", "$session_name retrieved the master encryption key");
|
||||
|
||||
appNotify("Master Key", "$session_name retrieved the master encryption key");
|
||||
|
||||
echo "==============================";
|
||||
echo "<br>Master encryption key:<br>";
|
||||
echo "<b>$site_encryption_master_key</b>";
|
||||
echo "<br>==============================";
|
||||
|
||||
} else {
|
||||
logAction("Master Key", "Download", "$session_name attempted to retrieve the master encryption key but failed");
|
||||
|
||||
flash_alert("Incorrect password.", 'error');
|
||||
|
||||
redirect();
|
||||
}
|
||||
}
|
||||
|
||||
99
admin/post/category.php
Normal file
99
admin/post/category.php
Normal file
@@ -0,0 +1,99 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* ITFlow - GET/POST request handler for categories ('category')
|
||||
*/
|
||||
|
||||
defined('FROM_POST_HANDLER') || die("Direct file access is not allowed");
|
||||
|
||||
if (isset($_POST['add_category'])) {
|
||||
|
||||
require_once 'category_model.php';
|
||||
|
||||
mysqli_query($mysqli,"INSERT INTO categories SET category_name = '$name', category_type = '$type', category_color = '$color'");
|
||||
|
||||
$category_id = mysqli_insert_id($mysqli);
|
||||
|
||||
logAction("Category", "Create", "$session_name created category $type $name", 0, $category_id);
|
||||
|
||||
flash_alert("Category $type <strong>$name</strong> created");
|
||||
|
||||
redirect();
|
||||
|
||||
}
|
||||
|
||||
if (isset($_POST['edit_category'])) {
|
||||
|
||||
require_once 'category_model.php';
|
||||
|
||||
$category_id = intval($_POST['category_id']);
|
||||
|
||||
mysqli_query($mysqli,"UPDATE categories SET category_name = '$name', category_type = '$type', category_color = '$color' WHERE category_id = $category_id");
|
||||
|
||||
logAction("Category", "Edit", "$session_name edited category $type $name", 0, $category_id);
|
||||
|
||||
flash_alert("Category $type <strong>$name</strong> edited");
|
||||
|
||||
redirect();
|
||||
|
||||
}
|
||||
|
||||
if (isset($_GET['archive_category'])) {
|
||||
|
||||
$category_id = intval($_GET['archive_category']);
|
||||
|
||||
// Get Category Name and Type for logging
|
||||
$sql = mysqli_query($mysqli,"SELECT category_name, category_type FROM categories WHERE category_id = $category_id");
|
||||
$row = mysqli_fetch_array($sql);
|
||||
$category_name = sanitizeInput($row['category_name']);
|
||||
$category_type = sanitizeInput($row['category_type']);
|
||||
|
||||
mysqli_query($mysqli,"UPDATE categories SET category_archived_at = NOW() WHERE category_id = $category_id");
|
||||
|
||||
logAction("Category", "Archive", "$session_name archived category $category_type $category_name", 0, $category_id);
|
||||
|
||||
flash_alert("Category $category_type <strong>$category_name</strong> archived", 'error');
|
||||
|
||||
redirect();
|
||||
|
||||
}
|
||||
|
||||
if (isset($_GET['unarchive_category'])) {
|
||||
|
||||
$category_id = intval($_GET['unarchive_category']);
|
||||
|
||||
// Get Category Name and Type for logging
|
||||
$sql = mysqli_query($mysqli,"SELECT category_name, category_type FROM categories WHERE category_id = $category_id");
|
||||
$row = mysqli_fetch_array($sql);
|
||||
$category_name = sanitizeInput($row['category_name']);
|
||||
$category_type = sanitizeInput($row['category_type']);
|
||||
|
||||
mysqli_query($mysqli,"UPDATE categories SET category_archived_at = NULL WHERE category_id = $category_id");
|
||||
|
||||
logAction("Category", "Unarchive", "$session_name unarchived category $category_type $category_name", 0, $category_id);
|
||||
|
||||
flash_alert("Category $category_type <strong>$category_name</strong> unarchived");
|
||||
|
||||
redirect();
|
||||
|
||||
}
|
||||
|
||||
if (isset($_GET['delete_category'])) {
|
||||
|
||||
$category_id = intval($_GET['delete_category']);
|
||||
|
||||
// Get Category Name and Type for logging
|
||||
$sql = mysqli_query($mysqli,"SELECT category_name, category_type FROM categories WHERE category_id = $category_id");
|
||||
$row = mysqli_fetch_array($sql);
|
||||
$category_name = sanitizeInput($row['category_name']);
|
||||
$category_type = sanitizeInput($row['category_type']);
|
||||
|
||||
mysqli_query($mysqli,"DELETE FROM categories WHERE category_id = $category_id");
|
||||
|
||||
logAction("Category", "Delete", "$session_name deleted category $category_type $category_name");
|
||||
|
||||
flash_alert("Category $category_type <strong>$category_name</strong> deleted", 'error');
|
||||
|
||||
redirect();
|
||||
|
||||
}
|
||||
6
admin/post/category_model.php
Normal file
6
admin/post/category_model.php
Normal file
@@ -0,0 +1,6 @@
|
||||
<?php
|
||||
defined('FROM_POST_HANDLER') || die("Direct file access is not allowed");
|
||||
|
||||
$name = sanitizeInput($_POST['name']);
|
||||
$type = sanitizeInput($_POST['type']);
|
||||
$color = sanitizeInput($_POST['color']);
|
||||
57
admin/post/custom_field.php
Normal file
57
admin/post/custom_field.php
Normal file
@@ -0,0 +1,57 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* ITFlow - GET/POST request handler for custom fields
|
||||
*/
|
||||
|
||||
defined('FROM_POST_HANDLER') || die("Direct file access is not allowed");
|
||||
|
||||
if(isset($_POST['create_custom_field'])){
|
||||
|
||||
require_once 'custom_field_model.php';
|
||||
|
||||
$table = sanitizeInput($_POST['table']);
|
||||
|
||||
mysqli_query($mysqli,"INSERT INTO custom_fields SET custom_field_table = '$table', custom_field_label = '$label', custom_field_type = '$type'");
|
||||
|
||||
$custom_field_id = mysqli_insert_id($mysqli);
|
||||
|
||||
logAction("Custom Field", "Create", "$session_name created custom field $label", 0, $custom_field_id);
|
||||
|
||||
flash_alert("Custom field <strong>$label</strong> created");
|
||||
|
||||
redirect();
|
||||
|
||||
}
|
||||
|
||||
if(isset($_POST['edit_custom_field'])){
|
||||
|
||||
require_once 'custom_field_model.php';
|
||||
|
||||
$custom_field_id = intval($_POST['custom_field_id']);
|
||||
|
||||
mysqli_query($mysqli,"UPDATE custom_fields SET custom_field_label = '$label', custom_field_type = '$type' WHERE custom_field_id = $custom_field_id");
|
||||
|
||||
logAction("Custom Field", "Edit", "$session_name edited custom field $label", 0, $custom_field_id);
|
||||
|
||||
flash_alert("Custom field <strong>$label</strong> edited");
|
||||
|
||||
redirect();
|
||||
|
||||
}
|
||||
|
||||
if(isset($_GET['delete_custom_field'])){
|
||||
|
||||
$custom_field_id = intval($_GET['delete_custom_field']);
|
||||
|
||||
$label = sanitizeInput(getFieldById('custom_fields', $custom_field_id, 'custom_field_label'));
|
||||
|
||||
mysqli_query($mysqli,"DELETE FROM custom_fields WHERE custom_field_id = $custom_field_id");
|
||||
|
||||
logAction("Custom Field", "Delete", "$session_name deleted custom field $label");
|
||||
|
||||
flash_alert("Custom field <strong>$label</strong> deleted", 'error');
|
||||
|
||||
redirect();
|
||||
|
||||
}
|
||||
5
admin/post/custom_field_model.php
Normal file
5
admin/post/custom_field_model.php
Normal file
@@ -0,0 +1,5 @@
|
||||
<?php
|
||||
defined('FROM_POST_HANDLER') || die("Direct file access is not allowed");
|
||||
|
||||
$label = sanitizeInput($_POST['label']);
|
||||
$type = sanitizeInput($_POST['type']);
|
||||
68
admin/post/custom_link.php
Normal file
68
admin/post/custom_link.php
Normal file
@@ -0,0 +1,68 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* ITFlow - GET/POST request handler for showing custom links on navbars
|
||||
*/
|
||||
|
||||
defined('FROM_POST_HANDLER') || die("Direct file access is not allowed");
|
||||
|
||||
if (isset($_POST['add_custom_link'])) {
|
||||
|
||||
$name = sanitizeInput($_POST['name']);
|
||||
$uri = sanitizeInput($_POST['uri']);
|
||||
$new_tab = intval($_POST['new_tab'] ?? 0);
|
||||
$icon = preg_replace("/[^0-9a-zA-Z-]/", "", sanitizeInput($_POST['icon']));
|
||||
$order = intval($_POST['order'] ?? 0);
|
||||
$location = intval($_POST['location']);
|
||||
|
||||
mysqli_query($mysqli,"INSERT INTO custom_links SET custom_link_name = '$name', custom_link_uri = '$uri', custom_link_new_tab = $new_tab, custom_link_icon = '$icon', custom_link_order = $order, custom_link_location = $location");
|
||||
|
||||
$custom_link_id = mysqli_insert_id($mysqli);
|
||||
|
||||
logAction("Custom Link", "Create", "$session_name created custom link $name -> $uri", 0, $custom_link_id);
|
||||
|
||||
flash_alert("Custom link <strong>$name</strong> created");
|
||||
|
||||
redirect();
|
||||
|
||||
}
|
||||
|
||||
if (isset($_POST['edit_custom_link'])) {
|
||||
|
||||
$custom_link_id = intval($_POST['custom_link_id']);
|
||||
$name = sanitizeInput($_POST['name']);
|
||||
$uri = sanitizeInput($_POST['uri']);
|
||||
$new_tab = intval($_POST['new_tab'] ?? 0);
|
||||
$icon = preg_replace("/[^0-9a-zA-Z-]/", "", sanitizeInput($_POST['icon']));
|
||||
$order = intval($_POST['order'] ?? 0);
|
||||
$location = intval($_POST['location']);
|
||||
|
||||
mysqli_query($mysqli,"UPDATE custom_links SET custom_link_name = '$name', custom_link_uri = '$uri', custom_link_new_tab = $new_tab, custom_link_icon = '$icon', custom_link_order = $order, custom_link_location = $location WHERE custom_link_id = $custom_link_id");
|
||||
|
||||
logAction("Custom Link", "Edit", "$session_name edited custom link $name -> $uri", 0, $custom_link_id);
|
||||
|
||||
flash_alert("Custom Link <strong>$name</strong> edited");
|
||||
|
||||
redirect();
|
||||
|
||||
}
|
||||
|
||||
if (isset($_GET['delete_custom_link'])) {
|
||||
|
||||
$custom_link_id = intval($_GET['delete_custom_link']);
|
||||
|
||||
// Get Custom Link name and uri for logging
|
||||
$sql = mysqli_query($mysqli,"SELECT custom_link_name, custom_link_uri FROM custom_links WHERE custom_link_id = $custom_link_id");
|
||||
$row = mysqli_fetch_array($sql);
|
||||
$custom_link_name = sanitizeInput($row['custom_link_name']);
|
||||
$custom_link_uri = sanitizeInput($row['custom_link_uri']);
|
||||
|
||||
mysqli_query($mysqli,"DELETE FROM custom_links WHERE custom_link_id = $custom_link_id");
|
||||
|
||||
logAction("Custom Link", "Delete", "$session_name deleted custom link $custom_link_name -> $custom_link_uri");
|
||||
|
||||
flash_alert("Custom Link <strong>$name</strong> deleted", 'error');
|
||||
|
||||
redirect();
|
||||
|
||||
}
|
||||
57
admin/post/document_template.php
Normal file
57
admin/post/document_template.php
Normal file
@@ -0,0 +1,57 @@
|
||||
<?php
|
||||
|
||||
// Doc Templates
|
||||
|
||||
defined('FROM_POST_HANDLER') || die("Direct file access is not allowed");
|
||||
|
||||
if (isset($_POST['add_document_template'])) {
|
||||
|
||||
$name = sanitizeInput($_POST['name']);
|
||||
$description = sanitizeInput($_POST['description']);
|
||||
$content = mysqli_real_escape_string($mysqli,$_POST['content']);
|
||||
|
||||
mysqli_query($mysqli,"INSERT INTO document_templates SET document_template_name = '$name', document_template_description = '$description', document_template_content = '$content', document_template_created_by = $session_user_id");
|
||||
|
||||
$document_template_id = mysqli_insert_id($mysqli);
|
||||
|
||||
logAction("Document Template", "Create", "$session_name created document template $name", 0, $document_template_id);
|
||||
|
||||
flash_alert("Document template <strong>$name</strong> created");
|
||||
|
||||
redirect();
|
||||
|
||||
}
|
||||
|
||||
if (isset($_POST['edit_document_template'])) {
|
||||
|
||||
$document_template_id = intval($_POST['document_template_id']);
|
||||
$name = sanitizeInput($_POST['name']);
|
||||
$description = sanitizeInput($_POST['description']);
|
||||
$content = mysqli_real_escape_string($mysqli,$_POST['content']);
|
||||
|
||||
// Document edit query
|
||||
mysqli_query($mysqli,"UPDATE document_templates SET document_template_name = '$name', document_template_description = '$description', document_template_content = '$content', document_template_updated_by = $session_user_id WHERE document_template_id = $document_template_id");
|
||||
|
||||
logAction("Document Template", "Edit", "$session_name edited document template $name", 0, $document_template_id);
|
||||
|
||||
flash_alert("Document Template <strong>$name</strong> edited");
|
||||
|
||||
redirect();
|
||||
|
||||
}
|
||||
|
||||
if (isset($_GET['delete_document_template'])) {
|
||||
|
||||
$document_template_id = intval($_GET['delete_document_template']);
|
||||
|
||||
$document_template_name = sanitizeInput(getFieldById('document_templates', $document_template_id, 'document_template_name'));
|
||||
|
||||
mysqli_query($mysqli,"DELETE FROM document_templates WHERE document_template_id = $document_template_id");
|
||||
|
||||
logAction("Document Template", "Delete", "$session_name deleted document template $document_template_name");
|
||||
|
||||
flash_alert("Document Template <strong>$document_template_name</strong> deleted", 'error');
|
||||
|
||||
redirect();
|
||||
|
||||
}
|
||||
20
admin/post/identity_provider.php
Normal file
20
admin/post/identity_provider.php
Normal file
@@ -0,0 +1,20 @@
|
||||
<?php
|
||||
|
||||
defined('FROM_POST_HANDLER') || die("Direct file access is not allowed");
|
||||
|
||||
if (isset($_POST['edit_identity_provider'])) {
|
||||
|
||||
validateCSRFToken($_POST['csrf_token']);
|
||||
|
||||
$azure_client_id = sanitizeInput($_POST['azure_client_id']);
|
||||
$azure_client_secret = sanitizeInput($_POST['azure_client_secret']);
|
||||
|
||||
mysqli_query($mysqli,"UPDATE settings SET config_azure_client_id = '$azure_client_id', config_azure_client_secret = '$azure_client_secret' WHERE company_id = 1");
|
||||
|
||||
logAction("Settings", "Edit", "$session_name edited identity provider settings");
|
||||
|
||||
flash_alert("Identity Provider Settings updated");
|
||||
|
||||
redirect();
|
||||
|
||||
}
|
||||
87
admin/post/mail_queue.php
Normal file
87
admin/post/mail_queue.php
Normal file
@@ -0,0 +1,87 @@
|
||||
<?php
|
||||
|
||||
defined('FROM_POST_HANDLER') || die("Direct file access is not allowed");
|
||||
|
||||
if (isset($_GET['send_failed_mail'])) {
|
||||
|
||||
$email_id = intval($_GET['send_failed_mail']);
|
||||
|
||||
mysqli_query($mysqli,"UPDATE email_queue SET email_status = 0, email_attempts = 3 WHERE email_id = $email_id");
|
||||
|
||||
logAction("Email", "Send", "$session_name attempted to force send email id: $email_id in the mail queue", 0, $email_id);
|
||||
|
||||
flash_alert("Email Force Sent, give it a minute to resend");
|
||||
|
||||
redirect();
|
||||
|
||||
}
|
||||
|
||||
if (isset($_GET['cancel_mail'])) {
|
||||
|
||||
$email_id = intval($_GET['cancel_mail']);
|
||||
|
||||
mysqli_query($mysqli,"UPDATE email_queue SET email_status = 2, email_attempts = 99, email_failed_at = NOW() WHERE email_id = $email_id");
|
||||
|
||||
logAction("Email", "Send", "$session_name canceled send email id: $email_id in the mail queue", 0, $email_id);
|
||||
|
||||
flash_alert("Email cancelled and marked as failed.", 'error');
|
||||
|
||||
redirect();
|
||||
|
||||
}
|
||||
|
||||
if (isset($_POST['bulk_cancel_emails'])) {
|
||||
|
||||
validateCSRFToken($_POST['csrf_token']);
|
||||
|
||||
if (isset($_POST['email_ids'])) {
|
||||
|
||||
$count = count($_POST['email_ids']);
|
||||
|
||||
// Cycle through array and mark each email as failed
|
||||
foreach ($_POST['email_ids'] as $email_id) {
|
||||
|
||||
$email_id = intval($email_id);
|
||||
mysqli_query($mysqli,"UPDATE email_queue SET email_status = 2, email_attempts = 99, email_failed_at = NOW() WHERE email_id = $email_id");
|
||||
|
||||
logAction("Email", "Cancel", "$session_name cancelled email id: $email_id in the mail queue", 0, $email_id);
|
||||
|
||||
}
|
||||
|
||||
logAction("Email", "Bulk Cancel", "$session_name cancelled $count email(s) in the mail queue");
|
||||
|
||||
flash_alert("Cancelled <strong>$count</strong> email(s)", 'error');
|
||||
|
||||
}
|
||||
|
||||
redirect();
|
||||
|
||||
}
|
||||
|
||||
if (isset($_POST['bulk_delete_emails'])) {
|
||||
|
||||
validateCSRFToken($_POST['csrf_token']);
|
||||
|
||||
if (isset($_POST['email_ids'])) {
|
||||
|
||||
$count = count($_POST['email_ids']);
|
||||
|
||||
// Cycle through array and delete each email
|
||||
foreach ($_POST['email_ids'] as $email_id) {
|
||||
|
||||
$email_id = intval($email_id);
|
||||
mysqli_query($mysqli,"DELETE FROM email_queue WHERE email_id = $email_id");
|
||||
|
||||
logAction("Email", "Delete", "$session_name deleted email id: $email_id from the mail queue");
|
||||
|
||||
}
|
||||
|
||||
logAction("Email", "Bulk Delete", "$session_name deleted $count email(s) from the mail queue");
|
||||
|
||||
flash_alert("Deleted <strong>$count</strong> email(s)", 'error');
|
||||
|
||||
}
|
||||
|
||||
redirect();
|
||||
|
||||
}
|
||||
58
admin/post/payment_method.php
Normal file
58
admin/post/payment_method.php
Normal file
@@ -0,0 +1,58 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* ITFlow - GET/POST request handler for AI Providers ('ai_providers')
|
||||
*/
|
||||
|
||||
defined('FROM_POST_HANDLER') || die("Direct file access is not allowed");
|
||||
|
||||
if (isset($_POST['add_payment_method'])) {
|
||||
|
||||
validateCSRFToken($_POST['csrf_token']);
|
||||
|
||||
$name = sanitizeInput($_POST['name']);
|
||||
$description = sanitizeInput($_POST['description']);
|
||||
|
||||
mysqli_query($mysqli,"INSERT INTO payment_methods SET payment_method_name = '$name', payment_method_description = '$description'");
|
||||
|
||||
logAction("Payment Method", "Create", "$session_name created Payment Method $name");
|
||||
|
||||
flash_alert("Payment Method <strong>$name</strong> created");
|
||||
|
||||
redirect();
|
||||
|
||||
}
|
||||
|
||||
if (isset($_POST['edit_payment_method'])) {
|
||||
|
||||
validateCSRFToken($_POST['csrf_token']);
|
||||
|
||||
$payment_method_id = intval($_POST['payment_method_id']);
|
||||
$name = sanitizeInput($_POST['name']);
|
||||
$description = sanitizeInput($_POST['description']);
|
||||
|
||||
mysqli_query($mysqli,"UPDATE payment_methods SET payment_method_name = '$name', payment_method_description = '$description' WHERE payment_method_id = $payment_method_id");
|
||||
|
||||
logAction("Payment Method", "Edit", "$session_name edited Payment Method $name");
|
||||
|
||||
flash_alert("Payment Method <strong>$name</strong> edited");
|
||||
|
||||
redirect();
|
||||
|
||||
}
|
||||
|
||||
if (isset($_GET['delete_payment_method'])) {
|
||||
|
||||
$payment_method_id = intval($_GET['delete_payment_method']);
|
||||
|
||||
$payment_method_name = sanitizeInput(getFieldById('payment_methods', $payment_method_is, 'payment_method_name'));
|
||||
|
||||
mysqli_query($mysqli,"DELETE FROM payment_methods WHERE payment_method_id = $payment_method_id");
|
||||
|
||||
logAction("Payment Method", "Delete", "$session_name deleted Payment Method $payment_method_name");
|
||||
|
||||
flash_alert("Payment Method <strong>$payment_method_name</strong> deleted", 'error');
|
||||
|
||||
redirect();
|
||||
|
||||
}
|
||||
115
admin/post/payment_provider.php
Normal file
115
admin/post/payment_provider.php
Normal file
@@ -0,0 +1,115 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* ITFlow - GET/POST request handler for AI Providers ('ai_providers')
|
||||
*/
|
||||
|
||||
defined('FROM_POST_HANDLER') || die("Direct file access is not allowed");
|
||||
|
||||
if (isset($_POST['add_payment_provider'])) {
|
||||
|
||||
validateCSRFToken($_POST['csrf_token']);
|
||||
|
||||
$provider = sanitizeInput($_POST['provider']);
|
||||
$public_key = sanitizeInput($_POST['public_key']);
|
||||
$private_key = sanitizeInput($_POST['private_key']);
|
||||
$threshold = floatval($_POST['threshold']);
|
||||
$enable_expense = intval($_POST['enable_expense'] ?? 0);
|
||||
$percentage_fee = floatval($_POST['percentage_fee']) / 100 ?? 0;
|
||||
$flat_fee = floatval($_POST['flat_fee']) ?? 0;
|
||||
|
||||
// Check to ensure provider isn't added twice
|
||||
$sql = "SELECT 1 FROM payment_providers WHERE payment_provider_name = '$provider' LIMIT 1";
|
||||
$result = mysqli_query($mysqli, $sql);
|
||||
if (mysqli_num_rows($result) > 0) {
|
||||
flash_alert("Payment Provider <strong>$provider</strong> already exists", 'error');
|
||||
redirect();
|
||||
}
|
||||
|
||||
// Check for Stripe Account, if not create it
|
||||
$sql_account = mysqli_query($mysqli,"SELECT account_id FROM accounts WHERE account_name = '$provider' AND account_archived_at IS NULL LIMIT 1");
|
||||
if (mysqli_num_rows($sql_account) == 0) {
|
||||
$account_id = mysqli_insert_id($mysqli);
|
||||
} else {
|
||||
$row = mysqli_fetch_array($sql_account);
|
||||
$account_id = intval($row['account_id']);
|
||||
}
|
||||
|
||||
// Expense defaults
|
||||
$category_id = 0;
|
||||
$vendor_id = 0;
|
||||
|
||||
if ($enable_expense) {
|
||||
// Category
|
||||
$sql_category = mysqli_query($mysqli,"SELECT category_id FROM categories WHERE category_name = 'Payment Processing' AND category_type = 'Expense' AND category_archived_at IS NULL LIMIT 1");
|
||||
if (mysqli_num_rows($sql_category) == 0) {
|
||||
mysqli_query($mysqli,"INSERT INTO categories SET category_name = 'Processing Fee', category_type = 'Payment Processing', category_color = 'gray'");
|
||||
$category_id = mysqli_insert_id($mysqli);
|
||||
} else {
|
||||
$row = mysqli_fetch_array($sql_category);
|
||||
$category_id = intval($row['category_id']);
|
||||
}
|
||||
// Vendor
|
||||
$sql_vendor = mysqli_query($mysqli,"SELECT vendor_id FROM vendors WHERE vendor_name = '$provider' AND vendor_client_id = 0 AND vendor_archived_at IS NULL LIMIT 1");
|
||||
if (mysqli_num_rows($sql_vendor) == 0) {
|
||||
mysqli_query($mysqli,"INSERT INTO vendors SET vendor_name = '$provider', vendor_description = 'Payment Processor Provider', vendor_client_id = 0");
|
||||
$vendor_id = mysqli_insert_id($mysqli);
|
||||
} else {
|
||||
$row = mysqli_fetch_array($sql_vendor);
|
||||
$vendor_id = intval($row['vendor_id']);
|
||||
}
|
||||
}
|
||||
|
||||
mysqli_query($mysqli,"INSERT INTO payment_providers SET payment_provider_name = '$provider', payment_provider_public_key = '$public_key', payment_provider_private_key = '$private_key', payment_provider_threshold = $threshold, payment_provider_account = $account_id, payment_provider_expense_vendor = $vendor_id, payment_provider_expense_category = $category_id, payment_provider_expense_percentage_fee = $percentage_fee, payment_provider_expense_flat_fee = $flat_fee");
|
||||
|
||||
$provider_id = mysqli_insert_id($mysqli);
|
||||
|
||||
logAction("Payment Provider", "Create", "$session_name created AI Provider $provider");
|
||||
|
||||
flash_alert("Payment provider <strong>$provider</strong> created");
|
||||
|
||||
redirect();
|
||||
|
||||
}
|
||||
|
||||
if (isset($_POST['edit_payment_provider'])) {
|
||||
|
||||
validateCSRFToken($_POST['csrf_token']);
|
||||
|
||||
$provider_id = intval($_POST['provider_id']);
|
||||
$description = sanitizeInput($_POST['description']);
|
||||
$public_key = sanitizeInput($_POST['public_key']);
|
||||
$private_key = sanitizeInput($_POST['private_key']);
|
||||
$threshold = floatval($_POST['threshold']);
|
||||
$enable_expense = intval($_POST['enable_expense'] ?? 0);
|
||||
$percentage_fee = floatval($_POST['percentage_fee']) / 100;
|
||||
$flat_fee = floatval($_POST['flat_fee']);
|
||||
|
||||
mysqli_query($mysqli,"UPDATE payment_providers SET payment_provider_public_key = '$public_key', payment_provider_private_key = '$private_key', payment_provider_threshold = $threshold, payment_provider_expense_percentage_fee = $percentage_fee, payment_provider_expense_flat_fee = $flat_fee WHERE payment_provider_id = $provider_id");
|
||||
|
||||
logAction("Payment Provider", "Edit", "$session_name edited Payment Provider $provider");
|
||||
|
||||
flash_alert("Payment Provider <strong>$provider</strong> edited");
|
||||
|
||||
redirect();
|
||||
|
||||
}
|
||||
|
||||
if (isset($_GET['delete_payment_provider'])) {
|
||||
|
||||
validateCSRFToken($_GET['csrf_token']);
|
||||
|
||||
$provider_id = intval($_GET['delete_payment_provider']);
|
||||
|
||||
$provider_name = sanitizeInput(getFieldById('payment_providers', $provider_id, 'provider_name'));
|
||||
|
||||
// Delete provider
|
||||
mysqli_query($mysqli,"DELETE FROM payment_providers WHERE payment_provider_id = $provider_id");
|
||||
|
||||
logAction("Payment Provider", "Delete", "$session_name deleted Payment Provider $provider_name");
|
||||
|
||||
flash_alert("Payment Provider <strong>$provider_name</strong> deleted", 'error');
|
||||
|
||||
redirect();
|
||||
|
||||
}
|
||||
99
admin/post/project_template.php
Normal file
99
admin/post/project_template.php
Normal file
@@ -0,0 +1,99 @@
|
||||
<?php
|
||||
|
||||
defined('FROM_POST_HANDLER') || die("Direct file access is not allowed");
|
||||
|
||||
if (isset($_POST['add_project_template'])) {
|
||||
|
||||
$name = sanitizeInput($_POST['name']);
|
||||
$description = sanitizeInput($_POST['description']);
|
||||
|
||||
mysqli_query($mysqli, "INSERT INTO project_templates SET project_template_name = '$name', project_template_description = '$description'");
|
||||
|
||||
$project_template_id = mysqli_insert_id($mysqli);
|
||||
|
||||
logAction("Project Template", "Create", "$session_name created project template $name", 0, $project_template_id);
|
||||
|
||||
flash_alert("Project Template <strong>$name</strong> created");
|
||||
|
||||
redirect();
|
||||
|
||||
}
|
||||
|
||||
if (isset($_POST['edit_project_template'])) {
|
||||
|
||||
$project_template_id = intval($_POST['project_template_id']);
|
||||
$name = sanitizeInput($_POST['name']);
|
||||
$description = sanitizeInput($_POST['description']);
|
||||
|
||||
mysqli_query($mysqli, "UPDATE project_templates SET project_template_name = '$name', project_template_description = '$description' WHERE project_template_id = $project_template_id");
|
||||
|
||||
logAction("Project Template", "Edit", "$session_name edited project template $name", 0, $project_template_id);
|
||||
|
||||
flash_alert("Project Template <strong>$name</strong> edited");
|
||||
|
||||
redirect();
|
||||
|
||||
}
|
||||
|
||||
if (isset($_POST['edit_ticket_template_order'])) {
|
||||
|
||||
$ticket_template_id = intval($_POST['ticket_template_id']);
|
||||
$project_template_id = intval($_POST['project_template_id']);
|
||||
$order = intval($_POST['order']);
|
||||
|
||||
mysqli_query($mysqli, "UPDATE project_template_ticket_templates SET ticket_template_order = $order WHERE ticket_template_id = $ticket_template_id AND project_template_id = $project_template_id");
|
||||
|
||||
redirect();
|
||||
|
||||
}
|
||||
|
||||
if (isset($_POST['add_ticket_template_to_project_template'])) {
|
||||
|
||||
$project_template_id = intval($_POST['project_template_id']);
|
||||
$ticket_template_id = intval($_POST['ticket_template_id']);
|
||||
$order = intval($_POST['order']);
|
||||
|
||||
mysqli_query($mysqli, "INSERT INTO project_template_ticket_templates SET project_template_id = $project_template_id, ticket_template_id = $ticket_template_id, ticket_template_order = $order");
|
||||
|
||||
logAction("Project Template", "Edit", "$session_name added ticket template to project_template", 0, $project_template_id);
|
||||
|
||||
flash_alert("Ticket template added");
|
||||
|
||||
redirect();
|
||||
|
||||
}
|
||||
|
||||
if (isset($_POST['remove_ticket_template_from_project_template'])) {
|
||||
|
||||
validateTechRole();
|
||||
$ticket_template_id = intval($_POST['ticket_template_id']);
|
||||
$project_template_id = intval($_POST['project_template_id']);
|
||||
|
||||
mysqli_query($mysqli, "DELETE FROM project_template_ticket_templates WHERE project_template_id = $project_template_id AND ticket_template_id = $ticket_template_id");
|
||||
|
||||
logAction("Project Template", "Edit", "$session_name removed ticket template from project template", 0, $project_template_id);
|
||||
|
||||
flash_alert("Ticket template removed", 'error');
|
||||
|
||||
redirect();
|
||||
|
||||
}
|
||||
|
||||
if (isset($_GET['delete_project_template'])) {
|
||||
|
||||
$project_template_id = intval($_GET['delete_project_template']);
|
||||
|
||||
$project_template_name = sanitizeInput(getFieldById('project_templates', $project_template_id, 'project_template_name'));
|
||||
|
||||
mysqli_query($mysqli, "DELETE FROM project_templates WHERE project_template_id = $project_template_id");
|
||||
|
||||
// Remove Associated Ticket Templates
|
||||
mysqli_query($mysqli, "DELETE FROM project_template_ticket_templates WHERE project_template_id = $project_template_id");
|
||||
|
||||
logAction("Project Template", "Delete", "$session_name deleted project template $project_template_name and its associated ticket templates and tasks");
|
||||
|
||||
flash_alert("Project Template <strong>$project_template_name</strong> and its associated ticket templates and tasks deleted", 'error');
|
||||
|
||||
redirect();
|
||||
|
||||
}
|
||||
87
admin/post/roles.php
Normal file
87
admin/post/roles.php
Normal file
@@ -0,0 +1,87 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* ITFlow - GET/POST request handler for roles
|
||||
*/
|
||||
|
||||
defined('FROM_POST_HANDLER') || die("Direct file access is not allowed");
|
||||
|
||||
if (isset($_POST['add_role'])) {
|
||||
|
||||
validateCSRFToken($_POST['csrf_token']);
|
||||
|
||||
$name = sanitizeInput($_POST['role_name']);
|
||||
$description = sanitizeInput($_POST['role_description']);
|
||||
$admin = intval($_POST['role_is_admin']);
|
||||
|
||||
mysqli_query($mysqli, "INSERT INTO user_roles SET role_name = '$name', role_description = '$description', role_is_admin = $admin");
|
||||
|
||||
$role_id = mysqli_insert_id($mysqli);
|
||||
|
||||
logAction("User Role", "Create", "$session_name created user role $name", 0, $role_id);
|
||||
|
||||
flash_alert("User Role <strong$name</strong> created");
|
||||
|
||||
redirect();
|
||||
|
||||
}
|
||||
|
||||
if (isset($_POST['edit_role'])) {
|
||||
|
||||
validateCSRFToken($_POST['csrf_token']);
|
||||
|
||||
$role_id = intval($_POST['role_id']);
|
||||
$name = sanitizeInput($_POST['role_name']);
|
||||
$description = sanitizeInput($_POST['role_description']);
|
||||
$admin = intval($_POST['role_is_admin']);
|
||||
|
||||
mysqli_query($mysqli, "UPDATE user_roles SET role_name = '$name', role_description = '$description', role_is_admin = $admin WHERE role_id = $role_id");
|
||||
|
||||
// Update role access levels
|
||||
mysqli_query($mysqli, "DELETE FROM user_role_permissions WHERE user_role_id = $role_id");
|
||||
foreach ($_POST as $key => $value) {
|
||||
if (str_contains($key, '##module_')){
|
||||
$module_id = intval(explode('##', $key)[0]);
|
||||
$access_level = intval($value);
|
||||
|
||||
if ($access_level > 0) {
|
||||
mysqli_query($mysqli, "INSERT INTO user_role_permissions SET user_role_id = $role_id, module_id = $module_id, user_role_permission_level = $access_level");
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
logAction("User Role", "Edit", "$session_name edited user role $name", 0, $role_id);
|
||||
|
||||
flash_alert("User Role <strong>$name</strong> edited");
|
||||
|
||||
redirect();
|
||||
|
||||
}
|
||||
|
||||
if (isset($_GET['archive_role'])) {
|
||||
|
||||
validateCSRFToken($_GET['csrf_token']);
|
||||
|
||||
$role_id = intval($_GET['archive_role']);
|
||||
|
||||
// Check role isn't in use
|
||||
$sql_role_user_count = mysqli_query($mysqli, "SELECT COUNT(user_id) FROM users WHERE user_role_id = $role_id AND user_archived_at IS NULL");
|
||||
$role_user_count = mysqli_fetch_row($sql_role_user_count)[0];
|
||||
if ($role_user_count != 0) {
|
||||
flash_alert("Role must not in use to archive it", 'error');
|
||||
|
||||
redirect();
|
||||
}
|
||||
|
||||
mysqli_query($mysqli, "UPDATE user_roles SET role_archived_at = NOW() WHERE role_id = $role_id");
|
||||
|
||||
$role_name = sanitizeInput(getFieldById('roles', $role_id, 'role_name'));
|
||||
|
||||
logAction("User Role", "Archive", "$session_name archived user role $role_name", 0, $role_id);
|
||||
|
||||
flash_alert("User Role <strong>$role_name</strong> archived", 'error');
|
||||
|
||||
redirect();
|
||||
|
||||
}
|
||||
70
admin/post/saved_payment_method.php
Normal file
70
admin/post/saved_payment_method.php
Normal file
@@ -0,0 +1,70 @@
|
||||
<?php
|
||||
|
||||
defined('FROM_POST_HANDLER') || die("Direct file access is not allowed");
|
||||
|
||||
if (isset($_GET['delete_saved_payment'])) {
|
||||
|
||||
validateCSRFToken($_GET['csrf_token']);
|
||||
|
||||
$saved_payment_id = intval($_GET['delete_saved_payment']);
|
||||
|
||||
$sql = mysqli_query($mysqli, "
|
||||
SELECT
|
||||
client_saved_payment_methods.saved_payment_id,
|
||||
client_saved_payment_methods.saved_payment_client_id,
|
||||
client_saved_payment_methods.saved_payment_provider_id,
|
||||
client_saved_payment_methods.saved_payment_provider_method,
|
||||
client_saved_payment_methods.saved_payment_description,
|
||||
client_payment_provider.payment_provider_client,
|
||||
payment_providers.payment_provider_name,
|
||||
payment_providers.payment_provider_private_key
|
||||
FROM client_saved_payment_methods
|
||||
LEFT JOIN client_payment_provider
|
||||
ON client_payment_provider.client_id = client_saved_payment_methods.saved_payment_client_id
|
||||
AND client_payment_provider.payment_provider_id = client_saved_payment_methods.saved_payment_provider_id
|
||||
LEFT JOIN payment_providers
|
||||
ON payment_providers.payment_provider_id = client_saved_payment_methods.saved_payment_provider_id
|
||||
WHERE client_saved_payment_methods.saved_payment_id = $saved_payment_id"
|
||||
);
|
||||
|
||||
$row = mysqli_fetch_array($sql);
|
||||
$client_id = intval($row['saved_payment_client_id']);
|
||||
$provider_id = intval($row['saved_payment_provider_id']);
|
||||
$payment_provider_name = nullable_htmlentities($row['payment_provider_name']);
|
||||
$saved_payment_description = nullable_htmlentities($row['saved_payment_description']);
|
||||
$provider_client = nullable_htmlentities($row['payment_provider_client']);
|
||||
$payment_method = $row['saved_payment_provider_method'];
|
||||
|
||||
$private_key = $row['payment_provider_private_key'];
|
||||
|
||||
// Separate logic for each Payment Provider
|
||||
if ($payment_provider_name == 'Stripe') {
|
||||
|
||||
try {
|
||||
// Initialize stripe
|
||||
require_once 'plugins/stripe-php/init.php';
|
||||
$stripe = new \Stripe\StripeClient($private_key);
|
||||
|
||||
// Detach PM
|
||||
$stripe->paymentMethods->detach($payment_method, []);
|
||||
|
||||
} catch (Exception $e) {
|
||||
$error = $e->getMessage();
|
||||
error_log("Stripe payment error - encountered exception when removing payment method info for $payment_method: $error");
|
||||
logApp("Stripe", "error", "Exception removing payment method for $payment_method: $error");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// Remove payment method from ITFlow
|
||||
mysqli_query($mysqli, "DELETE FROM client_saved_payment_methods WHERE saved_payment_id = $saved_payment_id");
|
||||
|
||||
// SQL Cascade delete will Remove All Associated Auto Payment Methods on recurring invoices in the recurring payments table.
|
||||
|
||||
logAction("Payment Provider", "Update", "$session_name deleted saved payment method $saved_payment_description (PM: $payment_method)", $client_id);
|
||||
|
||||
flash_alert("Payment method <strong>$saved_payment_description</strong> removed", 'error');
|
||||
|
||||
redirect();
|
||||
|
||||
}
|
||||
27
admin/post/settings_ai.php
Normal file
27
admin/post/settings_ai.php
Normal file
@@ -0,0 +1,27 @@
|
||||
<?php
|
||||
|
||||
defined('FROM_POST_HANDLER') || die("Direct file access is not allowed");
|
||||
|
||||
if (isset($_POST['edit_ai_settings'])) {
|
||||
|
||||
validateCSRFToken($_POST['csrf_token']);
|
||||
|
||||
$provider = sanitizeInput($_POST['provider']);
|
||||
if($provider){
|
||||
$ai_enable = 1;
|
||||
} else {
|
||||
$ai_enable = 0;
|
||||
}
|
||||
$model = sanitizeInput($_POST['model']);
|
||||
$url = sanitizeInput($_POST['url']);
|
||||
$api_key = sanitizeInput($_POST['api_key']);
|
||||
|
||||
mysqli_query($mysqli,"UPDATE settings SET config_ai_enable = $ai_enable, config_ai_provider = '$provider', config_ai_model = '$model', config_ai_url = '$url', config_ai_api_key = '$api_key' WHERE company_id = 1");
|
||||
|
||||
logAction("Settings", "Edit", "$session_name edited AI settings");
|
||||
|
||||
flash_alert("AI Settings updated");
|
||||
|
||||
redirect();
|
||||
|
||||
}
|
||||
71
admin/post/settings_company.php
Normal file
71
admin/post/settings_company.php
Normal file
@@ -0,0 +1,71 @@
|
||||
<?php
|
||||
|
||||
defined('FROM_POST_HANDLER') || die("Direct file access is not allowed");
|
||||
|
||||
if (isset($_POST['edit_company'])) {
|
||||
|
||||
validateCSRFToken($_POST['csrf_token']);
|
||||
|
||||
$name = sanitizeInput($_POST['name']);
|
||||
$address = sanitizeInput($_POST['address']);
|
||||
$city = sanitizeInput($_POST['city']);
|
||||
$state = sanitizeInput($_POST['state']);
|
||||
$zip = sanitizeInput($_POST['zip']);
|
||||
$country = sanitizeInput($_POST['country']);
|
||||
$phone_country_code = preg_replace("/[^0-9]/", '',$_POST['phone_country_code']);
|
||||
$phone = preg_replace("/[^0-9]/", '',$_POST['phone']);
|
||||
$email = sanitizeInput($_POST['email']);
|
||||
$website = sanitizeInput($_POST['website']);
|
||||
$tax_id = sanitizeInput($_POST['tax_id']);
|
||||
|
||||
$sql = mysqli_query($mysqli,"SELECT company_logo FROM companies WHERE company_id = 1");
|
||||
$row = mysqli_fetch_array($sql);
|
||||
$existing_file_name = sanitizeInput($row['company_logo']);
|
||||
|
||||
// Company logo
|
||||
if (isset($_FILES['file']['tmp_name'])) {
|
||||
if ($new_file_name = checkFileUpload($_FILES['file'], array('jpg', 'jpeg', 'png'))) {
|
||||
$file_tmp_path = $_FILES['file']['tmp_name'];
|
||||
|
||||
// directory in which the uploaded file will be moved
|
||||
$upload_file_dir = "../uploads/settings/";
|
||||
$dest_path = $upload_file_dir . $new_file_name;
|
||||
|
||||
move_uploaded_file($file_tmp_path, $dest_path);
|
||||
|
||||
// Delete old file
|
||||
unlink("../uploads/settings/$existing_file_name");
|
||||
|
||||
// Set Logo
|
||||
mysqli_query($mysqli,"UPDATE companies SET company_logo = '$new_file_name' WHERE company_id = 1");
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
mysqli_query($mysqli,"UPDATE companies SET company_name = '$name', company_address = '$address', company_city = '$city', company_state = '$state', company_zip = '$zip', company_country = '$country', company_phone_country_code = '$phone_country_code', company_phone = '$phone', company_email = '$email', company_website = '$website', company_tax_id = '$tax_id' WHERE company_id = 1");
|
||||
|
||||
logAction("Settings", "Edit", "$session_name edited company details");
|
||||
|
||||
flash_alert("Company <strong>$name</strong> edited");
|
||||
|
||||
redirect();
|
||||
|
||||
}
|
||||
|
||||
if (isset($_GET['remove_company_logo'])) {
|
||||
|
||||
$sql = mysqli_query($mysqli,"SELECT company_logo FROM companies");
|
||||
$row = mysqli_fetch_array($sql);
|
||||
$company_logo = $row['company_logo']; // FileSystem Operation Logo is already sanitized
|
||||
|
||||
unlink("../uploads/settings/$company_logo");
|
||||
|
||||
mysqli_query($mysqli,"UPDATE companies SET company_logo = NULL WHERE company_id = 1");
|
||||
|
||||
logAction("Settings", "Edit", "$session_name deleted company logo");
|
||||
|
||||
flash_alert("Removed company logo", 'error');
|
||||
|
||||
redirect();
|
||||
|
||||
}
|
||||
28
admin/post/settings_default.php
Normal file
28
admin/post/settings_default.php
Normal file
@@ -0,0 +1,28 @@
|
||||
<?php
|
||||
|
||||
defined('FROM_POST_HANDLER') || die("Direct file access is not allowed");
|
||||
|
||||
if (isset($_POST['edit_default_settings'])) {
|
||||
|
||||
validateCSRFToken($_POST['csrf_token']);
|
||||
|
||||
$start_page = sanitizeInput($_POST['start_page']);
|
||||
$expense_account = intval($_POST['expense_account']);
|
||||
$payment_account = intval($_POST['payment_account']);
|
||||
$payment_method = sanitizeInput($_POST['payment_method']);
|
||||
$expense_payment_method = sanitizeInput($_POST['expense_payment_method']);
|
||||
$transfer_from_account = intval($_POST['transfer_from_account']);
|
||||
$transfer_to_account = intval($_POST['transfer_to_account']);
|
||||
$calendar = intval($_POST['calendar']);
|
||||
$net_terms = intval($_POST['net_terms']);
|
||||
$hourly_rate = floatval($_POST['hourly_rate']);
|
||||
|
||||
mysqli_query($mysqli,"UPDATE settings SET config_start_page = '$start_page', config_default_expense_account = $expense_account, config_default_payment_account = $payment_account, config_default_payment_method = '$payment_method', config_default_expense_payment_method = '$expense_payment_method', config_default_transfer_from_account = $transfer_from_account, config_default_transfer_to_account = $transfer_to_account, config_default_calendar = $calendar, config_default_net_terms = $net_terms, config_default_hourly_rate = $hourly_rate WHERE company_id = 1");
|
||||
|
||||
logAction("Settings", "Edit", "$session_name edited default settings");
|
||||
|
||||
flash_alert("Default settings edited");
|
||||
|
||||
redirect();
|
||||
|
||||
}
|
||||
30
admin/post/settings_invoice.php
Normal file
30
admin/post/settings_invoice.php
Normal file
@@ -0,0 +1,30 @@
|
||||
<?php
|
||||
|
||||
defined('FROM_POST_HANDLER') || die("Direct file access is not allowed");
|
||||
|
||||
if (isset($_POST['edit_invoice_settings'])) {
|
||||
|
||||
validateCSRFToken($_POST['csrf_token']);
|
||||
|
||||
$config_invoice_prefix = sanitizeInput($_POST['config_invoice_prefix']);
|
||||
$config_invoice_next_number = intval($_POST['config_invoice_next_number']);
|
||||
$config_invoice_footer = sanitizeInput($_POST['config_invoice_footer']);
|
||||
$config_invoice_show_tax_id = intval($_POST['config_invoice_show_tax_id'] ?? 0);
|
||||
$config_invoice_late_fee_enable = intval($_POST['config_invoice_late_fee_enable'] ?? 0);
|
||||
$config_invoice_late_fee_percent = floatval($_POST['config_invoice_late_fee_percent']);
|
||||
$config_recurring_invoice_prefix = sanitizeInput($_POST['config_recurring_invoice_prefix']);
|
||||
$config_recurring_invoice_next_number = intval($_POST['config_recurring_invoice_next_number']);
|
||||
$config_invoice_paid_notification_email = '';
|
||||
if (filter_var($_POST['config_invoice_paid_notification_email'], FILTER_VALIDATE_EMAIL)) {
|
||||
$config_invoice_paid_notification_email = sanitizeInput($_POST['config_invoice_paid_notification_email']);
|
||||
}
|
||||
|
||||
mysqli_query($mysqli,"UPDATE settings SET config_invoice_prefix = '$config_invoice_prefix', config_invoice_next_number = $config_invoice_next_number, config_invoice_footer = '$config_invoice_footer', config_invoice_show_tax_id = $config_invoice_show_tax_id, config_invoice_late_fee_enable = $config_invoice_late_fee_enable, config_invoice_late_fee_percent = $config_invoice_late_fee_percent, config_invoice_paid_notification_email = '$config_invoice_paid_notification_email', config_recurring_invoice_prefix = '$config_recurring_invoice_prefix', config_recurring_invoice_next_number = $config_recurring_invoice_next_number WHERE company_id = 1");
|
||||
|
||||
logAction("Settings", "Edit", "$session_name edited invoice settings");
|
||||
|
||||
flash_alert("Invoice Settings edited");
|
||||
|
||||
redirect();
|
||||
|
||||
}
|
||||
23
admin/post/settings_localization.php
Normal file
23
admin/post/settings_localization.php
Normal file
@@ -0,0 +1,23 @@
|
||||
<?php
|
||||
|
||||
defined('FROM_POST_HANDLER') || die("Direct file access is not allowed");
|
||||
|
||||
if (isset($_POST['edit_localization'])) {
|
||||
|
||||
validateCSRFToken($_POST['csrf_token']);
|
||||
|
||||
$locale = sanitizeInput($_POST['locale']);
|
||||
$currency_code = sanitizeInput($_POST['currency_code']);
|
||||
$timezone = sanitizeInput($_POST['timezone']);
|
||||
|
||||
mysqli_query($mysqli,"UPDATE companies SET company_locale = '$locale', company_currency = '$currency_code' WHERE company_id = 1");
|
||||
|
||||
mysqli_query($mysqli,"UPDATE settings SET config_timezone = '$timezone' WHERE company_id = 1");
|
||||
|
||||
logAction("Settings", "Edit", "$session_name edited localization settings");
|
||||
|
||||
flash_alert("Company localization updated");
|
||||
|
||||
redirect();
|
||||
|
||||
}
|
||||
186
admin/post/settings_mail.php
Normal file
186
admin/post/settings_mail.php
Normal file
@@ -0,0 +1,186 @@
|
||||
<?php
|
||||
|
||||
defined('FROM_POST_HANDLER') || die("Direct file access is not allowed");
|
||||
|
||||
if (isset($_POST['edit_mail_smtp_settings'])) {
|
||||
|
||||
validateCSRFToken($_POST['csrf_token']);
|
||||
|
||||
$config_smtp_provider = sanitizeInput($_POST['config_smtp_provider']);
|
||||
$config_smtp_host = sanitizeInput($_POST['config_smtp_host']);
|
||||
$config_smtp_port = intval($_POST['config_smtp_port'] ?? 0);
|
||||
$config_smtp_encryption = sanitizeInput($_POST['config_smtp_encryption']);
|
||||
$config_smtp_username = sanitizeInput($_POST['config_smtp_username']);
|
||||
$config_smtp_password = sanitizeInput($_POST['config_smtp_password']);
|
||||
|
||||
// Shared OAuth fields
|
||||
$config_mail_oauth_client_id = sanitizeInput($_POST['config_mail_oauth_client_id']);
|
||||
$config_mail_oauth_client_secret = sanitizeInput($_POST['config_mail_oauth_client_secret']);
|
||||
$config_mail_oauth_tenant_id = sanitizeInput($_POST['config_mail_oauth_tenant_id']);
|
||||
$config_mail_oauth_refresh_token = sanitizeInput($_POST['config_mail_oauth_refresh_token']);
|
||||
$config_mail_oauth_access_token = sanitizeInput($_POST['config_mail_oauth_access_token']);
|
||||
|
||||
mysqli_query($mysqli, "
|
||||
UPDATE settings SET
|
||||
config_smtp_provider = '$config_smtp_provider',
|
||||
config_smtp_host = '$config_smtp_host',
|
||||
config_smtp_port = $config_smtp_port,
|
||||
config_smtp_encryption = '$config_smtp_encryption',
|
||||
config_smtp_username = '$config_smtp_username',
|
||||
config_smtp_password = '$config_smtp_password',
|
||||
config_mail_oauth_client_id = '$config_mail_oauth_client_id',
|
||||
config_mail_oauth_client_secret = '$config_mail_oauth_client_secret',
|
||||
config_mail_oauth_tenant_id = '$config_mail_oauth_tenant_id',
|
||||
config_mail_oauth_refresh_token = '$config_mail_oauth_refresh_token',
|
||||
config_mail_oauth_access_token = '$config_mail_oauth_access_token'
|
||||
WHERE company_id = 1
|
||||
");
|
||||
|
||||
logAction("Settings", "Edit", "$session_name edited SMTP settings");
|
||||
|
||||
flash_alert("SMTP Mail Settings updated");
|
||||
|
||||
redirect();
|
||||
|
||||
}
|
||||
|
||||
if (isset($_POST['edit_mail_imap_settings'])) {
|
||||
|
||||
validateCSRFToken($_POST['csrf_token']);
|
||||
|
||||
$config_imap_provider = sanitizeInput($_POST['config_imap_provider']);
|
||||
$config_imap_host = sanitizeInput($_POST['config_imap_host']);
|
||||
$config_imap_port = intval($_POST['config_imap_port'] ?? 0);
|
||||
$config_imap_encryption = sanitizeInput($_POST['config_imap_encryption']);
|
||||
$config_imap_username = sanitizeInput($_POST['config_imap_username']);
|
||||
$config_imap_password = sanitizeInput($_POST['config_imap_password']);
|
||||
|
||||
// Shared OAuth fields
|
||||
$config_mail_oauth_client_id = sanitizeInput($_POST['config_mail_oauth_client_id']);
|
||||
$config_mail_oauth_client_secret = sanitizeInput($_POST['config_mail_oauth_client_secret']);
|
||||
$config_mail_oauth_tenant_id = sanitizeInput($_POST['config_mail_oauth_tenant_id']);
|
||||
$config_mail_oauth_refresh_token = sanitizeInput($_POST['config_mail_oauth_refresh_token']);
|
||||
$config_mail_oauth_access_token = sanitizeInput($_POST['config_mail_oauth_access_token']);
|
||||
|
||||
mysqli_query($mysqli, "
|
||||
UPDATE settings SET
|
||||
config_imap_provider = '$config_imap_provider',
|
||||
config_imap_host = '$config_imap_host',
|
||||
config_imap_port = $config_imap_port,
|
||||
config_imap_encryption = '$config_imap_encryption',
|
||||
config_imap_username = '$config_imap_username',
|
||||
config_imap_password = '$config_imap_password',
|
||||
config_mail_oauth_client_id = '$config_mail_oauth_client_id',
|
||||
config_mail_oauth_client_secret = '$config_mail_oauth_client_secret',
|
||||
config_mail_oauth_tenant_id = '$config_mail_oauth_tenant_id',
|
||||
config_mail_oauth_refresh_token = '$config_mail_oauth_refresh_token',
|
||||
config_mail_oauth_access_token = '$config_mail_oauth_access_token'
|
||||
WHERE company_id = 1
|
||||
");
|
||||
|
||||
logAction("Settings", "Edit", "$session_name edited IMAP settings");
|
||||
|
||||
flash_alert("IMAP Mail Settings updated");
|
||||
|
||||
redirect();
|
||||
|
||||
}
|
||||
|
||||
if (isset($_POST['edit_mail_from_settings'])) {
|
||||
|
||||
validateCSRFToken($_POST['csrf_token']);
|
||||
|
||||
$config_mail_from_email = sanitizeInput(filter_var($_POST['config_mail_from_email'], FILTER_VALIDATE_EMAIL));
|
||||
$config_mail_from_name = sanitizeInput(preg_replace('/[^a-zA-Z0-9\s]/', '', $_POST['config_mail_from_name']));
|
||||
|
||||
$config_invoice_from_email = sanitizeInput(filter_var($_POST['config_invoice_from_email'], FILTER_VALIDATE_EMAIL));
|
||||
$config_invoice_from_name = sanitizeInput(preg_replace('/[^a-zA-Z0-9\s]/', '', $_POST['config_invoice_from_name']));
|
||||
|
||||
$config_quote_from_email = sanitizeInput(filter_var($_POST['config_quote_from_email'], FILTER_VALIDATE_EMAIL));
|
||||
$config_quote_from_name = sanitizeInput(preg_replace('/[^a-zA-Z0-9\s]/', '', $_POST['config_quote_from_name']));
|
||||
|
||||
$config_ticket_from_email = sanitizeInput(filter_var($_POST['config_ticket_from_email'], FILTER_VALIDATE_EMAIL));
|
||||
$config_ticket_from_name = sanitizeInput(preg_replace('/[^a-zA-Z0-9\s]/', '', $_POST['config_ticket_from_name']));
|
||||
|
||||
mysqli_query($mysqli,"UPDATE settings SET config_mail_from_email = '$config_mail_from_email', config_mail_from_name = '$config_mail_from_name', config_invoice_from_email = '$config_invoice_from_email', config_invoice_from_name = '$config_invoice_from_name', config_quote_from_email = '$config_quote_from_email', config_quote_from_name = '$config_quote_from_name', config_ticket_from_email = '$config_ticket_from_email', config_ticket_from_name = '$config_ticket_from_name' WHERE company_id = 1");
|
||||
|
||||
logAction("Settings", "Edit", "$session_name edited mail from settings");
|
||||
|
||||
flash_alert("Mail From Settings updated");
|
||||
|
||||
redirect();
|
||||
|
||||
}
|
||||
|
||||
if (isset($_POST['test_email_smtp'])) {
|
||||
|
||||
validateCSRFToken($_POST['csrf_token']);
|
||||
|
||||
$test_email = intval($_POST['test_email']);
|
||||
|
||||
if($test_email == 1) {
|
||||
$email_from = sanitizeInput($config_mail_from_email);
|
||||
$email_from_name = sanitizeInput($config_mail_from_name);
|
||||
} elseif ($test_email == 2) {
|
||||
$email_from = sanitizeInput($config_invoice_from_email);
|
||||
$email_from_name = sanitizeInput($config_invoice_from_name);
|
||||
} elseif ($test_email == 3) {
|
||||
$email_from = sanitizeInput($config_quote_from_email);
|
||||
$email_from_name = sanitizeInput($config_quote_from_name);
|
||||
} else {
|
||||
$email_from = sanitizeInput($config_ticket_from_email);
|
||||
$email_from_name = sanitizeInput($config_ticket_from_name);
|
||||
}
|
||||
|
||||
$email_to = sanitizeInput($_POST['email_to']);
|
||||
$subject = "Test email from ITFlow";
|
||||
$body = "This is a test email from ITFlow. If you are reading this, it worked!";
|
||||
|
||||
$data = [
|
||||
[
|
||||
'from' => $email_from,
|
||||
'from_name' => $email_from_name,
|
||||
'recipient' => $email_to,
|
||||
'recipient_name' => 'Chap',
|
||||
'subject' => $subject,
|
||||
'body' => $body
|
||||
]
|
||||
];
|
||||
|
||||
$mail = addToMailQueue($data);
|
||||
|
||||
if ($mail === true) {
|
||||
flash_alert("Test email queued! <a class='text-bold text-light' href='admin_mail_queue.php'>Check Admin > Mail queue</a>");
|
||||
} else {
|
||||
flash_alert("Failed to add test mail to queue", 'error');
|
||||
}
|
||||
|
||||
redirect();
|
||||
|
||||
}
|
||||
|
||||
if (isset($_POST['test_email_imap'])) {
|
||||
|
||||
validateCSRFToken($_POST['csrf_token']);
|
||||
|
||||
// Setup your IMAP connection parameters
|
||||
$hostname = "{" . $config_imap_host . ":" . $config_imap_port . "/" . $config_imap_encryption . "/novalidate-cert}INBOX";
|
||||
$username = $config_imap_username;
|
||||
$password = $config_imap_password;
|
||||
|
||||
try {
|
||||
$inbox = @imap_open($hostname, $username, $password);
|
||||
|
||||
if ($inbox) {
|
||||
imap_close($inbox);
|
||||
flash_alert("Connected successfully");
|
||||
} else {
|
||||
throw new Exception(imap_last_error());
|
||||
}
|
||||
} catch (Exception $e) {
|
||||
flash_alert("<strong>IMAP connection failed:</strong> " . $e->getMessage(), 'error');
|
||||
}
|
||||
|
||||
redirect();
|
||||
|
||||
}
|
||||
28
admin/post/settings_module.php
Normal file
28
admin/post/settings_module.php
Normal file
@@ -0,0 +1,28 @@
|
||||
<?php
|
||||
|
||||
defined('FROM_POST_HANDLER') || die("Direct file access is not allowed");
|
||||
|
||||
if (isset($_POST['edit_module_settings'])) {
|
||||
|
||||
$config_module_enable_itdoc = intval($_POST['config_module_enable_itdoc'] ?? 0);
|
||||
$config_module_enable_ticketing = intval($_POST['config_module_enable_ticketing'] ?? 0);
|
||||
$config_module_enable_accounting = intval($_POST['config_module_enable_accounting'] ?? 0);
|
||||
$config_client_portal_enable = intval($_POST['config_client_portal_enable'] ?? 0);
|
||||
$config_whitelabel_key = sanitizeInput($_POST['config_whitelabel_key']);
|
||||
|
||||
mysqli_query($mysqli,"UPDATE settings SET config_module_enable_itdoc = $config_module_enable_itdoc, config_module_enable_ticketing = $config_module_enable_ticketing, config_module_enable_accounting = $config_module_enable_accounting, config_client_portal_enable = $config_client_portal_enable WHERE company_id = 1");
|
||||
|
||||
// Validate white label key
|
||||
if (!empty($config_whitelabel_key && validateWhitelabelKey($config_whitelabel_key))) {
|
||||
mysqli_query($mysqli, "UPDATE settings SET config_whitelabel_enabled = 1, config_whitelabel_key = '$config_whitelabel_key' WHERE company_id = 1");
|
||||
} else {
|
||||
mysqli_query($mysqli, "UPDATE settings SET config_whitelabel_enabled = 0, config_whitelabel_key = '' WHERE company_id = 1");
|
||||
}
|
||||
|
||||
logAction("Settings", "Edit", "$session_name edited module settings");
|
||||
|
||||
flash_alert("Module Settings updated");
|
||||
|
||||
redirect();
|
||||
|
||||
}
|
||||
23
admin/post/settings_notification.php
Normal file
23
admin/post/settings_notification.php
Normal file
@@ -0,0 +1,23 @@
|
||||
<?php
|
||||
|
||||
defined('FROM_POST_HANDLER') || die("Direct file access is not allowed");
|
||||
|
||||
if (isset($_POST['edit_notification_settings'])) {
|
||||
|
||||
validateCSRFToken($_POST['csrf_token']);
|
||||
|
||||
$config_enable_cron = intval($_POST['config_enable_cron'] ?? 0);
|
||||
$config_enable_alert_domain_expire = intval($_POST['config_enable_alert_domain_expire'] ?? 0);
|
||||
$config_send_invoice_reminders = intval($_POST['config_send_invoice_reminders'] ?? 0);
|
||||
$config_recurring_auto_send_invoice = intval($_POST['config_recurring_auto_send_invoice'] ?? 0);
|
||||
$config_ticket_client_general_notifications = intval($_POST['config_ticket_client_general_notifications'] ?? 0);
|
||||
|
||||
mysqli_query($mysqli,"UPDATE settings SET config_send_invoice_reminders = $config_send_invoice_reminders, config_recurring_auto_send_invoice = $config_recurring_auto_send_invoice, config_enable_cron = $config_enable_cron, config_enable_alert_domain_expire = $config_enable_alert_domain_expire, config_ticket_client_general_notifications = $config_ticket_client_general_notifications WHERE company_id = 1");
|
||||
|
||||
logAction("Settings", "Edit", "$session_name edited notification settings");
|
||||
|
||||
flash_alert("Notification Settings updated");
|
||||
|
||||
redirect();
|
||||
|
||||
}
|
||||
30
admin/post/settings_online_payment.php
Normal file
30
admin/post/settings_online_payment.php
Normal file
@@ -0,0 +1,30 @@
|
||||
<?php
|
||||
|
||||
defined('FROM_POST_HANDLER') || die("Direct file access is not allowed");
|
||||
|
||||
if (isset($_POST['edit_online_payment_settings'])) {
|
||||
|
||||
validateCSRFToken($_POST['csrf_token']);
|
||||
|
||||
$config_stripe_enable = intval($_POST['config_stripe_enable'] ?? 0);
|
||||
$config_stripe_publishable = sanitizeInput($_POST['config_stripe_publishable']);
|
||||
$config_stripe_secret = sanitizeInput($_POST['config_stripe_secret']);
|
||||
$config_stripe_account = intval($_POST['config_stripe_account']);
|
||||
$config_stripe_expense_vendor = intval($_POST['config_stripe_expense_vendor']);
|
||||
$config_stripe_expense_category = intval($_POST['config_stripe_expense_category']);
|
||||
$config_stripe_percentage_fee = floatval($_POST['config_stripe_percentage_fee']) / 100;
|
||||
$config_stripe_flat_fee = floatval($_POST['config_stripe_flat_fee']);
|
||||
|
||||
mysqli_query($mysqli,"UPDATE settings SET config_stripe_enable = $config_stripe_enable, config_stripe_publishable = '$config_stripe_publishable', config_stripe_secret = '$config_stripe_secret', config_stripe_account = $config_stripe_account, config_stripe_expense_vendor = $config_stripe_expense_vendor, config_stripe_expense_category = $config_stripe_expense_category, config_stripe_percentage_fee = $config_stripe_percentage_fee, config_stripe_flat_fee = $config_stripe_flat_fee WHERE company_id = 1");
|
||||
|
||||
logAction("Settings", "Edit", "$session_name edited online payment settings");
|
||||
|
||||
if ($config_stripe_enable && $config_stripe_account == 0) {
|
||||
flash_alert("Stripe payment account must be specified!", 'error');
|
||||
} else {
|
||||
flash_alert("Online Payment Settings updated");
|
||||
}
|
||||
|
||||
redirect();
|
||||
|
||||
}
|
||||
73
admin/post/settings_online_payment_clients.php
Normal file
73
admin/post/settings_online_payment_clients.php
Normal file
@@ -0,0 +1,73 @@
|
||||
<?php
|
||||
|
||||
defined('FROM_POST_HANDLER') || die("Direct file access is not allowed");
|
||||
|
||||
if (isset($_GET['stripe_remove_pm'])) {
|
||||
|
||||
validateCSRFToken($_GET['csrf_token']);
|
||||
|
||||
if (!$config_stripe_enable) {
|
||||
flash_alert("Stripe not enabled", 'error');
|
||||
redirect();
|
||||
}
|
||||
|
||||
$client_id = intval($_GET['client_id']);
|
||||
$payment_method = sanitizeInput($_GET['pm']);
|
||||
|
||||
try {
|
||||
// Initialize stripe
|
||||
require_once '../plugins/stripe-php/init.php';
|
||||
$stripe = new \Stripe\StripeClient($config_stripe_secret);
|
||||
|
||||
// Detach PM
|
||||
$stripe->paymentMethods->detach($payment_method, []);
|
||||
|
||||
} catch (Exception $e) {
|
||||
$error = $e->getMessage();
|
||||
error_log("Stripe payment error - encountered exception when removing payment method info for $payment_method: $error");
|
||||
logApp("Stripe", "error", "Exception removing payment method for $payment_method: $error");
|
||||
}
|
||||
|
||||
// Remove payment method from ITFlow
|
||||
mysqli_query($mysqli, "UPDATE client_stripe SET stripe_pm = NULL WHERE client_id = $client_id LIMIT 1");
|
||||
|
||||
// Remove Auto Pay on recurring invoices that are stripe
|
||||
$sql_recurring_invoices = mysqli_query($mysqli, "SELECT recurring_invoice_id FROM recurring_invoices WHERE recurring_invoice_client_id = $client_id");
|
||||
|
||||
while ($row = mysqli_fetch_array($sql_recurring_invoices)) {
|
||||
$recurring_invoice_id = intval($row['recurring_invoice_id']);
|
||||
mysqli_query($mysqli, "DELETE FROM recurring_payments WHERE recurring_payment_method = 'Stripe' AND recurring_payment_recurring_invoice_id = $recurring_invoice_id");
|
||||
}
|
||||
|
||||
logAction("Stripe", "Update", "$session_name deleted saved Stripe payment method (PM: $payment_method)", $client_id);
|
||||
|
||||
flash_alert("Payment method removed", 'error');
|
||||
|
||||
redirect();
|
||||
|
||||
}
|
||||
|
||||
if (isset($_GET['stripe_reset_customer'])) {
|
||||
|
||||
validateCSRFToken($_GET['csrf_token']);
|
||||
|
||||
$client_id = intval($_GET['client_id']);
|
||||
|
||||
// Delete the customer id and payment method id stored in ITFlow, allowing the client to set these up again
|
||||
mysqli_query($mysqli, "DELETE FROM client_stripe WHERE client_id = $client_id");
|
||||
|
||||
// Remove Auto Pay on recurring invoices that are stripe
|
||||
$sql_recurring_invoices = mysqli_query($mysqli, "SELECT recurring_invoice_id FROM recurring_invoices WHERE recurring_invoice_client_id = $client_id");
|
||||
|
||||
while ($row = mysqli_fetch_array($sql_recurring_invoices)) {
|
||||
$recurring_invoice_id = intval($row['recurring_invoice_id']);
|
||||
mysqli_query($mysqli, "DELETE FROM recurring_payments WHERE recurring_payment_method = 'Stripe' AND recurring_payment_recurring_invoice_id = $recurring_invoice_id");
|
||||
}
|
||||
|
||||
logAction("Stripe", "Delete", "$session_name reset Stripe settings for client", $client_id);
|
||||
|
||||
flash_alert("Reset client Stripe settings", 'error');
|
||||
|
||||
redirect();
|
||||
|
||||
}
|
||||
20
admin/post/settings_project.php
Normal file
20
admin/post/settings_project.php
Normal file
@@ -0,0 +1,20 @@
|
||||
<?php
|
||||
|
||||
defined('FROM_POST_HANDLER') || die("Direct file access is not allowed");
|
||||
|
||||
if (isset($_POST['edit_project_settings'])) {
|
||||
|
||||
validateCSRFToken($_POST['csrf_token']);
|
||||
|
||||
$config_project_prefix = sanitizeInput($_POST['config_project_prefix']);
|
||||
$config_project_next_number = intval($_POST['config_project_next_number']);
|
||||
|
||||
mysqli_query($mysqli,"UPDATE settings SET config_project_prefix = '$config_project_prefix', config_project_next_number = $config_project_next_number WHERE company_id = 1");
|
||||
|
||||
logAction("Settings", "Edit", "$session_name edited project settings");
|
||||
|
||||
flash_alert("Project Settings updated");
|
||||
|
||||
redirect();
|
||||
|
||||
}
|
||||
25
admin/post/settings_quote.php
Normal file
25
admin/post/settings_quote.php
Normal file
@@ -0,0 +1,25 @@
|
||||
<?php
|
||||
|
||||
defined('FROM_POST_HANDLER') || die("Direct file access is not allowed");
|
||||
|
||||
if (isset($_POST['edit_quote_settings'])) {
|
||||
|
||||
validateCSRFToken($_POST['csrf_token']);
|
||||
|
||||
$config_quote_prefix = sanitizeInput($_POST['config_quote_prefix']);
|
||||
$config_quote_next_number = intval($_POST['config_quote_next_number']);
|
||||
$config_quote_footer = sanitizeInput($_POST['config_quote_footer']);
|
||||
$config_quote_notification_email = '';
|
||||
if (filter_var($_POST['config_quote_notification_email'], FILTER_VALIDATE_EMAIL)) {
|
||||
$config_quote_notification_email = sanitizeInput($_POST['config_quote_notification_email']);
|
||||
}
|
||||
|
||||
mysqli_query($mysqli,"UPDATE settings SET config_quote_prefix = '$config_quote_prefix', config_quote_next_number = $config_quote_next_number, config_quote_footer = '$config_quote_footer', config_quote_notification_email = '$config_quote_notification_email' WHERE company_id = 1");
|
||||
|
||||
logAction("Settings", "Edit", "$session_name edited Quote settings");
|
||||
|
||||
flash_alert("Quote Settings updated");
|
||||
|
||||
redirect();
|
||||
|
||||
}
|
||||
28
admin/post/settings_security.php
Normal file
28
admin/post/settings_security.php
Normal file
@@ -0,0 +1,28 @@
|
||||
<?php
|
||||
|
||||
defined('FROM_POST_HANDLER') || die("Direct file access is not allowed");
|
||||
|
||||
if (isset($_POST['edit_security_settings'])) {
|
||||
|
||||
validateCSRFToken($_POST['csrf_token']);
|
||||
|
||||
$config_login_message = sanitizeInput($_POST['config_login_message']);
|
||||
$config_login_key_required = intval($_POST['config_login_key_required'] ?? 0);
|
||||
$config_login_key_secret = sanitizeInput($_POST['config_login_key_secret']);
|
||||
$config_login_remember_me_expire = intval($_POST['config_login_remember_me_expire']);
|
||||
$config_log_retention = intval($_POST['config_log_retention']);
|
||||
|
||||
// Disallow turning on login key without a secret
|
||||
if (empty($config_login_key_secret)) {
|
||||
$config_login_key_required = 0;
|
||||
}
|
||||
|
||||
mysqli_query($mysqli,"UPDATE settings SET config_login_message = '$config_login_message', config_login_key_required = '$config_login_key_required', config_login_key_secret = '$config_login_key_secret', config_login_remember_me_expire = $config_login_remember_me_expire, config_log_retention = $config_log_retention WHERE company_id = 1");
|
||||
|
||||
logAction("Settings", "Edit", "$session_name edited security settings");
|
||||
|
||||
flash_alert("Security settings updated");
|
||||
|
||||
redirect();
|
||||
|
||||
}
|
||||
19
admin/post/settings_telemetry.php
Normal file
19
admin/post/settings_telemetry.php
Normal file
@@ -0,0 +1,19 @@
|
||||
<?php
|
||||
|
||||
defined('FROM_POST_HANDLER') || die("Direct file access is not allowed");
|
||||
|
||||
if (isset($_POST['edit_telemetry_settings'])) {
|
||||
|
||||
validateCSRFToken($_POST['csrf_token']);
|
||||
|
||||
$config_telemetry = intval($_POST['config_telemetry']);
|
||||
|
||||
mysqli_query($mysqli,"UPDATE settings SET config_telemetry = $config_telemetry WHERE company_id = 1");
|
||||
|
||||
logAction("Settings", "Edit", "$session_name edited telemetry settings");
|
||||
|
||||
flash_alert("Telemetry Settings updated");
|
||||
|
||||
redirect();
|
||||
|
||||
}
|
||||
51
admin/post/settings_theme.php
Normal file
51
admin/post/settings_theme.php
Normal file
@@ -0,0 +1,51 @@
|
||||
<?php
|
||||
|
||||
defined('FROM_POST_HANDLER') || die("Direct file access is not allowed");
|
||||
|
||||
if (isset($_POST['edit_theme_settings'])) {
|
||||
|
||||
validateCSRFToken($_POST['csrf_token']);
|
||||
|
||||
$theme = preg_replace("/[^0-9a-zA-Z-]/", "", sanitizeInput($_POST['edit_theme_settings']));
|
||||
|
||||
mysqli_query($mysqli,"UPDATE settings SET config_theme = '$theme' WHERE company_id = 1");
|
||||
|
||||
logAction("Settings", "Edit", "$session_name edited theme settings $dark_mode");
|
||||
|
||||
flash_alert("Changed theme to <strong>$theme</strong>");
|
||||
|
||||
redirect();
|
||||
|
||||
}
|
||||
|
||||
if (isset($_POST['edit_favicon_settings'])) {
|
||||
|
||||
validateCSRFToken($_POST['csrf_token']);
|
||||
|
||||
// Check to see if a file is attached
|
||||
if (isset($_FILES['file']['tmp_name'])) {
|
||||
if ($new_file_name = checkFileUpload($_FILES['file'], array('ico'))) {
|
||||
$file_tmp_path = $_FILES['file']['tmp_name'];
|
||||
|
||||
// Delete old file
|
||||
if(file_exists("../uploads/favicon.ico")) {
|
||||
unlink("../uploads/favicon.ico");
|
||||
}
|
||||
|
||||
// directory in which the uploaded file will be moved
|
||||
$upload_file_dir = "../uploads/";
|
||||
//Force File Name
|
||||
$new_file_name = "favicon.ico";
|
||||
$dest_path = $upload_file_dir . $new_file_name;
|
||||
|
||||
move_uploaded_file($file_tmp_path, $dest_path);
|
||||
}
|
||||
}
|
||||
|
||||
logAction("Settings", "Edit", "$session_name changed the favicon");
|
||||
|
||||
flash_alert("Favicon Updated");
|
||||
|
||||
redirect();
|
||||
|
||||
}
|
||||
30
admin/post/settings_ticket.php
Normal file
30
admin/post/settings_ticket.php
Normal file
@@ -0,0 +1,30 @@
|
||||
<?php
|
||||
|
||||
defined('FROM_POST_HANDLER') || die("Direct file access is not allowed");
|
||||
|
||||
if (isset($_POST['edit_ticket_settings'])) {
|
||||
|
||||
$config_ticket_prefix = sanitizeInput($_POST['config_ticket_prefix']);
|
||||
$config_ticket_next_number = intval($_POST['config_ticket_next_number']);
|
||||
$config_ticket_email_parse = intval($_POST['config_ticket_email_parse'] ?? 0);
|
||||
$config_ticket_email_parse_unknown_senders = intval($_POST['config_ticket_email_parse_unknown_senders'] ?? 0);
|
||||
$config_ticket_default_billable = intval($_POST['config_ticket_default_billable'] ?? 0);
|
||||
$config_ticket_autoclose_hours = intval($_POST['config_ticket_autoclose_hours']);
|
||||
$config_ticket_new_ticket_notification_email = '';
|
||||
if (filter_var($_POST['config_ticket_new_ticket_notification_email'], FILTER_VALIDATE_EMAIL)) {
|
||||
$config_ticket_new_ticket_notification_email = sanitizeInput($_POST['config_ticket_new_ticket_notification_email']);
|
||||
}
|
||||
$config_ticket_default_view = intval($_POST['config_ticket_default_view']);
|
||||
$config_ticket_moving_columns = intval($_POST['config_ticket_moving_columns']);
|
||||
$config_ticket_ordering = intval($_POST['config_ticket_ordering']);
|
||||
$config_ticket_timer_autostart = intval($_POST['config_ticket_timer_autostart']);
|
||||
|
||||
mysqli_query($mysqli,"UPDATE settings SET config_ticket_prefix = '$config_ticket_prefix', config_ticket_next_number = $config_ticket_next_number, config_ticket_email_parse = $config_ticket_email_parse, config_ticket_email_parse_unknown_senders = $config_ticket_email_parse_unknown_senders, config_ticket_autoclose_hours = $config_ticket_autoclose_hours, config_ticket_new_ticket_notification_email = '$config_ticket_new_ticket_notification_email', config_ticket_default_billable = $config_ticket_default_billable, config_ticket_default_view = $config_ticket_default_view, config_ticket_moving_columns = $config_ticket_moving_columns, config_ticket_ordering = $config_ticket_ordering, config_ticket_timer_autostart = $config_ticket_timer_autostart WHERE company_id = 1");
|
||||
|
||||
logAction("Settings", "Edit", "$session_name edited ticket settings");
|
||||
|
||||
flash_alert("Ticket Settings updated");
|
||||
|
||||
redirect();
|
||||
|
||||
}
|
||||
65
admin/post/software_template.php
Normal file
65
admin/post/software_template.php
Normal file
@@ -0,0 +1,65 @@
|
||||
<?php
|
||||
|
||||
// Software/License Templates
|
||||
|
||||
defined('FROM_POST_HANDLER') || die("Direct file access is not allowed");
|
||||
|
||||
if (isset($_POST['add_software_template'])) {
|
||||
|
||||
$name = sanitizeInput($_POST['name']);
|
||||
$version = sanitizeInput($_POST['version']);
|
||||
$description = sanitizeInput($_POST['description']);
|
||||
$type = sanitizeInput($_POST['type']);
|
||||
$license_type = sanitizeInput($_POST['license_type']);
|
||||
$notes = sanitizeInput($_POST['notes']);
|
||||
|
||||
mysqli_query($mysqli,"INSERT INTO software_templates SET software_template_name = '$name', software_template_version = '$version', software_template_description = '$description', software_template_type = '$type', software_template_license_type = '$license_type', software_template_notes = '$notes'");
|
||||
|
||||
$software_template_id = mysqli_insert_id($mysqli);
|
||||
|
||||
logAction("Software Template", "Create", "$session_name created software template $name", 0, $software_template_id);
|
||||
|
||||
flash_alert("Software template <strong>$name</strong> created");
|
||||
|
||||
redirect();
|
||||
|
||||
}
|
||||
|
||||
if (isset($_POST['edit_software_template'])) {
|
||||
|
||||
$software_template_id = intval($_POST['software_template_id']);
|
||||
$name = sanitizeInput($_POST['name']);
|
||||
$version = sanitizeInput($_POST['version']);
|
||||
$description = sanitizeInput($_POST['description']);
|
||||
$type = sanitizeInput($_POST['type']);
|
||||
$license_type = sanitizeInput($_POST['license_type']);
|
||||
$notes = sanitizeInput($_POST['notes']);
|
||||
|
||||
mysqli_query($mysqli,"UPDATE software_templates SET software_template_name = '$name', software_template_version = '$version', software_template_description = '$description', software_template_type = '$type', software_template_license_type = '$license_type', software_template_notes = '$notes' WHERE software_template_id = $software_template_id");
|
||||
|
||||
logAction("Software Template", "Edit", "$session_name edited software template $name", 0, $software_template_id);
|
||||
|
||||
flash_alert("Software template <strong>$name</strong> edited");
|
||||
|
||||
redirect();
|
||||
|
||||
}
|
||||
|
||||
if (isset($_GET['delete_software_template'])) {
|
||||
|
||||
$software_template_id = intval($_GET['delete_software_template']);
|
||||
|
||||
// Get Software Template Name for logging and alert message
|
||||
$sql = mysqli_query($mysqli,"SELECT software_template_name FROM software_templates WHERE software_template_id = $software_template_id");
|
||||
$row = mysqli_fetch_array($sql);
|
||||
$software_template_name = sanitizeInput($row['software_template_name']);
|
||||
|
||||
mysqli_query($mysqli,"DELETE FROM software_templates WHERE software_template_id = $software_template_id");
|
||||
|
||||
logAction("Software Template", "Delete", "$session_name deleted software template $software_template_name");
|
||||
|
||||
flash_alert("Software Template <strong>$software_template_name</strong> deleted", 'error');
|
||||
|
||||
redirect();
|
||||
|
||||
}
|
||||
55
admin/post/tag.php
Normal file
55
admin/post/tag.php
Normal file
@@ -0,0 +1,55 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* ITFlow - GET/POST request handler for tagging
|
||||
*/
|
||||
|
||||
defined('FROM_POST_HANDLER') || die("Direct file access is not allowed");
|
||||
|
||||
if (isset($_POST['add_tag'])) {
|
||||
|
||||
require_once 'tag_model.php';
|
||||
|
||||
mysqli_query($mysqli,"INSERT INTO tags SET tag_name = '$name', tag_type = $type, tag_color = '$color', tag_icon = '$icon'");
|
||||
|
||||
$tag_id = mysqli_insert_id($mysqli);
|
||||
|
||||
logAction("Tag", "Create", "$session_name created tag $name", 0, $tag_id);
|
||||
|
||||
flash_alert("Tag <strong>$name</strong> created");
|
||||
|
||||
redirect();
|
||||
|
||||
}
|
||||
|
||||
if (isset($_POST['edit_tag'])) {
|
||||
|
||||
require_once 'post/tag_model.php';
|
||||
|
||||
$tag_id = intval($_POST['tag_id']);
|
||||
|
||||
mysqli_query($mysqli,"UPDATE tags SET tag_name = '$name', tag_type = $type, tag_color = '$color', tag_icon = '$icon' WHERE tag_id = $tag_id");
|
||||
|
||||
logAction("Tag", "Edit", "$session_name edited tag $name", 0, $tag_id);
|
||||
|
||||
flash_alert("Tag <strong>$name</strong> edited");
|
||||
|
||||
redirect();
|
||||
|
||||
}
|
||||
|
||||
if (isset($_GET['delete_tag'])) {
|
||||
|
||||
$tag_id = intval($_GET['delete_tag']);
|
||||
|
||||
$tag_name = sanitizeInput(getFieldById('tags', $tag_id, 'tag_name'));
|
||||
|
||||
mysqli_query($mysqli,"DELETE FROM tags WHERE tag_id = $tag_id");
|
||||
|
||||
logAction("Tag", "Delete", "$session_name deleted tag $tag_name");
|
||||
|
||||
flash_alert("Tag <strong>$tag_name</strong> deleted", 'error');
|
||||
|
||||
redirect();
|
||||
|
||||
}
|
||||
7
admin/post/tag_model.php
Normal file
7
admin/post/tag_model.php
Normal file
@@ -0,0 +1,7 @@
|
||||
<?php
|
||||
defined('FROM_POST_HANDLER') || die("Direct file access is not allowed");
|
||||
|
||||
$name = sanitizeInput($_POST['name']);
|
||||
$type = intval($_POST['type']);
|
||||
$color = sanitizeInput($_POST['color']);
|
||||
$icon = preg_replace("/[^0-9a-zA-Z-]/", "", sanitizeInput($_POST['icon']));
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user