domingo, 25 de agosto de 2013

Esta é minha casa mesmo ? :: Tirando o 'public' da url no Zend Framework 2

Quem já já experimentou o Zend ( tanto o 1 quanto o 2 ) sabe que toda a festa rola na pasta 'public' da raiz de seu projeto, já que o 'index.php' fica lá.

Isso é uma situação muito chata, porque primeiramente, é feio aquele 'public' na url, e segundo porque é mais seguro manter o 'index.php' dentro da pasta 'public'.

eu já tinha ensinado aqui no Bar do Zend como se procede para tirar o 'public' no caso do ZF1,  então agora é a vez de fazer o mesmo no ZF2.

Para isso, tenha certeza que seu seu servidor web esteja configurado com o module 'rewrite'. Uma googlada por ai você pode achar a configuração certa para seu caso.

Certificando que o servidor está ok, criamos um arquivo '.htaccess' na raiz do projeto:


RewriteEngine On
RewriteBase /meuprojetozf2
RewriteCond %{REQUEST_FILENAME} -s [OR]
RewriteCond %{REQUEST_FILENAME} -l [OR]
RewriteCond %{REQUEST_FILENAME} -d
RewriteRule ^.*$ - [NC,L]
RewriteRule ^.*$ index.php [NC,L]

O endereço da raiz do projeto é aquele logo após seu domínio ( ex: http:///meusite.com/meuprojetozf2 ), ou após 'localhost' ( ex: http://localhost/meuprojetozf2 ) se estiver num servidor local. Caso o projeto esteja já na raiz do dominio, uma barra '/' já é suficiente.

Agora, criemos na raiz do projeto uma arquivo 'index.php' :

<?php
define('RUNNING_FROM_ROOT', true);
include 'public/index.php';

E pronto, pode acessar seu projeto e a sua url vai estar livre do 'public'.
Agora, um porém. Todos os arquivos que estão contidos na pasta 'public'  ( como os css, imagens e javascript ) deverão ser ter seus endereços acrecidos de 'public', pois para fins práticos, o aplicativo está rodando a partir da raiz, e não da pasta 'public'.

Então é isso, até a próxima.

domingo, 18 de agosto de 2013

Novas biritas : Introdução ao Zend Framework 2 - Parte 3 - 1 - Rotas, links e menus

Chegamos agora ao ponto onde você criou centenas de 'controllers' e outras dezenas de 'actions', e então faz-se necessário colocar tudo isso em menus ou links por ai.
Para conseguir organizar essa fauna de conteudos, o zf2 disponibiliza as 'routes' ( rotas em inglês, para quem não sabe ).
As 'routes' servem para fazer um mapeamento ou busca nas urls o caminho do conteudo desejado.

Para fazer uma rota, você precisa editar o arquivo do seu módulo 'module/Meumodulo/config/module.config.php' .

Dentro desse arquivo, você encontrara o array
return array(
    ...
    'router' =>array(
          'routes' => array(
                     ...
          ),
    ),
    ...
);

A variável 'router' é a variável que define o roteamento das páginas. Um modo de ficar mais simples de organizar esse array ( que pode ficar enorme conforme vai acrescentando coisas ),  é separar o array do router assim:

// Você declara e preenche a variável '$router' antes do 'return'
$router = array(
          'routes' => array(
                     ...
          ),
);

// E aqui o array de configuração do módulo
return array(
    ...
    'router' => $router,
    ...
);

Bom, sabendo da localização, vamos ver como usar isso. Primeiro temos de criar uma rota, que consiste na seguinte forma

$minharota= array(          
    'type' => 'Zend\Mvc\Router\Http\Literal',
    'options' => array(
        'route' => '/endereco/de/minha/rota',
        'defaults' => array(
            'controller' => 'Meumodulo\Controller\Meucontroller',
            'action'     => 'minhaaction',
        ),
    ),
);

Explicando:

type : define o tipo da rota. Aqui é o tipo 'Literal', que nada mais é que dizer explicitamente qual o módulo, controller e action do conteúdo.

route : esse é um alias, um endereço qualquer que você mesmo escolhe que deve ser digitado na url para acessar o conteúdo. Se você quiser que o conteúdo do action 'index' do controller 'index' do modulo 'application' apareça na url '/texto' ou '/esta/e/uma/url/estupidamente/grande' ,  basta colocar na variável route e digitar na url esses endereços bizarros que vai aparecer o conteúdo de '/application/index/index/'

defaults : aqui é definido o endereço REAL do conteúdo que deve ser acessado. Nas rotas literais, esse é o único endereço da rota, nas rotas do tipo 'segment' esse é um valor a ser chamado por padrão, isso será explicado daqui a pouco.

controller e action : bom, está claro o que são esses valores. Com ênfase na parte do controller, onde você precisa definir o módulo da qual o controller pertence.


Bom, assim que você cria sua rota, você adiciona aos 'routes'

$router = array(
    'routes' => array(
        'minharota1' => $minharota1,
        'minharota2' => $minharota2,
        ...
    ),
);

O nome 'minharota1' e a variável '$minharota1' e seguinte, não precisam ter o mesmo nome. Isso é uma padrão que eu adotei para facilitar a organização da configuração e melhor explicar nesse tutorial como funciona a coisa.
Na verdade você pode evitar essas variáveis e jogar como arrays puros diretamente na varável 'router' da configuração.

Uma coisa imprescindível é definir uma rota literal para sua página inicial do aplicativo.  Sim, bom do zendo que não precisa ser necessariamente o 'application\index\index' o endereço inicial, você pode definir uma route para a página inicial. No geral ela vem assim

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

e o que define a página inicial não é o nome 'home', mas sim a variável 'route' ser definida como '/' - o diretório raiz onde teremos

$router = array(
    'routes' => array(
        'home' => $home,
        'minharota1' => $minharota1,
        'minharota2' => $minharota2,
        ...
    ),
);

Agora, uma vez criadas as rotas e colocadas no config certo, você pode digitar os endereços definidos nas variáveis 'routes' para testar.

O tipo de rota literal é a mais simples, e boa para sites simples. Para sites um nível a mais de complexidade, os endereços são mais dinâmicos e envolve variáveis. Para isso existe a rota do tipo 'Segment'. 

O tipo 'Segment' segue a seguinte estrutura

$minharotasegment= array(          
    'type' => 'Zend\Mvc\Router\Http\Segment',
    'options' => array(
        'route' => '/algum/endereco[/:var]',
        'constraints' => array(
            'var' => '[a-zA-Z0-9_-]*', // Define o regexp de busca desejado
        ),
        'defaults' => array(
            'controller'    => 'Meumodule\Controller\Meucontroller',
            'action'        => 'meuaction',
            'var' => '123abc',
        ),
    ),
);

Aqui como podemos ver, temos uma mudança na variável 'route'. o termo '[:var]' define uma variável a ser digitada na url e tratada pelo zend no action 'meuaction' do controller 'Meucontroller' definido na variavel 'defaults'. Ainda em 'defaults', definimos um valor padrão para 'var' caso esse não tenha sido fornecido na url. Caso não precise de um valor padrão, basta apagar do 'defaults'.

Agora, para pegar o valor de 'var' da url, basta usar no controller definido no 'defaults' o helper

$var = $this->params('var');

Podemos definir varias variáveis no route

'route' => '/algum/endereco[/:var1[/:var2[/:var3]]]',

e basta declará-las em 'constraints' juntamente com o pattern desejado e no 'defaults' os valores padrões.

Ainda podemos fazer um mix de rota com variáveis

'route' => '/trecho1[/:var1[/trecho2[/:var2[/trecho3[/:var3]]]]]', 

e qualquer outra combinação que lhe venha a cabeça.
Para entender o essa route, só ver que tudo que estiver entre colchetes '[ ]' é considerado opcional, e tudo que vier depois do dois pontos ':' é o nome da variável. Portanto, não escreva nada atrás do nome da variável que não seja o colchete de fechamento ']'.

Também podemos ( e na maioria das vezes vamos ) usar variáveis pré-definidas no zend. Duas delas são o ':controller' e o ':action'. Numa rota seriam usados assim:

$minharotasegment=array(
    'type'    => 'Zend\Mvc\Router\Http\Segment',
    'options' => array(
        'route'    => '/endereco/segment/[:controller[/:action]]',
        'constraints' => array(
            'controller' => '[a-zA-Z][a-zA-Z0-9_-]*',
            'action'     => '[a-zA-Z][a-zA-Z0-9_-]*',
       	),
	'defaults' => array(
            'controller' => 'Meucontroller',
            'action'     => 'meuaction', 
        ),
    ),
);

onde vemos que podemos definir variáveis que chamem por um controller ou por um action na rota definida. Na verdade é isso que é feito por padrão no SkelettonApplication do Zend, ele define a rota da raiz '/[:controller[/:action]]' onde a sequência digitada é o controller e o action, como sempre foi no zend, apenas que agora as rotas dão liberdade para você definir o caminho como você precisar com mais poder. Não que não desse para fazer isso no ZF1, mas que enquanto no ZF1 isso era apenas uma regalia, agora no ZF2 é rotineiro.

Entremos na última parte sobre rotas nesse tutorial, as subrrotas. As subrotas são parecidas com as rotas segment, mas na verdade você pode considerá-las como um 'subconjunto' de uma rota pai que é segment ou literal. Uma subrota é definida assim:
$minhasubrrota=array(
    'type'    => 'Zend\Mvc\Router\Http\Literal',
    'options' => array(
        'route'    => '/endereco/da/subrrota',
        'constraints' => array(
            'controller' => 'Meumodulodasubrrota\Controller\Meucontrollerdasubrrota',
            'action'     => 'meuactiondasubrota',
       	),
    ),
);

enfim, você na verdade cria uma rota como qualquer outra, com a diferença que ela vai ser colocada aqui:

$minharota=array(
    'type' => 'Zend\Mvc\Router\Http\Literal',
    'options' => array(
        'route'    => '/application',
        'defaults' => array(
            '__NAMESPACE__' => 'Application\Controller',
            'controller'    => 'Index',
            'action'        => 'index',
        ),
    ),
    'may_terminate' => true,
    'child_routes' => array(
        'minhasubrota' => $minhasubrrota,
    ),
);

Como funciona isso ? Você simplesmente vai digitar na url '/endereco/da/rota' que vai aparecer o conteudo do controller e action no default, mas se voce digitar '/endereco/da/rota/endereco/da/surrota' vai aparecer o conteudo definido no controller e action do default da subrrota. A vantagem disso é que você pode colocar muitas subrrotas sob uma mesma rota:

$minharota=array(
    'type' => 'Zend\Mvc\Router\Http\Literal',
    'options' => array(
        'route'    => '/application',
        'defaults' => array(
            '__NAMESPACE__' => 'Application\Controller',
            'controller'    => 'Index',
            'action'        => 'index',
        ),
    ),
    'may_terminate' => true,
    'child_routes' => array(
        'minhasubrota1' => $minhasubrrota1,
        'minhasubrota2' => $minhasubrrota2,
        'minhasubrota3' => $minhasubrrota3,
        ...
    ),
);

de forma que cada rota vira um conjunto de subrrotas. Nos exemplos aqui em cima fizemos com rotas tipo 'Literal', mas tanto a rota quanto as subrrotas podem ser de qualquer tipo. E adiantando aqui, subrrotas são uma mão na roda na hora de criar submenus, se é que não foram feitas pensando nisso.

Bom, então, uma vez definidas as rotas , podemos localizar o conteudo de nosso aplicativo. Como a criação de rotas possuem várias possibilidades, crie uns 2 ou 3 controllers e uns 2 ou 3 actions em cada um deles e brinque criando suas rotas. No próximo parte dessa parte faremos uso de links, zf2 navigation e breadcrumbs.

Até lá.

segunda-feira, 25 de março de 2013

Novas biritas : Introdução ao Zend Framework 2 - Parte 2 - Criando seus controllers

Na parte 1 dessa série de tutoriais, mostrei como criar as actions e as views no controller padrão do módulo padrão do ZF2. Nesta segunda parte, vou ensinar como criar seus controllers.

A bem da verdade, é muito fácil.

  1. Na pasta 'module/Application/src/Application/Controller', crie seu controller com o nome que desejar. Aqui usaremos 'Meucontroller' e criaremos o arquivo 'MeucontrollerController.php'.

  2. Copie todo conteudo do arquivo 'IndexController.php' da mesma pasta. Apenas apague os actions que tem lá - que você pode ter feito a partir do tutorial anterior - deixando apenas o 'indexAction()'.

    Apague o conteudo do 'indexAction()' que agora você terá o mínimo que precisa para ter um controller funcional.

  3. Agora crie a pasta das views desse controller 'module/Application/view/application/user' e dentro dessa pasta crie o arquivo 'index.phtml', que é a 'view' do 'indexAction()' do controller 'Meucontroller'.

  4. E para finalizar, vamos rotear o controller para que ele funcione no módulo 'Application'

    Para isso, abre o arquivo de configuração do módulo 'module/Application/config/module.config.php'

    Dentro desse arquivo, encntre a sessão:

        'controllers' => array(
            'invokables' => array(
                'Application\Controller\Index' => 'Application\Controller\IndexController',
            ),
        ),
    

    e apenas acrescente a linha

        'controllers' => array(
            'invokables' => array(
                'Application\Controller\Index' => 'Application\Controller\IndexController',
                'Application\Controller\Meucontroller' => 'Application\Controller\MeucontrollerController'
            ),
        ),
    
  5. Acrescente algum conteudo na views 'index.phtml' de 'Meucontroller' e entre na url:

    http://localhost/meuprojeto/application/meucontroller/index

Se você viu seu conteudo do 'index.phtml' no navegador, então você fez tudo corretamente, e poderá fazer o mesmo processo para criar mais controllers, e junto com tutorial anterior, criar mais actions para cada um deles.

No próximo tutorial vamos tratar de rotas, links e navigation.

Até lá.

Novas biritas : Introdução ao Zend Framework 2 - Parte 1 - Instalação e zf2tool

Eis que agora temos a nova versão do Zend Framework - o ZF2.

Eu confesso que olhando o bicho, minha impressão é que ele é um pouco mais complicado de configurar que o ZF1, então tentei usar outro framework escolhido por motivos profissionais ( não vou falar qual é o concorrente, humft ! ).

Esse se mostrou tão mais complica do quanto o ZF2, então resolvi voltar ao velho framework.

As vantagens de se usar o ZF2 são as mesmas de sempre: padronização, modularização etc. Então, escolhido usar o ZF2, vamos trabalhar.

Para começar, devemos ter a mão o zf2tool. Para quem não sabe, o zf2tool é uma ferramenta de linha de comando que nos permite criar nosso projeto e seus componentes automaticamente usando a shell ao invés de criarmos cada coisinha a mão.

Baixe o zf2tool do endereço http://packages.zendframework.com/zftool.phar.

Salve esse arquivo 'zftool.phar' na sua pasta de executaveis do sistema, ou coloque numa pasta que esteja em seu PATH.

Agora, vamos trablhar com ele.

  1. Crie seu projeto ( aqui chamamos de 'meuprojeto' mesmo ):

    $ zf create project meuprojeto
    

    e assim será criado uma pasta de nome "meuprojeto " com o "esqueleto" do zf2.

  2. Se você percebeu, ao terminar o comando acima, foi mandado que você entre na pasta e execute o comando:

    $ composer.phar install
    

    Pois bem, faça isso.

    Caso você não tenha o composer instalado, baixe-o daqui http://getcomposer.org/.

  3. Se tudo deu certo, entre na url de seu projeto no navegador

    http://localhost/meuprojeto

    e se você ver a página de boas vindas do ZF2, então está tudo ok até agora.

  4. Aogra, para dar o gostinho de quero mais, vamos criar a coisa mais básica no zf2 : uma 'action'.

    Para isso, temos de ter em mente 3 arquivos:

    • module/Application/src/Application/Controller/IndexController.php
    • module/Application/view/application/index/index.phtml
    • module/Application/view/application/layout/layout.phtml

    Onde vemos aqui que o primeiro é o controller padrão da aplicação, na segunda linha temos a 'view' para o 'indexAction' e a terceira linha é o arquivo de layout do site.

    Você pode brincar a vontade com esses arquivos para ver como é a coisa.

  5. No controller 'IndexController.php', crie uma action com o nome que quiser ( aqui usaremos 'minhaaction' ):

    function minhaactionAction(){
        print "Alô mamãe !";
    }
    
  6. Agora, crie uma 'view' para 'minhaaction' na pasta 'module/Application/view/application/index' de nome 'minhaaction.phtml', e escreva algo dentro.
  7. Agora, no seu navegador, digite a url

    http://localhost/meuprojeto/application/index/minhaaction

    e se aparecer escrito "Alô, mamãe !", você acabou de criar sua action.

E pronto, agora você está apto a criar um site beeeem simples com o zf2, já que o processo de criação de mais 'actions' e mais 'views' segue o mesmo esquema.

Na parte 2 eu vou ensinar como criar seus controllers. Até lá.