sexta-feira, 17 de julho de 2015

Conceito 3 - Event Manager no Zend Framework 2

O terceiro e último conceito básico para um bom aproveitamento do zend framework 2 é o event manager.

O event manager é um gerenciador de eventos ou seja, é uma classe responsável por disparar um determinado método quando outro determinado método for chamado.

Exemplo 1:
Quando eu me logar no sistema eu quero que o seja gravado no banco de dados um log de acesso.
Quando o método logar for chamado eu disparo o evento log.

Exemplo 2:
Quando eu tentar acessar a área reservada do sistema quero que o login e senha sejam validados.
Quando o método logar for chamado eu disparo o evento validaAcesso.

Como fazer isso no Zend Framework 2?

Usando o exemplo 2, vamos fazer um teste no arquivo Module.php que fica na raiz da pasta do module. Existem várias formas de utilizar o event manager, abaixo vamos utilizar o getSharedManager().

public function init(ModuleManager $moduleManager) {
$sharedEvents = $moduleManager->getEventManager()->getSharedManager();
$sharedEvents->attach(
'Zend\Mvc\Controller\AbstractActionController', 
Zend\Mvc\MvcEvent::EVENT_DISPATCH,
array($this, 'validaAcesso'),
100
);
}

public function validaAcesso(){
        $sessionContainer = new Container('usuario_auth');
        if(!isset($sessionContainer->usuario_id) || $sessionContainer->usuario_id == 0){
            die('nao pode acessar');
        }        
}

Mais informações:

http://framework.zend.com/manual/current/en/modules/zend.event-manager.event-manager.html

http://framework.zend.com/manual/current/en/tutorials/tutorial.eventmanager.html

https://samsonasik.wordpress.com/2013/03/30/zend-framework-2-getting-closer-with-eventmanager/

quarta-feira, 8 de julho de 2015

Conceito 2 - Service Manager no Zend Framework 2

O segundo conceito básico para um bom aproveitamento do zend framework 2 é o service manager.

O service manager é uma classe que usamos para instanciar outras classes dentro de um módulo. O motivo disso é evitar o acoplamento (instanciar classes dentro de outras classes) pois quando o service manager instancia uma classe, ele guarda o registro dela na memória assim instanciando essa classe em toda aplicação somente uma vez.

Existem algumas formas de usar o service manager no zend framework 2, mas o modo básico é no arquivo Module.php localizado na root da pasta do seu módulo.

Iremos criar o método da seguinte forma:

public function getServiceConfig(){
return array(
'factories' => array(
'Usuario\Service\UsuarioService' => function(){
return new UsuarioService();
}
)
);
}

getServiceConfig => o método deve ter esse nome para ser reconhecido.
factories => iremos usar esse conceito, existem outros como por exemplo invokables.
Usuario\Service\UsuarioService => é o nome do nosso serviço. Por boas práticas é recomendável que o nome seja o caminho da classe para evitar duplicidades.

Como eu disse acima a principal função do service manager é evitar o acoplamento. Segue um exemplo dessa situação:

public function getServiceConfig(){
return array(
'factories' => array(
'Usuario\Service\UsuarioService' => function($serviceManager){
$entityManager = $serviceManager->get('Doctrine\ORM\EntityManager');
return new UsuarioService($entityManager);
}
)
);
}

$serviceManager => por padrão nosso método getServiceConfig recebe por parâmetro a instancia do serviceManager.
$serviceManager->get => com o método get nós localizamos e instanciamos uma classe do sistema.
UsuarioService($entityManager) => então podemos passar a instancia por parâmetro para nossa classe de serviços.

Na classe controller dentro de um módulo chamamos um serviço da seguinte forma:

public function insert(){
$usuarioService = $this->serviceLocator()->get('Usuario\Service\UsuarioService');
$usuarioService->insertData(array('usuario_nome'=>'Teste'));
}

$this->serviceLocator()->get() => é dessa forma que iremos localizar e instanciar qualquer serviço registrado no getServiceConfig().
$usuarioService => uma vez instanciado é só chamar um método que pertença a ele.

Na classe do serviço devemos nos atentar a um detalhe muito importante. Se passamos um parâmetro assim que instanciamos a classe no getServiceConfig esse parâmetro deve ser recuperado dentro do método mágico  __construct().

Segue um exemplo de uma classe service:

<?php

namespace Usuario\Service

use 'Doctrine\ORM\EntityManager';

class UsuarioService{

private $em;

public function __construct(EntityManager $entityManager){
$this->em = $entityManager;
}

public function insert(Array $data){
$obj = $this->arrayToObject($data);
$this->em->persist($obj);
return $this->em->flush();
}

EntityManager => recebemos a instancia da classe por parâmetro.
$this->em => criamos uma variável para guardar a instancia da classe e então podemos usa-la em qualquer método que desejamos.

Mais informações:

http://framework.zend.com/manual/current/en/modules/zend.service-manager.quick-start.html

terça-feira, 7 de julho de 2015

Conceito 1 - Rotas no Zend Framework 2

Na minha opinião o zend framework 2 possui três conceitos básicos para seu uso e aproveitamento. O primeiro conceito são as rotas.

As rotas são as responsáveis em acessar um controller e a action de um módulo e existem vários tipo de rotas, porém vamos nos focar em duas: Literal e Segment. O arquivo de configuração está localizado dentro de cada módulo na pasta config. O arquivo module.config.php é o responsável entre outras funções pela configuração das rotas.

return array(
    'router' => array(
        'routes' => array(
            'home' => array(
                'type' => 'Zend\Mvc\Router\Http\Literal',
                'options' => array(
                    'route'    => '/usuario',
                    'defaults' => array(
                        'controller' => 'Application\Controller\Index',
'action'     => 'index',
),
),
),

Segue abaixo uma explicação básica dos principais pontos da configuração da rota. Esses pontos são utilizados pra qualquer tipo de rota:

router => índice do array onde iremos configurar todas as rotas do módulo.
home => é o nome da rota geralmente usado quando vamos dar um redirect().
type =>  é literalmente o tipo da rota que vamos usar como literal, segment, etc
route => é o modo de como iremos acessar a rota pela url, por exemplo: /usuario. É importante lembrar que /usuario é diferente de /usuario/ para o zend framework 2, então temos que tomar muito cuidado com isso.
controller => é o nome da classe do controller do módulo que iremos instanciar por padrão, caso nenhum outro controller seja passado por parâmetro.
action => é o método do controller que queremos acessar por padrão, caso nenhuma outra action seja passada por parâmetro.

Rota Literal

'type' => 'Zend\Mvc\Router\Http\Literal'

É o tipo de rota mais simples. Ela não aceita parâmetros como por exemplo:


/usuario/alterar/10

Os únicos parâmetros permitidos são o controller (usuario) e a action (alterar).

Exemplo de configuração:

'router' => array(
     'routes' => array(
         'usuario-home' => array(
             'type' => '
Zend\Mvc\Router\Http\Literal',
             'options' => array(
                 'route'    => '/usuario',
                 'defaults' => array(
                     'controller' => 'Usuario\Controller\Usuario',
                     'action'     => 'selectAll',
                 ),
             ),
         )
     )
 )


Rota Segment

'type' => 'Zend\Mvc\Router\Http\Segment'

Talvez seja o tipo de rota mais utilizado, ao contrário da rota Literal, esta rota aceita parâmetros.

Exemplo de configuração:

'router' => array(
     'routes' => array(
         'usuario-edit' => array(
             'type' => 'segment', //também pode chamada assim
             'options' => array(
                 'route'    => '/usuario[/:action[/:id]]',
                 'defaults' => array(
                     'controller' => 'UsuarioController',
                     'action'     => 'edit'
                 ),
                 'constraints' => array(
                    'controller' => '[a-zA-Z][a-zA-Z0-9_-]*',
                    'action'     => '[a-zA-Z][a-zA-Z0-9_-]*',
                    'id' => '\d+'
                 ),
             ),
         )
     )
 )

route => neste exemplo o único parâmetro obrigatório é o controller. Tanto a action como o id são opcionais.
constraints => é a padronização de cada parâmetro que a rota pode receber.

OBS: O índice controller da rota é a referencia ao índice dos controllers invokables dentro do array controllers.

'controllers' => array(
        'invokables' => array(
            'UsuarioController' => 'Usuario\Controller\UsuarioController'
        ),

    ),

Por boas práticas e para evitar duplicidade no apelido do controller é recomendável que usamos o caminho do controller como apelidos como por exemplo:

Na rota:
'defaults' => array(     'controller' => 'Usuario\Controller\Usuario',

Nos controllers:
'invokables' => array(
     'Usuario\Controller\Usuario' => 'Usuario\Controller\UsuarioController',

Mais informações:

http://framework.zend.com/manual/current/en/in-depth-guide/understanding-routing.html

sexta-feira, 3 de julho de 2015

Estrutura do Módulo no Zend Framework 2

Ainda usando como base o Zend Skeleton Application, vamos entender como funciona a estrutura do módulo (module) no Zend Framework 2.

Segue abaixo a estrutura  e as regras básica de utilização de um Módulo:

/module
- NomeDoModulo
  - config
  - src
    - NomeDoModulo
      - Adapter
      - Entity
      - Form
      - Controller
      - Service
  - view
      - nomeDoModulo
        - error
        - layout
        - nomeDoController
          - nomeDoMetodoDoController.phtml
 Module.php

01 - Config
É neste diretório que encontramos o arquivo module.config.php, responsável por toda configuração do módulo. É nele que registramos as rotas de acesso, os controllers do módulos e etc

02 - Src
Neste diretório que iremos trabalhar a maior parte do tempo, é que aqui iremos criar nossas classes de Controllers, Services, Entities e etc.

03 - View
Todo front-end da aplicação fica centralizada nesse diretório. Aqui iremos criar nossas páginas de erro, nossos layouts e páginas de retorno do controllers. Vale lembrar que no Zend Framework todas as página de view devem ter a extenção .phtml caso contrário não serão localizadas.

04 - Module.php
Localizado na raiz no diretório os métodos dessa classe são responsáveis pelo carregamento de todas as classes do módulo. Nele podemos encontrar os métodos onBootstrap() (chamado sempre que o módulo for chamado) e o método init() (chamado sempre que o módulo for inicializado). Também é nessa classe que podemos definir outros métodos importantes como por exemplo o getServiceConfig().

Mais Informações:
http://framework.zend.com/manual/current/en/user-guide/modules.html

quinta-feira, 2 de julho de 2015

Estrutura Básica do Zend Framework 2

Usando como base o Zend Skeleton Application a estrutura básica é a seguinte:

PastaDoProjeto
- config
- data
- module
- public
- vendor
composer.phrar
composer.json
init_autoloader.php

Segue uma explicação básica sobre todos os diretórios e arquivos citados:

01 - Config: 
No diretório config encontramos a pasta autoload e o arquivo application.config.php. É neste arquivo que iremos registrar todos os módulos que criaremos para a aplicação se não registrar o nome do módulo aqui o framework não encontrará o mesmo.
Dentro da pasta autoload podemos encontrar alguns arquivos dentre ele o arquivo local.php.dist que deverá ser renomeado para local.php. Nele iremos registrar configurações locais como por exemplo os dados de acesso ao banco de dados. Em ambiente de produção deveremos criar um arquivo chamado global.php para as mesas finalidades. 

02 - Data:
Diretório para armazenar dados que serão usados pelo framework como por exemplo arquivos para controle de cache.

03 - Module:
Diretório para armazenamento dos módulos da aplicação. Quando instalado o Zend Skeleton Application é baixado o modulo "Application" como exemplo. Dentro podemos ver que existem as pastas config, src, language, view e o arquivo Module.php. Teremos um post especial para o diretório module onde iremos entender toda a arquitetura e utilidade da mesma.

04 - Public:
Diretório onde está localizado o index.php da framework, é esta pasta que devemos definir como root seja pelo VirtualHost, pelo servidor embutido do php e até quando fomos colocar nossa aplicação em ambiente de produção na nuvem.
Também é no diretório public que está localizado a estrutura de issets (css, images e js) do framework. Quando o Zend Skeleton Application é instalado junto com ele já é baixado o Twitter Bootstrap ficando ao nosso gosto usar-lo ou não.

05 - Vendor:
Diretório onde ficam armazenadas as classes/bibliotecas desenvolvidas por terceiros como por exemplo o Doctrine.

06 - Composer.phrar:
É neste arquivo que aplicamos os comando self-update, update, install via terminal para realizar modificações no framework.

07 - Composer.json:
É neste arquivo que devemos adicionar  ou remover as atualizações que queremos no framework. Como por exemplo a ZendTool, Z-Ray, Hounddog, etc

08 - Init_autoloader:
Arquivo responsável pelo carregamento dinâmico de todas as classes do framework.

quarta-feira, 1 de julho de 2015

Instalação do Zend Framework 2

Instalando o esqueleto da aplicação (ZendSkeletonApplication):

O Zend Skeleton Application é modo mais rápido e prático de instalarmos o Zend Framework 2.

A instalação do Zend Skeleton Application será feita via composer. Iremos fazer o download dos arquivos armazenados no github oficial do zend framework.

O Zend Skeleton Application é uma estrutura simples, é o ponto inicial da sua aplicação. Mesmo sendo enxuta com ela já podemos trabalharmos 100% com MVC e temos acesso a todos os principais recursos que o zend framework 2 possui.

Segue abaixo o passo-a-passo da instalação para ambientes Linux e Mac:

01 - Abra o terminal


02 - cd /var/html/www/
 
03 - git clone git://github.com/zendframework/ZendSkeletonApplication.git

04 - mv ZendSkeletonApplication/ zf2

05 - cd zf2

06 - php composer.phar self-update

07 - php composer.phar install (pode ser demorado)

08 - cd /public

09 - php -S localhost:8888 (servidor embutido desde a versão 5.4.0 do php)

Verificando se o zend framewoek foi instalado corretamente:


No browser

10 - http://localhost:8888


Mais informações: 

http://framework.zend.com/manual/current/en/user-guide/skeleton-application.html http://framework.zend.com/downloads/skeleton-app
https://github.com/zendframework/ZendSkeletonApplication
https://getcomposer.org/doc/00-intro.md