public function upgrade()

in Setup/UpgradeData.php [117:305]


    public function upgrade(
        ModuleDataSetupInterface $setup,
        ModuleContextInterface $context
    ) {
        $setup->startSetup();

        $eavSetup = $this->eavSetupFactory->create(['setup' => $setup]);
        $categorySetup = $this->categorySetupFactory->create(['setup' => $setup]);

        $this->helper->log("getVersion" . $context->getVersion());

        // introducing google product category in 1.2.2
        if (version_compare($context->getVersion(), '1.2.2') < 0) {
            $attrCode = 'google_product_category';
            if (!$eavSetup->getAttributeId(Product::ENTITY, $attrCode)) {
                try {
                    $eavSetup->addAttribute(Product::ENTITY, $attrCode, [
                        'group' => 'General',
                        'type' => 'varchar',
                        'label' => 'Google Product Category',
                        'input' => 'select',
                        'source' => 'Facebook\BusinessExtension\Model\Config\Source\Product\GoogleProductCategory',
                        'required' => false,
                        'sort_order' => 10,
                        'global' => ScopedAttributeInterface::SCOPE_GLOBAL,
                        'is_used_in_grid' => true,
                        'is_visible_in_grid' => true,
                        'is_filterable_in_grid' => true,
                        'visible' => true,
                        'is_html_allowed_on_front' => false,
                        'visible_on_front' => false
                    ]);
                } catch (Exception $e) {
                    $this->logger->critical($e);
                }
            }
        }

        if (version_compare($context->getVersion(), '1.2.0') < 0) {
            $attributeConfig = $this->attributeConfig->getAttributesConfig();
            foreach ($attributeConfig as $attrCode => $config) {
                // verify if already installed before
                if (!$eavSetup->getAttributeId(Product::ENTITY, $attrCode)) {
                    //Create the attribute
                    // $this->helper->log($attrCode . " not exist before, process it");
                    //  attribute does not exist
                    // add a new attribute
                    // and assign it to the "FacebookAttributeSet" attribute set
                    $eavSetup->addAttribute(
                        Product::ENTITY,
                        $attrCode,
                        [
                            'type' => $config['type'],
                            'label' => $config['label'],
                            'input' => $config['input'],
                            'source' => $config['source'],
                            'note' => $config['note'],
                            'global' => ScopedAttributeInterface::SCOPE_GLOBAL,
                            'required' => false,
                            'user_defined' => true,
                            'is_used_in_grid' => true,
                            'is_visible_in_grid' => true,
                            'is_filterable_in_grid' => true,
                            'visible' => true,
                            'is_html_allowed_on_front' => false,
                            'searchable' => false,
                            'filterable' => false,
                            'comparable' => false,
                            'visible_on_front' => false,
                            'used_in_product_listing' => true,
                            'unique' => false,
                            'attribute_set' => 'FacebookAttributeSet'
                        ]
                    );
                } else {
                    $this->helper->log($attrCode . " already installed, skip");
                }
            }

            /**
             * Create a custom attribute group in all attribute sets
             * And, Add attribute to that attribute group for all attribute sets
             */
            $attributeGroupName = $this->attributeConfig->getAttributeGroupName();

            // get the catalog_product entity type id/code
            $entityTypeId = $categorySetup->getEntityTypeId(Product::ENTITY);

            // get the attribute set ids of all the attribute sets present in your Magento store
            $attributeSetIds = $eavSetup->getAllAttributeSetIds($entityTypeId);

            foreach ($attributeSetIds as $attributeSetId) {
                $attr_group_sort_order = $this->getMinAttributeGroupSortOrder(
                    $eavSetup,
                    $entityTypeId,
                    $attributeSetId
                );
                $eavSetup->addAttributeGroup(
                    $entityTypeId,
                    $attributeSetId,
                    $attributeGroupName,
                    $attr_group_sort_order // sort order
                );

                foreach ($attributeConfig as $attributeCode => $config) {
                    // get the newly create attribute group id
                    $attributeGroupId = $eavSetup->getAttributeGroupId(
                        $entityTypeId,
                        $attributeSetId,
                        $attributeGroupName
                    );

                    // add attribute to group
                    $categorySetup->addAttributeToGroup(
                        $entityTypeId,
                        $attributeSetId,
                        $attributeGroupName, // attribute group
                        $attributeCode,
                        $config['sort_order']
                    );
                }
            }
        }
        // change attribute code facebook_software_system_requirements -> facebook_system_requirements
        // due to 30 length limit
        if (version_compare($context->getVersion(), '1.2.5') < 0) {
            $oldAttrCode = 'facebook_software_system_requirements';
            $newAttrCode = 'facebook_system_requirements';

            $oldAttrId = $eavSetup->getAttributeId(Product::ENTITY, $oldAttrCode);
            if ($oldAttrId) {
                $eavSetup->updateAttribute(
                    \Magento\Catalog\Model\Product::ENTITY,
                    $oldAttrId,
                    [
                        'attribute_code' => $newAttrCode,
                    ]
                );
            }
        }
        // user can config if they want to sync a category or not
        if (version_compare($context->getVersion(), '1.4.2') < 0) {
            $attrCode = "sync_to_facebook_catalog";
            $eavSetup->removeAttribute(Product::ENTITY, $attrCode);
            if (!$eavSetup->getAttributeId(Product::ENTITY, $attrCode)) {
                    $eavSetup->addAttribute(
                        \Magento\Catalog\Model\Category::ENTITY,
                        $attrCode,
                        [
                            'type'     => 'int',
                            'input'    => 'boolean',
                            'source'   => 'Magento\Eav\Model\Entity\Attribute\Source\Boolean',
                            'visible'  => true,
                            'default'  => "1",
                            'required' => false,
                            'global'   => \Magento\Eav\Model\Entity\Attribute\ScopedAttributeInterface::SCOPE_STORE,
                            'group'    => 'Display Settings',
                        ]
                    );
            }
        }

        // remove FB attributes from products admin grid
        if (version_compare($context->getVersion(), '1.4.3') < 0) {

            $removeAttributeFromGrid = function ($attrCode) use ($eavSetup) {
                $attrId = $eavSetup->getAttributeId(Product::ENTITY, $attrCode);
                if ($attrId) {
                    $eavSetup->updateAttribute(
                        \Magento\Catalog\Model\Product::ENTITY,
                        $attrId,
                        [
                            'is_used_in_grid' => false,
                            'is_visible_in_grid' => false,
                            'is_filterable_in_grid' => false,
                        ]
                    );
                }
            };

            $attributeConfig = $this->attributeConfig->getAttributesConfig();
            foreach ($attributeConfig as $attrCode => $config) {
                $removeAttributeFromGrid($attrCode);
            }
            $removeAttributeFromGrid('google_product_category');
        }

        $setup->endSetup();
    }