where's Callback after ,before insert,update etc #51

Closed
c1t1zen opened this Issue Jul 5, 2016 · 15 comments

Projects

None yet

6 participants

@c1t1zen
c1t1zen commented Jul 5, 2016

Hello!
am trying to use this package but it does not support edit like grocery crud

there are not Callbacks of after ,before insert,update ,delete etc

i tryed for example to rename file for elfinder but i can not i have been searching for 4-5 days

even i tried to make custom field image but with no luck

there's no callback available to make more control of coding

please try to add callback or we wont be able to edit or change code for our needs

thank you in advance

@tabacitu
Member
tabacitu commented Jul 5, 2016

Hi @c1t1zen ,

You're right, people are looking for callbacks and I'm considering putting them there, to make it easy for everyone.

But there is a way you can add that functionality, without callbacks, thanks to OOP:

  • say your model is Car;
  • your CarCrudController extends CrudController;
  • so overwriting a CrudController method (and its logic) can be done by just typing it in your CarCrudController, with the same name;

More than that, the update and insert methods are already in your controller, just waiting for you to edit them, but they're called store and update.

If all you want is to rename a file on save, here's how to do it, practically. Look for the comments with "<-----":

<?php namespace App\Http\Controllers\Admin;

use Backpack\CRUD\app\Http\Controllers\CrudController;

// VALIDATION: change the requests to match your own file names if you need form validation
use App\Http\Requests\CarRequest as StoreRequest;
use App\Http\Requests\CarRequest as UpdateRequest;

class CarCrudController extends CrudController {

    public function __construct() {
        parent::__construct();

        /*
        |--------------------------------------------------------------------------
        | BASIC CRUD INFORMATION
        |--------------------------------------------------------------------------
        */
        $this->crud->setModel("App\Models\Car");
        $this->crud->setRoute("admin/car");
        $this->crud->setEntityNameStrings('car', 'cars');

        /*
        |--------------------------------------------------------------------------
        | BASIC CRUD INFORMATION
        |--------------------------------------------------------------------------
        */
        $this->crud->setFromDb();
    }

    public function store(StoreRequest $request)
    {
        // <---------  here is where a before_insert callback logic would be
        $response = parent::storeCrud();
        // <---------  here is where a after_insert callback logic would be
        return $response;
    }

    public function update(UpdateRequest $request)
    {
        // <---------  here is where a before_update callback logic would be
        $response = parent::updateCrud();
        // <---------  here is where a after_update callback logic would be
         return $response;
    }
}

Also, if you want to modify how the actual saving is done, you can do that. You just go the the original CrudController, see the "storeCrud" method and copy whatever you want and modify it in your "store" method.

My thought was this was a more powerful way to do whatever you like with the save process, it's way less restrictive than callbacks, but people HAVE been looking for callbacks, so... I don't know....

@c1t1zen
c1t1zen commented Jul 14, 2016

Thank you alot
maybe more documents solve the callbacks needs

For your code example:

public function store(StoreRequest $request) { // <--------- here is where a before_insert callback logic would be $response = parent::storeCrud(); // <--------- here is where a after_insert callback logic would be return $response; }
before_insert:
when i need to rename the filed ('model_name') before_insert

after_insert:
when i need to get inserted id to make more code or to add new row in another table by the inserted id

i think it's just need some more document and it will be so good

i was working in codeigniter with grocery Crud
maybe this one will be more easier to modify views and other things

thank you alot for good reply

@tabacitu
Member

Glad to help. I'll close the issue then.

I've updated the documentation so people can find the callbacks logic a lot easier now. Cheers!

@tabacitu tabacitu closed this Jul 18, 2016
@c1t1zen
c1t1zen commented Jul 20, 2016

Thank You alot

@pacobabs

HI @tabacitu, nice job. Please can we have an example of how we can access the model values and update it before the parent::storeCrud() method is fired. I don't see a way to do it but i supect it is simple to achieve.
// <--------- here is where a before_insert callback logic would be but i don't see how
$response = parent::storeCrud();

thanks.

@pacobabs

I come with the solution for both but i don't know it's elegant enough.
For the update method in my ModelCrudController

public function update(UpdateRequest $request)
{

    $response = parent::updateCrud();
    $this->crud->update($request->get('id'), $array_of_fields_to_be_updated); // <--after update logic
    return $response;
}

For the store method in my ModelCrudController
I've just gone to the original CrudController, see the "storeCrud" method and copy it and add $item->update($array_of_fields_to_be_updated)) after the create function in the store method.
There must be a better way to achieve it maybe. Thanks.

@tabacitu
Member

HI @pacobabs - that's exactly the way it's intended to be used :-) Instead of callbacks, just overwrite the method you want to change and use its parent as an example.

Cheers!

@gustavenn

HI,
What would be the best way for the Callbacks delete or destroy?

@tabacitu
Member
tabacitu commented Sep 29, 2016 edited

Hi @gustavenn there are no callbacks. Your EntityCrudController extends CrudController, so you have the methods there.

I think the best way to achieve what you want is to define the destroy() method in your controller and do something like

public function destroy($id) {
 // do something before
 $return_value = parent::destroy($id);
 // do something after
 return $return_value;
}
@tabacitu
Member
tabacitu commented Sep 29, 2016 edited

@gustavenn another solution would be to use Eloquent Events to do something every time an entry is deleted for a model - either from CRUD or anywhere else. Personally, I like the "Observer" method more than the ServiceProvider one.

@gustavenn

@tabacitu thanks for your answers! I'll try your suggestions

excellent job!

@PhouvanhKCSV

Hi @tabacitu

How can i get lastInsertId from after_insert callback. Because i want to use the id to insert into another table

public function store(StoreRequest $request)
{
    // <---------  here is where a before_insert callback logic would be
    $response = parent::storeCrud();
    // <---------  here is where a after_insert callback logic would be
    return $response;
}
@tabacitu
Member

@PhouvanhKCSV I think the best way to achieve that would be in the model, using the created event. You'd have $this->id there. But if you really want to do it in the controller, you can replace the contents of your store() method with this:

public function storeCrud(StoreRequest $request = null)
    {
        $this->crud->hasAccessOrFail('create');

        // fallback to global request instance
        if (is_null($request)) {
            $request = \Request::instance();
        }

        // replace empty values with NULL, so that it will work with MySQL strict mode on
        foreach ($request->input() as $key => $value) {
            if (empty($value) && $value !== '0') {
                $request->request->set($key, null);
            }
        }

        // insert item in the db
        $item = $this->crud->create($request->except(['redirect_after_save', '_token']));

        // show a success message
        \Alert::success(trans('backpack::crud.insert_success'))->flash();

        // redirect the user where he chose to be redirected
        switch ($request->input('redirect_after_save')) {
            case 'current_item_edit':
                return \Redirect::to($this->crud->route.'/'.$item->getKey().'/edit');

            default:
                return \Redirect::to($request->input('redirect_after_save'));
        }
    }

But you're right. I'll make a note to store the entry in $this->crud->entry or $this->entry in the next update.

@PhouvanhKCSV
PhouvanhKCSV commented Nov 18, 2016 edited

Thank you for your advice @tabacitu i will take a look at it.

@OwenMelbz
Member

Downside of editing the storeCrud etc is you'll need to maintain this function with new functions.

e.g in 3.2 there is a change which dramatically alters the storeCrud methods.

Personally now I've started using model observers, there is no way im going back to callback hell and maintaining them :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment