Files
musadaq-saas/app/Services/FileStorageService.php

64 lines
2.1 KiB
PHP

<?php
declare(strict_types=1);
namespace App\Services;
use Exception;
final class FileStorageService
{
private string $storagePath;
public function __construct()
{
// Use dynamic path to avoid issues if Mac .env is deployed to Linux server
$this->storagePath = 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);
}
}