Why am I getting a DataProvider\Document instance in mass deletion?

613 views Asked by At

I am using Magento 2.4 and I want to add a custom admin Grid for company products. The problem is that I get a an error when I want to perform a mass delete action. The problem appears in my action

MassDelete.php

<?php

declare(strict_types=1);

namespace MyDomain\BestSelling\Controller\Adminhtml\Products;

use Exception;
use Magento\Backend\App\Action;
use Magento\Backend\Model\View\Result\Redirect;
use Magento\Catalog\Api\ProductRepositoryInterface;
use Magento\Framework\App\Action\HttpPostActionInterface;
use Magento\Framework\App\ObjectManager;
use Magento\Framework\Controller\ResultFactory;
use Magento\Backend\App\Action\Context;
use Magento\Framework\Exception\LocalizedException;
use Magento\Ui\Component\MassAction\Filter;
use MyDomain\BestSelling\Api\MyProductRepositoryInterface;
use MyDomain\BestSelling\Model\ResourceModel\Products\Grid\CollectionFactory as MyProductsFactory;
Use MyDomain\BestSelling\Model\Products\MyProduct as MyProductModel;
use MyDomain\BestSelling\Model\ResourceModel\Products\MyProduct as MyProductRessource;
use Psr\Log\LoggerInterface;

class MassDelete extends Action implements HttpPostActionInterface
{
    /**
     * @var Filter
     */
    protected $filter;

    /**
     * @var MyProductsFactory
     */
    protected $collectionFactory;
    /**
     * @var MyProductRessource
     */
    private $ressource;

    /**
     * @var MyProductRepositoryInterface
     */
    protected $productRepository;
    /**
     * @var LoggerInterface
     */
    private $logger;

    /**
     * @param Context $context
     * @param Filter $filter
     * @param MyProductsFactory $collectionFactory
     */
    public function __construct(
        Context $context,
        Filter $filter,
        MyProductsFactory $collectionFactory,
        MyProductRessource $ressource,
        LoggerInterface $logger,
        MyProductRepositoryInterface $productRepository
    )
    {
        parent::__construct($context);
        $this->productRepository = $productRepository;
        $this->filter = $filter;
        $this->collectionFactory = $collectionFactory;
        $this->ressource = $ressource;
        $this->logger = $logger;
    }
    /**
     * Execute action
     *
     * @return Redirect
     * @throws LocalizedException|Exception
     */
    public function execute()
    {
        $collection = $this->filter->getCollection($this->collectionFactory->create());
        $collectionSize = $collection->getSize();

        foreach ($collection->getItems() as $product) {
            try {
                $this->productRepository->delete($product);
            } catch (LocalizedException $exception) {
                $this->logger->error($exception->getLogMessage());
            }

            $this->messageManager->addSuccess(__('A total of %1 record(s) have been deleted.', $collectionSize));

            /** @var Redirect $resultRedirect */
            $resultRedirect = $this->resultFactory->create(ResultFactory::TYPE_REDIRECT);
            return $resultRedirect->setPath('*/*/');
        }
    }
}

In the the execute() method I am trying to delete the products with $this->productRepository->delete($product); but then I am getting the error message:

TypeError: Argument 1 passed to MyDomain\BestSelling\Model\Products\MyProductRepository::delete() must be an instance of MyDomain\BestSelling\Api\Data\MyProductInterface, instance of Magento\Framework\View\Element\UiComponent\DataProvider\Document given

Could it be that my Data Provider doesnt provide what I actually need? Here are my configurations:

UI-Component: best_selling_products_listing.xml

<listing xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:noNamespaceSchemaLocation="urn:magento:module:Magento_Ui:etc/ui_configuration.xsd">

    <argument name="data" xsi:type="array">
        <item name="js_config" xsi:type="array">
            <item name="provider"
                  xsi:type="string">best_selling_products_listing.best_selling_products_listing_data_source
            </item>
            <item name="deps"
                  xsi:type="string">best_selling_products_listing.best_selling_products_listing_data_source
            </item>
        </item>
        <item name="spinner" xsi:type="string">spinner_columns</item>
        <item name="buttons" xsi:type="array">
            <item name="add" xsi:type="array">
                <item name="name" xsi:type="string">add</item>
                <item name="label" xsi:type="string" translate="true">Add New Post</item>
                <item name="class" xsi:type="string">primary</item>
                <item name="url" xsi:type="string">*/*/addproduct</item>
            </item>
        </item>
    </argument>

    <dataSource name="best_selling_products_listing_data_source">
        <argument name="dataProvider" xsi:type="configurableObject">
            <argument name="class"
                      xsi:type="string">Magento\Framework\View\Element\UiComponent\DataProvider\DataProvider
            </argument>
            <argument name="name" xsi:type="string">best_selling_products_listing_data_source</argument>
            <argument name="primaryFieldName" xsi:type="string">id</argument>
            <argument name="requestFieldName" xsi:type="string">id</argument>
            <argument name="data" xsi:type="array">
                <item name="config" xsi:type="array">
                    <item name="component" xsi:type="string">Magento_Ui/js/grid/provider</item>
                    <item name="update_url" xsi:type="url" path="mui/index/render"/>
                    <item name="storageConfig" xsi:type="array">
                        <item name="indexField" xsi:type="string">id</item>
                    </item>
                </item>
            </argument>
        </argument>
    </dataSource>

    <listingToolbar name="listing_top">
        <argument name="data" xsi:type="array">
            <item name="config" xsi:type="array">
                <item name="sticky" xsi:type="boolean">true</item>
            </item>
        </argument>

        <bookmark name="bookmarks"/>
        <columnsControls name="columns_controls"/>
        <exportButton name="export_button"/>
        <filters name="listing_filters" />
        <filterSearch name="fulltext"/>

        <massaction name="listing_massaction">
            <argument name="data" xsi:type="array">
                <item name="config" xsi:type="array">
                    <item name="component" xsi:type="string">Magento_Ui/js/grid/tree-massactions</item>
                </item>
            </argument>
            <action name="delete">
                <argument name="data" xsi:type="array">
                    <item name="config" xsi:type="array">
                        <item name="type" xsi:type="string">delete</item>
                        <item name="label" xsi:type="string" translate="true">Delete</item>
                        <item name="url" xsi:type="url" path="best_selling/products/massDelete"/>
                        <item name="confirm" xsi:type="array">
                            <item name="title" xsi:type="string" translate="true">Delete Post</item>
                            <item name="message" xsi:type="string" translate="true">Are you sure you wan't to delete selected items?</item>
                        </item>
                    </item>
                </argument>
            </action>
        </massaction>

        <paging name="listing_paging"/>

    </listingToolbar>

    <columns name="spinner_columns">

        <selectionsColumn name="ids">
            <argument name="data" xsi:type="array">
                <item name="config" xsi:type="array">
                    <item name="resizeEnabled" xsi:type="boolean">false</item>
                    <item name="resizeDefaultWidth" xsi:type="string">55</item>
                    <item name="indexField" xsi:type="string">id</item>
                </item>
            </argument>
        </selectionsColumn>

        <column name="id">
            <argument name="data" xsi:type="array">
                <item name="config" xsi:type="array">
                    <item name="filter" xsi:type="string">textRange</item>
                    <item name="sorting" xsi:type="string">asc</item>
                    <item name="label" xsi:type="string" translate="true">ID</item>
                </item>
            </argument>
        </column>

        <column name="name">
            <argument name="data" xsi:type="array">
                <item name="config" xsi:type="array">
                    <item name="filter" xsi:type="string">text</item>
                    <item name="editor" xsi:type="array">
                        <item name="editorType" xsi:type="string">text</item>
                        <item name="validation" xsi:type="array">
                            <item name="required-entry" xsi:type="boolean">true</item>
                        </item>
                    </item>
                    <item name="label" xsi:type="string" translate="true">Name</item>
                </item>
            </argument>
        </column>

        <column name="price">
            <argument name="data" xsi:type="array">
                <item name="config" xsi:type="array">
                    <item name="filter" xsi:type="string">text</item>
                    <item name="editor" xsi:type="array">
                        <item name="editorType" xsi:type="string">text</item>
                        <item name="validation" xsi:type="array">
                            <item name="required-entry" xsi:type="boolean">true</item>
                        </item>
                    </item>
                    <item name="label" xsi:type="string" translate="true">Price</item>
                </item>
            </argument>
        </column>

    </columns>

    <button name="my_new_button">
        <argument name="data" xsi:type="array">
            <item name="config" xsi:type="array">
                <item name="actions" xsi:type="array">
                    <!-- Add your button's actions here -->
                    <item name="0" xsi:type="array">
                        <item name="targetName" xsi:type="string">TARGET_NAME</item>
                        <item name="actionName" xsi:type="string">ACTION_NAME</item>
                    </item>
                </item>
            </item>
        </argument>
        <settings>
            <displayAsLink>false</displayAsLink>
            <title><![CDATA[Test Button]]></title>
        </settings>
    </button>

</listing>

Layout: best_selling_products_index.xml

<?xml version="1.0" ?>
<page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:View/Layout/etc/page_configuration.xsd">
    <update handle="styles"/>
    <body>
        <referenceContainer name="content">
            <uiComponent name="best_selling_products_listing"/>
        </referenceContainer>
    </body>
</page>

Dependencies: 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\View\Element\UiComponent\DataProvider\CollectionFactory">
        <arguments>
            <argument name="collections" xsi:type="array">
                <item name="best_selling_products_listing_data_source" xsi:type="string">MyDomain\BestSelling\Model\ResourceModel\Products\Grid\Collection</item>
            </argument>
        </arguments>
    </type>
    <virtualType name="MyDomain\BestSelling\Model\ResourceModel\Products\Grid\Collection" type="Magento\Framework\View\Element\UiComponent\DataProvider\SearchResult">
        <arguments>
            <argument name="mainTable" xsi:type="string">mydomain_bestselling_my_products</argument>
            <argument name="resourceModel" xsi:type="string">MyDomain\BestSelling\Model\ResourceModel\Products\MyProduct</argument>
        </arguments>
    </virtualType>
</config>

Collection: Collection.php

<?php

declare(strict_types=1);

namespace MyDomain\BestSelling\Model\ResourceModel\Products\Grid;


use Magento\Framework\Model\ResourceModel\Db\Collection\AbstractCollection;
use MyDomain\BestSelling\Model\Products\MyProduct as MyProductModel;
use MyDomain\BestSelling\Model\ResourceModel\Products\MyProduct as MyProductResource;

class Collection extends AbstractCollection
{
    protected function _construct()
    {
        $this->_init(MyProductModel::class, MyProductResource::class);
    }
}

0

There are 0 answers