Shopware 6.7 introduces significant enhancements to its platform architecture, making it easier than ever to build custom integrations with third-party newsletter services. This technical deep dive explores how to create a robust newsletter integration that leverages the new features and APIs available in Shopware 6.7.
Understanding Shopware 6.7's Integration Framework
Shopware 6.7 brings substantial improvements to its plugin architecture, particularly around event handling, dependency injection, and API endpoints. The platform now offers better support for asynchronous processing through the new message queue system, which is crucial for newsletter integrations that often involve external API calls.
The integration framework in Shopware 6.7 provides several key components:
- Enhanced event system with better payload handling
- Improved service container with more granular dependency management
- Updated entity definitions and repository patterns
- Better caching mechanisms for improved performance
Plugin Structure and Setup
To begin building our newsletter integration, we first need to establish the proper plugin structure. In Shopware 6.7, plugins are organized using the new Symfony-based directory structure:
<?php declare(strict_types=1);
use Shopware\Core\Framework\Plugin;
class CustomNewsletterIntegration extends Plugin
{
public function build(ContainerBuilder $container): void
{
parent::build($container);
// Register custom services
$container->addResource(new FileResource(__DIR__.'/Resources/config/services.xml'));
}
}
The plugin configuration file (config.xml) defines the plugin's capabilities and integration points:
<?xml version="1.0" encoding="UTF-8"?>
<plugin xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="https://raw.githubusercontent.com/shopware/platform/master/src/Core/System/SystemConfig/Schema/plugin.xsd">
<metadata>
<name>CustomNewsletterIntegration</name>
<version>1.0.0</version>
<author>Your Company</author>
</metadata>
<config>
<elements>
<element name="apiKey" type="text">
<label>API Key</label>
<helpText>Enter your newsletter service API key</helpText>
</element>
</elements>
</config>
</plugin>
Core Integration Components
1. Service Layer Implementation
The heart of our newsletter integration lies in the service layer that handles communication with external services. In Shopware 6.7, we can leverage the new service container improvements to create a robust service:
<?php declare(strict_types=1);
namespace CustomNewsletterIntegration\Service;
use Psr\Log\LoggerInterface;
use Shopware\Core\Framework\Context;
use Shopware\Core\Framework\DataAbstractionLayer\EntityRepository;
use Shopware\Core\Framework\DataAbstractionLayer\Search\Criteria;
use Symfony\Component\HttpClient\HttpClient;
class NewsletterService
{
private HttpClient $client;
private LoggerInterface $logger;
private EntityRepository $customerRepository;
private string $apiKey;
public function __construct(
LoggerInterface $logger,
EntityRepository $customerRepository,
string $apiKey
) {
$this->client = HttpClient::create();
$this->logger = $logger;
$this->customerRepository = $customerRepository;
$this->apiKey = $apiKey;
}
public function subscribeCustomer(string $email, Context $context): bool
{
try {
$criteria = new Criteria();
$criteria->addFilter(new ContainsFilter('email', $email));
$customers = $this->customerRepository->search($criteria, $context);
if ($customers->getTotal() === 0) {
return false;
}
// Call external newsletter API
$response = $this->client->request('POST', 'https://api.newsletter.com/subscribers', [
'headers' => [
'Authorization' => 'Bearer ' . $this->apiKey,
'Content-Type' => 'application/json'
],
'json' => [
'email' => $email,
'status' => 'subscribed'
]
]);
return $response->getStatusCode() === 200;
} catch (\Exception $e) {
$this->logger->error('Newsletter subscription failed', ['exception' => $e]);
return false;
}
}
}
2. Event Handling and Dispatching
Shopware 6.7's event system provides powerful hooks for integrating with newsletter services. We can listen to customer registration events or custom events to trigger newsletter subscriptions:
<?php declare(strict_types=1);
namespace CustomNewsletterIntegration\Subscriber;
use Shopware\Core\Checkout\Customer\Event\CustomerRegisteredEvent;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
class NewsletterSubscriber implements EventSubscriberInterface
{
private NewsletterService $newsletterService;
public function __construct(NewsletterService $newsletterService)
{
$this->newsletterService = $newsletterService;
}
public static function getSubscribedEvents(): array
{
return [
CustomerRegisteredEvent::class => 'onCustomerRegistered'
];
}
public function onCustomerRegistered(CustomerRegisteredEvent $event): void
{
$context = $event->getSalesChannelContext()->getContext();
// Asynchronously process newsletter subscription
$this->newsletterService->subscribeCustomer(
$event->getCustomer()->getEmail(),
$context
);
}
}
Advanced Features and Optimizations
Message Queue Integration
One of the most significant improvements in Shopware 6.7 is the enhanced message queue system. For newsletter integrations, this allows us to process subscriptions asynchronously without blocking user requests:
<?php declare(strict_types=1);
namespace CustomNewsletterIntegration\MessageQueue;
use Symfony\Component\Messenger\Handler\MessageHandlerInterface;
use Symfony\Component\Messenger\MessageBusInterface;
class NewsletterSubscriptionHandler implements MessageHandlerInterface
{
private NewsletterService $newsletterService;
private MessageBusInterface $messageBus;
public function __construct(
NewsletterService $newsletterService,
MessageBusInterface $messageBus
) {
$this->newsletterService = $newsletterService;
$this->messageBus = $messageBus;
}
public function __invoke(NewsletterSubscriptionMessage $message): void
{
$result = $this->newsletterService->subscribeCustomer(
$message->getEmail(),
$message->getContext()
);
// Handle result asynchronously
if (!$result) {
// Retry logic or error handling
$this->messageBus->dispatch(new RetryNewsletterSubscriptionMessage($message));
}
}
}
Caching and Performance Optimization
Shopware 6.7 introduces improved caching mechanisms that are crucial for newsletter integrations. We can leverage the new cache tags system to invalidate cached customer data when subscriptions change:
<?php declare(strict_types=1);
namespace CustomNewsletterIntegration\Cache;
use Shopware\Core\Framework\DataAbstractionLayer\Cache\EntityCacheKeyGenerator;
use Shopware\Core\Framework\DataAbstractionLayer\Search\Criteria;
class NewsletterCacheKeyGenerator extends EntityCacheKeyGenerator
{
public function getCacheKey(Criteria $criteria, string $entityName): string
{
$key = parent::getCacheKey($criteria, $entityName);
// Add newsletter-specific cache tags
return $key . '_newsletter';
}
}
Configuration and Administration
The plugin configuration in Shopware 6.7 provides a modern interface for managing integration settings:
<?php declare(strict_types=1);
namespace CustomNewsletterIntegration\Controller;
use Shopware\Core\Framework\Routing\Annotation\RouteScope;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\Routing\Annotation\Route;
#[RouteScope(paths: ['admin'])]
class NewsletterConfigController extends AbstractController
{
#[Route('/api/_action/newsletter/test-connection', name: 'api.action.newsletter.test-connection', methods: ['POST'])]
public function testConnection(Request $request): JsonResponse
{
// Test API connectivity
return new JsonResponse(['success' => true]);
}
}
Error Handling and Monitoring
Robust error handling is essential for newsletter integrations. Shopware 6.7's improved logging capabilities help track integration issues:
<?php declare(strict_types=1);
namespace CustomNewsletterIntegration\Exception;
use Shopware\Core\Framework\ShopwareHttpException;
use Symfony\Component\HttpFoundation\Response;
class NewsletterIntegrationException extends ShopwareHttpException
{
public function __construct(string $message, array $parameters = [])
{
parent::__construct($message, $parameters, Response::HTTP_BAD_REQUEST);
}
public function getErrorCode(): string
{
return 'CUSTOM_NEWSLETTER_INTEGRATION_ERROR';
}
}
Testing and Quality Assurance
Shopware 6.7 provides enhanced testing capabilities for integration components:
<?php declare(strict_types=1);
namespace CustomNewsletterIntegration\Test;
use PHPUnit\Framework\TestCase;
use Symfony\Component\HttpFoundation\Response;
class NewsletterServiceTest extends TestCase
{
public function testSuccessfulSubscription(): void
{
$mockClient = $this->createMock(HttpClientInterface::class);
$mockResponse = $this->createMock(ResponseInterface::class);
$mockResponse->expects($this->once())
->method('getStatusCode')
->willReturn(Response::HTTP_OK);
$mockClient->expects($this->once())
->method('request')
->willReturn($mockResponse);
$service = new NewsletterService(
$this->createMock(LoggerInterface::class),
$this->createMock(EntityRepository::class),
'test-key'
);
$result = $service->subscribeCustomer('[email protected]', Context::createDefaultContext());
$this->assertTrue($result);
}
}
Performance Considerations
When building newsletter integrations in Shopware 6.7, consider these performance optimizations:
- Batch Processing: Process multiple subscriptions in batches to reduce API calls
- Caching: Cache external service responses where appropriate
- Asynchronous Operations: Use the message queue for non-critical operations
- Connection Pooling: Reuse HTTP connections when possible
Conclusion
Shopware 6.7 provides an excellent foundation for building custom newsletter integrations with enhanced performance, better error handling, and improved developer experience. The platform's new architecture supports modern integration patterns while maintaining backward compatibility.
By leveraging the improved service container, event system, and message queue capabilities, developers can create robust, scalable newsletter solutions that seamlessly integrate with various external services. The focus on asynchronous processing ensures that user experience remains unaffected while subscriptions are handled efficiently in the background.
The integration approach outlined here follows Shopware 6.7 best practices and provides a solid foundation for extending newsletter functionality in your e-commerce platform.