CakePHP 4: Load Extend Files from a Plugin

I am running inside a CakePHP 4 plugin and I need to extend a Vendor file in order to provide SMS support.

In CakePHP 2 I used:

App::import(‘Vendor’, ‘mypluginname.Twilio’, [‘file’ => ‘SMS’ . DS . ‘Twilio.php’]);

but that doesn’t work in CakePHP 4

I’ve required the vendor inside composer.json in my plugin:

“require”: {
“twilio/sdk”: “^6.10.0”
},

I try and use my custom class and it cannot find \Twilio\Http\CurlClient which causes it to throw an exception when I try to use the class

namespace mypluginname\Core;

use Twilio\Http\CurlClient;
use Twilio\Http\Response;

class MyTwilioClient extends \Twilio\Http\CurlClient
{

}

Any ideas how I can include/extend the vendor files?

Thanks in advance.

Did you regenerate the autoload files after updating your composer.json?

Thanks for replying, I did a composer install and it created an auto-load file, but I didn’t do anything else, I was under the impression because Twilio is listed under require it gets auto-included (maybe that’s my issue).

Here is my composer.json (I’ve removed the company name and changed to myplugin)

{
    "name": "me/myplugin",
    "description": "myplugin plugin for CakePHP",
    "type": "cakephp-plugin",
    "license": "MIT",
    "require": {
        "twilio/sdk": "^6.10.0"
    },
    "require-dev": {
    },
    "autoload": {
        "psr-4": {
            "myplugin\\": "src/"
        }
    },
    "autoload-dev": {
        "psr-4": {
        }
    }
}

Here is the folder structure and autoload.php inside the vendor folder

There is another autoload inside vendor/twilio/src/autoload.php, this is the one Twilio say to use if you don’t use composer, but then I have to somehow import this into my class but the class I want to extend is inside the require statement so it fails (and is messy, I would prefer the composer method)

You installed the twilio/sdk inside your plugin folder.
You have to install it on the application folder (the root app folder, outside of plugins folder)

I don’t have permission to the root application because it’s a third party application which I am extending, if I alter the main application with every apt update the changes will get undone.

In CakePHP 2 I was able to load vendors inside a plugin, I’m thinking there must be a way even if it’s not standard.

You might be able to do it with some manual edits to the autoload psr-4 section of your plugin’s composer.json. That’s not a Cake-specific thing, so there should be other relevant resources out there to help with it.

1 Like

Well composer only recognises your composer.json (and therefore your dependencies) if your plugin is loaded in the root package.json (so the one in the main app folder)

You can check Composer: Using your own local package | by Italo Baeza Cabrera | Medium how you can load a local plugin (here cakephp-plugin) with a valid composer.json into the root composer.json without needing to host it via packagist.org or any other remote repository.

But it still requires you to have access - or tell someone - to adjust the root composer.json because it needs to require your plugins composer.json. Without that no autoloading will work.

And I would hardly discourage you to fiddle around with manually autoloading something with your own spl_autoload_register() function.

I actually just tried to refactor all my plugin namespaces to be autoloaded via composer only (via requiring the local package which should load the namespace from the composer.json inside the plugin)

But it seems that at least phpunit has problems with that because its missing some namespaces. (Main app works for some reason :man_shrugging:)

So I keep defining the namespaces for all my local plugins like it is described here
https://book.cakephp.org/4/en/plugins.html#manually-autoloading-plugin-classes