Компоновка презентеров из трейтов
Если нам нужно реализовать один и тот же код в нескольких презентерах (например, проверку, что пользователь авторизован), предлагается разместить код в общем предке. Вторая возможность — создание одноцелевых трейтов.
Преимущество этого решения в том, что каждый из презентеров может использовать именно те трейты, которые ему действительно нужны, в то время как множественное наследование в PHP невозможно.
Эти трейты могут использовать тот факт, что при создании презентера последовательно вызываются все inject методы. Необходимо только следить за тем, чтобы имя каждого inject метода было уникальным.
Трейты могут навешивать инициализационный код на события onStartup или onRender.
Примеры:
trait RequireLoggedUser
{
public function injectRequireLoggedUser(): void
{
$this->onStartup[] = function () {
if (!$this->getUser()->isLoggedIn()) {
$this->redirect('Sign:in', $this->storeRequest());
}
};
}
}
trait StandardTemplateFilters
{
public function injectStandardTemplateFilters(TemplateBuilder $builder): void
{
$this->onRender[] = function () use ($builder) {
$builder->setupTemplate($this->template);
};
}
}
Презентер затем просто использует эти трейты:
class ArticlePresenter extends Nette\Application\UI\Presenter
{
use StandardTemplateFilters;
use RequireLoggedUser;
}