How can I define a replicate behavior for the execute method without changing all the models’ namespace?

I have a class like this:


namespace AppORM;

use CakeORMQuery as ORMQuery;
use CakeDatabaseValueBinder;
use CakeDatasourceConnectionManager;

class Query extends ORMQuery

    /*Some stuff which has no relevance in this question*/

    protected $mainRepository;

    protected function isReplicate()
        return ($this->mainRepository && $this->mainRepository->behaviors()->has('Replicate') && ($this->getConnection()->configName() !== 'c'));

    public function __construct($connection, $table)
        parent::__construct($connection, $table);
        $this->mainRepository = $table;

    public function execute()
        if ($this->isReplicate()) {
            $connection = $this->getConnection();
            $replica = clone $this;
        $result = parent::execute();
        return $result;

This works well, that is, there is a central c server and there are other servers that are separated by districts. There are some tables that are to be refreshed on c when something was executed for them on a district server. Table models that are to be replicated look like this:


namespace AppModelTable;

use AppORMTable;

class SomeNameTable extends Table
    public function initialize(array $config)
        /*Some initialization that's irrelevant from the problem's perspective*/

Everything works, but there is a catch. The use AppORMTable; statement specifies that my own Table implementation should be used and that Table implementation ensures that once query is being called, my Query class will be used, described in the first code chunk from this question. This is my Table class:


namespace AppORM;

use CakeORMTable as ORMTable;

class Table extends ORMTable
    public function query()
        return new Query($this->getConnection(), $this);

As mentioned earlier, everything works as expected, but this approach effectively means that I will need to change the namespace of the base class for all the models where this replication behavior is needed. This is surely easy to do now, but in the future I worry that some new tables are to be replicated and developers working on that will not read documentation and best practices section, inheriting the model directly from Cake’s class with the same name. Is there a way to tell Cake that I would like all models fulfilling some logical validation, (for example for models that have a behavior) will use the overriden execute method? In general, the answer to such questions would be a “no”, but I wonder whether Cake has a feature for overriding code behavior based on some rules.


function isReplicate($model) {
    return ($model->behaviors()->has('Replicate'));

The function above could determine whether the new execute is preferred or the old, Cake one.


Thank you for visiting the Q&A section on Magenaut. Please note that all the answers may not help you solve the issue immediately. So please treat them as advisements. If you found the post helpful (or not), leave a comment & I’ll get back to you as soon as possible.

Method 1

Not really, no, at least as far as I understand your question.

There’s events that you could utilize, Model.initialize for example, it would allow you to check whether the initialized model has a specific behavior loaded, but you would not be able to change how the inherited query() method behaves.

You could use it for validation purposes though, so that developers that don’t follow your documentation get slapped in the face when they don’t extend your base table class, eg check whether it’s being extended and throw an exception if that’s not the case, something along the lines of this:

// in `Application::bootstrap()`

    function (CakeEventEventInterface $event) {
        $table = $event->getSubject();
        assert($table instanceof CakeORMTable);

        if (
            $table->behaviors()->has('Replicate') &&
            !is_subclass_of($table, AppModelTableAppTable::class)
        ) {
            throw new LogicException(
                'Tables using the Replicate behavior must extend AppModelTableAppTable'

See also

All methods was sourced from or, is licensed under cc by-sa 2.5, cc by-sa 3.0 and cc by-sa 4.0

0 0 votes
Article Rating
Notify of

Inline Feedbacks
View all comments
Would love your thoughts, please comment.x