10

I want to create command for delete operation for simple product by sku. I'm getting following error.how to set admin area?

[Magento\Framework\Exception\LocalizedException]
Delete operation is forbidden for current area

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

Agree with Max that you should use the ProductRepositoryInterface::deleteById($sku), but you'll also need to make an additional change to get permissions to delete.

Note that the Admin area handles this by creating the following config in app/code/Magento/Backend/etc/adminhtml/di.xml

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

The Magento\Framework\Model\ActionValidator\RemoveAction\Allowed class prevents a permission check by simply returning true in the isAllowed method.

Without the above change to di.xml the Magento\Framework\Model\ActionValidator\RemoveAction class will be used, which will cause your delete request to fail unless $this->registry->registry('isSecureArea') is set to true.

It looks like you are trying to create some console commands and I'm not very familiar with them yet, so your best bet for now may be to set the registry to allow the delete operation and refactor later if a cleaner solution is found.

$this->registry->register('isSecureArea', true)
| improve this answer | |
  • its working fine.i hope i will get some clarity why should i use ProductRepository.meanwhile i will try to search usage of this class in devdocs. – sivakumar Apr 29 '15 at 17:21
  • Ideally use https://github.com/magento/magento2/blob/develop/app/code/Magento/Catalog/Api/ProductRepositoryInterface.php since it is a public API and therefore more stable. – Chris O'Toole Apr 29 '15 at 17:31
8

I recently had this problem while writing a console command to delete empty categories.

As said in another answer you need to register 'isSecureArea' to true.

To do this in a console command you need to have the Magento\Framework\Registry class passed into your constructor.

In my case I did in this way:

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


    parent::__construct();
}

and then in the execute method I used the repository to perform the actual deletion:

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

| improve this answer | |
5

if you using script please create the registry object as shown below.

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

Please click here for detailed explanation. http://www.pearlbells.co.uk/mass-delete-magento-2-categories-programmatically/

if it is a one time script, you can use OM

| improve this answer | |
  • Thank Bro, Good job! – David Duong Nov 7 '19 at 10:48
2

Expanding on Chris O'Toole's answer. I too need to delete categories from a command, actually from multiple commands. Initially just having

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

in one command worked fine, but when I put that in multiple commands (in the constructor) I got this error during compilation

Registry key "isSecureArea" already exists

First checking for the existence of the registry key solved it

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

I'm not sure if it's bad form to put that in the constructor, but assume that's why the error was encountered. Alternatively, you should be able to get away with running the first snippet from your commands' execute methods. Again, I'm not sure what's considered best practice...

| improve this answer | |
1

For operations with product you must use Repository.

Magento\Catalog\Model\ProductRepository
| improve this answer | |
  • 2
    thank you for your response.now i'm getting following error.[Magento\Framework\Exception\StateException] Unable to remove product samsung – sivakumar Apr 29 '15 at 14:03
  • @sivakumar same error . have you fixed it? It was long time ago but anyway :D – Giga Todadze Mar 25 at 4:46
1

Instead of setting isSecureArea you can also allow to remove a single type of object by overriding type RemoveAction arguments in your di.xml like this:

<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>
| improve this answer | |

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.