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

Copy module and get error

I have created multi module project with Devtools. I have modules: frontend, cli I copied Frontend module and rename to Backend and edited all namespace, module.php, services.php and loader.php, however I got this error:

Projectname\Controllerss\Backend\Controllers\IndexController handler class cannot be loaded

0 [internal function]: Phalcon\Mvc\Dispatcher->_throwDispatchException('Projectname\Controller...', 2)

1 [internal function]: Phalcon\Dispatcher->_dispatch()

2 [internal function]: Phalcon\Dispatcher->dispatch()

3 C:\xampp\htdocs\idoc\app\bootstrap_web.php(57): Phalcon\Mvc\Application->handle()

4 C:\xampp\htdocs\idoc\public\index.php(2): require('C:\xampp\htdocs...')

5 {main}

====== I dont know why is that, especially it's said that " Projectname\Controllerss" with double "s" after controllers, but I sure that I haven't type anything wrong. Please help .

Show us your dispatcher service definition. Did you edited modules.php and added new module ?



6.6k
edited Oct '16

<?php

use Phalcon\Loader;
use Phalcon\Mvc\Model\Metadata\Memory as MetaDataAdapter;
use Phalcon\Mvc\View\Engine\Volt as VoltEngine;
use Idoc\Mail\Mail;
use Idoc\Acl\Acl;
use Idoc\Auth\Auth;

 /**
* Shared configuration service
*/
$di->setShared('config', function () {
 return include APP_PATH . "/config/config.php";
 });

 /**
  * Database connection is created based in the parameters defined in the configuration file
  */
 $di->setShared('db', function () {
     $config = $this->getConfig();

     $class = 'Phalcon\Db\Adapter\Pdo\\' . $config->database->adapter;
     $connection = new $class([
         'host'     => $config->database->host,
         'username' => $config->database->username,
         'password' => $config->database->password,
         'dbname'   => $config->database->dbname,
         'schema'    => $config->database->schema
    ]);

     return $connection;
 });

 /**
  * If the configuration specify the use of metadata adapter use it or use memory otherwise
  */
 $di->setShared('modelsMetadata', function () {
     return new MetaDataAdapter();
 });

 /**
 * Configure the Volt service for rendering .volt templates
  */
 $di->setShared('voltShared', function ($view) {
     $config = $this->getConfig();

    $volt = new VoltEngine($view, $this);
     $volt->setOptions([
         'compiledPath' => $config->application->voltDir,
         'compiledSeparator' => '_'
     ]);
     return $volt;
 });

 /**
  * Mail service uses AmazonSES
  */
 $di->set('mail', function () {
     return new Mail();
 });

 /**
  * Logger service
  */
 $di->set('logger', function ($filename = null, $format = null) {
     $config = $this->getConfig();

     $format   = $format ?: $config->get('logger')->format;
     $filename = trim($filename ?: $config->get('logger')->filename, '\\/');
     $path     = rtrim($config->get('logger')->path, '\\/') . DIRECTORY_SEPARATOR;

    $formatter = new FormatterLine($format, $config->get('logger')->date);
    $logger    = new FileLogger($path . $filename);

     $logger->setFormatter($formatter);
     $logger->setLogLevel($config->get('logger')->logLevel);

     return $logger;
 });

 /**
  * Flash service with custom CSS classes
  */
 $di->set('flash', function () {
     return new Flash([
         'error' => 'alert alert-danger',
         'success' => 'alert alert-success',
         'notice' => 'alert alert-info',
         'warning' => 'alert alert-warning'
     ]);
 });

 /**
  * Access Control List
  */
 $di->set('acl', function () {
     return new Acl();
 });

 /**
  * Custom authentication component
  */
 $di->set('auth', function () {
     return new Auth();
 });

 /**
  * Start the session the first time some component request the session service
  */
 $di->set('session', function () {
     $session = new SessionAdapter();
     $session->start();
     return $session;
 });

 /**
  * Loading routes from the routes.php file
  */
 $di->set('router', function () {
     return require APP_PATH . '/config/routes.php';
});
```php

and here is the modules.php

```php
 <?php
 namespace Idoc\Modules\Backend;
> 
> use Phalcon\DiInterface;
> use Phalcon\Loader;
> use Phalcon\Mvc\View;
> use Phalcon\Mvc\View\Engine\Php as PhpEngine;
> use Phalcon\Mvc\ModuleDefinitionInterface;
> 
> class Module implements ModuleDefinitionInterface
> {
>     /**
>      * Registers an autoloader related to the module
>      *
>      * @param DiInterface $di
>      */
>     public function registerAutoloaders(DiInterface $di = null)
>     {
>         $loader = new Loader();
> 
>         $loader->registerNamespaces([
>             'Idoc\Modules\Backend\Controllers' => __DIR__ . '/controllers/',
>             'Idoc\Modules\Backend\Models' => __DIR__ . '/models/',
>         ]);
> 
>         $loader->register();
>     }
> 
>     /**
>      * Registers services related to the module
>      *
>      * @param DiInterface $di
>      */
>     public function registerServices(DiInterface $di)
>     {
>         /**
>          * Setting up the view component
>          */
>         $di->set('view', function () {
>             $view = new View();
>             $view->setDI($this);
>             $view->setViewsDir(__DIR__ . '/views/');
> 
>             $view->registerEngines([
>                 '.volt'  => 'voltShared',
>                 '.phtml' => PhpEngine::class
>             ]);
> 
>             return $view;
>         });
>     }
> }
```php

>Show us your dispatcher service definition. Did you edited modules.php and added new module ?

I was asking for modules.php not Module.php/module.php. I mean the place where you have stored array of modules like this:

$modules = [
    'admin' => [
        'className' => 'Suzuki\Module\Admin\Module',
        'path' => '../Module/Admin/Module.php',
    ],
    'backend' => [
        'className' => 'Suzuki\Module\Backend\Module',
        'path' => '../Module/Backend/Module.php',
    ],
    'error' => [
        'className' => 'Suzuki\Module\Error\Module',
        'path' => '../Module/Error/Module.php',
    ],
    'event' => [
        'className' => 'Suzuki\Module\Event\Module',
        'path' => '../Module/Event/Module.php',
    ],
    'frontend' => [
        'className' => 'Suzuki\Module\Frontend\Module',
        'path' => '../Module/Frontend/Module.php',
    ],
    'menu' => [
        'className' => 'Suzuki\Module\Menu\Module',
        'path' => '../Module/Menu/Module.php',
    ],
    'news' => [
        'className' => 'Suzuki\Module\News\Module',
        'path' => '../Module/News/Module.php',
    ],
    'page' => [
        'className' => 'Suzuki\Module\Page\Module',
        'path' => '../Module/Page/Module.php',
    ],
    'parent' => [
        'className' => 'Suzuki\Module\Parent\Module',
        'path' => '../Module/Parent/Module.php',
    ],
    'payment' => [
        'className' => 'Suzuki\Module\Payment\Module',
        'path' => '../Module/Payment/Module.php',
    ],
    'report' => [
        'className' => 'Suzuki\Module\Report\Module',
        'path' => '../Module/Report/Module.php',
    ],
    'student' => [
        'className' => 'Suzuki\Module\Student\Module',
        'path' => '../Module/Student/Module.php',
    ],
    'teacher' => [
        'className' => 'Suzuki\Module\Teacher\Module',
        'path' => '../Module/Teacher/Module.php',
    ],
    'gallery' =>[
        'className' => 'Suzuki\Module\Gallery\Module',
        'path' => '../Module/Gallery/Module.php',
    ]
];

$application->registerModules($modules);


6.6k

I think you ask for bootstrap_web.php

<?php

use Phalcon\Di\FactoryDefault; use Phalcon\Mvc\Application;

error_reporting(E_ALL); (new \Phalcon\Debug())->listen();

define('BASE_PATH', dirname(DIR)); define('APP_PATH', BASE_PATH . '/app');

try {

/**
 * The FactoryDefault Dependency Injector automatically registers the services that
 * provide a full stack framework. These default services can be overidden with custom ones.
 */
$di = new FactoryDefault();

/**
 * Include general services
 */
require APP_PATH . '/config/services.php';

/**
 * Include web environment specific services
 */
require APP_PATH . '/config/services_web.php';

/**
 * Get config service for use in inline setup below
 */
$config = $di->getConfig();

/**
 * Include Autoloader
 */
include APP_PATH . '/config/loader.php';

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

/**
 * Register application modules
 */
$application->registerModules([
    'frontend' => ['className' => 'Idoc\Modules\Frontend\Module'],
    'backend' => ['className' => 'Idoc\Modules\Backend\Module'],
]);

/**
 * Include routes
 */
require APP_PATH . '/config/routes.php';

echo $application->handle()->getContent();

} catch (\Exception $e) { echo $e->getMessage() . '<br>'; echo '<pre>' . $e->getTraceAsString() . '</pre>'; }

I was asking for modules.php not Module.php/module.php. I mean the place where you have stored array of modules like this:

$modules = [
   'admin' => [
       'className' => 'Suzuki\Module\Admin\Module',
       'path' => '../Module/Admin/Module.php',
   ],
   'backend' => [
       'className' => 'Suzuki\Module\Backend\Module',
       'path' => '../Module/Backend/Module.php',
   ],
   'error' => [
       'className' => 'Suzuki\Module\Error\Module',
       'path' => '../Module/Error/Module.php',
   ],
   'event' => [
       'className' => 'Suzuki\Module\Event\Module',
       'path' => '../Module/Event/Module.php',
   ],
   'frontend' => [
       'className' => 'Suzuki\Module\Frontend\Module',
       'path' => '../Module/Frontend/Module.php',
   ],
   'menu' => [
       'className' => 'Suzuki\Module\Menu\Module',
       'path' => '../Module/Menu/Module.php',
   ],
   'news' => [
       'className' => 'Suzuki\Module\News\Module',
       'path' => '../Module/News/Module.php',
   ],
   'page' => [
       'className' => 'Suzuki\Module\Page\Module',
       'path' => '../Module/Page/Module.php',
   ],
   'parent' => [
       'className' => 'Suzuki\Module\Parent\Module',
       'path' => '../Module/Parent/Module.php',
   ],
   'payment' => [
       'className' => 'Suzuki\Module\Payment\Module',
       'path' => '../Module/Payment/Module.php',
   ],
   'report' => [
       'className' => 'Suzuki\Module\Report\Module',
       'path' => '../Module/Report/Module.php',
   ],
   'student' => [
       'className' => 'Suzuki\Module\Student\Module',
       'path' => '../Module/Student/Module.php',
   ],
   'teacher' => [
       'className' => 'Suzuki\Module\Teacher\Module',
       'path' => '../Module/Teacher/Module.php',
   ],
   'gallery' =>[
       'className' => 'Suzuki\Module\Gallery\Module',
       'path' => '../Module/Gallery/Module.php',
   ]
];

$application->registerModules($modules);


6.6k

SO simple, can you tell me how to create other module with application generated with Devtool Multi module please

I was asking for modules.php not Module.php/module.php. I mean the place where you have stored array of modules like this:

$modules = [
   'admin' => [
       'className' => 'Suzuki\Module\Admin\Module',
       'path' => '../Module/Admin/Module.php',
   ],
   'backend' => [
       'className' => 'Suzuki\Module\Backend\Module',
       'path' => '../Module/Backend/Module.php',
   ],
   'error' => [
       'className' => 'Suzuki\Module\Error\Module',
       'path' => '../Module/Error/Module.php',
   ],
   'event' => [
       'className' => 'Suzuki\Module\Event\Module',
       'path' => '../Module/Event/Module.php',
   ],
   'frontend' => [
       'className' => 'Suzuki\Module\Frontend\Module',
       'path' => '../Module/Frontend/Module.php',
   ],
   'menu' => [
       'className' => 'Suzuki\Module\Menu\Module',
       'path' => '../Module/Menu/Module.php',
   ],
   'news' => [
       'className' => 'Suzuki\Module\News\Module',
       'path' => '../Module/News/Module.php',
   ],
   'page' => [
       'className' => 'Suzuki\Module\Page\Module',
       'path' => '../Module/Page/Module.php',
   ],
   'parent' => [
       'className' => 'Suzuki\Module\Parent\Module',
       'path' => '../Module/Parent/Module.php',
   ],
   'payment' => [
       'className' => 'Suzuki\Module\Payment\Module',
       'path' => '../Module/Payment/Module.php',
   ],
   'report' => [
       'className' => 'Suzuki\Module\Report\Module',
       'path' => '../Module/Report/Module.php',
   ],
   'student' => [
       'className' => 'Suzuki\Module\Student\Module',
       'path' => '../Module/Student/Module.php',
   ],
   'teacher' => [
       'className' => 'Suzuki\Module\Teacher\Module',
       'path' => '../Module/Teacher/Module.php',
   ],
   'gallery' =>[
       'className' => 'Suzuki\Module\Gallery\Module',
       'path' => '../Module/Gallery/Module.php',
   ]
];

$application->registerModules($modules);

Im not sure but try to add path key.



6.6k

Can you help me with 2 things:

  • If i register a new module just like frontend, what is the link to access it, in this case is "backend" module , i think i have accessed backned with wrong link like this : localhost/projectname/backend

  • Second, can you tell me how to create others module just like frontend , for example : backend , in case i generate application with devtools please.

Thank you so much

Im not sure but try to add path key.

edited Oct '16

The default router behaviour is only suitable for single module application. You need to add routes yourself to access actions in multi module. Read about here:

https://forum.phalcon.io/discussion/6416/multi-module-routing-default-behaviour

about dev tools - im not using it myself to generate modules. Im just doing them myself. Not so hard stuff.

I also had the same problem ... after having searched and searched within the code generated by the DevTool I found the bug. In the app/config/routes.php file the following line of code

$namespace = str_replace('Module','Controllers', $module["className"]);

should be replaced with

$namespace = preg_replace('/\bModule\b/u', 'Controllers', $module["className"]);

The problem is that the strings of the type "Projectname\Modules\Backend\Module" (the standard from DevTool) were mistakenly replaced with "Projectname\Controllerss\Backend\Controllers", with my script instead we replace only whole word "Model" and not the string "Model" inside Models word. Later would certainly found problems also in the default module (frontend) routes.

Sorry the bug is just solved in the 3.0.3 version

$namespace = preg_replace('/Module$/', 'Controllers', $module["className"]);