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>
sivakumar
la source

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)
Chris O'Toole
la source
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());

Mir
la source
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

Liz Eipe C
la source
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 ...

quickshiftin
la source
1

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

Magento\Catalog\Model\ProductRepository
Max Yekaterynenko
la source
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>
moineau
la source