Reputation: 31550
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:
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
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