Создание собственного View Helper в Zend Framework 2

У меня была задача для сайта, который я делал на фрилансе.
Задача следующая – есть модуль , который для этого же проекта и был написан. Он достаточно прост, в нем происходит сохранение страниц в бд, поиск, роутинг к страницам вида “/page/pagename/” и базовые шаблоны.


Но по функционалу и дизайну сайта необходимо было выводить некоторые страницы с предпросмотром на главную (или где угодно).

И поможет в решении данной задачи конечно же Zend\\.
Я хотел вызывать в view шаблонах некий хелпер следующим образом:

Т.е. где-то в произвольном шаблоне я подгружаю по alias нужную мне страницу и вывожу с нее данные. Кстати, эта же страница открывается по адресу “/page/welcome”, но уже с полным текстом. В примере выше я показал уже конечный вариант, но именно так я его и задумывал.

Для создания своего View Helper класс должен наследоваться от Zend\View\Helper\AbstractHelper.
Для того, чтобы вызвать свой класс как хелпер, он обязательно должен реализовывать магический метод __invoke().

Далее необходимо зарегестрировать наш класс как хелпер в Service. Это можно сделать двумя способами.
Первый не очень хороший, но рабочий:

Это похоже на обычный способ заведения сервиса в service manager. Так же можно вынести создающий код в Factory.

Второй способ более компактный и имеет свою особенность. Им я и воспользовался.

В файле module.config.php:

Так будет работать, но где же нужный для решения задачи ? А он будет записан в объект автоматически при создании, при условии, что класс реализует интерфейс ServiceLocatorAwareInterface.

Далее надо добавить в класс хелпера такой код.

Я добавил стандартные методы для интерфейса ServiceLocatorAwareInterface, свойство для сохранения менеджера и еще добавил метод, который достает Doctrine\ORM\EntityManager из сервисов. Он будет нужен для загрузки страницы.
Можно заметить некоторую особенность в строке

Дело в том, что сервис был зарегистрирован как хелпер, следовательно при создании в него будет помещен не ServiceManager сразу, а Zend\View\HelperPluginManager, который дает доступ к другим хелперам. И у него то уже и надо вызвать метод getServiceLocator() для доступа к нужному ServiceManager.

Далее дело за __invoke() и другими методами хелпера. В моем случае __invoke() выглядит так:

В коде видно, что я реализовал некий кеш в массиве, чтобы не делать лишние запросы в базу данных. Для этого создана статическая переменная $pagesCache, в которую сохраняется выбранный объект по alias.
Так же я сохраняю текущую запрошенную страницу в переменную, и возвращаю $this, чтобы я мог делать следующее:

Пример клиентского кода, который пользуется этими методами уже был приведен выше.

Объект Page, который я тут запрашиваю – это стандартный Doctrine Entity. Конфиги, как и весь остальной код, связанный с Page организован в модуль и возможно, он будет опубликован, когда я его закончу.