Skip to content
This repository has been archived by the owner on Jun 11, 2024. It is now read-only.

Commit

Permalink
Merge pull request #153 from afirlejczyk/feature/color-swatches
Browse files Browse the repository at this point in the history
Add support for visual swatches #15.
  • Loading branch information
afirlejczyk authored Nov 7, 2019
2 parents 8163fd9 + 0d7f299 commit 8d1ba39
Show file tree
Hide file tree
Showing 16 changed files with 250 additions and 32 deletions.
57 changes: 57 additions & 0 deletions CHANGELOG.MD
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,64 @@

## Unreleased

## [1.6.0] (2019.11.07)

### Added
- Add support for Visual Swatches. ([#15](https://github.com/DivanteLtd/magento2-vsbridge-indexer/issues/15))
Attribute options
```json
"options": [
{
"swatch": {
"type": 1,
"value": "#ffd500"
},
"value": "60",
"label": "Yellow",
"sort_order": 12
},
{
"swatch": {
"type": 3,
"value": null
},
"value": "105",
"label": "purple",
"sort_order": 13
},
{
"swatch": {
"type": 2,
"value": "/4/2/4245592.png"
},
"value": "106",
"label": "File",
"sort_order": 14
}
]
```

Product configurable option values
```json
"values": [
{
"value_index": "50",
"label": "blue defaul",
"swatch": {
"type": 1,
"value": "#1857f7"
}
},
{
"value_index": "49",
"label": "Black",
"swatch": {
"type": 1,
"value": "#000000"
}
}
]
```
- Add new command `vsbridge:index` to run indexer for one product, cms block, etc.
`bin/magento vsbridge:index vsbridge_product_indexer default 1`
vsbridge_product_indexer -> indexer code
Expand Down
4 changes: 3 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -185,7 +185,9 @@ Go to the new ‘Indexer’ section (Stores → Configuration → Vuestorefront

Sync Tier Prices → by default this option is disabled. Used to sync products tier prices.

Types of products to index → by default all product will be exported to ElasticSearch. This option allows for selecting certain product types that should be exported.
Types of products to index → by default all product will be exported to ElasticSearch. This option allows for selecting certain product types that should be exported.

Add swatches to `product.configurable_options` → by default No. Use to export information about swatches directly for a product type.

![](docs/images/config-catalog.png)

Expand Down
2 changes: 1 addition & 1 deletion composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
"name": "Agata",
"email": "[email protected]"
}],
"version": "1.5.2",
"version": "1.6.0",
"keywords": [
"magento",
"magento2",
Expand Down
Binary file modified docs/images/config-catalog.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,11 @@ public function useUrlKeyToGenerateSlug();
*/
public function syncTierPrices();

/**
* @return bool
*/
public function addSwatchesToConfigurableOptions();

/**
* @param int $storeId
*
Expand Down
18 changes: 15 additions & 3 deletions src/module-vsbridge-indexer-catalog/Index/Mapping/Attribute.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

use Divante\VsbridgeIndexerCore\Api\MappingInterface;
use Divante\VsbridgeIndexerCore\Api\Mapping\FieldInterface;
use Divante\VsbridgeIndexerCore\Index\Mapping\GeneralMapping;
use Magento\Framework\Event\ManagerInterface as EventManager;

/**
Expand All @@ -17,14 +18,23 @@ class Attribute implements MappingInterface
*/
private $eventManager;

/**
* @var GeneralMapping
*/
private $generalMapping;

/**
* Attribute constructor.
*
* @param GeneralMapping $generalMapping
* @param EventManager $eventManager
*/
public function __construct(EventManager $eventManager)
{
public function __construct(
GeneralMapping $generalMapping,
EventManager $eventManager
) {
$this->eventManager = $eventManager;
$this->generalMapping = $generalMapping;
}

/**
Expand Down Expand Up @@ -73,6 +83,7 @@ public function __construct(EventManager $eventManager)
*/
private $stringProperties = [
'attribute_code',
'swatch_input_type',
'attribute_model',
'backend_model',
'backend_table',
Expand Down Expand Up @@ -113,7 +124,8 @@ public function getMappingProperties()
'properties' => [
'value' => ['type' => FieldInterface::TYPE_TEXT],
'label' => ['type' => FieldInterface::TYPE_TEXT],
'sort_order' => ['type' => FieldInterface::TYPE_LONG],
'sort_order' => ['type' => FieldInterface::TYPE_INTEGER],
'swatch' => $this->generalMapping->getSwatchProperties(),
]
];

Expand Down
9 changes: 6 additions & 3 deletions src/module-vsbridge-indexer-catalog/Index/Mapping/Product.php
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ class Product extends AbstractMapping implements MappingInterface
* @param GeneralMapping $generalMapping
* @param ConfigurableAttributes $configurableAttributes
* @param AttributeDataProvider $resourceModel
* @param array $staticFieldMapping
*/
public function __construct(
EventManager $eventManager,
Expand Down Expand Up @@ -210,6 +211,8 @@ private function getConfigurableOptionsMapping(): array
'values' => [
'properties' => [
'value_index' => ['type' => FieldInterface::TYPE_KEYWORD],
'label' => ['type' => FieldInterface::TYPE_TEXT],
'swatch' => $this->generalMapping->getSwatchProperties(),
],
],
],
Expand Down Expand Up @@ -282,7 +285,7 @@ private function getCustomOptionsMapping(): array
'price' => ['type' => FieldInterface::TYPE_DOUBLE],
'price_type' => ['type' => FieldInterface::TYPE_TEXT],
'sku' => ['type' => FieldInterface::TYPE_KEYWORD],
'sort_order' => ['type' => FieldInterface::TYPE_LONG],
'sort_order' => ['type' => FieldInterface::TYPE_INTEGER],
'title' => ['type' => FieldInterface::TYPE_TEXT],
'type' => ['type' => FieldInterface::TYPE_TEXT],
'values' => [
Expand All @@ -291,7 +294,7 @@ private function getCustomOptionsMapping(): array
'price' => ['type' => FieldInterface::TYPE_DOUBLE],
'title' => ['type' => FieldInterface::TYPE_TEXT],
'price_type' => ['type' => FieldInterface::TYPE_TEXT],
'sort_order' => ['type' => FieldInterface::TYPE_LONG],
'sort_order' => ['type' => FieldInterface::TYPE_INTEGER],
'option_type_id' => ['type' => FieldInterface::TYPE_INTEGER],
]
]
Expand All @@ -311,7 +314,7 @@ private function getTierPricesMapping(): array
'value' => ['type' => FieldInterface::TYPE_DOUBLE],
'extension_attributes' => [
'properties' => [
'website_id' => ['type' => FieldInterface::TYPE_INTEGER]
'website_id' => ['type' => FieldInterface::TYPE_SHORT]
],
],
],
Expand Down
90 changes: 73 additions & 17 deletions src/module-vsbridge-indexer-catalog/Model/Attribute/LoadOptions.php
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,11 @@
namespace Divante\VsbridgeIndexerCatalog\Model\Attribute;

use Divante\VsbridgeIndexerCatalog\Model\ResourceModel\Product\AttributeDataProvider;
use Magento\Catalog\Model\ResourceModel\Eav\Attribute;

use Magento\Eav\Model\ResourceModel\Entity\Attribute\Option\Collection as OptionCollection;
use Magento\Eav\Model\ResourceModel\Entity\Attribute\Option\CollectionFactory;

use Magento\Eav\Model\Entity\Attribute;
use Magento\Eav\Model\Entity\Attribute\Source\AbstractSource;
use Magento\Eav\Model\Entity\Attribute\Source\Table as SourceTable;

/**
Expand Down Expand Up @@ -84,21 +85,19 @@ private function loadOptions(Attribute $attribute): array
$key = $attribute->getId() . '_' . $attribute->getStoreId();

if (!isset($this->optionsByAttribute[$key])) {
$source = $attribute->getSource();

if (SourceTable::class !== get_class($source) &&
$source instanceof \Magento\Eav\Model\Entity\Attribute\Source\AbstractSource
) {
if ($this->useSourceModel($attribute)) {
$source = $attribute->getSource();
$options = $source->getAllOptions();
} else {
$attributeId = $attribute->getAttributeId();
$storeId = $attribute->getStoreId();

/** @var OptionCollection $options */
$options = $this->collectionFactory->create();
$options->setOrder('sort_order', 'asc');
$options->setAttributeFilter($attributeId)->setStoreFilter($storeId);
$options = $this->toOptionArray($options);
$loadSwatches = $this->isVisualSwatch($attribute);
$optionCollection = $this->getOptionCollection($attribute, $loadSwatches);
$additionalFields = [];

if ($loadSwatches) {
$additionalFields['swatch'] = 'swatch';
}

$options = $this->toOptionArray($optionCollection, $additionalFields);
}

$this->optionsByAttribute[$key] = $options;
Expand All @@ -107,13 +106,70 @@ private function loadOptions(Attribute $attribute): array
return $this->optionsByAttribute[$key];
}

/**
* @param Attribute $attribute
*
* @return bool
*/
private function useSourceModel(Attribute $attribute)
{
$source = $attribute->getSource();

if ($source instanceof AbstractSource && !($source instanceof SourceTable)) {
return true;
}

return false;
}

/**
* @param Attribute $attribute
*
* @return OptionCollection
*/
private function getOptionCollection(Attribute $attribute, $loadSwatches)
{
$attributeId = $attribute->getAttributeId();
$storeId = $attribute->getStoreId();

/** @var OptionCollection $options */
$options = $this->collectionFactory->create();
$options->setOrder('sort_order', 'asc');
$options->setAttributeFilter($attributeId)
->setStoreFilter($storeId);

if ($loadSwatches) {
$options->getSelect()->joinLeft(
['swatch_table' => $options->getTable('eav_attribute_option_swatch')],
'swatch_table.option_id = main_table.option_id AND swatch_table.store_id = 0',
[
'swatch_value' => 'value',
'swatch_type' => 'type',
]
);
}

return $options;
}

/**
* @param Attribute $attribute
*
* @return bool
*/
private function isVisualSwatch(Attribute $attribute)
{
return \Magento\Swatches\Model\Swatch::SWATCH_INPUT_TYPE_VISUAL === $attribute->getData('swatch_input_type');
}

/**
* @param OptionCollection $collection
* @param array $additional
*
* @return array
*/
private function toOptionArray(OptionCollection $collection): array
private function toOptionArray(OptionCollection $collection, array $additional): array
{
return $this->optionCollectionToArray->execute($collection);
return $this->optionCollectionToArray->execute($collection, $additional);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@
*/
class OptionCollectionToArray
{

/**
* @param OptionCollection $collection
* @param array $additional
Expand Down Expand Up @@ -46,6 +45,13 @@ public function execute(OptionCollection $collection, array $additional = []): a
$value = (string)$value;
}

if ('swatch' === $field) {
$value = [
'type' => (int)$item->getData('swatch_type'),
'value' => $item->getData('swatch_value')
];
}

$data[$code] = $value;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,18 @@

use Divante\VsbridgeIndexerCatalog\Model\Attribute\LoadOptionById;
use Divante\VsbridgeIndexerCatalog\Model\Attribute\SortValues;
use Divante\VsbridgeIndexerCatalog\Api\Data\CatalogConfigurationInterface;

/**
* Class GetConfigurableOptions
*/
class GetConfigurableOptions
{
/**
* @var CatalogConfigurationInterface
*/
private $catalogSettings;

/**
* @var LoadOptionById
*/
Expand All @@ -28,13 +34,17 @@ class GetConfigurableOptions

/**
* GetConfigurableOptions constructor.
*
* @param LoadOptionById $loadOptions
* @param LoadOptionById $loadOptionById
* @param SortValues $sortValues
* @param CatalogConfigurationInterface $catalogSettings
*/
public function __construct(LoadOptionById $loadOptions, SortValues $sortValues)
{
$this->loadOptionById = $loadOptions;
public function __construct(
LoadOptionById $loadOptionById,
SortValues $sortValues,
CatalogConfigurationInterface $catalogSettings
) {
$this->loadOptionById = $loadOptionById;
$this->catalogSettings = $catalogSettings;
$this->sortValues = $sortValues;
}

Expand Down Expand Up @@ -66,6 +76,10 @@ public function execute(string $attributeCode, int $storeId, array $configurable
$option = $this->loadOptionById->execute($attributeCode, $value, $storeId);

if (!empty($option)) {
if (!$this->catalogSettings->addSwatchesToConfigurableOptions()) {
unset($option['swatch']);
}

$options[] = $option;
}
}
Expand Down
Loading

0 comments on commit 8d1ba39

Please sign in to comment.