Utilizar ZendAMF com Laravel 3

Bem, com meu histórico de amor e ódio com o Flex Framework (mais amor, diga-se), uma das primeiras tentativas de integração Laravel foi com o ZendAMF, implementação do protocolo AMF feita pela equipe Zend.

Foi necessário gastar um pouco de tempo com pesquisa, mas no final a integração foi tranquila. Uma das características do Laravel que o fazem ser tão bom é a facilidade de integração com bibliotecas externas. Sabendo disso, bastou iniciar a integração, entender os pulos-do-gato e correr para o abraço.

Segue o roteiro, passo a passo:

1) O primeiro foi imaginar onde eu poderia acomodar a biblioteca. A pasta /application/libraries seria uma boa escolha, porém, como o ZendAMF é um pouco complexo, com diversas classes e pastas, optei por criar um bundle. Adotei esta abordagem por dois motivos: sendo um bundle, as classes do ZendAMF ficariam a disposição do Laravel (e vice-versa) e o bundle possui o arquivo start.php, que é executado cada vez que o bundle é executado.

Item 1

Item 1

2) Uma vez que a library foi adicionada na pasta /bundles, é necessário informar ao Laravel que o bundle existe e precisa ser executado. Isso é feito no arquivo /application/bundles.php.

Item 2 - informar ao Laravel que o bundle precisa ser iniciado

Item 2 – informar ao Laravel que o bundle precisa ser iniciado

3) Agora, no arquivo start.php do bundle, adiciona-se a pasta library do ZendAMF ao class path do PHP. Isso é um tanto estranho, mas o ZendAMF é meio estúpido com includes. Melhor não brigar com gente estúpida. Utilizando a classe Autoloader do Laravel, adiciona-se os diretórios do Bundle que se precisa ter acesso pelo Laravel.

Item 3) Adiciona-se a pasta library ao class path do PHP

4) Agora é preciso criar uma URL para funcionar como gateway para chamadas a partir do Flex. Para simplificar as coisas, criei uma rota diretamente no arquivo application/routes.php, chamando-a de ‘/amf’ e ali no closure, criei uma instância do ZendAMF Server. Será ali também que abrirei acesso às classes que serão acessadas pelo Flex (VOs incluídos). É importante notar que a rota responderá a uma chamada POST, que é o verbo HTTP utilizado pelo RemoteObject do Flex. Para utilizar, basta colocar sua URL no RemoteObject do Flex. Ex.: endpoint=”http://<sua_url>/amf”.

Item 4) Cria-se a rota e nela o server AMF

Item 4) Cria-se a rota e nela o server AMF

5) Para manter nosso código organizado, criaremos nossas classes expostas ao Flex dentro de nosso bundle. Como estamos trabalhando com Laravel, todas as classes deste estão disponíveis para o bundle, sem que se precise fazer nada especial. No exemplo abaixo, foi utilizado um model chamado Produto, que estende Eloquent.

Item 5) A classe exposta ao Flex

6) Para finalizar (e este passo é opcional), é preciso adicionar à resposta que esta é do tipo AMF. Ter ou não esta informação não faz qualquer diferença ao Flex, porém, se você utiliza para debug uma ferramenta como Charles Proxy, este não exibe corretamente os dados caso o Content-Type não se passado como application/x-amf. Para isso, basta criar na rota ‘/amf’ um filtro do tipo after e ali determinar o Content-Type.

Item 6) Adiciona-se o Content-Type à resposta HTTP

Item 6) Adiciona-se o Content-Type à resposta HTTP

E é isso!

Vale lembrar que o mesmo procedimento pode ser utilizado para outros componentes do Zend Framework. Basta tentar!

Grande abraço,

Vedovelli

Laravel Framework: conditional assets

A big concern related to front end performance is the burden brought by javascript includes, which tend to be big in size. Fortunately there are techniques and best practices to minimize this issue. Loading javascript files (and why not CSS files…) during navigation can be a very good idea.

Laravel Framework has a class to manage assets that allows you, among other things, to load Javascript and CSS files only when needed. All you have to do is use asset containers. Add a new file to a container and it (the file) will be loaded when the route is called and the action is executed. Let’s take a look how it works from within a controller.

Let’s assume we have an asset container being registered and its assets being loaded in the layout file (layout.blade.php):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
< ?php
  // Register the files
  Asset::container('custom')->add('CustomJS', 'js/custom.js');
  Asset::container('custom')->add('CustomCSS', 'css/custom.css');
?>
< !doctype html>
<html lang="en">
<head>
	<meta charset="UTF-8"/>
	<title>Title</title>
        <!--dump assets to HTML-->
  	{{ Asset::container('custom')->styles() }}
	{{ Asset::container('custom')->scripts() }}
</head>
<body>
...
</body></html>

Now we have a javascript with instructions related to products only. We create a filter before in the controller:

1
2
3
4
5
6
7
8
9
10
11
12
13
class Product_Controller extends Base_Controller
{
    function __construct() 
    {
        parent::__contruct();
        // Aplicar o filtro apenas nestas actions
        $this->filter('before', 'addAssetsToProducts')->only( array('new', 'get') );     }
 
    public function action_new()
    {
    ...
}

And in the routes.php we add the filter behavior:

1
2
3
4
Route::filter('addAssetsToProducts', function()
{
    Asset::container("custom")->add("products", "js/products.js");});

When both actions new or get are executed, the file js/product.js (in this case stored in /public/js) will be inserted in our layout file and only for those actions.

Best!

Ved

Laravel Framework: assets condicionais

Uma das grandes preocupações de performance na interface do usuário é a carga trazida pelos includes Javascript, que tendem a ser grandes. Felizmente existem técnicas e boas práticas para minimizar o problema. Carregar arquivos javascript (e pq não folhas de estilos) durante a navegação pode se mostrar um coringa no seu desenvolvimento.

O Laravel Framework possui uma classe para gerenciar assets que lhe permite, entre outras coisas, carregar aquivos Javascript e CSS conforme se precisa deles. Basta utilizar o recurso de asset containers. Adicione um novo arquivo a um container e ele (o arquivo) será carregado quando o link da funcionalidade for requisitada. Vejamos como funciona a partir de um controller.

Supondo que se tenha um asset container sendo carregado no arquivo de layout (layout.blade.php) da aplicação:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
< ?php
  Asset::container('custom')->add('CustomJS', 'js/custom.js');
  Asset::container('custom')->add('CustomCSS', 'css/custom.css');
?>
< !doctype html>
<html lang="en">
<head>
	<meta charset="UTF-8"/>
	<title>Titulo</title>
  	{{ Asset::container('custom')->styles() }}
	{{ Asset::container('custom')->scripts() }}
</head>
<body>
...
</body></html>

Agora imagine que no controller produtos, se tenha um javascript cujo conteúdo seja relevantes apenas para a funcionalidade de produtos. Basta criar um filtro before no controller:

1
2
3
4
5
6
7
8
9
10
11
12
13
class Produtos_Controller extends Base_Controller
{
    function __construct() 
    {
        parent::__contruct();
        // Aplicar o filtro apenas nestas actions
        $this->filter('before', 'addAssetsToProducts')->only( array('new', 'get') );     }
 
    public function action_new()
    {
    ...
}

E no routes.php:

1
2
3
4
Route::filter('addAssetsToProducts', function()
{
    Asset::container("custom")->add("produtos", "js/produtos.js");});

Com isso, quando as actions new e get do controller produtos forem executadas, o javascript js/produtos.js (salvo em /public/js) será inserido no layout da aplicação e apenas para estas actions.

Grande abraço!

Ved

PHP Console: mais uma ferramenta para ajudar no desenvolvimento de apps

Eu frequentemente utilizo print_r() para ver o estado da informação naquele momento da execução, por diversos motivos. Quando se trata de uma API, recorro à gravação de arquivos texto no filesystem com a informação que preciso analisar (pense em chamadas AJAX que não podem ser quebradas). Certamente minha solução é um tanto mambembe e que, apesar de desconfortável, tem me atendido bem. Hoje me deparei com um serviço chamado PHP Console (http://phpconsole.com) que com um único include PHP lhe provê com diversos métodos que fazem o output dos seus dados no site do serviço. Achei uma boa proposta, pois você pode manter um histórico dos seus prints.

Já existe inclusive um package para Laravel 4: https://github.com/Prologue/Phpconsole/

Para entender bem, veja o curto video abaixo:

phpconsole – Getting Started from Support Phpconsole on Vimeo.

Screencast: Laravel e operações CRUD

Neste screencast serão abordadas as 4 operações básicas para o gerenciamento de informações e o armazenamento em banco de dados: Create, Read, Update and Delete, também conhecidas pela sigla CRUD.

Os recursos do framework utilizados durante o screencast foram:

  • Models e relacionamentos
  • ORM
  • Controllers
  • Templates
  • Filtros


Caso queira fazer o download do video, utilize este link: http://bit.ly/15vbgpW

Se encontrar alguma informação incorreta, por gentileza, me avise! vedovelli@gmail.com

Screencast: Laravel e o padrão MVC

Inicio este post agradecendo a todos pelo excelente feedback dado ao primeiro screencast (link) da série Laravel. Fiz tudo certinho, pois não apontaram nada! =D

Neste segundo vídeo, falo brevemente sobre o padrão de projeto MVC (Model, View, Controller) e sua implementação no Laravel.

Caso queira fazer o download do video, utilize este link: http://bit.ly/VqbmOC

Se encontrar alguma informação incorreta, por gentileza, me avise! vedovelli@gmail.com

E para quem está ansioso pela terceira parte, saiba que será sobre templates.

Cuecas (uma reflexão)

Na fila do caixa do Free Shop do aeroporto de GRU vi um rapaz comprando 3 pacotes de Marlboro, do vermelho. Imediatamente me veio ao pensamento uma única palavra, associada a meu passado: REFÉM.

Nicotina, pessoas, comida, álcool, comportamentos, sentimentos, cheque especial e rotina!

Quantas amarras mantive voluntariamente durante anos. E uma coisa corriqueira como a visão de um fumante se abastecendo conseguiu me lembrar do quanto mudei.

Hoje num almoço requintado, no qual servia-se bons vinhos e whisky de primeira qualidade, ao ser indagado o que beberia, não titubeei : “- Bebo água, de preferência com gás”. A possibilidade de eu ir à qualquer lugar e não encontrar água para beber é remota e atualmente é só o que preciso para ser feliz. E sem renegar nada. Sempre fiz questão de ser bêbado conhecido.

Diversão nas melhores capitais do sudeste brasileiro muitas vezes inclui shopping center e este possui a famigerada praça de alimentação, com seu McDonalds sempre lotado. Minha esposa aprendeu rapido: primeiro alimente a criatura para manter o mau humor na caverna. No caso, o meu humor. Já repararam em quanto comemos mais do que precisamos? E quanto dinheiro se gasta em restaurantes, sem qualquer controle de qualidade sobre o que se ingere. Quando analisei friamente fiquei assustado…. E tomei uma providência. Ainda não é hora de dizer o que fiz, mas que se registre que agi.

E com a mesma rapidez com que divaguei na fila do caixa, voltei a atenção para o que estava a fazer ali. Enquanto o moço estava garantindo mais um estoque de amarras, sorri imaginando o quanto minha vida está mais fácil, preocupado apenas em pagar pelas cuecas Calvin Klein que me dei de presente.

Esteja bem.