This forum has moved to a new location and is in read-only mode. Please visit talk.octobercms.com to access the new location.

vdomah
vdomah

Hello!

How to make available classes in plugin's classes dir from subdirectory? E.g. /plugins/myself/myplug/classes/Feature/FeatureItem.php

Tried to solved this via composer adding psr-4 autoloading but didn't help.

Last updated

Crazymodder
Crazymodder

Did you using correct namespace?

vdomah
vdomah

Yes, like use Myself/Myplug/Classes/Feature. Do you got this working with such approach?

philipptempel
philipptempel

Your slashes are incorrect. They have to be backward i.e, \ slashes, not forward slashes i.e., / Then it should work.

However, note, if you use Myself\Myplug\Classes\Feature you will still need to call Feature\FeatureItem as the whole namespace is used/imported, not just one class.

Last updated

Crazymodder
Crazymodder

@vdomah,

You have to do it the way philipptempel described it than it should work;)

vdomah
vdomah

Your slashes are incorrect. They have to be backward i.e, \ slashes, not forward slashes i.e., / Then it should work.

I used "\" in code - just made mistake here in rush.

@Crazymodder, @philipptempel Did you try your approach in real code?

I try to call this

dd(class_exists('\Myself\\Myplug\\Classes\\Feature\\FeatureItem'));
// gives false

and this

dd(class_exists('\Myself\\Myplug\\Classes\\FeatureItem'));
// gives true

FeatureItem class is same in both directories. First got namespace Myself\Myplug\Classes\Feature and second Myself\Myplug\Classes.

Last updated

philipptempel
philipptempel

I currently don't have a dev environment around, but am pretty sure that it is correct like that. The only thing I can think of right now: do you have the file located at plugins/myself/myplug/classes/Feature/FeatureItem.php? Or do you maybe have it one level higher i.e., at plugins/myself/myplug/classes/FeatureItem.php?

Also, you don't need the leading \ in strings. Strings with namespaces and class names are always relative to \ i.e., root.

vdomah
vdomah

Answer is in my previous post:

FeatureItem class is same in both directories. First got namespace Myself\Myplug\Classes\Feature and second Myself\Myplug\Classes.

Also reading previous post will make obviuos that leading slash doesn't matter as you can see that one of class_exists calls returns true.

To clarify my question. It's not about PHP-general explanation - the purpose is to discover October specific behavior in this case. I will be glad to see if someone did it in real work.

philipptempel
philipptempel

So you have two files at paths plugins/myself/myplug/classes/FeatureItem.php and plugins/myself/myplug/classes/Feature/FeatureItem.php Am I understanding that correctly? That's a weird setup but shouldn't matter to the question (unless you use both classes in the same file?!)

If you look at the source code of RainLab/Blog/Plugin.php in the repo you will see that it is using RainLab\Blog\Classes\TagProcessor. Thus it must work the way you want it to work (no matter the subdirectories). The only question that remains: do you capitalize the path properly?

vdomah
vdomah

@philipptempel man, no theory please. I appreciate your effort but if you didn't try classes/subdir structure don't flood the topic.

Last updated

alxy
alxy

The sub classes / namespaces are case SENSITIVE!

So it is perfectly ok to have a folder classes, whereas the namespace is Classes. However, any nested directory needs to match the case of the namespace directly. So make sure you directory is named Feature and not feature. Also check for spelling mistakes - no kidding. This is a simple failure, yet very hard to debug.

philipptempel
philipptempel

After a while of debugging to calm the nerves around here, I did seem to also be experiencing the same phenomenon as @vdomah. I even did what @alxy recommended - multiples time even. To no avail. Directories (or namespaces for that matter) inside plugins/acme/awesome-plugin/classes are not supported. Checked other plugins and the core, none of them actually has subdirectories. I tried going through the code as any good developer would do but didn't couldn't nail down where the directory is being added to any autoloader's directory (PluginManager has folder base_path() / plugins inside its searchable directories storage, but that's all info I could find).

vdomah
vdomah

@philipptempel, thanks. now at least we are sure that problem realy exists

alxy
alxy

I think I have done that before, but I will also try it again next week and check if I get the same issue...

denis.rendler
denis.rendler

If it is not too late, here is my two cents. I had the same issue of namespace/folder under classes. @alxy mentioned that under the classes/folder the case for the folder names needs to match exactly the namespace names because they are case sensitive. This is half true. The generated file name is case sensitive.

If we look into October\Rain\Support\ClassLoader at line 33 there is a call to static::normalizeClass($class). This method, found at line 50, will take the full namespace and lowercase it with the only exception being the class name. For example, a namespace like KoderHut\Plugin\Classes\Subfolder\MyClass will result in the following file path name: koderhut/plugin/classes/subfolder/MyClass.php

Hope it helps for future reference.

Tschallacka
Tschallacka

Uhm, just my 2 cents...

Make a composer.json

{
    "require": {
        "php": ">=5.4"
    },
    "autoload": {
        "psr-4": {
            "Applications\\": "vendor/applications"
        }
    }
}

and place this in your folder:

plugins/Authorname/Pluginname/vendor/composer.json

(assuming this example) Then make a folder named applications in your vendor directory.

Then, put the files in it you want autoloaded:

Imgur

And make sure the namespaces start with the name space you defined in PSR-4 autoload

<?php namespace Applications\Widgets;

use Applications\ApplicationBase;
use Exception;
use Illuminate\Contracts\Filesystem\FileNotFoundException;

abstract class WidgetBase {

This part in composer.json

 "psr-4": {
            "Applications\\": "vendor/applications"
        }

Tells composer to seek for which files, which namespaces in which directory.

If you wish to optimise things even further, you go to the directory with your shell and type:

> composer dump-autoload -o

So the classes will be loaded as smoothly as possible + it allows opcache to optimise the loading process.

denis.rendler
denis.rendler

PS: also, @Tschallacka version was added since Feb 22nd, 2016.

Last updated

vdomah
vdomah

Hi guys, thanks for contributing to this topic. The problem in my case was just wrong namespace syntax in composer.json

andre26885
andre26885

To me, the solution was to use lowercase folder names, as pointed by @denis.rendler.

1-19 of 19

You cannot edit posts or make replies: the forum has moved to talk.octobercms.com.