new ataxchments preview code

This commit is contained in:
Mark Gregory
2026-06-24 10:40:19 +01:00
parent a42b5787b9
commit c44b362710
17 changed files with 1071 additions and 43 deletions
+95 -10
View File
@@ -5,6 +5,8 @@ declare(strict_types=1);
namespace Modules\Helpdesk\Services;
use Illuminate\Http\UploadedFile;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Schema;
use Illuminate\Support\Facades\Storage;
use Livewire\Features\SupportFileUploads\TemporaryUploadedFile;
use Modules\Helpdesk\Models\Attachment;
@@ -43,16 +45,16 @@ final class AttachmentService
$size = (int) Storage::disk($disk)->size($path);
}
Attachment::query()->create([
'ticket_id' => $ticket->id,
'comment_id' => $comment?->id,
'user_id' => $userId,
'disk' => $disk,
'path' => $path,
'original_name' => $originalName,
'mime_type' => $mimeType,
'size' => $size,
]);
Attachment::query()->create($this->attachmentAttributes(
ticket: $ticket,
comment: $comment,
userId: $userId,
disk: $disk,
path: $path,
originalName: $originalName,
mimeType: $mimeType,
size: $size,
));
}
}
@@ -65,6 +67,89 @@ final class AttachmentService
$attachment->delete();
}
/**
* Build attachment attributes while remaining compatible with older databases.
*
* @return array<string, mixed>
*/
private function attachmentAttributes(Ticket $ticket, ?Comment $comment, int $userId, string $disk, string $path, string $originalName, string $mimeType, int $size): array
{
$attributes = [
'ticket_id' => $ticket->id,
'comment_id' => $comment?->id,
'user_id' => $userId,
'disk' => $disk,
'path' => $path,
'original_name' => $originalName,
'mime_type' => $mimeType,
'size' => $size,
];
if (Schema::hasColumn('helpdesk_attachments', 'extension')) {
$attributes['extension'] = strtolower((string) pathinfo($originalName, PATHINFO_EXTENSION));
}
if (Schema::hasColumn('helpdesk_attachments', 'category')) {
$attributes['category'] = $this->categoryFor($originalName, $mimeType);
}
if (Schema::hasColumn('helpdesk_attachments', 'checksum_sha256') && Storage::disk($disk)->exists($path)) {
$stream = Storage::disk($disk)->readStream($path);
if (is_resource($stream)) {
$context = hash_init('sha256');
hash_update_stream($context, $stream);
$attributes['checksum_sha256'] = hash_final($context);
fclose($stream);
}
}
return $attributes;
}
/**
* Categorise uploaded files for icons, previews and safe code viewing.
*/
private function categoryFor(string $originalName, string $mimeType): string
{
$extension = strtolower((string) pathinfo($originalName, PATHINFO_EXTENSION));
if (str_starts_with($mimeType, 'image/') || in_array($extension, ['png', 'jpg', 'jpeg', 'webp', 'gif'], true)) {
return 'image';
}
if ($extension === 'pdf' || $mimeType === 'application/pdf') {
return 'pdf';
}
if (in_array($extension, ['zip', 'tar', 'gz', '7z', 'rar'], true)) {
return 'archive';
}
if (in_array($extension, config('helpdesk.allowed_source_extensions', []), true)) {
return 'source';
}
return 'file';
}
/**
* Soft-delete a stored attachment while retaining audit metadata.
*/
public function softDelete(Attachment $attachment, int $userId): void
{
DB::table('helpdesk_attachments')
->where('id', $attachment->id)
->update(array_filter([
'deleted_at' => now(),
'deleted_by' => Schema::hasColumn('helpdesk_attachments', 'deleted_by') ? $userId : null,
], static fn (mixed $value): bool => $value !== null));
}
/**
* Determine whether the value is a storeable uploaded file.
*/