Shopware 6.7 introduces significant improvements to the platform's flexibility and extensibility, particularly when it comes to customizing product listings and sorting options. This technical deep dive explores how to implement custom sorting functionality that extends beyond the default options provided by the platform.
Understanding Shopware 6.7's Listing Architecture
Before diving into implementation details, it's crucial to understand how Shopware 6.7 handles product listings. The platform utilizes a sophisticated architecture based on Elasticsearch for search and indexing, with dedicated services for handling sorting operations within product collections.
The core components involved in listing sorting include:
ProductListingSortingCriteria- Defines available sorting optionsProductListingResult- Contains the actual sorted resultsProductListingService- Orchestrates the sorting processCriteria- Query builder used for constructing search requests
Prerequisites and Setup
To implement custom sorting in Shopware 6.7, you'll need to create a custom plugin structure. Begin by setting up your plugin directory:
src/
├── Plugin.php
├── Resources/
│ ├── config/
│ │ └── services.xml
│ ├── framework/
│ │ └── sorting/
│ │ └── custom-sorting.xml
│ └── migration/
└── Core/
└── Content/
└── Product/
└── Sort/
└── CustomProductSorting.php
Creating the Custom Sorting Service
The first step involves creating a service that defines your custom sorting logic. This service needs to implement the ProductListingSortingInterface:
<?php declare(strict_types=1);
namespace YourPlugin\Core\Content\Product\Sort;
use Shopware\Core\Content\Product\SalesChannel\Listing\ProductListingSortingInterface;
use Shopware\Core\Framework\DataAbstractionLayer\Search\Criteria;
class CustomProductSorting implements ProductListingSortingInterface
{
public function getLabel(): string
{
return 'Custom Sort Order';
}
public function getSortingKey(): string
{
return 'custom_sorting';
}
public function apply(Criteria $criteria): void
{
// Custom sorting logic implementation
$criteria->addSorting(
new \Shopware\Core\Framework\DataAbstractionLayer\Search\Sorting\FieldSorting(
'product.custom_field',
\Shopware\Core\Framework\DataAbstractionLayer\Search\Sorting\Sorting::DESCENDING
)
);
}
public function isAvailable(): bool
{
return true;
}
}
Registering the Custom Sorting Option
To make your custom sorting option available within Shopware 6.7, you need to register it through dependency injection in your plugin's service configuration:
<!-- src/Resources/config/services.xml -->
<?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>
<service id="YourPlugin\Core\Content\Product\Sort\CustomProductSorting">
<tag name="shopware.product.listing.sorting"/>
</service>
<service id="YourPlugin\Core\Content\Product\Sort\CustomProductSortingService">
<argument type="service" id="Shopware\Core\Framework\DataAbstractionLayer\Search\Criteria"/>
</service>
</services>
</container>
Advanced Sorting Implementation
For more complex scenarios, you might need to implement multi-field sorting or conditional logic. Here's an enhanced version that handles multiple sorting criteria:
<?php declare(strict_types=1);
namespace YourPlugin\Core\Content\Product\Sort;
use Shopware\Core\Content\Product\SalesChannel\Listing\ProductListingSortingInterface;
use Shopware\Core\Framework\DataAbstractionLayer\Search\Criteria;
use Shopware\Core\Framework\DataAbstractionLayer\Search\Sorting\FieldSorting;
class AdvancedCustomSorting implements ProductListingSortingInterface
{
public function getLabel(): string
{
return 'Advanced Custom Sorting';
}
public function getSortingKey(): string
{
return 'advanced_custom_sorting';
}
public function apply(Criteria $criteria): void
{
$sortings = [
new FieldSorting('product.custom_field_1', FieldSorting::DESCENDING),
new FieldSorting('product.custom_field_2', FieldSorting::ASCENDING),
new FieldSorting('product.name', FieldSorting::ASCENDING)
];
foreach ($sortings as $sorting) {
$criteria->addSorting($sorting);
}
}
public function isAvailable(): bool
{
return true;
}
}
Handling Performance Considerations
When implementing custom sorting, performance becomes a critical factor. Shopware 6.7's Elasticsearch integration requires careful consideration of indexing strategies:
<?php declare(strict_types=1);
namespace YourPlugin\Core\Content\Product\Sort;
use Shopware\Core\Content\Product\SalesChannel\Listing\ProductListingSortingInterface;
use Shopware\Core\Framework\DataAbstractionLayer\Search\Criteria;
class PerformanceOptimizedSorting implements ProductListingSortingInterface
{
public function getLabel(): string
{
return 'Performance Optimized Sorting';
}
public function getSortingKey(): string
{
return 'perf_optimized_sorting';
}
public function apply(Criteria $criteria): void
{
// Check if sorting is actually needed
if ($criteria->getSorting() !== null) {
return;
}
// Add only necessary fields to sorting
$criteria->addSorting(
new \Shopware\Core\Framework\DataAbstractionLayer\Search\Sorting\FieldSorting(
'product.custom_field',
\Shopware\Core\Framework\DataAbstractionLayer\Search\Sorting\Sorting::DESCENDING,
\Shopware\Core\Framework\DataAbstractionLayer\Search\Sorting\FieldSorting::NULLS_LAST
)
);
}
public function isAvailable(): bool
{
return true;
}
}
Integration with Product Custom Fields
One of the most powerful aspects of custom sorting in Shopware 6.7 is its ability to work with custom fields. Here's how to integrate with product custom fields:
<?php declare(strict_types=1);
namespace YourPlugin\Core\Content\Product\Sort;
use Shopware\Core\Content\Product\SalesChannel\Listing\ProductListingSortingInterface;
use Shopware\Core\Framework\DataAbstractionLayer\Search\Criteria;
class CustomFieldSorting implements ProductListingSortingInterface
{
private string $customFieldName;
public function __construct(string $customFieldName)
{
$this->customFieldName = $customFieldName;
}
public function getLabel(): string
{
return 'Custom Field Based Sorting';
}
public function getSortingKey(): string
{
return 'custom_field_sorting_' . $this->customFieldName;
}
public function apply(Criteria $criteria): void
{
// Validate that the custom field exists and is sortable
$criteria->addSorting(
new \Shopware\Core\Framework\DataAbstractionLayer\Search\Sorting\FieldSorting(
'product.custom_fields.' . $this->customFieldName,
\Shopware\Core\Framework\DataAbstractionLayer\Search\Sorting\Sorting::DESCENDING
)
);
}
public function isAvailable(): bool
{
return true;
}
}
Testing Your Custom Sorting Implementation
Testing custom sorting options requires creating proper unit tests that verify the criteria generation:
<?php declare(strict_types=1);
namespace YourPlugin\Tests\Unit\Core\Content\Product\Sort;
use PHPUnit\Framework\TestCase;
use Shopware\Core\Framework\DataAbstractionLayer\Search\Criteria;
use YourPlugin\Core\Content\Product\Sort\CustomProductSorting;
class CustomProductSortingTest extends TestCase
{
public function testApplySorting(): void
{
$sorting = new CustomProductSorting();
$criteria = new Criteria();
$sorting->apply($criteria);
$this->assertNotNull($criteria->getSorting());
$this->assertCount(1, $criteria->getSorting());
}
public function testGetSortingKey(): void
{
$sorting = new CustomProductSorting();
$this->assertEquals('custom_sorting', $sorting->getSortingKey());
}
}
Configuration and Administration
In Shopware 6.7, administrators can configure sorting options through the administration interface. Your custom sorting needs to be properly registered to appear in the available options:
// src/Resources/app/administration/src/module/sw-product/component/sw-product-listing-sorting/index.js
import { Mixin } from 'src/core/service/mixin.service';
export default {
mixins: [
Mixin.getByName('listing-sorting')
],
data() {
return {
customSortingOptions: [
{
value: 'custom_sorting',
label: 'Custom Sorting Option'
}
]
};
}
};
Best Practices and Recommendations
- Index Optimization: Ensure that fields used in custom sorting are properly indexed in Elasticsearch for optimal performance
- Caching Strategy: Implement appropriate caching mechanisms to reduce database load
- Fallback Handling: Always provide fallback sorting when custom fields are empty or null
- Performance Monitoring: Monitor query performance and optimize accordingly
- Security Considerations: Validate all input parameters to prevent injection attacks
Conclusion
Shopware 6.7 provides robust infrastructure for implementing custom sorting options that extend beyond the default capabilities. By leveraging the platform's service-oriented architecture and integration with Elasticsearch, developers can create sophisticated sorting logic that enhances user experience while maintaining performance standards.
The key to successful implementation lies in understanding the underlying data structures, properly registering services, and considering performance implications. With careful planning and execution, custom sorting options can significantly improve product discovery and overall shopping experience in Shopware 6.7 environments.
This approach not only demonstrates the platform's extensibility but also showcases how modern e-commerce platforms can be customized to meet specific business requirements while maintaining scalability and maintainability standards.