Das Löschen ist für den aktuellen Bereich verboten


10

Ich möchte einen Befehl zum Löschen eines einfachen Produkts von sku erstellen. Ich erhalte folgenden Fehler. Wie stelle ich den Admin-Bereich ein?

[Magento \ Framework \ Exception \ LocalizedException] Der
Löschvorgang ist für den aktuellen Bereich verboten

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

Antworten:


12

Stimmen Sie Max zu, dass Sie das verwenden sollten ProductRepositoryInterface::deleteById($sku), aber Sie müssen auch eine zusätzliche Änderung vornehmen, um die Berechtigungen zum Löschen zu erhalten.

Beachten Sie, dass der Admin-Bereich dies erledigt, indem Sie die folgende Konfiguration in erstellen app/code/Magento/Backend/etc/adminhtml/di.xml

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

Die Magento\Framework\Model\ActionValidator\RemoveAction\AllowedKlasse verhindert eine Berechtigungsprüfung, indem sie einfach truedie isAllowedMethode zurückgibt.

Ohne die obige Änderung an di.xml wird die Magento\Framework\Model\ActionValidator\RemoveActionKlasse verwendet, wodurch Ihre Löschanforderung fehlschlägt, sofern sie nicht $this->registry->registry('isSecureArea')auf true gesetzt ist.

Es sieht so aus, als würden Sie versuchen, einige Konsolenbefehle zu erstellen, und ich bin noch nicht sehr vertraut mit ihnen. Daher ist es möglicherweise am besten, die Registrierung so einzustellen, dass der Löschvorgang und das Refactor später möglich sind, wenn eine sauberere Lösung gefunden wird.

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

Ich hoffe, ich bekomme Klarheit darüber, warum ich ProductRepository verwenden soll. In der Zwischenzeit werde ich versuchen, die Verwendung dieser Klasse in Devdocs zu suchen.
Sivakumar

Idealerweise verwenden, https://github.com/magento/magento2/blob/develop/app/code/Magento/Catalog/Api/ProductRepositoryInterface.phpda es sich um eine öffentliche API handelt und daher stabiler ist.
Chris O'Toole

6

Ich hatte kürzlich dieses Problem beim Schreiben eines Konsolenbefehls zum Löschen leerer Kategorien.

Wie in einer anderen Antwort gesagt, müssen Sie sich 'isSecureArea'auf true registrieren .

Dazu muss in einem Konsolenbefehl die Klasse Magento \ Framework \ Registry an Ihren Konstruktor übergeben werden.

In meinem Fall habe ich Folgendes getan:

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


    parent::__construct();
}

und dann habe executeich in der Methode das Repository verwendet, um das eigentliche Löschen durchzuführen:

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


3

Wenn Sie ein Skript verwenden, erstellen Sie bitte das Registrierungsobjekt wie unten gezeigt.

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

Bitte klicken Sie hier für eine detaillierte Erklärung. http://www.pearlbells.co.uk/mass-delete-magento-2-categories-programmatic/

Wenn es sich um ein einmaliges Skript handelt, können Sie OM verwenden


Danke Bro, gute Arbeit!
David Duong

2

Erweiterung der Antwort von Chris O'Toole. Ich muss auch Kategorien aus einem Befehl löschen, tatsächlich aus mehreren Befehlen. Anfangs nur mit

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

in einem Befehl hat gut funktioniert, aber als ich das in mehrere Befehle (im Konstruktor) eingefügt habe, habe ich diesen Fehler beim Kompilieren bekommen

Der Registrierungsschlüssel "isSecureArea" ist bereits vorhanden

Die erste Überprüfung auf das Vorhandensein des Registrierungsschlüssels löste das Problem

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

Ich bin mir nicht sicher, ob es eine schlechte Form ist, das in den Konstruktor zu schreiben, aber nehme an, dass der Fehler deshalb aufgetreten ist. Alternativ sollten Sie in der Lage sein, das erste Snippet aus den executeMethoden Ihrer Befehle auszuführen . Auch hier bin ich mir nicht sicher, was als Best Practice gilt ...


1

Für Vorgänge mit Produkten müssen Sie das Repository verwenden.

Magento\Catalog\Model\ProductRepository

2
Vielen Dank für Ihre Antwort. Jetzt wird folgende Fehlermeldung angezeigt: [Magento \ Framework \ Exception \ StateException] Produkt Samsung
Sivakumar

@sivakumar gleichen Fehler. Hast du es repariert? Es ist lange her, aber trotzdem: D
Giga Todadze

1

Stattdessen isSecureArea der Einstellung können Sie auch eine einzige Art von Objekt zu entfernen , lassen nach Art zwingende RemoveActionin Ihre Argumente di.xmlwie folgt aus :

<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>
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.