Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 7 additions & 1 deletion en/appendices/4-1-migration-guide.rst
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ ORM

* BelongsToMany associations now respect the bindingKey set in the junction table's BelongsTo association.
Previously, the target table's primary key was always used instead.

TestSuite
---------

Expand Down Expand Up @@ -120,6 +120,12 @@ Log
* Log messages can now contain ``{foo}`` style placeholders. These placeholders
will be replaced by values from the ``$context`` parameter if available.

ORM
---

* The ORM now triggers an ``Model.afterMarshal`` event which is triggered after
each entity is marshaled from request data.

TestSuite
---------

Expand Down
28 changes: 28 additions & 0 deletions en/orm/saving-data.rst
Original file line number Diff line number Diff line change
Expand Up @@ -636,6 +636,34 @@ Moreover, the data in ``beforeMarshal`` is a copy of the passed data. This is
because it is important to preserve the original user input, as it may be used
elsewhere.

Modifying Entities After Updating From Request Data
---------------------------------------------------

The ``Model.afterMarshal`` event allows you to modify entities after they have
been created or updated from request data. It can be useful to apply additional
validation logic that you cannot easily express through Validator methods::

// Include use statements at the top of your file.
use Cake\Event\EventInterface;
use Cake\ORM\EntityInterface;
use ArrayObject;

// In a table or behavior class
public function afterMarshal(
EventInterface $event,
EntityInterface $entity,
ArrayObject $data,
ArrayObject $options
) {
// Don't accept people who have a name starting with J on the 20th
// of each month.
if (substr($entity->name, 1) == 'J' && date('d') === 20) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks!

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

date('d') is string .

Use either idate('d') or compare to '20'

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

(int) cast would also suffice, I fix that up.

$entity->setError('name', 'No J people today sorry.');
}
}

.. versionadded:: 4.1.0

Validating Data Before Building Entities
----------------------------------------

Expand Down
12 changes: 12 additions & 0 deletions en/orm/table-objects.rst
Original file line number Diff line number Diff line change
Expand Up @@ -139,6 +139,7 @@ Event List

* ``Model.initialize``
* ``Model.beforeMarshal``
* ``Model.afterMarshal``
* ``Model.beforeFind``
* ``Model.buildValidator``
* ``Model.buildRules``
Expand Down Expand Up @@ -196,6 +197,17 @@ beforeMarshal
The ``Model.beforeMarshal`` event is fired before request data is converted
into entities. See the :ref:`before-marshal` documentation for more information.

afterMarshal
-------------

.. php:method:: afterMarshal(EventInterface $event, EntityInterface $entity, ArrayObject $data, ArrayObject $options)

The ``Model.afterMarshal`` event is fired after request data is converted
into entities. Event handlers will get the converted entities, original request
data and the options provided to the ``patchEntity()`` or ``newEntity()`` call.

.. versionadded:: 4.1.0

beforeFind
----------

Expand Down