4

In order to build an extendable blogging system with CakePHP I’d like to realize something like extension hooks in Wordpress. My plan is to have a base SQL to load the articles in the main application. This SQL should be possible to extend by a variable set of plugins (one plugin for each special article type).

I already know that CakePHP’s way to realize something like that is the events system. I have some trouble registering listeners residing in my plugins, though.

The official documentation (3.x Book; http://book.cakephp.org/3.0/en/core-libraries/events.html#registering-listeners) says, that a listener can be registered this way:

// Attach the UserStatistic object to the Order's event manager
$statistics = new UserStatistic();
$this->Orders->eventManager()->on($statistics);

Unfortunately it doesn’t tell where to place this code in order to register the listener automatically while bootstrapping. Placing the following lines in my plugin’s bootstrap.php like so:

$tester = new Lib\Tester();
$this->Orders->eventManager()->on($tester);

… (having a class Tester in plugins/MyPlugin/src/Lib of course) results in errors. In the first line the listener class cannot be found (“Error: Class 'Lib\Tester' not found”). And in the second line $this must not be used in the context of bootstrap.php (“Error: Using $this when not in object context”).

In an old thread (Where to register event listeners) someone else asked for the same thing and got a pretty detailed answer. It was for CakePHP 2.x, though, and doesn’t work with CakePHP 3.x anymore. For example, the function App::uses doesn’t exist in CakePHP 3.x and I couldn’t find a replacement.

So: can someone please help me find the right way to set up a working listener within a plugin in CakePHP 3.x?

[UPDATE #1]

I've found a workaround that works for me (but is quite ugly). In the bootstrap.php of the plugin I was able to instantiate an object of my event listener class like this:

require __DIR__ . '/../src/Lib/Tester.php';
$tester = new MyPlugin\Lib\Tester();

After that I could register the listener on the Articles model (also in bootstrap.php of course):

Cake\ORM\TableRegistry::get('Articles')->eventManager()->on($tester);

That way I'm now able to build up a base request on the articles table and send it to several plugins. Then the plugins can enrich the request to join special tables or something like that.

So, one question remains: how can I avoid the use of the __DIR__ in bootstrap.php? How can the listener be instantiated properly?

[UPDATE #2]

It seems as if the complete src subdirectory of my plugin isn't part of the import path. None of the classes I put there gets loaded. That means that CakePHP doesn't find a simple Controller when I place one there.

Am I doing something wrong in general? Or might that be a bug in CakePHP?

Unfortunately I neither can find plugins for CakePHP 3.x whose source code could help me understand what I might do wrong.

Community
  • 1
  • 1
F.C.Kawé
  • 61
  • 4
  • Have you read and followed **http://book.cakephp.org/3.0/en/plugins.html#creating-a-plugin-using-bake** and **http://book.cakephp.org/3.0/en/plugins.html#autoloading-plugin-classes**? – ndm Apr 14 '16 at 18:10
  • Yes, of course. I didn't create my (current) plugin using bake, though. But that should be optional, shouldn't it? [EDIT:] And a former try was with bake... – F.C.Kawé Apr 15 '16 at 07:30
  • It is optional, yes, but requires you to setup autoloading manually. Generally this sounds like an autoloading issue to me, but I can't really tell you anything else than the linked docs. If you've followed it, and it still doesn't work, while loading the files manually does (ie no permission issue), then I'm kinda stumped. – ndm Apr 15 '16 at 08:25
  • Yeah, you really had the right idea. In fact I did a mistake in my application's `composer.json` file! :( After correcting that and running `dumpautoload` again it works now. I can't explain why my former example using bake didn't work either. But that doesn't really matter. Thank you very much! – F.C.Kawé Apr 15 '16 at 08:54

1 Answers1

0

... as ndm assumed in a comment above, there was something wrong with my manually inserted parts in the composer.json file. After fixing that and running dumpautoload again all classes get loaded, now.

F.C.Kawé
  • 61
  • 4