We have moved our forum to GitHub Discussions. For questions about Phalcon v3/v4/v5 you can visit here and for Phalcon v6 here.

To configure a router annotation with multiple modules?

How do you configure a router annotation with multiple modules? I tried everything that is way it always gives an error that does not recognize the controller class or controllerbase



43.9k

Hi,

from doc

If you’re using modules in your application, it is better use the addModuleResource() method:


<?php

use Phalcon\Mvc\Router\Annotations as RouterAnnotations;

$di["router"] = function () {
    // Use the annotations router
    $router = new RouterAnnotations(false);

    // Read the annotations from Backend\Controllers\ProductsController if the URI starts with /api/products
    $router->addModuleResource("backend", "Products", "/api/products");

    return $router;
};

It does not work, it says the class does not exist



43.9k

Maybe it's a stupid question: but did you already register all your modules and namespaces ?

If yes, if think I could not help you further without some relevant php code.

edited Mar '17

$loader->registerNamespaces (
    array (
        'Models' => $config->application->modelsDir,
        'Web' => $config->application->libraryDir
    )
)->register ();

$di = new FactoryDefault();
$di->setShared (
    'router',
    function () {
        $router = new RouterAnnotations( false );
        $router->addModuleResource('questionary', 'Web/Questionary/index');
});

$application = new Application();

$application->registerModules(array(
    'frontend' => array(
        'className' => 'Web\Frontend\Module',
        'path' => __DIR__ . '/../apps/modules/frontend/Module.php'
    ),
    'home' => array(
        'className' => 'Web\Home\Module',
        'path' => __DIR__ . '/../apps/modules/home/Module.php'
    ),
    'questionary' => array(
        'className' => 'Web\Questionary\Module',
        'path' => __DIR__ . '/../apps/modules/questionary/Module.php'
    )
));

$di->setShared (
    'router',
    function () {
        $router = new RouterAnnotations( false );
        $router->addModuleResource('questionary', 'Web/Questionary/Categoria');
        /*       $router->setDefaults (
                   array (
                       'namespace' => 'Web\Frontend\Controllers',
                       'module'    => 'frontend',
                   )
               );

               $router->notFound (
                   array (
                       'controller' => 'error',
                       'action'     => 'notfound'
                   )
               );
       */
        return $router;
    }
);

$application->setDI($di);
echo $application->handle()->getContent();
...

Module.php


...
    public function registerAutoloaders ( DiInterface $di = null )
    {

        $loader = new Loader();

        $loader->registerNamespaces (
            array (
                'Web\Questionario\Controllers' => __DIR__ . '/controllers/',
                'Web\Questionario\Models'      => __DIR__ . '/models/',
                'Web\Questionario\Forms'       => __DIR__ . '/forms/',
            )
        );

        $loader->register ();
    }

Result:

Class Web/Questionary/CategoriaController does not exist

0 [internal function]: ReflectionClass->__construct('Web/Questionary...')

1 [internal function]: Phalcon\Annotations\Reader->parse('Web/Questionary...')

2 [internal function]: Phalcon\Annotations\Adapter->get('Web/Questionary...')

3 [internal function]: Phalcon\Mvc\Router\Annotations->handle('')

4 /var/www/web/public/index.php(48): Phalcon\Mvc\Application->handle()

5 {main}



43.9k

Mybe it is because you load modules after router ....

In module it does not work, configure it in a normal way (without module) and maps a global namespace and it worked, so I saw phalcon is not prepared for router annotation with multiple modules, it needs a kludge to work ...



2.8k
Accepted
answer

it work withou module...


    /**
     * Read auto-loader
     */
    $loader = new \Phalcon\Loader();

    $loader->registerNamespaces (
        array (
            'Models'                      => $config->application->modelsDir ,
            'Web'                         => $config->application->libraryDir ,
            'Web\Questionary\Controllers' => $config->application->modulesDir . 'questionary/controllers/'
        )
    )->register ();

    $di = new FactoryDefault();

    $di->setShared (
        'router' ,
        function ()
        {
            $router = new RouterAnnotations( false );
            $router->addResource ( 'Web\Questionary\Controllers\Categoria', '/questionary/categoria' );

            return $router;
        } );

    $application = new Application($di);


43.9k

ok, but if doc says that you can handle a multi modules app with annotation router, it should work !!

As I said, did you try, in code you've given, to register your modules before the router (btw, you've registred the router twice in the DI)

It worked, from what I saw in the forum you should do exactly that, declare the global namespace for the controllers and then declare again on each module, the problem is precisely the redundancy that is mandatory and confusing.

edited Mar '17

It worked


/**
     * Read auto-loader
     */
    $loader = new \Phalcon\Loader();

    /**
    * namespace global
    */
    $loader->registerNamespaces (
        array (
            'Models'                      => $config->application->modelsDir ,
            'Web'                         => $config->application->libraryDir ,
            'Web\Questionary\Controllers' => $config->application->modulesDir . 'questionary/controllers/'
        )
    )->register ();

    $di = new FactoryDefault();

    $di->setShared (
        'router' ,
        function ()
        {
            $router = new RouterAnnotations( false );
            $router->addResource ( 'Web\Questionary\Controllers\Categoria', '/questionary/categoria' );

            return $router;
        } );

    $application = new Application($di);

    /**
    * register modules
    */
    $application->registerModules(array(
    'Questionary' => array(
        'className' => 'Web\Questionary\Module',
        'path' => $config->application->modulesDir . 'questionary/Module.php'
    )
));