0

I have a CakePHP 3.4 application, which has been developed a couple of years ago and has a few thousands users.

I am currently working on a new version of this application, and my client wants it to be visible only by a few selected users before we release it for everyone else.

Unsure about what is the right way to do so I have chosen to develop a new theme plugin, which overrides a few controllers, layouts, assets, routes etc.

Everything is working correctly, but now I need to specify which users should see the newer version. To accomplish this I've added a theme field in my users table, and in my AppController's beforeRender method I have added this:

$theme = $this->request->session()->read("Auth.User.theme");
    if ($theme !== null) {
    $this->viewBuilder()->theme('Theme2');
}

To use the newer version I also need to load the new theme in my bootstrap.php:

Plugin::load('Theme2', ['bootstrap' => false, 'routes' => true, 'autoload' => true]);

So, if both the theme and the plugin are set, the user will see the newer version.

If neither the theme or the plugin are set, the user will see the old version.

My question is: how can I load the theme plugin only for selected users?

ToX 82
  • 1,064
  • 12
  • 35
  • 1
    You're not limited to loading plugins in your bootstrap file, technically you can load them at any point. – ndm Aug 13 '18 at 11:16
  • You've just saved my day :) I've moved the plugin loading to my AppController's beforeRender (within the theme check) and it just works. Thanks! – ToX 82 Aug 13 '18 at 11:28
  • Unfortunately, after a few more tests it appears that loading the plugin in my AppController is not making it load the routes from the plugin... – ToX 82 Aug 13 '18 at 12:54
  • You can load the routes explicitly via `Plugin::routes('Theme2')`. You can also load the plugin earlier, that is before the automatic plugin route loading happens, for example in a [**custom middleware**](https://book.cakephp.org/3.0/en/controllers/middleware.html#creating-middleware) handler (placed before the routing middleware), at that point you also have access to the session via the request object (`$request->getAttribute('session')` or `$request->session()`, depending on the type cast used). – ndm Aug 13 '18 at 13:25
  • Adding `Plugin::routes('Theme2');` right after `Plugin::load('Theme2', ['bootstrap' => false, 'routes' => true, 'autoload' => true]);` doesn't seem to work, as the plugin's routes are still not loaded. I've tried putting that code in the `beforeFilter` method, is that right? – ToX 82 Aug 13 '18 at 13:55
  • Unless proven otherwise, I'd claim that this will load the routes. Maybe your code relies on these routes being present at an earlier point, if so, go with loading the plugin earlier. – ndm Aug 13 '18 at 14:24
  • What I find strange is that neither in the routes panel in DebugKit nor in the includes panel I see anything related to Theme2, if I remove the plugin loading from my `bootstrap.php` file... – ToX 82 Aug 13 '18 at 14:34
  • That is because Debug Kit controllers do not extend `AppController`, so neither the plugin nor the routes will be available to Debug Kit. Again, try loading the Plugin earlier at middleware level. – ndm Aug 13 '18 at 14:57

0 Answers0