diff --git a/Plugin/CheckWebsiteAssociation.php b/Plugin/CheckWebsiteAssociation.php new file mode 100644 index 0000000..5bbbf00 --- /dev/null +++ b/Plugin/CheckWebsiteAssociation.php @@ -0,0 +1,135 @@ +entitiesHelper = $entitiesHelper; + $this->storeHelper = $storeHelper; + $this->config = $config; + $this->configHelper = $configHelper; + $this->authenticator = $authenticator; + $this->searchBuilderFactory = $searchBuilderFactory; + $this->serializer = $serializer; + } + + public function beforeSetWebsites(product $subject) + { + $connection = $this->entitiesHelper->getConnection(); + /** @var string $tmpTable */ + $tmpTable = $this->entitiesHelper->getTableName($subject->getCode()); + $websiteAttribute = $this->configHelper->getWebsiteAttribute(); + $websites = $this->storeHelper->getStores('website_code'); + $websiteAssociation = $this->config->getValue('akeneo_connector/product/website_attribute'); + + $requiredAttributes = $this->getRequiredAttributes(); + + if ($connection->tableColumnExists($tmpTable, $websiteAttribute)) { + /** @var Select $select */ + $select = $connection->select()->from( + $tmpTable + ); + /** @var Mysql $query */ + $query = $connection->query($select); + /** @var array $row */ + while (($row = $query->fetch())) { + + if(!isset($row[$websiteAssociation])) { + continue; + } + + $websites = explode(',', $row[$websiteAssociation]); + $mapping = $this->getMappedWebsiteChannels(); + + foreach ($websites as $key => $website) { + $channel = $mapping[$website] ?? ''; + if (empty($channel)) { + continue; + } + + $locales = $this->storeHelper->getChannelStoreLangs($channel); + foreach ($requiredAttributes as $attribute) { + if (isset($attribute['localizable']) && $attribute['localizable'] === true) { + foreach ($locales as $locale) { + if (empty($row[$attribute['akeneo_attribute'] . '-' . $locale . '-' . $channel])) { + unset($websites[$key]); + break(2); + } + } + } else { + if (empty($row[$attribute])) { + unset($websites[$key]); + break(2); + } + } + } + } + + $connection->update( + $tmpTable, + [ + $websiteAssociation => implode(',', $websites), + ], + ['identifier = ?' => $row['identifier']] + ); + } + } + return [$subject]; + } + + public function getMappedWebsiteChannels() + { + /** @var mixed[] $mapping */ + $mapping = $this->configHelper->getWebsiteMapping(); + /** @var string[] $channels */ + $channels = array_column($mapping, 'channel', 'website'); + + return $channels; + } + + public function getRequiredAttributes() + { + if (!($requiredAttributes = $this->config->getValue('akeneo_connector/product/required_attribute_mapping'))) { + return []; + } + $requiredAttributes = $this->serializer->unserialize($requiredAttributes); + + foreach ($requiredAttributes as $key => &$requiredAttribute) { + $akeneoAttribute = $this->authenticator->getAkeneoApiClient()->getAttributeApi()->get($requiredAttribute['akeneo_attribute']); + $requiredAttribute['localizable'] = $akeneoAttribute['localizable']; + } + + return $requiredAttributes; + } +} diff --git a/README.md b/README.md index 8bf0d99..49b09ad 100644 --- a/README.md +++ b/README.md @@ -23,6 +23,7 @@ These features can be enabled / disabled via an extra configuration section call | Enable retrieving metric units | Sets Akeneo's metric unit in the eav_attribute - See configuration | | Channel for metric conversions | What channel to use for metric conversions | | Set families to not visible individually after importing | Sets products in selected families to `Not Visible Individually` | +| Unset Website when empty Product Attribute Mapping | When enabled this will unset the website from the product when a required attribute has no specific value. For example when the Name attribute in Akeneo is empty for the associated website | | Akeneo Import e-mail notifications | Setup e-mail notifications of Akeneo imports | | Slack Akeneo import notifications | Setup Slack notifications of Akeneo imports | | *Akeneo import log cleaner* | Cleans the Akeneo logs that are older then the configured number of days *Deprecated - the Akeneo Connector has this functionality built in since* [v102.2.0](https://github.com/akeneo/magento2-connector-community/releases/tag/v102.2.0) | diff --git a/etc/adminhtml/system.xml b/etc/adminhtml/system.xml index f3c4de2..bc58ec4 100644 --- a/etc/adminhtml/system.xml +++ b/etc/adminhtml/system.xml @@ -35,6 +35,12 @@ 1 + + + Akeneo\Connector\Block\Adminhtml\System\Config\Form\Field\Attribute + Magento\Config\Model\Config\Backend\Serialized\ArraySerialized + Each of the required product attributes will be checked. If one of the attributes is empty the Website Association is removed. For Example when a productname in Akeneo is empty, there may be errors in Magento. + JustBetter_AkeneoBundle::akeneobundle_config +