175 lines
4.5 KiB
PHP
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;
|
|
}
|
|
}
|