Операція видалення заборонена для поточної області


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>

Відповіді:


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)

його працює fine.i сподіваюся, що я отримаю деяку чіткість, чому я повинен використовувати ProductRepository.meaas, я спробую шукати використання цього класу в devdocs.
sivakumar

Ідеально використовувати, https://github.com/magento/magento2/blob/develop/app/code/Magento/Catalog/Api/ProductRepositoryInterface.phpоскільки це публічний API і, отже, більш стабільний.
Кріс О'Тул

6

Нещодавно у мене була ця проблема під час написання консольної команди для видалення порожніх категорій.

Як сказано в іншій відповіді, вам потрібно зареєструватися 'isSecureArea'до істини.

Для цього в команді консолі потрібно мати клас 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-programmatic/

якщо це одноразовий сценарій, ви можете використовувати OM


Дякую Бро, хороша робота!
Девід Дуонг

2

Розгортаючись на відповідь Кріса О'Тула. Мені теж потрібно видалити категорії з команди, фактично з декількох команд. Спочатку просто мав

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

в одній команді працював чудово, але коли я поставив це в декількох командах (у конструкторі), я отримав цю помилку під час компіляції

Ключ реєстру "isSecureArea" вже існує

Перша перевірка наявності ключа реєстру вирішила його

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

Я не впевнений, чи це погана форма, щоб помістити це в конструктор, але припустимо, що тому сталася помилка. Крім того, ви повинні мати можливість уникнути запуску першого фрагмента з executeметодів ваших команд . Знову ж таки, я не впевнений, що вважається найкращою практикою ...


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>
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.