La operación de eliminación está prohibida para el área actual

10

Quiero crear un comando para eliminar la operación para un producto simple por sku. Recibo el siguiente error. ¿Cómo configurar el área de administración?

[Magento \ Framework \ Exception \ LocalizedException] La
operación de eliminación está prohibida para el área actual

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

Respuestas:

12

De acuerdo con Max en que debe usar el ProductRepositoryInterface::deleteById($sku), pero también tendrá que hacer un cambio adicional para obtener permisos para eliminar.

Tenga en cuenta que el área de administración maneja esto creando la siguiente configuración en app/code/Magento/Backend/etc/adminhtml/di.xml

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

La Magento\Framework\Model\ActionValidator\RemoveAction\Allowedclase evita una verificación de permisos simplemente regresando trueen el isAllowedmétodo.

Sin el cambio anterior a di.xml Magento\Framework\Model\ActionValidator\RemoveAction, se utilizará la clase, lo que hará que su solicitud de eliminación falle a menos que $this->registry->registry('isSecureArea')se establezca en verdadero.

Parece que está intentando crear algunos comandos de consola y aún no estoy muy familiarizado con ellos, por lo que su mejor opción por ahora puede ser configurar el registro para permitir la operación de eliminación y refactorizar más adelante si se encuentra una solución más limpia.

$this->registry->register('isSecureArea', true)
Chris O'Toole
fuente
funciona bien. Espero tener algo de claridad por qué debería usar ProductRepository. Mientras tanto, intentaré buscar el uso de esta clase en devdocs.
sivakumar
Idealmente, https://github.com/magento/magento2/blob/develop/app/code/Magento/Catalog/Api/ProductRepositoryInterface.phpya que es una API pública y, por lo tanto, más estable.
Chris O'Toole
6

Recientemente tuve este problema al escribir un comando de consola para eliminar categorías vacías.

Como se dijo en otra respuesta, debe registrarse 'isSecureArea'en verdadero.

Para hacer esto en un comando de consola, debe pasar la clase Magento \ Framework \ Registry a su constructor.

En mi caso lo hice de esta manera:

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


    parent::__construct();
}

y luego en el executemétodo utilicé el repositorio para realizar la eliminación real:

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

Mir
fuente
4

Si usa un script, cree el objeto de registro como se muestra a continuación.

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

Haga clic aquí para obtener una explicación detallada. http://www.pearlbells.co.uk/mass-delete-magento-2-categories-programmatic/

si es un script de una sola vez, puede usar OM

Liz Eipe C
fuente
Gracias hermano, buen trabajo!
David Duong el
2

Ampliando la respuesta de Chris O'Toole. También necesito eliminar categorías de un comando, en realidad de múltiples comandos. Inicialmente solo teniendo

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

en un comando funcionó bien, pero cuando lo puse en varios comandos (en el constructor) recibí este error durante la compilación

La clave de registro "isSecureArea" ya existe

Primero comprobando la existencia de la clave de registro lo resolvió

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

No estoy seguro de si es una mala forma poner eso en el constructor, pero supongo que es por eso que se encontró el error. Alternativamente, debería poder ejecutar el primer fragmento de los executemétodos de sus comandos . De nuevo, no estoy seguro de qué se considera mejor práctica ...

quickshiftin
fuente
1

Para las operaciones con el producto, debe utilizar el repositorio.

Magento\Catalog\Model\ProductRepository
Max Yekaterynenko
fuente
2
gracias por su respuesta. ahora recibo el siguiente error. [Magento \ Framework \ Exception \ StateException] No se puede eliminar el producto samsung
sivakumar
@sivakumar mismo error. lo has arreglado? Fue hace mucho tiempo, pero de todos modos: D
Giga Todadze
1

En lugar de establecer isSecureArea, también puede permitir eliminar un solo tipo de objeto anulando los RemoveActionargumentos de tipo en su di.xmlestilo:

<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>
gorrión
fuente