diff --git a/expenses.php b/expenses.php index 0b878d8..ce38d28 100644 --- a/expenses.php +++ b/expenses.php @@ -1,6 +1,7 @@ prepare("INSERT INTO attachments (tenant_id, entity_type, entity_id, file_name, file_path, file_size, mime_type, uploaded_by) VALUES (?, 'expense', ?, ?, ?, ?, ?, 'John Manager')"); - $stmt->execute([$tenant_id, $expense_id, $file_name, $file_path, $file_size, $mime_type]); + $thumbnail_path = null; + if (isImage($mime_type)) { + $thumb_name = 'thumb_' . $new_file_name; + $thumb_path = 'uploads/' . $thumb_name; + if (createThumbnail($file_path, $thumb_path)) { + $thumbnail_path = $thumb_path; + } + } + $stmt = db()->prepare("INSERT INTO attachments (tenant_id, entity_type, entity_id, file_name, file_path, thumbnail_path, file_size, mime_type, uploaded_by) VALUES (?, 'expense', ?, ?, ?, ?, ?, ?, 'John Manager')"); + $stmt->execute([$tenant_id, $expense_id, $file_name, $file_path, $thumbnail_path, $file_size, $mime_type]); } } } diff --git a/includes/header.php b/includes/header.php index d03580e..fc0107d 100644 --- a/includes/header.php +++ b/includes/header.php @@ -57,11 +57,12 @@ $currentPage = basename($_SERVER['PHP_SELF']); Employees diff --git a/includes/media_helper.php b/includes/media_helper.php new file mode 100644 index 0000000..ac1c415 --- /dev/null +++ b/includes/media_helper.php @@ -0,0 +1,107 @@ += 1) { + $newWidth = $width; + $newHeight = $height; + } else { + $newWidth = (int)($width * $ratio); + $newHeight = (int)($height * $ratio); + } + + $thumbnail = imagecreatetruecolor($newWidth, $newHeight); + + // Handle transparency for PNG/GIF/WebP + if ($type == IMAGETYPE_PNG || $type == IMAGETYPE_GIF || $type == IMAGETYPE_WEBP) { + imagealphablending($thumbnail, false); + imagesavealpha($thumbnail, true); + $transparent = imagecolorallocatealpha($thumbnail, 255, 255, 255, 127); + imagefilledrectangle($thumbnail, 0, 0, $newWidth, $newHeight, $transparent); + } + + imagecopyresampled($thumbnail, $sourceImage, 0, 0, 0, 0, $newWidth, $newHeight, $width, $height); + + if (!is_dir(dirname($targetPath))) { + mkdir(dirname($targetPath), 0775, true); + } + + $success = false; + switch ($type) { + case IMAGETYPE_JPEG: + $success = imagejpeg($thumbnail, $targetPath, 85); + break; + case IMAGETYPE_PNG: + $success = imagepng($thumbnail, $targetPath); + break; + case IMAGETYPE_GIF: + $success = imagegif($thumbnail, $targetPath); + break; + case IMAGETYPE_WEBP: + $success = imagewebp($thumbnail, $targetPath); + break; + } + + imagedestroy($sourceImage); + imagedestroy($thumbnail); + + return $success; +} + +/** + * Checks if a mime type is an image. + */ +function isImage(string $mimeType): bool { + return str_starts_with($mimeType, 'image/'); +} + +/** + * Checks if a mime type is a video. + */ +function isVideo(string $mimeType): bool { + return str_starts_with($mimeType, 'video/'); +} diff --git a/labour.php b/labour.php index 0d5b0f8..25fd0f2 100644 --- a/labour.php +++ b/labour.php @@ -1,6 +1,7 @@ prepare("INSERT INTO attachments (tenant_id, entity_type, entity_id, file_name, file_path, file_size, mime_type, uploaded_by) VALUES (?, 'labour_entry', ?, ?, ?, ?, ?, ?)"); - $stmt->execute([$tenant_id, $labour_entry_id, $file_name, $file_path, $file_size, $mime_type, $currentUserName]); + $thumbnail_path = null; + if (isImage($mime_type)) { + $thumb_name = 'thumb_' . $new_file_name; + $thumb_path = 'uploads/' . $thumb_name; + if (createThumbnail($file_path, $thumb_path)) { + $thumbnail_path = $thumb_path; + } + } + + $stmt = $db->prepare("INSERT INTO attachments (tenant_id, entity_type, entity_id, file_name, file_path, thumbnail_path, file_size, mime_type, uploaded_by) VALUES (?, 'labour_entry', ?, ?, ?, ?, ?, ?, ?)"); + $stmt->execute([$tenant_id, $labour_entry_id, $file_name, $file_path, $thumbnail_path, $file_size, $mime_type, $currentUserName]); } } diff --git a/reports.php b/reports.php index fd30ee6..dffbece 100644 --- a/reports.php +++ b/reports.php @@ -115,6 +115,9 @@ include __DIR__ . '/includes/header.php'; + diff --git a/reports_media.php b/reports_media.php new file mode 100644 index 0000000..2e5012b --- /dev/null +++ b/reports_media.php @@ -0,0 +1,226 @@ += ?"; + $params[] = $filter_start; +} +if ($filter_end) { + $where[] = "DATE(a.created_at) <= ?"; + $params[] = $filter_end; +} + +$where_clause = implode(" AND ", $where); + +$query = " + SELECT a.*, + p.name as project_name, + et.name as evidence_type_name + FROM attachments a + LEFT JOIN labour_entries le ON a.entity_type = 'labour_entry' AND a.entity_id = le.id + LEFT JOIN expenses ex ON a.entity_type = 'expense' AND a.entity_id = ex.id + LEFT JOIN projects p ON p.id = COALESCE(le.project_id, ex.project_id) + LEFT JOIN evidence_types et ON le.evidence_type_id = et.id + WHERE $where_clause + ORDER BY a.created_at DESC +"; + +$stmt = db()->prepare($query); +$stmt->execute($params); +$mediaItems = $stmt->fetchAll(); + +// Get filter options +$authors = db()->prepare("SELECT DISTINCT uploaded_by FROM attachments WHERE tenant_id = ? AND uploaded_by IS NOT NULL ORDER BY uploaded_by"); +$authors->execute([$tenant_id]); +$authorList = $authors->fetchAll(PDO::FETCH_COLUMN); + +$projects = db()->prepare("SELECT id, name FROM projects WHERE tenant_id = ? AND is_archived = 0 ORDER BY name"); +$projects->execute([$tenant_id]); +$projectList = $projects->fetchAll(); + +$evidenceTypes = db()->prepare("SELECT id, name FROM evidence_types WHERE tenant_id = ? ORDER BY name"); +$evidenceTypes->execute([$tenant_id]); +$evidenceTypeList = $evidenceTypes->fetchAll(); + +$pageTitle = "SR&ED Manager - Media Gallery"; +include __DIR__ . '/includes/header.php'; +?> + +
+
+
+ +

Media Gallery

+
+
+ Total Items: +
+
+ + +
+
+
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+
+ + +
+
+
+
+
+ + +
+
+ +
No media files found
+

Try adjusting your filters or upload some images/videos.

+ Reset All Filters +
+
+ +
+ +
+
+
+ + <?= htmlspecialchars($item['file_name']) ?> + +
+ +
+ + +
+ +
+
+ +
+
+ + + + +
+
+ +
+
+ +
+ +
+ +
+ +
+
+ +
+ +
+
+
+
+ +
+ +
+ + + +