Files
Gnuboard7/modules/_bundled/sirsoft-page/src/Models/PageAttachment.php
T
chym1217 b03042b6d7 fix(page): 페이지·첨부 삭제를 물리 삭제로 전환해 슬러그 재사용 가능하도록 수정
페이지 삭제 후 동일 슬러그로 재생성 시 "이미 사용 중" 오류가 나던 문제 수정.
슬러그 중복 체크(SoftDeletes 스코프로 삭제 행 제외)와 생성 검증(Rule::unique로
삭제 행 포함)이 soft delete를 다르게 취급해 발생. Page/PageAttachment의
SoftDeletes를 제거하고 deleted_at 컬럼을 마이그레이션으로 정리해 두 경로를 정합화.
2026-07-06 09:37:01 +09:00

148 lines
3.2 KiB
PHP

<?php
namespace Modules\Sirsoft\Page\Models;
use App\Models\User;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
use Modules\Sirsoft\Page\Database\Factories\PageAttachmentFactory;
class PageAttachment extends Model
{
use HasFactory;
/**
* 팩토리 클래스를 반환합니다.
*/
protected static function newFactory(): PageAttachmentFactory
{
return PageAttachmentFactory::new();
}
/**
* 테이블명
*
* @var string
*/
protected $table = 'page_attachments';
/**
* 모델 부트
*/
protected static function boot(): void
{
parent::boot();
// 생성 시 hash 자동 생성 (URL용 고유 키)
static::creating(function (self $model) {
if (empty($model->hash)) {
$model->hash = self::generateHash();
}
});
}
/**
* 고유 해시를 생성합니다.
*
* @return string 12자리 고유 해시
*/
public static function generateHash(): string
{
do {
$hash = substr(bin2hex(random_bytes(6)), 0, 12);
} while (self::where('hash', $hash)->exists());
return $hash;
}
/**
* 대량 할당 가능한 속성
*
* @var array<int, string>
*/
protected $fillable = [
'page_id',
'temp_key',
'hash',
'original_filename',
'stored_filename',
'disk',
'path',
'mime_type',
'size',
'collection',
'order',
'meta',
'created_by',
];
/**
* 속성 캐스팅
*
* @return array<string, string>
*/
protected function casts(): array
{
return [
'meta' => 'array',
'size' => 'integer',
'order' => 'integer',
];
}
/**
* 페이지와의 관계를 정의합니다.
*
* @return BelongsTo<Page, PageAttachment>
*/
public function page(): BelongsTo
{
return $this->belongsTo(Page::class, 'page_id');
}
/**
* 업로더와의 관계를 정의합니다.
*
* @return BelongsTo<User, PageAttachment>
*/
public function creator(): BelongsTo
{
return $this->belongsTo(User::class, 'created_by');
}
/**
* 이미지 파일 여부를 확인합니다.
*
* @return bool 이미지 여부
*/
public function isImage(): bool
{
return str_starts_with($this->mime_type, 'image/');
}
/**
* 다운로드 URL을 반환합니다.
*
* @return string 다운로드 URL
*/
public function getDownloadUrlAttribute(): string
{
return '/api/modules/sirsoft-page/pages/attachment/'.$this->hash;
}
/**
* 이미지 미리보기 URL을 반환합니다.
*
* @return string|null 미리보기 URL (이미지가 아니면 null)
*/
public function getPreviewUrlAttribute(): ?string
{
if (! $this->isImage()) {
return null;
}
return '/api/modules/sirsoft-page/pages/attachment/'.$this->hash.'/preview';
}
}