Programação Para WEB

Preview:

DESCRIPTION

Slides de Programação

Citation preview

Programação para WEB

Regis Pires Magalhãesregispiresmag@gmail.com

O Framework CakePHP

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