SlideShare una empresa de Scribd logo
1 de 69
Descargar para leer sin conexión
Curso de CakePHP                             Página 1 /69



                                    Curso de CakePHP

1 – Introdução . . . . . . . .                .   .   .   .   .   .   .   .   2
2 – Configurações . . . . . . .               .   .   .   .   .   .   .   .   6
3 – Convenções . . . . . . .                  .   .   .   .   .   .   .   .   8
4 – Bake (Gerando aplicativos pela console)   .   .   .   .   .   .   .   .   12
5 – Model . . . . . . . . .                   .   .   .   .   .   .   .   .   20
6 – Controller . . . . . . . .                .   .   .   .   .   .   .   .   22
7 – View . . . . . . . . .                    .   .   .   .   .   .   .   .   25
8 – Action . . . . . . . . .                  .   .   .   .   .   .   .   .   29
9 – Scaffold . . . . . . . .                  .   .   .   .   .   .   .   .   33
10 – Validações . . . . . . .                 .   .   .   .   .   .   .   .   37
11 – Menus . . . . . . . .                    .   .   .   .   .   .   .   .   40
12 – CSS . . . . . . . . .                    .   .   .   .   .   .   .   .   41
13 – JavaScript     . . . . . . .             .   .   .   .   .   .   .   .   44
14 – Vendors . . . . . . . .                  .   .   .   .   .   .   .   .   45
15 – Relacionamentos . . . . . .              .   .   .   .   .   .   .   .   46
16 – Dicas . . . . . . . . .                  .   .   .   .   .   .   .   .   47
17 - Aplicativos de Exemplo
    17.1 - Aplicativo Livros . . . .          .   .   .   .   .   .   .   .   48
    17.2 - Aplicativo cake_olamundo . .       .   .   .   .   .   .   .   .   60
    17.3 - Outros Exemplos . . . .            .   .   .   .   .   .   .   .   66
18 – Referências . . . . . . .                .   .   .   .   .   .   .   .   67




                              Ribamar FS – http://cursos.ribafs.org
Curso de CakePHP                              Página 2 /69

                                       1 - Cake - Introdução

O que é CakePHP?

CakePHP é um framework de desenvolvimento rápido para PHP que fornece uma arquitetura
extensível para desenvolvimento,
manutenção e implantação de aplicativos. Usando padrões de projeto conhecidos como MVC e
ORM com o paradigma das convenções sobre
configurações, CakePHP reduz os custos de desenvolvimento e ajuda os desenvolvedores a escrever
menos código.

Site oficial - http://cakephp.org

Desde que Ruby on Rails se tornou um popular framework, equipes de desenvolvedores
tem criado clones do framework Rails ou Rails em várias linguagens: TurboGears para
Python; Zend, Symfony, e muitos outros para PHP; Catalyst para Perl; e assim por diante. Com
tantas opções, por que escolher CakePHP para seu projeto web?


Framework

Um framework pode ser definido como a planta baixa de onde todos os sistemas serão construídos,
ou como uma forma que bolos, que padroniza
a forma e o volume de todos os bolos criados com ela.

O framework enxerga cada tabela como uma classe, e cada registro da tabela como um objeto
específico da classe

Alguns softwares como os CMS são muito simples de instalar e usar, até mesmo sem nenhuma
documentação, como é o caso dos CMS.
Já os frameworks, a exemplo do CakePHP, requerem que tomemos conhecimento de pelo menos
algumas convenções que ele traz.
Caso não sigamos essas convenções ele não fará muito por nós.
Sem contar que os frameworks são softwares de um tipo que exigem mais conhecimento que os
CMS.

Características do Cake

Cake tem como objetivo simplificar o processo de desenvolvimento para a construção de
aplicações web provendo um método geral para organizar o banco de dados e outros recursos que
reduzem a codificação. Embora esta abordagem geral da programação web seja em si uma
característica importante do Cake, o seu repositório de outros recursos poderosos como validação
embutida, listas de controle de acesso (ACLs), sanitização de dados, segurança e componentes de
manipulação de sessão e cache de View fazem o Cake vale a pena para qualquer desenvolvedor
sério.



                                    Ribamar FS – http://cursos.ribafs.org
Curso de CakePHP                           Página 3 /69

Características Principais

- Sem Configuração (com convenções) – Configure o banco e deixe a mágica iniciar
- Extremamente Simples – Apenas veja o nome...Ele chama-se Cake/Bolo
- Ativa e Amigável Comunidade – Junte-se a nós no #cakephp (IRC). Adoraríamos ajudar você a
começar
- Licença Flexível – Distribuído sob a licença MIT
- Clean IP – Toda linha de código foi escrita pela equipe de desenvolvimento do CakePHP
- Melhores Práticas – cobrindo segurança, autenticação e manipulação de session, além de muitas
outras características
- OO – Caso seja um programador OO experiente ou novato se sentirá confortável
- Compatível com as versões 4 e 5 do PHP
- CRUD Integrado para interação com o banco de dados
- Aplicação scaffolding
- Geração de código
- Arquitetura MVC
- Requisição de dispatcher com URL limpa, personalizada e rotas/routes
- Validação embutida
- Rápidos e flexíveis templates (Sintaxe PHP, com helpers)
- View Helpers para AJAX, JavaScript, Forms HTML e mais
- Email, Cookie, Security, Session e Request Handling Components
- Flexível ACL
- Sanitização de Dados
- Flexível Caching
- Localização
- Trabalha a partir de qualquer diretório do site, com pouca ou nenhuma configuração do Apache
envolvidas


Requisitos

PHP 4.3.2 ou superior
Servidor Web Apache com o mod_rewrite

Tecnicamente um banco de dados não é obrigatório, mas nós imaginamos que a maioria
das aplicações irão utilizar um. CakePHP suporta uma variedade de banco de dados:

- MySQL (4 ou superior)
- PostgreSQL
- Firebird DB2
- Microsoft SQL Server
- Oracle
- SQLite
- ODBC
- ADOdb

Como pode mudar de versão para versão (a atual é a 1.2.4.8284), confira no diretório:
cake/libs/model/datasources/dbo:

                              Ribamar FS – http://cursos.ribafs.org
Curso de CakePHP                          Página 4 /69

dbo_db2.php, dbo_firebird.php, dbo_mssql.php, dbo_mysql.php, dbo_mysqli.php, dbo_odbc.php,
dbo_oracle.php, dbo_postgres.php, dbo_sqlite.php, dbo_sybase.php.


Estrutura original do diretório do cake:

cake/app
cake/cake
cake/vendors
cake/index.php
cake/index_webroot.txt
cake/README

Estrutura original do diretório app:

cake/app/config
cake/app/controllers
cake/app/locale
cake/app/models
cake/app/plugins
cake/app/tests
cake/app/tmp
cake/app/vendors
cake/app/views
cake/app/webroot
cake/app/index.php

A pasta app do CakePHP é onde normalmente você colocará sua aplicação em desenvolvimento.
Vamos dar uma olhada mais de perto dentro desta pasta.

config
Contém os arquivos de configuração. Detalhes das conexões ao banco de dados, bootstrapping,
arquivos de configuração do núcleo e outros devem ser armazenados aqui.

controllers
Contém os controladores da sua aplicação e seus componentes.

locale
Guarda os arquivos com as strings para internacionalização.

models
Contém os modelos, behaviors e datasources da sua aplicação.

plugins
Contém os pacotes de plugins.

tmp
Aqui é onde o CakePHP armazena os arquivos temporários. Os dados atuais são armazenados onde

                                Ribamar FS – http://cursos.ribafs.org
Curso de CakePHP                           Página 5 /69

você tenha configurado o CakePHP, mas esta
pasta normalmente é usada para guardar a descrição dos modelos, logs e outras informações, como
as das sessões.

vendors
Qualquer classe ou biblioteca de terceiro deve ser armazenada aqui. Para fazer um acesso rápido e
fácil, use a função vendors(). Você pode achar
que esta pasta é redundante, já que existe uma pasta com mesmo nome no nível superior da
estrutura. Nós vamos ver diferenças
entre estas duas pastas quando discutirmos sobre manipulação de múltiplas aplicações e sistemas
mais complexos.

views
Arquivos de apresentação devem vir aqui: elementos, páginas de erro, ajudantes, layouts e arquivos
de visões.

webroot
No modo de produção, esta pasta deve servir como a pasta raiz da sua aplicação. Dentro desta pasta
são guardados os arquivos públicos, como
estilos CSS, imagens e arquivos de JavaScript.

cake - bolo
baker - padeiro




                              Ribamar FS – http://cursos.ribafs.org
Curso de CakePHP                           Página 6 /69

                                2 - Cake - Configurações

Mesmo sendo focado em convenções ao invés de configurações, o Cake pode ter seu
comportamento alterado através de alguns arquivos de configuração, que encontram-se na pasta
config:

database
core
router
debug
tradução
testes
etc.

Vários Aplicativos num único Core
Podemos configurar para que várias aplicações usem um único core do Cake.

- Todos os aplicativos devem ficar assim:

cake
app1
app2
app3
...

E cada um deles deve ter seu arquivo webroot/index.php alterado na linha com
CAKE_CORE_INCLUDE_PATH, mudando para:
define('CAKE_CORE_INCLUDE_PATH', dirname(dirname(dirname(__FILE__))));


Debug
O debug nas fases de desenvolvimento e de testes é muito importante, mas após a conclusão e
entrega para o cliente devemos setar o debug para zero.

O Debug pode ser alterado manualmente no script config/core.php, na linha:
Configure::write('debug', 0);
O default é 2. Zero é sem debug (sem exibir as mensagens de erro ou alerta).

ou via código da nossa aplicação com:
Configure::write('debug', '0');

Os possíveis são:
0 = Production mode. No output. debug
1 = Show errors and warnings.
2 = Show errors, warnings, and SQL.
3 = Show errors, warnings, SQL, and complete controller dump.


                              Ribamar FS – http://cursos.ribafs.org
Curso de CakePHP                           Página 7 /69



Tradução

Também podemos traduzir algumas coisas do CakePHP, como as mensagens de erro

Download:
http://souagil.com.br/cake_i18n/pt_br.tar.gz

Adicionar linha ao final de config/core.php:
Configure::write('Config.language', 'pt-br');


Adicionar Testes com SimpleTest

Download - http://www.simpletest.org/
Descompacte e copie a pasta simpletest para a subpasta vendor do seu aplicativo.


Formatar Data e Hora

Trocar:
<?php echo $cliente['Cliente']['created'] ?>

por:
<?php echo $time->niceShort($cliente['Cliente']['created']) ?>




                                Ribamar FS – http://cursos.ribafs.org
Curso de CakePHP                           Página 8 /69

                                  3 - Cake - Convenções

O Cake previlegia convenções ao invés de configurações.
O que significa que seguindo as convenções estabelecidas o cake fará muito por nós.
Não somos obrigados a seguir as convenções, mas perderemos muito com isso, pois teremos que
fazer muito.

Apesar de tomar um pouco de tempo para aprender as convenções do CakePHP, você ganha tempo
em um longo processo: seguindo as convenções, você ganha funcionalidades gratuitamente e livra-
se de madrugadas de manutenção de arquivos de configuração. Convenções também fazem com que
o sistema fique uniformemente desenvolvido, permitindo que outros desenvolvedores o ajudem
mais facilmente, já que segue um padrão de trabalho.

Convenções no CakePHP têm sido produzidas por anos de experiência em desenvolvimento web e
boas práticas. Apesar de sugerirmos que você use essas convenções enquanto desenvolve em
CakePHP, devemos mencionar que muitos desses princípios são facilmente sobrescritos - algo que
especialmente acontece quando trabalha-se com sistemas legados.

Convenções de arquivos e nome de classes

Em geral, nome dos arquivos são sublinhados, enquanto nome de classes são CamelCased, ou seja,
primeiras letras das palavras em maiúsculo. A classe KissesAndHugsController pode ser encontrada
no arquivo kisses_and_hugs_controller.php, por exemplo.

Porém, o nome da class e seu tipo não são necessariamente encontrados no nome do arquivo. A
classe EmailComponent é encontrada no arquivo chamado email.php e a classe HtmlHelper é
encontrada no arquivo html.php.

Convenções de modelo

Nome das classes de modelo devem ser no singular e CamelCased. Person, BigPerson e
ReallyBigPerson são exemplos de nomes convencionados para modelos. Os nomes das tabelas
correspondentes a modelos do CakePHP devem estar no plural e sublinhados.
As tabelas para os modelos mencioados anteriormente devem ser people, big_people e
really_big_people, respectivamente.

Chaves estrangeiras em relacionamentos do tipo temMuitos (hasMany), pertenceA (belongsTo) ou
temUm (hasOne) são reconhecidos por padrão como o nome (no singular) do modelo relacionado,
seguido por _id. Assim, se um padeiro temMuitos bolos, a tabela bolos referenciará a um padeiro na

tabela padeiros através da chave estrangeira padeiro_id.

Tabelas associativas, usadas em relações temEPertenceAMuitos (hasAndBelongsToMany) entre
modelos, devem ser nomeadas depois dos modelos das tabelas que a compõem, em ordem
alfabética (apples_zebras em vez de zebras_apples).

Todas as tabelas com as quais os modelos CakePHP interagem (exceto as tabelas associativas)


                               Ribamar FS – http://cursos.ribafs.org
Curso de CakePHP                            Página 9 /69

exigem uma única chave primária para identificar unicamente cada linha. Se você deseja modelar
uma tabela que não tem uma chave primária de um único campo, como as linhas de nossa tabela
associativa posts_tags, a convenção do CakePHP é de que uma chave primária de um único campo
deve ser adicionada à tabela.

CakePHP não suporta chaves primárias compostas. No caso de você querer manipular diretamente
os dados das tabelas associativas, isso significa que você precisa usar chamadas a consultas diretas,
ou adicionar um campo como chave primária para ser capaz de atuar nela como em um modelo
normal. Por exemplo:
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));

Convenções de controlador
O nome das classes de controladores são no plural, CamelCased e no final 'Controller'.
PeopleController, BigPeopleController e ReallyBigPeopleController são todos os exemplos
convencionais para nome de controladores.

A primeira função que você deve escrever em um controlador deve ser o método index(). Quando
alguém requisita um controlador sem ação, o behavior padrão é renderizar o método index() do
controlador. Por exemplo, a requisição para http://www.exemplo.com.br/apples/ mapeia para a
chamada da função index() do ApplesController, assim como
http://www.exemplo.com.br/apples/view
mapeia para a chamada da função view() no ApplesController.
Você também pode alterar a visibilidade das funções do controlador em CakePHP colocando
sublinhados na frente do nome das funções. Se a função do controlador estiver com sublinhado na
frente, a função não será disponibilizada para acesso da web através do dispatcher, mas estará
disponível para uso interno.Por exemplo:

<?php
class NewsController extends AppController {
function latest() {
$this->_findNewArticles();
}
function _findNewArticles() {
//Logic to find latest news articles
}
}
?>

Apesar da página
http://www.example.com/news/latest/
possa ser acessada pelo usuário normalmente, alguém que tente acessar a página

                               Ribamar FS – http://cursos.ribafs.org
Curso de CakePHP                          Página 10 /69

http://www.example.com/news/_findNewArticles/
receberá um erro porque a função é precedida de um sublinhado.

Considerações sobre URLs para Nomes de Controladores

Como você acabou de ver, controladores de uma única palavra são mapeados facilmente para uma
URL simples em letras minúsculas. Por exemplo, ApplesController (que seria definida em um
arquivo de nome 'apples_controller.php') é acessada a partir de http://example.com/apples.
Controladores de múltiplas palavras mapeados para URLs em camelBacked mantendo a forma
plural. Por exemplo, RedApplesController (red_apples_controller.php) seria mapeada para
http://example.com/redApples
e OperatingSystemsController

(operating_systems_controller.php)
seria mapeada para
http://example.com/operatingSystems.

Convenções de visão

Os arquivos de template de visões são nomeados depois das funções de controladores que mostram
esses arquivos de template, na forma com sublinhados. A função getReady() da classe
PeopleController irá procurar pelo template da visão em /app/views/people/get_ready.ctp.
O modelo básico é /app/views/controller/underscored_function_name.ctp.
Nomeando os pedaços da aplicação usando as convenções do CakePHP, você ganha
funcionalidades sem luta e sem amarras de configuração. Aqui o exemplo final que vincula as
associações:

Tabela no banco de dados: 'people'
Classe do Modelo: 'Person', encontrada em /app/models/person.php
Classe do Controlador: 'PeopleController', encontrado em
/app/controllers/people_controller.php
Template da Visão: encontrado em /app/views/people/index.ctp

Usando estas convenções, CakePHP sabe que a requisição para http://www.exemplo.com.br/people/

mapeia para a chamada da função index() do PeopleController, onde o modelo Person é
automaticamente disponibilizado (e automaticamente associado à tabela 'people' no banco de
dados), e renderiza isso para o arquivo. Nenhuma destas relações foram configuradas por qualquer
meio que não seja através da criação de classes e arquivos que você precise criar em algum lugar.
Agora que você leu os fundamentos do CakePHP, você pode tentar seguir o tutorial de como fazer
um Blog em CakePHP, para ver como as coisas são feitas juntas.




                               Ribamar FS – http://cursos.ribafs.org
Curso de CakePHP                         Página 11 /69

Resumo

- bancos de dados – minúsculas e singular
- tabelas – minúsculas e plural
- chave primária de todas as tabelas deve ser chamada de id (opcionalmente)
- chaves estrangeiras devem ser chamadas de tabelanome_id, exemplo blog_id (nome tabela no
singular)
- nomes de modelos CamelCase e arquivos em minúsculas e singular e sublinhado para separar
palavras compostas: meu_post.php e MeuPost
- controladores – arquivo: minúsculas e plural. Classe CamelCase com Controller anexado, como:
PostsController. Nomes de arquivos com
sublinhado em palavras compostas: posts_controller.php

Associações entre Tabelas (relacionamentos)
hasOne: possui um
hasMany: possui muitos
belongsTo: pertence a
hasAndBelongsToMany: tem e pertence a muitos

O Cake automaticamente adiciona o tempo para campos que são do timo datetime e são nomeados
'created' ou 'modified'.




                             Ribamar FS – http://cursos.ribafs.org
Curso de CakePHP                           Página 12 /69

                    4 - Criar Aplicativos em Cake com o Bake

Operações de CRUD com o script bake.

Após a utilização do bake temos um "esqueleto" de aplicação.
Agora podemos customizar os códigos gerados para criarmos a aplicação final.


- Copiar a pasta app
Primeiro vamos copiar a pasta app para estoque


- Criar o banco
Depois vamos criar um banco chamado estoque (MySQL), no phpMydmin importe este script aqui.
O banco coterá cinco tabelas: clientes, funcionarios, produtos, pedidos e pedido_itens


- Relacionamentos
A tabela pedidos está relacionada com clientes e fun cionarios, portanto tem dois campos: cliente_id
e funcionario_id
A tabela pedido_itens se relaciona com pedidos pelo campo pedido_id.


- Criar aplicativo com Bake
Vamos usar o bake para criar o aplicativo através da console.


- Configurar para usar vários aplicativos com um único core
Configurar estoque/webroot/index.php
mudar a linha com define('CAKE_CORE_INCLUDE_PATH' para:
define('CAKE_CORE_INCLUDE_PATH', dirname(dirname(dirname(__FILE__))));


- Acessar a pasta console
cd /home/ribafs/public_html/cake/cake/console

ou

cd c:xampplitehtdocscakecakeconsole


1) Criar uma Configuração de banco

./cake bake -app estoque

Receberá a tela:

Welcome to CakePHP v1.2.4.8284 Console

                               Ribamar FS – http://cursos.ribafs.org
Curso de CakePHP                          Página 13 /69

---------------------------------------------------------------
App : estoque
Path: /home/ribafs/backup/public_html/cake/estoque
---------------------------------------------------------------
Your database configuration was not found. Take a moment to create one.
---------------------------------------------------------------
Database Configuration:
---------------------------------------------------------------
Name:
[default] >

Obs.: As opções entre colchetes como [default] acima são as opções sugeridas e default, basta teclar
Enter se queremos aceitá-la.

Tecle Enter para aceitar default como o nome da configuração do banco.

2) Selecionar o SGDB
Driver: (db2/firebird/mssql/mysql/mysqli/odbc/oracle/postgres/sqlite/sybase)
[mysql] >

Apenas tecle Enter para aceitar o mysql

3) Tipo de conexão
Persistent Connection? (y/n)
[n] >

Enter para aceitar não persistente

4) Host do Banco
Database Host:
[localhost] >

Enter para aceitar localhost ou digite o nome do seu host

5) Porta
Port?
[n] >

Enter para aceitar a porta default

6) Usuário
User:
[root] >

Enter para aceitar

7) Senha
Password:

                                Ribamar FS – http://cursos.ribafs.org
Curso de CakePHP                           Página 14 /69

>

Enter para aceitar sem senha ou digite a senha

8) Nome do banco
Database Name:
[cake] >

Digite estoque e tecle Enter

9) Prefixo das tabelas
Table Prefix?
[n] >

Enter para aceitar sem prefixo ou digite o prefixo

10) Codificação das tabelas
Table encoding?
[n] >
Enter para aceitar a default ou entre com a codificação (exemplo: utf8)

Então aparece o relatório:

---------------------------------------------------------------
The following database configuration will be created:
---------------------------------------------------------------
Name:          default
Driver:       mysql
Persistent: false
Host:        localhost
User:        root
Pass:        ******
Database: estoque
Encoding: utf8
---------------------------------------------------------------
Look okay? (y/n)
[y] >

Tecle enter para aceitar.

11) Outra configuração de banco?
Do you wish to add another database configuration?
[n] >

Enter para encerrar.

Então ele criará o arquivo:
Creating file /home/ribafs/public_html/cake/estoque/config/database.php

                                    Ribamar FS – http://cursos.ribafs.org
Curso de CakePHP                            Página 15 /69

Wrote /home/ribafs/public_html/cake/estoque/config/database.php

Ao executar novamente o comando:
./cake bake -app estoque

Aparecerá o menu:

Welcome to CakePHP v1.2.4.8284 Console
---------------------------------------------------------------
App : estoque
Path: /home/ribafs/backup/public_html/cake/estoque
---------------------------------------------------------------
Interactive Bake Shell
---------------------------------------------------------------
[D]atabase Configuration
[M]odel
[V]iew
[C]ontroller
[P]roject
[Q]uit
What would you like to Bake? (D/M/V/C/P/Q)
>

Vamos criar na seguinte ordem para cada tabela: model, controller e view

Criar o Model para a tabela Clientes

1) Tecle m e Enter (Model)

Bake Model
Path: /home/ribafs/backup/public_html/cake/estoque/models/
---------------------------------------------------------------
Possible Models based on your current database:
1. Cliente
2. Funcionario
3. PedidoIten
4. Pedido
5. Produto
Enter a number from the list above, type in the name of another model, or 'q' to exit
[q] >

2) Tecle 1 e Enter

Would you like to supply validation criteria for the fields in your model? (y/n)
[y] >


3) Validação


                                     Ribamar FS – http://cursos.ribafs.org
Curso de CakePHP                            Página 16 /69

Tecle n e Enter (não vamos validar agora)

4) Nome do campo chave
What is the primaryKey?
[cliente] >

No nosso caso está correto, apenas tecle Enter

5) Relacionamentos
Would you like to define model associations (hasMany, hasOne, belongsTo, etc.)? (y/n)
[y] >

n e Enter

6) Correto?
---------------------------------------------------------------
The following Model will be created:
---------------------------------------------------------------
Name:        Cliente
Primary Key: cliente
Associations:
---------------------------------------------------------------
Look okay? (y/n)
[y] >

Enter

7) Baking model class for Cliente...

Creating file /home/ribafs/backup/public_html/cake/estoque/models/cliente.php
Wrote /home/ribafs/backup/public_html/cake/estoque/models/cliente.php

Baking test fixture for Cliente...

Creating file /home/ribafs/backup/public_html/cake/estoque/tests/fixtures/cliente_fixture.php
Wrote /home/ribafs/backup/public_html/cake/estoque/tests/fixtures/cliente_fixture.php

Baking unit test for Cliente...

Creating file /home/ribafs/backup/public_html/cake/estoque/tests/cases/models/cliente.test.php
Wrote /home/ribafs/backup/public_html/cake/estoque/tests/cases/models/cliente.test.php



Criando o Model para Funcionarios
Agora de forma mais resumida

1) m e Enter

                                     Ribamar FS – http://cursos.ribafs.org
Curso de CakePHP                            Página 17 /69


2) 2 para funcionarios e Enter

3) n e Enter (sem validação)

4) Chave primária - Enter para funcionario

5) Relacionamentos - n e Enter

6) Tudo OK? - Enter


Criar o Model para Produtos
De forma semelhante crie o model para produtos.

Criar o Model para Pedidos
Esse é diferente, pois tem relacionamentos com cliente e funcionários

1) m e Enter

2) 4 e Enter para pedido

3) n e Enter para validação

4) pedido como chave

5) Relacionamento
Would you like to define model associations (hasMany, hasOne, belongsTo, etc.)? (y/n)
[y] >

Enter para sim.

One moment while the associations are detected.
---------------------------------------------------------------
Please confirm the following associations:
---------------------------------------------------------------
Pedido belongsTo Cliente? (y/n)
[y] >

Enter para aceitar a relação com Cliente

Pedido belongsTo Funcionario? (y/n)
[y] >

Enter para aceitar a relação com funcionario.

n para PedidoIten nas duas sugestões.


                                     Ribamar FS – http://cursos.ribafs.org
Curso de CakePHP                            Página 18 /69

Enter para não adicionais relações.

Relato:
---------------------------------------------------------------
The following Model will be created:
---------------------------------------------------------------
Name:        Pedido
Primary Key: pedido
Associations:
Pedido belongsTo Cliente
Pedido belongsTo Funcionario
---------------------------------------------------------------
Look okay? (y/n)
[y] >

Enter para aceitar.


Criar o modelo da tabela pedido_itens
Que se relaciona apenas com pedidos.

Criar o Controller para Clientes

1) c e Enter

2) 1 e Enter

Would you like to build your controller interactively? (y/n)
[y] > n

3) n para controller interativo

4) Incluir métodos básicos
Would you like to include some basic class methods (index(), add(), view(), edit())? (y/n)
[y] >

Enter para aceitar

5) Would you like to create the methods for admin routing? (y/n)
[y] >

n e Enter

6) Relato:
---------------------------------------------------------------
The following controller will be created:
---------------------------------------------------------------
Controller Name: Clientes

                                     Ribamar FS – http://cursos.ribafs.org
Curso de CakePHP                            Página 19 /69

---------------------------------------------------------------
Look okay? (y/n)
[y] >

Enter para aceitar

Criar os Controllers Funcionarios, PedidoItens, Pedidos e Produtos de forma semelhante


Criar a view para a tabela Clientes

1) v e Enter

2) 1 e Enter

3) Criar scaffolds para a view:
Would you like to create some scaffolded views (index, add, view, edit) for this controller?
NOTE: Before doing so, you'll need to create your controller and model classes (including
associated models). (y/n)
[n] >

y e Enter

n para não criar admin

De forma semenlhante criar as demais.

Procurando ID e sobrescrevendo pelas respectivas chaves primárias nas views.


Editar a views
cake/estoque/views/clientes/index.ctp

Procurar por id e sobrescrever com cliente.

Assim com as demais views.

Com isso temos um aplicativo com muitos bons recursos: CRUD, paginação, CSS, etc.


Para criar um novo projeto com bake use:
./cake bake -p nomeprojeto


Para ir direto para model, controller ou view:
./cake bake -app nomeapp model
./cake bake -app nomeapp controller
./cake bake -app nomeapp view

                                     Ribamar FS – http://cursos.ribafs.org
Curso de CakePHP                          Página 20 /69

                                      5 - Cake - Models

Os models formam a camada da letra M do MVC, aquele que vai ao banco e conversa com os
controllers atendendo as suas solicitações e devolvendo o resultado recebido do banco de dados.


Modelo simples:

cake/ola/models/cliente.php

<?php
class Cliente extends AppModel {
var $name = 'Cliente';
}
?>

Todos os models em Cake tem a função find() usada para buscar os registros da tabela do model.
Passando parâmetros para essa função nós podemos controlar os registros a buscar.


Um Model com validação dos campos (gerado pelo Bake):

<?php
class Produto extends AppModel {

var $name = 'Produto';
var $primaryKey = 'produto';
var $validate = array(
'produto' => array('numeric'),
'descricao' => array('notempty'),
'unidade' => array('notempty'),
'data_cadastro' => array('date')
);

}
?>

Model com relacionamento com clientes e funcionarios:

<?php
class Pedido extends AppModel {

var $name = 'Pedido';
var $primaryKey = 'pedido';

//The Associations below have been created with all possible keys, those that are not needed can be
removed


                                Ribamar FS – http://cursos.ribafs.org
Curso de CakePHP                          Página 21 /69


var $belongsTo = array(
'Cliente' => array(
'className' => 'Cliente',
'foreignKey' => 'cliente_id',
'conditions' => '',
'fields' => '',
'order' => ''
),
'Funcionario' => array(
'className' => 'Funcionario',
'foreignKey' => 'funcionario_id',
'conditions' => '',
'fields' => '',
'order' => ''
)
);

}
?>

Uma boa pedida para aprender sobre os Models na prática é criar aplicativos com o Bake na linha
de comando e depois analisar o código gerado.




                               Ribamar FS – http://cursos.ribafs.org
Curso de CakePHP                           Página 22 /69

                                     6 - Cake - Controllers

O controller representa a letra C do VMC e é a camada de processamento em PHP, onde existem os
for, if, while, etc. Ele recebe as requisições de uma View e manda para o respectivo Model. Ao
receber o resultado do Model ele devolve para a Views que pediu.

Em um aplicativo de posts...

Cada ação do controller deve pegar os posts no banco e retornar para a view.
A view deve então exibir todos os posts como lista.

Controllers simples:

cake/ola/controllers/clientes_controller.php

<?php
class ClientesController extends AppController
{
var $name = 'Clientes';
}
?>
Action
Toda função pública dentro da classe controller é chamada de action.
Esta action visualizará todos os clientes com a view index.ctp

<?php
class ClientesController extends AppController
{
var $name = 'Clientes';

function index() {
$this->set('clientes', $this->Cliente->find('all'));
}
}
?>

Controllers e Views
Um controller pode ter muitos actions e cada action tem sua view. Portanto um controller pode ter
muitas views.
Cake guarda todas as views de um controller em um diretório separado (do mesmo nome do
controller).




                                  Ribamar FS – http://cursos.ribafs.org
Curso de CakePHP                           Página 23 /69

Agora um controller mais sofisticado:

<?php
class PedidosController extends AppController {

var $name = 'Pedidos';
var $helpers = array('Html', 'Form');

function index() {
$this->Pedido->recursive = 0;
$this->set('pedidos', $this->paginate());
}

function view($id = null) {
if (!$id) {
$this->Session->setFlash(__('Invalid Pedido.', true));
$this->redirect(array('action'=>'index'));
}
$this->set('pedido', $this->Pedido->read(null, $id));
}

function add() {
if (!empty($this->data)) {
$this->Pedido->create();
if ($this->Pedido->save($this->data)) {
$this->Session->setFlash(__('The Pedido has been saved', true));
$this->redirect(array('action'=>'index'));
} else {
$this->Session->setFlash(__('The Pedido could not be saved. Please, try again.', true));
}
}
$clientes = $this->Pedido->Cliente->find('list');
$funcionarios = $this->Pedido->Funcionario->find('list');
$this->set(compact('clientes', 'funcionarios'));
}

function edit($id = null) {
if (!$id && empty($this->data)) {
$this->Session->setFlash(__('Invalid Pedido', true));
$this->redirect(array('action'=>'index'));
}
if (!empty($this->data)) {
if ($this->Pedido->save($this->data)) {
$this->Session->setFlash(__('The Pedido has been saved', true));
$this->redirect(array('action'=>'index'));
} else {
$this->Session->setFlash(__('The Pedido could not be saved. Please, try again.', true));
}

                                Ribamar FS – http://cursos.ribafs.org
Curso de CakePHP                          Página 24 /69

}
if (empty($this->data)) {
$this->data = $this->Pedido->read(null, $id);
}
$clientes = $this->Pedido->Cliente->find('list');
$funcionarios = $this->Pedido->Funcionario->find('list');
$this->set(compact('clientes','funcionarios'));
}

function delete($id = null) {
if (!$id) {
$this->Session->setFlash(__('Invalid id for Pedido', true));
$this->redirect(array('action'=>'index'));
}
if ($this->Pedido->del($id)) {
$this->Session->setFlash(__('Pedido deleted', true));
$this->redirect(array('action'=>'index'));
}
}

}
?>




                                Ribamar FS – http://cursos.ribafs.org
Curso de CakePHP                          Página 25 /69

                                        7 - Cake - Views

View representa a letra V do MVC.
As views são responsáveis por receber as requisições do cliente e mandar para o controller. O
controller manda para o model que devolve ao controller. Então o controller devolve para a view,
que renderiza o resultado para o cliente.
Lembrando que a view não deve ter nenhum contato direto com o model mas sempre passar pelo
controller.


Convenção - Todo action dos controllers e sua correspondente view tem o mesmo nome.
Quando o action finaliza a execução a view é renderizada.

View simples:

cake/ola/views/clientes/index.ctp

<h2>Clientes</h2>
<?php if(empty($clientes)): ?>
Nenum cliente encontrado
<?php else: ?>
<table>
<tr>
<th>ID</th>
<th>Nome</th>
<th>Ações</th>
</tr>
<?php foreach ($clientes as $cliente): ?>
<tr>
<td>
<?php echo $cliente['Cliente']['id'] ?>
</td>
<td>
<?php echo $cliente['Cliente']['nome'] ?>
</td>
<td>
<!-- actions on tasks will be added later -->
</td>
</tr>
<?php endforeach; ?>
</table>
<?php endif; ?>

Agora chamar no navegador assim:

http://localhost/cake/ola/clientes


                                Ribamar FS – http://cursos.ribafs.org
Curso de CakePHP                              Página 26 /69

Adicionar Registro
Adicionar view views/clientes/add.ctp correspondente ao action add:

Adicionar a view:
cake/ola/views/clientes/add.ctp

<?php echo $form->create('Cliente');?>
<fieldset>
<legend>Adicionar novo Cliente</legend>
<?php
echo $form->input('ID');
echo $form->input('Nome');
?>
</fieldset>
<?php echo $form->end('Adicionar');?>

Agora chame com o navegador:

http://localhost/cake/ola/clientes/add


As views sempre tem a extensão ctp (Cake Template Pages).


Link para Edição (adicionado logo após o comentário <!-- actions on tasks will be added later -->)

<h2>Clientes</h2>
<?php if(empty($clientes)): ?>
Nenum cliente encontrado
<?php else: ?>
<table>
<tr>
<th>ID</th>
<th>Nome</th>
<th>Ações</th>
</tr>
<?php foreach ($clientes as $cliente): ?>
<tr>
<td>
<?php echo $cliente['Cliente']['id'] ?>
</td>
<td>
<?php echo $cliente['Cliente']['nome'] ?>
</td>
<td>
<!-- actions on tasks will be added later -->
<?php echo $html->link('Editar', array('action'=>'edit', $cliente['Cliente']['id'])); ?>
</td>

                                  Ribamar FS – http://cursos.ribafs.org
Curso de CakePHP                           Página 27 /69

</tr>
<?php endforeach; ?>
</table>
<?php endif; ?>

<?php echo $html->link('Adicionar Cliente', array('action'=>'add')); ?>


Uma view mais sofisticada (gerada pelo Bake):


<div class="clientes index">
<h2><?php __('Clientes');?></h2>
<p>
<?php
echo $paginator->counter(array(
'format' => __('Page %page% of %pages%, showing %current% records out of %count% total,
starting on record %start%, ending on %end%', true)
));
?></p>
<table cellpadding="0" cellspacing="0">
<tr>
<th><?php echo $paginator->sort('cliente');?></th>
<th><?php echo $paginator->sort('cpf');?></th>
<th><?php echo $paginator->sort('nome');?></th>
<th><?php echo $paginator->sort('credito_liberado');?></th>
<th><?php echo $paginator->sort('data_nasc');?></th>
<th><?php echo $paginator->sort('email');?></th>
<th class="actions"><?php __('Actions');?></th>
</tr>
<?php
$i = 0;
foreach ($clientes as $cliente):
$class = null;
if ($i++ % 2 == 0) {
$class = ' class="altrow"';
}
?>
<tr<?php echo $class;?>>
<td>
<?php echo $cliente['Cliente']['cliente']; ?>
</td>
<td>
<?php echo $cliente['Cliente']['cpf']; ?>
</td>
<td>
<?php echo $cliente['Cliente']['nome']; ?>
</td>


                               Ribamar FS – http://cursos.ribafs.org
Curso de CakePHP                             Página 28 /69

<td>
<?php echo $cliente['Cliente']['credito_liberado']; ?>
</td>
<td>
<?php echo $cliente['Cliente']['data_nasc']; ?>
</td>
<td>
<?php echo $cliente['Cliente']['email']; ?>
</td>
<td class="actions">
<?php echo $html->link(__('View', true), array('action' => 'view', $cliente['Cliente']['cliente'])); ?>
<?php echo $html->link(__('Edit', true), array('action' => 'edit', $cliente['Cliente']['cliente'])); ?>
<?php echo $html->link(__('Delete', true), array('action' => 'delete', $cliente['Cliente']['cliente']),
null, sprintf(__('Are you sure you want to delete # %s?', true), $cliente['Cliente']['cliente'])); ?>
</td>
</tr>
<?php endforeach; ?>
</table>
</div>
<div class="paging">
<?php echo $paginator->prev('<< '.__('previous', true), array(), null, array('class'=>'disabled'));?>
| <?php echo $paginator->numbers();?>
<?php echo $paginator->next(__('next', true).' >>', array(), null, array('class' => 'disabled'));?>
</div>
<div class="actions">
<ul>
<li><?php echo $html->link(__('New Cliente', true), array('action' => 'add')); ?></li>
<li><?php echo $html->link(__('List Pedidos', true), array('controller' => 'pedidos', 'action' =>
'index')); ?> </li>
<li><?php echo $html->link(__('New Pedido', true), array('controller' => 'pedidos', 'action' =>
'add')); ?> </li>
</ul>
</div>




                                Ribamar FS – http://cursos.ribafs.org
Curso de CakePHP                           Página 29 /69

                                         8 - Cake - Actions

Os Actions como o nome sugere, representam ações do usuário, que as emitem pelas views e são
processadas nos controllers.
Cada ação do usuário é representada por uma função no controller e esta função deve ter o mesmo
nome da view.
Exemplo: index.ctp é a view que é atendida pelo action index() no controller.


Actions são funções públicas nas classes dos Controllers.

Exemplo da action index() que corresponde à view de nome semelhante (index.ctp):

<?php
class ClientesController extends AppController
{
var $name = 'Clientes';

function index() {
$this->set('clientes', $this->Cliente->find('all'));
}
}
?>


Action para adicionar registros

Para isso precisaremos adicionar uma variável (array $helpers) e uma função add() ao controller,
como também adicionar uma view à pasta
clientes, de nome add.ctp.

var $helpers = array('Html', 'Form');

function add() {
if (!empty($this->data)) {
$this->Cliente->create();
if ($this->Cliente->save($this->data)) {
$this->Session->setFlash('Cliente foi adicionado');
$this->redirect(array('action'=>'index'), null, true);
} else {
$this->Session->setFlash('Cliente não adicionado. Tente novamente.');
}
}
}




                                  Ribamar FS – http://cursos.ribafs.org
Curso de CakePHP                             Página 30 /69

Adicionando Registros

Para isso precisamos adicionar um action (edit) ao controller e uma view para este action
(views/clientes/edit.ctp).

function edit($id = null) {
if (!$id) {
$this->Session->setFlash('Cliente Inválido');
$this->redirect(array('action'=>'index'), null, true);
}
if (empty($this->data)) {
$this->data = $this->Cliente->find(array('id' => $id));
} else {
if ($this->Cliente->save($this->data)) {
$this->Session->setFlash('O Cliente foi salvo!');
$this->redirect(array('action'=>'index'), null, true);
} else {
$this->Session->setFlash('O Cliente não pôde ser salvo. Favor tentar novamente.');
}
}
}


Excluindo Registros

Para isso devemos adicionar um action ao controle chamado delete() correspondente e uma linha na
view index.ctp

function delete($id = null) {
if (!$id) {
$this->Session->setFlash(__('Invalid id for Cliente', true));
$this->redirect(array('action'=>'index'));
}
if ($this->Cliente->del($id)) {
$this->Session->setFlash(__('Cliente deleted', true));
$this->redirect(array('action'=>'index'));
}
}

Editar a view index.ctp e adicionar a linha com o delete:

<td class="actions">
<?php echo $html->link(__('View', true), array('action' => 'view', $cliente['Cliente']['cliente'])); ?>
<?php echo $html->link(__('Edit', true), array('action' => 'edit', $cliente['Cliente']['cliente'])); ?>
<?php echo $html->link(__('Delete', true), array('action' => 'delete', $cliente['Cliente']['cliente']),
null, sprintf(__('Are you sure you want to delete # %s?', true), $cliente['Cliente']['cliente'])); ?>
</td>



                                Ribamar FS – http://cursos.ribafs.org
Curso de CakePHP                          Página 31 /69

Ou seja, neste caso, não criamos mais uma views, mas apenas uma linha para o action delete().
Veja agora todos os actions comuns para a tabela clientes, no controller clientes.php e classe
Clientes:


<?php
class ClientesController extends AppController {
var $name = 'Clientes';
var $helpers = array('Html', 'Form');

function index() {
$this->Cliente->recursive = 0;
$this->set('clientes', $this->paginate());
}

function view($id = null) {
if (!$id) {
$this->Session->setFlash(__('Invalid Cliente.', true));
$this->redirect(array('action'=>'index'));
}
$this->set('cliente', $this->Cliente->read(null, $id));
}

function add() {
if (!empty($this->data)) {
$this->Cliente->create();
if ($this->Cliente->save($this->data)) {
$this->Session->setFlash(__('The Cliente has been saved', true));
$this->redirect(array('action'=>'index'));
} else {
$this->Session->setFlash(__('The Cliente could not be saved. Please, try again.', true));
}
}
}

function edit($id = null) {
if (!$id && empty($this->data)) {
$this->Session->setFlash(__('Invalid Cliente', true));
$this->redirect(array('action'=>'index'));
}
if (!empty($this->data)) {
if ($this->Cliente->save($this->data)) {
$this->Session->setFlash(__('The Cliente has been saved', true));
$this->redirect(array('action'=>'index'));
} else {
$this->Session->setFlash(__('The Cliente could not be saved. Please, try again.', true));
}

                                 Ribamar FS – http://cursos.ribafs.org
Curso de CakePHP                          Página 32 /69

}
if (empty($this->data)) {
$this->data = $this->Cliente->read(null, $id);
}
}

function delete($id = null) {
if (!$id) {
$this->Session->setFlash(__('Invalid id for Cliente', true));
$this->redirect(array('action'=>'index'));
}
if ($this->Cliente->del($id)) {
$this->Session->setFlash(__('Cliente deleted', true));
$this->redirect(array('action'=>'index'));
}
}
?>




                                Ribamar FS – http://cursos.ribafs.org
Curso de CakePHP                           Página 33 /69

                                     9 - Cake - Scaffold

Usando Scaffold no CakePHP

O scaffold no cake cria um CRUD rapidamente para manipulação de uma tabela.

As ações do Scaffoldo são nomeadas como: index(), add(), edit(), view(), and delete().

Podemos deixar as ações de CRUD do scaffold quando não desejamos gerar código manualmente.


Copiar a pasta app
Vamos copiar a pasta app do cake para scaffold


Configurar o banco de dados
Configurar scaffold/config/database.php


Configurar para vários aplicativos usarem o mesmo core do Cake
Configurar scaffold/webroot/index.php na linha com define('CAKE_CORE_INCLUDE_PATH'
para:
define('CAKE_CORE_INCLUDE_PATH', dirname(dirname(dirname(__FILE__))));

Criar tabela
create table clientes
(
id int not null auto_increment primary key,
nome char(45) not null
);

INSERT INTO clientes (id, nome) VALUES (1,'Joao Pereira Brito');
INSERT INTO clientes (id, nome) VALUES (2,'Roberto Pereira Brito');
INSERT INTO clientes (id, nome) VALUES (3,'Antônio Pereira Brito');
INSERT INTO clientes (id, nome) VALUES (4,'Carlos Pereira Brito');
INSERT INTO clientes (id, nome) VALUES (5,'Otoniel Pereira Brito');
INSERT INTO clientes (id, nome) VALUES (6,'Helena Pereira Brito');
INSERT INTO clientes (id, nome) VALUES (7,'Flávio Pereira Brito');
INSERT INTO clientes (id, nome) VALUES (8,'Joana Pereira Brito');
INSERT INTO clientes (id, nome) VALUES (9,'Francisco Pereira Brito');
INSERT INTO clientes (id, nome) VALUES (10,'Jorge Pereira Brito');
INSERT INTO clientes (id, nome) VALUES (11,'Pedro Pereira Brito');
INSERT INTO clientes (id, nome) VALUES (12,'Ribamar Pereira Brito');
INSERT INTO clientes (id, nome) VALUES (13,'Tiago Pereira Brito');
INSERT INTO clientes (id, nome) VALUES (14,'Elias Pereira Brito');
INSERT INTO clientes (id, nome) VALUES (15,'Marcos Pereira Brito');
INSERT INTO clientes (id, nome) VALUES (16,'Ricardo Pereira Brito');
INSERT INTO clientes (id, nome) VALUES (17,'Rômulo Pereira Brito');

                               Ribamar FS – http://cursos.ribafs.org
Curso de CakePHP                          Página 34 /69

INSERT INTO clientes (id, nome) VALUES (18,'Henrique Pereira Brito');
INSERT INTO clientes (id, nome) VALUES (19,'Francis Pereira Brito');
INSERT INTO clientes (id, nome) VALUES (20,'Otávio Pereira Brito');
INSERT INTO clientes (id, nome) VALUES (21,'Rogério Pereira Brito');
INSERT INTO clientes (id, nome) VALUES (22,'Jurandir Pereira Brito');
INSERT INTO clientes (id, nome) VALUES (23,'Raquél Pereira Brito');


Criar o model:
cake/scaffold/models/cliente.php

<?php
class Cliente extends AppModel
{
var $name = 'Cliente';
}
?>

Criar o controller:
cake/scaffold/controllers/clientes_controller.php

<?php
class ClientesController extends AppController
{
var $scaffold;
}
?>

Apontar o Firefox para o controller:
http://localhost/cake/scaffold/clientes

Pronto, temos um CRUD, com estilo e paginação.


Scaffold com tabelas relacionadas

Tabelas jogadores e equipes

create table equipes
(
id int not null auto_increment primary key,
nome char(45) not null
);

create table jogadores
(
id int not null auto_increment primary key,
nome char(45) not null,

                               Ribamar FS – http://cursos.ribafs.org
Curso de CakePHP                          Página 35 /69

posicao char(25) not null,
equipe_id int
);


Detalhe: na tabela jogadores devemos ter um campo para relacionar com a equipes, no caso temos
equipe_id.
Este campo segue a convenção do Cake: nometabelasingular_id

Criar os controllers
cake/scaffold/controllers/jogadores_controller.php

<?php
class JogadoresController extends AppController
{
var $scaffold;
}
?>

cake/scaffold/controllers/equipes_controller.php

<?php
class EquipesController extends AppController
{
var $scaffold;
}
?>

Criando os Models

cake/scaffold/models/jogador.php

<?php
class Jogador extends AppModel
{
var $name = 'Jogador';

var $belongTo = array('Equipe' =>
array('className' => 'Equipe',
'conditions' => '',
'order'     => '',
'foreignKey' => 'equipe_id'
)
);
}
?>

cake/scaffold/models/equipe.php

                               Ribamar FS – http://cursos.ribafs.org
Curso de CakePHP                          Página 36 /69


<?php
class Equipe extends AppModel
{
var $name = 'Equipe';
}
?>

Abrir no navagador:
http://localhost/cake/scaffold/equipes

e

http://localhost/cake/scaffold/jogadores

Original de W.Jason Gilmore - http://www.wjgilmore.com




                               Ribamar FS – http://cursos.ribafs.org
Curso de CakePHP                           Página 37 /69

                                    10 - Cake - Validações

Validar como Não Vazio
Vamos validar o campo nome para não aceitar vazio.

Editar o model e adicionar:

var $validate = array(
'nome' => array(
'rule' => VALID_NOT_EMPTY
)
);

A validação é por campo.
Uma boa idéia é gerar um aplicativo com o bake e ver como ele gera o código da validação no
model.

Agora uma validação que inclui relacionamento:

<?php
class Pedido extends AppModel {

var $name = 'Pedido';
var $primaryKey = 'pedido';

//The Associations below have been created with all possible keys, those that are not needed can be
removed

var $belongsTo = array(
'Cliente' => array(
'className' => 'Cliente',
'foreignKey' => 'cliente_id',
'conditions' => '',
'fields' => '',
'order' => ''
),
'Funcionario' => array(
'className' => 'Funcionario',
'foreignKey' => 'funcionario_id',
'conditions' => '',
'fields' => '',
'order' => ''
)
);

}
?>

                               Ribamar FS – http://cursos.ribafs.org
Curso de CakePHP                            Página 38 /69


Vejamos os vários tipos de validação embutida que o Cake oferece (via Bake):

Você deseja fornecer critérios de validação para os campos de seu model? (y/n)
[y] >
Qual é a primaryKey?
[cliente] >

Field: cliente
Type: integer
---------------------------------------------------------------
Please select one of the following validation options:
---------------------------------------------------------------
1 - alphaNumeric
2 - between
3 - blank
4 - boolean
5 - cc
6 - comparison
7 - custom
8 - date
9 - decimal
10 - email
11 - equalTo
12 - extension
13 - file
14 - inList
15 - ip
16 - maxLength
17 - minLength
18 - money
19 - multiple
20 - notEmpty
21 - numeric
22 - phone
23 - postal
24 - range
25 - ssn
26 - time
27 - url
28 - userDefined
29 - Do not do any validation on this field.
... or enter in a valid regex validation string.

[21] >

Veja que quando concordamos que queremos validar ele mostra o primeiro campo e já nos sugere
um tipo de validação.

                                     Ribamar FS – http://cursos.ribafs.org
Curso de CakePHP                          Página 39 /69

No exemplo acima o campo cliente e integer e o Bake sugere validar como 21, que representa
numeric.
Claro que podemos mudar para outro da lista, mas isso já ajuda quando não sabemos o que fazer.




                              Ribamar FS – http://cursos.ribafs.org
Curso de CakePHP                             Página 40 /69

                                       11 - Cake - Menu

Após criar o código para cada tabela devemos adicionar um menu que integre todo o código.
Uma forma simples e natural de fazer isso é adicionando o arquivo views/pages/home.ctp

Criando a Home Page do Projeto:

Criar appname/views/pages/home.ctp com o conteúdo:
<h1>Bem vindo ao Bake</h1>
<p>Aqui podmeos fazer:</p>
<ul>
<li><?php echo $html->link('Lista de todos os clientes', array('controller' => 'clientes',
'action'=>'index')); ?></li>
<li><?php echo $html->link('Adicionar novo Cliente', array('controller' => 'clientes',
'action'=>'add')); ?></li>
<li>Editar Clientes</li>
<li>Excluir Clientes</li>
</ul>

Agora então podemos navegar no aplicativo como um todo assim:
http://localhost/appname/

Caso exista outros itens os adicione ao arquivo home.ctp.




                                Ribamar FS – http://cursos.ribafs.org
Curso de CakePHP                         Página 41 /69

                                      12 - Cake - CSS

CakePHP e CSS

Criando o CSS para o layout

Para mudar o template default do Cake precisamos alterar o arquivo:
cake/cake/libs/view/layouts/default.ctp


Template padrão do Cake
Veja seu conteúdo, inclusive nele é onde se encontra aquela frase "CakePHP: the rapid
development php framework:"
caso queiramos remover, assim como a pequena imgem do rodapé.
Observe que a frase está no title e no body.

<?php
?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<?php echo $html->charset(); ?>
<title>
<?php __('CakePHP: the rapid development php framework:'); ?>
<?php echo $title_for_layout; ?>
</title>
<?php
echo $html->meta('icon');

echo $html->css('cake.generic');

echo $scripts_for_layout;
?>
</head>
<body>
<div id="container">
<div id="header">
<h1><?php echo $html->link(__('CakePHP: the rapid development php framework', true),
'http://cakephp.org'); ?></h1>
</div>
<div id="content">

<?php $session->flash(); ?>

<?php echo $content_for_layout; ?>


                              Ribamar FS – http://cursos.ribafs.org
Curso de CakePHP                            Página 42 /69

</div>
<div id="footer">
<?php echo $html->link(
$html->image('cake.power.gif', array('alt'=> __("CakePHP: the rapid development php framework",
true), 'border'=>"0")),
'http://www.cakephp.org/',
array('target'=>'_blank'), null, false
);
?>
</div>
</div>
<?php echo $cakeDebug; ?>
</body>
</html>

Mudando este arquivo podemos transformar automaticamente todas as aplicações geradas.


Personalizando o Template
Caso criemos um arquivo chamado:
cake/app/views/layouts/default.ctp

O Cake o usará e ignorará o anterior.

O arquivo CSS default usado no aplicativo é este:
/app/webroot/css/cake.generic.css

E é chamado nas views assim:
<link rel="stylesheet" type="text/css" href="/ProjectPath/css/cake.generic.css" />


Personalizando o CSS existente, entrando com um novo script CSS:

Editar o script app/webroot/css/cake.generic.css e cole o código abaixo ao final:

* { font-family: "Lucida Grande",Lucida,sans-serif; }
th {
font-size: 14px;
font-weight: bold;
background-color: #e1e1e1;
border-bottom: 1px solid #ccc;
padding: 10px;
}
div.actions ul {
list-style-type: none;
}

Observe que adicionando nosso próprio estilo podemos controlar a aparência do site.

                               Ribamar FS – http://cursos.ribafs.org
Curso de CakePHP                             Página 43 /69


Editar então o script app/views/layouts/default.ctp e alterar a linha 4 para:

<?php print $html->css('cake.generic');?>

Para que o CSS do Cake volte, mas agora um pouco personalizado por nós.

Observe que o layout não é o padrão do Cake, pois tem algumas diferenças.

Referência: http://letthemcodecake.com/learning-cakephp/4/




                                Ribamar FS – http://cursos.ribafs.org
Curso de CakePHP                           Página 44 /69

                                  13 - Cake - JavaScript

Os arquivos .js (Javascript) caso existam devem ser salvos no diretório webroot/js/


Referências:


http://bakery.cakephp.org/articles/view/toggling-items-with-javascript


http://debuggable.com/posts/passing-controller-variables-to-your-javascript:48b4f0c6-c718-47b2-
bca1-05794834cda3


http://netunno.com/2009/08/incluir-arquivos-javascript-e-css-pela-view-de-um-conteudo-no-
cakephp/


http://ryan.ifupdown.com/2009/08/22/how-to-use-javascript-codeblock-in-cakephp/




                               Ribamar FS – http://cursos.ribafs.org
Curso de CakePHP                           Página 45 /69

                                    14 - Cake - Verdors

São os scripts de terceiros, que não fazem parte do core do Cake, que ficam no diretório verdors.


Carregando arquivos de terceiros (vendors):
A tradicional forma é carregando arquivos da pasta "verdors" usando a função vendor() que está
caindo em desuso.
Recebemos um warning se a usarmos.
A nova maneira de usar é com App:import().
Para carregar um arquivo de nome exemplo.php use o seguinte:
App::import('Vendor', 'exemplo');

Tem um pequeno problema aqui: só funciona se o nome do arquivo tiver todas as letras em
minúsculas.
Caso o arquivo tenha a inicial maiúsculas ao invés use:
App::import('Vendor', 'exemplo', array('file' => 'Exemplo.php'));

O segundo parâmetro pode ser qualquer string, exceto varia ou null.
O mesmo se aplica para:
App::import('Vendor', 'example'.DS.'example'); // loads example/example.php
App::import('Vendor', 'example', array('file' =>
'Example'.DS.'example.php')); // loads Example/example.php
Refeência - http://cakebaker.42dh.com/2008/03/26/loading-vendor-files/



Referências:
http://lemoncake.wordpress.com/2007/08/08/vendors-in-cakephp/




                               Ribamar FS – http://cursos.ribafs.org
Curso de CakePHP                           Página 46 /69

                             15 - Cake - Relacionamentos

O cake detecta relacionamentos entre as tabelas, mas para isso precisamos atender a algumas das
suas convenções.
Para isso a chave primária deve ser id ou criar com o Bake e indicar a chave primária.
O campo foreign key da tabela relacionada deve chamar-se obrigatoriamente


nometabelasingular_id


Exemplo:
cliente_id


Agora o Cake irá detectar os relacionamentos e adicionar uma combo nos campos foreign key das
tabelas relacionadas que será preenchida com dados da outra tabela.




                               Ribamar FS – http://cursos.ribafs.org
Curso de CakePHP                            Página 47 /69

                                      16 - Cake - Dicas

1) Padronização do aplicativo default


Como cada vez que vou criar um novo aplicativo no cake:
- Copio a pasta app com o nome do novo aplicativo (Exemplo: cad_livros)
- Depois então vou realizar as personalizações necessárias para começar:
- locales/pt-BR
- views/layout/default.ctp (faço uma cópia de cake/cake/libs/view/layouts/default.ctp para a pasta
views/layout e personalizo)
- webroot/index.php (adapto para permitir que vários aplicativos usem o mesmo core)
- entre outros.


Como eu estou sempre fazendo isso, fica mais prático já efetuar todas essas alterações na pasta
"app" do cake para que quando eu a copie já leve todas as minhas alterações.




                               Ribamar FS – http://cursos.ribafs.org
Curso de CakePHP                            Página 48 /69

                           17 - Cake – Aplicativos de Exemplo
17.1 - Aplicativo Livros

Aplicativo gerado pelo Bake com a finalidade de mostrar um relacionamento entre as tabelas
autores e livros e também mostrar o comportamento das validações.

Criar um aplicativo para apenas duas tabelas relacionadas usando o Bake

Banco - livro

tabelas

create table autores
(
    autor int auto_increment primary key,
    nome char(45) not null,
    email char(50)
);

create table livros
(
    isbn char(17) primary key,
    titulo char(45) not null,
    editora char(50) not null,
    autore_id int not null,
   FOREIGN KEY (autore_id) REFERENCES autores(autor) ON DELETE RESTRICT
);

insert into autores values (1, 'Alexandre Dumas Pai', 'alex@alex.com');
insert into autores values (2, 'Camões', 'camoes@camoes.com');
insert into autores values (3, 'Dante Alighieri', 'dante@dante.com');
insert into autores values (4, 'Albert Camus', 'albert@albert.com');
insert into autores values (5, 'Jean Paul Sartre', 'sartre@sartre.org');
insert into autores values (6, 'Augusto Cury', 'cury@cury.org');

insert into livros values ('978-0-470-03899-4', 'O Conde de Monte Cristo', 'Nova Data', 1);
insert into livros values ('978-0-470-03899-5', 'Os Três Mosqueteiros', 'Nova Data', 1);
insert into livros values ('978-0-470-03899-6', 'Os Lusíadas', 'Saraiva', 2);
insert into livros values ('978-0-470-03899-7', 'A Divina Comédia', 'Moderna', 3);
insert into livros values ('978-0-470-03899-8', 'O Estrangeiro', 'Moderna', 4);
insert into livros values ('979-0-470-03899-4', 'A Idade da Razão', 'Novatec', 5);
insert into livros values ('976-0-470-03899-4', 'Pais Brilhantes, Professores Fascinantes', 'Eldorado',
6);

Copiar a pasta app para livro.
Configurar a webroot/index.php para que vários app usem o mesmo core.


                                Ribamar FS – http://cursos.ribafs.org
Curso de CakePHP                            Página 49 /69

Agora usemos o bake para criar o aplicativo, com validação dos campos e relacionamento.

cd /var/www/cake/cake/console

./cake bake -app livro

1) Crie a configuração com o banco de dados livro.
./cake bake -app livro

2) Criar o model, o controller e a view para autores.
3) Depois criar o model, o controller e a view para livros (sempre nesta ordem).

Use diretamente

./cake bake -app livro model
./cake bake -app livro controller
./cake bake -app livro view

Au final vamos criar um simples menu para o Aplicativo:

Adicionar o arquivo views/pages/home.ctp

<h1>Aplicativo Livros</h1>
<p>Tarefas</p>
<ul>
<li><?php echo $html->link('Lista de todos os Autores', array('controller' => 'autores',
'action'=>'index')); ?></li>
<li><?php echo $html->link('Adicionar novo Autor', array('controller' => 'autores', 'action'=>'add'));
?></li>
<li><?php echo $html->link('Lista de todos os Livros', array('controller' => 'livros',
'action'=>'index')); ?></li>
<li><?php echo $html->link('Adicionar novo Livro', array('controller' => 'livros', 'action'=>'add')); ?
></li>
<li>Editar e Excluir Autores</li>
<li>Editar e Excluir Livros</li>
</ul>

Aí poderiamos adicionar editar, visualizar, excluir para ambos.

Chamar no navegador com:
http://localhost/cake/livro/

Dar suporte a pt-BR

Após implementar o suporte a pt-BR as mensagens de erro serão traduzidas, os nomes das ações
dentre outros.




                                Ribamar FS – http://cursos.ribafs.org
Curso de CakePHP                          Página 50 /69

Código do Aplicativo Livro criado com o Cake Bake

models/autore.php
<?php
class Autore extends AppModel {

     var $name = 'Autore';
     var $primaryKey = 'autor';
     var $validate = array(
         'autor' => array('numeric'),
         'nome' => array('notempty'),
         'email' => array('email')
     );

}
?>

models/livro.php
<?php
class Livro extends AppModel {

     var $name = 'Livro';
     var $primaryKey = 'isbn';
     var $validate = array(
         'isbn' => array('notempty'),
         'titulo' => array('notempty'),
         'editora' => array('notempty'),
         'autore_id' => array('numeric')
     );

    //The Associations below have been created with all possible keys, those that are not needed can
be removed
    var $belongsTo = array(
        'Autore' => array(
            'className' => 'Autore',
            'foreignKey' => 'autore_id',
            'conditions' => '',
            'fields' => '',
            'order' => ''
        )
    );

}
?>

controllers/autores_controller.php
<?php
class AutoresController extends AppController {

                                 Ribamar FS – http://cursos.ribafs.org
Curso de CakePHP                              Página 51 /69


   var $name = 'Autores';
   var $helpers = array('Html', 'Form');

   function index() {
      $this->Autore->recursive = 0;
      $this->set('autores', $this->paginate());
   }

   function view($id = null) {
      if (!$id) {
           $this->Session->setFlash(__('Invalid Autore.', true));
           $this->redirect(array('action'=>'index'));
      }
      $this->set('autore', $this->Autore->read(null, $id));
   }

    function add() {
        if (!empty($this->data)) {
             $this->Autore->create();
             if ($this->Autore->save($this->data)) {
                  $this->Session->setFlash(__('The Autore has been saved', true));
                  $this->redirect(array('action'=>'index'));
             } else {
                  $this->Session->setFlash(__('The Autore could not be saved. Please, try again.',
true));
             }
        }
    }

    function edit($id = null) {
        if (!$id && empty($this->data)) {
             $this->Session->setFlash(__('Invalid Autore', true));
             $this->redirect(array('action'=>'index'));
        }
        if (!empty($this->data)) {
             if ($this->Autore->save($this->data)) {
                  $this->Session->setFlash(__('The Autore has been saved', true));
                  $this->redirect(array('action'=>'index'));
             } else {
                  $this->Session->setFlash(__('The Autore could not be saved. Please, try again.',
true));
             }
        }
        if (empty($this->data)) {
             $this->data = $this->Autore->read(null, $id);
        }
    }

                                Ribamar FS – http://cursos.ribafs.org
Curso de CakePHP                              Página 52 /69


     function delete($id = null) {
        if (!$id) {
             $this->Session->setFlash(__('Invalid id for Autore', true));
             $this->redirect(array('action'=>'index'));
        }
        if ($this->Autore->del($id)) {
             $this->Session->setFlash(__('Autore deleted', true));
             $this->redirect(array('action'=>'index'));
        }
     }

}
?>

controllers/livros_controller.php
<?php
class LivrosController extends AppController {

     var $name = 'Livros';
     var $helpers = array('Html', 'Form');

     function index() {
        $this->Livro->recursive = 0;
        $this->set('livros', $this->paginate());
     }

     function view($id = null) {
        if (!$id) {
             $this->Session->setFlash(__('Invalid Livro.', true));
             $this->redirect(array('action'=>'index'));
        }
        $this->set('livro', $this->Livro->read(null, $id));
     }

    function add() {
        if (!empty($this->data)) {
             $this->Livro->create();
             if ($this->Livro->save($this->data)) {
                  $this->Session->setFlash(__('The Livro has been saved', true));
                  $this->redirect(array('action'=>'index'));
             } else {
                  $this->Session->setFlash(__('The Livro could not be saved. Please, try again.',
true));
             }
        }
        $autores = $this->Livro->Autore->find('list');
        $this->set(compact('autores'));

                                 Ribamar FS – http://cursos.ribafs.org
Curso de CakePHP                            Página 53 /69

     }

    function edit($id = null) {
        if (!$id && empty($this->data)) {
             $this->Session->setFlash(__('Invalid Livro', true));
             $this->redirect(array('action'=>'index'));
        }
        if (!empty($this->data)) {
             if ($this->Livro->save($this->data)) {
                  $this->Session->setFlash(__('The Livro has been saved', true));
                  $this->redirect(array('action'=>'index'));
             } else {
                  $this->Session->setFlash(__('The Livro could not be saved. Please, try again.',
true));
             }
        }
        if (empty($this->data)) {
             $this->data = $this->Livro->read(null, $id);
        }
        $autores = $this->Livro->Autore->find('list');
        $this->set(compact('autores'));
    }

     function delete($id = null) {
        if (!$id) {
             $this->Session->setFlash(__('Invalid id for Livro', true));
             $this->redirect(array('action'=>'index'));
        }
        if ($this->Livro->del($id)) {
             $this->Session->setFlash(__('Livro deleted', true));
             $this->redirect(array('action'=>'index'));
        }
     }

}
?>

views/autores/autores/add.ctp
<div class="autores form">
<?php echo $form->create('Autore');?>
   <fieldset>
        <legend><?php __('Add Autore');?></legend>
   <?php
        echo $form->input('nome');
        echo $form->input('email');
   ?>
   </fieldset>
<?php echo $form->end('Submit');?>

                                 Ribamar FS – http://cursos.ribafs.org
Curso de CakePHP                            Página 54 /69

</div>
<div class="actions">
    <ul>
        <li><?php echo $html->link(__('List Autores', true), array('action' => 'index'));?></li>
    </ul>
</div>

views/autores/autores/edit.ctp
<div class="autores form">
<?php echo $form->create('Autore');?>
    <fieldset>
        <legend><?php __('Edit Autore');?></legend>
    <?php
        echo $form->input('autor');
        echo $form->input('nome');
        echo $form->input('email');
    ?>
    </fieldset>
<?php echo $form->end('Submit');?>
</div>
<div class="actions">
    <ul>
        <li><?php echo $html->link(__('Delete', true), array('action' => 'delete', $form-
>value('Autore.autor')), null, sprintf(__('Are you sure you want to delete # %s?', true), $form-
>value('Autore.autor'))); ?></li>
        <li><?php echo $html->link(__('List Autores', true), array('action' => 'index'));?></li>
    </ul>
</div>

views/autores/autores/index.ctp
<div class="autores index">
<h2><?php __('Autores');?></h2>
<p>
<?php
echo $paginator->counter(array(
'format' => __('Page %page% of %pages%, showing %current% records out of %count% total,
starting on record %start%, ending on %end%', true)
));
?></p>
<table cellpadding="0" cellspacing="0">
<tr>
    <th><?php echo $paginator->sort('autor');?></th>
    <th><?php echo $paginator->sort('nome');?></th>
    <th><?php echo $paginator->sort('email');?></th>
    <th class="actions"><?php __('Actions');?></th>
</tr>
<?php
$i = 0;

                               Ribamar FS – http://cursos.ribafs.org
Curso de CakePHP                             Página 55 /69

foreach ($autores as $autore):
    $class = null;
    if ($i++ % 2 == 0) {
         $class = ' class="altrow"';
    }
?>
    <tr<?php echo $class;?>>
         <td>
              <?php echo $autore['Autore']['autor']; ?>
         </td>
         <td>
              <?php echo $autore['Autore']['nome']; ?>
         </td>
         <td>
              <?php echo $autore['Autore']['email']; ?>
         </td>
         <td class="actions">
              <?php echo $html->link(__('View', true), array('action' => 'view', $autore['Autore']
['autor'])); ?>
              <?php echo $html->link(__('Edit', true), array('action' => 'edit', $autore['Autore']
['autor'])); ?>
              <?php echo $html->link(__('Delete', true), array('action' => 'delete', $autore['Autore']
['autor']), null, sprintf(__('Tem certeza de que deseja excluir o autor # %s?', true), $autore['Autore']
['autor'])); ?>
         </td>
    </tr>
<?php endforeach; ?>
</table>
</div>
<div class="paging">
    <?php echo $paginator->prev('<< '.__('previous', true), array(), null, array('class'=>'disabled'));?
>
 | <?php echo $paginator->numbers();?>
    <?php echo $paginator->next(__('next', true).' >>', array(), null, array('class' => 'disabled'));?>
</div>
<div class="actions">
    <ul>
         <li><?php echo $html->link(__('New Autore', true), array('action' => 'add')); ?></li>
    </ul>
</div>

views/autores/autores/view.ctp
<div class="autores view">
<h2><?php __('Autore');?></h2>
   <dl><?php $i = 0; $class = ' class="altrow"';?>
        <dt<?php if ($i % 2 == 0) echo $class;?>><?php __('Autor'); ?></dt>
        <dd<?php if ($i++ % 2 == 0) echo $class;?>>
           <?php echo $autore['Autore']['autor']; ?>

                                Ribamar FS – http://cursos.ribafs.org
Curso de CakePHP                             Página 56 /69

              &nbsp;
         </dd>
         <dt<?php if ($i % 2 == 0) echo $class;?>><?php __('Nome'); ?></dt>
         <dd<?php if ($i++ % 2 == 0) echo $class;?>>
              <?php echo $autore['Autore']['nome']; ?>
              &nbsp;
         </dd>
         <dt<?php if ($i % 2 == 0) echo $class;?>><?php __('Email'); ?></dt>
         <dd<?php if ($i++ % 2 == 0) echo $class;?>>
              <?php echo $autore['Autore']['email']; ?>
              &nbsp;
         </dd>
    </dl>
</div>
<div class="actions">
    <ul>
         <li><?php echo $html->link(__('Edit Autore', true), array('action' => 'edit', $autore['Autore']
['autor'])); ?> </li>
         <li><?php echo $html->link(__('Delete Autore', true), array('action' => 'delete',
$autore['Autore']['autor']), null, sprintf(__('Are you sure you want to delete # %s?', true),
$autore['Autore']['autor'])); ?> </li>
         <li><?php echo $html->link(__('List Autores', true), array('action' => 'index')); ?> </li>
         <li><?php echo $html->link(__('New Autore', true), array('action' => 'add')); ?> </li>
    </ul>
</div>

livro/views/livros/add.ctp
<div class="livros form">
<?php echo $form->create('Livro');?>
    <fieldset>
        <legend><?php __('Add Livro');?></legend>
    <?php
        echo $form->input('titulo');
        echo $form->input('editora');
        echo $form->input('autore_id');
    ?>
    </fieldset>
<?php echo $form->end('Submit');?>
</div>
<div class="actions">
    <ul>
        <li><?php echo $html->link(__('List Livros', true), array('action' => 'index'));?></li>
        <li><?php echo $html->link(__('List Autores', true), array('controller' => 'autores', 'action'
=> 'index')); ?> </li>
        <li><?php echo $html->link(__('New Autore', true), array('controller' => 'autores', 'action'
=> 'add')); ?> </li>
    </ul>
</div>

                                Ribamar FS – http://cursos.ribafs.org
Curso de CakePHP                             Página 57 /69


livro/views/livros/edit.ctp
<div class="livros form">
<?php echo $form->create('Livro');?>
    <fieldset>
        <legend><?php __('Edit Livro');?></legend>
    <?php
        echo $form->input('isbn');
        echo $form->input('titulo');
        echo $form->input('editora');
        echo $form->input('autore_id');
    ?>
    </fieldset>
<?php echo $form->end('Submit');?>
</div>
<div class="actions">
    <ul>
        <li><?php echo $html->link(__('Delete', true), array('action' => 'delete', $form-
>value('Livro.isbn')), null, sprintf(__('Are you sure you want to delete # %s?', true), $form-
>value('Livro.isbn'))); ?></li>
        <li><?php echo $html->link(__('List Livros', true), array('action' => 'index'));?></li>
        <li><?php echo $html->link(__('List Autores', true), array('controller' => 'autores', 'action'
=> 'index')); ?> </li>
        <li><?php echo $html->link(__('New Autore', true), array('controller' => 'autores', 'action'
=> 'add')); ?> </li>
    </ul>
</div>

livro/views/livros/index.ctp
<div class="livros index">
<h2><?php __('Livros');?></h2>
<p>
<?php
echo $paginator->counter(array(
'format' => __('Page %page% of %pages%, showing %current% records out of %count% total,
starting on record %start%, ending on %end%', true)
));
?></p>
<table cellpadding="0" cellspacing="0">
<tr>
    <th><?php echo $paginator->sort('isbn');?></th>
    <th><?php echo $paginator->sort('titulo');?></th>
    <th><?php echo $paginator->sort('editora');?></th>
    <th><?php echo $paginator->sort('autore_id');?></th>
    <th class="actions"><?php __('Actions');?></th>
</tr>
<?php
$i = 0;

                                Ribamar FS – http://cursos.ribafs.org
Curso de CakePHP                               Página 58 /69

foreach ($livros as $livro):
     $class = null;
     if ($i++ % 2 == 0) {
          $class = ' class="altrow"';
     }
?>
     <tr<?php echo $class;?>>
          <td>
              <?php echo $livro['Livro']['isbn']; ?>
          </td>
          <td>
              <?php echo $livro['Livro']['titulo']; ?>
          </td>
          <td>
              <?php echo $livro['Livro']['editora']; ?>
          </td>
          <td>
              <?php echo $html->link($livro['Autore']['autor'], array('controller' => 'autores', 'action'
=> 'view', $livro['Autore']['autor'])); ?>
          </td>
          <td class="actions">
              <?php echo $html->link(__('View', true), array('action' => 'view', $livro['Livro']
['isbn'])); ?>
              <?php echo $html->link(__('Edit', true), array('action' => 'edit', $livro['Livro']['isbn'])); ?
>
              <?php echo $html->link(__('Delete', true), array('action' => 'delete', $livro['Livro']
['isbn']), null, sprintf(__('Are you sure you want to delete # %s?', true), $livro['Livro']['isbn'])); ?>
          </td>
     </tr>
<?php endforeach; ?>
</table>
</div>
<div class="paging">
     <?php echo $paginator->prev('<< '.__('previous', true), array(), null, array('class'=>'disabled'));?
>
 | <?php echo $paginator->numbers();?>
     <?php echo $paginator->next(__('next', true).' >>', array(), null, array('class' => 'disabled'));?>
</div>
<div class="actions">
     <ul>
          <li><?php echo $html->link(__('New Livro', true), array('action' => 'add')); ?></li>
          <li><?php echo $html->link(__('List Autores', true), array('controller' => 'autores', 'action'
=> 'index')); ?> </li>
          <li><?php echo $html->link(__('New Autore', true), array('controller' => 'autores', 'action'
=> 'add')); ?> </li>
     </ul>
</div>



                                 Ribamar FS – http://cursos.ribafs.org
Curso de CakePHP                             Página 59 /69

livro/views/livros/view.ctp
<div class="livros view">
<h2><?php __('Livro');?></h2>
     <dl><?php $i = 0; $class = ' class="altrow"';?>
         <dt<?php if ($i % 2 == 0) echo $class;?>><?php __('Isbn'); ?></dt>
         <dd<?php if ($i++ % 2 == 0) echo $class;?>>
              <?php echo $livro['Livro']['isbn']; ?>
              &nbsp;
         </dd>
         <dt<?php if ($i % 2 == 0) echo $class;?>><?php __('Titulo'); ?></dt>
         <dd<?php if ($i++ % 2 == 0) echo $class;?>>
              <?php echo $livro['Livro']['titulo']; ?>
              &nbsp;
         </dd>
         <dt<?php if ($i % 2 == 0) echo $class;?>><?php __('Editora'); ?></dt>
         <dd<?php if ($i++ % 2 == 0) echo $class;?>>
              <?php echo $livro['Livro']['editora']; ?>
              &nbsp;
         </dd>
         <dt<?php if ($i % 2 == 0) echo $class;?>><?php __('Autore'); ?></dt>
         <dd<?php if ($i++ % 2 == 0) echo $class;?>>
              <?php echo $html->link($livro['Autore']['autor'], array('controller' => 'autores', 'action'
=> 'view', $livro['Autore']['autor'])); ?>
              &nbsp;
         </dd>
     </dl>
</div>
<div class="actions">
     <ul>
         <li><?php echo $html->link(__('Edit Livro', true), array('action' => 'edit', $livro['Livro']
['isbn'])); ?> </li>
         <li><?php echo $html->link(__('Delete Livro', true), array('action' => 'delete', $livro['Livro']
['isbn']), null, sprintf(__('Are you sure you want to delete # %s?', true), $livro['Livro']['isbn'])); ?>
</li>
         <li><?php echo $html->link(__('List Livros', true), array('action' => 'index')); ?> </li>
         <li><?php echo $html->link(__('New Livro', true), array('action' => 'add')); ?> </li>
         <li><?php echo $html->link(__('List Autores', true), array('controller' => 'autores', 'action'
=> 'index')); ?> </li>
         <li><?php echo $html->link(__('New Autore', true), array('controller' => 'autores', 'action'
=> 'add')); ?> </li>
     </ul>
</div>




                                Ribamar FS – http://cursos.ribafs.org
Curso de CakePHP                          Página 60 /69

17.2 - Aplicativo de Exemplo – cake_olamundo

Criando Aplicativo no CakePHP de forma Simples e Rápida

Vamos copiar a pasta app do cake para ola_cake

Criar o banco cad_cliente

Configurar ola_cake/config/database.php

Configurar ola_cake/webroot/index.php na linha com define('CAKE_CORE_INCLUDE_PATH'
para:
       define('CAKE_CORE_INCLUDE_PATH', dirname(dirname(dirname(__FILE__))));

Criar tabela

create table clientes
(
    id int not null auto_increment primary key,
    nome char(45) not null
);

INSERT INTO clientes (id, nome) VALUES (1,'Joao Pereira Brito');
INSERT INTO clientes (id, nome) VALUES (2,'Roberto Pereira Brito');
INSERT INTO clientes (id, nome) VALUES (3,'Antônio Pereira Brito');
INSERT INTO clientes (id, nome) VALUES (4,'Carlos Pereira Brito');
INSERT INTO clientes (id, nome) VALUES (5,'Otoniel Pereira Brito');
INSERT INTO clientes (id, nome) VALUES (6,'Helena Pereira Brito');
INSERT INTO clientes (id, nome) VALUES (7,'Flávio Pereira Brito');
INSERT INTO clientes (id, nome) VALUES (8,'Joana Pereira Brito');
INSERT INTO clientes (id, nome) VALUES (9,'Francisco Pereira Brito');
INSERT INTO clientes (id, nome) VALUES (10,'Jorge Pereira Brito');
INSERT INTO clientes (id, nome) VALUES (11,'Pedro Pereira Brito');
INSERT INTO clientes (id, nome) VALUES (12,'Ribamar Pereira Brito');
INSERT INTO clientes (id, nome) VALUES (13,'Tiago Pereira Brito');
INSERT INTO clientes (id, nome) VALUES (14,'Elias Pereira Brito');
INSERT INTO clientes (id, nome) VALUES (15,'Marcos Pereira Brito');
INSERT INTO clientes (id, nome) VALUES (16,'Ricardo Pereira Brito');
INSERT INTO clientes (id, nome) VALUES (17,'Rômulo Pereira Brito');
INSERT INTO clientes (id, nome) VALUES (18,'Henrique Pereira Brito');
INSERT INTO clientes (id, nome) VALUES (19,'Francis Pereira Brito');
INSERT INTO clientes (id, nome) VALUES (20,'Otávio Pereira Brito');
INSERT INTO clientes (id, nome) VALUES (21,'Rogério Pereira Brito');
INSERT INTO clientes (id, nome) VALUES (22,'Jurandir Pereira Brito');
INSERT INTO clientes (id, nome) VALUES (23,'Raquél Pereira Brito');

Passos para a criação de um aplicativo básico após as configurações:
- Criar o model

                               Ribamar FS – http://cursos.ribafs.org
Curso de CakePHP                          Página 61 /69

- Criar o controller
- Adicionar o action index para o controller
- Criar a view index.ctp


Model:
cake/ola_cake/models/cliente.php

<?php
class Cliente extends AppModel {
   var $name = 'Cliente';
}
?>


Controller:
cake/ola_cake/controllers/clientes_controller.php

<?php
class ClientesController extends AppController
{
   var $name = 'Clientes';
}
?>

Toda função pública dentro da classe controller é chamada de action.
Esta action visualizará todos os clientes com a view index.ctp

<?php
class ClientesController extends AppController
{
   var $name = 'Clientes';

     // Para a view index.ctp
     function index() {
         $this->set('clientes', $this->Cliente->find('all'));
     }
}
?>


View:
cake/ola_cake/views/clientes/index.ctp

<h2>Clientes</h2>
<?php if(empty($clientes)): ?>
 Nenum cliente encontrado
<?php else: ?>

                                  Ribamar FS – http://cursos.ribafs.org
Curso de CakePHP                          Página 62 /69

 <table>
   <tr>
     <th>ID</th>
     <th>Nome</th>
     <th>Ações</th>
   </tr>
   <?php foreach ($clientes as $cliente): ?>
     <tr>
       <td>
         <?php echo $cliente['Cliente']['id'] ?>
       </td>
       <td>
         <?php echo $cliente['Cliente']['nome'] ?>
       </td>
       <td>
          <!-- actions on tasks will be added later -->
       </td>
     </tr>
   <?php endforeach; ?>
 </table>
<?php endif; ?>


Agora chamar no navegador assim:

http://localhost/cake/ola_cake/clientes

Aí temos a listagem dos registros da tabela praticamente sem programação, apenas algumas poucas
linhas.


Adicionar Registros

Para isso precisaremos adicionar uma variável (array $helpers) e uma função add() ao controller,
como também adicionar uma view à pasta
clientes, de nome add.ctp.

   var $helpers = array('Html', 'Form');

   function add() {
      if (!empty($this->data)) {
         $this->Cliente->create();
         if ($this->Cliente->save($this->data)) {
             $this->Session->setFlash('Cliente foi adicionado');
             $this->redirect(array('action'=>'index'), null, true);
         } else {
             $this->Session->setFlash('Cliente não adicionado. Tente novamente.');
         }

                                Ribamar FS – http://cursos.ribafs.org
Curso de CakePHP                           Página 63 /69

         }
     }


Que ficará assim:
cake/ola_cake/controllers/clientes_controller.php

<?php
class ClientesController extends AppController
{
   var $name = 'Clientes';
    var $helpers = array('Html', 'Form');

     function index() {
        $this->set('clientes', $this->Cliente->find('all'));
     }

     function add() {
        if (!empty($this->data)) {
           $this->Cliente->create();
           if ($this->Cliente->save($this->data)) {
               $this->Session->setFlash('Cliente foi adicionado');
               $this->redirect(array('action'=>'index'), null, true);
           } else {
               $this->Session->setFlash('Cliente não adicionado. Tente novamente.');
           }
        }
     }
}
?>

Adicionar a view:
cake/ola_cake/views/clientes/add.ctp

<?php echo $form->create('Cliente');?>
 <fieldset>
   <legend>Adicionar novo Cliente</legend>
   <?php
     echo $form->input('ID');
     echo $form->input('Nome');
   ?>
 </fieldset>
<?php echo $form->end('Adicionar');?>

Agora chame com o navegador:

http://localhost/cake/ola_cake/clientes/add



                                  Ribamar FS – http://cursos.ribafs.org
Curso de CakePHP                              Página 64 /69


Adicionar um link do form Add para a nossa view index.ctp (adicionar ao final):

<?php echo $html->link('Adicionar Cliente', array('action'=>'add')); ?>


Adicionar um link para a view index na view add.ctp (ao final):

<?php echo $html->link('Listar todos os Clientes', array('action'=>'index')); ?>



Editar Registros

Para isso precisamos adicionar um action (edit) ao controller e uma view para este action
(views/clientes/edit.ctp).

cake/ola_cake/controllers/clientes_controller.php

<?php
class ClientesController extends AppController
{
   var $name = 'Clientes';

   var $helpers = array('Html', 'Form');

   function add() {
      if (!empty($this->data)) {
         $this->Cliente->create();
         if ($this->Cliente->save($this->data)) {
             $this->Session->setFlash('Cliente foi adicionado');
             $this->redirect(array('action'=>'index'), null, true);
         } else {
             $this->Session->setFlash('Cliente não adicionado. Tente novamente.');
         }
      }
   }

   function edit($id = null) {
     if (!$id) {
         $this->Session->setFlash('Cliente Inválido');
         $this->redirect(array('action'=>'index'), null, true);
     }
     if (empty($this->data)) {
         $this->data = $this->Cliente->find(array('id' => $id));
     } else {
         if ($this->Cliente->save($this->data)) {
            $this->Session->setFlash('O Cliente foi salvo!');

                               Ribamar FS – http://cursos.ribafs.org
Curso de CakePHP                           Página 65 /69

               $this->redirect(array('action'=>'index'), null, true);
             } else {
               $this->Session->setFlash('O Cliente não pôde ser salvo. Favor tentar novamente.');
             }
         }
     }
}
?>

Adicionar o link para Edição na index.ctp, para que fique assim:

<h2>Clientes</h2>
<?php if(empty($clientes)): ?>
 Nenum cliente encontrado
<?php else: ?>
 <table>
   <tr>
     <th>ID</th>
     <th>Nome</th>
     <th>Ações</th>
   </tr>
   <?php foreach ($clientes as $cliente): ?>
     <tr>
       <td>
         <?php echo $cliente['Cliente']['id'] ?>
       </td>
       <td>
         <?php echo $cliente['Cliente']['nome'] ?>
       </td>
       <td>
          <!-- actions on tasks will be added later -->
                <?php echo $html->link('Editar', array('action'=>'edit', $cliente['Cliente']['id'])); ?>
       </td>
     </tr>
   <?php endforeach; ?>
 </table>
<?php endif; ?>

<?php echo $html->link('Adicionar Cliente', array('action'=>'add')); ?>


Agora adicionar o link para o edit.ctp:

<?php echo $html->link('Listar Todos os Clientes', array('action'=>'index')); ?><br />
<?php echo $html->link('Adicionar Cliente', array('action'=>'add')); ?>




                                   Ribamar FS – http://cursos.ribafs.org
Curso de CakePHP                             Página 66 /69

Criar um Menu de entrada

Adicionar o arquivo home.ctp em views/pages:

<h1>Bem vindo ao Bake</h1>
<p>Aqui podmeos fazer:</p>
<ul>
  <li><?php echo $html->link('Lista de todos os clientes', array('controller' => 'clientes',
'action'=>'index')); ?></li>
  <li><?php echo $html->link('Adicionar novo Cliente', array('controller' => 'clientes',
'action'=>'add')); ?></li>
  <li>Editar Clientes</li>
  <li>Excluir Clientes</li>
</ul>


Agora basta chamar no navegador:
http://localhost/cake/ola_cake/




17.3 - Outros Aplicativos de Exemplo encontrados no Site:

   –   bake
   –   blog
   –   estoque
   –   foreign
   –   forum
   –   ola_cake




                                Ribamar FS – http://cursos.ribafs.org
Curso de CakePHP                            Página 67 /69

                                   18 - Cake - Referências

Site oficial
http://cakephp.org

Site Brasileiro do CakePHP
http://cakephp.com.br/


Manuais
Manual do Cake - CookBook
http://book.cakephp.org/pt/complete/3/The-Manual

Manual do Cake em Português
http://manual.cakephp.com.br/doku.php

Blog Tutorial
http://book.cakephp.org/view/219/the-cakephp-blog-tutorial

Screencasts
http://cakephp.org/screencasts

CheatSheets
http://cakephp.org/files/Resources/CakePHP-1.2-Cheatsheet.pdf
Listas
FAQs da Lista internacional
http://groups.google.com/group/cake-php/web/faq?pli=1

Lista internacional (em processo de mudança para outro servidor)
http://groups.google.com/group/cake-php/topics

Lista portuguesa
http://groups.google.com/group/cake-php-pt

Tutoriais
Tutorial da IBM em 5 partes somando mais de 130 páginas - Cook up Web sites fast with CakePHP
https://www.ibm.com/developerworks/opensource/tutorials/os-php-cake1/

* Part 1 focuses on getting CakePHP up and running, and the basics of how to put together a simple
application
allowing users to register for an account and log in to the application.
http://www.ibm.com/developerworks/opensource/tutorials/os-php-cake1/os-php-cake1-pdf.pdf
Código fonte - http://www.ibm.com/developerworks/apps/download/index.jsp?
contentid=390462&filename=os-php-cake1.source.zip&method=http&locale=worldwide

* Part 2 demonstrates how to use scaffolding and Bake to get a jump-start on your application, and
using CakePHP's access control lists (ACLs).

                                 Ribamar FS – http://cursos.ribafs.org
Curso CakePHP Completo
Curso CakePHP Completo

Más contenido relacionado

La actualidad más candente

Caelum csharp-dotnet-fn13
Caelum csharp-dotnet-fn13Caelum csharp-dotnet-fn13
Caelum csharp-dotnet-fn13Moisés Moura
 
Aprendendo action script 3.0
Aprendendo action script 3.0Aprendendo action script 3.0
Aprendendo action script 3.0Diogo FN
 
Caelum java-testes-jsf-web-services-design-patterns-fj22
Caelum java-testes-jsf-web-services-design-patterns-fj22Caelum java-testes-jsf-web-services-design-patterns-fj22
Caelum java-testes-jsf-web-services-design-patterns-fj22Moisés Moura
 
Apostila de Java: Orientação a Objetos
Apostila de Java: Orientação a ObjetosApostila de Java: Orientação a Objetos
Apostila de Java: Orientação a ObjetosK19 Treinamentos
 
Caelum java-testes-jsf-web-services-design-patterns-fj22
Caelum java-testes-jsf-web-services-design-patterns-fj22Caelum java-testes-jsf-web-services-design-patterns-fj22
Caelum java-testes-jsf-web-services-design-patterns-fj22Valdinho Pereira
 
K19 k32-desenvolvimento-web-com-aspnet-mvc
K19 k32-desenvolvimento-web-com-aspnet-mvcK19 k32-desenvolvimento-web-com-aspnet-mvc
K19 k32-desenvolvimento-web-com-aspnet-mvcTrioBlack Trioblack
 
K19 k03-sql-e-modelo-relacional
K19 k03-sql-e-modelo-relacionalK19 k03-sql-e-modelo-relacional
K19 k03-sql-e-modelo-relacionalJean Lopes
 
Caelum java-web-vraptor-hibernate-ajax-fj28
Caelum java-web-vraptor-hibernate-ajax-fj28Caelum java-web-vraptor-hibernate-ajax-fj28
Caelum java-web-vraptor-hibernate-ajax-fj28Valdinho Pereira
 
K19 k12-desenvolvimento-web-com-jsf2-e-jpa2
K19 k12-desenvolvimento-web-com-jsf2-e-jpa2K19 k12-desenvolvimento-web-com-jsf2-e-jpa2
K19 k12-desenvolvimento-web-com-jsf2-e-jpa2surdido
 

La actualidad más candente (17)

Caelum csharp-dotnet-fn13
Caelum csharp-dotnet-fn13Caelum csharp-dotnet-fn13
Caelum csharp-dotnet-fn13
 
Aprendendo action script 3.0
Aprendendo action script 3.0Aprendendo action script 3.0
Aprendendo action script 3.0
 
Caelum java-web-fj21
Caelum java-web-fj21Caelum java-web-fj21
Caelum java-web-fj21
 
Photoshop cs3
Photoshop cs3Photoshop cs3
Photoshop cs3
 
K19 sql
K19 sqlK19 sql
K19 sql
 
Apostila JSF 2.0 - K19
Apostila JSF 2.0 - K19Apostila JSF 2.0 - K19
Apostila JSF 2.0 - K19
 
Apostila UML
Apostila UML Apostila UML
Apostila UML
 
Algorimos java
Algorimos javaAlgorimos java
Algorimos java
 
Caelum java-testes-jsf-web-services-design-patterns-fj22
Caelum java-testes-jsf-web-services-design-patterns-fj22Caelum java-testes-jsf-web-services-design-patterns-fj22
Caelum java-testes-jsf-web-services-design-patterns-fj22
 
Apostila de Java: Orientação a Objetos
Apostila de Java: Orientação a ObjetosApostila de Java: Orientação a Objetos
Apostila de Java: Orientação a Objetos
 
Caelum java-testes-jsf-web-services-design-patterns-fj22
Caelum java-testes-jsf-web-services-design-patterns-fj22Caelum java-testes-jsf-web-services-design-patterns-fj22
Caelum java-testes-jsf-web-services-design-patterns-fj22
 
K19 k32-desenvolvimento-web-com-aspnet-mvc
K19 k32-desenvolvimento-web-com-aspnet-mvcK19 k32-desenvolvimento-web-com-aspnet-mvc
K19 k32-desenvolvimento-web-com-aspnet-mvc
 
K19 k03-sql-e-modelo-relacional
K19 k03-sql-e-modelo-relacionalK19 k03-sql-e-modelo-relacional
K19 k03-sql-e-modelo-relacional
 
Caelum java-web-vraptor-hibernate-ajax-fj28
Caelum java-web-vraptor-hibernate-ajax-fj28Caelum java-web-vraptor-hibernate-ajax-fj28
Caelum java-web-vraptor-hibernate-ajax-fj28
 
K19 k12-desenvolvimento-web-com-jsf2-e-jpa2
K19 k12-desenvolvimento-web-com-jsf2-e-jpa2K19 k12-desenvolvimento-web-com-jsf2-e-jpa2
K19 k12-desenvolvimento-web-com-jsf2-e-jpa2
 
Introdução ao SciLab
Introdução ao SciLabIntrodução ao SciLab
Introdução ao SciLab
 
Rslinx classic portugues
Rslinx classic portuguesRslinx classic portugues
Rslinx classic portugues
 

Destacado

Convenções de código para a linguagem de programação
Convenções de código para a linguagem de programaçãoConvenções de código para a linguagem de programação
Convenções de código para a linguagem de programaçãoalyssontmv
 
Apresentação linguagem cobol
Apresentação linguagem cobolApresentação linguagem cobol
Apresentação linguagem cobolAlexByDoomS
 
Lista de exercícios resolvidos
Lista de exercícios resolvidosLista de exercícios resolvidos
Lista de exercícios resolvidosCrishna Irion
 
cakephp 3.0 o bolo ainda serve muita gente
cakephp 3.0 o bolo ainda serve muita gentecakephp 3.0 o bolo ainda serve muita gente
cakephp 3.0 o bolo ainda serve muita gentetdc-globalcode
 
Kickstarter para jogos: É realmente necessário?
Kickstarter para jogos: É realmente necessário?Kickstarter para jogos: É realmente necessário?
Kickstarter para jogos: É realmente necessário?tdc-globalcode
 
Simbolos logicos com tabelas verdad
Simbolos logicos com tabelas verdadSimbolos logicos com tabelas verdad
Simbolos logicos com tabelas verdadReginaldo Steinhardt
 
CakePHP para iniciantes
CakePHP para iniciantesCakePHP para iniciantes
CakePHP para iniciantesIgor Feghali
 
Algoritmos resolvidos lista 2
Algoritmos resolvidos lista 2Algoritmos resolvidos lista 2
Algoritmos resolvidos lista 2isa_ise
 
Exercícios resolvidos de Algoritmo
Exercícios resolvidos de AlgoritmoExercícios resolvidos de Algoritmo
Exercícios resolvidos de AlgoritmoJota Thin
 
50978145 algoritmos-exercicios-resolvidos
50978145 algoritmos-exercicios-resolvidos50978145 algoritmos-exercicios-resolvidos
50978145 algoritmos-exercicios-resolvidosEdvan Mateó
 
Como criar um artigo em 1 HORA
Como criar um artigo em 1 HORAComo criar um artigo em 1 HORA
Como criar um artigo em 1 HORAinfo_cimol
 
Aula 8 - Lógica de Programação - Variáveis, Tipos de dados e Operadores
Aula 8 - Lógica de Programação - Variáveis, Tipos de dados e OperadoresAula 8 - Lógica de Programação - Variáveis, Tipos de dados e Operadores
Aula 8 - Lógica de Programação - Variáveis, Tipos de dados e OperadoresAndré Constantino da Silva
 
Assembly para pc-25paginas
Assembly para pc-25paginasAssembly para pc-25paginas
Assembly para pc-25paginasMikeNandes
 
Análise assintótica
Análise assintóticaAnálise assintótica
Análise assintóticaPablo Silva
 
CakePHP com sotaque brasileiro
CakePHP com sotaque brasileiroCakePHP com sotaque brasileiro
CakePHP com sotaque brasileiroJuan Basso
 
Glosario de qbasic liliana
Glosario de qbasic lilianaGlosario de qbasic liliana
Glosario de qbasic lilianakhjhjhjh
 

Destacado (20)

Convenções de código para a linguagem de programação
Convenções de código para a linguagem de programaçãoConvenções de código para a linguagem de programação
Convenções de código para a linguagem de programação
 
ideias de programação
ideias de programaçãoideias de programação
ideias de programação
 
Apresentação linguagem cobol
Apresentação linguagem cobolApresentação linguagem cobol
Apresentação linguagem cobol
 
Lista de exercícios resolvidos
Lista de exercícios resolvidosLista de exercícios resolvidos
Lista de exercícios resolvidos
 
cakephp 3.0 o bolo ainda serve muita gente
cakephp 3.0 o bolo ainda serve muita gentecakephp 3.0 o bolo ainda serve muita gente
cakephp 3.0 o bolo ainda serve muita gente
 
Kickstarter para jogos: É realmente necessário?
Kickstarter para jogos: É realmente necessário?Kickstarter para jogos: É realmente necessário?
Kickstarter para jogos: É realmente necessário?
 
Simbolos logicos com tabelas verdad
Simbolos logicos com tabelas verdadSimbolos logicos com tabelas verdad
Simbolos logicos com tabelas verdad
 
CakePHP para iniciantes
CakePHP para iniciantesCakePHP para iniciantes
CakePHP para iniciantes
 
Algoritmos resolvidos lista 2
Algoritmos resolvidos lista 2Algoritmos resolvidos lista 2
Algoritmos resolvidos lista 2
 
Exercícios resolvidos de Algoritmo
Exercícios resolvidos de AlgoritmoExercícios resolvidos de Algoritmo
Exercícios resolvidos de Algoritmo
 
Introdução ao Framework CakePHP
Introdução ao Framework CakePHPIntrodução ao Framework CakePHP
Introdução ao Framework CakePHP
 
50978145 algoritmos-exercicios-resolvidos
50978145 algoritmos-exercicios-resolvidos50978145 algoritmos-exercicios-resolvidos
50978145 algoritmos-exercicios-resolvidos
 
Como criar um artigo em 1 HORA
Como criar um artigo em 1 HORAComo criar um artigo em 1 HORA
Como criar um artigo em 1 HORA
 
Aula 2 - Processos de Software
Aula 2 - Processos de SoftwareAula 2 - Processos de Software
Aula 2 - Processos de Software
 
Aula 8 - Lógica de Programação - Variáveis, Tipos de dados e Operadores
Aula 8 - Lógica de Programação - Variáveis, Tipos de dados e OperadoresAula 8 - Lógica de Programação - Variáveis, Tipos de dados e Operadores
Aula 8 - Lógica de Programação - Variáveis, Tipos de dados e Operadores
 
Assembly para pc-25paginas
Assembly para pc-25paginasAssembly para pc-25paginas
Assembly para pc-25paginas
 
Análise assintótica
Análise assintóticaAnálise assintótica
Análise assintótica
 
PROGRAMAS QBASIC
PROGRAMAS QBASICPROGRAMAS QBASIC
PROGRAMAS QBASIC
 
CakePHP com sotaque brasileiro
CakePHP com sotaque brasileiroCakePHP com sotaque brasileiro
CakePHP com sotaque brasileiro
 
Glosario de qbasic liliana
Glosario de qbasic lilianaGlosario de qbasic liliana
Glosario de qbasic liliana
 

Similar a Curso CakePHP Completo

Java web fj21-- apostila da caelum
Java web fj21-- apostila da caelumJava web fj21-- apostila da caelum
Java web fj21-- apostila da caelumAgenor Neto
 
Jspservlets
JspservletsJspservlets
JspservletsTiago
 
JasperReports Tecnicas de geracao_de_relatorios1
JasperReports  Tecnicas de geracao_de_relatorios1JasperReports  Tecnicas de geracao_de_relatorios1
JasperReports Tecnicas de geracao_de_relatorios1Sliedesharessbarbosa
 
Fatec sbc lpbd-php_completo_como_programar
Fatec sbc lpbd-php_completo_como_programarFatec sbc lpbd-php_completo_como_programar
Fatec sbc lpbd-php_completo_como_programarTiago
 
Palestra - Symfony Framework MVC PHP 5
Palestra - Symfony Framework MVC PHP 5Palestra - Symfony Framework MVC PHP 5
Palestra - Symfony Framework MVC PHP 5Lucas Augusto Carvalho
 
Caelum java-web-vraptor-hibernate-ajax-fj28
Caelum java-web-vraptor-hibernate-ajax-fj28Caelum java-web-vraptor-hibernate-ajax-fj28
Caelum java-web-vraptor-hibernate-ajax-fj28Caique Moretto
 
Cakephp - framework de desenvolvimento de aplicações Web em PHP
Cakephp - framework de desenvolvimento de aplicações Web em PHPCakephp - framework de desenvolvimento de aplicações Web em PHP
Cakephp - framework de desenvolvimento de aplicações Web em PHPArlindo Santos
 
Pense no futuro: PHP com Zend Framework
Pense no futuro: PHP com Zend FrameworkPense no futuro: PHP com Zend Framework
Pense no futuro: PHP com Zend FrameworkFlávio Lisboa
 
Caelum html-css-javascript-php
Caelum html-css-javascript-phpCaelum html-css-javascript-php
Caelum html-css-javascript-phpLindomar ...
 
Lampada Php Conference Brasil 2007 Palestra
Lampada Php Conference Brasil 2007 PalestraLampada Php Conference Brasil 2007 Palestra
Lampada Php Conference Brasil 2007 PalestraDavid O'Keefe
 
Gerência de redes utilizando o cacti
Gerência de redes utilizando o cactiGerência de redes utilizando o cacti
Gerência de redes utilizando o cactiIsraelCunha
 
Postfix
PostfixPostfix
PostfixTiago
 
Introdução ao framework CodeIgniter
Introdução ao framework CodeIgniterIntrodução ao framework CodeIgniter
Introdução ao framework CodeIgniterAnderson Gonçalves
 
Treinamento Básico de Django
Treinamento Básico de DjangoTreinamento Básico de Django
Treinamento Básico de DjangoLeandro Zanuz
 

Similar a Curso CakePHP Completo (20)

Java web fj21-- apostila da caelum
Java web fj21-- apostila da caelumJava web fj21-- apostila da caelum
Java web fj21-- apostila da caelum
 
Cake Php
Cake PhpCake Php
Cake Php
 
Jspservlets
JspservletsJspservlets
Jspservlets
 
JasperReports Tecnicas de geracao_de_relatorios1
JasperReports  Tecnicas de geracao_de_relatorios1JasperReports  Tecnicas de geracao_de_relatorios1
JasperReports Tecnicas de geracao_de_relatorios1
 
Fatec sbc lpbd-php_completo_como_programar
Fatec sbc lpbd-php_completo_como_programarFatec sbc lpbd-php_completo_como_programar
Fatec sbc lpbd-php_completo_como_programar
 
CakePHP
CakePHPCakePHP
CakePHP
 
Palestra - Symfony Framework MVC PHP 5
Palestra - Symfony Framework MVC PHP 5Palestra - Symfony Framework MVC PHP 5
Palestra - Symfony Framework MVC PHP 5
 
Asp.net
Asp.netAsp.net
Asp.net
 
Caelum java-web-vraptor-hibernate-ajax-fj28
Caelum java-web-vraptor-hibernate-ajax-fj28Caelum java-web-vraptor-hibernate-ajax-fj28
Caelum java-web-vraptor-hibernate-ajax-fj28
 
Cakephp - framework de desenvolvimento de aplicações Web em PHP
Cakephp - framework de desenvolvimento de aplicações Web em PHPCakephp - framework de desenvolvimento de aplicações Web em PHP
Cakephp - framework de desenvolvimento de aplicações Web em PHP
 
Apresentando o CakePHP
Apresentando o CakePHPApresentando o CakePHP
Apresentando o CakePHP
 
Pense no futuro: PHP com Zend Framework
Pense no futuro: PHP com Zend FrameworkPense no futuro: PHP com Zend Framework
Pense no futuro: PHP com Zend Framework
 
Caelum html-css-javascript-php
Caelum html-css-javascript-phpCaelum html-css-javascript-php
Caelum html-css-javascript-php
 
Lampada Php Conference Brasil 2007 Palestra
Lampada Php Conference Brasil 2007 PalestraLampada Php Conference Brasil 2007 Palestra
Lampada Php Conference Brasil 2007 Palestra
 
Gerência de redes utilizando o cacti
Gerência de redes utilizando o cactiGerência de redes utilizando o cacti
Gerência de redes utilizando o cacti
 
Postfix
PostfixPostfix
Postfix
 
Introdução Play framework
Introdução Play frameworkIntrodução Play framework
Introdução Play framework
 
Introdução ao framework CodeIgniter
Introdução ao framework CodeIgniterIntrodução ao framework CodeIgniter
Introdução ao framework CodeIgniter
 
PHP 10 CodeIgniter
PHP 10 CodeIgniterPHP 10 CodeIgniter
PHP 10 CodeIgniter
 
Treinamento Básico de Django
Treinamento Básico de DjangoTreinamento Básico de Django
Treinamento Básico de Django
 

Más de Luiz Ladeira

Artigo - OS FUNDAMENTOS DE TESTE DE SOFTWARE E SUA IMPORTÂNCIA NA QUALIDADE D...
Artigo - OS FUNDAMENTOS DE TESTE DE SOFTWARE E SUA IMPORTÂNCIA NA QUALIDADE D...Artigo - OS FUNDAMENTOS DE TESTE DE SOFTWARE E SUA IMPORTÂNCIA NA QUALIDADE D...
Artigo - OS FUNDAMENTOS DE TESTE DE SOFTWARE E SUA IMPORTÂNCIA NA QUALIDADE D...Luiz Ladeira
 
OS FUNDAMENTOS DE TESTE DE SOFTWARE E SUA IMPORTÂNCIA NA QUALIDADE DE PROJETOS
OS FUNDAMENTOS DE TESTE DE SOFTWARE E SUA IMPORTÂNCIA NA QUALIDADE DE PROJETOSOS FUNDAMENTOS DE TESTE DE SOFTWARE E SUA IMPORTÂNCIA NA QUALIDADE DE PROJETOS
OS FUNDAMENTOS DE TESTE DE SOFTWARE E SUA IMPORTÂNCIA NA QUALIDADE DE PROJETOSLuiz Ladeira
 
E commerce - magento - produto simples e configuravel
E commerce - magento - produto simples e configuravelE commerce - magento - produto simples e configuravel
E commerce - magento - produto simples e configuravelLuiz Ladeira
 
Redes arquitetura de redes rm osi e tcp_ip
Redes  arquitetura de redes rm osi e tcp_ipRedes  arquitetura de redes rm osi e tcp_ip
Redes arquitetura de redes rm osi e tcp_ipLuiz Ladeira
 
Resumo a lógica matemática para concursos
Resumo a lógica matemática para concursosResumo a lógica matemática para concursos
Resumo a lógica matemática para concursosLuiz Ladeira
 
Resumo a lógica matemática para concursos
Resumo a lógica matemática para concursosResumo a lógica matemática para concursos
Resumo a lógica matemática para concursosLuiz Ladeira
 

Más de Luiz Ladeira (6)

Artigo - OS FUNDAMENTOS DE TESTE DE SOFTWARE E SUA IMPORTÂNCIA NA QUALIDADE D...
Artigo - OS FUNDAMENTOS DE TESTE DE SOFTWARE E SUA IMPORTÂNCIA NA QUALIDADE D...Artigo - OS FUNDAMENTOS DE TESTE DE SOFTWARE E SUA IMPORTÂNCIA NA QUALIDADE D...
Artigo - OS FUNDAMENTOS DE TESTE DE SOFTWARE E SUA IMPORTÂNCIA NA QUALIDADE D...
 
OS FUNDAMENTOS DE TESTE DE SOFTWARE E SUA IMPORTÂNCIA NA QUALIDADE DE PROJETOS
OS FUNDAMENTOS DE TESTE DE SOFTWARE E SUA IMPORTÂNCIA NA QUALIDADE DE PROJETOSOS FUNDAMENTOS DE TESTE DE SOFTWARE E SUA IMPORTÂNCIA NA QUALIDADE DE PROJETOS
OS FUNDAMENTOS DE TESTE DE SOFTWARE E SUA IMPORTÂNCIA NA QUALIDADE DE PROJETOS
 
E commerce - magento - produto simples e configuravel
E commerce - magento - produto simples e configuravelE commerce - magento - produto simples e configuravel
E commerce - magento - produto simples e configuravel
 
Redes arquitetura de redes rm osi e tcp_ip
Redes  arquitetura de redes rm osi e tcp_ipRedes  arquitetura de redes rm osi e tcp_ip
Redes arquitetura de redes rm osi e tcp_ip
 
Resumo a lógica matemática para concursos
Resumo a lógica matemática para concursosResumo a lógica matemática para concursos
Resumo a lógica matemática para concursos
 
Resumo a lógica matemática para concursos
Resumo a lógica matemática para concursosResumo a lógica matemática para concursos
Resumo a lógica matemática para concursos
 

Curso CakePHP Completo

  • 1. Curso de CakePHP Página 1 /69 Curso de CakePHP 1 – Introdução . . . . . . . . . . . . . . . . 2 2 – Configurações . . . . . . . . . . . . . . . 6 3 – Convenções . . . . . . . . . . . . . . . 8 4 – Bake (Gerando aplicativos pela console) . . . . . . . . 12 5 – Model . . . . . . . . . . . . . . . . . 20 6 – Controller . . . . . . . . . . . . . . . . 22 7 – View . . . . . . . . . . . . . . . . . 25 8 – Action . . . . . . . . . . . . . . . . . 29 9 – Scaffold . . . . . . . . . . . . . . . . 33 10 – Validações . . . . . . . . . . . . . . . 37 11 – Menus . . . . . . . . . . . . . . . . 40 12 – CSS . . . . . . . . . . . . . . . . . 41 13 – JavaScript . . . . . . . . . . . . . . . 44 14 – Vendors . . . . . . . . . . . . . . . . 45 15 – Relacionamentos . . . . . . . . . . . . . . 46 16 – Dicas . . . . . . . . . . . . . . . . . 47 17 - Aplicativos de Exemplo 17.1 - Aplicativo Livros . . . . . . . . . . . . 48 17.2 - Aplicativo cake_olamundo . . . . . . . . . . 60 17.3 - Outros Exemplos . . . . . . . . . . . . 66 18 – Referências . . . . . . . . . . . . . . . 67 Ribamar FS – http://cursos.ribafs.org
  • 2. Curso de CakePHP Página 2 /69 1 - Cake - Introdução O que é CakePHP? CakePHP é um framework de desenvolvimento rápido para PHP que fornece uma arquitetura extensível para desenvolvimento, manutenção e implantação de aplicativos. Usando padrões de projeto conhecidos como MVC e ORM com o paradigma das convenções sobre configurações, CakePHP reduz os custos de desenvolvimento e ajuda os desenvolvedores a escrever menos código. Site oficial - http://cakephp.org Desde que Ruby on Rails se tornou um popular framework, equipes de desenvolvedores tem criado clones do framework Rails ou Rails em várias linguagens: TurboGears para Python; Zend, Symfony, e muitos outros para PHP; Catalyst para Perl; e assim por diante. Com tantas opções, por que escolher CakePHP para seu projeto web? Framework Um framework pode ser definido como a planta baixa de onde todos os sistemas serão construídos, ou como uma forma que bolos, que padroniza a forma e o volume de todos os bolos criados com ela. O framework enxerga cada tabela como uma classe, e cada registro da tabela como um objeto específico da classe Alguns softwares como os CMS são muito simples de instalar e usar, até mesmo sem nenhuma documentação, como é o caso dos CMS. Já os frameworks, a exemplo do CakePHP, requerem que tomemos conhecimento de pelo menos algumas convenções que ele traz. Caso não sigamos essas convenções ele não fará muito por nós. Sem contar que os frameworks são softwares de um tipo que exigem mais conhecimento que os CMS. Características do Cake Cake tem como objetivo simplificar o processo de desenvolvimento para a construção de aplicações web provendo um método geral para organizar o banco de dados e outros recursos que reduzem a codificação. Embora esta abordagem geral da programação web seja em si uma característica importante do Cake, o seu repositório de outros recursos poderosos como validação embutida, listas de controle de acesso (ACLs), sanitização de dados, segurança e componentes de manipulação de sessão e cache de View fazem o Cake vale a pena para qualquer desenvolvedor sério. Ribamar FS – http://cursos.ribafs.org
  • 3. Curso de CakePHP Página 3 /69 Características Principais - Sem Configuração (com convenções) – Configure o banco e deixe a mágica iniciar - Extremamente Simples – Apenas veja o nome...Ele chama-se Cake/Bolo - Ativa e Amigável Comunidade – Junte-se a nós no #cakephp (IRC). Adoraríamos ajudar você a começar - Licença Flexível – Distribuído sob a licença MIT - Clean IP – Toda linha de código foi escrita pela equipe de desenvolvimento do CakePHP - Melhores Práticas – cobrindo segurança, autenticação e manipulação de session, além de muitas outras características - OO – Caso seja um programador OO experiente ou novato se sentirá confortável - Compatível com as versões 4 e 5 do PHP - CRUD Integrado para interação com o banco de dados - Aplicação scaffolding - Geração de código - Arquitetura MVC - Requisição de dispatcher com URL limpa, personalizada e rotas/routes - Validação embutida - Rápidos e flexíveis templates (Sintaxe PHP, com helpers) - View Helpers para AJAX, JavaScript, Forms HTML e mais - Email, Cookie, Security, Session e Request Handling Components - Flexível ACL - Sanitização de Dados - Flexível Caching - Localização - Trabalha a partir de qualquer diretório do site, com pouca ou nenhuma configuração do Apache envolvidas Requisitos PHP 4.3.2 ou superior Servidor Web Apache com o mod_rewrite Tecnicamente um banco de dados não é obrigatório, mas nós imaginamos que a maioria das aplicações irão utilizar um. CakePHP suporta uma variedade de banco de dados: - MySQL (4 ou superior) - PostgreSQL - Firebird DB2 - Microsoft SQL Server - Oracle - SQLite - ODBC - ADOdb Como pode mudar de versão para versão (a atual é a 1.2.4.8284), confira no diretório: cake/libs/model/datasources/dbo: Ribamar FS – http://cursos.ribafs.org
  • 4. Curso de CakePHP Página 4 /69 dbo_db2.php, dbo_firebird.php, dbo_mssql.php, dbo_mysql.php, dbo_mysqli.php, dbo_odbc.php, dbo_oracle.php, dbo_postgres.php, dbo_sqlite.php, dbo_sybase.php. Estrutura original do diretório do cake: cake/app cake/cake cake/vendors cake/index.php cake/index_webroot.txt cake/README Estrutura original do diretório app: cake/app/config cake/app/controllers cake/app/locale cake/app/models cake/app/plugins cake/app/tests cake/app/tmp cake/app/vendors cake/app/views cake/app/webroot cake/app/index.php A pasta app do CakePHP é onde normalmente você colocará sua aplicação em desenvolvimento. Vamos dar uma olhada mais de perto dentro desta pasta. config Contém os arquivos de configuração. Detalhes das conexões ao banco de dados, bootstrapping, arquivos de configuração do núcleo e outros devem ser armazenados aqui. controllers Contém os controladores da sua aplicação e seus componentes. locale Guarda os arquivos com as strings para internacionalização. models Contém os modelos, behaviors e datasources da sua aplicação. plugins Contém os pacotes de plugins. tmp Aqui é onde o CakePHP armazena os arquivos temporários. Os dados atuais são armazenados onde Ribamar FS – http://cursos.ribafs.org
  • 5. Curso de CakePHP Página 5 /69 você tenha configurado o CakePHP, mas esta pasta normalmente é usada para guardar a descrição dos modelos, logs e outras informações, como as das sessões. vendors Qualquer classe ou biblioteca de terceiro deve ser armazenada aqui. Para fazer um acesso rápido e fácil, use a função vendors(). Você pode achar que esta pasta é redundante, já que existe uma pasta com mesmo nome no nível superior da estrutura. Nós vamos ver diferenças entre estas duas pastas quando discutirmos sobre manipulação de múltiplas aplicações e sistemas mais complexos. views Arquivos de apresentação devem vir aqui: elementos, páginas de erro, ajudantes, layouts e arquivos de visões. webroot No modo de produção, esta pasta deve servir como a pasta raiz da sua aplicação. Dentro desta pasta são guardados os arquivos públicos, como estilos CSS, imagens e arquivos de JavaScript. cake - bolo baker - padeiro Ribamar FS – http://cursos.ribafs.org
  • 6. Curso de CakePHP Página 6 /69 2 - Cake - Configurações Mesmo sendo focado em convenções ao invés de configurações, o Cake pode ter seu comportamento alterado através de alguns arquivos de configuração, que encontram-se na pasta config: database core router debug tradução testes etc. Vários Aplicativos num único Core Podemos configurar para que várias aplicações usem um único core do Cake. - Todos os aplicativos devem ficar assim: cake app1 app2 app3 ... E cada um deles deve ter seu arquivo webroot/index.php alterado na linha com CAKE_CORE_INCLUDE_PATH, mudando para: define('CAKE_CORE_INCLUDE_PATH', dirname(dirname(dirname(__FILE__)))); Debug O debug nas fases de desenvolvimento e de testes é muito importante, mas após a conclusão e entrega para o cliente devemos setar o debug para zero. O Debug pode ser alterado manualmente no script config/core.php, na linha: Configure::write('debug', 0); O default é 2. Zero é sem debug (sem exibir as mensagens de erro ou alerta). ou via código da nossa aplicação com: Configure::write('debug', '0'); Os possíveis são: 0 = Production mode. No output. debug 1 = Show errors and warnings. 2 = Show errors, warnings, and SQL. 3 = Show errors, warnings, SQL, and complete controller dump. Ribamar FS – http://cursos.ribafs.org
  • 7. Curso de CakePHP Página 7 /69 Tradução Também podemos traduzir algumas coisas do CakePHP, como as mensagens de erro Download: http://souagil.com.br/cake_i18n/pt_br.tar.gz Adicionar linha ao final de config/core.php: Configure::write('Config.language', 'pt-br'); Adicionar Testes com SimpleTest Download - http://www.simpletest.org/ Descompacte e copie a pasta simpletest para a subpasta vendor do seu aplicativo. Formatar Data e Hora Trocar: <?php echo $cliente['Cliente']['created'] ?> por: <?php echo $time->niceShort($cliente['Cliente']['created']) ?> Ribamar FS – http://cursos.ribafs.org
  • 8. Curso de CakePHP Página 8 /69 3 - Cake - Convenções O Cake previlegia convenções ao invés de configurações. O que significa que seguindo as convenções estabelecidas o cake fará muito por nós. Não somos obrigados a seguir as convenções, mas perderemos muito com isso, pois teremos que fazer muito. Apesar de tomar um pouco de tempo para aprender as convenções do CakePHP, você ganha tempo em um longo processo: seguindo as convenções, você ganha funcionalidades gratuitamente e livra- se de madrugadas de manutenção de arquivos de configuração. Convenções também fazem com que o sistema fique uniformemente desenvolvido, permitindo que outros desenvolvedores o ajudem mais facilmente, já que segue um padrão de trabalho. Convenções no CakePHP têm sido produzidas por anos de experiência em desenvolvimento web e boas práticas. Apesar de sugerirmos que você use essas convenções enquanto desenvolve em CakePHP, devemos mencionar que muitos desses princípios são facilmente sobrescritos - algo que especialmente acontece quando trabalha-se com sistemas legados. Convenções de arquivos e nome de classes Em geral, nome dos arquivos são sublinhados, enquanto nome de classes são CamelCased, ou seja, primeiras letras das palavras em maiúsculo. A classe KissesAndHugsController pode ser encontrada no arquivo kisses_and_hugs_controller.php, por exemplo. Porém, o nome da class e seu tipo não são necessariamente encontrados no nome do arquivo. A classe EmailComponent é encontrada no arquivo chamado email.php e a classe HtmlHelper é encontrada no arquivo html.php. Convenções de modelo Nome das classes de modelo devem ser no singular e CamelCased. Person, BigPerson e ReallyBigPerson são exemplos de nomes convencionados para modelos. Os nomes das tabelas correspondentes a modelos do CakePHP devem estar no plural e sublinhados. As tabelas para os modelos mencioados anteriormente devem ser people, big_people e really_big_people, respectivamente. Chaves estrangeiras em relacionamentos do tipo temMuitos (hasMany), pertenceA (belongsTo) ou temUm (hasOne) são reconhecidos por padrão como o nome (no singular) do modelo relacionado, seguido por _id. Assim, se um padeiro temMuitos bolos, a tabela bolos referenciará a um padeiro na tabela padeiros através da chave estrangeira padeiro_id. Tabelas associativas, usadas em relações temEPertenceAMuitos (hasAndBelongsToMany) entre modelos, devem ser nomeadas depois dos modelos das tabelas que a compõem, em ordem alfabética (apples_zebras em vez de zebras_apples). Todas as tabelas com as quais os modelos CakePHP interagem (exceto as tabelas associativas) Ribamar FS – http://cursos.ribafs.org
  • 9. Curso de CakePHP Página 9 /69 exigem uma única chave primária para identificar unicamente cada linha. Se você deseja modelar uma tabela que não tem uma chave primária de um único campo, como as linhas de nossa tabela associativa posts_tags, a convenção do CakePHP é de que uma chave primária de um único campo deve ser adicionada à tabela. CakePHP não suporta chaves primárias compostas. No caso de você querer manipular diretamente os dados das tabelas associativas, isso significa que você precisa usar chamadas a consultas diretas, ou adicionar um campo como chave primária para ser capaz de atuar nela como em um modelo normal. Por exemplo: 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)); Convenções de controlador O nome das classes de controladores são no plural, CamelCased e no final 'Controller'. PeopleController, BigPeopleController e ReallyBigPeopleController são todos os exemplos convencionais para nome de controladores. A primeira função que você deve escrever em um controlador deve ser o método index(). Quando alguém requisita um controlador sem ação, o behavior padrão é renderizar o método index() do controlador. Por exemplo, a requisição para http://www.exemplo.com.br/apples/ mapeia para a chamada da função index() do ApplesController, assim como http://www.exemplo.com.br/apples/view mapeia para a chamada da função view() no ApplesController. Você também pode alterar a visibilidade das funções do controlador em CakePHP colocando sublinhados na frente do nome das funções. Se a função do controlador estiver com sublinhado na frente, a função não será disponibilizada para acesso da web através do dispatcher, mas estará disponível para uso interno.Por exemplo: <?php class NewsController extends AppController { function latest() { $this->_findNewArticles(); } function _findNewArticles() { //Logic to find latest news articles } } ?> Apesar da página http://www.example.com/news/latest/ possa ser acessada pelo usuário normalmente, alguém que tente acessar a página Ribamar FS – http://cursos.ribafs.org
  • 10. Curso de CakePHP Página 10 /69 http://www.example.com/news/_findNewArticles/ receberá um erro porque a função é precedida de um sublinhado. Considerações sobre URLs para Nomes de Controladores Como você acabou de ver, controladores de uma única palavra são mapeados facilmente para uma URL simples em letras minúsculas. Por exemplo, ApplesController (que seria definida em um arquivo de nome 'apples_controller.php') é acessada a partir de http://example.com/apples. Controladores de múltiplas palavras mapeados para URLs em camelBacked mantendo a forma plural. Por exemplo, RedApplesController (red_apples_controller.php) seria mapeada para http://example.com/redApples e OperatingSystemsController (operating_systems_controller.php) seria mapeada para http://example.com/operatingSystems. Convenções de visão Os arquivos de template de visões são nomeados depois das funções de controladores que mostram esses arquivos de template, na forma com sublinhados. A função getReady() da classe PeopleController irá procurar pelo template da visão em /app/views/people/get_ready.ctp. O modelo básico é /app/views/controller/underscored_function_name.ctp. Nomeando os pedaços da aplicação usando as convenções do CakePHP, você ganha funcionalidades sem luta e sem amarras de configuração. Aqui o exemplo final que vincula as associações: Tabela no banco de dados: 'people' Classe do Modelo: 'Person', encontrada em /app/models/person.php Classe do Controlador: 'PeopleController', encontrado em /app/controllers/people_controller.php Template da Visão: encontrado em /app/views/people/index.ctp Usando estas convenções, CakePHP sabe que a requisição para http://www.exemplo.com.br/people/ mapeia para a chamada da função index() do PeopleController, onde o modelo Person é automaticamente disponibilizado (e automaticamente associado à tabela 'people' no banco de dados), e renderiza isso para o arquivo. Nenhuma destas relações foram configuradas por qualquer meio que não seja através da criação de classes e arquivos que você precise criar em algum lugar. Agora que você leu os fundamentos do CakePHP, você pode tentar seguir o tutorial de como fazer um Blog em CakePHP, para ver como as coisas são feitas juntas. Ribamar FS – http://cursos.ribafs.org
  • 11. Curso de CakePHP Página 11 /69 Resumo - bancos de dados – minúsculas e singular - tabelas – minúsculas e plural - chave primária de todas as tabelas deve ser chamada de id (opcionalmente) - chaves estrangeiras devem ser chamadas de tabelanome_id, exemplo blog_id (nome tabela no singular) - nomes de modelos CamelCase e arquivos em minúsculas e singular e sublinhado para separar palavras compostas: meu_post.php e MeuPost - controladores – arquivo: minúsculas e plural. Classe CamelCase com Controller anexado, como: PostsController. Nomes de arquivos com sublinhado em palavras compostas: posts_controller.php Associações entre Tabelas (relacionamentos) hasOne: possui um hasMany: possui muitos belongsTo: pertence a hasAndBelongsToMany: tem e pertence a muitos O Cake automaticamente adiciona o tempo para campos que são do timo datetime e são nomeados 'created' ou 'modified'. Ribamar FS – http://cursos.ribafs.org
  • 12. Curso de CakePHP Página 12 /69 4 - Criar Aplicativos em Cake com o Bake Operações de CRUD com o script bake. Após a utilização do bake temos um "esqueleto" de aplicação. Agora podemos customizar os códigos gerados para criarmos a aplicação final. - Copiar a pasta app Primeiro vamos copiar a pasta app para estoque - Criar o banco Depois vamos criar um banco chamado estoque (MySQL), no phpMydmin importe este script aqui. O banco coterá cinco tabelas: clientes, funcionarios, produtos, pedidos e pedido_itens - Relacionamentos A tabela pedidos está relacionada com clientes e fun cionarios, portanto tem dois campos: cliente_id e funcionario_id A tabela pedido_itens se relaciona com pedidos pelo campo pedido_id. - Criar aplicativo com Bake Vamos usar o bake para criar o aplicativo através da console. - Configurar para usar vários aplicativos com um único core Configurar estoque/webroot/index.php mudar a linha com define('CAKE_CORE_INCLUDE_PATH' para: define('CAKE_CORE_INCLUDE_PATH', dirname(dirname(dirname(__FILE__)))); - Acessar a pasta console cd /home/ribafs/public_html/cake/cake/console ou cd c:xampplitehtdocscakecakeconsole 1) Criar uma Configuração de banco ./cake bake -app estoque Receberá a tela: Welcome to CakePHP v1.2.4.8284 Console Ribamar FS – http://cursos.ribafs.org
  • 13. Curso de CakePHP Página 13 /69 --------------------------------------------------------------- App : estoque Path: /home/ribafs/backup/public_html/cake/estoque --------------------------------------------------------------- Your database configuration was not found. Take a moment to create one. --------------------------------------------------------------- Database Configuration: --------------------------------------------------------------- Name: [default] > Obs.: As opções entre colchetes como [default] acima são as opções sugeridas e default, basta teclar Enter se queremos aceitá-la. Tecle Enter para aceitar default como o nome da configuração do banco. 2) Selecionar o SGDB Driver: (db2/firebird/mssql/mysql/mysqli/odbc/oracle/postgres/sqlite/sybase) [mysql] > Apenas tecle Enter para aceitar o mysql 3) Tipo de conexão Persistent Connection? (y/n) [n] > Enter para aceitar não persistente 4) Host do Banco Database Host: [localhost] > Enter para aceitar localhost ou digite o nome do seu host 5) Porta Port? [n] > Enter para aceitar a porta default 6) Usuário User: [root] > Enter para aceitar 7) Senha Password: Ribamar FS – http://cursos.ribafs.org
  • 14. Curso de CakePHP Página 14 /69 > Enter para aceitar sem senha ou digite a senha 8) Nome do banco Database Name: [cake] > Digite estoque e tecle Enter 9) Prefixo das tabelas Table Prefix? [n] > Enter para aceitar sem prefixo ou digite o prefixo 10) Codificação das tabelas Table encoding? [n] > Enter para aceitar a default ou entre com a codificação (exemplo: utf8) Então aparece o relatório: --------------------------------------------------------------- The following database configuration will be created: --------------------------------------------------------------- Name: default Driver: mysql Persistent: false Host: localhost User: root Pass: ****** Database: estoque Encoding: utf8 --------------------------------------------------------------- Look okay? (y/n) [y] > Tecle enter para aceitar. 11) Outra configuração de banco? Do you wish to add another database configuration? [n] > Enter para encerrar. Então ele criará o arquivo: Creating file /home/ribafs/public_html/cake/estoque/config/database.php Ribamar FS – http://cursos.ribafs.org
  • 15. Curso de CakePHP Página 15 /69 Wrote /home/ribafs/public_html/cake/estoque/config/database.php Ao executar novamente o comando: ./cake bake -app estoque Aparecerá o menu: Welcome to CakePHP v1.2.4.8284 Console --------------------------------------------------------------- App : estoque Path: /home/ribafs/backup/public_html/cake/estoque --------------------------------------------------------------- Interactive Bake Shell --------------------------------------------------------------- [D]atabase Configuration [M]odel [V]iew [C]ontroller [P]roject [Q]uit What would you like to Bake? (D/M/V/C/P/Q) > Vamos criar na seguinte ordem para cada tabela: model, controller e view Criar o Model para a tabela Clientes 1) Tecle m e Enter (Model) Bake Model Path: /home/ribafs/backup/public_html/cake/estoque/models/ --------------------------------------------------------------- Possible Models based on your current database: 1. Cliente 2. Funcionario 3. PedidoIten 4. Pedido 5. Produto Enter a number from the list above, type in the name of another model, or 'q' to exit [q] > 2) Tecle 1 e Enter Would you like to supply validation criteria for the fields in your model? (y/n) [y] > 3) Validação Ribamar FS – http://cursos.ribafs.org
  • 16. Curso de CakePHP Página 16 /69 Tecle n e Enter (não vamos validar agora) 4) Nome do campo chave What is the primaryKey? [cliente] > No nosso caso está correto, apenas tecle Enter 5) Relacionamentos Would you like to define model associations (hasMany, hasOne, belongsTo, etc.)? (y/n) [y] > n e Enter 6) Correto? --------------------------------------------------------------- The following Model will be created: --------------------------------------------------------------- Name: Cliente Primary Key: cliente Associations: --------------------------------------------------------------- Look okay? (y/n) [y] > Enter 7) Baking model class for Cliente... Creating file /home/ribafs/backup/public_html/cake/estoque/models/cliente.php Wrote /home/ribafs/backup/public_html/cake/estoque/models/cliente.php Baking test fixture for Cliente... Creating file /home/ribafs/backup/public_html/cake/estoque/tests/fixtures/cliente_fixture.php Wrote /home/ribafs/backup/public_html/cake/estoque/tests/fixtures/cliente_fixture.php Baking unit test for Cliente... Creating file /home/ribafs/backup/public_html/cake/estoque/tests/cases/models/cliente.test.php Wrote /home/ribafs/backup/public_html/cake/estoque/tests/cases/models/cliente.test.php Criando o Model para Funcionarios Agora de forma mais resumida 1) m e Enter Ribamar FS – http://cursos.ribafs.org
  • 17. Curso de CakePHP Página 17 /69 2) 2 para funcionarios e Enter 3) n e Enter (sem validação) 4) Chave primária - Enter para funcionario 5) Relacionamentos - n e Enter 6) Tudo OK? - Enter Criar o Model para Produtos De forma semelhante crie o model para produtos. Criar o Model para Pedidos Esse é diferente, pois tem relacionamentos com cliente e funcionários 1) m e Enter 2) 4 e Enter para pedido 3) n e Enter para validação 4) pedido como chave 5) Relacionamento Would you like to define model associations (hasMany, hasOne, belongsTo, etc.)? (y/n) [y] > Enter para sim. One moment while the associations are detected. --------------------------------------------------------------- Please confirm the following associations: --------------------------------------------------------------- Pedido belongsTo Cliente? (y/n) [y] > Enter para aceitar a relação com Cliente Pedido belongsTo Funcionario? (y/n) [y] > Enter para aceitar a relação com funcionario. n para PedidoIten nas duas sugestões. Ribamar FS – http://cursos.ribafs.org
  • 18. Curso de CakePHP Página 18 /69 Enter para não adicionais relações. Relato: --------------------------------------------------------------- The following Model will be created: --------------------------------------------------------------- Name: Pedido Primary Key: pedido Associations: Pedido belongsTo Cliente Pedido belongsTo Funcionario --------------------------------------------------------------- Look okay? (y/n) [y] > Enter para aceitar. Criar o modelo da tabela pedido_itens Que se relaciona apenas com pedidos. Criar o Controller para Clientes 1) c e Enter 2) 1 e Enter Would you like to build your controller interactively? (y/n) [y] > n 3) n para controller interativo 4) Incluir métodos básicos Would you like to include some basic class methods (index(), add(), view(), edit())? (y/n) [y] > Enter para aceitar 5) Would you like to create the methods for admin routing? (y/n) [y] > n e Enter 6) Relato: --------------------------------------------------------------- The following controller will be created: --------------------------------------------------------------- Controller Name: Clientes Ribamar FS – http://cursos.ribafs.org
  • 19. Curso de CakePHP Página 19 /69 --------------------------------------------------------------- Look okay? (y/n) [y] > Enter para aceitar Criar os Controllers Funcionarios, PedidoItens, Pedidos e Produtos de forma semelhante Criar a view para a tabela Clientes 1) v e Enter 2) 1 e Enter 3) Criar scaffolds para a view: Would you like to create some scaffolded views (index, add, view, edit) for this controller? NOTE: Before doing so, you'll need to create your controller and model classes (including associated models). (y/n) [n] > y e Enter n para não criar admin De forma semenlhante criar as demais. Procurando ID e sobrescrevendo pelas respectivas chaves primárias nas views. Editar a views cake/estoque/views/clientes/index.ctp Procurar por id e sobrescrever com cliente. Assim com as demais views. Com isso temos um aplicativo com muitos bons recursos: CRUD, paginação, CSS, etc. Para criar um novo projeto com bake use: ./cake bake -p nomeprojeto Para ir direto para model, controller ou view: ./cake bake -app nomeapp model ./cake bake -app nomeapp controller ./cake bake -app nomeapp view Ribamar FS – http://cursos.ribafs.org
  • 20. Curso de CakePHP Página 20 /69 5 - Cake - Models Os models formam a camada da letra M do MVC, aquele que vai ao banco e conversa com os controllers atendendo as suas solicitações e devolvendo o resultado recebido do banco de dados. Modelo simples: cake/ola/models/cliente.php <?php class Cliente extends AppModel { var $name = 'Cliente'; } ?> Todos os models em Cake tem a função find() usada para buscar os registros da tabela do model. Passando parâmetros para essa função nós podemos controlar os registros a buscar. Um Model com validação dos campos (gerado pelo Bake): <?php class Produto extends AppModel { var $name = 'Produto'; var $primaryKey = 'produto'; var $validate = array( 'produto' => array('numeric'), 'descricao' => array('notempty'), 'unidade' => array('notempty'), 'data_cadastro' => array('date') ); } ?> Model com relacionamento com clientes e funcionarios: <?php class Pedido extends AppModel { var $name = 'Pedido'; var $primaryKey = 'pedido'; //The Associations below have been created with all possible keys, those that are not needed can be removed Ribamar FS – http://cursos.ribafs.org
  • 21. Curso de CakePHP Página 21 /69 var $belongsTo = array( 'Cliente' => array( 'className' => 'Cliente', 'foreignKey' => 'cliente_id', 'conditions' => '', 'fields' => '', 'order' => '' ), 'Funcionario' => array( 'className' => 'Funcionario', 'foreignKey' => 'funcionario_id', 'conditions' => '', 'fields' => '', 'order' => '' ) ); } ?> Uma boa pedida para aprender sobre os Models na prática é criar aplicativos com o Bake na linha de comando e depois analisar o código gerado. Ribamar FS – http://cursos.ribafs.org
  • 22. Curso de CakePHP Página 22 /69 6 - Cake - Controllers O controller representa a letra C do VMC e é a camada de processamento em PHP, onde existem os for, if, while, etc. Ele recebe as requisições de uma View e manda para o respectivo Model. Ao receber o resultado do Model ele devolve para a Views que pediu. Em um aplicativo de posts... Cada ação do controller deve pegar os posts no banco e retornar para a view. A view deve então exibir todos os posts como lista. Controllers simples: cake/ola/controllers/clientes_controller.php <?php class ClientesController extends AppController { var $name = 'Clientes'; } ?> Action Toda função pública dentro da classe controller é chamada de action. Esta action visualizará todos os clientes com a view index.ctp <?php class ClientesController extends AppController { var $name = 'Clientes'; function index() { $this->set('clientes', $this->Cliente->find('all')); } } ?> Controllers e Views Um controller pode ter muitos actions e cada action tem sua view. Portanto um controller pode ter muitas views. Cake guarda todas as views de um controller em um diretório separado (do mesmo nome do controller). Ribamar FS – http://cursos.ribafs.org
  • 23. Curso de CakePHP Página 23 /69 Agora um controller mais sofisticado: <?php class PedidosController extends AppController { var $name = 'Pedidos'; var $helpers = array('Html', 'Form'); function index() { $this->Pedido->recursive = 0; $this->set('pedidos', $this->paginate()); } function view($id = null) { if (!$id) { $this->Session->setFlash(__('Invalid Pedido.', true)); $this->redirect(array('action'=>'index')); } $this->set('pedido', $this->Pedido->read(null, $id)); } function add() { if (!empty($this->data)) { $this->Pedido->create(); if ($this->Pedido->save($this->data)) { $this->Session->setFlash(__('The Pedido has been saved', true)); $this->redirect(array('action'=>'index')); } else { $this->Session->setFlash(__('The Pedido could not be saved. Please, try again.', true)); } } $clientes = $this->Pedido->Cliente->find('list'); $funcionarios = $this->Pedido->Funcionario->find('list'); $this->set(compact('clientes', 'funcionarios')); } function edit($id = null) { if (!$id && empty($this->data)) { $this->Session->setFlash(__('Invalid Pedido', true)); $this->redirect(array('action'=>'index')); } if (!empty($this->data)) { if ($this->Pedido->save($this->data)) { $this->Session->setFlash(__('The Pedido has been saved', true)); $this->redirect(array('action'=>'index')); } else { $this->Session->setFlash(__('The Pedido could not be saved. Please, try again.', true)); } Ribamar FS – http://cursos.ribafs.org
  • 24. Curso de CakePHP Página 24 /69 } if (empty($this->data)) { $this->data = $this->Pedido->read(null, $id); } $clientes = $this->Pedido->Cliente->find('list'); $funcionarios = $this->Pedido->Funcionario->find('list'); $this->set(compact('clientes','funcionarios')); } function delete($id = null) { if (!$id) { $this->Session->setFlash(__('Invalid id for Pedido', true)); $this->redirect(array('action'=>'index')); } if ($this->Pedido->del($id)) { $this->Session->setFlash(__('Pedido deleted', true)); $this->redirect(array('action'=>'index')); } } } ?> Ribamar FS – http://cursos.ribafs.org
  • 25. Curso de CakePHP Página 25 /69 7 - Cake - Views View representa a letra V do MVC. As views são responsáveis por receber as requisições do cliente e mandar para o controller. O controller manda para o model que devolve ao controller. Então o controller devolve para a view, que renderiza o resultado para o cliente. Lembrando que a view não deve ter nenhum contato direto com o model mas sempre passar pelo controller. Convenção - Todo action dos controllers e sua correspondente view tem o mesmo nome. Quando o action finaliza a execução a view é renderizada. View simples: cake/ola/views/clientes/index.ctp <h2>Clientes</h2> <?php if(empty($clientes)): ?> Nenum cliente encontrado <?php else: ?> <table> <tr> <th>ID</th> <th>Nome</th> <th>Ações</th> </tr> <?php foreach ($clientes as $cliente): ?> <tr> <td> <?php echo $cliente['Cliente']['id'] ?> </td> <td> <?php echo $cliente['Cliente']['nome'] ?> </td> <td> <!-- actions on tasks will be added later --> </td> </tr> <?php endforeach; ?> </table> <?php endif; ?> Agora chamar no navegador assim: http://localhost/cake/ola/clientes Ribamar FS – http://cursos.ribafs.org
  • 26. Curso de CakePHP Página 26 /69 Adicionar Registro Adicionar view views/clientes/add.ctp correspondente ao action add: Adicionar a view: cake/ola/views/clientes/add.ctp <?php echo $form->create('Cliente');?> <fieldset> <legend>Adicionar novo Cliente</legend> <?php echo $form->input('ID'); echo $form->input('Nome'); ?> </fieldset> <?php echo $form->end('Adicionar');?> Agora chame com o navegador: http://localhost/cake/ola/clientes/add As views sempre tem a extensão ctp (Cake Template Pages). Link para Edição (adicionado logo após o comentário <!-- actions on tasks will be added later -->) <h2>Clientes</h2> <?php if(empty($clientes)): ?> Nenum cliente encontrado <?php else: ?> <table> <tr> <th>ID</th> <th>Nome</th> <th>Ações</th> </tr> <?php foreach ($clientes as $cliente): ?> <tr> <td> <?php echo $cliente['Cliente']['id'] ?> </td> <td> <?php echo $cliente['Cliente']['nome'] ?> </td> <td> <!-- actions on tasks will be added later --> <?php echo $html->link('Editar', array('action'=>'edit', $cliente['Cliente']['id'])); ?> </td> Ribamar FS – http://cursos.ribafs.org
  • 27. Curso de CakePHP Página 27 /69 </tr> <?php endforeach; ?> </table> <?php endif; ?> <?php echo $html->link('Adicionar Cliente', array('action'=>'add')); ?> Uma view mais sofisticada (gerada pelo Bake): <div class="clientes index"> <h2><?php __('Clientes');?></h2> <p> <?php echo $paginator->counter(array( 'format' => __('Page %page% of %pages%, showing %current% records out of %count% total, starting on record %start%, ending on %end%', true) )); ?></p> <table cellpadding="0" cellspacing="0"> <tr> <th><?php echo $paginator->sort('cliente');?></th> <th><?php echo $paginator->sort('cpf');?></th> <th><?php echo $paginator->sort('nome');?></th> <th><?php echo $paginator->sort('credito_liberado');?></th> <th><?php echo $paginator->sort('data_nasc');?></th> <th><?php echo $paginator->sort('email');?></th> <th class="actions"><?php __('Actions');?></th> </tr> <?php $i = 0; foreach ($clientes as $cliente): $class = null; if ($i++ % 2 == 0) { $class = ' class="altrow"'; } ?> <tr<?php echo $class;?>> <td> <?php echo $cliente['Cliente']['cliente']; ?> </td> <td> <?php echo $cliente['Cliente']['cpf']; ?> </td> <td> <?php echo $cliente['Cliente']['nome']; ?> </td> Ribamar FS – http://cursos.ribafs.org
  • 28. Curso de CakePHP Página 28 /69 <td> <?php echo $cliente['Cliente']['credito_liberado']; ?> </td> <td> <?php echo $cliente['Cliente']['data_nasc']; ?> </td> <td> <?php echo $cliente['Cliente']['email']; ?> </td> <td class="actions"> <?php echo $html->link(__('View', true), array('action' => 'view', $cliente['Cliente']['cliente'])); ?> <?php echo $html->link(__('Edit', true), array('action' => 'edit', $cliente['Cliente']['cliente'])); ?> <?php echo $html->link(__('Delete', true), array('action' => 'delete', $cliente['Cliente']['cliente']), null, sprintf(__('Are you sure you want to delete # %s?', true), $cliente['Cliente']['cliente'])); ?> </td> </tr> <?php endforeach; ?> </table> </div> <div class="paging"> <?php echo $paginator->prev('<< '.__('previous', true), array(), null, array('class'=>'disabled'));?> | <?php echo $paginator->numbers();?> <?php echo $paginator->next(__('next', true).' >>', array(), null, array('class' => 'disabled'));?> </div> <div class="actions"> <ul> <li><?php echo $html->link(__('New Cliente', true), array('action' => 'add')); ?></li> <li><?php echo $html->link(__('List Pedidos', true), array('controller' => 'pedidos', 'action' => 'index')); ?> </li> <li><?php echo $html->link(__('New Pedido', true), array('controller' => 'pedidos', 'action' => 'add')); ?> </li> </ul> </div> Ribamar FS – http://cursos.ribafs.org
  • 29. Curso de CakePHP Página 29 /69 8 - Cake - Actions Os Actions como o nome sugere, representam ações do usuário, que as emitem pelas views e são processadas nos controllers. Cada ação do usuário é representada por uma função no controller e esta função deve ter o mesmo nome da view. Exemplo: index.ctp é a view que é atendida pelo action index() no controller. Actions são funções públicas nas classes dos Controllers. Exemplo da action index() que corresponde à view de nome semelhante (index.ctp): <?php class ClientesController extends AppController { var $name = 'Clientes'; function index() { $this->set('clientes', $this->Cliente->find('all')); } } ?> Action para adicionar registros Para isso precisaremos adicionar uma variável (array $helpers) e uma função add() ao controller, como também adicionar uma view à pasta clientes, de nome add.ctp. var $helpers = array('Html', 'Form'); function add() { if (!empty($this->data)) { $this->Cliente->create(); if ($this->Cliente->save($this->data)) { $this->Session->setFlash('Cliente foi adicionado'); $this->redirect(array('action'=>'index'), null, true); } else { $this->Session->setFlash('Cliente não adicionado. Tente novamente.'); } } } Ribamar FS – http://cursos.ribafs.org
  • 30. Curso de CakePHP Página 30 /69 Adicionando Registros Para isso precisamos adicionar um action (edit) ao controller e uma view para este action (views/clientes/edit.ctp). function edit($id = null) { if (!$id) { $this->Session->setFlash('Cliente Inválido'); $this->redirect(array('action'=>'index'), null, true); } if (empty($this->data)) { $this->data = $this->Cliente->find(array('id' => $id)); } else { if ($this->Cliente->save($this->data)) { $this->Session->setFlash('O Cliente foi salvo!'); $this->redirect(array('action'=>'index'), null, true); } else { $this->Session->setFlash('O Cliente não pôde ser salvo. Favor tentar novamente.'); } } } Excluindo Registros Para isso devemos adicionar um action ao controle chamado delete() correspondente e uma linha na view index.ctp function delete($id = null) { if (!$id) { $this->Session->setFlash(__('Invalid id for Cliente', true)); $this->redirect(array('action'=>'index')); } if ($this->Cliente->del($id)) { $this->Session->setFlash(__('Cliente deleted', true)); $this->redirect(array('action'=>'index')); } } Editar a view index.ctp e adicionar a linha com o delete: <td class="actions"> <?php echo $html->link(__('View', true), array('action' => 'view', $cliente['Cliente']['cliente'])); ?> <?php echo $html->link(__('Edit', true), array('action' => 'edit', $cliente['Cliente']['cliente'])); ?> <?php echo $html->link(__('Delete', true), array('action' => 'delete', $cliente['Cliente']['cliente']), null, sprintf(__('Are you sure you want to delete # %s?', true), $cliente['Cliente']['cliente'])); ?> </td> Ribamar FS – http://cursos.ribafs.org
  • 31. Curso de CakePHP Página 31 /69 Ou seja, neste caso, não criamos mais uma views, mas apenas uma linha para o action delete(). Veja agora todos os actions comuns para a tabela clientes, no controller clientes.php e classe Clientes: <?php class ClientesController extends AppController { var $name = 'Clientes'; var $helpers = array('Html', 'Form'); function index() { $this->Cliente->recursive = 0; $this->set('clientes', $this->paginate()); } function view($id = null) { if (!$id) { $this->Session->setFlash(__('Invalid Cliente.', true)); $this->redirect(array('action'=>'index')); } $this->set('cliente', $this->Cliente->read(null, $id)); } function add() { if (!empty($this->data)) { $this->Cliente->create(); if ($this->Cliente->save($this->data)) { $this->Session->setFlash(__('The Cliente has been saved', true)); $this->redirect(array('action'=>'index')); } else { $this->Session->setFlash(__('The Cliente could not be saved. Please, try again.', true)); } } } function edit($id = null) { if (!$id && empty($this->data)) { $this->Session->setFlash(__('Invalid Cliente', true)); $this->redirect(array('action'=>'index')); } if (!empty($this->data)) { if ($this->Cliente->save($this->data)) { $this->Session->setFlash(__('The Cliente has been saved', true)); $this->redirect(array('action'=>'index')); } else { $this->Session->setFlash(__('The Cliente could not be saved. Please, try again.', true)); } Ribamar FS – http://cursos.ribafs.org
  • 32. Curso de CakePHP Página 32 /69 } if (empty($this->data)) { $this->data = $this->Cliente->read(null, $id); } } function delete($id = null) { if (!$id) { $this->Session->setFlash(__('Invalid id for Cliente', true)); $this->redirect(array('action'=>'index')); } if ($this->Cliente->del($id)) { $this->Session->setFlash(__('Cliente deleted', true)); $this->redirect(array('action'=>'index')); } } ?> Ribamar FS – http://cursos.ribafs.org
  • 33. Curso de CakePHP Página 33 /69 9 - Cake - Scaffold Usando Scaffold no CakePHP O scaffold no cake cria um CRUD rapidamente para manipulação de uma tabela. As ações do Scaffoldo são nomeadas como: index(), add(), edit(), view(), and delete(). Podemos deixar as ações de CRUD do scaffold quando não desejamos gerar código manualmente. Copiar a pasta app Vamos copiar a pasta app do cake para scaffold Configurar o banco de dados Configurar scaffold/config/database.php Configurar para vários aplicativos usarem o mesmo core do Cake Configurar scaffold/webroot/index.php na linha com define('CAKE_CORE_INCLUDE_PATH' para: define('CAKE_CORE_INCLUDE_PATH', dirname(dirname(dirname(__FILE__)))); Criar tabela create table clientes ( id int not null auto_increment primary key, nome char(45) not null ); INSERT INTO clientes (id, nome) VALUES (1,'Joao Pereira Brito'); INSERT INTO clientes (id, nome) VALUES (2,'Roberto Pereira Brito'); INSERT INTO clientes (id, nome) VALUES (3,'Antônio Pereira Brito'); INSERT INTO clientes (id, nome) VALUES (4,'Carlos Pereira Brito'); INSERT INTO clientes (id, nome) VALUES (5,'Otoniel Pereira Brito'); INSERT INTO clientes (id, nome) VALUES (6,'Helena Pereira Brito'); INSERT INTO clientes (id, nome) VALUES (7,'Flávio Pereira Brito'); INSERT INTO clientes (id, nome) VALUES (8,'Joana Pereira Brito'); INSERT INTO clientes (id, nome) VALUES (9,'Francisco Pereira Brito'); INSERT INTO clientes (id, nome) VALUES (10,'Jorge Pereira Brito'); INSERT INTO clientes (id, nome) VALUES (11,'Pedro Pereira Brito'); INSERT INTO clientes (id, nome) VALUES (12,'Ribamar Pereira Brito'); INSERT INTO clientes (id, nome) VALUES (13,'Tiago Pereira Brito'); INSERT INTO clientes (id, nome) VALUES (14,'Elias Pereira Brito'); INSERT INTO clientes (id, nome) VALUES (15,'Marcos Pereira Brito'); INSERT INTO clientes (id, nome) VALUES (16,'Ricardo Pereira Brito'); INSERT INTO clientes (id, nome) VALUES (17,'Rômulo Pereira Brito'); Ribamar FS – http://cursos.ribafs.org
  • 34. Curso de CakePHP Página 34 /69 INSERT INTO clientes (id, nome) VALUES (18,'Henrique Pereira Brito'); INSERT INTO clientes (id, nome) VALUES (19,'Francis Pereira Brito'); INSERT INTO clientes (id, nome) VALUES (20,'Otávio Pereira Brito'); INSERT INTO clientes (id, nome) VALUES (21,'Rogério Pereira Brito'); INSERT INTO clientes (id, nome) VALUES (22,'Jurandir Pereira Brito'); INSERT INTO clientes (id, nome) VALUES (23,'Raquél Pereira Brito'); Criar o model: cake/scaffold/models/cliente.php <?php class Cliente extends AppModel { var $name = 'Cliente'; } ?> Criar o controller: cake/scaffold/controllers/clientes_controller.php <?php class ClientesController extends AppController { var $scaffold; } ?> Apontar o Firefox para o controller: http://localhost/cake/scaffold/clientes Pronto, temos um CRUD, com estilo e paginação. Scaffold com tabelas relacionadas Tabelas jogadores e equipes create table equipes ( id int not null auto_increment primary key, nome char(45) not null ); create table jogadores ( id int not null auto_increment primary key, nome char(45) not null, Ribamar FS – http://cursos.ribafs.org
  • 35. Curso de CakePHP Página 35 /69 posicao char(25) not null, equipe_id int ); Detalhe: na tabela jogadores devemos ter um campo para relacionar com a equipes, no caso temos equipe_id. Este campo segue a convenção do Cake: nometabelasingular_id Criar os controllers cake/scaffold/controllers/jogadores_controller.php <?php class JogadoresController extends AppController { var $scaffold; } ?> cake/scaffold/controllers/equipes_controller.php <?php class EquipesController extends AppController { var $scaffold; } ?> Criando os Models cake/scaffold/models/jogador.php <?php class Jogador extends AppModel { var $name = 'Jogador'; var $belongTo = array('Equipe' => array('className' => 'Equipe', 'conditions' => '', 'order' => '', 'foreignKey' => 'equipe_id' ) ); } ?> cake/scaffold/models/equipe.php Ribamar FS – http://cursos.ribafs.org
  • 36. Curso de CakePHP Página 36 /69 <?php class Equipe extends AppModel { var $name = 'Equipe'; } ?> Abrir no navagador: http://localhost/cake/scaffold/equipes e http://localhost/cake/scaffold/jogadores Original de W.Jason Gilmore - http://www.wjgilmore.com Ribamar FS – http://cursos.ribafs.org
  • 37. Curso de CakePHP Página 37 /69 10 - Cake - Validações Validar como Não Vazio Vamos validar o campo nome para não aceitar vazio. Editar o model e adicionar: var $validate = array( 'nome' => array( 'rule' => VALID_NOT_EMPTY ) ); A validação é por campo. Uma boa idéia é gerar um aplicativo com o bake e ver como ele gera o código da validação no model. Agora uma validação que inclui relacionamento: <?php class Pedido extends AppModel { var $name = 'Pedido'; var $primaryKey = 'pedido'; //The Associations below have been created with all possible keys, those that are not needed can be removed var $belongsTo = array( 'Cliente' => array( 'className' => 'Cliente', 'foreignKey' => 'cliente_id', 'conditions' => '', 'fields' => '', 'order' => '' ), 'Funcionario' => array( 'className' => 'Funcionario', 'foreignKey' => 'funcionario_id', 'conditions' => '', 'fields' => '', 'order' => '' ) ); } ?> Ribamar FS – http://cursos.ribafs.org
  • 38. Curso de CakePHP Página 38 /69 Vejamos os vários tipos de validação embutida que o Cake oferece (via Bake): Você deseja fornecer critérios de validação para os campos de seu model? (y/n) [y] > Qual é a primaryKey? [cliente] > Field: cliente Type: integer --------------------------------------------------------------- Please select one of the following validation options: --------------------------------------------------------------- 1 - alphaNumeric 2 - between 3 - blank 4 - boolean 5 - cc 6 - comparison 7 - custom 8 - date 9 - decimal 10 - email 11 - equalTo 12 - extension 13 - file 14 - inList 15 - ip 16 - maxLength 17 - minLength 18 - money 19 - multiple 20 - notEmpty 21 - numeric 22 - phone 23 - postal 24 - range 25 - ssn 26 - time 27 - url 28 - userDefined 29 - Do not do any validation on this field. ... or enter in a valid regex validation string. [21] > Veja que quando concordamos que queremos validar ele mostra o primeiro campo e já nos sugere um tipo de validação. Ribamar FS – http://cursos.ribafs.org
  • 39. Curso de CakePHP Página 39 /69 No exemplo acima o campo cliente e integer e o Bake sugere validar como 21, que representa numeric. Claro que podemos mudar para outro da lista, mas isso já ajuda quando não sabemos o que fazer. Ribamar FS – http://cursos.ribafs.org
  • 40. Curso de CakePHP Página 40 /69 11 - Cake - Menu Após criar o código para cada tabela devemos adicionar um menu que integre todo o código. Uma forma simples e natural de fazer isso é adicionando o arquivo views/pages/home.ctp Criando a Home Page do Projeto: Criar appname/views/pages/home.ctp com o conteúdo: <h1>Bem vindo ao Bake</h1> <p>Aqui podmeos fazer:</p> <ul> <li><?php echo $html->link('Lista de todos os clientes', array('controller' => 'clientes', 'action'=>'index')); ?></li> <li><?php echo $html->link('Adicionar novo Cliente', array('controller' => 'clientes', 'action'=>'add')); ?></li> <li>Editar Clientes</li> <li>Excluir Clientes</li> </ul> Agora então podemos navegar no aplicativo como um todo assim: http://localhost/appname/ Caso exista outros itens os adicione ao arquivo home.ctp. Ribamar FS – http://cursos.ribafs.org
  • 41. Curso de CakePHP Página 41 /69 12 - Cake - CSS CakePHP e CSS Criando o CSS para o layout Para mudar o template default do Cake precisamos alterar o arquivo: cake/cake/libs/view/layouts/default.ctp Template padrão do Cake Veja seu conteúdo, inclusive nele é onde se encontra aquela frase "CakePHP: the rapid development php framework:" caso queiramos remover, assim como a pequena imgem do rodapé. Observe que a frase está no title e no body. <?php ?> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <?php echo $html->charset(); ?> <title> <?php __('CakePHP: the rapid development php framework:'); ?> <?php echo $title_for_layout; ?> </title> <?php echo $html->meta('icon'); echo $html->css('cake.generic'); echo $scripts_for_layout; ?> </head> <body> <div id="container"> <div id="header"> <h1><?php echo $html->link(__('CakePHP: the rapid development php framework', true), 'http://cakephp.org'); ?></h1> </div> <div id="content"> <?php $session->flash(); ?> <?php echo $content_for_layout; ?> Ribamar FS – http://cursos.ribafs.org
  • 42. Curso de CakePHP Página 42 /69 </div> <div id="footer"> <?php echo $html->link( $html->image('cake.power.gif', array('alt'=> __("CakePHP: the rapid development php framework", true), 'border'=>"0")), 'http://www.cakephp.org/', array('target'=>'_blank'), null, false ); ?> </div> </div> <?php echo $cakeDebug; ?> </body> </html> Mudando este arquivo podemos transformar automaticamente todas as aplicações geradas. Personalizando o Template Caso criemos um arquivo chamado: cake/app/views/layouts/default.ctp O Cake o usará e ignorará o anterior. O arquivo CSS default usado no aplicativo é este: /app/webroot/css/cake.generic.css E é chamado nas views assim: <link rel="stylesheet" type="text/css" href="/ProjectPath/css/cake.generic.css" /> Personalizando o CSS existente, entrando com um novo script CSS: Editar o script app/webroot/css/cake.generic.css e cole o código abaixo ao final: * { font-family: "Lucida Grande",Lucida,sans-serif; } th { font-size: 14px; font-weight: bold; background-color: #e1e1e1; border-bottom: 1px solid #ccc; padding: 10px; } div.actions ul { list-style-type: none; } Observe que adicionando nosso próprio estilo podemos controlar a aparência do site. Ribamar FS – http://cursos.ribafs.org
  • 43. Curso de CakePHP Página 43 /69 Editar então o script app/views/layouts/default.ctp e alterar a linha 4 para: <?php print $html->css('cake.generic');?> Para que o CSS do Cake volte, mas agora um pouco personalizado por nós. Observe que o layout não é o padrão do Cake, pois tem algumas diferenças. Referência: http://letthemcodecake.com/learning-cakephp/4/ Ribamar FS – http://cursos.ribafs.org
  • 44. Curso de CakePHP Página 44 /69 13 - Cake - JavaScript Os arquivos .js (Javascript) caso existam devem ser salvos no diretório webroot/js/ Referências: http://bakery.cakephp.org/articles/view/toggling-items-with-javascript http://debuggable.com/posts/passing-controller-variables-to-your-javascript:48b4f0c6-c718-47b2- bca1-05794834cda3 http://netunno.com/2009/08/incluir-arquivos-javascript-e-css-pela-view-de-um-conteudo-no- cakephp/ http://ryan.ifupdown.com/2009/08/22/how-to-use-javascript-codeblock-in-cakephp/ Ribamar FS – http://cursos.ribafs.org
  • 45. Curso de CakePHP Página 45 /69 14 - Cake - Verdors São os scripts de terceiros, que não fazem parte do core do Cake, que ficam no diretório verdors. Carregando arquivos de terceiros (vendors): A tradicional forma é carregando arquivos da pasta "verdors" usando a função vendor() que está caindo em desuso. Recebemos um warning se a usarmos. A nova maneira de usar é com App:import(). Para carregar um arquivo de nome exemplo.php use o seguinte: App::import('Vendor', 'exemplo'); Tem um pequeno problema aqui: só funciona se o nome do arquivo tiver todas as letras em minúsculas. Caso o arquivo tenha a inicial maiúsculas ao invés use: App::import('Vendor', 'exemplo', array('file' => 'Exemplo.php')); O segundo parâmetro pode ser qualquer string, exceto varia ou null. O mesmo se aplica para: App::import('Vendor', 'example'.DS.'example'); // loads example/example.php App::import('Vendor', 'example', array('file' => 'Example'.DS.'example.php')); // loads Example/example.php Refeência - http://cakebaker.42dh.com/2008/03/26/loading-vendor-files/ Referências: http://lemoncake.wordpress.com/2007/08/08/vendors-in-cakephp/ Ribamar FS – http://cursos.ribafs.org
  • 46. Curso de CakePHP Página 46 /69 15 - Cake - Relacionamentos O cake detecta relacionamentos entre as tabelas, mas para isso precisamos atender a algumas das suas convenções. Para isso a chave primária deve ser id ou criar com o Bake e indicar a chave primária. O campo foreign key da tabela relacionada deve chamar-se obrigatoriamente nometabelasingular_id Exemplo: cliente_id Agora o Cake irá detectar os relacionamentos e adicionar uma combo nos campos foreign key das tabelas relacionadas que será preenchida com dados da outra tabela. Ribamar FS – http://cursos.ribafs.org
  • 47. Curso de CakePHP Página 47 /69 16 - Cake - Dicas 1) Padronização do aplicativo default Como cada vez que vou criar um novo aplicativo no cake: - Copio a pasta app com o nome do novo aplicativo (Exemplo: cad_livros) - Depois então vou realizar as personalizações necessárias para começar: - locales/pt-BR - views/layout/default.ctp (faço uma cópia de cake/cake/libs/view/layouts/default.ctp para a pasta views/layout e personalizo) - webroot/index.php (adapto para permitir que vários aplicativos usem o mesmo core) - entre outros. Como eu estou sempre fazendo isso, fica mais prático já efetuar todas essas alterações na pasta "app" do cake para que quando eu a copie já leve todas as minhas alterações. Ribamar FS – http://cursos.ribafs.org
  • 48. Curso de CakePHP Página 48 /69 17 - Cake – Aplicativos de Exemplo 17.1 - Aplicativo Livros Aplicativo gerado pelo Bake com a finalidade de mostrar um relacionamento entre as tabelas autores e livros e também mostrar o comportamento das validações. Criar um aplicativo para apenas duas tabelas relacionadas usando o Bake Banco - livro tabelas create table autores ( autor int auto_increment primary key, nome char(45) not null, email char(50) ); create table livros ( isbn char(17) primary key, titulo char(45) not null, editora char(50) not null, autore_id int not null, FOREIGN KEY (autore_id) REFERENCES autores(autor) ON DELETE RESTRICT ); insert into autores values (1, 'Alexandre Dumas Pai', 'alex@alex.com'); insert into autores values (2, 'Camões', 'camoes@camoes.com'); insert into autores values (3, 'Dante Alighieri', 'dante@dante.com'); insert into autores values (4, 'Albert Camus', 'albert@albert.com'); insert into autores values (5, 'Jean Paul Sartre', 'sartre@sartre.org'); insert into autores values (6, 'Augusto Cury', 'cury@cury.org'); insert into livros values ('978-0-470-03899-4', 'O Conde de Monte Cristo', 'Nova Data', 1); insert into livros values ('978-0-470-03899-5', 'Os Três Mosqueteiros', 'Nova Data', 1); insert into livros values ('978-0-470-03899-6', 'Os Lusíadas', 'Saraiva', 2); insert into livros values ('978-0-470-03899-7', 'A Divina Comédia', 'Moderna', 3); insert into livros values ('978-0-470-03899-8', 'O Estrangeiro', 'Moderna', 4); insert into livros values ('979-0-470-03899-4', 'A Idade da Razão', 'Novatec', 5); insert into livros values ('976-0-470-03899-4', 'Pais Brilhantes, Professores Fascinantes', 'Eldorado', 6); Copiar a pasta app para livro. Configurar a webroot/index.php para que vários app usem o mesmo core. Ribamar FS – http://cursos.ribafs.org
  • 49. Curso de CakePHP Página 49 /69 Agora usemos o bake para criar o aplicativo, com validação dos campos e relacionamento. cd /var/www/cake/cake/console ./cake bake -app livro 1) Crie a configuração com o banco de dados livro. ./cake bake -app livro 2) Criar o model, o controller e a view para autores. 3) Depois criar o model, o controller e a view para livros (sempre nesta ordem). Use diretamente ./cake bake -app livro model ./cake bake -app livro controller ./cake bake -app livro view Au final vamos criar um simples menu para o Aplicativo: Adicionar o arquivo views/pages/home.ctp <h1>Aplicativo Livros</h1> <p>Tarefas</p> <ul> <li><?php echo $html->link('Lista de todos os Autores', array('controller' => 'autores', 'action'=>'index')); ?></li> <li><?php echo $html->link('Adicionar novo Autor', array('controller' => 'autores', 'action'=>'add')); ?></li> <li><?php echo $html->link('Lista de todos os Livros', array('controller' => 'livros', 'action'=>'index')); ?></li> <li><?php echo $html->link('Adicionar novo Livro', array('controller' => 'livros', 'action'=>'add')); ? ></li> <li>Editar e Excluir Autores</li> <li>Editar e Excluir Livros</li> </ul> Aí poderiamos adicionar editar, visualizar, excluir para ambos. Chamar no navegador com: http://localhost/cake/livro/ Dar suporte a pt-BR Após implementar o suporte a pt-BR as mensagens de erro serão traduzidas, os nomes das ações dentre outros. Ribamar FS – http://cursos.ribafs.org
  • 50. Curso de CakePHP Página 50 /69 Código do Aplicativo Livro criado com o Cake Bake models/autore.php <?php class Autore extends AppModel { var $name = 'Autore'; var $primaryKey = 'autor'; var $validate = array( 'autor' => array('numeric'), 'nome' => array('notempty'), 'email' => array('email') ); } ?> models/livro.php <?php class Livro extends AppModel { var $name = 'Livro'; var $primaryKey = 'isbn'; var $validate = array( 'isbn' => array('notempty'), 'titulo' => array('notempty'), 'editora' => array('notempty'), 'autore_id' => array('numeric') ); //The Associations below have been created with all possible keys, those that are not needed can be removed var $belongsTo = array( 'Autore' => array( 'className' => 'Autore', 'foreignKey' => 'autore_id', 'conditions' => '', 'fields' => '', 'order' => '' ) ); } ?> controllers/autores_controller.php <?php class AutoresController extends AppController { Ribamar FS – http://cursos.ribafs.org
  • 51. Curso de CakePHP Página 51 /69 var $name = 'Autores'; var $helpers = array('Html', 'Form'); function index() { $this->Autore->recursive = 0; $this->set('autores', $this->paginate()); } function view($id = null) { if (!$id) { $this->Session->setFlash(__('Invalid Autore.', true)); $this->redirect(array('action'=>'index')); } $this->set('autore', $this->Autore->read(null, $id)); } function add() { if (!empty($this->data)) { $this->Autore->create(); if ($this->Autore->save($this->data)) { $this->Session->setFlash(__('The Autore has been saved', true)); $this->redirect(array('action'=>'index')); } else { $this->Session->setFlash(__('The Autore could not be saved. Please, try again.', true)); } } } function edit($id = null) { if (!$id && empty($this->data)) { $this->Session->setFlash(__('Invalid Autore', true)); $this->redirect(array('action'=>'index')); } if (!empty($this->data)) { if ($this->Autore->save($this->data)) { $this->Session->setFlash(__('The Autore has been saved', true)); $this->redirect(array('action'=>'index')); } else { $this->Session->setFlash(__('The Autore could not be saved. Please, try again.', true)); } } if (empty($this->data)) { $this->data = $this->Autore->read(null, $id); } } Ribamar FS – http://cursos.ribafs.org
  • 52. Curso de CakePHP Página 52 /69 function delete($id = null) { if (!$id) { $this->Session->setFlash(__('Invalid id for Autore', true)); $this->redirect(array('action'=>'index')); } if ($this->Autore->del($id)) { $this->Session->setFlash(__('Autore deleted', true)); $this->redirect(array('action'=>'index')); } } } ?> controllers/livros_controller.php <?php class LivrosController extends AppController { var $name = 'Livros'; var $helpers = array('Html', 'Form'); function index() { $this->Livro->recursive = 0; $this->set('livros', $this->paginate()); } function view($id = null) { if (!$id) { $this->Session->setFlash(__('Invalid Livro.', true)); $this->redirect(array('action'=>'index')); } $this->set('livro', $this->Livro->read(null, $id)); } function add() { if (!empty($this->data)) { $this->Livro->create(); if ($this->Livro->save($this->data)) { $this->Session->setFlash(__('The Livro has been saved', true)); $this->redirect(array('action'=>'index')); } else { $this->Session->setFlash(__('The Livro could not be saved. Please, try again.', true)); } } $autores = $this->Livro->Autore->find('list'); $this->set(compact('autores')); Ribamar FS – http://cursos.ribafs.org
  • 53. Curso de CakePHP Página 53 /69 } function edit($id = null) { if (!$id && empty($this->data)) { $this->Session->setFlash(__('Invalid Livro', true)); $this->redirect(array('action'=>'index')); } if (!empty($this->data)) { if ($this->Livro->save($this->data)) { $this->Session->setFlash(__('The Livro has been saved', true)); $this->redirect(array('action'=>'index')); } else { $this->Session->setFlash(__('The Livro could not be saved. Please, try again.', true)); } } if (empty($this->data)) { $this->data = $this->Livro->read(null, $id); } $autores = $this->Livro->Autore->find('list'); $this->set(compact('autores')); } function delete($id = null) { if (!$id) { $this->Session->setFlash(__('Invalid id for Livro', true)); $this->redirect(array('action'=>'index')); } if ($this->Livro->del($id)) { $this->Session->setFlash(__('Livro deleted', true)); $this->redirect(array('action'=>'index')); } } } ?> views/autores/autores/add.ctp <div class="autores form"> <?php echo $form->create('Autore');?> <fieldset> <legend><?php __('Add Autore');?></legend> <?php echo $form->input('nome'); echo $form->input('email'); ?> </fieldset> <?php echo $form->end('Submit');?> Ribamar FS – http://cursos.ribafs.org
  • 54. Curso de CakePHP Página 54 /69 </div> <div class="actions"> <ul> <li><?php echo $html->link(__('List Autores', true), array('action' => 'index'));?></li> </ul> </div> views/autores/autores/edit.ctp <div class="autores form"> <?php echo $form->create('Autore');?> <fieldset> <legend><?php __('Edit Autore');?></legend> <?php echo $form->input('autor'); echo $form->input('nome'); echo $form->input('email'); ?> </fieldset> <?php echo $form->end('Submit');?> </div> <div class="actions"> <ul> <li><?php echo $html->link(__('Delete', true), array('action' => 'delete', $form- >value('Autore.autor')), null, sprintf(__('Are you sure you want to delete # %s?', true), $form- >value('Autore.autor'))); ?></li> <li><?php echo $html->link(__('List Autores', true), array('action' => 'index'));?></li> </ul> </div> views/autores/autores/index.ctp <div class="autores index"> <h2><?php __('Autores');?></h2> <p> <?php echo $paginator->counter(array( 'format' => __('Page %page% of %pages%, showing %current% records out of %count% total, starting on record %start%, ending on %end%', true) )); ?></p> <table cellpadding="0" cellspacing="0"> <tr> <th><?php echo $paginator->sort('autor');?></th> <th><?php echo $paginator->sort('nome');?></th> <th><?php echo $paginator->sort('email');?></th> <th class="actions"><?php __('Actions');?></th> </tr> <?php $i = 0; Ribamar FS – http://cursos.ribafs.org
  • 55. Curso de CakePHP Página 55 /69 foreach ($autores as $autore): $class = null; if ($i++ % 2 == 0) { $class = ' class="altrow"'; } ?> <tr<?php echo $class;?>> <td> <?php echo $autore['Autore']['autor']; ?> </td> <td> <?php echo $autore['Autore']['nome']; ?> </td> <td> <?php echo $autore['Autore']['email']; ?> </td> <td class="actions"> <?php echo $html->link(__('View', true), array('action' => 'view', $autore['Autore'] ['autor'])); ?> <?php echo $html->link(__('Edit', true), array('action' => 'edit', $autore['Autore'] ['autor'])); ?> <?php echo $html->link(__('Delete', true), array('action' => 'delete', $autore['Autore'] ['autor']), null, sprintf(__('Tem certeza de que deseja excluir o autor # %s?', true), $autore['Autore'] ['autor'])); ?> </td> </tr> <?php endforeach; ?> </table> </div> <div class="paging"> <?php echo $paginator->prev('<< '.__('previous', true), array(), null, array('class'=>'disabled'));? > | <?php echo $paginator->numbers();?> <?php echo $paginator->next(__('next', true).' >>', array(), null, array('class' => 'disabled'));?> </div> <div class="actions"> <ul> <li><?php echo $html->link(__('New Autore', true), array('action' => 'add')); ?></li> </ul> </div> views/autores/autores/view.ctp <div class="autores view"> <h2><?php __('Autore');?></h2> <dl><?php $i = 0; $class = ' class="altrow"';?> <dt<?php if ($i % 2 == 0) echo $class;?>><?php __('Autor'); ?></dt> <dd<?php if ($i++ % 2 == 0) echo $class;?>> <?php echo $autore['Autore']['autor']; ?> Ribamar FS – http://cursos.ribafs.org
  • 56. Curso de CakePHP Página 56 /69 &nbsp; </dd> <dt<?php if ($i % 2 == 0) echo $class;?>><?php __('Nome'); ?></dt> <dd<?php if ($i++ % 2 == 0) echo $class;?>> <?php echo $autore['Autore']['nome']; ?> &nbsp; </dd> <dt<?php if ($i % 2 == 0) echo $class;?>><?php __('Email'); ?></dt> <dd<?php if ($i++ % 2 == 0) echo $class;?>> <?php echo $autore['Autore']['email']; ?> &nbsp; </dd> </dl> </div> <div class="actions"> <ul> <li><?php echo $html->link(__('Edit Autore', true), array('action' => 'edit', $autore['Autore'] ['autor'])); ?> </li> <li><?php echo $html->link(__('Delete Autore', true), array('action' => 'delete', $autore['Autore']['autor']), null, sprintf(__('Are you sure you want to delete # %s?', true), $autore['Autore']['autor'])); ?> </li> <li><?php echo $html->link(__('List Autores', true), array('action' => 'index')); ?> </li> <li><?php echo $html->link(__('New Autore', true), array('action' => 'add')); ?> </li> </ul> </div> livro/views/livros/add.ctp <div class="livros form"> <?php echo $form->create('Livro');?> <fieldset> <legend><?php __('Add Livro');?></legend> <?php echo $form->input('titulo'); echo $form->input('editora'); echo $form->input('autore_id'); ?> </fieldset> <?php echo $form->end('Submit');?> </div> <div class="actions"> <ul> <li><?php echo $html->link(__('List Livros', true), array('action' => 'index'));?></li> <li><?php echo $html->link(__('List Autores', true), array('controller' => 'autores', 'action' => 'index')); ?> </li> <li><?php echo $html->link(__('New Autore', true), array('controller' => 'autores', 'action' => 'add')); ?> </li> </ul> </div> Ribamar FS – http://cursos.ribafs.org
  • 57. Curso de CakePHP Página 57 /69 livro/views/livros/edit.ctp <div class="livros form"> <?php echo $form->create('Livro');?> <fieldset> <legend><?php __('Edit Livro');?></legend> <?php echo $form->input('isbn'); echo $form->input('titulo'); echo $form->input('editora'); echo $form->input('autore_id'); ?> </fieldset> <?php echo $form->end('Submit');?> </div> <div class="actions"> <ul> <li><?php echo $html->link(__('Delete', true), array('action' => 'delete', $form- >value('Livro.isbn')), null, sprintf(__('Are you sure you want to delete # %s?', true), $form- >value('Livro.isbn'))); ?></li> <li><?php echo $html->link(__('List Livros', true), array('action' => 'index'));?></li> <li><?php echo $html->link(__('List Autores', true), array('controller' => 'autores', 'action' => 'index')); ?> </li> <li><?php echo $html->link(__('New Autore', true), array('controller' => 'autores', 'action' => 'add')); ?> </li> </ul> </div> livro/views/livros/index.ctp <div class="livros index"> <h2><?php __('Livros');?></h2> <p> <?php echo $paginator->counter(array( 'format' => __('Page %page% of %pages%, showing %current% records out of %count% total, starting on record %start%, ending on %end%', true) )); ?></p> <table cellpadding="0" cellspacing="0"> <tr> <th><?php echo $paginator->sort('isbn');?></th> <th><?php echo $paginator->sort('titulo');?></th> <th><?php echo $paginator->sort('editora');?></th> <th><?php echo $paginator->sort('autore_id');?></th> <th class="actions"><?php __('Actions');?></th> </tr> <?php $i = 0; Ribamar FS – http://cursos.ribafs.org
  • 58. Curso de CakePHP Página 58 /69 foreach ($livros as $livro): $class = null; if ($i++ % 2 == 0) { $class = ' class="altrow"'; } ?> <tr<?php echo $class;?>> <td> <?php echo $livro['Livro']['isbn']; ?> </td> <td> <?php echo $livro['Livro']['titulo']; ?> </td> <td> <?php echo $livro['Livro']['editora']; ?> </td> <td> <?php echo $html->link($livro['Autore']['autor'], array('controller' => 'autores', 'action' => 'view', $livro['Autore']['autor'])); ?> </td> <td class="actions"> <?php echo $html->link(__('View', true), array('action' => 'view', $livro['Livro'] ['isbn'])); ?> <?php echo $html->link(__('Edit', true), array('action' => 'edit', $livro['Livro']['isbn'])); ? > <?php echo $html->link(__('Delete', true), array('action' => 'delete', $livro['Livro'] ['isbn']), null, sprintf(__('Are you sure you want to delete # %s?', true), $livro['Livro']['isbn'])); ?> </td> </tr> <?php endforeach; ?> </table> </div> <div class="paging"> <?php echo $paginator->prev('<< '.__('previous', true), array(), null, array('class'=>'disabled'));? > | <?php echo $paginator->numbers();?> <?php echo $paginator->next(__('next', true).' >>', array(), null, array('class' => 'disabled'));?> </div> <div class="actions"> <ul> <li><?php echo $html->link(__('New Livro', true), array('action' => 'add')); ?></li> <li><?php echo $html->link(__('List Autores', true), array('controller' => 'autores', 'action' => 'index')); ?> </li> <li><?php echo $html->link(__('New Autore', true), array('controller' => 'autores', 'action' => 'add')); ?> </li> </ul> </div> Ribamar FS – http://cursos.ribafs.org
  • 59. Curso de CakePHP Página 59 /69 livro/views/livros/view.ctp <div class="livros view"> <h2><?php __('Livro');?></h2> <dl><?php $i = 0; $class = ' class="altrow"';?> <dt<?php if ($i % 2 == 0) echo $class;?>><?php __('Isbn'); ?></dt> <dd<?php if ($i++ % 2 == 0) echo $class;?>> <?php echo $livro['Livro']['isbn']; ?> &nbsp; </dd> <dt<?php if ($i % 2 == 0) echo $class;?>><?php __('Titulo'); ?></dt> <dd<?php if ($i++ % 2 == 0) echo $class;?>> <?php echo $livro['Livro']['titulo']; ?> &nbsp; </dd> <dt<?php if ($i % 2 == 0) echo $class;?>><?php __('Editora'); ?></dt> <dd<?php if ($i++ % 2 == 0) echo $class;?>> <?php echo $livro['Livro']['editora']; ?> &nbsp; </dd> <dt<?php if ($i % 2 == 0) echo $class;?>><?php __('Autore'); ?></dt> <dd<?php if ($i++ % 2 == 0) echo $class;?>> <?php echo $html->link($livro['Autore']['autor'], array('controller' => 'autores', 'action' => 'view', $livro['Autore']['autor'])); ?> &nbsp; </dd> </dl> </div> <div class="actions"> <ul> <li><?php echo $html->link(__('Edit Livro', true), array('action' => 'edit', $livro['Livro'] ['isbn'])); ?> </li> <li><?php echo $html->link(__('Delete Livro', true), array('action' => 'delete', $livro['Livro'] ['isbn']), null, sprintf(__('Are you sure you want to delete # %s?', true), $livro['Livro']['isbn'])); ?> </li> <li><?php echo $html->link(__('List Livros', true), array('action' => 'index')); ?> </li> <li><?php echo $html->link(__('New Livro', true), array('action' => 'add')); ?> </li> <li><?php echo $html->link(__('List Autores', true), array('controller' => 'autores', 'action' => 'index')); ?> </li> <li><?php echo $html->link(__('New Autore', true), array('controller' => 'autores', 'action' => 'add')); ?> </li> </ul> </div> Ribamar FS – http://cursos.ribafs.org
  • 60. Curso de CakePHP Página 60 /69 17.2 - Aplicativo de Exemplo – cake_olamundo Criando Aplicativo no CakePHP de forma Simples e Rápida Vamos copiar a pasta app do cake para ola_cake Criar o banco cad_cliente Configurar ola_cake/config/database.php Configurar ola_cake/webroot/index.php na linha com define('CAKE_CORE_INCLUDE_PATH' para: define('CAKE_CORE_INCLUDE_PATH', dirname(dirname(dirname(__FILE__)))); Criar tabela create table clientes ( id int not null auto_increment primary key, nome char(45) not null ); INSERT INTO clientes (id, nome) VALUES (1,'Joao Pereira Brito'); INSERT INTO clientes (id, nome) VALUES (2,'Roberto Pereira Brito'); INSERT INTO clientes (id, nome) VALUES (3,'Antônio Pereira Brito'); INSERT INTO clientes (id, nome) VALUES (4,'Carlos Pereira Brito'); INSERT INTO clientes (id, nome) VALUES (5,'Otoniel Pereira Brito'); INSERT INTO clientes (id, nome) VALUES (6,'Helena Pereira Brito'); INSERT INTO clientes (id, nome) VALUES (7,'Flávio Pereira Brito'); INSERT INTO clientes (id, nome) VALUES (8,'Joana Pereira Brito'); INSERT INTO clientes (id, nome) VALUES (9,'Francisco Pereira Brito'); INSERT INTO clientes (id, nome) VALUES (10,'Jorge Pereira Brito'); INSERT INTO clientes (id, nome) VALUES (11,'Pedro Pereira Brito'); INSERT INTO clientes (id, nome) VALUES (12,'Ribamar Pereira Brito'); INSERT INTO clientes (id, nome) VALUES (13,'Tiago Pereira Brito'); INSERT INTO clientes (id, nome) VALUES (14,'Elias Pereira Brito'); INSERT INTO clientes (id, nome) VALUES (15,'Marcos Pereira Brito'); INSERT INTO clientes (id, nome) VALUES (16,'Ricardo Pereira Brito'); INSERT INTO clientes (id, nome) VALUES (17,'Rômulo Pereira Brito'); INSERT INTO clientes (id, nome) VALUES (18,'Henrique Pereira Brito'); INSERT INTO clientes (id, nome) VALUES (19,'Francis Pereira Brito'); INSERT INTO clientes (id, nome) VALUES (20,'Otávio Pereira Brito'); INSERT INTO clientes (id, nome) VALUES (21,'Rogério Pereira Brito'); INSERT INTO clientes (id, nome) VALUES (22,'Jurandir Pereira Brito'); INSERT INTO clientes (id, nome) VALUES (23,'Raquél Pereira Brito'); Passos para a criação de um aplicativo básico após as configurações: - Criar o model Ribamar FS – http://cursos.ribafs.org
  • 61. Curso de CakePHP Página 61 /69 - Criar o controller - Adicionar o action index para o controller - Criar a view index.ctp Model: cake/ola_cake/models/cliente.php <?php class Cliente extends AppModel { var $name = 'Cliente'; } ?> Controller: cake/ola_cake/controllers/clientes_controller.php <?php class ClientesController extends AppController { var $name = 'Clientes'; } ?> Toda função pública dentro da classe controller é chamada de action. Esta action visualizará todos os clientes com a view index.ctp <?php class ClientesController extends AppController { var $name = 'Clientes'; // Para a view index.ctp function index() { $this->set('clientes', $this->Cliente->find('all')); } } ?> View: cake/ola_cake/views/clientes/index.ctp <h2>Clientes</h2> <?php if(empty($clientes)): ?> Nenum cliente encontrado <?php else: ?> Ribamar FS – http://cursos.ribafs.org
  • 62. Curso de CakePHP Página 62 /69 <table> <tr> <th>ID</th> <th>Nome</th> <th>Ações</th> </tr> <?php foreach ($clientes as $cliente): ?> <tr> <td> <?php echo $cliente['Cliente']['id'] ?> </td> <td> <?php echo $cliente['Cliente']['nome'] ?> </td> <td> <!-- actions on tasks will be added later --> </td> </tr> <?php endforeach; ?> </table> <?php endif; ?> Agora chamar no navegador assim: http://localhost/cake/ola_cake/clientes Aí temos a listagem dos registros da tabela praticamente sem programação, apenas algumas poucas linhas. Adicionar Registros Para isso precisaremos adicionar uma variável (array $helpers) e uma função add() ao controller, como também adicionar uma view à pasta clientes, de nome add.ctp. var $helpers = array('Html', 'Form'); function add() { if (!empty($this->data)) { $this->Cliente->create(); if ($this->Cliente->save($this->data)) { $this->Session->setFlash('Cliente foi adicionado'); $this->redirect(array('action'=>'index'), null, true); } else { $this->Session->setFlash('Cliente não adicionado. Tente novamente.'); } Ribamar FS – http://cursos.ribafs.org
  • 63. Curso de CakePHP Página 63 /69 } } Que ficará assim: cake/ola_cake/controllers/clientes_controller.php <?php class ClientesController extends AppController { var $name = 'Clientes'; var $helpers = array('Html', 'Form'); function index() { $this->set('clientes', $this->Cliente->find('all')); } function add() { if (!empty($this->data)) { $this->Cliente->create(); if ($this->Cliente->save($this->data)) { $this->Session->setFlash('Cliente foi adicionado'); $this->redirect(array('action'=>'index'), null, true); } else { $this->Session->setFlash('Cliente não adicionado. Tente novamente.'); } } } } ?> Adicionar a view: cake/ola_cake/views/clientes/add.ctp <?php echo $form->create('Cliente');?> <fieldset> <legend>Adicionar novo Cliente</legend> <?php echo $form->input('ID'); echo $form->input('Nome'); ?> </fieldset> <?php echo $form->end('Adicionar');?> Agora chame com o navegador: http://localhost/cake/ola_cake/clientes/add Ribamar FS – http://cursos.ribafs.org
  • 64. Curso de CakePHP Página 64 /69 Adicionar um link do form Add para a nossa view index.ctp (adicionar ao final): <?php echo $html->link('Adicionar Cliente', array('action'=>'add')); ?> Adicionar um link para a view index na view add.ctp (ao final): <?php echo $html->link('Listar todos os Clientes', array('action'=>'index')); ?> Editar Registros Para isso precisamos adicionar um action (edit) ao controller e uma view para este action (views/clientes/edit.ctp). cake/ola_cake/controllers/clientes_controller.php <?php class ClientesController extends AppController { var $name = 'Clientes'; var $helpers = array('Html', 'Form'); function add() { if (!empty($this->data)) { $this->Cliente->create(); if ($this->Cliente->save($this->data)) { $this->Session->setFlash('Cliente foi adicionado'); $this->redirect(array('action'=>'index'), null, true); } else { $this->Session->setFlash('Cliente não adicionado. Tente novamente.'); } } } function edit($id = null) { if (!$id) { $this->Session->setFlash('Cliente Inválido'); $this->redirect(array('action'=>'index'), null, true); } if (empty($this->data)) { $this->data = $this->Cliente->find(array('id' => $id)); } else { if ($this->Cliente->save($this->data)) { $this->Session->setFlash('O Cliente foi salvo!'); Ribamar FS – http://cursos.ribafs.org
  • 65. Curso de CakePHP Página 65 /69 $this->redirect(array('action'=>'index'), null, true); } else { $this->Session->setFlash('O Cliente não pôde ser salvo. Favor tentar novamente.'); } } } } ?> Adicionar o link para Edição na index.ctp, para que fique assim: <h2>Clientes</h2> <?php if(empty($clientes)): ?> Nenum cliente encontrado <?php else: ?> <table> <tr> <th>ID</th> <th>Nome</th> <th>Ações</th> </tr> <?php foreach ($clientes as $cliente): ?> <tr> <td> <?php echo $cliente['Cliente']['id'] ?> </td> <td> <?php echo $cliente['Cliente']['nome'] ?> </td> <td> <!-- actions on tasks will be added later --> <?php echo $html->link('Editar', array('action'=>'edit', $cliente['Cliente']['id'])); ?> </td> </tr> <?php endforeach; ?> </table> <?php endif; ?> <?php echo $html->link('Adicionar Cliente', array('action'=>'add')); ?> Agora adicionar o link para o edit.ctp: <?php echo $html->link('Listar Todos os Clientes', array('action'=>'index')); ?><br /> <?php echo $html->link('Adicionar Cliente', array('action'=>'add')); ?> Ribamar FS – http://cursos.ribafs.org
  • 66. Curso de CakePHP Página 66 /69 Criar um Menu de entrada Adicionar o arquivo home.ctp em views/pages: <h1>Bem vindo ao Bake</h1> <p>Aqui podmeos fazer:</p> <ul> <li><?php echo $html->link('Lista de todos os clientes', array('controller' => 'clientes', 'action'=>'index')); ?></li> <li><?php echo $html->link('Adicionar novo Cliente', array('controller' => 'clientes', 'action'=>'add')); ?></li> <li>Editar Clientes</li> <li>Excluir Clientes</li> </ul> Agora basta chamar no navegador: http://localhost/cake/ola_cake/ 17.3 - Outros Aplicativos de Exemplo encontrados no Site: – bake – blog – estoque – foreign – forum – ola_cake Ribamar FS – http://cursos.ribafs.org
  • 67. Curso de CakePHP Página 67 /69 18 - Cake - Referências Site oficial http://cakephp.org Site Brasileiro do CakePHP http://cakephp.com.br/ Manuais Manual do Cake - CookBook http://book.cakephp.org/pt/complete/3/The-Manual Manual do Cake em Português http://manual.cakephp.com.br/doku.php Blog Tutorial http://book.cakephp.org/view/219/the-cakephp-blog-tutorial Screencasts http://cakephp.org/screencasts CheatSheets http://cakephp.org/files/Resources/CakePHP-1.2-Cheatsheet.pdf Listas FAQs da Lista internacional http://groups.google.com/group/cake-php/web/faq?pli=1 Lista internacional (em processo de mudança para outro servidor) http://groups.google.com/group/cake-php/topics Lista portuguesa http://groups.google.com/group/cake-php-pt Tutoriais Tutorial da IBM em 5 partes somando mais de 130 páginas - Cook up Web sites fast with CakePHP https://www.ibm.com/developerworks/opensource/tutorials/os-php-cake1/ * Part 1 focuses on getting CakePHP up and running, and the basics of how to put together a simple application allowing users to register for an account and log in to the application. http://www.ibm.com/developerworks/opensource/tutorials/os-php-cake1/os-php-cake1-pdf.pdf Código fonte - http://www.ibm.com/developerworks/apps/download/index.jsp? contentid=390462&filename=os-php-cake1.source.zip&method=http&locale=worldwide * Part 2 demonstrates how to use scaffolding and Bake to get a jump-start on your application, and using CakePHP's access control lists (ACLs). Ribamar FS – http://cursos.ribafs.org