Solved thread

This post is marked as solved. If you think the information contained on this thread must be part of the official documentation, please contribute submitting a pull request to its repository.

Multiple module router

Hello guys,

I have a muti-module website made with phalcon (backend and frontend modules).

The question is:

  • It is possible in the bootstrap file to set only router default module and in the ModuleDefinitionInterface to set defaultController and defaultAction and other routing rules?


37.7k

hey

This mean set deafult router in a module such as frontend, when go to website ?



1.6k

Yes. In the bootstrap module i have this one:

private function initRouter()
    {
        $this->_di->set('router', function()
        {
            $router = new Router();

            $router->removeExtraSlashes(true);

            $router->setDefaultModule($this->_module);

            return $router;

        }, false);
    }

And in the module.php of FrontEnd Module i have this one:

$di->set('router', function()
        {
            $router = new PhRouter();

            $router->setDefaultController('dashboard');
            $router->setDefaultAction('home');

            return $router;
        });

But it doesn't work. I got the error:

Frontend\Controllers\IndexController handler class cannot be loaded



48.2k
edited Feb '15

Create a services.php and services_web.php. Then also create two different bootstraps bootstrap_web.php and bootstrap_cli.php for your CLI and Web stuff. I'm assuming that this is what you mean by "backend" and not a web admin interface module? You don't have to duplicate services as I've found that the CLI doesn't need anything beyond what the Web needs and that the Web needs more services so load both of them for Web modules. Additionally you have room to grow by setting services in your CLI module that are very particular to that. Its like that you will eventually want more than one web related module so don't put too many services into a particular web related module.

If this is not what you meant then I'm thinking that you might not going about your setup in the right way. Its difficult to know what you are doing exactly.



48.2k
edited Feb '15

bootstrap module

Hmm. I've only ever seen non-namespaced bootstrap code. Are you creating class for your bootstrapping? Also if so then why?

What you are doing might be better but if you are still learning then perhaps you should follow the typical conventions first.



37.7k

Hi

Try this in bootstrap file

    $router = new Phalcon\Mvc\Router();

$router->setDefaultModule("frontend");
$router->setDefaultNamespace("Zphalcon\Frontend\Controllers");
$router->setDefaultController('dashboard');
$router->removeExtraSlashes(true);


1.6k
edited Feb '15

public index.php

<?php

error_reporting(0);

use Phalcon\Loader,
    Phalcon\Mvc\Router,
    Phalcon\Mvc\Application,
    Phalcon\DI\FactoryDefault;

define('BASE_PATH', realpath('..'));
define('CORE_PATH', BASE_PATH . '/core');
define('MODS_PATH', CORE_PATH . '/modules');
define('TEMP_PATH', BASE_PATH . '/assets/template');
define('DATA_PATH', BASE_PATH . '/assets/uploads');

class ZB_Bootstrap
{
    private $_di;

    private $_module = 'frontend';

    private $_domain = 'domain.com';

    private $_domain_prefixes = array(
        'acp' => array(
            'module' => array(
                'name'      => 'backend',
                'className' => 'ZB\Backend\Module',
                'path'      => '/backend/Module.php'
            )
            // other modules
        )
    );

    private $_default_module = array(
        'module' => array(
            'name'      => 'frontend',
            'className' => 'ZB\Frontend\Module',
            'path'      => '/frontend/Module.php'
        )
    );

    public function __construct($di)
    {
        $this->_di = $di;
    }

    public function run()
    {
        $initFunctions = array('settings', 'loader', 'router');
        $initModules = array();

        try
        {
            foreach($initFunctions AS $initFunction)
            {
                $initFunction = 'init'.ucfirst($initFunction);

                $this->$initFunction();
            }

            $this->_domain_prefixes['frontend'] = $this->_default_module;

            foreach($this->_domain_prefixes AS $m_name => $m_data)
            {
                $initModules[$m_data['module']['name']] = array(
                    'className' => $m_data['module']['className'],
                    'path'      => MODS_PATH . $m_data['module']['path']
                );
            }

            $application = new Application($this->_di);

            $application->registerModules($initModules);

            echo $application->handle()->getContent();
        }
        catch(\Exception $e)
        {
            echo $e->getFile().' - '.$e->getLine().'<br>'.$e->getMessage();
        }
    }

    private function initSettings()
    {
        $http_host = array(
            'length' => strlen($_SERVER['HTTP_HOST']),
            'name'   => $_SERVER['HTTP_HOST']
        );

        if(substr($http_host['name'], 0, $http_host['length'] - 1) != $this->_domain)
        {
            $url_parts = explode('.', $http_host['name']);

            $parts_num = count($url_parts);

            unset($url_parts[$parts_num - 1]);
            unset($url_parts[$parts_num - 2]);

            $url_prefix = implode('.', $url_parts);

            if(in_array($url_prefix, array_keys($this->_domain_prefixes)))
            {
                $this->_module = $this->_domain_prefixes[$url_prefix]['module']['name'];
            }
            else
            {
                $this->_module = $this->_default_module['module']['name'];

                $this->_di->set('company_slug', $url_prefix);
            }
        }
    }

    private function initLoader()
    {
        $loader = new Loader();

        $loader->registerNamespaces(array('ZB\Libraries' => CORE_PATH . '/libraries/'));

        $loader->register();
    }

    private function initRouter()
    {
        $this->_di->set('router', function()
        {
            $router = new Router();

            $router->removeExtraSlashes(true);

            $router->setDefaultModule($this->_module);

            return $router;

        }, false);
    }
}

$zb = new ZB_Bootstrap(new FactoryDefault());
$zb->run();

And i want in each module.php to define other route rules if this is possible...



1.5k
Accepted
answer
edited Feb '15

meh


<?php
use Phalcon\Mvc\Application;
error_reporting(E_ALL);
(new \Phalcon\Debug())->listen();

define('APPLICATION_PATH', dirname(dirname(__FILE__)) . '/apps');
    /**
     * Include services
     */
    require __DIR__ . '/../config/loader.php';
    require __DIR__ . '/../config/services.php';
    require __DIR__ . '/../config/assets.php';

    /**
     * Handle the request
     */
    $application = new Application($di);

    /**
     * Include modules
     */
    require __DIR__ . '/../config/modules.php';

    require __DIR__ .'/../config/routes.php';

    echo $application->handle()->getContent();
<?php
$router = $di->get("router");
foreach ($application->getModules() as $key => $module) {
    $namespace = sprintf("Learnflux\%s\Controllers", ucfirst($key));
    $router->add('/'.$key.'/:params', array(
            'namespace' => $namespace,
            'module' => $key,
            'controller' => 'index',
            'action' => 'index',
            'params' => 1
    ))->setName($key);
    $router->add('/'.$key.'/:controller/:params', array(
            'namespace' => $namespace,
            'module' => $key,
            'controller' => 1,
            'action' => 'index',
            'params' => 2
    ));
    $router->add('/'.$key.'/:controller/:action/:params', array(
            'namespace' => $namespace,
            'module' => $key,
            'controller' => 1,
            'action' => 2,
            'params' => 3
    ));
}

$modroutes = glob(APPLICATION_PATH."/*/config/routes.php");
foreach($modroutes as $route)
{
    include_once $route;
}
$di['router'] = function () {

    $router = new Router();
    $router->setDefaultModule('frontend');
    $router->removeExtraSlashes(true);
    return $router;
};
$di->set('dispatcher', function() use ($di) {
    $dispatcher = new Phalcon\Mvc\Dispatcher();
    $dispatcher->setDefaultNamespace('MyApp\Frontend\Controllers');
    return $dispatcher;
},true);

you are welcome.