Welcome Guest, Not a member yet? Register   Sign In
Migrations autoload namespaces
#1

Hello,

I just opened a thread within the support section but perhaps it is more a feature request. ( I'll  Big Grin )

I have plugins that are stored within the app\Plugins folder, each within its own folder (app\Plugins\[plugin_name]). Plugins can contain any CI4 entity: controllers, models, migrations etc and have the same structure of CI4 root. Models and controllers are loaded without problems with composer. Migrations work if the plugin's namespace is included within the $psr4 array ('Plugins\[plugin_name]\App').

Due to plugins are included/removed "dynamically" I need a way to auto load the namespaces of each plugin just adding the "root namespace" ( 'Plugins\' ) as I do within composer.json.

I figure out a way to do it but I had to editing the CI4's core (vendor folder).

What I did is editing the Autoloader::addNamespace() to check if the last char of the prefix is an '*', if so instead of add the prefix call the addSubNamespaces function

PHP Code:
private function addSubNamespaces($prefix)
{
    
$new_prefix rtrim($prefix'*');
    
$plugins array_slice(scandir(APPPATH $new_prefix), 2);
    foreach(
$plugins as $plugin){
        
$sub_folders array_slice(scandir(APPPATH $new_prefix '/' $plugin), 2);
        foreach(
$sub_folders as $sub_folder){
            
$this->prefixes[$new_prefix $plugin '\\' ucfirst($sub_folder)][] = rtrim(APPPATH $new_prefix '/' $plugin '/' $sub_folder'/') . '/';    
        }
    }                


And the for the MigrateRollback::run()  replace line 131 with:

PHP Code:
$namespaces Services::autoloader()->getNamespace(); 

This solution works for my environment and plugin structure but is not. Do you think it would be possible to introduce a feature similar to this that allows to include all the found psr4 "sub namespace" starting from the "namespace's root"

Thank you in advance.
Reply
#2

Not looking for sub-namespaces is intentional, and a performance feature. We don't look for anything more than we need to.

Since your case is a special case, and you've already figured out how to handle it, a better solution is to extend the core Autoloader class. You only need to include any modified methods that you need to override in it.

However, since Autoloader is one of only a couple of classes loaded directly by the bootstrap file, you'll have to include your file first in public/index.php so it can be found later.

Then, copy the autoloader method from system/Config/Services.php and place it into app/Config/Services.php. Then edit that method to load your class instead of the one in system. Now, whenever the system loads the autoloader it should load yours instead.

Seeing this does make me realize we could use a better solution for getting custom files into play first, though this problem only affects 3 files, I believe. Something I'll need to think on.
Reply
#3

Thank you so much for the answer! I'll do it that way.
Reply




Theme © iAndrew 2016 - Forum software by © MyBB