Skip to content

Commit

Permalink
Merge pull request #53 from psihius/master
Browse files Browse the repository at this point in the history
Out Of Memory for for attribute filters
  • Loading branch information
bitbager committed May 20, 2019
2 parents b8802d8 + 68d5432 commit 511ebff
Show file tree
Hide file tree
Showing 6 changed files with 100 additions and 4 deletions.
43 changes: 43 additions & 0 deletions src/EntityRepository/ProductAttributeRepository.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
<?php

declare(strict_types = 1);

namespace BitBag\SyliusElasticsearchPlugin\EntityRepository;

use Doctrine\ORM\QueryBuilder;
use Sylius\Bundle\ProductBundle\Doctrine\ORM\ProductAttributeValueRepository as BaseRepository;
use Sylius\Component\Attribute\Model\AttributeInterface;
use Sylius\Component\Product\Model\ProductAttributeValueInterface;

class ProductAttributeRepository implements ProductAttributeValueRepositoryInterface
{

/**
* @var BaseRepository
*/
protected $repository;

public function __construct(BaseRepository $repository)
{
$this->repository = $repository;
}

/**
* @param AttributeInterface $productAttribute
*
* @return array|ProductAttributeValueInterface[]
*/
public function getUniqueAttributeValues(AttributeInterface $productAttribute): array
{
/** @var QueryBuilder $queryBuilder */
$queryBuilder = $this->repository->createQueryBuilder('o');

return $queryBuilder
->where('o.attribute = :attribute')
->groupBy('o.'.$productAttribute->getStorageType())
->setParameter(':attribute', $productAttribute)
->getQuery()
->getResult();
}

}
19 changes: 19 additions & 0 deletions src/EntityRepository/ProductAttributeValueRepositoryInterface.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
<?php

declare(strict_types = 1);

namespace BitBag\SyliusElasticsearchPlugin\EntityRepository;

use Sylius\Component\Attribute\Model\AttributeInterface;
use Sylius\Component\Product\Model\ProductAttributeValueInterface;

interface ProductAttributeValueRepositoryInterface
{

/**
* @param AttributeInterface $productAttribute
*
* @return array|ProductAttributeValueInterface[]
*/
public function getUniqueAttributeValues(AttributeInterface $productAttribute): array;
}
24 changes: 22 additions & 2 deletions src/Form/Type/ChoiceMapper/ProductAttributesMapper.php
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,11 @@

namespace BitBag\SyliusElasticsearchPlugin\Form\Type\ChoiceMapper;

use BitBag\SyliusElasticsearchPlugin\EntityRepository\ProductAttributeValueRepositoryInterface;
use BitBag\SyliusElasticsearchPlugin\Formatter\StringFormatterInterface;
use Sylius\Component\Locale\Context\LocaleContextInterface;
use Sylius\Component\Product\Model\ProductAttributeInterface;
use Sylius\Component\Product\Model\ProductAttributeValueInterface;
use Sylius\Component\Product\Repository\ProductAttributeValueRepositoryInterface;

final class ProductAttributesMapper implements ProductAttributesMapperInterface
{
Expand All @@ -41,12 +41,31 @@ public function __construct(

public function mapToChoices(ProductAttributeInterface $productAttribute): array
{
$attributeValues = $this->productAttributeValueRepository->findBy(['attribute' => $productAttribute]);
$configuration = $productAttribute->getConfiguration();

/**
* If we have choices configured, no need to query and group by product attribute values -
* they are predefined by the choices array
*/
if (isset($configuration['choices']) && is_array($configuration['choices'])
) {
$choices = [];
foreach ($configuration['choices'] as $singleValue => $val) {
$choice = $this->stringFormatter->formatToLowercaseWithoutSpaces($singleValue);
$label = $configuration['choices'][$singleValue][$this->localeContext->getLocaleCode()];
$choices[$label] = $choice;
}
return $choices;
}

$attributeValues = $this->productAttributeValueRepository->getUniqueAttributeValues($productAttribute);

$choices = [];
array_walk($attributeValues, function (ProductAttributeValueInterface $productAttributeValue) use (&$choices): void {
$product = $productAttributeValue->getProduct();

if (!$product->isEnabled()) {
unset($product);
return;
}

Expand All @@ -67,6 +86,7 @@ public function mapToChoices(ProductAttributeInterface $productAttribute): array
$choices[$value] = $choice;
}
});
unset($attributeValues);

return $choices;
}
Expand Down
11 changes: 10 additions & 1 deletion src/Form/Type/ProductAttributesFilterType.php
Original file line number Diff line number Diff line change
Expand Up @@ -29,19 +29,28 @@ final class ProductAttributesFilterType extends AbstractFilterType
/** @var ProductAttributesMapperInterface */
private $productAttributesMapper;

/** @var array */
protected $excludedAttributes;

public function __construct(
ProductAttributesContextInterface $productAttributesContext,
ConcatedNameResolverInterface $attributeNameResolver,
ProductAttributesMapperInterface $productAttributesMapper
ProductAttributesMapperInterface $productAttributesMapper,
array $excludedAttributes
) {
$this->productAttributesContext = $productAttributesContext;
$this->attributeNameResolver = $attributeNameResolver;
$this->productAttributesMapper = $productAttributesMapper;
$this->excludedAttributes = $excludedAttributes;
}

public function buildForm(FormBuilderInterface $builder, array $attributes): void
{
foreach ($this->productAttributesContext->getAttributes() as $productAttribute) {
if (in_array($productAttribute->getCode(), $this->excludedAttributes)) {
continue;
}

$name = $this->attributeNameResolver->resolvePropertyName($productAttribute->getCode());
$choices = $this->productAttributesMapper->mapToChoices($productAttribute);

Expand Down
4 changes: 4 additions & 0 deletions src/Resources/config/services.xml
Original file line number Diff line number Diff line change
Expand Up @@ -22,5 +22,9 @@
<argument>%sylius.model.product_taxon.class%</argument>
<argument>%sylius.model.product_attribute_value.class%</argument>
</service>

<service id="bitbag.sylius_elasticsearch_plugin.entity_repository.product_attribute_value_repository" class="BitBag\SyliusElasticsearchPlugin\EntityRepository\ProductAttributeRepository">
<argument type="service" id="sylius.repository.product_attribute_value" />
</service>
</services>
</container>
3 changes: 2 additions & 1 deletion src/Resources/config/services/form.xml
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
<argument type="service" id="bitbag.sylius_elasticsearch_plugin.context.product_attributes" />
<argument type="service" id="bitbag_sylius_elasticsearch_plugin.property_name_resolver.attribute" />
<argument type="service" id="bitbag_sylius_elasticsearch_plugin.form.type.choice_mapper.product_attributes" />
<argument>%bitbag_es_excluded_filter_attributes%</argument>

<tag name="form.type" />
</service>
Expand All @@ -40,7 +41,7 @@
</service>

<service id="bitbag_sylius_elasticsearch_plugin.form.type.choice_mapper.product_attributes" class="BitBag\SyliusElasticsearchPlugin\Form\Type\ChoiceMapper\ProductAttributesMapper">
<argument type="service" id="sylius.repository.product_attribute_value" />
<argument type="service" id="bitbag.sylius_elasticsearch_plugin.entity_repository.product_attribute_value_repository" />
<argument type="service" id="sylius.context.locale" />
<argument type="service" id="bitbag.sylius_elasticsearch_plugin.string_formatter" />
</service>
Expand Down

0 comments on commit 511ebff

Please sign in to comment.