MVC: Presentation Layer

As mentioned, there is nothing particularly special about the Starter Application views and controllers beyond what is provided out of the ZF2 box. Controllers pass variables to views. View scripts render them.

Views

It is worth noting that, with some extra coding in the Domain factories, view scripts can access an object’s properties, including multi-valued properties, without causing performance issues such as the N+1 selects problem. More on this later.

View Helpers

I use view helpers extensively to isolate complex logic and avoid duplication. They live in the Core\View\Helper namespace, with sub-namespaces for further organisation. They are registered in the module's configuration, usually as an invokable or a factory.

Forms

Zend\Form makes easy work of creating and rendering forms. In most cases however I revert to hand-crafted forms for complete control over the layout. The inlineScript view helper makes easy work of managing related javascript. 

Controllers

The Starter Application's controllers extend from Zend's abstract controller and are therefore service-locator-aware. Controllers use the service locator to access other services including Service Layer services and Data Mappers. In addition, the Starter Application’s base controller inserts a helper trait.

All code examples in this discussion are based on the Foo-Bar application shown in the class diagram on the N+1 Selects Problem page. Here is an example of a Bar controller.

namespace Core\Controller;

class BarController extends AbstractController
{
    public function updateBazAction()
    {
        $this->serviceLocator->get('Core\Service\Bar')->updateBaz(
            $this->params()->fromQuery('bar'),
            $this->params()->fromQuery('baz')
        );
    }
}

Helper Trait

The helper trait is inserted into most supertypes within the Starter Application, not just the abstract controller. It is a good place for any utilities that are used widely throughout an application. One such utility that the Starter Application uses extensively is getShortType, and this brings us to an important naming convention.

In the discussion on Domain objects you will see that there is often a 1-to-1 relationship between a Domain object and its associates. For example a Foo object may have an associated Foo proxy, Foo factory, and more. The getShortType function accepts an object or class name, and merely returns the unqualified name of the class. Client code may use this function to find out exactly which Domain object, proxy or factory it is working with.

Tags: