Magento 2 — Установить атрибут продукта для использования значений по умолчанию

#magento #magento2

#magento #magento2

Вопрос:

Я хочу проверить использование по умолчанию для всех продуктов для конкретного представления магазина

Я использую этот код

 $objectManager = MagentoFrameworkAppObjectManager::getInstance();
$collection = $this->_productCollectionFactory->create();
foreach($collection as $data){
$product=$this->_product->setStoreId(1)->load($data->getEntityId()); 
$product->setData('name',false);
$product->save(); 
}  
  

Но это удаляет продукт из категорий.
Не могли бы вы, пожалуйста, сообщить мне, как я могу программно установить флажок Использовать по умолчанию.

Ответ №1:

Magento 2.1.3 EE

Следующее решение создает команду командной строки для непосредственного управления базой данных и удаления информации атрибута продукта, относящейся к конкретному хранилищу. Он был написан для Magento Enterprise Edition, поэтому, если вы используете Community Edition, вам придется изменить этот код, чтобы использовать entity_id вместо row_id .

Пожалуйста, будьте осторожны с этим. Изложенное здесь решение обходит классы модели и выполняет запросы прямого удаления к таблицам catalog_product_entity_datetime , catalog_product_entity_decimal catalog_product_entity_int catalog_product_entity_text и catalog_product_entity_varchar для подключения к базе данных по умолчанию. Сначала создайте резервную копию своей базы данных.

Шаг 1: Создайте модуль

app/code/StackOverflow/Question40177336/registration.php

 <?php
MagentoFrameworkComponentComponentRegistrar::register(
    MagentoFrameworkComponentComponentRegistrar::MODULE,
    'StackOverflow_Question40177336',
    __DIR__
);
  

app/code/StackOverflow/Question40177336/etc/module.xml

 <?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
        xsi:noNamespaceSchemaLocation="urn:magento:framework:Module/etc/module.xsd">
    <module name="StackOverflow_Question40177336" setup_version="0.0.1"/>
</config>
  

app/code/StackOverflow/Question40177336/etc/di.xml

 <?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd">
    <type name="MagentoFrameworkConsoleCommandListInterface">
        <arguments>
            <argument name="commands" xsi:type="array">
                <item name="stackoverflow_question40177336" xsi:type="object">StackOverflowQuestion40177336ConsoleCommandProductUseDefaultValue</item>
            </argument>
        </arguments>
    </type>
</config>
  

app/code/StackOverflow/Question40177336/Console/Command/Product/UseDefaultValue.php

 <?php

namespace StackOverflowQuestion40177336ConsoleCommandProduct;

use MagentoCatalogModelProduct;
use MagentoEavSetupEavSetup;
use MagentoFrameworkAppResourceConnection;
use MagentoStoreModelStoreManagerInterface;
use SymfonyComponentConsoleCommandCommand;
use SymfonyComponentConsoleInputInputArgument;
use SymfonyComponentConsoleInputInputInterface;
use SymfonyComponentConsoleOutputOutputInterface;

class UseDefaultValue extends Command
{
    /**
     * flag indicating if the command has been initialized yet
     *
     * @var bool
     */
    protected $initialized = false;

    /**
     * The attribute_id to use for the current command.
     *
     * @var int
     */
    protected $attributeId;

    /**
     * The row_id values(s) to use for the command (if any).
     *
     * @var array|bool
     */
    protected $rowIds;

    /**
     * The store_id to use for the current command.
     *
     * @var int
     */
    protected $storeId;

    /**
     * The table name to use for the current command.
     *
     * @var string
     */
    protected $tableName;

    /**
     * @var MagentoFrameworkDBAdapterAdapterInterface
     */
    protected $connection;

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

    /**
     * @var StoreManagerInterface
     */
    protected $storeManager;

    public function __construct(
        EavSetup $eavSetup,
        ResourceConnection $resourceConnection,
        StoreManagerInterface $storeManager
    ) {
        $this->connection = $resourceConnection->getConnection();
        $this->eavSetup = $eavSetup;
        $this->storeManager = $storeManager;
        parent::__construct();
    }

    /**
     * Configures the current command.
     */
    protected function configure()
    {
        $this
            ->setName('catalog:product:attributes:use-default-value')
            ->setDescription('Removes store specific data from a product(s) of given attribute code.')
            ->addArgument(
                'attribute_code',
                InputArgument::REQUIRED,
                'Attribute Code'
            )
            ->addArgument(
                'store',
                InputArgument::REQUIRED,
                'Store code or store_id (cannot be 'admin' or '0')'
            )
            ->addArgument(
                'sku',
                InputArgument::OPTIONAL,
                'Sku (omit to apply to all products)'
            )
        ;
    }

    /**
     * Executes the current command.
     *
     * @param InputInterface  $input  An InputInterface instance
     * @param OutputInterface $output An OutputInterface instance
     */
    protected function execute(InputInterface $input, OutputInterface $output)
    {
        $this->init($input);
        $conn = $this->connection;
        $bind = [
            $conn->quoteInto('store_id = ?', $this->getStoreId()),
            $conn->quoteInto('attribute_id = ?', $this->getAttributeId())
        ];
        if ($this->getRowIds()) {
            $bind[] = $conn->quoteInto('row_id IN (?)', $this->getRowIds());
        }
        $rows = $conn->delete($this->getTableName(), $bind);
        $output->writeln($rows.' rows deleted.');
    }

    /**
     * Return the row_id value(s) to use for the command (if any).
     *
     * @return array|boolean
     */
    protected function getRowIds()
    {
        if (!$this->initialized) {
            $this->errorInit(__METHOD__);
        }
        return $this->rowIds;
    }

    /**
     * Initializes some class properties.
     *
     * @param InputInterface $input
     */
    protected function init(InputInterface $input)
    {
        if (!$this->initialized) {
            $attributeCode = trim($input->getArgument('attribute_code'));
            if ($attributeCode == '') {
                throw new RuntimeException(__('attribute_code is required.'));
            } elseif (is_numeric($attributeCode)) {
                throw new RuntimeException(__('attribute_code cannot be numeric.'));
            }
            $attribute = $this->eavSetup->getAttribute(
                Product::ENTITY,
                $attributeCode
            );
            if (!$attribute) {
                throw new RuntimeException(__('Invalid attribute_code "%1"', $attributeCode));
            }
            $backendType = $attribute['backend_type'];
            $allowedTypes = ['datetime','decimal','int','text','varchar'];
            if (!in_array($backendType, $allowedTypes)) {
                throw new RuntimeException(__(
                    'backend_type "%1" is not allowed. Allowed types include: %2',
                    $backendType,
                    implode(', ', $allowedTypes)
                ));
            }
            $this->tableName = $this->connection->getTableName('catalog_product_entity_'.$backendType);
            $this->attributeId = (int) $attribute['attribute_id'];

            $store = $this->storeManager->getStore($input->getArgument('store'));
            if ($store->getCode() == 'admin') {
                throw new RuntimeException(__('Admin Store is not allowed for this command.'));
            }
            $this->storeId = (int) $store->getId();

            $sku = trim($input->getArgument('sku'));
            if ($sku != '') {
                $sql = $this->connection->select()
                    ->from($this->connection->getTableName('catalog_product_entity'), 'row_id')
                    ->where('sku = ?', $sku)
                ;
                $rowIds = $this->connection->fetchCol($sql);
                if (!$rowIds) {
                    throw new RuntimeException(__('Invalid Sku "%1"', $sku));
                }
                foreach ($rowIds as $k => $v) {
                    $rowIds[$k] = (int) $v;
                }
                $this->rowIds = $rowIds;
            } else {
                $this->rowIds = false;
            }

            $this->initialized = true;
        }
    }

    /**
     * Returns the attribute_id to use for the current command.
     *
     * @return int
     */
    protected function getAttributeId()
    {
        if (!$this->attributeId) {
            $this->errorInit(__METHOD__);
        }
        return $this->attributeId;
    }

    /**
     * Return the store id to use for the current command.
     *
     * @param InputInterface $input
     */
    protected function getStoreId()
    {
        if (!$this->storeId) {
            $this->errorInit(__METHOD__);
        }
        return $this->storeId;
    }

    /**
     * Return the qualified table name to use for the current command.
     *
     * @param InputInterface $input
     */
    protected function getTableName()
    {
        if (!$this->tableName) {
            $this->errorInit(__METHOD__);
        }
        return $this->tableName;
    }

    /**
     * Throws an exception.
     *
     * @param string $methodName
     * @throws LogicException
     */
    protected function errorInit($methodName)
    {
        throw new LogicException(
            __('Command has not been intialized. Call UseDefaultValue::init() before calling '.$methodName));
        ;
    }
}
  

Шаг 2: Включите модуль

php -f bin/magento module:enable StackOverflow_Question40177336

Шаг 3: Используйте свою новую команду CLI.

Команда имеет два обязательных аргумента, attribute_code и store . Хранилищем может быть либо идентификатор, либо код. Хранилище администратора запрещено по очевидным причинам. Команда также имеет необязательный третий параметр SKU, если вы хотите настроить таргетинг только на определенный SKU (исключение этого относится ко всем продуктам).

Например, если вы хотите удалить все значения «name» из представления хранилища «по умолчанию», ваша команда должна быть следующей:

php -f bin/magento catalog:product:attributes:use-default-value name default

Комментарии:

1. потрясающее решение 🙂