0

I am working on a website where I need a "widget" like view in my layout of Zend Framework 2. the widget should show the operational status of the server (this is done).

(Correct me if this is bad MVC style) I have build a controller with the

function viewStatusAction(){ 
   ... 
   return $viewModel(array($vars))
}

then i want to use a viewHelper to get the status of the action. This is where I'm stuck. I know how to create the viewHelper, but not where to start to get the returned view from the controller action. So how do i do this?

KatsuoRyuu
  • 321
  • 4
  • 19
  • Correct me if i'm wrong; you need to dispatch a controller action and create the widget from the resulting view model? – AlexP Aug 27 '14 at 19:10
  • I think this should work: ``return $this->getView()->render('application/controller/action', array('param' => 'value'));`` Never tried to dispatch from within a View Helper. – Gilberto Albino Aug 27 '14 at 19:15
  • Gilberto Albino -> Thank you. after re-reading about MVC i found that i should parse the render() and use services to parse data from the database etc. thanks. – KatsuoRyuu Aug 27 '14 at 21:23

2 Answers2

3

You can use the Zend\Mvc\Controller\Plugin\Forward controller plugin to dispatch another controller action from within another.

The docs say

Occasionally, you may want to dispatch additional controllers from within the matched controller – for instance, you might use this approach to build up “widgetized” content. The Forward plugin helps enable this.

This is useful if you have already have these actions but would like to combine them with others to build an aggregated view.

use Zend\View\Model\ViewModel;

class AdminController extends AbstractActionController 
{
    public function adminDashboardAction()
    {
        $view = new ViewModel();
        $view->setTemplate('admin/admin/dashboard');

        //..
        $serverStatsWidget = $this->forward()->dispatch('ServiceModule\Controller\Server', array(
            'action' => 'status',
            'foo' => 'bar',
        ));
        if ($serverStatsWidget instanceof ViewModel) {

            $view->addChild($serverStatsWidget, 'serviceStats');
        }

        return $view;
    }

As $serverStatsWidget is the result of the dispatched controller, you can then add it to the 'main' view as a child and render the result just by using echo.

// admin/admin/dashboard.phtml
echo $this->serviceStats;
AlexP
  • 9,906
  • 1
  • 24
  • 43
  • 1
    widgetized contents wouldn't be better built on top of View Helpers? I suppose since you may use the action itself for multiple purposes keeping the presentation logic for the View abstractly extended in a helper class. Forwarding seems to work on a routing layer other then for abstract view, which is the case. – Gilberto Albino Aug 27 '14 at 19:45
2

Here is what i did. This should also be the right way to do it

in module.php

public function getViewHelperConfig()
{
    return array(
        'factories' => array(
            'statusWidget' => function ($sm) {
                -- some service handling --
                $statusWidget = new statusWidget($service);
                return $statusWidget;
            }
        )
    );
}

then i created a viewHelper in operationalStatus\View\Helper

<?php
namespace operationalStatus\View\Helper;

use Zend\View\Helper\AbstractHelper;

class statusWidget extends AbstractHelper
{

    public function __construct($service){
        $this->service = $service
    }

    public function __invoke()
    {
        -- collect data from the service --

        return $this->getView()->render('operational-status/widget/status', array('operation' => $status));
    }

}
KatsuoRyuu
  • 321
  • 4
  • 19