Vous êtes sur la page 1sur 120

Advanced Web Developer PHP e MySQL

www.4linux.com.br

-2

Sumrio
Captulo 1 Introduo......................................................................................................................................6 1.1. MVC: Model View Controller .......................................................................................7 1.2. Object Relational Map........................................................................................................9 1.3. AJAX: Asynchronous Javascript And XML.......................................................................10 1.4. Symfony: Framework de desenvolvimento em PHP.......................................................11 1.5. Eclipse: Integrated Development Environment..............................................................12 Captulo 2 Instalando o ambiente de desenvolvimento...............................................................................13 2.1. Gerenciando pacotes com o apt-get................................................................................13 2.2. Instalando servidores e aplicativos bsicos....................................................................14 2.3. Instalando a IDE Eclipse com o EasyEclipse..................................................................15 Captulo 3 Instalando o Symfony..................................................................................................................16 3.1. Configurando um domnio virtual para a aplicao........................................................16 3.2. Porque tudo to complicado?.......................................................................................18 Captulo 4 Criando uma aplicao rpida com o Symfony..........................................................................19 4.1. Preparando o banco de dados.........................................................................................20 4.2. Criando o projeto no Symfony.........................................................................................21 4.3. Criando uma aplicao....................................................................................................21 4.4. Lendo o banco de dados e criando classes de acesso....................................................22 4.5. Configurando o Doctrine para o scaffolding...................................................................23 4.6. Ajustando rtulo de chaves estrangeiras........................................................................25 4.7. Criando um menu para navegao..................................................................................27 4.8. Criando uma pgina inicial..............................................................................................30 Captulo 5 Entendendo o Symfony................................................................................................................32 5.1. Introduo terica............................................................................................................32 5.2. Estrutura de diretrios....................................................................................................32 5.3. O MVC do Symfony..........................................................................................................34 5.4. Camada Model..................................................................................................................35 5.5. Camada View....................................................................................................................35

-3
5.6. Camada Controller...........................................................................................................36 5.7. Aplicaes, Mdulos e Aes...........................................................................................37 5.8. Ambientes e Handlers......................................................................................................38 5.9. Configurando Ambientes.................................................................................................39 5.10. A URL no Symfony.........................................................................................................42 Captulo 6 Usando o EasyEclipse..................................................................................................................45 6.1. Introduo terica............................................................................................................45 6.2. Iniciando um projeto........................................................................................................45 6.3. Criando um projeto..........................................................................................................46 6.4. Viso Geral da ferramenta...............................................................................................46 6.5. Configuraes teis.........................................................................................................47 Captulo 7 Camada Controller: controlando as requisies e respostas.....................................................48 7.1. Aes (Actions)................................................................................................................49 7.2. Trmino da ao...............................................................................................................52 7.3. Redirecionamento............................................................................................................53 7.4. ilizando sesses de usurio..............................................................................................57 7.5. Atributos Flash variveis de sesso descartveis........................................................57 7.6. Repassando variveis para a View..................................................................................58 Captulo 8 Camada Model: acesso ao banco de dados................................................................................59 8.1. Introduo terica............................................................................................................59 8.2. Classes de Tabelas...........................................................................................................62 8.3. Acessando dados atravs do Model.................................................................................62 8.4. Utilizando critrios no Doctrine......................................................................................62 8.5. Mtodos personalizados...................................................................................................63
8.5.1. Mtodo especial __toString.....................................................................................................63

8.6. Sobrescrita de mtodos...................................................................................................64 Captulo 9 Camada View: Apresentao.......................................................................................................66 9.1. Introduo terica............................................................................................................66 9.2. A montagem da View.......................................................................................................66 9.3. Partials (Parciais).............................................................................................................69 9.4. Variveis do Symfony.......................................................................................................70 9.5. Helpers.............................................................................................................................71

-4
Captulo 10 Forms: criando formulrios.........................................................................................................73 10.1. Introduo terica..........................................................................................................74 10.2. Gerando formulrios automaticamente........................................................................74 10.3. Widgets...........................................................................................................................77 10.4. Validators.......................................................................................................................79 10.5. Labels.............................................................................................................................82 10.6. Controlando o formulrio...............................................................................................83 10.7. Exibindo o formulrio....................................................................................................87
10.7.1. Mtodo automatizado...........................................................................................................87 10.7.2. Mtodo detalhado.................................................................................................................90

Captulo 11 AJAX.............................................................................................................................................92 11.1. Introduo terica..........................................................................................................92 11.2. Incluindo Javascript.......................................................................................................93 11.3. Criando um link para uma funo.................................................................................94 11.4. Alterado o contedo de um elemento HTML................................................................94 11.5. Chamando uma funo remota......................................................................................95
11.5.1. Atualizaes Peridicas........................................................................................................98 11.5.2. Formulrios AJAX..................................................................................................................99 11.5.3. Callbacks.............................................................................................................................101

Apndices...................................................................................................................................103 Captulo 12 Apndice Banco de dados "livraria"..........................................................................................................104 Captulo 13 Apndice sfDoctrineGuard plugin.............................................................................................................111
13.1.1. Implementando segurana em sua aplicao....................................................................112 13.1.2. Administrando seus usurios, permisses e grupos..........................................................114 13.1.3. Personalizando os templates do mdulo sfGuardAuth......................................................114 13.1.4. Personalizando os templates do mdulo sfGuardAuth......................................................115 13.1.5. Classe sfGuardSecurityUser...............................................................................................115 13.1.6. Flag superadministrador....................................................................................................116 13.1.7. Validators (Validadores).....................................................................................................116 13.1.8. Personalizando o Model sfGuardUser................................................................................117 13.1.9. Checar a senha do usurio com um mtodo externo.........................................................118

-5
13.1.10. Alterar o algoritmo utilizado para armazenar senhas.....................................................119 13.1.11. Alterando o nome ou o perodo de expirao do cookie "Remember Me"......................119 13.1.12. Personalizando a manipulao de redirecionamento de sfGuardAuth...........................120 13.1.13. Configurando o formulrio de login.................................................................................120

Captulo 1 Introduo - 6

Captulo 1 Introduo

Objetivo do Curso Este curso de Advanced Web Developer PHP e MySQL - 444 - visa dar bases slidas ao aluno para a construo de sistemas Web modernos, robustos, seguros e fundamentados em tcnicas dedesenvolvimento atuais e produtivas. Cabe lembrar que este nao um curso de Webdesign no h preocupao com a apresentao visual (layout) das paginas criadas, e sim com sua funcionalidade. No obstante, os arquivos so criados obedecendo os padres da W3C (World Wide Web Consortium) em XHTML vlido ou muito prximo disso, possibilitando uma ampla liberdade de criao de padres visuais (templates) com o uso de folhas de estilo em cascata (CSS). Isto sem que a funcionalidade seja abalada em qualquer momento. O curso vai trabalhar com os seguintes conceitos, tecnologia, framework e IDE: MVC - Model-View-Controller ORM - Object-Relational Mapping

Captulo 1 Introduo - 7 AJAX - Asynchronous Javascript And XML Symfony - Framework de desenvolvimento em PHP Eclipse - Integrated Development Environment

1.1. MVC: Model View Controller


Model-View-Controller (MVC) um padro de arquitetura de software. Sua inteno facilitar o desenvolvimento e manuteno de cdigos em projetos de mdio e grande porte, separando os dados(Model) e o layout, apresentao (View) da lgica de interao com o usurio final. Deste modo facilita tambm o trabalho entre equipes mistas de DBA (administradores de Banco de Dados), programadores e webdesigners, no caso aplicaes web. Model: Lgica de acesso a dados. Esta camada encapsula em classes toda lgica de acesso a dados. Normalmente a persistncia de uma aplicao feita num banco de dados, mas a camada Model no obrigatoriamente especfica para banco de dados, ela se ocupa de manter consistente a interao com uma base de persistncia que normalmente um banco de dados. View: Lgica de Apresentao. Representa a parte a apresentao visual das informaes. E tambm onde o usurio interage com o sistema. Geralmente trata de apresentar os dados do Model. Controller: Lgica da aplicao. Recebe as aes do usurio, processa, valida dados e realiza operaes no Model. No sentido contrrio, devolve informaes a serem visualizadas atravs da View.

Captulo 1 Introduo - 8

Figura1.1 :Exemplo de Funcionamento do MVC

Captulo 1 Introduo - 9

1.2. Object Relational Map


ORM uma metodologia de acesso a banco de dados relacionais atravs de orientao a objeto. feito um mapeamento entre as tabelas do banco de dados e classes que a acessam de forma transparente os dados destas tabelas. Geralmente a utilizao do ORM implica alguma forma de varredura no banco de dados para reconstruir todas as tabelas e suas relaes em forma de classes. Uma vez realizada, a linguagem SQL praticamente eliminada da programao, apesar de ainda ser possvel na maioria dos casos. Desta forma a abstrao de base de dados (um cdigo, multiplos bancos de dados possveis) chega a um nvel bastante elevado. O Symfony em sua verso 1.4 utiliza o Doctrine (http://www.doctrineproject.org) como ORM principal, que um projeto baseado no Hibernate do Java, mas ainda dispe a opo de utilizar o Propel como ORM (http://propel.phpdb.org).

Captulo 1 Introduo - 10

1.3. AJAX: Asynchronous Javascript And XML


AJAX (Asynchronous Javascript And XML) uma metodologia de uso de HTML ou XHTML, Cascading Style Sheets, Javascript, Document Object Model, XML, XSLT e o objeto XMLHttpRequest, providas por navegadores, para tornar pginas mais interativas com o usurio, utilizando-se de solicitaes assncronas de informaes. O AJAX no um modelo, no uma tecnologia, mas um conjunto de tecnologias que juntas criam para aplicativos web um novo padro de usabilidade, muitas vezes semelhante a aplicativos desktop. Curiosamente o AJAX nasceu de uma violao de padres que a Microsoft costuma fazer em seus produtos. Em 1998 ela introduziu uma biblioteca que permitia fazer consultas usando o protocolo HTTP de maneira autnoma e assncrona ( XMLHttpRequest). Inicialmente no houve utilidade para este recurso, que ficou um pouco esquecido. Tempos depois que se percebeu que em conjunto com outras tecnologias podia prover uma experincia mais rica ao usurio Web. Inicialmente o AJAX era implementado na mo grande, com dificuldades para ser executado em vrios navegadores. Atualmente existem vrios frameworks que so utilizados em conjunto com linguagens de programao no lado do servidor, como jQuery, Prototype, Dojo, Mootools, ExtJs. O Symfony possui plugins para alguns deles.

Captulo 1 Introduo - 11

1.4. Symfony: Framework de desenvolvimento em PHP


um conjunto de classes que cooperam entre si, fornecendo solues integradas para problemas comuns no desenvolvimento de software. As linguagens de programao utilizadas simplesmente com seus recursos bsicos no fornecem capacidade de soluo imediata de diversos problemas corriqueiros de programao aplicaes multibanco, telas bsicas de CRUD ( Create, Retrieve, Update, Delete), etc. O uso de solues avulsas rapidamente cria uma colcha de retalhos, e o framework se prope a resolver isto. Um framework necessita das seguintes caractersticas: Reutilizao: possibilidade de reuso de componente. Extensibilidade: possibilidade de ampliar recursos. Segurana: confiabilidade de execuo e implementao Completude: atender todas as necessidades dentro de um escopo de atuao. Um framework no precisa reinventar a roda, ainda mais se tratando de software livre. muito mais interessante atuar com uma cola que junta tecnologias j sedimentadas e as reune sob ma metodologia unificada de trabalho. Symfony um framework web escrito em PHP5 que segue o paradigma MVC. Tem como objetivo acelerar a criao e manuteno de aplicaes web. Utiliza-se de vrias tecnologias sedimentadas em sua base ( como os ORMs Doctrine e Propel, entre outras), extrai muitas de suas ideias do consagrado framework Ruby-On-Rails. Alm de ser um dos mais robustos, eficientes e documentados frameworks em PHP da atualidade, conta com um desenvolvimento e comunidade muito ativos. Poderia-se dizer que juntamente com o CakePHP e o ZendFramework so os trs mais influentes frameworks em PHP no momento.

Captulo 1 Introduo - 12

1.5. Eclipse: Integrated Development Environment


Eclipse uma IDE de cdigo aberto para o desenvolvimento de softwares. O projeto Eclipse foi patrocinado pela IBM que desenvolveu a primeira verso do produto e doou-o como software livre para a comunidade. Hoje o Eclipse a IDE Java mais utilizada no mundo. Entretanto, o Eclipse uma IDE altamente customizvel e expansvel. Assim no s aplicativos Java podem ser desenvolvidos utilizando o Eclipse, mas diversas outras linguagens. O PHP possui atualmente dois plugins livres para o Eclipse ( PHPEclipse e PDT), alm da verso do consagrado Zend Studio( a Zend a empresa que coordena o projeto PHP, fundada por dois de seus principais desenvolvedores).

Captulo 2 Instalando o ambiente de desenvolvimento - 13

Captulo 2 Instalando o ambiente de desenvolvimento

2.1. Gerenciando pacotes com o apt-get


Nosso curso ser realizado numa plataforma GNU/Linux utilizando a distribuio Debian 5 ( Lenny).O gerenciador de pacotes a ser utilizado o apt-get. Para o utilizarmos, precisamos inicialmente configurar os repositrios no arquivo /etc/apt/sources.list. No nosso caso, para agilizar a instalao e evitar o trfego intenso para o link externo, usaremos um repositrio interno. 1. Configurando as fontes 1. Logamos como root su root 2. Entramos no editor VIM vim /etc/apt/sources.list 3. Adicionamos as seguintes linhas no arquivo deb http://192.168.1.1/debian lenny main contrib non-free deb http://packages.dotdeb.org lenny all 4. Agora atualizaremos a base de dados local apt-get update

Captulo 2 Instalando o ambiente de desenvolvimento - 14

2.2. Instalando servidores e aplicativos bsicos

1.

Instalando o servidor web Apache2

# apt-get install apache2

2.

Instalando o PHP 5

# apt-get install php5 php5-cli

3.

Instalando o SGDB MySQL

# apt-get install mysql-server

4.

Instalando o suporte XSL no PHP 5

# apt-get install php5-xsl

5.

Instalando um gerenciador Web para o MySQL

# apt-get install phpmyadmin

6.

Reiniciando o servidor web

# /etc/init.d/apache2 restart

Captulo 2 Instalando o ambiente de desenvolvimento - 15 2.3. Instalando a IDE Eclipse com o EasyEclipse O Eclipse tem vrias formas de instalao: download direto, instalao via pacotes, etc. A forma mais simples de ter um ambiente rapidamente configurado e ainda poder levar aonde se quiser, fazer uso dos pacotes pr-configurados do EasyEclipse, encontrados em: http://www.easyeclipse.org A grande vantagem que os pacotes vem prontos, com a verso do Java necessria e um conjunto de plugins afins de cada linguagem de programao. Ele no muda o Eclipse, apenas o distribui com diferentes conjuntos de plugins. 1.Baixando o EasyEclipse Acesse: http://www.easyeclipse.org/site/distributions/php.html E realize o download conforme o sistema operacional desejado (em nosso caso, verso Linux). 2.Instalando o EasyEclipse O EasyEclipse um pacote compactado pronto. Basta descompactar num diretrio e rodar o executvel. Para facilitar, vamos criar um atalho para seu acesso (chamado no Gnome de Lanador). cd /opt Tar -xvzf /home/aluno/Downloads/easyeclipse-php-1.2.2.2.tar.gz

Para criar o atalho/lanador, clique com o boto direto na rea de Trabalho e selecione Criar Lanador.

Captulo 3 Instalando o Symfony - 16

Captulo 3 Instalando o Symfony

O mtodo utilizado ser a instalao via php-pear, que nos permite economizar espao e facilita atualizaes do Symfony alm de backups das aplicaes. 1. Atualizando canal do Symfony no PEAR pear channel-discover pear.symfony-project.com 2. Instalando o Symfony atravs do PEAR pear install symfony/symfony-1.4.4

3.1. Configurando um domnio virtual para a aplicao


Primeiro vamos criar um domnio virtal no Apache criando o arquivo: /etc/apache2/sites-available/livraria444 Estre arquivo ter o seguinte contedo (o arquivo est comentado para melhor entendimento) <VirtualHost *> # Nome do domnio virtual ServerName livraria.local # Diretrio dos arquivos do domnio virtual DocumentRoot /home/aluno/livraria444/web # Padro do ndice de diretrio (apenas o index.php)

Captulo 3 Instalando o Symfony - 17 DirectoryIndex index.php # Permisses do diretrio dos arquivos <Directory /home/aluno/livraria444/web/> AllowOverride All Allow from All </Directory> </VirtualHost> Agora ativamos o domnio virtual com o comando a2ensite livraria444 O Symfony faz uso do mdulo rewrite do Apache para criar URLs amigveis (endereos sem .php, ponto de interrogao ou E Comercial). Para ativ-lo, faz-se uso do comando: a2enmod rewrite Agora podemos recarregar o Apache para que estas alteraes tenham efeito: /etc/init.d/apache2 reload Feito isso, vamos criar a estrutura de diretrios padro do nosso aplicativo: mkdir /home/aluno/livraria444 mkdir /home/aluno/livraria444/web Para que seja possvel a navegao, precisamos ajustar nosso arquivo hosts: echo 127.0.0.1 livraria.local>>/etc/hosts

Para testar nosso novo endereo podemos acessar a URL: http://livraria.local

Captulo 3 Instalando o Symfony - 18

3.2. Porque tudo to complicado?


A instalao do Symfony detalhada porque se destina a aplicaes PROFISSIONAIS, que iro rodar em ambientes empresariais, websites de mdio e grande porte. Todos os passos garantem a segurana, portabilidade e facilidade na criao de aplicaes. Outras formas de instalao inclusive pelo cdigo fonte ou no Windows podem ser encontradas no site do Symfony: http://www.symfony-project.org

Captulo 3 Instalando o Symfony - 19

Captulo 4 Criando uma aplicao rpida com o Symfony

Uma das capacidades de um framework a possibilidade de criao de aplicaes rapidamente, em especial com integrao com o banco de dados. Sistemas que interagem com banco de dados possuem uma caracterstica interessante: a maioria das tabelas acessada para quatro operaes bsicas: Criar um registro na tabela Recuperar um registro (ou vrios) da tabela Atualizar um registro da tabela Excluir um registro da tabela

Estas operaes so conhecidas pela sigla em ingls CRUD: Create, Retrieve, Update, Delete. A grande maioria dos frameworks permite criar telas automaticamente para

Captulo 4 Criando uma aplicao rpida com o Symfony - 20 utilizao destas operaes. O Symfony no diferente, e sem a necessidade de nenhuma linha de programao possvel criar um mdulo para navegar em todas as tabelas de um banco de dados.

4.1. Preparando o banco de dados


No curso PHP & MySQL Essentials (412), utilizado o exemplo de uma livraria virtual. Neste curso usaremos o mesmo exemplo, mas de modo mais avanado. Entretanto, haver uma diferena: usaremos a integridade referencial (chaves estrangeiras) na modelagem do banco, pois o Symfony trata inteligentemente as relaes entre as tabelas. 1. Criando o banco de dados mysql -u root -p < livraria444.sql 2. Criando um usurio com permisses de acesso grant select, insert, update, delete on livraria444.* to

livraria444@localhost identified by 'senha444';

Captulo 4 Criando uma aplicao rpida com o Symfony - 21

4.2. Criando o projeto no Symfony


Conforme o mtodo utilizado na instalao (PEAR ou outros) a forma de criao de um projeto ser levemente diferente. Para criarmos o projeto, devemos digitar os comandos: cd /home/aluno/livraria444 symfony generate:project livraria444 Agora podemos comear a criar nossa aplicao, inicialmente do lado administrativo com CRUD para todas as tabelas. Todos os comandos sero executados no diretrio do

projero(/home/aluno/livraria444)

4.3. Criando uma aplicao


A aplicao criada receber o nome de admin symfony generate:app admin A tarefa generate:app cria uma aplicao dentro do projeto A opo escaping-strategy=on proteje a aplicao contra ataques XSS( Cross-site scripting) e pode ser adicionada antes do nome da aplicao

Captulo 4 Criando uma aplicao rpida com o Symfony - 22 A opo csrf-secret=SenhaQualquer proteje a aplicao contra ataques de CSRF (Cross-site request forgery) e pode ser adicionada antes do nome da aplicao admin o nome da aplicao criada

Informaes sobre estes tipos de ataques a sites web: http://pt.wikipedia.org/wiki/Cross-site_scripting http://en.wikipedia.org/wiki/CSRF J possvel acessar o projeto atravs do endereo: http://livraria.local O ambiente de desenvolvimento fica disponvel em: http://livraria.local/admin_dev.php Veja a barra de debug que aparece no canto superior direito.

4.4. Lendo o banco de dados e criando classes de acesso


Em aplicativos MVC (Model-View-Controler: termo explicado detalhadamente mais adiante), existe um recurso chamado scaffolding, que consiste em ler o contedo de um banco de dados e criar classes de acesso a ele, e tambm criar um aplicativo de backend (retaguarda ou administrativo) contendo o acesso bsico tabela o CRUD, j comentado. O Symfony dispe de recursos para realizar o scaffolding de modo muito mais simples, mas preciso seguir os passos adequadamente. Quem realiza esse trabalho o Doctrine, uma camada de ORM (Object-Relational Mapping: tambm explicado mais adiante) que incorporada ao Symfony.

Captulo 4 Criando uma aplicao rpida com o Symfony - 23

4.5. Configurando o Doctrine para o scaffolding


Vamos editar o arquivo databases.yml afim de configurar o acesso ao banco. vim /var/www/livraria444/config/databases.yml

Em arquivos yml, a identao feita atravs de espao e no backspace

all: doctrine: class: sfDoctrineDatabase param: dsn: mysql:host=localhost;dbname=livraria444 username: livraria444 password: senha444

O Doctrine utiliza um arquivo XML para criar as classes de acesso a dados. Para facilitar nosso trabalho, o Symfony cria este arquivo a partir do banco de dados com o comando a seguir: symfony doctrine:build-schema Model so classes de acesso a dados. O Symfony cria as classes para todas as tabelas no banco de dados incluindo relacionamentos atravs do comando: symfony doctrine:build-model

Os Models ficam disponveis no diretrio lib/model/doctrine

Captulo 4 Criando uma aplicao rpida com o Symfony - 24 O Symfony tambm cria as classes de formulrios para todas as tabelas do banco de dados. Isto facilita a criao de formulrios com validao, mensagens de erro, etc. Para criar os formulrios com o Symfony, usamos o comando: symfony doctrine:build-forms

Os formulrios ficam disponveis em lib/form/doctrine Os mdulos seriam equivalentes, a grosso modo, a arquivos .php que recebem parmetros e realizaes baseadas neles. Os mdulos so criados dentro de uma aplicao, e so diretrios dentro do diretrio da aplicao. Como o Symfony trabalha com MVC, e o Model j foi criado, no mdulo ficam o Controller (action) e a View (templates). Para gerar um mdulo, fazemos uso do cdigo abaixo: symfony doctrine:generate-module admin categoria Categoria Onde: admin: a aplicao, residente em apps/admin categoria: o nome do mdulo a ser criado, em

apps/admin/modules/categoria Categoria: o nome do Model, em lib/model/doctrine

importante perceber que o nome do Model tem a inicial maiscula, como foi gerado pelo Symfony. Uma vez que o comando termine, j possvel navegar na tabela categoria dentro do Symfony atravs da url: http://livraria.local/categoria

Captulo 4 Criando uma aplicao rpida com o Symfony - 25 Tambm possvel navegar em modo de desenvolvimento (debug): http://livraria.local/admin_dev.php/categoria Pode-se criar os mdulos para cada tabela do banco de dados que seja necessria symfony doctrine:generate-module admin cliente Cliente symfony doctrine:generate-module admin livro Livro symfony doctrine:generate-module admin pedido Pedido symfony doctrine:generate-module admin pedidoitem Pedidoitem symfony doctrine:generate-module admin usuario Usuario E tambm podemos navegar nestas tabelas pelos respectivos links: http://livraria.local/admin_dev.php/cliente http://livraria.local/admin_dev.php/livro http://livraria.local/admin_dev.php/pedido http://livraria.local/admin_dev.php/pedidoitem http://livraria.local/admin_dev.php/usuario

4.6. Ajustando rtulo de chaves estrangeiras


At agora no alteramos um nico arquivo em PHP. Mas, para que os formulrios que representam tabelas que possuem chaves estrangeiras (por exemplo, pedido que tem vnculo com a tabela cliente) preciso especificar que campo da tabela estrangeira que ser rtulo nos comboboxes. Nas novas verses do Symfony, fazendo uso do Doctrine, o Symfony nos cria os formulrios com os combox de chave estrangeira automaticamente, porm podemos nos defrontar com outras verses que no nos oferecem isso, por isso vamos ver como setar manualmente afim de ter conhecimentos em verses que no nos oferecem isso.

Captulo 4 Criando uma aplicao rpida com o Symfony - 26 Por exemplo, para a tabela cliente temos: lib/model/doctrine/base/BaseCliente.class.php lib/model/doctrine/Cliente.class.php As tabelas que possuem este tipo de relacionamento so: O primeiro arquivo no deve ser alterado, pois numa atualizao do Model ser sobrescrito. Toda a nossa personalizao ser realizada no segundo, que uma classe extendida da primeira. Para preencher os rtulos dos comboboxes criamos um mtodo __toString que retorna um dos campos da tabela. Neste momento apenas criaremos mecanicamente; mas adiante entenderemos como so feitas as chamadas aos campos. categoria (estrangeira para livro) cliente (estrangeira para pedido) pedido (estrangeira para pedidoitem)

Ento vamos alterar estes arquivos como segue: <?php // lib/model/doctrine/Categoria.class.php class Categoria extends BaseCategoria { public function __toString() { return $this->getNome(); } }

<?php

Captulo 4 Criando uma aplicao rpida com o Symfony - 27 // lib/model/doctrine/Cliente.class.php class Cliente extends BaseCliente { public function __toString() { return $this->getNome(); } }

<?php // lib/model/doctrine/Pedido.class.php class Pedido extends BasePedido { public function __toString() { return $this->getStatus(); } } Apesar de no ser perfeito ainda ( o formulrio para tabela livro no exibe o ISBN, mas corrigiremos isso mais adiante), nos falta apenas um menu para navegar nestas tabelas.

4.7. Criando um menu para navegao


Vamos alterar o template padro do mdulo para incluir um menu para todas as pginas do projeto. O arquivo que possui o layout bsico que utilizado por todos os arquivos do mdulo est em: apps/admin/templates/layout.php

Captulo 4 Criando uma aplicao rpida com o Symfony - 28 O arquivo possui o cabealho e rodap da pgina, e inclui o contedo gerado pelos templates de cada mdulo da aplicao. Ele criado em HTML com os trechos em PHP includos, pois faz parte da View do MVC. <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en"> <head> <?php include_http_metas() ?> <?php include_metas() ?> <?php include_title() ?> <link rel="shortcut icon" href="/favicon.ico" /> <?php include_stylesheets() ?> <?php include_javascripts() ?> </head> <body> <?php echo $sf_content ?> </body> </html>

Captulo 4 Criando uma aplicao rpida com o Symfony - 29 Para criarmos um menu modificamos seu cdigo como segue: <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en"> <head> <?php include_http_metas() ?> <?php include_metas() ?> <?php include_title() ?> <link rel="shortcut icon" href="/favicon.ico" /> <?php include_stylesheets() ?> <?php include_javascripts() ?> </head> <body> <div id=menu> <a href=<?php echo url_for('categoria/index');?>>Categoria</a> <a href=<?php echo url_for('cliente/index');?>>Cliente</a> <a href=<?php echo url_for('livro/index');?>>Livro</a> <a href=<?php echo url_for('pedido/index');?>>Pedido</a> <a href=<?php echo url_for('pedidoitem/index');?>>Pedido Item</a> <a href=<?php echo url_for('usuario/index');?>>Usu&aacute;rio</a> </div> <?php echo $sf_content ?> </body> </html> A funo url_for cria os links no formato do Symfony para o par mdulo/ao. Mais tarde, compreendendo melhor as aes, ficar mais clara sua utilizao. No momento, sabemos que ela criar de forma organizada, respeitando inclusive o ambiente (de produo ou de desenvolvimento).

Captulo 4 Criando uma aplicao rpida com o Symfony - 30

4.8. Criando uma pgina inicial

Nos falta uma index para carregarmos automaticamente. Para no misturarmos com os mdulos criados para cada tabela, criaremos um mdulo sem vnculo com tabela nenhuma, chamado index. symfony generate:module admin index Se navegamos agora para: Http://livraria.local/index Veremos a pgina padro do Symfony para novos mdulos criados. Isto facilmente alterado, como esta prpria pgina explica, retirando o forward (redirecionamento) que feito na ao padro deste novo mdulo, no arquivo: <?php // apps/modules/index/actions/action.class.php class indexActions extends sfActions { public function executeIndex(sfWeRequest $request) { } } Qualquer contedo que queiramos colocar nele, alm do menu que j estar como padro da aplicao, s alterar em seu template que se encontra em: apps/admin/modules/index/templates/indexSuccess.php Ele est criado vazio. Podemos alter-lo para: <h1>Bem vindo Livraria do TUX</h1> <h2>Utilize o menu para navegar</h2>

Captulo 4 Criando uma aplicao rpida com o Symfony - 31

Mas para ele tornar-se padro preciso alterar o arquivo de configurao do mdulo e direcionar para o par (modulo/ao) desde mdulo criado. apps/admin/config/routing.yml

#default rules homepage: url: / param: { module: index, action: index } default_index: url: /:module param: { action: index } default: url: /:module/:action/* Foi alterado em homepage, param, module de default (mdulo padro do Symfony) para index (mdulo recm-criado). Neste momento descobrimos uma funcionalidade do Symfony que nos atrapalha neste momento: o Cache. Todos os arquivos de configurao, para maior velocidade, so verificados em sua primeira utilizao e ento o Symfony cria arquivos otimizados em Cache. Isto excelente, mas quando alteramos um arquivo de configurao ou mudamos a localizao de algum arquivo de classe ele no encontrado enquanto no zeramos o cache. Isto feito com o comando: symfony cc Agora podemos acessar a pgina index diretamente: http://livraria.local Podemos tambm acessar o modo de desenvolvimento e debug: http://livraria.local/admin_dev.php

Captulo 5 Entendendo o Symfony - 32

Captulo 5 Entendendo o Symfony

5.1. Introduo terica


Para melhor entendimento de como o framework funciona, precisamos conhecer a fundo as entranhas do mesmo. Neste captulo, iremos ver desde a organizo dos arquivos at conceitos de MVC.

5.2. Estrutura de diretrios


Ao criar um projeto, o Symfony cria a seguinte estrutura de arquivos: livraria444-> apps-> cache-> config-> data-> doc-> lib-> log-> plugins-> test-> web->

Nos diretrios que vimos, podemos encontrar:

Captulo 5 Entendendo o Symfony - 33 apps: Cada aplicao corresponde a um diretrio dentro de apps; cache: Cache criado pelo Symfony, para otimizao de desempenho; config: Arquivos de configurao global do projeto; data: Diretrio com dados que podem ser importados no banco de dados, ou outras formas de dados variveis que sero gravados (por exemplo, um banco de dados SQLite); doc: Reservado para documentao do projeto; lib: Localizao de Models, Forms e no caso do SandBox, as bibliotecas do Symfony; log: Registro de atividades do projeto. til para debug e rastreio; plugins: Reservado para plugins que expandem as funcionalidades do Symfony; test: Diretrio de testes personalizados; web: Pasta pblica que contm arquivos acessados via navegador. Especialmente aqui esto imagens, css, javascript alm dos arquivos pblicos do prprio Symfony;

Captulo 5 Entendendo o Symfony - 34

5.3. O MVC do Symfony

A implementao do MVC do Symfony utiliza-se de vrios arquivos, o que inicialmente pode parecer confuso: Camada Model: Abstrao de Banco de Dados (Database abstraction) Acesso a Dados (Data access) Camada View: Layout Lgica de Apresentao Template Camada Controller: Controle Frontal (Front controller) Ao (Action)

Entretanto, na prtica, com o uso dos geradores de cdigo (em especial as opes dos comandos symfony doctrine:? ) a maioria desses arquivos j fica disposio do desenvolvedor, seja de forma permanente, seja como base para personalizaes.

Captulo 5 Entendendo o Symfony - 35

5.4. Camada Model


Fica localizada no diretrio lib/model. A abstrao de Banco de Dados realizada de forma transparente, mediante unicamente a configurao de acesso ( como visto no captulo Criando uma aplicao rpida com o Symfony). So criados basicamente trs tipos de arquivos: mapeamento: Utilizada internamente pelo ORM. No acessada diretamente pelo desenvolvedor. Classes das tabelas: Para instncia de objetos representando registros da tabela e seus relacionamentos.

Os arquivos criados pelo Symfony atravs dos comandos symfony doctrine:? Sero guardados dentro de lib/model/map e lib/model/om. So classes abstratas (no caso de classes de tabelas) que servem de base para as classes extendidas que se encontram em lib/model. Estas sim so classes disponveis ao desenvolvedor, e onde pode-se incluir novos mtodos conforme sua necessidade. Esta estrutura permite que o Symfony recrie os arquivos base sem afetar as personalizaes do desenvolvedor.

5.5. Camada View


Primeiro, preciso compreender o termo template: um modelo de cdigo para apresentao. No caso do Symfony, geralmente criado em XHTML, com trechos de PHP para incluso de informaes dinmicas. Layouts so templates globais para cada aplicao, representando a apresentao final das pginas. Ficam armazenados no diretrio apps/aplicao/templates, sendo que o apps/aplicao/templates/layout.php comum (e necessrio) que o layout padro inclua o cdigo dos templates gerados em cada ao de um mdulo. Entretanto, para organizao ou retulizao, podem ser criados layouts parciais (partials) a serem includos em determinados padro a utilizao do arquivo

Captulo 5 Entendendo o Symfony - 36 locais de layouts e templates. No Symfony, o termo templates referncia a arquivos chamados por aes do mdulo para compor o corpo da pgina. O layout geralmente os inclui em seu corpo. Localizam-se nos diretrios dos mdulos, pe no formato templates apps/aplicao/modules/modulo/templates. parciais (partials). A Lgica de Apresentao consiste na montagem desde quebra cabeas que resulta na pgina final exibida para o usurio. Isto envolve processos automatizados do Symfony mas tambm personalizaes que o desenvolvedor queira fazer diretamente no cdigo dos templates e layouts. Os arquivos de templates e layouts so arquivos em XHTML (por padro, mas fica a cargo da necessidade do desenvolvedor) e PHP comuns, com acesso a variveis especiais do Symfony para gerao de contedo de forma dinmica. Tambm possvel

5.6. Camada Controller


O Controle Frontal (Front controller) quem gerencia as requisies realizadas pelo usurio final. Encontra-se na raiz do diretrio web. Podem existir vrios Controles Frontais, conforme as aplicaes e ambientes configurados. Veremos isto na prxima seo. Aes (Actions) so arquivos actions.class.php residentes em cada mdulo. So chamados pelo Controlador Frontal e no acessados diretamente, por isto no precisam estar disponveis dentro do diretrio web. Em Aes acontece a maior parte do desenvolvimento no Symfony.

Captulo 5 Entendendo o Symfony - 37

5.7. Aplicaes, Mdulos e Aes


No exemplo do captulo Criando uma aplicao rpida com o Symfony foi aprendido como criar aplicaes e mdulos no Symfony. Agora aprofundaremos um pouco para compreender a estrutura destes elementos no Symfony.

Ao abrirmos o Diretrio ADMIN, nos encontramos com a seguinte estrutura de diretrios. Config: Arquivos de configurao da aplicao, em formato YAML (um simplificador do formato XML); i18n: Arquivos de traduo para aplicativos multilnguas; lib: Classes exclusivas do aplicativo; modules: Mdulos da aplicao; template: Layouts da aplicao (templates disponveis para todos os mdulos); actions: Controllers do mdulo. Normalmente s necessrio um arquivo, action.class.php; templates: Diretrio de templates do mdulo;

Uma aplicao pode conter vrios mdulos, vinculados ou no a um Model.

Captulo 5 Entendendo o Symfony - 38

5.8. Ambientes e Handlers


Existem dois problemas corriqueiros em aplicaes web: Um projeto, mltiplos clientes: Num sistema web bastante comum a necessidade de um portal administrativo ou restrito (backend) e um portal pblico ou para o usurio final (frontend); Ambiente tempo de de desenvolvimento: consultas Para desenvolver no a aplicao de

importante ter acesso a ferramentas de debuf, verificar variveis em execuo, realizadas banco dados, requisies, etc; tambm comum existir um banco de dados em teste e um banco de dados em produo; No Primeiro caso so praticamente dois sistemas diferentes (ou mais...) acessando o mesmo banco de dados com regras de requisio e resposta diferentes, apresentao diferente, mas com as mesmas regras de negcio de acesso ao banco. No segundo caso os desenvolvedores possuem um trabalho muito grande de ligar e desligar debugs, ter cpia de ambientes diferentes, com acesso a banco de dados diferentes, manter sincronizados estes dois ambientes, ou ento, mesmo que somente em sua mquina de desenvolvimento, h muita mo-de-obra para testar a viso do usurio final. O Symfony, para facilitar a vida do desenvolvedor, permite a criao de vrios ambientes dentro de um projeto, e para isto, utiliza os handlers. Handlers so arquivos em PHP que fazem o primeiro trabalho da Camada Controller, que definir qual aplicao, mdulo e ao sero executados.

Captulo 5 Entendendo o Symfony - 39

5.9. Configurando Ambientes


O Symfony, para no dificultar as configuraes utilizando o XML, ou retroagir utilizando o ultrapassado formato INI, ou ainda inventar um novo formato, optou por utilizar uma linguagem que um XML Simplificado, chamado de YAML (YAML Ain't Markup Language http://www.yaml.org/). O YAML muito simples de se escrever. Tem poucas regras, das quais resume-se abaixo as mais importantes: A hierarquia mantida pela identao; A identao com dois ESPAOS; No se utliza TABULAO como identao; Cada chave seguida de dois pontos; O valor depois dos dois pontos atribudo chave; preciso um espao entre os dois pontos e o valor; Texto com espao definido entre aspas SIMPLES; O que ficar aps um # um comentrio na linha;

Para configurar ambientes no Symfony, utilizamos inicialmente o arquivo: config/databases.yml

all: doctrine: class: sfDoctrineDatabase param: dsn: mysql:host=localhost;dbname=livraria444 username: livraria444 password: senha444

Captulo 5 Entendendo o Symfony - 40 Ento temos os ambientes dev, test, alm do prod, que padro e est omitido por no possuir personalizaes na configurao inicial. Alm deles temos o all que determina valores padro para todos os ambientes (que podem ser sobrescritos individualmente). prod: Ambiente de produo, com cache ativado e com apenas alertas de erros(sem debug); dev: Ambiente de desenvolvimento, com cache desativado, erros em nvel mximo(com debug); test: Ambiente especial semelhante ao de produo, mas que s executado em linha de comando para rodar testes automatizados; ??: possvel configurar outros ambientes personalizados.

Muito comum o ambiente de desenvolvimento utilizar outro banco de dados; ou ento, um ambiente intermedirio, com uma cpia do banco de produo criado para testes, mas com debug. Quando uma nova aplicao criada, por padro so criados dois handlers: web/minhaaplicacao.php: corresponde ao ambiente de produo; web/minhaaplicacao_dev.php; desenvolvimento; corresponde ao ambiente de

Se a aplicao a primeira a ser criada, seu ambiente de produo ter como handler web/index.php, e torna-se o aplicativo padro do projeto. Uma ferramenta importante do Symfony a barra de Debug, uma barra flutuante que aparece em todas as pginas, fornecendo informaes valiosas sobre varveis e consultas a banco de dados.

Captulo 5 Entendendo o Symfony - 41 Essa barra de debug ativada dentro do handler: <?php if(!in_array(@$_SERVER['REMOTE_ADDR'], array('127.0.0.1','::1'))) { die('You are not allowed to access this file. Check '. basename(__FILE__).' for more information.'); } require_once(dirname(__FILE__). '/../config/ProjectConfiguration.class.php'); $configuration = ProjectConfiguration::getApplicationConfiguration ('admin', 'dev', true); sfContext:createInstance($configuration)->dispatch(); ?> A ateno especial dada aos parmetros do mtodo esttico: ProjectConfiguration::getApplicationConfiguration('admin', 'dev', true); Ele recebe trs parmetros: aplicao: no exemplo 'admin'; ambiente: no exemplo 'dev'. Podendo ainda ser 'prod' (oque o caso do ambiente de produo) ou outro ambiente que tennha sido configurado no arquivo config/databases.yml webdebug: no exemplo true, ou seja, ativo(no ambiente de produo, false);

Captulo 5 Entendendo o Symfony - 42

5.10. A URL no Symfony


Na URL de uma aplicao Symfony, at os trs primeiros parmetros so determinadas a aplicao, o mdulo e a ao a serem executadas. 1. Situao 1 Homepage http://livraria.local Se no h parmetros aps o domnio, ento subentende-se que a aplicao e o ambiente so os definidos no arquivo: web/index.php

() // APLICAO = admin, AMBIENTE = prod, DEBUG = false $configuration () J o mdulo e a ao so os definidos no arquivo: apps/minhaaplicacao/config/routing.yml dentro da opo homepage, param () homepage: url: / param: {module: default, action: index} () = ProjectConfiguration::getApplicationConfiguration ('admin', 'prod', 'false');

Captulo 5 Entendendo o Symfony - 43 2. Situao 2 Um handler diferentes http://livraria.local/admin_dev.php Se o primeiro parmetro um handler, ento executado este handler, que estar no diretrio web, que define a aplicao. J o mdulo e a ao seguem a mesma situao acima, sendo definidos no arquivo: apps/minhaaplicacao/config/routing.yml 3. Situao 3 mdulo http://livraria.local/categoria http://livraria.local/admin_dev.php/categoria Se o primeiro parmetro no um handler, ou ento um handler seguido de uma barra mais uma palavra, ento esta ltima informao um mdulo (no exemplo acima, categoria). A ao definida no arquivo: apps/minhaaplicacao/config/routing.yml dentro da opo default_index, param (valor padro index). () default_index: url: /:module param: {action: index} () 4. Situao 4 mdulo/ao http://livraria.local/categoria/new http://livraria.local/admin_dev.php/categoria/new

Captulo 5 Entendendo o Symfony - 44 Se o primeiro parmetro no um handler, ou ento um handler seguido de uma barra mais uma palavra e de outra barra e palavra, ento esta ltima informao uma ao (no exemplo acima, new) e a penltima um mdulo (no exemplo acima, categoria). 5. Situao 5 mdulo/ao/variavel/valor http://livraria.local/categoria/edit/cat_id/1 http://livraria.local/admin_dev.php/categoria/edit/cat_id/1 Se j esto identificados aplicao, mdulo e ao, ento o que segue so sempre pares de varivel/valor, que sero enviados via GET. No exemplo acima, a ao edit do mdulo categoria receber a varivel cat_id com o valor 1. Seria o equivalente a: http://livraria.local/categoria/edit?cat_id=1 http://livraria.local/admin_dev.php/categoria/edit?cat_id=1 no PHP natural, o que equivaleria no script de destino a varivel: $_GET['cat_id'] = 1 apesar de que utiliza-se um mtodo prprio no Symfony para recuperar esta varivel, como ser visto mais adiante. Se houverem mais pares de varivel/valor, seguiro as mesmas regras: http://livraria.local/categoria/edit/cat_id/1/descricao/Romance http://livraria.local/admin_dev.phpcategoria/edit/cat_id/1/descricao/Romanc e equivale s variveis no destino: $_GET['cat_id'] = 1 $_GET['descricao'] = 'Romance'

Captulo 6 Usando o EasyEclipse - 45

Captulo 6 Usando o EasyEclipse

6.1. Introduo terica


O EasyEclipse (http://eclipse.org) j foi instalado com o plugin PHPEclipse. Vamos aprender a utiliz-lo para gerenciar um projeto em PHP e compreender algumas de suas facilidades.

6.2. Iniciando um projeto


Apesar do EasyEclipse ter sido instalado e possuir uma opo de menu para inici-lo, temos um problema: o usurio da mquina no possui acesso para salvar o diretrio /var/www/livraria444, pois foi criado pelo usurio root. Portanto, para facilitar a utilizao no desenvolvimento, prtico executar o EasyEclipse como superusurio. No Gnome possvel fazer iso pressionando ALT+F2 e digitando: gksu /opt/easyeclipse-php-1.2.2.2/eclipse Em seguida solicitada a senha do superusurio, e ento o EasyEclipse solicita que se defina a rea de trabalho (workspace) padro, que um diretrio dentro do diretrio do usurop onde, por padro o EasyEclipse sugerir que residam os projetos criados(mas no obrigatrio).

Captulo 6 Usando o EasyEclipse - 46

6.3. Criando um projeto


Acione o menu File / New / Project / PHP / PHP Project. Opcionalmente pode-se criar um novo projeto na rea do Navegador, clicando com o boto direito do mouse e selecionando File / New / Project / PHP / PHP Project. solicitado em seguida o caminho um nome e um caminho at o projeto. Este pode ser vazio(novo), ou um j existente. Neste ltimo caso, o EasyEclipse varre o diretrio e importa todos os arquivos para o projeto. Importante: o EasyEclipse mantm controle sobre as alteraes dos arquivos no simplesmente uma navegao de um diretrio. Se algum arquivo for criado no diretrio por fora do EasyEclipse, ele no vai enxergar. Do mesmo modo, se algum arquivo for alterado por fora do EasyEclipse, ele vai acusar esta inconsistncias; No caso do Symfony, isto bastante comum de acontecer com o uso das ferramentas de linha de comando que refazem os Models, por exemplo. Nestas situaes, basta solicitar ao EasyEclipse que releia o diretrio do projeto: clica-se com o boto direito em cima do nome do projeto e ento em Refresh (Atualizar).

6.4. Viso Geral da ferramenta


O EasyEclippse tem como base o PHPEclipse, que um plugin para desenvolvimento em PHP. Ele, alm do realce de sintaxe, trs outras facilidades como o auto-completar os comandos, sugesto de mtodos de classes (muitssimo til no Symfony, que 100% orientado a objeto), e incorpora recursos globais do Eclipse como navegao de classes, erros e tarefas(TODO). Para usurios Windows possvel integrar com o XAMPP(ambiente de desenvolvimento apache/MySQL/PHP para Windows) atravs do menu PHP/Apache. Como projetos em PHP envolvem invariavelmente em algum momento manipulao de arquivos XHTML/HTML, JavaScript, CSS e SQL, outros plugins incorporados abrem estes arquivos e apresentam facilidades para estas linguagens.

Captulo 6 Usando o EasyEclipse - 47 De moro geral, alguns atalhos de teclado so teis em todos os editores: CTRL+espao: sugere complementao de comandos ou parmetros; TAB: identa o cdigo vlido para vrias linhas selecionadas; SHIFT+TAB: selecionadas; CTRL+PGUP, CTRL+PGDN: navega pelas abas do editor(arquivos abertos); A lista completa de atalhos de teclado est disponvel no menu Help/ Key Assist... O EasyEclipse guarda a ltima janela encerrada; ou seja, quando se abrir novamente o EasyEclipse ele vai abrir exatamente como foi encerrado. Uma janela muito til do EasyEclipse o Outline, que permite a navegao dentro de um arquivo por exemplo, numa classe so listados os mtodos; num arquivo CSS, cada uma das entradas, etc. desidenta o cdigo vlido para vrias linhas

6.5. Configuraes teis


Um padro importante nos projetos atuais a quantidade de caracteres que so utilizados para identao. De modo geral o caracter TAB no ,aos utilizado (para evitar diferentes interpretaes por editores ou visualizadores), sendo utilizado o espao (o padro mais comum so 2 espaos). Entretanto, para facilitar, possvel automaticamente converter o pressionamento do TAB por espaos ( ou o contrrio com o SHIFT+TAB).

Captulo 7 Camada Controller: controlando as requisies e respostas - 48

Captulo 7 Camada Controller: controlando as requisies e respostas

Pelo padro MVC o Controller oque faz a interconexo entre a lgica de negcio (Model) e a apresentao (View). Basicamente o Symfony separa o Controller nos seguintes componentes: Front Controller (Controle frontal): ponto de entrada nico da aplicao; carrega a configurao e determinao de qual ao ser executada; Actions(Aes): lgica da aplicao, verifica a integridade da requisio e prepara os dados necessrios para a camada de apresentao; Objetos Request, Response, Session: do acesso aos parmetros requisitados, cabealhos de resposta e aos dados persistentes.

Captulo 7 Camada Controller: controlando as requisies e respostas - 49

7.1. Aes (Actions)


O Front Controller determina qual o mdulo e ao correspondente ser executado atravs da leitura da URL como j foi explicado anteriormente. Para que seja controlada a alao correspondente, ela deve existir dentro da classe. class pessoaActions extends sfActions { public function executeIndex(sfWebRequest $request) { $this->pessoas = Doctrine::getTable('Pessoa') ->createQuery('a') ->execute(); } public function executeNew(sfWebRequest $request) { $this->form = new PessoaForm(); } public function executeCreate(sfWebRequest $request) { $this->forward404Unless($request->isMethod(sfRequest::POST)); $this->form = new PessoaForm(); $this->processForm($request, $this->form); $this->setTemplate('new'); } public function executeEdit(sfWebRequest $request) { $this->forward404Unless($pessoa = Doctrine::getTable('Pessoa')>find(array($request->getParameter('id'))), sprintf('Object pessoa does not

Captulo 7 Camada Controller: controlando as requisies e respostas - 50 exist (%s).', $request->getParameter('id'))); $this->form = new PessoaForm($pessoa); } public function executeUpdate(sfWebRequest $request) { $this->forward404Unless($request->isMethod(sfRequest::POST) || $requ est->isMethod(sfRequest::PUT)); $this->forward404Unless($pessoa = Doctrine::getTable('Pessoa')>find(array($request->getParameter('id'))), sprintf('Object pessoa does not exist (%s).', $request->getParameter('id'))); $this->form = new PessoaForm($pessoa); $this->processForm($request, $this->form); $this->setTemplate('edit'); } public function executeDelete(sfWebRequest $request) { $request->checkCSRFProtection(); $this->forward404Unless($pessoa = Doctrine::getTable('Pessoa')>find(array($request->getParameter('id'))), sprintf('Object pessoa does not exist (%s).', $request->getParameter('id'))); $pessoa->delete(); $this->redirect('pessoa/index'); } protected function processForm(sfWebRequest $request, sfForm $form) { $form->bind($request->getParameter($form->getName()), $request>getFiles($form->getName())); if ($form->isValid())

Captulo 7 Camada Controller: controlando as requisies e respostas - 51 { $pessoa = $form->save(); $this->redirect('pessoa/edit?id='.$pessoa->getId()); } } } As aes devem manter o seguinte padro de nomenclatura para o mtodo: Iniciar com a palavra execute toda em minscula; Continuar com o nome da ao, com a primeira letra em maiscula;

Mtodos que no seguem este padro no so aes, no podem ser acessadas pelo Front Controller, apesar de ser possvel seu uso internamente pela classe, conforme a necessidade.

Captulo 7 Camada Controller: controlando as requisies e respostas - 52

7.2. Trmino da ao
As aes ao seu trmino, por padro, chamam um template de mesmo nome e sufixo Success. Portanto, a ao executeIndex chamar o template indexSucess.php, a ao executeList chamar o template listSuccess.php, e assim por diante. Na realidade existe um return implcito ao final de cada ao chamando a View padro, que : // Ambas aes chamam a View Success correspondente a cada ao public function executeIndex(sfWebRequest $request) { $this->pessoas = Doctrine::getTable('Pessoa') ->createQuery('a') ->execute(); } Para chamar uma View personalizada, a ao deve terminar assim: // O Symfony va procurar o template actionNameMeuTemplate.php public function executeIndex(){ return 'MeuTemplate'; } Mas possvel no chamar nenhum template. Este o caso, por exemplo, para funes que sero executadas em modo batch, ou em agendamentos no cron, ou seja, no tero sada. // O Symfony no vai executar nenhum template public function executeAgendamento(){ return sfView::NONE; }

Captulo 7 Camada Controller: controlando as requisies e respostas - 53

7.3. Redirecionamento
O Symfony permite dois tipos de redirecionamento: Para outra ao: algo interno, e no interfere na URL exibida para o usurio, que nem percebe que isto aconteceu; public function executeList(){ $this->forward('meumodulo','index'); } Para outra URL (Redirect) public function executeList(){ $this->redirect('meumodulo/index'); $this->redirect('http://www.terra.com.br');

O forward e o redirect functionam como o return, ou seja, o cdigo aps eles nunca ser executado. Existe um tipo de redirecionamento bastante comum, que o da pgina no encontrada (erro 404 do Apache). Seu uso exemplificado a seguir: $this->forward404Unless($pessoa = Doctrine::getTable('Pessoa')>find(array($request->getParameter('id'))), sprintf('Object pessoa does not exist (%s).', $request->getParameter('id'))); $this->form = new PessoaForm($pessoa);

A pgina de erro pode ser personalizada. Basta criar um template em um mdulo, uma ao e alterar a configurao no arquivo config/settings.yml da aplicao:

Captulo 7 Camada Controller: controlando as requisies e respostas - 54 all: .actions: error_404_module: default error_404_actions: error404 Entretanto comum necessitarmos realizar redirecionamento aps um teste lgico. Para isto o Symfony dispe de mais alguns mtodos: forwardIf() forwardUnless() forward404If() forward404Unless() redirectIf() redirectUnless()

$this->forward404Unless($pessoa = Doctrine::getTable('Pessoa')>find(array($request->getParameter('id'))), sprintf('Object pessoa does not exist (%s).', $request->getParameter('id'))); $this->form = new PessoaForm($pessoa); Quando o cliente envia uma requisio, uma srie de informaes so recebidas pelo servidor Web, como dados sobre navegador, URL, GET e POST. O Symfony dispe de todas estas informaes ao Controller atravs do objeto sfWebRequest Informaes da Requisio ------------------------------------------------------------------------------------------------------------------Nome Funo =>Exemplo ------------------------------------------------------------------------------------------------------------------isMethod($method) POST ou GET => true or false

Captulo 7 Camada Controller: controlando as requisies e respostas - 55 getMethod()Nome do mtodo de requisio => 'POST' getHttpHeader('Server') HTTP header => 'Apache/2.0.59 (Unix) DAV/2PHP/5.1.6'

getCookie('teste') Valor do nome do cookie => 'testando' isXmlHttpRequest() uma requisio Ajax? => true isSecure() uma requisio SSL? => true hasParameter('teste')Parmetro presente na requisio => true getParameter('teste') Valor de um parmetro => 'testando' getParameterHolder()->getAll() requisio ------------------------------------------------------------------------------------------------------------------Informaes da URI ------------------------------------------------------------------------------------------------------------------getUri() URI completa => 'http://localhost/mymodule/myaction' getPathInfo()Informao do caminho => 'mymodule/myaction' getReferer() Referer Array com todos os parmetros de

Captulo 7 Camada Controller: controlando as requisies e respostas - 56 => 'http://localhost/' getHost()Nome do Host => 'localhost'

getScriptName()Nome do Front Controller => 'index.php' ------------------------------------------------------------------------------------------------------------------Informao do navegador do cliente ------------------------------------------------------------------------------------------------------------------getLanguages() Array com as lnguas disponveis => Array( [0] => en_US [1] => en ) getCharsets() Array com os charsets disponveis => Array( [0] => UTF-8 [1] => ISO-8859-1 ) getAcceptableContentTypes() Array com os content types disponveis => Array( [0] => text/xml [1] => text/html ) O primeiro parmetro recebido pela ao o objeto sfWebRequest, ento, comumente recebido como uma varivel: $this->pessoas = Doctrine::getTable('Pessoa')->find(array($request>getParameter('id'))) ->createQuery('a') ->execute();

Captulo 7 Camada Controller: controlando as requisies e respostas - 57

7.4. ilizando sesses de usurio


O Symfony guarda as informaes de sesso no objeto sfUser. Ele pode ser recuperado na ao atravs do mtodo getUser. Apesar de seu nome, ele est disponvel mesmo que no haja controle de usurios // Armazenando valor na sesso public function executaEntrada(){ $this->getUser()->setAttribute('fone','3333.3333'); } // Recuperando valor da sesso // O mtodo permite um valor padro, caso no exista // a varivel na sesso public function executeSaida(){ $this->getUser->getAttribute('fone','no informado'); } // Removendo uma varivel da sesso public function executeRemovendo(){ $this->getUser->getAttributeHolder()->remove('fone'); } // Limpando todas as variveis de sesso public function executeLimpando(){ $this->getUser()->getAttributeHolder()->clear(); }

7.5. Atributos Flash variveis de sesso descartveis


Muitas vezes necessrio passar um valor de script para o outro dentro de um mesmo processamento. No PHP comum, isto geralmente fora que um redirecionamento utilizando header('Location') necessite ser montado com passagem de parmetros. Isto muito comum para passar cdigos de mensagens de erro, ou confirmao de gravao de registro, por exemplo. Isto seria mais elegantemente resolvido com uma varivel de sesso, mas depois ela seria intil.

Captulo 7 Camada Controller: controlando as requisies e respostas - 58 Para resolver este tipo de situao, o Symfony possui uma varivel de sesso descartvel, chamada flash. O importante lembrar: o valor do atributo flash s est disponvel dentro de uma mesma requisio. // Definindo o valor numa ao $this->getUser()->setFlash('mensagem','Registro Salvo'); // () // Recuperando o valor em outra ao $mensagem = $this->getUser()->getFlash('mensagem'); Tambm pode ser til recuperar o atributo flash num template. Para isto, s utilizar o objeto $sf_user: <?php if($sf_user->hasFlash('mensagem')): ?> <?php echo $sf_user->getFlash('mensagem') ?> <?php endif; ?>

7.6. Repassando variveis para a View


Uma funcionalidade muito importante que a ao realiza a lgica da aplicao mas necessita repassar informaes para a camada View. A forma que o Symfony faz isto criando variveis na ao que estaro disponveis na View. Se na ao temos o seguinte cdigo: public function executeShow(){ // Criando um atributo na ao // que ficar disponvel na View $this->pessoa = Doctrine::getTable('Pessoa')->find(array($request>getParameter('id'))); } No layout ou template teremos a varivel $pessoa, no caso um objeto Pessoa <?php echo $pessoa->getNome() ?>

Captulo 7 Camada Controller: controlando as requisies e respostas - 59

Captulo 8 Camada Model: acesso ao banco de dados

8.1. Introduo terica


Bancos de dados so Relacionais. O PHP 5 e o Symfony so Orientado a Objetos. Para que se possa ser mais efetivo no uso da orientao a objeto. neste contexto que se encaixa a ORM. Toda lgica de acesso a dados encapsulada pela ORM, mantendo todo o acesso a dados e suas regras de negcios num nico local. O grande benefcio o reuso, pois possvel reutilizar um mtodo de acesso que qualquer local do aplicativo, ou at de outro aplicativo. Alm disso, uma regra de negcio ou uma chamada comum fica em um nico lugar, facilitando o acesso e a manuteno. Outra facilidade: como os registros so objetos, incluir novas funcionalidades no significa criar obrigatriamente campos em uma tabela. Diferentes formas de visualizar um campo ou um conjunto de campos independe de qual banco de dados se est acessando.

Captulo 8 Camada Model: acesso ao banco de dados - 60 Exemplo: public function getPrimeiroNome() public function getSobrenome() public function getNomeCompleto() O mtodo getNomeCompleto utiliza os dois mtodos anteriores para apresentar o nome completo de um cliente, por exemplo. Independente de mudanas nos nomes dos campos ou at em qual banco (MySQL, Postgres, Oracle, etc) ser acessado, este mtodo estar sempre disponvel e consistente. Informaes mais complexas como o total de uma nota fiscal tambm podem ser criadas desta forma e acessando outras tabelas atravs de suas classes respectivas. Outra imensa vantagem no preocupar-se com as variaes nas sintaxes SQL entre diferentes bancos de dados. Padres de nomes de campos, tabelas e chaves estrangeiras, no so obrigatrios, mas facilita na posterior utilizao dos mtodos das classes. Nomes de tabelas sem hifens ou underscore (sublinhado vazio); Nomes de tabelas em minsculas; Nomes de campo em minsculas, com underscore (sublinhado vazio) separando campos grandes; O Doctrine ORM principal do Symfony em sua verso 1.4.4 converte campos como nome_funcionario para um mtodo como getNomeFuncionario, oque bastante claro e legvel. Os nomes de tabela so convertids de cliente para classe Cliente. muito importante definir chaves estrangeiras, pois o Doctrine vasculha os relacionamentos e cria os devidos mtodos de acesso.

Captulo 8 Camada Model: acesso ao banco de dados - 61 O Doctrine ORM baseia a construo dos modelos num arquivo schema.yml que possui uma estrutura como no exemplo a seguir: Pessoa: connection: doctrine tableName: pessoa columns: id: type: integer(4) fixed: false unsigned: false primary: true autoincrement: true nome: type: string() fixed: false unsigned: false primary: false notnull: true autoincrement: false sobre_nome: type: string() fixed: false unsigned: false primary: false notnull: true autoincrement: false email: type: string(45) fixed: false unsigned: false primary: false notnull: true autoincrement: false

Captulo 8 Camada Model: acesso ao banco de dados - 62 Neste curso no abordaremos esta forma de criao de Models, mas com a varredura do banco para criao deste esquema (como visto no captulo Criando uma aplicao rpida com o Symfony). Tambm j foi citado que na criao dos Models h dois tipos de arquivos: mapeamento, classes das tabelas. Vamos detalhar um pouco os ltimos dois, que so os utilizados na prtica.

8.2. Classes de Tabelas


As classes de tabelas representam um registro na tabela. O Doctrine cria dois tipos: a classe Base e a Custom (personalizada). A classe Base abstrata, no pode ser acessada diretamente, posteriores, e criada automaticamente sero realizadas pelo Doctrine. na Base. A classe Custom criada pelo Doctrine, mas nunca sobreescrita; ou seja, se houver alteraes somente Utiliza-se unicamente a Custom. Como herana da Base temos os getters(para recuperar valor dos campos) e setters (para alterar valor dos campos), mtodos para salvar e excluir, entre outros.

8.3. Acessando dados atravs do Model


Considerando o exemplo da classe Pessoa, veremos algumas operaes em seu arquivo actions.class.php.

8.4. Utilizando critrios no Doctrine


Para abstrair qualquer banco de dados, o Doctrine utiliza uma sintaxe prpria de filtragem. A seguir tem-se um resumo das estruturas mais utilizadas. Sintaxe Bsica: ------------------------------------------------------------------------------------------------------------------Where column = value => where(column = value);

Captulo 8 Camada Model: acesso ao banco de dados - 63

WHERE column <> value => where(colum <> value); ------------------------------------------------------------------------------------------------------------------DQL ------------------------------------------------------------------------------------------------------------------http://www.doctrine-project.org/documentation/manual/1_2/en/dql-doctrinequery-language ------------------------------------------------------------------------------------------------------------------Outras Sintaxes ------------------------------------------------------------------------------------------------------------------ORDER BY column ->addAscendingOrderByColumn(column); LIMIT limit ->limit(limit);

8.5. Mtodos personalizados 8.5.1. Mtodo especial __toString


J vimos que a classe tabela uma classe Custom, ou seja, pode ser personalizada. Entretanto existe um mtodo especial que pode ser adicionado e que muito til para tabelas que so pai em relacionamentos, ou seja, so tabelas estrangeiras: o mtodo __toString Este mtodo chamado automaticamente pelo Symfony quando da montagem de comboboxes em formulrios para preencher a legenda. Deste modo, possvel determinar como ser a legenda. <?php

Captulo 8 Camada Model: acesso ao banco de dados - 64 // lib/model/Pessoas.php class Pessoa extends BasePessoa{ public function __toString(){ return $this->getCodigo().'-'.$this->getNome(); } } foi determinado como legenda a concatenao entre Cdigo e Nome da Pessoa. Poderia ser qualquer outro formato necessrio.

8.6. Sobrescrita de mtodos


Muitas vezes necessrio um tratamento antes de alterar ou recuperar um campo, por exemplo. possvel alterar o comportamento padro simplesmente sobrescrevendo o mtodona classe extendida, como no exemplo: <?php // lib/model/Pessoa.php class Pessoa extends BasePessoa { /** * Set the value of [nome] column. * * @paramstring $v new value * @return Cliente The current object */ public function setNome($v) { if ($v !== null) { $v = (string) $v; }

Captulo 8 Camada Model: acesso ao banco de dados - 65 if ($this->nome !== $v) { // Colocando todas as letras em maisculas $this->nome = strtoupper($v); } return $this; } // setNome() } ?> Uma pequena alterao: o nome ser convertido todo para maisculas antes de ser gravado.

Captulo 9 Camada View: Apresentao

9.1. Introduo terica


J vimos anteriormente que a Camada View composta de Layouts e Templates. Como esta camada responsvel pelo resultado final de nosso trabalho

Captulo 9 Camada View: Apresentao - 66 de programao, importante compreendermos onde vamos colocar nosso cdigo.

9.2. A montagem da View


De modo geral, a montagem da View feita com a leitura de um layout (a nvel de aplicao) e um template (a nvel de mdulo/ao). J vimos que o padro de layout da aplicao : apps/aplicacao/templates/layout.php enquanto os templates residem no diretrio templates de cada mdulo. No captulo sobre Controllers vimos que cada ao, ao seu final, chama um template.Ainda temos a situao de utilizar trechos de templates, que so os partials. Vamos conhecer o layout padro do Symfony <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en"> <head> <?php include_http_metas() ?> <?php include_metas() ?> <?php include_title() ?> <link REL="shortcut icon" HREF="/favicon.ico" /> </head> <body> <?php echo $sf_content ?> </body> </html> </comandoNumerado> e considerando um template como segue: <h1> Ol, Mundo </h1> Teremos a seguinte pgina gerada:

Captulo 9 Camada View: Apresentao - 67 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en"> <head> <meta HTTP-EQUIV="content-type" CONTENT="text/html; charset=utf-8" /> <meta name="title" CONTENT="symfony project" /> <meta name="robots" CONTENT="index, follow" /> <meta name="description" CONTENT="symfony project" /> <meta name="keywords" CONTENT="symfony, project" /> <title>symfony project</title> <link REL="stylesheet" TYPE="text/css" HREF="/css/main.css" /> <link REL="shortcut icon" HREF="/favicon.ico"> </head> <body> <h1>Ol, Mundo</h1> </body> </html> Ento percebe-se que o trecho de cdigo: <?php echo $sf_content ?> inclui o template. Conforme a distribuio do layout da pgina (com cabealho, menu, rodap, etc), ento posicionamos este cdigo adequadamente. Existem tambm trs funes especiais (include_http_metas(),

include_metas(), include_title()). Elas geram os headers do XHTML/HMTL baseados na configurao da View na aplicao e no mdulo requisitado. Para a aplicao, encontramos esta configurao em: apps/aplicacao/config/view.yml

default:

Captulo 9 Camada View: Apresentao - 68 http_metas: content-type: text/html metas: #title: symfony project #description: symfony project #keywords: symfony, project #language: en #robots: index, follow stylesheets: [main.css] javascripts: [] has_layout: on layout:layout Para o mdulo, no h um arquivo criado. Se criado, ele vai ser lido em cascata, ou seja, o que estiver na configurao lido primeiro, e depois ele lido e sobrescreve as informaes. apps/aplicacao/modulo/config/view.yml

editSuccess: metas: title: Editando Pessoa listSuccess: metas: title: Listagem de Pessoas printSuccess: metas: title: Imprimir registro

Captulo 9 Camada View: Apresentao - 69 stylesheets: [print.css] all: metas: title: Cadastro de Pessoas No exemplo acima, a palavra chave all representa um padro para o mdulo, e cada template referenciado possui informaes personalizadas. Isto uma forma muito simples de incluir arquivos javascript onde so necessrios, por exemplo.

9.3. Partials (Parciais)


Partials, como j foi visto anteriormente, so trechos de template que podem ser includos em determinados pontos do layout ou do template. Eles iniciam com um underscore ( _ ) e residem ou no diretrio de layouts da aplicao (globais) ou no diretrio de templates de cada mdulo. Para incluir partials, utiliza-se um dos trs cdigos abaixo, conforme a necessidade: // Estando no mesmo mdulo, possvel incluir o partial // apps/aplicacao/modules/meumodulo/templates/_parcial.php // sem citar o mdulo <?php include_partial('parcial') ?> // Se quiser incluir em qualquer outro lugar fora do mdulo // ento preciso informar o mdulo <?php include_partial('meumodulo/parcial') ?> // Um partial global como // apps/aplicacao/templates/_parcialGlobal.php // includo assim <?php include_partial('global/parcialGlobal') ?>

Captulo 9 Camada View: Apresentao - 70 Entretanto, os partials no tem acesso s variveis disponveis.

9.4. Variveis do Symfony


O Symfony dispe algumas variveis para que a View possa ser montada com informaes provenientes de vrios lugares. J foi visto no captulo sobre Controllers como as aes passam variveis para a View, mas existem outras informaes que esto disponveis nas aes que tambm esto disponveis na View. $sf_context: sfContext $sf_request: sfRequest $sf_params: Parmetros do objeto Request $sf_use: sfUser

Os usos so semelhantes ao do Controller.

9.5. Helpers
Helpers so funes em PHP que retornam algum tipo de trecho em HTML. O Symfony possui vrios pr-definidos e possvel tambm criar Helpers personalizados. Existem vrios grupos de Helpers, e nem todos esto ativos por padro. Para carregar um que no esteja ativo, utiliza-se: <?php use_helper('HelperName') ?> <?php use_helper('HelperName1', 'HelperName2', 'HelperName3') ?>

Abaixo uma lista dos mais utilizados. // Grupo Tag // ========= <?php echo tag('input', array('name' => 'endereco', 'type' => 'text')) ?>

Captulo 9 Camada View: Apresentao - 71 // ou <?php echo tag('input', 'name=endereco type=text') ?> => <input name="endereco" TYPE="text" /> <?php echo content_tag('textarea', 'Texto livre', 'name=texto') ?> => <textarea name="texto">Texto livre</textarea>

// Grupo Url // ========= // Link para a ao de criao de novo registro no mdulo pessoa // Importante: o link ser gerado considerando o roteamento, // o front controller atual, etc. <?php echo link_to('Nova Pessoa', 'pessoa/new') ?> => <a HREF="/pessoa/new">Nova Pessoa</a>

// Grupo Asset // =========== // Tag IMG <?php echo image_tag('logo.png', 'alt=Logotipo size=200x100') ?> => <img SRC="/images/logo.png" ALT="Logotipo" WIDTH="200" height="100"/> // Incluindo Javascript <?php echo javascript_include_tag('atualizar') ?> => <script language="JavaScript" TYPE="text/javascript" src="/js/atualizar.js"></script> // Incluindo CSS <?php echo stylesheet_tag('formatacao') ?> => <link HREF="/stylesheets/formatacao.css" MEDIA="screen" rel="stylesheet"type="text/css" />

Captulo 9 Camada View: Apresentao - 72

Captulo 10 Forms: criando formulrios - 73

Captulo 10 Forms: criando formulrios

10.1. Introduo terica


Uma necessidade especial no trabalho com o aplicativos Web a criao e manipulao de formulrios. Isto envolve algumas tarefas recorrentes: Montar o formulrio: atravs de tags XHTML/HTML, preciso criar uma a uma cada tag de cada campo; Tratar o envio do formulrio: definir na tag form como o formulrio ser enviado; Validar os campos do formulrio: ao receber os valores, decidir se so ou no vlidos; Exibir erros de validao: se algum campo no for validado, retornar erro; Armazenar os dados: se estiverem vinculados a alguma tabela de banco de dados; Retornar informao sobre gravao de registro: alguma

Captulo 10 Forms: criando formulrios - 74 mensagem informativa, confirmando ou no a gravao. Estas tarefas se tornam ainda mais tediosas e de complexa manuteno conforme aumenta o nmero de tabelas e campos nestas tabelas. O Symfony prope uma abordagem muito eficiente para centralizar tanto a criao como a validao dos formulrios. Veremos agora como utilizar de forma bsica seus recursos.

10.2. Gerando formulrios automaticamente


A maioria dos formulrios num sistema so baseados em tabelas de um banco de dados. Para facilitar nosso estudo, comearemos com a visualizao de um formulrio criado no captulo Criando uma aplicao rpida com o Symfony. Lembrando que ele foi criado com o uso de uma tarefa automatizada do Doctrine: symfony doctrine:build-forms Agora vamos conhecer o arquivo: lib/form/doctrine/base/BaseLivroForm.class.php

<?php class BaseLivroForm extends BaseFormDoctrine { public function setup() { $this->setWidgets(array( 'isbn' => new sfWidgetFormInputHidden(), 'autor'=> new sfWidgetFormInput(), 'titulo' => new sfWidgetFormInput(), 'cat_id' => new sfWidgetFormDoctrineChoice( array('model' => 'Categoria', 'add_empty' => true)), 'preco'=> new sfWidgetFormInput(),

Captulo 10 Forms: criando formulrios - 75 'sumario' => new sfWidgetFormInput(), )); $this->setValidators(array( 'isbn' => new sfValidatorDoctrineChoice( array('model' => 'Livro', 'column' => 'isbn', 'required' => false)), 'autor'=> new sfValidatorString( array('max_length' => 80, 'required' => false)), 'titulo' => new sfValidatorString( array('max_length' => 100, 'required' => false)), 'cat_id' => new sfValidatorDoctrineChoice( array('model' => 'Categoria', 'column' => 'cat_id', 'required' => false)), 'preco'=> new sfValidatorNumber(), 'sumario' => new sfValidatorString( array('max_length' => 1000, 'required' => false)), )); $this->widgetSchema->setNameFormat('livro[%s]'); $this->errorSchema = new sfValidatorErrorSchema( $this->validatorSchema); parent::setup(); } public function getModelName() { return 'Livro';

Captulo 10 Forms: criando formulrios - 76 } } ?> Lembrando que ele no deve ser alterado ou acessado diretamente, mas sim a classe extendida LivroForm que est em: lib/form/doctrine/LivroForm.class.php

<?php class LivroForm extends BaseLivroForm { public function configure() { } } ?>

O que for implementado dentro do mtodo configure() sobrescreve o que foi definido na classe Base. Podemos identificar na classe Base quatro trechos bsicos que so: $this->setWidgets: define os widgets (elementos de formulrio) para cada campo da tabela; $this->setValidators: define os validadores para cada campo da tabela; $this->widgetSchema->setNameFormat: define um padro para os nomes de campos (o padro criar um array com o nome da tabela, onde cada chave do array o nome de um campo);

Captulo 10 Forms: criando formulrios - 77 $this->errorSchema: define o esquema de erros.

Os dois ltimos so padronizados e raramente til personaliz-los. Os dois primeiros so a alma do esquema de formulrios do Symfony, e ento vamos conhec-los um pouco mais.

10.3. Widgets
Na criao da classe BaseLivroForm vemos que ela uma classe extendida de BaseFormDoctrine - que por sua vez uma classe extendida de sfForm. A classe BaseFormDoctrine uma "verso para o ORM Doctrine" da classe padro de manipulao de formulrios do Symfony. A classe sfForm manipula todas as operaes de formulrio e seus campos, chamados Widgets. Cada Widgets uma extenso da classe base sfWidget, e possui um funcionalidade especfica. Quando vamos criar um formulrio Web existem vrias dificuldades, incluindo tamanho dos campos, o rtulo (label), o tipo de input (text, password, radio, checkbox, alm das opes de select e textarea), e muitas vezes ainda necessrio pegar informaes de listagem ou de outras tabelas para criar listagens.

Isto no Symfony fica muito simples: existem Widgets para cada situao corriqueira. Se olhamos o cdigo especfico de criao dos Widgets, temos: $this->setWidgets(array( 'isbn' => new sfWidgetFormInputHidden(), 'autor'=> new sfWidgetFormInput(), 'titulo' => new sfWidgetFormInput(), 'cat_id' => new sfWidgetFormDoctrineChoice( array('model' => 'Categoria', 'add_empty' => true)), 'preco'=> new sfWidgetFormInput(), 'sumario' => new sfWidgetFormInput(), )); vemos, por exemplo, que o campo isbn est como hidden, sendo exibido assim:

Captulo 10 Forms: criando formulrios - 78 <input type="hidden" name="livro[isbn]" id="livro_isbn" /> Os campos tipo input so gerados de forma simples: <input type="text" name="livro[autor]" id="livro_autor" /> <input type="text" name="livro[titulo]" id="livro_titulo" /> <input type="text" name="livro[preco]" id="livro_preco" /> <input type="text" name="livro[sumario]" id="livro_sumario" /> Mas o poder do Symfony visto no campo cat_id, que select montado na tabela categoria: <select name="livro[cat_id]" id="livro_cat_id"> <option value="" selected="selected"></option> <option value="1">Informtica</option> <option value="2">Auto Ajuda</option> <option value="4">Administrao</option> <option value="5">Fico</option> </select>

No captulo Criando uma aplicao rpida com o Symfony vimos que para esta funcionalidade ser efetiva preciso criar um mtodo __toString que retorna um dos campos da tabela. Isto feito no Model, pois ele que chamado neste momento para preencher o select. Existem diversos Widgets, e cada um possui seus atributos. No cabe estudar um a um, mas conforme for necessrio, se detalhando em cada um que se utilizar. Uma lista completa de referncia dos Widgets encontrada em: http://www.symfony-project.org/api/1_4/widget

10.4. Validators
Uma vez que temos os Widgets podemos anexar a eles Validators

Captulo 10 Forms: criando formulrios - 79 (validadores), que so regras para aceitar os valores enviados pelo formulrio. Os Validators, preciso deixar claro, sempre testam TODOS os campos; portanto, mesmo que no seja necessrio validar um campo, preciso definir uma validao "vazia", ou no obrigatria. Vejamos os ... gerados automaticamente pelo Doctrine: $this->setValidators(array( 'isbn' => new sfValidatorDoctrineChoice( array('model' => 'Livro', 'column' => 'isbn', 'required' => false)), 'autor'=> new sfValidatorString( array('max_length' => 80, 'required' => false)), 'titulo' => new sfValidatorString( array('max_length' => 100, 'required' => false)), 'cat_id' => new sfValidatorDoctrineChoice( array('model' => 'Categoria', 'column' => 'cat_id', 'required' => false)), 'preco'=> new sfValidatorNumber(), 'sumario' => new sfValidatorString( array('max_length' => 1000, 'required' => false)), )); Cada Validator j possui regras pr-definidas e aceita um ou dois arrays como parmetro: primeiro: opes segundo: mensagens

Se no h o segundo array, ento as mensagens sero padro. Mas veremos logo a seguir como personaliz-las.

Captulo 10 Forms: criando formulrios - 80 Novamente, h muitas opes, que variam conforme o Validator. Alguns so muito usados e comuns: max_length: tamanho mximo de caracteres min_length: tamanho mnimo de caracteres required: campo obrigatrio ou no default: valor padro para o campo label: rtulo para o campo

No exemplo acima, sfValidatorDoctrineChoice exige model e column, ou seja, vai checar se o valor enviado est dentro dos possveis desta tabela e campo (ou seja, checa a integridade referencial antes de salvar no banco, o que evita erros de SQL). As mensagens de erro so definidas no segundo array, e existem duas mensagens bsicas: required: quando o campo de preenchimento obrigatrio ('Required') invalid: quando a regra de validao no foi atendida ('Invalid')

Outros so comuns para max_lenght e min_lenght, que informam o tamanho mximo e mnimo necessrios. Para personalizar as mensagens, envia-se o segundo array como parmetro do Validator: // (...) 'email'=> new sfValidatorEmail( array('required' => true), array('required' => 'Email obrigatrio', 'invalid' => 'Email invlido') ), // (...) Opcionalmente possvel definir uma mensagem padro de required e invalid

Captulo 10 Forms: criando formulrios - 81 para os Validators informando: <?php class LivroForm extends BaseLivroForm { public function configure() { $this->setRequiredMessage('Campo obrigatrio'); $this->setInvalidMessage('Valor invlido - corrija'); } } ?> sem, entretanto, perder a funcionalidade de criar mensagens personalizadas para cada campo. H vrios Validators, e da mesma forma que os Widgets mais interessante estud-los quando necessitamos deles. Uma lista com os Validators disponveis encontrada em:

http://www.symfony-project.org/api/1_4/validator

10.5. Labels
O Symfony cria automaticamente rtulos (labels) para os campos baseado em seu nome. De forma simples, ele tenta manter o seguinte padro: data_nascimento => Data Nascimento codigo_area => Codigo Area

Apesar de ser interessante, este padro no muito til em portugus, pois temos acentuao e isto no gravado com o nome do campo (pelo menos no por administradores e projetistas de banco com o um mnimo de bom senso). Podemos personalizar os rtulos atravs do prprio Widget com a opo label

Captulo 10 Forms: criando formulrios - 82 como utilizando um mtodo especfico: <?php class LivroForm extends BaseLivroForm { public function configure() { $this->widgetSchema->setLabels(array( 'isbn' => 'ISBN', 'autor'=> 'Autor', 'titulo' => 'Ttulo', 'cat_id' => 'Categoria', 'preco'=> 'Preo', 'sumario' => 'Sumrio', )); } } ?>

10.6. Controlando o formulrio


Todo controle do formulrio, como no poderia deixar de ser, realizado nas aes (controller). Abaixo segue um arquivo actions.class.php do mdulo livro, comentado para melhor compreenso do mecanismo. Os mtodos no relacionados ao formulrio foram excludos para melhor didtica <?php class livroActions extends sfActions {

Captulo 10 Forms: criando formulrios - 83 // (...) // Mtodo para criao de novo registro public function executeNew(sfWebRequest $request) { // Cria uma nova instncia de LivroForm // e o disponibiliza para a View. // // Como no est vinculado a um registro pr-existente, // quando for chamado $form->getObject()->isNew() // resultar "true", e ento as opes para novo registro // sero exibidas na View, como no caso de para qual ao // ser enviada o formulrio $this->form = new LivroForm(); } // Mtodo que processa a criao de um novo registro public function executeCreate(sfWebRequest $request) { // Se no foi recebido um POST, redireciona para // pgina no encontrada (erro 404) $this->forward404Unless($request->isMethod('post')); // Cria uma nova instncia de LivroForm $this->form = new LivroForm(); // Processa o formulrio atravs do mtodo // processForm desta classe (mais adiante) $this->processForm($request, $this->form); // Define o template como newSuccess.php // (o padro seria createSuccess.php)

Captulo 10 Forms: criando formulrios - 84 $this->setTemplate('new'); } // Mtodo para edio de registro public function executeEdit(sfWebRequest $request) { // Se no conseguir recuperar um parmetro "isbn" e com ele // recuperar um registro do banco de dados, retorna // pgina no encontrada (erro 404) com a mensagem: // Object livro does not exist $this->forward404Unless( $livro=Doctrine::getTable('Livro')->find(array($request>getParameter('isbn'))), sprintf('Object livro does not exist (%s).', $request->getParameter('isbn'))); // Cria uma nova instncia de LivroForm // mas agora com dados do livro recuperado do banco de dados $this->form = new LivroForm($livro); } // Mtodo que processa a atualizao do registro public function executeUpdate(sfWebRequest $request) { // Se no foi recebido um POST ou um PUT, redireciona para // pgina no encontrada (erro 404) // (ver informao sobre o PUT na seo sobre a apresentao // do formulrio mais adiante. $this->forward404Unless($request->isMethod('post') || $request->isMethod('put')); // Se no conseguir recuperar um parmetro "isbn" e com ele // recuperar um registro do banco de dados, retorna // pgina no encontrada (erro 404) com a mensagem:

Captulo 10 Forms: criando formulrios - 85 // Object livro does not exist $this->forward404Unless( $livro=Doctrine::getTable('Livro')->find(array($request>getParameter('isbn'))), sprintf('Object livro does not exist (%s).', $request->getParameter('isbn'))); // Cria uma nova instncia de LivroForm // mas agora com dados do livro recuperado do banco de dados $this->form = new LivroForm($livro); // Processa o formulrio atravs do mtodo // processForm desta classe (mais adiante) $this->processForm($request, $this->form); // Define o template como editSuccess.php // (o padro seria updateSuccess.php) $this->setTemplate('edit'); } // Mtodo que processa o envio do formulrio // em separado para evitar duplicidade de cdigo protected function processForm(sfWebRequest $request, sfForm $form) { // O mtodo bind do formulrio recupera os dados enviados // no $request para poder validar os dados $form->bind($request->getParameter( $form->getName()), $request->getFiles($form->getName())); // Realiza a validao do formulrio if ($form->isValid()) { // Se o formulrio foi validado, salva o registro

Captulo 10 Forms: criando formulrios - 86 $livro = $form->save(); // e ento redireciona para a tela edio, evitando // o problema de recarregar a pgina (F5) gerar um novo // envio do formulrio $this->redirect('livro/edit?isbn='.$livro->getIsbn()); } // Se o formulrio no foi validado, ento na exibio do // formulrio as mensagens de erro aparecero } } ?>

10.7. Exibindo o formulrio

At o momento s estudamos a configurao do formulrio, agora veremos como exib-lo no template.

10.7.1. Mtodo automatizado

A gerao automtica que realizamos no captulo Criando uma aplicao rpida com o Symfony nos d uma idia simples de como criar a parte visual do formulrio. O arquivo um partial que pode ser utilizado em qualquer lugar da aplicao. O arquivo segue comentado para melhor compreenso. apps/admin/modules/livro/templates/_form.php

Captulo 10 Forms: criando formulrios - 87

<!-Incluso de CSS e Javascript para o formulrio, se houver --> <?php include_stylesheets_for_form($form) ?> <?php include_javascripts_for_form($form) ?> <!-Tag "form" Algumas condies so includas para num nico arquivo trabalhar tanto edio quanto criao de registro. O objeto $form, criado pela ao, pode verificar se o objeto novo ou no (ou seja, ainda no foi salvo), e ento optar por montar o link com a ao create ou update. De mesmo modo, se no for novo, coloca a chave primria como parmetro (este um modo de fazer isto). --> <form action="<?php echo url_for('livro/'. ($form->getObject()->isNew() ? 'create' : 'update'). (!$form->getObject()->isNew() ? '? isbn='.$form->getObject()->getIsbn() : '')) ?>" method="post" <?php $form->isMultipart() and print 'enctype="multipart/form-data" ' ?>> <!-Novamente se for no for um objeto novo, o Symfony inclui um campo oculto para simular o mtodo PUT do HTTP (algo ainda pouco utilizado, e por isto simulado pelo Symfony para aumentar a segurana)

Captulo 10 Forms: criando formulrios - 88 --> <?php if (!$form->getObject()->isNew()): ?> <input type="hidden" name="sf_method" value="put" /> <?php endif; ?> <!-Montando a tabela base --> <table> <!-Utilizando a tag tfoot, ou rodap da tabela. Mesmo sendo informada aqui no incio, ser exibida ao final da tabela --> <tfoot> <td colspan="2"> <!-O boto de cancelar retorna para a listagem de registros --> &nbsp;<a href="<?php echo url_for('livro/index') ?>"> Cancel</a> <!-Se o registro no novo, ento exibe um boto para excluir. Como o uso do helper link_to montado o link, enviando a chave primria e ainda fazendo uso de um recurso de javascript para exibir uma janela de confirmao de excluso (Are you sure? Tem certeza?) --> <?php if (!$form->getObject()->isNew()): ?> &nbsp;<?php echo link_to('Delete', 'livro/delete?isbn='. $form->getObject()->getIsbn(), array('method' => 'delete',

Captulo 10 Forms: criando formulrios - 89 'confirm' => 'Are you sure?')) ?> <?php endif; ?> <!-Boto de envio --> <input type="submit" value="Save" /> </td> </tfoot> <tbody> <!-A renderizao do form propriamente dito --> <?php echo $form ?> </tbody> </table> </form>

10.7.2. Mtodo detalhado


Vimos que com o comando: <?php echo $form ?> todos os campos so listados em forma de tabela. Mas possvel especificar o layout campo a campo. O Symfony renderiza para cada campo trs partes: Rtulo: renderLabel()

<?php echo $form['email']->renderLabel() ?> // HTML <label for="pessoa_email">Email</label>

Captulo 10 Forms: criando formulrios - 90

Tag do formulrio: render()

<?php echo $form['email']->render() ?> // HTML <input type="text" name="pessoa[email]" id="pessoa_email" />

Mensagens

de

erro:

renderError()

(exibido

apenas

se

formulrio foi validado e o campo no passou na validao)

<?php echo $form['email']->renderError() ?> // HTML <ul class="error_list"> <li>Email invlido</li> </ul> possvel gerar tambm a linha de tabela inteira: // Gerando uma linha de tabela // No h diferena da linha gerada pelo // echo $form <?php echo $form['email']->renderRow() ?>

Captulo 10 Forms: criando formulrios - 91

Captulo 11 AJAX - 92

Captulo 11 AJAX

11.1. Introduo terica


J estudamos na introduo o conceito de AJAX. A grande questo do AJAX : AJAX deixa tudo muito legal, mas...

... AJAX d muito trabalho!!

Isto uma realidade muito em funo da quantidade de Javascript que necessrio escrever adicionalmente ao cdigo gerado no servidor. Entretando, com o Symfony, pouco se utiliza o Javascript - a no ser que se necessite de uma funcionalidade muitssimo especfica. Utilizando por padro o framework para AJAX Prototype possvel ter diversas funcionalidades com nenhuma ou pouca escrita de Javascript.

Captulo 11 AJAX - 93

11.2. Incluindo Javascript

No captulo Camada View: Apresentao conhecemos os Helpers. Existe um grupo de Helpers para Javascript. Seu uso bsico num layout ou template : <?php // Inclundo o Helper use_helper('Javascript') ; ?> <?php // Utilizando o Helper para criar uma funo echo javascript_tag(" function alterarNome() { ... } ") ?> <!-HTML Gerado: Para validar em XHTML gerado dentro da declarao CDATA --> <script type="text/javascript"> //<![CDATA[ function alterarNome() { ... } //]]> </script>

Captulo 11 AJAX - 94

11.3. Criando um link para uma funo


<?php echo link_to_function('Alterar Nome', "alterarNome()") ?> <!-HTML Gerado: --> <a href="#" onClick="alterarNome(); return none;">Alterar Nome</a> Existe ainda o Helper button_to_function, que faz um link para uma funo num boto, ou ento possvel fazer uma imagem clicvel que aciona uma funo em javascript; basta mudar o primeiro parmetro de link_to_function, para image_tag('imagem.png').

11.4. Alterado o contedo de um elemento HTML


<div id="processando">Iniciado processamento</div> <?php echo javascript_tag( update_element_function('processando', array( 'content' => "Processamento completo", )) ) ?> // Colocando o contedo aps o contedo atual // com "before" seria antes. update_element_function('processando', array( 'position' => 'after', 'content' => "Agora o contedo ficou depois", ));

Captulo 11 AJAX - 95

11.5. Chamando uma funo remota


Aqui realmente comea a interao via AJAX. Inicialmente precisamos confirmar se o acesso biblioteca do AJAX est disponvel. symfony plugin:install sfProtoculousPlugin Agora s utilizar os recursos do AJAX. Vamos criar uma pequena ao para teste: apps/admin/modules/livro/actions/action.class.php

<?php class livroActions extends sfActions { // (...) // Mtodo para devolver um valor via AJAX public function executeAjax($request) { // Testando se uma requisio AJAX vlida if($this->getRequest()->isXmlHttpRequest()) { // Retornando um texto concatenado com o parmetro enviado return $this->renderText('Ok, recebi uma requisio: ' . $request->getParameter('valor')); } else { // Se a requisio no AJAX, ento envia uma mensage de erro return $this->renderText('Requisio mal formatada'); } } ?>

Captulo 11 AJAX - 96 Agora vamos adicionar um cdigo index do mdulo livro para aprendermos como fazer a requisio e recuperar o valor em um elemento do HTML: apps/admin/modules/livro/templates/indexSuccess.php

<?php // Inclundo o Helper use_helper('Javascript') ; // (...) ?> <!-- div que recebe o retorno da requisio AJAX --> <div id="retorno"></div> <?php /* A funo link_to_remote */ echo link_to_remote('Teste de Ajax', array( 'update' => 'retorno', 'url' => 'livro/ajax?valor=TESTANDO', )) ?> <?php /* A funo link_to_remote com confirmao */ echo link_to_remote('Teste de Ajax', array( 'update' => 'retorno',

Captulo 11 AJAX - 97 'url' => 'livro/ajax?valor=TESTANDO', 'confirm' => 'Tem certeza?', )) ?> <?php /* A funo link_to_remote com mtodo GET */ echo link_to_remote('Teste de Ajax', array( 'update' => 'retorno', 'url' => 'livro/ajax?valor=TESTANDO', 'method' => 'get', )) ?> Se a inteno que a funo seja executada imediatamente no carregamento da pgina, ento utilziada o helper remote_function: <?php // Inclundo o Helper use_helper('Javascript') ; // (...) ?> <!-- div que recebe o retorno da requisio AJAX --> <div id="retorno"></div> <?php /* A funo remote_function */

Captulo 11 AJAX - 98 echo remote_function('Teste de Ajax', array( 'update' => 'retorno', 'url' => 'livro/ajax?valor=TESTANDO', )) ?>

11.5.1. Atualizaes Peridicas

Este tipo de chamada AJAX realizada para atualizar constantemente uma pgina, como por exemplo para checar o recebimento de novos emails. <div id="retorno"></div> <?php // "frequency" o tempo em segundos // "with" permite passar como parmetro o valor de algum elemento // do HTML (utilizando a syntaxe do Prototype) echo periodically_call_remote(array( 'frequency' => 60, 'update' => 'retorno', 'url' => 'modulo/acao', 'with'=> "'param=' + \$F('mycontent')", )) ?>

Captulo 11 AJAX - 99

11.5.2. Formulrios AJAX


Vamos fazer um exemplo com o formulrio do mdulo categoria. Primeiramente, criamos uma ao para tratar a requisio AJAX de envio do formulrio: <?php class categoriaActions extends sfActions { // (...) // Mtodo que trata o formulrio via AJAX public function executeCreateajax(sfWebRequest $request) { // Verifica se uma requisio AJAX e se um // formulrio enviado if($request->isXmlHttpRequest() && $request->isMethod('post')) { // Cria uma nova instncia de CategoriaForm $this->form = new CategoriaForm(); // O mtodo bind do formulrio recupera os dados enviados // no $request para poder validar os dados $this->form->bind($request->getParameter( $this->form->getName()), $request->getFiles($this->form->getName())); // Realiza a validao do formulrio if ($this->form->isValid()) { // Se o formulrio foi validado, salva o registro $categoria = $this->form->save(); // Devolve uma mensagem via AJAX - ok return $this->renderText('Registro Salvo');

Captulo 11 AJAX - 100 } else { // Devolve uma mensagem via AJAX - erro return $this->renderText('Erro ao salvar registro'); } } else { // Se no uma requisio AJAX ou no um POST // devolve uma mensagem de erro return $this->renderText('Requisio mal formatada'); } } } ?>

11.5.3. Callbacks
Callbacks so aes que so executadas durante a requisio AJAX. O uso mais comum delas dar ao usurio uma noo de que o "servidor est trabalhando" enquanto ele aguarda uma requisio - os famosos "Carregando" ou imagem com animao. Os callbacks so os seguintes: before: Antes da requisio ser iniciada after: Imediatamente aps a requisio ser inicia e antes de carregar loading: Quando a resposta remota est sendo carregada pelo navegador loaded: Quando o navegador terminou de carregar a resposta remota interactive: quando o usurio pode interagir com a resposta remota, mesmo que ainda no tenha terminado

Captulo 11 AJAX - 101 success: Quando o XMLHttpRequest est completo, e o status HTTP est na faixa 2xx failure: Quando o XMLHttpRequest est completo, e o status HTTP no est na faixa 2xx 404: Quando a requisio retorna o status 404 complete: Quando XMLHttpRequest est completo (gerado logo aps success ou failure, se ocorrerem) O exemplo clssico: um "Carregando": <div id="retorno"></div> <div id="carregando">Carregando algo...</div> <?php echo link_to_remote('Vamos pegar algo', array( 'update'=> 'retorno', 'url'=> 'modulo/acao', 'loading' => "Element.show('carregando')", 'complete' => "Element.hide('carregando')", )) ?>

Captulo 11 AJAX - 102

Captulo 11 AJAX - 103

Apndices

Captulo 12 ApndiceBanco de dados "livraria" - 104

Captulo 12 Apndice Banco de dados "livraria"

--- Banco de Dados: `livraria444` --

CREATE DATABASE `livraria444` DEFAULT CHARACTER SET utf8 COLLATE utf8_unicode_ci;

USE `livraria444`;

SET FOREIGN_KEY_CHECKS=0;

SET SQL_MODE="NO_AUTO_VALUE_ON_ZERO";

/*!40101 @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */; /*!40101 @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */;

SET

SET

Captulo 12 ApndiceBanco de dados "livraria" - 105 /*!40101 @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */; /*!40101 SET NAMES utf8 */; SET

--- Estrutura da tabela `categoria` --

DROP TABLE IF EXISTS `categoria`; CREATE TABLE IF NOT EXISTS `categoria` ( `cat_id` int(10) unsigned NOT NULL auto_increment, `descricao` char(60) collate utf8_unicode_ci NOT NULL, PRIMARY KEY (`cat_id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;

--- Estrutura da tabela `cliente` --

DROP TABLE IF EXISTS `cliente`; CREATE TABLE IF NOT EXISTS `cliente` ( `cliente_id` int(10) unsigned NOT NULL auto_increment,

Captulo 12 ApndiceBanco de dados "livraria" - 106 `nome` char(60) collate utf8_unicode_ci NOT NULL, `endereco` char(80) collate utf8_unicode_ci NOT NULL, `cidade` char(30) collate utf8_unicode_ci NOT NULL, `uf` char(20) collate utf8_unicode_ci default NULL, `cep` char(9) collate utf8_unicode_ci default NULL, PRIMARY KEY (`cliente_id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;

--- Estrutura da tabela `livro` --

DROP TABLE IF EXISTS `livro`; CREATE TABLE IF NOT EXISTS `livro` ( `isbn` char(13) collate utf8_unicode_ci NOT NULL, `autor` char(80) collate utf8_unicode_ci default NULL, `titulo` char(100) collate utf8_unicode_ci default NULL, `cat_id` int(10) unsigned default NULL, `preco` float(10,2) NOT NULL, `sumario` varchar(1000) collate utf8_unicode_ci default NULL, PRIMARY KEY (`isbn`), KEY `cat_id` (`cat_id`)

Captulo 12 ApndiceBanco de dados "livraria" - 107 ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;

--- Estrutura da tabela `pedido` --

DROP TABLE IF EXISTS `pedido`; CREATE TABLE IF NOT EXISTS `pedido` ( `pedido_id` int(10) unsigned NOT NULL auto_increment, `cliente_id` int(10) unsigned NOT NULL, `total` float(6,2) default NULL, `data_pedido` date NOT NULL, `status` char(10) collate utf8_unicode_ci default NULL, `entrega_nome` char(60) collate utf8_unicode_ci NOT NULL, `entrega_endereco` char(80) collate utf8_unicode_ci NOT NULL, `entrega_cidade` char(30) collate utf8_unicode_ci NOT NULL, `entrega_uf` char(20) collate utf8_unicode_ci default NULL, `entrega_cep` char(9) collate utf8_unicode_ci default NULL, `forma_pagto` enum('BOLETO','DEPSITO','CARTO') collate utf8_unicode_ci NOT NULL, PRIMARY KEY (`pedido_id`), KEY `cliente_id` (`cliente_id`)

Captulo 12 ApndiceBanco de dados "livraria" - 108 ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci ;

--- Estrutura da tabela `pedidoitem` --

DROP TABLE IF EXISTS `pedidoitem`; CREATE TABLE IF NOT EXISTS `pedidoitem` ( `peditem_id` int(10) unsigned NOT NULL auto_increment, `pedido_id` int(10) unsigned NOT NULL, `isbn` char(13) collate utf8_unicode_ci NOT NULL, `preco` float(10,2) NOT NULL, `quantidade` tinyint(3) unsigned NOT NULL, PRIMARY KEY (`peditem_id`), KEY `pedido_id` (`pedido_id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci ;

--- Estrutura da tabela `usuario` --

DROP TABLE IF EXISTS `usuario`; CREATE TABLE IF NOT EXISTS `usuario` (

Captulo 12 ApndiceBanco de dados "livraria" - 109 `login` char(16) collate utf8_unicode_ci NOT NULL, `nome` char(16) collate utf8_unicode_ci NOT NULL, `senha` char(40) collate utf8_unicode_ci NOT NULL, `perfil` enum('admin','gerente','despacho') collate utf8_unicode_ci NOT NULL, PRIMARY KEY (`login`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;

--- Restries para as tabelas dumpadas --

--- Restries para a tabela `livro` -ALTER TABLE `livro` ADD CONSTRAINT `livro_ibfk_1` FOREIGN KEY (`cat_id`) REFERENCES `categoria` (`cat_id`);

--- Restries para a tabela `pedido` -ALTER TABLE `pedido`

Captulo 12 ApndiceBanco de dados "livraria" - 110 ADD CONSTRAINT `pedido_ibfk_1` FOREIGN KEY (`cliente_id`) REFERENCES `cliente` (`cliente_id`);

--- Restries para a tabela `pedidoitem` -ALTER TABLE `pedidoitem` ADD CONSTRAINT `pedidoitem_ibfk_1` FOREIGN KEY (`pedido_id`) REFERENCES `pedido` (`pedido_id`);

SET FOREIGN_KEY_CHECKS=1;

Captulo 13 ApndicesfDoctrineGuard plugin - 111

Captulo 13 Apndice sfDoctrineGuard plugin

http://www.symfony-project.org/plugins/sfDoctrineGuardPlugin

sfDoctrineGuardPlugin um plugin do Symfony que fornece capacidade autenticao e autorizao sobre o padro de segurana do Symfony. Lhe d um Model (objetos usurio, grupo e permisso) e mdulos

(backend/retaguarda e frontend/frente) para implementar segurana em sua aplicao Symfony em um minuto num plugin configurvel Para instalar o plugin: symfony plugin:install sfDoctrineGuardPlugin Reconstrua seu Model: symfony doctrine:build-model symfony doctrine:build-sql symfony doctrine:build-forms symfony doctrine:build-filters Atualize as tabelas de seu banco de dados reiniciando-as (isto vai excluir todas as tabelas e recri-las symfony doctrine:insert-sql

Captulo 13 ApndicesfDoctrineGuard plugin - 112 Ative um ou mais mdulos no seu settings.yml (opcional) Para sua aplicao backend/retaguarda: sfGuardUser, sfGuardGroup,

sfGuardPermission Para sua aplicao frontend/frente: sfGuardAuth all: .settings: enabled_modules:[default, sfGuardGroup, sfGuardUser, sfGuardPermission] Limpe seu cache symfony cc Opcionalmente crie um usurio padro symfony guard:create-user fabien $secret Opcionalmente ative o filtro "Remember Me" em filters.yml security: class: sfGuardBasicSecurityFilter

13.1.1. Implementando segurana em sua aplicao


Para implementar a segurana em uma aplicao Symfony: Ativando o mdulo sfGuardAuth em settings.yml all: .settings: enabled_modules: [..., sfGuardAuth] Altere o padro para os mdulos de login e segurana em settings.yml login_module:sfGuardAuth login_action:signin secure_module: sfGuardAuth secure_action: secure

Captulo 13 ApndicesfDoctrineGuard plugin - 113

Altere a classe pai em myUser.class.php class myUser extends sfGuardSecurityUser { } Adicionamente altere as regras de forward em routing.yml sf_guard_signin: url:/login param: { module: sfGuardAuth, action: signin } sf_guard_signout: url:/logout param: { module: sfGuardAuth, action: signout } sf_guard_password: url:/request_password param: { module: sfGuardAuth, action: password } Voc pode personalizar o parmetro url em cada rota. Voc deve ter uma regra de roteamento @homepage (utilizado quando o usurio faz logout). Estas rotas so automativamente registradas pelo plugin se o mdulo sfGuardAuth ativado, a no ser que voc defina sf_guard_plugin_routes_register para falso no arquivo de configurao app.yml all: sf_guard_plugin: routes_register: false Ative a segurana para alguns mdulos ou para a aplicao inteira em security.yml default:

Captulo 13 ApndicesfDoctrineGuard plugin - 114 is_secure: on Est feito. Agora, se voc tentar acessar uma pgina segura, ser

redirecionado para a pgina de login. Se voc carregou o arquivo padro de dados do plugin, tente logar com o usurio admin com a senha admin.

13.1.2. Administrando seus usurios, permisses e grupos


Para administrar seus usurios, permisses e grupos, o sfDoctrineGuardPlugin vem com 3 mdulos que podem ser integrados sua aplicao backend/retaguarda. Estes mdulos so auto-gerados graas ao Symfony Admin Generator. Ative os mdulos em settings.yml all: .settings: enabled_modules: [..., sfGuardGroup, sfGuardPermission, sfGuardUser] Acesse os mdulos com a rota padro: http://livraria.local/sfGuardUser

13.1.3. Personalizando os templates do mdulo sfGuardAuth


Por padro, o mdulo sfGuardAuth vem com dois templates muito simples: signinSuccess.php secureSuccess.php

Se voc quer personalizar um destes templates: Crie o mdulo sfGuardAuth em sua aplicao (no utilize a tarefa initmodule, apenas crie o diretrio sfGuardAuth) Crie um template com o nome do template que voc quer personalizar no diretrio sfGuardAuth/templates O Symfony agora monta seu template ao invs do padro.

Captulo 13 ApndicesfDoctrineGuard plugin - 115

13.1.4. Personalizando os templates do mdulo sfGuardAuth


Se voc quer personalizar ou adicionar mtodos ao sfGuardAuth: Crie um mdulo sfGuardAuth em sua aplicao Crie um arquivo actions.class.php em seu diretrio actions que herde de BasesfGuardAuthActions Symfony) <?php require_once(sfConfig::get('sf_plugins_dir'). '/sfDoctrineGuardPlugin/modules/sfGuardAuth/lib/BasesfGuardAuthActions. class.php'); class sfGuardAuthActions extends BasesfGuardAuthActions { public function executeNewAction() { return $this->renderText('This is a new sfGuardAuth action.'); } } ?> (no esquea de incluir BasesfGuardAuthActionspois ele no pode ser autocarregado pelo

13.1.5. Classe sfGuardSecurityUser


Esta classe herda da classe sfBasicSecurityUser do Symfony e utilizada pelo objeto user na sua aplicao Symfony (por que voc modificou a classe base myUser anteriormente). Ento, para acess-la, voc pode utilzizar o padro $this-;gt;getUser() em suas aes ou $sf_user em seus templates.

Captulo 13 ApndicesfDoctrineGuard plugin - 116 sfGuardSecurityUser adiciona alguns mtodos: signIn() and signOut() getGuardUser() que retorna o objeto sfGuardUser Um conjunto de mtodos "proxy" para acessar diretamente o objeto sfGuardUser Por exemplo, para recuperar o nome de usurio atual: $this->getUser()->getGuardUser()->getUsername() // ou via proxy method $this->getUser()->getUsername()

13.1.6. Flag superadministrador


O sfDoctrineGuardPlugin tem o conceito de super administrator. Um usurio que superadministrador sobrepem-se a todas as checagens de credencial. A flag de superadministrador no pode ser definida via web, voc deve definir esta flag diretamente no banco de dados ou atravs da tarefa de linha de comando: symfony promote-super-admin admin symfony guard:promote admin (verso 3.1.3)

13.1.7. Validators (Validadores)


O sfDoctrineGuardPlugin vem com um validador para voc utilizar em seus mdulos: sfGuardUserValidator. Este validador utilizado pelo mdulo sfGuardAuth para validar o usurio e senha e automaticamente logar o usurio.

Captulo 13 ApndicesfDoctrineGuard plugin - 117

13.1.8. Personalizando o Model sfGuardUser


O Model sfGuardUser muito simples. No h colunas email ou first-name ou birthday. Como voc no pode adicionar mtodos classe, o sfAuthPlugin possibilita definir uma classe com o perfil do usurio. Por padro, sfGuardUser procura a classe sfGuardUserProfile. Aqui est um exemplo simples de uma classe sfGuardUserProfile que voc pode adicionar ao schema.yml: sf_guard_user_profile: _attributes: { phpName: sfGuardUserProfile } id: user_id: { type: integer, foreignTable: sf_guard_user, foreignReference: id, required: true, onDelete: cascade } first_name: varchar(20) last_name:varchar(20) birthday: date Agora voc pode acessar os dados do usurio atravs do objeto user: $this->getUser()->getGuardUser()->getProfile()->getFirstName() // or via the proxy method $this->getUser()->getProfile()->getFirstName() O mtodogetProfile() recupera o objeto de perfil de usurio associado ou cria um novo se ainda no existe. Quando voc exclui um usurio, o perfil associado tambm excludo. Voc pode mudar o nome da classe de perfil de usurio e o nome da chave estrangeira em app.yml: all: sf_guard_plugin: profile_class:sfGuardUserProfile profile_field_name: user_id

Captulo 13 ApndicesfDoctrineGuard plugin - 118

13.1.9. Checar a senha do usurio com um mtodo externo


Se voc no pode armazenar a senha no banco de dados porque possui um servidor LDAP, um arquivo .htaccess ou voc armazena sua suas senhas em outra tabela, voc pode informar sua prpria chamada checkPassword (mtodo esttico ou funo) em app.uml all: sf_guard_plugin: check_password_callable: [MyLDAPClass, checkPassword] Quando o Symfony chama o mtodo $this->getUser()->checkPassword(), ir chamar seu mtodo ou funo. Sua funo deve receber dois parmetros, o primeiro o nome de usurio e o segundo a senha. Deve retornar true ou false. Aqui segue um modelo para esta funo: function checkLDAPPassword($username, $password) { $user = LDAP::getUser($username); if ($user->checkPassword($password)) { return true; } else { return false; } }

Captulo 13 ApndicesfDoctrineGuard plugin - 119

13.1.10. Alterar o algoritmo utilizado para armazenar senhas


Por padro, senhas so armazenadas num hash sha1(). Mas voc pode modificar isto para qualquer chamada em app.yml: all: sf_guard_plugin: algorithm_callable: [MyCryptoClass, MyCryptoMethod] # or all: sf_guard_plugin: algorithm_callable: md5 Como o algoritmo armazenado para cada usurio, voc pode mudar de idia depois sem a necessidade de regerar todas as senhas atuais dos usurios.

13.1.11. Alterando o nome ou o perodo de expirao do cookie "Remember Me"


Por em app.yml: all: sf_guard_plugin: remember_key_expiration_age: 2592000# 30 days in seconds remember_cookie_name: myAppRememberMe padro, a funcionalide Remember Me cria um cookie chamado sfRemember vai permanecer por 15 dias. Voc pode modificar este comportamente

Captulo 13 ApndicesfDoctrineGuard plugin - 120

13.1.12. Personalizando a manipulao de redirecionamento de sfGuardAuth


Se voc deseja redirecionar o usurio para seu perfil aps um login ou definir um destino de logout, voc pode alterar os valores de redirecionamente em app.yml: all: sf_guard_plugin: # the plugin use the referer as default success_signin_url:@my_route?param=value # the plugin use the referer as default success_signout_url: module/action

13.1.13. Configurando o formulrio de login


Voc pode modificar o formurio de login do mdulo sfGuardAuth em app.yml: all: sf_guard_plugin: signin_form: sfGuardFormSigninCustom

Vous aimerez peut-être aussi