U siebie rozwiązuje to w ten sposób, że kontroler praktycznie uruchamiam na samym końcu, a wszystko co jest przed nim, w "jądrze" frameworka, uruchamia się różnie. Różnie, znaczy tyle, że są pewne elementy które muszą zostać uruchomione (cache, request, response, templates itp), ale również są elementy opcjonalne, które się uruchamiają jeżeli ustawię je w konfiguracji. Do takich uruchamianych w zależności od potrzeb, klas, należą klasy bazy danych, obsługi użytkownika, internacjonalizacja, sesja itp. Klasy do obsługi użytkownika, bo jest ich kilka, mają swoje zadanie. I jest tam między innymi klasa Authentication, odpowiedzialna za uwierzytelnianie użytkownika. Normalnie nie zalogowany użytkownik, dostaje odpowiednią role: ROLE_GUEST, jeżeli sobie w routingu ustawię że dla danej akcji wymagane będzie uprawnienie ROLE_USER, to klasa Authentication sprawdzi jaki poziom uprawnień posiada użytkownik i jest kilka warunków. Sprawdzanie czy zalogowany (ROLE_USER) i jeżeli nie jest, jest przekierowywany na podstronę logowania, jeżeli jest zalogowany i nie posiada odpowiednich uprawnień (ROLE_ADMIN przykładowo) dostaje komunikat (domyślnie wyjątek AccessDeniedException który dziedziczy po HttpException i dostanie błąd 403) o tym że nie posiada odpowiednich uprawnień.
Jeżeli bym umieścił gdzieś w module kod odpowiedzialny za uwierzytelnianie to powielać bym go musiał wiele razy. Jeżeli wrzuciłbym gdzieś to do kontrolera, a jednocześnie nie chciałbym używać klas użytkownika, również bym posiadał kod który robi coś, do czego dana klasa nie została przeznaczona. A ładowanie takiej usługi użytkownika, jest względnie proste:
if(Config::has('framework.default_database') && Config::has('framework.session') && Config::has('framework.users'))
{
$this->container->setService('user.manager', new UserManager($this->container->getService('database'), $this->container->getService('request')));
$this->container->setService('user', new User());
$this->container->setService('user.auth', new Authentication($this->container));
$this->container->setService('group.manager', new GroupManager($this->container->getService('database')));
}
Z racji że przetestowałem kilka wariantów, wydaje mi się takie wyjście w moim przypadku najsłuszniejsze. Pomyśl o czymś podobnym, żeby całość jakoś elegancko wyglądała. Zwłaszcza z tym dostępem do strony, dla użytkownika o odpowiednich uprawnieniach