Quasipickle
Quasipickle

Reputation: 4498

Phalcon: how to get controller and action name

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();
}
*/

Upvotes: 2

Views: 15304

Answers (4)

Aghyul Kyoku
Aghyul Kyoku

Reputation: 1060

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
});

Upvotes: 1

Richard
Richard

Reputation: 95

XD $this->router->getActionName()

Upvotes: -3

CodeMonkey
CodeMonkey

Reputation: 3331

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 />";

Upvotes: 1

jodator
jodator

Reputation: 2465

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.

Upvotes: 4

Related Questions