Skip to content
This repository has been archived by the owner on Jan 6, 2023. It is now read-only.

Cannot resolve custom extension class #669

Closed
honzabilek4 opened this issue Dec 21, 2018 · 17 comments
Closed

Cannot resolve custom extension class #669

honzabilek4 opened this issue Dec 21, 2018 · 17 comments
Labels
documentation Needs documentation enhancement New feature or request

Comments

@honzabilek4
Copy link

honzabilek4 commented Dec 21, 2018

Hi,
I'm creating an extension class which will be called from Directus hook. Some code logic is omitted for simplicity.
public/extensions/custom/hooks/presentations/AfterCreatePresentation.php

<?php

namespace Directus\Custom\Hooks\Presentations;

use Directus\Application\Application;
use Directus\Mail\Message;
use function Directus\send_mail_with_layout;
use Directus\Services\UsersService;

class AfterCreatePresentation
{
    protected $container = null;

    public function __invoke($data = null)
    {
        $this->container = Application::getInstance()->getContainer();
        $userService = new UsersService($this->container);
        $users = $userService->findAll();

        foreach ($users['data'] as $user) {
            if ($user['email_notifications'] == true){
                send_mail_with_layout(
                  ...
                );
            }
        }
    }
}

And the hook is registered in config/api.php as:

...
    'hooks' => [
        'actions' => [
            'item.create.presentations' => new \Directus\Custom\Hooks\Presentations\AfterCreatePresentation()
        ],
        'filters' => [],
    ],
...

However the following error is being thrown:

2018/12/20 14:32:07 [error] 10498#10498: *123657 FastCGI sent in stderr: "PHP message: PHP Fatal error:  Uncaught Error: Class 'Directus\Custom\Hooks\Presentations\AfterCreatePresentation' not found in /var/www/api.elisiondesign.cz/config/api.php:114
Stack trace:
#0 /var/www/api.elisiondesign.cz/src/web.php(43): require()
#1 /var/www/api.elisiondesign.cz/public/index.php(3): require('/var/www/api.el...')
#2 {main}
  thrown in /var/www/api.elisiondesign.cz/config/api.php on line 114" while reading response header from upstream, client: 89.102.32.192, server: api.elisiondesign.cz, request: "GET /server/ping HTTP/1.1", upstream: "fastcgi://unix:/run/php/php7.0-fpm.sock:", host: "api.elisiondesign.cz", referrer: "https://app.elisiondesign.cz/"

It works perfectly on my system MacOS, but when deployed to production (Ubuntu) it throws the error. I was tying to figure out some differences between the system and the most important is that Ubuntu is case-sensitive system, while MacOs is not. This would explain the not found problem. So I've tried to put the file in the folders named with uppercase /Custom/Hooks/Presentations to help the autoloader find the class in the namespace, but with no effect.

NOTE: The example hook for 'products' throws the same error when enabled.

  • OS: [Ubuntu 16.04]
  • Web Server: [nginx/1.14.1 ]
  • PHP Version: [ 7.0.32]
  • Database: [ MySQL 5.7.24]
  • API [2.0.12]
@honzabilek4 honzabilek4 changed the title Cannot resolve extension hook class Cannot resolve custom extension class Dec 21, 2018
@honzabilek4 honzabilek4 added the bug Something isn't working label Dec 21, 2018
@wellingguzman
Copy link
Contributor

I don't want to give any conclusion but I am start to believe it's because of the case sensitive nature of ubuntu.

I will try this on a ubuntu machine and see if I can reproduce this.

@wellingguzman wellingguzman added this to Needs triage in Bug Triage Dec 25, 2018
@benhaynes
Copy link
Sponsor Member

Any update on this @wellingguzman?

@benhaynes benhaynes added this to To do in v2.0.14 via automation Dec 26, 2018
@wellingguzman
Copy link
Contributor

No update. I haven't worked on this yet.

@honzabilek4
Copy link
Author

Hi, got any update on this? :)
I would like to get this resolved, cause sadly it's blocking us in any further development 😞 Tell me if you need any help or reach me on slack.
Thanks!

@honzabilek4
Copy link
Author

honzabilek4 commented Jan 4, 2019

Hey @wellingguzman,
I did a bit of investigation and the problem appears to be in the build branch only. On the Ubuntu server, I've checked out from the build branch to master, did composer install and in /extenstions foldernpm run build and the hooks classes are working perfectly.
Checking back to build again breaks the api though.

@rijkvanzanten
Copy link
Member

@honzabilek4 Could it be that the autoload.php file doesn't read your newly created file? The autoload file is generated using authoritative class maps which doesn't read the actual file system but instead relies on a pre-made map of all the files that (should) be there. If you added a new file after that and try to load it in using Composer's autoload, it might fail.

Could you try installing the dependencies using composer install -a in your test and see if it still works?

@honzabilek4
Copy link
Author

Well, yeah I've figured it out in the process 😆. This fixes the problem. I understand that this option might make the entire application faster, but it's not very convenient for deploying extensions.
Maybe we should mention it in the docs?

@rijkvanzanten
Copy link
Member

rijkvanzanten commented Jan 4, 2019

Gotcha! If it messes up deploying extensions, it's not a suitable way of building the API. I wish Composer has a way to have the best of both worlds?

@wellingguzman wellingguzman added enhancement New feature or request documentation Needs documentation and removed bug Something isn't working labels Jan 4, 2019
@wellingguzman
Copy link
Contributor

I believe the composer dump-autoload should works in this case to, to update the whole autoloader.

Bug Triage automation moved this from Needs triage to Closed Jan 4, 2019
v2.0.14 automation moved this from To do to Done Jan 4, 2019
@rijkvanzanten
Copy link
Member

@honzabilek4 @wellingguzman Should I create the bundle without the -a optimization flag to prevent this from happening?

@wellingguzman
Copy link
Contributor

I closed this ticket with some notes about reinstalling the composer.json file.

I am going to add a note on update it when there's a composer.json

@wellingguzman
Copy link
Contributor

@rijkvanzanten I don't know what actually install -a does, but to me it seems running composer dump-autoload should do it, as the problem here seems to be an incompatible autoloader. So I believe it depends always on where it was built and where is going to be used, if those are incompatible the result will be the same.

@rijkvanzanten
Copy link
Member

@wellingguzman Normally, composer will read the file system and read the files based on that. The -a flag will create a file listing all other files, so it doesn't have to read the file system on runtime. This will speed up the API pretty drastically, but also means that it doesn't "see" new files added

@honzabilek4
Copy link
Author

Since the composer.json file is missing in the build branch, it's not possible to run the mentioned commands in this branch. You have to create the file manually, which adds more overhead to the initial configuration.
I'm imagining being a newcomer trying to develop a new extension class, it might be pretty confusing to do so:

  1. I'll create a new extension and upload it to custom extensions folder
  2. Class is not found and the whole API breaks, so I spend some amount of time trying to find out why it works only on localhost.
  3. I discover this issue in Github (or some note in docs), so I'll try to run the composer commands, but composer.json not found.
  4. Have to manually copy the file and run composer install.
  5. Finally the API is back again.

That's seems to be a pretty tedious process. I'm also not sure how to avoid this down time without redeploying the entire api instance.

@rijkvanzanten rijkvanzanten reopened this Jan 12, 2019
@honzabilek4
Copy link
Author

I think it’s important to make the extension development workflow more streamlined, so it’s easy to understand for other developers. Some additional info in the docs might help as well.

@benhaynes
Copy link
Sponsor Member

We agree. @rijkvanzanten is starting in on the 7.1 refactor in a few days, so it'd be great to get as much input as possible into how the community thinks we should streamline the extensions, Docs, code structure — and therefore the development process.

@wellingguzman
Copy link
Contributor

I will close this in favor of directus/directus#2273. As soon as that one is closed the issue will be also resolved. Any new related inconvenience should be discussed there to keep the discussion in one place.

samvasko pushed a commit to samvasko/api that referenced this issue Nov 25, 2019
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
documentation Needs documentation enhancement New feature or request
Projects
Bug Triage
  
Closed
v2.0.14
  
Done
Development

No branches or pull requests

4 participants