Upload
fernando-lusardo
View
219
Download
3
Embed Size (px)
DESCRIPTION
Slides de Programação
Citation preview
Framework
Oferece uma arquitetura que pode ser usada em várias aplicações.
Toda aplicação tem um conjunto de características básicas em comum, que terminam sendo copiadas para a criação de novos códigos.
Um framework é projetado para prover uma estrutura para esses elementos comuns.
Publicações sobre CakePHP CakePHP in Action - The Official Guide
Duane O'Brien
Beginning CakePHP: From Novice to Professional
David Golding
Publicações sobre CakePHP
Frameworks para Desenvolvimento em PHP
Elton Luís Minetto
Histórico
Em 2005, Michal Tatarynowicz escreveu uma pequena versão de um framework para aplicações rápidas em PHP.
Depois ele publicou o framework sob licença MIT, chamando-o de Cake e abrindo-o à comunidade que agora o mantém com o nome de CakePHP.
Características Baseado no framework Ruby on Rails:
Convenção sobre Configuração; Full Stack Web Framework; DRY – Don´t Repeat Yourself – Não se repita Arquitetura MVC – Modelo, Visão, Controlador Funcionalidade CRUD para interação com banco
de dados Scaffolding Validações nativas Helpers nas visões para AJAX, JavaScript, HTML,
formulários, etc. URLs e rotas personalizáveis e limpas
Características Ativo Comunidade amigável e extensa Licença bastante flexível (MIT) Compatibilidade com PHP 4 e PHP 5 Geração de código Componentes de E-mail, Cookie, Segurança,
Sessões, Manipulação de Requisições, etc. Lista de controle de acessos (ACL) flexível Cache flexível Internacionalização e Localização Facilidade de disponibilização
Comparativo com outros frameworks
Estrutura MVC mais eficiente que Symfony e Zend, além de ocupar pouco espaço no servidor. (David Golding)
Boa documentação, inclusive em português. Livros estão sendo publicados.
Comunidade grande e ativa. Atualizações freqüentes.
Arquitetura MVC
Arquitetura MVC
Modelos para toda a interação com banco de dados;
Visões para todas as apresentações e saídas;
Controladores para comandos e scripts.
MVC – Vantagens
Tarefas repetitivas podem ser separadas, facilitando a manutenção, entendimento, alterações, descoberta de erros e bugs, divisão 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
diretório para o nome mais adequado para sua aplicação.
Geração de código com Bake Entre no diretório do projeto:cd \xampplite\htdocs\projeto-cake
Execute o gerador de código (bake):cake\console\cake bake -app app
Bake
Welcome to CakePHP v1.2.0.6311 beta Console--------------------------------------------------------------App : appPath: C:\xampplite\htdocs\locadora\app--------------------------------------------------------------Interactive Bake Shell--------------------------------------------------------------[D]atabase Configuration[M]odel[V]iew[C]ontroller[P]roject[Q]uitWhat would you like to Bake? (D/M/V/C/P/Q)
Estrutura de Diretórios app – nossa aplicação fica aqui. cake – o framework fica aqui. Não mexa!!!
Pode-se atualizar a versão do CakePHP sem interferir na aplicação.
docs – documentação da nossa aplicação. index.php – coletor de requisições. Recebe as
requisições se: mod_rewrite ou .htaccess não estiver disponível /public não estiver definido como web root.
vendors – bibliotecas de terceiros.
Estrutura de Diretórios No diretório App temos :
config: Arquivos de configuração controllers: controladores models: modelos views: visões webroot: html's, imagens, swf, css, javascript,
etc.
Configurando o CakePHP Teste a aplicação. Algumas observações aparecerão e deverão
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 aplicação.
Configurações da base de dados driver
Nome do driver da base de dados para esta configuração. Exemplos: mysql, postgres, sqlite, pear-drivername, adodb-drivername, mssql, oracle, ou odbc.
persistent Se usará ou não uma conexão persistente com a base de dados.
host O nome do servidor da base de dados (ou endereço IP).
login O usuário desta conta.
password A senha desta conta.
database O nome da base de dados que esta conexão irá usar.
prefix (opcional) Esta string será adicionada como prefixo no nome de todas tabelas de sua base de
dados.Se suas tabelas não 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 indicações SQL ao servidor. schema
Usado em instalações de base de dados PostgreSQL para especificar qual schema usar.
Base de Dados usando MySQL
<?phpclass DATABASE_CONFIG {
var $default = array('driver' => 'mysql','persistent' => true,'host' => 'localhost','port' => '','login' => 'root','password' => '','database' => 'prog_web','schema' => '','prefix' => '','encoding' => 'utf8'
);// ...
}?>
app/config/database.php
Base de Dados usando MySQLi
<?phpclass DATABASE_CONFIG {
var $default = array('driver' => 'mysqli','persistent' => true,'host' => 'localhost','port' => '0','login' => 'root','password' => '','database' => 'prog_web','schema' => '','prefix' => '','encoding' => 'utf8'
);// ...
}?>
app/config/database.php
Olá, Mundo!!!
<?php class HelloController extends AppController {
var $uses = array(); var $autoRender = false;
function index() {echo 'Olá, Mundo!!!';
}}?>
app/controllers/hello_controller.php
Olá, Mundo!!!
<?php class HelloController extends AppController {
var $uses = array();
function index() {}
}?>
<p>Olá, Mundo!!!</p>
app/views/hello/index.ctp
app/controllers/hello_controller.php
Envio de dados do controlador para a visão
<?php class HelloController extends AppController {
var $uses = array();
function index() {$this->set('nome','Regis');
}}?>
<p>Olá, <?php echo $nome; ?>.</p>
app/views/hello/index.ctp
app/controllers/hello_controller.php
Método set
O método set usado nos controladores serve para enviar dados do controlador para a visão.
Exemplos:
$this->set('cor','azul');
$this->set('colecoes',$this->Colecao->findAll());
Layouts Layout padrão:
cake/libs/view/layouts/default.ctp Layout personalizado:
app\views\layouts\default.ctp
<html><head>
<title>Aplicação Exemplo</title></head><body>
<h1>Minha Aplicação</h1><?php echo $content_for_layout; ?>
</body></html>
Fluxo de funcionamento do CakePHP
Configuração
app/config/core.php debug
0 = Modo de Produção. Nenhuma saída. 1 = Exibe erros e alertas. 2 = Exibe erros, alertas e SQL. 3 = Exibe erros, alertas, SQL e listagem completa
do controller.
Paginação
Padrão: 20 itens por página Configuração 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'));
Paginação
Uso:$filmes = $this->paginate();$this->set('filmes', $filmes); Ou:
$filmes = $this->paginate('Filme');$this->set('filmes', $filmes);
Paginação
<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>
Na visão:
Paginação
<!-- 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(); ?>
Na visão:
Paginação
O contador pode ser personalizado:<?phpecho $paginator->counter(array(
'format' => 'Página %page% de %pages%, mostrando %current% registros de um total de %count%. Registro inicial: %start%. Registro final: %end%')); ?>
Validação
<?phpclass User extends AppModel { var $name = 'User'; var $validate = array( 'login' => 'alphaNumeric', 'email' => 'email', 'born' => 'date' );}?>
Validação<?phpclass Genero extends AppModel {
var $name = 'Genero';var $useTable = 'generos';var $displayField = 'descricao';
var $validate = array('descricao' => VALID_NOT_EMPTY);
//...}?>
Validação
<?phpclass Filme extends AppModel {
var $name = 'Filme';var $useTable = 'filmes';var $validate = array(
'titulo' => array( array('rule' => array('minLength',1),
'message'=>'Não pode ficar em branco'), array('rule' => array('maxLength',50),
'message'=>'Texto muito longo.')),'sinopse' => array('rule' => array('minLength',1)),'ano_lancamento' => array('numeric')
);//...
}?>
Validação<?phpclass 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 ) );}?>
Validação alphaNumeric between blank cc comparison date decimal email equalTo extension ip minLength maxLength money numeric
phone postal range url
Associações
$belongsTo $hasOne $hasMany $hasAndBelongsToMany
Associações
<?phpclass User extends AppModel {
var $name = 'User';var $hasOne = 'Profile';var $hasMany = array(
'Recipe' => array('className' => 'Recipe','conditions' => 'Recipe.approved = 1','order' => 'Recipe.created DESC'
));}?>
Associações
<?phpclass Filme extends AppModel {
var $name = 'Filme';var $useTable = 'filmes';// ...var $belongsTo = array(
'Genero' => array('className' => 'Genero','foreignKey' => 'genero_id','conditions' => '','fields' => '','order' => ''
));
}?>
Associações
$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'));
No modelo (genero.php):
Nas actions add e edit do controller (filmes_controller.php):
var $displayField = 'descricao';
Rotas
Definições de rota dizem ao CakePHP como mapear URLs para ações de controladores.
Comportamento padrão: A URL "/controller/action/var1/var2" é mapeada
para Controller::action($var1, $var2) Tal comportamento pode ser personalizado.
Definição de Rotas
Arquivo: /app/config/routes.php
Exemplo:<?phpRouter::connect('/', array('controller' => 'filmes', 'action' => 'index'));Router::connect('/pages/*',array('controller' => 'pages', 'action' => 'display'));?>
Flash Usado para comunicação entre ações. Contém uma string contendo informação ou erro. Existe somente durante uma requisição. No controller:
$this->Session->setFlash('OK');
Na view:<?phpif ($session->check('Message.flash')): $session->flash();endif;?>
Logging
Usar:$this->log("Ops, algo não deu certo!");
$this->log('mensagem de debug.', LOG_DEBUG);
Verificar em: app/tmp/logs/error.log app/tmp/logs/debug.log
Níveis de log: LOG_ERROR LOG_DEBUG
Model Normalmente representam tabelas no banco
de dados, mas também podem ser entradas LDAP, feeds RSS, arquivos no sistema, etc.
Model
<?phpclass Pessoa extends AppModel {}?>
app/models/pessoa.php
Personalização de plurais Pode-se ajustar a pluralização no arquivo:
/app/config/inflections.php Exemplo:
$irregularPlural = array('valor' => 'valores');
Controller
<?phpclass PessoasController extends AppController {
var $scaffold;}?>
app/controllers/pessoas_controller.php
View
Obtém dados do controller e os usa para gerar a apresentação para o cliente.
Views são normalmente HTML, mas também podem ser: PDF, XML, objetos JSON, etc.
Layouts
Por padrão, cada visão gerada pelo controlador é colocada dentro de um layout.
Helpers de Visão
Ajudam na lógica de apresentação. Compartilhados entre várias visões.
$html->link
<?php echo $html->link('Filmes', array('controller'=>'filmes', 'action'=>'index')); ?>
<?php echo $html->link('Gêneros', array('controller'=>'generos', 'action'=>'index')); ?>
Compartilhamento de Código
Controladores, Helpers e Modelos possuem uma super-classe que permitem o compartilhamento de código entre vários 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 são callbacks?
São funções/métodos que ao invés de serem chamados diretamente por nós, são executadas pelo sistema/framework quando necessário.
Callbacks são usados quando precisamos de alguma lógica entre operações do próprio CakePHP.
Controller - Callbacks
Callbacks disponíveis nos controladores: beforeFilter() - executado antes de qualquer ação
do controlador. beforeRender() - executado após a lógica do
controlador, mas antes da geração da visão. afterFilter() - executado após toda a lógica do
controlador e geração da visão. afterRender() - A mesma coisa que afterFilter(),
exceto quando há alguma lógica após uma chamada explícita a render() na ação do controller.
Model – Callbacks beforeFind() afterFind() beforeValidate() beforeSave() afterSave() beforeDelete() afterDelete()
Autenticação
Criar tabela usuarios Campo email - varchar(100) Campo senha – varchar(40)
Criar modelo, visão e controlador para Usuario
Autenticação AppController<?phpclass 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 = "Usuário ou senha inválido(s)";
$this->Auth->authError = 'Acesso não autorizado.'; }}?>
Autenticação Criar ações login e logout no controlador
de usuários:<?phpclass UsuariosController extends AppController {
var $name = 'Usuarios';var $helpers = array('Html', 'Form');
// ... function login() { }
function logout(){
$this->Session->setFlash('Desconectado.'); $this->redirect($this->Auth->logout()); }
}?>
Autenticação Criar visão de login (/app/views/usuarios/login.ctp)
<div class="login"><h2>Digite usuário 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>
Autenticação
No Layout Item de Menu:
<?php echo $html->link('Sair',array('controller'=> 'usuarios','action'=>'logout')); ?>
Mensagem:
<?phpif ($session->check('Message.auth')) {
$session->flash('auth');}?>
Permissões de Acesso
ACL – Access Control Lists ARO – Access Request Objects
Usuários ou Grupos Exemplo: admin, usuario, convidado
ACO – Access Control Objects Controladores, ações Exemplo: Filme, Genero
ACL decide se um ARO pode acessar um ACO. Ou seja: se um usuário tem acesso a uma ação 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( 1, null, 'Bob Marley' );$aro->create( 2, null, 'Jimi Hendrix');$aro->create( 3, null, 'George Washington');$aro->create( 4, null, '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<?phpclass 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
<?phpclass 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;
} }}?>
$this->Acl->check($aro, $aco, $action = '*');
ACL
cd app..\cake\console\cake schema run create DbAcl
Criando as tabelas de ACL:
Referências The Cookbook
http://book.cakephp.org API
http://api.cakephp.org/1.2 Bakery
http://bakery.cakephp.org CakeForge
http://bakery.cakephp.org Site oficial
http://www.cakephp.org Grupo Google
http://groups.google.com/group/cake-php