A operação de exclusão é proibida para a área atual

10

Quero criar um comando para operação de exclusão de um produto simples por sku. Estou recebendo o seguinte error.how para definir a área de administração?

[Magento \ Framework \ Exception \ LocalizedException] A
operação de exclusão é proibida para a área atual

<?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
fonte

Respostas:

12

Concorde com Max que você deve usar o ProductRepositoryInterface::deleteById($sku), mas também precisará fazer uma alteração adicional para obter permissões para excluir.

Observe que a área Admin lida com isso criando a seguinte configuração em app/code/Magento/Backend/etc/adminhtml/di.xml

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

A Magento\Framework\Model\ActionValidator\RemoveAction\Allowedclasse impede uma verificação de permissão simplesmente retornando trueno isAllowedmétodo

Sem a alteração acima para di.xml, a Magento\Framework\Model\ActionValidator\RemoveActionclasse será usada, o que fará com que sua solicitação de exclusão falhe, a menos que $this->registry->registry('isSecureArea')esteja definido como true.

Parece que você está tentando criar alguns comandos do console e ainda não estou familiarizado com eles. Portanto, sua melhor aposta agora é definir o registro para permitir a operação de exclusão e refatorar mais tarde, se uma solução mais limpa for encontrada.

$this->registry->register('isSecureArea', true)
Chris O'Toole
fonte
Espero que tenha alguma clareza por que devo usar o ProductRepository.mean enquanto tentarei pesquisar o uso dessa classe nos devdocs.
Sivakumar
O ideal é usar, https://github.com/magento/magento2/blob/develop/app/code/Magento/Catalog/Api/ProductRepositoryInterface.phppois é uma API pública e, portanto, mais estável.
Chris O'Toole
6

Recentemente, tive esse problema ao escrever um comando do console para excluir categorias vazias.

Como dito em outra resposta, você precisa se registrar 'isSecureArea' como true.

Para fazer isso em um comando do console, você precisa que a classe Magento \ Framework \ Registry seja passada ao seu construtor.

No meu caso, fiz desta maneira:

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


    parent::__construct();
}

e, em seguida, no executemétodo, usei o repositório para executar a exclusão real:

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

Mir
fonte
4

se você estiver usando script, crie o objeto de registro como mostrado abaixo.

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

Clique aqui para obter uma explicação detalhada. http://www.pearlbells.co.uk/mass-delete-magento-2-categories-programmatically/

se for um script único, você pode usar o OM

Liz Eipe C
fonte
Obrigado Bro, Bom trabalho!
David Duong
2

Expandindo a resposta de Chris O'Toole. Eu também preciso excluir categorias de um comando, na verdade, de vários comandos. Inicialmente apenas tendo

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

em um comando funcionou bem, mas quando coloquei isso em vários comandos (no construtor), recebi esse erro durante a compilação

A chave do registro "isSecureArea" já existe

A primeira verificação da existência da chave do registro resolveu

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

Não tenho certeza se é uma má forma colocar isso no construtor, mas suponha que é por isso que o erro foi encontrado. Como alternativa, você deve conseguir executar o primeiro trecho dos executemétodos dos seus comandos . Novamente, não tenho certeza do que é considerado uma boa prática ...

troca rápida
fonte
1

Para operações com o produto, você deve usar o Repositório.

Magento\Catalog\Model\ProductRepository
Max Yekaterynenko
fonte
2
obrigado por sua response.now que estou recebendo seguinte erro [Magento \ Framework \ Exception \ StateException] Não é possível remover o produto Samsung.
sivakumar
@sivakumar mesmo erro. você consertou? Foi há muito tempo, mas de qualquer maneira: D
Giga Todadze 25/03
1

Em vez de definir isSecureArea, você também pode permitir remover um único tipo de objeto substituindo RemoveActionargumentos de tipo di.xmlcomo este:

<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>
pardal
fonte