Операция удаления запрещена для текущей области

10

Я хочу создать команду для операции удаления для простого продукта по sku. Я получаю следующую ошибку. Как установить админку?

[Magento \ Framework \ Exception \ LocalizedException]
Операция удаления запрещена для текущей области

<?php
namespace Sivakumar\Sample\Console;

use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputOption;

class DeleteSimpleProduct extends Command
{
    protected $_product;
    public function __construct(\Magento\Catalog\Model\Product $_product)
    {
        $this->_product =$_product;
        parent::__construct();
    }

    /**
     * {@inheritdoc}
     */
    protected function configure()
    {
        $this->setName('delete_simple_product')
            ->setDescription('Delete Simple Product')
            ->setDefinition($this->getOptionsList());

        parent::configure();
    }

    /**
     * {@inheritdoc}
     */
    protected function execute(InputInterface $input, OutputInterface $output)
    {
        $errors = $this->validate($input);
        if ($errors) {
            throw new \InvalidArgumentException(implode("\n", $errors));
        }

    $product_id = $this->_product->getIdBySku($input->getOption('sku'));
    $product=$this->_product->load($product_id);
        $product->delete();
        $output->writeln('<info>product deleted ' . $input->getOption('sku') . '</info>');
    }

    public function getOptionsList()
    {
        return [
            new InputOption('sku', null, InputOption::VALUE_REQUIRED, 'SKU'),
        ];
    }

    public function validate(InputInterface $input)
    {
        $errors = [];
        $required =['sku',]; 

        foreach ($required as $key) {
            if (!$input->getOption($key)) {
                $errors[] = 'Missing option ' . $key;
            }
        }
        return $errors;
    }
}

di.xml

<?xml version="1.0" ?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../lib/internal/Magento/Framework/ObjectManager/etc/config.xsd">
<type name="Magento\Framework\Console\CommandList">
    <arguments>
        <argument name="commands" xsi:type="array">
            <item name="delete_simple_product" xsi:type="object">Sivakumar\Sample\Console\DeleteSimpleProduct</item>
        </argument>
    </arguments>
</type>
</config>
Sivakumar
источник

Ответы:

12

Согласитесь с Максом, что вам следует использовать ProductRepositoryInterface::deleteById($sku), но вам также нужно будет внести дополнительные изменения, чтобы получить разрешения на удаление.

Обратите внимание, что область администратора обрабатывает это путем создания следующей конфигурации в app/code/Magento/Backend/etc/adminhtml/di.xml

    <preference for="Magento\Framework\Model\ActionValidator\RemoveAction" type="Magento\Framework\Model\ActionValidator\RemoveAction\Allowed" />

Magento\Framework\Model\ActionValidator\RemoveAction\AllowedКласс предотвращает проверку разрешений, просто возвращаются trueв isAllowedметоде.

Без вышеуказанного изменения в di.xml Magento\Framework\Model\ActionValidator\RemoveActionбудет использоваться класс, что приведет к сбою вашего запроса на удаление, если $this->registry->registry('isSecureArea')не установлено значение true.

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

$this->registry->register('isSecureArea', true)
Крис О'Тул
источник
он работает нормально. Надеюсь, я получу некоторую ясность, почему я должен использовать ProductRepository.meanse, в то время как я попытаюсь найти использование этого класса в devdocs.
Сивакумар
Идеально использовать, https://github.com/magento/magento2/blob/develop/app/code/Magento/Catalog/Api/ProductRepositoryInterface.phpтак как это публичный API и, следовательно, более стабильный.
Крис О'Тул
6

У меня недавно была эта проблема при написании консольной команды для удаления пустых категорий.

Как сказано в другом ответе, вам необходимо зарегистрироваться 'isSecureArea'на true.

Для этого в консольной команде вам нужно передать класс Magento \ Framework \ Registry в ваш конструктор.

В моем случае я сделал так:

public function __construct(CategoryManagementInterface $categoryManagementInterface, CategoryRepositoryInterface $categoryRepositoryInterface, Registry $registry)
{
    $this->_categoryRepository = $categoryRepositoryInterface;
    $this->_categoryManagement = $categoryManagementInterface;
    $registry->register('isSecureArea', true);


    parent::__construct();
}

а затем в executeметоде я использовал хранилище для фактического удаления:

$this->_categoryRepository->deleteByIdentifier($category->getId());

Мир
источник
4

Если вы используете скрипт, пожалуйста, создайте объект реестра, как показано ниже.

  $objectManager = \Magento\Framework\App\ObjectManager::getInstance();
  $objectManager->get('Magento\Framework\Registry')->register('isSecureArea', true);

Пожалуйста, нажмите здесь для подробного объяснения. http://www.pearlbells.co.uk/mass-delete-magento-2-categories-programmatically/

если это одноразовый скрипт, вы можете использовать OM

Лиз Айпе С
источник
Спасибо Бро, Хорошая работа!
Дэвид Дуонг,
2

Расширяя ответ Криса О'Тула. Мне тоже нужно удалить категории из команды, на самом деле из нескольких команд. Первоначально просто имея

$oRegistry->register('isSecureArea', true);

в одной команде работал нормально, но когда я положил это в несколько команд (в конструкторе), я получил эту ошибку во время компиляции

Раздел реестра "isSecureArea" уже существует

Сначала проверка на наличие ключа реестра решена

if($oRegistry->registry('isSecureArea') === null) {
    $oRegistry->register('isSecureArea', true);
}

Я не уверен, что это плохо - помещать это в конструктор, но предположим, что именно поэтому возникла ошибка. Кроме того, вы должны иметь возможность запустить первый фрагмент из executeметодов ваших команд . Опять же, я не уверен, что считается лучшей практикой ...

quickshiftin
источник
1

Для работы с продуктом вы должны использовать репозиторий.

Magento\Catalog\Model\ProductRepository
Макс Екатериненко
источник
2
спасибо за ваш ответ. Теперь я получаю следующую ошибку. [Magento \ Framework \ Exception \ StateException] Невозможно удалить продукт samsung
sivakumar
@sivakumar та же ошибка. ты это исправил? Это было давно, но в любом случае: D
Гига Тодадзе
1

Вместо установки isSecureArea вы также можете разрешить удаление объекта одного типа, переопределив RemoveActionаргументы типа в вашем di.xmlвиде:

<type name="Magento\Framework\Model\ActionValidator\RemoveAction">
    <arguments>
        <argument name="protectedModels" xsi:type="array">
            <item name="salesOrder" xsi:type="null" /> <!--allow orders to be removed from front area-->
        </argument>
    </arguments>
</type>
воробей
источник