spaghetti php

69
Introdução ao desenvolvimento com Spaghetti* Aprenda a desenvolver com produtividade e diversão por Julio Gre e Rafael Marin

Upload: evandro-guimaraes-demuth

Post on 23-Jun-2015

628 views

Category:

Documents


1 download

DESCRIPTION

Tutorial da framework Php Spaghetti

TRANSCRIPT

Page 1: Spaghetti Php

Introdução aodesenvolvimentocom Spaghetti*Aprenda a desenvolver com

produtividade e diversão

por Julio Gre e Rafael Marin

Page 2: Spaghetti Php

Olá!Seja bem vindo ao mundo do desenvolvimento Web

divertido. Desenvolver Web já foi chato e

desmotivador. Hoje, com Spaghetti*, o seu trabalho

pode ser mais excitante a cada novo dia. Esteja você

começando no mundo do desenvolvimento, ou

começando a pensar sobre como você tem

desenvolvido ultimamente, ou ainda procurando um

framework pequeno mas totalmente extensível,

Spaghetti* é para você.

Spaghetti* é desenvolvido por pessoas que amam a

Internet, e que sobretudo pensam que ela é, na

verdade, uma rede de pessoas. O framework é

escrito e testado em projetos reais de clientes reais

com necessidades reais. Desde o início. É pouca

teoria e muita prática. É menos reunião e mais

produção. É menos projeto e mais resultado.

A Internet é um meio que muda muito. Então você,

desenvolvedor, tem à sua disposição uma ferramenta

que entende não somente o fato de que haverão

mudanças durante o processo de desenvolvimento,

mas também entende que você, como ser humano,

comete erros. Vendemos com o Spaghetti* não

apenas uma ferramenta, mas uma filosofia. Uma

filosofia de desenvolvimento produtivo e divertido,

com qualidade de código.

O Spaghetti* tem feito nosso dia melhor, e

acreditamos que ele também pode fazer o seu e de

sua equipe.

Um forte abraço da

equipe do Spaghetti*

Page 3: Spaghetti Php

Seja bem vindo!Seja bem vindo ao primeiro livro do Spaghetti*! Aqui você

pode descobrir um pouco mais sobre nosso framework, suas

características e funcionalidades. Seja uma pequena dúvida ou

uma grande curiosade, você encontrará aqui!

Além de entregar um framework de qualidade, também nos

preocupamos em mantê-lo bem documentado, para que qualquer um

possa aprender a usá-lo, e tornar seu trabalho cada vez melhor. O

resultado é essa documentação em formato de livro que, apesar de se

manter simples, é compreensiva o bastante para cobrir todos os

aspectos pertinentes do Spaghetti*.

Começando

Se você é novo no mundo do Spaghetti*, pode começar descobrindo um

pouco mais sobre este framework, o que ele faz e por que você pode

usá-lo. Mas se você já é mais experiente e sabe o que procurar, pode se

guiar pela documentação on-line, ou ainda conhecer o código-fonte do

Spaghetti* de perto.

Como obter ajuda

Caso este libro não seja suficiente, você encontra em nosso site

tutoriais e screencasts, além da documentação mais atualizada.

Page 4: Spaghetti Php

Introdução sobre MVCO Spaghetti* foi construído baseando-se no design pattern

MVC, separando as camadas da sua aplicação, tornando o

desenvolvimento e manutenção muito mais fáceis e rápidos.

Na prática, toda a camada de lógica e dados fica separada da

camada de apresentação de sua aplicação, mantendo seu

código PHP longe do código HTML, fazendo com que

designers e programadores possam trabalhar

simultaneamente de maneira harmoniosa e eficiente.

Modelos de Dados

Os modelos de dados, ou Models, representam os dados de sua

aplicação. Embora os dados geralmente venham de bancos de dados

como MySQL, SQL Server e similares, eles podem ser basicamente

qualquer coisa, desde arquivos de texto até documentos em XML. O

limite é a sua criatividade.

As classes do Spaghetti* irão auxiliá-lo na manipulação de seus dados,

sem que você precise escrever uma única linha de SQL. O Spaghetti* faz

o trabalho sujo, enquanto você se preocupa com o que realmente

interessa.

No momento, os modelos de dados do Spaghetti* funcionam apenas

com MySQL, embora o suporte a outros bancos de dados já esteja

previsto para a próxima versão. Isso também significa que, se não existir

um driver para o banco de dados que você usa, você mesmo poderá

criá-lo e compartilhar com a comunidade do Spaghetti*.

Controladores

É nos Controllers que a mágica realmente acontece. É aqui onde você irá

tratar as respostas do usuário, buscar e processar dados e retorná-los

para as Views. Nada de código HTML, nada de CSS, nada de JavaScript.

Única e puramente código PHP.

Page 5: Spaghetti Php

Mesmo você estando no comando, o Spaghetti* irá lhe auxiliar dando

acesso aos seus Models e facilitando o envio de dados para as Views.

Você se diverte programando, e o Spaghetti* o ajuda com o resto.

Visualizações

As Views fazem parte da camada de apresentação de sua aplicação.

Nessa camada você se preocupa unicamente em mostrar os dados ao

usuário, usando apenas algumas estruturas básicas em PHP, evitando

aquela típica mistura de lógica e apresentação em um mesmo arquivo.

Além disso, também é possível usar comandos para a criação fácil de

links, imagens e formulários, sem que você precise se preocupar com

detalhes chatos de implementação.

Escolhemos o MVC por ser um pattern que faz bastante sentido no

desenvolvimento Web, além de aumentar a produtividade, diminuir a

repetição de código, facilitar a correção de bugs e tornar a vida dos

desenvolvedores um pouco mais divertida. E você, está pronto para

entrar brincadeira, e se unir a nós por um desenvolvimento melhor?

Page 6: Spaghetti Php

Configurando sua aplicaçãoGigantescos arquivos de configuração? Não nesse framework.

Qualquer aplicação do Spaghetti* já está pronta para ser

desenvolvida em questão de segundos!

Configurar o Spaghetti* é realmente muito fácil. Embora algumas outras

configurações sejam possíveis, a única coisa que você necessita para ter

uma aplicação rodando é definir as configurações de seu banco de

dados.

Configurando o banco de dados

Para configurar seu banco de dados, você precisa editar o arquivo

app/config/database.php. O Spaghetti* já vem com uma configuração

de exemplo, você só precisa alterar os campos necessários, e sua

configuração ficará assim:

$database = array( "development" => array( "host" => "localhost", "user" => "username", "password" => "password", "database" => "spaghetti", "prefix" => "" ));

O Spaghetti* suporta configurações diferentes para cada ambiente de

desenvolvimento. No exemplo acima, definimos o ambiente

development, mas também podemos definir quantos mais forem

necessários. Isso evita que você sobrescreva configurações, facilitando o

deploy da aplicação.

Escolhendo o Ambiente

Para escolher o ambiente que você deseja usar, basta alterar a

configuração environment no arquivo app/config/settings.php:

Page 7: Spaghetti Php

Config::write("environment", "development");

E o que mais?

Apesar de você poder customizar um pouco mais sua aplicação, você

não precisa mais nada para começar sua aplicação. O Spaghetti* prefere

convenção em vez de configuração, e todo o resto é deduzido através da

estrutura do framework. Agora você está pronto pra começar a

trabalhar!

Page 8: Spaghetti Php

RotasURLs complicadas, sem sentido ou apenas longas demais são

um problema comum. Entretanto, com as rotas do Spaghetti*

a solução é simples e rápida, e você nem mesmo precisará

escrever mais do que algumas linhas!

Nem sempre a estrutura padrão controller/action/id é a melhor ou

mais indicada para sua aplicação. Embora faça sentido, você pode

precisar fazer suas próprias modificações nessa estrutura. Esse é o

propósito do arquivo app/config/routes.php.

Rotas Padrão

Quando você abrir o arquivo de configuração de rotas, você já

encontrará uma chamada ao método Mapper::connect(), definindo a

rota padrão de sua aplicação.

Mapper::connect("/", "/home");

A rota acima vinculará a raiz de sua aplicação com o HomeController.

Essa rota pode apontar para qualquer outro controller de sua aplicação,

mas ela é necessária pois o Spaghetti* precisa saber como proceder

quando nenhum controller é especificado na URL. Caso contrário, será

chamada a classe Controller, que é apenas uma classe base, e não um

controller propriamente dito.

Definindo novas rotas

A definição de novas rotas modificará a resposta de sua aplicação de

acordo com a URL acessada. As rotas devem ser definidas no mesmo

arquivo app/config/routes.php, pois ele é chamado antes de qualquer

processamento do Spaghetti*.

Para conectar novas rotas a determinadas URLs, utilizamos o método

Page 9: Spaghetti Php

Mapper::connect(), que deve receber dois parâmetros: o padrão a ser

comparado e a rota que esse padrão deve seguir. Ou seja, o padrão será

a URL acessada, e a rota será o caminho que essa URL terá. Com a rota

abaixo, por exemplo, a URL /posts/definindo-novas-rotas aponta

para /posts/view/definindo-novas-rotas:

Mapper::connect("/posts/:any", "/posts/view/$1");

O Mapper::connect() tem suporte a expressões regulares, tornando a

comparação ainda mais poderosa. Entretanto, para evitar que você tenha

que escrever expressões, o Spaghetti* já possui algumas strings

“mágicas” para os casos mais comuns:

:any corresponde a qualquer caracter, incluindo barras

:num corresponde a qualquer número, mas não inclui barras

:part corresponde a qualquer caracter, seja ele dígito ou número,mas não considera barras

Para recuperar essas ocorrências depois, usamos a mesma sintaxe usada

em expressões regulares: $1 retorna a primeira ocorrência, $2 retorna a

segunda ocorrência, e assim sucessivamente.

Nota: Para que expressões regulares sejam retornadas depois, é

necessário que estejam entre parênteses.

Definindo prefixos

Várias aplicações necessitam de áreas distintas dentro de sua estrutura.

Mais do que apenas controllers diferentes, às vezes se torna necessário

realizar as mesmas ações, mas por usuários com permissões diferentes.

Isso acontece quando é necessária uma seção para administração, por

exemplo.

Para esse tipo de necessidade, o Spaghetti* conta com prefixos, através

do método Mapper::prefix():

Page 10: Spaghetti Php

Mapper::prefix("admin");

Quando um prefixo é definido, o Spaghetti* passa a chamar actions

diferentes. Quando a URL /admin/users for chamada, será chamada a

action admin_index de UsersController, em vez de apenas index.

Com essas ações distintas, é possível manter níveis de permissão, além

da possibilidade de alterar o comportamento de cada ação.

Nota: Prefixos também estão sujeitos a ação de rotas, ou seja, uma

rota pode redirecionar um prefixo e causar problemas em sua

aplicação.

Caso você queira definir vários prefixos, também é possível fazê-lo com

apenas uma chamada ao método, passando vários argumentos:

Mapper::prefix("admin", "user");

Através da criação de múltiplos prefixos você pode segmentar sua

aplicação, criando várias áreas distintas, com uma estrutura flexível e

bem definida.

Page 11: Spaghetti Php

ModelsVocê não precisa escrever tanto SQL. Os modelos de dados do

Spaghetti*, além de facilitarem a iteração entre registros,

também geram todo o SQL necessário para as suas consultas,

através de arrays simples, apenas com código PHP.

Os models do Spaghetti são os responsáveis por todas as tarefas de

banco de dados. Desde criar e alterar registros até buscas complexas e

relacionamentos entre tabelas, sem escrever uma única linha de SQL.

Mas não se preocupe: caso você precise ser ainda mais específico, você

também pode digitar diretamente suas consultas.

Criando Modelos

Dentro da estrutura de arquivos do Spaghetti*, os modelos se encontram

em app/models, e seguem a convenção nome_do_modelo.php.

Basicamente, um modelo é apenas uma definição de classe vazia:

class Users extends AppModel { }

Através da extensão da classe AppModel, Users herda todos os métodos

necessários para qualquer operação de banco de dados. Além disso, o

Spaghetti* já assume que o nome da tabela do banco de dados

associada a esse modelo chama-se users. Entretanto, caso você use

nomes de tabelas diferentes dos nomes dos modelos, é possível definir

o nome manualmente através da variável table.

class Users extends AppModel {public $table = "users_table";

}

Buscando Registros

Page 12: Spaghetti Php

findAll( mixed $conditions, mixed $order, string $limit,

integer $recursion )

mixed$conditions

Array ou string contendo as condições para abusca

mixed $orderArray ou string que define a ordenação dosregistros

string $limit Limite de registros a serem recuperados

integer$recursion

Número de recursões para tabelas relacionadas

O método Model::findAll() retorna todos os registros que obedeçam à

condição $conditions especificada, ordenados por $order, limitando a

$limit registros.

O parâmetro $conditions pode ser uma string SQL qualquer, como

username = "admin" ou text LIKE "%spaghetti%". Entretanto, você

não estaria usando de todo o potencial do Spaghetti*. Através de arrays,

é possível criar uma gama enorme de condições diferentes.

$conditions = array( "username" => "admin", "text LIKE" => "%spaghetti%");

// equivalente a // username = "admin" AND text LIKE "%spaghetti%"

$this->Users->findAll($conditions);

Além de consultas simples como as usadas acima, o Spaghetti* também

permite condições mais complexas, como você pode descobrir em

Condições Complexas.

A ordenação de registros funciona de maneira semelhante, utilizando

strings ou arrays. Arrays seguem a seguinte estrutura:

$order = array("id" => "ASC", "date" => "DESC");

Page 13: Spaghetti Php

O retorno do método é um array contendo vários outros arrays, tendo

como chaves os nomes dos campos, pronto para uso em blocos for e

foreach, como qualquer outro array.

Array( [0] => Array ( [id] => 1 [name] => admin, [password] => spaghettiphp ) [1] => Array ( [id] => 2 [name] => root, [password] => root ) [2] => Array ( [id] => 3 [name] => user [password] => 123456 ))

find( mixed $conditions, mixed $order, integer

$recursion )

mixed$conditions

Array ou string contendo as condições para abusca

mixed $orderArray ou string que define a ordenação dosregistros

integer$recursion

Número de recursões para tabelas relacionadas

O método Model::find() funciona exatamente como Model::findAll(),

exceto por retornar apenas o primeiro registro que obedeça às

condições passadas. A estrutura do array também é ligeiramente

diferente, sendo unidimensional:

Array(

Page 14: Spaghetti Php

[id] => 1, [username] => admin [password] => spaghettiphp)

findAllBy( string $field, string $value, mixed $conditions,

mixed $order, string $limit, integer $recursion )

string $field Campo a ser utilizado como condicional

string $value Valor usado como condição para o campo

mixed$conditions

Array ou string contendo condições adicionaispara a busca

mixed $orderArray ou string que define a ordenação dosregistros

string $limit Limite de registros a serem recuperados

integer$recursion

Número de recursões para tabelas relacionadas

Model::findAllBy() busca todos os registros em que $field seja igual a

$value, usando $conditions como parâmetros adicionais. Seu retorno

é idêntico a Model::findAll(). Esse método é útil quando se quer usar

apenas um campo como condição para a busca:

$this->Users->findAllBy("level", "admin");

Apesar do propósito da função ser a busca por apenas um campo, é

possível adicionar outros campos como condições adicionais, tornando a

busca um pouco mais específica:

$this->Users->findAllBy("level", "user", array("approved" => true));

Também é possível utilizar um atalho para essa função,

Model::findAllBy<field>(), onde $field é definido no próprio nome da

função, e suprimido da lista de argumentos. Assim, $value se torna o

primeiro argumento.

Page 15: Spaghetti Php

$this->Users->findAllByLevel("user", array("approved" => true));

findBy( string $field, string $value, mixed $conditions,

mixed $order, integer $recursion )

string $field Campo a ser utilizado como condicional

string $value Valor usado como condição para o campo

mixed$conditions

Array ou string contendo condições adicionaispara a busca

mixed $orderArray ou string que define a ordenação dosregistros

integer$recursion

Número de recursões para tabelas relacionadas

Model::findBy() funciona como Model::findAllBy(), exceto por

retornar apenas o primeiro item encontrado, em um array

unidimensional.

Assim como Model::findAllBy(), também aceita o atalho

Model::findAllBy<field>():

$this->Users->findAllById(1);

Salvando Registros

save( array $data )

array $data Dados a serem salvos

O salvamento de registros é sempre algo complicado. Primeiro é

necessário saber se um registro existe, para depois podermos decidir se

ele deve ser inserido ou se deve ser apenas atualizado. Com o

Spaghetti*, você se preocupa apenas em enviar os dados, e o resto é

trabalho do framework.

Page 16: Spaghetti Php

Para que o Spaghetti* possa salvar corretamente os dados, o array $data

deve ser construído assim:

Array( [id] => 1, [username] => admin [password] => spaghettiphp)

Caso algum campo não seja passado, ele não será considerado na

consulta SQL, ou seja, ele permanecerá intacto na tabela, caso exista. Se

você passar algum campo inexistente, ele será completamente

desconsiderado, então não é necessário se preocupar em limpar arrays

vindos de formulários.

Para que o modelo possa descobrir se o registro já existe na tabela, é

necessário que seja passado o campo id. É realizada uma busca na

tabela, e caso outro registro com mesma identificação já exista, ele é

atualizado. Caso contrário, ele é criado. Tudo isso na mesma função,

sem você precisar se preocupar.

Quando estiver usando Model::save() dentro de loops, não esqueça

de usar Model->create() para evitar que os dados sejam

sobrescritos.

created e modified

Muitas vezes é necessário manter registro das datas de criação e

modificação de um registro. Para que você não precise explicitamente

definir valor para esses campos, o Spaghetti* faz isso para você.

Para que esse comportamento seja usado, é necessário ter os campos

created ou modied definidos como DATETIME em sua tabela. O campo

created é definido apenas uma vez, na criação do registro, e somente

caso não tenha um valor já definido em $data. Já o campo modified é

redefinido a cada salvamento do registro, também somente caso não

esteja definido em $data.

Page 17: Spaghetti Php

Prevenção contra SQL Injection

Também somos preocupados com segurança. Por isso, toda e qualquer

string usada como valor é passada pelo método Model::escape(),

escapando qualquer caracter que possa ser perigoso caso esteja em uma

consulta SQL. E não se preocupe com magic_quotes, o modelo já faz a

verificação e elimina barras quando necessário.

Caso você precise fazer consultas de maneira manual, ou precise

escapar qualquer string dentro da aplicação, basta usar essa mesma

função.

$this->Users->escape("String 'potencialmente' perigosa");// Retorna "String \'potencialmente\' perigosa"

saveAll( array $data )

array $data Dados a serem salvos

Caso você precise salvar vários registros de uma só vez, o Spaghetti* lhe

dá a opção do método Model::saveAll(). Ele dispõe de todas as

funcionalidades de Model::save(), com exceção do parâmetro

recebido. Esse parâmetro deve ser um array com a seguinte estrutura:

Array( [0] => Array ( [id] => 1 [name] => admin, [password] => spaghettiphp ) [1] => Array ( [id] => 2 [name] => root, [password] => root ) [2] => Array ( [id] => 3 [name] => user [password] => 123456

Page 18: Spaghetti Php

))

Apagando Registros

delete( integer $id )

integer $id ID do registro a ser apagado

Model::delete() apaga apenas um registro com ID $id da tabela.

Como ele é limitado a apenas um registro, mesmo que existam vários

IDs iguais, apenas o primeiro será apagado.

deleteAll( mixed $conditions, mixed $order, integer

$limit )

mixed$conditions

Array ou string contendo as condições para queum registro seja apagado

mixed $orderArray ou string que define a ordenação dosregistros a serem apagados

integer $limit Limite de registros apagados

Model::deleteAll() faz a remoção de vários registros de uma única

vez, apagando registros que obedeçam às condições $conditions,

ordenados por $order e limitados por $limit.

Esse método é útil quando é necessário apagar vários registros, que não

obedeçam apenas a IDs, como usuários não aprovados ou mensagens de

spam.

$this->Users->deleteAll(array("approved" => false));

Métodos Personalizados

Os modelos de dados do Spaghetti* são poderosos o suficiente para

prover todas as funcionalidades básicas que você precisa para

desenvolver sua aplicação sem se preocupar com detalhes como

Page 19: Spaghetti Php

escrever SQL. Entretanto, você pode precisar de um pouco mais.

Não esqueça que as classes de modelo podem ser estendidas: basta

você adicionar métodos e propriedades! Qualquer função repetitiva

relacionada a banco de dados deve ser escrita aqui. Depois, você poderá

usá-la em qualquer controller que use esse modelo. DRY, tudo definido

em um lugar só!

class Posts extends AppModel { public function findLastPosts() { return $this->findAll(array("created <" => "curda te()"), array("created" => "DESC")); }}

O método Posts::findLastPost(), depois de definido, pode ser

utilizado normalmente dentro de um controller.

$this->Posts->findLastPosts();

Page 20: Spaghetti Php

Relacionamentos entreModelsOs relacionamentos entre modelos são uma das

características mais poderosas do Spaghetti*. Através deles, é

possível mapear as associações entre tabelas, tornando mais

fácil o trabalho com dados relacionados.

A necessidade de relacionamentos é suficientemente óbvia, e

naturalmente definida. Por exemplo, uma postagem em um blog

pertence a uma categoria, enquanto esse mesmo post possui vários

comentários. Através dessa definição, é possível acessar registros

relacionados entre si, retornando-os em apenas uma consulta.

Tipos de Relacionamentos

Até a versão atual, o Spaghetti* trabalha com 3 tipos diferentes de

associações: um para um, um para muitos e muitos para um.

Tipo deRelacionamento

Relacionamento Exemplos

hasOne Um para umUm usuário possui umperfil

hasMany Um para muitosUm usuário possui váriosposts

belongsTo Muitos para umUm usuário pertence a umgrupo de usuários

Para que os relacionamentos funcionem corretamente é preciso que, em

uma das duas tabelas, exista um campo de chave estrangeira. Suponha

que exista um modelo Posts e um modelo Usuarios, e que vários posts

pertençam a um usuário. Nesse caso, é necessário que na tabela posts

exista um campo users_id para servir como chave estrangeira.

hasOne

Page 21: Spaghetti Php

Uma associação hasOne existe quando um registro pode ter apenas um

registro correspondente na tabela relacionada. Esse tipo de

relacionamento acontece, principalmente, entre tabelas de usuários e

tabelas de perfis.

Para definir o relacionamento um para um em um modelo, é preciso

definir a variável hasOne, com um array contendo todos os outros

modelos relacionados:

class Users extends AppModel {public $hasOne = array("Profiles");

}

Nota: Para relacionamentos hasOne, uma das tabelas deve ter a chave

estrangeira correspondente. Em nosso caso, Profiles deveria possuir

o campo users_id.

Através desse relacionamento, é possível retornar todas as informações

de um usuário, com apenas uma chamada ao método

Users::findAll(), por exemplo.

$this->Users->findAll();

Através da consulta acima, é retornado um array com a seguinte

estrutura:

Array( [0] => Array ( [id] => 1 [name] => admin, [password] => spaghettiphp [profiles] => Array ( [id] => 1 [users_id] => 1

Page 22: Spaghetti Php

[realname] => Administrador do Site ) ) [1] => Array ( [id] => 2 [name] => root, [password] => root [profiles] => Array ( [id] => 2 [users_id] => 2 [realname] => Super Usuário ) ) [2] => Array ( [id] => 3 [name] => user [password] => 123456 [profiles] => Array ( [id] => 3 [users_id] => 3 [realname] => Usuário Comum ) ))

hasMany

Um relacionamento um para muitos, assim como seu inverso, é um dos

mais comuns. Ele acontece quando um registro em determinada tabela

possui mais de um registro correspondente em outra tabela. Por

exemplo, um usuário pode ter vários posts, ou um post pode ter vários

comentários.

Para definir um relacionamento um para muitos, é preciso declarar a

variável hasMany no modelo de dados.

class Users extends AppModel {public $hasMany = array("Posts");

}

Assim como em hasOne, também é possível acessar os registros

correspondentes através de métodos como Model::findAll().

Entretanto, por padrão o Spaghetti* retorna apenas os dados de

Page 23: Spaghetti Php

relacionamentos belongsTo e hasOne, para evitar a sobrecarga de seu

banco de dados. Para retornar registros de hasMany, é necessário passar

o parâmetro $recursion:

$this->Users->findAll(array(), null, null, 1);

O array retornado é apenas ligeiramente diferente do retornado por

hasOne:

Array( [0] => Array ( [id] => 1 [name] => admin, [password] => spaghettiphp [posts] => Array ( [0] => Array ( [id] => 1 [users_id] => 1 [title] => Meu Primeiro Post ) ) ) [1] => Array ( [id] => 2 [name] => root, [password] => root [posts] => Array ( [0] => Array ( [id] => 2 [users_id] => 2 [title] => Esse é outro. ) [1] => Array ( [id] => 3 [users_id] => 2 [title] => Mais um post meu =P ) ) ))

Page 24: Spaghetti Php

Nota: nesse caso, a chave estrangeira deve estar presente apenas no

modelo relacionado, e não naquele em que se descreve o

relacionamento.

belongsTo

Relacionamentos muitos para um são exatamento o inverso de

relacionamentos um para muitos. Embora não seja necessário, acontece

em qualquer lado oposto de um relacionamento hasMany. Acontece

quando um post pertence a um usuário, ou quando um post pertence a

uma categoria.

Para descrever um relacionamento muitos para um, é necessário definir

a variável belongsTo no modelo desejado:

class Comments extends AppModel {public $belongsTo = array("Posts");

}

Nota: em relacionamentos belongsTo, a chave estrangeira deve estar

presente apenas na tabela em que se descreve o relacionamento, e

não no modelo relacionado, justamente o contrário de

relacionamentos hasMany

Definindo Recursão

O Spaghetti* define uma recursão padrão para seus modelos, para que

você não precise se preocupar com sobrecarga em seu servidor de

banco de dados. Entretanto, muitas vezes é necessário definir uma

recursão maior, ou mesmo menor. É possível modificar essa recursão

padrão através da variável $recursion, definida na classe dos modelos

de dados.

class Users extends AppModel {public $recursion = 1;

Page 25: Spaghetti Php

}

Caso esse número de recursões seja compartilhado entre todos os

modelos de sua aplicação, você pode criar o modelo AppModel em

app/models/app.php, e definir a mesma variável.

class AppModel extends Model { // aqui estendemos Model em vez de AppModel!public $recursion = 1;

}

O valor da recursão pode variar dependendo de sua necessidade. Os

valores possíves variam desde -1 até qualquer número positivo.

Recursão Dados retornados

-1 Nenhum registro relacionado é retornado.

0São retornados apenas os registros relacionadosdiretamente por hasOne e belongsTo

1São retornados todos os registros relacionadosdiretamente pelo modelo, incluindo hasMany

n > 2Além dos registros relacionados diretamente, retorna nníveis de recursão

Não é necessário definir níveis de recursão maiores do que o necessário.

Isso pode diminuir a velocidade de sua aplicação, assim como causar

sobrecarga em seu servidor. Use com responsabilidade!

Definindo atributos para relacionamentos

O Spaghetti*, além de lhe prover várias convenções, também consegue

trabalhar muito bem sobre configuração. Você pode ter várias opções

para definir melhor seus relacionamentos.

Para definir as opções de relacionamentos, é necessário modificar um

pouco como os relacionamentos são definidos. Em vez de apenas um

array numerado, é necessário nomeá-lo, da seguinte maneira:

Page 26: Spaghetti Php

public $hasMany = array("assocName" => array("option" =>"value"));

className determina o nome da classe do modelo relacionado.Assim, é possível definir qualquer nome para a associação, sem que aassociação pare de funcionar.

foreignKey determina o nome da chave estrangeira. Como oSpaghetti* ainda não conta com singularização/pluralização, vocêpode definir manualmente um nome no singular, ou mesmo qualqueroutro nome, para a chave.

conditions é um array ou string de condições. Somente os registrosque obedeçam a essa condição serão adicionados à associação.

Page 27: Spaghetti Php

Condições ComplexasArrays simples não dão conta de suas necessidades de SQL?

Tudo bem, o Spaghetti* ainda lhe dá mais poder na hora de

gerenciar suas consultas.

Com o Spaghetti*, a escrita de consultas SQL é tão rara que você

dificilmente se deparará com elas, a menos em casos bem específicos.

Com o uso de arrays, é possível criar condições facilmente, de leitura e

manutenção extremamente simples.

Basicamente, um array de condições contém pares de chaves e valores

definindo cada declaração. A condição abaixo, por exemplo, encontrará

registros em que title é igual a Hello World.

$conditions = array("title" => "Hello World");

É tão simples que você esquecerá que um dia precisou escrever SQL.

Mas isso não é tudo, é possível mais! Para adicionar outras declarações à

condição, basta adicionar outro item ao array.

$conditions = array("id" => "3", "title" => "Hello World");

Agora vamos a outros tipos de comparações. E se você estiver

procurando um registro no qual o título NÃO seja Hello World?

$conditions = array("title <>" => "Hello World");

Usando o operador SQL <>, o Spaghetti* encontrará registros em que o

título seja diferente de Hello World. Além desse operador, você pode

usar qualquer outro operador SQL válido, como >, < e LIKE, e o

Spaghetti* o reconhecerá e montará a consulta.

Page 28: Spaghetti Php

Para que o operador SQL seja reconhecido como tal, é necessário que

ele esteja separado do nome do campo por um espaço.

Além de comparações com um valor, também é possível usar

comparações com um conjunto de valores, como em uma consulta IN:

$conditions = array("title" => array("Primeiro Post", "Segundo Post", "Terceiro Post"));

Esse mesmo princípio funciona com diferentes campos em uma mesma

condição OR:

$conditions = array(array("id" => 3, "title" => "HelloWorld"));

Consultas BETWEEN também são criadas facilmente, basta adicionar o

operador BETWEEN juntamente com o nome do campo.

$conditions = array("id BETWEEN" => array(1, 15));

Embora o Spaghetti* cuide do trabalho sujo para você, algumas vezes é

necessário sujar as mãos e escrever SQL diretamente. Para isso, você só

precisa passar uma string como parâmetro.

$conditions = "id = 1 AND title = 'Hello World'";

Nota: em consultas manuais, os valores não são escapados pelo

Spaghetti*. Nunca confie em dados vindos do usuário, e sempre use

Model::escape() para fazer o escape de valores.

Page 29: Spaghetti Php

ControllersÉ nos controllers onde tudo acontece. Aqui você começa a

programar de verdade, e a usar de todo o poder do

Spaghetti*.

Os controllers trabalham com toda a lógica da aplicação. Tarefas como o

processamento de dados vindos do usuário, a busca de registros no

banco de dados através dos models e a passagem dos dados para as

views.

Geralmente, controllers são associados a um único modelo. Para facilitar

seu trabalho, o Spaghetti* já associa por padrão seu controller com um

model de mesmo nome, sem necessitar de nenhuma configuração.

Criando Controllers

Para criarmos um controller, é preciso definir a classe

<nome>Controller, e salvá-la em app/controllers

/<nome>_controller.php. Também é necessário estender a classe

AppController, para que todos os métodos necessários sejam

herdados, e sua aplicação funcione corretamente.

class PostsController extends AppController { }

A partir de agora, a URL /posts já está disponível, embora retorne um

erro dizendo que a action ainda não existe. Precisamos resolver isso!

Criando Actions

Actions nada mais são do que métodos dentro de uma classe de

controller. Cada action corresponde a uma ação diferente de sua

aplicação. Ações podem ser o envio de um e-mail, o cadastro de um

usuário, a postagem de um artigo, entre qualquer outra coisa.

Page 30: Spaghetti Php

Para que sua aplicação funcione, é necessária a criação de actions e suas

respectivas views. Vamos criar uma action simples, para gerar uma lista

de posts:

class PostsController extends AppController { public function index() { $this->set("posts", $this->Posts->findAll()); }}

A primeira coisa que devemos saber para podermos interagir entre

controllers e views é como se faz a passagem de variáveis. Para isso,

usa-se o método Controller::set, passando como parâmetros o

nome da variável e seu respectivo valor. Dentro da view, essa variável

estará disponível como uma variável local comum, acessível por $posts,

no nosso caso.

Você também pode notar que o modelo de dados já está disponível em

$this->Posts. Através desse objeto, é possível acessar todas as

propriedades do model Posts (que já deve existir em app/models

/posts.php).

A partir de agora, se a view já tiver sido criada em app/views/posts

/index.phtm, você já poderá ver o resultado em /posts. Como

nenhuma action é passada pela URL, o Spaghetti* supõe que esta seja

index. Qualquer outra action pode ser acessada através da estrutura

/controller/action.

Recebendo parâmetros

Diferente de páginas PHP comuns, os parâmetros no Spaghetti* não são

passados através de query strings, como ?id=1&page=2. Eles são

passados como parte da URL, com cada parâmetro gerando uma URL

diferente. O parâmetro mais usado é um número de identificação de um

registro, para que ele possa ser identificado no banco de dados. Quando

esse ID é passado como terceira parte da URL, ele já é identificado e

enviado para o controller.

Page 31: Spaghetti Php

Para que uma action possa receber parâmetros, é necessário definí-los

na função. Em uma ação de visualização de posts, pode-se fazer assim:

public function view($id = null) { $this->set("post", $this->Posts->findById($id));}

É recomendável que todo parâmetro tenha um valor padrão. Caso

contrário, se esse parâmetro não for passado, o PHP disparará um erro,

quebrando sua aplicação.

Além do ID, é possível passar qualquer outro parâmetro, bastando

adicionar mais partes na URL. Esse parâmetros são passados

sequencialmente para a action. Para receber os parâmetro passados pela

URL /posts/view/1/hello-world, nossa action precisaria mudar para:

public function view($id = null, $slug = "") { $this->set("post", $this->Posts->find(array("id" => $id, "slug" => $slug)));}

Nota: mesmo quando não estiver presente na URL, o ID é passado

como um valor nulo para a action. Caso você esteja usando

parâmetros textuais, é necessário definir o primeiro parâmetro

mesmo assim.

Recebendo Dados do Usuário

Além de receber parâmetros como ID, também é necessário receber os

dados enviados pelo usuário através do método POST. Assim que o

usuário envia uma requisição a partir de um formulário, todos os dados

de $_POST ficam disponíveis através da variável Controller::data.

Quando esses dados são recebidos, eles já estão prontos para serem

usados em qualquer consulta Model::save(), bastando passá-los como

parâmetro.

Page 32: Spaghetti Php

public function add() { if(!empty($this->data)): $this->Posts->save($this->data); endif;}

E lembre-se: a menos que seja definido um campo de nome id, o ID

passado como parâmetro na URL não é passado para

Controller::data, sendo necessário definí-lo manualmente.

public funcion edit($id = null) { if(!empty($this->data)): $this->data["id"] = $id; $this->Posts->save($this->data); endif;}

Modelos, Helpers e Componentes

Por padrão, o Spaghetti* já vincula seu controller com um modelo de

mesmo nome. Entretanto, você pode precisar usar um modelo diferente

em determinados controllers, ou mesmo usar vários modelos dentro de

um mesmo controller. Para isso, o Spaghetti* usa a variável uses.

class UsersController extends AppController { public $uses = array("Users", "Profiles");}

Nota: Não é necessário incluir modelos relacionados caso eles não

sejam usados diretamente, o Spaghetti* já se encarrega disso!

Caso você não deseje utilizar modelo algum em seu controller, basta

definir essa variável como um array vazio:

class UsersController extends AppController { public $uses = array();

Page 33: Spaghetti Php

}

Os componentes e helpers desejados também devem ser incluídos no

controller, através de suas respectivas variáveis components e helpers,

assim como na definição de modelos.

class UsersController extends AppController { public $uses = array("Users", "Profiles"); public $components = array("Auth"); public $helpers = array("Html", "Form", "Date");}

A menos que você deseje incluir outros helpers, não é necessário definir

Html e Form, já que eles são herdados de AppController.

Usando Layouts

Fazendo o uso de layouts, você economiza código HTML, gerando todo

o esqueleto da página apenas uma vez. Por padrão, o Spaghetti*

renderiza o layout default, que se encontra em app/layouts

/default.phtm. Entretanto, é possível escolher qualquer outro layout

disponível em sua aplicação através da variável layout.

class HomeController extends AppController { public $layout = "home";}

Muitas vezes um layout não é necessário, e você deseja que o Spaghetti*

não renderize nenhum. Nesse caso, é possível definir o valor da variável

como false e pronto!

Também usado geralmente nos layouts, o título da página também pode

ser definido pelo controller. Para tal, define-se a variável pageTitle,

com um texto qualquer que você queira ver no título.

class HomeController extends AppController {

Page 34: Spaghetti Php

public $pageTitle = "Minha Aplicação com Spaghetti*";}

Essa variável também é recebida como uma variável local, tanto em

views quanto em layouts. Você pode imprimí-la onde desejar, seja na

tag <title>, em tags <h1>, ou onde mais se fizer necessário.

Redirecionamentos

Após uma ação, geralmente após editar ou apagar algum registro,

geralmente acontece um redirecionamento da aplicação. Os controllers

do Spaghetti* já herdam o método Controller::redirect() para esse

propósito. Basta definir a URL para a qual se deseja redirecionar.

$this->redirect("/home");

Como o redirecionamento é feito através de um header HTTP, também é

possível adicionar mais um header indicando o status da requisição.

Basta passar como segundo parâmetro o número do status, e o

Spaghetti* se encarrega de definir o header apropriado:

$this->redirect("/home", 404);// gerando um erro 404 – página não encontrada

Além de redirecionamentos HTTP, o Spaghetti* também suporta que

você redirecione uma ação para outra do mesmo controller. Isso é feito

através do método Controller::setAction(), passando o nome da

ação como parâmetro. Qualquer outro parâmetro será passado

diretamente para a action definida.

Esse método é bastante útil para evitar a criação de várias views para

ações semelhantes, como adicionar e editar registros, por exemplo.

public function add() { $this->setAction("edit");

Page 35: Spaghetti Php

}public function edit($id = null) { if(!empty($this->data)): $this->data["id"] = $id; $this->Posts->save($this->data); endif;}

Callbacks

Os callbacks são funções executadas em determinados momentos da

execução do Spaghetti*, como antes da execução de uma ação do

controller ou antes da renderização de uma view.

Callback Momento da execução

beforeFilter Antes da execução da action

beforeRenderDepois da execução da action, mas antes darenderização da view

afterFilter Após execução da action e renderização da view

Esse callbacks podem ser usados para executar qualquer coisa que você

precise para seus controllers. Para definí-los, basta criar sua função

correspondente na classe de controller.

class HomeController extends AppController { public function beforeFilter() {

$this->AuthComponent->check();}

}

AppController

AppController é o controller base para todos os outros controllers na

aplicação. Isso significa que todo e qualquer método ou atributo que for

definido dentro dessa classe estará disponível para todos os outros

controllers da aplicação.

O uso dessa herança é muito útil no uso de callbacks, quando é

necessário que eles sejam executados em todas as partes da aplicação.

Page 36: Spaghetti Php

O componente AuthComponent, por exemplo requer que o método

check seja executado em todas as partes da aplicação.

Por padrão, o Spaghetti* usa o AppController da biblioteca padrão.

Entretanto, você pode criar o arquivo app/controllers

/app_controller.php, e então o Spaghetti* passará a usá-lo para

estender todos os outros controllers de sua aplicação.

Page 37: Spaghetti Php

ViewsE chegamos à camada apresentacional do paradigma MVC: as

Views. Uma view é, geralmente, um arquivo HTML com pouca

ou nenhuma programação que serve para exibir na tela o

conteúdo que você desejar para uma action.

Enquanto dentro de um controller você desenvolve toda a lógica de

programação do seu sistema, utilizando modelos de acesso a dados e

outros componentes, em uma view você determina qual conteúdo será

exibido em uma determinada action.

No geral, pouco código PHP é escrito dentro de uma view, apenas as

estruturas básicas necessárias para manipular o conteúdo já mastigado

que você deve enviar a partir do controller. Existem quatro tipos básicos

de views:

Views estáticas1.

Views dinâmicas2.

Layouts3.

Elements4.

Views estáticas

As views estáticas são o tipo de view mais simples. Uma view estática

não recebe nenhum tipo de informação de um controller, logo, você

pode criar views estáticas sem precisar criar um controller. Por exemplo,

se você quiser criar uma página “Sobre Nós”, que em termos gerais não

demanda nenhum tipo de programação, apenas HTML simples, não faz

sentido criar um controller SobreNosController.

Então, para que você consiga acessar esta página através da URL

/sobre-nos/, por exemplo, você deve criar uma pasta sobre-nos no

diretório app/views/, e dentro dela criar um arquivo index.phtm.

Você pode, seguindo os mesmos princípios de funcionamento dos

controllers, criar sub-páginas estáticas. Se você quiser criar uma página

Page 38: Spaghetti Php

no endereço /sobre-nos/equipe, deve criar dentro daquela mesma

pasta app/views/sobre-nos o arquivo equipe.phtm.

Nota: o que faz uma view ser estática é o fato de não possuir código

PHP embutido. Porém, elas seguem exatamente as convenções das

views comuns, como a estrutura nos diretórios, extensão de arquivos,

etc.

Views dinâmicas

Ao contrário das views estáticas, as dinâmicas são aquelas onde você

utiliza código PHP em meio ao HTML. Desta maneira, torna-se

obrigatória a presença de um controller. Como descreve o padrão MVC,

a camada Controller é a responsável por manipular dados e pela lógica

de programação, apenas passando para a camada View o conteúdo já

digerido, pronto para ser apresentado na tela.

Por isso, em uma view dinâmica você irá, geralmente, receber apenas

variáveis enviadas pelo seu controller contendo strings ou arrays, e tudo

o que você precisará utilizar de código PHP dentro delas servirá para

imprimir o conteúdo destas variáveis na tela. Desta maneira, em sua

view você utiliza apenas estruturas básicas do PHP, como if, for e

foreach, apenas com esta lógica de apresentação da página.

Manipulando as variáveis enviadas pelo controller

Você receberá variáveis vindas do controller de maneira normal, como as

variáveis padrão do PHP. Se, por exemplo, você definir uma variável no

seu controller, conforme o exemplo:

$this->set("fruits", array("lemon","orange","apple","grape"));

Você então, em sua view, receberá uma variável $fruits, contendo

exatamente o mesmo array passado como segundo parâmetro do

método set do Controller. Se, por exemplo, quiser transformar este

array em uma lista não ordenada, pode utilizar a estrutura de controle

Page 39: Spaghetti Php

foreach, de acordo com o exemplo abaixo:

<ul><?php foreach($fruits as $fruit): ?> <li><?php echo $fruit; ?></li><?php endforeach; ?></ul>

Layouts

Os layouts servem para englobar o conteúdo de uma view – geralmente

para adicionar a navegação geral do site, topo, menus e rodapé.

Elements

Os elements, por sua vez, são views que guardam trechos de código que

você utiliza com freqüência em várias partes diferentes de sua aplicação,

para que você possa utilizar o mesmo código várias vezes sem ter que

reescrevê-lo e sem copiar e colar.

Page 40: Spaghetti Php

LayoutsOs layouts fazem parte da camada de View da sua aplicação.

Geralmente compõem toda a parte apresentacional que

envolve uma view. Em um layout você geralmente inclui sua

marca, os menus de navegação, rodapé, entre outros.

Os layouts possuem um comportamento bastante semelhante ao das

outras views: são arquivos HTML mas, se necessário, você pode usar

estruturas simples de PHP, como laços de repetição. Contudo, eles não

possuem um controller-pai, pois são compartilhados geralmente entre

uma aplicação inteira.

O arquivo de layout padrão da sua aplicação Spaghetti* é o arquivo

app/layouts/default.phtm, mas você pode criar quantos layouts

diferentes você achar necessário.

Recebendo o conteúdo de uma view

Se você sobrescrever o layout padrão, montando uma estrutura

semelhante à seguinte, por exemplo:

<html><head> <title>My Page</title></head>

<body> <h1>Welcome to My Page</h1></body></html>

Você, no exemplo acima, terá uma página apenas com um cabeçalho

“Welcome to My Page”, porém perceberá que o conteúdo da view que

você pretendia exibir não aparece neste documento HTML. Acontece que

você precisa incluir uma variável convencionada chamada

$content_for_layout no local onde você deseja exibir o conteúdo de

sua view dentro deste layout, conforme o exemplo que segue:

Page 41: Spaghetti Php

<html><head> <title>My Page</title></head><body> <h1>Welcome to My Page</h1> <?php echo $content_for_layout; ?></body></html>

No exemplo acima, portanto, além do cabeçalho “Welcome to My Page”,

o conteúdo da view solicitada será impresso logo em seguida.

Criando layouts e escolhendo qual utilizar

Se você possuir uma página de login em seu sistema, provavelmente

optará por escrever um layout próprio para esta página, livre dos

elementos de navegação presentes em todo o restante do sistema. Para

tal, você precisa criar um novo layout na pasta app/layouts/ com o

nome do arquivo que você desejar.

Então, deve entrar no controller onde deseja alterar o layout, e incluir

em seu controller a seguinte atribuição:

public $layout = "login";

No exemplo acima, quando alguma action do controller onde a variável

$layout foi atribuída for chamada, o Spaghetti* procurará pelo arquivo

login.phtm na pasta app/layouts/. Você pode também definir um

layout específico para uma action, sem precisar afetar todo as outras

actions de um mesmo controller. Para tal, adicione a seguinte atribuição

dentro da __action desejada:

$this->layout = "login";

Neste caso, apenas a action onde a atribuição acima foi feita é que será

afetada pelo layout escolhido, neste caso app/layouts/login.phtm.

Page 42: Spaghetti Php

Alterando o layout padrão da aplicação

Conforme dito anteriormente, o layout padrão da sua aplicação é

app/layouts/default.phtm. Porém, caso prefira utilizar outro arquivo,

pode alterar o layout padrão definindo-o no AppController de sua

aplicação, que encontra-se em app/controllers

/app_controller.php, adicionando a seguinte atribuição à classe

AppController:

<?phpclass AppController extends Controller { public $layout = "login";}?>

Neste caso, a aplicação toda será afetada e o layout login.phtm.

Usando helpers nos layouts

Você pode utilizar todos os helpers disponíveis para suas views em seus

layouts, contanto que estes helpers tenham sido definidos dentro do

controller atual. Para evitar que algum helper não seja incluído por

acidente, é uma boa dica carregar os helpers de sua aplicação no

AppController, ao invés de carregá-lo em cada controller que criar.

Definindo um título para a página

Há uma maneira de definir o conteúdo da tag <title> de maneira a não

criar código com gambiarras. De modo semelhante à variável

$content_for_layout, há uma variável chamada $this->pageTitle,

definida dentro de um controller ou action (à sua escolha), onde você

pode especificar o conteúdo da tag <title> que será exibido em

qualquer lugar do documento HTML.

Para exibir o conteúdo da variável $this->pageTitle em seu layout,

escreva seu conteúdo dentro da tag <title>, como no exemplo:

Page 43: Spaghetti Php

<title><?php echo $this->pageTitle; ?></title>

E para definir o conteúdo da variável $this->pageTitle, faça uma

atribuição normal dentro do controller ou action desejado, como nos

respectivos exemplos que seguem:

public $pageTitle = "Page Title Goes Here";

$this->pageTitle = "Page Title Goes Here";

Page 44: Spaghetti Php

ElementsPor muitas vezes você ocupa pequenos trechos de código em

várias páginas, porém estes trechos não fazem parte de um

layout. Não se repita, utilize elements. Elementos são views

que servem apenas nestas ocasiões.

Quer um exemplo? Você pode ter um formulário de login ao topo da

página e um no meio do conteúdo. Vai copiar e colar código? E quando

for necessário fazer manutenção? É trabalho dobrado para você. Se você

criar um element, tudo o que você precisará fazer é escrever o trecho de

código uma única vez, e então chamá-lo sempre que necessário.

Criando um element

A criação é muito simples. Crie um arquivo com o nome desejado para

seu element, com a extensão .phtm, logo na pasta app/views/, sem

colocar em nenhuma subpasta. No início do nome do arquivo deve

constar um caracter underscore (_), para sinalizar que aquele arquivo é

um element. Veja o exemplo abaixo:

app/views/_formulario_de_login.phtm

Quando você quiser incluir o conteúdo deste element em alguma outra

view, seja ela estática, dinâmica ou um layout, basta utilizar o método

$this->element(), passando como parâmetro o nome do elemento sem o

underscore nem a extensão do arquivo:

<?php echo $this->element("formulario_de_login"); ?>

E pronto. O conteúdo do elemento será renderizado tantas vezes quanto

for chamado, e nos lugares onde for chamado.

Passando parâmetros para elements

Page 45: Spaghetti Php

Hora ou outra você pode precisar passar conteúdo dinâmico para um

element. Por exemplo, você pode criar um element para armazenar um

elemento <select> com a lista dos estados nacionais. Este elemento de

formulário seria utilizado em diferentes formulários no seu site.

Porém, você pode querer passar para este campo de formulário qual é o

estado que deve estar selecionado, baseado no estado onde o usuário

logado mora. Sem elements, além de manter diversos formulários por

todo o site, você teria que reescrever código e a cada manutenção, bom,

você já sabe.

Para passar variáveis para um element, ao usar o método

$this->element() você pode passar como segundo parâmetro um

array, onde a chave de um item é o nome da variável e seu valor é o

conteúdo da variável, como no exemplo:

$options = array( "selectedState" => "SP");echo $this->element("formulario_dos_estados", $options);

E então, dentro do element você possui condições de manipular esta

variável, chamando-a pelo nome.

<?php echo $selectedState; ?>

Elements são um instrumento bastante interessante de manter o código

reaproveitável e de mais fácil manutenção. Use sem moderação ;D

Page 46: Spaghetti Php

HelpersHelpers são classes semelhante aos componentes, porém são

exclusivas para as views e para a lógica presentacional

compartilhada entre views, layouts e elements. Nestas classes

você encontra funções que tornam o seu desenvolvimento

client-side mais rápido e fácil.

Dois helpers vêm habilitados por padrão na instalação do Spaghetti*: um

para HTML e outro para formulários.

Utilizando os helpers

Conforme dito acima, você só poderá usar as funções de um helper

dentro de uma view, layout ou element. Para mais informações sobre

como utilizar cada helper, consulte as documentações específicas ao

lado.

Criando seu próprio helper

Para criar um helper, crie um arquivo nome_do_helper_helper.php na

pasta app/helpers/. Por exemplo, se fôssemos criar um helper

chamado Number, ele seria o arquivo app/helpers

/number_helper.php, e dentro dele haveria a classe NumberHelper que

estende a classe Helper.

Como os helpers são específicos para as views, você não conseguirá

ter acesso a modelos de dados de dentro deles.

Carregando um helper

Você precisa então chamar este helper no controller onde você pretende

usá-lo. Caso queira usar um helper com toda a aplicação, carregue-o

dentro do AppController, localizado em app/controllers

/app_controller.php, adicionando a seguinte variável de instância à

Page 47: Spaghetti Php

classe:

public $helpers = array("Number");

Continuando no exemplo, neste caso carregaríamos no controller o

helper Number. Porém é importante ressaltar que, definindo o array com

apenas Number, os outro helpers embutidos no Spaghetti* não serão

mais carregados, pois você está sobrescrendo a chamada padrão. Para

continuar a carregar os helpers padrão do Spaghetti, adicione a variável

de classe desta maneira:

public $helpers = array("Html", "Form", "Number");

Agora seu helper já está pronto para ser usado nas views do seu

controller (ou da aplicação inteira, caso tenha incluído o helper no

AppController).

Usando o helper na view

Se o seu helper se chamar Number, logo ele estará acessível em uma

view através da variável $number, como no exemplo abaixo:

<h1>My Blog</h1><?php echo $number->ceil(2.0324); ?>

A chamada acima procurará pelo helper Number e pelo seu método

ceil(), que pode ser escrito assim:

<?php class NumberHelper extends Helper { public function ceil($number = null) { $numeroArredondado = ceil($number); $this->output($numeroArredondado); }} ?>

Page 48: Spaghetti Php

Repare que para passar a saída da função você utiliza o método

$this->output() passando como parâmetro o conteúdo que você

deseja retornar.

Page 49: Spaghetti Php

HTML HelperO helper HTML agiliza a criação de alguns dos elementos que

mais tomam tempo, como os chamados para CSS e JavaScript,

criação de links a e inserção de imagens img.

O helper HTML vem carregado por padrão na sua aplicação Spaghetti*, e

portanto é acessível de qualquer view utilizando a variável $html.

Inserindo links para outras páginas

$html->link( string $value, string $url, array $attributes

)

string $value String contendo o conteúdo do link

string $url String contendo a URL do link

array $attributes Array contendo atributos do elemento a

Para gerar links internos basta escrever a URL iniciando pela barra (/),

passando esta URL normalmente como segundo parâmetro do método

$html->link(). O helper gerará o endereço completo para você.

<?php echo $html->link("Adicionar Recado", "/recados/ adicionar"); ?>

// Gerará o seguinte:// <a href="/recados/adicionar">Recados</a>

Criando links para páginas externas

Para gerar links externos basta escrever a URL normalmente como

segundo parâmetro do método $html->link():

<?php echo $html->link("Google", "http://www.google.com .br"); ?>

// Gerará o seguinte:

Page 50: Spaghetti Php

// <a href="http://www.google.com.br">Google</a>

Passando atributos para o elemento a

Você pode definir todos os atributos disponíveis passando-os como

itens de array no terceiro parâmetro do método $html->link():

<?php echo $html->link("Google", "http://www.google.com .br", array("class"=>"google-link")); ?>

// Gerará o seguinte:// <a href="http://www.google.com.br" class="google-link" >Google</a>

Criando links em imagens

Além disso, se quiser gerar um link em uma imagem, pode também

utilizar o método $html->image() do helper HTML para gerar a tag

img, conforme o exemplo abaixo:

<?php echo $html->link( $html->image("btadicionar.gif", "Adicionar Recado") , "/recados/adicionar"); ?>

// Gerará o seguinte:// <a href="/recados/adicionar"><img src=/images/botao_ adicionar.gif" alt="Adicionar Recado" /></a>

Criando links com URLs completas

Por fim, caso precise gerar URL’s completas em seus links, defina o

quarto parâmetro do método $html->link() como true.

<?php echo $html->link("Apagar Página", "/paginas/apagar" , array(), true); ?>

// Gerará o seguinte: // <a href="http://suaapp.com/pagina/apagar">Apagar</a>

Inserindo imagens na sua página

$html->image( string $url, string $alt, array $attributes )

Page 51: Spaghetti Php

string $url String contendo a URL da imagem

string $altString contendo o texto do atributo alt (conteúdoalternativo) da imagem

array$attributes

Array contendo atributos do elemento img

O exemplo abaixo mostra como inserir uma imagem no documento

HTML.

<?php echo $html->image("natal/foto01.jpg", "Foto de Natal"); ?>

// Gerará o seguinte:// <img src="http://www.suaaplicacao.com/images/natal/ foto01.jpg" alt="Foto de Natal" />

Nota: O diretório base das imagens é app/webroot/images/. Por

exemplo, se a imagem logo.gif estiver logo na raiz da pasta

app/webroot/images/, você deve passar como URL da imagem

apenas logo.gif, pois o helper se encarregará de completar o

endereço automaticamente.

Inserindo imagens hospedadas externamente

Para inserir imagens hospedadas em endereços externos, tudo o que

você precisa fazer é informar a URL completa da imagem, como mostra

o exemplo abaixo.

<?php echo $html->image("http://google.com/coruja.gif", "Coruja"); ?>

// Gerará o seguinte:// <img src="http://google.com/coruja.gif" alt="Coruja" />

Passando mais atributos para a imagem

Se precisar inserir mais atributos HTML em sua imagem, passe como

terceiro parâmetro do método $html->image() um array contendo os

atributos desejados, como no exemplo abaixo.

Page 52: Spaghetti Php

<?php echo $html->image("/papagaio.gif", "Papagaio", array("class"=>"foto")); ?>

// Gerará o seguinte:// <img src="/images/papagaio.gif" alt="Papagaio" class= "foto" />

Insira CSS em sua página

$html->stylesheet( mixed $url, array $attributes,

boolean $full )

mixed $urlString contendo a URL do arquivo CSS ou Array,caso sejam várias folhas de estilo

array$attributes

Array contendo atributos do elemento style

boolean $full Se true, passa a URL inteira como atributo href

O seguinte exemplo gerará um elemento style chamando um arquivo

CSS.

<?php echo $html->stylesheet("default.css"); ?>

// Gerará o seguinte: // <link href="/styles/default.css" rel="stylesheet" type="text/css" />

Nota: O diretório base dos arquivos CSS é app/webroot/styles/,

então quando você utilizar o helper HTML para incluir seus arquivos

CSS, a URL da folha de estilos deve ser relativa a este diretório.

Inserindo estilos hospedados em um servidor externo

Para incluir um CSS hospedado em outro servidor, apenas informe a URL

completa, como no exemplo que segue:

<?php echo $html->stylesheet("http://www.google.com/

Page 53: Spaghetti Php

default.css"); ?>

// Gerará o seguinte: // <link href="http://www.google.com/default.css" rel= "stylesheet" type="text/css" />

Inserindo múltiplos estilos de uma vez

Seguindo os princípios de DRY, passar uma nova instrução nova para

cada folha de estilo a ser inserida é desperdício de tempo. Por isso, se

você precisar incluir várias folhas de estilo, pode passar um array de

URLs como primeiro parâmetro do método $html->stylesheet(),

como no exemplo abaixo:

<?php echo $html->stylesheet(array("default.css", "home.css" ,"form.css")); ?>

// Gerará o seguinte: // <link href="/styles/default.css" rel="stylesheet" type="text/css" />

// <link href="/styles/home.css" rel="stylesheet" type= "text/css" />

// <link href="/styles/form.css" rel="stylesheet" type= "text/css" />

Passando atributos para a tag style

Se você precisar passar parâmetros para a tag style, pode fazê-lo

passando um array de argumentos como segundo parâmetro do método

$html->stylesheet(), seguindo o exemplo abaixo:

<?php echo $html->stylesheet("default.css", array( "media"=>"handheld")); ?>

// Gerará o seguinte: // <link href="/styles/default.css" rel="stylesheet" type="text/css" media="handheld" />

Chamando folhas de estilo com URLs completas

Por fim, caso precise gerar URL’s completas em suas tags style, defina

o terceiro parâmetro do método $html->stylesheet() como true.

Page 54: Spaghetti Php

<?php echo $html->stylesheet("default.css", array(), true ); ?>

// Gerará o seguinte: // <link href="http://suaapp.com/styles/default.css" rel="stylesheet" type="text/css" />

Inserindo arquivos JavaScript na página

$html->script(mixed $src, array $attributes, array

$full )

mixed $urlString contendo a URL do arquivo Javascript ouArray, caso sejam vários arquivos

array$attributes

Array contendo atributos do elemento script

boolean $full Se true, passa a URL inteira como atributo src

O seguinte trecho de código gerará um elemento script chamando um

arquivo .js.

<?php echo $html->script("default.js"); ?>

// Gerará o seguinte: // <script src="/scripts/default.js" type="text/javascript"></script>

Nota: O diretório base dos arquivos JavaScript é app/webroot

/scripts/, então quando você utilizar o helper HTML para incluir

seus arquivos JavaScript, a URL do arquivo deve ser relativa a este

diretório.

Inserindo arquivos de script hospedados em um servidor externo

Para incluir um arquivo JavaScript hospedado em outro servidor, apenas

informe a URL completa, como no exemplo que segue:

Page 55: Spaghetti Php

<?php echo $html->script("http://www.google.com/defa ult.js"); ?>

// Gerará o seguinte: // <script src="http://www.google.com/default.js" type="text/javascript"></script>

Inserindo múltiplos arquivos JavaScript de uma vez

Seguindo os princípios de DRY, passar uma nova instrução nova para

cada arquivo de script a ser inserido é desperdício de tempo. Por isso, se

você precisar incluir vários arquivosp, pode passar um array de URLs

como primeiro parâmetro do método $html->script() como no

exemplo abaixo:

<?php echo $html->script(array("default.js", "jquery.js")); ?>

// Gerará o seguinte: // <script src="/scripts/default.js" type="text/javascript"> </script>// <script src="/scripts/jquery.js" type="text/javascript"> </script>

Passando atributos para a tag script

Se você precisar passar parâmetros para a tag script, pode fazê-lo

passando um array de argumentos como segundo parâmetro do método

$html->script() seguindo o exemplo abaixo:

<?php echo $html->script("default.js", array("defer" => "defer")); ?>

// Gerará o seguinte: // <script src="/scripts/default.js" type="text/javascript" defer="defer"></script>

Chamando arquivos de script com URLs completas

Por fim, caso precise gerar URL’s completas em suas tags script, defina

o terceiro parâmetro do método $html->script() como true.

Page 56: Spaghetti Php

<?php echo $html->script("default.js", null, true) ; ?>

// Gerará o seguinte: // <script src="http://suaapp.com/scripts/default.js" type="text/javascript" />

Page 57: Spaghetti Php

Form HelperO Form Helper é o helper que torna a criação de formulários

em HTML um pouco menos trabalhosa. Embora ainda esteja

em um estágio inicial de desenvolvimento, já provém as

funcionalidades básicas para agilizar a escrita de formulários.

O helper Form já vem instalado e habilitado por padrão em sua

instalação do Spaghetti*. Portanto, a partir de qualquer view, pode

acessar os métodos disponíveis através da variável $form.

Criando um formulário novo

$form->create( string $action, array $attributes )

string $actionString opcional indicando a URL de ação doformulário

array$attributes

Array opcional de atributos da tag form

Se você utilizar o método $form->create() sem passar qualquer

parâmetro, a tag padrão será criada, apontando a ação para a URL atual.

<?php echo $form->create(); ?>

// Gerará o seguinte:// <form action="http://suaapp.com/url_atual_da_pagina" method="post">

Especificando uma URL de ação para o formulário

Para especificar a URL para onde o formulário deverá ser enviado, você

precisa apenas passar esta URL como primeiro parâmetro do método

$form->create().

<?php echo $form->create("http://suaapp.com/enviar"); ?>

Page 58: Spaghetti Php

// Gerará o seguinte:// <form action="http://suaapp.com/enviar" method="post">

Passando outros atributos para a tag form

Caso você ainda precise passar outros atributos para a tag de abertura

do formulário, como por exemplo alterar o método de envio de POST

para GET, pode fazê-lo passando um array de argumentos como

segundo parâmetro do método $form->create().

<?php echo $form->create(null, array("method"=>"get")); ?>

// Gerará o seguinte:// <form action="http://suaapp.com/url_atual_da_pagina" method="get">

Adicionando campos ao seu formulário

Você pode criar todas as tags de um formulário utilizando o método

$form->input(), seguindo a seqüência de parâmetros abaixo. Você

pode passar, no parâmetro $options, um array contendo todos os

atributos disponíveis para o elemento em questão.

$form->input( string $name, string $value, array

$options )

string $nameNome do campo de formulário que você desejacriar

string $value Valor opcional do campo de formulário

array$options

Array de opções e atributos do campo

Criando campos de texto (text)

<?php echo $form->input("nome", "João da Silva", array( "type"=>"text", "id"=>"seuNome")); ?>

// Gerará o seguinte:// <input type="text" name="nome" value="João da Silva"

Page 59: Spaghetti Php

id="seuNome" />

Criando caixas de texto (textarea)

<?php echo $form->input("biografia", "Nasci em São Paulo." , array("type"=>"textarea", "id"=>"suaBiografia")); ?>

// Gerará o seguinte:// <textarea name="nome" id="suaBiografia">Nasci em São Paulo.</ textarea>

Criando campos de senha (password)

<?php echo $form->input("senha", null, array("type"=> "password", "id"=>"suaSenha")); ?>

// Gerará o seguinte:// <input type="password" name="senha" id="suaSenha" />

Criando caixas de seleção (select)

<?php echo $form->input("estado", "rj", array("type"=> "select", "options" => array("rj"=>"Rio de Janeiro", "sp" => "São Paulo") )); ?>

// Gerará o seguinte:// <select name="estado">// <option name="rj" selected="selected">Rio</option>// <option name="sp">São Paulo</option>// </select>

Nota: Neste caso, você passa como segundo parâmetro do método

$form->input() a chave do campo que deve estar selecionado por

padrão dentro do select.

Criando campos de arquivo (file)

<?php echo $form->input("foto", null, array("type"=>"file") ); ?>

// Gerará o seguinte:// <input type="file" name="foto" />

Page 60: Spaghetti Php

Nota: Sempre que você for fazer upload de arquivos, deve acrescentar

à tag de abertura do formulário o atributo enctype com o valor

multipart/form-data.

Finalizando e enviando o formulário

Você geralmente coloca seu botão de envio de formulários logo antes do

término do mesmo. Por esse motivo, você pode usar o mesmo método

de encerramento do formulário para gerar – de maneira fácil – o botão

de envio.

$form->close( string $buttonValue, array $attributes )

string$buttonValue

Nome do botão de envio, caso você queirautilizá-lo

array $attributes Array de atributos do botão de envio

Passando apenas o método, sem qualquer parâmetro, você apenas

encerra o formulário com a tag </code>.

<?php echo $form->close(); ?>

// Gerará o seguinte:// </form>

Agora, passando também um parâmetro, você gerará um input button

antes do encerramento do formulário.

<?php echo $form->close("Enviar"); ?>

// Gerará o seguinte:// <input type="submit" name="Enviar" />// </form>

Se você ainda precisar de outros atributos em seu botão, pode passar

como segundo parâmetro do método $form->close() um array

contendo estes atributos.

Page 61: Spaghetti Php

<?php echo $form->close("Enviar", array( "id"=>"submitButton")); ?>

// Gerará o seguinte:// <input type="submit" name="Enviar" id="submitButton" />// </form>

Criando labels para os campos

É importante rotular seus campos, e usando o elemento label você

torna esta rotulagem ainda mais semântica. Você não precisa chamar

métodos adicionais para rotular um campo, apenas deve incluir um

atributo no array de atributos do elemento que você deseja rotular.

<?php echo $form->input("company", null, array( "type"=>"text", "id"=>"myCompany", "label"=>"Sua Empresa")); ?>

// Gerará o seguinte:// <label for="myCompany">Sua Empresa// <input type="text" name="company" id="myCompany" />// </label>

Page 62: Spaghetti Php

ComponentsVocê já viu essa história antes: você começa um projeto,

programa uma solução, começa um novo projeto, programa

novamente a mesma solução. Components são extensões

auto-suficientes, plug and play, para que você não se

incomode mais com tarefas repetitivas.

Os exemplos mais clássicos incluem envio de e-mails, upload de

arquivos e autenticação de usuários. Estamos sempre desenvolvendo

novos componentes para nossos próprios problemas, e então

compartilhamos eles aqui.

Instalando um componente

Não há segredos quanto a instalação de um novo componente em sua

aplicação. Quando você baixa um componente, extraia o arquivo ZIP e

copie o arquivo PHP para a pasta app/components/. E é isso. Já está

instalado.

Um componente, entretanto, embora esteja instalado não é ativado por

padrão. Isso quer dizer que você precisa informar quando deseja usar

um componente dentro de um controlador. Para tal, adicione a variável

de instância em seu controller conforme o exemplo abaixo:

public $components = array("NomeDoComponente");

Você pode ainda carregar vários componentes dentro de um controller

passando vários itens dentro do array:

public $components = array("NomeDoComponente1", "Nome do Componente2");

Utilizando o componente

Page 63: Spaghetti Php

Vamos supor que você tenha carregado um componente chamado

Upload em seu controlador Fotos. Para que você tenha acesso às

funcionalidades dentro do controller Fotos, a instância do objeto Upload

fica gravada em $this->UploadComponent.

Por exemplo, caso você precise utilizar o método upload() deste

componente, você o faria dentro de uma action da seguinte maneira:

$this->UploadComponent->upload()

Nota: Lembre-se sempre que cada componente possui seus próprios

métodos e próprio funcionamento. O exemplo acima meramente

ilustra como carregar, instanciar e utilizar os métodos de um

componente.

Escrevendo seus próprios componentes

Um componente basicamente é composto por uma classe, chamada de

NomeDoComponenteComponent, que estende a classe Component. O

arquivo deve ser chamado, neste exemplo,

nome_do_componente_component.php, e deve estar na pasta de

componentes da sua aplicação em app/components/.

Um objeto da classe do seu componente será instanciado

automaticamente sempre que um controller solicitar. Por tanto, pelo fato

de se tratar de um processo automático, não há como passar

parâmetros para o construtor de sua classe. Isso significa que, se você

precisar atribuir valores às variáveis de instância, deve fazê-lo dentro do

controlador, conforme o exemplo:

$person = $this->PersonComponent;$person->name = "Roberto";$person->age = 32;

Page 64: Spaghetti Php

AuthComponentA autenticação de usuários é algo comum a maioria das

aplicações hoje em dia. Pensando nisso, o Spaghetti* já traz o

componente AuthComponent em seu núcleo, pronto para ser

usado!

O uso do AuthComponent é extremamente simples, e sua configuração

requer apenas algumas linhas. Em poucos minutos você já tem um

sistema de autenticação de usuários simples funcionando.

Para usar o AuthComponent, primeiro é preciso ativá-lo nos controllers

em que você deseja usá-lo. Como geralmente a autenticação se aplica a

vários controllers dentro da aplicação, é recomendável definí-lo

diretamente no AppController.

class AppController extends Controller {public $components = array("Auth");

}

Assim que o componente é ativado, ele se torna disponível dentro do

controller através de $this->AuthComponent. Assim, podemos começar

a utilizar seus métodos.

Criando o modelo de usuários

O AuthComponent já espera que você possua um modelo Users, e sua

respectiva tabela com, no mínimo, os campos username e password.

Caso seja necessário mudar essas opções, você precisa definir isso

dentro do controller, no callback beforeFilter().

class AppController extends Controller {public $components = array("Auth");public function beforeFilter() {

Page 65: Spaghetti Php

// definindo o modelo de usuários$this->AuthComponent->userModel = "AppUsers";// definindo os campos de nome de usuário e senha$this->AuthComponent->fields = array(

"username" => "name","password" => "passphrase"

);}

}

Ações de Login e Logout

Para que possamos fazer a autenticação do usuário, é necessário

criarmos as actions para login e logout. AuthComponent, por padrão,

redireciona o usuário para /users/login e /users/logout. Então, em

um controller Users, devemos criar essas duas ações.

class UsersController extends AppController {public function login() {

$this->AuthComponent->login();}public function logout() {

$this->AuthComponent->logout();}

}

Assim que essas duas ações são chamadas, é necessário disparar os

métodos da classe AuthComponent, login() e logout(). São essas

duas funções que farão a verificação, autenticação e desautenticação do

usuário. Embora essas funções cuidem da parte difícil, você ainda

precisa criar a view de login.

<?php echo $form->create(); ?><?php echo $form->input("username"); // deve ser o mesmo nome definido em // AuthComponent::fields["username"] ?><?php echo $form->input("password"); // deve ser o mesmo nome definido em // AuthComponent::fields["password"] ?><?php echo $form->close("Entrar"); ?>

Checando o usuário e permitindo acesso

Page 66: Spaghetti Php

Para que possamos checar se o usuário está autenticado, precisamos

adicionar uma chamada ao método AuthComponent::check() no

callback beforeFilter() do controller. Esse método checa se o usuário

está autenticado, e faz o redirecionamento para a tela de login, quando

necessário.

public function beforeFilter() {$this->AuthComponent->check();

}

Mesmo assim, o usuário ainda tem acesso a todos os recursos da

aplicação, por padrão o componente permite acesso a toda a aplicação.

As permissões podem ser definidas aos níveis de prefixo, controller e

action, e são definidas através dos métodos allow e deny.

public function beforeFilter() {$this->AuthComponent->check();$this->AuthComponent->deny("*");// nega acesso a toda página que não possuir um prefixo$this->AuthComponent->allow(array("controller" => "users", "action" => "register"));$this->AuthComponent->allow(array("prefix" => "public"));

}

Às vezes, também é preciso verificar se um usuário está aprovado para

efetuar login, ou se ele pertence a determinado grupo de usuários.

Nesse caso, usa-se o atributo userScope, que provê condições

adicionais para a verificação.

public function beforeFilter() {$this->AuthComponent->check();$this->AuthComponent->deny("*");$this->AuthComponent->userScope = array("approved" => true, "group <>" => "banned");

}

Recuperando dados do usuário

Dentro da aplicação, também pode se fazer necessária a recuperação de

Page 67: Spaghetti Php

dados do usuário, para poder usá-los na identificação de registros.

Sempre que for necessária a utilização de alguma informação do usuário

na aplicação, usa-se o método AuthComponent::user(), passando

como parâmetro o campo que se deseja retornar.

$this->AuthComponent->user("id"); // retornará o id do usuário

Encriptando Senhas

Não é seguro, e nem considerado uma boa prática, manter as senhas

dos usuários sem nenhum tipo de criptografia. O AuthComponent usa

hashes MD5, que são um tipo de criptografia de apenas uma via, para

armazenar senhas. Isso significa que uma vez que uma senha for

criptografada, não há maneira de convertê-la de volta, apenas criar uma

nova senha. Assim, toda senha em seu banco de dados deve seguir esse

padrão.

Para que você não precise usar diretamente a função md5(), o

AuthComponent já possui o método hashPasswords(). Ele recebe um

parâmetro provindo de Controller::data, e criptografa o campo

definido como campo de senha por

AuthComponent->fields["password"].

Variáveis para personalização

Caso alguma das configurações padrão do AuthComponent seja

diferente das suas necessidades, é possível personalizá-lo de forma que

lhe atenda melhor. As variáveis configuráveis são:

Variável Função

loginActionURL para a qual o usuário será redirecionado quandonão estiver autenticado

loginRedirectURL para qual o usuário será redirecionado quandoefetuar login

Page 68: Spaghetti Php

logoutRedirectURL para a qual o usuário será redirecionado quandoefetuar logout

Page 69: Spaghetti Php

Próximasetapas

Pois é, acredite se quiser: você chegou ao fim

do livro. Estamos felizes pelo seu interesse em

aprender mais sobre o Spaghetti* e sobre como

tornar seu trabalho mais divertido e produtivo.

Neste ponto você deve estar pronto para fazer

sua primeira aplicação, fazendo o uso de todos

os conceitos e conhecimentos adquiridos

durante a leitura deste livro.

Acima de tudo, independente de qual

framework ou linguagem você vá utilizar daqui

em diante, parabenizamos você por optar

desenvolver Web do jeito certo. Agradecemos

pela oportunidade que você nos deu de

conhecer o nosso trabalho, e ficaremos ainda

mais contentes se você utilizar o Spaghetti* em

algum projeto.

A partir de agora, se você tiver interesse, pode

continuar acompanhando a evolução e as

novidades que virão através do site,

http://spaghettiphp.org. Lá você sempre

encontrará a documentação mais atual,

screencasts, tutoriais e o Trac - onde está o

repositório de versões de todo o código escrito

para o projeto.

Saúde e prosperidade para você e sua equipe, e

divirta-se com Spaghetti*!

Publicado em 1 de janeiro de 2009

E-mail de contato:

[email protected]

Este documento está licenciado sobre a Licença Creative Atribuição-Compartilhamento pela mesma

Licença 2.5 Brasil Commons, disponível em http://creativecommons.org/licenses/by-sa/2.5/br

/legalcode.