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

Is there a shorter way to make all modules use one bootstrap in Phalcon php?

For source code: https://github.com/OkveeNet/phalcon-begins

I have 2 modules.

  1. is core and 2. is contact

This is the Module.php file for core module.

<?php
/* 
 * 
 *  @author Vee W.
 *  @license https://opensource.org/licenses/MIT
 * 
 */

namespace Core;

use Phalcon\Loader,
    Phalcon\Mvc\Dispatcher,
    Phalcon\Mvc\View,
    Phalcon\Mvc\View\Engine\Volt,
    Phalcon\Mvc\ModuleDefinitionInterface;

class Module implements ModuleDefinitionInterface
{

    /**
     * Register a specific autoloader for the module
     */
    public function registerAutoloaders()
    {

        $loader = new Loader();

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

        $loader->register();
    }// registerAutoloaders

    /**
     * Register specific services for the module
     */
    public function registerServices($di)
    {
        $config = include APPFULLPATH.'/config/config.php';
        $dispatcher = $di->getShared('dispatcher');

        // Registering a dispatcher
        $di->set('dispatcher', function() use($di, $dispatcher) {
            $dispatcher->setDefaultNamespace("Core\\Controllers");
            return $dispatcher;
        });

        // Registering the view component
        $di->set('view', function() use ($config) {
            $view = new View();
            $view->setViewsDir(__DIR__.'/views/');
            $view->registerEngines(array(
                '.volt' => function ($view, $di) use ($config) {

                    $volt = new Volt($view, $di);

                    $volt->setOptions(array(
                        'compiledPath' => $config->application->cacheDir,
                        'compiledSeparator' => '_'
                    ));

                    return $volt;
                },
                '.phtml' => 'Phalcon\Mvc\View\Engine\Php',
                '.php' => 'Phalcon\Mvc\View\Engine\Php',
            ));
            return $view;
        });
    }

}

And this is Module.php file for contact module.

<?php
/* 
 * 
 *  @author Vee W.
 *  @license https://opensource.org/licenses/MIT
 * 
 */

namespace Modules\Contact;

use Phalcon\Loader,
    Phalcon\Mvc\Dispatcher,
    Phalcon\Mvc\View,
    Phalcon\Mvc\View\Engine\Volt,
    Phalcon\Mvc\ModuleDefinitionInterface;

class Module implements ModuleDefinitionInterface
{

    /**
     * Register a specific autoloader for the module
     */
    public function registerAutoloaders()
    {

        $loader = new Loader();

        $loader->registerNamespaces(
            array(
                'Modules\\Contact\\Controllers' => __DIR__.'/controllers/',
                'Modules\\Contact\\Models'      => __DIR__.'/models/',
                'Core\\Controllers' => APPFULLPATH.'/controllers/',
            )
        );

        $loader->register();
    }// registerAutoloaders

    /**
     * Register specific services for the module
     */
    public function registerServices($di)
    {
        $config = include APPFULLPATH.'/config/config.php';

        // Registering a dispatcher
        $di->set('dispatcher', function() use ($di) {
            $evManager = $di->getShared('eventsManager');

            $evManager->attach('dispatch:beforeException', function($event, $dispatcher, $exception) {
                switch ($exception->getCode()) {
                    case PhDispatcher::EXCEPTION_HANDLER_NOT_FOUND:
                    case PhDispatcher::EXCEPTION_ACTION_NOT_FOUND:
                        $dispatcher->forward(
                            array(
                                'module' => 'core',
                                'controller' => 'error',
                                'action' => 'e404',
                            )
                        );
                        return false;
                }
            }, true);
            $dispatcher = new Dispatcher;
            $dispatcher->setEventsManager($evManager);
            $dispatcher->setDefaultNamespace('Modules\\Contact\\Controllers');
            return $dispatcher;
        });

        // Registering the view component
        $di->set('view', function() use ($config) {
            $view = new View();
            $view->setViewsDir(__DIR__.'/views/');
            $view->registerEngines(array(
                '.volt' => function ($view, $di) use ($config) {

                    $volt = new Volt($view, $di);

                    $volt->setOptions(array(
                        'compiledPath' => $config->application->cacheDir,
                        'compiledSeparator' => '_'
                    ));

                    return $volt;
                },
                '.phtml' => 'Phalcon\Mvc\View\Engine\Php',
                '.php' => 'Phalcon\Mvc\View\Engine\Php',
            ));
            return $view;
        });
    }// registerServices

}

I must register service in all modules i have which is very inconvenient and hard to make change later. If it uses only main bootstrap it is easier to manage. For example, make change on view component, change dispatcher settings to show 404 page.

How to use shared main bootstrap in Phalcon php?



16.4k
Accepted
answer

I would

  • Extend from Core or Use a Trait to share the login and use properties for the variables that change depending on the model

Let me know what you think



6.2k

Interesting.

But i don't understand why share the login? Doesn't it use cookie to check the login? And i'm really cannot imagine how to extend or from where.



16.4k

My bad, share The logic ^^



6.2k

I don't know what class to extend from core.



6.2k

It worked!

ModuleTrait.php

<?php

namespace Extend;

use Phalcon\Loader,
    Phalcon\Mvc\Dispatcher,
    Phalcon\Mvc\View,
    Phalcon\Mvc\View\Engine\Volt;

/**
 * Modules trait.<br><br>
 * Use this file to manage register services in one place.<br>
 * To use this trait, set your module like Phalcon Module.php but extend \Extend\ModulesAbstract<br>
 * Setup $controller_namespace property for Module class to your default controller namespace<br>
 * Set $module_full_path property to __DIR__ for easy to manage.<br>
 */
trait ModulesTrait
{

    protected $default_controller_namespace = 'Core\\Controllers';
    protected $default_module_full_path = APPFULLPATH.'/core';

    /**
     * Register specific services for the module
     */
    public function registerServices($di)
    {
        $module_caller_name = get_called_class();
        $module_caller = new $module_caller_name;
        if (property_exists($module_caller, 'controller_namespace')) {
            $default_namespace = $module_caller->controller_namespace;
        } else {
            $default_namespace = $this->default_controller_namespace;
        }
        if (property_exists($module_caller, 'module_full_path')) {
            $module_full_path = $module_caller->module_full_path;
        } else {
            $module_full_path = $this->default_module_full_path;
        }
        unset($module_caller_name);

        $config = include APPFULLPATH.'/config/config.php';

        // Registering a dispatcher
        $di->set('dispatcher', function() use ($di, $default_namespace) {
            $evManager = $di->getShared('eventsManager');
            $evManager->attach('dispatch:beforeException', function($event, $dispatcher, $exception) {
                switch ($exception->getCode()) {
                    case Dispatcher::EXCEPTION_HANDLER_NOT_FOUND:
                    case Dispatcher::EXCEPTION_ACTION_NOT_FOUND:
                        $dispatcher->forward(
                            array(
                                'namespace' => 'Core\\Controllers',
                                'module' => 'core',
                                'controller' => 'error',
                                'action' => 'e404',
                            )
                        );
                        return false;
                }
            }, true);

            $dispatcher = new Dispatcher;
            $dispatcher->setEventsManager($evManager);
            $dispatcher->setDefaultNamespace($default_namespace);
            return $dispatcher;
        });

        // Registering the view component
        $di->set('view', function() use ($config, $module_full_path) {
            $view = new View();
            $view->setViewsDir($module_full_path.'/views/');
            $view->registerEngines(array(
                '.volt' => function ($view, $di) use ($config) {

                    $volt = new Volt($view, $di);

                    $volt->setOptions(array(
                        'compiledPath' => $config->application->cacheDir,
                        'compiledSeparator' => '_'
                    ));

                    return $volt;
                },
                '.phtml' => 'Phalcon\Mvc\View\Engine\Php',
                '.php' => 'Phalcon\Mvc\View\Engine\Php',
            ));
            return $view;
        });
    }// registerServices

}

ModuleAbstract.php

<?php

namespace Extend;

use Phalcon\Mvc\ModuleDefinitionInterface;

/**
 * Modules abstract class<br>
 * For more information and how to use please read on ModuleTrait.php
 */
abstract class ModulesAbstract implements ModuleDefinitionInterface
{

    use \Extend\ModulesTrait;

}

In each modules{module_name}\Module.php

<?php

namespace Modules\Contact;

use Phalcon\Loader;

class Module extends \Extend\ModulesAbstract
{

    protected $controller_namespace = 'Modules\\Contact\\Controllers';
    protected $module_full_path = __DIR__;

    /**
     * Register a specific autoloader for the module
     */
    public function registerAutoloaders()
    {

        $loader = new Loader();

        $loader->registerNamespaces(
            array(
                $this->controller_namespace => __DIR__.'/controllers/',
                'Modules\\Contact\\Models'      => __DIR__.'/models/',
                'Core\\Controllers' => APPFULLPATH.'/controllers/',
            )
        );

        $loader->register();
    }// registerAutoloaders

}


16.4k