CakePHP 4.0 Unable to use custom component in custom plugin

I’m not sure if I’m doing this correctly. I want to load a component from a plugin in the AppController (or any controller). I believe the correct plugin syntax is simply $this->loadComponent('Foo.Foo') for a Foo plugin with a FooComponent.

Here is my plugin directory structure:

├── Foo
│ ├── README.md
│ ├── composer.json
│ ├── phpunit.xml.dist
│ ├── src
│ │ ├── Controller
│ │ │ ├── AppController.php
│ │ │ └── Component
│ │ │ └── FooComponent.php
│ │ └── Plugin.php
│ ├── tests
│ │ ├── TestCase
│ │ │ └── Controller
│ │ │ └── Component
│ │ │ └── FooComponentTest.php
│ │ └── bootstrap.php
│ └── webroot

When attempting to call an endpoint with a controller that inherits from AppController, I receive the following serialized error:

{
“message”: “Component class FooComponent could not be found.”,
“url”: “/controller-that-uses-app-controller”,
“code”: 500,
“file”: “path/to/project/vendor/cakephp/cakephp/src/Controller/ComponentRegistry.php”,
“line”: 111
}

FooComponent:

namespace Foo\Controller\Component;

use Cake\Controller\Component;
use Cake\Controller\ComponentRegistry;

/**

  • Foo component
    /
    class FooComponent extends Component
    {
    /
    *
    • Default configuration.
    • @var array
      */
      protected $_defaultConfig = [];
      }

Foo plugin composer.json psr-4 directive:

"autoload": {
    "psr-4": {
        "Foo\\": "src/"
    }
}

First party Authorization and Authentication components/plugins work fine.

Im guessing it’s a problem with autoloading/namespaces/directory structure. For now, I’ve removed the plugins and just moved everything back into the main application. After refactoring namespaces, everything is working again for now.

Did you do a composer dumpautoload after changing the composer.json?

Thanks for the reply. I didn’t. I’ll refactor the feature into a plugin and try again when done.

That seems to have fixed it. I thought psr4 was automatic?

Composer requires running an appropriate command that trigger it to update its autoload file which establishes known namespace to filepath relationships. After that referencing (sub)items within known namespace-filepath-relationships works automatically.

Performance being a huge reason for that behavior (it would kill performance reevaluating everything on each request).

1 Like