Skip to content

Commit

Permalink
Merge pull request #26 from AleksandrsKondratjevs/performance-improve…
Browse files Browse the repository at this point in the history
…ments

Performance improvements
  • Loading branch information
carinadues authored Dec 9, 2021
2 parents e0d350a + 48ca2b9 commit 60ce18f
Show file tree
Hide file tree
Showing 5 changed files with 60 additions and 73 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,8 @@

namespace ScandiPWA\Performance\Model\Resolver\Products\CollectionPostProcessor;

use GraphQL\Language\AST\FieldNode;
use Magento\Catalog\Model\ResourceModel\Product\Collection;
use Magento\Framework\Exception\LocalizedException;
use Magento\Framework\GraphQl\Schema\Type\ResolveInfo;
use ScandiPWA\Performance\Api\ProductsCollectionPostProcessorInterface;
use ScandiPWA\Performance\Model\Resolver\ResolveInfoFieldsTrait;

class Options implements ProductsCollectionPostProcessorInterface
{
Expand Down
122 changes: 57 additions & 65 deletions src/Model/Resolver/Products/DataPostProcessor/Attributes.php
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,9 @@
use Magento\Catalog\Model\Product;
use Magento\Catalog\Model\ResourceModel\Eav\Attribute;
use Magento\Framework\Api\ExtensibleDataInterface;
use Magento\Framework\Api\Search\SearchCriteriaInterface;
use Magento\Framework\Api\SearchCriteriaBuilder;
use Magento\Framework\Exception\LocalizedException;
use ScandiPWA\Performance\Model\ResourceModel\Product\CollectionFactory;
use Magento\Framework\GraphQl\Schema\Type\ResolveInfo;
use Magento\Swatches\Helper\Data;
use ScandiPWA\Performance\Api\ProductsDataPostProcessorInterface;
use ScandiPWA\Performance\Model\Resolver\ResolveInfoFieldsTrait;
Expand Down Expand Up @@ -172,7 +170,7 @@ protected function appendWithGroup(
// Find the correct group for every attribute
/** @var AttributeGroupInterface $group */
foreach ($groupCollection as $group) {
if ($attributeGroupId === $group->getAttributeGroupId()) {
if ($attributeGroupId === $group->getAttributeGroupId()) {
$attributeDataBySetId[$attributeSetId][$attributeCode]['attribute_group_name'] = $group->getAttributeGroupName();
$attributeDataBySetId[$attributeSetId][$attributeCode]['attribute_group_id'] = $group->getAttributeGroupId();
$attributeDataBySetId[$attributeSetId][$attributeCode]['attribute_group_code'] = $group->getAttributeGroupCode();
Expand All @@ -190,60 +188,59 @@ protected function appendWithGroup(
* @param $attributes ProductAttributeInterface[]
* @param $products ExtensibleDataInterface[]
* @param $productAttributes array
* @param $swatchAttributes array
*/
protected function appendWithOptions(
array $attributes,
array $products,
array $swatchAttributes,
array &$productAttributes
): void {
$attributeCodes = array_keys($attributes);
$searchCriteria = $this->searchCriteriaBuilder
->addFilter('main_table.attribute_code', $attributeCodes, 'in')
->create();

/** @var SearchCriteriaInterface $searchCriteria */
$attributeRepository = $this->attributeRepository->getList($searchCriteria);
$detailedAttributes = $attributeRepository->getItems();

// To collect ids of options, to later load swatch data
$optionIds = [];
$formattedAttributes = [];
$swatchAttributes = [];

// Loop again, get options sorted in the right places
/** @var Product $product */
foreach ($products as $product) {
$id = $product->getId();
// Format attribute to use them later
foreach ($attributes as $attributeCode => $attribute) {
$options = $attribute->getOptions();

$configuration = $product->getTypeId() === 'configurable'
? $product->getTypeInstance()->getConfigurableOptions($product)
: [];
if (!$options) {
continue;
}

foreach ($detailedAttributes as $attribute) {
$key = $attribute->getAttributeCode();
// Remove first option from array since it is empty
array_shift($options);

if (!isset($productAttributes[$id][$key])) {
continue;
}
$formattedAttributes[$attributeCode] = [
'attribute_id' => $attribute->getAttributeId(),
'attribute_options' => $options
];
}

$productAttributes[$id][$key]['attribute_options'] = [];
$variantAttributeValues = [];
foreach ($formattedAttributes as $attributeCode => $attribute) {
$attributeId = $attribute['attribute_id'];

if ($product->getTypeId() === 'configurable') {
$attributeId = $attribute->getAttributeId();
$productAttributeVariants = $configuration[$attributeId] ?? [];
foreach ($products as $product) {
$productId = $product->getId();
$configuration = $product->getTypeId() === 'configurable' ?
$product->getTypeInstance()->getConfigurableOptions($product)
: [];

$variantAttributeValues = array_filter(
array_column($productAttributeVariants, 'value_index')
);
if (!isset($productAttributes[$productId][$attributeCode])) {
continue;
}

$productAttributeVariants = $configuration[$attributeId] ?? [];

$variantAttributeValues = array_filter(
array_column($productAttributeVariants, 'value_index')
);

if (
!isset($productAttributes[$id][$key]['attribute_value'])
!isset($productAttributes[$productId][$attributeCode]['attribute_value'])
&& !count($variantAttributeValues)
) {
// Remove attribute if it has no value and empty options
unset($productAttributes[$id][$key]);
unset($productAttributes[$productId][$attributeCode]);
continue;
}

Expand All @@ -253,38 +250,43 @@ protected function appendWithOptions(
$values = array_flip( // Flip Array
array_merge( // phpcs:ignore
array_filter( // explode might return array with empty value, remove such values
explode(',', $productAttributes[$id][$key]['attribute_value'] ?? '')
explode(',', $productAttributes[$productId][$attributeCode]['attribute_value'] ?? '')
),
$variantAttributeValues
)
);

$options = $attribute->getOptions();
array_shift($options);
$productAttributes[$id][$key]['attribute_options'] = [];
$productAttributes[$productId][$attributeCode]['attribute_options'] = [];

foreach ($options as $option) {
foreach ($attribute['attribute_options'] as $option) {
$value = $option->getValue();

if (!isset($values[$value])) {
continue;
}

$optionIds[] = $value;
$productAttributes[$id][$key]['attribute_options'][$value] = [
$productAttributes[$productId][$attributeCode]['attribute_options'][$value] = [
'value' => $value,
'label' => $option->getLabel()
];
}
}
}

foreach ($attributes as $attributeCode => $attribute) {
// Collect all swatches (we will need additional data for them)
if ($this->swatchHelper->isSwatchAttribute($attribute)) {
$swatchAttributes[] = $attributeCode;
}
}

if (!empty($swatchAttributes)) {
$this->appendWithSwatchOptions(
$swatchAttributes,
$optionIds,
$products,
$detailedAttributes,
$formattedAttributes,
$productAttributes
);
}
Expand All @@ -294,35 +296,35 @@ protected function appendWithOptions(
* @param array $swatchAttributes
* @param array $optionIds
* @param array $products
* @param array $detailedAttributes
* @param array $formattedAttributes
* @param array $productAttributes
*/
protected function appendWithSwatchOptions(
array $swatchAttributes,
array $optionIds,
array $products,
array $detailedAttributes,
&$productAttributes
array $formattedAttributes,
array &$productAttributes
) {
array_unique($optionIds);
$swatchOptions = $this->swatchHelper->getSwatchesByOptionsId($optionIds);

if (empty($swatchOptions)) {
return;
}

/** @var Product $product */
foreach ($products as $product) {
$id = $product->getId();

foreach ($detailedAttributes as $attribute) {
$key = $attribute->getAttributeCode();

if (in_array($key, $swatchAttributes)) {
$options = $attribute->getOptions();

foreach ($options as $option) {
foreach ($formattedAttributes as $attributeCode => $attribute) {
if (in_array($attributeCode, $swatchAttributes)) {
foreach ($attribute['attribute_options'] as $option) {
$value = $option->getValue();

if (isset($swatchOptions[$value])
&& isset($productAttributes[$id][$key]['attribute_options'][$value])) {
$productAttributes[$id][$key]['attribute_options'][$value]['swatch_data']
&& isset($productAttributes[$id][$attributeCode]['attribute_options'][$value])) {
$productAttributes[$id][$attributeCode]['attribute_options'][$value]['swatch_data']
= $swatchOptions[$value];
}
}
Expand Down Expand Up @@ -369,7 +371,6 @@ public function process(
$productIds = [];
$productAttributes = [];
$attributes = [];
$swatchAttributes = [];

$isSingleProduct = isset($processorOptions['isSingleProduct']) ? $processorOptions['isSingleProduct'] : false;
$isCompare = isset($processorOptions['isCompare']) ? $processorOptions['isCompare'] : false;
Expand Down Expand Up @@ -417,18 +418,10 @@ public function process(
// Collect valid attributes
if (!isset($attributes[$attributeCode])) {
$attributes[$attributeCode] = $attribute;

}
}
}

foreach ($attributes as $attributeCode => $attribute) {
// Collect all swatches (we will need additional data for them)
if ($isCollectOptions && $this->swatchHelper->isSwatchAttribute($attribute)) {
$swatchAttributes[] = $attributeCode;
}
}

$this->appendWithGroup(
$attributes,
array_keys($attributesBySetId),
Expand Down Expand Up @@ -462,7 +455,6 @@ public function process(
$this->appendWithOptions(
$attributes,
$products,
$swatchAttributes,
$productAttributes
);
}
Expand Down
1 change: 0 additions & 1 deletion src/Model/Resolver/Products/DataPostProcessor/Stocks.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@
use Magento\CatalogInventory\Model\Configuration;
use Magento\Framework\Api\SearchCriteriaBuilder;
use Magento\Framework\App\Config\ScopeConfigInterface;
use Magento\Framework\GraphQl\Schema\Type\ResolveInfo;
use Magento\InventoryApi\Api\Data\SourceItemInterface;
use Magento\InventoryApi\Api\SourceItemRepositoryInterface;
use Magento\Store\Model\ScopeInterface;
Expand Down
2 changes: 1 addition & 1 deletion src/Model/ResourceModel/Product/Collection.php
Original file line number Diff line number Diff line change
Expand Up @@ -99,4 +99,4 @@ protected function addAttributeOrAttributeEntityToSelect($attribute, $joinType =

return $this;
}
}
}
4 changes: 2 additions & 2 deletions src/etc/di.xml
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,6 @@
</arguments>
</type>
<preference
for="Magento\InventoryCatalog\Plugin\CatalogInventory\Model\ResourceModel\Stock\Status\AdaptAddIsInStockFilterToCollectionPlugin"
type="ScandiPWA\Performance\Plugin\CatalogInventory\Model\ResourceModel\Stock\Status\AdaptAddIsInStockFilterToCollectionPlugin"/>
for="Magento\InventoryCatalog\Plugin\CatalogInventory\Model\ResourceModel\Stock\Status\AdaptAddIsInStockFilterToCollectionPlugin"
type="ScandiPWA\Performance\Plugin\CatalogInventory\Model\ResourceModel\Stock\Status\AdaptAddIsInStockFilterToCollectionPlugin"/>
</config>

0 comments on commit 60ce18f

Please sign in to comment.