Desenvolvimento Web com Simfony Framework.

Post on 25-May-2015

2.927 views 4 download

description

Desenvolvimento Web com Simfony Framework.

Transcript of Desenvolvimento Web com Simfony Framework.

Prof. Vinícius de Paula

viniciusdepaula@unitri.edu.br

Desenvolvimento Web com

O que é MVC?

Model View Controller: é um padrão de arquitetura de software.

Consiste em separar a aplicação em camadas: Model: modelo de dados; View: apresentação (User Interface); Controller: lógica de negócio. Model

Modelo de Dados

View

Apresentação (UI)

Controller

Lógica de Negócio

O que é Symfony?

Framework MVC desenhado para otimizar o desenvolvimento de aplicações Web.

Estabelece um conjunto de melhores práticas de desenvolvimento.

Arquitetura

Principais Características

Fácil de instalar e configurar; Engine de banco de dados independente; Compatível com as melhores práticas de desenvolvimento

Web e padrões de projeto; Código legível e comentado (phpDocumentor); Fácil de extender, permitindo a integração com outros

framerowks.

Breve Histórico

Criado pelo Francês Fabien Potencier;

Versão Mês/Ano

1.0 Janeiro/2007

1.1 Junho/2007

1.2 Novembro/2008

1.3 Novembro/2009

1.4 Dezembro/2009

2.0 Dezembro/2010

Tecnologias Envolvidas

Servidor Web Apache 2 >

Linguagem PHP 5.2.4 >

Banco de Dados MySQL, PostgreSQL, Oracle e

Microsoft SQL Server

Sistema Operacional Linux, Unix, Windows e Mac OS

CLI (Command Line Interface)

O Symfony framework possibilita o uso de comandos via console possibilitando a automatização de diversas tarefas.

O Symfony é um script PHP localizado no diretório root de um projeto. O comando Symfony é seguido de uma tarefa, e algumas dessas tarefas precisam de parâmetros adicionais. Para chamar o script, utilize a seguinte sintaxe: php symfony <NOME_DA_TAREFA> [argumentos]

Antes de Iniciar a Instalação

Devemos verificar as configurações do PHP:

Instalação

O processo de instalação é bem simples: Crie o diretório sfproject dentro de htdocs; Crie a seguinte árvore de diretórios:

sfproject\lib\vendor\symfony Descompacte o conteúdo do arquivo symfony-1.4.1.zip dentro do

diretório sfproject\lib\vendor\symfony

Instalação

Após a instalação, vamos verificar se tudo ocorreu perfeitamente.

A opção –V exibe a versão do Symfony e o diretório onde ele se encontra instalado.

Projetos

No Symfony, aplicações que compartilham o mesmo modelo de dados são agrupadas dentro de projetos.

Na grande maioria dos projetos, nós teremos basicamente dois tipos de aplicações: Frontend Backend

Criação de Projetos

O processo de criação de projetos pode ser automatizado pela TASK: symfony generate:project php lib\vendor\symfony\data\bin\symfony generate:project

NOME_DO_PROJETO

Estrutura de Diretórios

A task symfony generate:project gera a estrutura de diretórios e os arquivos necessários para um projeto Symfony.

Diretório Descrição

apps Contém todas as aplicações do projeto

cache Contém os arquivos “cacheados” pelo framework

config Contém os arquivos de configuração

lib Contém as bibliotecas e classes

log Contém os logs do framework

test Contém os arquivos para testes unitários e funcionais

web Diretório Web raiz

Configuração do Banco de Dados

O Symfony suporta todos os banco de dados suportados pelo PDO (MySQL, PostgreSQL, SQLite, Oracle, MSSQL, …)

Duas ferramentas ORM (Object relational mapping) são suportadas pelo Symfony: Propel Doctrine

Quando criamos um novo projeto Symfony o Doctrine é

configurado por padrão. Para configurar o banco de dados utilizamos a task: configure:database php symfony configure:database

"mysql:host=localhost;dbname=dbname" root mYsEcret

O que é Doctrine?

É uma ferramenta de ORM (Mapeamento objeto-relacional) construída para trabalhar com PHP 5.2.3+ Tabelas = Classes Colunas = Instâncias das Classes

Criação da Aplicação

Utilizamos a task generate:app para criar uma nova aplicação: php symfony generate:app frontend php symfony generate:app backend

A seguinte estrutura de diretórios é criada sob o diretório: apps/frontend ou apps/backend:

Diretório Descrição

config Arquivos de configuração da aplicação

lib Bibliotecas e classes da aplicação

i18n Arquivos de internacionalização

config O código da aplicação (MVC)

templates Arquivos globais de template

Configuração do Servidor Web

Para que o projeto possa ser acessado, é necessário alterar algumas configurações no arquivo httpd.conf do Apache.

<VirtualHost 127.0.0.1>

DocumentRoot "C:\xampp\htdocs\sfproject\web"

DirectoryIndex index.php

<Directory "C:\xampp\htdocs\sfproject\web">

AllowOverride All

Allow from All

</Directory>

Alias /sf C:\xampp\htdocs\sfproject\lib\vendor\symfony\data\web\sf

<Directory "C:\xampp\htdocs\sfproject\lib\vendor\symfony\data\web\sf">

AllowOverride All

Allow from All

</Directory>

</VirtualHost>

Testando a Configuração

Acesse http://127.0.0.1

Ambiente de Desenvolvimento

Acesse http://127.0.0.1/frontend_dev.php/

Ambientes

No Symfony cada aplicação possui dois arquivos denominados front controllers: index.php

frontend_dev.php

Todas as requisições da aplicação passam por eles.

Ambos apontam para mesma aplicação, porém para ambientes diferentes.

Produçãoindex.php

Desenvolvimentofrontend_dev.php

Exception em Desenvolvimento

Exception em Produção

PHP Convencional

<?php

$link = mysql_connect('localhost', 'myuser', 'mypassword');

mysql_select_db('blog_db', $link);

$result = mysql_query('SELECT date, title FROM post', $link);

?>

<table>

<tr><th>Date</th>

<th>Title</th></tr>

<?php

while ($row = mysql_fetch_array($result, MYSQL_ASSOC)) {

echo "\t<tr>\n";

printf("\t\t<td> %s </td>\n", $row['date']);

printf("\t\t<td> %s </td>\n", $row['title']);

echo "\t</tr>\n"; } ?>

</table>

<?php

mysql_close($link);

?>

PHP Convencional

Principais problemas: Não existe tratativa de erros; HTML e PHP estão misturados, dificultando a manu; O código esta amarrado ao MySQL; Falta de organização.

Isolando a Camada de Apresentação

<html>

<head>

<title>List of Posts</title>

</head>

<body>

<h1>List of Posts</h1>

<table>

<tr><th>Date</th>

<th>Title</th></tr>

<?php foreach ($posts as $post): ?>

<tr>

<td><?php echo $post['date'] ?></td>

<td><?php echo $post['title'] ?></td>

</tr>

<?php endforeach; ?>

</table>

</body>

</html>

Isolando a Camada de Dados

<?php function getAllPosts() {

$link = mysql_connect('localhost', 'myuser', 'mypassword');

mysql_select_db('blog_db', $link);

$result = mysql_query('SELECT date, title FROM post', $link);

$posts = array();

while ($row = mysql_fetch_array($result, MYSQL_ASSOC)) {

$posts[] = $row;

}

mysql_close($link);

return $posts;

}

?>

Controlador

<?php

require_once('model.php');

$posts = getAllPosts();

require('view.php');

?>

Abstração do Banco de Dados

<?php

function open_connection($host, $user, $password) {

return mysql_connect($host, $user, $password);

}

function close_connection($link) {

mysql_close($link);

}

function query_database($query, $database, $link)

mysql_select_db($database, $link);

return mysql_query($query, $link);

}

function fetch_results($result) {

return mysql_fetch_array($result, MYSQL_ASSOC);

}

?>

Acessando Dados do Modelo

function getAllPosts() {

$link = open_connection('localhost', 'myuser', 'mypassword');

$result = query_database('SELECT date, title FROM post', 'blog_db', $link);

$posts = array();

while ($row = fetch_results($result)) {

$posts[] = $row;

}

close_connection($link);

return $posts;

}

Implementação MVC do Symfony

Model LayerDatabase abstraction

Data access

View LayerView

TemplateLayout

Controller LayerFront Controller

Action

Classes Core

sfController: classe controladora. Recebe a requisição e a direciona para o Action.

sfRequest: armazena todos os elementos de uma requisição (request).

sfResponse: contém o cabeçalho e o conteúdo da resposta (response). Representa o objeto que é convertido em HTML e retornado ao usuário.

Organização de Código

Projeto: conjunto de serviços e operações disponível em um domínio, compartilhando o mesmo modelo de objetos.

Aplicações: operações lógicas, que podem ser executadas independente de outras aplicações.

Módulos: representa um grupo de páginas que possuam um propósito similar.

Organização de Código

Prática

Verificar se os requisitos necessários estão contemplados: php lib\vendor\symfony\data\bin\check_configuration.php

Verificar a versão instalada: php lib\vendor\symfony\data\bin\symfony -V

Criar o projeto myproject: php lib\vendor\symfony\data\bin\symfony generate:project

myproject

Criar uma aplicação frontend: php lib\vendor\symfony\data\bin\symfony generate:app frontend

Adicionar a configuração do host:

Prática

<VirtualHost 127.0.0.1> DocumentRoot "C:\xampp\htdocs\sfproject\web" DirectoryIndex index.php <Directory "C:\xampp\htdocs\sfproject\web"> AllowOverride All Allow from All </Directory> Alias /sf C:\xampp\htdocs\sfproject\lib\vendor\symfony\data\web\sf <Directory "C:\xampp\htdocs\sfproject\lib\vendor\symfony\data\web\

sf"> AllowOverride All Allow from All </Directory></VirtualHost>

Módulos

Módulos são grupos de páginas. Antes de criarmos as páginas, precisamos criar um módulo.

O seguinte comando automatiza a criação de módulos: php lib\vendor\symfony\data\bin\symfony generate:module

frontend content

Para cada módulo criado, uma Action principal é gerada: actions/actions.class.php

Módulos

Acesse: http://127.0.0.1/frontend_dev.php/content/index

Páginas

A lógica de execução de uma página é armazenada em uma Action, e a lógica de apresentação em um template.

Uma página sem nenhuma lógica de execução requer uma Action vazia.

Actions

Actions podem ser representadas por métodos; O nome do método deve seguir o padrão:

executeXxx()

Vamos adicionar o método abaixo na Action Class localizado em: frontend\modules\content\actions

public function executeShow(sfWebRequest $request){ }

Em seguida, acesse: http://127.0.0.1/frontend_dev.php/content/show

Actions

Actions

No Symfony, uma página é composta por uma Action e um Template.

PáginaAction

Template

Templates

Um arquivo de Template é localizado dentro do diretório /templates de um módulo.

Uma Action espera que um Template a renderize.

O padrão de nomenclatura de um arquivo de Template é: Action + Terminação (Ex.: showSuccess.php)

Exemplo do conteúdo de um template:<p>Hello, world!</p>

<?php if ($test): ?>

<p><?php echo time(); ?></p>

<?php endif; ?>

Atributos do Action para o Template

Podemos acessar atributos de uma Action Class diretamente de um template via global namespace.

Action

$this->msg = "teste";

Template

echo $msg;

Atributos do Action para o Template

<?php

class contentActions extends sfActions

{

public function executeShow(sfWebRequest $request)

{

$today = getdate();

$this->hour = $today['hours'];

$this->now = $today['hours'] . ':' . $today['minutes'];

}

}

Arquivo modules\content\actions\actions.class.php

Passando Informações do Action para o Template<p>Meu Template!</p>

<?php if ($hour >= 12): ?>

<p>Boa tarde! Agora sao:

<?php echo $now ?>.</p>

<?php endif; ?>

Arquivo modules\content\templates\showSuccess.php

Links para Actions

Podemos criar links ou realizar chamadas de Actions através dos comandos: link_to()

<?php echo link_to(‘Link aqui‘, ‘content/update?name=anonymous') ?>

url_to() <form method="post" action="<?php echo url_for('content/update') ?>">

Recuperando Parâmetros do Request

Parâmetros enviados via POST ou GET podem ser recuperados em uma Action através do método getParameter() da classe sfRequest.

public function executeSaveRegister(sfWebRequest $request)

{

$this->name = $request->getParameter('name');

}

<p>Ola, <?php echo $name; ?>!</p>

Arquivo actions\actions.class.php

Arquivo templates\saveRegisterSuccess.php

Recuperando Parâmetros do Request

Também podemos recuperar parâmetros de uma requisição

diretamente de um Template através do comando: $sf_params->get(‘parametro')

public function executeSaveRegister(sfWebRequest $request)

{

}

<p>Ola, <?php echo $sf_params->get('name') ?>!</p>

Arquivo templates/saveRegisterSuccess.php

Arquivo actions\actions.class.php

Recuperando Parâmetros do Request

Para testar a existência de um parâmetro no Template podemos utilizar o comando: $sf_params->has(‘parametro')

<?php if ($sf_params->has('name')): ?>

<p>Ola, <?php echo $sf_params->get('name') ?>!</p>

<?php else: ?>

<p>Request vazio</p>

<?php endif; ?>

Arquivo templates/saveRegisterSuccess.php

Arquivos de Configuração do Symfony

São escritos no formato YAML (YAML Ain't Markup Language). Existem vários níveis para os arquivos de configuração: projeto,

aplicação e módulos. Os valores definidos podem ser utilizados no código PHP.

Arquivos de Configuração do Symfony

Projeto (projeto/config)

Arquivo Descrição

ProjectConfiguration.class.php Classe principal do projeto que contém o endereço de instalação do framework

databases.yml Arquivo onde é armazenado as informações de conexão com o banco de dados

properties.ini Arquivo contendo alguns parâmetros a serem utilizados via linha de comando

rsync_exclude.txt Arquivo contendo os diretórios que devem ser ignorados durante a sincronização entre servidores

Arquivos de Configuração do Symfony

Aplicação - aplicação/config

Arquivo Descrição

app.yml Arquivo contendo configurações específicas da aplicação

frontendConfiguration.class.php Classe responsável por carregar as dependências e iniciar a execução da aplicação

factories.yml Arquivo que define qual classe tratará o view, o request e o response

filters.yml Arquivo contendo trechos de código que deverão ser executados a cada requisição

routing.yml Arquivo contendo as regras de roteamento de URLs

settings.yml Arquivo contendo as configurações da aplicação

view.yml Arquivo contendo as configurações da estrutura do view

security.yml Arquivo contendo as restrições de acesso

Acessando Configurações via PHP

Podemos acessar as configurações através de nossa aplicação através do método get classe sfConfig. $parameter = sfConfig::get('param_name' );

Também podemos alterar o valor de determinada configuração através do método set: sfConfig::set('param_name', $value);

Prefixos referentes ao arquivo de configuração: sf_ settings.yml app_ app.yml mod_ module.yml

Acessando Configurações via PHP

all: admin: name: Joao da Silva email: admin@teste.com mail: contact: contact@teste.com

Arquivo apps\frontend\config\app.yml

Acessando Configurações via PHP

<p>Nome do Administrador:<?php echo sfConfig::get('app_admin_name'); ?></p><p>E-mail do Admin:<?php echo sfConfig::get('app_admin_email'); ?></p<p>E-mail de Contato:<?php echo sfConfig::get('app_mail_contact'); ?></p

Arquivo modules\content\templates\getPropertiesSuccess.php

Sintaxe Alternativa Action Class

Actions podem ser separadas em arquivos diferentes, um arquivo para cada Action.

Cada Action deve extender a classe sfAction ao invés da classe sfActions. O nome do arquivo deve seguir o padrão:

actionNameAction O método da classe deve ser nomeado como:

execute

Sintaxe Alternativa Action Class

<?phpclass contentActions extends sfActions { public function executeFormCustomer(sfWebRequest $request) { } public function executeFormSupplier(sfWebRequest $request) { }} ?>

Arquivo frontend/modules/content/actions/actions.class.php

Sintaxe Alternativa Action Class

<?phpclass formCustomerAction extends sfAction{ public function execute($request) { }}?>

Arquivo frontend/modules/content/actions/formCustomerAction.class.php

Sintaxe Alternativa Action Class

<?phpclass formSupplierAction extends sfAction{ public function execute($request) { }}?>

Arquivo frontend/modules/content/actions/formSupplierAction.class.php

Sintaxe Alternativa Action Class

<fieldset> <legend>Cadastro de Clientes</legend> <form> <p> <label for="name">Nome</label> <input type="text" name="name" id="name" /> </p> <p> <label for="email">Email</label> <input type="text" name="email" id="email" /> </p> <button type="submit">Salvar</button> </form></fieldset>

Arquivo frontend/modules/content/templates/formCustomerSuccess.php

Sintaxe Alternativa Action Class

<fieldset> <legend>Cadastro de Fornecedores</legend> <form> <p> <label for="name">Nome da Empresa</label> <input type="text" name="name" id="name" /> </p> <p> <label for="email">Email</label> <input type="text" name="email" id="email" /> </p> <button type="submit">Salvar</button> </form></fieldset>

Arquivo frontend/modules/content/templates/formSupplierSuccess.php

Invocando Outra Action

Em alguns casos a execução de uma Action termina em uma requisição a outra Action.

Caso a action realize a chamada de outra action: $this->forward('Module', 'index');

Caso a action realize um redirecionamento para uma página: $this->redirect('otherModule/index'); $this->redirect('http://www.google.com/');

Invocando Outra Action

public function executeRedirect(sfWebRequest $request) { } public function executeRedirectAction(sfWebRequest $request) {

$this->redirect('content/redirect'); }

<p>P&aacute;gina com Redirect</p>

Arquivo frontend/modules/content/actions/actions.class.php

Arquivo frontend/modules/content/templates/redirectSuccess.php

Invocando Outra Action

public function executeForward(sfWebRequest $request) { } public function executeForwardAction(sfWebRequest $request) {

$this->forward('content', 'forward'); }

<p>P&aacute;gina com Forward</p>

Arquivo frontend/modules/content/actions/actions.class.php

Arquivo frontend/modules/content/templates/forwardSuccess.php

Sessão do Usuário

A sessão do usuário é gerenciada automaticamente pelo Symfony. O objeto de sessão do usuário pode ser acessado em uma action através

do método getUser() que é uma instância da classe sfUser. Para armazenar um objeto da sessão:

$this->getUser()->setAttribute('nickname', $nickname);

Para recuperar um objeto da sessão: $nickname = $this->getUser()->getAttribute('nickname', 'Anonymous');

Sessão do Usuário

public function executeForward(sfWebRequest $request) {

$this->email = $this->getUser()->getAttribute('email'); } public function executeForwardAction(sfWebRequest $request) {

$email = 'joao@teste.com'; $this->getUser()->setAttribute('email', $email); $this->forward('content', 'forward');

}

<p><?php echo $email; ?></p>Arquivo frontend/modules/content/actions/actions.class.php

Arquivo frontend/modules/content/templates/forwardSuccess.php

Sessão do Usuário

public function executeRedirect(sfWebRequest $request) {

$this->email = $this->getUser()->getAttribute('email'); } public function executeRedirectAction(sfWebRequest $request) {

$this->redirect('content/redirect'); }

<p><?php echo $email; ?></p>Arquivo frontend/modules/content/actions/actions.class.php

Arquivo frontend/modules/content/templates/redirectSuccess.php

Sessão do Usuário

Para remover um objeto da sessão: $this->getUser()->getAttributeHolder()->remove('email');

Para limpar todos os objetos da sessão: $this->getUser()->getAttributeHolder()->clear();

Sessão do Usuário

public function executeForward(sfWebRequest $request) {

$this->email = $this->getUser()->getAttribute('email'); $this->name = $this->getUser()->getAttribute('name');

} public function executeForwardAction(sfWebRequest $request) {

$email = 'joao@teste.com'; $this->getUser()->setAttribute('email', $email); $name = 'Joao da Silva'; $this->getUser()->setAttribute('name', $name); $this->forward('content', 'forward');

}

<p><?php echo $email; ?></p><p><?php echo $name; ?></p>

Arquivo frontend/modules/content/actions/actions.class.php

Arquivo frontend/modules/content/templates/forwardSuccess.php

Sessão do Usuário

public function executeRedirect(sfWebRequest $request) {

$this->email = $this->getUser()->getAttribute('email'); $this->getUser()->getAttributeHolder()->remove('email'); $this->name = $this->getUser()->getAttribute('name');

} public function executeRedirectAction(sfWebRequest $request) {

$this->redirect('content/redirect'); }

<p><?php echo $email; ?></p><p><?php echo $name; ?></p>

Arquivo frontend/modules/content/actions/actions.class.php

Arquivo frontend/modules/content/templates/redirectSuccess.php

Sessão do Usuário

Templates também podem recuperar os objetos de uma sessão através da variável $sf_user: $sf_user->getAttribute(email')

<p><?php echo $sf_user->getAttribute(email') ?></p>

Arquivo frontend/modules/content/templates/forwardSuccess.php

Flash Atributos

São atributos temporários, que desaparecem após a próxima requisição, deixando a sessão do usuário limpa.

É a maneira mais simples de passar informações para a próxima requisição. Para definir flash atributos utilizamos:

$this->getUser()->setFlash('email', $valor);

Para recuperar um flash atributos utilizamos: $this->getUser()->getFlash('email');

Flash Atributos

public function executeFlash(sfWebRequest $request) {

$this->email = $this->getUser()->getFlash('email'); } public function executeFlashAction(sfWebRequest $request) {

$email = 'joao@teste.com'; $this->getUser()->setFlash('email', $email); $this->redirect('content/flash');

}

Arquivo frontend/modules/content/actions/actions.class.php

Segurança (Restrição de Acesso)

Toda Action antes de ser executada, passa por um filtro que verifica se o usuário que esta fazendo a requisição possui privilégios para acessá-la.

O acesso a uma Action pode ser restringido através do arquivo security.yml localizado no diretório config do módulo.

Privilégios são compostos de duas partes: Usuário autenticado; Usuário com credenciais (organização da segurança em grupos).

all: is_secure: true #todas as actions exigem autenticacao

Arquivo frontend/config/security.yml

Segurança (Restrição de Acesso)

Página padrão quando o usuário não possui privilégios para acessar a Action

Segurança (Garantia de Acesso)

Para acessar uma Action restrita, o usuário precisa estar autenticado e possuir a devidas credenciais.

A definição das credenciais, pode ser realizada no arquivo securiry.yml:

confidential:

is_secure: true

credentials: admin

Arquivo frontend/config/security.yml

Segurança (Garantia de Acesso)

Algumas combinações de credenciais podem ser realizadas no arquivo securiry.yml:

editArticle:

credentials: [ admin, editor ] # admin e editor tem acesso

publishArticle:

credentials: [ admin, publisher ] # admin e publisher tem acesso

userManagement:

credentials: [[ admin, publisher ]] # admin ou publisher tem acesso

Arquivo frontend/config/security.yml

Segurança (Garantia de Acesso)

O status de autenticação do usuário pode ser alterado utilizando o método setAuthenticated(): $this->getUser()->setAuthenticated(true); $this->getUser()->setAuthenticated(false);

Segurança (Garantia de Acesso)

private function authenticationOn()

{

$user = $this->getUser();

$user->setAuthenticated(true);

}

Arquivo frontend/modules/content/actions/actions.class.php

Segurança (Garantia de Acesso)

private function authenticationOff()

{

$user = $this->getUser();

$user->setAuthenticated(false);

}

Arquivo frontend/modules/content/actions/actions.class.php

Segurança (Garantia de Acesso)

Para verificar se o usuário esta autenticado utilizamos o método isAuthenticated():

<?php if ($sf_user->isAuthenticated()): ?>

<li style="color:#060; font-weight:bold;">Usuário autenticado</li>

<?php else: ?>

<li style="color:#F00; font-weight:bold;">Usuário não autenticado</li>

<?php endif ?>

Arquivo frontend/modules/content/templates/confidentialSuccess.php

Segurança (Garantia de Acesso)

Credenciais podem ser atribuídas com o auxílio do método

addCredential() ou addCredentials() : $user->addCredential('admin');

$user->addCredentials('admin','editor');

Para remover uma credencial específica: $user->removeeCredential('admin');

Para remover todas as credenciais atribuídas: $user->clearCredential();

Segurança (Garantia de Acesso)

public function executeCreateCredentials()

{

$user = $this->getUser();

$this->authenticationOn();

$user->addCredential('admin');

$this->forward('content', 'confidential');

}

Arquivo frontend/modules/content/actions/actions.class.php

Segurança (Garantia de Acesso)

public function executeRemoveCredentials()

{

$user = $this->getUser();

$user->removeCredential('admin');

$this->authenticationOff();

$this->forward('content', 'confidential');

}

Arquivo frontend/modules/content/actions/actions.class.php

Helpers

São funções PHP responsáveis por gerar código HTML utilizados nos templates.

Produzem um ótimo HTML em termos de performance e acessibilidade.

Abaixo um exemplo de utilização:<?php echo input_tag('name') ?>

Código gerado pelo helper:<input type="text" name="name" id="name" value="" />

Helpers

Podemos criar funções helpers, conforme o exemplo abaixo:

function input_tag($name, $value = null)

{

return '<input type="text" name="'.$name.'" id="'.$name.'"value="'.$value.'" />';

}

Declaração de Helpers

Os arquivos contendo as definições dos helpers não são carregados automaticamente.

Todas as funções helpers relacionadas a texto estão definidas no arquivo TextHelper.php localizado no diretório symfony/lib/helper.

Antes de um helper poder ser utilizado ele precisa ser declarado, especificando qual o grupo de helper será utilizado:

<?php use_helper('Text') ?>

<p><?php echo auto_link('Clique aqui http://www.google.com') ?></p>

Declaração de Helpers

Vários grupos de helpers podem ser declarados de forma simultânea:

<?php use_helper('Text', ‘JavaScript') ) ?>

Declaração de Helpers

Alguns helpers estão disponíveis por padrão nos templates, sem a necessidade de serem declarados:

Grupo Descrição

Helper Necessário para a inclusão da função use_helper()

Tag Tags básicas do helper

Url Helper utilizado para links e urls

Asset Helpers utilizados para popular o <head>

Partial Helpers utilizados para a inclusão de fragmentos de templates

Cache Helpers utilizados para a manipulação de cache

Form Helpers utilizados para os elementos dos formulários

Helpers Frequentemente Utilizados

// Helper group

<?php use_helper('HelperName') ?>

// Tag group

<?php echo tag('input', 'name=foo type=text') ?> //

<?php echo content_tag('textarea', 'dummy content', 'name=foo') ?>

// Url group

<?php echo link_to('click me', 'mymodule/myaction') ?>

// Asset group

<?php echo image_tag('myimage', 'alt=foo size=200x100') ?>

<?php echo javascript_include_tag('myscript') ?>

<?php echo stylesheet_tag('style') ?>

Criando Helpers

Funções helpers devem ser criadas em um arquivo chamado FooBarHelper.php, onde FooBar é o nome do grupo do helper.

O arquivo de helper deve ser salvo no diretório: apps/frontend/lib/helper/ ou symfony/lib/helper Onde frontend é o nome da aplicação.

Criando Helpers

Funções helpers devem ser criadas em um arquivo chamado FooBarHelper.php, onde FooBar é o nome do grupo do helper.

O arquivo de helper deve ser salvo no diretório: apps/frontend/lib/helper/ ou symfony/lib/helper Onde frontend é o nome da aplicação.

Layout

O layout da página de uma aplicação é definido no arquivo layout.php (template global) localizado no diretório templates da aplicação.

O template global possui todo o HTML que é comum em todas as páginas da aplicação evitando a repetição de código nos templates.

O conteúdo de um template é integrado dentro do layout.

Layout Layout

TemplateTemplate

Página Final

+ =

Layout

<!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" xml:lang="en" lang="en">

<head>

<?php include_http_metas() ?>

<?php include_metas() ?>

<?php include_title() ?>

<link rel="shortcut icon" href="/favicon.ico" />

</head>

<body>

<?php echo $sf_content ?>

</body>

</html>

Layout padrão do arquivo apps/frontend/templates/layout.php

Layout (Atalhos nos Templates)

Algumas variáveis estão sempre acessíveis nos templates. Para acessar variáveis nos templates utilizamos os seguintes

objetos:

Objeto Descrição

$sf_context Representa o contexto da aplicação

$sf_request Representa a requisição

$sf_params Representa os parâmetros do objeto da requisição

$sf_user Representa a sessão do usuário

Layout (Fragmentos de Código)

Fragmentos devem ser utilizados para evitar a repetição de código.

Os fragmentos criados devem ficar dentro do diretório de templates da aplicação.

Para incluir o template:<?php include(sfConfig::get('sf_app_template_dir').'/myFragment.php') ?>

Layout (Partials)

Um partial é uma parte reutilizável de um código de um template localizado no diretório de templates do módulo.

O nome de um arquivo partial deve iniciar com underscore (_), o que ajuda a distinguir um partail de um template.

Article Detail Best Articles Latest Articles

Article Partial Article Partial

Article Partial

Article Partial

Article Partial

Article Partial

Reutilização de partials em um template

Layout (Partials)

//frontend/modules/mymodule/templates/_mypartial1.php partial

<?php include_partial('mypartial1') ?>

// frontend/modules/foobar/templates/_mypartial2.php partial

<?php include_partial('foobar/mypartial2') ?>

// Include the frontend/templates/_mypartial3.php partial

<?php include_partial('global/mypartial3') ?>

Inclusão de vários partials em um template

Layout (Partials)

public function executeIndex(sfWebRequest $request)

{

this->mensagem = "Vamos testar os partials...";

}

Arquivo frontend/modules/content/actions/actions.class.php

Layout (Partials)

<p><?php echo $minhaMensagem ?></p>

Arquivo frontend/modules/content/templates/_myPartial.php

Layout (Partials)

<p>Veja a mensagem do Meu Partial</p>

<?php include_partial('myPartial', array('minhaMensagem' => $mensagem)) ?>

Arquivo frontend/modules/content/templates/indexSuccess.php

Layout (Configuração da View)

Na camada de apresentação (View) o que não é HTML é considerado como sendo uma configuração.

As configurações são recomendadas quando valores não dependem do contexto ou uma query no banco de dados.

O arquivo responsável por armazenar as configurações é o view.yml localizado dentro do diretório config do módulo.

Layout (Configuração da View)

#Definicao padrao para todas as Views

default:

http_metas:

content-type: text/html

metas:

title: Meu Projeto

description: symfony project

keywords: Treinamento Symfony, Curso Symfony

language: pt-br

robots: index, follow

stylesheets: [style.css]

javascripts: []

has_layout: true

layout: layout

Arquivo frontend/config/view.yml

Layout (Configuração da View)

#Definicao padrao para a View indexSuccess

indexSuccess:

http_metas:

content-type: text/html

metas:

title: Meu Projeto

description: symfony project

keywords: Treinamento Symfony, Curso Symfony

language: pt-br

robots: index, follow

stylesheets: [style.css]

javascripts: []

has_layout: true

layout: layout

Arquivo frontend/config/view.yml

Prática (Construção de um Layout)

<!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" xml:lang="pt-br" lang="pt-br">

<head>

<?php include_http_metas() ?>

<?php include_metas() ?>

<?php include_title() ?>

<link rel="shortcut icon" href="/favicon.ico" />

<?php include_stylesheets() ?>

<?php include_javascripts() ?>

</head>

<body>

Arquivo frontend/templates/layout.php

Prática (Construção de um Layout)

<div id="container">

<div id="header">

<?php include(sfConfig::get('sf_app_template_dir').'/header.php') ?>

<!-- end #header -->

</div>

<div id="sidebar">

<?php include(sfConfig::get('sf_app_template_dir').'/sidebar.php') ?>

<!-- end #sidebar -->

</div>

<div id="mainContent"> <?php echo $sf_content ?>

<!-- end #mainContent -->

</div>

<div id="footer">

<?php include(sfConfig::get('sf_app_template_dir').'/footer.php') ?>

<!-- end #footer -->

</div>

<!-- end #container -->

</div>

</body>

</html>

Arquivo frontend/templates/layout.php

Prática (Construção de um Layout)

<h1>Header</h1>

<h3>sidebar Content</h3>

<p>Footer</p>

Arquivo frontend/templates/header.php

Arquivo frontend/templates/sidebar.php

Arquivo frontend/templates/footer.php

Prática (Construção de um Layout)

@charset "utf-8";

/* CSS Document */

body {font: 100% Verdana, Arial, Helvetica, sans-serif; margin: 0; padding: 0;text-

align: center; color: #000000; }

#container { width: 99.9%; background: #FFFFFF; margin: 0 auto; text-align: left; }

#header { background: #0CF; padding: 0 10px; }

#header h1 { margin: 0; padding: 10px 0; }

#sidebar { float: left; width: 24%; background: #6F9; padding: 15px 0; height:493px; }

#sidebar h3, #sidebar p { margin-left: 10px; margin-right: 10px; }

#mainContent { margin: 0 20px 0 26%; }

#footer { position:absolute; bottom:0; left:0; background:#FF9; width:100%; text-align:center; }

#footer p { margin: 0; padding: 10px 0; }

Arquivo sfproject/web/css/style.css

Prática (Construção de um Layout)

http://127.0.0.1/frontend_dev.php/content

Configuração do Banco de Dados

O Symfony suporta todos os banco de dados suportados pelo PDO.

As configurações do banco de dados são armazenadas no arquivo databases.yml localizado dentro do diretório config do projeto.

Para realizar a configuração de um banco de dados utilizamos a task configure:database php symfony configure:database "mysql:host=localhost;dbname=blog" blogusr blogpwd

Onde:

Host: nome do host

Dbname: nome do banco de dados

blogusr: nome do usuário do banco de dados

blogpwd: senha de acesso do usuário

Doctrine

A ferramenta ORM que utilizaremos será o Doctrine. Para visualizar as tasks disponibilizadas pelo Doctrine utilize o comando:

php symfony list doctrine

Criação do Modelo de Dados

A estrutura de dados a ser utilizada pelo Symfony pode ser

criada de duas formas:

Estrutura SQL do banco de dados baseado em um schema existente (schema.yml):

php symfony doctrine:build-sql

O arquivo schema.sql será criado dentro do

diretório data/sql

Para realizar a criação das tabelas no banco de dados

utilizaremos a task doctrine:insert-sql

php symfony doctrine:insert-sql

Criação do Modelo de Dados

Geração do modelo YAML de um banco de dados existente: php symfony doctrine:build-schema

O arquivo schema.yml será criado dentro do diretório config/doctrine

Criação do Modelo de Dados

Article:

actAs:

Timestampable:

I18n:

fields: [title, content]

columns:

author_id: integer

status:

type: enum

values: [Draft, Published]

notnull: true

title:

type: string(255)

notnull: true

content:

type: clob

notnull: true

is_on_homepage: boolean

published_at: timestamp

relations:

Author:

foreignAlias: Articles

Categories:

class: Category

refClass: ArticleCategory

foreignAlias: Articles

Arquivo config/doctrine/schema.yml

Criação do Modelo de Dados

Category:

columns:

name:

type: string(255)

notnull: true

Author:

columns:

name:

type: string(255)

notnull: true

about: string(1000)

ArticleCategory:

columns:

article_id: integer

category_id: integer

relations:

Article:

foreignAlias: ArticleCategories

Category:

foreignAlias: ArticleCategories

Arquivo config/doctrine/schema.yml

Criação do Modelo de Dados

DER representado no arquivo schema.yml

Mapeamento Tabelas em Objetos

Para gerar as classes PHP responsáveis por mapear as tabelas do banco de dados utilizamos a task: doctrine:build-model php symfony doctrine:build-model

As classes geradas serão criadas no diretório lib/model/doctrine do projeto.

Criação do Modelo de Dados (Prática)

Criar o modelo do banco de dados com base no arquivo schema.yml: php symfony doctrine:build-model

php symfony doctrine:build-sql

php symfony doctrine:insert-sql

Criação do Modelo de Dados (Prática)

Criar o schema.yml com base no banco de dados existente: php symfony doctrine:build-schema

Criação dos Forms (Prática)

Para criarmos as classes responsáveis por renderizar os formulários do modelo utilizamos a task: doctrine:build-forms

php symfony doctrine:build-forms

As classes geradas serão criadas no diretório lib/form/doctrine do projeto.

Criação dos Filters (Prática)

Para criarmos as classes responsáveis por realizar os filtros nos formulários do modelo utilizamos a task:

doctrine:build-filters php symfony doctrine:build-filters

Criação Automatizada de Classes

Todo o procedimento executado para a geração das classes de Model, Forms e Filters pode ser automatizado através da task: doctrine:build –all php symfony doctrine:build --all

Criação dos Módulos(Prática)

Para criarmos um módulo utilizando o Doctrine utilizaremos a task: doctrine:generate-module php symfony doctrine:generate-module frontend author Author

Onde:

frontend é o nome da aplicação

author é o nome do módulo

Author é o nome do modelo

Criação dos Módulos(Prática)

http://127.0.0.1/frontend_dev.php/author

Criação dos Módulos(Prática)

php symfony doctrine:generate-module frontend article Article

Onde:

frontend é o nome da aplicação

article é o nome do módulo

Article é o nome do modelo

Criação dos Módulos(Prática)

http://127.0.0.1/frontend_dev.php/article

Criação dos Módulos(Prática)

php symfony doctrine:generate-module frontend articlecategory ArticleCategory

Onde:

frontend é o nome da aplicação

articlecategory é o nome do módulo

ArticleCategory é o nome do modelo

Criação dos Módulos(Prática)

http://127.0.0.1/frontend_dev.php/articlecategory

Criação dos Módulos(Prática)

php symfony doctrine:generate-module frontend category Category

Onde:

frontend é o nome da aplicação

category é o nome do módulo

Category é o nome do modelo

Criação dos Módulos(Prática)

http://127.0.0.1/frontend_dev.php/category

Criação dos Módulos(Prática)

php symfony doctrine:generate-module frontend blogcomment BlogComment

Onde:

frontend é o nome da aplicação

blogcomment é o nome do módulo

BlogComment é o nome do modelo

Criação dos Módulos(Prática)

http://127.0.0.1/frontend_dev.php/blogcomment

Criação dos Módulos(Prática)

php symfony doctrine:generate-module frontend blogarticle BlogArticle

Onde:

frontend é o nome da aplicação

blogarticle é o nome do módulo

BlogArticle é o nome do modelo

Criação dos Módulos(Prática)

http://127.0.0.1/frontend_dev.php/blogarticle

Criação dos Módulos(Prática)

Para criarmos um módulo utilizando o Doctrine utilizaremos a task: doctrine:generate-module php symfony doctrine:generate-module frontend author Author

Onde:

frontend é o nome da aplicação

author é o nome do módulo

Author é o nome do modelo

Roteamento

É um mecanismo responsável por reescrever as URL’s tornando-as mais “amigáveis” aos usuários.

Um exemplo comum de URL:http://www.example.com/web/controller/article.php?id=123456&format_code=6532

Potencial vulnerabilidade de segurança.

Em caso de alteração toda a URL tem que ser alterada.

Roteamento

As URL’s passam a ser parte da interface, trazendo informação ao usuário.

A URL apresentada para o usuário final não é relacionada com os parâmetros esperados pela requisição. http://www.example.com/articles/finance/2006/activity-breakdown.html

URL’s podem trazer informações sobre a página, como a data de publicação.

Roteamento

O Symfony converte uma URL (Uniform Resource Locator) em uma URI (Uniform Resource Identifier).

// Sintaxe de uma URI interna

<module>/<action>[?param1=value1][&param2=value2][&param3=value3]...

// URI que nunca aparecerá para o usuário final

article/permalink?year=2006&subject=finance&title=activity-breakdown

// URL externa que aparecerá para o usuário final

http://www.example.com/articles/finance/2006/activity-breakdown.html

Roteamento

As regras de roteamento são definidas no arquivo routing.yml localizado dentro do diretório config da aplicação.

ROUTE_1:

# definition of route 1

ROUTE_2:

# definition of route 2

Exemplo de rota no arquivo frontend/config/routing.yml

Roteamento

article_by_title:

url: articles/:subject/:year/:title

param: { module: article, action: permalink }

Arquivo frontend/config/routing.yml

Roteamento

Toda requisição realizada passa pelo sistema de roteamento através do respectivo Front Controller da aplicação.

O usuário digita ou clica na seguinte URL: http://www.example.com/articles/finance/2006/activity-breakdown

O Front Controller encontrar a regra article_by_title

O sistema de roteamento cria os seguintes parâmetros para a

requisição: 'module' => 'article'

'action' => 'permalink'

'subject' => 'finance'

'year' => '2006'

'title' => 'activity-breakdown'

Roteamento

<h3>sidebar Content</h3>

<ul>

<li>

<a href="<?php echo url_for('article/permalink?subject=finance&year=2006&title=activity-breakdown') ?>">Artigos</a>

</li>

<li>

<?php echo link_to('Artigos', 'article/permalink?subject=finance&year=2006&title=activity-breakdown') ?>

</li>

</ul>

Arquivo frontend/templates/sidebar.php

Roteamento

public function executePermalink(sfWebRequest $request)

{

$this->subject = $request->getParameter('subject');

$this->year = $request->getParameter('year');

$this->title = $request->getParameter('title');

}

Arquivo article/actions/actions.class.php

Roteamento

<h1>Link Permanente</h1>

<h3>Recuperando os parametros</h3>

<?php echo $subject; ?><br>

<?php echo $year; ?><br>

<?php echo $title; ?>

Arquivo article/templates/permalinkSuccess.php

Roteamento

A regra de roteamento pode ser acessada diretamente do link criado, através do prefixo @ <?php echo link_to('Home', '@homepage') ?>

homepage:

url: /

param: { module: content, action: index }

Arquivo frontend/config/routing.yml