هپشلث عحمخشی

This commit is contained in:
2026-07-06 22:01:16 +03:30
parent 61383a6dda
commit c05a24d57b
3 changed files with 142 additions and 101 deletions
+73 -83
View File
@@ -1,83 +1,73 @@
<?php
namespace App\Http\Controllers\Admin;
use App\Http\Controllers\Controller;
use App\Models\File;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Storage;
class FileController extends Controller
{
/**
* make directory in Public Storage By Date
*
* @return string
*/
protected function createDir(): string
{
$now = Verta();
$path = preg_replace('/-/', '/', $now->formatDate());
$disk = Storage::disk('public');
if (! $disk->exists($path)) {
$disk->makeDirectory($path);
$disk->makeDirectory($path.'/thumb');
}
return $path;
}
public function store(Request $request)
{
$uploaded = $request->file('file');
if (! $uploaded || ! $uploaded->isValid()) {
return response()->json(['message' => 'فایل بارگذاری نشد یا خالی است'], 422);
}
if ($uploaded->getSize() < 1) {
return response()->json(['message' => 'فایل خالی است'], 422);
}
$path = $this->createDir();
$data = $request->all();
$data['original_name'] = $uploaded->getClientOriginalName();
$data['ext'] = $uploaded->getClientOriginalExtension()
?: $uploaded->extension()
?: 'jpg';
if (! isset($data['title']) || is_null($data['title'])) {
$data['title'] = $data['original_name'];
}
$file_name_src = md5(time().$data['original_name']);
$file_name = $file_name_src.'.'.$data['ext'];
$data['has_thumb'] = false;
$data['size'] = $uploaded->getSize();
$stored = Storage::disk('public')->putFileAs($path, $uploaded, $file_name);
if (! $stored) {
return response()->json(['message' => 'ذخیره فایل روی سرور ناموفق بود'], 500);
}
$storageFile = storage_path('app/public/'.$path.'/'.$file_name);
$publicFile = public_path('storage/'.$path.'/'.$file_name);
if (! is_file($publicFile) && is_file($storageFile)) {
$publicDir = dirname($publicFile);
if (! is_dir($publicDir)) {
mkdir($publicDir, 0755, true);
}
@copy($storageFile, $publicFile);
}
$data['src'] = 'storage/'.$path.'/'.$file_name;
$data['user_id'] = auth()->id();
$data['sts'] = 1;
$relativePath = $data['src'];
$file_create = File::create($data);
$fullSrc = File::publicUrl($relativePath);
$payload = $file_create->fresh()->toArray();
$payload['path'] = $relativePath;
$payload['full_src'] = $fullSrc;
$payload['src'] = $fullSrc;
return response()->json($payload);
}
}
<?php
namespace App\Http\Controllers\Admin;
use App\Http\Controllers\Controller;
use App\Models\File;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Storage;
class FileController extends Controller
{
/**
* make directory in Public Storage By Date
*
* @return string
*/
protected function createDir(): string
{
$now = Verta();
$path = preg_replace('/-/', '/', $now->formatDate());
$disk = Storage::disk('public');
if (! $disk->exists($path)) {
$disk->makeDirectory($path);
$disk->makeDirectory($path.'/thumb');
}
return $path;
}
public function store(Request $request)
{
$uploaded = $request->file('file');
if (! $uploaded || ! $uploaded->isValid()) {
return response()->json(['message' => 'فایل بارگذاری نشد یا خالی است'], 422);
}
if ($uploaded->getSize() < 1) {
return response()->json(['message' => 'فایل خالی است'], 422);
}
$path = $this->createDir();
$data = $request->all();
$data['original_name'] = $uploaded->getClientOriginalName();
$data['ext'] = $uploaded->getClientOriginalExtension()
?: $uploaded->extension()
?: 'jpg';
if (! isset($data['title']) || is_null($data['title'])) {
$data['title'] = $data['original_name'];
}
$file_name_src = md5(time().$data['original_name']);
$file_name = $file_name_src.'.'.$data['ext'];
$data['has_thumb'] = false;
$data['size'] = $uploaded->getSize();
$stored = Storage::disk('public')->putFileAs($path, $uploaded, $file_name);
if (! $stored || ! Storage::disk('public')->exists($stored)) {
return response()->json(['message' => 'ذخیره فایل روی سرور ناموفق بود'], 500);
}
$data['src'] = 'storage/'.$stored;
$data['user_id'] = auth()->id();
$data['sts'] = 1;
$relativePath = $data['src'];
$file_create = File::create($data);
$fullSrc = File::publicUrl($relativePath);
$payload = $file_create->fresh()->toArray();
$payload['path'] = $relativePath;
$payload['full_src'] = $fullSrc;
$payload['src'] = $fullSrc;
return response()->json($payload);
}
}
+11
View File
@@ -109,9 +109,15 @@ class File extends Model
/**
* پایهٔ URL فایل‌های storage.
* در درخواست HTTP، دامنهٔ همان درخواست اولویت دارد (جلوگیری از URL اشتباه وقتی settings دامنهٔ ماژول دیگر است).
*/
public static function resolvePublicBaseUrl(): string
{
$fromRequest = self::baseUrlFromRequest();
if ($fromRequest !== '') {
return $fromRequest;
}
$fromSettings = self::baseUrlFromSettings();
if ($fromSettings !== '') {
return self::ensureAbsoluteUrl($fromSettings);
@@ -127,6 +133,11 @@ class File extends Model
return self::ensureAbsoluteUrl(self::ensureServerPublicBase(rtrim($appUrl, '/')));
}
return '';
}
private static function baseUrlFromRequest(): string
{
try {
if (app()->bound('request')) {
$request = request();
+58 -18
View File
@@ -4,52 +4,76 @@ namespace Tests\Unit;
use App\Models\File;
use App\Models\Setting;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Config;
use Tests\TestCase;
class FilePublicUrlTest extends TestCase
{
private function seedGaroosiAdminUrl(): void
private function bindRequest(string $host, string $path = '/server/admin/file'): Request
{
$request = Request::create('https://'.$host.$path, 'POST');
$this->app->instance('request', $request);
return $request;
}
private function expectedServerBase(string $host): string
{
return 'https://'.$host.'/server';
}
private function seedServerUrlSetting(string $host): void
{
Setting::query()->updateOrCreate(
['key' => 'admin_url'],
['value' => 'https://garoosigholaktala.ir/admin/', 'is_active' => 1, 'title_fa' => 'admin']
['key' => 'server_url'],
['value' => $this->expectedServerBase($host), 'is_active' => 1, 'title_fa' => 'server']
);
}
public function test_public_url_uses_server_storage_path_from_site_domain(): void
private function seedAdminUrlSetting(string $host): void
{
$this->seedGaroosiAdminUrl();
Config::set('app.domain', 'https://garoosigholaktala.ir');
Setting::query()->updateOrCreate(
['key' => 'admin_url'],
['value' => 'https://'.$host.'/admin/', 'is_active' => 1, 'title_fa' => 'admin']
);
}
public function test_public_url_uses_request_host_for_storage_path(): void
{
$host = 'tenant-a.test';
$this->bindRequest($host);
$url = File::publicUrl('storage/1405/02/27/sample.jpg');
$this->assertSame(
'https://garoosigholaktala.ir/server/storage/1405/02/27/sample.jpg',
$this->expectedServerBase($host).'/storage/1405/02/27/sample.jpg',
$url
);
}
public function test_public_url_rewrites_legacy_wrong_absolute_url(): void
public function test_public_url_rewrites_legacy_wrong_absolute_url_using_request_host(): void
{
$this->seedGaroosiAdminUrl();
Config::set('app.domain', 'https://garoosigholaktala.ir');
$host = 'tenant-a.test';
$this->bindRequest($host);
$url = File::publicUrl('https://garoosigholaktala.ir/storage/1405/02/27/sample.jpg');
$url = File::publicUrl('https://'.$host.'/storage/1405/02/27/sample.jpg');
$this->assertSame(
'https://garoosigholaktala.ir/server/storage/1405/02/27/sample.jpg',
$this->expectedServerBase($host).'/storage/1405/02/27/sample.jpg',
$url
);
}
public function test_resolve_base_from_admin_url_setting(): void
public function test_resolve_base_from_admin_url_setting_when_no_http_request(): void
{
Config::set('app.domain', null);
Config::set('app.url', 'http://localhost');
$this->seedGaroosiAdminUrl();
$this->assertSame('https://garoosigholaktala.ir/server', File::resolvePublicBaseUrl());
$host = 'tenant-b.test';
$this->seedAdminUrlSetting($host);
$this->assertSame($this->expectedServerBase($host), File::resolvePublicBaseUrl());
}
public function test_public_url_falls_back_to_relative_path_when_base_unknown(): void
@@ -67,9 +91,25 @@ class FilePublicUrlTest extends TestCase
Config::set('app.domain', null);
Config::set('app.url', 'http://localhost');
$request = \Illuminate\Http\Request::create('https://niazitala.ir/server/admin/file', 'POST');
$this->app->instance('request', $request);
$host = 'tenant-c.test';
$this->bindRequest($host);
$this->assertSame('https://niazitala.ir/server', File::resolvePublicBaseUrl());
$this->assertSame($this->expectedServerBase($host), File::resolvePublicBaseUrl());
}
public function test_request_host_wins_over_stale_settings_domain(): void
{
$staleHost = 'stale-tenant.test';
$requestHost = 'current-tenant.test';
$this->seedServerUrlSetting($staleHost);
$this->bindRequest($requestHost);
$url = File::publicUrl('storage/1405/04/15/sample.png');
$this->assertSame(
$this->expectedServerBase($requestHost).'/storage/1405/04/15/sample.png',
$url
);
}
}