Skip to content

Commit a18a6da

Browse files
authored
feat: Add per-SalesChannel activation setting (#93)
* feat: add per-SalesChannel activation setting Add new 'active' config option to enable/disable product compare functionality per SalesChannel. When disabled: - Compare routes return 404 - Compare buttons are hidden in storefront - Cross-selling comparison is disabled - Subscribers skip processing This allows shop owners to selectively enable the compare feature only for specific SalesChannels. * chore: Increase version * chore: Default enable true
1 parent 1c1968d commit a18a6da

File tree

11 files changed

+72
-19
lines changed

11 files changed

+72
-19
lines changed

composer.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
22
"name": "frosh/product-compare",
33
"description": "A Simple Product Compare plugin for Shopware 6",
4-
"version": "4.0.0",
4+
"version": "4.0.1",
55
"type": "shopware-platform-plugin",
66
"license": "MIT",
77
"authors": [

src/Controller/CompareProductController.php

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,12 @@
66

77
use Frosh\FroshProductCompare\Page\CompareProductPageLoader;
88
use Shopware\Core\System\SalesChannel\SalesChannelContext;
9+
use Shopware\Core\System\SystemConfig\SystemConfigService;
910
use Shopware\Storefront\Controller\StorefrontController;
1011
use Shopware\Storefront\Page\GenericPageLoaderInterface;
1112
use Symfony\Component\HttpFoundation\Request;
1213
use Symfony\Component\HttpFoundation\Response;
14+
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
1315
use Symfony\Component\Routing\Attribute\Route;
1416

1517
#[Route(defaults: ['_routeScope' => ['storefront']])]
@@ -18,11 +20,14 @@ class CompareProductController extends StorefrontController
1820
public function __construct(
1921
private readonly CompareProductPageLoader $compareProductPageLoader,
2022
private readonly GenericPageLoaderInterface $genericPageLoader,
23+
private readonly SystemConfigService $systemConfigService,
2124
) {}
2225

2326
#[Route(path: '/compare', name: 'frontend.compare.page', options: ['seo' => false], defaults: ['_httpCache' => false], methods: ['GET'])]
2427
public function comparePage(Request $request, SalesChannelContext $context): Response
2528
{
29+
$this->ensureCompareIsActive($context);
30+
2631
$page = $this->genericPageLoader->load($request, $context);
2732

2833
return $this->renderStorefront('@FroshProductCompare/storefront/page/compare.html.twig', ['page' => $page]);
@@ -31,6 +36,8 @@ public function comparePage(Request $request, SalesChannelContext $context): Res
3136
#[Route(path: '/compare/content', name: 'frontend.compare.content', options: ['seo' => false], defaults: ['_httpCache' => false, 'XmlHttpRequest' => true], methods: ['POST'])]
3237
public function comparePageContent(Request $request, SalesChannelContext $context): Response
3338
{
39+
$this->ensureCompareIsActive($context);
40+
3441
$productIds = $request->request->all('productIds');
3542
$productIds = array_values(array_filter($productIds, is_string(...)));
3643

@@ -42,11 +49,20 @@ public function comparePageContent(Request $request, SalesChannelContext $contex
4249
#[Route(path: '/compare/offcanvas', name: 'frontend.compare.offcanvas', options: ['seo' => false], defaults: ['_httpCache' => false, 'XmlHttpRequest' => true], methods: ['POST'])]
4350
public function offcanvas(Request $request, SalesChannelContext $context): Response
4451
{
52+
$this->ensureCompareIsActive($context);
53+
4554
$productIds = $request->request->all('productIds');
4655
$productIds = array_filter($productIds, is_string(...));
4756

4857
$page = $this->compareProductPageLoader->loadPreview($productIds, $request, $context);
4958

5059
return $this->renderStorefront('@FroshProductCompare/storefront/component/compare/offcanvas-compare-list.html.twig', ['page' => $page]);
5160
}
61+
62+
private function ensureCompareIsActive(SalesChannelContext $context): void
63+
{
64+
if (!$this->systemConfigService->getBool('FroshProductCompare.config.active', $context->getSalesChannelId())) {
65+
throw new NotFoundHttpException('Product compare is not enabled for this sales channel');
66+
}
67+
}
5268
}

src/DependencyInjection/services.xml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
<service id="Frosh\FroshProductCompare\Controller\CompareProductController" public="true">
2727
<argument type="service" id="Frosh\FroshProductCompare\Page\CompareProductPageLoader"/>
2828
<argument type="service" id="Shopware\Storefront\Page\GenericPageLoader"/>
29+
<argument type="service" id="Shopware\Core\System\SystemConfig\SystemConfigService"/>
2930
<call method="setContainer">
3031
<argument type="service" id="service_container"/>
3132
</call>
@@ -35,10 +36,12 @@
3536
<service id="Frosh\FroshProductCompare\Subscriber\FroshCrossSellingProductListingSubscriber">
3637
<argument type="service" id="Frosh\FroshProductCompare\Page\CompareProductPageLoader"/>
3738
<argument type="service" id="Shopware\Core\Content\Product\Cart\ProductGateway"/>
39+
<argument type="service" id="Shopware\Core\System\SystemConfig\SystemConfigService"/>
3840
<tag name="kernel.event_subscriber"/>
3941
</service>
4042

4143
<service id="Frosh\FroshProductCompare\Subscriber\FroshProductGatewayCriteriaSubscriber">
44+
<argument type="service" id="Shopware\Core\System\SystemConfig\SystemConfigService"/>
4245
<tag name="kernel.event_subscriber"/>
4346
</service>
4447

src/Resources/config/config.xml

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,13 @@
55
<title>Product Compare Configuration</title>
66
<title lang="de-DE">Produktvergleichskonfiguration</title>
77

8+
<input-field type="bool">
9+
<name>active</name>
10+
<label>Enable Product Compare</label>
11+
<label lang="de-DE">Produktvergleich aktivieren</label>
12+
<defaultValue>true</defaultValue>
13+
</input-field>
14+
815
<input-field type="bool">
916
<name>showIconOnly</name>
1017
<label>Add to compare with icon only</label>

src/Resources/views/storefront/base.html.twig

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,9 @@
33
{% block base_body_inner %}
44
{{ parent() }}
55

6-
{% block frosh_product_compare_float_button_container %}
7-
{% sw_include '@Storefront/storefront/component/compare/compare-float.html.twig' %}
8-
{% endblock %}
6+
{% if config('FroshProductCompare.config.active') %}
7+
{% block frosh_product_compare_float_button_container %}
8+
{% sw_include '@Storefront/storefront/component/compare/compare-float.html.twig' %}
9+
{% endblock %}
10+
{% endif %}
911
{% endblock %}

src/Resources/views/storefront/component/product/card/action.html.twig

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
{% block component_product_box_action_buy %}
44
{{ parent() }}
55

6-
{% if activeRoute != 'frontend.compare.content' %}
6+
{% if config('FroshProductCompare.config.active') and activeRoute != 'frontend.compare.content' %}
77
{% block component_product_box_action_add_to_compare_button %}
88
{% sw_include '@Storefront/storefront/component/product/card/compare-button.html.twig' %}
99
{% endblock %}
@@ -13,7 +13,7 @@
1313
{% block component_product_box_action_detail %}
1414
{{ parent() }}
1515

16-
{% if activeRoute != 'frontend.compare.content' %}
16+
{% if config('FroshProductCompare.config.active') and activeRoute != 'frontend.compare.content' %}
1717
{% block component_product_box_action_detail_add_to_compare_button %}
1818
{% sw_include '@Storefront/storefront/component/product/card/compare-button.html.twig' %}
1919
{% endblock %}

src/Resources/views/storefront/element/cms-element-cross-selling.html.twig

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
{% set products = item.products %}
88
{% set id = crossSelling.id %}
99
{% set crossSellingComparable = item.crossSelling.extensions.crossSellingComparable %}
10-
{% if crossSellingComparable and crossSellingComparable.isComparable %}
10+
{% if config('FroshProductCompare.config.active') and crossSellingComparable and crossSellingComparable.isComparable %}
1111
{% set page = {
1212
products: products,
1313
properties: crossSelling.extensions.compareProperties

src/Resources/views/storefront/layout/header/header.html.twig

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
{% block layout_header_search_toggle %}
44
{{ parent() }}
55

6-
{% if config('FroshProductCompare.config.showInHeader') %}
6+
{% if config('FroshProductCompare.config.active') and config('FroshProductCompare.config.showInHeader') %}
77
{% block frosh_product_compare_widget_button %}
88
<div class="col-auto">
99
{% sw_include '@Storefront/storefront/component/compare/compare-float.html.twig' with {

src/Resources/views/storefront/page/product-detail/buy-widget.html.twig

Lines changed: 11 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -3,13 +3,15 @@
33
{% block page_product_detail_buy_container %}
44
{{ parent() }}
55

6-
{% block page_product_detail_add_to_compare_button %}
7-
<div class="mb-2">
8-
{% sw_include '@Storefront/storefront/component/product/card/compare-button.html.twig' with {
9-
navigationTree: page.header.navigation.tree,
10-
categoryTree: page.product.categoryTree|last,
11-
product: page.product
12-
} only %}
13-
</div>
14-
{% endblock %}
6+
{% if config('FroshProductCompare.config.active') %}
7+
{% block page_product_detail_add_to_compare_button %}
8+
<div class="mb-2">
9+
{% sw_include '@Storefront/storefront/component/product/card/compare-button.html.twig' with {
10+
navigationTree: page.header.navigation.tree,
11+
categoryTree: page.product.categoryTree|last,
12+
product: page.product
13+
} only %}
14+
</div>
15+
{% endblock %}
16+
{% endif %}
1517
{% endblock %}

src/Subscriber/FroshCrossSellingProductListingSubscriber.php

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,13 +20,15 @@
2020
use Shopware\Core\Framework\DataAbstractionLayer\Search\Filter\MultiFilter;
2121
use Shopware\Core\Framework\DataAbstractionLayer\Search\Filter\NotFilter;
2222
use Shopware\Core\System\SalesChannel\SalesChannelContext;
23+
use Shopware\Core\System\SystemConfig\SystemConfigService;
2324
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
2425

2526
class FroshCrossSellingProductListingSubscriber implements EventSubscriberInterface
2627
{
2728
public function __construct(
2829
private readonly CompareProductPageLoader $compareProductPageLoader,
2930
private readonly ProductGatewayInterface $productGateway,
31+
private readonly SystemConfigService $systemConfigService,
3032
) {}
3133

3234
public static function getSubscribedEvents(): array
@@ -46,6 +48,12 @@ public static function getSubscribedEvents(): array
4648

4749
public function handleCriteriaLoadedRequest(ProductCrossSellingCriteriaEvent $event): void
4850
{
51+
$context = $event->getSalesChannelContext();
52+
53+
if (!$this->systemConfigService->getBool('FroshProductCompare.config.active', $context->getSalesChannelId())) {
54+
return;
55+
}
56+
4957
$crossSelling = $event->getCrossSelling();
5058
$crossSellingComparable = $crossSelling->getExtension('crossSellingComparable');
5159

@@ -76,10 +84,14 @@ public function handleCriteriaLoadedRequest(ProductCrossSellingCriteriaEvent $ev
7684

7785
public function handleCrossSellingLoadedEvent(ProductCrossSellingsLoadedEvent $event): void
7886
{
79-
$crossSellings = $event->getCrossSellings();
80-
8187
$salesChannelContext = $event->getSalesChannelContext();
8288

89+
if (!$this->systemConfigService->getBool('FroshProductCompare.config.active', $salesChannelContext->getSalesChannelId())) {
90+
return;
91+
}
92+
93+
$crossSellings = $event->getCrossSellings();
94+
8395
/** @var CrossSellingElement $crossSellingElement */
8496
foreach ($crossSellings as $crossSellingElement) {
8597
$crossSelling = $crossSellingElement->getCrossSelling();

0 commit comments

Comments
 (0)