我想通过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;
    }
}

迪。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>
有帮助吗?

解决方案

同意Max的意见,你应该使用 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 类通过简单地返回来防止权限检查 trueisAllowed 方法。

没有上述对di的改变。xml的 Magento\Framework\Model\ActionValidator\RemoveAction 类将被使用,这将导致您的删除请求失败,除非 $this->registry->registry('isSecureArea') 被设置为true。

看起来你正在尝试创建一些控制台命令,我还不太熟悉它们,所以你现在最好的选择可能是将注册表设置为允许删除操作,如果找到更干净的解决方案,

$this->registry->register('isSecureArea', true)

其他提示

我最近在编写控制台命令时有这个问题删除空型。

如在另一个答案中所说,您需要注册生成的'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());

如果使用脚本,请创建注册表对象,如下所示。

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

请点击此处获取详细说明。 http://www.pearlbells.co.uk/mass-delete-magento-2类 - 以编程/

如果是一个时间脚本,可以使用OM

扩展Chris O'Toole的答案。我也需要从一个命令中删除类别,实际上是从多个命令中删除。最初只是有

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

在一个命令工作正常,但是当我把它放在多个命令(在构造函数中)时,我在编译过程中得到了这个错误

注册表项"isSecureArea"已经存在

首先检查注册表项的存在解决了它

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

我不确定将其放在构造函数中是否是不好的形式,但假设这就是遇到错误的原因。或者,您应该能够从您的命令中运行第一个代码段 execute 方法。同样,我不确定什么被认为是最佳实践。..

使用产品的操作,您必须使用存储库。

Magento\Catalog\Model\ProductRepository
.

您还可以允许通过重写类型来删除单个类型的对象,而不是设置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>
许可以下: CC-BY-SA归因
scroll top