Skip to content

Commit

Permalink
✨ product image group url validation (#210)
Browse files Browse the repository at this point in the history
  • Loading branch information
julianzimmermann committed Jan 30, 2024
1 parent c59a8e1 commit 1a2cf32
Show file tree
Hide file tree
Showing 12 changed files with 520 additions and 190 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
<?php

namespace FondOfImpala\Zed\ProductImageGroupingProductPageSearch\Business\Expander;

use FondOfImpala\Zed\ProductImageGroupingProductPageSearch\Business\Validator\UrlValidatorInterface;
use Generated\Shared\Transfer\ProductPageSearchTransfer;
use Spryker\Shared\ProductPageSearch\ProductPageSearchConfig;

class ProductImageGroupPageDataExpander implements ProductPageDataExpanderInterface
{
/**
* @var string
*/
protected const IMAGE_GROUP_NAME_EMPTY = '*';

/**
* @var string
*/
protected const EXTERNAL_URL_PREFIX = 'external_url';

protected UrlValidatorInterface $urlValidator;

/**
* @param \FondOfImpala\Zed\ProductImageGroupingProductPageSearch\Business\Validator\UrlValidatorInterface $urlValidator
*/
public function __construct(UrlValidatorInterface $urlValidator)
{
$this->urlValidator = $urlValidator;
}

/**
* {@inheritDoc}
*
* @api
*
* @param array<string, mixed> $productData
* @param \Generated\Shared\Transfer\ProductPageSearchTransfer $productAbstractPageSearchTransfer
*
* @return \Generated\Shared\Transfer\ProductPageSearchTransfer
*/
public function expandProductPageData(array $productData, ProductPageSearchTransfer $productAbstractPageSearchTransfer): ProductPageSearchTransfer
{
/** @var \Generated\Shared\Transfer\ProductPayloadTransfer $productPayloadTransfer */
$productPayloadTransfer = $productData[ProductPageSearchConfig::PRODUCT_ABSTRACT_PAGE_LOAD_DATA];
$imageSets = $productPayloadTransfer->getImages();
/** @var array<\Orm\Zed\ProductImage\Persistence\SpyProductImageSet> $imageSetsByLocale */
$imageSetsByLocale = $imageSets[$productData['fk_locale']] ?? [];

$productImages = $productAbstractPageSearchTransfer->getProductImages();

$regrouped = [];

foreach ($imageSetsByLocale as $imageSet) {
foreach ($productImages as $productImage) {
if ($productImage['fk_product_image_set'] === $imageSet->getIdProductImageSet()) {
$key = $imageSet->getName();
$regrouped[$key === null || $key === '' ? static::IMAGE_GROUP_NAME_EMPTY : $key][] = $this->validateProductImageUrls($productImage);
}
}
}

return $productAbstractPageSearchTransfer->setGroupedProductImages($regrouped);
}

/**
* @param array $productImage
*
* @return array
*/
protected function validateProductImageUrls(array $productImage): array
{
foreach ($productImage as $key => $data) {
if ($data !== null && str_starts_with($key, static::EXTERNAL_URL_PREFIX)) {
$productImage[$key] = $this->urlValidator->isValid($data) ? $data : null;
}
}

return $productImage;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
<?php

namespace FondOfImpala\Zed\ProductImageGroupingProductPageSearch\Business\Expander;

use Generated\Shared\Transfer\ProductPageSearchTransfer;

interface ProductPageDataExpanderInterface
{
/**
* {@inheritDoc}
*
* @api
*
* @param array<string, mixed> $productData
* @param \Generated\Shared\Transfer\ProductPageSearchTransfer $productAbstractPageSearchTransfer
*
* @return \Generated\Shared\Transfer\ProductPageSearchTransfer
*/
public function expandProductPageData(array $productData, ProductPageSearchTransfer $productAbstractPageSearchTransfer): ProductPageSearchTransfer;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
<?php

namespace FondOfImpala\Zed\ProductImageGroupingProductPageSearch\Business;

use FondOfImpala\Zed\ProductImageGroupingProductPageSearch\Business\Expander\ProductImageGroupPageDataExpander;
use FondOfImpala\Zed\ProductImageGroupingProductPageSearch\Business\Expander\ProductPageDataExpanderInterface;
use FondOfImpala\Zed\ProductImageGroupingProductPageSearch\Business\Validator\UrlValidator;
use FondOfImpala\Zed\ProductImageGroupingProductPageSearch\Business\Validator\UrlValidatorInterface;
use Spryker\Zed\Kernel\Business\AbstractBusinessFactory;

class ProductImageGroupingProductPageSearchBusinessFactory extends AbstractBusinessFactory
{
/**
* @return \FondOfImpala\Zed\ProductImageGroupingProductPageSearch\Business\Expander\ProductPageDataExpanderInterface
*/
public function createProductImageGroupPageDataExpander(): ProductPageDataExpanderInterface
{
return new ProductImageGroupPageDataExpander($this->createUrlValidator());
}

/**
* @return \FondOfImpala\Zed\ProductImageGroupingProductPageSearch\Business\Validator\UrlValidatorInterface
*/
public function createUrlValidator(): UrlValidatorInterface
{
return new UrlValidator();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
<?php

namespace FondOfImpala\Zed\ProductImageGroupingProductPageSearch\Business;

use Generated\Shared\Transfer\ProductPageSearchTransfer;
use Spryker\Zed\Kernel\Business\AbstractFacade;

/**
* @method \FondOfImpala\Zed\ProductImageGroupingProductPageSearch\Business\ProductImageGroupingProductPageSearchBusinessFactory getFactory()
*/
class ProductImageGroupingProductPageSearchFacade extends AbstractFacade implements ProductImageGroupingProductPageSearchFacadeInterface
{
/**
* {@inheritDoc}
*
* @api
*
* @param array<string, mixed> $productData
* @param \Generated\Shared\Transfer\ProductPageSearchTransfer $productAbstractPageSearchTransfer
*
* @return \Generated\Shared\Transfer\ProductPageSearchTransfer
*/
public function groupProductImageData(array $productData, ProductPageSearchTransfer $productAbstractPageSearchTransfer): ProductPageSearchTransfer
{
return $this->getFactory()->createProductImageGroupPageDataExpander()->expandProductPageData($productData, $productAbstractPageSearchTransfer);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
<?php

namespace FondOfImpala\Zed\ProductImageGroupingProductPageSearch\Business;

use Generated\Shared\Transfer\ProductPageSearchTransfer;

interface ProductImageGroupingProductPageSearchFacadeInterface
{
/**
* {@inheritDoc}
*
* @api
*
* @param array<string, mixed> $productData
* @param \Generated\Shared\Transfer\ProductPageSearchTransfer $productAbstractPageSearchTransfer
*
* @return \Generated\Shared\Transfer\ProductPageSearchTransfer
*/
public function groupProductImageData(array $productData, ProductPageSearchTransfer $productAbstractPageSearchTransfer): ProductPageSearchTransfer;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
<?php

namespace FondOfImpala\Zed\ProductImageGroupingProductPageSearch\Business\Validator;

class UrlValidator implements UrlValidatorInterface
{
/**
* @var string
*/
protected const PROTOCOL = '@^http|https://@i';

/**
* @param string $url
*
* @return bool
*/
public function isValid(string $url): bool
{
return (preg_match(static::PROTOCOL, $url)) && (filter_var($url, FILTER_VALIDATE_URL) !== false);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
<?php

namespace FondOfImpala\Zed\ProductImageGroupingProductPageSearch\Business\Validator;

interface UrlValidatorInterface
{
/**
* @param string $url
*
* @return bool
*/
public function isValid(string $url): bool;
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,6 @@
use Spryker\Zed\ProductPageSearchExtension\Dependency\PageMapBuilderInterface;
use Spryker\Zed\ProductPageSearchExtension\Dependency\Plugin\ProductAbstractMapExpanderPluginInterface;

/**
* @method \Spryker\Zed\ProductPageSearch\Persistence\ProductPageSearchQueryContainerInterface getQueryContainer()
* @method \Spryker\Zed\ProductPageSearch\Communication\ProductPageSearchCommunicationFactory getFactory()
* @method \Spryker\Zed\ProductPageSearch\Business\ProductPageSearchFacadeInterface getFacade()
* @method \Spryker\Zed\ProductPageSearch\ProductPageSearchConfig getConfig()
*/
class ProductImageGroupMapExpanderPlugin extends AbstractPlugin implements ProductAbstractMapExpanderPluginInterface
{
/**
Expand Down Expand Up @@ -43,7 +37,7 @@ public function expandProductMap(
PageMapBuilderInterface $pageMapBuilder,
array $productData,
LocaleTransfer $localeTransfer
) {
): PageMapTransfer {
$pageMapBuilder->addSearchResultData($pageMapTransfer, static::KEY, $productData[static::VALUE]);

return $pageMapTransfer;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,23 +3,14 @@
namespace FondOfImpala\Zed\ProductImageGroupingProductPageSearch\Communication\Plugin\ProductPageSearch;

use Generated\Shared\Transfer\ProductPageSearchTransfer;
use Spryker\Shared\ProductPageSearch\ProductPageSearchConfig;
use Spryker\Zed\Kernel\Communication\AbstractPlugin;
use Spryker\Zed\ProductPageSearchExtension\Dependency\Plugin\ProductPageDataExpanderPluginInterface;

/**
* @method \Spryker\Zed\ProductPageSearch\Persistence\ProductPageSearchQueryContainerInterface getQueryContainer()
* @method \Spryker\Zed\ProductPageSearch\Communication\ProductPageSearchCommunicationFactory getFactory()
* @method \Spryker\Zed\ProductPageSearch\Business\ProductPageSearchFacadeInterface getFacade()
* @method \Spryker\Zed\ProductPageSearch\ProductPageSearchConfig getConfig()
* @method \FondOfImpala\Zed\ProductImageGroupingProductPageSearch\Business\ProductImageGroupingProductPageSearchFacadeInterface getFacade()
*/
class ProductImageGroupedPageDataLoaderExpanderPlugin extends AbstractPlugin implements ProductPageDataExpanderPluginInterface
{
/**
* @var string
*/
protected const IMAGE_GROUP_NAME_EMPTY = '*';

/**
* {@inheritDoc}
*
Expand All @@ -32,26 +23,6 @@ class ProductImageGroupedPageDataLoaderExpanderPlugin extends AbstractPlugin imp
*/
public function expandProductPageData(array $productData, ProductPageSearchTransfer $productAbstractPageSearchTransfer)
{
/** @var \Generated\Shared\Transfer\ProductPayloadTransfer $productPayloadTransfer */
$productPayloadTransfer = $productData[ProductPageSearchConfig::PRODUCT_ABSTRACT_PAGE_LOAD_DATA];
$imageSets = $productPayloadTransfer->getImages();
/** @var array<\Orm\Zed\ProductImage\Persistence\SpyProductImageSet> $imageSetsByLocale */
$imageSetsByLocale = $imageSets[$productData['fk_locale']] ?? [];

$productImages = $productAbstractPageSearchTransfer->getProductImages();

$regrouped = [];

foreach ($imageSetsByLocale as $imageSet) {
foreach ($productImages as $productImage) {
if ($productImage['fk_product_image_set'] === $imageSet->getIdProductImageSet()) {
$key = $imageSet->getName();

$regrouped[$key === null || $key === '' ? static::IMAGE_GROUP_NAME_EMPTY : $key][] = $productImage;
}
}
}

$productAbstractPageSearchTransfer->setGroupedProductImages($regrouped);
$this->getFacade()->groupProductImageData($productData, $productAbstractPageSearchTransfer);
}
}

0 comments on commit 1a2cf32

Please sign in to comment.