1

In my custom module, my Grid Records are deleting perfect without applying filter. When i apply filter on grid records and try to delete only filtered records, it not only delete filtered records but other records also gets deleted and grid gets empty.

<?php

namespace Vendor\Module\Controller\Adminhtml;
use Magento\Framework\Model\ResourceModel\Db\Collection\AbstractCollection;
use Magento\Framework\Controller\ResultFactory;

class AbstractMassDelete extends \Magento\Backend\App\Action
{

const REDIRECT_URL = '*/*/';

protected $collection = 'Magento\Framework\Model\Resource\Db\Collection\AbstractCollection';

protected $model = 'Magento\Framework\Model\AbstractModel';
protected $cat = false;

/**
 * Execute action
 *
 * @return \Magento\Backend\Model\View\Result\Redirect
 * @throws \Magento\Framework\Exception\LocalizedException|\Exception
 */
public function execute()
{

    $selected = $this->getRequest()->getParam('selected');
    $excluded = $this->getRequest()->getParam('excluded');

    try {
        if (isset($excluded)) {
            if (!empty($excluded) && is_array($excluded)) {
                $this->excludedDelete($excluded);
            } else {
                $this->deleteAll();
            }
        } elseif (!empty($selected)) {
            $this->selectedDelete($selected);
        } else {
            $this->messageManager->addError(__('Please select item(s).'));
        }
    } catch (\Exception $e) {
        $this->messageManager->addError($e->getMessage());
    }


    $resultRedirect = $this->resultFactory->create(ResultFactory::TYPE_REDIRECT);
    return $resultRedirect->setPath(static::REDIRECT_URL);
}

/**
 * Delete all
 *
 * @return void
 * @throws \Exception
 */
protected function deleteAll()
{
    /** @var AbstractCollection $collection */
    $collection = $this->_objectManager->get($this->collection);
    $this->delete($collection, true);
}

/**
 * Delete all but the not selected
 *
 * @param array $excluded
 * @return void
 * @throws \Exception
 */
protected function excludedDelete(array $excluded)
{
    /** @var AbstractCollection $collection */
    $collection = $this->_objectManager->get($this->collection);
    $collection->addFieldToFilter(static::ID_FIELD, ['nin' => $excluded]);
    $this->delete($collection);
}

/**
 * Delete selected items
 *
 * @param array $selected
 * @return void
 * @throws \Exception
 */
protected function selectedDelete(array $selected)
{
    /** @var AbstractCollection $collection */
    $collection = $this->_objectManager->get($this->collection);
    $collection->addFieldToFilter(static::ID_FIELD, ['in' => $selected]);
    $this->delete($collection);
}

/**
 * Delete collection items
 *
 * @param AbstractCollection $collection
 * @return int
 */
protected function delete(AbstractCollection $collection, $all = false)
{
    $count = 0;
    if ($all) {
        $count = $collection->getSize();

        foreach ($collection as $item) {
            $item->delete();
        }
    }
    foreach ($collection->getAllIds() as $id) {
        /** @var \Magento\Framework\Model\AbstractModel $model */
        if ($this->cat) {
            $msg = $this->_objectManager->create('Vendor\Module\Model\Productcats')->deleteCategory($id);
        } else {
            $msg = null;
        }
        if ($msg != null) {
            $this->messageManager->addError($msg);
            return;
        } else {
            $model = $this->_objectManager->get($this->model);
            $model->load($id);
            $model->delete();
            ++$count;
        }
    }
    $this->setSuccessMessage($count);
    return $count;
}

/**
 * Set error messages
 *
 * @param int $count
 * @return void
 */
protected function setSuccessMessage($count)
{
    $this->messageManager->addSuccess(__('A total of %1 record(s) have been deleted.', $count));
}

protected function _isAllowed()
{
    return true;
}
}

1 Answer 1

0

1) you should directly address the ObjectManager, you should create a __construct and use direct injection. Here's an example where I'm injecting RuleFactory into one of my controller actions.

public function __construct(
    Context $context,
    PageFactory $resultPageFactory,
    ForwardFactory $resultForwardFactory,
    JsonFactory $resultJsonFactory,
    Registry $registry,
    ManagerInterface $messageManager,
    RuleFactory $ruleFactory
) {
    $this->_coreRegistry = $registry;
    $this->_messageManager = $messageManager;
    $this->_ruleFactory = $ruleFactory;

    parent::__construct($context);

    $this->resultPageFactory = $resultPageFactory;
    $this->resultForwardFactory = $resultForwardFactory;
    $this->resultJsonFactory = $resultJsonFactory;
}

2) Use the PHP use statement to shorted very long path names and make code readable and easier to maintain.

3) Look at the new ui_component methods for MassAction, they don't use the concept of passing an array of IDS back to the controller action.

Here's a link to a good example

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.