<commit_before><?php

namespace CtiDigital\Configurator\Component;

use CtiDigital\Configurator\Exception\ComponentException;
use CtiDigital\Configurator\Api\LoggerInterface;
use Magento\Eav\Api\AttributeSetRepositoryInterface;
use Magento\Catalog\Model\Product;
use Magento\Eav\Api\Data\AttributeSetInterface;
use Magento\Eav\Setup\EavSetup;
use Magento\Framework\ObjectManagerInterface;
use Magento\Eav\Model\AttributeSetRepository;

/**
 * Class AttributeSets
 * @package CtiDigital\Configurator\Model\Component
 * @SuppressWarnings(PHPMD.LongVariable)
 */
class AttributeSets extends YamlComponentAbstract
{
    protected $alias = 'attribute_sets';
    protected $name = 'Attribute Sets';
    protected $description = 'Component to create/maintain attribute sets.';

    /**
     * @var EavSetup
     */
    protected $eavSetup;

    /**
     * @var AttributeSetRepository
     */
    protected $attributeSetRepository;

    /**
     * AttributeSets constructor.
     * @param LoggerInterface $log
     * @param ObjectManagerInterface $objectManager
     * @param EavSetup $eavSetup
     * @param AttributeSetRepositoryInterface $attributeSetRepository
     */
    public function __construct(
        LoggerInterface $log,
        ObjectManagerInterface $objectManager,
        EavSetup $eavSetup,
        AttributeSetRepositoryInterface $attributeSetRepository
    ) {

        parent::__construct($log, $objectManager);

        $this->eavSetup = $eavSetup;
        $this->attributeSetRepository = $attributeSetRepository;
    }

    /**
     * @param array $attributeConfigurationData
     */
    protected function processData($attributeConfigurationData = null)
    {
        try {
            foreach ($attributeConfigurationData['attribute_sets'] as $attributeSetConfiguration) {
                $this->processAttributeSet($attributeSetConfiguration);
            }
        } catch (ComponentException $e) {
            $this->log->logError($e->getMessage());
        }
    }

    /**
     * @param array $attributeSetConfig
     */
    protected function processAttributeSet(array $attributeSetConfig)
    {
        $this->eavSetup->addAttributeSet(Product::ENTITY, $attributeSetConfig['name']);

        $this->log->logInfo(sprintf('Creating attribute set: "%s"', $attributeSetConfig['name']));

        $attributeSetId = $this->eavSetup->getAttributeSetId(Product::ENTITY, $attributeSetConfig['name']);
        $attributeSetEntity = $this->attributeSetRepository->get($attributeSetId);
        if (array_key_exists('inherit', $attributeSetConfig)) {
            $attributeSetEntity->initFromSkeleton($this->getAttributeSetId($attributeSetConfig['inherit']));
            $this->attributeSetRepository->save($attributeSetEntity);
        }

        if (array_key_exists('groups', $attributeSetConfig) && count($attributeSetConfig['groups']) > 0) {
            $this->addAttributeGroups($attributeSetEntity, $attributeSetConfig['groups']);
        }
    }

    /**
     * @param AttributeSetInterface $attributeSetEntity
     * @param array $attributeGroupData
     */
    protected function addAttributeGroups(AttributeSetInterface $attributeSetEntity, array $attributeGroupData)
    {
        $attributeSetName = $attributeSetEntity->getAttributeSetName();

        // Loop through the groups that belong to the attribute set
        foreach ($attributeGroupData as $group) {

            try {
                // Used to predetermine the code if not using a custom attribute group code
                if (!isset($group['code'])) {
                    $group['code'] = $this->eavSetup->convertToAttributeGroupCode($group['name']);
                }

                // Check if the attribute group exist
                $attributeGroup = $this->eavSetup->getAttributeGroup(
                    Product::ENTITY,
                    $attributeSetName,
                    $group['code'],
                    'attribute_set_id'
                );

                // If not then create the group
                if (!$attributeGroup) {
                    $this->eavSetup->addAttributeGroup(Product::ENTITY, $attributeSetName, $group['name']);
                    $this->log->logInfo(sprintf('Creating group: "%s"', $group['name']), 1);
                }

                if ($attributeGroup) {
                    $this->log->logComment(sprintf('Existing group: "%s"', $group['name']), 1);
                }

                // Attempt to associate the attributes to the group
                $this->addAttributeGroupAssociations($attributeSetEntity, $group);

            } catch (\Zend_Db_Statement_Exception $exception) {
                $this->log->logError(
                    'Magento sometimes uses different attribute codes to attribute names. '
                    .'You may require to specify the code too.',
                    1
                );
                $this->log->logError(
                    sprintf('Attribute Set: %s, Group: %s', $attributeSetName, $group['name']),
                    1
                );
                $this->log->logError($exception->getMessage(), 1);
            }

        }
    }

    /**
     * @param AttributeSetInterface $attributeSetEntity
     * @param array $group
     */
    protected function addAttributeGroupAssociations(
        AttributeSetInterface $attributeSetEntity,
        array $group
    ) {
        foreach ($group['attributes'] as $attributeCode) {
            $attributeData = $this->eavSetup->getAttribute(Product::ENTITY, $attributeCode);

            if (count($attributeData) === 0) {
                throw new ComponentException("Attribute '{$attributeCode}' does not exist.");
            }

            $this->eavSetup->addAttributeToGroup(
                Product::ENTITY,
                $attributeSetEntity->getId(),
                $group['name'],
                $attributeCode
            );

            $this->log->logInfo(sprintf('Adding attribute "%s"', $attributeCode), 2);
        }
    }<commit_msg>Fix for when an attribute set has a code that differs from the name<commit_after><?php

namespace CtiDigital\Configurator\Component;

use CtiDigital\Configurator\Exception\ComponentException;
use CtiDigital\Configurator\Api\LoggerInterface;
use Magento\Eav\Api\AttributeSetRepositoryInterface;
use Magento\Catalog\Model\Product;
use Magento\Eav\Api\Data\AttributeSetInterface;
use Magento\Eav\Setup\EavSetup;
use Magento\Framework\ObjectManagerInterface;
use Magento\Eav\Model\AttributeSetRepository;

/**
 * Class AttributeSets
 * @package CtiDigital\Configurator\Model\Component
 * @SuppressWarnings(PHPMD.LongVariable)
 */
class AttributeSets extends YamlComponentAbstract
{
    protected $alias = 'attribute_sets';
    protected $name = 'Attribute Sets';
    protected $description = 'Component to create/maintain attribute sets.';

    /**
     * @var EavSetup
     */
    protected $eavSetup;

    /**
     * @var AttributeSetRepository
     */
    protected $attributeSetRepository;

    /**
     * AttributeSets constructor.
     * @param LoggerInterface $log
     * @param ObjectManagerInterface $objectManager
     * @param EavSetup $eavSetup
     * @param AttributeSetRepositoryInterface $attributeSetRepository
     */
    public function __construct(
        LoggerInterface $log,
        ObjectManagerInterface $objectManager,
        EavSetup $eavSetup,
        AttributeSetRepositoryInterface $attributeSetRepository
    ) {

        parent::__construct($log, $objectManager);

        $this->eavSetup = $eavSetup;
        $this->attributeSetRepository = $attributeSetRepository;
    }

    /**
     * @param array $attributeConfigurationData
     */
    protected function processData($attributeConfigurationData = null)
    {
        try {
            foreach ($attributeConfigurationData['attribute_sets'] as $attributeSetConfiguration) {
                $this->processAttributeSet($attributeSetConfiguration);
            }
        } catch (ComponentException $e) {
            $this->log->logError($e->getMessage());
        }
    }

    /**
     * @param array $attributeSetConfig
     */
    protected function processAttributeSet(array $attributeSetConfig)
    {
        $this->eavSetup->addAttributeSet(Product::ENTITY, $attributeSetConfig['name']);

        $this->log->logInfo(sprintf('Creating attribute set: "%s"', $attributeSetConfig['name']));

        $attributeSetId = $this->eavSetup->getAttributeSetId(Product::ENTITY, $attributeSetConfig['name']);
        $attributeSetEntity = $this->attributeSetRepository->get($attributeSetId);
        if (array_key_exists('inherit', $attributeSetConfig)) {
            $attributeSetEntity->initFromSkeleton($this->getAttributeSetId($attributeSetConfig['inherit']));
            $this->attributeSetRepository->save($attributeSetEntity);
        }

        if (array_key_exists('groups', $attributeSetConfig) && count($attributeSetConfig['groups']) > 0) {
            $this->addAttributeGroups($attributeSetEntity, $attributeSetConfig['groups']);
        }
    }

    /**
     * @param AttributeSetInterface $attributeSetEntity
     * @param array $attributeGroupData
     */
    protected function addAttributeGroups(AttributeSetInterface $attributeSetEntity, array $attributeGroupData)
    {
        $attributeSetName = $attributeSetEntity->getAttributeSetName();

        // Loop through the groups that belong to the attribute set
        foreach ($attributeGroupData as $group) {

            try {
                // Used to predetermine the code if not using a custom attribute group code
                if (!isset($group['code'])) {
                    $group['code'] = $this->eavSetup->convertToAttributeGroupCode($group['name']);
                }

                // Check if the attribute group exist
                $attributeGroup = $this->eavSetup->getAttributeGroup(
                    Product::ENTITY,
                    $attributeSetName,
                    $group['code'],
                    'attribute_set_id'
                );

                // If not then create the group
                if (!$attributeGroup) {
                    $this->eavSetup->addAttributeGroup(Product::ENTITY, $attributeSetName, $group['name']);
                    $this->log->logInfo(sprintf('Creating group: "%s"', $group['name']), 1);
                }

                if ($attributeGroup) {
                    $this->log->logComment(sprintf('Existing group: "%s"', $group['name']), 1);
                }

                // Attempt to associate the attributes to the group
                $this->addAttributeGroupAssociations($attributeSetEntity, $group);

            } catch (\Zend_Db_Statement_Exception $exception) {
                $this->log->logError(
                    'Magento sometimes uses different attribute codes to attribute names. '
                    .'You may require to specify the code too.',
                    1
                );
                $this->log->logError(
                    sprintf('Attribute Set: %s, Group: %s', $attributeSetName, $group['name']),
                    1
                );
                $this->log->logError($exception->getMessage(), 1);
            }

        }
    }

    /**
     * @param AttributeSetInterface $attributeSetEntity
     * @param array $group
     */
    protected function addAttributeGroupAssociations(
        AttributeSetInterface $attributeSetEntity,
        array $group
    ) {
        foreach ($group['attributes'] as $attributeCode) {
            $attributeData = $this->eavSetup->getAttribute(Product::ENTITY, $attributeCode);

            if (count($attributeData) === 0) {
                throw new ComponentException("Attribute '{$attributeCode}' does not exist.");
            }

            $this->eavSetup->addAttributeToGroup(
                Product::ENTITY,
                $attributeSetEntity->getId(),
                $group['code'],
                $attributeCode
            );

            $this->log->logInfo(sprintf('Adding attribute "%s"', $attributeCode), 2);
        }
    }
{'fraction_non_alphanumeric': 0.11425732737208147, 'fraction_numerical': 0.001324722636198046, 'mean_word_length': 2.4044532130777903, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 95, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '488076', 'n_tokens_mistral': 3075, 'n_tokens_neox': 2954, 'n_words': 599}