63 lines
2.1 KiB
PHP
63 lines
2.1 KiB
PHP
<?php
|
|
|
|
declare(strict_types=1);
|
|
|
|
namespace App\Services;
|
|
|
|
use Exception;
|
|
|
|
final class FileStorageService
|
|
{
|
|
private string $storagePath;
|
|
|
|
public function __construct()
|
|
{
|
|
$this->storagePath = $_ENV['STORAGE_PATH'] ?? dirname(__DIR__, 2) . '/storage';
|
|
}
|
|
|
|
public function store(array $file, string $tenantId, string $companyId): string
|
|
{
|
|
// 1. Validate MIME
|
|
$finfo = finfo_open(FILEINFO_MIME_TYPE);
|
|
$mime = finfo_file($finfo, $file['tmp_name']);
|
|
finfo_close($finfo);
|
|
|
|
$allowedMimes = ['application/pdf', 'image/jpeg', 'image/png', 'image/webp', 'application/json', 'text/plain', 'text/xml', 'application/xml'];
|
|
if (!in_array($mime, $allowedMimes)) {
|
|
throw new Exception("نوع الملف غير مسموح به ({$mime})");
|
|
}
|
|
|
|
// 2. Generate path
|
|
$dir = $this->storagePath . '/invoices/' . $tenantId . '/' . $companyId;
|
|
if (!is_dir($dir)) {
|
|
if (!mkdir($dir, 0777, true)) {
|
|
$err = error_get_last();
|
|
throw new Exception("فشل إنشاء مجلد الحفظ: " . $dir . " - " . ($err['message'] ?? ''));
|
|
}
|
|
}
|
|
|
|
$extension = pathinfo($file['name'], PATHINFO_EXTENSION);
|
|
$filename = hash('sha256', $file['name'] . time() . uniqid()) . '.' . $extension;
|
|
$targetPath = $dir . '/' . $filename;
|
|
|
|
if (isset($file['error']) && $file['error'] !== UPLOAD_ERR_OK) {
|
|
throw new Exception("حدث خطأ أثناء رفع الملف من المتصفح. كود الخطأ: " . $file['error']);
|
|
}
|
|
|
|
if (!move_uploaded_file($file['tmp_name'], $targetPath)) {
|
|
// Fallback for some non-standard PHP environments
|
|
if (!copy($file['tmp_name'], $targetPath)) {
|
|
$err = error_get_last();
|
|
throw new Exception("فشل نقل الملف إلى: " . $targetPath . " - " . ($err['message'] ?? ''));
|
|
}
|
|
}
|
|
|
|
return $targetPath;
|
|
}
|
|
|
|
public function getHash(string $filePath): string
|
|
{
|
|
return hash_file('sha256', $filePath);
|
|
}
|
|
}
|