Files
michaelschiemer/src/Framework/Notification/Templates/NotificationTemplate.php
Michael Schiemer 3b623e7afb feat(Deployment): Integrate Ansible deployment via PHP deployment pipeline
- Create AnsibleDeployStage using framework's Process module for secure command execution
- Integrate AnsibleDeployStage into DeploymentPipelineCommands for production deployments
- Add force_deploy flag support in Ansible playbook to override stale locks
- Use PHP deployment module as orchestrator (php console.php deploy:production)
- Fix ErrorAggregationInitializer to use Environment class instead of $_ENV superglobal

Architecture:
- BuildStage → AnsibleDeployStage → HealthCheckStage for production
- Process module provides timeout, error handling, and output capture
- Ansible playbook supports rollback via rollback-git-based.yml
- Zero-downtime deployments with health checks
2025-10-26 14:08:07 +01:00

143 lines
4.8 KiB
PHP

<?php
declare(strict_types=1);
namespace App\Framework\Notification\Templates;
use App\Framework\Notification\ValueObjects\NotificationChannel;
use App\Framework\Notification\ValueObjects\NotificationPriority;
/**
* Notification Template
*
* Reusable template with placeholders for dynamic content
* Supports per-channel customization and variable substitution
*/
final readonly class NotificationTemplate
{
/**
* @param TemplateId $id Unique template identifier
* @param string $name Template name (e.g., 'order.shipped', 'user.welcome')
* @param string $titleTemplate Title with placeholders (e.g., 'Order {{order_id}} shipped')
* @param string $bodyTemplate Body with placeholders
* @param array<NotificationChannel, ChannelTemplate> $channelTemplates Per-channel customization
* @param NotificationPriority $defaultPriority Default priority for notifications using this template
* @param array<string> $requiredVariables Variables that must be provided when rendering
* @param array<string, mixed> $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"
);
}
}
}
}