Składanie presenterów z traitów

Jeśli potrzebujesz zaimplementować tę samą funkcjonalność w wielu presenterach (np. weryfikację zalogowania użytkownika), typowym podejściem jest umieszczenie kodu we wspólnym przodku. Inną możliwością jest utworzenie jednozadaniowych traitów.

Zaletą traitów jest to, że każdy presenter może włączyć tylko te traity, których faktycznie potrzebuje, zwłaszcza że PHP nie obsługuje dziedziczenia wielokrotnego.

Traity te mogą wykorzystać fakt, że przy tworzeniu instancji presentera wywoływane są kolejno wszystkie metody inject. Musisz tylko zadbać o to, aby nazwa każdej metody inject była unikalna we wszystkich użytych traitach i w samym presenterze.

Traity mogą podpiąć kod inicjalizacyjny do zdarzeń onStartup albo onRender.

Przykłady:

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

Presenter po prostu używa potem tych traitów:

class ArticlePresenter extends Nette\Application\UI\Presenter
{
	use StandardTemplateFilters;
	use RequireLoggedUser;
}