Passing values to future entities of a given table?

Hi everyone

What I have

I’m working on a CakePHP 5 plugin that acts as a connector to an external database. My intention was to allow having multiple instances of the same plugin connected to different databases on the same page.

Example:

/*
 * Connector->__construct() takes configuration name, fetches it, and saves a copy to a local property, say `$this->configuration`
 */
$instance1 = new \MyPlugin\Connector('config1');
$instance2 = new \MyPlugin\Connector('config2');
/*
 * Users is not a real property, it gets passed to `__get()` where I find the right table and return it.
 */
$instance1->Users->find(…)->first();
$instance2->Users->find(…)->first();

The above already works and I’m getting two separate User entities from different databases. So far so good.

What I want

I want each of these entities to know the configuration they came from.

I can manipulate the table object inside __get before I return it. This seems like the only place where I have access to both my configuration and the actual table instance from which the entities will be coming out of.

What I tried

  • The simplest would be to just put something into a property on the table instance. But that’s useless since I can’t access the actual table instance from within an entity. I can only get the name/alias of the table, but not the table instance itself.
  • I also searched for something like an afterEntity in Table events list, but there’s nothing like that.
  • I also considered maybe hooking into the table afterFind, so that I can get my hands on the results and just add my information to each of the entities that way, but afterFind has been removed from CakePHP

At this point I start feeling like I’m fighting the framework, which is never a good sign. But then again I think what I want to accomplish is reasonable?

Please let me know if something is unclear

Figured I should try to be as clear as possible. So here’s a specific case.

  1. My plugin is a Wordpress connector. It should query Posts table and return Post entities.
  2. A Post entity needs to have a way to return the post url. Via a method or a virtual field, doesn’t matter.
  3. The issue is that permalink format is configurable in Wordpress. So the Post entity needs to be aware of that. Querying the WP Options database table from within Post entity is bad practice.
  4. Best way out of this seems to be fetching all Options for a specific Wordpress site on Connector::__construct(), i.e. when I do $instance1 = new \MyPlugin\Connector('config1');, and then cache these options somewhere inside the connector instance.
  5. Figure out a way to have each entity in this plugin be aware of which connector it belongs to.

It does seem like you’re fighting the framework, which I agree is a bad sign. If you really need to do this, perhaps you need to step outside the framework slightly, by overriding some table methods in whatever class $instanceX->Users is? I haven’t looked at any of the specifics of what you’d need here, but maybe it’s as simple as overloading the first and all functions to call the default (parent) implementation, then update the entity/entities that they return before returning it/them to the caller? Maybe there’s some common function they both use for creating entities which would be an even better place to hook in…