Operacja usuwania jest zabroniona dla bieżącego obszaru

10

Chcę utworzyć polecenie operacji usuwania dla prostego produktu przez sku. Otrzymuję następujący komunikat o błędzie. Jak ustawić obszar administratora?

[Magento \ Framework \ Exception \ LocalizedException]
Operacja usuwania jest zabroniona dla bieżącego obszaru

<?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
źródło

Odpowiedzi:

12

Zgadzam się z Maxem, że powinieneś użyć ProductRepositoryInterface::deleteById($sku), ale musisz także wprowadzić dodatkową zmianę, aby uzyskać uprawnienia do usunięcia.

Zauważ, że obszar administracyjny obsługuje to, tworząc następującą konfigurację w app/code/Magento/Backend/etc/adminhtml/di.xml

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

Magento\Framework\Model\ActionValidator\RemoveAction\AllowedKlasa uniemożliwia sprawdzenie uprawnień po prostu powrót truedo isAllowedmetody.

Bez powyższej zmiany w pliku di.xml Magento\Framework\Model\ActionValidator\RemoveActionzostanie użyta klasa, co spowoduje niepowodzenie żądania usunięcia, chyba że $this->registry->registry('isSecureArea')zostanie ustawiona wartość true.

Wygląda na to, że próbujesz utworzyć niektóre polecenia konsoli i nie jestem jeszcze z nimi zaznajomiony, więc najlepszym rozwiązaniem na razie może być ustawienie rejestru tak, aby zezwalał na operację usuwania i refaktoryzacja później, jeśli zostanie znalezione czystsze rozwiązanie.

$this->registry->register('isSecureArea', true)
Chris O'Toole
źródło
działa dobrze. mam nadzieję, że uzyskam trochę jasności, dlaczego powinienem używać ProductRepository.mean, podczas gdy spróbuję wyszukać użycie tej klasy w devdocs.
sivakumar
Idealnie https://github.com/magento/magento2/blob/develop/app/code/Magento/Catalog/Api/ProductRepositoryInterface.phpnadaje się, ponieważ jest to publiczny interfejs API, a zatem jest bardziej stabilny.
Chris O'Toole,
6

Ostatnio miałem ten problem podczas pisania polecenia konsoli, aby usunąć puste kategorie.

Jak powiedziano w innej odpowiedzi, musisz się zarejestrować, 'isSecureArea'aby uzyskać wartość true.

Aby to zrobić w poleceniu konsoli, musisz mieć klasę Magento \ Framework \ Registry przekazaną do twojego konstruktora.

W moim przypadku zrobiłem w ten sposób:

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


    parent::__construct();
}

a następnie w executemetodzie użyłem repozytorium do faktycznego usunięcia:

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

Mir
źródło
4

jeśli używasz skryptu, utwórz obiekt rejestru, jak pokazano poniżej.

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

Kliknij tutaj, aby uzyskać szczegółowe wyjaśnienia. http://www.pearlbells.co.uk/mass-delete-magento-2-categories-programmatically/

jeśli jest to skrypt jednorazowy, możesz użyć OM

Liz Eipe C.
źródło
Dziękuję Bro, Dobra robota!
David Duong,
2

Rozwijając odpowiedź Chrisa O'Toole'a. Ja też muszę usunąć kategorie z polecenia, a właściwie z wielu poleceń. Początkowo tylko

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

w jednym poleceniu działało dobrze, ale kiedy wstawiłem to do wielu poleceń (w konstruktorze), dostałem ten błąd podczas kompilacji

Klucz rejestru „isSecureArea” już istnieje

Pierwsze sprawdzenie istnienia klucza rejestru rozwiązało go

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

Nie jestem pewien, czy umieszczenie tego w konstruktorze jest złe, ale załóżmy, że właśnie dlatego napotkano błąd. Alternatywnie powinieneś być w stanie uciec od uruchomienia pierwszego fragmentu kodu z executemetod poleceń . Ponownie nie jestem pewien, co uważa się za najlepszą praktykę ...

szybka zmiana
źródło
1

Do operacji z produktem należy użyć repozytorium.

Magento\Catalog\Model\ProductRepository
Max Jekaterynenko
źródło
2
dziękuję za odpowiedź. teraz otrzymuję następujący błąd. [Magento \ Framework \ Exception \ StateException] Nie można usunąć produktu samsung
sivakumar
@ sivakumar sam błąd. naprawiłeś to? To było dawno, ale tak czy inaczej: D
Giga Todadze
1

Zamiast ustawienia isSecureArea możesz także zezwolić na usunięcie jednego typu obiektu, zastępując RemoveActionargumenty typu w di.xmlpodobny sposób:

<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>
wróbel
źródło