Files
My-KOPKB/be/app/Services/DocumentService.php
T
ISMAIL MASSERAN 94ecbe5887 first init
2026-06-08 11:37:14 +08:00

175 lines
4.5 KiB
PHP

<?php
namespace App\Services;
use App\Models\Document;
use Exception;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Http\UploadedFile;
use Illuminate\Support\Facades\Storage;
class DocumentService
{
/**
* Upload a document for any model.
*/
public function uploadDocument(
Model $model,
UploadedFile $file,
string $documentType = 'general',
?string $description = null
): Document {
// Generate unique filename
$fileName = time().'_'.$file->getClientOriginalName();
// Store file in a folder named after the model
$folderName = strtolower(class_basename($model));
$filePath = $file->storeAs("documents/{$folderName}", $fileName, 'public');
// Create document record
return Document::create([
'documentable_type' => get_class($model),
'documentable_id' => $model->id,
'document_name' => $file->getClientOriginalName(),
'document_path' => $filePath,
'file_size' => $file->getSize(),
'mime_type' => $file->getClientMimeType(),
'document_type' => $documentType,
'description' => $description,
'uploaded_by' => auth()->id(),
]);
}
/**
* Delete a document.
*/
public function deleteDocument(int $documentId): bool
{
$document = Document::findOrFail($documentId);
return $document->delete();
}
/**
* Get all documents for a model.
*/
public function getDocuments(Model $model, ?string $documentType = null)
{
$query = $model->documents();
if ($documentType) {
$query->where('document_type', $documentType);
}
return $query->with('uploadedBy')->get();
}
/**
* Get document by ID with validation.
*/
public function getDocument(int $documentId): Document
{
return Document::with('uploadedBy')->findOrFail($documentId);
}
/**
* Download a document.
*/
public function downloadDocument(int $documentId)
{
$document = $this->getDocument($documentId);
if (! Storage::exists($document->document_path)) {
throw new Exception('File not found');
}
return Storage::download($document->document_path, $document->document_name);
}
/**
* Get documents count for a model.
*/
public function getDocumentsCount(Model $model, ?string $documentType = null): int
{
$query = $model->documents();
if ($documentType) {
$query->where('document_type', $documentType);
}
return $query->count();
}
/**
* Check if model has documents.
*/
public function hasDocuments(Model $model, ?string $documentType = null): bool
{
return $this->getDocumentsCount($model, $documentType) > 0;
}
/**
* Get supported file types.
*/
public function getSupportedFileTypes(): array
{
return [
'pdf' => 'application/pdf',
'doc' => 'application/msword',
'docx' => 'application/vnd.openxmlformats-officedocument.wordprocessingml.document',
'jpg' => 'image/jpeg',
'jpeg' => 'image/jpeg',
'png' => 'image/png',
'gif' => 'image/gif',
];
}
/**
* Get max file size in KB.
*/
public function getMaxFileSize(): int
{
return 10240; // 10MB
}
/**
* Validate file upload.
*/
public function validateFile(UploadedFile $file): bool
{
$supportedTypes = $this->getSupportedFileTypes();
$maxSize = $this->getMaxFileSize() * 1024; // Convert to bytes
// Check file size
if ($file->getSize() > $maxSize) {
throw new Exception('File size exceeds maximum limit of '.$this->getMaxFileSize().'KB');
}
// Check mime type
if (! in_array($file->getClientMimeType(), $supportedTypes)) {
throw new Exception('File type not supported. Supported types: '.implode(', ', array_keys($supportedTypes)));
}
return true;
}
/**
* Bulk delete documents for a model.
*/
public function bulkDeleteDocuments(Model $model, array $documentIds): int
{
$deletedCount = 0;
foreach ($documentIds as $documentId) {
$document = $model->documents()->find($documentId);
if ($document) {
$document->delete();
$deletedCount++;
}
}
return $deletedCount;
}
}