2

I've created a CSV for all the attributes and sets that need to be added and a script to import them. After doing so I'm unable to load the attribute sets in the admin while creating a new product. They (attribute sets) do show up in the list but once selected it returns a 500 followed by a 404.

What am I doing wrong? I'm using the eavSetupFactory so no strange/weird code

One solution could be to upgrade to 2.3.0 but I currently can't due to a PostNL (shipping module) https://github.com/tig-nl/postnl-magento2/issues/78

Preconditions (*)

  • Magento CE 2.2.6 without sample data
  • Magento CE 2.2.7 without sample data

Steps to reproduce (*)

  1. Added attributes and set via script

    /**
     * @param ModuleDataSetupInterface $setup
     * @param ModuleContextInterface $context
     * @throws \Magento\Framework\Exception\LocalizedException
     */
    public function install(ModuleDataSetupInterface $setup, ModuleContextInterface $context)
    {
        $setup->startSetup();
        $this->setup = $setup;
        $eavSetup = $this->eavSetupFactory->create(['setup' => $setup]);

        $categorySetup = $this->categorySetupFactory->create(['setup' => $setup]);
        $entityTypeId = $categorySetup->getEntityTypeId(\Magento\Catalog\Model\Product::ENTITY);
        $attributeSetId = $categorySetup->getDefaultAttributeSetId($entityTypeId);

        // Create attribute sets
        foreach($this->csv_helper->getAttributeSets() as $attributeSetName) {
            if($eavSetup->getAttributeSet($entityTypeId, $attributeSetName)) {
                continue;
            }

            $this->logger->debug("Creating attribute set: $attributeSetName");            
            $eavSetup->addAttributeSet(
                $entityTypeId,
                $attributeSetName
            );
        }

        // Create attributes
        foreach($this->getAttributes() as $attributeData) {
            $attributeCode = $attributeData['code'];
            if ($eavSetup->getAttribute($entityTypeId, $attributeCode)) {
                continue;
            }

            $this->logger->debug("Creating attribute: $attributeCode");

            $eavSetup->addAttribute(
                $entityTypeId,
                $attributeCode,
                $this->prepAttributeProperties($attributeData)
            );
        }

        $setup->endSetup();
    }

Upgrade


    public function assignAttributeToSet($eavSetup, $attributeSet, $attributeCodes, $attributeGroupCode="General") {

        $entityTypeId = $eavSetup->getEntityTypeId('catalog_product');

        /** @var Set $attributeSet */
        foreach ($attributeCodes as $attributeCode) {
            $n = $attributeSet->getAttributeSetName();
            if(empty($n)) {
                continue;
            }

            $attributeGroupId = $eavSetup->getAttributeGroupId(
                $entityTypeId, 
                $attributeSet->getId(), 
                $attributeGroupCode
            );

            if(!$attributeGroupId) {
                $eavSetup->addAttributeGroup(
                    $entityTypeId, 
                    $attributeSet->getId(), 
                    $attributeGroupCode
                );
                $attributeGroupId = $eavSetup->getAttributeGroupId(
                    $entityTypeId, 
                    $attributeSet->getId(), 
                    $attributeGroupCode
                );
            }

            $attributeId = $eavSetup->getAttributeId($entityTypeId, $attributeCode);
            $eavSetup->addAttributeToGroup(
                $entityTypeId, 
                $attributeSet->getId(), 
                $attributeGroupId, 
                $attributeId, 
                null
            );
        }
    }
    public function upgrade(ModuleDataSetupInterface $setup, ModuleContextInterface $context)
    {
        $setup->startSetup();
        $this->setup = $setup;
        $eavSetup = $this->eavSetupFactory->create(['setup' => $setup]);

        // Assign attribute to attribute set
        $attibutesToSets = $this->csv_helper->getAttributesToSets();
        foreach($this->getAttributes() as $attributeData) {
            $attributeCode = $attributeData['code'];
            if(array_key_exists($attributeCode, $attibutesToSets)) {

                foreach($attibutesToSets[$attributeCode] as $attributeSetName) {                
                    if(!$attributeData['group'] || empty($attributeData['group'])) {
                        $this->logger->error("Group is empty for attribute '$attributeCode'");
                        continue;
                    }
                    $this->logger->debug("Assigning '$attributeCode' to $attributeSetName");
                    $this->assignAttributeToSet(
                        $eavSetup, 
                        $this->getAttributeSetByName($attributeSetName), 
                        array($attributeCode), 
                        $attributeData['group']
                    );
                }
            }
        }
        $setup->endSetup();
    }
  1. bin/magento setup:upgrade
  2. bin/magento indexer:reindex
  3. bin/magento cache:flush
  4. open admin
  5. Validate the attribute set via admin/catalog/product_set/index

image

  1. Add simple product
  2. select attribute set

Expected result (*)

1. attributes to add new product

Actual result (*)

  1. image
  2. POST /admin_/catalog/product/reload/type/simple/store/0/popup/1/componentJson/1/prev_set_id/9/key/XXX/?set=undefined&isAjax=true
  3. POST /admin_/catalog/product/reload/type/simple/store/0/popup/1/componentJson/1/prev_set_id/12/key/XXXXX/?set=&isAjax=true

    Fatal error:  Uncaught TypeError: Argument 3 passed to Magento\Framework\View\Element\UiComponentFactory::mergeMetadataElement() must be of the type array, null given, called in vendor/magento/framework/View/Element/UiComponentFactory.php on line 379 and defined in vendor/magento/framework/View/Element/UiComponentFactory.php:329
    Stack trace:
    #0 vendor/magento/framework/View/Element/UiComponentFactory.php(379): Magento\Framework\View\Element\UiComponentFactory->mergeMetadataElement(Array, 'configurableExi...', NULL, false)
    #1 vendor/magento/framework/View/Element/UiComponentFactory.php(404): Magento\Framework\View\Element\UiComponentFactory->mergeMetadataItem(Array, Array, false)
    #2 vendor/magento/framework/View/Element/UiComponentFactory.php(404): Magento\Framework\Vi in vendor/magento/framework/View/Element/UiComponentFactory.php on line 329

Following the code:

/**
 * Merge metadata item to components
 *
 * @param array $bundleComponents
 * @param array $metadata
 * @param bool $reverseMerge
 * @return array
 * @throws LocalizedException
 * @since 100.1.0
 */
protected function mergeMetadataItem(array $bundleComponents, array $metadata, $reverseMerge = false)
{
    foreach ($metadata as $name => $data) {
        $selfData = $data;
        if (isset($selfData['children'])) {
            unset($selfData['children']);
        }

        list($bundleComponents, $isMerged) = $this->mergeMetadataElement(
            $bundleComponents,
            $name,
            $selfData,
            $reverseMerge
        );

the $name in this case is configurableExistingAttributeSetId, $selfData is NULL

Related info

1 Answer 1

0

The issue is caused by

$eavSetup->addAttributeSet(
    $entityTypeId,
    $attributeSetName
);

This creates an actual empty attribute set without the required base attributes causing the backend to fail.

I've replaced it with the following:

public function __construct(
    EavSetupFactory $eavSetupFactory,
    AttributeSetCollectionFactory $attributeSetCollectionFactory,
    AttributeSetFactory $attributeSetFactory, 
    CategorySetupFactory $categorySetupFactory,
    \Psr\Log\LoggerInterface $logger,
    CsvHelper $csv_helper
) {
    $this->eavSetupFactory = $eavSetupFactory;
    $this->attributeSetCollectionFactory = $attributeSetCollectionFactory;
    $this->attributeSetFactory = $attributeSetFactory; 
    $this->categorySetupFactory = $categorySetupFactory;
    $this->logger = $logger;
    $this->csv_helper = $csv_helper;
}

/**
 * @param ModuleDataSetupInterface $setup
 * @param ModuleContextInterface $context
 * @throws \Magento\Framework\Exception\LocalizedException
 */
public function install(ModuleDataSetupInterface $setup, ModuleContextInterface $context)
{
    // $eavSetup = $this->eavSetupFactory->create(['setup' => $setup]);
    $objectManager = \Magento\Framework\App\ObjectManager::getInstance();
    $eavSetup = $objectManager->create('X043\ProductInfo\Setup\MySetup', array());

    $categorySetup = $this->categorySetupFactory->create(['setup' => $setup]);
    $entityTypeId = $categorySetup->getEntityTypeId(\Magento\Catalog\Model\Product::ENTITY);
    $attributeSetId = $categorySetup->getDefaultAttributeSetId($entityTypeId);

    $i = 200;
    // Create attribute sets
    foreach($this->csv_helper->getAttributeSets() as $attributeSetName) {
        $i++;
        if($eavSetup->getAttributeSet(\Magento\Catalog\Model\Product::ENTITY, $attributeSetName))
            continue;

        $this->logger->debug("Creating attribute set: $attributeSetName");            
        $attributeSet = $this->attributeSetFactory->create();
        $data = [
            'attribute_set_name' => $attributeSetName,
            'entity_type_id' => $entityTypeId,
            'sort_order' => $i,
        ];
        $attributeSet->setData($data);
        $attributeSet->validate();
        $attributeSet->save();
        $attributeSet->initFromSkeleton($attributeSetId);
        $attributeSet->save();   
    }

    // Create attributes
    foreach($this->getAttributes() as $attributeData) {
        $attributeCode = $attributeData['code'];
        if ($eavSetup->getAttribute(\Magento\Catalog\Model\Product::ENTITY, $attributeCode))
            continue;

        $this->logger->debug("Creating attribute: $attributeCode");
        $eavSetup->addAttribute(
            \Magento\Catalog\Model\Product::ENTITY,
            $attributeCode,
            $this->prepAttributeProperties($attributeData)
        );
    }

    $setup->endSetup();
}
1

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.