 | Tor, até o momento
Até agora, você usou o CakePHP para criar um aplicativo simples para gerenciar produtos e vendedores. Na Parte 1, você aprendeu sobre o paradigma MVC. Na Parte 2, usou o poderoso componente de scaffolding para desenvolver facilmente a estrutura do seu aplicativo. Concluiu a Parte 3 com vários projetos para aprimorar o Tor. O primeiro era higienizar seus dados.
O que higienizar
Quando você higienizou seus dados, provavelmente notou que a maior parte da entrada de usuário até o momento é bastante simples. A maior parte da entrada de dados pode ser filtrada usando o método paranoid, visto que não deve deixar nada complexo demais do usuário. A ação login do controlador de usuários é mostrada abaixo.
Listagem 1. Higienizando a entrada de nome de usuário
function login()
{
if ($this->data)
{
$results = $this->User->findByUsername(Sanitize::paranoid($this->data
['User']['username']));
if ($results && $results['User']['password'] == md5($this->data
['User']['password']))
{
$this->Session->write('user', $this->data['User']['username']);
$this->redirect(array('action' => 'index'), null, true);
} else {
$this->set('error', true);
}
}
}
|
De modo similar para registro, seria de esperar que o nome do usuário contivesse apenas letras, espaços, hifens e apóstrofos. Contudo, apóstrofes e hifens podem ser más notícias para um banco de dados SQL. A maior parte da limpeza normal de SQL, do tipo injeção, é gerenciada pela camada DBO, mas você pode suar o método de limpeza para executar higienização pesada em dados de outras entradas, se quiser.
Listagem 2. Você deve higienizar entradas diferentes com base nos seus valores esperados
function register()
{
if (!empty($this->data))
{
$this->data['User']['username'] = Sanitize::paranoid($this->data
['User']['username']);
$this->data['User']['email'] = Sanitize::paranoid($this->data
['User']['email'], array('@', '.', '-', '+'));
$this->data['User']['first_name'] = Sanitize::sql($this->data
['User']['first_name']);
$this->data['User']['last_name'] = Sanitize::sql($this->data
['User']['last_name']);
$this->data['User']['password'] = md5($this->data
['User']['password']);
|
Aqui vão alguns exemplos de como higienizar seus dados.
Tornando o aplicativo seguro.
Sua próxima tarefa era tornar o Tor seguro usando o componente de Segurança. Se analisar que formulários precisam de mais segurança, um palpite natural seria aqueles que alteram o banco de dados. Essa é uma boa regra prática: Se for feita uma mudança no banco de dados, o formulário deverá ser enviado pelo método POST.
Uma ação que se ajusta a essa descrição é a ação delete de produto. Visto que excluir um produto remove uma linha do banco de dados, deveria ser uma solicitação apenas de POST. O código para exigir isso é mostrado abaixo.
Listagem 3. ProductsController exige POST para ação de exclusão
function beforeFilter()
{
$this->Security->requireAuth('delete');
$this->Security->requirePost('delete');
}
|
Se você tentar excluir um produto agora, notará que receberá um erro 400. Isso é bom porque significa que qualquer exclusão precisa ocorrer em resultado de uma solicitação formatada específica. Contudo, precisamos recuperar a funcionalidade de exclusão, de modo que você precisará fazer a alteração apropriada nas suas visualizações que apontam para a ação delete. Veja na Listagem 4 como a nova seção showDelete deve se parecer.
Listagem 4. As chamadas da ação delete devem ocorrer dentro de formulários
<?php if ($showDelete) { ?>
<?php echo $form->create('Product', array('action' => 'delete/' .
$product['Product']['id']));?>
<li><?php echo $form->end('Delete product');?></li>
<?php } ?>
|
Fornecendo feedback para solicitações inválidas
Sua tarefa final era usar blackHoleCallback para fornecer ao usuário uma resposta apropriada em resultado de uma solicitação inválida. Seu objetivo era fornecer feedback útil e amigável, em vez de um desagradável erro de servidor.
Uma possível implementação desse código é encontrada abaixo.
Listagem 5. Informações mais amigáveis para uma função de solicitação ruim beforeFilter()
{
$this->Security->requireAuth('delete');
$this->Security->requirePost('delete');
$this->Security->blackHoleCallback='invalid';
}
function invalid() {
header('HTTP/x 400 Bad Request');
echo('<h1>Tor</h1>');
echo('<p>We\'re sorry - there has been a problem processing your request.
Please try submitting the form again.</p>');
die;
}
|
Alterando o layout padrão
Você vai acrescentar o recurso de produtos favoritos ao Tor. Os visitantes do seu site devem poder salvar produtos para uso futuro e usar um feed de RSS para acompanhar os novos produtos que ficarem disponíveis. Para acrescentar essa funcionalidade, você vai lidar com a função de manuseio de sessão e o componente do Manipulador de Solicitação. Contudo, antes de começar, você precisa expandir um pouco o Tor para que haja lugar para esses recursos. Para esse fim, você vai alterar o layout padrão a fim de customizar a aparência do Tor.
Quando você criou o controlador de produtos para o Tor, usou o script do Bake para criar a estrutura do aplicativo. O resultado foi uma página genérica com uma única tabela que se parecia com a Figura 1.
Figura 1. Scaffolding puro 
Embora esse scaffolding seja bom para estabilizar o design do seu aplicativo, você está agora em um ponto em que os usuários vão precisar de mais funcionalidade do que simplesmente ver produtos. Visto que o layout padrão forneceu um bom ponto de partida, tudo o que você precisa fazer é atualizar um pouco as visualizações existentes para organizar o aplicativo.
Layouts
Layouts são um tipo de visualização que não corresponde diretamente a um controlador ou modelo. Explicado de forma simples, um layout é um template. Mudar o layout padrão afeta a área ao redor de todas as outras visualizações e geralmente é usado para coisas como cabeçalhos, rodapés e barras de menus.
Estivemos utilizando o layout padrão do CakePHP, que se encontra em cake/libs/view/layouts/default.ctp (não mude isso!). Para substituir o layout por seu template customizado, copie o template padrão para app/views/layouts/default.ctp e modifique-o até que ele se pareça com a Listagem 6 (nada após as mudanças de menu div do template padrão).
Listagem 6. Substituindo o layout por seu template customizado
<!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>
<title>
Tor : <?php echo $title_for_layout;?>
</title>
<?php echo $html->charset();?>
<link rel="icon" href="<?php echo $this->webroot;?>favicon.ico"
type="image/x-icon" />
<link rel="shortcut icon" href="<?php echo $this->webroot;?>
favicon.ico" type="image/x-icon" />
<?php echo $html->css('cake.generic');?>
<?php echo $scripts_for_layout;?>
</head>
<body>
<div id="container">
<div id="header">
<h1><?php echo $html->link('Tor', '/'); ?>
: Welcome <?php echo $session->read('user') ?></h1>
</div>
<div id="content">
<div id="menu">
<?php echo $html->link('Products',
array('controller' => 'products')); ?> | <?php echo
$html->link('Favorites', array('controller' => 'users',
'action' => 'favorites')); ?> |
<?php echo $html->link('Login', array('controller' =>
'users', 'action' => 'login')); ?> |
<?php echo $html->link('Logout', array('controller' =>
'users', 'action' => 'logout')); ?>
</div>
...
(message flash, content for layour, cake link, debug, etc
...
</body>
</html>
|
Esse código se baseia no layout padrão do CakePHP e simplesmente acrescenta uma barra de menus e a marca Tor. Visto que ele ainda usa o CSS padrão, o site não vai mudar muito visualmente.
Note que o layout é o XHTML Transitional. Embora todas as nossas visualizações sejam em XHTML, é totalmente possível elas serem conectadas a um layout em outro formato, como Atom, WML ou XHTML-Mobile. Vamos voltar à ideia de layouts quando acrescentarmos essa funcionalidade ao site.
|  |