Skip to content

Commit 65c8d23

Browse files
authored
SUPESC-789 Allowed editing super attributes from BO. (#11707)
SUPESC-789 Allowed editing super attributes from BO.
1 parent 0019185 commit 65c8d23

File tree

11 files changed

+360
-1
lines changed

11 files changed

+360
-1
lines changed

composer.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,12 +6,13 @@
66
"require": {
77
"php": ">=8.2",
88
"spryker/event-behavior": "^1.10.0",
9-
"spryker/kernel": "^3.30.0",
9+
"spryker/kernel": "^3.77.0",
1010
"spryker/laminas": "^1.0.0",
1111
"spryker/locale": "^3.1.0 || ^4.0.0",
1212
"spryker/product": "^5.5.0 || ^6.0.0",
1313
"spryker/product-storage-extension": "^1.7.0",
1414
"spryker/propel-orm": "^1.5.0",
15+
"spryker/publisher-extension": "^1.0.0",
1516
"spryker/sitemap-extension": "^1.1.0",
1617
"spryker/storage": "^3.4.0",
1718
"spryker/store": "^1.7.0",

src/Spryker/Zed/ProductStorage/Business/ProductStorageBusinessFactory.php

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,11 @@
1111
use Spryker\Zed\ProductStorage\Business\Attribute\AttributeMap;
1212
use Spryker\Zed\ProductStorage\Business\Filter\SingleValueSuperAttributeFilter;
1313
use Spryker\Zed\ProductStorage\Business\Filter\SingleValueSuperAttributeFilterInterface;
14+
use Spryker\Zed\ProductStorage\Business\Publisher\ProductAbstractStoragePublisher;
15+
use Spryker\Zed\ProductStorage\Business\Publisher\ProductAbstractStoragePublisherInterface;
1416
use Spryker\Zed\ProductStorage\Business\Storage\ProductAbstractStorageWriter;
1517
use Spryker\Zed\ProductStorage\Business\Storage\ProductConcreteStorageWriter;
18+
use Spryker\Zed\ProductStorage\Dependency\Facade\ProductStorageToEventBehaviorFacadeInterface;
1619
use Spryker\Zed\ProductStorage\Dependency\Facade\ProductStorageToStoreFacadeInterface;
1720
use Spryker\Zed\ProductStorage\ProductStorageDependencyProvider;
1821

@@ -62,6 +65,18 @@ public function createSingleValueSuperAttributeFilter(): SingleValueSuperAttribu
6265
return new SingleValueSuperAttributeFilter();
6366
}
6467

68+
/**
69+
* @return \Spryker\Zed\ProductStorage\Business\Publisher\ProductAbstractStoragePublisherInterface
70+
*/
71+
public function createProductAbstractStoragePublisher(): ProductAbstractStoragePublisherInterface
72+
{
73+
return new ProductAbstractStoragePublisher(
74+
$this->getEventBehaviorFacade(),
75+
$this->createProductAbstractStorageWriter(),
76+
$this->getRepository(),
77+
);
78+
}
79+
6580
/**
6681
* @return \Spryker\Zed\ProductStorage\Business\Attribute\AttributeMapInterface
6782
*/
@@ -91,6 +106,14 @@ public function getStoreFacade(): ProductStorageToStoreFacadeInterface
91106
return $this->getProvidedDependency(ProductStorageDependencyProvider::FACADE_STORE);
92107
}
93108

109+
/**
110+
* @return \Spryker\Zed\ProductStorage\Dependency\Facade\ProductStorageToEventBehaviorFacadeInterface
111+
*/
112+
public function getEventBehaviorFacade(): ProductStorageToEventBehaviorFacadeInterface
113+
{
114+
return $this->getProvidedDependency(ProductStorageDependencyProvider::FACADE_EVENT_BEHAVIOR);
115+
}
116+
94117
/**
95118
* @return array<\Spryker\Zed\ProductStorageExtension\Dependency\Plugin\ProductAbstractStorageExpanderPluginInterface>
96119
*/
Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
<?php
2+
3+
/**
4+
* Copyright © 2016-present Spryker Systems GmbH. All rights reserved.
5+
* Use of this software requires acceptance of the Evaluation License Agreement. See LICENSE file.
6+
*/
7+
8+
namespace Spryker\Zed\ProductStorage\Business\Publisher;
9+
10+
use Spryker\Zed\ProductStorage\Business\Storage\ProductAbstractStorageWriterInterface;
11+
use Spryker\Zed\ProductStorage\Dependency\Facade\ProductStorageToEventBehaviorFacadeInterface;
12+
use Spryker\Zed\ProductStorage\Persistence\ProductStorageRepositoryInterface;
13+
14+
class ProductAbstractStoragePublisher implements ProductAbstractStoragePublisherInterface
15+
{
16+
/**
17+
* @uses \Orm\Zed\Product\Persistence\Map\SpyProductLocalizedAttributesTableMap::COL_FK_PRODUCT
18+
*
19+
* @var string
20+
*/
21+
protected const COL_FK_PRODUCT = 'spy_product_localized_attributes.fk_product';
22+
23+
/**
24+
* @param \Spryker\Zed\ProductStorage\Dependency\Facade\ProductStorageToEventBehaviorFacadeInterface $eventBehaviorFacade
25+
* @param \Spryker\Zed\ProductStorage\Business\Storage\ProductAbstractStorageWriterInterface $productAbstractStorageWriter
26+
* @param \Spryker\Zed\ProductStorage\Persistence\ProductStorageRepositoryInterface $productStorageRepository
27+
*/
28+
public function __construct(
29+
protected ProductStorageToEventBehaviorFacadeInterface $eventBehaviorFacade,
30+
protected ProductAbstractStorageWriterInterface $productAbstractStorageWriter,
31+
protected ProductStorageRepositoryInterface $productStorageRepository
32+
) {
33+
}
34+
35+
/**
36+
* @param list<\Generated\Shared\Transfer\EventEntityTransfer> $eventEntityTransfers
37+
* @param string $eventName
38+
*
39+
* @return void
40+
*/
41+
public function publishByProductLocalizedAttributesEvents(array $eventEntityTransfers, string $eventName): void
42+
{
43+
$productIds = $this->eventBehaviorFacade->getEventTransferForeignKeys($eventEntityTransfers, static::COL_FK_PRODUCT);
44+
45+
if (!$productIds) {
46+
return;
47+
}
48+
49+
$productAbstractIds = $this->productStorageRepository->getProductAbstractIdsByProductIds($productIds);
50+
51+
if (!$productAbstractIds) {
52+
return;
53+
}
54+
55+
$this->productAbstractStorageWriter->publish($productAbstractIds);
56+
}
57+
}
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
<?php
2+
3+
/**
4+
* Copyright © 2016-present Spryker Systems GmbH. All rights reserved.
5+
* Use of this software requires acceptance of the Evaluation License Agreement. See LICENSE file.
6+
*/
7+
8+
namespace Spryker\Zed\ProductStorage\Business\Publisher;
9+
10+
interface ProductAbstractStoragePublisherInterface
11+
{
12+
/**
13+
* @param list<\Generated\Shared\Transfer\EventEntityTransfer> $eventEntityTransfers
14+
* @param string $eventName
15+
*
16+
* @return void
17+
*/
18+
public function publishByProductLocalizedAttributesEvents(array $eventEntityTransfers, string $eventName): void;
19+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
<?php
2+
3+
/**
4+
* Copyright © 2016-present Spryker Systems GmbH. All rights reserved.
5+
* Use of this software requires acceptance of the Evaluation License Agreement. See LICENSE file.
6+
*/
7+
8+
namespace Spryker\Zed\ProductStorage\Communication\Plugin\Publisher\ProductAbstract;
9+
10+
use Spryker\Zed\Kernel\Communication\AbstractPlugin;
11+
use Spryker\Zed\Product\Dependency\ProductEvents;
12+
use Spryker\Zed\PublisherExtension\Dependency\Plugin\PublisherPluginInterface;
13+
14+
/**
15+
* @method \Spryker\Zed\ProductStorage\Communication\ProductStorageCommunicationFactory getFactory()
16+
* @method \Spryker\Zed\ProductStorage\ProductStorageConfig getConfig()
17+
* @method \Spryker\Zed\ProductStorage\Business\ProductStorageFacadeInterface getFacade()
18+
* @method \Spryker\Zed\ProductStorage\Business\ProductStorageBusinessFactory getBusinessFactory()
19+
*/
20+
class ProductLocalizedAttributesProductAbstractWritePublisherPlugin extends AbstractPlugin implements PublisherPluginInterface
21+
{
22+
/**
23+
* {@inheritDoc}
24+
* - Publishes product abstract data by `SpyProductLocalizedAttributes` entity events.
25+
*
26+
* @api
27+
*
28+
* @param list<\Generated\Shared\Transfer\EventEntityTransfer> $eventEntityTransfers
29+
* @param string $eventName
30+
*
31+
* @return void
32+
*/
33+
public function handleBulk(array $eventEntityTransfers, $eventName): void
34+
{
35+
$this->getBusinessFactory()
36+
->createProductAbstractStoragePublisher()
37+
->publishByProductLocalizedAttributesEvents($eventEntityTransfers, $eventName);
38+
}
39+
40+
/**
41+
* {@inheritDoc}
42+
*
43+
* @api
44+
*
45+
* @return list<string>
46+
*/
47+
public function getSubscribedEvents(): array
48+
{
49+
return [
50+
ProductEvents::ENTITY_SPY_PRODUCT_LOCALIZED_ATTRIBUTES_UPDATE,
51+
];
52+
}
53+
}

src/Spryker/Zed/ProductStorage/Persistence/ProductStorageRepository.php

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99

1010
use Generator;
1111
use Orm\Zed\Product\Persistence\Map\SpyProductAbstractLocalizedAttributesTableMap;
12+
use Orm\Zed\Product\Persistence\Map\SpyProductTableMap;
1213
use Orm\Zed\Url\Persistence\Map\SpyUrlTableMap;
1314
use Propel\Runtime\ActiveQuery\ModelCriteria;
1415
use Spryker\Zed\Kernel\Persistence\AbstractRepository;
@@ -150,4 +151,22 @@ public function getSitemapGeneratorUrls(string $storeName, int $limit): Generato
150151

151152
yield [];
152153
}
154+
155+
/**
156+
* @module Product
157+
*
158+
* @param list<int> $productIds
159+
*
160+
* @return list<int>
161+
*/
162+
public function getProductAbstractIdsByProductIds(array $productIds): array
163+
{
164+
return $this->getFactory()
165+
->getProductPropelQuery()
166+
->filterByIdProduct_In($productIds)
167+
->select([SpyProductTableMap::COL_FK_PRODUCT_ABSTRACT])
168+
->distinct()
169+
->find()
170+
->getData();
171+
}
153172
}

src/Spryker/Zed/ProductStorage/Persistence/ProductStorageRepositoryInterface.php

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,4 +46,11 @@ public function getSitemapUrls(string $storeName): array;
4646
* @return \Generator
4747
*/
4848
public function getSitemapGeneratorUrls(string $storeName, int $limit): Generator;
49+
50+
/**
51+
* @param list<int> $productIds
52+
*
53+
* @return list<int>
54+
*/
55+
public function getProductAbstractIdsByProductIds(array $productIds): array;
4956
}

src/Spryker/Zed/ProductStorage/ProductStorageDependencyProvider.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,7 @@ public function provideBusinessLayerDependencies(Container $container)
9999
$container = $this->addProductConcreteStorageCollectionExpanderPlugins($container);
100100
$container = $this->addProductAbstractStorageCollectionFilterPlugins($container);
101101
$container = $this->addProductConcreteStorageCollectionFilterPlugins($container);
102+
$container = $this->addEventBehaviorFacade($container);
102103

103104
return $container;
104105
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,124 @@
1+
<?php
2+
3+
/**
4+
* Copyright © 2016-present Spryker Systems GmbH. All rights reserved.
5+
* Use of this software requires acceptance of the Evaluation License Agreement. See LICENSE file.
6+
*/
7+
8+
namespace SprykerTest\Zed\ProductStorage\Communication\Plugin\Publisher\ProductAbstract;
9+
10+
use Codeception\Test\Unit;
11+
use Generated\Shared\Transfer\EventEntityTransfer;
12+
use Spryker\Client\Kernel\Container;
13+
use Spryker\Client\Queue\QueueDependencyProvider;
14+
use Spryker\Zed\Product\Dependency\ProductEvents;
15+
use Spryker\Zed\ProductStorage\Communication\Plugin\Publisher\ProductAbstract\ProductLocalizedAttributesProductAbstractWritePublisherPlugin;
16+
use SprykerTest\Zed\ProductStorage\ProductStorageCommunicationTester;
17+
18+
/**
19+
* Auto-generated group annotations
20+
*
21+
* @group SprykerTest
22+
* @group Zed
23+
* @group ProductStorage
24+
* @group Communication
25+
* @group Plugin
26+
* @group Publisher
27+
* @group ProductAbstract
28+
* @group ProductLocalizedAttributesProductAbstractWritePublisherPluginTest
29+
* Add your own group annotations below this line
30+
*/
31+
class ProductLocalizedAttributesProductAbstractWritePublisherPluginTest extends Unit
32+
{
33+
/**
34+
* @uses \Spryker\Zed\ProductStorage\Business\Publisher\ProductAbstractStoragePublisher::COL_FK_PRODUCT
35+
*
36+
* @var string
37+
*/
38+
protected const COL_FK_PRODUCT = 'spy_product_localized_attributes.fk_product';
39+
40+
/**
41+
* @var \SprykerTest\Zed\ProductStorage\ProductStorageCommunicationTester
42+
*/
43+
protected ProductStorageCommunicationTester $tester;
44+
45+
/**
46+
* @return void
47+
*/
48+
protected function setUp(): void
49+
{
50+
parent::setUp();
51+
52+
$this->tester->setDependency(QueueDependencyProvider::QUEUE_ADAPTERS, function (Container $container) {
53+
return [
54+
$this->tester->getLocator()->rabbitMq()->client()->createQueueAdapter(),
55+
];
56+
});
57+
$this->tester->ensureProductAbstractStorageTableIsEmpty();
58+
}
59+
60+
/**
61+
* @return void
62+
*/
63+
public function testHandleBulkStoresProductAbstractStorageEntity(): void
64+
{
65+
// Arrange
66+
$productConcreteTransfer = $this->tester->haveFullProduct();
67+
$eventEntityTransfer = (new EventEntityTransfer())->setForeignKeys([
68+
static::COL_FK_PRODUCT => $productConcreteTransfer->getIdProductConcreteOrFail(),
69+
]);
70+
71+
// Act
72+
(new ProductLocalizedAttributesProductAbstractWritePublisherPlugin())->handleBulk(
73+
[$eventEntityTransfer],
74+
ProductEvents::ENTITY_SPY_PRODUCT_LOCALIZED_ATTRIBUTES_UPDATE,
75+
);
76+
77+
// Assert
78+
$this->assertNotNull($this->tester->findProductAbstractStorageEntityByIdProductAbstract(
79+
$productConcreteTransfer->getFkProductAbstractOrFail(),
80+
));
81+
}
82+
83+
/**
84+
* @return void
85+
*/
86+
public function testHandleBulkDoesNothingWhenIdProductConcreteIsNotPassedInEventEntityTransfer(): void
87+
{
88+
// Arrange
89+
$productConcreteTransfer = $this->tester->haveFullProduct();
90+
$eventEntityTransfer = (new EventEntityTransfer())->setForeignKeys([
91+
'testKey' => $productConcreteTransfer->getIdProductConcreteOrFail(),
92+
]);
93+
94+
// Act
95+
(new ProductLocalizedAttributesProductAbstractWritePublisherPlugin())->handleBulk(
96+
[$eventEntityTransfer],
97+
ProductEvents::ENTITY_SPY_PRODUCT_LOCALIZED_ATTRIBUTES_UPDATE,
98+
);
99+
100+
// Assert
101+
$this->assertSame(0, $this->tester->countProductAbstractStorageEntities());
102+
}
103+
104+
/**
105+
* @return void
106+
*/
107+
public function testHandleBulkDoesNothingWhenProductAbstractDoesNotExist(): void
108+
{
109+
// Arrange
110+
$this->tester->ensureProductAbstractTableIsEmpty();
111+
$eventEntityTransfer = (new EventEntityTransfer())->setForeignKeys([
112+
static::COL_FK_PRODUCT => 1,
113+
]);
114+
115+
// Act
116+
(new ProductLocalizedAttributesProductAbstractWritePublisherPlugin())->handleBulk(
117+
[$eventEntityTransfer],
118+
ProductEvents::ENTITY_SPY_PRODUCT_LOCALIZED_ATTRIBUTES_UPDATE,
119+
);
120+
121+
// Assert
122+
$this->assertSame(0, $this->tester->countProductAbstractStorageEntities());
123+
}
124+
}

0 commit comments

Comments
 (0)