Você está na página 1de 130

CakePHP Cookbook Documentation

Release 2.x
Cake Software Foundation
July 17, 2014
Contedo
1 Primeiros Passos 1
Blog . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1
Blog - Continuao . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5
2 Instalao 25
Requisitos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 25
Licena . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 25
Baixando o CakePHP . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 26
Permisses . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 26
Congurao . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 26
Desenvolvimento . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 26
Produo . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 27
Instalao Avanada e Congurao Especca por Servidor . . . . . . . . . . . . . . . . . . . . 28
Comece agora! . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 34
3 Viso Geral do CakePHP 35
O que o CakePHP? Porque us-lo? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 35
Entendendo o Model-View-Controller . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 36
Onde obter ajuda . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 39
4 Controllers 41
A Classe AppController . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 41
Parmetros de Requisio . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 42
Aes de Controllers . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 42
Ciclo de Vida dos Callbacks em uma Requisio . . . . . . . . . . . . . . . . . . . . . . . . . . . 43
Mtodos dos Controllers . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 43
Atributos do Controller . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 50
Mais sobre Controllers . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 52
5 Views 69
i
View Templates . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 69
Usando Blocos de Views (Vises) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 71
Layouts . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 73
Elements . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 75
View API . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 78
6 Plugins 81
Instalando um Plugin . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 81
Usando um Plugin . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 82
Criando Seus Prprios Plugins . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 83
Plugin Controllers . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 84
Plugin Models . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 84
Plugin Views . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 85
Imagens de Plugin, CSS e Javascript . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 86
Components, Helpers e Behaviors . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 86
Expanda seu Plugin . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 87
Plugin Dicas . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 87
7 Desenvolvimento 89
8 Implementao 91
Denindo a Raiz . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 91
Atualizar o core.php . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 91
Multiplas aplicaes usando o mesmo core do CakePHP . . . . . . . . . . . . . . . . . . . . . . 92
9 Tutoriais & Exemplos 93
Blog . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 93
Blog - Continuao . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 97
Autenticao simples e Autorizao da Aplicao . . . . . . . . . . . . . . . . . . . . . . . . . . 108
10 Apndices 115
Guia de Migrao para a Verso 2.0 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 115
Guia de Migrao para a Verso 2.1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 115
Migrando da Verso 1.2 para 1.3 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 122
Informaes Gerais . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 122
11 Indices and tables 123
Index 125
ii
CAPTULO 1
Primeiros Passos
O framework CakePHP fornece uma base robusta e slida para suas aplicaes. Podendo tratar todos os as-
pectos, da requisio inicial do usurio at a renderizao de uma pgina web. Visto que o framework segue
o princpio MVC, ele lhe permite customizar e estender facilmente muitos dos aspectos de sua aplicao.
O framework tambm fornece uma organizao estrutural bsica de nome de arquivos a nomes de tabelas do
banco de dados, mantendo toda sua aplicao consistente e lgica. Este conceito simples mas poderoso.
Siga as convenes e voc sempre saber exatamente onde as coisas esto e como esto organizadas.
A melhor maneira de experimentar e aprender o CakePHP sentar em frente ao computador e construir
alguma coisa. Para comear vamos construir um blog simples.
Blog
Bem vindo ao CakePHP. Voc provavelmente est lendo este tutorial porque quer aprender mais sobre como
o CakePHP funciona. Nosso objetivo aumentar a produtividade e fazer a programao uma tarefa mais
divertida: Esperamos que voc veja isto na prtica enquanto mergulha nos cdigos.
Este tutorial ir cobrir a criao de uma aplicao de blog simples. Ns iremos baixar e instalar o Cake, criar
e congurar o banco de dados e criar a lgica da aplicao suciente para listar, adicionar, editar e deletar
posts do blog.
Aqui vai uma lista do que voc vai precisar:
1. Um servidor web rodando. Ns iremos assumir que voc esteja usando o Apache, embora as in-
strues para usar outros servidores sejam bem semelhantes. Talvez tenhamos que brincar um pouco
com as conguraes do servidor mas a maioria das pessoas sero capazes de ter o Cake rodando sem
precisar congurar nada.
2. Um servidor de banco de dados. Ns iremos usar o MySQL Server neste tutorial. Voc precisa saber
o mnimo sobre SQL para criar um banco de dados. O Cake pegar as rdeas a partir deste ponto.
3. Conhecimento bsico da linguagemPHP. Quanto mais orientado a objetos voc j programou, melhor:
mas no tenha medo se f de programao procedural.
1
CakePHP Cookbook Documentation, Release 2.x
4. E por ltimo, voc vai precisar de um conhecimento bsico do padro de projetos MVC. Uma rpida
viso geral pode ser encontrada em Entendendo o Model-View-Controller. No se preocupe, deve ter
meia pgina ou menos.
Ento, vamos comear!
Baixando o Cake
Primeiro, vamos baixar uma cpia recente do CakePHP.
Para fazer o download de uma cpia recente, visite o projeto do CakePHP no github:
http://github.com/cakephp/cakephp/downloads e faa o download da ltima verso 2.0.
Voc tambm pode clonar o repositrio usando o git
1
. git clone
git://github.com/cakephp/cakephp.git.
Idependente da maneira de como voc baixou o Cake, coloque o cdigo obtido dentro do seu diretrio web
pblico. A estrutura dos diretrios deve car parecido com o seguinte:
/caminho_para_diretorio_web_publico
/app
/lib
/plugins
/vendors
.htaccess
index.php
README
Agora pode ser um bom momento para aprender um pouco sobre como funciona a estrutura de diretrios do
CakePHP: Veja a seo Estrutura de Diretrios no CakePHP.
Criando o Banco de Dados do Blog
Em seguida, vamos congurar o banco de dados correspondente ao nosso blog. Se voc j no tiver feito
isto, crie um banco de dados vazio para usar neste tutorial com o nome que desejar. Neste momento, vamos
criar apenas uma tabela para armazenar nossos posts. Tambm vamos inserir alguns posts para usar como
teste. Execute as instrues a seguir no seu banco de dados:
-- Primeiro, criamos nossa tabela de posts
CREATE TABLE posts (
id INT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
title VARCHAR(50),
body TEXT,
created DATETIME DEFAULT NULL,
modified DATETIME DEFAULT NULL
);
-- Agora inserimos alguns posts para testar
INSERT INTO posts (title, body, created)
VALUES (The title, This is the post body., NOW());
1
http://git-scm.com/
2 Captulo 1. Primeiros Passos
CakePHP Cookbook Documentation, Release 2.x
INSERT INTO posts (title, body, created)
VALUES (A title once again, And the post body follows., NOW());
INSERT INTO posts (title, body, created)
VALUES (Title strikes back, This is really exciting! Not., NOW());
A escolha do nome de tabelas e colunas no so arbitrrias. Se voc seguir as convenes de nomenclatura
para estruturas do banco de dados e as convenes para nomes de classes (ambas descritas em Convenes
no CakePHP), voc ser capaz de tirar proveito de muitas funcionalidades do CakePHP e evitar arquivos
de conguraes. O Cake exivel o bastante para acomodar at mesmo os piores esquemas de banco de
dados legados, mas aderindo as convenes voc poupa seu tempo.
Veja Convenes no CakePHP para mais informaes. Aqui, basta dizer que ao nomear nossa tabela de
posts, automaticamente ela ser ligada ao nosso model Post e as colunas modied e created sero
automagicamente atualizadas pelo CakePHP.
Conguraes do Banco de Dados
Para o Alto e Avante: Vamos agora avisar ao Cake onde est nosso banco de dados e como conectar a ele.
Para muitos, esta a primeira e ltima congurao a ser feita.
Uma exemplo de arquivo de congurao do banco de dados pode ser encontrado em
/app/Config/database.php.default. Copie este arquivo no mesmo diretrio renomeando-o
para database.php.
O arquivo bem simples: basta alterar os valores da varivel $default com os dados da nossa congurao.
Um exemplo completo desta congurao ir se parecer com esta:
public $default = array(
datasource => Database/Mysql,
persistent => false,
host => localhost,
port => ,
login => cakeBlog,
password => c4k3-rUl3Z,
database => cake_blog_tutorial,
schema => ,
prefix => ,
encoding =>
);
Aps salvar seu novo arquivo database.php, voc estar apto para abrir seu navegador e ver a pgina de boas
vindas do Cake. A pgina de boas vindas dever lhe mostrar uma mensagem dizendo que seu arquivo de
conexo com o banco de dados foi encontrado, e que o Cake conseguiu se conectar com o banco de dados.
Congurao Opcional
Existem outros trs itens que podem ser congurados. Muitos desenvolvedores sempre conguram estes
itens, mas eles no so obrigatrios para este tutorial. Uma das conguraes customizar uma string (ou
salt) para ser utilizada nos hashes de segurana. O segundo denir um nmero (ou seed) para uso em
criptograa. E o terceiro dar permisso de escrita para o CakePHP na pasta tmp.
Blog 3
CakePHP Cookbook Documentation, Release 2.x
O security salt utilizado para gerar hashes. Altere o valor padro do salt editando o arquivo
/app/Config/core.php na linha 187. No importa muito o que o novo valor seja, basta que no
seja fcil de adivinhar.
/
**
*
A random string used in security hashing methods.
*
/
Configure::write(Security.salt, pl345e-P45s_7h3
*
S@l7!);
?>
O cipher seed usado para criptografar/descriptografar strings. Altere o valor padro editando o arquivo
/app/Config/core.php na linha 192. Como no security salt, no importa muito o que o novo valor
seja, basta que no seja fcil de adivinhar.
/
**
*
A random numeric string (digits only) used to encrypt/decrypt strings.
*
/
Configure::write(Security.cipherSeed, 7485712659625147843639846751);
?>
A ltima tarefa garantir acesso de escrita para a pasta app/tmp. A melhor maneira para fazer isto
localizar o usurio com que o seu servidor web executado (<?php echo whoami; ?>) e alterar o
dono da pasta app/tmp para este usurio. Voc pode executar (em *nix) o comando a seguir para alterar o
usurio dono da pasta.
$ chown -R www-data app/tmp
Se por alguma razo o CakePHP no conseguir escrever nesta pasta, voc ser avisado por uma mensagem
enquanto estiver em modo de desenvolvimento.
Uma Palavra Sobre o mod_rewrite
Ocasionalmente, um novo usurio ir esbarrar em problemas com o mod_rewrite, ento vou abord-los su-
percialmente aqui. Se a pgina de boas-vindas do CakePHP parecer um pouco sem graa (sem imagens,
sem cores e sem os estilos css), isso um indcio de que o mod_rewrite provavelmente no esteja funcio-
nando em seu sistema. Aqui esto algumas dicas para lhe ajudar a deixar tudo funcionando corretamente:
1. Certique-se de que a sobrescrita de opes do .htaccess est habilitada: em seu arquivo httpd.conf,
voc deve ter uma parte que dene uma seo para cada <Directory> do seu servidor. Certique-se de
que a opo AllowOverride esteja com o valor All para o <Directory> correto. Por questes de
segurana e performance, no dena AllowOverride para All em <Directory />. Ao invs
disso, procure o bloco <Directory> que se refere ao seu diretrio raz de seu website.
2. Certique-se de estar editando o arquivo httpd.conf ao invs de algum especco, que seja vlido
apenas para um dado usurio ou para um dado site.
3. Por alguma razo, voc pode ter obtido uma cpia do CakePHP sem os arquivos .htaccess. Isto
algumas vezes acontece porque alguns sistemas operacionais tratam arquivos que comeam com .
como arquivos ocultos e normalmente no fazem cpias deles. Certique-se de obter sua cpia do
CakePHP diretamente da seo de downloads do site ou de nosso repositrio git.
4 Captulo 1. Primeiros Passos
CakePHP Cookbook Documentation, Release 2.x
4. Certique-se de que o Apache esteja carregando o mod_rewrite corretamente! Voc deve ver algo
como:
LoadModule rewrite_module libexec/httpd/mod_rewrite.so
ou (para o Apache 1.3):
AddModule mod_rewrite.c
em seu httpd.conf.
Se voc no quiser ou no puder carregar o mod_rewrite (ou algum outro mdulo compatvel)
em seu servidor, voc vai precisar usar o recurso de URLs amigveis do CakePHP. No arquivo
/app/Config/core.php, descomente uma linha parecida com:
Configure::write(App.baseUrl, env(SCRIPT_NAME));
E remova tambm os arquivos .htaccess em:
/.htaccess
/app/.htaccess
/app/webroot/.htaccess
Comisto, suas URLs caro parecidas comwww.exemplo.com/index.php/nomecontroller/nomeaction/param
ao invs de www.exemplo.com/nomecontroller/nomeaction/param.
Se voc est instalando o CakePHP em outro webserver diferente do Apache, voc pode encontrar instrues
para ter a reescrita de URLs funcionando na seo Instalao Avanada.
Continue lendo este tutorial em Blog - Continuao para comear a construir sua primeira aplicao
CakePHP.
Blog - Continuao
Crie um Model Post
A classe Model o po com manteiga das aplicaes CakePHP. Ao criar um model do CakePHP que
ir interagir com nossa base de dados, teremos os alicerces necessrios para posteriormente fazer nossas
operaes de visualizar, adicionar, editar e excluir.
Os arquivos de classe do tipo model do CakePHP cam em/app/Model e o arquivo que iremos criar ser
salvo em /app/Model/Post.php. O contedo completo deste arquivo deve car assim:
class Post extends AppModel {
public $name = Post;
}
A nomenclatura da classe segue uma conveno que muito importante no CakePHP. Ao chamar nosso
model de Post, o CakePHP pode automaticamente deduzir que este model ser usado num PostsController,
e que manipular os dados de uma tabela do banco chamada de posts.
Note: O CakePHP ir criar um objeto (instncia) do model dinamicamente para voc, se no encontrar
Blog - Continuao 5
CakePHP Cookbook Documentation, Release 2.x
um arquivo correspondente na pasta /app/Model. Isto tambm signica que, se voc acidentalmente der um
nome errado ao seu arquivo (p.ex. post.php ou posts.php) o CakePHP no ser capaz de reconhecer nenhuma
de suas conguraes adicionais e ao invs disso, passar a usar seus padres denidos internamente na
classe Model.
Para saber mais sobre models, como prexos de nomes de tabelas, callbacks e validaes, conra o captulo
sobre /models deste manual.
Crie o Controller Posts
A seguir, vamos criar um controller para nossos posts. O controller onde toda a lgica de negcio para
interaes vai acontecer. De uma forma geral, o local onde voc vai manipular os models e lidar com
o resultado das aes feitas sobre nossos posts. Vamos pr este novo controller num arquivo chamado
PostsController.php dentro do diretrio /app/Controller. Aqui est como um controller
bsico deve se parecer:
class PostsController extends AppController {
public $helpers = array (Html,Form);
public $name = Posts;
}
Agora, vamos adicionar uma action ao nosso controller. Actions quase sempre representam uma
nica funo ou interface numa aplicao. Por exemplo, quando os usurios acessarem o endereo
www.exemplo.com/posts/index (que, neste caso o mesmo que www.exemplo.com/posts/), eles esperam
ver a listagem dos posts. O cdigo para tal ao deve se parecer com algo assim:
class PostsController extends AppController {
public $helpers = array (Html,Form);
public $name = Posts;
function index() {
$this->set(posts, $this->Post->find(all));
}
}
Deixe-me explicar a ao um pouco. Denindo a funo index() em nosso PostsController, os usurios
podem acessar esta lgica visitando o endereo www.exemplo.com/posts/index. De maneira semelhante,
se denirmos um mtodo chamado foobar() dentro do controller, os usurios deveriam ser capazes de
acess-lo pelo endereo www.exemplo.com/posts/foobar.
Warning: Voc pode car tentado a nomear seus controller e actions de uma certa maneira visando
obter uma certa URL. Mas resista a esta tentao. Siga as convenes do CakePHP (nomes de controllers
no plural, etc) e crie nomes de actions e controllers que sejam legveis e tambm compreensveis. Voc
sempre vai poder mapear URLs para seu cdigo utilizando rotas, conforme mostraremos mais frente.
A nica declarao na nossa action utiliza o mtodo set() para passar dados do controller para a view
(que vamos criar logo mais). A linha dene uma varivel na view chamada posts que vai conter o retorno
da chamada do mtodo find(all) do model Post. Nosso model Post est automaticamente disponvel
como $this->Post uma vez que seguimos as convenes de nomenclatura do Cake.
6 Captulo 1. Primeiros Passos
CakePHP Cookbook Documentation, Release 2.x
Para aprender mais sobre controllers do CakePHP, conra a seo Controllers.
Criando as Views de Posts
Agora que temos nossos dados chegando ao nosso model e com a lgica da nossa aplicao denida em
nosso controller, vamos criar uma view para a ao index() que criamos acima.
As views do Cake so meros fragmentos voltados apresentao de dados que vo dentro do layout da
aplicao. Para a maioria das aplicaes, as views sero marcaes HTML intercalados com cdigo PHP,
mas as views tambm podem ser renderizadas como XML, CVS ou mesmo como dados binrios.
Os layouts so pginas que encapsulam as views e que podem ser intercambiveis, mas por agora, vamos
apenas usar o layout padro.
Lembra da ltima seo, em que associamos a varivel posts para a view usando o mtodo set()? Com
aquilo, os dados foram repassados para a view num formato parecido com este:
// print_r($posts) output:
Array
(
[0] => Array
(
[Post] => Array
(
[id] => 1
[title] => The title
[body] => This is the post body.
[created] => 2008-02-13 18:34:55
[modified] =>
)
)
[1] => Array
(
[Post] => Array
(
[id] => 2
[title] => A title once again
[body] => And the post body follows.
[created] => 2008-02-13 18:34:56
[modified] =>
)
)
[2] => Array
(
[Post] => Array
(
[id] => 3
[title] => Title strikes back
[body] => This is really exciting! Not.
[created] => 2008-02-13 18:34:57
[modified] =>
)
Blog - Continuao 7
CakePHP Cookbook Documentation, Release 2.x
)
)
Os arquivos de view do Cake so armazenados na pasta /app/View dentro de uma pasta com o mesmo
nome do controller a que correspondem (em nosso caso, vamos criar uma pasta chamada Posts). Para
apresentar os dados do post num formato adequado de tabela, o cdigo de nossa view deve ser algo como:
<!-- File: /app/View/Posts/index.ctp -->
<h1>Posts do Blog</h1>
<table>
<tr>
<th>Id</th>
<th>Ttulo</th>
<th>Data de Criao</th>
</tr>
<!-- Aqui onde ns percorremos nossa matriz $posts, imprimindo
as informaes dos posts -->
<?php foreach ($posts as $post): ?>
<tr>
<td><?php echo $post[Post][id]; ?></td>
<td>
<?php echo $this->Html->link($post[Post][title],
array(controller => posts, action => view, $post[Post][id])); ?>
</td>
<td><?php echo $post[Post][created]; ?></td>
</tr>
<?php endforeach; ?>
</table>
Isto to simples quanto parece!
Voc deve ter notado o uso de um objeto chamado $this->Html. Esta uma instncia da classe
HtmlHelper do CakePHP. O CakePHP vem com um conjunto de helpers que tornam uma moleza fazer
coisas como criar links, gerar formulrios, Javascript e elementos dinmicos com Ajax. Voc pode aprender
mais sobre como us-los na seo /views/helpers, mas o importante a ser notado aqui que o mtodo
link() ir gerar um link em HTML com o ttulo (o primeiro parmetro) e URL (o segundo parmetro)
dados.
Ao especicar URLs no Cake, recomendado que voc use o formato de array. Este assunto expli-
cado com mais detalhes na seo sobre Rotas. Usar o formato de array para URLs, permite que voc
tire vantagens da capacidade do CakePHP de reverter este formato de URL em URLs relativas e vice
versa. voc tambm pode simplesmente informar um caminho relativo base da aplicao na forma /con-
troller/action/parametro_1/parametro_2.
Neste ponto, voc deve ser capaz de apontar seu navegador para http://www.exemplo.com/posts/index. Voc
deve ver sua view, corretamente formatada com o ttulo e a tabela listando os posts.
Se lhe ocorreu clicar num dos links que criamos nesta view (no ttulo do post e que apontam para uma URL
/posts/view/algum_id), voc provavelmente recebeu uma mensagemdo CakePHP dizendo que a action ainda
8 Captulo 1. Primeiros Passos
CakePHP Cookbook Documentation, Release 2.x
no foi denida. Se voc no tiver visto um aviso assim, ento ou alguma coisa deu errado ou ento voc j
tinha denido uma action anteriormente, e neste caso, voc muito afoito. Se no, vamos cri-la em nosso
PostsController agora:
class PostsController extends AppController {
public $helpers = array(Html, Form);
public $name = Posts;
public function index() {
$this->set(posts, $this->Post->find(all));
}
public function view($id = null) {
$this->Post->id = $id;
$this->set(post, $this->Post->read());
}
}
A chamada do mtodo set() deve lhe parece familiar. Perceba que estamos usando o mtodo read() ao
invs do find(all) porque ns realmente s queremos informaes de um nico post.
Note que a action de nossa view recebe um parmetro: O ID do post que queremos ver. Este parmetro
repassado action por meio da URL requisitada. Se um usurio acessar uma URL /posts/view/3, ento o
valor 3 ser atribudo ao parmetro $id.
Agora vamos criar a view para nossa nova action view e coloc-la em/app/View/Posts/view.ctp:
<!-- File: /app/View/Posts/view.ctp -->
<h1><?php echo $post[Post][title]?></h1>
<p><small>Created: <?php echo $post[Post][created]?></small></p>
<p><?php echo $post[Post][body]?></p>
Conra se est funcionando tentando acessar os links em/posts/index ou requisitando diretamente um
post acessando /posts/view/1.
Adicionando Posts
Ler a partir da base de dados e exibir os posts foi um grande comeo, mas precisamos permitir tambm que
os usurios adicionem novos posts.
Primeiramente, comece criando uma action add() no PostsController:
class PostsController extends AppController {
public $helpers = array(Html, Form);
public $name = Posts;
public $components = array(Session);
public function index() {
$this->set(posts, $this->Post->find(all));
}
Blog - Continuao 9
CakePHP Cookbook Documentation, Release 2.x
public function view($id) {
$this->Post->id = $id;
$this->set(post, $this->Post->read());
}
public function add() {
if ($this->request->is(post)) {
if ($this->Post->save($this->request->data)) {
$this->Session->setFlash(Your post has been saved.);
$this->redirect(array(action => index));
}
}
}
}
Note: Voc precisa incluir o componente SessionComponent e o helper SessionHelper em qualquer con-
troller que voc manipula variveis de sesso. Neste caso, inclumos apenas o componente porque ele
carrega o helper automaticamente. Se voc sempre utiliza sesses, inclua o componente no seu arquivo
AppController.
Aqui est o que a action add() faz: se o mtodo da requisio feita pelo cliente for do tipo post, ou seja, se
ele enviou dados pelo formulrio, tenta salvar os dados usando o model Post. Se, por alguma razo ele no
salvar, apenas renderize a view. Isto nos d uma oportunidade de mostrar erros de validao e outros avisos
ao usurio.
Quando umusurio utiliza umformulrio para submeter (POSTar) dados para sua aplicao, esta informao
ca disponvel em$this->request->data.Voc pode usar as funes pr() ou debug() para exibir
os dados se voc quiser conferir como eles se parecem.
Ns usamos o mtodo SessionComponent::setFlash() do componente SessionComponent para
denir uma varivel de sesso com uma mensagem a ser exibida na pgina depois de ser redirecionada. No
layout, ns temos SessionHelper::flash que exibe a mensagem e limpa a varivel de sesso corre-
spondente. O mtodo Controller::redirect do controller redireciona para outra URL. O parmetro
array(action => index) convertido para a URL /posts, em outras palavras, a action index
do controller posts. Voc pode conferir a funo Router::url() na API para ver os formatos que voc
pode usar ao especicar uma URL para actions do CakePHP.
Chamar o mtodo save() ir vericar por erros de validao e abortar o salvamento se algum erro ocorrer.
Vamos falar mais sobre erros de validao e sobre como manipul-los nas sees seguintes.
Validao de Dados
O CakePHP percorreu uma longa estrada combatendo a monotonia da validao de dados de formulrios.
Todo mundo detesta codicar formulrios interminveis e suas rotinas de validao. O CakePHP torna tudo
isso mais fcil e mais rpido.
Para usufruir das vantagens dos recursos de validao, voc vai precisar usar o FormHelper do Cake em suas
views. O FormHelper est disponvel por padro em todas as suas views na varivel $this->Form.
10 Captulo 1. Primeiros Passos
CakePHP Cookbook Documentation, Release 2.x
Aqui est nossa view add:
<!-- File: /app/View/Posts/add.ctp -->
<h1>Add Post</h1>
<?php
echo $this->Form->create(Post);
echo $this->Form->input(title);
echo $this->Form->input(body, array(rows => 3));
echo $this->Form->end(Save Post);
Aqui, usamos o FormHelper para gerar a tag de abertura para um formulrio. Aqui est o HTML gerado
pelo $this->Form->create():
<form id="PostAddForm" method="post" action="/posts/add">
Se o mtodo create() for chamado sem quaisquer parmetros, o CakePHP assume que voc est criando
um formulrio que submete para a action add() do controller atual (ou para a action edit() se um campo
id for includo nos dados do formulrio), via POST.
O mtodo $this->Form->input() usado para criar elementos de formulrio de mesmo nome. O
primeiro parmetro informa ao CakePHP qual o campo correspondente e o segundo parmetro permite que
voc especique um extenso array de opes. Neste caso, o nmero de linhas para o textarea. H alguma
introspeco automgica envolvida aqui: o input() ir exibir diferentes elementos de formulrio com
base no campo do model em questo.
A chamada $this->Form->end() gera um boto de submisso e encerra o formulrio. Se uma
string for informada como primeiro parmetro para o end(), o FormHelper exibe um boto de submit
apropriadamente rotulado junto com a tag de fechamento do formulrio. Novamente, conra o captulo
sobre os /views/helpers disponveis no CakePHP para mais informaes sobre os helpers.
Agora vamos voltar e atualizar nossa view /app/View/Post/index.ctp para incluir um novo link
para Adicionar Post. Antes de <table>, adicione a seguinte linha:
echo $this->Html->link(Add Post, array(controller => posts, action => add));
Voc pode estar imaginando: como eu informo ao CakePHP sobre os requisitos de validao de meus dados?
Regras de validao so denidas no model. Vamos olhar de volta nosso model Post e fazer alguns pequenos
ajustes:
class Post extends AppModel {
public $name = Post;
public $validate = array(
title => array(
rule => notEmpty
),
body => array(
rule => notEmpty
)
);
}
O array $validate diz ao CakePHP sobre como validar seus dados quando o mtodo save() for
Blog - Continuao 11
CakePHP Cookbook Documentation, Release 2.x
chamado. Aqui, eu especiquei que tanto os campos body e title no podem ser vazios. O mecanismo
de validao do CakePHP robusto, com diversas regras predenidas (nmeros de carto de crdito, en-
dereos de e-mail, etc.) alm de ser bastante exvel, permitindo adicionar suas prprias regras de validao.
Para mais informaes, conra o captulo sobre /models/data-validation.
Agora que voc incluiu as devidas regras de validao, tente adicionar umpost comum ttulo ou com o corpo
vazio para ver como funciona. Uma vez que usamos o mtodo FormHelper::input() do FormHelper
para criar nossos elementos de formulrio, nossas mensagens de erros de validao sero mostradas auto-
maticamente.
Editando Posts
Edio de Posts: Aqui vamos ns. A partir de agora voc j um prossional do CakePHP, ento voc deve
ter identicado um padro. Criar a action e ento criar a view. Aqui est como o cdigo da action edit()
do PostsController deve se parecer:
function edit($id = null) {
$this->Post->id = $id;
if ($this->request->is(get)) {
$this->request->data = $this->Post->read();
} else {
if ($this->Post->save($this->request->data)) {
$this->Session->setFlash(Your post has been updated.);
$this->redirect(array(action => index));
}
}
}
Esta action primeiro verica se a requisio do tipo GET. Se for, ns buscamos o Post e passamos para a
view. Se a requisio no for do tipo GET, provavelmente esta contm dados de um formulrio POST. Ns
usaremos estes dados para atualizar o registro do nosso Post ou exibir novamente a view mostrando para o
usurio os erros de validao.
A view edit pode ser algo parecido com isto:
<!-- File: /app/View/Posts/edit.ctp -->
<h1>Edit Post</h1>
<?php
echo $this->Form->create(Post, array(action => edit));
echo $this->Form->input(title);
echo $this->Form->input(body, array(rows => 3));
echo $this->Form->input(id, array(type => hidden));
echo $this->Form->end(Save Post);
Esta view exibe o formulrio de edio (com os valores populados), juntamente com quaisquer mensagens
de erro de validao.
Uma coisa a atentar aqui: o CakePHP vai assumir que voc est editando um model se o campo id estiver
presente no array de dados. Se nenhum id estiver presente (como a view add de insero), o Cake ir
assumir que voc est inserindo um novo model quando o mtodo save() for chamado.
12 Captulo 1. Primeiros Passos
CakePHP Cookbook Documentation, Release 2.x
Voc agora pode atualizar sua view index com os links para editar os posts especcos:
<!-- File: /app/View/Posts/index.ctp (links para edio adicionados) -->
<h1>Blog posts</h1>
<p><?php echo $this->Html->link("Add Post", array(action => add)); ?></p>
<table>
<tr>
<th>Id</th>
<th>Title</th>
<th>Action</th>
<th>Created</th>
</tr>
<!-- Aqui onde ns percorremos nossa matriz $posts, imprimindo
as informaes dos posts -->
<?php foreach ($posts as $post): ?>
<tr>
<td><?php echo $post[Post][id]; ?></td>
<td>
<?php echo $this->Html->link($post[Post][title], array(action => view, $post[Post][id]));?>
</td>
<td>
<?php echo $this->Form->postLink(
Delete,
array(action => delete, $post[Post][id]),
array(confirm => Are you sure?)
)?>
<?php echo $this->Html->link(Edit, array(action => edit, $post[Post][id]));?>
</td>
<td><?php echo $post[Post][created]; ?></td>
</tr>
<?php endforeach; ?>
</table>
Deletando Posts
A seguir, vamos criar uma maneira para os usurios exclurem posts. Comece com uma action delete()
no PostsController:
function delete($id) {
if (!$this->request->is(post)) {
throw new MethodNotAllowedException();
}
if ($this->Post->delete($id)) {
$this->Session->setFlash(The post with id: . $id . has been deleted.);
$this->redirect(array(action => index));
}
}
Esta lgica exclui o post dado por $id, e utiliza $this->Session->setFlash() para mostrar uma
Blog - Continuao 13
CakePHP Cookbook Documentation, Release 2.x
mensagem de conrmao para o usurio depois de redirecion-lo para /posts.
Se o usurio tentar deletar um post usando uma requisio do tipo GET, ns lanamos uma exceo. Ex-
cees no apanhadas so capturadas pelo manipulador de excees do CakePHP e uma pgina de erro
amigvel mostrada. O CakePHP vem com muitas /development/exceptions que voc pode usar
para indicar vrios tipos de erros HTTP que sua aplicao pode precisar gerar.
Como estamos executando apenas uma lgica de negcio e redirecionando, esta action no tem uma view.
Voc pode querer atualizar sua view index com links que permitam ao usurios excluir posts, porm, como
um link executa uma requisio do tipo GET, nossa action ir lanar uma exceo. Precisamos ento criar
um pequeno formulrio que enviar um mtodo POST adequado. Para estes casos o helper FormHelper
fornece o mtodo postLink():
<!-- File: /app/View/Posts/index.ctp -->
<h1>Blog posts</h1>
<p><?php echo $this->Html->link(Add Post, array(action => add)); ?></p>
<table>
<tr>
<th>Id</th>
<th>Title</th>
<th>Actions</th>
<th>Created</th>
</tr>
<!-- Aqui onde ns percorremos nossa matriz $posts, imprimindo
as informaes dos posts -->
<?php foreach ($posts as $post): ?>
<tr>
<td><?php echo $post[Post][id]; ?></td>
<td>
<?php echo $this->Html->link($post[Post][title], array(action => view, $post[Post][id]));?>
</td>
<td>
<?php echo $this->Form->postLink(
Delete,
array(action => delete, $post[Post][id]),
array(confirm => Are you sure?));
?>
</td>
<td><?php echo $post[Post][created]; ?></td>
</tr>
<?php endforeach; ?>
</table>
Note: O cdigo desta view tambm utiliza o HtmlHelper para solicitar uma conrmao do usurio com
um dilogo em Javascript antes de tentar excluir o post.
14 Captulo 1. Primeiros Passos
CakePHP Cookbook Documentation, Release 2.x
Rotas
Para alguns, o roteamento padro do CakePHP funcionar muito bem. Os desenvolvedores que estiverem
mais afeitos a criar produtos ainda mais amigveis aos usurios e aos mecanismos de busca iro gostar da
maneira que as URLs do CakePHP so mapeadas para actions especcas. Ento vamos fazer uma pequena
alterao de rotas neste tutorial.
Para mais informaes sobre tcnicas avanadas de roteamento, veja routes-conguration.
Por padro, o CakePHP responde a requisies para a raiz de seu site (i.e. http://www.exemplo.com) usando
seu PagesController e renderizando uma view chamada de home. Ao invs disso, vamos substituir isto
por nosso PostsController criando uma regra de roteamento.
As rotas do Cake so encontrada no arquivo /app/Config/routes.php. Voc vai querer comentar ou
remover a linha que dene a rota raiz padro. Ela se parece com:
Router::connect(/, array(controller => pages, action => display, home));
Esta linha conecta a URL / com a home page padro do CakePHP. Queremos conect-la com nosso prprio
controller, ento adicionamos uma linha parecida com isto:
Router::connect(/, array(controller => posts, action => index));
Isto deve conectar as requisies de / action index() que criaremos em nosso PostsController.
Note: O CakePHP tambm faz uso do roteamento reverso - se, com a rota denida acima, voc passar
array(controller => posts, action => index) a um mtodo que espere um
array, a URL resultante ser /. sempre uma boa ideia usar arrays para URLs, j que a partir disto que
suas rotas denem para onde suas URLs apontam, alm de garantir que os links sempre apontem para o
mesmo lugar.
Concluso
Criar aplicaes desta maneira ir lhe trazer paz, honra, amor e dinheiro alm de satisfazer s suas mais
ousadas fantasias. Simples, no? Tenha em mente que este tutorial foi muito bsico. O CakePHP possui
muito mais recursos a oferecer e exvel de tantas maneiras que no conseguimos mostrar aqui por questes
de simplicidade. Utilize o resto deste manual como guia para construir mais aplicaes ricas em recursos.
Agora que voc criou uma aplicao bsica com o Cake, voc est pronto para a coisa real. Comece seu
prprio projeto, leia o restante do Manual e da API
2
.
E se voc precisar de ajuda, nos vemos no canal #cakephp (e no #cakephp-pt). Seja bem-vindo ao CakePHP!
Leitura Recomendada
Estas so as tarefas comuns que pessoas aprendendo o CakePHP geralmente querem estudar:
1. Layouts: Customizando o layout do seu website
2
http://api20.cakephp.org
Blog - Continuao 15
CakePHP Cookbook Documentation, Release 2.x
2. Elements Incluindo e reutilizando trechos de cdigo
3. Scaffolding (arcabouos): Prototipando antes de programar
4. /console-and-shells/code-generation-with-bake Gerando cdigo CRUD bsico
5. Autenticao simples e Autorizao da Aplicao: Tutorial de autenticao e autorizao de usurios
Leitura Adicional
Uma Requisio Tpica do CakePHP
Ns j abordamos os ingredientes bsicos do CakePHP, ento agora vamos dar uma olhada em como os
objetos trabalham juntos para completar uma requisio bsica. Continuando com o exemplo da requisio
original, vamos imaginar que nosso amigo Ricardo apenas clicou no link Compre um bolo personalizado
agora! em uma landing page
3
de uma aplicao CakePHP.
Figura 1.1: Um diagrama de uxo mostrando uma tpica requisio CakePHP
Figure: 2. Requisio tpica do CakePHP.
Em preto = elemento requerido, em cinza = elemento opcional, em Azul = callbacks
3
http://pt.wikipedia.org/wiki/Landing_page
16 Captulo 1. Primeiros Passos
CakePHP Cookbook Documentation, Release 2.x
1. Ricardo clica no link apontando para http://www.example.com/cakes/buy, e o navegador dele faz uma
requisio para seu servidor web.
2. O roteador analisa a URL para extrair os parmetros desta requisio: o controller, a ao, e qualquer
outro argumento que afeta a lgica do negcio durante esta requisio.
3. Usando rotas, a URL da requisio mapeada para uma ao de um controller (um mtodo em
uma classe controller especca). Neste caso, ser o mtodo buy() do controller CakesController.
O callback beforeFilter() do controller chamado antes de qualquer ao lgica do controller. As
linhas tracejadas em azul mostram isso no diagrama.
4. O controller pode usar models para obter acesso aos dados do aplicativo. Neste exemplo o con-
troller usa o model para pegar no banco de dados as ltimas compras do Ricardo. Qualquer callback
do model, behaviors ou DataSources que for aplicvel neste momento, ser chamado. Enquanto a
utilizao de Models no seja obrigatria, todas os controllers inicialmente requerem ao menos um
model.
5. Aps o model buscar os dados, estes so retornados para o controller. Callbacks de um Model podem
ser aplicados.
6. O controller poder utilizar componentes para renar os dados ou executar outras operaes (manip-
ular sesso, autenticar ou enviar e-mails so exemplos)
7. Uma vez que o controller usou os models e componentes para preparar os dados de forma suciente,
os dados so passados para a view usando o mtodo set() do controller. Callbacks do controller
podem ser chamados antes que os dados sejam passados. A view executada, podendo incluir o uso
de elementos e/ou helpers. Por padro, a view renderizada dentro de um layout.
8. Adicionalmente, callbacks do controller (como o afterFilter) podem ser aplicados. A view renderizada
e completa enviada para o navegador do Ricardo.
Convenes no CakePHP
Ns somos grandes fns de convenes sobre congurao
4
. Enquanto pode levar um tempo para aprender
as convenes do CakePHP, voc ganhar muito tempo a longo prazo: seguindo as convenes voc ganhar
funcionalidades e car livre dos pesadelos de manter arquivos de congurao. As convenes tambm
contribuem para o desenvolvimento de sistemas mais uniformes, permitindo que outros desenvolvedores
entrem no projeto e comecem a trabalhar muito mais rapidamente.
As convenes do CakePHP foram destiladas ao longo de anos de experincia no desenvolvimento de apli-
caes web e boas prticas. Da mesma forma que sugerimos que voc use essas convenes enquanto
desenvolve com o CakePHP, devemos mencionar que muitos destes princpios so facilmente sobrescritos
algo que especialmente til quando se trabalha com sistemas legados.
Convenes nos Controllers
As classes Controllers devem ser escritas no plural, usando o formato CamelCase
5
e terminarem com a
palavra Controller. PeopleController e LatestArticlesController so dois exemplos
4
http://pt.wikipedia.org/wiki/Conven%C3%A7%C3%A3o_sobre_congura%C3%A7%C3%A3o
5
http://pt.wikipedia.org/wiki/CamelCase
Blog - Continuao 17
CakePHP Cookbook Documentation, Release 2.x
de nomes de controllers que seguem a conveno.
O primeiro mtodo que voc pode escrever para um controller o mtodo index(). Quando uma req-
uisio especica o controller mas no a ao, o comportamento padro do CakePHP executar o mtodo
index(). Por exemplo, uma requisio para http://www.example.com/apples/ mapeada para o mtodo
index() do controller ApplesController, enquanto a URL http://www.example.com/apples/view/
mapeada para a chamada do mtodo view() do mesmo controller.
Voc tambm pode alterar a visibilidade dos mtodos de controllers no CakePHP prexando os nome dos
mtodos com underscores. Se um mtodo de um controller for prexado, o mtodo no poder ser acessado
diretamente da web mas estar disponvel para uso interno. Por exemplo:
class NewsController extends AppController {
function latest() {
$this->_findNewArticles();
}
function _findNewArticles() {
// lgica para encontrar os os ltimos artigos
}
}
Enquanto a pgina http://www.example.com/news/latest/ pode ser acessada normalmente pelos usurios,
alguem tentando visitar a pgina http://www.example.com/news/_ndNewArticles/ receber um erro porque
o nome do mtodo prexado com um underscore. Voc tambm pode utilizar as palavras-chave de visi-
bilidade do PHP para indicar se um mtodo pode ou no ser acessado por uma URL. Mtodos privados no
podem ser acessados.
Consideraes sobre URLs para nomes de Controllers Como voc viu, controllers com nomes forma-
dos por uma palavra so mapeados por URLs em caixa baixa. Por exemplo, ApplesController (que
seria denido em um arquivo com o nome de ApplesController.php) pode ser acessado com a seguinte
URL: http://example.com/apples.
Controllers formados por mais de uma palavra podem ter qualquer forma exionada do nome:
/redApples
/RedApples
/Red_apples
/red_apples
Todas sero resolvidas para o mtodo index do controller RedApples. Porm, a conveno diz que suas
URLs devem ser em caixa baixa e usar underscores, portanto /red_apples/go_pick a forma mais apropriada
para acessar a ao RedApplesController::go_pick.
Para mais informaes sobre as URLs do CakePHP e o tratamento de parmetros, veja routes-conguration.
18 Captulo 1. Primeiros Passos
CakePHP Cookbook Documentation, Release 2.x
Convenes de Arquivos e Nomes de Classes
Geralmente, nomes de arquivos correspondem com o nome de suas classes, que so em CamelCase
6
. Ento
se voc possui uma classe MyNiftyClass, para o Cake, o nome do arquivo deve ser MyNiftyClass.php.
Abaixo esto alguns exemplos de como nomear arquivos para diferentes tipos de classes que voc usar em
aplicaes CakePHP:
O controller KissesAndHugsController seria encontrado em um arquivo chamado KissesAnd-
HugsController.php
O componente MyHandyComponent seria encontrado em um arquivo chamado MyHandyCompo-
nent.php
O model OptionValue seria encontrado em um arquivo chamado OptionValue.php
O behavior EspeciallyFunkableBehavior seria encontrado em um arquivo chamado Especially-
FunkableBehavior.php
A View SuperSimpleView seria encontrado em um arquivo chamado SuperSimpleView.php
O helper BestEverHelper seria encontrado em um arquivo chamado BestEverHelper.php
Cada arquivo dever estar em uma pasta apropriada no diretrio app da sua aplicao.
Convenes de Models e Banco de Dados
O nome dos Models devem ser escritos no singular e no formato CamelCase
7
. Car, BigCar e ReallyBigCar
so todos exemplos de nomes de models que seguem a conveno.
Nomes de tabelas correspondentes models do CakePHP so escritos no plural e usando underscores.
As tabelas correspondentes para os models mencionados acima so respectivamente cars, big\_cars
e really\_big\_cars.
Voc pode usar a biblioteca utilitria Inflector para vericar a forma singular/plural das palavras. Veja
a classe /core-utility-libraries/inflector para mais informaes.
Nomes de colunas formadas por mais de uma palavra devem ser separadas usando underscore como em
rst_name.
Chaves estrangeiras em associaes do tipo hasMany, belongsTo ou hasOne so reconhecidas por padro
como o nome (no singular) das tabelas relacionadas seguidas por _id. Ento, se Baker hasMany (possui
muitos) Cake, a tabela cakes ir fazer referncia a tabela bakers via chave estrangeira baker_id. Para tabelas
formadas por mais de uma palavra como category_types, a chave estrangeira seria category_type_id.
Tabelas de junes usadas em relacionamentos do tipo hasAndBelongsToMany (HABTM) entre models
devem ser nomeadas usando o nome das tabelas dos models referenciados unidas em ordem alfabtica
(apples_zebras ao invs de zebras_apples).
Todas as tabela com que models do CakePHP interagem (com exceo das tabelas de juno) requerem uma
chave primria para identicar unicamente cada registro. Se voc quiser modelar uma tabela que no possua
6
http://pt.wikipedia.org/wiki/CamelCase
7
http://pt.wikipedia.org/wiki/CamelCase
Blog - Continuao 19
CakePHP Cookbook Documentation, Release 2.x
uma chave primria nica, a conveno do CakePHP diz que voc deve adicionar uma se quiser utiliz-la
com um model.
O CakePHP no suporta chaves primrias compostas. Se voc quiser manipular os dados das tabelas de
junes diretamente, use chamadas de query diretas ou adicione uma chave primaria para us-las como um
model normal. Ex.:
CREATE TABLE posts_tags (
id INT(10) NOT NULL AUTO_INCREMENT,
post_id INT(10) NOT NULL,
tag_id INT(10) NOT NULL,
PRIMARY KEY(id)
);
Ao invs de usar chaves auto incrementadas, voc tambm pode usar o tipo char(36). Desta forma o Cake
ir usar um identicador nico (uuid) de 36 caracteres criado por String::uuid sempre que voc salvar um
novo registro usando o mtodo Model::save.
Convenes de Views
Arquivos de templates de views so nomeados de acordo com o nome do mtodo do controller que exibem
no formato underscore. O mtodo getReady() da classe PeopleController ir utilizar uma view localizada
em /app/View/People/get_ready.ctp.
O molde padro /app/View/Controller/underscored_function_name.ctp.
Nomeando as partes de sua aplicao usando as convenes do CakePHP, voc ganha funcionalidades sem
os incmodos e problemticos arquivos de congurao. Segue agora um exemplo nal que mostra as
convenes todas juntas.
Tabela do banco de dados: cars
Classe Model: Car, encontrada em /app/Model/Car.php
Classe Controller: CarsController, encontrada em /app/Controller/CarsController.php
Arquivo de View encontrada em /app/View/Cars/index.ctp
Usando estas convenes o CakePHP saber que uma requisio feita pela URL http://example.com/cars/
refere-se a uma chamada para o mtodo index() da classe CarsController, onde o model Car automati-
camente disponibilizado (e automaticamente amarrado com a tabela cars no banco de dados) e renderiza
o arquivo /app/View/Cars/index.ctp. Nenhum destes relacionamentos precisou ser congurado, a no ser a
criao de classes e arquivos que voc precisaria criar de qualquer maneira.
Agora que voc j foi introduzido aos fundamentos do CakePHP, voc pode tentar o Blog para ver como
todas as coisas se encaixam juntas.
Estrutura de Diretrios no CakePHP
Aps ter baixado e extrado o CakePHP, voc dever encontrar os seguintes arquivos e pastas:
app
20 Captulo 1. Primeiros Passos
CakePHP Cookbook Documentation, Release 2.x
lib
vendors
plugins
.htaccess
index.php
README
Voc encontrar trs pastas principais:
No diretrio app onde voc far sua mgica, ou seja: o lugar que voc colocar os arquivos de sua
aplicao.
No diretrio lib onde fazemos nossa mgica. comprometa-se em no editar nenhum arquivo deste
diretrio. No podemos ajud-lo se voc modicar o ncleo do framework.
E nalmente, no diretrio vendors onde voc pode colocar as bibliotecas de terceiros que precisar
usar em suas aplicaes com o CakePHP.
O Diretrio App
No diretrio app do Cake onde voc faz a maior parte do desenvolvimento de sua aplicao. Vamos dar
uma olhada mais de perto nas pastas que esto dentro de app.
Cong Armazena os (poucos) arquivos de congurao que o CakePHP utiliza. Parmetros de conexo
com o banco de dados, inicializao do sistema (Bootstrapping
8
), arquivos de congurao do ncleo
do framework, e outros, devem car aqui.
Controller Contm os controllers e componentes da sua aplicao.
Lib Contm suas bibliotecas pessoais e diferentes das obtidas de terceiros. Isto permite separar as bibliote-
cas internas de sua empresa das que foram criadas por outras pessoas ou fornecedores.
Locale Armazena arquivos contendo strings de internacionalizao.
Model Contm os Models, behaviors e datasources de sua aplicao.
Plugin Contm pacotes de plugins.
tmp Este diretrio onde o CakePHP armazena dados temporrios. Os dados armazenados dependem de
como voc congurou o CakePHP mas geralmente usada para armazenar o cache das descries dos
models, logs e por vezes os dados de sesso.
Tenha certeza de que esta pasta exista e que seja gravvel, seno o desempenho de sua aplicao ser
prejudicado severamente.
Vendor Qualquer classe ou biblioteca de terceiros devem car aqui. Fazendo isto, torna fcil acess-las us-
ando o mtodo App::import(vendor, name). Olhos aguados notaram que isto parece redundante,
j que temos outra pasta chamada vendors, um nvel acima do diretrio app. Ns entraremos nos
8
http://pt.wikipedia.org/wiki/Bootstrapping
Blog - Continuao 21
CakePHP Cookbook Documentation, Release 2.x
detalhes, explicando a diferena dos dois diretrios quando estivermos discutindo sobre como gerir
mltiplas aplicaes e conguraes de sistemas mais complexos.
View Arquivos de apresentao so colocados aqui: elementos, pginas de erros, helpers, layouts e arquivos
de views.
webroot Quando voc congurar sua aplicao para rodar em produo, este diretrio deve ser a raiz do seu
diretrio web pblico. Pastas aqui dentro tambm servem para colocar seus arquivos CSS, imagens e
Javascripts.
Estrutura do CakePHP
O CakePHP possui as classes essenciais Controller, Model e View, mas tambm apresenta algumas outras
classes e objetos adicionais que fazem o desenvolvimento com o MVC um pouco mais rpido e divertido.
Componentes, Behaviors e Helpers so classes que fornecem extensibilidade e reusabilidade para adicionar
funcionalidades base das classes do MVC em sua aplicao. Por enquanto, vamos fazer uma explicao
supercial destas ferramentas e detalh-las mais tarde.
Extenses de Aplicao
Cada controller, helper e model possui uma classe me que voc pode usar para
incluir mudanas vlidas por toda a aplicao. As classes AppController (lo-
calizada em /app/Controller/AppController.php), AppHelper (local-
izada em /app/View/Helper/AppHelper.php) e AppModel (localizada em
/app/Model/AppModel.php) so excelentes lugares para colocar mtodos que voc quer com-
partilhar entre todos os controllers, helpers ou models.
Embora rotas no sejamclasses ou arquivos, elas desempenhamumpapel nas requisies feitas ao CakePHP.
Denies de rotas dizem ao CakePHP como mapear URLs para as aes de controllers. O comportamento
padro assume que a URL /controller/action/var1/var2 deve ser mapeada para o mtodo Con-
troller::action($var1, $var2), mas voc pode usar as rotas para customizar as URLs e como elas so inter-
pretadas por sua aplicao.
Alguns recursos em uma aplicao merecem ser reunidas em um pacote. Um plugin um pacote de models,
controllers e views que cumprem um objetivo especco e que podem ser utilizados em vrias aplicaes.
Um sistema de gerenciamento de usurios ou um blog simplicado podem ser bons candidatos para plugins
do CakePHP.
Extenses de Controllers (Componentes)
Um Component uma classe que d suporte s lgicas nos controllers. Se voc possui uma lgica que
queira compartilhar entre controllers, um componente geralmente uma boa escolha para coloc-la. Como
um exemplo, a classe EmailComponent do Cake permite criar e enviar emails num piscar de olhos.
Ao invs de escrever um mtodo em um controller nico que executa esta lgica, voc pode empacotar a
lgica para que seja possvel compartilh-la.
22 Captulo 1. Primeiros Passos
CakePHP Cookbook Documentation, Release 2.x
Os controllers tambm esto equipados com callbacks. Estes callbacks esto disponveis para que voc
possa utiliz-los, bem nos casos em que voc precisa inserir alguma lgica entre as operaes do ncleo do
CakePHP. Os callbacks disponibilizados so:
beforeFilter(), executado antes de qualquer ao de um controller.
beforeRender(), executado aps a lgica de um controller, mas antes da view ser renderizada.
afterFilter(), executada aps a lgica de um controller, incluindo a renderizao da view. Pode
no haver diferenas entre o afterRender() e o afterFilter() ao menos que voc tenha
chamado o mtodo render() na ao de um controller e tenha includo alguma lgica depois desta
chamada.
Extenses de Models (Behaviors)
Similarmente, Behaviors trabalham para adicionar funcionalidades comuns entre models. Por exemplo, se
voc armazena os dados dos usurios em uma estrutura de dados do tipo rvore, voc pode especicar que
seu model Usuario se comporta tal como uma rvore e assim, ganha funcionalidades para remover, adicionar
e substituir ns na estrutura que existe por baixo do model.
Models tambm recebem o suporte de outra classe chamada DataSource. DataSources so uma abstrao
que permite os models manipularemconsistentemente diferentes tipos de dados. Embora a fonte principal de
dados emuma aplicao usando o CakePHP seja banco de dados, voc pode escrever DataSources adicionais
que permitem seus models representarem feeds RSS, arquivos CSV, entradas LDAP ou eventos do iCal. Os
DataSources permitem voc associar registros de diferentes fontes: Diferente de estar limitado pelas junes
do SQL, os DataSources permitem voc dizer para seu Model LDAP que est associado muitos eventos
do iCal.
Assim como os controllers, os models tambm possuem callbacks:
beforeFind(), executado antes de uma busca.
afterFind(), executado aps uma busca.
beforeValidate(), executado antes de fazer uma validao de dados.
beforeSave(), executado antes de salvar ou atualizar registros de um model.
afterSave(), executado aps salvar ou atualizar registros de um model.
beforeDelete(), executado antes de remover registros de um model.
afterDelete(), executado aps remover registros de um model.
Com a mnima descrio dada, deve ser possvel saber o que estes callbacks fazem. Voc pode encontrar
mais detalhes no captulo dos models.
Extenses de Views (Helpers)
Um Helper uma classe que ajuda na lgica das views. Muito parecido como os componentes que so
usados pelos controllers, os helpers ajudam na lgica de apresentao que podem ser acessadas e compar-
tilhadas entre as views. Um dos Helpers que acompanha o Cake o AjaxHelper que torna requisies em
ajax nas views muito mais fcil.
Blog - Continuao 23
CakePHP Cookbook Documentation, Release 2.x
Muitas aplicaes possuem pedaos de cdigo de apresentao que so usados repetidamente. O CakePHP
facilita a reutilizao destes trechos com layouts e elementos. Por padro, cada view renderizada por um
controller colocada dentro de um layout. Elementos so usados quando pequenos trechos de contedo
precisam ser reusados em muitas views.
24 Captulo 1. Primeiros Passos
CAPTULO 2
Instalao
O CakePHP rpido e fcil de instalar. Os requisitos mnimos so um servidor web e uma cpia do Cake, s
isso! Apesar deste manual focar principalmente na congurao do Apache (porque ele o mais comum),
voc pode congurar o Cake para executar emdiversos servidores web, tais como LightHTTPDou Microsoft
IIS.
Requisitos
Servidor HTTP. Por exemplo: Apache. prefervel ter o mod_rewrite habilitado mas no uma
exigncia.
PHP 5.2.6 ou superior.
Tecnicamente no exigido um banco de dados mas imaginamos que a maioria das aplicaes ir utilizar
um. O CakePHP suporta uma variedade deles:
MySQL (4 ou superior)
PostgreSQL
Microsoft SQL Server
SQLite
Note: Todos os drivers inclusos internamente requerem o PDO. Voc deve ter certeza que possui a extenso
correta do PDO instalada.
Licena
O CakePHP licenciado sob uma Licena MIT. Isto signica que voc tem liberdade para modicar, dis-
tribuir e republicar o cdigo-fonte com a condio de que os avisos de copyright permaneam intactos. Voc
tambm tem liberdade para incorporar o CakePHP em qualquer aplicao comercial ou de cdigo fechado.
25
CakePHP Cookbook Documentation, Release 2.x
Baixando o CakePHP
H duas maneiras de se obter uma cpia atualizada do CakePHP. Voc pode fazer o download de um arquivo
comprimido (zip/tar.gz/tar.bz2) no site principal ou obter o cdigo a partir do repositrio git.
Para fazer o download da verso estvel mais recente do CakePHP, visite o site principal http://cakephp.org.
L haver um link chamado Download Now! para baixar.
Todas as verses liberadas do CakePHP esto hospedadas no Github
1
. O Github do CakePHP abriga o
prprio Cake assim como muitos outros plugins para ele. As verses disponveis esto na pgina Github
tags
2
.
Alternativamente voc pode obter uma cpia contendo todas as correes de bugs e atualizaes recentes
clonando o repositrio do Github:
git clone git://github.com/cakephp/cakephp.git
Permisses
O CakePHP usa o diretrio /app/tmp para diferentes operaes. Descries do modelo, cache das views,
e informaes das sesses so alguns exemplos.
Assim, tenha certeza que o diretrio /app/tmp na sua instalao do cake permite a escrita pelo usurio do
servidor web.
Congurao
Congurar o CakePHP pode ser to simples como descompact-lo em seu servidor web, ou to complexo
e exvel se voc desejar. Esta seo ir cobrir trs principais tipos de instalao do CakePHP: desenvolvi-
mento, produo e avanada.
Desenvolvimento: fcil para comear, as URLs da aplicao incluem o nome do diretrio de insta-
lao e menos seguro.
Produo: Requer maior habilidade para congurar o diretrio raiz do servidor web, URLs limpas,
muito seguro.
Avanada: Com algumas conguraes, permite que voc coloque os diretrios do CakePHP em
diferentes locais do sistema de arquivos, permitindo compartilhar o ncleo do CakePHP entre diversas
aplicaes.
Desenvolvimento
A instalao de desenvolvimento o mtodo mais rpido de congurao do Cake. Este exemplo ir te
ajudar a instalar uma aplicao CakePHP e torn-la disponvel em http://www.example.com/cake_2_0/.
1
http://github.com/cakephp/cakephp
2
https://github.com/cakephp/cakephp/tags
26 Captulo 2. Instalao
CakePHP Cookbook Documentation, Release 2.x
Assumimos, para efeitos deste exemplo que a sua raiz do documento denido como /var/www/html.
Descompacte o contedo do arquivo do Cake em /var/www/html. Voc agora tem uma pasta na raiz do
seu servidor web com o nome da verso que voc baixou (por exemplo, cake2.0.0). Renomeie essa pasta
para cake_2_0. Sua congurao de desenvolvimento ser semelhante a esta em seu sistema de arquivos:
/var/www/html
/cake_2_0
/app
/lib
/vendors
/plugins
/.htaccess
/index.php
/README
Se o seu servidor web est congurado corretamente, agora voc deve encontrar sua aplicao Cake
acessvel em http://www.example.com/cake_2_0/.
Produo
A instalao de produo uma forma mais exvel de congurao do Cake Usando este mtodo permite
um total domnio para agir como uma nica aplicao CakePHP. Este exemplo ir ajud-lo a instalar o Cake
em qualquer lugar do seu sistema de arquivos e torn-lo disponvel em http://www.example.com. Note que
esta instalao pode requerer os privilgios para alterao do DocumentRoot do servidor apache.
Descompacte o contedo do arquivo do Cake em um diretrio de sua escolha. Para ns deste exemplo, as-
sumimos que voc escolheu instalar o Cake em /cake_install. Sua congurao de produo ser semelhante
a esta em seu sistema de arquivos:
/cake_install/
/app
*
/webroot (este diretrio ser usado na diretiva DocumentRoot)
/lib
/vendors
/.htaccess
/index.php
/README
Desenvolvedores usando o Apache devem denir o DocumentRoot do domnio para:
Produo 27
CakePHP Cookbook Documentation, Release 2.x
DocumentRoot /cake_install/app/webroot
Se o seu servidor web estiver congurado corretamente, voc deve encontrar agora sua aplicao Cake
acessvel em http://www.example.com.
Instalao Avanada e Congurao Especca por Servidor
Instalao Avanada
Pode haver algumas situaes onde voc deseja colocar os diretrios do CakePHP em diferentes locais no
sistema de arquivos. Isto pode ser devido a uma restrio do servidor compartilhado, ou talvez voc queira
apenas que algumas aplicaes compartilhem as bibliotecas do Cake. Esta seo descreve como espalhar
seus diretrios do CakePHP em um sistema de arquivos.
Em primeiro lugar, note que h trs partes principais de uma aplicao CakePHP.
1. As bibliotecas do ncleo do CakePHP, em /cake.
2. O cdigo da sua aplicao, em /app.
3. Os arquivos pblicos da sua aplicao, normalmente em /app/webroot.
Cada um desses diretrios podem ser localizados em qualquer em seu sistema de arquivos, com exceo do
webroot, que precisa ser acessvel pelo seu servidor web. Voc pode at mesmo mover a pasta webroot para
fora da pasta app, desde que voc dia ao Cake onde voc colocou.
Para congurar sua instalao do Cake, voc precisa fazer algumas modicaes nos seguintes arquivos.
/app/webroot/index.php
/app/webroot/test.php (se voc utilizar o recurso de Testes.)
H trs constantes que voc precisa editar: ROOT, APP_DIR, e CAKE_CORE_INCLUDE_PATH.
ROOT deve ser congurada para o diretrio que contm sua pasta app.
APP_DIR deve ser denida como o nome de sua pasta app.
CAKE_CORE_INCLUDE_PATH deve ser denida como o caminho da sua pasta de bibliotecas do
CakePHP.
Vamos fazer um exemplo para que voc possa ver como funciona uma instalao avanada na prtica.
Imagine que eu quero que a aplicao funcione como segue:
O ncleo do CakePHP ser colocado em /usr/lib/cake.
O diretrio webroot da minha aplicao ser /var/www/mysite/.
O diretrio app da minha aplicao ser /home/me/myapp.
Dado este tipo de congurao, eu preciso editar meu arquivo webroot/index.php (que vai acabar em
/var/www/mysite/index.php, neste exemplo) para algo como o seguinte:
28 Captulo 2. Instalao
CakePHP Cookbook Documentation, Release 2.x
// /app/webroot/index.php (parcial, comentrios removidos)
if (!defined(ROOT)) {
define(ROOT, DS . home . DS . me);
}
if (!defined(APP_DIR)) {
define (APP_DIR, myapp);
}
if (!defined(CAKE_CORE_INCLUDE_PATH)) {
define(CAKE_CORE_INCLUDE_PATH, DS . usr . DS . lib);
}
Recomenda-se a utilizao da constante DS ao invs das barras para delimitar os caminhos de arquivos. Isso
previne qualquer erros sobre falta de arquivos que voc pode obter, por ter usado o delimitador errado, e isso
torna o seu cdigo mais portvel.
Apache e mod_rewrite (e .htaccess)
O CakePHP desenvolvido para trabalhar com o mod_rewrite, mas percebemos que alguns usurios apan-
haram ppara fazer isto funcionar nos seus sistemas, ento ns lhe daremos algumas dicas que voc pode
tentar fazer para rodar corretamente.
Aqui esto algumas coisas que voc pode tentar fazer para rodar corretamente. Primeiro veja o seu httpd.conf
(tenha certeza de estar editando o httpd.conf do sistema e no o de um usurio ou de um site especco).
1. Tenha certeza que a sobreposio do .htaccess est sendo permitida, ou seja, que o AllowOverride
est congurado como All para o DocumentRoot. Voc deve ver algo similar a isso:
# Cada diretrio com o Apache tenha acesso pode ser configurado com
# relao aos quais servios e recursos so permitidos e/ou
# desabilitados neste diretrio (e seus subdiretrios).
#
# Primeiro, configuramos o o "padro" para ter um conjunto muito
# restrito de recursos.
#
<Directory />
Options FollowSymLinks
AllowOverride All
# Order deny,allow
# Deny from all
</Directory>
2. Tenha certeza de estar carregando o mod_rewrite corretamente. Voc deve ver algo como:
LoadModule rewrite_module libexec/apache2/mod_rewrite.so
Em muitos sistemas isso vem comentado por padro (comeando com um #), ento voc apenas
precisa remover esses smbolos.
Depois de fazer as alteraes, reinicie o Apache para ter certeza que as conguraes esto aivas.
Instalao Avanada e Congurao Especca por Servidor 29
CakePHP Cookbook Documentation, Release 2.x
Verique se os seus arquivos .htaccess esto nos diretrios corretos.
Isso pode acontecer durante a cpia, pois alguns sistemas operacionais tratam arquivos que comeam
com . como oculto e, portanto, voc no poder v-los copiar.
3. Tenha certeza que sua cpia do CakePHP veio da seo de downloads do nosso site ou do nosso
repositrio GIT, e foi descompactada corretamente vericando os seus arquivos .htaccess.
No diretrio raiz do Cake (precisa ser copiado para o seu DocumentRoot, este redireciona tudo para a
sua aplicao):
<IfModule mod_rewrite.c>
RewriteEngine on
RewriteRule ^ $ app/webroot/ [L]
RewriteRule (.
*
) app/webroot/ $ 1 [L]
</IfModule>
O diretrio app do seu Cake (ser copiado para o diretrio principal da sua aplicao pelo bake):
<IfModule mod_rewrite.c>
RewriteEngine on
RewriteRule ^ $ webroot/ [L]
RewriteRule (.
*
) webroot/ $ 1 [L]
</IfModule>
Diretrio webroot do Cake (ser copiado para a raiz da sua aplicao web pelo bake):
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.
*
) $ index.php [QSA,L]
</IfModule>
Para muitos servios de hospedagem (GoDaddy, 1and1), seu servidor web sendo servido a partir de
um diretrio de usurio que j utiliza o mod_rewrite. Se voc est instalando o CakePHP dentro
do diretrio de um usurio (http://example.com/~username/cakephp/), ou qualquer outra estrutura de
URL que j utiliza o mod_rewrite, voc ir precisar adicionar instrues RewriteBase para os arquivos
.htaccess do CakePHP (/.htaccess, /app/.htaccess, /app/webroot/.htaccess).
Isto pode ser adicionado mesma seo da diretiva RewriteEngine, por exemplo, o arquivo .htaccess
do seu webroot seria algo como:
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /path/to/cake/app
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.
*
) $ index.php [QSA,L]
</IfModule>
Os detalhes dessa mudana vai depender de sua congurao, e pode incluir algumas coisas adicionais
que no esto relacionadas ao Cake. Por favor, consulte a documentao online do Apache para mais
informaes.
30 Captulo 2. Instalao
CakePHP Cookbook Documentation, Release 2.x
URLs amigveis e Lighttpd
Embora o Lighttpd apresenta um mdulo de reescrita, ele no equivalente ao mod_rewrite do Apache.
Para obter URLs amigveis ao usar Lighty voc tem duas opes. Uma usar o mod_rewrite a outra
usar um script LUA com o mod_magnet.
Usando o mod_rewrite O modo mais fcil para se obter URLs amigveis adicionando este script na
congurao do seu lighty. Basta editar a URL, e tudo deve funcionar. Por favor, note que isto no funciona
em instalaes do Cake em subdiretrios.
$HTTP["host"] =~ "^(www\.)?example.com$" {
url.rewrite-once = (
# if the request is for css|files etc, do not pass on to Cake
"^/(css|files|img|js)/(.
*
)" => "/$1/$2",
"^([^\?]
*
)(\?(.+))?$" => "/index.php?url=$1&$3",
)
evhost.path-pattern = "/home/%2-%1/www/www/%4/app/webroot/"
}
Usando o mod_magnet Para utiizar URLs amigveis com o CakePHP e o Lighttpd, coloque este script
LUA em /etc/lighttpd/cake.
-- little helper function
function file_exists(path)
local attr = lighty.stat(path)
if (attr) then
return true
else
return false
end
end
function removePrefix(str, prefix)
return str:sub(1,#prefix+1) == prefix.."/" and str:sub(#prefix+2)
end
-- prefix without the trailing slash
local prefix =
-- the magic ;)
if (not file_exists(lighty.env["physical.path"])) then
-- file still missing. pass it to the fastcgi backend
request_uri = removePrefix(lighty.env["uri.path"], prefix)
if request_uri then
lighty.env["uri.path"] = prefix .. "/index.php"
local uriquery = lighty.env["uri.query"] or ""
lighty.env["uri.query"] = uriquery .. (uriquery ~= "" and "&" or "") .. "url=" .. request_uri
lighty.env["physical.rel-path"] = lighty.env["uri.path"]
lighty.env["request.orig-uri"] = lighty.env["request.uri"]
lighty.env["physical.path"] = lighty.env["physical.doc-root"] .. lighty.env["physical.rel-path"]
end
end
-- fallthrough will put it back into the lighty request loop
-- that means we get the 304 handling for free. ;)
Instalao Avanada e Congurao Especca por Servidor 31
CakePHP Cookbook Documentation, Release 2.x
Note: Se voc estiver rodando sua instalao do CakePHP a partir de um subdiretrio, voc precisa denir
o prex = subdiretorio no script acima
Ento, informe ao Lighttpd sobre o seu vhost:
$HTTP["host"] =~ "example.com" {
server.error-handler-404 = "/index.php"
magnet.attract-physical-path-to = ( "/etc/lighttpd/cake.lua" )
server.document-root = "/var/www/cake-1.2/app/webroot/"
# Think about getting vim tmp files out of the way too
url.access-deny = (
"~", ".inc", ".sh", "sql", ".sql", ".tpl.php",
".xtmpl", "Entries", "Repository", "Root",
".ctp", "empty"
)
}
URLs amigveis no nginx
nginx um servidor popular que, como Lighttpd, usa menos recursos do sistema. O inconveniente que no
faz uso de arquivos .htaccess como o Apache e o Lighttpd, por isso necessrio criar as URLs reescritas na
congurao site-available. Dependendo de sua instalao, voc ter que modicar isso, mas no mnimo,
voc ir precisar do PHP sendo executado como FastCGI.
server {
listen 80;
server_name www.example.com;
rewrite ^(.
*
) http://example.com $ 1 permanent;
}
server {
listen 80;
server_name example.com;
# root directive should be global
root /var/www/example.com/public/app/webroot/;
index index.php;
access_log /var/www/example.com/log/access.log;
error_log /var/www/example.com/log/error.log;
location / {
try_files $uri $uri/ /index.php?$uri&$args;
}
location ~ \.php $ {
include /etc/nginx/fastcgi_params;
32 Captulo 2. Instalao
CakePHP Cookbook Documentation, Release 2.x
try_files $uri =404;
fastcgi_pass 127.0.0.1:9000;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
}
}
URL Rewrites no IIS7 (Windows hosts)
O IIS7 no suporta nativamente os arquivos .htaccess. Embora haja add-ons que podem adicionar esse
suporte, voc tambm pode importar regras htaccess no IIS para usar as regras de reescritas nativas do
CakePHP. Para fazer isso, siga estes passos:
1. Use o Microsift Web Plataform Installer para instalar o URL Rewrite Module 2.0.
2. Crie um novo arquivo dentro de sua pasta do CakePHP, chamado web.cong.
3. Usando o Notepad ou algum outro editor de XML, copie o seguinte cdigo no seu novo arquivo
web.cong...
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<system.webServer>
<rewrite>
<rules>
<rule name="Imported Rule 1" stopProcessing="true">
<match url="^(.
*
)$" ignoreCase="false" />
<conditions logicalGrouping="MatchAll">
<add input="{REQUEST_FILENAME}" matchType="IsDirectory" negate="true" />
<add input="{REQUEST_FILENAME}" matchType="IsFile" negate="true" />
</conditions>
<action type="Rewrite" url="index.php?url={R:1}" appendQueryString="true" />
</rule>
<rule name="Imported Rule 2" stopProcessing="true">
<match url="^$" ignoreCase="false" />
<action type="Rewrite" url="/" />
</rule>
<rule name="Imported Rule 3" stopProcessing="true">
<match url="(.
*
)" ignoreCase="false" />
<action type="Rewrite" url="/{R:1}" />
</rule>
<rule name="Imported Rule 4" stopProcessing="true">
<match url="^(.
*
)$" ignoreCase="false" />
<conditions logicalGrouping="MatchAll">
<add input="{REQUEST_FILENAME}" matchType="IsDirectory" negate="true" />
<add input="{REQUEST_FILENAME}" matchType="IsFile" negate="true" />
</conditions>
<action type="Rewrite" url="index.php?url={R:1}" appendQueryString="true" />
</rule>
Instalao Avanada e Congurao Especca por Servidor 33
CakePHP Cookbook Documentation, Release 2.x
</rules>
</rewrite>
</system.webServer>
</configuration>
Tambm possvel usar a funcionalidade de importao no modulo de reescrita de URL do IIS para importar
regras diretamente dos arquivos .htaccess do CakePHP nas pastas /app/, e /app/webroot/ - embora algumas
edies no IIS podem ser necessrias para faz-los funcionar. Importando as regras desta maneira, o IIS ir
automaticamente criar o arquivo web.cong para voc.
Uma vez que o arquivo web.cong criado com o conjunto de regras de reescrita do IIS, links do CakePHP,
css, js, e o redirecionamento devem funcionar corretamente.
Comece agora!
Tudo bem, vamos ver o CakePHP em ao. Dependendo de qual congurao voc adotou, voc deve
apontar seu navegador para http://example.com/ ou http://example.com/cake_install/. Neste ponto, voc
ver a pgina padro do CakePHP e a mensagem do estado da congurao do seu banco de dados.
Parabns! Voc j est pronto para criar sua primeira aplicao CakePHP.
No est funcionando? Se voc estiver recebendo erros do PHP relacionados ao fuso horrio, descomente
uma linha no app/Cong/core.php:
/
**
*
Uncomment this line and correct your server timezone to fix
*
any date & time related errors.
*
/
date_default_timezone_set(UTC);
34 Captulo 2. Instalao
CAPTULO 3
Viso Geral do CakePHP
Bem vindo ao Cookbook, o manual para o framework de aplicaes web CakePHP que torna o desenvolvi-
mento um pedao de bolo!
Este manual assume que voc tenha um entendimento geral sobre PHP e conhecimentos bsicos em progra-
mao orientada a objetos. Diferentes funcionalidades dentro do framework utilizam diversas tecnologias
como SQL, Javascript e XML e este manual no tenta explicar estas tecnologias, somente como so
usadas neste no contexto.
O que o CakePHP? Porque us-lo?
O CakePHP
1
um framework
2
de desenvolvimento rpido
3
para PHP
4
, livre
5
e de Cdigo aberto
6
. Nosso
principal objetivo permitir que voc trabalhe de forma estruturada e rpida sem perder a exibilidade.
O CakePHP tira a monotonia do desenvolvimento web. Ns fornecemos todas as ferramentas que voc
precisa para comear programando o que realmente deseja: a lgica especca da sua aplicao. Em vez de
reinventar a roda a cada vez que se constri um novo projeto, pegue uma cpia do CakePHP e comece com
o interior de sua aplicao.
O CakePHP possui uma equipe de desenvolvedores
7
ativa e uma grande comunidade, trazendo grande valor
ao projeto. Alm de manter voc fora da reinveno da roda, usando o CakePHP signica que o ncleo da
sua aplicao bem testado e est em constante aperfeioamento.
Abaixo segue uma pequena lista dos recursos que voc poder desfrutar no CakePHP:
Comunidade
8
ativa e amigvel
1
http://www.cakephp.org/
2
http://pt.wikipedia.org/wiki/Framework
3
http://pt.wikipedia.org/wiki/Rapid_Application_Development
4
http://www.php.net/
5
http://pt.wikipedia.org/wiki/Licena_MIT
6
http://pt.wikipedia.org/wiki/Cdigo_aberto
7
http://github.com/cakephp/cakephp/contributors
8
http://cakephp.org/feeds
35
CakePHP Cookbook Documentation, Release 2.x
Licena
9
exvel
Compatvel com o PHP 5.2.6 e superior
CRUD
10
integrado para interao com o banco de dados
Scaffolding
11
para criar prottipos
Gerao de cdigo
Arquitetura MVC
12
Requisies feitas com clareza, URLs e rotas customizveis
Validaes
13
embutidas
Templates
14
rpidos e exveis (Sintaxe PHP, com helpers)
Helpers para AJAX, JavaScript, formulrios HTML e outros
Componentes de Email, Cookie, Segurana, Sesso, e Tratamento de Requisies
Controle de Acessos
15
exvel
Limpeza dos dados
Sistema de Cache
16
exvel
Localizao
Funciona a partir de qualquer diretrio do website, com pouca ou nenhuma congurao do Apache
Entendendo o Model-View-Controller
O CakePHP segue o padro de projeto MVC
17
. Programar usando o MVC separa sua aplicao em trs
partes principais:
Note: Optamos por no traduzir as palavras Model, View e Controller. Gostariamos que voc se acos-
tumasse com elas pois so muito utilizadas no dia a dia de um desenvolvedor CakePHP. Assim como o
Portugus incorporou diversas palavras estrangeiras, o que voc acha de incorporar estas palavras no seu
vocabulrio?
9
http://pt.wikipedia.org/wiki/Licena_MIT
10
http://pt.wikipedia.org/wiki/CRUD
11
http://en.wikipedia.org/wiki/Scaffold_(programming)
12
http://pt.wikipedia.org/wiki/MVC
13
http://en.wikipedia.org/wiki/Data_validation
14
http://en.wikipedia.org/wiki/Web_template_system
15
http://pt.wikipedia.org/wiki/Access_Control_List
16
http://en.wikipedia.org/wiki/Web_cache
17
http://pt.wikipedia.org/wiki/MVC
36 Captulo 3. Viso Geral do CakePHP
CakePHP Cookbook Documentation, Release 2.x
A camada Model
A camada Model (modelo) representa a parte de sua aplicao que implementa a lgica do negcio. Isto
signica que ela responsvel por obter os dados convertendo-os em conceitos signicativos para sua apli-
cao, assim como, processar, validar, associar e qualquer outra tarefa relativa ao tratamento dos dados.
primeira vista, os objetos do tipo Model podem ser vistos como a primeira camada de interao com
qualquer banco de dados que voc possa estar usando na sua aplicao. Mas em geral eles representam os
principais conceitos em torno do qual voc implementa sua aplicao.
No caso de uma rede social, a camada Model cuida de tarefas como as de salvar os dados dos usurios e
o relacionamento entre amigos, armazenar e recuperar as fotos dos usurios, encontrar novos amigos para
sugestes e etc. Neste exemplo os Models podem ser vistos como Amigo, Usuario, Comentarioe
Foto.
A camada View
Uma View exibe uma representao dos dados modelados. Sendo separadas do objeto Model, responsvel
por usar as informaes disponibilizadas para produzir qualquer interface de apresentao que sua aplicao
possa necessitar.
Por exemplo, como a camada Model retorna um conjunto de dados, a view pode us-los para exibir uma
pgina HTML ou retornar o resultado em um formato XML para que outros o consuma.
A camada View no est limitada representaes dos dados no formato HTML ou texto, podendo ser
usada para entregar uma variedade de formatos diferentes, dependendo do que voc precisar, como vdeos,
msicas, documentos e qualquer outro formato que voc puder pensar.
A camada Controller
A camada Controller (controlador) lida com as requisies dos usurios. responsvel por retornar uma
resposta com a ajuda das camadas Model e View.
Os Controllers podem ser vistos como gerentes tomando os devidos cuidados para que todos os recursos
necessrios para completar uma tarefa sejam delegados para os trabalhadores corretos. Ele aguarda os
pedidos dos clientes, verica a validade de acordo com as regras de autenticao e autorizao, delega
dados para serem obtidos ou processados pelos Models e seleciona o tipo correto de apresentao dos dados
para o qual o cliente est aceitando para nalmente delegar o trabalho de renderizao para a camada de
visualizao.
Entendendo o Model-View-Controller 37
CakePHP Cookbook Documentation, Release 2.x
Ciclo de Requisio no CakePHP
Figura: 1: Uma requisio bsica no MVC
Figura 1: Mostra o tratamento de uma simples requisio de um cliente pelo CakePHP.
Um ciclo de requisio tpico do CakePHP comea com o usurio solicitando uma pgina ou recurso em sua
aplicao. Esta solicitao primeiramente processada por um dispatcher (expedidor) que ir selecionar o
objeto Controller correto para lidar com a solicitao feita.
Assim que a solicitao do cliente chega ao Controller, este ir se comunicar como a camada Model para
processar qualquer operao de busca ou armazenamento de dados que for necessrio. Aps esta comuni-
cao terminar, o Controller continuar delegando, agora para o objeto View correto a tarefa de gerar uma
sada resultante dos dados fornecidos pelo Model.
Finalmente quando a sada gerada, ela imediatamente enviada para o usurio.
Praticamente todas as requisies feitas para a sua aplicao iro seguir este padro.
Depois ns iremos adicionar mais alguns detalhes especcos do CakePHP, portanto, tenha isto em mente
enquanto prosseguimos.
Benefcios
Por que usar MVC? Porque um verdadeiro e testado padro de projeto de software que transforma uma
aplicao em pacotes de desenvolvimento rpido, de fcil manuteno e modular. Elaborar tarefas divi-
didas entre models, views e controllers faz com que sua aplicao que leve. Novas funcionalidades so
facilmente adicionadas e pode-se dar nova cara nas caractersticas antigas num piscar de olhos. O design
modular e separado tambm permite aos desenvolvedores e designers trabalharem simultaneamente, in-
cluindo a capacidade de se construir um prottipo
18
muito rapidamente. A separao tambm permite que
os desenvolvedores alterem uma parte da aplicao sem afetar outras.
18
http://en.wikipedia.org/wiki/Software_prototyping
38 Captulo 3. Viso Geral do CakePHP
CakePHP Cookbook Documentation, Release 2.x
Se voc nunca construiu uma aplicao desta forma, leva algum tempo para se acostumar, mas estamos
conantes que uma vez que voc tenha construdo sua primeira aplicao usando CakePHP, voc no vai
querer fazer de outra maneira.
Para comear a sua primeira aplicao CakePHP, tente seguir o tutorial para a construo de um blog
Onde obter ajuda
Site ocial do CakePHP
http://www.cakephp.org
O site ocial do CakePHP sempre o melhor lugar para visitar. Possui links para ferramentas frequente-
mente utilizadas para desenvolvedores, screencasts, oportunidades de doaes e downloads.
O Cookbook
http://book.cakephp.org
Este manual dever ser provavelmente o primeiro lugar que voc v para obter respostas. Como acontece
com muitos outros projetos de cdigo aberto, temos novas pessoas regularmente. Tente primeiro dar o
seu melhor para responder s suas prprias perguntas. As respostas podem vir mais lentas, porem, sero
duradouras e tambm aliviar nossa demanda de suporte. Tanto o manual como a API podem ser consultadas
online.
O Bakery
http://bakery.cakephp.org
O CakePHP Bakery um centro de intercmbio para todas as coisas sobre o CakePHP. Locais para tutoriais,
estudos de casos, exemplos de cdigos. Uma vez que voc estiver familiarizado com o CakePHP, faa logon
e compartilhe seus conhecimentos com a comunidade e ganhe fama e fortuna.
A API
http://api20.cakephp.org/
Direto ao ponto e diretamente dos desenvolvedores do ncleo, a API (Application Programming Interface)
do CakePHP a mais completa documentao acerca dos mnimos detalhes do funcionamento interno do
framework.
Casos de Testes
Se voc sentiu que a informao fornecida na API no suciente, verique o cdigo dos casos de testes
fornecido com o CakePHP. Eles podem servir como exemplos prticos de utilizao das funcionalidades de
uma classe:
Onde obter ajuda 39
CakePHP Cookbook Documentation, Release 2.x
lib/Cake/Test/Case
O canal IRC
Canais IRC na rede irc.freenode.net:
#cakephp Discusses gerais
#cakephp-docs Documentao
#cakephp-bakery Bakery
#cakephp-pt Discusses gerais em Portugus
Se voc est confuso, d um grito no canal do CakePHP no IRC. Algum da equipe de desenvolvimento
est geralmente l, especialmente durante o dia para os usurios da Amrica do Norte e Sul. Adoraramos
ouvir de voc, se precisar de alguma ajuda, se quiser encontrar usurios por perto ou quiser doar seu novo
carro esportivo.
O Google Group
http://groups.google.com/group/cake-php
http://groups.google.com/group/cakephp-pt
CakePHP tambm tem um grupo muito ativo no Google. Pode ser um excelente recurso para encontrar
respostas arquivadas, perguntas frequentes, e obter respostas para problemas imediatos.
40 Captulo 3. Viso Geral do CakePHP
CAPTULO 4
Controllers
Os controllers correspondem ao C no padro MVC. Aps o roteamento ter sido aplicado e o controller
correto encontrado, a ao do controller chamada. Seu controller deve lidar com a interpretao dos dados
de uma requisio, certicando-se que os models corretos so chamados e a resposta ou view esperada seja
exibida. Os controllers podem ser vistos como intermedirios entre a camada Model e View. Voc vai querer
manter seus controllers magros e seus Models gordos. Isso lhe ajudar a reutilizar seu cdigo e test-los
mais facilmente.
Mais comumente, controllers so usados para gerenciar a lgica de um nico model. Por exemplo, se
voc est construindo um site para uma padaria online, voc pode ter um RecipesController e um
IngredientsController gerenciando suas receitas e seus ingredientes. No CakePHP, controllers so
nomeados de acordo com o model que manipulam. tambm absolutamente possvel ter controllers que
usam mais de um model.
Os controllers da sua aplicao so classes que estendem a classe CakePHP AppController, a qual
por sua vez estende a classe Controller do CakePHP. A classe AppController pode ser denida
em /app/Controller/AppController.php e deve conter mtodos que so compartilhados entre
todos os seus controllers.
Os controllers fornecem uma srie de mtodos que so chamados de aes. Aes so mtodos em um
controller que manipulam requisies. Por padro, todos os mtodos pblicos em um controller so aes e
acessveis por urls.
A Classe AppController
Como mencionado anteriormente, a classe AppController a me de todos os outros con-
trollers da sua aplicao. O prprio AppController estendida da classe Controller
que faz parte da biblioteca do CakePHP. Assim sendo, AppController denido em
/app/Controller/AppController.php como:
class AppController extends Controller {
}
41
CakePHP Cookbook Documentation, Release 2.x
Os atributos e mtodos criados emAppController vo estar disponveis para todos os controllers da sua
aplicao. Este o lugar ideal para criar cdigos que so comuns para todos os seus controllers. Compo-
nentes (que voc vai aprender mais tarde) so a melhor alternativa para cdigos que so usados por muitos
(mas no obrigatoriamente em todos) controllers.
Enquanto regras normais de herana de classes orientadas objetos so aplicadas, o CakePHP tambm
faz um pequeno trabalho extra quando se trata de atributos especiais do controller. A lista de componentes
(components) e helpers usados no controller so tratados diferentemente. Nestes casos, as cadeias de valores
do AppController so mescladas com os valores de seus controllers lhos. Os valores dos controllers
lhos sempre sobrescreveram os do AppController.
Note: O CakePHP mescla as seguintes variveis do AppController em controllers da sua aplicao:
$components
$helpers
$uses
Lembre-se de adicionar os helpers Html e Form padres se voc incluiu o atributo $helpers em seu
AppController.
Tambm lembre de fazer as chamadas de callbacks do AppController nos controllers lhos para obter
melhores resultados:
function beforeFilter() {
parent::beforeFilter();
}
Parmetros de Requisio
Quando uma requisio feita para uma aplicao CakePHP, a classe Router e a classe Dispatcher
do Cake usa a routes-conguration para encontrar e criar o controller correto. Os dados da requisio so
encapsulados em um objeto de requisio. O CakePHP coloca todas as informaes importantes de uma
requisio na propriedade $this->request. Veja a seo Objetos de Requisio e Resposta para mais
informaes sobre o objeto de requisio do CakePHP.
Aes de Controllers
Retornando ao nosso exemplo da padaria online, nosso controller RecipesController
poderia conter as aes view(), share() e search() e poderia ser encontrado em
/app/Controller/RecipesController.php contendo o cdigo a seguir:
# /app/Controller/RecipesController.php
class RecipesController extends AppController {
function view($id) {
// a lgica da ao vai aqui
}
42 Captulo 4. Controllers
CakePHP Cookbook Documentation, Release 2.x
function share($customer_id, $recipe_id) {
// a lgica da ao vai aqui
}
function search($query) {
// a lgica da ao vai aqui
}
}
Para que voc use de forma ecaz os controllers em sua aplicao, ns iremos cobrir alguns dos atributos e
mtodos inclusos no controller fornecido pelo CakePHP.
Ciclo de Vida dos Callbacks em uma Requisio
class Controller
Os controllers do CakePHP vm equipados com callbacks que voc pode usar para inserir lgicas em torno
do ciclo de vida de uma requisio:
Controller::beforeFilter()
Este mtodo executado antes de cada ao dos controllers. um timo lugar para vericar se h
uma sesso ativa ou inspecionar as permisses de um usurio.
Note: Omtodo beforeFilter() ser chamado para aes no encontradas e aes criadas pelo scaffold
do Cake.
Controller::beforeRender()
Chamada aps a lgica da ao de um controller, mas antes da view ser renderizada. Este callback
no usado com frequncia mas pode ser preciso se voc chamar o mtodo render() manualmente
antes do trmino de uma ao.
Controller::afterFilter()
Chamada aps cada ao dos controllers, e aps a completa renderizao da view. Este o ltimo
mtodo executado do controller.
Em adio aos callbacks dos controllers, os Componentes tambm fornecem um conjunto de callbacks
similares.
Mtodos dos Controllers
Para uma lista completa dos mtodos e suas descries, visite a API do CakePHP. Siga para
http://api20.cakephp.org/class/controller.
Interagindo Com as Views
Os controllers interagem com as views de diversas maneiras. Primeiramente eles so capazes de passar
dados para as views usando o mtodo set(). Voc tambm pode no seu controller decidir qual classe de
Ciclo de Vida dos Callbacks em uma Requisio 43
CakePHP Cookbook Documentation, Release 2.x
View usar e qual arquivo deve ser renderizado.
Controller::set(string $var, mixed $value)
O mtodo set() a principal maneira de enviar dados do seu controller para a sua view. Aps ter
usado o mtodo set(), a varivel pode ser acessada em sua view:
// Primeiro voc passa os dados do controller:
$this->set(color, pink);
//Ento, na view, voc pode utilizar os dados:
?>
Voc selecionou a cobertura <?php echo $color; ?> para o bolo.
O mtodo set() tambm aceita um array associativo como primeiro parmetro, podendo oferecer
uma forma rpida para atribuir uma srie de informaes para a view.
Changed in version 1.3: Chaves de arrays no sero mais exionados antes de serem atribudas view
(underscored_key no se torna underscoredKey, etc.):
$data = array(
color => pink,
type => sugar,
base_price => 23.95
);
// Torna $color, $type e $base_price
// disponvel na view:
$this->set($data);
O atributo $pageTitle no existe mais, use o mtodo set() para denir o ttulo na view:
$this->set(title_for_layout, This is the page title);
?>
Controller::render(string $action, string $layout, string $le)
O mtodo render() chamado automaticamente no m de cada ao requisitada de um controller.
Este mtodo executa toda a lgica da view (usando os dados que voc passou usando o mtodo
set()), coloca a view dentro do seu layout e serve de volta para o usurio nal.
O arquivo view usado pelo mtodo render() determinado por conveno. Se a ao
search() do controller RecipesController requisitada, o arquivo view encontrado em
/app/View/Recipes/search.ctp ser renderizado:
class RecipesController extends AppController {
...
function search() {
// Renderiza a view em /View/Recipes/search.ctp
$this->render();
}
...
}
44 Captulo 4. Controllers
CakePHP Cookbook Documentation, Release 2.x
Embora o CakePHP ir chamar o mtodo render automaticamente (ao menos que voc altere o
atributo $this->autoRender para false) aps cada ao, voc pode us-lo para especicar um
arquivo view alternativo alterando o nome de ao no controller usando o parmetro $action.
Se o parmetro $action comear com / assumido que o arquivo view ou elemento que voc
queira usar relativo ao diretrio /app/View. Isto permite a renderizao direta de elementos,
muito til em chamadas Ajax.
// Renderiza o elemento presente em /View/Elements/ajaxreturn.ctp
$this->render(/Elements/ajaxreturn);
Voc tambm pode especicar uma arquivo view ou elemento usando o terceiro parmetro chamado
$file. O parmetro $layout permite voc especicar o layout em que a view ser inserido.
Renderizando Uma View Especca
Em seu controller voc pode querer renderizar uma view diferente do que a conveno proporciona au-
tomaticamente. Voc pode fazer isso chamando o mtodo render() diretamente. Aps ter chamado o
mtodo render(), o CakePHP no ir tentar renderizar novamente a view:
class PostsController extends AppController {
function my_action() {
$this->render(custom_file);
}
}
Isto ir renderizar o arquivo app/View/Posts/custom_file.ctp ao invs de
app/View/Posts/my_action.ctp
Controle de Fluxo
Controller::redirect(mixed $url, integer $status, boolean $exit)
O mtodo de controle de uxo que voc vai usar na maioria das vezes o redirect(). Este
mtodo recebe seu primeiro parmetro na forma de uma URL relativa do CakePHP. Quando um
usurio executou um pedido que altera dados no servidor, voc pode querer redirecion-lo para uma
outra tela de recepo.:
function place_order() {
// Logic for finalizing order goes here
if ($success) {
$this->redirect(array(controller => orders, action => thanks));
} else {
$this->redirect(array(controller => orders, action => confirm));
}
}
Note: Voc pode aprender mais sobre a importncia de redirecionar o usurio aps um formulrio
do tipo POST no artigo Post/Redirect/Get (en)
1
.
1
http://en.wikipedia.org/wiki/Post/Redirect/Get
Mtodos dos Controllers 45
CakePHP Cookbook Documentation, Release 2.x
Voc tambm pode usar uma URL relativa ou absoluta como argumento:
$this->redirect(/orders/thanks));
$this->redirect(http://www.example.com);
Voc tambm pode passar dados para a ao:
// observe o parmetro $id
$this->redirect(array(action => edit, $id));
O segundo parmetro passado no redirect() permite voc denir um cdigo de status HTTP para
acompanhar o redirecionamento. Voc pode querer usar o cdigo 301 (movido permanentemente) ou
303 (siga outro), dependendo da natureza do redirecionamento.
O mtodo vai assumir um exit() aps o redirecionamento ao menos que voc passe o terceiro
parmetro como false.
Se voc precisa redirecionar o usurio de volta para a pgina que fez a requisio, voc pode usar:
$this->redirect($this->referer());
Controller::flash(string $message, string $url, integer $pause, string $layout)
Assim como o mtodo redirect(), o mtodo flash() usado para direcionar o usurio para
uma nova pgina aps uma operao. O mtodo flash() diferente na forma de transio,
mostrando uma mensagem antes de transferir o usurio para a URL especicada.
O primeiro parmetro deve conter a mensagem que ser exibida e o segundo parmetro uma URL
relativa do CakePHP. O Cake ir mostrar o contedo da varivel $message pelos segundos especi-
cados em $pause antes de encaminhar o usurio para a URL especicada em $url.
Se existir um template particular que voc queira usar para mostrar a mensagem para o usurio, voc
deve especicar o nome deste layout passando o parmetro $layout.
Para mensagens ash exibidas dentro de pginas, de uma olhada no mtodo setFlash() do com-
ponente SessionComponent.
Callbacks
Em adio ao Ciclo de Vida dos Callbacks em uma Requisio. O CakePHP tambm suporta callbacks
relacionados a scaffolding.
Controller::beforeScaffold($method)
$method o nome do mtodo chamado, por exemplo: index, edit, etc.
Controller::scaffoldError($method)
$method o nome do mtodo chamado, por exemplo: index, edit, etc.
Controller::afterScaffoldSave($method)
$method o nome do mtodo chamado, podendo ser: edit ou update.
Controller::afterScaffoldSaveError($method)
$method o nome do mtodo chamado, podendo ser: edit ou update.
46 Captulo 4. Controllers
CakePHP Cookbook Documentation, Release 2.x
Outros Mtodos teis
Controller::constructClasses()
Este mtodo carrega os models requeridos pelo controller. Este processo de carregamento feito
normalmente pelo CakePHP, mas pode ser til quando for acessar controllers de outras perspec-
tivas. Se voc precisa de um controller num script de linha de comando ou para outros lugares,
constructClasses() pode vir a calhar.
Controller::referer(mixed $default = null, boolean $local = false)
Retorna a URL de referncia para a requisio atual. O parmetro $default pode ser usado para
fornecer uma URL padro a ser usada caso o HTTP_REFERER no puder ser lido do cabealho da
requisio. Ento, ao invs de fazer isto:
class UserController extends AppController {
function delete($id) {
// delete code goes here, and then...
if ($this->referer() != /) {
$this->redirect($this->referer());
} else {
$this->redirect(array(action => index));
}
}
}
Voc pode fazer isto:
class UserController extends AppController {
function delete($id) {
// delete code goes here, and then...
$this->redirect($this->referer(array(action => index)));
}
}
Se o parmetro $default no for passado, o comportamento padro a raiz do seu domnio - /.
Se o parmetro $local for passado como true, o redirecionamento restringe a URL de referncia
apenas para o servidor local.
Controller::disableCache()
Usado para dizer ao browser do usurio no fazer cache do resultado exibido. Isto diferente do
cache de views, abordado em um captulo posterior.
O cabealho enviado para este efeito so:
Expires: Mon, 26 Jul 1997 05:00:00 GMT
Last-Modified: [data e hora atual] GMT
Cache-Control: no-store, no-cache, must-revalidate
Cache-Control: post-check=0, pre-check=0
Pragma: no-cache
Controller::postConditions(array $data, mixed $op, string $bool, boolean $exclusive)
Use este mtodo para transformar um conjunto de dados POSTados de um model (vindos de inputs
compatveis com o FormHelper) em um conjunto de condies de busca. Este mtodo oferece um
Mtodos dos Controllers 47
CakePHP Cookbook Documentation, Release 2.x
atalho rpido no momento de construir operaes de busca. Por exemplo, um usurio administra-
tivo pode querer pesquisar pedidos para saber quais itens precisaro ser enviados. Voc pode usar
o FormHelper do CakePHP para criar um formulrio de busca para o model Order. Assim, uma
ao de um controller pode usar os dados enviados deste formulrio e criar as condies de busca
necessrias para completar a tarefa:
function index() {
$conditions = $this->postConditions($this->request->data);
$orders = $this->Order->find(all, compact(conditions));
$this->set(orders, $orders);
}
Se $this->request->data[Order][destination] for igual a Old Towne Bak-
ery, o mtodo postConditions() converte esta condio em um array compatvel para o uso em
um mtodo Model->nd(). Neste caso, array(Order.destination => Old Towne
Bakery).
Se voc quiser usar um operador diferente entre os termos, informe-os usando o segundo parmetro:
/
*
Contedo do atributo $this->request->data
array(
Order => array(
num_items => 4,
referrer => Ye Olde
)
)
*
/
// Vamos pegar os pedidos que possuem no mnimo 4 itens e que contm Ye Olde
$conditions = $this->postConditions(
$this->request->data,
array(
num_items => >=,
referrer => LIKE
)
);
$orders = $this->Order->find(all, compact(conditions));
O terceiro parmetro permite voc dizer ao CakePHP qual operador SQL booleano usar entre as
condies de busca. Strings como AND, OR e XOR so todos valores vlidos.
Finalmente, se o ltimo parmetro for passado como true, e a varivel $op for um array, os campos
no inclusos em $op no sero retornados entre as condies.
Controller::paginate()
Este mtodo usado para fazer a paginao dos resultados retornados por seus models. Voc pode
especicar o tamanho da pgina (quantos resultados sero retornados), as condies de busca e outros
parmetros. Veja a seo pagination para mais detalhes sobre como usar o mtodo paginate()
Controller::requestAction(string $url, array $options)
Este mtodo chama uma ao de um controller de qualquer lugar e retorna os dados da ao requi-
sitada. A $url passada uma URL relativa do Cake (/controller_name/action_name/params). Para
48 Captulo 4. Controllers
CakePHP Cookbook Documentation, Release 2.x
passar dados extras para serem recebidos pela ao do controller, adicione-os no parmetro options
em um formato de array.
Note: Voc pode usar o requestAction() para recuperar uma view totalmente renderizada
passando return no array de opes: requestAction($url, array(return));.
importante notar que fazendo uma requisio usando return em um controller podem fazer com que
tags javascripts e css no funcionem corretamente.
Warning: Se o mtodo requestAction() for usado sem fazer cache apropriado do resultado
obtido, a performance da ao pode ser bem ruim. raro o uso apropriado deste mtodo em um
controller ou model.
O uso do requestAction melhor usado em conjunto com elementos (cacheados) como uma
maneira de recuperar dados para um elemento antes de renderiz-los. Vamos usar o exemplo de por
o elemento ltimos comentrios no layout. Primeiro ns precisamos criar um mtodo no controller
que ir retornar os dados:
// Controller/CommentsController.php
class CommentsController extends AppController {
function latest() {
return $this->Comment->find(all, array(order => Comment.created DESC, limit => 10));
}
}
Se agora ns criarmos um elemento simples para chamar este mtodo:
// View/Elements/latest_comments.ctp
$comments = $this->requestAction(/comments/latest);
foreach ($comments as $comment) {
echo $comment[Comment][title];
}
Ns podemos por este elemento em qualquer lugar para ter a sada usando:
echo $this->element(latest_comments);
Fazendo desta maneira, sempre que o elemento for renderizado, uma requisio ser feita para nosso
controller para pegar os dados, process-los e retorn-los. Porm, de acordo com o aviso acima,
melhor fazer uso de caching do elemento para evitar um processamento desnecessrio. Modicando
a chamada do elemento para se parecer com isto:
echo $this->element(latest_comments, array(cache => +1 hour));
A chamada para o requestAction no ser feita enquanto o arquivo de cache do elemento existir
e for vlido.
Alm disso, o requestAction pode receber uma URL no formato de array do Cake:
echo $this->requestAction(
array(controller => articles, action => featured),
Mtodos dos Controllers 49
CakePHP Cookbook Documentation, Release 2.x
array(return)
);
Isto permite o requestAction contornar o uso do mtodo Router::url() para descobrir o
controller e a ao, aumentando a performance. As URLs baseadas em arrays so as mesmas usadas
pelo mtodo HtmlHelper::link() com uma diferena, se voc est usando parmetros nomea-
dos ou passados, voc deve coloc-los em um segundo array envolvendo elas com a chave correta.
Isto deve ser feito porque o requestAction mescla o array de parmetros nomeados (no segundo
parmetro do requestAction) com o array Controller::params e no coloca explicitamente o
array de parmetros nomeados na chave named. Alm disso, membros do array $options sero
disponibilizados no array Controller::params da ao que for chamada.:
echo $this->requestAction(/articles/featured/limit:3);
echo $this->requestAction(/articles/view/5);
Um array no requestAction poderia ser:
echo $this->requestAction(
array(controller => articles, action => featured),
array(named => array(limit => 3))
);
echo $this->requestAction(
array(controller => articles, action => view),
array(pass => array(5))
);
Note: Diferente de outros lugares onde URLs no formato de arrays so anlogas as URLs no formato
de string, o requestAction tratam elas diferentemente.
Quando for usar URLs no formato de arrays em conjunto com o requestAction() voc deve es-
pecicar todos os parmetros que voc vai precisar na requisio da ao. Isto inclui parmetros como
$this->request->data. Alm disso, todos os parmetros requeridos, parmetros nomeados e
passados devem ser feitos no segundo array como visto acima.
Controller::loadModel(string $modelClass, mixed $id)
O mtodo loadModel vem a calhar quando voc precisa usar um model que no padro do con-
troller ou o seu model no est associado com este.
$this->loadModel(Article);
$recentArticles = $this->Article->find(all, array(limit => 5, order => Article.created DESC));
$this->loadModel(User, 2);
$user = $this->User->read();
Atributos do Controller
Para uma completa lista dos atributos dos controllers e suas descries, visite a API do CakePHP. Siga para
http://api20.cakephp.org/class/controller.
50 Captulo 4. Controllers
CakePHP Cookbook Documentation, Release 2.x
property Controller::$name
O atributo $name deve ser denido com o nome do controller. Normalmente apenas a forma plural
do nome do model principal que o controller usa. Esta propriedade no requerida mas salva o
CakePHP de ter que exionar o nome do model para chegar no valor correto:
# Exemplo de uso do atributo $name do controller
class RecipesController extends AppController {
public $name = Recipes;
}
$components, $helpers e $uses
Os seguintes atributos do controller usados com mais frequncia dizem ao CakePHP quais helpers, com-
ponentes e models voc ir usar em conjunto com o controller corrente. Usar estes atributos faz com que
as classes MVC dadas por $components e $uses sejam disponibilizadas como atributos no controller
(por exemplo, $this->ModelName) e os dados por $helpers disponibilizados como referncias para
objetos apropriados ($this->{$helpername}) na view.
Note: Cada controller possui algumas destas classes disponibilizadas por padro, ento voc pode nem ao
menos precisar de congurar estes atributos.
property Controller::$uses
Os controllers possuem acesso ao seu model principal por padro. Nosso controller Recipes ter a
classe model Recipe disposta em $this->Recipe e nosso controller Products tambm apresenta
o model Product em $this->Product. Porm, quando for permitir um controller acessar models
adicionais pela congurao do atributo $uses, o nome do model do controller atual deve tambm
estar incluso. Este caso ilustrado no exemplo logo abaixo.
Se voc no quiser usar um model em seu controller, dena o atributo como um array vazio (public
$uses = array()). Isto lhe permitir usar um controller sem a necessidade de um arquivo model
correspondente.
property Controller::$helpers
Os helpers Html, Form e Session so disponibilizados por padro como feito o
SessionComponent. Mas se voc escolher denir seu prprio array de $helpers no
AppController, tenha certeza de incluir o Html e o Form se quiser que eles continuem a es-
tar disponveis nos seus controllers. Voc tambm pode passar conguraes na declarao de seus
helpers. Para aprender mais sobre estas classes, visite suas respectivas sees mais tarde neste manual.
Vamos ver como dizer para um controller do Cake que voc planeja usar classes MVC adicionais:
class RecipesController extends AppController {
public $uses = array(Recipe, User);
public $helpers = array(Js);
public $components = array(RequestHandler);
}
Cada uma destas variveis so mescladas com seus valores herdados, portanto, no necessrio (por
exemplo) redeclarar o FormHelper ou qualquer uma das classes que j foram declaradas no seu
Atributos do Controller 51
CakePHP Cookbook Documentation, Release 2.x
AppController.
property Controller::$components
O array de componentes permite que voc diga ao CakePHP quais Componentes um controller
ir usar. Como o $helpers e o $uses, $components so mesclados com os denidos no
AppController. E assim como nos $helpers, voc pode passar conguraes para os com-
ponentes. Veja Congurando Componentes para mais informaes.
Outros Atributos
Enquanto voc pode conferir todos os detalhes de todos os atributos dos controllers na API, existem outros
atributos dos controllers que merecem suas prprias sees neste manual.
property Controller::$cacheAction
O atributo $cacheAction usado para denir a durao e outras informaes sobre o cache com-
pleto de pginas. Voc pode ler mais sobre o caching completo de pginas na documentao do
CacheHelper.
property Controller::$paginate
O atributo $paginate uma propriedade de compatibilidade obsoleta. Usando este atributo, o
componente PaginatorComponent ser carregado e congurado, no entanto, recomendado at-
ualizar seu cdigo para usar as conguraes normais de componentes:
class ArticlesController extends AppController {
public $components = array(
Paginator => array(
Article => array(
conditions => array(published => 1)
)
)
);
}
Mais sobre Controllers
Objetos de Requisio e Resposta
Os objetos Request e Response so novos no CakePHP 2.0. Anteriormente, estes objetos eram representados
por arrays e os mtodos relacionados espalhados nas classes RequestHandlerComponent, Router,
Dispatcher e Controller. No havia nenhum objeto com autoridades sobre as informaes contidas
em uma requisio. No CakePHP 2.0, as classes CakeRequest e CakeResponse so usadas para este
propsito.
CakeRequest
A classe CakeRequest o objeto padro para requisies usadas no CakePHP. Ela centraliza inmeras
funcionalidades para interagir com os dados das requisies.
52 Captulo 4. Controllers
CakePHP Cookbook Documentation, Release 2.x
A cada requisio feita, um CakeRequest criado e passado por referncia para as vrias camadas
de uma aplicao que usam os dados de uma requisio. Por padro, CakeRequest atribudo em
$this->request e disponibilizado nos controller, views e helpers. Voc pode tambm acess-la em
componentes usando a referncia do controller. Algumas das tarefas que o CakeRequest executa inclui:
Processar os arrays GET, POST e FILES na estrutura de dados que voc est familiarizado.
Fornecer a introspeco do ambiente pertencente a requisio. Coisas como cabealhos enviados,
endereo IP dos clientes e informaes de domnio/subdomnio sobre o servidor que a aplicao est
rodando.
Prover acesso aos parmetros da requisio pelo uso de arrays ou propriedades do objeto.
Acessando parmetros de uma Requisio
O CakeRequest expe vrias maneiras de acessar os parmetros de uma requisio. A primeira o acesso
por ndices de array, a segunda maneira pelo $this->request->params e a terceira por propriedades
do objeto:
$this->request[controller];
$this->request->controller;
$this->request->params[controller]
Todas as alternativas acima iro acessar o mesmo valor. Foram criadas vrias maneiras de acessar os
parmetros para facilitar a migrao de aplicaes existentes que utilizam verses antigas do Cake. To-
dos os route-elements podem ser acessados por esta interface.
alm dos route-elements, muitas vezes voc precisar ter acesso aos passed-arguments e os named-
parameters. Ambos estaro disponveis no objeto da classe CakeRequest:
// Argumentos passados
$this->request[pass];
$this->request->pass;
$this->request->params[pass];
// Parmetros nomeados
$this->request[named];
$this->request->named;
$this->request->params[named];
Todos iro lhe proporcionar o acesso aos argumentos passados e os parmetros nomeados. Existem diversos
parmetros que so importantes/teis que o CakePHP utiliza internamente e podem tambm ser encontrados
nos parmetros da requisio:
plugin O nome do plugin que trata a requisio. ser null quando no for nenhum plugin.
controller O nome do controller que trata a requisio corrente.
action A ao responsvel por manipular a requisio corrente.
prefix O prexo da ao corrente. Veja prex-routing para mais informaes.
bare Presente quando uma requisio chega por meio do mtodo requestAction() e inclui a
opo bare. Requisies despidas (bare) no possuem layouts.
Mais sobre Controllers 53
CakePHP Cookbook Documentation, Release 2.x
requested Presente e denida como true quando vindas de um uma chamada do mtodo
requestAction().
Acessando parmetros do tipo querystring
Parmetros do tipo query string presentes tipicamente em requisies do tipo GET podem ser lidos usando
CakeRequest::$query:
// Sendo a url /posts/index?page=1&sort=title
$this->request->query[page];
// Voc tambm pode acessar o valor via array
$this->request[url][page];
Acessando dados em requisies do tipo POST
Todos os dados encontrados em requisies do tipo POST podem ser acessados usando o atributo
CakeRequest::$data. Qualquer dado passado por formulrios que contenha o prexo data ter este
prexo removido. Por exemplo:
// Uma tag input com o atributo "name" igual a data[Post][title]
acessavel em:
$this->request->data[Post][title];
voc pode acessar a propriedade data como tambm pode usar o mtodo CakeRequest::data() para
ler os dados do array de forma a evitar erros. Qualquer chave que no exista ir retornar o valor null.
Desta maneira no preciso vericar se a chave existe antes de us-la:
$foo = $this->request->data(Valor.que.nao.existe);
// $foo == null
Acessando dados XML ou JSON
Aplicaes que empregam mtodos /development/rest muitas vezes transferem dados em formatos
no codicados no padro URL. Voc pode ler estas entradas de dados com qualquer formato usando o
mtodo CakeRequest::input(). Fornecendo uma funo de decodicao, voc pode receber o con-
tedo em um formato desserializado:
// Obtm dados codificados no formato JSON submetidos por um mtodo PUT/POST
$data = $this->request->input(json_decode);
Como alguns mtodos de desserializao requeremparmetros adicionais ao seremchamados, como a opo
as array da funo json_decode ou se voc quiser um XML convertido em um objeto DOMDocument,
o mtodo CakeRequest::input() tambm suporta a passagem de parmetros adicionais:
// Obtm dados codificados em XML submetidos por um mtodo PUT/POST
$data = $this->request->input(Xml::build, array(return => domdocument));
54 Captulo 4. Controllers
CakePHP Cookbook Documentation, Release 2.x
Acessando informaes sobre o caminho das URLs
O CakeRequest tambm fornece informaes teis sobre o caminho de sua aplicao. O
CakeRequest::$base e o CakeRequest::$webroot so teis para gerar urls e determinar se sua
aplicao est ou no em um subdiretrio.
Inspecionando a Requisio
Anteriormente, era preciso utilizar o RequestHandlerComponent para detectar vrios aspectos de
uma requisio. Estes mtodos foram transferidos para o CakeRequest e esta classe oferece uma nova
interface enquanto mantem certa compatibilidade com as verses anteriores do Cake:
$this->request->is(post);
$this->request->isPost();
Ambas os mtodos chamados iro retornar o mesmo valor. Por enquanto os mtodos ainda
so disponibilizados no RequestHandler mas so depreciados e ainda podem ser removidos futura-
mente. Voc tambm pode facilmente estender os detectores que esto disponveis usando o mtodo
CakeRequest::addDetector() para criar novos tipos de detectores. Existem quatro formas difer-
entes de detectores que voc pode criar:
Comparao de valores de ambiente - Uma comparao feita em valores do ambiente compara valores
encontrados pela funo env() no ambiente da aplicao, com o valor fornecido.
Comparao por expresso regular - Permite comparar valores encontrados pela funo env() com
uma expresso regular fornecida.
Comparao baseada em opes - Usa uma lista de opes para criar expresses regulares. Chamadas
subsequentes para adicionar opes j fornecidas ao detector sero mescladas.
Detectores do tipo Callback - Permitem fornecer um callback para tratar a vericao. O callback
ir receber o objeto de requisio como parmetro nico.
Alguns exemplos de uso:
// Adiciona um detector baseado em variveis do ambiente
$this->request->addDetector(post, array(env => REQUEST_METHOD, value => POST));
// Adicionar um detector usando expresses regulares
$this->request->addDetector(iphone, array(env => HTTP_USER_AGENT, pattern => /iPhone/i));
// Adicionar um detector baseado em uma lista de opes
$this->request->addDetector(internalIp, array(
env => CLIENT_IP,
options => array(192.168.0.101, 192.168.0.100)
));
// Adiciona um detector callback. Pode ser tanto uma funo annima
// quanto o nome de uma funo a ser chamada.
$this->request->addDetector(awesome , function ($request) {
return isset($request->awesome);
});
Mais sobre Controllers 55
CakePHP Cookbook Documentation, Release 2.x
O CakeRequest tambm inclui mtodos como CakeRequest::domain(),
CakeRequest::subdomains() e CakeRequest::host() para ajudar em aplicaes que
utilizam subdomnios, tornando a vida um pouco mais fcil.
Existem vrios detectores inclusos no Cake que voc j pode usar:
is(get) Verica se a requisio corrente do tipo GET.
is(put) Verica se a requisio corrente do tipo PUT.
is(post) Verica se a requisio corrente do tipo POST.
is(delete) Verica se a requisio corrente do tipo DELETE.
is(head) Verica se a requisio corrente do tipo HEAD.
is(options) Verica se a requisio corrente do tipo OPTIONS.
is(ajax) Verica se a requisio corrente acompanha o cabealho X-Requested-With = XML-
HttpRequest.
is(ssl) Verica se a requisio corrente via SSL.
is(flash) Verica se a requisio foi feita por um objeto do Flash.
is(mobile) Verica se a requisio veio de uma lista comum de dispositivos mveis.
CakeRequest e o RequestHandlerComponent
Como muitas das caracteristicas que o CakeRequest oferece eram de domnio do componente
RequestHandlerComponent, foi preciso repensar como esta se encaixa no quadro atual. Para o
CakePHP 2.0, a classe RequestHandlerComponent age como uma cereja em cima do bolo. Provendo
uma camada adicional de funcionalidades sobre o CakeRequest, como a mudana do layout baseado
no tipo de contedo ou chamadas em ajax. A separao destas duas classes permitem voc escolher mais
facilmente o que voc quer e precisa.
Interagindo com outros aspectos da requisio
Voc pode usar o CakeRequest para introspectar uma variedade de coisas sobre a requisio. Alm dos
detectores, voc tambm pode encontrar outras informaes vindas de vrias propriedades e mtodos.
$this->request->webroot contm o diretrio webroot (a raiz do diretrio web).
$this->request->base contm o caminho base.
$this->request->here contm a uri solicitada da requisio corrente.
$this->request->query contm os parmetros enviados por query strings.
API do CakeRequest
class CakeRequest
A classe CakeRequest encapsula o tratamento e introspeco dos parmetros das requisies.
56 Captulo 4. Controllers
CakePHP Cookbook Documentation, Release 2.x
CakeRequest::domain()
Retorna o nome do domnio onde sua aplicao esta sendo executada.
CakeRequest::subdomains()
Retorna os subdomnios de onde sua aplicao est sendo executada em um formato de array.
CakeRequest::host()
Retorna o host em que sua aplicao esta sendo executada.
CakeRequest::method()
Retorna o mtodo HTTP em que a requisio foi feita.
CakeRequest::referer()
Retorna o endereo que referenciou a requisio.
CakeRequest::clientIp()
Retorna o endereo IP do visitante corrente.
CakeRequest::header()
Permite voc acessar qualquer cabealho HTTP_
*
que tenha sido usado na requisio:
$this->request->header(User-Agent);
Retornaria o user agent utilizado para a solicitao.
CakeRequest::input($callback[, $options ])
Resgata os dados de entrada de uma requisio. Opcionalmente o resultado passado por uma funo
de decodicao dos dados. Parmetros adicionais para a funo de decodicao podem ser passadas
como argumentos para input().
CakeRequest::data($key)
Fornece acesso aos dados da requisio numa notao pontuada, permitindo a leitura e modicao
dos dados da requisio. Chamadas tambm podem ser encadeadas:
// Modifica alguns dados da requisio, assim voc pode popular
// previamente alguns campos dos formulrios.
$this->request->data(Post.title, New post)
->data(Comment.1.author, Mark);
// Voc tambm pode ler os dados.
$value = $this->request->data(Post.title);
CakeRequest::is($check)
Verica se uma requisio corresponde a um certo critrio. Utiliza os detectores inclusos por padro
alm das regras adicionadas com o mtodo CakeRequest::addDetector().
CakeRequest::addDetector($name, $callback)
Adiciona um detector para ser usado com o mtodo is(). Veja Inspecionando a Requisio para
mais informaes.
CakeRequest::accepts($type)
Descobre quais os tipos de contedo que o cliente aceita ou verica se ele aceita um determinado tipo
de contedo.
Obtm todos os tipos:
Mais sobre Controllers 57
CakePHP Cookbook Documentation, Release 2.x
<?php
$this->request->accepts();
Verica apenas um tipo:
$this->request->accepts(application/json);
static CakeRequest::acceptLanguage($language)
Obter todas os idiomas aceitos pelo cliente ou verica se um determinado idioma aceito.
Obtm uma lista dos idiomas aceitos:
CakeRequest::acceptLanguage();
Verica se um idioma especco aceito:
CakeRequest::acceptLanguage(es-es);
property CakeRequest::$data
Um array de dados enviados pelo mtodo POST. Voc pode usar o mtodo
CakeRequest::data() para ler o contedo desta propriedade de uma forma a suprimir
avisos quando a chave informada no existir.
property CakeRequest::$query
Um array de parmetros passados por query strings.
property CakeRequest::$params
Um array contendo os elementos da rota e os parmetros da requisio.
property CakeRequest::$here
Contm a uri solicitada no momento da requisio.
property CakeRequest::$base
O caminho de base para a aplicao, geralmente equivale a /, ao menos que sua aplicao esteja em
um subdiretrio.
property CakeRequest::$webroot
O diretrio web de sua aplicao.
CakeResponse
O CakeResponse a classe padro para respostas no CakePHP. Ela encapsula inmeras caracters-
ticas e funcionalidades para gerar respostas HTTP em sua aplicao. Ela tambm auxilia nos testes
da aplicao e pode ser forjada, permitindo inspecionar os cabealhos que sero enviados. Como
na classe CakeRequest, o CakeResponse consolida vrios mtodos encontrados previamente no
Controller, RequestHandlerComponent e Dispatcher. Os mtodos antigos foram depreci-
ados, favorecendo o uso do CakeResponse.
CakeResponse fornece uma interface para envolver as tarefas comuns relacionadas ao envio de respostas
para o cliente como:
Enviar cabealhos de redirecionamento.
58 Captulo 4. Controllers
CakePHP Cookbook Documentation, Release 2.x
Enviar cabealhos com o tipo de contedo.
Enviar qualquer outro cabealho.
Enviar o corpo da resposta.
Alterando a classe de Resposta
O CakePHP utiliza o CakeResponse por padro. O CakeResponse uma classe de uso exvel e
transparente, mas se voc precisar alter-la por uma classe especca da aplicao, voc poder sobrescrev-
la e e substitu-la por sua prpria classe, alterando o CakeResponse usado no arquivo index.php.
Isto far com que todos os controllers da sua aplicao use CustomResponse ao invs de
CakeResponse. Voc pode tambm substituir a instancia utilizada, denindo o novo objeto em
$this->response nos seus controllers. sobrescrever o objeto de resposta til durante os testes, per-
mitindo voc simular os mtodos que interagem com o header(). Veja a seo CakeResponse e Testes
para mais informaes.
Lidando com tipos de contedo
Voc pode controlar o Content-Type da resposta de sua aplicao usando o mtodo
CakeResponse::type(). Se sua aplicao precisa lidar com tipos de contedos que no esto
inclusos no CakeResponse, voc tambm poder mapear estes tipos utilizando o mtodo type():
// Adiciona o tipo vCard
$this->response->type(array(vcf => text/v-card));
// Define o Content-Type para vcard.
$this->response->type(vcf);
Normalmente voc vai querer mapear os tipos de contedo adicionais no callback beforeFilter do
seu controller, assim, se voc estiver usando o RequestHandlerComponent, poder tirar proveito da
funcionalidade de troca de views baseado no tipo do contedo.
Enviando Anexos
Poder existir momentos em que voc queira enviar respostas dos controllers como sendo arquivos para
downloads. Voc pode conseguir este resultado usando /views/media-view ou usando as funcional-
idades do CakeResponse. O mtodo CakeResponse::download() permite voc enviar respostas
como arquivos para download:
function sendFile($id) {
$this->autoRender = false;
$file = $this->Attachment->getFile($id);
$this->response->type($file[type]);
$this->response->download($file[name]);
$this->response->body($file[content]);
$this->response->send();
}
Mais sobre Controllers 59
CakePHP Cookbook Documentation, Release 2.x
O exemplo acima demonstra como voc pode utilizar o CakeResponse para gerar um arquivo para down-
load sem precisar usar a classe MediaView. Em geral, voc vai preferir utilizar a classe MediaView por
possuir maiores funcionalidades que o CakeResponse.
Interagindo com o cache do navegador
Algumas vezes voc precisar forar o browser do cliente a no fazer cache dos resultados de uma ao de
um controller. CakeResponse::disableCache() destinado para estes casos.:
function index() {
// faz alguma coisa.
$this->response->disableCache();
}
Warning: Usar o disableCache() para downloads em domnios SSL enquanto tenta enviar ar-
quivos para o Internet Explorer poder resultar em erros.
Voc tambm poder dizer ao cliente para fazer cache da resposta. Usando CakeResponse::cache():
function index() {
// faz alguma coisa.
$this->response->cache(time(), +5 days);
}
O cdigo acima diz aos clientes para armazenar em cache a resposta resultante por cinco dias, podendo
acelerar a experincia dos seus visitantes.
Denindo Cabealhos
possvel denir cabealhos para a resposta utilizando o mtodo CakeResponse::header(). Po-
dendo ser chamada de algumas formas diferentes:
// Define um nico cabealho
$this->response->header(Location, http://example.com);
// Define mltiplos cabealhos
$this->response->header(array(Location => http://example.com, X-Extra => My header));
$this->response->header(array(WWW-Authenticate: Negotiate, Content-type: application/pdf));
Denir o mesmo cabealho mltiplas vezes ir causar a sobrescrita do valor anterior, como numa
chamada comum ao mtodo header() do PHP. Os cabealhos no sero enviados quando o mtodo
CakeResponse::header() for chamado. Os cabealhos so armazenados em buffer at que a resposta
seja efetivamente enviada.
CakeResponse e Testes
Provavelmente uma das grandes vitrias da classe CakeResponse vem de como ela torna mais fcil os
testes de controllers e componentes. Ao invs de mtodos espalhados em diversos objetos, voc precisa de
60 Captulo 4. Controllers
CakePHP Cookbook Documentation, Release 2.x
apenas um simples objeto para forjar e utilizar nos controllers e componentes. Isto lhe ajuda a criar seus
testes unitrios mais rapidamente:
function testSomething() {
$this->controller->response = $this->getMock(CakeResponse);
$this->controller->response->expects($this->once())->method(header);
...
}
Adicionalmente, voc consegue testar sua aplicao pela linha de comando mais facilmente pois consegue
forjar os cabealhos que quiser sem precisar car tentando denir os cabealhos diretos na interface de
linha de comandos.
API do CakeResponse
class CakeResponse
A classe CakeResponse fornece vrios mtodos teis para interagir com as respostas que voc
envia para um cliente.
CakeResponse::header()
Permite voc denir diretamente um ou muitos cabealhos para serem enviados com a resposta.
CakeResponse::charset()
Dene o mapa de caracteres (charset) que ser usado na resposta.
CakeResponse::type($type)
Dene o tipo de contedo para a resposta. Voc pode usar um apelido de um tipo conhecido de
contedo ou usar um nome completo para o tipo do contedo.
CakeResponse::cache()
Permite voc denir os cabealhos de cache em sua resposta.
CakeResponse::disableCache()
Dene os cabealhos apropriados para desabilitar o cache da resposta pelo cliente.
CakeResponse::compress()
Habilita a compresso gzip para o envio da resposta.
CakeResponse::download()
Permite voc enviar a resposta como um anexo e denir o nome do arquivo.
CakeResponse::statusCode()
Permite voc alterar o cdigo do status da resposta.
CakeResponse::body()
Dene o contedo do corpo da resposta que ser enviada.
CakeResponse::send()
Aps ter criado a resposta, chamar o mtodo send() ir enviar os todos cabealhos denidos
assim como o corpo da resposta. Isto feito automaticamente no nal de cada requisio pelo
Dispatcher.
Mais sobre Controllers 61
CakePHP Cookbook Documentation, Release 2.x
Scaffolding (arcabouos)
O recurso de scaffold de aplicaes uma tcnica que permite ao desenvolvedor denir e criar uma aplicao
bsica que possa inserir, selecionar, atualizar e excluir objetos. scaffold no CakePHP tambm possibilita que
os desenvolvedores denam como os objetos esto relacionados entre si alm de como criar e destruir estas
relaes.
Tudo o que necessrio para criar um scaffold um model e seu controller correspondente. Uma vez que
voc tiver denido o atributo $scaffold em seu controller, este estar pronto para funcionar. O scaffold
do CakePHP muito legal. Ele permite que voc tenha uma aplicao CRUD com tudo funcionando em
minutos. to legal que voc pode querer at us-lo em produo. Podemos at achar isto legal tambm,
mas por favor tenha em mente que scaffold ... ahn... apenas um arcabouo. O uso de scaffold poupa o
trabalho da criao da estrutura real para acelerar o incio de um projeto em etapas iniciais. Scaffold no tem
inteno de ser completamente exvel, mas sim um jeito temporrio de fazer as coisas funcionarem com
brevidade. Se voc se vir numa situao de querer personalizar a lgica e suas views, hora de deixar de
usar o recurso de scaffold e escrever o cdigo de fato. A ferramenta de linha de comando Bake do CakePHP,
abordado na prxima seo um grande passo frente: Ele gera todo o cdigo que voc deve precisar para
produzir o mesmo resultado que teria atualmente com o scaffold.
Scaffold uma excelente maneira de iniciar o desenvolvimento de partes prematuras da sua aplicao web.
Primeiras verses de esquemas de bases de dados tendem a sofrer mudanas, o que algo perfeitamente nor-
mal nas etapas iniciais do projeto da aplicao. Isto tem um lado negativo: Um desenvolvedor web detesta
criar formulrios que nunca viro a ser efetivamente usados. Para minimizar o esforo do desenvolvedor, o
recurso de scaffold foi includo no CakePHP. O scaffold analisa as tabelas de sua base de dados e cria uma
listagem padronizada com botes de insero, edio e excluso, formulrios padronizados para edio e
views padronizadas para visualizao de um nico registro da base de dados.
Para adicionar o recurso de scaffold sua aplicao, no controller, adicione o atributo $scaffold:
class CategoriesController extends AppController {
public $scaffold;
}
Assumindo que voc tenha criado um arquivo com a classe model mais bsica para o Category (em
/app/Model/Category.php), as coisas j estaro prontas. Acesse http://example.com/categories para
ver sua nova aplicao com scaffold.
Note: Criar mtodos em controllers que possuam denies de scaffold pode causar resultados indesejados.
Por exemplo, se voc criar um mtodo index() em um controller com scaffold, seu mtodo index ser
renderizado no lugar da funcionalidade do scaffold.
O scaffold tem conhecimento sobre as associaes de models, ento se seu model Category possuir uma
referncia a (belongsTo) User, voc ver os IDs dos usurios relacionados na listagem de Category.
Enquanto o scaffold sabe como tratar os relacionamentos entre models, voc no ver nenhum registro
relacionado nas views do scaffold at que voc tenha adicionado manualmente as relaes entre os models.
Por exemplo, se Group hasMany (possui muitos) User e User belongsTo (pertence ) Group, voc
precisa adicionar manualmente o cdigo necessrio a seguir nos seus models User e Group. Antes de
voc adicionar o cdigo a seguir, a view mostrar uma tag select vazia para Group no formulrio de adio
do model User. Aps voc adicionar o cdigo, a view ir mostrar uma tag select populada com os IDs ou
nomes vindos da tabela groups no formulrio de adio de User.
62 Captulo 4. Controllers
CakePHP Cookbook Documentation, Release 2.x
// Em Group.php
public $hasMany = User;
// Em User.php
public $belongsTo = Group;
Se voc preferir ver algo alm do ID (como o primeiro nome dos usurios), voc pode alterar o valor do
atributo $displayField no model. Vamos ver o $displayField na nossa classe User de forma que
os usurios relacionados com categorias sejam mostrados pelo primeiro nome ao invs de apenas o ID. Em
muitos casos, este recurso torna o scaffold mais legvel.
class User extends AppModel {
public $name = User;
public $displayField = first_name;
}
Criando uma interface administrativa simples com scaffolding
Se voc tiver habilitado as rotas de admin em seu arquivo de congurao app/Config/core.php com
a alterao a seguir Configure::write(Routing.prefixes, array(admin));, voc
poder usar o scaffold para gerar interfaces administrativas.
Uma vez que voc tenha ativado a rota de admin atribua seu prexo admin varivel scaffolding:
public $scaffold = admin;
Agora voc poder acessar o arcabouo de suas aes administrativas:
http://example.com/admin/controller/index
http://example.com/admin/controller/view
http://example.com/admin/controller/edit
http://example.com/admin/controller/add
http://example.com/admin/controller/delete
Esta uma forma fcil de criar uma interface de administrao simples rapidamente. Tenha em mente que
voc no pode ter ambos os mtodos de scaffold, um para admin e outro para no-admin ao mesmo tempo.
Assim como em um scaffold normal voc pode sobrescrever um mtodo individual com seu prprio cdigo:
function admin_view($id = null) {
// cdigo customizado aqui
}
Uma vez que voc tenha substitudo uma ao de scaffold voc tambm precisar criar um arquivo de view
para a ao.
Customizando as Views de Scaffold
Se voc quiser uma view de scaffold um pouco diferente, voc pode criar templates. Continuamos a no
recomendar o uso desta tcnica para aplicaes em produo, mas tal customizao pode ser til durante o
perodo de prototipao.
Mais sobre Controllers 63
CakePHP Cookbook Documentation, Release 2.x
A customizao feita criando templates de view:
Views de scaffold customizadas para um controller especco (PostsController neste example) devem ser
colocadas no diretrio das views desta maneira:
/app/View/Posts/scaffold.index.ctp
/app/View/Posts/scaffold.show.ctp
/app/View/Posts/scaffold.edit.ctp
/app/View/Posts/scaffold.new.ctp
Views de scaffold customizadas para todos os controllers devem ser criadas desta maneira:
/app/View/Scaffolds/index.ctp
/app/View/Scaffolds/form.ctp
/app/View/Scaffolds/view.ctp
O Controller Pages
O CakePHP j vem com um controller padro chamado PagesController
(lib/Cake/Controller/PagesController.php). A pgina inicial que voc v logo aps
a instalao gerada usando este controller. Este controller geralmente usado para servir pginas
estticas. Ex. Se voc fez uma view app/View/Pages/sobre_nos.ctp, voc pode acess-la usando
a seguinte URL http://example.com/pages/sobre_nos
Quando voc constri uma aplicao utilizando o console bake o controller Pages copiado para seu
diretrio app/Controller/ e voc pode modic-lo se for preciso. Ou voc pode fazer uma cpia do arquivo
PagesController.php da pasta lib/Cake para seu diretrio app/Controller/ existente.
Warning: No modique nenhum arquivo dentro do diretrio Cake diretamente para evitar problemas
futuros quando for atualizar o ncleo do framework CakePHP.
Componentes
Componentes (components) so pacotes com funes lgicas que so usadas para serem compartilhadas
entre os controllers. Se voc est querendo copiar e colar coisas entre seus controllers, talvez seja uma boa
ideia considerar a possibilidade de empacotar estas funcionalidades em componentes.
O CakePHP tambm j vem com uma quantidade fantstica de componentes includos, que voc pode usar
para lhe ajudar com:
Segurana
Sesses
Lista de Controle de Acesso (do ingls ACL, Access control lists)
Emails
Cookies
Autenticao
64 Captulo 4. Controllers
CakePHP Cookbook Documentation, Release 2.x
Tratamento de Requisies
Cada um destes componentes do Cake so detalhados em seus prprios captulos. Neste momento, ns
lhe mostraremos como criar e usar seus prprios componentes. Criar componentes mantem o cdigo dos
controllers limpos e permitem a reutilizao de cdigos entre projetos.
Congurando Componentes
Muitos dos componentes includos no Cake requerem alguma congurao. Exemplos de com-
ponentes que requerem congurao so: /core-libraries/components/authentication,
/core-libraries/components/cookie e /core-libraries/components/email. As
conguraes para estes componentes, e outros em geral, so feitas no array $components ou no mtodo
beforeFilter() do seu controller:
class PostsController extends AppController {
public $components = array(
Auth => array(
authorize => array(controller),
loginAction => array(controller => users, action => login)
),
Cookie => array(name => CookieMonster)
);
O exemplo acima seria um exemplo de como congurar um componente usando o array $components.
Todos os componentes includos no Cake permitem ser congurados desta forma. Alm disso, voc pode
congurar componentes no mtodo beforeFilter() de seus controllers. Isto til quando voc precisa
atribuir os resultados de uma funo para uma propriedade do componente. O exemplo acima tambm pode
ser expressado da seguinte maneira:
public function beforeFilter() {
$this->Auth->authorize = array(controller);
$this->Auth->loginAction = array(controller => users, action => login);
$this->Cookie->name = CookieMonster;
}
possvel, no entanto, que um componente requeira que certa congurao seja feita antes do mtodo
beforeFilter() do controller ser executado. Para este m, alguns componentes permitem que cong-
uraes sejam feitas no array $components:
public $components = array(DebugKit.Toolbar => array(panels => array(history, session)));
Consulte a documentao relevante para determinar quais opes de congurao cada componente oferece.
Usando Componentes
Aps ter includo alguns componentes em seu controller, us-los muito simples. Cada componente que
voc usa exposto como uma propriedade em seu controller. Se voc carregou o SessionComponent e
o CookieComponent no seu controller, voc pode acess-los da seguinte maneira:
Mais sobre Controllers 65
CakePHP Cookbook Documentation, Release 2.x
class PostsController extends AppController {
public $components = array(Session, Cookie);
public function delete() {
if ($this->Post->delete($this->request->data(Post.id)) {
$this->Session->setFlash(Post deleted.);
$this->redirect(array(action => index));
}
}
Note: Como os models e componentes so adicionados no controller como propriedades eles compartilham
o mesmo espao de nomes (namespace). Tenha certeza de no ter um componente e um model com o
mesmo nome.
Carregando componentes sob demanda
Voc pode no precisar de todos os componentes disponibilizados em cada ao dos controllers. Nestas situ-
aes voc pode carregar um componente em tempo de execuo usando o Component Collection.
Dentro de um controller voc pode fazer o seguinte:
$this->OneTimer = $this->Components->load(OneTimer);
$this->OneTimer->getTime();
Callbacks de Componentes
Componentes tambm oferecem alguns callbacks do ciclo de vida de uma requisio, permitindo acrescentar
rotinas ao uxo. Veja a API dos Componentes para mais informaes sobre os callbacks que os componentes
oferecem.
Criando um Componente
Suponhamos que nossa aplicao online precisa realizar uma operao matemtica complexa em diferentes
partes da aplicao. Podemos criar um componente para abrigar esta lgica para ser usada nos diferentes
controllers.
O primeiro passo criar um novo arquivo para a classe do componente. Crie o arquivo em
/app/Controller/Component/MathComponent.php. A estrutura bsica para o componente ir
se parecer com algo assim:
class MathComponent extends Component {
function doComplexOperation($amount1, $amount2) {
return $amount1 + $amount2;
}
}
Note: Todos os componentes devem estender a classe Component. Se no zer isto, o Cake ir disparar
uma exceo.
66 Captulo 4. Controllers
CakePHP Cookbook Documentation, Release 2.x
Incluindo seus componentes nos seus controllers
Aps nosso componente estiver pronto, podemos us-lo nos controllers da nossa aplicao pondo o nome
do componente (sem o suxo Component) no array $components do controller. O controller ir re-
ceber um novo atributo com o mesmo nome do componente, o qual poderemos acess-lo como sendo uma
instncia da classe componente que queremos.
/
*
Torna o novo componente acessvel em $this->Math,
bem como o $this->Session
*
/
public $components = array(Math, Session);
Componentes declarados no AppController sero mesclados com os de outros controllers. Ento no
h necessidade de redeclarar o mesmo componente duas vezes.
Ao incluir componentes em um controller voc tambm pode declarar um conjunto de parmetros que sero
passados para o construtor do componente. Estes parmetros podem ser usados pelo componente.
public $components = array(
Math => array(
precision => 2,
randomGenerator => srand
),
Session, Auth
);
O exemplo acima ir passar no segundo parmetro do construtor MathComponent::__construct()
um array contendo o atributo precision e randomGenerator.
Por conveno, qualquer congurao que voc tenha passado e que tambm seja um atributo pblico do
seu componente, ir ter seu valor denido com base no array.
Usando outros componentes nos seus Componentes
s vezes, um de seus componentes poder precisar usar outro componente. Neste caso voc pode incluir
outros componentes no seu da mesma forma que inclui em controllers, usando o atributo $components:
// app/Controller/Component/CustomComponent.php
class CustomComponent extends Component {
// O outro componente que seu componente utiliza
public $components = array(Existing);
function initialize(Controller $controller) {
$this->Existing->foo();
}
function bar() {
// ...
}
}
Mais sobre Controllers 67
CakePHP Cookbook Documentation, Release 2.x
// app/Controller/Component/ExistingComponent.php
class ExistingComponent extends Component {
function initialize(Controller $controller) {
$this->Parent->bar();
}
function foo() {
// ...
}
}
API dos Componentes
class Component
A classe base Component oferece alguns mtodos para carregar sob demanda (Lazy loading. Pos-
sibilita adiar a inicializao de um objeto at que este seja utilizado) outros componentes utilizando
o ComponentCollection assim como lidar com as conguraes bsicas. Esta classe tambm
fornece os prottipos para todos os callbacks dos componentes.
Component::__construct(ComponentCollection $collection, $settings = array())
O contrutor da classe Component. Todos as propriedades pblicas da classe tero seus valores
alterados para corresponder com o valor de $settings.
Callbacks
Component::initialize($controller)
O mtodo initialize chamado antes do mtodo beforeFilter do controller.
Component::startup($controller)
O mtodo startup chamado aps o mtodo beforeFilter do controller mas antes que o
controller execute a ao.
Component::beforeRender($controller)
O mtodo beforeRender chamado aps o controller executar a lgica da ao requisitada mas
antes que o controller renderize a view e o layout.
Component::shutdown($controller)
O mtodo shutdown chamado antes que o contedo seja enviado para o browser.
Component::beforeRedirect($controller, $url, $status=null, $exit=true)
O mtodo beforeRedirect invocado quando o mtodo redirect de um controller chamado
mas antes de qualquer ao. Se este mtodo retornar false o controller no ir continuar com o
redirecionamento. As variveis $url, $status e $exit possuem o mesmo signicado do mtodo
do controller. Voc pode tambm retornar uma string que ser interpretada como uma URL para ser
usada no redirecionamento ou retornar um array associativo com a chave url e opcionalmente com
a chave status e a chave exit.
68 Captulo 4. Controllers
CAPTULO 5
Views
Views (ou Vises) so o V do MVC. Views so responsveis por gerar a sada de dados especca para
uma determinada requisio. Geralmente esta sada apresentada na forma de HTML, XML ou JSON. No
entanto, disponibilizar arquivos atravs de streaming (uxo de informao, geralmente multimdia, atravs
de pacotes) ou criar PDFs, que podem ser baixados, tambm so de responsabilidade da Camada View.
O CakePHP traz incluso vrias classes do tipo View para lidar com os cenrios mais comuns de renderizao:
Para criar webservices em XML ou JSON, voc pode usar o views/json-and-xml-views
Para prover arquivos protegidos ou arquivos criados dinamicamente, voc pode usar
views/media-view
Para criar mltiplos temas para as vises, voc pode usar views/themes
View Templates
Em CakePHP, voc fala com seus usurios atravs da camada view (viso). Na maior parte do tempo, suas
views exibiro documentos (X)HTML nos navegadores, mas voc pode tambm precisar prover dados AMF
para um objeto em Flash, responder a uma aplicao remota via SOAP ou gerar um arquivo CSV para um
usurio.
Por padro, no CakePHP os arquivos do tipo view so escritos em PHP comum e possuem a extenso .ctp
(CakePHP Template). Estes arquivos contm toda a lgica de apresentao necessria para transformar os
dados recebidos do controller em um formato pronto para o pblico. Caso voc prera usar uma linguagem
de template como Twig ou Smarty, uma subclasse da View ir fazer uma ponte entre sua linguagem de
template e o CakePHP.
Arquivos do tipo view so guardados em /app/View/, dentro do diretrio com o nome do controller
que usa os arquivos e nomeado de acordo com a ao correspondente. Por exemplo, a ao view() do
controller Products ser normalmente encontrada em /app/View/Products/view.ctp.
A camada view no CakePHP pode ser composta de diferentes partes. Cada parte tem diferentes usos e sero
cobertas em sees especcas:
69
CakePHP Cookbook Documentation, Release 2.x
views: views a nica parte da pgina que est em execuo. Compem a parte crucial da resposta
da aplicao.
elements: pedaos de cdigo pequenos e reutilizveis. Elements geralmente so renderizados dentro
de views.
layouts: arquivos da viewcontendo cdigo de apresentao que envolve vrias interfaces da aplicao.
A maior parte dos arquivos views renderizada dentro de um layout.
helpers: essas classes encapsulam lgica da view que seja necessria em vrios lugares na camada
view. Helpers no CakePHP podem ajud-lo a construir formulrios, construir funcionalidade AJAX,
paginar dados do model, prover feeds RSS, dentre outras coisas.
Estendendo Views
New in version 2.1.
A extenso de uma View permite que voc inclua uma view dentro de outra. Combinando isto com view
blocks voc tem uma maneira poderosa para deixar suas views DRY (enxutas). Por exemplo, sua aplicao
tem uma barra lateral (sidebar) que precisa mudar a depender de quando uma view especca renderizada.
Estendendo um mesmo arquivo de view, voc pode evitar repeties de marcaes em comum e apenas
denir as que mudam:
// app/View/Common/view.ctp
<h1><?php echo $this->fetch(title); ?></h1>
<?php echo $this->fetch(content); ?>
<div class="actions">
<h3>Related actions</h3>
<ul>
<?php echo $this->fetch(sidebar); ?>
</ul>
</div>
O arquivo de view acima pode ser usado como uma view pai. Esta espera que a view que a estende dena os
blocos sidebar e title. O bloco content um bloco especial que o CakePHP cria. Ele conter todo
o contedo no-capturado da view que a estende. Considerando que nosso arquivo view tem uma varivel
$post com informao sobre nosso post, nossa view poder parecer como:
<?php
// app/View/Posts/view.ctp
$this->extend(/Common/view);
$this->assign(title, $post)
$this->start(sidebar);
?>
<li> echo $this->Html->link(edit, array(
action => edit,
$post[Post][id]
)); ?>
</li>
70 Captulo 5. Views
CakePHP Cookbook Documentation, Release 2.x
<?php $this->end(); ?>
// O contedo restante estar disponvel como o bloco content
// na view pai.
echo h($post[Post][body]);
A view de post acima mostra como voc pode estender uma view e preenche-la com um conjunto de blocos.
Qualquer contedo que no estiver denido em um bloco ser capturado e colocado em um bloco especial
chamado content. Quando uma view contm uma chamada para extend(), a execuo continua at o
m do arquivo view atual. Uma vez nalizada, a view estendida ser renderizada. Chamar extend() mais
de uma vez em um arquivo view ir sobrescrever a view pai que ser processada em seguida:
$this->extend(/Common/view);
$this->extend(/Common/index);
O trecho acima resultar em /Common/index.ctp sendo renderizada como a view pai para a view atual.
Voc pode aninhar views estendidas quantas vezes forem necessrias. Cada view pode estender outra view
se quiser. Cada view pai pegar o contedo da view anterior como o bloco content.
Note: Voc deve evitar o uso de content como o nome de um bloco em sua aplicao. CakePHP usa
este nome em views estendidas para contedos no-capturados.
Usando Blocos de Views (Vises)
New in version 2.1.
Blocos de views substituem $scripts_for_layout e provm uma API exvel que permite criar slots
ou blocos em suas views/layouts que podem ser denidas em qualquer lugar. Por exemplo, blocos so ideais
para implementar recursos como barras laterais ou regies para carregar sees na parte de baixo ou no topo
do layout. Blocos podem ser denidos de duas formas. Seja capturando um bloco ou por atribuio direta.
Os mtodos start(), append() e end() permitem trabalhar com captura de blocos:
// cria um bloco lateral.
$this->start(sidebar);
echo $this->element(sidebar/recent_topics);
echo $this->element(sidebar/recent_comments);
$this->end();
// Concatena na barra lateral em seguida.
$this->append(sidebar);
echo $this->element(sidebar/popular_topics);
$this->end();
Tambm possvel concatenar blocos utilizando o mtodo start() mltiplas vezes. O mtodo
assign() pode ser usado para limpar ou sobrescrever o bloco:
Usando Blocos de Views (Vises) 71
CakePHP Cookbook Documentation, Release 2.x
// Limpa o contedo anterior da barra lateral.
$this->assign(sidebar, );
Note: Voc deve evitar o uso de content como o nome de um bloco em sua aplicao. CakePHP usa
este nome em views estendidas para contedos no-capturados .
Exibindo blocos
New in version 2.1.
Voc pode exibir blocos usando o mtodo fetch(). fecht() ir retornar um bloco de maneira segura,
retornando se o bloco no existir:
echo $this->fetch(sidebar);
Voc tambm pode usar o fetch para exibir condicionalmente um contedo que deve envolver um bloco que
deveria existir. Isto til em layouts ou views estendidas, nas quais voc queira mostrar cabealhos e outras
marcaes condicionalmente:
// em app/View/Layouts/default.ctp
<?php if ($this->fetch(menu)): ?>
<div class="menu">
<h3>Menu options</h3>
<?php echo $this->fetch(menu); ?>
</div>
<?php endif; ?>
Utilizando blocos para arquivos de script e CSS
New in version 2.1.
Blocos substituem a varivel obsoleta $scripts_for_layout do layout. Em vez de us-la, voc
deve usar blocos. A HtmlHelper vincula-se aos blocos da view e a cada um dos seus mtodos
php:meth:~HtmlHelper::script(), css() e meta() quando o bloco com o mesmo nome utiliza a opo
inline = false:
<?php
// no seu arquivo de view
$this->Html->script(carousel, array(inline => false));
$this->Html->css(carousel, array(inline => false));
?>
// no seu arquivo de layout
<!DOCTYPE html>
<html lang="en">
<head>
<title><?php echo $this->fetch(title); ?></title>
<?php echo $this->fetch(script); ?>
<?php echo $this->fetch(css); ?>
72 Captulo 5. Views
CakePHP Cookbook Documentation, Release 2.x
</head>
// o resto do layout continua
A HtmlHelper tambm permite voc controlar para que bloco os scripts e CSS vo:
// na sua view
$this->Html->script(carousel, array(block => scriptBottom));
// no seu layout
echo $this->fetch(scriptBottom);
Layouts
Um layout contem o cdigo de apresentao que envolve uma view. Qualquer coisa que voc queira ver em
todas as suas views deve ser colocada em um layout.
Arquivos de layouts devem ser colocados em /app/View/Layouts. O layout padro do CakePHP pode
ser sobrescrito criando um novo layout padro em /app/View/Layouts/default.ctp. Uma vez
que um novo layout padro tenha sido criado, o cdigo da view renderizado pelo controller colocado
dentro do layout padro quando a pgina renderizada.
Quando voc cria um layout, voc precisa dizer ao CakePHP onde colocar o cdigo de suas views. Para isso,
garanta que o seu layout inclui um lugar para $this->fetch(content). A seguir, um exemplo de
como um layout padro deve parecer:
<!DOCTYPE html>
<html lang="en">
<head>
<title><?php echo $title_for_layout?></title>
<link rel="shortcut icon" href="favicon.ico" type="image/x-icon">
<!-- Incluir arquivos extenos e scripts aqui (Ver o helper HTML para mais detalhes) -->
echo $this->fetch(meta);
echo $this->fetch(css);
echo $this->fetch(script);
?>
</head>
<body>
<!-- Se voc quiser exibir algum menu
em todas as suas views, inclua-o aqui -->
<div id="header">
<div id="menu">...</div>
</div>
<!-- Aqui onde eu quero que minhas views sejam exibidas -->
<?php echo $this->fetch(content); ?>
<!-- Adicionar um rodap para cada pgina exibida -->
<div id="footer">...</div>
Layouts 73
CakePHP Cookbook Documentation, Release 2.x
</body>
</html>
Note: Na verso anterior a 2.1, o mtodo fetch() no estava disponvel, fetch(content)
uma substituio para $content_for_layout e as linhas fetch(meta), fetch(css) and
fetch(script) estavam contidas na varivel $scripts_for_layout na verso 2.0.
Os blocos script, css e meta contm qualquer contedo denido nas views usando o helper HTML
embutido. til na incluso de arquivos javascript e CSS de views.
Note: Quando usar HtmlHelper::css() ou HtmlHelper::script() em views, especique
false para a opo inline para colocar o cdigo html em um bloco de mesmo nome. (Veja a API para
mais detalhes de uso)
O bloco content contem o contedo da view renderizada.
$title_for_layout contm o ttulo da pgina, Esta varivel gerada automaticamente, mas voc
poder sobrescrev-la denindo-a em seu controller/view.
Para denir o ttulo para o layout, o modo mais fcil no controller, setando a varivel
$title_for_layout:
class UsersController extends AppController {
public function view_active() {
$this->set(title_for_layout, View Active Users);
}
}
Voc tambm pode setar a varivel title_for_layout no arquivo de view:
$this->set(title_for_layout, $titleContent);
Voc pode criar quantos layouts voc desejar: apenas coloque-os no diretrio app/View/Layouts, e
dena qual deles usar dentro das aes do seu controller usando a propriedade $layout do controller ou
view:
// de um controller
public function admin_view() {
// cdigos
$this->layout = admin;
}
// de um arquivo view
$this->layout = loggedin;
Por exemplo, se a seo do meu site incluir um pequeno espao para banner, eu posso criar um novo layout
com um pequeno espao para propaganda e especic-lo como layout para as aes de todos os controllers
usando algo como:
class UsersController extends AppController {
public function view_active() {
$this->set(title_for_layout, View Active Users);
74 Captulo 5. Views
CakePHP Cookbook Documentation, Release 2.x
$this->layout = default_small_ad;
}
public function view_image() {
$this->layout = image;
//output user image
}
}
O CakePHP tem em seu ncleo, dois layouts (alm do layout padro) que voc pode usar em suas prprias
aplicaes: ajax e ash. O layout Ajax til para elaborar respostas Ajax - um layout vazio (a maior
parte das chamadas ajax requer pouca marcao de retorno, preferencialmente a uma interface totalmente
renderizada). O layout ash usado para mensagens mostradas pelo mtodo Controller::flash().
Outros trs layouts, XML, JS, e RSS, existem no ncleo como um modo rpido e fcil de servir contedo
que no seja text/html.
Usando layouts a partir de plugins
New in version 2.1.
Se voc quiser usar um layout que existe em um plugin, voc pode usar a sintaxe de plugin. Por exemplo,
para usar o layout de contato do plugin de contatos:
class UsersController extends AppController {
public function view_active() {
$this->layout = Contacts.contact;
}
}
Elements
Muitas aplicaes possuem pequenos blocos de cdigo de apresentao que precisam ser repetidos a cada
pgina, s vezes em diferentes lugares no layout. O CakePHP ajuda voc a repetir partes do seu website
que precisam ser reutilizados. Estas partes reutilizveis so chamadas de Elements (ou Elementos). Propa-
gandas, caixas de ajuda, controles de navegao, menus extras, formulrios de login e chamadas geralmente
so implementadas como elements. Um element bsicamente uma mini-view que pode ser includa em
outras views, layouts e at mesmo em outros elements. Elements podem ser usados para criar uma view mais
legvel, colocando o processamento de elementos repetidos em seu prprio arquivo. Eles tambm podem
ajud-lo a re-usar contedos fragmentados pela sua aplicao.
Elements so colocados na pasta /app/View/Elements/ e possuema extenso .ctp no nome do arquivo.
Eles so exibidos atravs do uso do mtodo element da view:
echo $this->element(helpbox);
Elements 75
CakePHP Cookbook Documentation, Release 2.x
Passando variveis em um Element
Voc pode passar dados para um element atravs do segundo argumento do element:
echo $this->element(helpbox, array(
"helptext" => "Oh, este texto muito til."
));
Dentro do arquivo do element, todas as variveis passadas esto disponveis como membros do array
de parmetros (da mesma forma que Controller::set() no controller trabalha com arquivos de
views). No exemplo acima, o arquivo /app/View/Elements/helpbox.ctp pode usar a varivel
$helptext:
// Dentro de app/View/Elements/helpbox.ctp
echo $helptext; //outputs "Oh, este texto muito til."
O mtodo View::element() tambm suporta opes para o element. As opes suportadas so cache
e callbacks. Um exemplo:
echo $this->element(helpbox, array(
"helptext" => "Isto passado para o
*
element
*
como $helptext",
"foobar" => "TIsto passado para o
*
element
*
como $foobar",
),
array(
"cache" => "long_view", // usa a configurao de cache "long_view"
"callbacks" => true // atribue verdadeiro para ter before/afterRender chamado pelo
*
element
*
)
);
O cache de element facilitado atravs da classe Cache. Voc pode congurar elements para serem guarda-
dos em qualquer congurao de cache que voc tenha denido. Isto permite uma maior exibilidade para
decidir onde e por quantos elements so guardados. Para fazer o cache de diferentes verses de um mesmo
element em uma aplicao, dena uma nica chave de cache usando o seguinte formato:
$this->element(helpbox, array(), array(
"cache" => array(config => short, key => unique value)
)
);
Voc pode tirar vantagem de elements usando requestAction(). A funo requestAction() car-
rega variveis da views a partir de aes do controller e as retorna como um array. Isto habilita seus elements
para atuar verdadeiramente no estilo MVC. Crie uma ao de controller que prepara as variveis da view
para seu element, depois chame requestAction() no segundo parmetro do element() para carregar
as variveis da view a partir do seu controller.
Para isto, em seu controller, adicione algo como segue, como exemplo de Post:
class PostsController extends AppController {
// ...
public function index() {
$posts = $this->paginate();
if ($this->request->is(requested)) {
return $posts;
76 Captulo 5. Views
CakePHP Cookbook Documentation, Release 2.x
} else {
$this->set(posts, $posts);
}
}
}
Em seguida, no element, voc poder acessar os modelos de posts paginados. Para obter os ltimos cinco
posts em uma lista ordenada, voc pode fazer algo como:
<h2>Latest Posts</h2>
<?php $posts = $this->requestAction(posts/index/sort:created/direction:asc/limit:5); ?>
<?php foreach ($posts as $post): ?>
<ol>
<li><?php echo $post[Post][title]; ?></li>
</ol>
<?php endforeach; ?>
Caching Elements
Voc pode tomar proveito do CakePHP view caching, se voc fornecer um parmetro de cache. Se denido
como true, o element ser guardado na congurao de cache default. Caso contrrio, voc poder denir
qual congurao de cache deve ser usada. Veja /core-libraries/caching para mais informaes
de congurao Cache. Um exemplo simples de caching um element seria:
echo $this->element(helpbox, array(), array(cache => true));
Se voc renderiza o mesmo element mais que uma vez em uma view e tem caching ativado, esteja certo
de denir o parmetro chave (key) para um nome diferente cada vez. Isto ir prevenir que cada chamada
sucessiva substitua o resultado armazenado da chamada element() anterior. E.g.:
echo $this->element(
helpbox,
array(var => $var),
array(cache => array(key => first_use, config => view_long)
);
echo $this->element(
helpbox,
array(var => $differenVar),
array(cache => array(key => second_use, config => view_long)
);
O cdigo acima garante que ambos os resultados do element sero armazenados separadamente. Se voc
quiser que todos os elementos armazenados usem a mesma congurao de cache, voc pode salvar al-
guma repetio, setando View::$elementCache para a congurao de cache que voc quer usar. O
CakePHP usar esta congurao, quando nenhuma outra for dada.
Elements 77
CakePHP Cookbook Documentation, Release 2.x
Requisitando Elements de um Plugin
2.0
Para carregar um element de um plugin, use a opo plugin (retirada da opo data na verso 1.x):
echo $this->element(helpbox, array(), array(plugin => Contacts));
2.1
Se voc est usando um plugin e deseja usar elements de dentro deste plugin apenas use plugin syntax.
Se a view est renderizando para um controller/action de plugin, o nome do plugin ser automaticamente
prexado antes de todos os elements usados, ao menos que outro nome de plugin esteja presente. Se o
element no existir no plugin, ser procurado na pasta principal da APP.:
echo $this->element(Contacts.helpbox);
Se sua view parte de um plugin voc pode omitir o nome do plugin. Por exemplo, se voc est no
ContactsController do plugin Contatos:
echo $this->element(helpbox);
// and
echo $this->element(Contacts.helpbox);
So equivalentes e resultaro no mesmo elemento sendo renderizado.
Changed in version 2.1: A opo $options[plugin] foi descontinuada e o suporte para
Plugin.element foi adicionado.
View API
class View
Mtodos de Views so acessveis por todas as views, elements e arquivos de layout. Para chamar qualquer
mtodo de uma view use $this->method().
View::set(string $var, mixed $value)
Views tm mtodos set() que so anlogos aos set() encontrados nos objetos controllers. Usando
set() em seu arquivo view sero adicionados variveis para layouts e elements que sero renderizados
posteriormente. Veja Mtodos dos Controllers para maiores informaes de como usar o set().
No seu arquivo de view, voc pode:
$this->set(activeMenuButton, posts);
Assim em seu layout a varivel $activeMenuButton estar disponvel e conter o valor posts.
View::getVar(string $var)
Obtem o valor de viewVar com o nome $var
78 Captulo 5. Views
CakePHP Cookbook Documentation, Release 2.x
View::getVars()
Obtem uma lista de todas as variveis disponveis da view, no escopo renderizado corrente. Retorna
um array com os nomes das variveis.
View::element(string $elementPath, array $data, array $options = array())
Renderiza um elemento ou parte de uma view. Veja a seo Elements para maiores informaes e
exemplos.
View::uuid(string $object, mixed $url)
Gera um DOM ID no randmico nico para um objeto, baseado no tipo do objeto e url. Este
mtodo frequentemente usado por helpers que precisam gerar DOM ID nicos para elementos como
JsHelper:
$uuid = $this->uuid(form, array(controller => posts, action => index));
//$uuid contains form0425fe3bad
View::addScript(string $name, string $content)
Adiciona contedo para buffer de scripts internos. Este buffer disponibilizado no layout
como $scripts_for_layout. Este mtodo auxilia na criao de helpers que necessi-
tam adicionar javascript or css diretamente para o layout. Ciente que scripts adicionados de
layouts, or elements do layout no sero adicionados para $scripts_for_layout. Este
mtodo frequentemente usado dentro dos helpers, como nos Helpers /core-libraries/helpers/js e
/core-libraries/helpers/html.
Deprecated since version 2.1: Use a feature Usando Blocos de Views (Vises), ao invs.
View::blocks()
Obtem o nome de todos os blocos denidos como um array.
View::start($name)
Inicia a caputura de bloco para um bloco de view. Veja a seo em Usando Blocos de Views (Vises)
para exemplos.
New in version 2.1.
View::end()
Finaliza o mais recente bloco sendo capturado. Veja a seo em Usando Blocos de Views (Vises)
para exemplos.
New in version 2.1.
View::append($name, $content)
Anexa no bloco com $name. Veja a seo em Usando Blocos de Views (Vises) para examplos.
New in version 2.1.
View::assign($name, $content)
Atribui o valor de um bloco. Isso ir sobrescrever qualquer contedo existente. Veja a seo em
Usando Blocos de Views (Vises) para exemplos.
New in version 2.1.
View::fetch($name)
Fetch o valor do bloco. Sero retornados de blocos que no esto denidos Veja a seo em Usando
Blocos de Views (Vises) para exemplos.
View API 79
CakePHP Cookbook Documentation, Release 2.x
New in version 2.1.
View::extend($name)
Estende o view/element/layout corrente com o nome fornecido. Veja a seo em Estendendo Views
para examplos.
New in version 2.1.
property View::$layout
Seta o layout onde a view corrente ser envolvida.
property View::$elementCache
A congurao de cache usada para armazenar elements. Setando esta propriedade a congurao
padro usada para armazenar elements ser alterada Este padro pode ser sobrescrito usando a opo
cache no mtodo do element.
property View::$request
Uma instncia de CakeRequest. Use esta instncia para acessar informaoes sobre a requisio
atual.
property View::$output
Contem o ltimo contedo renderizado de uma view, seja um arquivo de view ou contedo do layout.
Deprecated since version 2.1: Use $view->Blocks->get(content); ao invs.
property View::$Blocks
Uma instncia de ViewBlock. Usada para prover um bloco de funcionalidades de view na view
renderizada.
New in version 2.1.
80 Captulo 5. Views
CAPTULO 6
Plugins
CakePHP permite que voc dena uma combinao de controllers, models, e views e lance-os como um
pacote de aplicao que outras pessoas podem usar em suas aplicaes CakePHP. Voc quer ter um mdulo
de gesto de usurios, um blog simples, ou um mdulo de servios web em uma das suas aplicaes?
Empacote-os como um plugin do CakePHP para que voc possa coloc-lo em outras aplicaes.
A principal diferena entre um plugin e a aplicao em que ele instalado, a congurao da aplicao
(base de dados, conexo, etc.). Caso contrrio, ele opera em seu prprio espao, comportando-se como se
fosse uma aplicao por conta prpria.
Instalando um Plugin
Para instalar um plugin, basta simplesmente colocar a pasta plugin dentro do diretrio app/Plugin. Se voc
est instalando um plugin chamado ContactManager, ento voc deve ter uma pasta dentro de app/Plugin
chamado ContactManager em que podem estar os diretrios de plugin: View, Model, Controller, webroot,
e qualquer outro diretrio.
Novo para CakePHP 2.0, plugins precisam ser carregados manualmente em app/Cong/bootstrap.php.
Voc pode carreg-los um por um ou todos eles em uma nica chamada:
CakePlugin::loadAll(); // Carrega todos os plugins de uma vez
CakePlugin::load(ContactManager); // Carrega um nico plugin
loadAll carrega todos os plugins disponveis, enquanto permite que voc dena certas conguraes para
plugins especcos. load() funciona de maneira semelhante, mas carrega somente os plugins que voc
especicar explicitamente.
H uma poro de coisas que voc pode fazer com os mtodos load e loadAll para ajudar com a congu-
rao do plugin e roteamento. Talvez voc tenha que carregar todos os plugins automaticamente, enquanto
especica rotas personalizadas e arquivos de bootstrap para certos plugins.
Sem problema:
81
CakePHP Cookbook Documentation, Release 2.x
CakePlugin::loadAll(array(
Blog => array(routes => true),
ContactManager => array(bootstrap => true),
WebmasterTools => array(bootstrap => true, routes => true),
));
Com este estilo de congurao, voc no precisa mais fazer manualmente um include() ou require() de
arquivo de congurao do plugin ou rotas acontece automaticamente no lugar e na hora certa. Os exatos
mesmos parmetros tambm poderiam ter sido fornecidos ao mtodo load(), o que teria carregado apenas
aqueles trs plugins, e no o resto.
Finalmente, voc pode especicar tambm um conjunto de padres para loadAll que se aplicar a cada
plugin que no tem uma congurao mais especca.
Carrega o arquivo bootstrap de todos os plugins, e as rotas do plugin Blog:
CakePlugin::loadAll(array(
array(bootstrap => true),
Blog => array(routes => true)
));
Note que todos os arquivos especicados devem realmente existir no plugin(s) congurado ou o PHP ir dar
avisos (warnings) para cada arquivo que no pde carregar. Isto especialmente importante para lembrar ao
especicar padres para todos os plugins.
Alguns plugins precisam que seja criado uma ou mais tabelas em sua base de dados. Nesses casos, muitas
vezes eles vo incluir um arquivo de esquema que voc pode chamar a partir do cake shell dessa forma:
user@host $ cake schema create --plugin ContactManager
A maioria dos plugins indicar o procedimento adequado para a congur-los e congurar a base de dados,
em sua documentao. Alguns plugins iro exigir mais conguraes do que outros.
Usando um Plugin
Voc pode referenciar controllers, models, components, behaviors, e helpers de um plugin, prexando o
nome do plugin antes do nome da classe.
Por exemplo, digamos que voc queira usar o ContactInfoHelper do plugin CantactManager para a sada de
algumas informaes de contato em uma de suas views. Em seu controller, seu array $helpers poderia ser
assim:
public $helpers = array(ContactManager.ContactInfo);
Voc ento ser capaz de acessar o ContactInfoHelper como qualquer outro helper em sua view, tal como:
echo $this->ContactInfo->address($contact);
82 Captulo 6. Plugins
CakePHP Cookbook Documentation, Release 2.x
Criando Seus Prprios Plugins
Como um exemplo de trabalho, vamos comear a criar o plugin ContactManager referenciado acima. Para
comear, vamos montar a nossa estrutura bsica de plugins. Ela deve se parecer com isso:
/app
/Plugin
/ContactManager
/Controller
/Component
/Model
/Behavior
/View
/Helper
/Layouts
Note o nome da pasta do plugin, ContactManager. importante que essa pasta tenha o mesmo nome do
plugin.
Dentro da pasta do plugin, voc ver que se parece muito com uma aplicao CakePHP, e que basicamente
isso mesmo. Voc realmente no tem que incluir qualquer uma dessas pastas se voc no for us-las.
Alguns plugins podem denir somente um Component e um Behavior, e nesse caso eles podem omitir
completamente o diretrio View.
Um plugin pode tambm ter basicamente qualquer um dos outros diretrios que sua aplicao pode, como
Cong, Console, Lib, webroot, etc.
Note: Se voc quer ser capaz de acessar seu plugin com uma URL, necessrio denir um AppCon-
troller e AppModel para o plugin. Estas duas classes especiais so nomeadas aps o plugin, e estendem
AppController e AppModel da aplicao pai. Aqui est o que deve ser semelhante para nosso exemplo
ContactManager:
// /app/Plugin/ContactManager/Controller/ContactManagerAppController.php:
class ContactManagerAppController extends AppController {
}
// /app/Plugin/ContactManager/Model/ContactManagerAppModel.php:
class ContactManagerAppModel extends AppModel {
}
Se voc se esqueceu de denir estas classes especiais, o CakePHP ir entregar a voc erros Missing Con-
troller at que voc tenha feito isso.
Por favor, note que o processo de criao de plugins pode ser muito simplicado usando o Cake shell.
Para assar um plugin por favor use o seguinte comando:
user@host $ cake bake plugin ContactManager
Agora voc pode assar usando as mesmas convenes que se aplicam ao resto de sua aplicao. Por exemplo
- assando controllers:
Criando Seus Prprios Plugins 83
CakePHP Cookbook Documentation, Release 2.x
user@host $ cake bake controller Contacts --plugin ContactManager
Por favor consulte o captulo /console-and-shells/code-generation-with-bake se voc
tiver quaisquer problemas com o uso da linha de comando.
Plugin Controllers
Controllers de nosso plugin ContactManager sero armazenados em
/app/Plugin/ContactManager/Controller/. Como a principal coisa que vamos fazer a gesto de con-
tatos, vamos precisar de um ContactsController para este plugin.
Ento, ns colocamos nosso novo ContactsController em /app/Plugin/ContactManager/Controller e deve se
parecer com isso:
// app/Plugin/ContactManager/Controller/ContactsController.php
class ContactsController extends ContactManagerAppController {
public $uses = array(ContactManager.Contact);
public function index() {
//...
}
}
Note: Este controller estende o AppController do plugin (chamado ContactManagerAppController) ao
invs do AppController da aplicao pai.
Observe tambm como o nome do model prexado com o nome do plugin. Isto necessrio para diferen-
ciar entre models do plugin e models da aplicao principal.
Neste caso, o array $uses no seria necessrio com ContactManager. Contact seria o model padro para este
controller, no entanto est includo para demostrar adequadamente como preceder o nome do plugin.
Se voc quiser acessar o que ns zemos at agora, visite /contact_manager/contacts. Voc deve obter um
erro Missing Model porque no temos um model Contact denido ainda.
Plugin Models
Models para plugins so armazenados em /app/Plugin/ContactManager/Model. Ns j denimos um Con-
tactsController para este plugin, ento vamos criar o model para o controller, chamado Contact:
// /app/Plugin/ContactManager/Model/Contact.php:
class Contact extends ContactManagerAppModel {
}
Visitando /contact_manager/contacts agora (dado que voc tem uma tabela em seu banco de dados chamada
contacts) deveria nos dar um erro Missing View. Vamos criar na prxima.
Note: Se voc precisar fazer referncia a um model dentro de seu plugin, voc precisa incluir o nome do
84 Captulo 6. Plugins
CakePHP Cookbook Documentation, Release 2.x
plugin com o nome do model, separados por um ponto.
Por exemplo:
// /app/Plugin/ContactManager/Model/Contact.php:
class Contact extends ContactManagerAppModel {
public $hasMany = array(ContactManager.AltName);
}
Se voc preferir que as chaves do array para associao no tenha o prexo do plugin nelas, use uma sintaxe
alternativa:
// /app/Plugin/ContactManager/Model/Contact.php:
class Contact extends ContactManagerAppModel {
public $hasMany = array(
AltName => array(
className => ContactManager.AltName
)
);
}
Plugin Views
Views se comportam exatamente como fazem em aplicaes normais. Basta coloc-las na pasta certa dentro
de /app/Plugin/[PluginName]/View/. Para nosso plugin ContactManager, vamos precisar de uma view para
nosso action ContactsController::index(), por isso vamos incluir isso como:
// /app/Plugin/ContactManager/View/Contacts/index.ctp:
<h1>Contacts</h1>
<p>Following is a sortable list of your contacts</p>
<!-- A sortable list of contacts would go here....-->
Note: Para obter informaes sobre como usar elements de um plugin, veja Elements
Substituindo views de plugins de dentro da sua aplicao
Voc pode substituir algumas views de plugins de dentro da sua app usando caminhos especi-
ais. Se voc tem um plugin chamado ContactManager voc pode substituir os arquivos de view
do plugin com lgicas de view da aplicao especca criando arquivos usando o modelo a seguir
app/View/Plugin/[Plugin]/[Controller]/[view].ctp. Para o controller Contacts voc pode fazer o seguinte
arquivo:
/app/View/Plugin/ContactManager/Contacts/index.ctp
A criao desse, permite a voc substituir /app/Plugin/ContactManager/View/Contacts/index.ctp.
Plugin Views 85
CakePHP Cookbook Documentation, Release 2.x
Imagens de Plugin, CSS e Javascript
Imagens, css e javascript de um plugin (mas no arquivos PHP), podem ser servidos por meio do diretrio
de plugin webroot, assim como imagens, css e javascript da aplicao principal:
app/Plugin/ContactManager/webroot/
css/
js/
img/
flash/
pdf/
Voc pode colocar qualquer tipo de arquivo em qualquer diretrio, assim como um webroot normal. A nica
restrio que MediaView precisa saber o mime-type do arquivo.
Linkando para imagens, css e javascript em plugins
Basta preceder /plugin_name/ no incio de um pedido para um arquivo dentro do plugin, e ele vai funcionar
como se fosse um arquivo do webroot de sua aplicao.
Por exemplo, linkando para /contact_manager/js/some_le.js deveria servir o arquivo
app/Plugin/ContactManager/webroot/js/some_le.js.
Note: importante notar o /your_plugin/ prexado antes do caminho do arquivo. Isso faz a magica
acontecer!
Components, Helpers e Behaviors
Um plugin pode ter Conponents, Helpers e Behaviors como uma aplicao CakePHP normal. Voc pode
at criar plugins que consistem apenas de Components, Helpers ou Behaviors que podem ser uma tima
maneira de contruir componentes reutilizveis que podem ser facilmente acoplados em qualquer projeto.
A construo destes componentes exatamente o mesmo que contruir dentro de uma aplicao normal, sem
conveno especial de nomenclatura.
Referindo-se ao seu componente de dentro ou fora do seu plugin, exige somente que o nome do plugin esteja
prexado antes do nome do componente. Por exemplo:
// Componente definido no plugin ContactManager
class ExampleComponent extends Component {
}
// dentro de seu controller:
public $components = array(ContactManager.Example);
A mesma tcnica se aplica aos Helpers e Behaviors.
Note: Ao criar Helpers voc pode notar que AppHelper no est disponvel automaticamente. Voc deve
declarar os recursos que precisar com Uses:
86 Captulo 6. Plugins
CakePHP Cookbook Documentation, Release 2.x
// Declare o uso do AppHelper para seu Helper Plugin
App::uses(AppHelper, View/Helper);
Expanda seu Plugin
Este exemplo criou um bom comeo para um plugin, mas h muito mais coisas que voc pode fazer. Como
uma regra geral, qualquer coisa que voc pode fazer com sua aplicao, voc pode fazer dentro de um plugin
em seu lugar.
V em frente, inclua algumas bibliotecas de terceiros em Vendor, adicione algumas novas shells para o
cake console, e no se esquea de criar casos de testes para que usurios de seus plugins possam testar
automaticamente as funcionalidades de seus plugins!
Em nosso exemplo ContactManager, poderamos criar os actions add/remove/edit/delete em ContactsCon-
troller, implementar a validao no model Contact, e implementar uma funcionalidade que poderia se esperar
ao gerenciar seus contatos. Cabe a voc decidir o que implementar em seus plugins. S no se esquea de
compartilhar seu cdigo com a comunidade para que todos possam se beneciar de seus impressionantes
componentes reutilizveis!
Plugin Dicas
Uma vez que o plugin foi instalado em /app/Plugin, voc pode acess-lo atravs da URL /plu-
gin_name/controller_name/action. Em nosso plugin ContactManager de exemplo, acessamos nosso Con-
tactsController com /contact_manager/contacts.
Algumas dicas nais sobre como trabalhar com plugins em suas aplicaes CakePHP:
Quando voc no tiver um [Plugin]AppController e [Plugin]AppModel, voc ter um erro Missing
Controller quando estiver tentando acessar um controller de plugin.
Voc pode denir seus layouts para plugins, dentro de app/Plugin/[Plugin]/View/Layouts. Caso con-
trrio, o plugin ir utilizar por padro os layouts da pasta /app/View/Layouts.
Voc pode fazer uminter-plugin de comunicao usando $this->requestAction(/plugin_name/controller_name/action);
em seus controllers.
Se voc usar requestAction, esteja certo que os nomes dos controllers e das models sejam to nicos
quanto possvel. Caso contrrio voc poder obter do PHP o erro redened class ...
Expanda seu Plugin 87
CakePHP Cookbook Documentation, Release 2.x
88 Captulo 6. Plugins
CAPTULO 7
Desenvolvimento
Nesta seo vamos cobrir os vrios aspectos do desenvolvimento de uma aplicao CakePHP. Temas como
congurao, manipulao de erros e excees, depurao e testes sero abordados.
89
CakePHP Cookbook Documentation, Release 2.x
90 Captulo 7. Desenvolvimento
CAPTULO 8
Implementao
Uma vez que sua aplicao est completa, ou mesmo antes quando voc quiser coloc-la no ar. Existem
algumas poucas coisas que voc deve fazer quando colocar em produo uma aplicao CakePHP.
Denindo a Raiz
Denir a raiz do documento da sua aplicao corretamente um passo importante para manter seu cdigo
protegido e sua aplicao mais segura. As aplicaes desenvolvidas com o CakePHP devem ter a raiz apon-
tando para o diretrio app/webroot. Isto torna a aplicao e os arquivos de conguraes inacessveis
via URL. Congurar a raiz do documento depende de cada webserver. Veja a Instalao Avanada para
informaes sobre webservers especcos.
Atualizar o core.php
Atualizar o arquivo core.php, especicamente o valor do debug de extrema importncia. Tornar o
debug igual a 0 desabilita muitos recursos do processo de desenvolvimento que nunca devem ser expostos
ao mundo. Desabilitando o debug, as coisas a seguir mudaro:
Mensagens de depurao criadas com pr() e debug() sero desabilitadas.
O cache interno do CakePHP ser descartado aps 99 anos em vez de 10 segundos.
Views de erros sero menos informativas, retornando mensagens de erros genricas.
Erros no sero mostrados.
O rastro da pilha de excees ser desabilitado.
Alm dos itens citados acima, muitos plugins e extenses usam o valor do debug para modicarem seus
comportamentos.
91
CakePHP Cookbook Documentation, Release 2.x
Multiplas aplicaes usando o mesmo core do CakePHP
Existem algumas maneiras de voc congurar mltiplas aplicaes para usarem o mesmo core
(ncleo) do CakePHP. Voc pode usar o include_path do PHP ou denir a constante
CAKE_CORE_INCLUDE_PATH no webroot/index.php da sua aplicao. Geralmente, usar o
include_path do PHP a meneira mais fcil e robusta pois o CakePHP j vem pr-congurado para
olhar o include_path.
No seu arquivo php.ini localize a diretiva include_path existente e anexe no nal o caminho para o
diretrio lib do CakePHP:
include_path = .:/usr/share/php:/usr/share/cakephp-2.0/lib
Assumimos que voc est rodando um servidor *nix e instalou o CakePHP em
/usr/share/cakephp-2.0.
92 Captulo 8. Implementao
CAPTULO 9
Tutoriais & Exemplos
Nesta seo, voc poder caminhar ao longo de tpicas aplicaes CakePHP para ver como todas as peas
se encaixam.
Como alternativa, voc pode preferir visitar o repositrio no ocial de plugins para o CakePHP CakePack-
ages
1
ou a Padaria
2
para conhecer aplicaes e componentes existentes.
Blog
Bem vindo ao CakePHP. Voc provavelmente est lendo este tutorial porque quer aprender mais sobre como
o CakePHP funciona. Nosso objetivo aumentar a produtividade e fazer a programao uma tarefa mais
divertida: Esperamos que voc veja isto na prtica enquanto mergulha nos cdigos.
Este tutorial ir cobrir a criao de uma aplicao de blog simples. Ns iremos baixar e instalar o Cake, criar
e congurar o banco de dados e criar a lgica da aplicao suciente para listar, adicionar, editar e deletar
posts do blog.
Aqui vai uma lista do que voc vai precisar:
1. Um servidor web rodando. Ns iremos assumir que voc esteja usando o Apache, embora as in-
strues para usar outros servidores sejam bem semelhantes. Talvez tenhamos que brincar um pouco
com as conguraes do servidor mas a maioria das pessoas sero capazes de ter o Cake rodando sem
precisar congurar nada.
2. Um servidor de banco de dados. Ns iremos usar o MySQL Server neste tutorial. Voc precisa saber
o mnimo sobre SQL para criar um banco de dados. O Cake pegar as rdeas a partir deste ponto.
3. Conhecimento bsico da linguagemPHP. Quanto mais orientado a objetos voc j programou, melhor:
mas no tenha medo se f de programao procedural.
4. E por ltimo, voc vai precisar de um conhecimento bsico do padro de projetos MVC. Uma rpida
viso geral pode ser encontrada em Entendendo o Model-View-Controller. No se preocupe, deve ter
meia pgina ou menos.
1
http://plugins.cakephp.org/
2
http://bakery.cakephp.org/
93
CakePHP Cookbook Documentation, Release 2.x
Ento, vamos comear!
Baixando o Cake
Primeiro, vamos baixar uma cpia recente do CakePHP.
Para fazer o download de uma cpia recente, visite o projeto do CakePHP no github:
http://github.com/cakephp/cakephp/downloads e faa o download da ltima verso 2.0.
Voc tambm pode clonar o repositrio usando o git
3
. git clone
git://github.com/cakephp/cakephp.git.
Idependente da maneira de como voc baixou o Cake, coloque o cdigo obtido dentro do seu diretrio web
pblico. A estrutura dos diretrios deve car parecido com o seguinte:
/caminho_para_diretorio_web_publico
/app
/lib
/plugins
/vendors
.htaccess
index.php
README
Agora pode ser um bom momento para aprender um pouco sobre como funciona a estrutura de diretrios do
CakePHP: Veja a seo Estrutura de Diretrios no CakePHP.
Criando o Banco de Dados do Blog
Em seguida, vamos congurar o banco de dados correspondente ao nosso blog. Se voc j no tiver feito
isto, crie um banco de dados vazio para usar neste tutorial com o nome que desejar. Neste momento, vamos
criar apenas uma tabela para armazenar nossos posts. Tambm vamos inserir alguns posts para usar como
teste. Execute as instrues a seguir no seu banco de dados:
-- Primeiro, criamos nossa tabela de posts
CREATE TABLE posts (
id INT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
title VARCHAR(50),
body TEXT,
created DATETIME DEFAULT NULL,
modified DATETIME DEFAULT NULL
);
-- Agora inserimos alguns posts para testar
INSERT INTO posts (title, body, created)
VALUES (The title, This is the post body., NOW());
INSERT INTO posts (title, body, created)
VALUES (A title once again, And the post body follows., NOW());
INSERT INTO posts (title, body, created)
VALUES (Title strikes back, This is really exciting! Not., NOW());
3
http://git-scm.com/
94 Captulo 9. Tutoriais & Exemplos
CakePHP Cookbook Documentation, Release 2.x
A escolha do nome de tabelas e colunas no so arbitrrias. Se voc seguir as convenes de nomenclatura
para estruturas do banco de dados e as convenes para nomes de classes (ambas descritas em Convenes
no CakePHP), voc ser capaz de tirar proveito de muitas funcionalidades do CakePHP e evitar arquivos
de conguraes. O Cake exivel o bastante para acomodar at mesmo os piores esquemas de banco de
dados legados, mas aderindo as convenes voc poupa seu tempo.
Veja Convenes no CakePHP para mais informaes. Aqui, basta dizer que ao nomear nossa tabela de
posts, automaticamente ela ser ligada ao nosso model Post e as colunas modied e created sero
automagicamente atualizadas pelo CakePHP.
Conguraes do Banco de Dados
Para o Alto e Avante: Vamos agora avisar ao Cake onde est nosso banco de dados e como conectar a ele.
Para muitos, esta a primeira e ltima congurao a ser feita.
Uma exemplo de arquivo de congurao do banco de dados pode ser encontrado em
/app/Config/database.php.default. Copie este arquivo no mesmo diretrio renomeando-o
para database.php.
O arquivo bem simples: basta alterar os valores da varivel $default com os dados da nossa congurao.
Um exemplo completo desta congurao ir se parecer com esta:
public $default = array(
datasource => Database/Mysql,
persistent => false,
host => localhost,
port => ,
login => cakeBlog,
password => c4k3-rUl3Z,
database => cake_blog_tutorial,
schema => ,
prefix => ,
encoding =>
);
Aps salvar seu novo arquivo database.php, voc estar apto para abrir seu navegador e ver a pgina de boas
vindas do Cake. A pgina de boas vindas dever lhe mostrar uma mensagem dizendo que seu arquivo de
conexo com o banco de dados foi encontrado, e que o Cake conseguiu se conectar com o banco de dados.
Congurao Opcional
Existem outros trs itens que podem ser congurados. Muitos desenvolvedores sempre conguram estes
itens, mas eles no so obrigatrios para este tutorial. Uma das conguraes customizar uma string (ou
salt) para ser utilizada nos hashes de segurana. O segundo denir um nmero (ou seed) para uso em
criptograa. E o terceiro dar permisso de escrita para o CakePHP na pasta tmp.
O security salt utilizado para gerar hashes. Altere o valor padro do salt editando o arquivo
/app/Config/core.php na linha 187. No importa muito o que o novo valor seja, basta que no
seja fcil de adivinhar.
Blog 95
CakePHP Cookbook Documentation, Release 2.x
/
**
*
A random string used in security hashing methods.
*
/
Configure::write(Security.salt, pl345e-P45s_7h3
*
S@l7!);
?>
O cipher seed usado para criptografar/descriptografar strings. Altere o valor padro editando o arquivo
/app/Config/core.php na linha 192. Como no security salt, no importa muito o que o novo valor
seja, basta que no seja fcil de adivinhar.
/
**
*
A random numeric string (digits only) used to encrypt/decrypt strings.
*
/
Configure::write(Security.cipherSeed, 7485712659625147843639846751);
?>
A ltima tarefa garantir acesso de escrita para a pasta app/tmp. A melhor maneira para fazer isto
localizar o usurio com que o seu servidor web executado (<?php echo whoami; ?>) e alterar o
dono da pasta app/tmp para este usurio. Voc pode executar (em *nix) o comando a seguir para alterar o
usurio dono da pasta.
$ chown -R www-data app/tmp
Se por alguma razo o CakePHP no conseguir escrever nesta pasta, voc ser avisado por uma mensagem
enquanto estiver em modo de desenvolvimento.
Uma Palavra Sobre o mod_rewrite
Ocasionalmente, um novo usurio ir esbarrar em problemas com o mod_rewrite, ento vou abord-los su-
percialmente aqui. Se a pgina de boas-vindas do CakePHP parecer um pouco sem graa (sem imagens,
sem cores e sem os estilos css), isso um indcio de que o mod_rewrite provavelmente no esteja funcio-
nando em seu sistema. Aqui esto algumas dicas para lhe ajudar a deixar tudo funcionando corretamente:
1. Certique-se de que a sobrescrita de opes do .htaccess est habilitada: em seu arquivo httpd.conf,
voc deve ter uma parte que dene uma seo para cada <Directory> do seu servidor. Certique-se de
que a opo AllowOverride esteja com o valor All para o <Directory> correto. Por questes de
segurana e performance, no dena AllowOverride para All em <Directory />. Ao invs
disso, procure o bloco <Directory> que se refere ao seu diretrio raz de seu website.
2. Certique-se de estar editando o arquivo httpd.conf ao invs de algum especco, que seja vlido
apenas para um dado usurio ou para um dado site.
3. Por alguma razo, voc pode ter obtido uma cpia do CakePHP sem os arquivos .htaccess. Isto
algumas vezes acontece porque alguns sistemas operacionais tratam arquivos que comeam com .
como arquivos ocultos e normalmente no fazem cpias deles. Certique-se de obter sua cpia do
CakePHP diretamente da seo de downloads do site ou de nosso repositrio git.
4. Certique-se de que o Apache esteja carregando o mod_rewrite corretamente! Voc deve ver algo
como:
96 Captulo 9. Tutoriais & Exemplos
CakePHP Cookbook Documentation, Release 2.x
LoadModule rewrite_module libexec/httpd/mod_rewrite.so
ou (para o Apache 1.3):
AddModule mod_rewrite.c
em seu httpd.conf.
Se voc no quiser ou no puder carregar o mod_rewrite (ou algum outro mdulo compatvel)
em seu servidor, voc vai precisar usar o recurso de URLs amigveis do CakePHP. No arquivo
/app/Config/core.php, descomente uma linha parecida com:
Configure::write(App.baseUrl, env(SCRIPT_NAME));
E remova tambm os arquivos .htaccess em:
/.htaccess
/app/.htaccess
/app/webroot/.htaccess
Comisto, suas URLs caro parecidas comwww.exemplo.com/index.php/nomecontroller/nomeaction/param
ao invs de www.exemplo.com/nomecontroller/nomeaction/param.
Se voc est instalando o CakePHP em outro webserver diferente do Apache, voc pode encontrar instrues
para ter a reescrita de URLs funcionando na seo Instalao Avanada.
Continue lendo este tutorial em Blog - Continuao para comear a construir sua primeira aplicao
CakePHP.
Blog - Continuao
Crie um Model Post
A classe Model o po com manteiga das aplicaes CakePHP. Ao criar um model do CakePHP que
ir interagir com nossa base de dados, teremos os alicerces necessrios para posteriormente fazer nossas
operaes de visualizar, adicionar, editar e excluir.
Os arquivos de classe do tipo model do CakePHP cam em/app/Model e o arquivo que iremos criar ser
salvo em /app/Model/Post.php. O contedo completo deste arquivo deve car assim:
class Post extends AppModel {
public $name = Post;
}
A nomenclatura da classe segue uma conveno que muito importante no CakePHP. Ao chamar nosso
model de Post, o CakePHP pode automaticamente deduzir que este model ser usado num PostsController,
e que manipular os dados de uma tabela do banco chamada de posts.
Note: O CakePHP ir criar um objeto (instncia) do model dinamicamente para voc, se no encontrar
um arquivo correspondente na pasta /app/Model. Isto tambm signica que, se voc acidentalmente der um
nome errado ao seu arquivo (p.ex. post.php ou posts.php) o CakePHP no ser capaz de reconhecer nenhuma
Blog - Continuao 97
CakePHP Cookbook Documentation, Release 2.x
de suas conguraes adicionais e ao invs disso, passar a usar seus padres denidos internamente na
classe Model.
Para saber mais sobre models, como prexos de nomes de tabelas, callbacks e validaes, conra o captulo
sobre /models deste manual.
Crie o Controller Posts
A seguir, vamos criar um controller para nossos posts. O controller onde toda a lgica de negcio para
interaes vai acontecer. De uma forma geral, o local onde voc vai manipular os models e lidar com
o resultado das aes feitas sobre nossos posts. Vamos pr este novo controller num arquivo chamado
PostsController.php dentro do diretrio /app/Controller. Aqui est como um controller
bsico deve se parecer:
class PostsController extends AppController {
public $helpers = array (Html,Form);
public $name = Posts;
}
Agora, vamos adicionar uma action ao nosso controller. Actions quase sempre representam uma
nica funo ou interface numa aplicao. Por exemplo, quando os usurios acessarem o endereo
www.exemplo.com/posts/index (que, neste caso o mesmo que www.exemplo.com/posts/), eles esperam
ver a listagem dos posts. O cdigo para tal ao deve se parecer com algo assim:
class PostsController extends AppController {
public $helpers = array (Html,Form);
public $name = Posts;
function index() {
$this->set(posts, $this->Post->find(all));
}
}
Deixe-me explicar a ao um pouco. Denindo a funo index() em nosso PostsController, os usurios
podem acessar esta lgica visitando o endereo www.exemplo.com/posts/index. De maneira semelhante,
se denirmos um mtodo chamado foobar() dentro do controller, os usurios deveriam ser capazes de
acess-lo pelo endereo www.exemplo.com/posts/foobar.
Warning: Voc pode car tentado a nomear seus controller e actions de uma certa maneira visando
obter uma certa URL. Mas resista a esta tentao. Siga as convenes do CakePHP (nomes de controllers
no plural, etc) e crie nomes de actions e controllers que sejam legveis e tambm compreensveis. Voc
sempre vai poder mapear URLs para seu cdigo utilizando rotas, conforme mostraremos mais frente.
A nica declarao na nossa action utiliza o mtodo set() para passar dados do controller para a view
(que vamos criar logo mais). A linha dene uma varivel na view chamada posts que vai conter o retorno
da chamada do mtodo find(all) do model Post. Nosso model Post est automaticamente disponvel
como $this->Post uma vez que seguimos as convenes de nomenclatura do Cake.
Para aprender mais sobre controllers do CakePHP, conra a seo Controllers.
98 Captulo 9. Tutoriais & Exemplos
CakePHP Cookbook Documentation, Release 2.x
Criando as Views de Posts
Agora que temos nossos dados chegando ao nosso model e com a lgica da nossa aplicao denida em
nosso controller, vamos criar uma view para a ao index() que criamos acima.
As views do Cake so meros fragmentos voltados apresentao de dados que vo dentro do layout da
aplicao. Para a maioria das aplicaes, as views sero marcaes HTML intercalados com cdigo PHP,
mas as views tambm podem ser renderizadas como XML, CVS ou mesmo como dados binrios.
Os layouts so pginas que encapsulam as views e que podem ser intercambiveis, mas por agora, vamos
apenas usar o layout padro.
Lembra da ltima seo, em que associamos a varivel posts para a view usando o mtodo set()? Com
aquilo, os dados foram repassados para a view num formato parecido com este:
// print_r($posts) output:
Array
(
[0] => Array
(
[Post] => Array
(
[id] => 1
[title] => The title
[body] => This is the post body.
[created] => 2008-02-13 18:34:55
[modified] =>
)
)
[1] => Array
(
[Post] => Array
(
[id] => 2
[title] => A title once again
[body] => And the post body follows.
[created] => 2008-02-13 18:34:56
[modified] =>
)
)
[2] => Array
(
[Post] => Array
(
[id] => 3
[title] => Title strikes back
[body] => This is really exciting! Not.
[created] => 2008-02-13 18:34:57
[modified] =>
)
)
)
Blog - Continuao 99
CakePHP Cookbook Documentation, Release 2.x
Os arquivos de view do Cake so armazenados na pasta /app/View dentro de uma pasta com o mesmo
nome do controller a que correspondem (em nosso caso, vamos criar uma pasta chamada Posts). Para
apresentar os dados do post num formato adequado de tabela, o cdigo de nossa view deve ser algo como:
<!-- File: /app/View/Posts/index.ctp -->
<h1>Posts do Blog</h1>
<table>
<tr>
<th>Id</th>
<th>Ttulo</th>
<th>Data de Criao</th>
</tr>
<!-- Aqui onde ns percorremos nossa matriz $posts, imprimindo
as informaes dos posts -->
<?php foreach ($posts as $post): ?>
<tr>
<td><?php echo $post[Post][id]; ?></td>
<td>
<?php echo $this->Html->link($post[Post][title],
array(controller => posts, action => view, $post[Post][id])); ?>
</td>
<td><?php echo $post[Post][created]; ?></td>
</tr>
<?php endforeach; ?>
</table>
Isto to simples quanto parece!
Voc deve ter notado o uso de um objeto chamado $this->Html. Esta uma instncia da classe
HtmlHelper do CakePHP. O CakePHP vem com um conjunto de helpers que tornam uma moleza fazer
coisas como criar links, gerar formulrios, Javascript e elementos dinmicos com Ajax. Voc pode aprender
mais sobre como us-los na seo /views/helpers, mas o importante a ser notado aqui que o mtodo
link() ir gerar um link em HTML com o ttulo (o primeiro parmetro) e URL (o segundo parmetro)
dados.
Ao especicar URLs no Cake, recomendado que voc use o formato de array. Este assunto expli-
cado com mais detalhes na seo sobre Rotas. Usar o formato de array para URLs, permite que voc
tire vantagens da capacidade do CakePHP de reverter este formato de URL em URLs relativas e vice
versa. voc tambm pode simplesmente informar um caminho relativo base da aplicao na forma /con-
troller/action/parametro_1/parametro_2.
Neste ponto, voc deve ser capaz de apontar seu navegador para http://www.exemplo.com/posts/index. Voc
deve ver sua view, corretamente formatada com o ttulo e a tabela listando os posts.
Se lhe ocorreu clicar num dos links que criamos nesta view (no ttulo do post e que apontam para uma URL
/posts/view/algum_id), voc provavelmente recebeu uma mensagemdo CakePHP dizendo que a action ainda
no foi denida. Se voc no tiver visto um aviso assim, ento ou alguma coisa deu errado ou ento voc j
tinha denido uma action anteriormente, e neste caso, voc muito afoito. Se no, vamos cri-la em nosso
PostsController agora:
100 Captulo 9. Tutoriais & Exemplos
CakePHP Cookbook Documentation, Release 2.x
class PostsController extends AppController {
public $helpers = array(Html, Form);
public $name = Posts;
public function index() {
$this->set(posts, $this->Post->find(all));
}
public function view($id = null) {
$this->Post->id = $id;
$this->set(post, $this->Post->read());
}
}
A chamada do mtodo set() deve lhe parece familiar. Perceba que estamos usando o mtodo read() ao
invs do find(all) porque ns realmente s queremos informaes de um nico post.
Note que a action de nossa view recebe um parmetro: O ID do post que queremos ver. Este parmetro
repassado action por meio da URL requisitada. Se um usurio acessar uma URL /posts/view/3, ento o
valor 3 ser atribudo ao parmetro $id.
Agora vamos criar a view para nossa nova action view e coloc-la em/app/View/Posts/view.ctp:
<!-- File: /app/View/Posts/view.ctp -->
<h1><?php echo $post[Post][title]?></h1>
<p><small>Created: <?php echo $post[Post][created]?></small></p>
<p><?php echo $post[Post][body]?></p>
Conra se est funcionando tentando acessar os links em/posts/index ou requisitando diretamente um
post acessando /posts/view/1.
Adicionando Posts
Ler a partir da base de dados e exibir os posts foi um grande comeo, mas precisamos permitir tambm que
os usurios adicionem novos posts.
Primeiramente, comece criando uma action add() no PostsController:
class PostsController extends AppController {
public $helpers = array(Html, Form);
public $name = Posts;
public $components = array(Session);
public function index() {
$this->set(posts, $this->Post->find(all));
}
public function view($id) {
$this->Post->id = $id;
$this->set(post, $this->Post->read());
Blog - Continuao 101
CakePHP Cookbook Documentation, Release 2.x
}
public function add() {
if ($this->request->is(post)) {
if ($this->Post->save($this->request->data)) {
$this->Session->setFlash(Your post has been saved.);
$this->redirect(array(action => index));
}
}
}
}
Note: Voc precisa incluir o componente SessionComponent e o helper SessionHelper em qualquer con-
troller que voc manipula variveis de sesso. Neste caso, inclumos apenas o componente porque ele
carrega o helper automaticamente. Se voc sempre utiliza sesses, inclua o componente no seu arquivo
AppController.
Aqui est o que a action add() faz: se o mtodo da requisio feita pelo cliente for do tipo post, ou seja, se
ele enviou dados pelo formulrio, tenta salvar os dados usando o model Post. Se, por alguma razo ele no
salvar, apenas renderize a view. Isto nos d uma oportunidade de mostrar erros de validao e outros avisos
ao usurio.
Quando umusurio utiliza umformulrio para submeter (POSTar) dados para sua aplicao, esta informao
ca disponvel em$this->request->data.Voc pode usar as funes pr() ou debug() para exibir
os dados se voc quiser conferir como eles se parecem.
Ns usamos o mtodo SessionComponent::setFlash() do componente SessionComponent para
denir uma varivel de sesso com uma mensagem a ser exibida na pgina depois de ser redirecionada. No
layout, ns temos SessionHelper::flash que exibe a mensagem e limpa a varivel de sesso corre-
spondente. O mtodo Controller::redirect do controller redireciona para outra URL. O parmetro
array(action => index) convertido para a URL /posts, em outras palavras, a action index
do controller posts. Voc pode conferir a funo Router::url() na API para ver os formatos que voc
pode usar ao especicar uma URL para actions do CakePHP.
Chamar o mtodo save() ir vericar por erros de validao e abortar o salvamento se algum erro ocorrer.
Vamos falar mais sobre erros de validao e sobre como manipul-los nas sees seguintes.
Validao de Dados
O CakePHP percorreu uma longa estrada combatendo a monotonia da validao de dados de formulrios.
Todo mundo detesta codicar formulrios interminveis e suas rotinas de validao. O CakePHP torna tudo
isso mais fcil e mais rpido.
Para usufruir das vantagens dos recursos de validao, voc vai precisar usar o FormHelper do Cake em suas
views. O FormHelper est disponvel por padro em todas as suas views na varivel $this->Form.
Aqui est nossa view add:
<!-- File: /app/View/Posts/add.ctp -->
102 Captulo 9. Tutoriais & Exemplos
CakePHP Cookbook Documentation, Release 2.x
<h1>Add Post</h1>
<?php
echo $this->Form->create(Post);
echo $this->Form->input(title);
echo $this->Form->input(body, array(rows => 3));
echo $this->Form->end(Save Post);
Aqui, usamos o FormHelper para gerar a tag de abertura para um formulrio. Aqui est o HTML gerado
pelo $this->Form->create():
<form id="PostAddForm" method="post" action="/posts/add">
Se o mtodo create() for chamado sem quaisquer parmetros, o CakePHP assume que voc est criando
um formulrio que submete para a action add() do controller atual (ou para a action edit() se um campo
id for includo nos dados do formulrio), via POST.
O mtodo $this->Form->input() usado para criar elementos de formulrio de mesmo nome. O
primeiro parmetro informa ao CakePHP qual o campo correspondente e o segundo parmetro permite que
voc especique um extenso array de opes. Neste caso, o nmero de linhas para o textarea. H alguma
introspeco automgica envolvida aqui: o input() ir exibir diferentes elementos de formulrio com
base no campo do model em questo.
A chamada $this->Form->end() gera um boto de submisso e encerra o formulrio. Se uma
string for informada como primeiro parmetro para o end(), o FormHelper exibe um boto de submit
apropriadamente rotulado junto com a tag de fechamento do formulrio. Novamente, conra o captulo
sobre os /views/helpers disponveis no CakePHP para mais informaes sobre os helpers.
Agora vamos voltar e atualizar nossa view /app/View/Post/index.ctp para incluir um novo link
para Adicionar Post. Antes de <table>, adicione a seguinte linha:
echo $this->Html->link(Add Post, array(controller => posts, action => add));
Voc pode estar imaginando: como eu informo ao CakePHP sobre os requisitos de validao de meus dados?
Regras de validao so denidas no model. Vamos olhar de volta nosso model Post e fazer alguns pequenos
ajustes:
class Post extends AppModel {
public $name = Post;
public $validate = array(
title => array(
rule => notEmpty
),
body => array(
rule => notEmpty
)
);
}
O array $validate diz ao CakePHP sobre como validar seus dados quando o mtodo save() for
chamado. Aqui, eu especiquei que tanto os campos body e title no podem ser vazios. O mecanismo
de validao do CakePHP robusto, com diversas regras predenidas (nmeros de carto de crdito, en-
dereos de e-mail, etc.) alm de ser bastante exvel, permitindo adicionar suas prprias regras de validao.
Blog - Continuao 103
CakePHP Cookbook Documentation, Release 2.x
Para mais informaes, conra o captulo sobre /models/data-validation.
Agora que voc incluiu as devidas regras de validao, tente adicionar umpost comum ttulo ou com o corpo
vazio para ver como funciona. Uma vez que usamos o mtodo FormHelper::input() do FormHelper
para criar nossos elementos de formulrio, nossas mensagens de erros de validao sero mostradas auto-
maticamente.
Editando Posts
Edio de Posts: Aqui vamos ns. A partir de agora voc j um prossional do CakePHP, ento voc deve
ter identicado um padro. Criar a action e ento criar a view. Aqui est como o cdigo da action edit()
do PostsController deve se parecer:
function edit($id = null) {
$this->Post->id = $id;
if ($this->request->is(get)) {
$this->request->data = $this->Post->read();
} else {
if ($this->Post->save($this->request->data)) {
$this->Session->setFlash(Your post has been updated.);
$this->redirect(array(action => index));
}
}
}
Esta action primeiro verica se a requisio do tipo GET. Se for, ns buscamos o Post e passamos para a
view. Se a requisio no for do tipo GET, provavelmente esta contm dados de um formulrio POST. Ns
usaremos estes dados para atualizar o registro do nosso Post ou exibir novamente a view mostrando para o
usurio os erros de validao.
A view edit pode ser algo parecido com isto:
<!-- File: /app/View/Posts/edit.ctp -->
<h1>Edit Post</h1>
<?php
echo $this->Form->create(Post, array(action => edit));
echo $this->Form->input(title);
echo $this->Form->input(body, array(rows => 3));
echo $this->Form->input(id, array(type => hidden));
echo $this->Form->end(Save Post);
Esta view exibe o formulrio de edio (com os valores populados), juntamente com quaisquer mensagens
de erro de validao.
Uma coisa a atentar aqui: o CakePHP vai assumir que voc est editando um model se o campo id estiver
presente no array de dados. Se nenhum id estiver presente (como a view add de insero), o Cake ir
assumir que voc est inserindo um novo model quando o mtodo save() for chamado.
Voc agora pode atualizar sua view index com os links para editar os posts especcos:
104 Captulo 9. Tutoriais & Exemplos
CakePHP Cookbook Documentation, Release 2.x
<!-- File: /app/View/Posts/index.ctp (links para edio adicionados) -->
<h1>Blog posts</h1>
<p><?php echo $this->Html->link("Add Post", array(action => add)); ?></p>
<table>
<tr>
<th>Id</th>
<th>Title</th>
<th>Action</th>
<th>Created</th>
</tr>
<!-- Aqui onde ns percorremos nossa matriz $posts, imprimindo
as informaes dos posts -->
<?php foreach ($posts as $post): ?>
<tr>
<td><?php echo $post[Post][id]; ?></td>
<td>
<?php echo $this->Html->link($post[Post][title], array(action => view, $post[Post][id]));?>
</td>
<td>
<?php echo $this->Form->postLink(
Delete,
array(action => delete, $post[Post][id]),
array(confirm => Are you sure?)
)?>
<?php echo $this->Html->link(Edit, array(action => edit, $post[Post][id]));?>
</td>
<td><?php echo $post[Post][created]; ?></td>
</tr>
<?php endforeach; ?>
</table>
Deletando Posts
A seguir, vamos criar uma maneira para os usurios exclurem posts. Comece com uma action delete()
no PostsController:
function delete($id) {
if (!$this->request->is(post)) {
throw new MethodNotAllowedException();
}
if ($this->Post->delete($id)) {
$this->Session->setFlash(The post with id: . $id . has been deleted.);
$this->redirect(array(action => index));
}
}
Esta lgica exclui o post dado por $id, e utiliza $this->Session->setFlash() para mostrar uma
mensagem de conrmao para o usurio depois de redirecion-lo para /posts.
Blog - Continuao 105
CakePHP Cookbook Documentation, Release 2.x
Se o usurio tentar deletar um post usando uma requisio do tipo GET, ns lanamos uma exceo. Ex-
cees no apanhadas so capturadas pelo manipulador de excees do CakePHP e uma pgina de erro
amigvel mostrada. O CakePHP vem com muitas /development/exceptions que voc pode usar
para indicar vrios tipos de erros HTTP que sua aplicao pode precisar gerar.
Como estamos executando apenas uma lgica de negcio e redirecionando, esta action no tem uma view.
Voc pode querer atualizar sua view index com links que permitam ao usurios excluir posts, porm, como
um link executa uma requisio do tipo GET, nossa action ir lanar uma exceo. Precisamos ento criar
um pequeno formulrio que enviar um mtodo POST adequado. Para estes casos o helper FormHelper
fornece o mtodo postLink():
<!-- File: /app/View/Posts/index.ctp -->
<h1>Blog posts</h1>
<p><?php echo $this->Html->link(Add Post, array(action => add)); ?></p>
<table>
<tr>
<th>Id</th>
<th>Title</th>
<th>Actions</th>
<th>Created</th>
</tr>
<!-- Aqui onde ns percorremos nossa matriz $posts, imprimindo
as informaes dos posts -->
<?php foreach ($posts as $post): ?>
<tr>
<td><?php echo $post[Post][id]; ?></td>
<td>
<?php echo $this->Html->link($post[Post][title], array(action => view, $post[Post][id]));?>
</td>
<td>
<?php echo $this->Form->postLink(
Delete,
array(action => delete, $post[Post][id]),
array(confirm => Are you sure?));
?>
</td>
<td><?php echo $post[Post][created]; ?></td>
</tr>
<?php endforeach; ?>
</table>
Note: O cdigo desta view tambm utiliza o HtmlHelper para solicitar uma conrmao do usurio com
um dilogo em Javascript antes de tentar excluir o post.
106 Captulo 9. Tutoriais & Exemplos
CakePHP Cookbook Documentation, Release 2.x
Rotas
Para alguns, o roteamento padro do CakePHP funcionar muito bem. Os desenvolvedores que estiverem
mais afeitos a criar produtos ainda mais amigveis aos usurios e aos mecanismos de busca iro gostar da
maneira que as URLs do CakePHP so mapeadas para actions especcas. Ento vamos fazer uma pequena
alterao de rotas neste tutorial.
Para mais informaes sobre tcnicas avanadas de roteamento, veja routes-conguration.
Por padro, o CakePHP responde a requisies para a raiz de seu site (i.e. http://www.exemplo.com) usando
seu PagesController e renderizando uma view chamada de home. Ao invs disso, vamos substituir isto
por nosso PostsController criando uma regra de roteamento.
As rotas do Cake so encontrada no arquivo /app/Config/routes.php. Voc vai querer comentar ou
remover a linha que dene a rota raiz padro. Ela se parece com:
Router::connect(/, array(controller => pages, action => display, home));
Esta linha conecta a URL / com a home page padro do CakePHP. Queremos conect-la com nosso prprio
controller, ento adicionamos uma linha parecida com isto:
Router::connect(/, array(controller => posts, action => index));
Isto deve conectar as requisies de / action index() que criaremos em nosso PostsController.
Note: O CakePHP tambm faz uso do roteamento reverso - se, com a rota denida acima, voc passar
array(controller => posts, action => index) a um mtodo que espere um
array, a URL resultante ser /. sempre uma boa ideia usar arrays para URLs, j que a partir disto que
suas rotas denem para onde suas URLs apontam, alm de garantir que os links sempre apontem para o
mesmo lugar.
Concluso
Criar aplicaes desta maneira ir lhe trazer paz, honra, amor e dinheiro alm de satisfazer s suas mais
ousadas fantasias. Simples, no? Tenha em mente que este tutorial foi muito bsico. O CakePHP possui
muito mais recursos a oferecer e exvel de tantas maneiras que no conseguimos mostrar aqui por questes
de simplicidade. Utilize o resto deste manual como guia para construir mais aplicaes ricas em recursos.
Agora que voc criou uma aplicao bsica com o Cake, voc est pronto para a coisa real. Comece seu
prprio projeto, leia o restante do Manual e da API
4
.
E se voc precisar de ajuda, nos vemos no canal #cakephp (e no #cakephp-pt). Seja bem-vindo ao CakePHP!
Leitura Recomendada
Estas so as tarefas comuns que pessoas aprendendo o CakePHP geralmente querem estudar:
1. Layouts: Customizando o layout do seu website
4
http://api20.cakephp.org
Blog - Continuao 107
CakePHP Cookbook Documentation, Release 2.x
2. Elements Incluindo e reutilizando trechos de cdigo
3. Scaffolding (arcabouos): Prototipando antes de programar
4. /console-and-shells/code-generation-with-bake Gerando cdigo CRUD bsico
5. Autenticao simples e Autorizao da Aplicao: Tutorial de autenticao e autorizao de usurios
Autenticao simples e Autorizao da Aplicao
Seguindo com nosso exemplo do Blog, imagine que queremos fornececer acesso seguro s nossas urls,
baseada em autenticao de usurio. Ns tambm temos outro requisito, permitir que muitos autores possam
criar seus prprios posts, editar e deletar os post deles sem que afete o que os outros autores zeram em seus
posts.
Criando a tabela de usurios
Primeiro, vamos criar uma nova tabela na nossa base de dados do blog para armazenar os dados de usurios:
CREATE TABLE users (
id INT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
username VARCHAR(50),
password VARCHAR(50),
role VARCHAR(20),
created DATETIME DEFAULT NULL,
modified DATETIME DEFAULT NULL
);
Ns respeitamos as convenes do CakePHP para nomear tabelas, mas tambm aproveitamos outra con-
veno: usando as colunas username e password em nossa tabela users, o CakePHP ser capaz de auto
congurar as coisas quando implementarmos os mecanismos de login de nossos usurios.
A prxima etapa criar o nosso model User, responsvel pelas pesquisas, gravaes e validaes de dados
dos usurios:
// app/Model/User.php
class User extends AppModel {
public $name = User;
public $validate = array(
username => array(
required => array(
rule => array(notEmpty),
message => A username is required
)
),
password => array(
required => array(
rule => array(notEmpty),
message => A password is required
)
),
108 Captulo 9. Tutoriais & Exemplos
CakePHP Cookbook Documentation, Release 2.x
role => array(
valid => array(
rule => array(inList, array(admin, author)),
message => Please enter a valid role,
allowEmpty => false
)
)
);
}
Vamos criar tambmnosso UsersController, o contedo a seguir corresponde classe UsersController bsica
cozida usando a ferramenta de gerao de cdigos presente no CakePHP:
// app/Controller/UsersController.php
class UsersController extends AppController {
public function beforeFilter() {
parent::beforeFilter();
$this->Auth->allow(add, logout);
}
public function index() {
$this->User->recursive = 0;
$this->set(users, $this->paginate());
}
public function view($id = null) {
$this->User->id = $id;
if (!$this->User->exists()) {
throw new NotFoundException(__(Invalid user));
}
$this->set(user, $this->User->read(null, $id));
}
public function add() {
if ($this->request->is(post)) {
$this->User->create();
if ($this->User->save($this->request->data)) {
$this->Session->setFlash(__(The user has been saved));
$this->redirect(array(action => index));
} else {
$this->Session->setFlash(__(The user could not be saved. Please, try again.));
}
}
}
public function edit($id = null) {
$this->User->id = $id;
if (!$this->User->exists()) {
throw new NotFoundException(__(Invalid user));
}
if ($this->request->is(post) || $this->request->is(put)) {
Autenticao simples e Autorizao da Aplicao 109
CakePHP Cookbook Documentation, Release 2.x
if ($this->User->save($this->request->data)) {
$this->Session->setFlash(__(The user has been saved));
$this->redirect(array(action => index));
} else {
$this->Session->setFlash(__(The user could not be saved. Please, try again.));
}
} else {
$this->request->data = $this->User->read(null, $id);
unset($this->request->data[User][password]);
}
}
public function delete($id = null) {
if (!$this->request->is(post)) {
throw new MethodNotAllowedException();
}
$this->User->id = $id;
if (!$this->User->exists()) {
throw new NotFoundException(__(Invalid user));
}
if ($this->User->delete()) {
$this->Session->setFlash(__(User deleted));
$this->redirect(array(action => index));
}
$this->Session->setFlash(__(User was not deleted));
$this->redirect(array(action => index));
}
Da mesma forma criamos as views para nossos posts no blog ou usando a ferramanta de gerao de cdigo,
ns implementamos as views. Para o propsito de nosso tutorial, iremos mostrar somente o add.ctp:
<!-- app/View/Users/add.ctp -->
<div class="users form">
<?php echo $this->Form->create(User);?>
<fieldset>
<legend><?php echo __(Add User); ?></legend>
<?php echo $this->Form->input(username);
echo $this->Form->input(password);
echo $this->Form->input(role, array(
options => array(admin => Admin, author => Author)
));
?>
</fieldset>
<?php echo $this->Form->end(__(Submit));?>
</div>
Autorizao (login e logout)
Ns agora estamos prontos para adicionar a camada de autorizao. No CakePHP isso feito pela
AuthComponent, uma classe responsvel por solicitar login para certas aes, manipulando sign-in e
sign-out, e tambm autorizando usurios logados a acessarem actions as quais possuem permisso.
110 Captulo 9. Tutoriais & Exemplos
CakePHP Cookbook Documentation, Release 2.x
Para adicionar esse componente em sua aplicao abra seu arquivo
app/Controller/AppController.php e adicione as seguintes linhas:
// app/Controller/AppController.php
class AppController extends Controller {
//...
public $components = array(
Session,
Auth => array(
loginRedirect => array(controller => posts, action => index),
logoutRedirect => array(controller => pages, action => display, home)
)
);
function beforeFilter() {
$this->Auth->allow(index, view);
}
//...
}
Aqui no h muito para congurar, como ns usamos convenes na tabela users. Ns somente cong-
uramos as urls que sero carregadas aps as aes de login e logout, em nosso caso so /posts/ e /
respectivamente.
O que zemos na funo beforeFilter foi dizer ao AuthComponent para no solicitar um login para
todas as actions index e view, em todos os controller. Ns queremos que nossos visitantes possam ler
qualquer post sem precisar se registrar no site.
Agora, ns precisamos autorizar que novos usurios possam se registrar, salvando o nome de usurio e a
senha deles, e o mais importante encriptar a senha pra que ela no seja armazenada como texto plano em
nosso banco de dados. Vamos dizer ao AuthComponet para permitir que usurios deslogados acessem a
funo add e implementar a ao de login e logout:
// app/Controller/UsersController.php
public function beforeFilter() {
parent::beforeFilter();
$this->Auth->allow(add); // Permitindo que os usurios se registrem
}
public function login() {
if ($this->Auth->login()) {
$this->redirect($this->Auth->redirect());
} else {
$this->Session->setFlash(__(Invalid username or password, try again));
}
}
public function logout() {
$this->redirect($this->Auth->logout());
}
Hash da senha no foi feito ainda, abra o seu arquivo de model app/Model/User.php e adicione o
Autenticao simples e Autorizao da Aplicao 111
CakePHP Cookbook Documentation, Release 2.x
seguinte:
// app/Model/User.php
App::uses(AuthComponent, Controller/Component);
class User extends AppModel {
// ...
public function beforeSave($options = array()) {
if (isset($this->data[$this->alias][password])) {
$this->data[$this->alias][password] = AuthComponent::password($this->data[$this->alias][password]);
}
return true;
}
// ...
Ento, agora toda vez que um usurio for salvo, a senha ser encriptada usando o hashing padro disponi-
bilizado pela classe AuthComponent. Est faltando somente um arquivo view para a funo de login, Aqui
est ele:
<div class="users form">
<?php echo $this->Session->flash(auth); ?>
<?php echo $this->Form->create(User);?>
<fieldset>
<legend><?php echo __(Please enter your username and password); ?></legend>
<?php echo $this->Form->input(username);
echo $this->Form->input(password);
?>
</fieldset>
<?php echo $this->Form->end(__(Login));?>
</div>
Voc pode registrar um novo usurio acessando a url /users/add e autenticar com as credenciais do
usurio recm criado indo para a url /users/login. Tente tambm acessar qualquer outra url sem que
a permiso tenha sido explicitada, como em /posts/add, voc ver que a aplicao ir redirecion-lo
automaticamente para a pgina de login.
E isso! Parece simples demais para ser verdade. Vamos voltar um pouco para explicar o que aconteceu.
A funo beforeFilter est falando para o AuthComponent no solicitar um login para a ao add
em adio as aes index e view que foram prontamente autorizadas na funo beforeFilter do
AppController.
A ao de login chama a funo $this->Auth->login() do AuthComponent, e ele funciona sem
qualquer congurao adicional porque seguimos as convenes mencionadas anteriormente. Isso , temos
um model User com uma coluna username e uma password, e usamos um form para postar os dados do
usurio para o controller. Essa funo retorna se o login foi bem sucedido ou no, e caso ela retorne sucesso,
ento ns redirecionamos o usurio para a url que conguramos quando adicionamos o AuthComponent em
nossa aplicao.
O logout funciona exatamente quando acessamos a url /users/logout e ir redirecionar o usurio
para a url congurada em logoutUrl anteriormente descrita. Essa url acionada quando a funo
AuthComponent::logout() obtm sucesso.
112 Captulo 9. Tutoriais & Exemplos
CakePHP Cookbook Documentation, Release 2.x
Autorizao (quem tem permisso de acessar o que)
Como armado anteriormente, ns estamos convertendo esse blog em uma ferramenta multi usurio de
autoria, e para fazer isso, ns precisamos modicar um pouco a tabela posts para adicionar a referncia ao
model User:
ALTER TABLE posts ADD COLUMN user_id INT(11);
Tambm, necessria uma pequena mudana no PostsController para guardar a referncia do usurio logado
para o post criado:
// app/Controller/PostsController.php
public function add() {
if ($this->request->is(post)) {
$this->request->data[Post][user_id] = $this->Auth->user(id); // Adicionada essa linha
if ($this->Post->save($this->request->data)) {
$this->Session->setFlash(Your post has been saved.);
$this->redirect(array(action => index));
}
}
}
A funo user() fornecida pelo component retorna qualquer coluna do usurio logado no momento. Ns
usamos esse metdo para adicionar a informao dentro de request data para que ela seja salva.
Vamos garantir que nossa app evite que alguns autores editem ou apaguem posts de outros. Uma regra
bsica para nossa aplicao que usurios admin possam acessar qualquer url, enquanto usurios normais
(o papel author) podem somente acessar as actions permitidas. Abra novamente a classe AppController e
adicione um pouco mais de opes para as conguraes do Auth:
// app/Controller/AppController.php
public $components = array(
Session,
Auth => array(
loginRedirect => array(controller => posts, action => index),
logoutRedirect => array(controller => pages, action => display, home),
authorize => array(Controller) // Adicionamos essa linha
)
);
public function isAuthorized($user) {
if (isset($user[role]) && $user[role] === admin) {
return true; // Admin pode acessar todas actions
}
return false; // Os outros usurios no podem
}
Ns acabamos de criar um mecanismo de autorizao muito simples. Nesse caso os usurios com papel
admin podero acessar qualquer url no site quando estiverem logados, mas o restante dos usurios (i.e o
papel author) no podem acessar qualquer coisa diferente dos usurios no logados.
Isso no exatamente o que ns queremos, por isso precisamos corrigir nosso metdo isAuthorized()
para fornecer mais regras. Mas ao invs de fazer isso no AppController, vamos delegar a cada con-
Autenticao simples e Autorizao da Aplicao 113
CakePHP Cookbook Documentation, Release 2.x
troller para suprir essas regras extras. As regras que adicionaremos para o add de PostsController deve
permitir ao autores criarem os posts mas evitar a edio de posts que no sejam deles. Abra o arquivo
PostsController.php e adicione o seguinte contedo:
// app/Controller/PostsController.php
public function isAuthorized($user) {
if (!parent::isAuthorized($user)) {
if ($this->action === add) {
// Todos os usurios registrados podem criar posts
return true;
}
if (in_array($this->action, array(edit, delete))) {
$postId = (int) $this->request->params[pass][0];
return $this->Post->isOwnedBy($postId, $user[id]);
}
}
return false;
}
Ns estamos sobreescrevendo a chamada do isAuthorized() do AppController e internamente verif-
icando na classe pai se o usurio est autorizado. Caso ele no esteja, permitiremos acesso ao add, e
condicionamente acesso s aes edit e delete. A ltima coisa que falta implementar, dizer se usurio
autorizado a editar o post ou no, ns estamos chamando a funo isOwnedBy() no model Post. Mover
lgica para dentro dos models normalmente uma boa prtica. Vamos ento implementar essa funo:
// app/Model/Post.php
public function isOwnedBy($post, $user) {
return $this->field(id, array(id => $post, user_id => $user)) === $post;
}
Isso conclui ento nossa autorizao simples e nosso tutorial de autorizao. Para garantir o UsersController
voc pode seguir as mesmas tcnicas que usamos para PostsController, voc tambm pode ser mais criativo
e codicar algumas coisas mais gerais no AppController para suas prprias regras baseadas em papis.
Se precisar de mais controle, ns sugerimos que leia o guia completo do Auth
/core-libraries/components/authentication seo onde voc encontrar mais sobre
a congurao do componente, criao de classes de Autorizao customizadas, e muito mais.
Sugerimos as seguintes leituras
1. /console-and-shells/code-generation-with-bake Generating basic CRUD code
2. /core-libraries/components/authentication: User registration and login
114 Captulo 9. Tutoriais & Exemplos
CAPTULO 10
Apndices
Os apndices contm informaes sobre os novos recursos introduzidos na verso 2.0 e o guia de migrao
da verso 1.3 para a verso 2.0.
Guia de Migrao para a Verso 2.0
Guia de Migrao para a Verso 2.1
Guia de Migrao para a Verso 2.1
O CakePHP 2.1 um atualizao totalmente compatvel com API do 2.0. Esta pgina apresenta as mudanas
e melhorias feitas no 2.1.
AppController, AppHelper, AppModel and AppShell
Como essas classes foram removidas do ncleo do CakePHP, agora elas so obrigatrias em sua aplicao.
Se voc no tiver essas classes, voc pode usar o seguinte durante a atualizao:
// app/View/Helper/AppHelper.php
App::uses(Helper, View);
class AppHelper extends Helper {
}
// app/Model/AppModel.php
App::uses(Model, Model);
class AppModel extends Model {
}
// app/Controller/AppController.php
App::uses(Controller, Controller);
class AppController extends Controller {
}
115
CakePHP Cookbook Documentation, Release 2.x
// app/Console/Command/AppShell.php
App::uses(Shell, Console);
class AppShell extends Shell {
}
Se sua aplicao j tiver esses arquivos/classes voc no precisa fazer nada. Alm disso, se voc estiver
utilizando o PagesController do ncleo do CakePHP, voc precisa copi-lo para a pasta app/Controller tam-
bm.
Arquivos .htaccess
Os arquivos .htaccess foram alterados, voc deve lembrar de atuliz-los ou a atualizar o esquema de
reescrita de URL re-writing para combinar com as atualizaes feitas.
Models
O callbackbeforeDelete ser disparado antes dos callbacks beforeDelete dos behaviors. Isto o
torna consistente com o resto dos eventos disparados na camada de modelo.
O mtodo Model::find(threaded) agora aceita o parmetro $options[parent] se
estiver usando outro campo como parent_id. Alm disso, se o model tem o TreeBehavior e con-
gurado com outro campo denido para o pai, o threaded ir encontr-lo e o utilizar por padro.
Parmetros para consultas usando instrues preparadas (prepared statements) agora ser
parte do dump SQL.
Arrays de validao agora podem ser mais especcos quando um campo obrigatrio. A chave
required agora aceita create e update. Esses valores faro o campo obrigatrio quando criar
ou atualizar.
Behaviors
TranslateBehavior
I18nModel foi movida para um arquivo separado.
Excees
A renderizao padro de excees agora inclui os stack traces mais detalhados, incluindo trechos de ar-
quivos e os argumentos para todas as funes.
116 Captulo 10. Apndices
CakePHP Cookbook Documentation, Release 2.x
Utilidade
Debugger
Debugger::getType() foi adicionada. Pode ser utilizada para obter o tipo das variveis.
Debugger::exportVar() foi modicada para criar uma sada mais legvel e til.
debug()
debug() agora utiliza Debugger internamente. Isto o torna mais consistente como Debugger, e tira proveito
das melhorias feitas l.
Set
Set::nest() foi adicionada. Recebe uma matriz simples e retorna uma matriz aninhada.
File
File::info() inclui o tamanho do arquivo e o seu mimetype.
File::mime() foi adicionada.
Cache
CacheEngine foi movida para um arquivo separado.
Congure
ConfigReaderInterface foi movida para um arquivo separado.
App
App::build() agora tem a capacidade de registrar novos pacotes usando App::REGISTER. Veja
app-build-register para mais informaes.
As classes que no podem ser encontradas nos caminhos congurados sero pesquisados dentro de
APP, como um caminho alternativo. Isso torna o carregamento automtico dos diretrios aninhados
em app/Vendedor mais fcil.
Guia de Migrao para a Verso 2.1 117
CakePHP Cookbook Documentation, Release 2.x
Console
Test Shell
Um novo TestShell foi adicionado. Ele reduz a digitao necessria para executar os testes unitrios, e
oferece uma interface baseada nos caminhos dos arquivos:
# Run the post model tests
Console/cake test app/Model/Post.php
Console/cake test app/Controller/PostsController.php
O antigo shell testsuite e sua sintaxe ainda esto disponveis.
General
Arquivos gerados no contm timestamps com o dia/hora da gerao.
Rotas
Router
As rotas agora podem usar uma sintaxe especial /
**
para incluir todos os argumentos nais como
um nico argumento passado. Veja a seo sobre connecting-routes para mais informaes.
Router::resourceMap() foi adicionada.
Router::defaultRouteClass() foi adicionada. Este mtodo permite que voc dena a classe
padro usada para todas as rotas denidas.
Network
CakeRequest
Adicionado is(requested) e isRequested() para a deteco de requestAction.
CakeResponse
Adicionado CakeResponse::cookie() para a congurao de cookies.
Foi adicionada uma srie de mtodos para cake-response-caching
118 Captulo 10. Apndices
CakePHP Cookbook Documentation, Release 2.x
Controller
Controller
O Controller::$uses foi modicado, seu valor padro agora true em vez de false. Alm
disso, valores diferentes so tratados de maneira ligeiramente diferente, mas ir comportar o mesmo
na maioria dos casos.
true Ir carregar o modelo padro e mesclar com AppController.
Um array ir carregar os modelos e mesclar com AppController.
An empty array will not load any models other than those declared in the base class.
Um array vazio no vai carregar outros modelos que no os declarados na classe base.
false no ir carregar qualquer modelo, e no vai se fundir com a classe base tambm.
Componentes
AuthComponent
AuthComponent::allow() no aceita mais allow(
*
) como um curinga para todas as
aes. Basta usar allow(). Isso unica a API entre allow() e deny().
A opo recursive foi adicionada a todos os adaptadores de autenticao. Permite controlar mais
facilmente as associaes armazenados na sesso.
AclComponent
AclComponent no mais inexiona o nome da classe usada para Acl.classname. Em vez disso
utiliza o valor como fornecido.
Implementaes do Acl agora devem ser colocadas em Controller/Component/Acl.
Implementaes do Acl agora devem ser movidas da pasta Component para a pasta
Component/Acl. Por exemplo: se sua classe Acl se chama CustomAclComponent, e
est em Controller/Component/CustomAclComponent.php. Ela deve ser movida para
Controller/Component/Acl/CustomAcl.php e renomeada para CustomAcl.
DbAcl foi movida para um arquivo separado.
IniAcl foi movida para um arquivo separado.
AclInterface foi movida para um arquivo separado.
Guia de Migrao para a Verso 2.1 119
CakePHP Cookbook Documentation, Release 2.x
Helpers
TextHelper
TextHelper::autoLink(), TextHelper::autoLinkUrls(),
TextHelper::autoLinkEmails() escapa o HTML por padro. Voc pode controlar
este comportamento com a opo escape.
HtmlHelper
HtmlHelper::script() teve a opo block adicionada.
HtmlHelper::scriptBlock() teve a opo block adicionada.
HtmlHelper::css() teve a opo block adicionada.
HtmlHelper::meta() teve a opo block adicionada.
O parmetro $startText do HtmlHelper::getCrumbs() pode ser um array. Isto d mais
controle e exibilidade.
HtmlHelper::docType() o padro agora o html5
HtmlHelper::image() agora tem a opo fullBase.
HtmlHelper::media() foi adicionado. Voc pode usar este mtodo para criar elementos de
vdeo/audio do HTML5.
O suporte a plugin syntax foi adicionado nos mtodos HtmlHelper::script(),
HtmlHelper::css(), HtmlHelper::image(). Agora voc pode facilmente vincular
recursos de plugins usando Plugin.asset.
HtmlHelper::getCrumbList() teve o parmetro $startText adicionado.
View
View::$output est obsoleto.
$content_for_layout est obsoleto. Use $this->fetch(content); instead.
$scripts_for_layout est obsoleto. Use o seguinte:
echo $this->fetch(meta);
echo $this->fetch(css);
echo $this->fetch(script);
$scripts_for_layout ainda est disponvel, mas a API view blocks API mais exvel e ex-
tensvel.
A sintaxe Plugin.view est agora disponvel em todos os lugares. Voc pode usar esta sintaxe em
qualquer lugar que voc zer referncia ao nome de uma view, layout ou element.
120 Captulo 10. Apndices
CakePHP Cookbook Documentation, Release 2.x
A opo $options[plugin] para element() est obsoleta. Em vez disso voc deve utilizar
Plugin.element_name.
Content type views
Duas classes de exibio foram adicionadas ao CakePHP. A JsonView e a XmlView permite
gerar facilmente views XML e JSON. Voc pode aprender mais sobre essas classes na seo
/views/json-and-xml-views.
Estendendo as views
View has a new method allowing you to wrap or extend a view/element/layout with another le. See the
section on Estendendo Views for more information on this feature.
Temas
A classe ThemeView est obsoleta em favor da classe View. Simplesmente dena o $this->theme =
MyTheme que o suporte a temas ser habilitado, e todas as classes de View personalizadas que estendem
da ThemeView deve estender de View.
Blocos de View
Blocos de View so uma maneira exvel de criar slots ou blocos em suas views. Os blocos substituem
$scripts_for_layout com uma API mais robusta e exvel. Consulte a seo sobre Usando Blocos
de Views (Vises) para mais informaes.
Helpers
Novos callbacks
Dois novos callbacks foram adicionados aos Helpers. Helper::beforeRenderFile() e
Helper::afterRenderFile() esses novos callbacks so disparados antes/depois que cada fragmento
da view renderizado. Isto inclui elements, layouts e views.
CacheHelper
As tags <!--nocache--> agora funcionam corretamente dentro dos elementos.
FormHelper
O FormHelper agora omite campos desabilitados a partir do hash dos campos protegidos. Isso torna
o trabalho com SecurityComponent e os inputs desabilitados mais fcil.
Guia de Migrao para a Verso 2.1 121
CakePHP Cookbook Documentation, Release 2.x
A opo between quando utilizado em conjunto com os radio inputs, agora se comporta de forma
diferente. O valor do between agora colocado entre a legenda e o primeiro input.
A opo hiddenField dos campos checkbox pode agora ser denida para um valor especco,
como N ao invs de apenas 0.
O atributo for para campos datetime agora reete o primeiro campo gerado. Isso pode resultar na
mudana do atributo for de acordo com os campo geradas.
O atributo type para FormHelper::button() pode ser removido agora. O padro ainda
submit.
FormHelper::radio() agora permite que voc desabilite todas as opes. Voc pode
fazer isso denindo disabled => true ou disabled => disabled no array
$attributes.
PaginatorHelper
PaginatorHelper::numbers() agora possui a opo currentClass.
Testando
Web test runner agora exibe a verso do PHPUnit.
Web test runner agora mostra os testes da aplicao por padro.
Fixtures podem ser criados em datasources que no seja $test.
Modelos carregados usando o ClassRegistry e usando outro datasource vai ter o nome de seu
datasource prexado com test_ (por exemplo, o datasource master ir tentar usar test_master
no testsuite)
Os casos de teste so gerados com os mtodos de congurao especcos.
Eventos
Um novo sistema de eventos genrico foi construdo e que substituiu a forma como callbacks so
disparados. Isso no deve representar qualquer alterao em seu cdigo.
Voc pode enviar seus prprios eventos e callbacks para serem anexados, til para a comunicao
entre plugins e fcil desacoplamento de suas classes.
Migrando da Verso 1.2 para 1.3
Informaes Gerais
122 Captulo 10. Apndices
CAPTULO 11
Indices and tables
genindex
modindex
123
CakePHP Cookbook Documentation, Release 2.x
124 Captulo 11. Indices and tables
Index
Symbols
$this->request, 52
$this->response, 58
__construct() (Component method), 68
A
acceptLanguage() (CakeRequest method), 58
accepts() (CakeRequest method), 57
addDetector() (CakeRequest method), 57
addScript() (View method), 79
afterFilter() (Controller method), 43
afterScaffoldSave() (Controller method), 46
afterScaffoldSaveError() (Controller method), 46
append() (View method), 79
assign() (View method), 79
B
base (CakeRequest property), 58
beforeFilter() (Controller method), 43
beforeRedirect() (Component method), 68
beforeRender() (Component method), 68
beforeRender() (Controller method), 43
beforeScaffold() (Controller method), 46
Blocks (View property), 80
blocks() (View method), 79
body() (CakeResponse method), 61
C
cache() (CakeResponse method), 61
cacheAction (Controller property), 52
CakeRequest (class), 56
CakeResponse (class), 61
charset() (CakeResponse method), 61
clientIp() (CakeRequest method), 57
Component (class), 68
components (Controller property), 52
compress() (CakeResponse method), 61
constructClasses() (Controller method), 47
Controller (class), 43
D
data (CakeRequest property), 58
data() (CakeRequest method), 57
disableCache() (CakeResponse method), 61
disableCache() (Controller method), 47
domain() (CakeRequest method), 56
download() (CakeResponse method), 61
E
element() (View method), 79
elementCache (View property), 80
end() (View method), 79
extend() (View method), 80
F
fetch() (View method), 79
ash() (Controller method), 46
G
getVar() (View method), 78
getVars() (View method), 78
H
header() (CakeRequest method), 57
header() (CakeResponse method), 61
helpers (Controller property), 51
here (CakeRequest property), 58
125
CakePHP Cookbook Documentation, Release 2.x
host() (CakeRequest method), 57
I
initialize() (Component method), 68
input() (CakeRequest method), 57
is() (CakeRequest method), 57
L
layout (View property), 80
loadModel() (Controller method), 50
M
method() (CakeRequest method), 57
N
name (Controller property), 50
O
output (View property), 80
P
paginate (Controller property), 52
paginate() (Controller method), 48
params (CakeRequest property), 58
postConditions() (Controller method), 47
Q
query (CakeRequest property), 58
R
redirect() (Controller method), 45
referer() (CakeRequest method), 57
referer() (Controller method), 47
render() (Controller method), 44
request (View property), 80
requestAction() (Controller method), 48
S
scaffoldError() (Controller method), 46
send() (CakeResponse method), 61
set() (Controller method), 44
set() (View method), 78
shutdown() (Component method), 68
start() (View method), 79
startup() (Component method), 68
statusCode() (CakeResponse method), 61
subdomains() (CakeRequest method), 57
T
type() (CakeResponse method), 61
U
uses (Controller property), 51
uuid() (View method), 79
V
View (class), 78
W
webroot (CakeRequest property), 58
126 Index

Você também pode gostar