silexphp / Silex

[DEPRECATED -- Use Symfony instead] The PHP micro-framework based on the Symfony Components
https://silex.symfony.com
MIT License
3.58k stars 718 forks source link

Accessing _controller in $application->before() #543

Closed ryanzec closed 11 years ago

ryanzec commented 11 years ago

So I have a framework that using Silex as its core:

https://github.com/ryanzec/salvomvc-component

One piece of code I have is:

<?php
$application->before(function($event) use ($application)
{
    //make sure that the controller in a class
    $controller = $event->attributes->get('_controller');
    $application['requested_controller'] = null;
    $application['requested_action'] = null;

    if(is_string($controller) && strpos($controller, '::') !== false)
    {
        //set the requested controller and action
        $controllerParts = explode('::', $controller);

        $application['requested_controller'] = substr(ClassHelper::getNonNamespacedClass($controllerParts[0]), 0, -10);
        $application['requested_action'] = substr($controllerParts[1], 0, -6);
    }
}, 1100);

What this does is allow me to know what the controller and method that is going to be accessed. I use this in order to implement security such as this:

<?php
$application->before(function($event) use ($application)
{
    $currentPage = $application['requested_controller'] . '::' . $application['requested_action'];
    $noneSecurePages = array
    (
        'Authentication::session'
    );

    //see if the resource requested in a rest api call
    $requestUri = $event->getRequestUri();

    if(strpos($requestUri, 'api/v'))
    {
        //skipp authentication key check if the user is already logged into the system
        if(!$application['session']->get('loggedIn'))
        {
            if(!in_array($currentPage, $noneSecurePages))
            {
                //throw new HttpException(401, $currentPage);
            }
        }
    }
}, 999);

Which requires authentication in order to access the REST API of the application except when accessing the authentication session call.

The issue that has come up is that when I updated all the libraries through composer today, the _controller is no longer set when inside that first $application->before() (just to test, it is set if I do it the $application->after()).

I should also mention that I am linked to the dev-master version of silex. This is something I was planning on changing soon as I was still in development of the framework. I understand linking to dev-master can have these types of problems, I just want to figure out if this is something I need to fix in my framework or if this is a bug in Silex.

The question I have is whether or not this is an actually bug or if this was intentionally changed to function this way. If this is an intentionally change, is there any other way to get the behavior I am looking for here?

davedevelopment commented 11 years ago

This was an intentional change, I think you just need to knock down your priorities, I think the router listens in at 32, so anything lower than that should be okay.

Looking at the changes, I think if I were you I'd fire the one you want running first at Application::LATE_EVENT and the second at Application::LATE_EVENT - 1

ryanzec commented 11 years ago

@davedevelopment Thanks, I have updated my code accordingly and everything now looks good.