37748-vm/includes/helpers.php
2026-01-23 15:54:08 +00:00

209 lines
8.6 KiB
PHP

<?php
require_once __DIR__ . '/../db/config.php';
function getCurrentAppUser() {
// In a real application, this would fetch the logged-in user from a session or token.
// For now, we'll hardcode the admin user from the seeded data.
// This assumes the admin user has company_id 1 (from the seed).
// This will need to be replaced with proper authentication later.
static $user = null;
if ($user === null) {
$user = db()->query("SELECT * FROM users WHERE role = 'admin' LIMIT 1")->fetch(PDO::FETCH_ASSOC);
}
return $user;
}
function get_current_company_id() {
$user = getCurrentAppUser();
return $user ? $user['company_id'] : null;
}
function get_company_onboarding_status($company_id) {
$stmt = db()->prepare("SELECT onboarding_complete FROM companies WHERE id = ?");
$stmt->execute([$company_id]);
$result = $stmt->fetch(PDO::FETCH_ASSOC);
return $result ? (bool)$result['onboarding_complete'] : false;
}
function logActivity($job_id, $event_type, $field_name = null, $old_value = null, $new_value = null) {
$user = getCurrentAppUser();
if (!$user) { return; } // Don't log if no user context
$stmt = db()->prepare("INSERT INTO activity_logs (job_id, company_id, user_id, user_name, event_type, field_name, old_value, new_value) VALUES (?, ?, ?, ?, ?, ?, ?, ?)");
$stmt->execute([
$job_id,
$user['company_id'],
$user['id'],
$user['name'],
$event_type,
$field_name,
$old_value,
$new_value
]);
}
function getJobStatuses($company_id) {
$stmt = db()->prepare("SELECT * FROM job_statuses WHERE company_id = ?");
$stmt->execute([$company_id]);
return $stmt->fetchAll(PDO::FETCH_ASSOC);
}
function getClients($company_id) {
$stmt = db()->prepare("SELECT * FROM clients WHERE company_id = ? AND is_active = 1");
$stmt->execute([$company_id]);
return $stmt->fetchAll(PDO::FETCH_ASSOC);
}
function getCompanyRequiredFolders($company_id) {
$stmt = db()->prepare("SELECT * FROM job_folders WHERE company_id = ? AND is_required = TRUE ORDER BY name ASC");
$stmt->execute([$company_id]);
return $stmt->fetchAll(PDO::FETCH_ASSOC);
}
// New functions for File & Folder Manager
/**
* Ensures all required folders for a company are created for a specific job.
* This should be called when a new job is created or when new required folders are added globally.
*/
function ensureRequiredJobFoldersExist($job_id, $company_id) {
$pdo = db();
$required_folders = getCompanyRequiredFolders($company_id);
$insert_stmt = $pdo->prepare(
"INSERT IGNORE INTO job_job_folders (job_id, company_id, folder_id, name, is_custom)
VALUES (?, ?, ?, ?, ?)"
);
foreach ($required_folders as $rf) {
// Check if this required folder already exists for this job
$check_stmt = $pdo->prepare(
"SELECT COUNT(*) FROM job_job_folders WHERE job_id = ? AND company_id = ? AND folder_id = ? AND is_custom = FALSE"
);
$check_stmt->execute([$job_id, $company_id, $rf['id']]);
if ($check_stmt->fetchColumn() == 0) {
$insert_stmt->execute([$job_id, $company_id, $rf['id'], $rf['name'], FALSE]);
}
}
}
function getJobFolders($job_id, $company_id) {
$stmt = db()->prepare("SELECT jjf.*, COUNT(jf.id) as file_count
FROM job_job_folders jjf
LEFT JOIN job_files jf ON jjf.id = jf.job_job_folder_id
WHERE jjf.job_id = ? AND jjf.company_id = ?
GROUP BY jjf.id
ORDER BY jjf.is_custom ASC, jjf.name ASC");
$stmt->execute([$job_id, $company_id]);
return $stmt->fetchAll(PDO::FETCH_ASSOC);
}
function getFilesInJobFolder($job_job_folder_id, $company_id) {
$stmt = db()->prepare("SELECT * FROM job_files WHERE job_job_folder_id = ? AND company_id = ? ORDER BY filename ASC");
$stmt->execute([$job_job_folder_id, $company_id]);
return $stmt->fetchAll(PDO::FETCH_ASSOC);
}
function createJobFolder($job_id, $company_id, $folder_name, $is_custom = TRUE, $folder_id = null) {
$pdo = db();
// Check for duplicate folder name for this job
$check_stmt = $pdo->prepare("SELECT COUNT(*) FROM job_job_folders WHERE job_id = ? AND company_id = ? AND name = ?");
$check_stmt->execute([$job_id, $company_id, $folder_name]);
if ($check_stmt->fetchColumn() > 0) {
return ['success' => FALSE, 'message' => 'Folder with this name already exists for this job.'];
}
$stmt = $pdo->prepare("INSERT INTO job_job_folders (job_id, company_id, folder_id, name, is_custom) VALUES (?, ?, ?, ?, ?)");
$success = $stmt->execute([$job_id, $company_id, $folder_id, $folder_name, $is_custom]);
return ['success' => $success, 'id' => $pdo->lastInsertId()];
}
function deleteJobFolder($job_job_folder_id, $job_id, $company_id) {
$pdo = db();
$pdo->beginTransaction();
try {
// Check if the folder is custom and empty
$folder_info_stmt = $pdo->prepare("SELECT is_custom FROM job_job_folders WHERE id = ? AND job_id = ? AND company_id = ?");
$folder_info_stmt->execute([$job_job_folder_id, $job_id, $company_id]);
$folder = $folder_info_stmt->fetch(PDO::FETCH_ASSOC);
if (!$folder) {
$pdo->rollBack();
return ['success' => FALSE, 'message' => 'Folder not found.'];
}
if (!$folder['is_custom']) {
$pdo->rollBack();
return ['success' => FALSE, 'message' => 'Required folders cannot be deleted.'];
}
$file_count_stmt = $pdo->prepare("SELECT COUNT(*) FROM job_files WHERE job_job_folder_id = ? AND company_id = ?");
$file_count_stmt->execute([$job_job_folder_id, $company_id]);
if ($file_count_stmt->fetchColumn() > 0) {
$pdo->rollBack();
return ['success' => FALSE, 'message' => 'This folder must be empty before it can be deleted.'];
}
// Delete the folder entry from the database
$delete_stmt = $pdo->prepare("DELETE FROM job_job_folders WHERE id = ? AND job_id = ? AND company_id = ?");
$success = $delete_stmt->execute([$job_job_folder_id, $job_id, $company_id]);
if ($success) {
logActivity($job_id, 'folder_deleted', 'folder', $folder_info_stmt->fetchColumn(3), null); // Log the name of the deleted folder
$pdo->commit();
return ['success' => TRUE];
} else {
$pdo->rollBack();
return ['success' => FALSE, 'message' => 'Failed to delete folder.'];
}
} catch (PDOException $e) {
$pdo->rollBack();
return ['success' => FALSE, 'message' => 'Database error: ' . $e->getMessage()];
}
}
function addJobFile($job_id, $job_job_folder_id, $company_id, $user_id, $filename, $filepath, $mimetype, $size) {
$pdo = db();
$stmt = $pdo->prepare("INSERT INTO job_files (job_id, job_job_folder_id, company_id, user_id, filename, filepath, mimetype, size) VALUES (?, ?, ?, ?, ?, ?, ?, ?)");
$success = $stmt->execute([$job_id, $job_job_folder_id, $company_id, $user_id, $filename, $filepath, $mimetype, $size]);
if ($success) {
logActivity($job_id, 'file_uploaded', 'file', null, $filename); // Log the uploaded file
}
return ['success' => $success, 'id' => $pdo->lastInsertId()];
}
function deleteJobFile($file_id, $job_id, $company_id) {
$pdo = db();
$pdo->beginTransaction();
try {
// Get file information to delete from file system
$file_info_stmt = $pdo->prepare("SELECT filename, filepath FROM job_files WHERE id = ? AND job_id = ? AND company_id = ?");
$file_info_stmt->execute([$file_id, $job_id, $company_id]);
$file = $file_info_stmt->fetch(PDO::FETCH_ASSOC);
if (!$file) {
$pdo->rollBack();
return ['success' => FALSE, 'message' => 'File not found.'];
}
// Delete file from filesystem
if (file_exists($file['filepath'])) {
unlink($file['filepath']);
}
// Delete from database
$delete_stmt = $pdo->prepare("DELETE FROM job_files WHERE id = ? AND job_id = ? AND company_id = ?");
$success = $delete_stmt->execute([$file_id, $job_id, $company_id]);
if ($success) {
logActivity($job_id, 'file_deleted', 'file', $file['filename'], null); // Log the deleted file
$pdo->commit();
return ['success' => TRUE];
} else {
$pdo->rollBack();
return ['success' => FALSE, 'message' => 'Failed to delete file from database.'];
}
} catch (PDOException $e) {
$pdo->rollBack();
return ['success' => FALSE, 'message' => 'Database error: ' . $e->getMessage()];
}
}