Modify table and entity of main app from plugin


#1

Hii there,

This may sound a bit weird, but I have a main app that has the Permission table with the following columns:

  • role_id (foreign key from the Roles table, but that shouldn’t matter)
  • access_cms (boolean)

These columns also have been added to the entity.

Now in my plugin, I want to modify this table from the plugin’s migrations by adding the add_posts column.
Ofcourse, I also need the required entity for this.

My question is, how would I go about this?
Due to the way we want to set up our app (everything that is non-core - eg. the blog part - will become a plugin).
So that’s the catch in this, I can’t simply add it to the main app, because we won’t use it in all websites we base on this App.

My first thought is to create the Table and Entity in the plugin’s sources, but then I don’t know how to load these into the main Table and Entity.
I know that Controllers have parent::initialize() but is there something like that for the Tables and Entities? (and since I also need to update the $_protected, I wonder how that would work)


#2

You can use behaviors for that.
On plugin initialization, do something like this

TableRegistry::get('App.Posts')->addBehavior('MyPlugin.Post');

On the behavior initialization you get the table via $this->_table variable, you can call setEntityClass to the plugins entity.

But I think if you change the entity properties, you can’t do this twice as will be 2 distinct classes. The marshaller only use one at the time (the last one setted)


#3

Behaviours don’t seem to accomplish what I wanted.
Because I do not see how I would go about creating the stuff this plugin needs in the actual database n such.
Or I’m misunderstanding the use of behaviours.


#4

For actual changes in the database you need to use migrations. But If your base is customizable you might need to create bake templates for those Migrations.

If the table will always be the same (‘posts’) then you can run migrations like

bin/cake migrations migrate -p MyPlugin

#5

Yes, the migrations have been made, but don’t I need to edit the Table and Entity in the model aswell?
because that’s what my question is mainly about.
and using behaviours doesn’t seem like they are made for that purpose.


#6

Behaviors can change everything of the table.

// src/Model/Table/MyTable.php
public function initialize($config)
{
    parent::initialize($config);
    $this->setTable('my_table');
    $this->setPrimaryKey('id');

   $this->addBehavior('MyPlugin.Custom');
}


// plugins/MyPlugin/src/Model/Behavior/CustomBehavior.php
public function initialize($config)
{
    parent::initialize($config);
    $this->_table->setPrimaryKey('another_id');
    $this->_table->setEntityClass(\MyPlugin\Model\Entity\Custom::class);
}


// In a Controller/Shell/etc
$this->loadModel('MyTable');
// Without the behavior
$this->MyTable->get(1); // an instance of \App\Model\Entity\MyTable
// With the behavior
$this->MyTable->get(1); // an instance of \MyPlugin\Model\Entity\Custom

#7

Ohhhh, I see now :slight_smile:
With these examples, it made a lot more sense :slight_smile:

I’ll go fiddle with it over the next few days!

One more question

will this override the previous class or add it to the previous class?


#8

It will Override it. You may have to force the use of traits/interfaces in the original EntityClass