L'opération de suppression est interdite pour la zone actuelle


10

Je veux créer une commande pour l'opération de suppression d'un produit simple par sku. Je reçois le message d'erreur suivant: comment définir la zone d'administration?

[Magento \ Framework \ Exception \ LocalizedException] L'
opération de suppression est interdite pour la zone actuelle

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

Réponses:


12

Convenez avec Max que vous devez utiliser le ProductRepositoryInterface::deleteById($sku), mais vous devrez également apporter une modification supplémentaire pour obtenir les autorisations de suppression.

Notez que la zone Admin gère cela en créant la configuration suivante dans 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\Allowedclasse empêche une vérification des autorisations en retournant simplement truela isAllowedméthode.

Sans la modification ci-dessus en di.xml, la Magento\Framework\Model\ActionValidator\RemoveActionclasse sera utilisée, ce qui entraînera l'échec de votre demande de suppression à moins qu'elle ne $this->registry->registry('isSecureArea')soit définie sur true.

Il semble que vous essayiez de créer des commandes de console et je ne les connais pas encore très bien, donc votre meilleur pari pour le moment est peut-être de configurer le registre pour autoriser l'opération de suppression et de refactoriser plus tard si une solution plus propre est trouvée.

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

son fonctionnement très bien. J'espère que j'obtiendrai une certaine clarté pourquoi devrais-je utiliser ProductRepository.m pendant que j'essaierai de rechercher l'utilisation de cette classe dans devdocs.
sivakumar

Idéalement utiliser https://github.com/magento/magento2/blob/develop/app/code/Magento/Catalog/Api/ProductRepositoryInterface.phpcar c'est une API publique et donc plus stable.
Chris O'Toole

6

J'ai récemment rencontré ce problème lors de l'écriture d'une commande de console pour supprimer des catégories vides.

Comme indiqué dans une autre réponse, vous devez vous inscrire 'isSecureArea'sur true.

Pour ce faire dans une commande de console, vous devez avoir la classe Magento \ Framework \ Registry passée dans votre constructeur.

Dans mon cas, j'ai fait de cette façon:

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


    parent::__construct();
}

puis dans la executeméthode, j'ai utilisé le référentiel pour effectuer la suppression réelle:

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


4

si vous utilisez un script, veuillez créer l'objet de registre comme indiqué ci-dessous.

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

Veuillez cliquer ici pour une explication détaillée. http://www.pearlbells.co.uk/mass-delete-magento-2-categories-programmatically/

s'il s'agit d'un script à usage unique, vous pouvez utiliser OM


Merci Bro, bon travail!
David Duong

2

Développant la réponse de Chris O'Toole. J'ai aussi besoin de supprimer des catégories d'une commande, en fait de plusieurs commandes. Au départ juste avoir

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

dans une commande a bien fonctionné, mais quand je l'ai mis dans plusieurs commandes (dans le constructeur) j'ai eu cette erreur lors de la compilation

La clé de registre "isSecureArea" existe déjà

La première vérification de l'existence de la clé de registre l'a résolu

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

Je ne sais pas si c'est une mauvaise forme de mettre cela dans le constructeur, mais supposez que c'est la raison pour laquelle l'erreur a été rencontrée. Alternativement, vous devriez être en mesure d'exécuter le premier extrait à partir des executeméthodes de vos commandes . Encore une fois, je ne suis pas sûr de ce qui est considéré comme la meilleure pratique ...


1

Pour les opérations avec le produit, vous devez utiliser le référentiel.

Magento\Catalog\Model\ProductRepository

2
merci pour votre response.now j'obtiens l'erreur suivante. [Magento \ Framework \ Exception \ StateException] Impossible de supprimer le produit samsung
sivakumar

@sivakumar même erreur. l'avez-vous réparé? C'était il y a longtemps mais de toute façon: D
Giga Todadze

1

Au lieu de définir isSecureArea, vous pouvez également permettre de supprimer un seul type d'objet en remplaçant les RemoveActionarguments de type dans votre di.xmlcomme ceci:

<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>
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.