$channelTemplates Per-channel customization * @param NotificationPriority $defaultPriority Default priority for notifications using this template * @param array $requiredVariables Variables that must be provided when rendering * @param array $defaultVariables Default values for optional variables */ public function __construct( public TemplateId $id, public string $name, public string $titleTemplate, public string $bodyTemplate, public array $channelTemplates = [], public NotificationPriority $defaultPriority = NotificationPriority::NORMAL, public array $requiredVariables = [], public array $defaultVariables = [] ) { if (empty($name)) { throw new \InvalidArgumentException('Template name cannot be empty'); } if (empty($titleTemplate)) { throw new \InvalidArgumentException('Title template cannot be empty'); } if (empty($bodyTemplate)) { throw new \InvalidArgumentException('Body template cannot be empty'); } } public static function create( string $name, string $titleTemplate, string $bodyTemplate ): self { return new self( id: TemplateId::generate(), name: $name, titleTemplate: $titleTemplate, bodyTemplate: $bodyTemplate ); } public function withChannelTemplate( NotificationChannel $channel, ChannelTemplate $template ): self { return new self( id: $this->id, name: $this->name, titleTemplate: $this->titleTemplate, bodyTemplate: $this->bodyTemplate, channelTemplates: [...$this->channelTemplates, $channel => $template], defaultPriority: $this->defaultPriority, requiredVariables: $this->requiredVariables, defaultVariables: $this->defaultVariables ); } public function withPriority(NotificationPriority $priority): self { return new self( id: $this->id, name: $this->name, titleTemplate: $this->titleTemplate, bodyTemplate: $this->bodyTemplate, channelTemplates: $this->channelTemplates, defaultPriority: $priority, requiredVariables: $this->requiredVariables, defaultVariables: $this->defaultVariables ); } public function withRequiredVariables(string ...$variables): self { return new self( id: $this->id, name: $this->name, titleTemplate: $this->titleTemplate, bodyTemplate: $this->bodyTemplate, channelTemplates: $this->channelTemplates, defaultPriority: $this->defaultPriority, requiredVariables: $variables, defaultVariables: $this->defaultVariables ); } public function withDefaultVariables(array $defaults): self { return new self( id: $this->id, name: $this->name, titleTemplate: $this->titleTemplate, bodyTemplate: $this->bodyTemplate, channelTemplates: $this->channelTemplates, defaultPriority: $this->defaultPriority, requiredVariables: $this->requiredVariables, defaultVariables: [...$this->defaultVariables, ...$defaults] ); } public function hasChannelTemplate(NotificationChannel $channel): bool { return isset($this->channelTemplates[$channel]); } public function getChannelTemplate(NotificationChannel $channel): ?ChannelTemplate { return $this->channelTemplates[$channel] ?? null; } public function validateVariables(array $variables): void { foreach ($this->requiredVariables as $required) { if (!array_key_exists($required, $variables)) { throw new \InvalidArgumentException( "Required variable '{$required}' is missing" ); } } } }