How to resolve multiple plugin communication with "core" plugin (CakePHP 4)

Hello

Situation: I want to build “core” plugin that does login and permission based on type of user that joined the system so let’s say
MainPlugin -> and all urls should be domain.com/main-plugin/* and we check if he’s logged in do all cool stuff.
Now I want to have for example SecondPlugin and ThirdPlugin that may both or just one of them be in a project depending on client needs.
And here’s the issues I want ALL requests that are done to Second/Third plugin controller to go through my MainPlugin AppController so they always have all user validation done
so when user goes to /second-plugin/workers/index -> first it’s processed by main-plugin and THEN it’s filtered by second-plugin.

I hope it’s clear enough, basically I want to attach as many of plugins that do their own thing and keep them separate from core plugin on which they are depended which is performing all necessary user permission magic so I do not have to copy into them any single line related to checking logged user.

And hello to everyone:) since I believe this is my first post

Right. And plugins are added before controllers are even running, so no login, so no validation of the user can be done?

Not sure if this will work but:

I’m guessing your plugins are being loaded in src/Application.php So, only load your authentication plugin.

In the controller context, once you know the user is validated but before the actual controller action is called trigger an event that has a handler defined in Application.php. That event handler should then have the information it needs to decide which additional plugins to load.

I’m not sure if the beforeFilter() event falls in the correct place but it feels about right. But I have no experience of research to suggest that is correct. Here are your choices

1 Like

You should be using Authentication and/or Authorization as Middlewares, maybe have a MainAuthorizationMiddleware as base and one for each plugins that extends it, (applying scoped middlewares)

That way those middlewares are what you are calling ‘AppController’

Yea but like I said MainPlugin does magic ;D so selecting right layout/loading extra data while authorisation and authentication is only part of its job.
So when the request goes to SecondPlugin I need the request first to use all the “initial” setup from main plugin which involves beforeFilter beforeRender.

So let’s say we have calendarplugin
backend master admin opens /calendarplugin/index so before calendar plugin loads “content” I want main plugin to setup right layout/info about logged user
backend low level admin opens /calendarplugin/index he gets the view without some actions in his preferred language and seeing only his event
backend super low level admin opens /calendarplugin/index he gets nice information that he cannot access any of those informations.

So the calendarplugin does only it’s own thing and it’s a matter of uninstall/install in project to add this functionality. Because I do not want to have main plugin with everything (which would solve all my problems :smiley: ) because then it’s much harder to update parts of it or remove/add something based on client needs.

Right now I just do components/helpers in my “childplugins” and use them in mainplugin but I want to put there full MVC, yet I do not succeed in running from mainplugin events like beforeFilter/Render etc.
and then their own.

Worst case scenario I can move “mainplugin” to default AppController -> but I want to avoid it and keep it as clean as possible so it’s only doing frontend managment

Definitely sounds like what you need is for your plugins’ initialization (main as well as optional ones) to register some listeners for specific events (e.g. the beforeFilter and beforeRender). There can be as many listeners as required on any given event, so your main plugin can use them to set the theme, while the optional plugins could use them to add menu items, for example.

Thank you :slight_smile: gonna dig into it this week !

You can also set the plugins controllers to extend MainPlugin’s AppController, just call parent::beforeFilter and such

namespace MainPlugin/Controller;
class AppController extends Controller {
   public function beforeFilter() {
      // ...
   }
}
// ...
namespace MyPlugin/src/Controllers;
class AppController extends MainPlugin/Controller/AppController {
   public function beforeFilter() {
      parent::beforeFilter();
      // ...
   }
}

This would not, however, have any effect on pages generated by controllers in the other plugins, unless they also extend this AppController. Whether that’s a bug or a feature is very much situation-dependent.