Files
My-KOPKB/be/app/Services/DocumentService.php
T

169 lines
4.3 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 {
$fileName = time().'_'.$file->getClientOriginalName();
$folderName = strtolower(class_basename($model));
$filePath = $file->storeAs("documents/{$folderName}", $fileName, Document::STORAGE_DISK);
return $model->documents()->create([
'name' => $file->getClientOriginalName(),
'path' => $filePath,
'file_size' => $file->getSize(),
'mime_type' => $file->getClientMimeType(),
'type' => $documentType,
'description' => $description,
'uploaded_by' => auth()->id(),
]);
}
/**
* Delete a document.
*/
public function deleteDocument(string $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('type', $documentType);
}
return $query->with('uploadedBy')->get();
}
/**
* Get document by ID with validation.
*/
public function getDocument(string $documentId): Document
{
return Document::with('uploadedBy')->findOrFail($documentId);
}
/**
* Download a document.
*/
public function downloadDocument(string $documentId)
{
$document = $this->getDocument($documentId);
$disk = Storage::disk(Document::STORAGE_DISK);
if (! $disk->exists($document->path)) {
throw new Exception('File not found');
}
return $disk->download($document->path, $document->name);
}
/**
* Get documents count for a model.
*/
public function getDocumentsCount(Model $model, ?string $documentType = null): int
{
$query = $model->documents();
if ($documentType) {
$query->where('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
if ($file->getSize() > $maxSize) {
throw new Exception('File size exceeds maximum limit of '.$this->getMaxFileSize().'KB');
}
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;
}
}