Migrate Document templates to its own table

This commit is contained in:
johnnyq 2025-06-17 19:00:56 -04:00
parent 85e1515080
commit 473fa2671d
10 changed files with 150 additions and 104 deletions

View File

@ -1,27 +1,19 @@
<?php
// Default Column Sort by Filter
$sort = "document_name";
$sort = "document_template_name";
$order = "ASC";
require_once "includes/inc_all_admin.php";
// Search query SQL snippet
if (!empty($q)) {
$query_snippet = "AND (MATCH(document_content_raw) AGAINST ('$q') OR document_name LIKE '%$q%')";
} else {
$query_snippet = ""; // empty
}
// Rebuild URL
$url_query_strings_sort = http_build_query($get_copy);
$sql = mysqli_query(
$mysqli,
"SELECT SQL_CALC_FOUND_ROWS * FROM documents
LEFT JOIN users ON document_created_by = user_id
WHERE document_template = 1
$query_snippet
"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"
);
@ -55,18 +47,18 @@
<thead class="text-dark <?php if ($num_rows[0] == 0) { echo "d-none"; } ?>">
<tr>
<th>
<a class="text-secondary" href="?<?php echo $url_query_strings_sort; ?>&sort=document_name&order=<?php echo $disp; ?>">
Template Name <?php if ($sort == 'document_name') { echo $order_icon; } ?>
<a 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_created_at&order=<?php echo $disp; ?>">
Created <?php if ($sort == 'document_created_at') { echo $order_icon; } ?>
<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_updated_at&order=<?php echo $disp; ?>">
Updated <?php if ($sort == 'document_updated_at') { echo $order_icon; } ?>
<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">
@ -78,27 +70,26 @@
<?php
while ($row = mysqli_fetch_array($sql)) {
$document_id = intval($row['document_id']);
$document_name = nullable_htmlentities($row['document_name']);
$document_description = nullable_htmlentities($row['document_description']);
$document_content = nullable_htmlentities($row['document_content']);
$document_created_by_name = nullable_htmlentities($row['user_name']);
$document_created_at = nullable_htmlentities($row['document_created_at']);
$document_updated_at = nullable_htmlentities($row['document_updated_at']);
$document_folder_id = intval($row['document_folder_id']);
$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="admin_document_template_details.php?document_id=<?php echo $document_id; ?>"><i class="fas fa-fw fa-file-alt text-dark"></i> <?php echo $document_name; ?></a>
<div class="mt-1 text-secondary"><?php echo $document_description; ?></div>
<a class="text-bold" href="admin_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_created_at; ?>
<div class="text-secondary"><?php echo $document_created_by_name; ?></div>
<?php echo $document_template_created_at; ?>
<div class="text-secondary"><?php echo $document_template_created_by_name; ?></div>
</td>
<td><?php echo $document_updated_at; ?></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">
@ -109,12 +100,12 @@
data-toggle="ajax-modal"
data-modal-size="xl"
data-ajax-url="ajax/ajax_document_template_edit.php"
data-ajax-id="<?php echo $document_id; ?>"
data-ajax-id="<?php echo $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=<?php echo $document_id; ?>">
<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>

View File

@ -11,19 +11,19 @@ $purifier_config->set('Cache.DefinitionImpl', null); // Disable cache by setting
$purifier_config->set('URI.AllowedSchemes', ['data' => true, 'src' => true, 'http' => true, 'https' => true]);
$purifier = new HTMLPurifier($purifier_config);
if (isset($_GET['document_id'])) {
$document_id = intval($_GET['document_id']);
if (isset($_GET['document_template_id'])) {
$document_template_id = intval($_GET['document_template_id']);
}
$sql_document = mysqli_query($mysqli, "SELECT * FROM documents WHERE document_template = 1 AND document_id = $document_id");
$sql_document = mysqli_query($mysqli, "SELECT * FROM document_templates WHERE document_template_id = $document_template_id");
$row = mysqli_fetch_array($sql_document);
$document_name = nullable_htmlentities($row['document_name']);
$document_description = nullable_htmlentities($row['document_description']);
$document_content = $purifier->purify($row['document_content']);
$document_created_at = nullable_htmlentities($row['document_created_at']);
$document_updated_at = nullable_htmlentities($row['document_updated_at']);
$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']);
?>
@ -37,27 +37,27 @@ $document_updated_at = nullable_htmlentities($row['document_updated_at']);
<li class="breadcrumb-item">
<a href="admin_document_template.php">Document Templates</a>
</li>
<li class="breadcrumb-item active"><i class="fas fa-file mr-2"></i><?php echo $document_name; ?></li>
<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_name; ?></h3>
<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"
data-toggle="ajax-modal"
data-modal-size="xl"
data-ajax-url="ajax/ajax_document_template_edit.php"
data-ajax-id="<?php echo $document_id; ?>"
data-ajax-id="<?php echo $document_template_id; ?>"
>
<i class="fas fa-edit mr-2"></i>Edit
</button>
</div>
</div>
<div class="card-body prettyContent">
<?php echo $document_content; ?>
<?php echo $document_template_content; ?>
</div>
</div>

View File

@ -2,38 +2,38 @@
require_once '../includes/ajax_header.php';
$document_id = intval($_GET['id']);
$document_template_id = intval($_GET['id']);
$sql = mysqli_query($mysqli, "SELECT * FROM documents WHERE document_id = $document_id LIMIT 1");
$sql = mysqli_query($mysqli, "SELECT * FROM document_templates WHERE document_template_id = $document_template_id LIMIT 1");
$row = mysqli_fetch_array($sql);
$document_name = nullable_htmlentities($row['document_name']);
$document_description = nullable_htmlentities($row['document_description']);
$document_content = nullable_htmlentities($row['document_content']);
$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">
<h5 class="modal-title"><i class="fa fa-fw fa-file-alt mr-2"></i>Editing template: <strong><?php echo $document_name; ?></strong></h5>
<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>&times;</span>
</button>
</div>
<form action="post.php" method="post" autocomplete="off">
<input type="hidden" name="document_id" value="<?php echo $document_id; ?>">
<input type="hidden" name="document_template_id" value="<?php echo $document_template_id; ?>">
<div class="modal-body bg-white">
<div class="form-group">
<input type="text" class="form-control" name="name" maxlength="200" value="<?php echo $document_name; ?>" placeholder="Name" required>
<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_content; ?></textarea>
<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_description; ?>" placeholder="Short summary">
<input type="text" class="form-control" name="description" value="<?php echo $document_template_description; ?>" placeholder="Short summary">
</div>
</div>

View File

@ -41,8 +41,6 @@ if ($get_folder_id == 0 && $_GET["q"]) {
"SELECT SQL_CALC_FOUND_ROWS * FROM documents
LEFT JOIN users ON document_created_by = user_id
WHERE document_client_id = $client_id
AND document_template = 0
AND document_archived_at IS NULL
$query_snippet
ORDER BY $sort $order LIMIT $record_from, $record_to"
@ -53,7 +51,6 @@ if ($get_folder_id == 0 && $_GET["q"]) {
"SELECT SQL_CALC_FOUND_ROWS * FROM documents
LEFT JOIN users ON document_created_by = user_id
WHERE document_client_id = $client_id
AND document_template = 0
AND document_folder_id = $folder
AND document_archived_at IS NULL
$query_snippet

View File

@ -3497,10 +3497,58 @@ if (LATEST_DATABASE_VERSION > CURRENT_DATABASE_VERSION) {
mysqli_query($mysqli, "UPDATE `settings` SET `config_current_database_version` = '2.1.6'");
}
// if (CURRENT_DATABASE_VERSION == '2.1.6') {
// // Insert queries here required to update to DB version 2.1.7
if (CURRENT_DATABASE_VERSION == '2.1.6') {
mysqli_query($mysqli, "CREATE TABLE `document_templates` (
`document_template_id` INT(11) NOT NULL AUTO_INCREMENT,
`document_template_name` VARCHAR(200) NOT NULL,
`document_template_description` TEXT DEFAULT NULL,
`document_template_content` LONGTEXT NOT NULL,
`document_template_created_at` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
`document_template_updated_at` DATETIME NULL ON UPDATE CURRENT_TIMESTAMP,
`document_template_archived_at` DATETIME NULL DEFAULT NULL,
`document_template_created_by` INT(11) NOT NULL DEFAULT 0,
`document_template_updated_by` INT(11) NOT NULL DEFAULT 0,
PRIMARY KEY (`document_template_id`)
)");
// Copy Document Templates over to new document templates table
mysqli_query($mysqli, "
INSERT INTO document_templates (
document_template_name,
document_template_description,
document_template_content,
document_template_created_at,
document_template_updated_at,
document_template_archived_at,
document_template_created_by,
document_template_updated_by
)
SELECT
document_name,
document_description,
document_content,
document_created_at,
document_updated_at,
document_archived_at,
document_created_by,
document_updated_by
FROM
documents
WHERE
document_template = 1
");
mysqli_query($mysqli, "DELETE FROM documents WHERE document_template = 1");
mysqli_query($mysqli, "ALTER TABLE `documents` DROP `document_template`");
mysqli_query($mysqli, "UPDATE `settings` SET `config_current_database_version` = '2.1.7'");
}
// if (CURRENT_DATABASE_VERSION == '2.1.7') {
// // Insert queries here required to update to DB version 2.1.8
// // Then, update the database to the next sequential version
// mysqli_query($mysqli, "UPDATE `settings` SET `config_current_database_version` = '2.1.7'");
// mysqli_query($mysqli, "UPDATE `settings` SET `config_current_database_version` = '2.1.8'");
// }
} else {

24
db.sql
View File

@ -830,6 +830,27 @@ CREATE TABLE `document_files` (
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci;
/*!40101 SET character_set_client = @saved_cs_client */;
--
-- Table structure for table `document_templates`
--
DROP TABLE IF EXISTS `document_templates`;
/*!40101 SET @saved_cs_client = @@character_set_client */;
/*!40101 SET character_set_client = utf8mb4 */;
CREATE TABLE `document_templates` (
`document_template_id` int(11) NOT NULL AUTO_INCREMENT,
`document_template_name` varchar(200) NOT NULL,
`document_template_description` text DEFAULT NULL,
`document_template_content` longtext NOT NULL,
`document_template_created_at` datetime NOT NULL DEFAULT current_timestamp(),
`document_template_updated_at` datetime DEFAULT NULL ON UPDATE current_timestamp(),
`document_template_archived_at` datetime DEFAULT NULL,
`document_template_created_by` int(11) NOT NULL DEFAULT 0,
`document_template_updated_by` int(11) NOT NULL DEFAULT 0,
PRIMARY KEY (`document_template_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci;
/*!40101 SET character_set_client = @saved_cs_client */;
--
-- Table structure for table `document_versions`
--
@ -868,7 +889,6 @@ CREATE TABLE `documents` (
`document_updated_at` datetime DEFAULT NULL ON UPDATE current_timestamp(),
`document_archived_at` datetime DEFAULT NULL,
`document_accessed_at` datetime DEFAULT NULL,
`document_template` tinyint(1) NOT NULL DEFAULT 0,
`document_folder_id` int(11) NOT NULL DEFAULT 0,
`document_created_by` int(11) NOT NULL DEFAULT 0,
`document_updated_by` int(11) NOT NULL DEFAULT 0,
@ -2522,4 +2542,4 @@ CREATE TABLE `vendors` (
/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */;
/*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */;
-- Dump completed on 2025-06-17 17:56:40
-- Dump completed on 2025-06-17 19:00:19

View File

@ -5,4 +5,4 @@
* It is used in conjunction with database_updates.php
*/
DEFINE("LATEST_DATABASE_VERSION", "2.1.6");
DEFINE("LATEST_DATABASE_VERSION", "2.1.7");

View File

@ -20,10 +20,10 @@
<select class="form-control" name="document_template_id" required>
<option value="">- Select Template -</option>
<?php
$sql_document_templates = mysqli_query($mysqli, "SELECT * FROM documents WHERE document_template = 1 AND document_archived_at IS NULL ORDER BY document_name ASC");
$sql_document_templates = mysqli_query($mysqli, "SELECT * FROM document_templates WHERE document_template_archived_at IS NULL ORDER BY document_template_name ASC");
while ($row = mysqli_fetch_array($sql_document_templates)) {
$document_template_id = intval($row['document_id']);
$document_template_name = nullable_htmlentities($row['document_name']);
$document_template_id = intval($row['document_template_id']);
$document_template_name = nullable_htmlentities($row['document_template_name']);
?>
<option value="<?php echo $document_template_id ?>"><?php echo $document_template_name; ?></option>

View File

@ -4,28 +4,41 @@
defined('FROM_POST_HANDLER') || die("Direct file access is not allowed");
// Import shared code from user-side docs as we reuse functions
require_once 'post/user/document.php';
if (isset($_POST['add_document_template'])) {
$client_id = intval($_POST['client_id']);
$name = sanitizeInput($_POST['name']);
$description = sanitizeInput($_POST['description']);
$content = mysqli_real_escape_string($mysqli,$_POST['content']);
$content_raw = sanitizeInput($_POST['name'] . " " . str_replace("<", " <", $_POST['content']));
// Content Raw is used for FULL INDEX searching. Adding a space before HTML tags to allow spaces between newlines, bulletpoints, etc. for searching.
// Document create query
mysqli_query($mysqli,"INSERT INTO documents SET document_name = '$name', document_description = '$description', document_content = '$content', document_content_raw = '$content_raw', document_template = 1, document_folder_id = 0, document_created_by = $session_user_id, document_client_id = 0");
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_id = mysqli_insert_id($mysqli);
$document_template_id = mysqli_insert_id($mysqli);
// Logging
logAction("Document Template", "Create", "$session_name created document template $name", $client_id, $document_id);
logAction("Document Template", "Create", "$session_name created document template $name", 0, $document_template_id);
$_SESSION['alert_message'] = "Document template <strong>$name</strong> created";
header("Location: " . $_SERVER["HTTP_REFERER"]);
}
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");
// Logging
logAction("Document Template", "Edit", "$session_name edited document template $name", 0, $document_template_id);
$_SESSION['alert_message'] = "Document Template <strong>$name</strong> edited";
header("Location: " . $_SERVER["HTTP_REFERER"]);
}

View File

@ -49,17 +49,17 @@ if (isset($_POST['add_document_from_template'])) {
$document_template_id = intval($_POST['document_template_id']);
$folder = intval($_POST['folder']);
//GET Document Info
$sql_document = mysqli_query($mysqli,"SELECT * FROM documents WHERE document_id = $document_template_id");
// GET Document Template Info
$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 = sanitizeInput($row['document_name']);
$content = mysqli_real_escape_string($mysqli,$row['document_content']);
$document_template_name = sanitizeInput($row['document_template_name']);
$content = mysqli_real_escape_string($mysqli,$row['document_template_content']);
$content_raw = sanitizeInput($_POST['name'] . " " . str_replace("<", " <", $row['document_content']));
// Document add query
mysqli_query($mysqli,"INSERT INTO documents SET document_name = '$document_name', document_description = '$document_description', document_content = '$content', document_content_raw = '$content_raw', document_template = 0, document_folder_id = $folder, document_created_by = $session_user_id, document_client_id = $client_id");
mysqli_query($mysqli,"INSERT INTO documents SET document_name = '$document_name', document_description = '$document_description', document_content = '$content', document_content_raw = '$content_raw', document_folder_id = $folder, document_created_by = $session_user_id, document_client_id = $client_id");
$document_id = mysqli_insert_id($mysqli);
@ -520,29 +520,6 @@ if (isset($_GET['unlink_software_from_document'])) {
}
if (isset($_POST['edit_document_template'])) {
enforceUserPermission('module_support', 2);
$document_id = intval($_POST['document_id']);
$name = sanitizeInput($_POST['name']);
$description = sanitizeInput($_POST['description']);
$content = mysqli_real_escape_string($mysqli,$_POST['content']);
$content_raw = sanitizeInput($_POST['name'] . " " . str_replace("<", " <", $_POST['content']));
// Content Raw is used for FULL INDEX searching. Adding a space before HTML tags to allow spaces between newlines, bulletpoints, etc. for searching.
// Document edit query
mysqli_query($mysqli,"UPDATE documents SET document_name = '$name', document_description = '$description', document_content = '$content', document_content_raw = '$content_raw', document_updated_by = $session_user_id WHERE document_id = $document_id");
// Logging
logAction("Document Template", "Edit", "$session_name edited document template $name", 0, $document_id);
$_SESSION['alert_message'] = "Document Template <strong>$name</strong> edited";
header("Location: " . $_SERVER["HTTP_REFERER"]);
}
if (isset($_POST['toggle_document_visibility'])) {
enforceUserPermission('module_support', 2);