Skip to content

Commit

Permalink
FRW-9739 Adjusted DDE API performance. (#11273)
Browse files Browse the repository at this point in the history
FRW-9739 Adjusted DDE API performance.
  • Loading branch information
dimitriyTsemma authored Jan 28, 2025
1 parent 6796e82 commit f41bbdd
Show file tree
Hide file tree
Showing 16 changed files with 277 additions and 2 deletions.
7 changes: 7 additions & 0 deletions architecture-baseline.json
Original file line number Diff line number Diff line change
Expand Up @@ -237,6 +237,13 @@
"ruleset": "Spryker",
"priority": "2"
},
{
"fileName": "src/Spryker/Zed/Product/Dependency/Facade/ProductToUrlBridge.php",
"description": "Bridges: Method `saveUrlCollection()` must have `public function [update|create]<DomainEntity>Collection(<DomainEntity>CollectionRequestTransfer): <DomainEntity>CollectionResponseTransfer` signature.",
"rule": "BridgeFacadeMethodsRule",
"ruleset": "Spryker",
"priority": "2"
},
{
"fileName": "src/Spryker/Zed/Product/Dependency/Facade/ProductToUrlInterface.php",
"description": "Bridges: The bridge interface has incorrect method signature for `createUrl()`. Missed return type. That violates the rule \"All bridge interface methods must have exactly the same or more strict signature as their parent\"",
Expand Down
2 changes: 1 addition & 1 deletion composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
"spryker/symfony": "^3.0.0",
"spryker/touch": "^3.0.0 || ^4.0.0",
"spryker/transfer": "^3.27.0",
"spryker/url": "^3.2.1",
"spryker/url": "^3.16.0",
"spryker/util-encoding": "^2.0.0",
"spryker/util-text": "^1.1.0"
},
Expand Down
1 change: 1 addition & 0 deletions src/Spryker/Shared/Product/Transfer/product.transfer.xml
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,7 @@
<property name="idUrl" type="int"/>
<property name="fkResourceProductAbstract" type="int"/>
<property name="fkLocale" type="int"/>
<property name="originalUrl" type="string"/>
</transfer>

<transfer name="ProductCriteria">
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,35 @@ public function generateProductUrl(ProductAbstractTransfer $productAbstractTrans
return $productUrlTransfer;
}

/**
* @param array<\Generated\Shared\Transfer\ProductAbstractTransfer> $productAbstractTransfers
*
* @return array<\Generated\Shared\Transfer\ProductUrlTransfer>
*/
public function generateProductsUrl(array $productAbstractTransfers): array
{
$availableLocales = $this->localeFacade->getLocaleCollection();
$productUrlTransfers = [];

foreach ($productAbstractTransfers as $productAbstractTransfer) {
$productUrlTransfer = new ProductUrlTransfer();
$productUrlTransfer->setAbstractSku($productAbstractTransfer->getSku());

foreach ($availableLocales as $localeTransfer) {
$url = $this->generateUrlByLocale($productAbstractTransfer, $localeTransfer);

$localizedUrl = new LocalizedUrlTransfer();
$localizedUrl->setLocale($localeTransfer);
$localizedUrl->setUrl($url);

$productUrlTransfer->addUrl($localizedUrl);
}
$productUrlTransfers[] = $productUrlTransfer;
}

return $productUrlTransfers;
}

/**
* @param \Generated\Shared\Transfer\ProductAbstractTransfer $productAbstractTransfer
* @param \Generated\Shared\Transfer\LocaleTransfer $localeTransfer
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,4 +17,11 @@ interface ProductUrlGeneratorInterface
* @return \Generated\Shared\Transfer\ProductUrlTransfer
*/
public function generateProductUrl(ProductAbstractTransfer $productAbstractTransfer);

/**
* @param array<\Generated\Shared\Transfer\ProductAbstractTransfer> $productAbstractTransfers
*
* @return array<\Generated\Shared\Transfer\ProductUrlTransfer>
*/
public function generateProductsUrl(array $productAbstractTransfers): array;
}
127 changes: 126 additions & 1 deletion src/Spryker/Zed/Product/Business/Product/Url/ProductUrlManager.php
Original file line number Diff line number Diff line change
Expand Up @@ -17,11 +17,22 @@
use Spryker\Zed\Product\Dependency\Facade\ProductToTouchInterface;
use Spryker\Zed\Product\Dependency\Facade\ProductToUrlInterface;
use Spryker\Zed\Product\Persistence\ProductQueryContainerInterface;
use Spryker\Zed\Product\Persistence\ProductRepositoryInterface;

class ProductUrlManager implements ProductUrlManagerInterface
{
use TransactionTrait;

/**
* @var string
*/
protected const FIELD_LOCALE_ID = 'localeId';

/**
* @var string
*/
protected const FIELD_URL = 'url';

/**
* @var \Spryker\Zed\Product\Dependency\Facade\ProductToUrlInterface
*/
Expand Down Expand Up @@ -52,28 +63,36 @@ class ProductUrlManager implements ProductUrlManagerInterface
*/
protected $productEventTrigger;

/**
* @var \Spryker\Zed\Product\Persistence\ProductRepositoryInterface
*/
protected ProductRepositoryInterface $productRepository;

/**
* @param \Spryker\Zed\Product\Dependency\Facade\ProductToUrlInterface $urlFacade
* @param \Spryker\Zed\Product\Dependency\Facade\ProductToTouchInterface $touchFacade
* @param \Spryker\Zed\Product\Dependency\Facade\ProductToLocaleInterface $localeFacade
* @param \Spryker\Zed\Product\Persistence\ProductQueryContainerInterface $productQueryContainer
* @param \Spryker\Zed\Product\Business\Product\Url\ProductUrlGeneratorInterface $urlGenerator
* @param \Spryker\Zed\Product\Business\Product\Trigger\ProductEventTriggerInterface $productEventTrigger
* @param \Spryker\Zed\Product\Persistence\ProductRepositoryInterface $productRepository
*/
public function __construct(
ProductToUrlInterface $urlFacade,
ProductToTouchInterface $touchFacade,
ProductToLocaleInterface $localeFacade,
ProductQueryContainerInterface $productQueryContainer,
ProductUrlGeneratorInterface $urlGenerator,
ProductEventTriggerInterface $productEventTrigger
ProductEventTriggerInterface $productEventTrigger,
ProductRepositoryInterface $productRepository
) {
$this->urlFacade = $urlFacade;
$this->touchFacade = $touchFacade;
$this->localeFacade = $localeFacade;
$this->productQueryContainer = $productQueryContainer;
$this->urlGenerator = $urlGenerator;
$this->productEventTrigger = $productEventTrigger;
$this->productRepository = $productRepository;
}

/**
Expand All @@ -100,6 +119,18 @@ public function updateProductUrl(ProductAbstractTransfer $productAbstractTransfe
});
}

/**
* @param array<\Generated\Shared\Transfer\ProductAbstractTransfer> $productAbstractTransfers
*
* @return array<\Generated\Shared\Transfer\UrlTransfer>
*/
public function updateProductUrls(array $productAbstractTransfers): array
{
return $this->getTransactionHandler()->handleTransaction(function () use ($productAbstractTransfers): array {
return $this->executeUpdateProductsUrlTransaction($productAbstractTransfers);
});
}

/**
* @param \Generated\Shared\Transfer\ProductAbstractTransfer $productAbstractTransfer
*
Expand Down Expand Up @@ -219,6 +250,25 @@ protected function executeUpdateProductUrlTransaction(ProductAbstractTransfer $p
return $productUrl;
}

/**
* @param array<\Generated\Shared\Transfer\ProductAbstractTransfer> $productAbstractTransfers
*
* @return array<\Generated\Shared\Transfer\UrlTransfer>
*/
protected function executeUpdateProductsUrlTransaction(array $productAbstractTransfers): array
{
$productUrls = $this->urlGenerator->generateProductsUrl($productAbstractTransfers);

$urlTransfers = $this->getUrlByProductAbstractIdsAndLocaleIds(
array_map(function (ProductAbstractTransfer $productAbstractTransfer) {
return $productAbstractTransfer->requireIdProductAbstract()->getIdProductAbstract();
}, $productAbstractTransfers),
$productUrls,
);

return $this->urlFacade->saveUrlCollection($urlTransfers);
}

/**
* @param \Generated\Shared\Transfer\ProductAbstractTransfer $productAbstractTransfer
*
Expand Down Expand Up @@ -299,4 +349,79 @@ protected function getUrlByIdProductAbstractAndIdLocale($idProductAbstract, $idL

return $urlTransfer;
}

/**
* @param array<int> $productAbstractIds
* @param array<\Generated\Shared\Transfer\ProductUrlTransfer> $productUrls
*
* @return array<string, \Generated\Shared\Transfer\UrlTransfer>
*/
protected function getUrlByProductAbstractIdsAndLocaleIds(array $productAbstractIds, array $productUrls): array
{
$indexedUrlTransfers = $this->productRepository->getUrlsByProductAbstractIds(
$productAbstractIds,
fn (int $productAbstractId, int $localeId) => $this->generateIndex($productAbstractId, $localeId),
);

$urlTransfers = [];

foreach ($productAbstractIds as $productAbstractId) {
$urlTransfers = array_merge($urlTransfers, $this->processProductUrls($productAbstractId, $productUrls, $indexedUrlTransfers));
}

return $urlTransfers;
}

/**
* @param int $productAbstractId
* @param array<\Generated\Shared\Transfer\ProductUrlTransfer> $productUrls
* @param array<string, \Generated\Shared\Transfer\UrlTransfer> $indexedUrlTransfers
*
* @return array<string, \Generated\Shared\Transfer\UrlTransfer>
*/
protected function processProductUrls(int $productAbstractId, array $productUrls, array $indexedUrlTransfers): array
{
$urlTransfers = [];
foreach ($productUrls as $productUrlTransfer) {
$urlTransfers = array_merge($urlTransfers, $this->processUrls($productAbstractId, $productUrlTransfer, $indexedUrlTransfers));
}

return $urlTransfers;
}

/**
* @param int $productAbstractId
* @param \Generated\Shared\Transfer\ProductUrlTransfer $productUrlTransfer
* @param array<string, \Generated\Shared\Transfer\UrlTransfer> $indexedUrlTransfers
*
* @return array<string, \Generated\Shared\Transfer\UrlTransfer>
*/
protected function processUrls(int $productAbstractId, ProductUrlTransfer $productUrlTransfer, array $indexedUrlTransfers): array
{
$urlTransfers = [];
foreach ($productUrlTransfer->getUrls() as $url) {
$index = sprintf('%s-%s', $productAbstractId, $url->getLocale()->getIdLocale());
$urlTransfer = $indexedUrlTransfers[$index] ?? (new UrlTransfer())
->setFkResourceProductAbstract($productAbstractId)
->setFkLocale($url->getLocale()->getIdLocale());
if ($urlTransfer->getUrl() !== $url->getUrl()) {
$urlTransfer->setOriginalUrl($urlTransfer->getUrl());
}
$urlTransfer = $urlTransfer->setUrl($url->getUrl());
$urlTransfers[$url->getUrl()] = $urlTransfer;
}

return $urlTransfers;
}

/**
* @param int $productAbstractId
* @param int $localeId
*
* @return string
*/
protected function generateIndex(int $productAbstractId, int $localeId): string
{
return sprintf('%s-%s', $productAbstractId, $localeId);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,13 @@ public function createProductUrl(ProductAbstractTransfer $productAbstractTransfe
*/
public function updateProductUrl(ProductAbstractTransfer $productAbstractTransfer);

/**
* @param array<\Generated\Shared\Transfer\ProductAbstractTransfer> $productAbstractTransfers
*
* @return array<string, \Generated\Shared\Transfer\UrlTransfer>
*/
public function updateProductUrls(array $productAbstractTransfers): array;

/**
* @param \Generated\Shared\Transfer\ProductAbstractTransfer $productAbstractTransfer
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -181,6 +181,7 @@ public function createProductUrlManager()
$this->getQueryContainer(),
$this->createProductUrlGenerator(),
$this->createProductEventTrigger(),
$this->getRepository(),
);
}

Expand Down
16 changes: 16 additions & 0 deletions src/Spryker/Zed/Product/Business/ProductFacade.php
Original file line number Diff line number Diff line change
Expand Up @@ -587,6 +587,22 @@ public function updateProductUrl(ProductAbstractTransfer $productAbstractTransfe
->updateProductUrl($productAbstractTransfer);
}

/**
* {@inheritDoc}
*
* @api
*
* @param array<\Generated\Shared\Transfer\ProductAbstractTransfer> $productAbstractTransfers
*
* @return array<\Generated\Shared\Transfer\UrlTransfer>
*/
public function updateProductsUrl(array $productAbstractTransfers): array
{
return $this->getFactory()
->createProductUrlManager()
->updateProductUrls($productAbstractTransfers);
}

/**
* {@inheritDoc}
*
Expand Down
14 changes: 14 additions & 0 deletions src/Spryker/Zed/Product/Business/ProductFacadeInterface.php
Original file line number Diff line number Diff line change
Expand Up @@ -500,6 +500,20 @@ public function createProductUrl(ProductAbstractTransfer $productAbstractTransfe
*/
public function updateProductUrl(ProductAbstractTransfer $productAbstractTransfer);

/**
* Specification:
* - Updates localized abstract product URLs based on abstract products localized attributes name.
* - Executes touch logic for abstract products URL update.
* - Not following Bulk Facade methods flow due to the necessity to be as fast as possible.
*
* @api
*
* @param array<\Generated\Shared\Transfer\ProductAbstractTransfer> $productAbstractTransfers
*
* @return array<\Generated\Shared\Transfer\UrlTransfer>
*/
public function updateProductsUrl(array $productAbstractTransfers): array;

/**
* Specification:
* - Returns localized abstract product URLs for all available locales.
Expand Down
10 changes: 10 additions & 0 deletions src/Spryker/Zed/Product/Dependency/Facade/ProductToUrlBridge.php
Original file line number Diff line number Diff line change
Expand Up @@ -77,4 +77,14 @@ public function deactivateUrl(UrlTransfer $urlTransfer)
{
$this->urlFacade->deactivateUrl($urlTransfer);
}

/**
* @param array<\Generated\Shared\Transfer\UrlTransfer> $urlTransfers
*
* @return array<\Generated\Shared\Transfer\UrlTransfer>
*/
public function saveUrlCollection(array $urlTransfers): array
{
return $this->urlFacade->saveUrlCollection($urlTransfers);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -49,4 +49,11 @@ public function activateUrl(UrlTransfer $urlTransfer);
* @return void
*/
public function deactivateUrl(UrlTransfer $urlTransfer);

/**
* @param array<\Generated\Shared\Transfer\UrlTransfer> $urlTransfers
*
* @return array<\Generated\Shared\Transfer\UrlTransfer>
*/
public function saveUrlCollection(array $urlTransfers): array;
}
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
use Orm\Zed\Product\Persistence\SpyProductAttributeKeyQuery;
use Orm\Zed\Product\Persistence\SpyProductLocalizedAttributesQuery;
use Orm\Zed\Product\Persistence\SpyProductQuery;
use Orm\Zed\Url\Persistence\SpyUrlQuery;
use Spryker\Zed\Kernel\Persistence\AbstractPersistenceFactory;
use Spryker\Zed\Product\Dependency\Service\ProductToUtilEncodingInterface;
use Spryker\Zed\Product\Persistence\Mapper\LocalizedAttributesMapper;
Expand Down Expand Up @@ -128,4 +129,12 @@ public function createProductAttributeKeyMapper(): ProductAttributeKeyMapper
{
return new ProductAttributeKeyMapper();
}

/**
* @return \Orm\Zed\Url\Persistence\SpyUrlQuery
*/
public function createUrlQuery(): SpyUrlQuery
{
return SpyUrlQuery::create();
}
}
Loading

0 comments on commit f41bbdd

Please sign in to comment.