KoolReport's Forum

Official Support Area, Q&As, Discussions, Suggestions and Bug reports.
Forum's Guidelines

Admin Panel: how to override deleteRecord function #3300

Closed Eugene opened this topic on on May 23 - 3 comments

Eugene commented on May 23

Hi, team

I tried to create my own deleteRecord() function. I have added it to my Resource file but It looks like it is not executed at all. It does not have any code to delete records now but the records is still deleted (I commented it for the testing )... magic...

So what am I doing wrong?

My Resource code (a part):

<?php

namespace...\Special\WineReport\Admin\Resources;

use ...\DB\Database;
use koolreport\dashboard\admin\actions\DeleteAction;
use koolreport\dashboard\admin\actions\DetailAction;
use koolreport\dashboard\admin\actions\InlineEditAction;
use koolreport\dashboard\admin\actions\UpdateAction;
use koolreport\dashboard\admin\relations\HasMany;
use \koolreport\dashboard\admin\Resource;
use \koolreport\dashboard\fields\ID;
use \koolreport\dashboard\fields\Text;


class WineCategory extends Resource
{
    protected function onCreated()
    {
        $this->manageTable('wine_categories')->inSource(Database::class);
    }
    protected function actions()
    {
        return [
            DetailAction::create(),
            UpdateAction::create(),
            DeleteAction::create()->enabled(function () {
                //Only allow delete if user is admin
                return $this->app()->user()->hasRole('admin');
            }),
        ];
    }
    protected function fields()
    {
        return [
            ID::create('category_id')
                ->label('id')
                ->sortable(true)
                ->showOnUpdate(false)
                ->showOnCreate(false),
            Text::create('category_name'),
        ];
    }

  
    public function deleteRecord($ids)
    {
        $idColName = $this->getIDField()->colName();
        if ($idColName === null) {
            throw new \Exception('ID field is required');
        }

//        $query = $this->getQuery()->whereIn($idColName, $ids)->delete();
//        if ($query->run() === false) {
//            throw new \Exception('[SQL Error] ' . $query->errorMessage() . ' : ' . $query);
//        }
        return true;
    }


}
KoolReport commented on May 24

You are right, the real query execution is in the DeleteAction manualHandle function, and the way to handle custom delete is to create your own action or override the DeleteAction.

Previously the Resource does not have the deleteRecord or deleteRecordByConditions method. Later we think this function might be needed so we added for developer to be faster in CRUD.

BUT, we have not linked the DeleteAction with the deleteRecord() function, that's why there is no effect when you overwrite the deleteRecord.

I will mark your question as suggestion.

Eugene commented on May 24

hehe... it is not a suggestion it is a bug ;-))) because you have declared this feature in your documentation already. But ok :-))

Well, I need your advice. The situation is like this. I have 2 tables Items and Categories. The Item has a relationship with Categories. So if any category is used in the Item table, this category cannot be deleted. So when I try to delete it I got Integrity constraint violation SQL error. It is not good for my users, so my idea was to check Integrity constraint before deleting it. I planned to do it in the overrided deleteRecord function

I think it is usual case in databases with the relationship, so what is the solution?

KoolReport commented on May 24

Let do this:

Create a custom DeleteAction:

<?php

namespace wine;

use koolreport\dashboard\admin\screens\DetailScreen;
use koolreport\dashboard\admin\screens\ListScreen;
use koolreport\dashboard\Client;
use koolreport\dashboard\Lang;
use koolreport\dashboard\notifications\Alert;
use koolreport\dashboard\notifications\Note;

class DeleteAction extends Action
{
    protected function beforeOnCreated()
    {
        parent::beforeOnCreated();
        $this
        ->type("danger")
        ->needConfirmation(true)
        ->showOnActionBox(true)
        ->showOnTable(true)
        ->showOnDetail(true)
        ->icon("far fa-trash-alt")
        ->title(Lang::t("Delete"));
        $this->confirmModal()->title($this->title());        
    }

    protected function handle($form,$models)
    {
        $ids = $models->pluck($this->resource()->getIDField()->name());

        if($this->resource()->deleteRecords($ids)===false)
        {
                return Note::danger("Failed to delete");
        }
        //When successful, below are just notification depending on screen that delete action is taken.
            if($this->resource()->screen() instanceof ListScreen) {
                $this->resource()->listScreen()->adminTable()->update();
                return Note::success(Lang::t("The record has been deleted"), Lang::t("Successful"));
            } else if ($this->resource()->screen() instanceof DetailScreen) {
                return Client::historyBack();
            } else if ($this->actionHost()!==null) {
                $this->actionHost()->update();
            }

    }

}

Now you use this wine\DeleteAction instead of original DeleteAction in actions() methods.

Lastly, you overwrite the deleteRecord($ids) in WineCategory as you planned.

Hope that helps.

Build Your Excellent Data Report

Let KoolReport help you to make great reports. It's free & open-source released under MIT license.

Download KoolReport View demo
suggestion

None