Working with Craft (like any other system) means that you are stuck doing things the way the system dictates or causing a lot of trouble for yourself.
One of the things where this becomes clear is when developers want to use arbitrary classes in their Craft plugins.
Usually this means people just dump the class somewhere (like in the services or model directory), bung an appropriate suffix to their classname (for instance
Model) so the class will get auto-loaded and Bob's your uncle.
Of course this has the disadvantage that your meticulously crafted SOAP client is now called
Besides being semantically wrong this is also confusing for any developer not familiar with the project.
So I thought to myself "There has to be a better way".
Using the framework's autoloader
At first I tried to get things to work through Composer and use the autoloaders it provides, but that felt very much like going against the grain. Craft is build on top of the YII framework (version 1, not version 2).
So I looked into how YII handles things.
The code of YII.v1 is a bit of an eyesore. Many things that are now considered a bad practice are prevelant in YII.v1. Naming conventions are one of them. This means adhering to some standards that are not PSR-2 or PSR-4 compliant. But it'll work none the less.
Go ahead, be a rebel. I'm sure no-one will mind, as long as it works.
Step by step
- Create a directory named
srcin the root directory of the plugin
initmethod of the plugin class with a namespace of choice.
- Create a class in the
srcdirectory using the registered namespace.
Please be aware that folders/files must match the namespace/classname capitalization. So if your class is called
Foo\bar the filepath must be
Example files are included with this gist
Variation on a theme
Because of the way the "aliassing" works, it is not possible to add a "sub-namespace". If you have your heart set on using
MyVendor\MyPlugin instead of the admittedly ugly
src directory should be registered as vendor
\YiiBase::setPathOfAlias('MyVendor', __DIR__ . '/src'); and a directory needs to be created in