red888
red888

Reputation: 31550

Zend Framework 2: Unsure of how to hook up my templates to my controller's actions

I'm trying to teach myself zend and MVC in general and I was hoping to get some guidance on this program I'm writing. Its really basic, but I'm a little uncertain of how to proceed. I may be conceptualizing MVC in the wrong way.

I have two templates: index and tickets.

index is just a landing page with two links: "View open tickets" and "View closed tickets".

"tickets" is the template that is actually displaying the data from a DB my controller serves it.

So here is "index.phtml" (right now both the links are the same)

<a href="<?php echo $this->url(
    'helpdesk', array('action'=>'tickets'));?>">View open tickets</a>

<a href="<?php echo $this->url(
    'helpdesk', array('action'=>'tickets'));?>">View closed tickets</a>

Initially I was going to have each link call a different action like:

'action'=>'openTickets'
'action'=>'closedTickets'

But if I'm adhering to MVC each action should be its own page and then I would need two templates for opened and closed tickets which would be redundant.

So here is what I want to do:

  1. For each link pass a parameter in the url() method specifying "opened" or "closed"
  2. Then my controller looks at that parameter in its "ticketsAction" and returns either closed or open tickets for tickets.phtml to display
  3. tickets.phtml doesn't care whether the tickets are closed or open it displays them all the same way

Here is a hypothetical controller I'm thinking of. The $displayStatus would hold the parameter determining opened or closed tickets.

class HelpdeskController extends AbstractActionController {
    protected $ticketTable;
    protected $displayStatus;

    public function indexAction() {
        return new ViewModel(array(
        ));
    }

    public function ticketsAction() {
        return new ViewModel(array(
            if($displayStatus === 'opened'){
                'tickets' => $this->getOpenTickets()
            } else {
                'tickets' => $this->getClosedTickets()
            }


        ));
    }

    public function getOpenTickets() {
        return $this->getTicketTable()->fetchOpenedTickets();
    }

    public function getClosedTickets() {
        return $this->getTicketTable()->fetchClosedTickets();
    }

Is this possible with url()? Should I even be doing it this way or am I falling into an anti-pattern?

Upvotes: 1

Views: 202

Answers (1)

Jurian Sluiman
Jurian Sluiman

Reputation: 13558

Yes. What you are asking is possible and a very good example how to use an url to filter out entities. In your case, you filter on either open or closed tickets.

First, I would start with the routes. Say you have the helpdesk (/helpdesk) and you visit open or closed tickets (/helpdesk/tickets/open or /helpdesk/tickets/closed). This could be captured in a route with a child route.

'router' => array(
    'routes' => array(
        'helpdesk' => array(
            'type'    => 'literal',
            'options' => array(
                'route'    => '/helpdesk',
                'defaults' => array(
                    'controller' => 'Helpdesk\Controller\HelpdeskController',
                    'action'     => 'index',
                ),
            ),
            'may_terminate' => true,
            'child_routes'  => array(
                'tickets' => array(
                    'type'    => 'segment',
                    'options' => array(
                        'route' => '/tickets/:type',
                        'defaults' => array(
                            'action'     => 'tickets',
                        ),
                        'constraints' => array(
                            'type' => '[open|closed]',
                        ),
                    ),
                ),
            ),
        ),
    ),
),

In this example, there is route helpdesk, which shows the "dashboard" and a route helpdesk/tickets which shows either the open or closed tickets. The child route has a parameter "type" which must be given (it's not optional). Also, the type can only be "open" or "closed", otherwise the route doesn't match.

Then, in your controller, you can just check the value of the type parameter:

public function ticketsAction()
{
    $type    = $this->params('type');
    $tickets = $this->getTicketWithType($type);

    return new ViewModel(array('tickets' => $tickets));
}

What happens in this action are three things: first, the type is grabbed from the route match. This gives either "open" or "closed". Then, the tickets are fetched, but just use your own code here. The third one piece here is to return the view model with the tickets.

Thirdly, you want to create routes using the url() view helper. An url is assembled with the route name and its optional parameters. For the root route, it's quite simple:

$url = $this->url('helpdesk') // Returns "/helpdesk";

For the child route, you have to use the complete route name (helpdesk/tickets) and also the parameter:

// helpdesk/tickets/open
$url = $this->url('helpdesk/tickets', array('type' => 'open'));

// helpdesk/tickets/closed
$url = $this->url('helpdesk/tickets', array('type' => 'closed'));

Perhaps you only needed this last part, but I think it's good to get the complete picture here :)

Upvotes: 4

Related Questions