Files
michaelschiemer/examples/notification-template-example.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

310 lines
10 KiB
PHP

<?php
declare(strict_types=1);
require_once __DIR__ . '/../vendor/autoload.php';
use App\Framework\Notification\Templates\NotificationTemplate;
use App\Framework\Notification\Templates\TemplateRenderer;
use App\Framework\Notification\Templates\ChannelTemplate;
use App\Framework\Notification\Templates\InMemoryTemplateRegistry;
use App\Framework\Notification\ValueObjects\NotificationChannel;
use App\Framework\Notification\ValueObjects\NotificationPriority;
use App\Framework\Notification\ValueObjects\SystemNotificationType;
/**
* Notification Template System Example
*
* Demonstrates:
* - Template creation with placeholders
* - Variable substitution
* - Per-channel customization
* - Template registry
* - Required and default variables
*/
echo "=== Notification Template System Examples ===\n\n";
// Setup
$registry = new InMemoryTemplateRegistry();
$renderer = new TemplateRenderer();
// Example 1: Basic Template with Simple Placeholders
echo "1. Basic Template - Order Shipped\n";
echo str_repeat("-", 50) . "\n";
$orderShippedTemplate = NotificationTemplate::create(
name: 'order.shipped',
titleTemplate: 'Order {{order_id}} Shipped',
bodyTemplate: 'Your order {{order_id}} has been shipped and will arrive by {{delivery_date}}. Track your package: {{tracking_url}}'
)->withPriority(NotificationPriority::HIGH)
->withRequiredVariables('order_id', 'delivery_date', 'tracking_url');
$registry->register($orderShippedTemplate);
// Render notification
$notification = $renderer->render(
template: $orderShippedTemplate,
recipientId: 'user_123',
variables: [
'order_id' => '#12345',
'delivery_date' => 'December 25, 2024',
'tracking_url' => 'https://example.com/track/ABC123',
],
channels: [NotificationChannel::EMAIL, NotificationChannel::TELEGRAM],
type: new SystemNotificationType('order.shipped')
);
echo "Title: {$notification->title}\n";
echo "Body: {$notification->body}\n";
echo "Priority: {$notification->priority->value}\n";
echo "Template Data: " . json_encode($notification->data, JSON_PRETTY_PRINT) . "\n";
echo "\n";
// Example 2: Template with Nested Variables
echo "2. Nested Variables - User Welcome\n";
echo str_repeat("-", 50) . "\n";
$welcomeTemplate = NotificationTemplate::create(
name: 'user.welcome',
titleTemplate: 'Welcome to {{app.name}}, {{user.name}}!',
bodyTemplate: 'Hi {{user.name}}, welcome to {{app.name}}! Your account has been created successfully. Get started here: {{app.url}}'
)->withRequiredVariables('user.name')
->withDefaultVariables([
'app' => [
'name' => 'My Application',
'url' => 'https://example.com/start',
],
]);
$registry->register($welcomeTemplate);
$notification = $renderer->render(
template: $welcomeTemplate,
recipientId: 'user_456',
variables: [
'user' => [
'name' => 'John Doe',
'email' => 'john@example.com',
],
],
channels: [NotificationChannel::EMAIL],
type: new SystemNotificationType('user.welcome')
);
echo "Title: {$notification->title}\n";
echo "Body: {$notification->body}\n";
echo "\n";
// Example 3: Per-Channel Customization
echo "3. Per-Channel Templates - Different Formats\n";
echo str_repeat("-", 50) . "\n";
$securityAlertTemplate = NotificationTemplate::create(
name: 'security.alert',
titleTemplate: 'Security Alert',
bodyTemplate: 'Unusual login activity detected from {{ip_address}} at {{time}}.'
)->withPriority(NotificationPriority::URGENT);
// Telegram: Use Markdown formatting
$telegramTemplate = ChannelTemplate::create(
titleTemplate: '🔒 *Security Alert*',
bodyTemplate: '⚠️ Unusual login activity detected:\n\n📍 IP: `{{ip_address}}`\n⏰ Time: {{time}}\n\nIf this wasn\'t you, secure your account immediately!'
)->withMetadata(['parse_mode' => 'Markdown']);
// Email: Use HTML formatting
$emailTemplate = ChannelTemplate::create(
titleTemplate: '🔒 Security Alert',
bodyTemplate: '<h2>Unusual Login Activity</h2><p>We detected a login from <strong>{{ip_address}}</strong> at {{time}}.</p><p>If this wasn\'t you, please secure your account immediately.</p>'
)->withMetadata(['content_type' => 'text/html']);
// SMS: Keep it short and plain
$smsTemplate = ChannelTemplate::create(
bodyTemplate: 'SECURITY ALERT: Login from {{ip_address}} at {{time}}. If not you, secure account now.'
);
$securityAlertTemplate = $securityAlertTemplate
->withChannelTemplate(NotificationChannel::TELEGRAM, $telegramTemplate)
->withChannelTemplate(NotificationChannel::EMAIL, $emailTemplate)
->withChannelTemplate(NotificationChannel::SMS, $smsTemplate);
$registry->register($securityAlertTemplate);
// Render for each channel
$variables = [
'ip_address' => '203.0.113.42',
'time' => '2024-12-19 15:30:00 UTC',
];
echo "TELEGRAM VERSION:\n";
$telegramContent = $renderer->renderForChannel(
$securityAlertTemplate,
NotificationChannel::TELEGRAM,
$variables
);
echo "Title: {$telegramContent->title}\n";
echo "Body:\n{$telegramContent->body}\n";
echo "Metadata: " . json_encode($telegramContent->metadata) . "\n\n";
echo "EMAIL VERSION:\n";
$emailContent = $renderer->renderForChannel(
$securityAlertTemplate,
NotificationChannel::EMAIL,
$variables
);
echo "Title: {$emailContent->title}\n";
echo "Body:\n{$emailContent->body}\n";
echo "Metadata: " . json_encode($emailContent->metadata) . "\n\n";
echo "SMS VERSION:\n";
$smsContent = $renderer->renderForChannel(
$securityAlertTemplate,
NotificationChannel::SMS,
$variables
);
echo "Body: {$smsContent->body}\n";
echo "\n";
// Example 4: Template with Default Variables
echo "4. Default Variables - Newsletter Template\n";
echo str_repeat("-", 50) . "\n";
$newsletterTemplate = NotificationTemplate::create(
name: 'newsletter.weekly',
titleTemplate: '{{newsletter.title}} - Week {{week_number}}',
bodyTemplate: 'Hi {{user.name}}, here\'s your weekly {{newsletter.title}}! This week\'s highlights: {{highlights}}. Read more: {{newsletter.url}}'
)->withDefaultVariables([
'newsletter' => [
'title' => 'Weekly Update',
'url' => 'https://example.com/newsletter',
],
'highlights' => 'New features, bug fixes, and improvements',
])->withRequiredVariables('user.name', 'week_number');
$registry->register($newsletterTemplate);
$notification = $renderer->render(
template: $newsletterTemplate,
recipientId: 'user_789',
variables: [
'user' => ['name' => 'Jane Smith'],
'week_number' => '51',
// Using default values for newsletter and highlights
],
channels: [NotificationChannel::EMAIL],
type: new SystemNotificationType('newsletter.weekly')
);
echo "Title: {$notification->title}\n";
echo "Body: {$notification->body}\n";
echo "\n";
// Example 5: Template Registry Usage
echo "5. Template Registry - Lookup and Reuse\n";
echo str_repeat("-", 50) . "\n";
echo "Registered templates:\n";
foreach ($registry->all() as $name => $template) {
echo " - {$name} (Priority: {$template->defaultPriority->value})\n";
}
echo "\n";
// Reuse template from registry
$template = $registry->get('order.shipped');
if ($template !== null) {
echo "Retrieved template: {$template->name}\n";
echo "Required variables: " . implode(', ', $template->requiredVariables) . "\n";
}
echo "\n";
// Example 6: Error Handling - Missing Required Variable
echo "6. Error Handling - Validation\n";
echo str_repeat("-", 50) . "\n";
try {
$renderer->render(
template: $orderShippedTemplate,
recipientId: 'user_999',
variables: [
'order_id' => '#67890',
// Missing 'delivery_date' and 'tracking_url'
],
channels: [NotificationChannel::EMAIL],
type: new SystemNotificationType('order.shipped')
);
} catch (\InvalidArgumentException $e) {
echo "❌ Validation Error: {$e->getMessage()}\n";
}
echo "\n";
// Example 7: Complex Object in Variables
echo "7. Complex Objects - Value Object Support\n";
echo str_repeat("-", 50) . "\n";
$paymentTemplate = NotificationTemplate::create(
name: 'payment.received',
titleTemplate: 'Payment Received',
bodyTemplate: 'We received your payment of {{amount}} on {{date}}. Transaction ID: {{transaction.id}}'
);
// Create notification with object variables
$notification = $renderer->render(
template: $paymentTemplate,
recipientId: 'user_101',
variables: [
'amount' => '$99.00',
'date' => '2024-12-19',
'transaction' => [
'id' => 'TXN_123456',
'status' => 'completed',
],
],
channels: [NotificationChannel::EMAIL, NotificationChannel::TELEGRAM],
type: new SystemNotificationType('payment.received')
);
echo "Title: {$notification->title}\n";
echo "Body: {$notification->body}\n";
echo "\n";
// Example 8: Integration with NotificationDispatcher
echo "8. Template + Dispatcher Integration\n";
echo str_repeat("-", 50) . "\n";
echo "Step 1: Create template\n";
$template = NotificationTemplate::create(
name: 'account.deleted',
titleTemplate: 'Account Deletion Confirmation',
bodyTemplate: 'Your account {{username}} has been permanently deleted on {{deletion_date}}.'
)->withPriority(NotificationPriority::URGENT);
echo "Step 2: Render notification from template\n";
$notification = $renderer->render(
template: $template,
recipientId: 'user_202',
variables: [
'username' => 'johndoe',
'deletion_date' => '2024-12-19',
],
channels: [NotificationChannel::EMAIL, NotificationChannel::SMS],
type: new SystemNotificationType('account.deleted')
);
echo "Step 3: Dispatch via NotificationDispatcher\n";
echo " (In real app: \$dispatcher->sendNow(\$notification, DispatchStrategy::ALL_OR_NONE))\n";
echo " Notification ready for dispatch:\n";
echo " - Title: {$notification->title}\n";
echo " - Channels: " . count($notification->channels) . "\n";
echo " - Priority: {$notification->priority->value}\n";
echo "\n";
// Summary
echo "=== Template System Summary ===\n";
echo "✅ Created " . count($registry->all()) . " templates\n";
echo "✅ Demonstrated placeholder substitution ({{variable}})\n";
echo "✅ Demonstrated nested variables ({{user.name}})\n";
echo "✅ Demonstrated per-channel customization\n";
echo "✅ Demonstrated default variables\n";
echo "✅ Demonstrated validation and error handling\n";
echo "✅ Template system ready for production use\n";