zf2: Introduzindo ao nosso primeiro módulo “Blog”

Este artigo é uma tradução mal feita do artigo Introducing our first “Blog” Module da documentação do zend Framework 2.4 feita por mim mesmo (Vasconcelos) para minhas consultas futuras, é claro que estou deixando disponível para qualquer pessoal que necessitar.

Agora que nós sabemos o básico sobre a aplicação esqueleto do Zend
Framework 2, vamos continuar e criar o nosso próprio
módulo. Iremos criar um módulo chamado “Blog”. Este módulo irá exibir uma lista de registros no banco de dados que representam um único post do blog. Cada post terá três propriedades: id, text e no title. Vamos criar formulários para inserir novos post em nosso banco de dados e para editar posts existentes. Além do mais, vamos fazer usando boas práticas em todo este QuickStart.

Escrevendo um novo Módulo

Vamos começar criando uma nova pasta dentro do diretório /module chamado Blog.

Para ser reconhecido como um módulo pelo ModuleManager tudo o que temos que fazer é criar uma class PHP nomeada Module dentro do nosso módulo, que é Blog. Create the file /module/Blog/Module.php


<?php
// Filename: /module/Blog/Module.php
namespace Blog;
class Module
{
}

Agora nós temos um módulo que pode ser detectado pelos ModuleManager ZF2s. Vamos adicionar este módulo a nossa aplicação. Embora nosso módulo não tenha nada ainda, apenas por ter a classe Module.php permite que ele seja carregado pelo ModuleManager ZF2. Para fazer isso, adicione uma entrada para Blog dentro do array de múdulos na aplicação principal no arquivo de configurações em /config/application.config.php:

<?php
// Filename: /config/application.config.php
return array(
'modules' => array(
'Application',
'Blog'
),
// ...
);

Se você atualizar a sua aplicação agora você não verá alteração (mas também sem erros).

Neste ponto, vale a pena dar um passo para trás para discutir o que são módulos. Em resumo, um módulo é um conjunto encapsulado de recursos para a sua aplicação. Como você pode ver um módulo pode adicionar recursos a um aplicativo, como o nosso módulo Blog; ou pode fornecer funcionalidades em plano de fundo para uso por outros módulos do aplicativo, como interagir com um terceiro a partir de API.

Organizar seu código em módulos torna mais fácil para que você reutilizar funcionalidade em outro aplicativo, ou para usar módulos escritos pela comunidade.

Configurando o Módulo

A próxima coisa que vamos fazer é adicionar uma rota para nossa aplicação para que nosso módulo possa ser acessado através da URL  localhost:8080/blog. Fazemos isto através da adição de configurações de rotas para nosso módulo, mas primeiro precisamos deixar o ModuleManager saber que nosso módulo tem configuração que ele precisa carregar.

Isto é feito através da função getConfig() para a classe Module que retorna a configuração.(Esta função é definida em ConfigProviderInterface embora realmente implementar esta interface na classe module seja opcional.) Esta função deve retornar um array ou um objeto Traversable. Continue editando seu /module/Blog/Module.php:


<?php
// Filename: /module/Blog/Module.php
namespace Blog;
use Zend\ModuleManager\Feature\ConfigProviderInterface;
class Module implements ConfigProviderInterface
{
public function getConfig()
{
return array();
}
}

Com este nosso Module agora pode ser configurado. Arquivos de configurações podem se tornarem bastante grandes e embora mantendo tudo dentro da função getConfig() não será o ideal. Para ajudar a manter o nosso projeto organizado vamos colocar a nossa configuração do array em um arquivo separado. Vá em frente e crie esse arquivo /module/Blog/config/module.config.php:


<?php
// Filename: /module/Blog/config/module.config.php
return array();

Agora vamos reescrever a função getConfig() para incluir esse arquivo recém-criada em vez de retornar diretamente o array.


<?php 
// Filename: /module/Blog/Module.php
namespace Blog;
use Zend\ModuleManager\Feature\ConfigProviderInterface;
class Module implements ConfigProviderInterface
{
public function getConfig()
{
return include __DIR__ . '/config/module.config.php';
}
}

Recarregue seu aplicativo e você verá que tudo permanece como era. Em seguida, adicione a nova rota para o nosso arquivo de configuração:

Criamos agora uma rota chamada post que responde para a URL localhost:8080/blog. Sempre que alguém acessar esta rota, a função indexAction() da classe Blog\Controller\List será executada. No entanto, este controller ainda não existe, por isso, se você recarregar a página, você verá essa mensagem de erro:

A 404 error occurred
Page not found.
The requested controller could not be mapped to an existing controller class.

Controller:
Blog\Controller\List(resolves to invalid controller class or alias: Blog\Controller\List)
No Exception available

Agora nós precisamos dizer ao nosso módulo onde encontrar este controller chamado Blog\Controller\List. Para conseguir isso, nós temos que adicionar esta chave de configuração para o controllers dentro do seu /module/Blog/config/module.config.php.

 array(
'invokables' => array(
'Blog\Controller\List' => 'Blog\Controller\ListController'
)
),
'router' => array( /** Route Configuration */ )
);

Estas configurações definem Blog\Controller\List como um alias para o ListController sob o namespace Blog\Controller. Recarregando a página dará a você então:

( ! ) Fatal error: Class ‘Blog\Controller\ListController’ not found in {libPath}/Zend/ServiceManager/AbstractPluginManager.php on line {lineNumber}

Este erro nos diz que a aplicação sabe qual classe é para carregar, mas não onde encontrá-la. Para corrigir isso, precisamos configurar o autoloading para o nosso Módulo. Autoloading é um processo que permite o PHP carregar automaticamente classes sob demanda. Para o nosso módulo nós vamos configurar através da adição de uma função getAutoloaderConfig() para nossa classe Module.(Esta função é definida em AutoloaderProviderInterface, embora a presença da função seja suficiente, a implementando efetivamente da interface é opcional.)


<?php
// Filename: /module/Blog/Module.php
namespace Blog;

use Zend\ModuleManager\Feature\AutoloaderProviderInterface;
use Zend\ModuleManager\Feature\ConfigProviderInterface;

class Module implements
AutoloaderProviderInterface,
ConfigProviderInterface
{
/**
    * Return an array for passing to Zend\Loader\AutoloaderFactory.
    *
    * @return array
    */
    public function getAutoloaderConfig()
    {
        return array(
        'Zend\Loader\StandardAutoloader' => array(
            'namespaces' => array(
                // Autoload all classes from namespace 'Blog' from '/module/Blog/src/Blog'
                __NAMESPACE__ => __DIR__ . '/src/' . __NAMESPACE__,
                )
            )
        );
    }

    /**
    * Returns configuration to merge with application configuration
    *
    * @return array|\Traversable
    */
    public function getConfig()
    {
        return include __DIR__ . '/config/module.config.php';
    }
}

Agora parece muitas mudanças, mas não tenha medo. Nós adicionamos uma função getAutoloaderConfig(), que fornece configuração para o Zend\Loader\StandardAutoloader. Esta configuração diz ao aplicativo que as classes em __NAMESPACE__ (Blog) pode ser encontrada dentro __DIR__ . '/src/' . __NAMESPACE__ (/module/Blog/src/Blog).

O Zend\Loader\StandardAutoloader usa o padrão chamado PSR-0 que é dirigido comunidade PHP <https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-0.md>`_. Entre outras coisas, esta norma define o caminho para o PHP para mapear nomes de classes para o sistema de arquivos. Assim, com esta configuração, A aplicação sabe que nossa classe Blog\Controller\ListControlle estará em /module/Blog/src/Blog/Controller/ListController.php.

Se você atualizar o navegador agora você vai ver o mesmo erro, o mesmo que de quando você configurou o autoloader, ainda precisamos criar a classe controller. Vamos criar este arquivo agora:



// Filename: /module/Blog/src/Blog/Controller/ListController.php
namespace Blog\Controller;

class ListController
{

}

Recarregando a página agora vai finalmente entrar em uma nova tela. A nova mensagem de erro parecido com este:

A 404 error occurred
Page not found.
The requested controller was not dispatchable.

Controller:
Blog\Controller\List(resolves to invalid controller class or alias: Blog\Controller\List)

Additional information:
Zend\Mvc\Exception\InvalidControllerException

File:
{libraryPath}/Zend/Mvc/Controller/ControllerManager.php:{lineNumber}
Message:
Controller of type Blog\Controller\ListController is invalid; must implement Zend\Stdlib\DispatchableInterface

Isso acontece porque nosso controller deve ser despachado ou executado em ordem para implementar ZendStdlibDispatchableInterface, por camada MVC do ZendFramework. O ZendFramework providencia uma base de controller com a implementação de AbstractActionController, que vamos usar. Vamos modificar nosso controller de agora


<?php
// Filename: /module/Blog/src/Blog/Controller/ListController.php
namespace Blog\Controller;

use Zend\Mvc\Controller\AbstractActionController;

class ListController extends AbstractActionController
{
}

Está na hora de fazer outra atualização no site. Você irá ver agora um novo erro:

An error occurred
An error occurred during execution; please try again later.

Additional information:
Zend\View\Exception\RuntimeException

File:
{libraryPath}/library/Zend/View/Renderer/PhpRenderer.php:{lineNumber}
Message:
Zend\View\Renderer\PhpRenderer::render: Unable to render template “blog/list/index”; resolver could not resolve to a file

Agora a aplicação lhe diz que um arquivo de template de visão não pode ser renderizado, O que é de se esperar que nós não o criamos ainda. A aplicação está na espectativa de encontrar em /module/Blog/view/blog/list/index.phtml. Crie este arquivo e adicione algum conteúdo fictício a ele:


<!-- Filename: /module/Blog/view/blog/list/index.phtml -->
<h1>Blog\ListController::indexAction()</h1>

Antes de continuarmos, vamos rapidamente dar uma olhada onde colocamos este arquivo. Note que arquivos de visão são encontrados dentro do subdiretório /view, não em /src como eles não são arquivos de classe PHP, mas sim arquivos de template para renderização HTML. O caminho a seguir no entanto merece uma explicação, mas é bem simples. Primeiro temos o namespace em minúsculo.
Seguido pelo nome do controller em minúsculo e sem o prefixo “controller” e por último vem o nome da action que você está acessando, novamente sem o prefixo “action”. E tudo isto se parece com isto: /view/{namespace}/{controller}/{action}.phtml. Isto se tornou um padão da comunidade mas você pode alterar isto a qualquer hora.

No entanto apenas criando este arquivo não é suficiente e isso traz o assunto para o final desta parte do QuickStart. Nós precisamos fazer com que a aplicação saiba onde procurar os arquivos de view. Nos fazemos isto dentro do nosso arquivo de configuração module.config.php.


<?php
// Filename: /module/Blog/config/module.config.php
return array(
    'view_manager' => array(
        'template_path_stack' => array(
            __DIR__ . '/../view',
        ),
    ),
    'controllers' => array( /** Controller Configuration */),
    'router'      => array( /** Route Configuration */ )
);

A configuração acima informa ao aplicativo que a pasta /module/Blog/view tem arquivos de view que correspondem ao esquema padrão descrito acima.

Recarregue seu site agora. Finalmente estamos em um ponto onde vemos alguma coisa diferente de um erro sendo exibida na tela. Parabéns, não só por ter criado um módulo no estilo “Hello World”, mas você também aprendeu muito sobre mensagens de erro e suas causas. Se nós não cansamos você, continue com nosso QuickStart e vamos criar um módulo que realmente faça alguma coisa.

Introdução a Services e a ServiceManager >

Deixe uma resposta

Preencha os seus dados abaixo ou clique em um ícone para log in:

Logotipo do WordPress.com

Você está comentando utilizando sua conta WordPress.com. Sair / Alterar )

Imagem do Twitter

Você está comentando utilizando sua conta Twitter. Sair / Alterar )

Foto do Facebook

Você está comentando utilizando sua conta Facebook. Sair / Alterar )

Foto do Google+

Você está comentando utilizando sua conta Google+. Sair / Alterar )

Conectando a %s

%d blogueiros gostam disto: