Question

How could i reference the controllerName and actionName that triggered the beforeExecuteRoute from the event itself?

<?php
use Phalcon\Events\Manager as EventsManager;

//Create a events manager
$eventManager = new EventsManager();

//Listen all the application events
$eventManager->attach('micro', function($event, $app) {

    if ($event->getType() == 'beforeExecuteRoute') {
        //how to get controller name to handle acl stuff
    }
});
Was it helpful?

Solution 2

This way you can get the route in string format to parse it:

$router->getMatchedRoute()->getPattern();

Hope this help. I found no other way to do this.

OTHER TIPS

From the documentation - http://docs.phalconphp.com/en/latest/api/Phalcon_Mvc_Dispatcher.html

getModuleName () - Gets the module where the controller class is
getControllerName () - Gets last dispatched controller name
getActionName () - Gets the lastest dispatched action name

Example:

<?php
use Phalcon\Events\Manager as EventsManager;

//Create a events manager
$eventManager = new EventsManager();

//Listen all the application events
$eventManager->attach('micro', function($event, $app) { 
    if ($event->getType() == 'beforeExecuteRoute') {            
        $controllerName = $app->getControllerName();
        $moduleName = $app->getModuleName();
        $actionName = $app->getActionName();          
    }
});

If you don't have a dispatcher you must be getting those values from the router. I'm not very familiar with specifics of micro apps, but from looking at the docs it must be something like that.

<?php
use Phalcon\Events\Manager as EventsManager;

//Create a events manager
$eventManager = new EventsManager();

//Listen all the application events
$eventManager->attach('micro', function($event, $app) {

    if ($event->getType() == 'beforeExecuteRoute') {
        //how to get controller name to handle acl stuff

        DI::getDefault()->get('router')->getControllerName();
        DI::getDefault()->get('router')->getActionName();

        // or

        $app->getRouter()->getControllerName();
        $app->getRouter()->getActionName();
    }
});

Does this work?

I actually ran into a similar confusion, but the other answers didn't help, and Phalcon's official documentation didn't find the right way to get it, so if you're using Micro, it's hard to find an effective answer on the web.So I used my reflection to understand Phalcon's before, and finally came up with the following answer, which I hope will help you. Good luck!

<?php

$eventsManager = new \Phalcon\Events\Manager();
$eventsManager->attach(
    'micro:beforeExecuteRoute',
    function (\Phalcon\Events\Event $event, $app) {
        $controllerName = $event->getSource()->getActiveHandler()[0]->getDefinition();
        $actionName = $event->getSource()->getActiveHandler()[1];
    }
);

$app = new \Phalcon\Mvc\Micro($di);
$app->setEventsManager($eventsManager);

If you want to implement the ACL with the before event, the following AclAnnotation code may help:

<?php

class AclAnnotation
{
    protected $private = true;
    protected $roles = [];
    protected $component = [];
    protected $access = [];

    public function __construct($event, $app)
    {
        $controllerName = $event->getSource()->getActiveHandler()[0]->getDefinition();
        $actionName = $event->getSource()->getActiveHandler()[1];

        $reflector   = $app->annotations->get($controllerName);
        $annotations = $reflector->getClassAnnotations();
        if (!$annotations) {
            throw new ErrorException('The permission configuration is abnormal. Please check the resource permission comments.');
            return;
        }

        if (
            $annotations->has('Private')
            && ($annotation = $annotations->get('Private'))->numberArguments() > 0
        ) {
            $this->private = $annotation->getArguments('Private')[0];
        }

        if (
            $annotations->has('Roles')
            && ($annotation = $annotations->get('Roles'))->numberArguments() > 0
        ) {
            $this->roles = $annotation->getArguments('Roles');
        }

        if (
            $annotations->has('Components')
            && ($annotation = $annotations->get('Components'))->numberArguments() > 0
        ) {
            $this->components = $annotation->getArguments('Components');
        }

        $annotations = $app->annotations->getMethod($controllerName, $actionName);
        if (
            $annotations->has('Access')
            && ($annotation = $annotations->get('Access'))->numberArguments() > 0
        ) {
            $this->access = $annotation->getArguments('Access');
        }
    }

    public function isPrivate()
    {
        return $this->private;
    }

    public function getRoles()
    {
        return $this->roles;
    }

    public function getComponents()
    {
        return $this->components;
    }

    public function getAccess()
    {
        return $this->access;
    }
}

Create an event listener in index.php:

<?php

    $eventsManager = new \Phalcon\Events\Manager();
    $eventsManager->attach(
        'micro:beforeExecuteRoute',
        function (\Phalcon\Events\Event $event, $app) {
            $aclAnnotation = new AclAnnotation($event, $app);
            if (!$aclAnnotation->isPrivate()) {
                return true;
            }

            $acl = $app->currentACL;
            // Verify that you have access permission for the interface
            if (!$acl->isAllowed($aclAnnotation->getRoles(), $aclAnnotation->getComponents(), $aclAnnotation->getAccess())) {
                throw new \ErrorException('You do not have access to the resource', 40001);
                return false;
            }

            return true;
        }
    );

    $app = new \Phalcon\Mvc\Micro($di);
    $app->setEventsManager($eventsManager);

As for the use of annotations, you can refer to here:

https://docs.phalcon.io/5.0/en/annotations

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top