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

use two plugins class together in one event manager in dispatcher

i need use two plugins class (Security class & Exceptions class) together in one event manager in dispatcher : Exceptions.php

namespace Multiple\Frontend\Plugins;

use Phalcon\Mvc\Dispatcher,
    Phalcon\Events\Event,
    Phalcon\Mvc\User\Plugin,
    Phalcon\Mvc\Dispatcher\Exception as DispatchException,
    Phalcon\Acl;

class Exceptions extends Plugin
{

    public function beforeException(Event $event, Dispatcher $dispatcher, $exception)
    {

        //Handle 404 exceptions
        if ($exception instanceof DispatchException) {
            $dispatcher->forward(array(
                'controller' => 'error',
                'action' => 'show404'
            ));
            return false;
        }

        //Handle other exceptions
        $dispatcher->forward(array(
            'controller' => 'error',
            'action' => 'show503'
        ));

        return false;
    }
}

Security.php >>>

namespace Multiple\Frontend\Plugins;

use Phalcon\Events\Event,
    Phalcon\Mvc\User\Plugin,
    Phalcon\Mvc\Dispatcher,
    Phalcon\Acl;

/**
 * Security
 *
 * This is the security plugin which controls that users only have access to the modules they're assigned to
 */
class Security extends Plugin
{

    public function __construct($dependencyInjector)
    {
        $this->_dependencyInjector = $dependencyInjector;
    }

    public function getAcl()
    {
        if (!isset($this->persistent->acl)) {

            $acl = new \Phalcon\Acl\Adapter\Memory();

            //Default action is deny access
            $acl->setDefaultAction(\Phalcon\Acl::DENY);

            //Register roles
            $roles = array(
                'users' => new \Phalcon\Acl\Role('Users'),
                'guests' => new \Phalcon\Acl\Role('Guests')
            );
            foreach ($roles as $role) {
                $acl->addRole($role);
            }

            //Private area resources
            $privateResources = array();
            foreach ($privateResources as $resource => $actions) {
                $acl->addResource(new Phalcon\Acl\Resource($resource), $actions);
            }

            //Public area resources
            $publicResources = array(
                'index' => array('index'),
                'error' => array('show404', 'index'),
                'session' => array('index', 'register', 'start', 'end'),
                'contact' => array('index', 'send')
            );

            foreach ($publicResources as $resource => $actions) {
                $acl->addResource(new \Phalcon\Acl\Resource($resource), $actions);
            }

            //Grant access to public areas to both users and guests
            foreach ($roles as $role) {
                foreach ($publicResources as $resource => $actions) {
                    $acl->allow($role->getName(), $resource, '*');
                }
            }

            //Grant acess to private area to role Users
            foreach ($privateResources as $resource => $actions) {
                foreach ($actions as $action){
                    $acl->allow('Users', $resource, $action);
                }
            }

            //The acl is stored in session, APC would be useful here too
            $this->persistent->acl = $acl;
        }
        // print_r($this->persistent->acl);
        return $this->persistent->acl;
    }

    /**
     * This action is executed before execute any action in the application
     */
    public function beforeDispatch(Event $event, Dispatcher $dispatcher)
    {

        $auth = $this->session->get('auth');
        if (!$auth){
            $role = 'Guests';
        } else {
            $role = 'Users';
        }

        $controller = $dispatcher->getControllerName();
        $action = $dispatcher->getActionName();

        $acl = $this->getAcl();
        // echo $role;
        // echo $controller . ':' . $acl->isAllowed($role, $controller, $action). '<br/>';
        // echo Acl::ALLOW. '<br>';

        $allowed = $acl->isAllowed($role, $controller, $action);
        if ($allowed != Acl::ALLOW) {
            $this->flash->error("You don't have access to this module");
            $dispatcher->forward(
                array(
                    'controller' => 'index',
                    'action' => 'index'
                )
            );
            return false;
        }

    }

}

dispatcher code >>>

$di->set('dispatcher', function() use ($di) {

    //Create an EventsManager
    $eventsManager = new EventsManager();

    $exceptions = new Multiple\Frontend\Plugins\Exceptions($di);
    $security = new Multiple\Frontend\Plugins\Security($di);

    /**
     * We listen for events in the dispatcher using the Security plugin
     */
    $eventsManager->attach('dispatch:beforeException', $exceptions);

    $dispatcher = new Phalcon\Mvc\Dispatcher();
    $dispatcher->setEventsManager($eventsManager);

    return $dispatcher;
});

how to manage more than one event together for EX: use event beforeDispatch with beforeException



98.9k
edited Jun '14

What the events manager does is check for a method with the name of the event that it's triggering, so you can implement a class handling both events:

namespace Multiple\Frontend\Plugins;

use Phalcon\Mvc\Dispatcher,
    Phalcon\Events\Event,
    Phalcon\Mvc\User\Plugin,
    Phalcon\Mvc\Dispatcher\Exception as DispatchException;

class MyPlugin extends Plugin
{
    public function beforeDispatch(Event $event, Dispatcher $dispatcher)
    {
        //...
    }

    public function beforeException(Event $event, Dispatcher $dispatcher, $exception)
    {
        //...
    }
}

Register the plugin:

$di->set('dispatcher', function() use ($di) {

    //Create an EventsManager
    $eventsManager = new EventsManager();

    $plugin = new Multiple\Frontend\Plugins\MyPlugin($di);
    $eventsManager->attach('dispatch', $plugin);

    $dispatcher = new Phalcon\Mvc\Dispatcher();
    $dispatcher->setEventsManager($eventsManager);

    return $dispatcher;
});

so tanx i used but at this line that call event for triggering at the first run dispatch:beforeDispatch then dispatch:beforeException that not work !!! for example : https://localhost:8888/site/error : define on publicResources , out put after run ok https://localhost:8888/site/errorxxx : is not a controller so most refer to error controller and show404 index but refer to index and show : You don't have access to this module and refer to index