Você está na página 1de 70

Programao para WEB

O Framework
CakePHP
Regis Pires Magalhes
regispiresmag@gmail.com

Framework

Oferece uma arquitetura que pode ser


usada em vrias aplicaes.
Toda aplicao tem um conjunto de
caractersticas bsicas em comum, que
terminam sendo copiadas para a criao
de novos cdigos.
Um framework projetado para prover
uma estrutura para esses elementos
comuns.

Publicaes sobre CakePHP

CakePHP in Action - The Official Guide

Duane O'Brien

Beginning CakePHP: From Novice to


Professional

David Golding

Publicaes sobre CakePHP

Frameworks para Desenvolvimento


em PHP

Elton Lus Minetto

Histrico

Em 2005, Michal Tatarynowicz escreveu


uma pequena verso de um framework
para aplicaes rpidas em PHP.
Depois ele publicou o framework sob
licena MIT, chamando-o de Cake e
abrindo-o comunidade que agora o
mantm com o nome de CakePHP.

Caractersticas

Baseado no framework Ruby on Rails:

Conveno sobre Configurao;


Full Stack Web Framework;
DRY Dont Repeat Yourself No se repita
Arquitetura MVC Modelo, Viso, Controlador
Funcionalidade CRUD para interao com banco
de dados
Scaffolding
Validaes nativas
Helpers nas vises para AJAX, JavaScript, HTML,
formulrios, etc.
URLs e rotas personalizveis e limpas

Caractersticas

Ativo
Comunidade amigvel e extensa
Licena bastante flexvel (MIT)
Compatibilidade com PHP 4 e PHP 5
Gerao de cdigo
Componentes de E-mail, Cookie, Segurana,
Sesses, Manipulao de Requisies, etc.
Lista de controle de acessos (ACL) flexvel
Cache flexvel
Internacionalizao e Localizao
Facilidade de disponibilizao

Comparativo com outros frameworks

Estrutura MVC mais eficiente que Symfony


e Zend, alm de ocupar pouco espao no
servidor. (David Golding)
Boa documentao, inclusive em
portugus. Livros esto sendo publicados.

Comunidade grande e ativa.

Atualizaes freqentes.

Arquitetura MVC

Arquitetura MVC

Modelos para toda a interao com banco


de dados;
Vises para todas as apresentaes e
sadas;
Controladores para comandos e scripts.

MVC Vantagens

Tarefas repetitivas podem ser separadas,


facilitando a manuteno, entendimento,
alteraes, descoberta de erros e bugs,
diviso de tarefas, etc.

Testando o PHP via console


php -v

Instalando o CakePHP

Baixe o CakePHP em:

http://cakephp.org/downloads

Descompacte-o na pasta htdocs e renomeie o


diretrio para o nome mais adequado para
sua aplicao.

Gerao de cdigo com Bake

Entre no diretrio do projeto:

cd \xampplite\htdocs\projeto-cake

Execute o gerador de cdigo (bake):

cake\console\cake bake -app app

Bake
Welcome to CakePHP v1.2.0.6311 beta Console
-------------------------------------------------------------App : app
Path: C:\xampplite\htdocs\locadora\app
-------------------------------------------------------------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)

Estrutura de Diretrios

app nossa aplicao fica aqui.


cake o framework fica aqui. No mexa!!!
Pode-se atualizar a verso do CakePHP sem
interferir na aplicao.
docs documentao da nossa aplicao.
index.php coletor de requisies. Recebe
as requisies se:

mod_rewrite ou .htaccess no estiver disponvel

/public no estiver definido como web root.

Estrutura de Diretrios

No diretrio App temos :

config: Arquivos de configurao


controllers: controladores
models: modelos
views: vises
webroot: html's, imagens, swf, css, javascript,
etc.

Configurando o CakePHP

Teste a aplicao.
Algumas observaes aparecero e devero
ser seguidas:

Alterar a seguinte linha do arquivo


/app/config/core.php:

Configure::write('Security.salt',
'DyhG93b0qyJfIxfs2guVoUubWwvniR2G0FgaC9mi');

Renomear o arquivo
config/database.php.default para
config/database.php e configur-lo para acessar

o banco de dados de nossa aplicao.

Configuraes da base de dados

driver

Nome do driver da base de dados para esta configurao. Exemplos: mysql,


postgres, sqlite, pear-drivername, adodb-drivername, mssql, oracle, ou odbc.
persistent

Se usar ou no uma conexo persistente com a base de dados.


host

O nome do servidor da base de dados (ou endereo IP).


login

O usurio desta conta.


password

A senha desta conta.


database

O nome da base de dados que esta conexo ir usar.


prefix (opcional)

Esta string ser adicionada como prefixo no nome de todas tabelas de sua base de
dados.Se suas tabelas no possuem prefixo, deixe esta string vazia.
port (opcional)

A porta TCP ou socket Unix usado para conectar com o servidor.


enconding

Indica qual caractere definido ser usado para enviar indicaes SQL ao servidor.
schema

Usado em instalaes de base de dados PostgreSQL para especificar qual schema

Base de Dados usando MySQL


app/config/database.php

<?php
class DATABASE_CONFIG {
var $default = array(
'driver' => 'mysql',
'persistent' => true,
'host' => 'localhost',
'port' => '',
'login' => 'root',
'password' => '',
'database' => 'prog_web',
'schema' => '',
'prefix' => '',
'encoding' => 'utf8'
);
// ...
}
?>

Base de Dados usando MySQLi


app/config/database.php

<?php
class DATABASE_CONFIG {
var $default = array(
'driver' => 'mysqli',
'persistent' => true,
'host' => 'localhost',
'port' => '0',
'login' => 'root',
'password' => '',
'database' => 'prog_web',
'schema' => '',
'prefix' => '',
'encoding' => 'utf8'
);
// ...
}
?>

Ol, Mundo!!!
app/controllers/hello_controller.php

<?php
class HelloController extends AppController {
var $uses = array();
var $autoRender = false;

}
?>

function index() {
echo 'Ol, Mundo!!!';
}

Ol, Mundo!!!
app/controllers/hello_controller.php

<?php
class HelloController extends AppController {
var $uses = array();

}
?>

function index() {
}

app/views/hello/index.ctp

<p>Ol, Mundo!!!</p>

Envio de dados do controlador para a viso


app/controllers/hello_controller.php

<?php
class HelloController extends AppController {
var $uses = array();

}
?>

function index() {
$this->set('nome','Regis');
}

app/views/hello/index.ctp

<p>Ol, <?php echo $nome; ?>.</p>

Mtodo set

O mtodo set usado nos controladores


serve para enviar dados do controlador
para a viso.
Exemplos:

$this->set('cor','azul');
$this->set('colecoes',$this->Colecao->findAll());

Layouts

Layout padro:

cake/libs/view/layouts/default.ctp

Layout personalizado:

app\views\layouts\default.ctp

<html>
<head>
<title>Aplicao Exemplo</title>
</head>
<body>
<h1>Minha Aplicao</h1>
<?php echo $content_for_layout; ?>
</body>
</html>

Fluxo de funcionamento do CakePHP

Configurao

app/config/core.php

debug

0 = Modo de Produo. Nenhuma sada.

1 = Exibe erros e alertas.

2 = Exibe erros, alertas e SQL.

3 = Exibe erros, alertas, SQL e listagem completa


do controller.

Paginao

Padro: 20 itens por pgina

Configurao no controller:

var $paginate = array('limit' => 10);

var $paginate = array('limit' => 10,


'order' => 'Filme.titulo');

var $paginate = array('limit' => 10,


'order' => array('Filme.titulo' => 'desc'));

Paginao

Uso:

$filmes = $this->paginate();
$this->set('filmes', $filmes);

Ou:

$filmes = $this->paginate('Filme');
$this->set('filmes', $filmes);

Paginao

Na viso:

<table>
<tr>
<th>
<?php echo $paginator->sort('ID', 'id'); ?>
</th>
<th>
<?php echo $paginator->sort('Title', 'title'); ?>
</th>
</tr>
<?php foreach($data as $recipe): ?>
<tr>
<td><?php echo $recipe['Recipe']['id']; ?> </td>
<td>
<?php echo $recipe['Recipe']['title']; ?>
</td>
</tr>
<?php endforeach; ?>
</table>

Paginao

Na viso:

<!-- Shows the next and previous links -->


<?php
echo $paginator->prev(' Previous ', null, null,
array('class' => 'disabled'));
echo $paginator->next(' Next ', null, null,
array('class' => 'disabled'));
?>
<!-- prints X of Y, where X is current page and Y is number of
pages -->
<?php echo $paginator->counter(); ?>

Paginao

O contador pode ser personalizado:

<?php
echo $paginator->counter(array(
'format' => 'Pgina %page% de %pages%,
mostrando %current% registros de um total
de %count%. Registro inicial: %start%.
Registro final: %end%'
));
?>

Validao
<?php
class User extends AppModel {
var $name = 'User';
var $validate = array(
'login' => 'alphaNumeric',
'email' => 'email',
'born' => 'date'
);
}
?>

Validao
<?php
class Genero extends AppModel {
var $name = 'Genero';
var $useTable = 'generos';
var $displayField = 'descricao';
var $validate = array('descricao' => VALID_NOT_EMPTY);
}
?>

//...

Validao
<?php
class Filme extends AppModel {
var $name = 'Filme';
var $useTable = 'filmes';
var $validate = array(
'titulo' => array(
array('rule' => array('minLength',1),
'message'=>'No pode ficar em branco'),
array('rule' => array('maxLength',50),
'message'=>'Texto muito longo.')),
'sinopse' => array('rule' => array('minLength',1)),
'ano_lancamento' => array('numeric')
);
//...
}
?>

Validao
<?php
class User extends AppModel {
var $name = 'User';
var $validate = array(
'login' => array(
'alphanumeric' => array(
'rule' => 'alphaNumeric',
'required' => true,
'message' => 'Alphabets and numbers only'
),
'between' => array(
'rule' => array('between', 5, 15)
)
),
'password' => array(
'rule' => array('minLength', '8'),
'message' => 'Mimimum 8 characters long'
),
'born' => array(
'rule' => 'date',
'message' => 'Enter a valid date',
'allowEmpty' => true
)
);
}
?>

Validao

alphaNumeric
between
blank
cc
comparison
date
decimal
email
equalTo
extension
ip
minLength
maxLength
money
numeric

phone
postal
range
url

Associaes

$belongsTo

$hasOne

$hasMany

$hasAndBelongsToMany

Associaes
<?php
class User extends AppModel {
var $name = 'User';
var $hasOne = 'Profile';
var $hasMany = array(
'Recipe' => array(
'className' => 'Recipe',
'conditions' => 'Recipe.approved = 1',
'order' => 'Recipe.created DESC'
));
}
?>

Associaes
<?php
class Filme extends AppModel {
var $name = 'Filme';
var $useTable = 'filmes';
// ...
var $belongsTo = array(
'Genero' => array('className' => 'Genero',
'foreignKey' => 'genero_id',
'conditions' => '',
'fields' => '',
'order' => ''
)
);
}
?>

Associaes

No modelo (genero.php):
var $displayField = 'descricao';

Nas actions add e edit do controller


(filmes_controller.php):

$generos = $this->Filme->Genero->find('list',
array('order' => 'Genero.descricao'));
$this->set(compact('generos'));
$generos = $this->Filme->Genero->find('list',
array('conditions' => array('Genero.descricao' =>
'like a%'), 'order' => 'Genero.descricao'));
$this->set(compact('generos'));

Rotas

Definies de rota dizem ao CakePHP como


mapear URLs para aes de controladores.
Comportamento padro:

A URL "/controller/action/var1/var2" mapeada


para Controller::action($var1, $var2)

Tal comportamento pode ser personalizado.

Definio de Rotas

Arquivo:

/app/config/routes.php

Exemplo:

<?php
Router::connect('/', array('controller' =>
'filmes', 'action' => 'index'));
Router::connect('/pages/*',array('controller' =>
'pages', 'action' => 'display'));
?>

Flash

Usado para comunicao entre aes.


Contm uma string contendo informao ou erro.
Existe somente durante uma requisio.
No controller:

$this->Session->setFlash('OK');

Na view:

<?php
if ($session->check('Message.flash')):
$session->flash();
endif;
?>

Logging

Usar:

$this->log("Ops, algo no deu certo!");


$this->log('mensagem de debug.', LOG_DEBUG);

Verificar em:

app/tmp/logs/error.log

app/tmp/logs/debug.log

Nveis de log:

LOG_ERROR

LOG_DEBUG

Model

Normalmente representam tabelas no banco


de dados, mas tambm podem ser entradas
LDAP, feeds RSS, arquivos no sistema, etc.

Model
app/models/pessoa.php

<?php
class Pessoa extends AppModel {
}
?>

Personalizao de plurais

Pode-se ajustar a pluralizao no arquivo:

/app/config/inflections.php

Exemplo:

$irregularPlural = array('valor' => 'valores');

Controller
app/controllers/pessoas_controller.php

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

View

Obtm dados do controller e os usa para


gerar a apresentao para o cliente.
Views so normalmente HTML, mas
tambm podem ser: PDF, XML, objetos
JSON, etc.

Layouts

Por padro, cada viso gerada pelo


controlador colocada dentro de um
layout.

Helpers de Viso

Ajudam na lgica de apresentao.

Compartilhados entre vrias vises.

$html->link
<?php echo $html->link('Filmes',
array('controller'=>'filmes',
'action'=>'index')); ?>
<?php echo $html->link('Gneros',
array('controller'=>'generos',
'action'=>'index')); ?>

Compartilhamento de Cdigo

Controladores, Helpers e Modelos


possuem uma super-classe que permitem
o compartilhamento de cdigo entre vrios
controladores, helpers ou modelos:

AppController /app/app_controller.php

AppHelper /app/app_helper.php

AppModel /app/app_model.php

Controller - Callbacks

Controladores possuem callbacks.

E o que so callbacks?

So funes/mtodos que ao invs de serem


chamados diretamente por ns, so executadas
pelo sistema/framework quando necessrio.

Callbacks so usados quando precisamos de


alguma lgica entre operaes do prprio
CakePHP.

Controller - Callbacks

Callbacks disponveis nos controladores:

beforeFilter() - executado antes de qualquer ao


do controlador.
beforeRender() - executado aps a lgica do
controlador, mas antes da gerao da viso.
afterFilter() - executado aps toda a lgica do
controlador e gerao da viso.
afterRender() - A mesma coisa que afterFilter(),
exceto quando h alguma lgica aps uma
chamada explcita a render() na ao do controller.

Model Callbacks

beforeFind()

afterFind()

beforeValidate()

beforeSave()

afterSave()

beforeDelete()

afterDelete()

Autenticao

Criar tabela usuarios

Campo email - varchar(100)

Campo senha varchar(40)

Criar modelo, viso e controlador para


Usuario

Autenticao

AppController

<?php
class AppController extends Controller {
var $components = array('Auth');

}
?>

function beforeFilter(){
$this->Auth->userModel = 'Usuario';
$this->Auth->fields = array('username' =>
'email', 'password' => 'senha');
$this->Auth->loginAction = array('controller' =>
'usuarios', 'action' => 'login');
$this->Auth->loginRedirect = array('controller' =>
'filmes', 'action' => 'index');
$this->Auth->loginError =
"Usurio ou senha invlido(s)";
$this->Auth->authError =
'Acesso no autorizado.';
}

Autenticao

Criar aes login e logout no controlador


de usurios:

<?php
class UsuariosController extends AppController {
var $name = 'Usuarios';
var $helpers = array('Html', 'Form');
// ...
function login() {
}
function logout(){
$this->Session->setFlash('Desconectado.');
$this->redirect($this->Auth->logout());
}
}
?>

Autenticao

Criar viso de login (/app/views/usuarios/login.ctp)

<div class="login">
<h2>Digite usurio e senha para acessar o
sistema<h2>
<?php echo $form->create('Usuario',
array('action' => 'login'));?>
<?php echo $form->input('email'); ?>
<?php echo $form->input('senha',
array('type'=>'password')); ?>
<?php echo $form->end('Login');?>
</div>

Autenticao

No Layout

Item de Menu:

<?php echo $html->link('Sair',array('controller'=>


'usuarios','action'=>'logout')); ?>

Mensagem:
<?php
if ($session->check('Message.auth')) {
$session->flash('auth');
}
?>

Permisses de Acesso

ACL Access Control Lists


ARO Access Request Objects

ACO Access Control Objects

Usurios ou Grupos
Exemplo: admin, usuario, convidado
Controladores, aes
Exemplo: Filme, Genero

ACL decide se um ARO pode acessar um ACO.

Ou seja: se um usurio tem acesso a uma ao C, R, U


ou D do ACO.

AROs
$aro = new Aro();
$aro->create($user_id, $parent_id, $alias);
$aro->create(0, null, 'Presidents');
$aro->create(0, null, 'Artists');
$aro->create(
$aro->create(
$aro->create(
$aro->create(

1,
2,
3,
4,

null,
null,
null,
null,

'Bob Marley' );
'Jimi Hendrix');
'George Washington');
'Abraham Lincoln');

$aro->setParent('Presidents', 'George Washington');


$aro->setParent('Presidents', 'Abraham Lincoln');
$aro->setParent('Artists', 'Jimi Hendrix');
$aro->setParent('Artists', 'Bob Marley');?>

ACOs
$aco = new Aco();
$aco->create($id, $parent, $alias);
$aco->create(1, null, 'Electric Guitar');
$aco->create(2, null, 'United States Army');
$aco->create(3, null, 'Fans');

ACL
<?php
class SomethingsController extends AppController {
var $components = array('Acl');
function someAction() {
// ALLLOW
$this->Acl->allow('Jimi Hendrix', 'Electric Guitar');
$this->Acl->allow('Bob Marley', 'Electric Guitar');
$this->Acl->Allow('Presidents', 'United States Army');
$this->Acl->allow('George Washington', 'Electric Guitar',
'read');
$this->Acl->allow('Abraham Lincoln', 'Electric Guitar',
'read');

}
?>

// DENY
$this->Acl->deny('Abraham Lincoln', 'United States Army');

ACL
$this->Acl->check($aro, $aco, $action = '*');
<?php
class AppController extends Controller{
var $components = array('Acl');

}
?>

function checkAccess($aco){
$access = $this->Acl->check($this->Session->
read('user_alias'), $aco, $action = "*");
if ($access === false) {
echo "access denied";
exit;
} else {
echo "access allowed";
exit;
}
}

ACL

Criando as tabelas de ACL:

cd app
..\cake\console\cake schema run create DbAcl

Referncias

The Cookbook

API

http://bakery.cakephp.org

Site oficial

http://bakery.cakephp.org

CakeForge

http://api.cakephp.org/1.2

Bakery

http://book.cakephp.org

http://www.cakephp.org

Grupo Google

Você também pode gostar