Events

Events are the backbone of Crud, and your primary gateway into customization of Crud and fitting it to your applications.

You can subscribe to events from almost everywhere, and in multiple ways.

Controller

implementedEvents

We override the implementedEvents() method in the controller, and bind the Crud.beforeFind event to the _beforeFind() method in the controller.

When using this technique, you need to prefix all the event names with Crud.

Most of the other ways to listen for events do not need this, as it’s done automatically.

namespace app\Controller;

class BlogsController extends AppController
{

    public function implementedEvents()
    {
        return parent::implementedEvents() + ['Crud.beforeFind' => '_beforeFind'];
    }

    public function _beforeFind(\Cake\Event\Event $event)
    {

    }
}

Note

It’s important that the controller event method is public, since it’s called from the CakePHP event manager, outside of the Controller scope.

The added _ prefix is there only to prevent it being executed as an controller action.

Action

You can bind events directly in your controller actions, simply call the on() method in Crud and provide a callback. The example below uses a closure for the callback, but everything that is valid for call_user_func() can be used

public function view($id)
{
  $this->Crud->on('beforeFind', function(\Cake\Event\Event $event) {
      // Will only execute for the view() action
  });

  return $this->Crud->execute();
}

Note

When implementing events in your controller actions, it’s important to include return $this->Crud->execute(); otherwise Crud will not process the action.

The benefit of the controller method is that you can easily share it between two actions, like below.

public function view($id)
{
    $this->Crud->on('beforeFind', [$this, '_beforeFind']);
    return $this->Crud->execute();
}

public function admin_view($id)
{
    $this->Crud->on('beforeFind', [$this, '_beforeFind']);
    return $this->Crud->execute();
}

public function _beforeFind(\Cake\Event\Event $event)
{
    // Will execute for both view() and admin_view()
}

Core Crud Events

Different Crud actions will emit a different combination of events during their execution, with different Subject data. If you are looking for events specific to an action, check the specific Crud action documentation page.

Included actions

This is a full list of all events emitted from Crud.

Crud.beforeFilter

Triggered when a CrudAction is going to handle a CakePHP request.

It’s emitted from CrudComponent::beforeFilter and thus is fired in the same cycle as all Controller::beforeFilter events.

Crud.startup

Called after the Controller::beforeFilter() and before the Crud action.

It’s emitted from CrudComponent::startup() and thus is fired in the same cycle as all Component::startup() events.

Crud.beforeDelete

This event is emitted before calling Table::delete.

The Crud Subject contains the following keys:

  • id The ID of the entity, from the URL
  • item The Entity from the find() call.

To abort a delete() simply stop the event by calling $event->stopPropagation().

Stop Delete
public function delete($id)
{
    $this->Crud->on('beforeDelete', function(\Cake\Event\Event $event) {
        // Stop the delete event, the entity will not be deleted
        if ($event->getSubject()->item->author !== 'admin') {
            $event->stopPropagation();
        }
    });

    return $this->Crud->execute();
}

Crud.afterDelete

This event is emitted after Table::delete() has been called.

The Crud Subject contains two keys:

  • success if true the delete() call succeeded, false otherwise
  • id The ID that was originally passed to the action and is usually the primary key of your model.
  • item The record that was found in the database.
Check Success
public function delete($id)
{
    $this->Crud->on('afterDelete', function(\Cake\Event\Event $event) {
        if (!$event->getSubject()->success) {
            $this->log("Delete failed for entity " . $event->getSubject()->id);
        }
    });

    return $this->Crud->execute();
}

Crud.beforeFind

The event is emitted before calling the find method in the table.

The Crud Subject contains the following keys:

  • id The ID that was originally passed to the action and usually the primary key value of your table.
  • repository An instance of the Repository (Table) which the query will be executed against.
  • query A Query object from the Repository where $PrimaryKey => $IdFromRequest is already added to the conditions.

This is the last place you can modify the query before it’s executed against the database.

Note

An example

Given the URL: /posts/view/10 the repository object will be an instance of PostsTable and the query includes a WHERE condition with Posts.id = 10

After the event has emitted, the database query is executed with LIMIT 1.

If a record is found the Crud.afterFind event is emitted.

Warning

If no record is found in the database, the recordNotFound event is emitted instead of Crud.afterFind.

Add Conditions
public function delete($id)
{
    $this->Crud->on('beforeFind', function(\Cake\Event\Event $event) {
        $event->getSubject()->query->where(['author' => $this->Auth->user('id')]);
    });

    return $this->Crud->execute();
}

Crud.afterFind

After the query has been executed, and a record has been found this event is emitted.

The Crud Subject contains two keys:

  • id The ID that was originally passed to the action and is usually the primary key of your model.
  • entity The record that was found in the database.

Note

If an entity is not found, the RecordNotFound event is emitted instead.

Logging the Found Item
public function delete($id)
{
    $this->Crud->on('afterFind', function(\Cake\Event\Event $event) {
        $this->log("Found item: " . $event->getSubject()->entity->id . " in the database");
    });

    return $this->Crud->execute();
}

Crud.beforeSave

Note

Do not confuse this event with the beforeSave callback in the ORM layer

Called right before calling Table::save().

The Crud Subject contains the following keys:

  • entity An entity object marshaled with the HTTP POST data from the request.
  • saveMethod A string with the saveMethod.
  • saveOptions An array with the saveOptions.

All modifications to these keys will be passed into the Table::$saveMethod.

Warning

After this event has been emitted, changes done through the $action->saveMethod() or $action->saveOptions() methods will no longer affect the code, as the rest of the code uses the values from the Crud Subject

Crud.afterSave

Note

Do not confuse this event with the afterSave callback in the ORM layer.

This event is emitted right after the call to Table::save().

The Crud Subject contains the following keys:

  • id The newly inserted ID. It’s only available if the call to Table::save() was successful.
  • success indicates whether or not the Table::save() call succeed or not.
  • created true if the record was created and false if the record was updated.
  • entity An entity object marshaled with the HTTP POST data from the request and the save() logic.
Check Created Status
public function edit($id)
{
    $this->Crud->on('afterSave', function(\Cake\Event\Event $event) {
        if ($event->getSubject()->created) {
            $this->log("The entity was created");
        } else {
            $this->log("The entity was updated");
        }
    });

    return $this->Crud->execute();
}
Check Success Status
public function edit($id)
{
    $this->Crud->on('afterSave', function(\Cake\Event\Event $event) {
        if ($event->getSubject()->success) {
            $this->log("The entity was saved successfully");
        } else {
            $this->log("The entity was NOT saved successfully");
        }
    });

    return $this->Crud->execute();
}
Get Entity ID
public function add()
{
    $this->Crud->on('afterSave', function(\Cake\Event\Event $event) {
        if ($event->getSubject()->created) {
            $this->log("The entity was created with id: " . $event->getSubject()->id);
        }
    });

    return $this->Crud->execute();
}

Crud.beforePaginate

This event is emitted before Controller::paginate() is called.

Add Conditions
public function index()
{
    $this->Crud->on('beforePaginate', function(\Cake\Event\Event $event) {
        $this->paginate['conditions']['is_active'] = true;
    });

    return $this->Crud->execute();
}

Crud.afterPaginate

This event is emitted right after the call to Controller::paginate().

The entities property of the event object contains all the database records found in the pagination call.

Modify the Result
public function index()
{
    $this->Crud->on('afterPaginate', function(\Cake\Event\Event $event) {
        foreach ($event->getSubject()->entities as $entity) {
            // $entity is an entity
        }
    });

    return $this->Crud->execute();
}

Crud.beforeRedirect

Simple and event driven wrapper for Controller::redirect().

The Crud Subject contains the following keys:

  • url The 1st argument to Controller::redirect().
  • status The 2nd argument to Controller::redirect().
  • exit The 3rd argument to Controller::redirect().
  • entity (Optional) The Entity from the previously emitted event.

All keys can be modified as you see fit, at the end of the event cycle they will be passed directly to Controller::redirect().

The redirect $url can be changed on the fly either by posting a redirect_url field from your form or by providing a redirect_url HTTP query key.

The default for most redirects are simply to return to the index() action.

Crud.beforeRender

Invoked right before the view will be rendered.

This is also before the controllers own beforeRender callback.

Crud.recordNotFound

Note

This event will throw an exception.

The default configuration will thrown an Cake\Error\NotFoundException which will yield a 404 response.

The event is triggered after a find did not find any records in the database.

You can modify the exception class thrown using CrudComponent::message method

Crud.setFlash

Simple and event driven wrapper for SessionComponent::setFlash.

The Crud Subject contains the following keys:

  • text The 1st argument to SessionComponent::setFlash.
  • element The 2nd argument to SessionComponent::setFlash.
  • params The 3rd argument to SessionComponent::setFlash.
  • key The 4th argument to SessionComponent::setFlash.
  • entity (Optional) The Entity from the previously emitted event.

All keys can be modified as you see fit, at the end of the event cycle they will be passed directly to SessionComponent::setFlash.

Defaults are stored in the messages configuration array for each action.

If you do not want to use this feature, simply stop the event by calling it’s stopPropagation() method.

If you’d like to customise the flash messages that are used, perhaps you’re using friendsofcake/bootstrap-ui. It’s actually quite simple to do, and can be done as part of the component configuration or on the fly.

public function initialize()
{
      $this->loadComponent('Crud.Crud', [
          'actions' => [
              'edit' => [
                  'className' => 'Crud.Edit',
                  'messages' => [
                      'success' => [
                          'params' => ['class' => 'alert alert-success alert-dismissible']
                      ],
                      'error' => [
                          'params' => ['class' => 'alert alert-danger alert-dismissible']
                      ]
                  ],
              ]
          ]
      ]);
}

If you’d like to configure it on the fly you can use the eventManager to change the event subject as the event is emitted.

$this->eventManager()->on('Crud.setFlash', function (Event $event) {
    if ($event->getSubject()->success) {
        $event->getSubject()->params['class'] = 'alert alert-success alert-dismissible';
    }
});
  v: 5.1.0
Versions
latest
stable
5.1.0
5.0.0
4.4.4
4.4.3
4.4.2
4.4.1
4.4.0
4.3.5
4.3.4
4.3.3
4.3.2
4.3.1
4.3.0
4.2.4
4.2.3
4.2.2
v4.0.0
cake3
Downloads
On Read the Docs
Project Home
Builds
Downloads
On GitHub
View
Edit

Free document hosting provided by Read the Docs.