Revision: Fri, 20 Dec 2024 23:34:11 GMT

Mapper extending

You can alter any of the command(s) generated by the ORM mappers by replacing it with your own implementation. Another option is to create your own commands and link them to the update, insert or delete.

Hook into Insert/Update/Delete command

To add your own handler when an entity is created, updated or deleted modify the methods queueCreate, queueUpdate and queueDelete of your entity wrapper.

php
use Cycle\ORM\Command\CommandInterface;
use Cycle\ORM\Mapper\Mapper;
use Cycle\ORM\Heap\Node;
use Cycle\ORM\Heap\State;

class MyMapper extends Mapper
{
    public function queueCreate(object $entity, Node $node, State $state): CommandInterface
    {
        $cmd = parent::queueCreate($entity, $node, $state);
        
        // do something
        
        return $cmd;
    }

    public function queueUpdate(object $entity, Node $node, State $state): CommandInterface
    {
        $cmd = parent::queueUpdate($entity, $node, $state);
        
        // do something
        
        return $cmd;
    }

    public function queueDelete(object $entity, Node $node, State $state): CommandInterface
    {
        $cmd = parent::queueDelete($entity, $node, $state);
        
        // do something
        
        return $cmd;
    }
}

And assign the entity to the specific mapper:

php
use Cycle\Annotated\Annotation\Entity;

#[Entity(mapper: MyMapper::class)]
class User
{
   //...
}

Command Chain

We can link another command to be executed right after $cmd:

php
use Cycle\ORM\Command;
use Cycle\ORM\Heap;

public function queueCreate(object $entity, Heap\Node $node, Heap\State $state): Command\CommandInterface
{
    $cmd = parent::queueCreate($entity, $node, $state);

    $cs = new Command\Special\Sequence($cmd);
    $cs->addCommand(new OurCommand());

    return $cs;
}

In case of Create, the primary key sequence won't be available at the moment of queueCreate call (it will be available after SQL INSERT query).

This value must be forwarded to our command using forward method from $cmd:

php
use Cycle\ORM\Commande;
use Cycle\ORM\Heap;
use Cycle\ORM\Command\Database\Insert;

public function queueCreate(object $entity, Heap\Node $node, Heap\State $state): Commande\CommandInterface
{
    $cmd = parent::queueCreate($entity, $node, $state);
    $our = new OurCommand();

    // wait for cmd_id value or fail
    $our->waitContext('cmd_id', true);

    // send lastID value as cmd_id to $our command
    $cmd->forward(Insert::INSERT_ID, $our, 'cmd_id');

    $cs = new Command\Special\Sequence($cmd);
    $cs->addCommand($our);

    return $cs;
}

Example: see sample implementation which copies all entity changes into a separate table.

Autoconfiguration

ORM schema provides one reserved Entity constant SCHEMA which can be used to specify custom Mapper behavior. You can combine schema-builder and custom mapper implementation to create configurable mappers.

Cycle does not provide such mapper implementations (a.k.a. "behaviors") out of the box, feel free to suggest your implementation as an extension.

Edit this page