Welcome Guest, Not a member yet? Register   Sign In
Codeigniter 4 dynamic routing to controller
#1

(This post was last modified: 12-12-2022, 07:29 AM by kaligula.)

Hi, guys. I'm trying to move (from CI3) my CMS system, that have modular structure. I wanna to leave modular structure on CI4, because this allows me to simply drag and drop module folders to make it work, without having to write it down in the system files, how can I do this with Codeigniter 4?

So, the main task is to make the system as independent as possible so that plug-ins (modules) can be dragged into the admin system and they start working. 
The file structure is as follows:
/app
/system
/modules/
/modules/admin/core/controllers/ <--- main system controllers folder
/modules/admin/users/controllers/ <--- controllers for management users
/modules/admin/blog/controllers/ <--- controllers for management blog posts/cats
/modules/blog/controllers/ <-- public/website controllers for blog
/public
/writable

The main problem at Routes. I wanna to write only one (main) system namespace and load from it all routes (/modules/admin/config/Routes.php). But codeigniter 4 doesn't allow to user this patterns (dynamic controllers): 

Code:
<?php
namespace Admin\Config;

// Create a new instance of our RouteCollection class.
$routes = \Config\Services::routes();


$routes->group('Admin', static function ($routes) {

    $routes->get('', '\Admin\Core\Controllers\Auth::index');
    $routes->get('login', '\Admin\Core\Controllers\Auth::login');

    $routes->group('module', static function ($routes) {
        $routes->get('(:segment)', '\Admin\$1\Controllers\$1::index');
    });
});

My Codeigniter 3 Routes was have next lines of code for dynamic routes:

Code:
$route['admin/module/(:any)/(:any)/(:any)/(:any)/(:any)/(:any)']  = '$1/admin/$2/$3/$4/$5/$6';
$route['admin/module/(:any)/(:any)/(:any)/(:any)/(:any)']          = '$1/admin/$2/$3/$4/$5';
$route['admin/module/(:any)/(:any)/(:any)/(:any)']                = '$1/admin/$2/$3/$4';
$route['admin/module/(:any)/(:any)/(:any)']                        = '$1/admin/$2/$3';
$route['admin/module/(:any)/(:any)']                              = '$1/admin/$2';
$route['admin/module/(:any)']                                      = '$1/admin';
Reply
#2

Create your own router (or extend the CI4 router).
See https://codeigniter4.github.io/CodeIgnit...re-classes

CI4 does not support dynamic controller.
Ci4's module has its own routing file.
Reply
#3

(12-12-2022, 07:43 PM)kenjis Wrote: Create your own router (or extend the CI4 router).
See https://codeigniter4.github.io/CodeIgnit...re-classes

CI4 does not support dynamic controller.
Ci4's module has its own routing file.

Thanks for response.

So the best way – is to write routes.php for each module?

What u thinking, if at autoload.php (app/config) – i will scan my directory for modules and load them (namespaces) automatically (so each routes.php will load automatically)?
Reply
#4

If you add the module namespace in the app/Config/Autoload.php, the route file in the module will be loaded automatically.

Read https://codeigniter4.github.io/CodeIgnit...dules.html
Reply
#5

(This post was last modified: 12-13-2022, 04:02 AM by kaligula.)

(12-13-2022, 02:02 AM)kenjis Wrote: If you add the module namespace in the app/Config/Autoload.php, the route file in the module will be loaded automatically.

Read https://codeigniter4.github.io/CodeIgnit...dules.html

Yeah, i know. I speaking about like that: 

PHP Code:
    $modules array_map('basename'glob(getcwd() . '/modules/Admin/*' GLOB_ONLYDIR));
    foreach($modules as $module)
    {
        $psr4['Admin\\'.$module] = ROOTPATH 'modules/Admin/'.$module;
    

Can I implement something like that to Autoloader.php? I need to do this, because if admin submodule folder exist in my Admin module folder – i need this module, but i don't wanna on each project connect each module and write this config to Autoloader.php by my own.


UPD. I think i found a solution, but is it a good idea to do this like that?

Add this to app/Config/Autoloader.php at bottom of a file:

PHP Code:
public function __construct()
    {
        
parent::__construct();


        
$modules array_map('basename'glob(getcwd() . '/modules/Admin/*' GLOB_ONLYDIR));
        foreach(
$modules as $module)
        {
            
$this->psr4['Admin\\'.$module] = ROOTPATH 'modules/Admin/'.$module;
        } 
    } 
Reply
#6

It is not too bad. It works.

But on every request it scans the folder and updates the `$psr4`.
So I think it is better to write a command to update the Config file `$psr4`
if you don't want to update manually.
Reply
#7

(12-13-2022, 07:26 PM)kenjis Wrote: It is not too bad. It works.

But on every request it scans the folder and updates the `$psr4`.
So I think it is better to write a command to update the Config file `$psr4`
if you don't want to update manually.

Thanks for response, this thread was very helpful!
Reply




Theme © iAndrew 2016 - Forum software by © MyBB