It's been a little while since I asked this; however I did find the solution I was after. It was indeed related to how the new ViewModel
is attached back to the MvcEvent
.
Previously I had tried to set the event's result property with no luck :
$mvcEvent->setResult($myNewViewModel);
The key was to first fetch the MvcEvent
's own view model and then attach my custom one to it as a child.
$mvcEvent->getViewModel()->addChild($myNewViewModel, 'content');
I've also incorporated the point that @Crisp made regarding the event managers target. Previously, I was attaching to the main application dispatch event meaning that the listener would be called on every dispatch event.
I now specifically target the controllers I want to listen to.
$eventManager->attach(array(
'JobboardUser\Controller\AccountController',
'JobboardUser\Controller\ProfileController'
),
MvcEvent::EVENT_DISPATCH,
array($this, 'addUserAccountLayout'),
-80
);
The final listener code looks like this
public function addUserAccountLayout(EventInterface $event)
{
$result = $event->getResult();
if (! $result instanceof ViewModel || $result instanceof JsonModel) {
return;
}
$application = $event->getApplication();
$serviceManager = $application->getServiceManager();
$accountService = $serviceManager->get('JobboardUser\Service\AccountService');
$currentUser = $accountService->getCurrentUser();
$layout = new ViewModel();
$layout->setVariables(array('user' => $currentUser));
$layout->setTemplate('jobboard-user/widget/user-account');
$layout->addChild($result, 'userContent');
$event->getViewModel()->addChild($layout, 'content');
}