Files
clinicpro/src/Representation/Service/DomainContextResolver.php
T

70 lines
2.9 KiB
PHP

<?php
namespace App\Representation\Service;
use App\Location\Repository\CityRepository;
use App\Representation\Entity\Representation;
use App\Representation\Repository\RepresentationRepository;
/**
* تنها نقطه‌ی نگاشت host → context در backend. هیچ سرویس/کنترلر دیگری نباید
* مستقیماً دامنه را parse یا با cities/representations تطبیق دهد.
*
* ورودی هر شکلی از آدرس را می‌پذیرد (host خالص، URL کامل، با www/پورت).
*/
class DomainContextResolver
{
public function __construct(
private readonly CityRepository $cityRepo,
private readonly RepresentationRepository $representationRepo,
) {}
/**
* اعمال scope دامنه روی فیلترهای لیست‌های عمومی (doctors/clinics):
* دامنه‌ی نماینده‌ی سراسری → فقط ردیف‌های همان نماینده؛ فیلتر شهر/استان بی‌اثر.
* دامنه‌ی شهری/ناشناخته → فیلترها دست‌نخورده (فقط کلید domain حذف می‌شود).
*/
public function applyToListFilters(array $filters): array
{
$domain = $filters['domain'] ?? null;
unset($filters['domain']);
if (!is_string($domain) || $domain === '') {
return $filters;
}
$ctx = $this->resolve($domain);
if ($ctx->isGlobalRepresentation) {
$filters['representation_id'] = $ctx->representationId();
unset($filters['city_id'], $filters['state_id'], $filters['city'], $filters['state']);
}
return $filters;
}
public function resolve(?string $hostOrUrl): DomainContext
{
$domain = Representation::normalizeDomain($hostOrUrl);
if ($domain === null) {
return DomainContext::empty();
}
$city = $this->cityRepo->findByDomain($domain);
if ($city !== null) {
// دامنه‌ی شهری؛ نماینده‌ای که دامنه‌ی اختصاصی‌اش این باشد وجود ندارد،
// ولی ممکن است نماینده‌ای دامنه‌ی شهر را به‌عنوان دامنه‌ی خودش ثبت کرده باشد.
$rep = $this->representationRepo->findActiveByDomain($domain);
return new DomainContext($rep, $city, false);
}
// exact ابتدا (production: host = دامنه‌ی واقعی)، سپس fallback اولین-label
// (dev: host = `<prefix>.localhost` باید نماینده‌ی `<prefix>.ir` را بیابد).
$rep = $this->representationRepo->findActiveByDomain($domain)
?? $this->representationRepo->findActiveByDomainPrefix(explode('.', $domain)[0]);
if ($rep !== null) {
return new DomainContext($rep, null, $rep->isGlobal());
}
return DomainContext::empty();
}
}