Your SlideShare is downloading. ×
Manual cake
Manual cake
Manual cake
Manual cake
Manual cake
Manual cake
Manual cake
Manual cake
Manual cake
Manual cake
Manual cake
Manual cake
Manual cake
Manual cake
Manual cake
Manual cake
Manual cake
Manual cake
Manual cake
Manual cake
Manual cake
Manual cake
Manual cake
Manual cake
Manual cake
Manual cake
Manual cake
Manual cake
Manual cake
Manual cake
Manual cake
Manual cake
Manual cake
Manual cake
Manual cake
Manual cake
Manual cake
Manual cake
Manual cake
Manual cake
Manual cake
Manual cake
Manual cake
Manual cake
Manual cake
Manual cake
Manual cake
Manual cake
Manual cake
Manual cake
Manual cake
Manual cake
Manual cake
Manual cake
Manual cake
Manual cake
Manual cake
Manual cake
Manual cake
Manual cake
Manual cake
Manual cake
Manual cake
Manual cake
Manual cake
Manual cake
Manual cake
Manual cake
Manual cake
Manual cake
Manual cake
Manual cake
Manual cake
Manual cake
Manual cake
Manual cake
Manual cake
Manual cake
Manual cake
Manual cake
Upcoming SlideShare
Loading in...5
×

Thanks for flagging this SlideShare!

Oops! An error has occurred.

×
Saving this for later? Get the SlideShare app to save on your phone or tablet. Read anywhere, anytime – even offline.
Text the download link to your phone
Standard text messaging rates apply

Manual cake

4,258

Published on

Manual CakePHP 1.2

Manual CakePHP 1.2

Published in: Education
0 Comments
2 Likes
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total Views
4,258
On Slideshare
0
From Embeds
0
Number of Embeds
1
Actions
Shares
0
Downloads
231
Comments
0
Likes
2
Embeds 0
No embeds

Report content
Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
No notes for slide

Transcript

  • 1. MANUAL CAKEPHP 1.2 Juan Basso 3 de março de 2008
  • 2. SumárioPARTE I. COMEÇANDO COM CAKEPHP ......................................................................7Prefácio ................................................................................................................................................. 7 Requisitos do leitor .................................................................................................................................. 7Introdução ao CakePHP ......................................................................................................................... 7 O que é CakePHP? Por que usar? ............................................................................................................. 7 Onde obter ajuda? ................................................................................................................................... 8Entendendo o Model-View-Controller (MVC) ........................................................................................ 9 Introdução ................................................................................................................................................ 9 Benefícios ............................................................................................................................................... 10PARTE II. PRINCÍPIOS BÁSICOS DO CAKEPHP ....................................................... 11Estrutura CakePHP ............................................................................................................................... 11 Extensões de controller ......................................................................................................................... 11 Extensões de view .................................................................................................................................. 11 Extensões do model ............................................................................................................................... 11 Extensões de aplicação .......................................................................................................................... 12Estrutura de arquivos do CakePHP ....................................................................................................... 12 Estrutura do diretório App ..................................................................................................................... 13Requisição típica do CakePHP .............................................................................................................. 13Convenções CakePHP ........................................................................................................................... 15 Convenções de arquivos e nome de classes .......................................................................................... 15 Convenções de modelos ........................................................................................................................ 15 Convenções de controladores................................................................................................................ 15 Convenções de visões ............................................................................................................................ 16PARTE III. DESENVOLVENDO COM CAKEPHP ...................................................... 17Requisitos ............................................................................................................................................ 17Preparativos para instalação................................................................................................................ 17 Baixando o CakePHP .............................................................................................................................. 17 Permissões ............................................................................................................................................. 17Instalação ............................................................................................................................................ 18 Desenvolvimento ................................................................................................................................... 18 Produção ................................................................................................................................................ 18 Instalação avançada ............................................................................................................................... 19 Caminho de classes adicionais ........................................................................................................... 20 i
  • 3. Apache e mod_rewrite .......................................................................................................................... 20 Comece agora! ....................................................................................................................................... 20Configuração........................................................................................................................................ 21 Configuração da base de dados ............................................................................................................. 21 Configuração do núcleo ......................................................................................................................... 22 As classes de configuração ..................................................................................................................... 22 Classes de configuração ..................................................................................................................... 22 Variáveis de configuração do núcleo ................................................................................................. 22 Constantes de configuração .............................................................................................................. 22 Configuração de rotas (Routes) ............................................................................................................. 22 Inflexão personalizada ........................................................................................................................... 23 Configuração de inicialização (bootstrap) .............................................................................................. 24Controllers (Controladores) ................................................................................................................. 24 Introdução .............................................................................................................................................. 24 Atributos ................................................................................................................................................ 25 $name ................................................................................................................................................ 25 $components, $helpers e $uses ........................................................................................................ 25 Relativo à página: $layout e $pageTitle ............................................................................................. 26 Atributos dos parâmetros ($params) ................................................................................................ 26 Outros atributos ................................................................................................................................ 27 Métodos ................................................................................................................................................. 28 Interagindo com as visões ................................................................................................................. 28 Fluxo de controle ............................................................................................................................... 29 Callbacks ............................................................................................................................................ 29 Outros métodos ................................................................................................................................. 30Components (Componentes) ............................................................................................................... 33 Introdução .............................................................................................................................................. 33 Construindo componentes personalizados............................................................................................ 33 Acessando classes do MVC de dentro dos componentes ...................................................................... 34Models (Modelos)................................................................................................................................ 34 Introdução .............................................................................................................................................. 34 Campos mágicos .................................................................................................................................... 34 Atributos ................................................................................................................................................ 34 Métodos ................................................................................................................................................. 34 Associações ............................................................................................................................................ 34 Introdução ......................................................................................................................................... 34 hasOne ............................................................................................................................................... 35 belongsTo .......................................................................................................................................... 37 hasMany ............................................................................................................................................ 38 hasAndBelongsToMany (HABTM) ...................................................................................................... 41 Salvando dados em tabelas relacionadas (hasOne, hasMany, belongsTo) ....................................... 43 Salvando dados em tabelas relacionadas (HABTM) .......................................................................... 44 Criando e removendo relações durante execução ............................................................................ 45 DataSources ........................................................................................................................................... 47 Behaviors................................................................................................................................................ 47 ii
  • 4. Introdução ......................................................................................................................................... 47 Usando Behaviors .............................................................................................................................. 47 TreeBehavior ..................................................................................................................................... 47 TranslateBehavior .............................................................................................................................. 47 ACLBehavior ....................................................................................................................................... 47Views (Visões)...................................................................................................................................... 47 Templates / Skin ..................................................................................................................................... 47 Layouts ................................................................................................................................................... 48 Elements (Elementos) ............................................................................................................................ 50Helpers (Ajudantes) ............................................................................................................................. 50 Introdução .............................................................................................................................................. 50 Helpers do CakePHP ............................................................................................................................... 51 Criando helpers ...................................................................................................................................... 52 Incluindo outros helpers .................................................................................................................... 52 Usando seus helpers personalizados ................................................................................................. 53 Contribuindo ...................................................................................................................................... 53Scaffolding ........................................................................................................................................... 53 Introdução .............................................................................................................................................. 53 Personalizando os scaffolds ................................................................................................................... 54CakePHP Console ................................................................................................................................. 55 Introdução .............................................................................................................................................. 55 Criando Shells e Tasks ............................................................................................................................ 55 Criando suas Shells ............................................................................................................................ 55 Tasks .................................................................................................................................................. 55Gerando código com Bake ................................................................................................................... 55Plugins ................................................................................................................................................. 55 Criando um plugin .................................................................................................................................. 55 Plugin de controladores ..................................................................................................................... 55 Plugin de modelos ............................................................................................................................. 55 Plugin de visões ................................................................................................................................. 55 Plugin de informações ....................................................................................................................... 55Constantes e funções globais ............................................................................................................... 55 Funções globais ...................................................................................................................................... 55 Constantes do núcleo ............................................................................................................................. 58 Constantes do diretório ......................................................................................................................... 58PARTE IV. TAREFAS COMUNS COM CAKEPHP ......................................................... 60Validação de dados .............................................................................................................................. 60 Regras simples ....................................................................................................................................... 60 Uma regra por campo ............................................................................................................................ 60 rule ..................................................................................................................................................... 60 iii
  • 5. required ............................................................................................................................................. 60 allowEmpty ........................................................................................................................................ 60 on ....................................................................................................................................................... 60 message ............................................................................................................................................. 60 Múltiplas regras por campo ................................................................................................................... 60 Construindo regras de validação ............................................................................................................ 60 alphaNumeric .................................................................................................................................... 60 between ............................................................................................................................................. 60 blank .................................................................................................................................................. 60 cc ........................................................................................................................................................ 60 comparison ........................................................................................................................................ 60 date .................................................................................................................................................... 60 email .................................................................................................................................................. 60 ip ........................................................................................................................................................ 60 minLength .......................................................................................................................................... 60 maxLength ......................................................................................................................................... 60 numeric .............................................................................................................................................. 60 phone ................................................................................................................................................. 60 postal ................................................................................................................................................. 60 ssn ...................................................................................................................................................... 60 url ....................................................................................................................................................... 60 Regras de validação personalizada ........................................................................................................ 60 Validação por expressões regulares personalizadas ......................................................................... 61 Validação por métodos personalizados ............................................................................................. 61Limpeza de dados ................................................................................................................................ 61Manipulação de erros .......................................................................................................................... 61Debugando .......................................................................................................................................... 61Gerando caches ................................................................................................................................... 61Logando ............................................................................................................................................... 61 Introdução .............................................................................................................................................. 61 Usando as funções de log ...................................................................................................................... 61Testando .............................................................................................................................................. 62Internacionalizando ............................................................................................................................. 62 Definindo o locale da sua aplicação ....................................................................................................... 62 Internacionalizando em CakePHP .......................................................................................................... 63Paginação ............................................................................................................................................ 64 Configurando os controladores ............................................................................................................. 64 Paginando nas visões ............................................................................................................................. 64 Paginando com AJAX .............................................................................................................................. 64 Alterações no layout .......................................................................................................................... 64 Alterações nas visões ......................................................................................................................... 64 iv
  • 6. PARTE V. COMPONENTES INTERNOS ....................................................................... 65Lista de controle de acessos (ACL)........................................................................................................ 65Autenticação........................................................................................................................................ 65Sessões ................................................................................................................................................ 65Manipulando requisições ..................................................................................................................... 65Segurança ............................................................................................................................................ 65E-mail .................................................................................................................................................. 65Cookies ................................................................................................................................................ 65 Introdução .............................................................................................................................................. 65 Configurando os controladores ............................................................................................................. 65 Usando o componente ........................................................................................................................... 65PARTE VI. HELPERS INTERNOS .................................................................................... 66Formulários ......................................................................................................................................... 66 Criando formulários ............................................................................................................................... 66 $options[type].................................................................................................................................. 66 $options[action] ............................................................................................................................... 67 $options[url] .................................................................................................................................... 67 $options[default] ............................................................................................................................. 67 Fechando formulários ............................................................................................................................ 68 Elemento de formulário mágico ............................................................................................................ 68 $options[type].................................................................................................................................. 69 $options[before], $options[between] e $options[after].............................................................. 69 $options[options]............................................................................................................................. 69 $options[multiple] ........................................................................................................................... 70 $options[maxLength] ....................................................................................................................... 70 $options[div] .................................................................................................................................... 70 $options[label] ................................................................................................................................. 70 $options[id] ...................................................................................................................................... 70 $options[error] ................................................................................................................................ 70 $options[selected] ........................................................................................................................... 70 $options[rows], $options[cols] ...................................................................................................... 70 $options[empty] .............................................................................................................................. 70 $options[timeFormat] ...................................................................................................................... 70 $options[dateFormat] ...................................................................................................................... 71 Métodos específicos do elemento de formulário .................................................................................. 71HTML ................................................................................................................................................... 73 Inserindo elementos bem-formados ..................................................................................................... 73JavaScript............................................................................................................................................. 73 v
  • 7. AJAX ....................................................................................................................................................... 73 Opções do AjaxHelper ............................................................................................................................ 73 Opções gerais..................................................................................................................................... 73 Opções de callback ............................................................................................................................ 73 Métodos ................................................................................................................................................. 73Cache ................................................................................................................................................... 73Form .................................................................................................................................................... 73Number ............................................................................................................................................... 73Text ..................................................................................................................................................... 73Time..................................................................................................................................................... 73PARTE VII. EXEMPLOS .................................................................................................. 74Tutorial de como fazer um blog em CakePHP ....................................................................................... 74Sistema simples de autenticação de usuários ...................................................................................... 74PARTE VIII. APÊNDICES ................................................................................................. 75Escritores da versão inglesa ................................................................................................................. 75Tradutores para língua portuguesa ...................................................................................................... 75 Apoio e revisão da versão traduzida ...................................................................................................... 75Inflexão em português ......................................................................................................................... 75 vi
  • 8. Começando com CakePHP 7 Parte I. Começando com CakePHPPrefácioBem vindo ao paraíso de desenvolvimento web.Se você está lendo o prefácio de um manual técnico, é porque está lhe sobrando bastantetempo. Não somos celebridades e o material é o que vem depois. Você pode pular estescapítulos supérfluos e ir direto ao ponto nas seções que você quer.Requisitos do leitorPara ler este manual, você já deve estar familiarizado com o PHP. Conhecer de programaçãoorientada a objeto irá lhe ajudar bastante, porém eu suponho que as seções de introduçãodeste manual servirão como um bom exemplo do que vem pela frente. Com isso, este materialé escrito para desenvolvedores de todos os níveis de habilidade que desejam criar algorobusto, sustentável, rápido e agradável.Devo alertar que haverá seções que abordam tecnologias que estão realmente fora do âmbitodeste manual. Administração de servidor Web, AJAX e JavaScript, por exemplo, podem sermencionados em partes do texto, mas na maior parte do texto nós estaremos focado noCakePHP.Introdução ao CakePHPO que é CakePHP? Por que usar?CakePHP é gratuito, de código aberto, uma framework em PHP para desenvolvimento ágil. Éuma estrutura fundamental para programadores criarem aplicações web. Nosso principalobjetivo é permitir que você trabalhe em uma estrutura que possa programar de forma rápidae sem a perda de flexibilidade.CakePHP joga fora a monotonia do desenvolvimento web. Nós oferecemos todas asferramentas que você precisa para começar programando o que realmente deseja: a lógicaespecífica da sua aplicação. Em vez de reinventar a roda cada vez que se constrói um novoprojeto, pegue uma cópia do CakePHP e comece a construir sua carruagem real da suaaplicação.CakePHP tem uma equipe de desenvolvedores e uma grande comunidade, trazendo grandevalor ao projeto. Além de manter você fora do reinvento da roda, usando CakePHP significaque o núcleo da sua aplicação é bem testado e constantemente aperfeiçoado.Abaixo segue uma pequena lista dos recursos que você poderá desfrutar no CakePHP:  Ativo e com comunidade amigável;  Licença flexível;  Compatibilidade com PHP 4 e PHP 5;  Integrando funcionalidade CRUD (Create, Read, Update and Delete, ou Criar, Ler, Atualizar e Excluir) para interagir com o banco de dados;
  • 9. Começando com CakePHP 8  Aplicações scaffolding;  Geração de código;  Arquitetura MVC (Model, View, Controller, ou Modelo, Visões, Controlador);  Requisições ao expedidor com clareza, URLs personalizáveis e rotas;  Validações internas;  Templates rápidos e flexíveis (Sintaxe PHP e com ajudantes);  Ajudantes para usar AJAX, JavaScript, HTML, formulários e outros nas visões;  Componentes de E-mail, Cookie, Segurança, Sessões, Manipulação de Requisições e outros;  Lista de controle de acessos flexível;  Limpeza de dados;  Flexibilidade com cache;  Internacionalização;  Funciona em qualquer subdiretório do seu website, com poucas configurações do Apache.Onde obter ajuda?Você começou no lugar certo. Este manual (e a API) deve ser provavelmente o primeiro lugarque você vá para procurar as respostas das suas dúvidas. Assim como acontece com muitosoutros projetos de código aberto, nós obtemos novos usuários regularmente. Tentamos ser osmelhores para responder seus questionamentos em primeiro lugar. As respostas podemdemorar a chegar, mas permanecerá por tempos e ajudará a esclarecer outras pessoas. Tantoo manual, quanto a API podem ser encontradas online.http://manual.cakephp.com.br (em português)http://manual.cakephp.org (em inglês)http://api.cakephp.org/1.2 (em inglês)Se você estiver assustado, dê um grito pelo canal de IRC internacional ou entre no grupo dacomunidade luso-brasileira. Além da equipe de desenvolvimento do núcleo do CakePHP nocanal, principalmente durante o dia. Se você precisar de alguma ajuda, deseja encontrarusuários na sua área ou gostaria de doar o novo carro esportivo, gostaríamos de falar comvocê.Grupo da comunidade luso-brasileira: http://groups.google.com/group/cake-php-pt#cakephp-pt @ irc.freenode.net (em português)#cakephp @ irc.freenode.net (em inglês)O CakePHP Bakery é uma casa para todas as coisas de CakePHP. Visite este site para vertutoriais, estudos de caso e exemplos de código. Assim que estiver familiarizado com oCakePHP, faça o login e compartilhe seus conhecimentos com a comunidade para ganhar famae fortuna.http://bakery.cakephp.org
  • 10. Começando com CakePHP 9O CakeForge é outro recurso que os desenvolvedores podem usar para hospedar seus projetosusando CakePHP e compartilhar com outras pessoas. Se você está olhando para achar projetosexistentes, ou querendo compartilhar, acesso o CakeForge.http://www.cakeforge.orgO site oficial do CakePHP está sempre esperando sua visita. Ele tem links para sites de outrosdesenvolvedores, screencasts, oportunidade para doar ao projeto e downloads.http://www.cakephp.orgEntendendo o Model-View-Controller (MVC)IntroduçãoAplicações bem escritas em CakePHP segue o design pattern MVC (Model-View-Controller ouModelo-Visão-Controlador). Programando em MVC separa sua aplicação em três partesprincipais. O model representa os dados, a view representa a visualização dos dados e ocontroller manipula e roteia as requisições dos usuários. Figura 1. Requisição típica do CakePHPA Figura 1 mostra um exemplo de uma simples requisição MVC em CakePHP. Para finsilustrativos, digamos que um usuário chamado Ricardo apenas clicou no link “Comprar umbolo personalizado agora!” da sua aplicação. 1. Ricardo clica no link apontando para http://www.exemplo.com.br/cakes/comprar e seu navegador faz uma requisição ao site; 2. O dispatcher (expedidor) verifica a URL requisitada (/cakes/comprar) e redireciona ao controller correto; 3. O controller executa a lógica específica da aplicação. Por exemplo, verifica se o Ricardo está logado; 4. O controller também usa os models para acessar os dados da sua aplicação. Muitas vezes, os models representam as tabelas do banco de dados, mas podem representar registros LDAP, feeds de RSS ou até mesmo arquivos do sistema. Neste exemplo, o controller usa o model para trazer ao Ricardo as últimas compras do banco de dados; 5. Depois que o controller fez sua mágica sobre os dados, ele repassa para a view. A view faz com que os dados fiquem prontos para a representação do usuário. As views em CakePHP normalmente vem no formato HTML, mas pode ser facilmente exibidas em
  • 11. Começando com CakePHP 10 PDF, documento XML, um objeto JSON ou outro formato qualquer, dependendo da sua necessidade; 6. Uma vez que a visão tenha usado os dados provenientes do controller para construir a página, o conteúdo é retornado ao browser do Ricardo.Aproximadamente toda requisição da sua aplicação seguirá o modelo básico do modelo. Nósvamos especificar os detalhes mais adiante, mas mantenha essa visão geral no seupensamento.BenefíciosPor que usar MVC? Porque é um verdadeiro padrão de desenvolvimento (design pattern) etorna fácil a manutenção da sua aplicação, com pacotes modulares de rápidodesenvolvimento. Elaborar tarefas divididas entre models, views e controllers, faz com que suaaplicação fique leve e independente. Novas funcionalidades são facilmente adicionadas e darnova cara nas características antigas pode ser feitas num piscar de olhos. O design modular eseparado também permite aos desenvolvedores e designers trabalhem simultaneamente,incluindo a habilidade de um construir um rápido protótipo. A separação também permite queos desenvolvedores alterem uma parte da aplicação sem afetar outras.Se você nunca desenvolveu uma aplicação neste sentido, isso vai lhe agradar muito, masestamos confiantes que depois de construir sua primeira aplicação em CakePHP, você não vaiquerer voltar atrás.
  • 12. Princípios básicos do CakePHP 11 Parte II. Princípios básicos do CakePHPEstrutura CakePHPCakePHP possui a característica de usar as classes de Controller, Model e View, mas tambémpossui classes e objetos adicionais que fazem o desenvolvimento em MVC mais rápido eagradável. Components, Behaviors e Helpers são classes que proporcionam extensibilidade ereuso para adicionar funcionalidades rapidamente à base MVC das suas aplicações. Agoravamos começar a subir um pouco o nível para analisar os detalhes de como usar estasferramentas mais tarde.Extensões de controllerO Component (Componente) é uma classe que ajuda na lógica do controller. Se você tem amesma lógica e quer compartilhar entre controllers (ou aplicações), o component é uma boasaída. Por exemplo, o component interno EmailComponent cria e envia e-mails em segundoplano. Ao invés de escrever um método em cada controller que utiliza esta lógica, pode-se criarum component que empacote esta funcionalidade e seja compartilhado entre os controllers.Controllers também são equipados com callbacks. Estes callbacks estão disponíveis para quevocê possa utilizar, apenas se você precisar inserir uma lógica entre operações do núcleo doCakePHP. Os callbacks disponíveis incluem:  beforeFilter(), executado antes de qualquer ação do controller;  beforeRender(), executado depois da lógica do controller, mas antes da view ser renderizada;  afterFilter(), executado depois de todas as lógicas do controller, incluindo a renderização da view. Não há diferença entre afterRender() e afterFilter(), exceto que você tenha feito uma chamada manualmente para render() no seu método do controller e tenha incluído alguma lógica depois dessa chamada.Extensões de viewO Helper (Ajudante) é a classe que ajuda na lógica da view. Assim como o component ajuda ocontroller, os helpers permitem a apresentação lógica ser acessada e compartilhada entre asviews. AjaxHelper é um dos principais helpers. Ele faz requisições AJAX facilmente de dentrodas views.A maioria das aplicações tem partes do código que são usados repetidamente nas views.CakePHP facilita o reuso de código na view com a utilização de layouts e elements (elementos).Por padrão, toda view é renderizada por um controller seguindo algum layout. Os elements sãocomo pequenos trechos de código necessários que podem ser reutilizados em diversas views.Extensões do modelAssim como as outras extensões, os Behaviors funcionam do mesmo modo, adicionandofuncionalidades entre os models. Por exemplo, se você armazenar os dados do usuário emuma estrutura de árvore, você pode especificar o model User como comportamento de árvoree ganhar funcionalidades para remover, adicionar e alterar nós em sua estrutura de árvorefundamental.
  • 13. Princípios básicos do CakePHP 12Os models também são suportados por outra classe chamada DataSource. DataSources sãoabstrações que permitem os models manipularem diferentes tipos de dadosconsistentemente. Enquanto a principal fonte de dados numa aplicação CakePHP é via bancode dados, você pode escrever DataSources adicionais que permitem seu model representar umfeed RSS, arquivo CSV, entidades LDAP ou eventos iCal. DataSources permite você associarregistros de diferentes fontes: ao invés de limitar em joins do SQL, DataSources permitem vocêchamar seu model de LDAP que está associada a vários eventos iCal.Assim como nos controllers, models têm recursos de callback como:  beforeFind()  afterFind()  beforeValidate()  beforeSave()  afterSave()  beforeDelete()  afterDelete()Os nomes desses métodos devem ser descritivos o bastante para que você saiba o que elesfazem. Certifique-se de pegar os detalhes no capítulo sobre model.Extensões de aplicaçãoTanto os controllers, helpers e models têm uma classe pai que você pode usar para definirmodificações na aplicação. AppController (localizado em “/app/app_controller.php”),AppHelper (localizado em “/app/app_helper.php”) e AppModel (localizado em“/app/app_model.php”) são bons lugares para colocar métodos que você precisa para acessarentre todos os controllers, helpers e models.Embora não sejam classes ou arquivos, as rotas definem regras na requisição feita para oCakePHP. As definições das rotas definem como o CakePHP deve mapear uma URL para ummétodo do controller. O behavior padrão assume que a URL “/controller/action/var1/var2”mapeia para Controller::action($var1, $var2), mas você pode usar rotas para personalizar URLse como elas devem ser interpretadas pela sua aplicação.Alguns recursos na sua aplicação podem ser empacotados com mérito. Um plugin é um pacotede model, controller e view que realiza um objetivo específico que pode abranger váriosaplicativos. Um sistema de gestão de usuários ou um blog simplificado podem ser bonsexemplos de plugins para CakePHP.Estrutura de arquivos do CakePHPVamos dar uma olhada o que é o CakePHP fora da caixa. Você que o CakePHP utiliza-se darequisição básica do MVC, mas não sabe como que os arquivos são organizados.  app  cake  docs  index.php
  • 14. Princípios básicos do CakePHP 13  vendorsQuando você faz o download do CakePHP, você verá que possui quatro pastas principais. Apasta app será o lugar da sua mágica: aqui serão guardados os arquivos da sua aplicação. Apasta cake é onde a mágica acontece. Faça um compromisso pessoal de não editar os arquivosdesta pasta! Nós não ajudamos você se você modificá-la. A pasta docs contém as informaçõesde alterações, licença, etc. Finalmente, a pasta vendors é onde você colocará aplicativos deterceiros para utilizar na aplicação, por exemplo, jQuery, prototype, FCKEditor, etc.Estrutura do diretório AppA pasta app do CakePHP é onde normalmente você colocará sua aplicação emdesenvolvimento, Vamos dar uma olhada mais de perto dentro desta pasta. Tabela 1. Descrição dos diretórios de appDiretório Descriçãoconfig Contém os arquivos de configuração. Detalhes das conexões ao banco de dados, bootstrapping, arquivos de configuração do núcleo e outros devem ser armazenados aqui.controllers Contém os controllers da sua aplicação e seus components.locale Guarda os arquivos com as strings para internacionalizaçao.models Contém os models, behaviors e datasources da sua aplicação.plugins Contém os pacotes de plugins.tmp Aqui é onde o CakePHP armazena os arquivos temporários. Os dados atuais são armazenados onde você tenha configurado o CakePHP, mas esta pasta normalmente é usada para guardar a descrição dos models, logs e outras informações, como as das sessões.vendors Qualquer classe ou biblioteca de terceiro deve ser armazenada aqui. Para fazer um acesso rápido e fácil, use a função vendors(). Você pode achar que esta pasta é redundante, já que existe uma pasta com mesmo nome no nível superior da estrutura. Nós vamos ver diferenças entre estas duas pastas quando discutirmos sobre manipulação de múltiplas aplicações e sistemas mais complexos.views Arquivos de apresentação devem vir aqui: elements, páginas de erro, helpers, layouts e arquivos de views.webroot No modo de produção, esta pasta deve servir como a pasta raiz da sua aplicação. Dentro desta pastas são guardados os arquivos públicos, como estilos CSS, imagens e arquivos de JavaScript.Requisição típica do CakePHPNós cobrimos os ingredientes básicos no CakePHP, então vamos ver como cada objetofunciona em uma completa requisição. Continuando com nossa requisição original deexemplo, vamos imaginar que nosso amigo Ricardo tenha clicado no link em “Comprar umbolo personalizado agora!” da sua aplicação CakePHP.
  • 15. Princípios básicos do CakePHP 14Figura 2. Requisição típica no CakePHP. Em preto, elemento necessário; Em cinza, elemento opcional; Em azul, callback 1. Ricardo clica no link apontando para http://www.exemplo.com.br/cakes/buy, e seu navegador faz a requisição ao seu servidor de web; 2. O roteador processa a URL, extraindo os parâmetros desta requisição: o controller, action (ação) e qualquer outro argumento que vai afetar na lógica do negócio durante esta requisição; 3. Usando rotas, a requisição da URL é mapeada para a action do controller (um método específico da classe do controller). Neste caso, o método buy() do CakesController. O callback beforeFilter() do controller é chamado antes de qualquer action do controller ser executada; 4. O controller pode usar métodos para ter acesso aos dados da aplicação. Neste exemplo, o controller usa o model para ver no banco de dados as últimas compras de Ricardo. Qualquer callback aplicável do modelo, behaviors e DataSources podem ser aplicados durante esta operação. Enquanto um model não é necessário, todos os controllers do CakePHP inicialmente requisitam de pelo menos um model; 5. Depois do model ter adquiridos os dados, ele retorna-os ao controller. Podem ser aplicados callbacks no model; 6. O controller pode usar components para refinar os dados ou efetuar outras operações (manipular sessões, autenticação ou enviar e-mails, por exemplo); 7. Uma vez que o controller tenha usado os models e os components para preparado os dados suficientemente, estes dados são repassados as views usando o método set() do controller. Callbacks dos controllers podem ser aplicados antes dos dados serem enviados. A lógica da view é efetuada, podendo incluir elements ou helpers. Por padrão, as views são sempre renderizadas dentro de um layout; 8. Além disso, callbacks dos controllers (como afterFilter) pode ser aplicado. Para completar, o código renderizado pela view vai para o navegador do Ricardo.
  • 16. Princípios básicos do CakePHP 15Convenções CakePHPNós somos grandes fãs de convenções nas configurações. Enquanto isso toma um pouco detempo para aprender as convenções do CakePHP, você ganha tempo em um longo processo:seguindo as convenções, você ganha funcionalidades gratuitamente e livra-sede madrugas demanutenção de arquivos de configuração. Convenções também fazem com que o sistemafique uniformemente desenvolvido, permitindo outros desenvolvedores o ajudem maisfacilmente.Convenções no CakePHP tem sido produzida por anos de experiência em desenvolvimentoweb e boas práticas. Enquanto nós sugerimos você a usar essas convenções enquantodesenvolve em CakePHP, nós devemos mencionar que muitos desses princípios são facilmentesobrescritos por alguma coisa que é especialmente passado quando trabalha-se com sistemaslegados.Convenções de arquivos e nome de classesEm geral, nome dos arquivos são sublinhados, enquanto nome de classes são CamelCased, ouseja, primeiras letras das palavras em maiúsculo. A classe KissesAndHugsController pode serencontrada no arquivo kisses_and_hugs_controller.php, por exemplo.Porém, o nome da class e seu tipo não são necessariamente encontrados no nome do arquivo.A classe EmailComponent é encontrada no arquivo chamado email.php e a classe HtmlHelperé encontrada no arquivo html.php.Convenções de modelosNome das classes de modelo devem ser no singular e CamelCased. Person, BigPerson eReallyBigPerson são todos os exemplos de nomes convencionados para modelos.Os nomes das tabelas correspondem ao nome do modelo do CakePHP, mas no plural esublinhados. As tabelas para os modelos mencionados anteriormente devem ser people,big_people e really_big_people, respectivamente.Tabelas associadas, usadas em relações hasAndBelongsToMany entre modelos, devem sernomeadas depois dos modelos das tabelas que a compõem, em ordem alfabética(apples_zebras em vez de zebras_apples). Se sua aplicação possui esse tipo de relação entre osmodelos Tag e Post, o nome deve ser posts_tags.Convenções de controladoresO nome das classes de controladores são no plural, CamelCased e no final “Controller”.PeopleController, BigPeopleController e ReallyBigPeopleController são todos os exemplosconvencionais para nome de controladores.A primeira função que você deve escrever em um controlador deve ser o método index().Quando alguém requisita um controlador sem ação, o behavior padrão é renderizar o métodoindex() do controlador. Por exemplo, a requisição para http://www.exemplo.com.br/apples/mapeia para a chamada da função index() do ApplesController, assim comohttp://www.exemplo.com.br/apples/view mapeia para a chamada da função view() noApplesController.
  • 17. Princípios básicos do CakePHP 16Você também pode alterar a visibilidade das funções do controlador em CakePHP colocandosublinhados na frente do nome das funções. Se a função do controlador estiver comsublinhado na frente, a função não será disponibilizada para acesso da web através dodispatcher, mas estará disponível para uso interno.Convenções de visõesOs arquivos de template das visões são chamados depois das funções que os controladoresmostram, na forma com sublinhados. A função getReady() da classe PeopleController iráprocurar pelo template da visão em /app/views/people/get_ready.ctp.O modelo básico é /app/views/controller/underscored_function_name.ctp.Nomeando os pedaços da aplicação usando as convenções do CakePHP, você ganhafuncionalidades sem luta e proteção configuração. Aqui o exemplo final que vincula asassociações:  Tabela no banco de dados: “people”  Classe do Modelo: “Person”, encontrada em /app/models/person.php  Classe do Controlador: “PeopleController”, encontrado em /app/controllers/people_controller.php  Template da Visão: encontrado em /app/views/people/index.ctpUsando estas convenções, CakePHP sabe que a requisição parahttp://www.exemplo.com.br/people/ mapeia para a chamada da função index() doPeopleController, onde o modelo Person é automaticamente disponibilizado (eautomaticamente associado a tabela “people” no banco de dados), e renderiza isso para oarquivo. Nenhuma destas relações foram configuradas por qualquer meio que não seja atravésda criação de classes e arquivos que você precise criar em algum lugar.Agora que você leu os fundamentos do CakePHP, você pode tentar seguir o Tutorial de comofazer um blog em CakePHP, disponível na parte de Exemplos deste manual.
  • 18. Desenvolvendo com CakePHP 17 Parte III. Desenvolvendo com CakePHPRequisitos  Servidor HTTP. Apache com mod_rewrite é preferido, mas não é obrigatório.  PHP 4.3.2 ou superior. Sim! CakePHP funciona com PHP 4 e PHP 5.Tecnicamente um banco de dados não é obrigatório, mas nós imaginamos que a maioria dasaplicações irão utilizar um. CakePHP suporte uma variedade de banco de dados:  MySQL (4 ou superior);  PostgreSQL;  Firebird DB2;  Microsoft SQL Server;  Oracle;  SQLite;  ODBC;  ADOdb.Preparativos para instalaçãoBaixando o CakePHPHá duas maneiras de pegar uma cópia do CakePHP, Primeiro: você pode baixar o arquivo(zip/tar.gz/tar.bz2) ou você pode baixar o código do repositório SVN.Para pegar a cópia estável, visite o site http://www.cakephp.org. Lá haverá um link chamado“Download Now!” para baixar. Os arquivos do CakePHP também são armazenados noCakeForge e você pode visitar a página do projeto no sitehttp://cakeforge.org/projects/cakephp.Se você quer os arquivos mais atuais, verifique no sitehttp://cakephp.org/downloads/index/nightly e verás a última versão estável, porém nemsempre a última release. Nestas versões incluem correções entre releases. Ou seja, são versõesintermediárias entre releases, mas que são estáveis.Para pegar os arquivos direto do repositório SVN, conecte-se emhttps://svn.cakephp.org/repo/branches/1.2.x.x.PermissõesO CakePHP usa o diretório /app/tmp para diversas operações. Descritivos dos modelos, fazercache de visões e informações das sessões são alguns exemplos.Assim, tenha certeza que o diretório /app/tmp na instalação do seu cake permite escrita pelousuário do servidor de web.
  • 19. Desenvolvendo com CakePHP 18InstalaçãoInstalando o CakePHP pode ser feito simplesmente descompactando o conteúdo no seuservidor web ou de forma mais complexa e flexível, do jeito que você preferir. Esta seção vaisfalar de três maneiras de instalar o CakePHP: desenvolvimento, produção e avançada.  Desenvolvimento: fácil para começar, URL dos seus aplicativos incluem o diretório de instalação do CakePHP e é menos seguro;  Produção: Requer maior habilidade para configurar o servidor web, porém mais seguro e com URLs mais amigáveis;  Avançada: Com algumas configurações, permite você colocar os diretórios do CakePHP em diferentes locais do sistema, possibilitando compartilhar o núcleo do CakePHP entre diversas aplicações.DesenvolvimentoApenas coloque seus arquivos do CakePHP no diretório público do seu servidor web(normalmente htdocs, www, public_html). Por exemplo, assumindo que o diretório público doseu servidor web seja /var/www/html, os arquivos devem ficar desta maneira:  /var/www/html o /cake_1_2  /app  /cake  /docs  /index.php  /vendorsPara ver a sua aplicação CakePHP, entre no link http://www.exemplo.com/cake_1_2/.ProduçãoPara utilizar-se do modelo de produção, você precisará ter privilégios de acessar o diretóriopúblico do servidor web. Escolhendo o modo de produção significa que todo o domínio agecomo um único pedido CakePHP.A disposição dos arquivos no modo de produção fica da seguinte maneira:  /pasta_para_o_cake/ o /app  /webroot (este diretório deve ser seu diretório público do servidor web) o /cake o /docs o /index.php o /vendorsSe sua aplicação está hospedada no Apache, a diretiva DocumentRoot para seu domínio deveficar assim:DocumentRoot /pasta_para_o_cake/app/webroot
  • 20. Desenvolvendo com CakePHP 19Para ver sua aplicação CakePHP, entre no link http://www.exemplo.com.br.Instalação avançadaAqui estão algumas situações que você escolhe o lugar onde os diretórios do CakePHP vão ficarno seu sistema. Isto pode ser por causa de uma restrição do sistema ou para compartilhar asbibliotecas entre diferentes aplicações. Esta seção descreve como espalhar seus diretórios dosCakePHP no sistema.Primeiro, note que há três partes principais da sua aplicação CakePHP: 1. As bibliotecas do núcleo do CakePHP, em /cake; 2. O código da sua aplicação, em /app; 3. Os arquivos públicos da sua aplicação, normalmente em /app/webroot.Cada um desses diretórios pode ser colocado em qualquer lugar do seu sistema, com exceçãodo webroot, que precisa estar acessível pelo servidor web. Você pode mover a pasta webrootpara fora do diretório da sua aplicação (app), desde que informe ao Cake onde você vai colocá-la.Para configurar sua instalação do Cake, nós vamos ter que fazer algumas alterações no arquivo/app/webroot/index.php. Aqui existem três constantes que precisaremos editar: ROOT,APP_DIR e CAKE_CORE_INCLUDE_PATH.  ROOT deve ser configurada para informar o diretório onde sua aplicação se encontra, ou seja, onde está a pasta app;  APP_DIR deve ser configurada para informar qual a pasta app;  CAKE_CORE_INCLUDE_PATH deve ser configurada para informar o diretório onde estão as bibliotecas do CakePHP (a pasta cake).Vamos fazer um exemplo para que você veja como funciona a instalação avançada na prática.Imagine que eu quero que a aplicação funcione como segue:  As bibliotecas do CakePHP deverão ser colocadas em /usr/lib/cake;  O diretório público da minha aplicação (webroot) deve ser em /var/www/meusite;  O diretório da aplicação deve ser /home/eu/meusite.Com estas configurações, eu preciso editar o meu arquivo webroot/index.php (que no finaldeve estar em /var/www/meusite/index.php, neste exemplo) e ver o seguinte:if (!defined(ROOT)) { define(ROOT, DS.home.DS.eu);}if (!defined(APP_DIR)) { define (APP_DIR, meusite);}if (!defined(CAKE_CORE_INCLUDE_PATH)) { define(CAKE_CORE_INCLUDE_PATH, DS.usr.DS.lib.DS.cake); /app/webroot/index.php (parcialmente, comentários foram removidos)
  • 21. Desenvolvendo com CakePHP 20É recomendado que você use a constante DS no lugar das barras para entre os diretórios. Issoprevine que não cause erro quando se use a aplicação em sistemas operacionais diferentes,tornando seu código mais portável.Caminho de classes adicionaisEm algumas ocasiões é interessante você compartilhar as classes do MVC entre as aplicaçõesno mesmo sistema. Se você quer um mesmo controller para mesma aplicação, você pode usaro arquivo bootstrap.php do CakePHP para adicionar estas classes adicionais.No bootstrap.php, defina algumas variáveis com nomes especiais para fazer com que oCakePHP olhe nestes diretórios a procura da sua classe:$viewPaths = array();$controllerPaths = array();$modelPaths = array();$helperPaths = array();$componentPaths = array();$behaviorPaths = array();Cada um dessas variáveis especiais pode ser um conjunto na array com o diretório absolutoonde estão às classes que você desejar. Tenha certeza que cada diretório especificado incluaas barras com DS.Apache e mod_rewriteEnquanto o CakePHP é construído para trabalhar com o mod_rewrite e vimos que muitosusuários apanham para conseguir fazer isto funcionar nos seus sistemas, nós lhe daremosalgumas dicas que você pode tentar para tentar rodar corretamente:  Tenha certeza que o override está habilitado no .htaccess. Em seu httpd.conf, você deve olhar na seção que define seu Directory no servidor. Tenha certeza que AllowOverride está configurado como All para o diretório correto de DocumentRoot;  Tenha certeza que você está editando o httpd.conf do sistema antes da configuração do usuário ou do site em específico;  Tenha certeza que o arquivo .htacess está na pasta do CakePHP. Em alguns sistemas operacionais ele pode ficar oculto na hora de mover devido a interpretarem o “.” como sinônimo de ocultamento. Tenha certeza que sua cópia do CakePHP é do site ou repositório oficial do CakePHP e que foi extraído corretamente;  Tenha certeza que você está carregando o mod_rewrite corretamente. Você pode ver algo como LoadModule rewrite_module libexec/httpd/mod_rewirte.so e AddModule mod_rewrite.c no seu httpd.conf;  Se você está instalando no diretório do usuário (http://exemplo.com.br/~username), você terá que modificar o arquivo .htaccess no diretório da base da instalação do CakePHP. Apenas adicione a linha “RewriteBase /~meuusername/”.Comece agora!Tudo bem, vamos ver o CakePHP em ação. Dependendo de qual opção de instalação vocêutilizou, acesse no seu navegador o link http://exemplo.com.br ouhttp://exemplo.com.br/cake_instalado/. Neste ponto, você verá a página padrão do CakePHPe a mensagem do estado da configuração do seu banco de dados.
  • 22. Desenvolvendo com CakePHP 21Parabéns! Você já pode criar sua primeira aplicação CakePHP.ConfiguraçãoConfiguração da base de dadosO CakePHP espera que os detalhes de configuração da base de dados estejam no arquivo“app/config/database.php”. Um exemplo de configuração da base de dados pode serencontrado em “app/config/database.php.default”.A configuração final deve ser parecida com o exemplo abaixo.var $default = array(driver => mysql, persistent => false, host => localhost, login => usuarioDB, password => senhaDB, database => basededados, prefix => ); Exemplo de configuração da base de dadosA conexão $default é usada a menos que outra configuração seja especificada pelapropriedade $useDbConfig em um model. Por exemplo, se minha aplicação tiver uma base dedados adicional do legacy além do padrão, eu poderia usá-la em meus models criando umanova conexão da base de dados de $legacy similar a configuração $default, e ajustando a var$useDbConfig = legacy; nos models apropriados.Preencha corretamente os pares de chave/valor na configuração para atender melhor às suasnecessidades. Tabela 2. Configurações da base de dadosChave Valordriver O nome do driver da base de dados para esta configuração. Exemplos: mysql, postgres, sqlite, pear-drivername, adodb-drivername, mssql, oracle, ou odbc.persistent Se usará ou não uma conexão persistente com a base de dados.host O nome do servidor da base de dados (ou endereço IP).login O usuário desta conta.password A senha desta conta.database O nome da base de dados que esta conexão irá usar.prefix Esta string será adicionada como prefixo no nome de todas tabelas de sua base(opcional) de dados.Se suas tabelas não possuem prefixo, deixe esta string vazia.port A porta TCP ou socket Unix usado para conectar com o servidor.(opcional)enconding Indica qual caractere definido será usado para enviar indicações SQL ao servidor.schema Usado em instalações de base de dados PostgreSQL para especificar qual schema usar.Note que as configurações de prefixo são para as tabelas, não para os models. Por exemplo, sevocê criou um relacionamento entre as tabelas Apple e Flavor, o nome seráprefixo_apples_flavors (não prefixo_apples_prefixo_flavors), isso se sua opção de prefixoestiver como prefixo_.
  • 23. Desenvolvendo com CakePHP 22A partir deste ponto, você deve dar uma olhada nas Convenções CakePHP, mostradas nestemanual. A nomenclatura correta para suas tabelas (e o nome de algumas colunas) pode livrarde algumas implementações e configurações desnecessárias.Configuração do núcleoAs classes de configuraçãoClasses de configuraçãoVariáveis de configuração do núcleoConstantes de configuraçãoConfiguração de rotas (Routes)Routes é uma funcionalidade que mapeia URLs em ações do controller. Foi adicionado aoCakePHP para tornar URL amigáveis mais configuráveis e flexíveis. Não é obrigatório o uso domod_rewrite para usar routes, mas usando-o fará sua barra de endereços muito mais limpa earrumada.Routes no CakePHP 1.2 foi ampliada e pode ser muito mais poderosa.Antes de você aprender sobre como configurar suas próprias rotas, você deveria saber que oCakePHP vem configurado com um conjunto de rotas padrão. A configuração padrão de rotasdo CakePHP deixará as URLs mais bonitas para qualquer aplicação. Você pode acessardiretamente uma ação via URL colocando seu nome na requisição. Você pode também passarparâmetros para suas ações no controller usando a própria URL.URL para a rota padrão:http://examplo.com/controller/action/param1/param2/param3A URL /noticias/ler mapeia para a ação ler() do controller Noticias (NoticiasController), e/produtos/verInformacoes mapeia para a ação view_informacoes() do controller Produto(ProdutosController). Se nenhuma ação é especificada na URL, a ação index() será chamada.A rota padrão também permite passar parâmetros para as ações usando a URL. Umarequisição /noticias/ler/12 seria equivalente a chamar o método ler(12) no controller Noticias(NoticiasController), por exemplo.Uma novidade no CakePHP 1.2 é a possibilidade de usar parâmetros nomeados. Você podenomear parâmetros e enviar seus valores usando a URL. Uma requisição/noticias/ler/titulo:primeira+noticia/categoria:esportes teria como resultado uma chamada aação ler() do controller Noticias (NoticiasController). Nesta ação, você encontraria os valoresdos parâmetros título e categoria dentro de $this->passedArgs[titulo] e $this->passedArgs[categoria] respectivamente.Alguns exemplos para a rota padrão:URL mapeadas para as ações dos controladores, usando rotas padrão:URL: /monkeys/jump
  • 24. Desenvolvendo com CakePHP 23Mapeado para: MonkeysController->jump();URL: /productsMapeado para: ProductsController->index();URL: /tasks/view/45Mapeado para: TasksController->view(45);URL: /donations/view/recent/2001Mapeado para: DonationsController->view(recent, 2001);URL: /contents/view/chapter:models/section:associationsMapeado para: ContentsController->view();$this->passedArgs[chapter] = models;$this->passedArgs[section] = associations;Definindo suas próprias rotas permite você definir como sua aplicação irá responder a umadada URL. Defina suas próprias rotas no arquivo “/app/config/routes.php” usando o métodoRouter::connect().O método connect() recebe três parâmetros: a URL que você deseja casar, o valor padrão paraos elementos de rota, e regras de expressões regulares para ajudar a encontrar elementos naURL.O formato básico para uma definição de rota é:Router::connect( URL, array(paramName => defaultValue), array(paramName => matchingRegex))Inflexão personalizadaAs convenções de nomenclatura do Cake podem ser realmente legais. Você pode nomear suatabela big_boxes, seu model BigBox, seu controller BigBoxesController e tudo isso funciona emconjunto automaticamente. A maneira que o CakePHP usa para associar todas juntas é atravésda utilização de inflections (inflexões), que transformam as palavras do singular em plural evice-versa.Existem ocasiões (especialmente para nossos amigos que não falam inglês - nosso caso), ondevocê pode rodar o inflector do CakePHP (a classe que pluraliza, singulariza, camelCases eunder_scores) e não funcionar como você gostaria. Se o CakePHP não reconhecer seu Foci ouFish, editando o arquivo de configuração personalizada de inflexões você poderá indicar seuscasos especiais. O arquivo de configuração é encontrado em /app/config/inflections.php.Neste arquivo, você irá encontrar seis variáveis. Cada uma permite você fazer o ajuste fino dasinflections do CakePHP.Variáveis do inflections.php Descrição$pluralRules Este array contém regras de expressões regulares para pluralizar casos especiais. A chave do array são os patterns e o valor são as substituições.
  • 25. Desenvolvendo com CakePHP 24$uninflectedPlural Um array que contém palavras que não precisam ser alteradas quando passadas para o plural (lápis, etc.).$irregularPlural Um array que contém palavras e seus plurais. A chave do array contém a forma no singular e o valor a forma no plural. Este array deve ser usado para guardar palavras que não seguem as definições em $pluralRules.$singularRules Similar a $pluralRules, contém as regras para singularizar as palavras.$uninflectedSingular Similar a $uninflectedPlural, contém as palavras que não contém forma no singular. Por padrão, este array tem o mesmo valor de $uninflectedPlural.$irregularSingular Similar a $irregularPlural, contém as palavras que possuem apenas a forma singular.A versão para língua portuguesa do inflections.php pode ser encontrada nos apêndices, com otítulo Inflexão em português.Configuração de inicialização (bootstrap)Controllers (Controladores)IntroduçãoUm controller (ou controlador) é usado para gerenciar a lógica para uma parte de suaaplicação. Mais comumente, controllers são usados para gerenciar a lógica de um único model.Por exemplo, se você está construindo um site para uma padaria online, você pode ter umReceitasController e um IngredientesController gerenciando suas receitas e seus ingredientes.No CakePHP, controllers são nomeados de acordo com o model que manipulam, no plural.O model Receita é manipulado pelo ReceitasController, o model Produto é manipulado peloProdutosController, e por aí vai.Seus controllers de aplicação são classes que estendem a classe CakePHP AppController, a qualpor sua vez estende a classe núcleo Controller. A classe AppController pode ser definida emapp/app_controller.php e deve conter métodos que são compartilhados entre todos os seuscontrollers. A classe AppController estende o Controller que é uma classe padrão da bibliotecaCakePHP.Controllers podem incluir qualquer número de métodos que são geralmente referidos comoactions (ações). Actions são métodos do controlador usados para mostrar views (visões). Umaaction é um único método de um controller. O dispatcher (despachante) do CakePHP chamaactions quando uma requisição casa uma URL com uma action do controller. Retornando aonosso exemplo da padaria online, nosso ReceitasController pode conter as actions ver(),compartilhar() e buscar(). O controller poderia ser encontrado emapp/controllers/receitas_controller.php e poderia conter:<?phpclass ReceitasController extends AppController { function ver($id) { // a lógica da action vai aqui... }
  • 26. Desenvolvendo com CakePHP 25 function compartilhar($cliente_id, $receita_id) { // a lógica da action vai aqui... } function buscar($busca) { // a lógica da action vai aqui... }}?> app/controllers/receitas_controller.phpPara que você possa usar o controller de forma mais efetiva em sua aplicação, vamos cobriralguns dos principais atributos e métodos fornecidos pelos controllers do CakePHP.AtributosPara uma lista completa de atributos do controller e suas descrições visite a API do CakePHP.Dê uma olhada http://api.cakephp.org/1.2/classController.html.$nameUsuários PHP4 devem iniciar suas definições de controllers usando o atributo $name. Oatributo $name deve conter o nome do controller. Geralmente é apenas a forma plural donome do model. Isso cuida de alguns dos problemas de nomes de classe do PHP4 e ajuda oCakePHP a encontrar os nomes das coisas.<?phpclass ReceitasController extends AppController { var $name = Receitas;}?> Exemplo de uso do atributo $name do controller$components, $helpers e $usesOs próximos atributos de controller usados com maior freqüência dizem ao CakePHP quehelpers (ajudantes), components (componentes), e models você usará junto com o controlleratual. Usar esses atributos disponibiliza essas classes MVC para o controller como variáveis declasse ($this->NomeDoModel, por exemplo).Por favor, perceba que cada controller tem algumas dessas classes disponíveis por padrão,então você pode nem mesmo ter que configurar o seu controller.Controllers tem por padrão seu model principal disponível. Nosso ReceitasController terá omodel Receita disponível em $this->Receita, e nosso ProdutosController também tem acessoao model Produto em $this->Produto.Os helpers Html e Session estão sempre disponíveis por padrão, assim como o componentSession. Para aprender mais sobre essas classes, lembre-se de dar uma olhada em suasrepectivas sessões mais a frente nesse manual.
  • 27. Desenvolvendo com CakePHP 26Vamos ver como chamar um controller CakePHP no qual você planeja usar classes MVCadicionais.<?phpclass ReceitasController extends AppController { var $name = Receitas; var $uses = array(Receita, Usuário); var $helpers = array(Html, Ajax); var $components = array(Session, Email);}?>Quando estiver definindo esses atributos, tenha certeza de incluir as classes padrão (comoHtml no array $helpers, por exemplo) se você pretende usá-los.Relativo à página: $layout e $pageTitleAlguns poucos atributos existem nos controllers CakePHP que dão maior controle sobre comosuas views são embutidas em um layout.O atributo $layout pode conter o nome do layout salvo em /app/views/layouts. Vocêespecifica um layout atribuindo ao atributo $layout o nome do arquivo de layout menos aextensão .ctp. Se esse atributo não for definido, o CakePHP renderiza o layout default(padrão). Se você não definiu um em /app/views/default.ctp, o layout default do núcleo doCakePHP será renderizado.<?phpclass RecipesController extends AppController { function quickSave() { $this->layout = ajax; }}?> Usando $layout para definir um layout alternativoO atributo $pageTitle do controller torna possível definir o título da página renderizada. Paraque isso funcione apropriadamente, seu layout precisa ter embutido a variável$title_for_layout entre as tags <title> no cabeçalho do documento HTML.Apenas atribua à $pageTitle a string que você quer ver no <title> do seu documento.Atributos dos parâmetros ($params)Parâmetros do controller estão disponíveis em $this->params no seu controller CakePHP. Essavariável é usada para dar acesso à informação sobre a requisição atual. O uso mais comum do$this->params é obter acesso à informação que foi enviada ao controller via operações POSTou GET.  $this->params[form]
  • 28. Desenvolvendo com CakePHP 27 o Qualquer dado do POST de qualquer formulário é guardado aqui, incluindo também informação encontrada em $_FILES.  $this->params[bare] o Guarda 1 se o layout atual está vazio, 0 se não.  $this->params[isAjax] o Guarda 1 se o layout atual é ajax, 0 se não. Essa variável só é configurada se o component RequestHandler está sendo usado no controller.  $this->params[controller] o Guarda o nome do controller atual manipulando a requisição. Por exemplo, se a URL /posts/ver/1 foi requisitada, $this->params[controller] será igual à posts.  $this->params[action] o Guarda o nome da action atual manipulando a requisição. Por exemplo, se a URL /posts/ver/1 é requisitada, $this->params[action] será igual ver.  $this->params[pass] o Guarda a query string GET passada com a requisição atual. Por exemplo, se a URL /posts/ver/?var1=3&var2=4 foi requisitada, $this->params[pass] será igual à ?var1=3&var2=4.  $this->params[url] o Guarda a URL atual requisitada, com os pares chave-valor das variáveis GET. Por exemplo, se a URL /posts/view/?var1=3&var2=4 foi chamada, $this- >params[url] conterá: [url] => Array( [url] => posts/view [var1] => 3 [var2] => 4)  $this->data o Usado para manipular os dados POST enviados dos formulários FormHelper ao controller.// O FormHelper é usado para criar um elemento form:$form->text(Usuario.primeiro_nome);// Quando rederizado, se parece com:<input name="data[Usuario][primeiro_nome]" value="" type="text" />// Quando o formulário é enviado para o controller via POST,// os dados são mostrados em $this->data// O primeiro nome pode ser encontrado aqui:$this->data[Usuario][primeiro_nome];Outros atributosAinda que você possa dar uma olhada nos detalhes de todos os atributos de controllers na API,existem outros atributos de controllers que merecem suas próprias sessões no manual.
  • 29. Desenvolvendo com CakePHP 28O atributo $cacheAction serve para criar cache das views, e o atributo $paginate é usado paracriar a paginação padrão para o controller. Para mais informação sobre como usar essesatributos, dê uma olhada em suas respectivas sessões mais a frente nesse manual.MétodosPara uma lista completa de métodos do controller e suas descrições visite a API CakePHP. Dêuma olhada http://api.cakephp.org/1.2/class_controller.html.Interagindo com as visões  set(string $var, mixed $value)O método set() é a principal forma de enviar dados do seu controller para sua view. Uma vezque você usou set(), a variável pode ser acessada na sua view.// Primeiro você passa os dados do controller:$this->set(cor, "pink");// Então, na view, você pode utilizar os dados:<p>Você selecionou a cor <?php echo $cor; ?> para colorizar o cake.</p> Exemplo de uso do set()O método set() também pega um array associativo como seu primeiro parâmetro. Esse podeser geralmente um caminho rápido para atribuir um grupo de informações para a view.Perceba que os índices de seu array sofrerão inflection antes de serem atribuídos à view(indice_com_underline se torna indiceComUnderline, etc.):$dados = array( cor => pink, tipo => açucar, preco_base => 23.95);// fazem $cor, $tipo, e $precoBase// disponíveis na view:$this->set($dados);  render(string $action, string $layout, string $file)O método render() é automaticamente chamado ao final de cada action do controllerrequisitada. Esse método executa toda a lógica da view (usando dados que você forneceuusando o método set()), insere a view dentro do layout e o serve de volta para o usuário final.O arquivo de view padrão renderizado é determinado por convenção. Se a action buscar() doReceitasController é requisitada, o arquivo de view /app/views/receitas/buscar.ctp serárenderizado.
  • 30. Desenvolvendo com CakePHP 29Ainda que o CakePHP vá automaticamente chamá-lo (a menos que você configure $this->autoRender para false) depois de cada lógica de action, você pode usá-lo para especificar umarquivo de view alternativo configurando o nome da action no controller usando $action. Vocêpode também especificar um arquivo alternativo um terceiro parâmetro, $file. Quando usar$file, lembre-se de utilizar um pouco das constantes globais do CakePHP (como a VIEWS).O parâmetro $layout permite especificar o layout na qual a view é renderizada.Fluxo de controle  redirect(string $url, integer $status, boolean $exit)O método de controle de fluxo que você vai usar com maior freqüência é o redirect(). Essemétodo pega seu primeiro parâmetro na forma de uma URL relativa CakePHP. Quando umusuário fez uma compra com sucesso, você provavelmente irá redirecioná-lo para a tela derecibo.function comprar() { // A lógica para finalizar a compra vai aqui... if($sucesso) { $this->redirect(/compras/obrigado); } else { $this->redirect(/compras/confirmar); }} Exemplo de uso do redirect()O segundo parâmetro do redirect() lhe permite definir um código de status HTTP paraacompanhar o redirecionamento. Você pode querer usar 301 (movido permanentemente) ou303 (veja outro), dependendo da natureza do redirecionamento.Esse método não chama exit() depois de redirecionar a menos que você configure o terceiroparâmetro para true.  flash(string $message, string $url, integer $pause)Similarmente, o método flash() é usado para direcionar o usuário para uma nova página depoisde uma operação. O método flash() é diferente pelo fato de mostrar uma mensagem antes depassar o usuário para uma outra URL.O primeiro parâmetro deve guardar a mensagem a ser mostrada, e o segundo parâmetro éuma URL relativa CakePHP. CakePHP vai mostrar a mensagem na variável $message, por umtempo definido em segundos na variável $pause antes de direcionar o usuário.Para mensagens flash dentro da página, dê uma olhada no método setFlash() do componentSession.CallbacksControllers CakePHP vem com callbacks para inserir lógica exatamente antes ou depois dasactions serem rederizadas.
  • 31. Desenvolvendo com CakePHP 30  beforeFilter()Essa função é executada antes de qualquer action no controller. É o lugar ideal para checaruma sessão ativa ou inspecionar permissões.  beforeRender()Chamada após a lógica da action do controller, mas antes da view ser renderizada. Essecallback não é usado geralmente, mas pode ser necessário se você está chamando render()manualmente antes do final de uma dada action.  afterFilter()Chamada depois de toda action do controller.  afterRender()Chamada depois que uma action tiver sido renderizada.Outros métodos  constructClasses()Esse método carrega os models requeridos pelo controller. Esse processo de carregamento éfeito pelo CakePHP normalmente, mas o método é uma boa quando estiver acessandocontrollers de diferentes perspectivas. Se você precisa do CakePHP em um script de linha decomando ou outro uso de fora, constructClasses() pode ser uma boa.  referrer()Retorna a URL referida pela requisição atual.  disableCache()Usado para dizer ao navegador do usuário não fazer cache dos resultados na requisição atual.Isso é diferente do cache da view, coberto no capítulo anterior.  postConditions(array $data, mixed $op, string $bool, boolean $exclusive)Use esse método para tornar um grupo de dados enviados por POST (de inputs compatíveiscom o helper Html) em um grupo de condições de busca para o model. Essa função oferece umatalho rápido para criar lógica de busca. Por exemplo, um usuário administrativo pode quererser capaz de buscar compras para saber quais itens precisam ser enviados. Você pode criar umrápido formulário baseado no model Compra. Então a action do controller pode usar os dadosenviados do formulário para criar as condições de busca.function index() { $c = $this->Compras->findAll($this->postConditions($this->data)); $this->set(compras, $c);}
  • 32. Desenvolvendo com CakePHP 31Se $this->data[Compra][destino] é igual a “Padaria da Cidade Velha”, postConditionsconverte essa condição para um array compatível para uso no método NomeDoModel->findAll(). Nesse caso, array(“Compra.destino” => “Padaria da Cidade Velha”).Se você quer usar um operador SQL diferente entre os termos, forneça-os usando o segundoparâmetro./*Conteúdo de $this->dataarray( Compra => array( num_de_itens => 4, fornecedor => Trigo Integral LTDA ))*/// Vamos pegar compras que tem ao menos 4 itens e contém Trigo IntegralLTDA$c = $this->Compra->findAll($this->postConditions( $this->data, array(>=, LIKE)));O índice nas especificações de operadores é a ordem das colunas no array $this->data. Já quenum_de_itens é o primeiro, o operador >= aplica-se a ele.O terceiro parâmetro lhe permite dizer ao CakePHP que operador booleano SQL usar entre ascondições de busca. Strings com AND, OR, e XOR são todos valores válidos.Finalmente, se o último parâmetro está configurado para true, e o parâmetro $op é um array,os campos não incluídos em $op não serão incluídos nas condições retornadas.  cleanUpFields(string $modelClass = null)Esse método de conveniência concatena as várias partes de datas em $this->data antes desalvar. Se você tem inputs de data do helper Form, esse método concatena o ano, mês, dia ehora em uma string mais compatível com banco de dados.Esse método usa o model padrão do controller (por ex.: o model Cookie para o controllerCookiesController) como alvo para a concatenação, mas uma classe alternativa pode ser usadacomo primeiro parâmetro.  paginate()Esse método é usado para paginar os resultados divididos pelos seus models. Você podeespecificar tamanhos de páginas, condições de busca do model e mais. Detalhes sobre essemétodo mais a frente. Dê uma olhada no capítulo de paginação mais a frente nesse manual.  requestAction(string $url, array $options)Essa função chama uma action de controller de qualquer lugar e retorna os dados dessa action.A $url passada é uma URL relativa ao CakePHP
  • 33. Desenvolvendo com CakePHP 32(/nomedocontroller/nomedaaction/parametros). Se o array $options incluir um valor dereturno. AutoRender é automaticamente configurada para true para a action do controller,tendo a requestAction te levando para a view totalmente renderizada.Nota: apesar de ser possível usar requestAction() para pegar uma view totalmenterenderizada, a perda performance que você obtém passando por toda a camada da viewnovamente na realidade não faz valer a pena. O método requestAction() é melhor usado emconjunto com elements - como um caminho para enviar lógica de negócio para um elementantes da renderização.Primeiro, vamos ver como pegar dados da action do controller. Primeiro, nós precisamos criara action do controller que retorna algum dado que precisamos em vários lugares através daaplicação:// Aqui está nosso controller simples:class UsuariosController extends AppController { function pegarListaDeUsuarios() { return $this->Usuario->findAll("Usuario.ativo = 1"); }}Imagine que nós precisamos criar uma simples tabela mostrando os usuários ativos nosistema. Ao invés de duplicar o código de geração de lista em outro controller, nós podemospegar dados do UsuariosController->pegarListaDeUsuarios() ao invés de usar requestAction();class ProdutosController extends AppController { function mostrarProdutosDoUsuario() { $this->set( usuarios, $this->requestAction(/usuarios/pegarListaDeUsuarios) ); // Agora a variável $usuarios na view vai ter dados do // UsuariosController::pegarListaDeUsuarios(). }}Se você tem um element na sua aplicação que não é estático, você pode querer usarrequestAction() para enviar lógica equivalente à do controller para o element a medida em quevocê o injeta nas suas views. Apesar de elements sempre tem acesso a qualquer variável daview que o controller passou, essa é uma forma de passar dados para o element vindos deoutro controller.Se você criou uma action do controller que fornece a lógica necessária, você pode pegar dadose passá-lo para o segundo parâmetro do método renderElement() da view usandorequestAction().<?phpecho $this->renderElement( usuarios, $this->requestAction(/usuarios/pegarListaDeUsuarios));
  • 34. Desenvolvendo com CakePHP 33?>Se o array $options contiver um valor “return”, a action do controller será renderizada dentrode um layout vazio e retornada. Dessa forma, a função requestAction() é útil também emsituações Ajax onde um pequeno elemento de uma view precisa ser preenchido antes oudurante uma atualização Ajax.Components (Componentes)IntroduçãoComponents (Componentes) são pacotes com funções lógicas que são usadas para seremcompartilhadas entre os controllers. Se você está querendo copiar e colar coisas entre oscontrollers, você pode criar funcionalidades em components para isso.O CakePHP já vem com um conjunto de components para os mais diversos usos, por exemplo:  Segurança  Sessões  Lista de controle de acessos (ACL)  E-mails  Cookies  Autenticação  Manipulação de requisiçõesCada um dos components será explicado em outros capítulos. Por enquanto, mostraremosapenas como criar seus próprios components. Criando components ajuda a manter o código docontroller limpo e permite que você reuse o código entre os projetos ou controllers.Construindo componentes personalizadosSuponha que sua aplicação online precisa utilizar funções complexas de matemática emdiversas partes da aplicação. Poderíamos, então, criar um component para que esta lógica sejacompartilhada entre diversos controllers.O primeiro passo é criar um arquivo para o component e uma classe. Crie o arquivo em/app/controllers/components/math.php. A estrutura básica do arquivo do component ésimilar a apresentada abaixo.<?phpclass MathComponent extends Object { function doComplexOperation($amount1, $amount2) { return $amount1 + $amount2; }}?>Quando seu component estiver criado, nós podemos utilizá-lo nos controllers da aplicaçãocolocando o nome do component no vetor da variável $components:// Isso faz com que o novo component possa ser acessado usando $this->Math
  • 35. Desenvolvendo com CakePHP 34var $components = (Math, Session);Acessando classes do MVC de dentro dos componentesPara ter acesso a instância do controlador dentro do seu novo component, você precisaimplementar o método startup(). Este é um método especial que trás a referência docontroller como primeiro parâmetro e esta função é chamada automaticamente depois dafunção beforeFilter() do controller. Se por alguma razão você não quer que o método startup()seja executado quando o controller é instanciado, defina o valor da variável $disableStartuppara true.Se você deseja inserir uma lógica antes que o controller seja chamado, use o método initialize()no seu component.<?phpclass MathComponent extends Object { // chamado antes de Controller:beforeFilter() function initialize() { } // chamado depois de Controller::beforeFilter() function startup(&$controller) { } function doComplexOperation($amount1, $amount2) { return $amount1 + $amount2; }}?>Você pode também querer utilizar outros components dentro de um componentpersonalizado. Para isso, basta criar a variável $components na classe (assim como você fariaem um controller) como um array que contenha os nomes dos components que você desejautilizar.Models (Modelos)IntroduçãoCampos mágicosAtributosMétodosAssociaçõesIntroduçãoUm dos mais poderosos recursos do CakePHP é o mapeamento relacional fornecido pelosmodels. No CakePHP, as ligações entre os models são manipuladas através de associações.
  • 36. Desenvolvendo com CakePHP 35Definir as relações entre os diversos objetos em sua aplicação deve ser um processo natural.Por exemplo: em uma base de dados de receitas, uma receita pode ter muitas opiniões,opiniões têm um único autor, e os autores podem ter muitas receitas. Definir a forma comoestas relações trabalham permite o acesso aos seus dados de uma forma intuitiva e poderosa.O objetivo desta seção é para mostrar-lhe como planejar, definir, utilizar as associações entreos models no CakePHP. Porque a forma mais comum de armazenamento em aplicações web éuma base relacional, a maior parte daquilo que nós vamos cobrir neste manual será, em umbanco de dados com um contexto relacionado.Os quatro tipos de associação no CakePHP são: hasOne, hasMany, belongsTo, ehasAndBelongsToMany (HABTM). Tabela 3. Tipos de associações possíveisTipo de associação ExemplohasOne Um usuário tem um perfil.hasMany Usuários em um sistema pode ter várias receitas.belongsTo Uma receita pertence a um usuário.hasAndBelongsToMany Receitas tem, e pertencem a muitas tags1.Associações são definidas através da criação de uma classe variável com o nome da associaçãoque você está definindo. A classe variável às vezes pode ser tão simples como uma string, maspode ser tão completa como um array multidimensional utilizado para definir associaçõesespecíficas.<?phpclass User extends AppModel { var $name = User; var $hasOne = Profile; var $hasMany = array( Recipe => array( className => Recipe, conditions => Recipe.approved = 1, order => Recipe.created DESC ) );}?>hasOneVamos criar um model chamado User que tenha a relação hasOne com o model Profile.Primeiro, suas tabelas da base de dados devem ser introduzidas corretamente. Para umarelação hasOne trabalhar, uma tabela tem de incluir uma chave estrangeira que aponta paraum registro na outra. Neste caso, a tabela profiles deverá conter um campo chamado user_id.O padrão básico é:HasOne: os *outros* models contêm a chave estrangeira.1 Tag: palavra-chave ou etiqueta, neste contexto significa palavra-chave.
  • 37. Desenvolvendo com CakePHP 36Apple hasOne Banana => bananas.apple_idUser hasOne Profile => profiles.user_idDoctor hasOne Mentor => mentors.doctor_idO arquivo do model User será salvo em “/app/models/user.php”. Para definir a associação“User hasOne Profile”, adicione a propriedade $hasOne a classe do model. Lembre-se de terum model Profile em “/app/models/profile.php”, ou a associação não irá funcionar.<?phpclass User extends AppModel { var $name = User; var $hasOne = Profile;}?>Existem duas formas de descrever essa relação nos seus models. O método mais simplesconsiste em definir o atributo $hasOne para uma string contendo o nome da classe do modelassociado, como fizemos anteriormente.Se você precisar de mais controle, você pode definir suas associações usando um array. Porexemplo, você pode querer classificar linhas relacionadas em ordem decrescente, de acordocom uma data, ou você pode querer limitar a associação para incluir apenas alguns registros.<?phpclass User extends AppModel { var $name = User; var $hasOne = array( Profile => array( className => Profile, conditions => Profile.published = 1, dependent => true ) );}?>As possíveis chaves do array para associações hasOne são:className: o nome da classe do model a ser associado ao model atual. Se você estiverdefinindo um relacionamento “User hasOne Profile”, o valor da chave className deve serigual a Profile;foreignKey: o nome da chave estrangeira encontrada no outro model. Isto é especialmente útilse você precisa definir múltiplos relacionamentos hasOne. O valor padrão para esta chave é onome no singular do outro model, seguida de “_id”.conditions: Um fragmento SQL utilizado para filtrar registros relacionados do model. É umaboa prática a utilização dos nomes dos modelos nos fragmentos SQL: “Profile.approved = 1” ésempre melhor do que apenas “approved = 1”.
  • 38. Desenvolvendo com CakePHP 37fields: A lista de campos da tabela a serem recuperados quando os dados do model associadosão coletados. Retorna todos os campos por padrão.dependent: Quando true, e o método delete() do model é chamado com o parâmetro cascade(cascata) para true, os registros associados do model também são apagados. Neste caso,defini-lo true, a exclusão do User também vai apagar o seu Profile associado.Uma vez que esta associação tenha sido definida, operações de busca sobre o modelo Usertambém vai buscar um registro relacionado de Profile, se existir:// Exemplo de resultados de uma chamada $this->User->find();Array( [User] => Array ( [id] => 121 [name] => Gwoo the Kungwoo [created] => 2007-05-01 10:31:01 ) [Profile] => Array ( [id] => 12 [user_id] => 121 [skill] => Baking Cakes [created] => 2007-05-01 10:31:01 ))belongsToAgora que temos o acesso aos dados do Profile pelo model User, vamos definir uma associaçãobelongsTo no model Profile, a fim de obter acesso aos dados relacionados de User. Aassociação belongsTo é um complemento natural à associações hasOne e hasMany : ele nospermite ver os dados da outra direção.Quando você estiver fazendo suas tabelas na base de dados, com um relacionamentobelongsTo, seguir esta convenção:belongsTo: O model *atual* contém a chave estrangeira.Banana belongsTo Apple => bananas.apple_idProfile belongsTo User => profiles.user_idMentor belongsTo Doctor => mentors.doctor_idSe uma tabela contém uma chave estrangeira, ela faz relacionamento belongsTo.Podemos definir a associação belongsTo no nosso model Profile em “/app/models/profile.php”usando a sintaxe de string como segue:<?phpclass Profile extends AppModel { var $name = Profile; var $belongsTo = User;}
  • 39. Desenvolvendo com CakePHP 38?>As possíveis chaves do array para associações belongsTo são:className: o nome da classe do model a ser associado ao model atual. Se você estiverdefinindo um relacionamento “Profile belongsTo User”, o valor da chave className deve serigual a User;foreignKey: O nome da chave estrangeira encontrada no outro model. Isto é especialmenteútil se você precisa definir múltiplos relacionamentos belongsTo. O valor padrão para estachave é o singular do nome do outro model, seguida de _id.conditions: Um fragmento SQL utilizado para filtrar registros relacionados do model. É umaboa prática a utilização dos nomes dos models nos fragmentos SQL: “User.active = 1” é sempremelhor do que apenas “active = 1”.fields: A lista de campos da tabela a serem recuperados quando os dados do model associadosão coletados. Retorna todos os campos por padrão.Uma vez que esta associação tenha sido definida, as operações de busca sobre o model Profiletambém vai buscar um registro ligado ao registro de User se existir:// Exemplo de resultados de uma chamada $this->Profile->find().Array( [Profile] => Array ( [id] => 12 [user_id] => 121 [skill] => Baking Cakes [created] => 2007-05-01 10:31:01 ) [User] => Array ( [id] => 121 [name] => Gwoo the Kungwoo [created] => 2007-05-01 10:31:01 ))hasManyPróximo passo: definir uma associação “User hasMany Comment”. A associação hasMany nospermitirá buscar comentários de um usuário quando faz uma operação de busca no modelUser.Quando você estiver fazendo suas tabelas na base de dados, com um relacionamentohasMany, seguir esta convenção:hasMany: os *outros* models contêm a chave estrangeira.User hasMany Comment => Comment.user_idCake hasMany Virtue => Virtue.cake_id
  • 40. Desenvolvendo com CakePHP 39Product hasMany Option => Option.product_idPodemos definir a associação hasMany no nosso model User /app/models/user.php usando asintaxe string como segue:<?phpclass User extends AppModel { var $name = User; var $hasMany = Comment;}?>Nós também podemos definir uma relação mais específica utilizando sintaxe de array:<?phpclass User extends AppModel { var $name = User; var $hasMany = array( Comment => array( className => Comment, foreignKey => user_id, conditions => Comment.status = 1, order => Comment.created DESC, limit => 5, dependent=> true ) );}?>As possíveis chaves do array para associações hasMany são:className: o nome da classe do model a ser associado ao model atual. Se você estiverdefinindo um relacionamento “User hasMany Comment”, a chave className deve ser igual“Comment”.foreignKey: o nome da chave estrangeira encontrada no outro model. Isto é especialmente útilse você precisa definir múltiplos relacionamentos hasMany. O valor padrão para esta chave é onome do outro model no singular, seguida de “_id”.conditions: Um fragmento SQL utilizado para filtrar registros no model relacionado. É uma boaprática a utilização nome do model nos fragmentos SQL: “Comment.status = 1” é sempremelhor do que apenas “status = 1”.fields: A lista de campos a serem recuperados quando os dados do model associado sãocoletados. Retorna todos os campos por padrão.order: Um fragmento SQL que define a classificação para a ordem para o retorno de linhasassociadas.limit: O número máximo de linhas associadas que você quer que retorne.
  • 41. Desenvolvendo com CakePHP 40offset: O número de linhas associadas para saltar sobre (dadas as atuais condições e ordem),antes de ir buscar e associar.dependent: Quando true, é possível a eliminação recursiva. Neste exemplo, Os registros deComment serão apagados quando o seu associado registro de User for excluído.Nota: o segundo parâmetro do método Model->delete() deve ser true, a fim de ocorrer asupressão (eliminação) recursiva.finderQuery: Uma completa consulta SQL CakePHP que pode-se usar para buscar registrosassociados. Isto deve ser utilizado em situações que exijam muito resultado personalizado.Uma vez que esta associação tenha sido definida, As operações de busca sobre o model Usertambém vai buscar registros relacionados em Comment se existirem:// Exemplo de resultados de uma chamada $this->User->find();Array( [User] => Array ( [id] => 121 [name] => Gwoo the Kungwoo [created] => 2007-05-01 10:31:01 ) [Comment] => Array ( [0] => Array ( [id] => 123 [user_id] => 121 [title] => On Gwoo the Kungwoo [body] => The Kungwooness is not so Gwooish [created] => 2006-05-01 10:31:01 ) [1] => Array ( [id] => 123 [user_id] => 121 [title] => More on Gwoo [body] => But what of the Nut? [created] => 2006-05-01 10:41:01 ) ))Uma coisa para se lembrar é que você precisará de um nova associação “Comment belongsToUser”, a fim de obter os dados de ambos os sentidos. O que temos esboçado nesta seção lhedá poderes para obter os dados dos comentários do usuário. Adicionando a associaçãoComment belongsTo User no model Comment lhe dá poderes para obter os dados do usuário apartir do model Comment - completa a ligação e permitindo que haja o fluxo de informação apartir de qualquer perspectiva de model.
  • 42. Desenvolvendo com CakePHP 41hasAndBelongsToMany (HABTM)Tudo bem. Neste ponto, você já pode chamar você mesmo de profissional em associações demodels no CakePHP. Você já está bem versado (experiente) nas três associações que ocupam amaior parte das relações entre objetos.Vamos resolver o último tipo de relacionamento: hasAndBelongsToMany, ou HABTM. Estaassociação é usada quando você tem dois models que precisam se juntar, várias vezes, muitasvezes, de muitas formas diferentes.A principal diferença entre hasMany e HABTM é que a ligação entre os modelos em HABTMnão é exclusiva. Por exemplo, estamos prestes a juntar nosso model Recipe (Receita) com omodel Tag usando HABTM. Anexando a tag “Italian” a minha receita “grandmas Gnocci” não“esgota” o registro do Tag. Também posso marcar o meu churrasco Honey Glazed Spaghettioscom a tag “Italian” se eu quiser.Ligações entre objetos associados com hasMany são exclusivos. Se User hasMany Comment,um comentário é apenas ligado a um usuário específico. Deixou-se para ganhar.Avancemos. É preciso criar uma tabela extra no banco de dados para manipular associaçõesHABTM. Esta nova tabela deve juntar o nome das tabelas associadas, incluindo os nomes deambos os models envolvidos, em ordem alfabética. O conteúdo da tabela deve ser de pelomenos dois campos, cada um com uma chave estrangeira (que devem ser inteiros) apontandopara ambas as chaves primárias dos modelos envolvidos.HABTM: Requer uma tabela separada que inclui os dois nomes dos models.Nota: O nome da tabela deve estar em ordem alfabética.Recipe HABTM Tag => recipes_tags.recipe_id, recipes_tags.tag_idCake HABTM Fan => cakes_fans.cake_id, cakes_fans.fan_idFoo HABTM Bar => bars_foos.foo_id, bars_foos.bar_idUma vez que esta nova tabela foi criada, podemos definir a associação HABTM nos arquivosdos models. Estamos indo saltar diretamente a sintaxe array desta vez:<?phpclass Recipe extends AppModel { var $name = Recipe; var $hasAndBelongsToMany = array( Tag => array(className => Tag, joinTable => recipes_tags, foreignKey => tag_id, associationForeignKey => recipe_id, conditions => , order => , limit => , uniq => true, finderQuery => , deleteQuery => , insertQuery => ) );
  • 43. Desenvolvendo com CakePHP 42}?>foreignKey: O nome da chave estrangeira encontrada no outro model. Isto é especialmenteútil se você precisa definir múltiplos relacionamentos HABTM. O valor padrão para esta chaveé o nome do outro model no singular, seguida de “_id”.associationForeignKey: O nome da chave estrangeira encontrada no model atual. Isto éespecialmente útil se você precisa definir múltiplos relacionamentos HABTM. O valor padrãopara esta chave é o nome do atual model no singular, seguida de “_id”.conditions: Um fragmento SQL utilizado para filtrar registros no model relacionado. É uma boaprática a utilização nome do model nos fragmentos SQL: “Recipe.status = 1” é sempre melhordo que apenas “status = 1”.fields: A lista de campos a serem recuperados quando os dados do model associado sãocoletados. Retorna todos os campos por padrão.order: Um fragmento SQL que define a classificação para a ordem para o retorno de linhasassociadas.limit: O número máximo de linhas associadas que você quer que retorne.offset: O número de linhas associadas para saltar sobre (dadas as atuais condições e ordem),antes de ir buscar e associar.dependent: Quando true, é possível a eliminação recursiva. Neste exemplo, Os registros deComment serão apagados quando o seu associado registro de User for excluído.Nota: o segundo parâmetro do método Model->delete() deve ser true, a fim de ocorrer asupressão (eliminação) recursiva.finderQuery, deleteQuery, insertQuery: Uma completa consulta SQL CakePHP que pode-seusar para buscar registros associados. Isto deve ser utilizado em situações que exijam muitoresultado personalizado.Uma vez que esta associação tenha sido definida, operações de busca sobre o model Recipe(Receita) também vai buscar registros relacionados em Tag caso existam:// Exemplo de resultados de uma chamada $this->Recipe->find();Array( [Recipe] => Array ( [id] => 2745 [name] => Chocolate Frosted Sugar Bombs [created] => 2007-05-01 10:31:01 [user_id] => 2346 ) [Tag] => Array (
  • 44. Desenvolvendo com CakePHP 43 [0] => Array ( [id] => 123 [name] => Breakfast ) [1] => Array ( [id] => 123 [name] => Dessert ) [2] => Array ( [id] => 123 [name] => Heart Disease ) ))Lembre-se de definir uma associação HABTM no model Tag se quiser buscar dados do modelRecipe, quando se utiliza o model Tag para pesquisas.Salvando dados em tabelas relacionadas (hasOne, hasMany, belongsTo)Ao trabalhar com models associados, é importante perceber que ao salvar os dados do modeldeve sempre ser feita pelo model CakePHP correspondente. Se você está salvando um novoPost e seus comentários associados, então você deve usar ambos os models Post e Commentdurante a operação de salvamento.Se nenhum dos registros do model associado, existem ainda no sistema (por exemplo, vocêpretende gravar um novo User com seus respectivos registros de Profile ao mesmo tempo),você precisa primeiro salvar o primário, ou model pai.Para ter uma idéia de como isso funciona, vamos imaginar que temos uma função no nossoUsersController que manipula o salvamento de um novo User e seu relacionado Profile. Oexemplo mostrado abaixo, a função irá assumir que você POSTou dados suficientes (usando oFormHelper) para criar um único usuário e um único perfil.function add() { if (!empty($this->data)) { // Podemos salvar os dados de User // Deve-se estar em $this->data[User] $this->User->save($this->data); // Agora nós adicionamos a informação que identifica // o usuário da base de dados a $this->data[Profile] // e salvamos o Profile. // A ID do usuário recém-criado foi definida // em $this->User->id. $this->data[Profile][user_id] = $this->User->id; // O salvamento do Profile pode ocorrer no model User // Porque a nossa relação "User hasOne Profile", pode acessar // o model Profile através do model User:
  • 45. Desenvolvendo com CakePHP 44 $this->User->Profile->save($this->data); }}Como regra geral, quando se trabalha com associações hasOne, hasMany, e belongsTo. Estassão todas as informações sobre a sua implementação. A idéia básica é obter a chave de ummodel e colocá-la no campo chave estrangeira do outro. Por vezes, este poderia envolver autilização do atributo $id da classe do model após um save(), mas outras vezes isso podeenvolver apenas recolher o ID de um input hidden em um formulário que é apenas tenha sidoPOSTado a uma função do controller.Salvando dados em tabelas relacionadas (HABTM)Salvando models que estão associados por hasOne, belongsTo, e hasMany é bastante simples:basta você preencher o campo chave estrangeira com a ID do model associado. Feito isso,basta você chamar o método save() sobre o model, e tudo fica ligado corretamente.Com HABTM, é um pouco complicado, mas temos ido fora da nossa forma a torná-lo o maissimples possível. Em consonância (concordância), juntamente com o nosso exemplo, vamosprecisar fazer algum tipo de formulário que relaciona tags a receitas. Vamos agora criar umformulário que gera tags, e associá-las a uma lista de receitas existentes.Talvez você realmente deseje criar um formulário que cria novas tags e associá-las durante aexecução - mas pelo bem da simplicidade, vamos apenas mostrar-lhe como associá-los e deixá-lo continuar a partir daí.Vamos apenas iniciar com a parte do formulário que gera uma tag. Lembra-se de nossooriginal exemplo “Recipe HABTM Tags”? O mais simples de HTML pode parecer algo como isto:<?php echo $form->create(Tag);?> <?php echo $form->hidden( Recipe.Recipe, array(value => $recipe_id) ) ?> <p><?php echo $form->input(Tag.name);?></p> <p><?php echo $form->end(Adicionar Tag);?></p></form>Ligações HABTM são formadas por um campo de formulário, nomeado com o nome do outromodel envolvido na associação HABTM. Neste exemplo, você pode ver o campo hiddenRecipe/Recipe cujo valor é definido com a ID da receita que queremos relacionar para a tagque será salva. A função do controller que trata este formulário poderá ser semelhante a esta:function add() { // Primeiro, vamos obter a ID da tag atual $this->Tag->recursive = 0; $tag = $this->Tag->findByName($this->data[Tag][name]); // Você pode querer criar a tag aqui se não existir, // Mas nós estamos assumindo que ela existe para avançar. :) // Definimos esta ID em $this->data, marcando-a como a
  • 46. Desenvolvendo com CakePHP 45 // tag que queremos associar. $this->data[Tag][id] = $tag[Tag][id]; // Definimos a ID da receita em $this->data, marcando-a como a // receita que queremos associar. $this->data[Recipe][Recipe] = array( $this->data[Recipe][Recipe] ); // Salva a associação if ($this->Tag->save($this->data)) { // Faça alguma coisa quando obter sucesso. }}Voila, dados dos models estão associados. Para analisar: a fim de salvar relacionamentosHABTM, preencher $this->data[OutroModelo][OutroModelo] com um array contendo a ID(ou IDs) dos registros que você deseja associar, e salvar o model atual , certificando-se que$this->data[ModeloAtual][id] esteja em vigor.Criando e removendo relações durante execuçãoPor vezes, torna-se necessário criar e destruir associações no model durante a execução. Issopode acontecer por algum número de razões:  Você deseja reduzir a quantidade coletada de dados associados, mas todas as suas associações estão no primeiro nível de recursão;  Você quer mudar o modo como uma associação é definida, a fim de ordenar ou filtrar dados associados.Esta criação e destruição de associação é feita usando os métodos bindModel() eunbindModel() do model CakePHP. Vamos configurar alguns models, para que possamos vercomo bindModel() e unbindModel() trabalham. Nós vamos começar com dois models:<?phpclass Leader extends AppModel { var $name = Leader; var $hasMany = array( Follower => array( className => Follower, order => Follower.rank ) );}?><?phpclass Follower extends AppModel { var $name = Follower;}?>
  • 47. Desenvolvendo com CakePHP 46Agora, no LeadersController, podemos usar o método find() do model Leader para buscar umlíder e seus seguidores associados. Como você pode ver acima, a associação em sintaxe dearray no model Leader define um relacionamento “Leader hasMany Follower”. Para fins dedemonstração, vamos usar unbindModel() para remover esta associação em uma função docontroller.function someAction() { // Isto recupera Líderes, e seus seguidores associados $this->Leader->findAll(); // Vamos remover o hasMany ... $this->Leader->unbindModel( array(hasMany => array(Follower)) ); // Agora usando a função find() irá retornar // Líderes, sem os seus seguidores $this->Leader->find(); // NOTA: unbindModel() afeta somente a mais próxima // função find(). Uma nova chamada find() será usada // a informação configurada na associação do model. // Já utilizando findAll(), após unbindModel(), // esta vai buscar Líderes com seguidores // associados mais uma vez ... $this->Leader->findAll();}Mais um lembrete. Removendo ou adicionando associações usando bind e unbindModel() sófunciona para a próxima operação do model, a menos que o segundo parâmetro $reset forescolhido para true. Se o segundo parâmetro foi escolhido para true, ao vincular esteparâmetro, a funções binds, mantém-se em vigor para o restante dos pedidos ou pesquisas.Aqui está a base para o uso padrão de unbindModel():$this->Model->unbindModel( array(associationType => array(associatedModelClassName)));// associationType => O tipo de associação com o outro model(associatedModelClassName) que você quer remover.Agora que removida com êxito uma associação durante a execução, vamos adicionar uma.Nossa como de ainda temos Líderes sem princípios necessitamos alguns Princípios associados.O arquivo do model para o nosso model Principle está vazio, com exceção para a declaraçãovar $name. Vamos associar alguns princípios para ao nosso model Leader durante a execução(mas lembre: apenas servirá a próxima operação de busca). Esta função aparece noLeadersController:function anotherAction() { // Não há "Leader hasMany Principles" no // arquivo do model leader.php, // aqui somente vamos encontrar Líderes.
  • 48. Desenvolvendo com CakePHP 47 $this->Leader->findAll(); // Vamos usar bindModel() para adicionar uma nova associação // para o model Leader. $this->Leader->bindModel( array(hasMany => array( Principle => array( className => Principle ) ) ) ); // Agora que está ligado corretamente, // Podemos utilizar uma única função find() para buscar // Líderes com seus associados princípios: $this->Leader->findAll();}Isto é o que você tem. A base para uso do bindModel() é o encapsulamento de uma associaçãonormal dentro de um array cuja chave é nomeada após o tipo de associação que você estátentando criar:$this->Model->bindModel( array(associationName => array( associatedModelClassName => array( // Aqui você pode usar normalmente as chaves e/ou opçõesde associação. ) ) ) );Embora o model recém-vinculado não precise de nenhum tipo de associação na definição domodel dentro do arquivo dele, ele ainda precisa ser introduzido corretamente para que a novaassociação funcione corretamente.DataSourcesBehaviorsIntroduçãoUsando BehaviorsTreeBehaviorTranslateBehaviorACLBehaviorViews (Visões)Templates / SkinEm CakePHP, você fala com seus usuários através da camada das views. A maior parte dotempo, suas views estarão mostrando documentos (x)HTML para os navegadores, mas você
  • 49. Desenvolvendo com CakePHP 48pode também precisar servir dados AMF para um objeto Flash, responder a uma aplicaçãoremota via SOAP, ou exportar um arquivo CSV para um usuário.Os arquivos de view do CakePHP são escritos em PHP comum e tem a extensão padrão de .ctp(CakePHP Template). Esses arquivos contêm toda a lógica de apresentação necessária paratransformar os dados recebidos do controller em um formato que está pronto para aaudiência.Arquivos de view são guardados em /app/views/, em um diretório com o nome do controllerque usa os arquivos, e nomeado de acordo com a view a qual corresponde. Por exemplo, aaction ver() do controller Produtos será normalmente encontrada em/app/views/produtos/ver.ctp.A camada da view no CakePHP pode ser feita de algumas diferentes partes. Cada parte temdiferentes usos, e será coberta em seu capítulo:  layouts: arquivos view que contém o código da apresentação que é encontrado envolvendo muitas interfaces em sua aplicação. A maior parte das views é renderizada dentro de um layout;  elements: pedaços de código pequenos e reutilizáveis. Elements são geralmente renderizados dentro de views;  helpers: essas classes encapsulam lógica da view que é necessária em muitos lugares na camada da view. Entre outras coisas, helpers no CakePHP podem ajudá-lo a construir formulários, construir funcionalidade Ajax, paginar dados do model, ou servir feeds RSS.LayoutsUm layout contém código de apresentação que envolve uma view. Qualquer coisa que vocêquiser ver em todas as suas views deve ser colocada em um layout.Arquivos de layout devem ser colocados em /app/views/layouts. O layout padrão pode sersobrescrito criando um novo layout padrão em /app/views/layouts/default.ctp. Uma vez queum novo layout foi criado, código de view renderizado pelo controller é colocado dentro dolayout padrão quando a página é renderizada.Quando você cria um layout, você precisa dizer ao CakePHP onde colocar o código de suasviews. Para tanto, garanta que seu layout tem um lugar para o conteúdo do layout através davariável $content_for_layout (e opcionalmente, título para o layout através da variável$title_for_layout). Aqui vai um exemplo do que um layout padrão deve parecer:<!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"><head><title><?php echo $title_for_layout?></title><link rel="shortcut icon" href="favicon.ico" type="image/x-icon"></head><body><!-- Se você gostaria que algum tipo de menu seja
  • 50. Desenvolvendo com CakePHP 49mostrado em todas as suas views, insira ele aqui --><div id="header"> <div id="menu">...</div></div><!-- É aqui que eu quero que minhas views apareçam --><?php echo $content_for_layout ?><!-- Adicione um rodapé para cada página mostrada --><div id="footer">...</div></body></html>Para configurar um título para o layout, é mais fácil fazê-lo no controller, usando a variável decontroller $pageTitle.class UsuariosController extends AppController { function verAtivos() { $this->pageTitle = Ver Usuários Ativos; }}Você pode criar quantos layouts você desejar: apenas coloque-os no diretório/app/views/layouts, e escolha entre eles o ideal para cada action do controller usando avariável $layout ou a função setLayout(). Controllers que não tenham a variável $layoutconfigurada usarão o layout padrão.Por exemplo, se uma sessão do meu site incluir um pequeno espaço para banner, eu possocriar um novo layout com um pequeno espaço para propaganda e especificá-lo como layoutpara todas as actions de controller usando algo como:class UsuariosController extends AppController { var $layout = padrao_propag_mini; function verAtivos() { $this->pageTitle = Ver Usuários Ativos; $this->layout = padrao_propag_mini; } function verImagem() { $this->layout = imagem; // imprimir a imagem para o usuário }}CakePHP tem em seu núcleo, dois layouts (além do layout padrão) que você pode usar em suasaplicações: ajax e flash. O layout Ajax é ótimo para criar respostas Ajax - é um layout vazio (amaior parte das chamadas ajax requer pouca marcação em retorno, ao invés uma interfacetotalmente renderizada). O layout flash é usado para mensagens mostradas pelos métodosflash() dos controllers.Três outros layouts - xml, js, e rss - existem no núcleo para acelerar e facilitar servir conteúdodiferente de text/html.
  • 51. Desenvolvendo com CakePHP 50Elements (Elementos)Muitas aplicações têm pequenos blocos de código de apresentação que precisa ser repetidode página em página, algumas vezes em diferentes lugares no layout. O CakePHP te ajuda arepetir partes do seu website que precisam ser reutilizadas. Essas partes reutilizáveis sãochamadas elements. Um element é basicamente uma mini-view que pode ser incluída emoutras views.Elements vivem no diretório /app/views/elements/, e tem uma extensão .ctp no nome dearquivo.Por padrão, elements são estáticos. Você pode dar vida aos seus elements e passar para elesvariáveis da view usando um parâmetro adicional no método renderElement().// Chamando um element sem parâmetros// Esse element só contém código estático de view.<?php echo $this->element(ajuda); ?>// Chamando um element passando um array de dados,// permitindo que o element se comporte dinamicamente.<?php echo$this->element( ajuda, array(mensagem => Ah, esse texto é realmente muito útil.));?>Nota: Você pode aproveitar o sistema de cache de view do CakePHP se você fornecer “cache”como true no segundo parâmetro do método element().// Renderiza o element e faz cache dele por um dia<?php echo $this->element(ajuda, array(cache => true)); ?>Dentro do arquivo element, todos as variáveis estão disponíveis como os nomes dos índices doarray fornecido (muito parecido com como set() funciona no controller com arquivos de view).No exemplo acima, o arquivo /app/views/elements/ajuda.ctp pode usar a variável$mensagem.Uma forma de aproveitar totalmente os elements é usar requestAction(). A funçãorequestAction() preenche a view com variáveis da action do controller e as retorna como umarray. Isso torna possível aos seus elements agir realmente no estilo MVC. Crie uma action docontroller que prepara as variáveis da view para seus elements e chame requestAction() dentrodo segundo parâmetro de requestElement() para preencher o element com as variáveis deview vindas do controller.Elements podem ser usados para fazer a view mais legível, colocando os elementos repetitivosem seus próprios arquivos. Eles podem também ajudá-lo a reutilizar fragmentos de conteúdoem sua aplicação.Helpers (Ajudantes)IntroduçãoHelpers (Ajudantes) são classes do tipo component para a camada de apresentação da suaaplicação. Eles contêm lógica de apresentação que é compartilhada entre muitas views,
  • 52. Desenvolvendo com CakePHP 51elements ou layouts. Cada helper estende AppHelper (opcionalmente definido em/app/app_helper.php), uma classe que guarda qualquer lógica necessária para todos oshelpers.O propósito desse capítulo é mostrar a você como criar seus próprios helpers, destacaralgumas tarefas básicas que os helpers do CakePHP podem ajudá-lo a realizar.Você usa helpers em CakePHP tornando os controllers conscientes deles. Cada controller temuma variável de classe especial chamada $helpers que mantém uma lista dos helpersdisponíveis para todas as views que esse controller renderiza. Para disponibilizar um helper emsua view do controller, adicione o nome do helper no array $helpers desse controller.<?phpclass PadeirosController extends AppController { var $helpers = array(Form, Html, Javascript, Time);}?>Helpers do CakePHPO CakePHP tem alguns helpers muito úteis na criação de views. Eles ajudam na criação demarcação bem formatada (incluindo formulários), ajudam na formatação de texto, datas enúmeros, e pode até acelerar uma funcionalidade Ajax. Aqui está uma lista rápida dos helperscom um resumo das suas habilidades. Para mais informação sobre um helper particular, dêuma olhada em sua respectiva sessão da parte de Helpers internos. Tabela 4. Helpers internos do CakePHPHelper CakePHP DescriçãoAjax Usado também com a biblioteca JavaScript Prototype para criar funcionalidade Ajax nas views. Contém métodos de atalho para arrastar/soltar, formulários ajax & links, observers, e mais.Cache Usado internamente para para criar cache do conteúdo das views.Form Cria formulários HTML e elementos de formulários com habilidade de auto-popular e manipulam problemas de validação.Html Métodos de conveniência para criação de marcação bem formatada. Imagens, links, tabelas, tags de cabeçalho e mais.Javascript Usado para escapar valores para uso em JavaScripts, escrever dados para objetos JSON, e formatar blocos de código.Number Formatação de números e moedasPaginator Paginação de dados do model e organização.Rss Métodos de conveniência para exportar dados XML RSSSession Acesso para escrita de valores de sessão nas viewsText Links automáticos, destaques, e truncamento automático de palavras.Time Detecção de proximidade (é o ano quem vem?), formatação de strings (Hoje, 10:30 am) e conversão de zona de tempo.Xml Métodos de conveniência para criar cabeçalhos e elementos XML.
  • 53. Desenvolvendo com CakePHP 52Criando helpersSe um helper interno (ou um mostrado em Cakeforge ou em Bakery) não se adapta a suasnecessidades, helpers são fáceis de fazer.Vamos dizer que nós queremos criar um helper que pode ser usado para imprimir um tipoespecífico de link CSS que você precisa em muitos lugares diferentes em sua aplicação. Paracolocar sua lógica na estrutura de helpers dos CakePHP, você deve criar uma nova classe em/app/views/helpers. Vamos chamar nosso helper de LinkHelper. O arquivo de classe PHP atualvai se parecer com isso:<?php/* /app/views/helpers/link.php */class LinkHelper extends AppHelper { function editar($titulo, $caminho) { // Lógica para criar links especialmente formatados vai aqui... }}?>  output(string $string)Use essa função para enviar qualquer dado de volta para sua view.function editar($titulo, $caminho) { // Use essa função para enviar qualquer dado formatado // de volta para sua view: return $this->output( "<div class="editarContainer"> <a href="$caminho" class="editar">$titulo</a> </div>" );}Incluindo outros helpersVocê pode querer usar alguma funcionalidade já existente em outro helper. Para tanto, vocêpode especificar os helpers que você deseja usar com o array $helper, formatado exatamentecomo você faria no controller.// /app/views/helpers/link.php (usando outros helpers)class LinkHelper extends Helper { var $helpers = array(Html); function editar($titulo, $caminho) { // Usando o helper HTML para criar // dados formatados: $link = $this->Html->link($titulo, $caminho, array(class =>editar)); return $this->output("<div class="editarContainer">$link</div>"); }}
  • 54. Desenvolvendo com CakePHP 53Usando seus helpers personalizadosUma vez que você criou seu helper e o colocou em /app/views/helpers/, você estará habilitadoa usá-lo em seus controllers usando a variável especial $helpers.Assim que seu controller estiver consciente de sua nova classe, você pode usá-la em suas viewsacessando uma variável com o nome do helper:<!-- faz um link usando o novo helper --><?php $link->editar(Mudar esta receita, /receitas/editar/5) ?>Nota: lembre-se de incluir o HtmlHelper e/ou FormHelper em seu array $helpers se vocêplaneja usá-los em qualquer lugar.ContribuindoPor favor, considere doar seu código de volta ao CakePHP - contate um dos desenvolvedoresusando nosso sistema de Trac ou a lista de e-mails, ou abra um novo projeto em CakeForgepara compartilhar seu novo helper com outros.ScaffoldingIntroduçãoScaffold (equivalente em português seria andaime, aqui trataremos como protótipo) deaplicação é uma técnica que permite ao desenvolvedor definir e criar uma aplicação básica quepode criar, obter, atualizar e excluir objetos. Scaffold em CakePHP também permitedesenvolvedores definir como objetos são relacionados com outros, e criar e quebrar essasligações.Tudo que é necessário para criar um scaffold é um model e seu controller. Uma vez que vocêconfigurou a variável $scaffold no seu controller você já tem tudo funcionando.O scaffold do CakePHP é muito legal. Ele te dá uma aplicação CRUD (Create - Criar, Retrive -Obter, Update - Atualizar, Delete - Excluir) totalmente funcional em minutos. Tão legal quevocê vai querer usá-lo em aplicações em fase de produção. Agora, nós também pensamos queele é legal, mas, por favor, perceba que scaffold é... bem... apenas scaffold. É uma estruturasimples que você põe para funcionar muito rápido no início do projeto para ter algofuncionando o mais rápido possível. Ele não tem intenção de ser completamente flexível, ele émais como uma forma de já começar com algo funcionando. Se você se perceber precisandopersonalizar suas lógica e suas views, é hora deixar de lado seu scaffold e escrever um poucode código. O console Bake do CakePHP, coberto em uma sessão mais a frente, é ótimopróximo passo: ele gera todo o código que produzirá um resultado parecido com o scaffoldatual.Scaffold é uma ótima forma de lidar com as partes iniciais do desenvolvimento de umaaplicação web. Esquemas de banco de dados iniciais estão sujeitos a mudanças, o que éperfeitamente normal na parte inicial do processo de design. E aí existe um problema:desenvolvedores web detestam criar formulários que nunca serão realmente usados. Parareduzir o trabalho do desenvolvedor, o scaffold foi adicionado no CakePHP. Ao fazer scaffold oCakePHP analisa suas tabelas do banco de dados e cria listas padronizadas com botões add,
  • 55. Desenvolvendo com CakePHP 54delete e edit, formulários padrões de edição e views padronizadas para inspeção de itens nobanco de dados.Para adicionar scaffold na sua aplicação, em seu controller adicione a variável $scaffold:<?phpclass CategoriasController extends AppController { var $scaffold;}?>Assumindo que você criou até mesmo o arquivo de classe model Categoria (em/app/models/categoria.php), você está pronto para ir. Visite http://exemplo.com/categoriaspara ver seu novo scaffold.Nota: criar métodos em controllers que tem scaffold pode causar resultados não desejados.Por exemplo, se você criar uma método index() em um controller com scaffold, seu métodoindex será renderizado ao invés da funcionalidade do scaffold.O scaffold está ciente das associações entre models, então se o seu model Categoria estáassociado através de belongsTo a um model Usuario, você verá a listagem de IDs do Usuario.Se você ao invés do ID quer ver outra coisa (como o nome do usuário), você pode configurar avariável $displayField no model.Vamos configurar a variável $displayField na class Usuario para que as categorias mostremusuários pelo nome ao invés de apenas o ID no scaffold. Esse recurso faz com que o scaffold setorne mais legível em muitas situações.<?phpclass Usuario extends AppModel { var $name = Usuario; var $displayField = nome;}?>Personalizando os scaffoldsSe você está procurando por algo um pouco diferente em suas views de scaffold, você podecriar templates. Nós não recomendamos essa técnica para aplicações em nível de produção,mas esse nível de personalização pode ser útil durante as fases de interação.A personalização é feita através da criação de templates para as views:Views scaffold personalizadas para um controller específico (PostsControllerneste exemplo) deve ser colocado assim:/app/views/posts/scaffold.index.ctp/app/views/posts/scaffold.show.ctp/app/views/posts/scaffold.edit.ctp/app/views/posts/scaffold.new.ctpViews scaffold para todos os controllers devem ser colocadas assim:
  • 56. Desenvolvendo com CakePHP 55/app/views/scaffolds/index.ctp/app/views/scaffolds/show.ctp/app/views/scaffolds/edit.ctp/app/views/scaffolds/new.ctp/app/views/scaffolds/add.ctpCakePHP ConsoleIntroduçãoCriando Shells e TasksCriando suas ShellsTasksGerando código com BakePluginsCriando um pluginPlugin de controladoresPlugin de modelosPlugin de visõesPlugin de informaçõesConstantes e funções globaisEmbora a maior parte do seu dia-a-dia no trabalho com o CakePHP será utilizando as classes eos métodos do núcleo, o CakePHP apresenta inúmeras funções globais que podem ser úteis.Muitas destas funções são para o uso das classes do CakePHP (carregando classes Models ouComponents), mas muitas outras funções tornam o trabalho com arrays ou strings um poucomais fácil.Iremos também abranger algumas das constantes disponíveis. Fazendo uso destas constantes,as atualizações irão se tornar mais fáceis, mas também, são uma maneira conveniente deapontar para determinados arquivos ou diretórios em suas aplicações.Funções globaisAqui estão as funções globais disponíveis no CakePHP. Muitos delas são longas funções do PHPconvenientemente reescritas, mas algumas (como vendor(), e uses()) podem ser usadas paraincluir códigos ou executar outras funções úteis. Provavelmente, se você estiver querendouma função para realizar uma tarefa repetitiva, ela estará aqui.  __(string $string_id, boolean $return = false)Esta função manipula a internacionalização nas aplicações CakePHP. A string $string_ididentifica a ID para uma tradução, e o segundo parâmetro lhe permite "echoar" a stringdiretamente (este é o padrão), ou devolvê-la para o tratamento posterior (você deve passar
  • 57. Desenvolvendo com CakePHP 56um valor booleano true para ativar esse comportamento). Confira a seçãoInternacionalizando para obter mais informações.  a(mixed $one, $two, $three...)Retorna uma array com os parâmetros utilizados na chamada desta função.print_r(a(foo, bar));// Saída:array( [0] => foo, [1] => bar)  aa(array $one, $two, $three...)Usado para criar arrays associativas, formada com os parâmetros utilizados na chamada destafunção.echo aa(a,b);// Saída:array(a => b)  am(array $one, $two, $three...)Agrupa todas as arrays passadas como parâmetros.  convertSlash(string $string)Converte barras em underlines e remove o primeiro e ultimo underline em uma string. Retornaa string convertida.  countdim(array $array)Retorna o número de dimensões de uma array fornecida.  debug(mixed $var, boolean $showHtml = false)Se o nível de debug da aplicação é diferente de zero, $var é impresso na tela. Se $showHTMLfor verdadeiro (true), os dados serão exibidos de forma mais amigável à leitura no navegador.  e(mixed $data)Conveniente reescrita da função echo().  env(string $key)Retorna uma variável de ambiente a partir de fontes disponíveis. Utilizado como um backupcaso $_SERVER ou $_ENV estiverem desabilitados.
  • 58. Desenvolvendo com CakePHP 57Esta função também emula PHP_SELF e DOCUMENT_ROOT em servidores que não ossuportam. De fato, é uma boa idéia usar sempre a função env() em vez de usar $_SERVER ougetenv() (especialmente se você pretende distribuir seu código), uma vez que ele é umcompleto emulador das variáveis citadas acima.  fileExistsInPath(string $file)Verifica se o arquivo fornecido está dentro do atual include_path do PHP. Retorna umresultado booleano.  ife($condition, $ifNotEmpty, $ifEmpty)Utilizado em operações ternárias. Se $condition não é vazio, $ifNotEmpty é retornado se não$ifEmpty é retornado.  loadBehavior()  loadComponent()  loadController()  loadControllers()  loadHelper()  loadModel()  loadModels()  loadPluginComponent()  loadPluginController()  loadPluginHelper()  loadPluginModels()  loadView()Este conjunto de funções globais é usado para carregar classes do núcleo do CakePHP paraposterior instanciação. Basta fornecer o nome da(s) classe(s) que você gostaria de carregar.Isto é especialmente útil para o console de tarefas.loadModel(Orders);$Order = new Order();  low(string $string)Conveniente reescrita da função strtolower() do PHP.  paths()Retorna uma array contendo o caminho dos diretórios do CakePHP indexados por Models,Behaviors, Controllers, Components, e Helpers.  pr(mixed $var)Conveniente reescrita da função print_r() do PHP, com a adição da tag <pre> englobando asaída de print_r().
  • 59. Desenvolvendo com CakePHP 58  r(string $search, string $replace, string $subject)Conveniente reescrita da função str_replace() do PHP.  stripslashes_deep(array $value)Retira as barras da array informada de forma recursiva, retornando a array modificada.  up(string $string)Conveniente reescrita da função strtoupper() do PHP.  uses(string $lib1, $lib2, $lib3...)Usado para carregar bibliotecas do núcleo do CakePHP (encontradas em cake/libs/).  vendor(string $lib1, $lib2, $lib3...)Usado para carregar bibliotecas externas (de terceiros) encontrados no diretório /vendors ouapp/vendors.Constantes do núcleo Tabela 5. Constantes do CakePHPConstante DescriçãoCOMPRESS_CSS Se definido como verdadeiro (true) as folhas de estilo CSS serão compactadas em modo de produção. Isto requer um diretório /var/cache com permissão de escrita pelo servidor. Para utilizar, inclua suas folhas de estilo referenciando-as com o caminho /ccss (diferente de /css) ou utilize o método Controller::cssTag().LOG_ERROR Constante de erro. Usado para diferenciar erros de Log e Debug. Atualmente o PHP suporta LOG_DEBUGConstantes do diretório Tabela 6. Constantes dos diretóriosConstante Caminho absoluto dos diretórios do aplicativoAPP Diretório raizAPP_PATH Diretório do aplicativoCACHE Diretório para os arquivos de cache do aplicativoCAKE Diretório do CakePHPCOMPONENTS Diretório dos componentsCONFIGS Diretório dos arquivos de configuração do aplicativoCONTROLLER_TESTS Diretório do controller de testesCONTROLLERS Diretório dos controladorsCSS Diretório dos arquivos CSSELEMENTS Diretório dos elementsHELPER_TESTS Diretório dos helpers de testeHELPERS Diretório dos helpersINFLECTIONS Diretório das inflexões (geralmente o mesmo diretório dos arquivos de configuração)JS Diretório dos arquivos JavaScript (no webroot)
  • 60. Desenvolvendo com CakePHP 59LAYOUTS Diretório dos layoutsLIB_TESTS Diretório das bibliotecas de testes do CakePHPLIBS Diretório das bibliotecas do CakePHPLOGS Diretório dos arquivos de log (no app)MODEL_TESTS Diretório dos models de testeMODELS Diretório dos modelsSCRIPTS Diretório de scripts do CakePHPTESTS Diretório de testes (pai das pastas models, controllers, etc. No diretório de testes)TMP Diretório de arquivos temporáriosVENDORS Diretório para bibliotecas externas (de terceiros)VIEWS Diretório das views
  • 61. Tarefas comuns com CakePHP 60 Parte IV. Tarefas comuns com CakePHPValidação de dadosRegras simplesUma regra por camporulerequiredallowEmptyonmessageMúltiplas regras por campoConstruindo regras de validaçãoalphaNumericbetweenblankcccomparisondateemailipminLengthmaxLengthnumericphonepostalssnurlRegras de validação personalizada
  • 62. Tarefas comuns com CakePHP 61Validação por expressões regulares personalizadasValidação por métodos personalizadosLimpeza de dadosManipulação de errosDebugandoGerando cachesLogandoIntroduçãoEnquanto algumas definições da Classe de Configuração do CakePHP podem realmente ajudá-lo a ver o que está acontecendo por debaixo dos panos, há certos momentos em que vocêprecisa logar os dados no disco (em um arquivo de texto) para descobrir o que estáacontecendo. Num mundo que está cada vez mais dependente de tecnologias como SOAP eAJAX, o ato de debugar pode ser bastante difícil.Logar também pode ser uma maneira de descobrir o que está acontecendo na sua aplicação aolongo do tempo. Quais os termos de busca estão sendo usados? Quais erros estão sendomostrados aos meus usuários? Quantas vezes uma determinada consulta está sendoexecutada?Logar dados no CakePHP é fácil. A função log() faz parte da classe Object, que é uma classeancestral comum para quase todas as outras classes do CakePHP. Se o contexto for uma classeCakePHP (Model, Controller, Component... quase todas), você pode logar seus dados.Usando as funções de logA função log() recebe dois parâmetros. A primeira é a mensagem que você gostaria deescrever no arquivo de log. Por padrão, esta mensagem de erro é escrita no log de errosencontrado em app/tmp/logs/error.log:// Execute isto dentro de uma classe do CakePHP:$this->log("Algo não funciona!");// O resultado será adicionado ao final do arquivo app/tmp/logs/error.log2007-11-02 10:22:02 Error: Algo não funciona!O segundo parâmetro é usado para definir o tipo de mensagem de log que você desejaescrever. Se não for informado, o padrão é LOG_ERROR, que escreverá no arquivomencionado anteriormente. Você pode passar este segundo parâmetro como LOG_DEBUG eescrever as suas mensagens no arquivo de log para debug encontrado emapp/tmp/logs/debug.log// Execute isto dentro de uma classe do CakePHP:
  • 63. Tarefas comuns com CakePHP 62$this->log(Uma mensagem de debugação., LOG_DEBUG);// O resultado será adicionado ao final do arquivo app/tmp/logs/debug.log (emvez de error.log)2007-11-02 10:22:02 Error: Uma mensagem de debugação.Observação: O diretório app/tmp deve ter permissão de escrita pelo usuário do servidor webpara que esta função execute corretamente.TestandoInternacionalizandoUm dos melhores caminhos para chegar a uma grande platéia é fazer um aplicativo emdiversos idiomas. Isso pode representar uma grande tarefa, mas os recursos deinternacionalização no CakePHP fazem isto muito mais fácil.Primeiro, é importante que você entenda a terminologia. O termo localização (localization)refere-se à adaptação de uma aplicação para atender as necessidades de um idioma específico(ou cultura), como, por exemplo, um locale. Internacionalização (internacionalization) refere-se à habilidade de sua aplicação se "localizável". Internacionalização e localização sãoabreviadas como i18n e l10n, respectivamente; 18 e 10 representam a quantidade decaracteres entre o primeiro e o último caractere.Definindo o locale da sua aplicaçãoQualquer controlador que usa o conteúdo localizado inclui a classe L10 do núcleo do CakePHP.<?php// Include the L10n class:uses(‘L10n’);class RecipesController extends AppController { // ...}?>Em seguida, você precisa criar os arquivos de idioma que controlam as stringsinternacionalizáveis. Cada idioma contém um conjunto de strings com suas IDs. Criando estesarquivos, você tem um caminho para ser organizado e traduzido. Cada idioma deve conter oarquivo default.po em uma pasta com o nome do idioma a que se refere./app/locale/eng/LC_MESSAGES/default.po (Inglês)/app/locale/fre/LC_MESSAGES/default.po (Francês)/app/locale/por/LC_MESSAGES/default.po (Português)/app/local/pt_br/LC_MESSAGES/default.po (Português - Brasil)A pasta locale fica dentro da pasta app da sua instalação do CakePHP. Os caracteres delocalização (ex: eng, por, pt_br) seguem o padrão ISO 639-2 (exemplos podem ser encontradosno site do Library of Congress, http://www.loc.gov/standards/iso639-2/php/code_list.php).
  • 64. Tarefas comuns com CakePHP 63Depois de criar os arquivos, preencha-os com as strings chaves e os valores usados para oprocesso de internacionalização. Cada string chave deve ter um único valor correspondente.Aqui um exemplo básico que deve estar dentro do arquivo .po do idioma português:msgid "purchase"msgstr "Para comprar o item selecionado, clique em Comprar Agora."msgid "search"msgstr "Clique aqui para procurar na nossa base de dados."Note que seus arquivos .po devem ser codificados usando o padrão ISO-8859-1, e que estesnão excedam o limite de 1024 caracteres na string de valor (msgstr).Depois de criar os arquivos .po corretamente, sua aplicação já está internacionalizada.Internacionalizando em CakePHPUsando os dados de localização na sua aplicação é simples. O primeiro passo é avisar aoCakePHP qual idioma sua aplicação deve utilizar para mostrar o conteúdo. Isso pode ser feitodetectando subdomínios (en.exemplo.com.br ou pt.exemplo.com.br), usando a informação dobrowser ou qualquer outra maneira.Alteração de idioma deve ser feita no controlador:$this->L10n = new L10n();$this->L10n->get("en");Configure::write(Config.language, "en");Você pode por este código no beforeFilter para fazer com que cada ação no controlador sejamostrada usando o idioma corretamente, ou você pode querer colocar isso em uma ação quemanipule a autenticação, ou ainda colocar para escolher o idioma padrão.Para fazer suas strings internacionalizáveis, utilize a função __(). Esta função está disponívelglobalmente, mas você provavelmente utilizará mais nas visões. O primeiro parâmetro dafunção é o texto que vai na msgid do arquivo .po. Este conteúdo é exibido (echo) por padrão,mas um segundo parâmetro pode ser utilizado (opcional), que informa se você quer retornar otexto (para manipulação de links, por exemplo). O pequeno exemplo abaixo mostra comointernacionalizar strings usando a função __(). A atual saída depende do idioma que foiselecionado usando a classe L10n e as configurações setadas.<hr /> <p><?php __("purchase"); ?></p><hr />Lembre-se de usar o parâmetro de retorno em métodos de helper se você deseja que oconteúdo seja traduzido na chamada do método do ajudante. Use o segundo parâmetro do__() para retornar os dados ao invés de exibir (echo):<?php echo $form->error( Card.cardNumber, __("errorCardNumber", true), array(escape => false)); ?>
  • 65. Tarefas comuns com CakePHP 64PaginaçãoConfigurando os controladoresPaginando nas visõesPaginando com AJAXAlterações no layoutAlterações nas visões
  • 66. Componentes internos 65 Parte V. Componentes internosLista de controle de acessos (ACL)AutenticaçãoSessõesManipulando requisiçõesSegurançaE-mailCookiesIntroduçãoConfigurando os controladoresUsando o componente
  • 67. Helpers internos 66 Parte VI. Helpers internosFormuláriosO FormHelper é uma nova adição ao CakePHP. A maior parte do trabalho pesado na criação deformulário é agora feita usando esta nova classe, em vez dos (agora obsoletos) métodos doHtmlHelper. O FormHelper centra-se na criação de formulários rapidamente, de uma formaque irá dinamizar validação, re-preenchimento e o layout. O FormHelper também é flexível,que vai fazer quase tudo para você automagicamente ou você pode usar métodos específicospara obter apenas o que necessita.Criando formuláriosO primeiro método que você precisará usar na ordem para ganhar vantagens do FormHelper éo create(). Este método especial retorna uma tag de abertura de formulário.  create(string $model = null, array $options = array())Todos os parâmetros são opcionais. Se create() é chamada sem parâmetros fornecidos, Estaassume que você está construindo um formulário que será submetido a função add() docontrolador atual, via POST. O elemento do formulário também é retornado com o atributo idseguindo um padrão DOM “ModelActionForm”, em forma de camelo. Se eu fosse chamarcreate() dentro de uma visão (view) do controlador UserController, Eu veria algo como aseguinte saída na visão.<form id="UserAddForm" method="post" action="/users/add">O método create() permite personalizar muito mais usando os parâmetros, no entanto.Primeiro, você pode especificar um nome de modelo. Este modelo é, então, assumido como opadrão para todos os campos do formulário, bem como o id em DOM da tag do formulário éalterada.<?php echo $form->create(Recipe); ?>// Saída:<form id="RecipeAddForm" method="post" action="/recipes/add"> * Recipe = ReceitaO array $options é onde a maior parte da configuração do formulário acontece. Este arrayespecial pode conter um número de diferentes pares valor-chave que afetam a forma como atag do formulário é gerada.$options[type]Esta chave é utilizada para especificar o tipo de formulário a ser criado. Os valores válidosincluem post, get, file, put e delete.Preenchendo com post ou get muda o modo de como o formulário submete a informação.<?php echo $form->create(User, array(type => get)); ?>
  • 68. Helpers internos 67// Saída:<form id="UserAddForm" method="get" action="/users/add">Especificando file muda a forma de submeter para o método “post”, e inclui um atributoenctype de “multipart/form-data” na tag do formulário. Isto é para ser usado se houver algumelemento de entrada de arquivo, dentro do formulário. A ausência de um bom atributoenctype, fará com que o upload de arquivo não funcione.<?php echo $form->create(User, array(type => file)); ?>// Saída:<form id="UserAddForm" enctype="multipart/form-data" method="post"action="/users/add">Quando estiver usando “put” ou “delete”, o formulário será funcionalmente equivalente a umformulário submetido em modo post, mas, quando submetido, o método de solicitação HTTPserá ultrapassado com PUT ou DELETE, respectivamente. Isto permite o CakePHP emularadequadamente o suporte em navegadores web.$options[action]A chave $action permite que você aponte o formulário para uma action específica no seucontroller atual. Por exemplo, se você gostaria de apontar o formulário para a action login() docontroller atual, você deve fornecer um array $options como o seguinte:<?php echo $form->create(Usuario, array(action => login)); ?>// Saída:<form id="UsuarioLoginForm" method="post" action="/usuarios/login">$options[url]Se o destino do formulário atual não é o controller atual, você pode especificar a URL para oatributo action do formulário utilizando a chave url do array $options. A URL pode serfornecida em relação a sua aplicação CakePHP (URL relativa), ou pode apontar para umdomínio externo (URL absoluta).<?php echo $form->create(null, array(url => recipes/add)); ?>// Saída:<form method="post" action="/recipes/add"><?php echo $form->create(null, array( url => http://www.google.com/search type => get)); ?>// Saída:<form method="get" action="http://www.google.com/search">$options[default]Se default foi definido para booleano false, a forma de submeter é modificada, de modo quepressionando o botão submit não envia o formulário. Se o formulário destina-se a ser
  • 69. Helpers internos 68submetido via AJAX, a configuração default para false suprime a forma do comportamentopadrão, para que você possa pegar os dados e enviá-los via AJAX.Fechando formuláriosO FormHelper inclui também um método end() que completa a marcação do formulário.Freqüentemente, end() só imprime uma tag de fechamento de formulário, mas usando o end()também permite o FormHelper inserir elementos hidden de formulário quando necessários,isso tudo depende da forma de como é usado.<?php echo $form->create(); ?><!-- Form elements go here --><?php echo $form->end(); ?>Se uma string é fornecida como o primeiro parâmetro para end(), o FormHelper retorna umbotão de submissão nomeado (ou com o valor) da string dada, juntamente com a tag defechamento o formulário.<?php echo $form->end(Finish); ?>Saída:<div class="submit"> <input type="submit" value="Finish" /></div></form>Elemento de formulário mágicoPrimeiro, vamos olhar para alguns dos muitos métodos de criação automática de formuláriosdo FormHelper. O principal método que vamos olhar é o input(). Este método iráautomaticamente deduzir o campo do modelo que foi fornecido no primeiro parâmetro, ecriará um campo de formulário adequado para esse campo. Tabela 7. Tipo de campos na interface conforme tipo de campo no banco de dadosTipo da coluna Resultando no campo de formuláriostring (char, varchar, etc.) textboolean, tinyint(1) checkboxText textareatext, nomeado como password, passwordpasswd, ou pswordDate selects de dia, mês, e ano.datetime, timestamp selects de dia, mês, ano, hora, minuto, e meridianoTime selects de hora, minuto, e meridianoPor exemplo, vamos supor que o meu model User inclui campos de username (varchar), apassword (varchar), approved (datetime) e quote (text). Posso usar o método input() doFormHelper para criar uma entrada adequada para todos estes campos de formulário.<?php echo $form->create(); ?> <?php
  • 70. Helpers internos 69 echo $form->input(username); // text echo $form->input(password); // text echo $form->input(approved); // selects de dia, mês, ano, // hora, minuto, meridiano echo $form->input(quote); // textarea ?><?php echo $form->end(Adicionar); ?>$options[type]Você pode forçar o tipo de uma entrada (e sobrepor a dedução pelo model), especificando otipo. Além dos tipos de campos encontrados na tabela acima, você também pode criarentradas file, e password.<?php $form->input(field, array(type => file));Saída:<div class="input"> <label for="UserField">Field</label> <input type="file" name="data[User][field]" id="UserField" /></div>$options[before], $options[between] e $options[after]Utilize estas chaves se você precisa injetar alguma marcação dentro da saída do métodoinput().<?php echo $form->input(field, array( before => --before--, after => --after--, between => --between---));?>Saída:<div class="input">--before--<label for="UserField">Field</label>--between---<input name="data[User][field]" type="text" value="" id="UserField" />--after--</div>$options[options]Esta chave permite que você especifique manualmente as opções para uma entrada select, oupara um grupo de rádio. A menos que type esteja especificada como radio, o FormHelper iráassumir que a meta de saída é um entrada select.<?php echo $form->input(field, array(options => array(1,2,3,4,5)));?>Saída:<div class="input"> <label for="UserField">Field</label>
  • 71. Helpers internos 70 <select name="data[User][field]" id="UserField"> <option value="0">1</option> <option value="1">2</option> <option value="2">3</option> <option value="3">4</option> <option value="4">5</option> </select></div>As opções também podem ser preenchidas como pares chave-valor.$options[multiple]Se multiple, foi escolhida para true para uma entrada que retorna um select, a escolha nestaentrada select permitirá várias seleções.$options[maxLength]Define o número máximo de caracteres permitidos em uma entrada de texto.$options[div]Defina esta chave false para desativar a saída do div em torno da entrada e de seu marcador(label).$options[label]Defina esta chave false para desativar a saída do marcador (label) que habitualmenteacompanha o input.$options[id]Definir esta chave para forçar o valor da id DOM para a entrada.$options[error]Esta chave deve ser ajustada para uma string que será mostrada na eventualidade de um errode validação. Se error não está definida, uma mensagem de erro genérico padrão serámostrada.$options[selected]Usado em combinação com uma entrada do tipo select. Defina selected para o valor do itemque deseja ser selecionado por padrão quando a entrada é renderizada.$options[rows], $options[cols]Estas duas chaves especificam o número de linhas e colunas em uma entrada de texto(textarea).$options[empty]Se escolhida para true, força a entrada para permanecer vazia. Isso é útil para entrada desenha que normalmente não deveria está preenchida com uma senha do usuário comoacontece com o valor padrão.$options[timeFormat]Utilizado para especificar o formato do tempo nas entradas relacionadas com o tempo. Osvalores válidos incluem 12, 24, none.
  • 72. Helpers internos 71$options[dateFormat]Utilizado para especificar o formato do conjunto de entradas para selecionar uma data. Osvalores válidos incluem DMY, MDY, YMD, e NONE.Métodos específicos do elemento de formulárioO restante dos métodos disponíveis no FormHelper são para a criação específica de elementosde formulários. Muitos destes métodos também fazem uso de um parâmetro especial$options. Neste caso, porém, $options é usado principalmente para especificar atributos datag HTML(tais como o valor ou id (DOM) de um elemento do formulário).<?php echo $form->text(username, array(class => users)); ?>Saída:<input name="data[User][username]" type="text" class="users"id="UserUsername" />  checkbox(string $fieldName, array $options)Cria um elemento checkbox. Este método também gera um elemento hidden associado paraforçar a apresentação de dados para o especificado campo.<?php echo $form->checkbox(done); ?>Saída:<input type="hidden" name="data[User][done]" value="0" id="UserDone_" /><input type="checkbox" name="data[User][done]" value="1" id="UserDone" />  year(string $fieldName, int $minYear, int $maxYear, mixed $selected, array $attributes, boolean $showEmpty)Cria um elemento select preenchido com o passar dos anos a partir de $minYear para$maxYear, com o ano $selected selecionado por padrão. Atributos HTML podem seroferecidos em $attributes. Se $showEmpty é false, o elemento select não inclue a opção vazia.  month(string $fieldName, mixed $selected, array $attributes, boolean $showEmpty)Cria um elemento select preenchido com nomes dos meses.  dateTime(string $fieldName, string $dateFormat = DMY, $timeFormat = 12, mixed $selected, array $attributes, boolean $showEmpty)Cria um conjunto de entradas select para selecionar data e hora. Os valores válidos para$dateformat são DMY, MDY, YMD ou NONE. Os valores válidos para $timeFormat são12,24, e NONE.  day(string $fieldName, mixed $selected, array $attributes, boolean $showEmpty)Cria um elemento select preenchido com os dias (numérico) do mês.  hour(string $fieldName, boolean $format24Hours, mixed $selected, array $attributes, Boolean $showEmpty)
  • 73. Helpers internos 72Cria um elemento select preenchido com a hora do dia.  minute(string $fieldName, mixed $selected, array $attributes, boolean $showEmpty)Cria um elemento select preenchido com os minutos da hora.  meridian(string $fieldName, mixed $selected, array $attributes, boolean $showEmpty)Cria um elemento select preenchido com am e pm.  error(string $fieldName, string $text, array $options)Mostra uma mensagem de erro de validação, especificado por $text, para o determinadocampo, no evento que um erro de validação tenha ocorrido.  file(string $fieldName, array $options)Cria uma entrada de arquivo.  hidden(string $fieldName, array $options)Cria uma entrada de fomulário hidden.  isFieldError(string $fieldName)Retorna true se o campo fornecido em $fieldName tem uma validação de erro ativa.  label(string $fieldName, string $text, array $attributes)Cria um elemento tag (etiqueta), preenchido com $text.  password(string $fieldName, array $options)Cria uma entrada de senha (password).  radio(string $fieldName, array $options, array $attributes)Cria uma entrada radio.  select(string $fieldName, array $options, mixed $selected, array $attributes, boolean $showEmpty)Cria um elemento select, preenchido com os itens de $options, com uma opção selecionadapor padrão, especificada por $selected. Defina $showEmpty para false se você não quer umaopção vazia dentro do select.  submit(string $caption, array $options)Cria um botão Submit com legenda $caption. Se a definição de $caption for uma URL de umaimagem (que contém o caracter . (ponto)), o botão submit será exibido como uma imagem.  submitImage(string $path, array $options)
  • 74. Helpers internos 73Cria um botão imagem de submissão, com a imagem especificada pela URL em $path(caminho).  text(string $fieldName, array $options)Cria uma entrada textarea.  textarea(string $fieldName, array $options)Cria uma entrada textarea.HTMLInserindo elementos bem-formadosJavaScriptAJAXOpções do AjaxHelperOpções geraisOpções de callbackMétodosCacheFormNumberTextTime
  • 75. Exemplos 74 Parte VII. ExemplosTutorial de como fazer um blog em CakePHPSistema simples de autenticação de usuários
  • 76. Apêndices 75 Parte VIII. ApêndicesEscritores da versão inglesa  José Lorenzo  derelm  mar3k  Tarique Sani  Aaron Thies  Ahsanul Bari  Nate Abele  Garrett J. Woodworth  Larry Masters  Mark StoryTradutores para língua portuguesa  Bill Jr.  Juan Basso  Julio Protzek  Sadjow Medeiros Leão  Tarcísio Sassara  Tulio FariaApoio e revisão da versão traduzida  Gustavo Carreno  Icaro MonteiroInflexão em portuguêsAbaixo segue o código para a inflexão para língua portuguesa. Caso você queira utilizar,coloque o código no arquivo /app/config/inflections.php.<?php /* * Por Sadjow Medeiros Leão (sadjow@gmail.com) * Baseado em http://forum.rubyonbr.org/forums/14/topics/520 */ $pluralRules = array( # # Regra geral: adiciona um "s" no final da palavra # #casa - casas /^([a-zA-Z]*)a$/i => 1as, # #pe - pes /^([a-zA-Z]*)e$/i => 1es, # #sem exemplo /^([a-zA-Z]*)i$/i => 1is, # #carro - carros /^([a-zA-Z]*)o$/i => 1os,
  • 77. Apêndices 76 # #pneu - pneus /^([a-zA-Z]*)u$/i => 1us, # # Se a palavra termina com "r" or "z", adiciona "es" # #luz - luzes # #flor - flores # #arroz - arrozes /^([a-zA-Z]*)r$/i => 1res, /^([a-zA-Z]*)z$/i => 1zes, # # Se a palavra termina com "al", "el", "ol", "ul": Troca "l"por "is" # #farol - farois # #hospital - hospitais # #telemovel - telemoveis # #pincel - pinceis # #anzol - anzois /^([a-zA-Z]*)al$/i => 1ais, /^([a-zA-Z]*)el$/i => 1eis, /^([a-zA-Z]*)ol$/i => 1ois, /^([a-zA-Z]*)ul$/i => 1uis, # # Se palavra termina em "il" e tem acento agudo na últimasílaba, troca "il", por "is" #cantil - cantis /^([a-zA-Z]*)il$/i => 1is, # # TODO # # Se a palavra termina com "il" e tiver um acento agudo napenultima sílaba, troca "il" por "eis" # # sem exemplo // Esse aqui é um pouco mais complicado. Fiquei de fazer, porquenão tem como // identificar acentos quando não se usa acentos( nome dastabelas) // Ainda estou pensando. Me ajuda ok?! # # Se a palavra termina com "m", troca "m" por "ns" # #armazem - armazens # #portagem - portagens # inflect.plural /^([a-zA-z]*)m$/i, 1ns /^([a-zA-Z]*)m$/i => 1ns, # #TODO # # Se a palavra termina com "s" e tem uma sílaba, troca "s"por "es" # #sem exemplo # #inflect.plural /^([a-zA-z]*)e$/i, 1es # # #TODO # # Se a palavra termina com "x" fica a mesma # #sem exemplo... professor X, telvez? # #inflect.plural /^([a-zA-z]*)x$/i, 1x #
  • 78. Apêndices 77 # # Se a palavra termina com "ão", Existem 3 jeitos para oprural: ãos, ães, ões # #NOTA: Difícil de achar, Eu usei os casos mais conhecidos # # e depois usei os casos irregulares (lá embaixo em$irregularPlural) para os outros. Se alguém conhece # # mais casos, por favor adicione na lista e mande-me um e-mail, obrigado! # # # #cão - cães # #colchão - colchões # #portão - portões # #pão - pães # #alemão - alemães # #chão - ? # #pilhão - pilhões # #canhão - canhões # #bidão - bidões # #mão - mãos /^([a-zA-Z]*)ao$/i => 1oes );/** * This is a key only array of plural words that should not be inflected. * Notice the last comma * * $uninflectedPlural = array(.*[nrlm]ese, .*deer, .*fish, .*measles,.*ois, .*pox); */ $uninflectedPlural = array();/** * This is a key => value array of plural irregular words. * If key matches then the value is returned. * * $irregularPlural = array(atlas => atlases, beef => beefs,brother => brothers) */ //$irregularPlural = array(); /* Sadjow Medeiros Leão (sadjow@gmail.com) // Irregular */ $irregularPlural = array( cao => caes, pao => paes, mao => maos, alemao => alemaes );/** * This is a key => value array of regex used to match words. * If key matches then the value is returned. * * $singularRules = array(/(s)tatuses$/i => 12tatus, /(matr)ices$/i=>1ix,/(vert|ind)ices$/i) */ //$singularRules = array(); /* * Sadjow Medeiros Leão ( sadjow@gmail.com )
  • 79. Apêndices 78 */ $singularRules = array( # #pes - pe # #carros - carro # #pneus - pneu /^([a-zA-Z]*)as$/i => 1a, /^([a-zA-Z]*)es$/i => 1e, /^([a-zA-Z]*)is$/i => 1i, /^([a-zA-Z]*)os$/i => 1o, /^([a-zA-Z]*)us$/i => 1u, # #luzes - luz # #flores - flor # #arrozes - arroz /^([a-zA-Z]*)res$/i => 1r, /^([a-zA-Z]*)zes$/i => 1z, # #cantis - cantil /^([a-zA-Z]*)is$/i => 1il, # # #farois - farol # #hospitais - hospital # #telemoveis - telemovel # #pinceis - pincel # #anzois - anzol /^([a-zA-Z]*)ais$/i => 1al, /^([a-zA-Z]*)eis$/i => 1el, /^([a-zA-Z]*)ois$/i => 1ol, /^([a-zA-Z]*)uis$/i => 1ul, # # #armazens - armazem # #portagens - portagem /^([a-zA-Z]*)ns$/i => 1m, # # #cães - cão # #colchões - colchão # #portões - portão # #pães - pão # #alemães - alemão /^([a-zA-Z]*)oes$/i => 1ao, /^([a-zA-Z]*)aes$/i => 1ao, /^([a-zA-Z]*)aos$/i => 1ao );/** * This is a key only array of singular words that should not be inflected. * You should not have to change this value below if you do change it usesame format * as the $uninflectedPlural above. */ $uninflectedSingular = $uninflectedPlural;/** * This is a key => value array of singular irregular words. * Most of the time this will be a reverse of the above $irregularPluralarray * You should not have to change this value below if you do change it usesame format
  • 80. Apêndices 79 * * $irregularSingular = array(atlases => atlas, beefs => beef,brothers => brother) */ $irregularSingular = array_flip($irregularPlural);?>

×