mivita/dev/subdomain-optimization/DomainContext.php
2025-08-12 18:01:59 +02:00

290 lines
No EOL
7.5 KiB
PHP

<?php
namespace App\Domain;
use App\Models\UserShop;
/**
* Domain Context - Immutable context object representing current domain state
*
* This class provides a clean, immutable way to pass domain context
* throughout the application without relying on global state.
*/
class DomainContext
{
public function __construct(
public readonly string $type, // 'main', 'main-shop', 'crm', 'portal', 'checkout', 'user-shop', 'unknown'
public readonly string $fullDomain, // Complete domain (e.g., 'shop.mivita.care')
public readonly string $domain, // Base domain (e.g., 'mivita')
public readonly ?string $subdomain, // Subdomain part (e.g., 'shop') or null
public readonly string $tld, // TLD (e.g., '.care')
public readonly ?UserShop $userShop = null, // For user shop contexts
public readonly array $config = [] // Additional configuration
) {}
/**
* Check if this is the main domain (mivita.care)
*/
public function isMainDomain(): bool
{
return $this->type === 'main';
}
/**
* Check if this is the main shop domain (mivita.shop)
*/
public function isMainShopDomain(): bool
{
return $this->type === 'main-shop';
}
/**
* Check if this is any main domain variant
*/
public function isAnyMainDomain(): bool
{
return $this->isMainDomain() || $this->isMainShopDomain();
}
/**
* Check if this is the CRM domain (my.mivita.care)
*/
public function isCrmDomain(): bool
{
return $this->type === 'crm';
}
/**
* Check if this is the portal domain (in.mivita.care)
*/
public function isPortalDomain(): bool
{
return $this->type === 'portal';
}
/**
* Check if this is the checkout domain (checkout.mivita.care)
*/
public function isCheckoutDomain(): bool
{
return $this->type === 'checkout';
}
/**
* Check if this is a user shop domain ({slug}.mivita.care)
*/
public function isUserShopDomain(): bool
{
return $this->type === 'user-shop';
}
/**
* Check if this is an unknown/invalid domain
*/
public function isUnknownDomain(): bool
{
return $this->type === 'unknown';
}
/**
* Check if this domain supports e-commerce functionality
*/
public function supportsEcommerce(): bool
{
return in_array($this->type, ['main-shop', 'user-shop']);
}
/**
* Check if this domain requires authentication
*/
public function requiresAuthentication(): bool
{
return in_array($this->type, ['crm', 'portal']);
}
/**
* Get the appropriate route prefix for this domain
*/
public function getRoutePrefix(): ?string
{
return match($this->type) {
'crm' => 'crm',
'portal' => 'portal',
'checkout' => 'checkout',
'user-shop' => 'shop',
default => null
};
}
/**
* Get the user shop slug (if applicable)
*/
public function getUserShopSlug(): ?string
{
return $this->userShop?->slug ?? $this->subdomain;
}
/**
* Get the middleware stack appropriate for this domain
*/
public function getMiddlewareStack(): array
{
$middleware = ['web']; // Base middleware
switch ($this->type) {
case 'crm':
$middleware[] = 'auth';
break;
case 'portal':
$middleware[] = 'auth:customers';
break;
case 'checkout':
$middleware[] = 'checkout';
break;
case 'user-shop':
$middleware[] = 'subdomain';
break;
}
return $middleware;
}
/**
* Get the view namespace for this domain
*/
public function getViewNamespace(): ?string
{
return match($this->type) {
'crm' => 'crm',
'portal' => 'portal',
'checkout' => 'checkout',
'user-shop' => 'shop',
default => null
};
}
/**
* Get the layout template for this domain
*/
public function getLayoutTemplate(): string
{
return match($this->type) {
'crm' => 'layouts.crm',
'portal' => 'layouts.portal',
'checkout' => 'layouts.checkout',
'user-shop' => 'web.layouts.application',
'main-shop' => 'web.layouts.application',
default => 'layouts.app'
};
}
/**
* Check if this domain allows cart functionality
*/
public function allowsCart(): bool
{
return $this->supportsEcommerce();
}
/**
* Get session configuration for this domain
*/
public function getSessionConfig(): array
{
$config = [
'lifetime' => config('session.lifetime'),
'expire_on_close' => config('session.expire_on_close'),
];
// Set domain-specific session domain
if ($this->isUserShopDomain()) {
$config['domain'] = '.' . $this->domain . $this->tld;
}
return $config;
}
/**
* Create a new context with updated user shop
*/
public function withUserShop(UserShop $userShop): self
{
return new self(
$this->type,
$this->fullDomain,
$this->domain,
$this->subdomain,
$this->tld,
$userShop,
$this->config
);
}
/**
* Create a new context with additional configuration
*/
public function withConfig(array $config): self
{
return new self(
$this->type,
$this->fullDomain,
$this->domain,
$this->subdomain,
$this->tld,
$this->userShop,
array_merge($this->config, $config)
);
}
/**
* Convert to array for debugging/logging
*/
public function toArray(): array
{
return [
'type' => $this->type,
'full_domain' => $this->fullDomain,
'domain' => $this->domain,
'subdomain' => $this->subdomain,
'tld' => $this->tld,
'user_shop_slug' => $this->getUserShopSlug(),
'user_shop_id' => $this->userShop?->id,
'config' => $this->config,
];
}
/**
* Get a human-readable description of this domain context
*/
public function getDescription(): string
{
return match($this->type) {
'main' => 'Main Website',
'main-shop' => 'Main Shop',
'crm' => 'CRM System',
'portal' => 'Customer Portal',
'checkout' => 'Checkout System',
'user-shop' => "User Shop ({$this->getUserShopSlug()})",
'unknown' => 'Unknown Domain',
default => 'Undefined Domain Type'
};
}
/**
* Static factory method to create context from domain service
*/
public static function fromDomainInfo(array $domainInfo, ?UserShop $userShop = null): self
{
return new self(
$domainInfo['type'],
$domainInfo['full_domain'],
$domainInfo['domain'],
$domainInfo['subdomain'],
$domainInfo['tld'],
$userShop
);
}
}