Introduction
Shopware 6.7 introduces significant enhancements to the number range system, providing developers with more flexibility and control over generating unique identifiers for various entities within the commerce platform. The number range system is crucial for maintaining data integrity and ensuring that order numbers, product numbers, customer IDs, and other business-critical identifiers are properly generated and managed.
In this technical deep dive, we'll explore how to register custom number range types in Shopware 6.7, examining the underlying architecture, configuration options, and implementation patterns that make this feature both powerful and extensible.
Understanding Number Ranges in Shopware 6.7
Before diving into custom registration, it's essential to understand how Shopware's number range system operates. The system is built around the concept of configurable ranges that generate unique sequential numbers for different business entities. These ranges can be configured with various patterns, prefixes, suffixes, and padding options.
In Shopware 6.7, the number range system has been enhanced with improved performance, better configuration management, and more granular control over generation logic. The core components include:
- NumberRangeEntity: Represents individual number ranges
- NumberRangeRepository: Handles persistence operations
- NumberRangeType: Defines the type of number range
- NumberRangeGeneratorInterface: Interface for generating numbers
Prerequisites and Setup
To register a custom number range type, you'll need to understand the plugin structure in Shopware 6.7. Your custom plugin should be structured with the following key files:
custom-plugin/
├── src/
│ ├── Core/
│ │ └── Framework/
│ │ └── NumberRange/
│ │ ├── NumberRangeType/
│ │ │ └── CustomNumberRangeType.php
│ │ └── Generator/
│ │ └── CustomNumberRangeGenerator.php
│ └── Resources/
│ └── config/
│ └── services.xml
├── src/CustomPlugin.php
└── composer.json
Creating the Number Range Type
The first step in registering a custom number range type is to create the type definition. This involves implementing a class that extends the base number range type and registers itself with the system.
<?php declare(strict_types=1);
namespace CustomPlugin\Core\Framework\NumberRange\NumberRangeType;
use Shopware\Core\Framework\NumberRange\NumberRangeType;
use Symfony\Contracts\Translation\TranslatorInterface;
class CustomNumberRangeType extends NumberRangeType
{
public const TYPE = 'custom';
public function __construct(
TranslatorInterface $translator,
string $name,
?string $description = null
) {
parent::__construct(
self::TYPE,
$translator->trans('custom-plugin.number-range.type.custom'),
$description ?? $translator->trans('custom-plugin.number-range.type.custom.description')
);
}
}
Implementing the Generator
The heart of any number range type lies in its generator implementation. The generator is responsible for creating unique, sequential numbers based on the configured pattern and business logic.
<?php declare(strict_types=1);
namespace CustomPlugin\Core\Framework\NumberRange\Generator;
use Shopware\Core\Framework\Context;
use Shopware\Core\Framework\DataAbstractionLayer\EntityRepositoryInterface;
use Shopware\Core\Framework\NumberRange\Exception\NumberRangeTypeNotFoundException;
use Shopware\Core\Framework\NumberRange\Generator\NumberRangeGeneratorInterface;
use Shopware\Core\Framework\NumberRange\NumberRangeConfig;
use Shopware\Core\Framework\NumberRange\NumberRangeEntity;
use Shopware\Core\Framework\NumberRange\NumberRangeException;
use Symfony\Component\DependencyInjection\ContainerInterface;
class CustomNumberRangeGenerator implements NumberRangeGeneratorInterface
{
private EntityRepositoryInterface $numberRangeRepository;
private ContainerInterface $container;
public function __construct(
EntityRepositoryInterface $numberRangeRepository,
ContainerInterface $container
) {
$this->numberRangeRepository = $numberRangeRepository;
$this->container = $container;
}
public function generate(string $type, Context $context): string
{
// Get the number range configuration for our custom type
$numberRange = $this->getNumberRange($type, $context);
if (!$numberRange) {
throw new NumberRangeTypeNotFoundException($type);
}
$config = $numberRange->getConfig();
// Generate the next sequential number
$nextNumber = $this->getNextNumber($numberRange, $context);
// Apply formatting rules
return $this->formatNumber($config, $nextNumber);
}
private function getNumberRange(string $type, Context $context): ?NumberRangeEntity
{
$criteria = new Criteria();
$criteria->addFilter(new EqualsFilter('type', $type));
$criteria->setLimit(1);
return $this->numberRangeRepository->search($criteria, $context)->first();
}
private function getNextNumber(NumberRangeEntity $numberRange, Context $context): int
{
// Get current counter value
$counter = (int) $numberRange->getGlobalCounter() ?? 0;
// Increment and update
$newCounter = $counter + 1;
$this->numberRangeRepository->update([
[
'id' => $numberRange->getId(),
'globalCounter' => $newCounter,
]
], $context);
return $newCounter;
}
private function formatNumber(NumberRangeConfig $config, int $number): string
{
$prefix = $config->getPrefix() ?? '';
$suffix = $config->getSuffix() ?? '';
$padding = $config->getPadding() ?? 0;
$formattedNumber = str_pad((string) $number, $padding, '0', STR_PAD_LEFT);
return $prefix . $formattedNumber . $suffix;
}
}
Service Registration and Configuration
The next crucial step involves registering your custom number range type and generator with Shopware's service container. This is typically done through the services.xml configuration file.
<?xml version="1.0" ?>
<container xmlns="http://symfony.com/schema/dic/services"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://symfony.com/schema/dic/services http://symfony.com/schema/dic/services/services-1.0.xsd">
<services>
<!-- Custom Number Range Type -->
<service id="CustomPlugin\Core\Framework\NumberRange\NumberRangeType\CustomNumberRangeType">
<argument type="service" id="translator"/>
<argument>custom</argument>
<argument>Custom number range type for special entities</argument>
<tag name="shopware.number_range.type"/>
</service>
<!-- Custom Number Range Generator -->
<service id="CustomPlugin\Core\Framework\NumberRange\Generator\CustomNumberRangeGenerator">
<argument type="service" id="number_range.repository"/>
<argument type="service" id="service_container"/>
<tag name="shopware.number_range.generator"/>
</service>
<!-- Register with Number Range Configurator -->
<service id="CustomPlugin\Core\Framework\NumberRange\NumberRangeConfigurator">
<argument type="service" id="CustomPlugin\Core\Framework\NumberRange\Generator\CustomNumberRangeGenerator"/>
<tag name="shopware.number_range.configurator"/>
</service>
</services>
</container>
Advanced Configuration Options
Shopware 6.7 supports various advanced configuration options for number ranges, including:
Date-Based Generation
public function generateWithDate(string $type, Context $context): string
{
$date = date('Ym');
$number = $this->getNextNumber($type, $context);
return $date . '-' . str_pad((string) $number, 6, '0', STR_PAD_LEFT);
}
Multi-Entity Support
public function generateForEntity(string $type, string $entityName, Context $context): string
{
// Generate different ranges based on entity type
$config = $this->getConfiguration($type, $entityName, $context);
return $this->formatNumber($config, $this->getNextNumber($type, $context));
}
Validation and Error Handling
public function validateConfig(NumberRangeConfig $config): void
{
if (empty($config->getPrefix()) && empty($config->getSuffix())) {
throw new NumberRangeException('Either prefix or suffix must be configured');
}
if ($config->getPadding() < 0) {
throw new NumberRangeException('Padding cannot be negative');
}
}
Integration with Existing Systems
The custom number range type integrates seamlessly with Shopware's existing framework components. When registering a new type, it automatically becomes available through:
- Admin panel configuration
- API endpoints for management
- Database persistence layer
- Event system hooks
// Example of integrating with events
public function onNumberRangeCreated(NumberRangeCreatedEvent $event): void
{
// Custom logic when a number range is created
if ($event->getType() === CustomNumberRangeType::TYPE) {
$this->logNewRange($event->getNumberRange());
}
}
Performance Considerations
In high-traffic scenarios, performance optimization becomes critical. Shopware 6.7 addresses this through:
- Caching Mechanisms: Configurations are cached to reduce database queries
- Batch Operations: Multiple increments handled efficiently
- Connection Pooling: Optimized database connections for concurrent access
- Asynchronous Processing: Background generation for non-critical operations
Testing Your Implementation
Comprehensive testing is essential for custom number range types:
public function testCustomNumberRangeGeneration(): void
{
$context = Context::createDefaultContext();
$generated = $this->generator->generate(CustomNumberRangeType::TYPE, $context);
self::assertMatchesRegularExpression('/^CUSTOM-\d{6}$/', $generated);
}
Conclusion
Registering custom number range types in Shopware 6.7 provides developers with powerful capabilities to extend the platform's core functionality while maintaining data integrity and business continuity. The enhanced architecture supports complex generation logic, flexible configuration options, and seamless integration with existing systems.
By following the patterns outlined in this technical guide, developers can create robust, scalable number range implementations that meet specific business requirements while leveraging Shopware 6.7's improved performance and extensibility features. The system's modular design ensures that custom implementations remain maintainable and upgrade-compatible, making it an excellent foundation for enterprise-level commerce solutions.
The key to successful implementation lies in understanding the underlying architecture, properly configuring service dependencies, and implementing appropriate error handling and validation mechanisms. With careful attention to these aspects, custom number range types can significantly enhance the functionality of Shopware 6.7 installations while maintaining the platform's reliability and performance standards.