Files
boursecu_server/app/Models/File.php
T

188 lines
5.2 KiB
PHP
Raw Normal View History

2026-02-16 09:29:37 +00:00
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
class File extends Model
{
2026-06-29 20:02:20 +03:30
use HasFactory, Selector;
2026-06-29 19:58:06 +03:30
2026-02-16 09:29:37 +00:00
protected $fillable = [
'original_name',
'title',
'ext',
'src',
'size',
'user_id',
'type',
'has_thumb',
'url',
];
2026-06-29 19:58:06 +03:30
2026-02-16 09:29:37 +00:00
protected $casts = [
2026-06-29 19:58:06 +03:30
'has_thumb' => 'boolean',
2026-02-16 09:29:37 +00:00
];
2026-06-29 19:58:06 +03:30
protected $appends = [
'full_src',
];
/**
2026-06-29 20:02:20 +03:30
* URL کامل تصویر — همان قرارداد قبلی API (src = آدرس قابل نمایش).
2026-06-29 19:58:06 +03:30
*/
public function getSrcAttribute(): ?string
{
return self::publicUrl($this->attributes['src'] ?? null);
}
2026-06-29 20:02:20 +03:30
public function getFullSrcAttribute(): ?string
{
return $this->src;
}
2026-06-29 19:58:06 +03:30
public static function publicUrl(?string $path): ?string
{
if ($path === null || trim($path) === '') {
return null;
}
$trimmed = trim($path);
if (preg_match('/^https?:\/\//i', $trimmed)) {
2026-06-29 20:11:39 +03:30
return self::rewriteWrongPublicUrl($trimmed) ?? $trimmed;
}
$relative = self::normalizeRelativeStoragePath($trimmed);
$base = self::resolvePublicBaseUrl();
if ($base === '' || $relative === '') {
return null;
}
return $base.'/'.$relative;
}
/**
* مسیر نسبی داخل public/storage — حتی اگر قبلاً URL کامل اشتباه در DB ذخیره شده باشد.
*/
public static function normalizeRelativeStoragePath(string $path): string
{
$path = trim($path);
if (preg_match('#/storage/(.+)$#i', $path, $matches)) {
return 'storage/'.ltrim($matches[1], '/');
}
$relative = ltrim($path, '/');
if (! str_starts_with($relative, 'storage/')) {
$relative = 'storage/'.$relative;
}
return $relative;
}
/**
* اصلاح URLهای قدیمی: https://site.ir/storage/... → https://site.ir/server/storage/...
*/
public static function rewriteWrongPublicUrl(string $url): ?string
{
if (! preg_match('#^(https?://[^/]+)/storage/(.+)$#i', $url, $matches)) {
return null;
2026-06-29 19:58:06 +03:30
}
2026-06-29 20:07:03 +03:30
$base = self::resolvePublicBaseUrl();
if ($base === '') {
return null;
}
2026-06-29 20:02:20 +03:30
2026-06-29 20:11:39 +03:30
if (str_contains($base, '/server') && ! str_contains($matches[1].'/storage/', '/server/storage/')) {
return $base.'/storage/'.$matches[2];
2026-06-29 20:07:03 +03:30
}
2026-06-29 20:11:39 +03:30
return null;
2026-06-29 20:07:03 +03:30
}
/**
2026-06-29 20:11:39 +03:30
* پایهٔ URL فایل‌های storage.
2026-06-29 20:07:03 +03:30
*/
public static function resolvePublicBaseUrl(): string
{
2026-06-29 20:11:39 +03:30
$fromSettings = self::baseUrlFromSettings();
if ($fromSettings !== '') {
2026-07-06 17:06:03 +03:30
return self::ensureAbsoluteUrl($fromSettings);
2026-06-29 20:11:39 +03:30
}
2026-06-29 20:07:03 +03:30
$domain = config('app.domain');
if (is_string($domain) && $domain !== '' && ! str_contains($domain, 'localhost')) {
2026-07-06 17:06:03 +03:30
return self::ensureAbsoluteUrl(self::ensureServerPublicBase(rtrim($domain, '/')));
2026-06-29 20:07:03 +03:30
}
$appUrl = config('app.url');
2026-06-29 20:11:39 +03:30
if (is_string($appUrl) && $appUrl !== '' && ! str_contains($appUrl, 'localhost')) {
2026-07-06 17:06:03 +03:30
return self::ensureAbsoluteUrl(self::ensureServerPublicBase(rtrim($appUrl, '/')));
2026-06-29 20:07:03 +03:30
}
2026-06-29 20:11:39 +03:30
return '';
}
2026-07-06 17:06:03 +03:30
private static function ensureAbsoluteUrl(string $base): string
{
$base = rtrim(trim($base), '/');
if ($base === '') {
return '';
}
if (! preg_match('/^https?:\/\//i', $base)) {
$base = 'https://'.ltrim($base, '/');
}
return $base;
}
2026-06-29 20:11:39 +03:30
private static function baseUrlFromSettings(): string
{
2026-06-29 20:07:03 +03:30
try {
$rows = Setting::query()
->whereIn('key', ['bace_url', 'server_url', 'admin_url', 'app_url'])
->where('is_active', 1)
->pluck('value', 'key');
2026-06-29 20:11:39 +03:30
foreach (['server_url', 'bace_url'] as $key) {
2026-06-29 20:07:03 +03:30
$value = trim((string) ($rows[$key] ?? ''));
2026-07-06 17:06:03 +03:30
if ($value !== '') {
2026-06-29 20:07:03 +03:30
return rtrim($value, '/');
}
}
$adminUrl = trim((string) ($rows['admin_url'] ?? ''));
if ($adminUrl !== '' && preg_match('#/admin#i', $adminUrl)) {
return rtrim(preg_replace('#/admin/?$#i', '/server', rtrim($adminUrl, '/')), '/');
}
$siteUrl = trim((string) ($rows['app_url'] ?? ''));
2026-07-06 17:06:03 +03:30
if ($siteUrl !== '') {
$siteUrl = rtrim($siteUrl, '/');
if (! preg_match('#/server$#i', $siteUrl)) {
$siteUrl .= '/server';
}
return $siteUrl;
2026-06-29 20:07:03 +03:30
}
} catch (\Throwable) {
}
return '';
2026-02-16 09:29:37 +00:00
}
2026-06-29 20:11:39 +03:30
private static function ensureServerPublicBase(string $base): string
{
if (preg_match('#/(server|api)(/|$)#i', $base)) {
return rtrim($base, '/');
}
return rtrim($base, '/').'/server';
}
2026-02-16 09:29:37 +00:00
}