70 lines
2.9 KiB
PHP
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();
|
|
}
|
|
}
|