ecphp/cns-client-bundle
Symfony bundle to send notifications via the EU Corporate Notification System (CNS). Provides a simple client to deliver GDPR-compliant emails to internal and external users. Requires PHP 7.4+ and Symfony 5.3+.
Install the Bundle
composer require ecphp/cns-client-bundle
Ensure your project meets the requirements: PHP ≥ 7.4 and Symfony ≥ 5.3.
Configure the Bundle
Add the bundle to config/bundles.php:
return [
// ...
Ecphp\CnsClientBundle\EcphpCnsClientBundle::class => ['all' => true],
];
Environment Configuration
Add CNS credentials to .env:
CNS_CLIENT_ID=your_client_id
CNS_CLIENT_SECRET=your_client_secret
CNS_ENDPOINT=https://api.cns.example.com
First Usage
Inject the CnsClientInterface into a service/controller:
use Ecphp\CnsClientBundle\Service\CnsClientInterface;
public function __construct(private CnsClientInterface $cnsClient) {}
public function sendNotification()
{
$recipient = new NotificationRecipient('[email protected]', 'John Doe');
$content = new NotificationContent('Hello from CNS!');
$this->cnsClient->sendNotification($recipient, $content);
}
Define Recipients
Use NotificationRecipient for internal/external users:
$recipient = new NotificationRecipient('[email protected]', 'John Doe', true); // GDPR-compliant
Structure Content
Use NotificationContent for subject/body:
$content = new NotificationContent('Welcome!');
$content->setBody('Thanks for signing up.');
Attach Files
$content->addAttachmentFromUpload('/path/to/file.pdf');
// OR for remote files:
$content->addAttachmentFromUrl('https://example.com/file.pdf');
Send via Service
$this->cnsClient->sendNotification($recipient, $content);
$recipients = [
new NotificationRecipient('[email protected]', 'User 1'),
new NotificationRecipient('[email protected]', 'User 2'),
];
$this->cnsClient->sendBulkNotification($recipients, $content);
$content = new NotificationContent('Template ID: welcome_email');
$content->setTemplateVariables(['name' => 'John']);
Wrap calls in try-catch:
try {
$this->cnsClient->sendNotification($recipient, $content);
} catch (CnsClientException $e) {
// Log or retry (e.g., for rate limits)
$this->logger->error('CNS Error: ' . $e->getMessage());
}
Use the CnsClientMock for unit tests:
$mock = new CnsClientMock();
$mock->expects($this->once())->method('sendNotification');
$this->cnsClient = $this->createMock(CnsClientInterface::class);
Symfony Events
Trigger notifications via Symfony events (e.g., user.registered):
$eventDispatcher->addListener('user.registered', function (UserRegisteredEvent $event) {
$recipient = new NotificationRecipient($event->getUser()->getEmail());
$content = new NotificationContent('Welcome!');
$this->cnsClient->sendNotification($recipient, $content);
});
Queue Delayed Sends Use Symfony Messenger for async processing:
$message = new SendCnsNotification($recipient, $content);
$this->messageBus->dispatch($message);
Logging
Enable debug logging in config/packages/dev/ecphp_cns_client.yaml:
ecphp_cns_client:
debug: true
Authentication Failures
CNS_CLIENT_ID/SECRET are correct and not hardcoded.Attachment Limits
if ($file->getSize() > 10_000_000) { // 10MB
throw new \RuntimeException('File too large');
}
GDPR Compliance
isExternal = true and valid consent. Use:
$recipient = new NotificationRecipient('[email protected]', null, true);
Rate Limiting
$retryAfter = $response->getHeader('Retry-After');
if ($retryAfter) {
sleep((int) $retryAfter);
}
Enable Verbose Logging
Add to config/services.yaml:
services:
Ecphp\CnsClientBundle\Service\CnsClient:
arguments:
$logger: '@logger'
Then check var/log/dev.log for raw API responses.
Mock the Client
For local testing, use the CnsClientMock to simulate responses:
$mock = new CnsClientMock();
$mock->setResponse(new Response(200, [], json_encode(['status' => 'success'])));
Validate JSON Payloads
CNS expects strict JSON formats. Use json_encode($data, JSON_THROW_ON_ERROR) to catch malformed data.
Custom Headers
Extend the CnsClient to add headers:
$client = new CnsClient($httpClient, $config);
$client->addHeader('X-Custom-Header', 'value');
Middleware Add request/response middleware via Symfony’s HTTP client:
# config/packages/ecphp_cns_client.yaml
ecphp_cns_client:
http_client:
middleware:
- 'some.middleware.service'
Event Subscribers
Listen for cns.notification.sent events to track metrics:
$eventDispatcher->addListener('cns.notification.sent', function (NotificationSentEvent $event) {
$this->stats->increment('notifications.sent');
});
Symfony 6+ Compatibility
symfony/http-client-contracts dependencies in v1.0.4.symfony/http-client is installed if using Symfony 6.Default Values
null. Set explicitly for clarity:
$recipient = new NotificationRecipient('[email protected]', 'John Doe');
Endpoint Overrides
config/packages/ecphp_cns_client.yaml:
ecphp_cns_client:
endpoint: 'https://custom.cns.endpoint'
How can I help you explore Laravel packages today?