289 lines
9.1 KiB
PHP
289 lines
9.1 KiB
PHP
<?php
|
|
|
|
namespace App\Repositories;
|
|
|
|
use App\Contracts\Repositories\LayoutExtensionRepositoryInterface;
|
|
use App\Enums\LayoutExtensionType;
|
|
use App\Enums\LayoutSourceType;
|
|
use App\Models\LayoutExtension;
|
|
use Illuminate\Support\Collection;
|
|
|
|
/**
|
|
* 레이아웃 확장 리포지토리 구현
|
|
*/
|
|
class LayoutExtensionRepository implements LayoutExtensionRepositoryInterface
|
|
{
|
|
/**
|
|
* 특정 확장점에 등록된 확장 목록 조회
|
|
*
|
|
* @param int $templateId 템플릿 ID
|
|
* @param string $extensionPointName 확장점 이름
|
|
* @return Collection<int, LayoutExtension>
|
|
*/
|
|
public function getByExtensionPoint(int $templateId, string $extensionPointName): Collection
|
|
{
|
|
return LayoutExtension::query()
|
|
->where('template_id', $templateId)
|
|
->extensionPoints()
|
|
->where('target_name', $extensionPointName)
|
|
->active()
|
|
->ordered()
|
|
->get();
|
|
}
|
|
|
|
/**
|
|
* 특정 레이아웃을 타겟으로 하는 오버레이 목록 조회
|
|
*
|
|
* @param int $templateId 템플릿 ID
|
|
* @param string $layoutName 레이아웃 이름
|
|
* @return Collection<int, LayoutExtension>
|
|
*/
|
|
public function getOverlaysByLayout(int $templateId, string $layoutName): Collection
|
|
{
|
|
return LayoutExtension::query()
|
|
->where('template_id', $templateId)
|
|
->overlays()
|
|
->where('target_name', $layoutName)
|
|
->active()
|
|
->ordered()
|
|
->get();
|
|
}
|
|
|
|
/**
|
|
* 확장 등록
|
|
*
|
|
* @param array $data 확장 데이터
|
|
* @return LayoutExtension
|
|
*/
|
|
public function create(array $data): LayoutExtension
|
|
{
|
|
return LayoutExtension::create($data);
|
|
}
|
|
|
|
/**
|
|
* 확장 등록 또는 업데이트 (upsert)
|
|
*
|
|
* 동일한 조건의 확장이 존재하면 업데이트하고, 없으면 생성합니다.
|
|
* soft delete된 레코드도 복원하여 업데이트합니다.
|
|
*
|
|
* @param array $attributes 조회 조건
|
|
* @param array $values 생성/업데이트할 값
|
|
* @return LayoutExtension
|
|
*/
|
|
public function updateOrCreate(array $attributes, array $values): LayoutExtension
|
|
{
|
|
// soft delete된 레코드도 포함하여 조회
|
|
$existing = LayoutExtension::withTrashed()
|
|
->where($attributes)
|
|
->first();
|
|
|
|
if ($existing) {
|
|
// 기존 레코드가 있으면 복원 후 업데이트
|
|
if ($existing->trashed()) {
|
|
$existing->restore();
|
|
}
|
|
$existing->update($values);
|
|
|
|
return $existing->fresh();
|
|
}
|
|
|
|
// 없으면 새로 생성
|
|
return LayoutExtension::create(array_merge($attributes, $values));
|
|
}
|
|
|
|
/**
|
|
* 출처별 확장 삭제 (soft delete)
|
|
*
|
|
* @param LayoutSourceType $sourceType 출처 타입
|
|
* @param string $identifier 출처 식별자
|
|
* @return int 삭제된 레코드 수
|
|
*/
|
|
public function softDeleteBySource(LayoutSourceType $sourceType, string $identifier): int
|
|
{
|
|
return LayoutExtension::query()
|
|
->bySource($sourceType, $identifier)
|
|
->delete();
|
|
}
|
|
|
|
/**
|
|
* 출처별 확장 복원
|
|
*
|
|
* @param LayoutSourceType $sourceType 출처 타입
|
|
* @param string $identifier 출처 식별자
|
|
* @return int 복원된 레코드 수
|
|
*/
|
|
public function restoreBySource(LayoutSourceType $sourceType, string $identifier): int
|
|
{
|
|
return LayoutExtension::query()
|
|
->withTrashed()
|
|
->bySource($sourceType, $identifier)
|
|
->restore();
|
|
}
|
|
|
|
/**
|
|
* 출처별 확장 영구 삭제
|
|
*
|
|
* @param LayoutSourceType $sourceType 출처 타입
|
|
* @param string $identifier 출처 식별자
|
|
* @return int 삭제된 레코드 수
|
|
*/
|
|
public function forceDeleteBySource(LayoutSourceType $sourceType, string $identifier): int
|
|
{
|
|
return LayoutExtension::query()
|
|
->withTrashed()
|
|
->bySource($sourceType, $identifier)
|
|
->forceDelete();
|
|
}
|
|
|
|
/**
|
|
* 템플릿 오버라이드 확인 (Extension Point용)
|
|
*
|
|
* @param int $templateId 템플릿 ID
|
|
* @param string $extensionPointName 확장점 이름
|
|
* @param string $moduleIdentifier 모듈/플러그인 식별자
|
|
* @return LayoutExtension|null
|
|
*/
|
|
public function findTemplateOverrideForExtensionPoint(
|
|
int $templateId,
|
|
string $extensionPointName,
|
|
string $moduleIdentifier
|
|
): ?LayoutExtension {
|
|
return LayoutExtension::query()
|
|
->where('template_id', $templateId)
|
|
->extensionPoints()
|
|
->where('target_name', $extensionPointName)
|
|
->templateOverrides()
|
|
->overridingTarget($moduleIdentifier)
|
|
->active()
|
|
->first();
|
|
}
|
|
|
|
/**
|
|
* 템플릿 오버라이드 확인 (Overlay용)
|
|
*
|
|
* @param int $templateId 템플릿 ID
|
|
* @param string $layoutName 레이아웃 이름
|
|
* @param string $moduleIdentifier 모듈/플러그인 식별자
|
|
* @return LayoutExtension|null
|
|
*/
|
|
public function findTemplateOverrideForOverlay(
|
|
int $templateId,
|
|
string $layoutName,
|
|
string $moduleIdentifier
|
|
): ?LayoutExtension {
|
|
return LayoutExtension::query()
|
|
->where('template_id', $templateId)
|
|
->overlays()
|
|
->where('target_name', $layoutName)
|
|
->templateOverrides()
|
|
->overridingTarget($moduleIdentifier)
|
|
->active()
|
|
->first();
|
|
}
|
|
|
|
/**
|
|
* 오버라이드를 고려한 Extension Point 조회
|
|
*
|
|
* @param int $templateId 템플릿 ID
|
|
* @param string $extensionPointName 확장점 이름
|
|
* @return Collection<int, LayoutExtension>
|
|
*/
|
|
public function getResolvedExtensionPoints(int $templateId, string $extensionPointName): Collection
|
|
{
|
|
// 1. 모든 확장 조회 (모듈/플러그인/템플릿 오버라이드 포함)
|
|
$allExtensions = LayoutExtension::query()
|
|
->where('template_id', $templateId)
|
|
->extensionPoints()
|
|
->where('target_name', $extensionPointName)
|
|
->active()
|
|
->ordered()
|
|
->get();
|
|
|
|
// 2. 템플릿 오버라이드가 있는 모듈 식별자 추출
|
|
$overriddenModules = $allExtensions
|
|
->where('source_type', LayoutSourceType::Template)
|
|
->pluck('override_target')
|
|
->filter()
|
|
->unique()
|
|
->toArray();
|
|
|
|
// 3. 오버라이드된 모듈/플러그인 확장은 제외하고 반환
|
|
return $allExtensions->filter(function ($extension) use ($overriddenModules) {
|
|
// 템플릿 오버라이드는 항상 포함
|
|
if ($extension->source_type === LayoutSourceType::Template) {
|
|
return true;
|
|
}
|
|
|
|
// 오버라이드된 모듈/플러그인 확장은 제외
|
|
return ! in_array($extension->source_identifier, $overriddenModules, true);
|
|
})->values();
|
|
}
|
|
|
|
/**
|
|
* 오버라이드를 고려한 Overlay 조회
|
|
*
|
|
* @param int $templateId 템플릿 ID
|
|
* @param string $layoutName 레이아웃 이름
|
|
* @return Collection<int, LayoutExtension>
|
|
*/
|
|
public function getResolvedOverlays(int $templateId, string $layoutName): Collection
|
|
{
|
|
// 1. 모든 오버레이 조회
|
|
$allOverlays = LayoutExtension::query()
|
|
->where('template_id', $templateId)
|
|
->overlays()
|
|
->where('target_name', $layoutName)
|
|
->active()
|
|
->ordered()
|
|
->get();
|
|
|
|
// 2. 템플릿 오버라이드가 있는 모듈 식별자 추출
|
|
$overriddenModules = $allOverlays
|
|
->where('source_type', LayoutSourceType::Template)
|
|
->pluck('override_target')
|
|
->filter()
|
|
->unique()
|
|
->toArray();
|
|
|
|
// 3. 오버라이드된 모듈/플러그인 확장은 제외하고 반환
|
|
return $allOverlays->filter(function ($overlay) use ($overriddenModules) {
|
|
// 템플릿 오버라이드는 항상 포함
|
|
if ($overlay->source_type === LayoutSourceType::Template) {
|
|
return true;
|
|
}
|
|
|
|
// 오버라이드된 모듈/플러그인 확장은 제외
|
|
return ! in_array($overlay->source_identifier, $overriddenModules, true);
|
|
})->values();
|
|
}
|
|
|
|
/**
|
|
* 특정 템플릿의 모든 확장 조회
|
|
*
|
|
* @param int $templateId 템플릿 ID
|
|
* @return Collection<int, LayoutExtension>
|
|
*/
|
|
public function getByTemplateId(int $templateId): Collection
|
|
{
|
|
return LayoutExtension::query()
|
|
->where('template_id', $templateId)
|
|
->active()
|
|
->ordered()
|
|
->get();
|
|
}
|
|
|
|
/**
|
|
* 특정 템플릿의 모든 확장 삭제
|
|
*
|
|
* @param int $templateId 템플릿 ID
|
|
* @return int 삭제된 레코드 수
|
|
*/
|
|
public function deleteByTemplateId(int $templateId): int
|
|
{
|
|
return LayoutExtension::query()
|
|
->withTrashed()
|
|
->where('template_id', $templateId)
|
|
->forceDelete();
|
|
}
|
|
}
|