Phalcon: how to get controller and action name

14,602

Solution 1

I think that untill you call $app->handle() the dispatcher won't be properly setup.

Maybe not a direct response, but I've manage to successfully implement authorization using Vokuro app as a example: https://github.com/phalcon/vokuro.

Your bootstrap looks ok should work.

I'm using this in bootstrap file :

/**
 * Handle the request
 */
$application = new \Phalcon\Mvc\Application();
$application->setDI($di);
if (!empty($_SERVER['REQUEST_URI'])) {
    $uriParts = explode('?', $_SERVER['REQUEST_URI']);
    $uri = $uriParts[0];
} else {
    $uri = '/';
}
echo $application->handle($uri)->getContent();

As you can see there is $uri parameter passed to $application->handle() function. Inside controllers: $this->dispatcher->getControllerName() works fine.

Solution 2

I am using a Router object so the following works for me before the ->handle call

/** @var $router \Phalcon\Mvc\Router */
$router = require APPLICATION_PATH.'/routes/default.php';
$router->handle($url);
$router->setUriSource(\Phalcon\Mvc\Router::URI_SOURCE_SERVER_REQUEST_URI);

/** @var $matched \Phalcon\Mvc\Router\Route */
$matched = $router->getMatchedRoute();
$paths = $matched->getPaths();

echo 'controller : ',$paths['controller'],"<br />";
echo 'action : ',$paths['action'],"<br />";

Solution 3

This is an old thread but in case people still need it, I will show you two ways to properly handle authorization.

In both cases, you should check authorization in a "before middleware", not anywhere else.

Checking authorization directly in your front controller is a bit premature.


1. By retrieving the handler, as you asked

Here you perform authorization checks only if needed. It is a bit more code, but a bit more effective too because you don't have to even use the database if you don't need to.

$app = \Phalcon\Mvc\Micro;
$app->before(function() use ($app)
{
    /**
     * @var \Phalcon\Mvc\Controller $oHandler
     */
    $oHandler = null;
    $sAction = null;
    $aHandlerArr = (array)$app->getActiveHandler();
    if (!empty($aHandlerArr) && !empty($aHandlerArr[1]))
    {
        $oHandler = $aHandlerArr[0];
        $sAction = $aHandlerArr[1];
    }

    if ($oHandler && $oHandler->isAuthRequired($sAction))
    {
        // Do auth, and send an error if failed
    }
});

2. Without voodoo magic

The other way is to simply try authorization in your before middleware without checking if you need it. It is the same code as above, but without the handler retrieval.

$app = \Phalcon\Mvc\Micro;
$app->before(function() use ($app)
{
    // Do auth ...
    // Set member in your app, if auth succeeded.
    // Then in your controller actions, simply check for the member in your app
});
Share:
14,602
Quasipickle
Author by

Quasipickle

Updated on June 04, 2022

Comments

  • Quasipickle
    Quasipickle almost 2 years

    I'm trying to build some authorization into my Phalcon-based app. In my bootstrap file I instantiate my Auth class (which extends Component), and run my authorize() function. Inside that function I get the dispatcher by calling $Dispatcher = $this->di->getShared('dispatcher').

    That all seems to run fine. However, when I then call $Dispatcher->getControllerName(), it returns NULL.

    How do I access the controller name?

    Here is my bootstrap file:

    $Debug = new \Phalcon\Debug();
    $Debug->listen();
    
    #try{
        # Create a Dependency Injection container
        $DI = new \Phalcon\DI\FactoryDefault();
    
        # Load config
        $Config = require '../app/config/config.php';
        $DI->setShared('config',$Config);
    
        # Register an autoloader
        $Loader = new \Phalcon\Loader();
        $Loader->registerDirs($Config->phalcon->load_dirs->toArray());
        $Loader->registerNamespaces($Config->phalcon->namespaces->toArray());
        $Loader->register();
    
        # Initialize Session
        $Session = new \Phalcon\Session\Adapter\Files();
        $Session->start();
        $DI->setShared('session',$Session);
    
        # Set up the View component
        $DI->set('view',function() use($Config){
            $View = new \Phalcon\Mvc\View();
            $View->setViewsDir($Config->dir->views_dir);
            $View->registerEngines(['.phtml'=> function($View,$DI) use ($Config){
                                                $Volt = new \Phalcon\Mvc\View\Engine\Volt($View,$DI);
                                                $Volt->setOptions([ 'compiledPath'  =>  $Config->dir->views_compile_dir,
                                                                    'compileAlways' =>  $Config->app->views_compile_always
                                                                  ]);
                                                return $Volt;
                                            }
                                ]);
            $View->Config = $Config;
            return $View;
        });
    
        # Check authorization
        $Auth = new Auth($DI);
        if($Auth->authorize()){
            $DI->setShared('user',$Auth->getUser());
        }
        else{
            $DI->get('view')->render('system','notallowed');
            exit();
        }
    
    
        # Set up connection to database
        $DI->set('db',function() use($Config){
            return new \Phalcon\DB\Adapter\Pdo\Mysql([  'host'      => $Config->database->host,
                                                        'dbname'    => $Config->database->database,
                                                        'username'  => $Config->database->username,
                                                        'password'  => $Config->database->password
                                                    ]);
        });
    
        # Set up base URL
        $DI->set('url',function() use($Config){
            $URL = new \Phalcon\Mvc\Url();
            $URL->setBaseUri('/'.basename($Config->dir->app_dir_web));
            return $URL;
        });
    
        # Set up message flashing to use session instead of direct
        $DI->set('flash',function(){
            return new \Phalcon\Flash\Session();
        });
    
        # Handle the requested URL
        $App = new \Phalcon\Mvc\Application($DI);
    
        # Echo the output
        echo $App->handle()->getContent();
    /*
    }
    catch(\Phalcon\Exception $e){
        echo 'Phalcon Exception: ',$e->getMessage();
    }
    */
    
  • Quasipickle
    Quasipickle almost 11 years
    So I guess there is no Phalcon-specific way to get the controller/action name in the bootstrap then? Guess I'll roll my own like you showed. Thanks.
  • Quasipickle
    Quasipickle over 8 years
    Thanks for this update. Note, however, that my initial question wasn't for a Micro application, so this isn't really applicable to the original question.
  • Lideln Kyoku
    Lideln Kyoku over 8 years
    Ok Pickle, my bad! Though the principles stay the same. For FullMVC, you can try the dispatcher and events manager as described here: docs.phalconphp.com/en/latest/reference/dispatching.html (although I am not sure it did actually exist when you asked your question a long time ago :) )
  • Luke
    Luke almost 8 years
    Answer is correct but consider describing response using full sentences and possibly avoid emoticons. That's the answers style we (the community) are trying to keep for clarity