PK nyFm$! crud-4.1.3/.buildinfo# Sphinx build info version 1 # This file hashes the configuration used when building these files. When it is not found, a full rebuild will be done. config: tags: PK nyFpf crud-4.1.3/objects.inv# Sphinx inventory version 2 # Project: crud # Version: 4.0 # The remainder of this file is compressed using zlib. xKOKIP(.IILJQ5THe(+x\)XT$}SJsRS3P@Ġ! S D1PK nyFry0 0 crud-4.1.3/contents.html
CRUD was built to be scaffolding on steroids, and allow developers to have enough flexibility to use it for both rapid prototyping and production applications, even on the same code base – saving you time.
API
for any action you have enabled through CRUD, which eliminates maintaining both a HTML frontend and a JSON and/or XML interface for your applications – saving you tons of time and having a leaner code base.If you happen to stumble upon a bug, please feel free to create a pull request with a fix (optionally with a test), and a description of the bug and how it was resolved.
You can also create an issue with a description to raise awareness of the bug.
If you have a good idea for a Crud feature, please join us on IRC and let’s discuss it. Pull requests are always more than welcome.
You can join us on IRC in the #FriendsOfCake channel on irc.freenode.net for any support or questions.
Installing composer is quick and simple.
You can get the Crud source code using either composer or git.
The recommended installation method for this plugin is by using composer.
Using the inline require for composer:
composer require friendsofcake/crud:~4.0
Or add this to your composer.json configuration:
{
"require" : {
"FriendsOfCake/crud": "~4.0"
}
}
Or add it as a git module, this is recommended over git clone
since it’s
easier to keep up to date with development that way:
git submodule add git://github.com/FriendsOfCake/crud.git Plugin/Crud
cd Plugin/Crud
In your AppController add the following code:
<?php
namespace App\Controller;
class AppController extends \Cake\Controller\Controller {
use \Crud\Controller\ControllerTrait;
}
Note
It’s not required to add the ControllerTrait
to AppController
- you can add it to any specific controller
as well if you don’t want Crud installed application wide
Adding the ControllerTrait
itself do not enable anything CRUD, but simply installs the code to handle
the \Cake\Error\MissingActionException
exception so you don’t have to implement an action in your controller
for Crud to work. This will make a lot of sense later.
The Configuration page explains how to setup and configure the Crud component.
You are busy, and you just want to get things done™
, so let’s get going.
After installation, you are ready to CRUD-ify your app.
So the application our pointy-haired boss has tasked us to create today is a Blog.
Since CRUD is awesome, and you already started to kinda love it, we want to enable CRUD for our entire application.
Let’s setup CRUD to handle all index()
, add()
, edit()
, view()
and delete()
actions automatically,
we do this by enabling Crud in the AppController
with the correct actions
configuration.
<?php
namespace App\Controller;
class AppController extends \Cake\Controller\Controller {
use \Crud\Controller\ControllerTrait;
public $components = [
'Crud.Crud' => [
'actions' => [
'Crud.Index',
'Crud.Add',
'Crud.Edit',
'Crud.View',
'Crud.Delete'
]
]
];
}
There we go, that was easy.
So, our new shiny Blog needs a Posts Controller
to, well, manage the posts.
<?php
namespace App\Controller;
class PostsController extends AppController {
}
(...) and that’s it! we don’t really need any logic there for now, since we have configured CRUD to take care of all actions
But... since CRUD doesn’t provide any views (yet), you will have to bake the views for now
Console/cake bake view posts
Let’s check out our new application, go to /posts
and behold, a nice paginated ìndex()
template, all without any code
in your controller.
You should now be able to navigate to /posts/add
as well and create your first post.
This section is WIP.
Configuration of Crud is done through the Crud component
- either on the fly
anywhere in you application, or by providing the configuration in the
Controller::$components
property.
Assuming you have followed the installation guide we will now begin the actual configuration of Crud.
Crud is loaded like any other Component
in CakePHP - simply by adding it to
the $components
variable in the controller
class AppController extends \Cake\Controller\Controller {
public $components = ['Crud.Crud'];
}
At this time, the Crud Component is loaded and ready for usage.
However, Crud has not been configured to handle any controller actions yet.
Configuring Crud to handle actions is simple.
The list of actions is provided either as Component
configuration, or on the
fly.
An example of Component
configuration:
class AppController extends \Cake\Controller\Controller {
public $components = [
'Crud.Crud' => [
'actions' => ['Crud.Index']
]
];
}
An example of on the fly enabling an Crud action:
class AppController extends \Cake\Controller\Controller {
public function beforeFilter(\Cake\Event\Event $event) {
$this->Crud->mapAction('index', 'Crud.Index');
}
}
The examples above are functionally identical, and instructs Crud to handle the
index
action in controllers using Crud.Index
action class.
Note
If you do not wish for Crud to be enabled across all controllers, or even use
all actions
provided by Crud
you can pick and chose which to use. Crud will not force take-over any
application logic, and you can enable/disable
them as you see fit.
Note
Each Crud Action have a different set of configuration settings, please see their individual documentation page for more information.
Passing in configuration for an action is simple.
Note
In the examples below, we reconfigure the Index Action to render
my_index.ctp
instead of index.ctp
An example of Component
configuration
class AppController extends \Cake\Controller\Controller {
public $components = [
'Crud.Crud' => [
'actions' => [
'index' => ['className' => 'Crud.Index', 'view' => 'my_index']
]
]
];
}
An example of on the fly enabling an Crud action with configuration
class AppController extends \Cake\Controller\Controller {
public function beforeFilter(\Cake\Event\Event $event) {
$this->Crud->mapAction('index', [
'className' => 'Crud.Index',
'view' => 'my_index'
]);
}
}
Crud provides the default CRUD
actions out of the box.
It’s possible to create your own Crud Action
as well, or overwrite the
built-in ones.
Simply provide the className
configuration key for an action, and Crud will
use that one instead.
Note
Each Crud Listener have a different set of configuration settings, please see their individual documentation page for more information.
Note
CRUD already provides the basic Index
, View
, Add
, Edit
and
Delete
actions, so you do not need to implement these on your own.
You can find the documentation for these actions in the menu to the left.
Actions are the backbone of CRUD - this is where most of the logic happens.
A Crud Action
contains more or less the exact same code as a normal
controller action.
The main difference between your normal Controller actions and a CRUD Action is that the CRUD Action is highly generic and flexible.
A CRUD action roughly translates to a normal Controller action.
The primary difference is that CRUD actions are made to be as generic and secure out of the box as possible.
You can consider a CRUD action as a more flexible PHP trait that fits nicely within the CakePHP ecosystem.
Below is the code for the Index Crud Action
In the next few sections we will walk through the code and explain how it works, and what every single line of code does.
For each section, the relevant lines of code will be highlighted.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 | <?php
namespace Crud\Action;
class Index extends BaseAction {
/**
* Generic handler for all HTTP verbs
*
* @return void
*/
protected function _handle() {
$subject = $this->_subject();
$subject->set(['success' => true, 'viewVar' => $this->viewVar()]);
$this->_trigger('beforePaginate', $subject);
$controller = $this->_controller();
$items = $controller->paginate();
$subject->set(['items' => $items]);
$this->_trigger('afterPaginate', $subject);
$controller->set(['success' => $subject->success, $subject->viewVar => $subject->items]);
$this->_trigger('beforeRender', $subject);
}
}
|
All build-in actions in Crud live in the Crud\Action
namespace.
All actions in Crud, even your own, should inherit from the
Crud\Action\Base
class.
This class is abstract
and provides numerous auxiliary methods which can be
useful for you both as a developer as an action creator.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 | <?php
namespace Crud\Action;
class Index extends BaseAction {
/**
* Generic handler for all HTTP verbs
*
* @return void
*/
protected function _handle() {
$subject = $this->_subject();
$subject->set(['success' => true, 'viewVar' => $this->viewVar()]);
$this->_trigger('beforePaginate', $subject);
$controller = $this->_controller();
$items = $controller->paginate();
$subject->set(['items' => $items]);
$this->_trigger('afterPaginate', $subject);
$controller->set(['success' => $subject->success, $subject->viewVar => $subject->items]);
$this->_trigger('beforeRender', $subject);
}
}
|
Next is the method _handle
. A Crud Action can respond to any HTTP verb
(GET
, POST
, PUT
, DELETE
).
Each HTTP verb can be implemented as method, e.g. _get()
for HTTP GET,
_post()
for HTTP POST and _put()
for HTTP PUT.
If no HTTP verb specific method is found in the class, _handle()
will be
executed.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 | <?php
namespace Crud\Action;
class Index extends BaseAction {
/**
* Generic handler for all HTTP verbs
*
* @return void
*/
protected function _handle() {
$subject = $this->_subject();
$subject->set(['success' => true, 'viewVar' => $this->viewVar()]);
$this->_trigger('beforePaginate', $subject);
$controller = $this->_controller();
$items = $controller->paginate();
$subject->set(['items' => $items]);
$this->_trigger('afterPaginate', $subject);
$controller->set(['success' => $subject->success, $subject->viewVar => $subject->items]);
$this->_trigger('beforeRender', $subject);
}
}
|
You can treat the _handle()
method as a catch-all, if your crud action
wants to process all possible HTTP verbs.
An advantage of this setup is that you can separate the logic on a request type level instead of mixing all of the logic into one big block of code.
For example the Edit Crud Action implements _get()
,
_post()
and _put()
methods. The _get()
method simply reads the entity
from the database and passes it to the form, while _put()
handles validation
and saving the entity back to the database.
All Crud actions emit a range of events, and all of these events always contain a
Crud Subject`. The Crud Subject`
can change its state between emitted events. This object is a simple StdClass
which contains the current state of the Crud request.
The real beauty of Crud is the events and the flexibility they provide.
All calls to _trigger()
emit an event, that you as a developer can listen to
and inject your own application logic. These events are in no way magical, they
are simply normal CakePHP events, dispatched like all other events in CakePHP.
You can for example listen for the beforePaginate
event and add conditions
to your pagination query, just with a few lines of code. Those few lines
of code is what makes your application unique. The rest of the code you would
normally have is simply repeated boiler plate code.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 | <?php
namespace Crud\Action;
class Index extends BaseAction {
/**
* Generic handler for all HTTP verbs
*
* @return void
*/
protected function _handle() {
$subject = $this->_subject();
$subject->set(['success' => true, 'viewVar' => $this->viewVar()]);
$this->_trigger('beforePaginate', $subject);
$controller = $this->_controller();
$items = $controller->paginate();
$subject->set(['items' => $items]);
$this->_trigger('afterPaginate', $subject);
$controller->set(['success' => $subject->success, $subject->viewVar => $subject->items]);
$this->_trigger('beforeRender', $subject);
}
}
|
Only the code that you would normally have in your controller is left now.
While these 3 lines seem simple, and the whole Crud implementation a bit overkill at first, the true power of this setup will be clear when your application grows and the requirements increase.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 | <?php
namespace Crud\Action;
class Index extends BaseAction {
/**
* Generic handler for all HTTP verbs
*
* @return void
*/
protected function _handle() {
$subject = $this->_subject();
$subject->set(['success' => true, 'viewVar' => $this->viewVar()]);
$this->_trigger('beforePaginate', $subject);
$controller = $this->_controller();
$items = $controller->paginate();
$subject->set(['items' => $items]);
$this->_trigger('afterPaginate', $subject);
$controller->set(['success' => $subject->success, $subject->viewVar => $subject->items]);
$this->_trigger('beforeRender', $subject);
}
}
|
For example adding an API layer to your application later in time will be non-trivial and time consuming if you do not use crud - especially if you have many controllers.
Using Crud, it would be as simple as loading the API listener and everything would be taken care of. All validation, exceptions, success and error responses would work immediately, and with just a few lines of code.
This is because the powerful event system can hook into the request and hijack the rendering easily and effortlessly – something baked controllers do not offer.
The Index Crud Action
paginates over the primary model in the controller.
On a high level it’s basically just calling Controller::paginate()
.
Note
Before applying any configuration to an action
it must be mapped first.
If the action have not been mapped an exception will be raised.
Test or modify if the Crud Action is enabled or not.
When a CrudAction is disabled, Crud will not handle any requests to the action, and CakePHP will raise the normal
\Cake\Error\MissingActionException
exception if you haven’t implemented the action in your controller.
To test if an action is enabled, call the enabled
method on the action.
$this->Crud->action()->enabled();
To disable an action, call the disable
method on the action.
$this->Crud->action()->disable();
To enable an action, call the enable
method on the action.
$this->Crud->action()->enable();
To disable or enable multiple actions at the same time, Crud Component
provides helper methods.
The enable
and disable
method can take a string or an array, for easy mass-updating.
$this->Crud->enable('index');
$this->Crud->enable(['index', 'add']);
$this->Crud->disable('index');
$this->Crud->disable(['index', 'add']);
Note
These methods simply calls the enable
and disable
method in each Crud Action
class, and do not provide any magic
other than mass updating.
Warning
While it’s possible to update the enabled
property directly on an action using the config
methods,
it’s not recommend, as important cleanup logic will not be applied if you use the config()
method directly.
Get or set the view file to render at the end of the request.
The view setting is passed directly and unmodified to Controller::render()
.
To get the current configured view
call the view
method without any arguments.
$this->Crud->action()->view();
To change the view to render, pass a string
as first argument.
$this->Crud->action()->view('my_custom_view');
Note
If the first parameter is NULL
- which is the default value - the normal CakePHP behavior will be used.
Warning
Due to the nature of this method, once a custom view has been set, it’s not possible to revert back to
the default behavior by calling ->view(null)
as it will return the current configuration.
Note
This maps directly to the $key
argument in Controller::set($key, $value)
Change the name of the variable which contains the result of a index
or view
action query result.
To get the current configured viewVar
call the viewViar
method without any arguments.
$this->Crud->action()->viewVar();
To change the viewVar, pass a string
as first argument.
$this->Crud->action()->viewVar('items');
For Index Action the default is plural version of the controller name.
Having a controller named PostsController
would mean that the viewVar
would be posts
by default.
For View Action the default is singular version of the controller name.
Having a controller named PostsController
would mean that the viewVar
would be post
by default.
Note
This setting is only relevant if you use the API listener.
Note
The API listener will always enforce success
and data
to be part of the _serialize
array.
This method is intended to allow you to add additional keys to your API responses with ease. An example of this is the API Query Log.
To get the current configured serialize
keys call the serialize
method without any arguments.
$this->Crud->action()->serialize();
To change the serialize keys, pass a string
or an array
as first argument.
If a string is passed, it will be cast to array
automatically.
$this->Crud->action()->serialize(['my', 'extra', 'keys']);
This is a list of events emitted from the Index Crud Action
.
Please see the events documentation for a full list of generic properties and how to use the event system correctly.
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.
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.
This event is emitted before Controller::paginate()
is called.
public function index() {
$this->Crud->on('beforePaginate', function(\Cake\Event\Event $event) {
$this->paginate['conditions']['is_active'] = true;
});
return $this->Crud->execute();
}
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.
public function index() {
$this->Crud->on('afterPaginate', function(\Cake\Event\Event $event) {
foreach ($event->subject->entities as $entity) {
// $entity is an entity
}
});
return $this->Crud->execute();
}
Invoked right before the view will be rendered.
This is also before the controllers own beforeRender callback.
The View Crud Action
will read a record from a data source based on the ID
that is part of the request.
Note
Before applying any configuration to an action
it must be mapped first.
If the action have not been mapped an exception will be raised.
Test or modify if the Crud Action is enabled or not.
When a CrudAction is disabled, Crud will not handle any requests to the action, and CakePHP will raise the normal
\Cake\Error\MissingActionException
exception if you haven’t implemented the action in your controller.
To test if an action is enabled, call the enabled
method on the action.
$this->Crud->action()->enabled();
To disable an action, call the disable
method on the action.
$this->Crud->action()->disable();
To enable an action, call the enable
method on the action.
$this->Crud->action()->enable();
To disable or enable multiple actions at the same time, Crud Component
provides helper methods.
The enable
and disable
method can take a string or an array, for easy mass-updating.
$this->Crud->enable('index');
$this->Crud->enable(['index', 'add']);
$this->Crud->disable('index');
$this->Crud->disable(['index', 'add']);
Note
These methods simply calls the enable
and disable
method in each Crud Action
class, and do not provide any magic
other than mass updating.
Warning
While it’s possible to update the enabled
property directly on an action using the config
methods,
it’s not recommend, as important cleanup logic will not be applied if you use the config()
method directly.
The 1st parameter to Table::find()
- the default value is all
.
To get the current configured findMethod
keys call the findMethod
method without any arguments.
$this->Crud->action()->findMethod();
To change the findMethod value pass an string argument to the method
$this->Crud->action()->findMethod('my_custom_finder');
Get or set the view file to render at the end of the request.
The view setting is passed directly and unmodified to Controller::render()
.
To get the current configured view
call the view
method without any arguments.
$this->Crud->action()->view();
To change the view to render, pass a string
as first argument.
$this->Crud->action()->view('my_custom_view');
Note
If the first parameter is NULL
- which is the default value - the normal CakePHP behavior will be used.
Warning
Due to the nature of this method, once a custom view has been set, it’s not possible to revert back to
the default behavior by calling ->view(null)
as it will return the current configuration.
Note
This maps directly to the $key
argument in Controller::set($key, $value)
Change the name of the variable which contains the result of a index
or view
action query result.
To get the current configured viewVar
call the viewViar
method without any arguments.
$this->Crud->action()->viewVar();
To change the viewVar, pass a string
as first argument.
$this->Crud->action()->viewVar('items');
For Index Action the default is plural version of the controller name.
Having a controller named PostsController
would mean that the viewVar
would be posts
by default.
For View Action the default is singular version of the controller name.
Having a controller named PostsController
would mean that the viewVar
would be post
by default.
Note
This setting is only relevant if you use the API listener.
Note
The API listener will always enforce success
and data
to be part of the _serialize
array.
This method is intended to allow you to add additional keys to your API responses with ease. An example of this is the API Query Log.
To get the current configured serialize
keys call the serialize
method without any arguments.
$this->Crud->action()->serialize();
To change the serialize keys, pass a string
or an array
as first argument.
If a string is passed, it will be cast to array
automatically.
$this->Crud->action()->serialize(['my', 'extra', 'keys']);
This is a list of events emitted from the View Crud Action
.
Please see the events documentation for a full list of generic properties and how to use the event system correctly.
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.
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.
The event is emitted before calling the find method in the table.
The Crud Subject contains the following keys:
Repository
(Table
) which the query will be executed against.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 Crud.recordNotFound
event is emitted instead of Crud.afterFind
.
public function delete($id) {
$this->Crud->on('beforeFind', function(\Cake\Event\Event $event) {
$event->subject->query->where(['author' => $this->Auth->user('id')]);
});
return $this->Crud->execute();
}
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.item
The record that was found in the database.Note
If an entity is not found, the RecordNotFound
event is emitted instead.
public function delete($id) {
$this->Crud->on('afterFind', function(\Cake\Event\Event $event) {
$this->log("Found item: $event->subject->item->id in the database");
});
return $this->Crud->execute();
}
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
Invoked right before the view will be rendered.
This is also before the controllers own beforeRender callback.
The Add Crud Action
will create a new record if the request is POST
and the data validates - otherwise it will attempt to render a form to the end-user.
Note
Before applying any configuration to an action
it must be mapped first.
If the action have not been mapped an exception will be raised.
Test or modify if the Crud Action is enabled or not.
When a CrudAction is disabled, Crud will not handle any requests to the action, and CakePHP will raise the normal
\Cake\Error\MissingActionException
exception if you haven’t implemented the action in your controller.
To test if an action is enabled, call the enabled
method on the action.
$this->Crud->action()->enabled();
To disable an action, call the disable
method on the action.
$this->Crud->action()->disable();
To enable an action, call the enable
method on the action.
$this->Crud->action()->enable();
To disable or enable multiple actions at the same time, Crud Component
provides helper methods.
The enable
and disable
method can take a string or an array, for easy mass-updating.
$this->Crud->enable('index');
$this->Crud->enable(['index', 'add']);
$this->Crud->disable('index');
$this->Crud->disable(['index', 'add']);
Note
These methods simply calls the enable
and disable
method in each Crud Action
class, and do not provide any magic
other than mass updating.
Warning
While it’s possible to update the enabled
property directly on an action using the config
methods,
it’s not recommend, as important cleanup logic will not be applied if you use the config()
method directly.
Get or set the view file to render at the end of the request.
The view setting is passed directly and unmodified to Controller::render()
.
To get the current configured view
call the view
method without any arguments.
$this->Crud->action()->view();
To change the view to render, pass a string
as first argument.
$this->Crud->action()->view('my_custom_view');
Note
If the first parameter is NULL
- which is the default value - the normal CakePHP behavior will be used.
Warning
Due to the nature of this method, once a custom view has been set, it’s not possible to revert back to
the default behavior by calling ->view(null)
as it will return the current configuration.
The method to execute on Table::
when saving an entity - the default value is save
.
To get the current configured saveMethod
keys call the saveMethod
method without any arguments.
$this->Crud->action()->saveMethod();
To change the saveMethod value pass an string argument to the method
$this->Crud->action()->saveMethod('my_custom_save_method');
The 2nd parameter to Table::save()
- the default value is ['validate' => true, 'atomic' => true]
.
To get the current configured saveOptions
keys call the saveOptions
method without any arguments.
$this->Crud->action()->saveOptions();
To change the saveOptions value pass an array argument to the method
$this->Crud->action()->saveOptions(['atomic' => false]);
Note
This setting is only relevant if you use the API listener.
Note
The API listener will always enforce success
and data
to be part of the _serialize
array.
This method is intended to allow you to add additional keys to your API responses with ease. An example of this is the API Query Log.
To get the current configured serialize
keys call the serialize
method without any arguments.
$this->Crud->action()->serialize();
To change the serialize keys, pass a string
or an array
as first argument.
If a string is passed, it will be cast to array
automatically.
$this->Crud->action()->serialize(['my', 'extra', 'keys']);
This is a list of events emitted from the Add Crud Action
.
Please see the events documentation for a full list of generic properties and how to use the event system correctly.
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.
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.
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
object marshaled with the HTTP POST
data from the request.string
with the saveMethod
.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
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:
Table::save()
was successful.Table::save()
call succeed or not.true
if the record was created
and false
if the record was updated
.entity
object marshaled with the HTTP POST
data from the request and the save()
logic.public function edit($id) {
$this->Crud->on('afterSave', function(\Cake\Event\Event $event) {
if ($event->subject->created) {
$this->log("The entity was created");
} else {
$this->log("The entity was updated");
}
});
return $this->Crud->execute();
}
public function edit($id) {
$this->Crud->on('afterSave', function(\Cake\Event\Event $event) {
if ($event->subject->success) {
$this->log("The entity was saved successfully");
} else {
$this->log("The entity was NOT saved successfully");
}
});
return $this->Crud->execute();
}
public function add() {
$this->Crud->on('afterSave', function(\Cake\Event\Event $event) {
if ($event->subject->created) {
$this->log("The entity was created with id: $event->subject->id");
}
});
return $this->Crud->execute();
}
Simple and event driven wrapper for SessionComponent::setFlash
.
The Crud Subject contains the following keys:
SessionComponent::setFlash
.SessionComponent::setFlash
.SessionComponent::setFlash
.SessionComponent::setFlash
.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.
Simple and event driven wrapper for Controller::redirect()
.
The Crud Subject contains the following keys:
Controller::redirect()
.Controller::redirect()
.Controller::redirect()
.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.
Invoked right before the view will be rendered.
This is also before the controllers own beforeRender callback.
The Edit Crud Action
will update an existing record if the request is POST
or PUT
and the data validates - otherwise it will attempt to render a form to the end-user.
Note
Before applying any configuration to an action
it must be mapped first.
If the action have not been mapped an exception will be raised.
Test or modify if the Crud Action is enabled or not.
When a CrudAction is disabled, Crud will not handle any requests to the action, and CakePHP will raise the normal
\Cake\Error\MissingActionException
exception if you haven’t implemented the action in your controller.
To test if an action is enabled, call the enabled
method on the action.
$this->Crud->action()->enabled();
To disable an action, call the disable
method on the action.
$this->Crud->action()->disable();
To enable an action, call the enable
method on the action.
$this->Crud->action()->enable();
To disable or enable multiple actions at the same time, Crud Component
provides helper methods.
The enable
and disable
method can take a string or an array, for easy mass-updating.
$this->Crud->enable('index');
$this->Crud->enable(['index', 'add']);
$this->Crud->disable('index');
$this->Crud->disable(['index', 'add']);
Note
These methods simply calls the enable
and disable
method in each Crud Action
class, and do not provide any magic
other than mass updating.
Warning
While it’s possible to update the enabled
property directly on an action using the config
methods,
it’s not recommend, as important cleanup logic will not be applied if you use the config()
method directly.
Get or set the view file to render at the end of the request.
The view setting is passed directly and unmodified to Controller::render()
.
To get the current configured view
call the view
method without any arguments.
$this->Crud->action()->view();
To change the view to render, pass a string
as first argument.
$this->Crud->action()->view('my_custom_view');
Note
If the first parameter is NULL
- which is the default value - the normal CakePHP behavior will be used.
Warning
Due to the nature of this method, once a custom view has been set, it’s not possible to revert back to
the default behavior by calling ->view(null)
as it will return the current configuration.
The 1st parameter to Table::find()
- the default value is all
.
To get the current configured findMethod
keys call the findMethod
method without any arguments.
$this->Crud->action()->findMethod();
To change the findMethod value pass an string argument to the method
$this->Crud->action()->findMethod('my_custom_finder');
The method to execute on Table::
when saving an entity - the default value is save
.
To get the current configured saveMethod
keys call the saveMethod
method without any arguments.
$this->Crud->action()->saveMethod();
To change the saveMethod value pass an string argument to the method
$this->Crud->action()->saveMethod('my_custom_save_method');
The 2nd parameter to Table::save()
- the default value is ['validate' => true, 'atomic' => true]
.
To get the current configured saveOptions
keys call the saveOptions
method without any arguments.
$this->Crud->action()->saveOptions();
To change the saveOptions value pass an array argument to the method
$this->Crud->action()->saveOptions(['atomic' => false]);
Note
This setting is only relevant if you use the API listener.
Note
The API listener will always enforce success
and data
to be part of the _serialize
array.
This method is intended to allow you to add additional keys to your API responses with ease. An example of this is the API Query Log.
To get the current configured serialize
keys call the serialize
method without any arguments.
$this->Crud->action()->serialize();
To change the serialize keys, pass a string
or an array
as first argument.
If a string is passed, it will be cast to array
automatically.
$this->Crud->action()->serialize(['my', 'extra', 'keys']);
This is a list of events emitted from the Edit Crud Action
.
Please see the events documentation for a full list of generic properties and how to use the event system correctly.
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.
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.
The event is emitted before calling the find method in the table.
The Crud Subject contains the following keys:
Repository
(Table
) which the query will be executed against.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 Crud.recordNotFound
event is emitted instead of Crud.afterFind
.
public function delete($id) {
$this->Crud->on('beforeFind', function(\Cake\Event\Event $event) {
$event->subject->query->where(['author' => $this->Auth->user('id')]);
});
return $this->Crud->execute();
}
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.item
The record that was found in the database.Note
If an entity is not found, the RecordNotFound
event is emitted instead.
public function delete($id) {
$this->Crud->on('afterFind', function(\Cake\Event\Event $event) {
$this->log("Found item: $event->subject->item->id in the database");
});
return $this->Crud->execute();
}
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
object marshaled with the HTTP POST
data from the request.string
with the saveMethod
.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
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:
Table::save()
was successful.Table::save()
call succeed or not.true
if the record was created
and false
if the record was updated
.entity
object marshaled with the HTTP POST
data from the request and the save()
logic.public function edit($id) {
$this->Crud->on('afterSave', function(\Cake\Event\Event $event) {
if ($event->subject->created) {
$this->log("The entity was created");
} else {
$this->log("The entity was updated");
}
});
return $this->Crud->execute();
}
public function edit($id) {
$this->Crud->on('afterSave', function(\Cake\Event\Event $event) {
if ($event->subject->success) {
$this->log("The entity was saved successfully");
} else {
$this->log("The entity was NOT saved successfully");
}
});
return $this->Crud->execute();
}
public function add() {
$this->Crud->on('afterSave', function(\Cake\Event\Event $event) {
if ($event->subject->created) {
$this->log("The entity was created with id: $event->subject->id");
}
});
return $this->Crud->execute();
}
Simple and event driven wrapper for SessionComponent::setFlash
.
The Crud Subject contains the following keys:
SessionComponent::setFlash
.SessionComponent::setFlash
.SessionComponent::setFlash
.SessionComponent::setFlash
.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.
Simple and event driven wrapper for Controller::redirect()
.
The Crud Subject contains the following keys:
Controller::redirect()
.Controller::redirect()
.Controller::redirect()
.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.
Invoked right before the view will be rendered.
This is also before the controllers own beforeRender callback.
The Delete Crud Action
will delete a record by the id provided in the URL.
Note
Before applying any configuration to an action
it must be mapped first.
If the action have not been mapped an exception will be raised.
Test or modify if the Crud Action is enabled or not.
When a CrudAction is disabled, Crud will not handle any requests to the action, and CakePHP will raise the normal
\Cake\Error\MissingActionException
exception if you haven’t implemented the action in your controller.
To test if an action is enabled, call the enabled
method on the action.
$this->Crud->action()->enabled();
To disable an action, call the disable
method on the action.
$this->Crud->action()->disable();
To enable an action, call the enable
method on the action.
$this->Crud->action()->enable();
To disable or enable multiple actions at the same time, Crud Component
provides helper methods.
The enable
and disable
method can take a string or an array, for easy mass-updating.
$this->Crud->enable('index');
$this->Crud->enable(['index', 'add']);
$this->Crud->disable('index');
$this->Crud->disable(['index', 'add']);
Note
These methods simply calls the enable
and disable
method in each Crud Action
class, and do not provide any magic
other than mass updating.
Warning
While it’s possible to update the enabled
property directly on an action using the config
methods,
it’s not recommend, as important cleanup logic will not be applied if you use the config()
method directly.
The 1st parameter to Table::find()
- the default value is all
.
To get the current configured findMethod
keys call the findMethod
method without any arguments.
$this->Crud->action()->findMethod();
To change the findMethod value pass an string argument to the method
$this->Crud->action()->findMethod('my_custom_finder');
Note
This setting is only relevant if you use the API listener.
Note
The API listener will always enforce success
and data
to be part of the _serialize
array.
This method is intended to allow you to add additional keys to your API responses with ease. An example of this is the API Query Log.
To get the current configured serialize
keys call the serialize
method without any arguments.
$this->Crud->action()->serialize();
To change the serialize keys, pass a string
or an array
as first argument.
If a string is passed, it will be cast to array
automatically.
$this->Crud->action()->serialize(['my', 'extra', 'keys']);
This is a list of events emitted from the Delete Crud Action
.
Please see the events documentation for a full list of generic properties and how to use the event system correctly.
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.
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.
The event is emitted before calling the find method in the table.
The Crud Subject contains the following keys:
Repository
(Table
) which the query will be executed against.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 Crud.recordNotFound
event is emitted instead of Crud.afterFind
.
public function delete($id) {
$this->Crud->on('beforeFind', function(\Cake\Event\Event $event) {
$event->subject->query->where(['author' => $this->Auth->user('id')]);
});
return $this->Crud->execute();
}
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.item
The record that was found in the database.Note
If an entity is not found, the RecordNotFound
event is emitted instead.
public function delete($id) {
$this->Crud->on('afterFind', function(\Cake\Event\Event $event) {
$this->log("Found item: $event->subject->item->id in the database");
});
return $this->Crud->execute();
}
This event is emitted before calling Table::delete
.
The Crud Subject contains the following keys:
Entity
from the find()
call.To abort a delete()
simply stop the event by calling
$event->stopPropagation()
.
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->subject->item->author !== 'admin') {
$event->stopPropagation();
}
});
return $this->Crud->execute();
}
This event is emitted after Table::delete()
has been called.
The Crud Subject contains two keys:
true
the delete()
call succeeded, false
otherwisepublic function delete($id) {
$this->Crud->on('afterDelete', function(\Cake\Event\Event $event) {
if (!$event->subject->success) {
$this->log("Delete failed for entity $event->subject->id");
}
});
return $this->Crud->execute();
}
Simple and event driven wrapper for Controller::redirect()
.
The Crud Subject contains the following keys:
Controller::redirect()
.Controller::redirect()
.Controller::redirect()
.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.
If you need to perform an action against a number of records, you can extend
the abstract Bulk\BaseAction
class to create your own.
Three BulkAction classes exist in the core:
To create your own BulkAction, simply create a new action class with a _bulk
method. This method takes a CakePHP Query
object as it’s first argument
<?php
namespace App\Crud\Action;
use Cake\ORM\Query;
use Crud\Action\Bulk\BaseAction;
class ApproveAction extends BaseAction
{
/**
* Set the value of the approved field to true
* for a set of entities
*
* @param \Cake\ORM\Query $query The query to act upon
* @return boolean
*/
protected function _handle(Query $query)
{
$query->update()->set(['approved' => true]);
$statement = $query->execute();
$statement->closeCursor();
return $statement->rowCount();
}
}
Note
Before applying any configuration to an action
it must be mapped first.
If the action have not been mapped an exception will be raised.
Test or modify if the Crud Action is enabled or not.
When a CrudAction is disabled, Crud will not handle any requests to the action, and CakePHP will raise the normal
\Cake\Error\MissingActionException
exception if you haven’t implemented the action in your controller.
To test if an action is enabled, call the enabled
method on the action.
$this->Crud->action()->enabled();
To disable an action, call the disable
method on the action.
$this->Crud->action()->disable();
To enable an action, call the enable
method on the action.
$this->Crud->action()->enable();
To disable or enable multiple actions at the same time, Crud Component
provides helper methods.
The enable
and disable
method can take a string or an array, for easy mass-updating.
$this->Crud->enable('index');
$this->Crud->enable(['index', 'add']);
$this->Crud->disable('index');
$this->Crud->disable(['index', 'add']);
Note
These methods simply calls the enable
and disable
method in each Crud Action
class, and do not provide any magic
other than mass updating.
Warning
While it’s possible to update the enabled
property directly on an action using the config
methods,
it’s not recommend, as important cleanup logic will not be applied if you use the config()
method directly.
The 1st parameter to Table::find()
- the default value is all
.
To get the current configured findMethod
keys call the findMethod
method without any arguments.
$this->Crud->action()->findMethod();
To change the findMethod value pass an string argument to the method
$this->Crud->action()->findMethod('my_custom_finder');
This is a list of events emitted from actions that extend Bulk\BaseAction
.
Please see the events documentation for a full list of generic properties and how to use the event system correctly.
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.
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.
This event is emitted before _bulk()
is called on a Bulk Crud action.
The Crud Subject contains the following keys:
Repository
(Table
) which the query will be executed against.Query
object from the Repository
where $PrimaryKey => $IdFromRequest
is already added to the conditions.To abort a bulk action, simply stop the event by calling
$event->stopPropagation()
.
public function bulk($id) {
$this->Crud->on('beforeBulk', function(\Cake\Event\Event $event) {
// Stop the bulk event, the action will not continue
if ($event->subject->item->author !== 'admin') {
$event->stopPropagation();
}
});
return $this->Crud->execute();
}
This event is emitted after calling _bulk()
on a Bulk Crud action.
The Crud Subject contains two keys:
true
the _bulk()
call succeeded, false
otherwiseRepository
(Table
) which the query will be executed against.Query
object from the Repository
where $PrimaryKey => $IdFromRequest
is already added to the conditions.public function bulk($id) {
$this->Crud->on('afterBulk', function(\Cake\Event\Event $event) {
if (!$event->subject->success) {
$this->log("Bulk action failed");
}
});
return $this->Crud->execute();
}
Simple and event driven wrapper for SessionComponent::setFlash
.
The Crud Subject contains the following keys:
SessionComponent::setFlash
.SessionComponent::setFlash
.SessionComponent::setFlash
.SessionComponent::setFlash
.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.
Simple and event driven wrapper for Controller::redirect()
.
The Crud Subject contains the following keys:
Controller::redirect()
.Controller::redirect()
.Controller::redirect()
.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.
You can use the Bulk\DeleteAction
class to delete a group of database records.
<?php
namespace App\Controller;
class PostsController extends AppController
{
public function initialize()
{
parent::initialize();
$this->Crud->mapAction('deleteAll', 'Crud.Bulk/Delete');
}
}
Note
Before applying any configuration to an action
it must be mapped first.
If the action have not been mapped an exception will be raised.
Test or modify if the Crud Action is enabled or not.
When a CrudAction is disabled, Crud will not handle any requests to the action, and CakePHP will raise the normal
\Cake\Error\MissingActionException
exception if you haven’t implemented the action in your controller.
To test if an action is enabled, call the enabled
method on the action.
$this->Crud->action()->enabled();
To disable an action, call the disable
method on the action.
$this->Crud->action()->disable();
To enable an action, call the enable
method on the action.
$this->Crud->action()->enable();
To disable or enable multiple actions at the same time, Crud Component
provides helper methods.
The enable
and disable
method can take a string or an array, for easy mass-updating.
$this->Crud->enable('index');
$this->Crud->enable(['index', 'add']);
$this->Crud->disable('index');
$this->Crud->disable(['index', 'add']);
Note
These methods simply calls the enable
and disable
method in each Crud Action
class, and do not provide any magic
other than mass updating.
Warning
While it’s possible to update the enabled
property directly on an action using the config
methods,
it’s not recommend, as important cleanup logic will not be applied if you use the config()
method directly.
The 1st parameter to Table::find()
- the default value is all
.
To get the current configured findMethod
keys call the findMethod
method without any arguments.
$this->Crud->action()->findMethod();
To change the findMethod value pass an string argument to the method
$this->Crud->action()->findMethod('my_custom_finder');
This is a list of events emitted from actions that extend Bulk\BaseAction
.
Please see the events documentation for a full list of generic properties and how to use the event system correctly.
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.
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.
This event is emitted before _bulk()
is called on a Bulk Crud action.
The Crud Subject contains the following keys:
Repository
(Table
) which the query will be executed against.Query
object from the Repository
where $PrimaryKey => $IdFromRequest
is already added to the conditions.To abort a bulk action, simply stop the event by calling
$event->stopPropagation()
.
public function bulk($id) {
$this->Crud->on('beforeBulk', function(\Cake\Event\Event $event) {
// Stop the bulk event, the action will not continue
if ($event->subject->item->author !== 'admin') {
$event->stopPropagation();
}
});
return $this->Crud->execute();
}
This event is emitted after calling _bulk()
on a Bulk Crud action.
The Crud Subject contains two keys:
true
the _bulk()
call succeeded, false
otherwiseRepository
(Table
) which the query will be executed against.Query
object from the Repository
where $PrimaryKey => $IdFromRequest
is already added to the conditions.public function bulk($id) {
$this->Crud->on('afterBulk', function(\Cake\Event\Event $event) {
if (!$event->subject->success) {
$this->log("Bulk action failed");
}
});
return $this->Crud->execute();
}
Simple and event driven wrapper for SessionComponent::setFlash
.
The Crud Subject contains the following keys:
SessionComponent::setFlash
.SessionComponent::setFlash
.SessionComponent::setFlash
.SessionComponent::setFlash
.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.
Simple and event driven wrapper for Controller::redirect()
.
The Crud Subject contains the following keys:
Controller::redirect()
.Controller::redirect()
.Controller::redirect()
.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.
You can use the Bulk\SetValueAction
class to specify the value of a
given field for a group of database records.
<?php
namespace App\Controller;
class PostsController extends AppController
{
public function initialize()
{
parent::initialize();
$this->Crud->mapAction('publishAll', [
'className' => 'Crud.Bulk/SetValue',
'field' => 'status',
'value' => 'publish',
]);
}
}
Note
Before applying any configuration to an action
it must be mapped first.
If the action have not been mapped an exception will be raised.
Test or modify if the Crud Action is enabled or not.
When a CrudAction is disabled, Crud will not handle any requests to the action, and CakePHP will raise the normal
\Cake\Error\MissingActionException
exception if you haven’t implemented the action in your controller.
To test if an action is enabled, call the enabled
method on the action.
$this->Crud->action()->enabled();
To disable an action, call the disable
method on the action.
$this->Crud->action()->disable();
To enable an action, call the enable
method on the action.
$this->Crud->action()->enable();
To disable or enable multiple actions at the same time, Crud Component
provides helper methods.
The enable
and disable
method can take a string or an array, for easy mass-updating.
$this->Crud->enable('index');
$this->Crud->enable(['index', 'add']);
$this->Crud->disable('index');
$this->Crud->disable(['index', 'add']);
Note
These methods simply calls the enable
and disable
method in each Crud Action
class, and do not provide any magic
other than mass updating.
Warning
While it’s possible to update the enabled
property directly on an action using the config
methods,
it’s not recommend, as important cleanup logic will not be applied if you use the config()
method directly.
The 1st parameter to Table::find()
- the default value is all
.
To get the current configured findMethod
keys call the findMethod
method without any arguments.
$this->Crud->action()->findMethod();
To change the findMethod value pass an string argument to the method
$this->Crud->action()->findMethod('my_custom_finder');
This is a list of events emitted from actions that extend Bulk\BaseAction
.
Please see the events documentation for a full list of generic properties and how to use the event system correctly.
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.
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.
This event is emitted before _bulk()
is called on a Bulk Crud action.
The Crud Subject contains the following keys:
Repository
(Table
) which the query will be executed against.Query
object from the Repository
where $PrimaryKey => $IdFromRequest
is already added to the conditions.To abort a bulk action, simply stop the event by calling
$event->stopPropagation()
.
public function bulk($id) {
$this->Crud->on('beforeBulk', function(\Cake\Event\Event $event) {
// Stop the bulk event, the action will not continue
if ($event->subject->item->author !== 'admin') {
$event->stopPropagation();
}
});
return $this->Crud->execute();
}
This event is emitted after calling _bulk()
on a Bulk Crud action.
The Crud Subject contains two keys:
true
the _bulk()
call succeeded, false
otherwiseRepository
(Table
) which the query will be executed against.Query
object from the Repository
where $PrimaryKey => $IdFromRequest
is already added to the conditions.public function bulk($id) {
$this->Crud->on('afterBulk', function(\Cake\Event\Event $event) {
if (!$event->subject->success) {
$this->log("Bulk action failed");
}
});
return $this->Crud->execute();
}
Simple and event driven wrapper for SessionComponent::setFlash
.
The Crud Subject contains the following keys:
SessionComponent::setFlash
.SessionComponent::setFlash
.SessionComponent::setFlash
.SessionComponent::setFlash
.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.
Simple and event driven wrapper for Controller::redirect()
.
The Crud Subject contains the following keys:
Controller::redirect()
.Controller::redirect()
.Controller::redirect()
.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.
You can use the Bulk\ToggleAction
class to toggle the value of a
boolean field for a group of database records.
<?php
namespace App\Controller;
class PostsController extends AppController
{
public function initialize()
{
parent::initialize();
$this->Crud->mapAction('toggleActive', [
'className' => 'Crud.Bulk/Toggle',
'field' => 'toggle',
]);
}
}
Note
Before applying any configuration to an action
it must be mapped first.
If the action have not been mapped an exception will be raised.
Test or modify if the Crud Action is enabled or not.
When a CrudAction is disabled, Crud will not handle any requests to the action, and CakePHP will raise the normal
\Cake\Error\MissingActionException
exception if you haven’t implemented the action in your controller.
To test if an action is enabled, call the enabled
method on the action.
$this->Crud->action()->enabled();
To disable an action, call the disable
method on the action.
$this->Crud->action()->disable();
To enable an action, call the enable
method on the action.
$this->Crud->action()->enable();
To disable or enable multiple actions at the same time, Crud Component
provides helper methods.
The enable
and disable
method can take a string or an array, for easy mass-updating.
$this->Crud->enable('index');
$this->Crud->enable(['index', 'add']);
$this->Crud->disable('index');
$this->Crud->disable(['index', 'add']);
Note
These methods simply calls the enable
and disable
method in each Crud Action
class, and do not provide any magic
other than mass updating.
Warning
While it’s possible to update the enabled
property directly on an action using the config
methods,
it’s not recommend, as important cleanup logic will not be applied if you use the config()
method directly.
The 1st parameter to Table::find()
- the default value is all
.
To get the current configured findMethod
keys call the findMethod
method without any arguments.
$this->Crud->action()->findMethod();
To change the findMethod value pass an string argument to the method
$this->Crud->action()->findMethod('my_custom_finder');
This is a list of events emitted from actions that extend Bulk\BaseAction
.
Please see the events documentation for a full list of generic properties and how to use the event system correctly.
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.
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.
This event is emitted before _bulk()
is called on a Bulk Crud action.
The Crud Subject contains the following keys:
Repository
(Table
) which the query will be executed against.Query
object from the Repository
where $PrimaryKey => $IdFromRequest
is already added to the conditions.To abort a bulk action, simply stop the event by calling
$event->stopPropagation()
.
public function bulk($id) {
$this->Crud->on('beforeBulk', function(\Cake\Event\Event $event) {
// Stop the bulk event, the action will not continue
if ($event->subject->item->author !== 'admin') {
$event->stopPropagation();
}
});
return $this->Crud->execute();
}
This event is emitted after calling _bulk()
on a Bulk Crud action.
The Crud Subject contains two keys:
true
the _bulk()
call succeeded, false
otherwiseRepository
(Table
) which the query will be executed against.Query
object from the Repository
where $PrimaryKey => $IdFromRequest
is already added to the conditions.public function bulk($id) {
$this->Crud->on('afterBulk', function(\Cake\Event\Event $event) {
if (!$event->subject->success) {
$this->log("Bulk action failed");
}
});
return $this->Crud->execute();
}
Simple and event driven wrapper for SessionComponent::setFlash
.
The Crud Subject contains the following keys:
SessionComponent::setFlash
.SessionComponent::setFlash
.SessionComponent::setFlash
.SessionComponent::setFlash
.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.
Simple and event driven wrapper for Controller::redirect()
.
The Crud Subject contains the following keys:
Controller::redirect()
.Controller::redirect()
.Controller::redirect()
.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.
If you are not satisfied with the Actions bundled with CRUD - you can easily add your own.
A Crud Action can respond to any HTTP
verb (GET
, POST
, PUT
, DELETE
).
Each HTTP verb can be implemented as method, e.g. _get() for HTTP GET
,
_post() for HTTP POST
and _put() for HTTP PUT
.
If no HTTP verb specific method is found in the class, _handle()
will be executed.
<?php
namespace App\Crud\Action;
class Index extends \Crud\Action\BaseAction {
/**
* Generic handler for all HTTP verbs
*
* @return void
*/
protected function _handle() {
}
}
Tip
While CRUD provides many listeners, it’s definitely possible and recommended that you add your own reusable listeners for your application needs
Listeners are the foundation for the extreme flexibility CRUD provides you as an application developer.
The event system allows you to hook into the most important part of the CRUD action flow and customize it to your unique application needs.
The listener system is simply the Events System from CakePHP, and all the official documentation and usage also applies to CRUD.
The CRUD event system uses two methods trigger()
and on()
to interface
the underlying CakePHP event system.
The only hard requirement for a CRUD listener is that it needs to either implement
the implementedEvents()
method or extend \Crud\Listener\Base
.
Below is the code for a simple CRUD listener.
In the next few sections we will walk through the code and explain how it works, and what every single line of code does.
For each section, the relevant lines of code will be highlighted.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 | <?php
namespace Crud\Listener;
class Example extends \Crud\Listener\BaseListener {
/**
* Returns a list of all events that will fire in the lister during the
* CRUD life-cycle.
*
* @return array
*/
public function implementedEvents() {
return [
'Crud.beforeRender' => ['callable' => 'beforeRender']
];
}
/**
* Executed when Crud.beforeRender is emitted
*
* @param \Cake\Event\Event $event
* @return void
*/
public function beforeRender(Cake\Event\Event $event) {
$this->_response()->header('X-Powered-By', 'CRUD 4.0');
}
}
|
All built-in listeners in CRUD live in the Crud\Listener
namespace.
All listeners in CRUD, even your own, should inherit from the
Crud\Listener\Base
class.
This class is abstract
and provides numerous auxiliary methods which can be
useful for you both as a developer and as an action creator.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 | <?php
namespace Crud\Listener;
class Example extends \Crud\Listener\BaseListener {
/**
* Returns a list of all events that will fire in the lister during the
* CRUD life-cycle.
*
* @return array
*/
public function implementedEvents() {
return [
'Crud.beforeRender' => ['callable' => 'beforeRender']
];
}
/**
* Executed when Crud.beforeRender is emitted
*
* @param \Cake\Event\Event $event
* @return void
*/
public function beforeRender(Cake\Event\Event $event) {
$this->_response()->header('X-Powered-By', 'CRUD 4.0');
}
}
|
As documented in the CakePHP Events System
all listeners must contain a implementedEvents
method.
In this example, we simply request that beforeRender
in our class is executed
every time a Crud.beforeRender
event is emitted.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 | <?php
namespace Crud\Listener;
class Example extends \Crud\Listener\BaseListener {
/**
* Returns a list of all events that will fire in the lister during the
* CRUD life-cycle.
*
* @return array
*/
public function implementedEvents() {
return [
'Crud.beforeRender' => ['callable' => 'beforeRender']
];
}
/**
* Executed when Crud.beforeRender is emitted
*
* @param \Cake\Event\Event $event
* @return void
*/
public function beforeRender(Cake\Event\Event $event) {
$this->_response()->header('X-Powered-By', 'CRUD 4.0');
}
}
|
Note
The Crud.beforeRender
event is similar to the Controller and View event of the
same name, but Crud.beforeRender
is called first, and can halt the entire
rendering process
This method gets executed every time a Crud.beforeRender
event is emitted
from within CRUD or by you as a developer.
When the event is emitted, we append a header to the client HTTP response named
X-Powered-By
with the value CRUD 4.0
.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 | <?php
namespace Crud\Listener;
class Example extends \Crud\Listener\BaseListener {
/**
* Returns a list of all events that will fire in the lister during the
* CRUD life-cycle.
*
* @return array
*/
public function implementedEvents() {
return [
'Crud.beforeRender' => ['callable' => 'beforeRender']
];
}
/**
* Executed when Crud.beforeRender is emitted
*
* @param \Cake\Event\Event $event
* @return void
*/
public function beforeRender(Cake\Event\Event $event) {
$this->_response()->header('X-Powered-By', 'CRUD 4.0');
}
}
|
This listener allows you to easily create a JSON or XML Api built on top of Crud.
The API listener
depends on the RequestHandler
to be loaded before Crud
[Please also see the CakePHP documentation on JSON and XML views] (http://book.cakephp.org/2.0/en/views/json-and-xml-views.html#enabling-data-views-in-your-application)
You need to tell the Router
to parse extensions else it won’t be able to
process and render json
and xml
URL extension
// config/routes.php
Router::extensions(['json', 'xml']);
Ensure this statement is used before connecting any routes.
Attach it on the fly in your controller beforeFilter, this is recommended if you want to attach it only to specific controllers and actions
<?php
class SamplesController extends AppController {
public function beforeFilter() {
parent::beforeFilter();
$this->Crud->addListener('Crud.Api');
}
}
Attach it using components array, this is recommended if you want to attach it to all controllers, application wide
<?php
class AppController extends Controller {
public $components = [
'RequestHandler',
'Crud.Crud' => [
'actions' => ['Crud.Index', 'Crud.View'],
'listeners' => ['Crud.Api']
]
];
}
The Api Listener creates 3 new detectors in your CakeRequest
object.
Checks if the extension of the request is .json
or if the requester accepts
json as part of the HTTP accepts
header
Checks if the extension of the request is .xml
or if the requester accepts
XML as part of the HTTP accepts
header
Checking if the request is either is('json')
or is('xml')
If the current request doesn’t evaluate is('api')
to true, the listener
won’t do anything at all.
All it’s callbacks will simply return NULL
and don’t get in your way.
The Api listener overrides the Exception.renderer
for api
requests,
so in case of an error, a standardized error will be returned, in either
json
or xml
- according to the API request type.
The API listener will try to enforce some best practices on how an API should behave.
For a request to index
and view
the HTTP request type must be
HTTP GET
- else an MethodNotAllowed
exception will be raised.
For a request to add
the HTTP request type must be HTTP POST
-
else an MethodNotAllowed
exception will be raised.
For a request to edit
the HTTP request type must be HTTP PUT
-
else an MethodNotAllowed
exception will be raised.
For a request to delete
the HTTP request type must be HTTP DELETE
-
else an MethodNotAllowed
exception will be raised.
The default response format for both XML and JSON is two root keys,
success
and data
.
It’s possible to add your own root keys simply by _serialize
view var.
{
"success": true,
"data": {
}
}
<response>
<success>1</success>
<data></data>
</response>
The data.exception
key is only returned if debug
is > 0
{
"success": false,
"data": {
"code": 500,
"url": "/some/url.json",
"name": "Some exception message",
"exception": {
"class": "CakeException",
"code": 500,
"message": "Some exception message",
"trace": []
}
}
}
<response>
<success>0</success>
<data>
<code>500</code>
<url>/some/url.json</url>
<name>Some exception message</name>
<exception>
<class>CakeException</class>
<code>500</code>
<message>Some exception message</message>
<trace></trace>
<trace></trace>
</exception>
<queryLog/>
</data>
</response>
success
is based on the event->subject->success
parameter from Add
or Edit
action.
If success
is false
a HTTP response code of 400
will be returned,
and the data
property will be the list of validation errors from the model.
If success
is true
a HTTP response code of 201
will be returned
if the model item was created else a 301
response code will be used.
A success will always include a HTTP Location
header to the view
action with the existing or newly created id of the record
success
is based on the event->subject->success
parameter from
the delete
action.
data
will always be null
.
No special HTTP codes is sent.
In case an id
is provided to a crud action and the id does not exist in
the database, a 404
NotFoundException` will be thrown.
In case a ìd
is provided to a crud action and the id is not valid
according to the database type a 500 BadRequestException
will be thrown
Note
This feature requires the API listener to work.
This listener appends pagination information to the API responses that is contain pagination information.
Attach it on the fly in your controller beforeFilter, this is recommended if you want to attach it only to specific controllers and actions
<?php
class SamplesController extends AppController {
public function beforeFilter() {
$this->Crud->addListener('Crud.Api'); // Required
$this->Crud->addListener('Crud.ApiPagination');
}
}
Attach it using components array, this is recommended if you want to attach it to all controllers, application wide
<?php
class SamplesController extends AppController {
public $components = [
'RequestHandler',
'Crud.Crud' => [
'listeners' => [
'Crud.Api', // Required
'Crud.ApiPagination'
]
];
}
Paginated results will include a
{
"success": true,
"data":[
],
"pagination":{
"page_count": 13,
"current_page": 1,
"count": 25,
"has_prev_page": false,
"has_next_page": true
}
}
Note
This feature requires the API listener to work.
This listener appends query log information to the API responses
The listener will only append the queryLog
key if debug
is set to true.
Attach it on the fly in your controller beforeFilter, this is recommended if you want to attach it only to specific controllers and actions
<?php
class SamplesController extends AppController {
public function beforeFilter() {
$this->Crud->addListener('Crud.Api'); // Required
$this->Crud->addListener('Crud.ApiQueryLog');
}
}
Attach it using components array, this is recommended if you want to attach it to all controllers, application wide
<?php
class SamplesController extends AppController {
public $components = [
'RequestHandler',
'Crud.Crud' => [
'listeners' => [
'Crud.Api', // Required
'Crud.ApiQueryLog'
]
];
}
Paginated results will include a
{
"success": true,
"data": [
],
"queryLog": {
"default": {
"log": [
{
"query": "SELECT SOMETHING FROM SOMEWHERE",
"took": 2,
"params": [
],
"affected": 25,
"numRows": 25
},
{
"query": "SELECT SOMETHING FROM SOMEWHERE'",
"params": [
],
"affected": 1,
"numRows": 1,
"took": 0
}
]
}
}
}
Enable more complex redirect rules.
Attach it on the fly in your controller beforeFilter, this is recommended if you want to attach it only to specific controllers and actions:
<?php
class SamplesController extends AppController {
public function beforeFilter() {
$this->Crud->addListener('Crud.Redirect');
parent::beforeFilter();
}
}
?>
Attach it using components array, this is recommended if you want to attach it to all controllers, application wide:
<?php
class SamplesController extends AppController {
public $components = [
'Crud.Crud' => [
'actions' => ['index', 'view'],
'listeners' => ['Crud.Redirect']
];
}
?>
A reader is a closure that can access a field in an object through different means.
Below is a list of the build-in readers you can use:
Name | Pseudo code | Description |
---|---|---|
request.key |
$this->request->{$field} |
Access a property directly on the Request object |
request.data |
$this->request->data($field) |
Access a HTTP POST data field using Hash::get() compatible format |
request.query |
$this->request->query($field) |
Access a HTTP query argument using Hash::get() compatible format |
model.key |
$Model->{$field} |
Access a property directly on the Model instance |
model.data |
$Model->data[$field] |
Access a model data key using Hash::get() compatible format |
model.field |
$Model->field($field) |
Access a model key by going to the database and read the value |
subject.key |
$CrudSubject->{$key} |
Access a property directly on the event subject |
Adding or overriding a reader is very simple.
The closure takes two arguments:
CrudSubject $subject
$key = null
<?php
class SamplesController extends AppController {
public function beforeFilter() {
$listener = $this->Crud->listener('Redirect');
$listener->reader($name, Closure $closure);
// Example on a reader using Configure
$listener->reader('configure.key', function(CrudSubject $subject, $key)) {
return Configure::read($key);
});
parent::beforeFilter();
}
}
?>
Below is the defaults provided by build-in Crud actions:
By default Add Crud Action always redirect to array('action' => 'index')
on afterSave
Name | Reader | Key | Result | Description |
---|---|---|---|---|
post_add |
request.data |
_add |
array('action' => 'add') |
By providing _add as a post key, the user will be redirected back to the add action |
post_edit |
request.data |
_edit |
array('action' => 'edit', $id) |
By providing _edit as a post key, the user will be redirected to the edit action with the newly created ID as parameter |
By default Edit Crud Action always redirect to array('action' => 'index')
on afterSave
Name | Reader | Key | Result | Description |
---|---|---|---|---|
post_add |
request.data |
_add |
array('action' => 'add') |
By providing _add as a post key, the user will be redirected back to the add action |
post_edit |
request.data |
_edit |
array('action' => 'edit', $id) |
By providing _edit as a post key, the user will be redirected to the edit action with the same ID as parameter as the current URL |
It’s very simple to modify existing or add your own redirect rules:
<?php
class SamplesController extends AppController {
public function beforeFilter() {
// Get all the redirect rules
$rules = $this->Crud->action()->redirectConfig();
// Get one named rule only
$rule = $this->Crud->action()->redirectConfig('add');
// Configure a redirect rule:
//
// if $_POST['_view'] is set then redirect to
// 'view' action with the value of '$subject->id'
$this->Crud->action()->redirectConfig('view',
[
'reader' => 'request.data', // Any reader from the list above
'key' => '_view', // The key to check for, passed to the reader
'url' => [ // The url to redirect to
'action' => 'view', // The final url will be '/view/$id'
['subject.key', 'id'] // If an array is encountered, it will be expanded the same was as 'reader'+'key'
]
]
);
parent::beforeFilter();
}
}
?>
Any class can be used as a CRUD Listener, even the controller.
We override the implementedEvents()
method in the controller, and bind
the Crud.beforeFind
event to the _beforeFind()
method in the controller.
<?php
namespace app\Controller;
class BlogsController extends AppController {
public function implementedEvents() {
return parent::implementedEvents() + [
'Crud.beforeFind' => '_beforeFind'
];
}
public function _beforeFind(\Cake\Event\Event $event) {
}
}
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.
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.
<?php
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.
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();
- else CRUD will not process the
action.
This is functionality wise more or less the same as using an controller method instead.
The benefit of the controller method is that you can easily share it between two actions, like showcased 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()
}
This is a full list of all events emitted from CRUD.
Each individual CRUD action contains the same documentation, but only the events relevant for that action.
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.
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.
This event is emitted before calling Table::delete
.
The Crud Subject contains the following keys:
Entity
from the find()
call.To abort a delete()
simply stop the event by calling
$event->stopPropagation()
.
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->subject->item->author !== 'admin') {
$event->stopPropagation();
}
});
return $this->Crud->execute();
}
This event is emitted after Table::delete()
has been called.
The Crud Subject contains two keys:
true
the delete()
call succeeded, false
otherwisepublic function delete($id) {
$this->Crud->on('afterDelete', function(\Cake\Event\Event $event) {
if (!$event->subject->success) {
$this->log("Delete failed for entity $event->subject->id");
}
});
return $this->Crud->execute();
}
The event is emitted before calling the find method in the table.
The Crud Subject contains the following keys:
Repository
(Table
) which the query will be executed against.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 Crud.recordNotFound
event is emitted instead of Crud.afterFind
.
public function delete($id) {
$this->Crud->on('beforeFind', function(\Cake\Event\Event $event) {
$event->subject->query->where(['author' => $this->Auth->user('id')]);
});
return $this->Crud->execute();
}
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.item
The record that was found in the database.Note
If an entity is not found, the RecordNotFound
event is emitted instead.
public function delete($id) {
$this->Crud->on('afterFind', function(\Cake\Event\Event $event) {
$this->log("Found item: $event->subject->item->id in the database");
});
return $this->Crud->execute();
}
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
object marshaled with the HTTP POST
data from the request.string
with the saveMethod
.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
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:
Table::save()
was successful.Table::save()
call succeed or not.true
if the record was created
and false
if the record was updated
.entity
object marshaled with the HTTP POST
data from the request and the save()
logic.public function edit($id) {
$this->Crud->on('afterSave', function(\Cake\Event\Event $event) {
if ($event->subject->created) {
$this->log("The entity was created");
} else {
$this->log("The entity was updated");
}
});
return $this->Crud->execute();
}
public function edit($id) {
$this->Crud->on('afterSave', function(\Cake\Event\Event $event) {
if ($event->subject->success) {
$this->log("The entity was saved successfully");
} else {
$this->log("The entity was NOT saved successfully");
}
});
return $this->Crud->execute();
}
public function add() {
$this->Crud->on('afterSave', function(\Cake\Event\Event $event) {
if ($event->subject->created) {
$this->log("The entity was created with id: $event->subject->id");
}
});
return $this->Crud->execute();
}
This event is emitted before Controller::paginate()
is called.
public function index() {
$this->Crud->on('beforePaginate', function(\Cake\Event\Event $event) {
$this->paginate['conditions']['is_active'] = true;
});
return $this->Crud->execute();
}
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.
public function index() {
$this->Crud->on('afterPaginate', function(\Cake\Event\Event $event) {
foreach ($event->subject->entities as $entity) {
// $entity is an entity
}
});
return $this->Crud->execute();
}
Simple and event driven wrapper for Controller::redirect()
.
The Crud Subject contains the following keys:
Controller::redirect()
.Controller::redirect()
.Controller::redirect()
.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.
Invoked right before the view will be rendered.
This is also before the controllers own beforeRender callback.
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
Simple and event driven wrapper for SessionComponent::setFlash
.
The Crud Subject contains the following keys:
SessionComponent::setFlash
.SessionComponent::setFlash
.SessionComponent::setFlash
.SessionComponent::setFlash
.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.
To ease with unit testing of Crud Listeners and Crud Actions, it’s recommended to use the proxy methods found in [CrudBaseObject]({{site.url}}/api/develop/class-CrudBaseObject.html).
These methods are much easier to mock than the full CrudComponent object.
They also allow you to just mock the methods you need for your specific test, rather than the big dependency nightmare the CrudComponent can be in some cases.<br />
These methods are available in all CrudAction and CrudListener objects.
Trigger a Crud Event
$this->_trigger('beforeSave')
$this->_trigger('beforeSave', ['data' => 'keys'])
$this->_trigger('beforeSave', $this->_subject(['data' => 'keys']))
Create a Crud Subject - used in $this->_trigger
$this->_subject()
$this->_subject(['data' => 'keys'])