هپشلث عحمخشی

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
+2 -12
View File
@@ -52,21 +52,11 @@ class FileController extends Controller
$data['has_thumb'] = false; $data['has_thumb'] = false;
$data['size'] = $uploaded->getSize(); $data['size'] = $uploaded->getSize();
$stored = Storage::disk('public')->putFileAs($path, $uploaded, $file_name); $stored = Storage::disk('public')->putFileAs($path, $uploaded, $file_name);
if (! $stored) { if (! $stored || ! Storage::disk('public')->exists($stored)) {
return response()->json(['message' => 'ذخیره فایل روی سرور ناموفق بود'], 500); return response()->json(['message' => 'ذخیره فایل روی سرور ناموفق بود'], 500);
} }
$storageFile = storage_path('app/public/'.$path.'/'.$file_name); $data['src'] = 'storage/'.$stored;
$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['user_id'] = auth()->id();
$data['sts'] = 1; $data['sts'] = 1;
$relativePath = $data['src']; $relativePath = $data['src'];
+11
View File
@@ -109,9 +109,15 @@ class File extends Model
/** /**
* پایهٔ URL فایل‌های storage. * پایهٔ URL فایل‌های storage.
* در درخواست HTTP، دامنهٔ همان درخواست اولویت دارد (جلوگیری از URL اشتباه وقتی settings دامنهٔ ماژول دیگر است).
*/ */
public static function resolvePublicBaseUrl(): string public static function resolvePublicBaseUrl(): string
{ {
$fromRequest = self::baseUrlFromRequest();
if ($fromRequest !== '') {
return $fromRequest;
}
$fromSettings = self::baseUrlFromSettings(); $fromSettings = self::baseUrlFromSettings();
if ($fromSettings !== '') { if ($fromSettings !== '') {
return self::ensureAbsoluteUrl($fromSettings); return self::ensureAbsoluteUrl($fromSettings);
@@ -127,6 +133,11 @@ class File extends Model
return self::ensureAbsoluteUrl(self::ensureServerPublicBase(rtrim($appUrl, '/'))); return self::ensureAbsoluteUrl(self::ensureServerPublicBase(rtrim($appUrl, '/')));
} }
return '';
}
private static function baseUrlFromRequest(): string
{
try { try {
if (app()->bound('request')) { if (app()->bound('request')) {
$request = request(); $request = request();
+58 -18
View File
@@ -4,52 +4,76 @@ namespace Tests\Unit;
use App\Models\File; use App\Models\File;
use App\Models\Setting; use App\Models\Setting;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Config; use Illuminate\Support\Facades\Config;
use Tests\TestCase; use Tests\TestCase;
class FilePublicUrlTest extends 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( Setting::query()->updateOrCreate(
['key' => 'admin_url'], ['key' => 'server_url'],
['value' => 'https://garoosigholaktala.ir/admin/', 'is_active' => 1, 'title_fa' => 'admin'] ['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(); Setting::query()->updateOrCreate(
Config::set('app.domain', 'https://garoosigholaktala.ir'); ['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'); $url = File::publicUrl('storage/1405/02/27/sample.jpg');
$this->assertSame( $this->assertSame(
'https://garoosigholaktala.ir/server/storage/1405/02/27/sample.jpg', $this->expectedServerBase($host).'/storage/1405/02/27/sample.jpg',
$url $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(); $host = 'tenant-a.test';
Config::set('app.domain', 'https://garoosigholaktala.ir'); $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( $this->assertSame(
'https://garoosigholaktala.ir/server/storage/1405/02/27/sample.jpg', $this->expectedServerBase($host).'/storage/1405/02/27/sample.jpg',
$url $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.domain', null);
Config::set('app.url', 'http://localhost'); 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 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.domain', null);
Config::set('app.url', 'http://localhost'); Config::set('app.url', 'http://localhost');
$request = \Illuminate\Http\Request::create('https://niazitala.ir/server/admin/file', 'POST'); $host = 'tenant-c.test';
$this->app->instance('request', $request); $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
);
} }
} }