<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Jonnas Fonini</title>
	<atom:link href="http://www.fonini.net/blog/feed" rel="self" type="application/rss+xml" />
	<link>http://www.fonini.net/blog</link>
	<description></description>
	<lastBuildDate>Tue, 27 Dec 2011 15:38:31 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.1</generator>
		<item>
		<title>&#8220;Doritos&#8221; na URL de logout do Google</title>
		<link>http://www.fonini.net/blog/doritos-na-url-de-logout-do-google</link>
		<comments>http://www.fonini.net/blog/doritos-na-url-de-logout-do-google#comments</comments>
		<pubDate>Tue, 27 Dec 2011 15:38:31 +0000</pubDate>
		<dc:creator>fonini</dc:creator>
				<category><![CDATA[Geral]]></category>
		<category><![CDATA[Easter Egg]]></category>

		<guid isPermaLink="false">http://www.fonini.net/blog/?p=318</guid>
		<description><![CDATA[Há algum tempo atrás pensei estar vendo coisas. Uma dessas coisas me pareceu ser a palavra "doritos" na URL de logout do Google. Mas o logout acontece tão rápido que nunca consegui tirar um print pra confirmar. E outra, não é sempre que aparece. Hoje pela manhã consegui! Veja na imagem abaixo: Repito: não é [...]]]></description>
			<content:encoded><![CDATA[<p>Há algum tempo atrás pensei estar vendo coisas. Uma dessas coisas me pareceu ser a palavra "doritos" na URL de logout do Google. Mas o logout acontece tão rápido que nunca consegui tirar um print pra confirmar. E outra, não é sempre que aparece. Hoje pela manhã consegui! Veja na imagem abaixo:</p>
<p><a href="http://www.fonini.net/blog/wp-content/uploads/2011/12/google-doritos-url-get-param.png"><img class="alignnone  wp-image-319" title="google-doritos-url-get-param" src="http://www.fonini.net/blog/wp-content/uploads/2011/12/google-doritos-url-get-param.png" alt="FINALMENTE CAPTUREI O PRINT!" width="813" height="27" /></a></p>
<p>Repito: não é sempre que aparece.</p>
<p>Segundo o Bruno Bemfica (<a href="http://twitter.com/ubuntroll">@ubuntroll</a>), é  porque o Google não gosta de cookies e prefere usar Doritos em suas páginas.</p>
<p>Abraço e bom final de ano!</p>
]]></content:encoded>
			<wfw:commentRss>http://www.fonini.net/blog/doritos-na-url-de-logout-do-google/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>HTTPRequest, classe PHP para retornar conteúdo remoto em servidores sem cURL</title>
		<link>http://www.fonini.net/blog/httprequest-classe-php-para-retornar-conteudo-remoto-em-servidores-sem-curl</link>
		<comments>http://www.fonini.net/blog/httprequest-classe-php-para-retornar-conteudo-remoto-em-servidores-sem-curl#comments</comments>
		<pubDate>Tue, 01 Mar 2011 19:49:14 +0000</pubDate>
		<dc:creator>fonini</dc:creator>
				<category><![CDATA[Web]]></category>
		<category><![CDATA[PHP]]></category>

		<guid isPermaLink="false">http://www.fonini.net/blog/?p=130</guid>
		<description><![CDATA[Ataquei de freelancer recentemente, tendo que desenvolver um site. O cliente já havia contratado um popular provedor de acesso à internet da região para hospedar o site. Nada além do apocalipse poderia acontecer. Vou explicar. Os provedores da região na qual resido deveriam se preocupar um pouco mais em oferecer acesso de qualidade e deixar [...]]]></description>
			<content:encoded><![CDATA[<p>
	Ataquei de freelancer recentemente, tendo que desenvolver um site. O cliente já havia contratado um popular provedor de acesso à internet da região para hospedar o site. Nada além do apocalipse poderia acontecer. Vou explicar. Os provedores da região na qual resido deveriam se preocupar um pouco mais em oferecer acesso de qualidade e deixar o ramo de hospedagem de aplicações web para quem realmente entende. O maldito servidor estava simplesmente "pelado", extensões importantes faltando e metade dos recursos úteis desabilitados.</p>
<p>
	Aonde já se viu um servidor sem cURL? Pois é, ainda fiz uma última tentativa para obter conteúdo remoto (previsão do tempo, infelizmente ainda é uma triste realidade por aqui o cliente exigir isso no site) usando file_get_contents(), mas adivinhem: allow_url_fopen desabilitado.</p>
<p>
	Felizmente existem os sockets! Dei uma fuçada na net, juntei alguns snippets e criei uma classe para facilitar o serviço. Podem conferir o código e outras informações no meu <a href="http://www.github.com/fonini/HTTPRequest" rel="externo nofollow">Github</a>.</p>
<p>
	Grande abraço!</p>
]]></content:encoded>
			<wfw:commentRss>http://www.fonini.net/blog/httprequest-classe-php-para-retornar-conteudo-remoto-em-servidores-sem-curl/feed</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Meu ambiente de trabalho em 7 itens</title>
		<link>http://www.fonini.net/blog/meu-ambiente-de-trabalho-em-7-itens</link>
		<comments>http://www.fonini.net/blog/meu-ambiente-de-trabalho-em-7-itens#comments</comments>
		<pubDate>Mon, 27 Dec 2010 19:52:09 +0000</pubDate>
		<dc:creator>fonini</dc:creator>
				<category><![CDATA[Geral]]></category>
		<category><![CDATA[Soudev]]></category>

		<guid isPermaLink="false">http://www.fonini.net/blog/?p=128</guid>
		<description><![CDATA[Eis que temos mais um meme: Meu ambiente de trabalho em 7 itens. Recebi 2 convites hoje para descrever o meu, do @edipofederle e do @fr_prado. Uso 2 ambientes, um no trabalho e um no notebook pessoal. Vamos lá: 1) Sistema Operacional No trabalho uso Windows 7, pois preciso programar com o auxílio do framework [...]]]></description>
			<content:encoded><![CDATA[<p>
	Eis que temos mais um meme: Meu ambiente de trabalho em 7 itens. Recebi 2 convites hoje para descrever o meu, do <a href="http://www.twitter.com/edipofederle" rel="externo nofollow">@edipofederle</a> e do <a href="http://www.twitter.com/fr_prado" rel="externo nofollow">@fr_prado</a>. Uso 2 ambientes, um no trabalho e um no notebook pessoal. Vamos lá:</p>
<p>
	<strong>1) Sistema Operacional<br />
	</strong></p>
<p>
	No trabalho uso Windows 7, pois preciso programar com o auxílio do framework Adobe Flex. Na verdade eu poderia escrever o código em um editor de texto e compilar no compilador disponível para Linux, mas preciso de desenvolvimento ágil, além de <em>otras cositas mas</em>. Em casa uso o Ubuntu, sempre atualizado a cada nova versão. Atualmente tenho formatado minha máquina a cada novo release, pois sempre acabo enchendo-a de lixo. No próximo release irei atualizar a instalação, sem formatar.</p>
<p>
	<strong>2) IDE<br />
	</strong></p>
<p>
	Em casa, minha IDE é o Gedit. Com alguns plugins, ele se torna minha IDE preferida, extremamente leve e eficiente. Para gerenciamento do banco PostgreSQL utilizo o terminal do Linux, através do psql. No trabalho, no Windows, utilizo Eclipse com alguns plugins como o Hibernate Tools e o Flex Builder, Notepad++ para PHP e EMS SQL Manager para o banco de dados.</p>
<p>
	<strong>3) Controle de Versão<br />
	</strong></p>
<p>
	Para os meus projetos uso e recomendo o git. No trabalho, uso o TortoiseSVN.</p>
<p>
	<strong>4) Utilitários<br />
	</strong></p>
<p>
	Uso o Filezilla como cliente de FTP nos dois ambientes, na maioria das vezes para ajustes rápidos em páginas. Sempre que posso, faço o uso do SSH e SCP no Linux e do PuTTY e WinSCP no Windows.</p>
<p>
	<strong>5) Navegador/e-mail<br />
	</strong></p>
<p>
	Sou fã de carteirinha do Firefox, uso nos dois ambientes. No trabalho, também tenho instalados: Google Chrome, Opera e Internet Explorer (bleargh!) para testes nos sites. No Firefox, uso bastante os plugins Firebug (debug) e ColorZilla (captura de cores na páginas). Uso o Thunderbird para cliente de e-mail.</p>
<p>
	<strong>6) Entretenimento<br />
	</strong></p>
<p>
	Não disponho de entretenimento no trabalho. Em casa, o player de vídeos padrão do Ubuntu, o Totem, me serve muito bem. Para áudio, também uso o player padrão, o Rhythmbox, com alguns plugins bacanas. Tentei usar o Banshee, mas o mesmo trava com a minha imensa biblioteca de músicas, então voltei para o Rhythmbox. Tenho uma estranha mania de remover a voz das músicas, só para ouvir o instrumental. Para isso uso o Audacity. BTW, segue um tutorial rápido de como fazer isso sem precisar de plugins.</p>
<p>
	- Abra a música no Audacity<br />
	- Na barra de título da faixa da música, que fica no meio do programa, existe um menu suspenso. Clique e selecione a opção "Faixa Estéreo para Mono". Isso irá dividir a faixa em 2 pistas mono.<br />
	- Por último, selecione a pista de baixo e clique em Efeitos/Inverter Verticalmente. Feito!</p>
<p>
	<strong>7) Comunicação<br />
	</strong></p>
<p>
	No trabalho, tento me concentrar o máximo possível, dando uma escapada no Twitter de vez em quando. Para isso, uso o Twhirl. Em casa, também uso o mesmo cliente, além do Emesene para MSN/GTalk e do Skype. Adicionem lá: MSN: msn@fonini.net; GTalk: jonnasfonini@gmail.com; Skype: jonnas.fonini</p>
<p>
	Convido agora os amigos <a href="http://www.twitter.com/jandersonfc" rel="externo nofollow">@jandersonfc</a>, <a href="http://www.twitter.com/mpbonatti" rel="externo nofollow">@mpbonatti</a>, <a href="http://www.twitter.com/emersonbroga" rel="externo nofollow">@emersonbroga</a>, <a href="http://www.twitter.com/lshenr" rel="externo nofollow">@lshenr</a> e <a href="http://www.twitter.com/felipeborges" rel="externo nofollow">@felipeborges</a> para compartilhar um pouco de seus ambientes.</p>
<p>
	Abraço e até a próxima!</p>
]]></content:encoded>
			<wfw:commentRss>http://www.fonini.net/blog/meu-ambiente-de-trabalho-em-7-itens/feed</wfw:commentRss>
		<slash:comments>7</slash:comments>
		</item>
		<item>
		<title>Retornando os dias da semana atual em ActionScript 3 / Flex</title>
		<link>http://www.fonini.net/blog/retornando-os-dias-da-semana-atual-em-actionscript-3-flex</link>
		<comments>http://www.fonini.net/blog/retornando-os-dias-da-semana-atual-em-actionscript-3-flex#comments</comments>
		<pubDate>Thu, 09 Dec 2010 09:51:35 +0000</pubDate>
		<dc:creator>fonini</dc:creator>
				<category><![CDATA[Web]]></category>
		<category><![CDATA[Action Script 3]]></category>
		<category><![CDATA[Flex]]></category>
		<category><![CDATA[Função]]></category>

		<guid isPermaLink="false">http://www.fonini.net/blog/?p=126</guid>
		<description><![CDATA[Final de ano, projetos da empresa indo a milhão, últimas provas do semestre...é, não tá fácil, a correria tá desgraçada. Passei aqui pra remover as teias de aranha do blog e compartilhar esta função que pode ser útil para alguém. Infelizmente perdi a fonte de onde encontrei esta função, mas lembro que ela tinha um [...]]]></description>
			<content:encoded><![CDATA[<p>Final de ano, projetos da empresa indo a milhão, últimas provas do semestre...é, não tá fácil, a correria tá desgraçada. Passei aqui pra remover as teias de aranha do blog e compartilhar esta função que pode ser útil para alguém. Infelizmente perdi a fonte de onde encontrei esta função, mas lembro que ela tinha um erro no retorno (já corrigido por mim). A função original só retornava os dias úteis da semana, mas o que eu precisava era dos dias da semana inteira, começando no domingo. Com algumas modificações, aí está o resultado.<br />Essa função é bastante útil para se colocar num helper (que sabe numa dessas crio um e publico o código).</p>
<p></p>
<pre class="brush: as3; title: ; notranslate">
public function getCurrentWeekDays():Array{
	var output:Array = new Array();
	var formattedDate:String;
	var date:Date = new Date();

	date.setDate(date.getDate() - date.getDay() - 1);

	for (var i:int = 0; i &lt; 7; i++) {
		date.setDate(date.getDate() + 1);

		formattedDate = (date.getDate() &lt; 10) ? &quot;0&quot; +
date.getDate().toString() : date.getDate().toString();
		formattedDate += &quot;/&quot;;
		formattedDate += (date.getMonth() + 1 &lt; 10) ? &quot;0&quot; +
(date.getMonth() + 1).toString() : (date.getMonth() + 1).toString();

		output[i] = formattedDate;
	}
	return output;
}</pre>
<p>E para usar:</p>
<pre class="brush: as3; title: ; notranslate">
var diasSemana:Array = getCurrentWeekDays();</pre>
<p>Os dias serão retornados no seguinte formato: 05/11, 06/11, 07/11. A função pode ser facilmente adaptada para também retornar o ano ou retornar a data em outro formato.</p>
<p>É isso aí pessoal, esse é o último post do ano. Ano que vem prometo posts mais freqüentes.<br />
Um Feliz Natal para todos e um Ano Novo repleto de realizações, muito café, código e eterno aprendizado.</p>
<p>Grande abraço a todos!</p>
]]></content:encoded>
			<wfw:commentRss>http://www.fonini.net/blog/retornando-os-dias-da-semana-atual-em-actionscript-3-flex/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Desenvolvendo um módulo de contato no Symfony 1.4</title>
		<link>http://www.fonini.net/blog/desenvolvendo-um-modulo-de-contato-no-symfony-1-4</link>
		<comments>http://www.fonini.net/blog/desenvolvendo-um-modulo-de-contato-no-symfony-1-4#comments</comments>
		<pubDate>Fri, 08 Oct 2010 08:35:11 +0000</pubDate>
		<dc:creator>fonini</dc:creator>
				<category><![CDATA[Web]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[Symfony]]></category>

		<guid isPermaLink="false">http://www.fonini.net/blog/?p=124</guid>
		<description><![CDATA[Olá pessoal, o tutorial de hoje mostra como fazer um módulo com formulário de contato e envio dos dados por email usando o framework Symfony. Você já deve possuir um projeto criado para poder proseeguir. Primeiro, crie o módulo vazio com o comando abaixo: fonini@valhalla:$ ./symfony generate:module frontend contato O comando acima cria um módulo [...]]]></description>
			<content:encoded><![CDATA[<p>Olá pessoal, o tutorial de hoje mostra como fazer um módulo com formulário de contato e envio dos dados por email usando o framework <a href="http://www.symfony-project.org" rel="nofollow externo">Symfony</a>. Você já deve possuir um projeto criado para poder proseeguir.</p>
<p>
	Primeiro, crie o módulo vazio com o comando abaixo:</p>

<div class="wp-terminal">fonini@valhalla:$ ./symfony generate:module frontend contato<br/></div>

<p>
	O comando acima cria um módulo vazio, localizado em <strong>apps/frontend/modules/contato</strong>. O próximo passo é criar a classe do formulário. Esta classe irá conter todos os widgets (entenda por inputs, textareas, selects) que irão compor o formulário.<br />
	Crie um arquivo chamado ContatoForm.class.php em lib/form, com o conteúdo abaixo:</p>
<pre class="brush: php; title: ; notranslate">// lib/form/ContatoForm.class.php
class ContactForm extends BaseForm
{
  public function configure()
  {
    $this-&gt;setWidgets(array(
      'nome'    =&gt; new sfWidgetFormInputText(),
      'email'   =&gt; new sfWidgetFormInputText(),
      'assunto' =&gt; new sfWidgetFormInputText(),
      'mensagem' =&gt; new sfWidgetFormTextarea(),
    ));

    $this-&gt;widgetSchema-&gt;setLabels(array(
      'nome'    =&gt; 'Nome',
      'email'   =&gt; 'Email',
      'assunto' =&gt; 'Assunto',
      'mensagem' =&gt; 'Mensagem'
    ));

    $this-&gt;setValidators(array(
      'nome'    =&gt; new sfValidatorString(array('required' =&gt; true)),
      'email'   =&gt; new sfValidatorEmail(),
      'assunto' =&gt; new sfValidatorString(array('required' =&gt; true)),
      'mensagem' =&gt; new sfValidatorString(array('min_length' =&gt; 10)),
    ));

    // se esta opção não for setada, serão geradas tabelas no HTML
    $this-&gt;widgetSchema-&gt;setFormFormatterName('list');

    $this-&gt;widgetSchema-&gt;setNameFormat('contato[%s]');
  }
}
</pre>
<p>
	Com a classe do formulário pronta, basta passar uma instância dela para o template. Edite o arquivo apps/frontend/modules/contato/actions/actions.class.php e adapte-o para o código que segue:</p>
<pre class="brush: php; title: ; notranslate">// apps/frontend/modules/contato/actions/actions.class.php
class contatoActions extends sfActions
{
  public function executeIndex(sfWebRequest $request)
  {
    $this-&gt;form = new ContatoForm();

    if ($request-&gt;isMethod('post'))
    {
      $this-&gt;form-&gt;bind($request-&gt;getParameter('contato'));

      if ($this-&gt;form-&gt;isValid())
      {
        $this-&gt;redirect('contato/enviar?'.http_build_query($this-&gt;form-&gt;getValues()));
      }
    }
  }
}
</pre>
<p>
	Agora definiremos o template que irá receber a instância da classe ContatoForm, gerando os campos do formulário. Edite o arquivo apps/frontend/modules/contato/templates/indexSucess.php. Faço um parentêses aqui. Para cada action que você definir (no arquivo de actions, obviamente), você pode criar um arquivo nomedaactionSuccess.php. O conteúdo desse arquivo será exibido ao executar a action (a menos que ela redirecione para outra action). Exemplo: uma action enviaemail deve possuir um template enviaemailSuccess.php.</p>
<pre class="brush: xml; title: ; notranslate">// apps/frontend/modules/contato/templates/indexSuccess.php

&lt;form action=&quot;&lt;?php echo url_for('contato/index') ?&gt;&quot; method=&quot;post&quot;&gt;
	&lt;ul&gt;
                &lt;?php echo $form; ?&gt;
		&lt;li&gt;
			&lt;input type=&quot;submit&quot; value=&quot;Enviar&quot; /&gt;
                &lt;/li&gt;
	&lt;/ul&gt;
&lt;/form&gt;
</pre>
</p>
<p>
	Você deve ter percebido que a action do formulário está apontando para contato/enviar. Ou seja, ao ser submetido, o método enviar da classe contatoActions será invocado, logo teremos que criá-lo. Volte para o arquivo apps/frontend/modules/contato/actions/actions.class.php e adicione os métodos abaixo, o método que enviará o email e o método que será chamado se o envio for bem sucedido. Mude as configurações para seu servidor de envio. Outros parâmetros na <a href="http://www.swiftmailer.org" rel="externo nofollow">documentação da Swift Mailer</a>.</p>
</p>
<pre class="brush: php; title: ; notranslate">// apps/frontend/modules/contato/actions/actions.class.php

public function executeEnviar(sfWebRequest $request)
{
  $transport = Swift_SmtpTransport::newInstance('smtp.seudominio.com', 25)
    -&gt;setUsername('seuemail@dominio.com')
    -&gt;setPassword('senha');

  $mailer = Swift_Mailer::newInstance($transport);

  $message = Swift_Message::newInstance()
    -&gt;setSubject( $request-&gt;getParameter('assunto') )
    -&gt;setFrom(array( $request-&gt;getParameter('email')  =&gt; $request-&gt;getParameter('nome') ))
    -&gt;setTo(array('email_contato@seudominio.com.br'))
    -&gt;setReplyTo( $request-&gt;;getParameter('email') )
    -&gt;setBody( $request-&gt;getParameter('mensagem') );

  if ($mailer-&gt;send($message)){
    $this-&gt;redirect('contato/feito');
  }
}

public function executeFeito()
{
}
</pre>
<p>
	Agora basta criar um template para o método executeFeito, mostrando uma mensagem de envio bem sucedido.</p>
<pre class="brush: xml; title: ; notranslate">&lt;!-- apps/frontend/modules/contato/templates/feitoSuccess.php --&gt;
&lt;span style=&quot;font-weight: bold; font-size: 14px;&quot;&gt;Contato enviado com sucesso. Obrigado!&lt;/span&gt;
</pre>
<p>
	Tudo pronto! Teste seu módulo agora: http://localhost/seuprojeto/index.php/contato.</p>
<p>
	<strong>Download</strong></p>
<p>	Caso algo tenha dado errado, baixe os arquivos utilizados e coloque-os em suas devidas pastas. Melhor ainda que substituir os arquivos é tentar encontrar a causa do problema e quem sabe melhorar o módulo, que está bem básico.</p>
<p>	<a href="http://www.fonini.net/labs/modulo-contato-symfony.zip">Download dos arquivos</a></p>
<p>
	Grande abraço e até a próxima!</p>
]]></content:encoded>
			<wfw:commentRss>http://www.fonini.net/blog/desenvolvendo-um-modulo-de-contato-no-symfony-1-4/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Enviando emails autenticados do Gmail com PHP usando Swift Mailer</title>
		<link>http://www.fonini.net/blog/enviando-emails-autenticados-do-gmail-com-php-usando-swift-mailer</link>
		<comments>http://www.fonini.net/blog/enviando-emails-autenticados-do-gmail-com-php-usando-swift-mailer#comments</comments>
		<pubDate>Thu, 30 Sep 2010 08:42:41 +0000</pubDate>
		<dc:creator>fonini</dc:creator>
				<category><![CDATA[Web]]></category>
		<category><![CDATA[PHP]]></category>

		<guid isPermaLink="false">http://www.fonini.net/blog/?p=122</guid>
		<description><![CDATA[O Swift Mailer é uma biblioteca para envio de emails, usando PHP5. Conheci a biblioteca inicialmente no framework Symfony, pois a mesma é responsável pela tarefa de enviar emails no framework, pois seu uso é muito simples e a biblioteca é muito poderosa. Tenho notado que muitas empresas estão adotando cada vez mais o uso [...]]]></description>
			<content:encoded><![CDATA[<p>O <a href="http://www.swiftmailer.org" rel="externo nofollow">Swift Mailer</a> é uma biblioteca para envio de emails, usando PHP5. Conheci a biblioteca inicialmente no framework <a href="http://www.symfony-project.org" rel="externo nofollow">Symfony</a>, pois a mesma é responsável pela tarefa de enviar emails no framework, pois seu uso é muito simples e a biblioteca é muito poderosa.</p>
<p>Tenho notado que muitas empresas estão adotando cada vez mais o uso do Google Apps como serviço de webmail, dada a facilidade de uso e configuração do sistema. O primeiro exemplo mostra como enviar emails autenticados a partir de uma conta de email do Google (Gmail ou Apps) e os outros tratam do envio de mensagens com anexo. Usei a versão 4.0.6 para o exemplo.</p>
<p><span style="font-size: 14px;"><strong>Enviando emails com autenticação no Gmail (incluindo Google Apps)</strong></span></p>
<pre class="brush: php; title: ; notranslate">require('lib/swift_required.php');

$transport = Swift_SmtpTransport::newInstance('smtp.gmail.com', 465, 'ssl')
	-&gt;setUsername('usuario@gmail.com')
	-&gt;setPassword('senha');

$mailer = Swift_Mailer::newInstance($transport);

$message = Swift_Message::newInstance('Assunto')
	-&gt;setFrom(array('seuemail@dominio.com.br' =&gt; 'Seu Nome'))
	-&gt;setTo(array('fulano@teste.com.br'))
	-&gt;setReplyTo('seuemail@dominio.com.br')
	-&gt;setBody('Conteudo da mensagem');

if ($mailer-&gt;send($message)){
	echo 'Mensagem enviada com sucesso';
}
else{
	echo 'Problema ao enviar mensagem. Tente novamente mais tarde';
}
</pre>
<p><span style="font-size: 14px;"><br />
<strong>Enviando emails com imagens embutidas (inline)</strong></span><br />
Útil para enviar emails com imagens que não serão bloqueadas pelos softwares leitores de email, já que estão embutidas no código e não em servidores remotos.</p>
<pre class="brush: php; title: ; notranslate">require('lib/swift_required.php');

$transport = Swift_SmtpTransport::newInstance('smtp.gmail.com', 465, 'ssl')
	-&gt;setUsername('usuario@gmail.com')
	-&gt;setPassword('senha');

$mailer = Swift_Mailer::newInstance($transport);

$message = Swift_Message::newInstance('Assunto')
	-&gt;setFrom(array('seuemail@dominio.com.br' =&gt; 'Seu Nome'))
	-&gt;setTo(array('fulano@teste.com.br'))
	-&gt;setReplyTo('seuemail@dominio.com.br');

$imagem_inline = $message-&gt;embed(Swift_Image::fromPath('logotipo.png'));

$message-&gt;setBody(
	'&lt;html&gt;'.
	' &lt;head&gt;&lt;/head&gt;'.
	' &lt;body&gt;' .
	'  &lt;img src=&quot;'.$imagem_inline.'&quot; alt=&quot;Imagem embutida na mensagem&quot; /&gt;'.
	'  &lt;br /&gt;&lt;br /&gt;Texto da mensagem'.
	' &lt;/body&gt;'.
	'&lt;/html&gt;',
  'text/html' //Definimos o tipo da mensagem para text/html, ao invés de texto puro
);

if ($mailer-&gt;send($message)){
	echo 'Mensagem enviada com sucesso';
}
else{
	echo 'Problema ao enviar mensagem. Tente novamente mais tarde';
}
</pre>
<p><span style="font-size: 14px;"><br />
<strong>Enviando emails com anexo</strong></span></p>
<pre class="brush: php; title: ; notranslate">require_once 'lib/swift_required.php';

$transport = Swift_SmtpTransport::newInstance('smtp.seudominio.com', 25)
	-&gt;setUsername('seuemail@dominio.com')
	-&gt;setPassword('senha');

$mailer = Swift_Mailer::newInstance($transport);

$message = Swift_Message::newInstance()
	-&gt;setSubject('Email com PDF anexado')
	-&gt;setFrom(array('seuemail@seudominio.com' =&gt; 'Seu nome'))
	-&gt;setTo(array('contato1@teste.org', 'contato2@teste.org'))
	-&gt;setBody('Leia a apostila em anexo')
	-&gt;attach(Swift_Attachment::fromPath('apostilas/apostila_inicial.pdf'));

if ( ! $mailer-&gt;send($message)){
	echo 'Erro ao enviar email';
}
</pre>
<p>Bom, esses foram alguns exemplos bem básicos do uso da biblioteca Swift Mailer. Consulte a <a href="http://swiftmailer.org/docs/introduction" rel="externo nofollow">documentação oficial</a> para mais informações e um guia de referência completo.</p>
<p>Abraço e até a próxima!</p>
]]></content:encoded>
			<wfw:commentRss>http://www.fonini.net/blog/enviando-emails-autenticados-do-gmail-com-php-usando-swift-mailer/feed</wfw:commentRss>
		<slash:comments>8</slash:comments>
		</item>
		<item>
		<title>Validadores do Doctrine (validators)</title>
		<link>http://www.fonini.net/blog/validadores-do-doctrine-validators</link>
		<comments>http://www.fonini.net/blog/validadores-do-doctrine-validators#comments</comments>
		<pubDate>Thu, 23 Sep 2010 08:48:24 +0000</pubDate>
		<dc:creator>fonini</dc:creator>
				<category><![CDATA[Web]]></category>
		<category><![CDATA[Doctrine]]></category>
		<category><![CDATA[PHP]]></category>

		<guid isPermaLink="false">http://www.fonini.net/blog/?p=120</guid>
		<description><![CDATA[Neste post mostrarei os validadores presentes no Doctrine (usei a versão 1.2.3). O Doctrine facilita a validação dos dados, bastando apenas definir os validadores para cada atributo ao invés de fazer vários malabarismos com funções do PHP e expressões regulares. Você pode definir os validadores na classe que estende a classe base. Dessa maneira, você [...]]]></description>
			<content:encoded><![CDATA[<p>
	Neste post mostrarei os validadores presentes no <a href="http://www.doctrine-project.org" rel="externo nofollow">Doctrine</a> (usei a versão 1.2.3). O Doctrine facilita a validação dos dados, bastando apenas definir os validadores para cada atributo ao invés de fazer vários malabarismos com funções do PHP e expressões regulares. Você pode definir os validadores na classe que estende a classe base. Dessa maneira, você pode gerar o model novamente e suas alterações não serão perdidas. Primeiro listarei os validadores e ao final mostrarei alguns exemplos. Vamos lá.</p>
<p>
	<span style="color: rgb(255, 0, 0);"><strong>Importante</strong></span><br />
	Para que seus dados sejam validados, cheque se seu "bootstrap.php" contém a diretiva abaixo. Caso contrário, seus dados não serão validados.</p>
<pre class="brush: php; title: ; notranslate">$manager-&gt;setAttribute(Doctrine_Core::ATTR_VALIDATE, Doctrine_Core::VALIDATE_ALL);
</pre>
</p>
<p>
	<strong>notnull</strong><br />
	Garante que o valor não seja nulo na aplicação e no banco de dados.</p>
<pre class="brush: php; title: ; notranslate">// models/SuaClasse.php

class SuaClasse extends BaseSuaClasse
{
    // ...

	public function setTableDefinition(){
		parent::setTableDefinition();

		// ...

		$this-&gt;hasColumn('nome', 'string', 70, array(
				'notnull' =&gt; true
			)
		);
	}
}
</pre>
<p>
	<span style="color: rgb(22, 188, 42);"><strong>Válido: </strong></span>teste, jonnas<br />
	<span style="color: rgb(255, 0, 0);"><strong>Inválido: </strong></span>valores nulos</p>
</p>
<p>
	<strong>email</strong><br />
	Checa se o valor é um endereço de email válido.</p>
<pre class="brush: php; title: ; notranslate">	$this-&gt;hasColumn('email', 'string', 100, array(
				'email' =&gt; true
			)
	);
</pre>
<p>
	<span style="color: rgb(22, 188, 42);"><strong>Válido: </strong></span>contato@fonini.net<br />
	<span style="color: rgb(255, 0, 0);"><strong>Inválido: </strong></span>fulano!#@server</p>
</p>
<p>
	<strong>notblank</strong><br />
	Este validador é semelhante ao validador notnull, exceto que além de não validar valores nulos, também não valida strings vazias.</p>
<pre class="brush: php; title: ; notranslate">	$this-&gt;hasColumn('nome', 'string', 100, array(
				'notblank' =&gt; true
			)
	);
</pre>
<p>
	<span style="color: rgb(22, 188, 42);"><strong>Válido: </strong></span>teste, jonnas<br />
	<span style="color: rgb(255, 0, 0);"><strong>Inválido: </strong></span>valores nulos, ''</p>
</p>
<p>
	<strong>nospace</strong><br />
	Checa se o valor não contém espaços.</p>
<pre class="brush: php; title: ; notranslate">	$this-&gt;hasColumn('campo_sem_espacos', 'string', 100, array(
				'nospace' =&gt; true
			)
	);
</pre>
<p>
	<span style="color: rgb(22, 188, 42);"><strong>Válido: </strong></span>JonnasFonini<br />
	<span style="color: rgb(255, 0, 0);"><strong>Inválido: </strong></span>Jonnas Fonini</p>
</p>
<p>
	<strong>past</strong><br />
	Checa se o valor é uma data que já ocorreu, o dia de ontem, por exemplo.</p>
<pre class="brush: php; title: ; notranslate">	$this-&gt;hasColumn('data', 'timestamp', null, array(
				'past' =&gt; true
			)
	);
</pre>
<p>
	<span style="color: rgb(22, 188, 42);"><strong>Válido: </strong></span>Sendo hoje 14/09/2010, 01/01/2010 é válida<br />
	<span style="color: rgb(255, 0, 0);"><strong>Inválido: </strong></span>Sendo hoje 14/09/2010, a mesma e posteriores são inválidas</p>
</p>
<p>
	<strong>future</strong><br />
	Checa se o valor é uma data que ainda não aconteceu, amanhã, por exemplo.</p>
<pre class="brush: php; title: ; notranslate">	$this-&gt;hasColumn('data', 'timestamp', null, array(
				'future' =&gt; true
			)
	);
</pre>
<p>
	<span style="color: rgb(22, 188, 42);"><strong>Válido: </strong></span>Sendo hoje 14/09/2010, 15/09/2010 é válida<br />
	<span style="color: rgb(255, 0, 0);"><strong>Inválido: </strong></span>Sendo hoje 14/09/2010, a mesma e anteriores são inválidas</p>
</p>
<p>
	<strong>minlength</strong><br />
	Checa se o valor passado tem o tamanho mínimo necessário.</p>
<pre class="brush: php; title: ; notranslate">	$this-&gt;hasColumn('senha', 'string', 32, array(
				'minlength' =&gt; 6
			)
	);
</pre>
<p>
	<span style="color: rgb(22, 188, 42);"><strong>Válido: </strong></span>abcdef, abcdefg<br />
	<span style="color: rgb(255, 0, 0);"><strong>Inválido: </strong></span>abc</p>
</p>
<p>
	<strong>ip</strong><br />
	Checa se o valor passado é um endereço IP válido.</p>
<pre class="brush: php; title: ; notranslate">	$this-&gt;hasColumn('endereco_ip', 'string', 15, array(
				'ip' =&gt; true
			)
	);
</pre>
<p>
	<span style="color: rgb(22, 188, 42);"><strong>Válido: </strong></span>192.168.250.222, 201.10.34.21<br />
	<span style="color: rgb(255, 0, 0);"><strong>Inválido: </strong></span>345.10.10.290</p>
</p>
<p>
	<strong>htmlcolor</strong><br />
	Checa se o valor passado é uma cor HTML em hexadecimal.</p>
<pre class="brush: php; title: ; notranslate">	$this-&gt;hasColumn('cor', 'string', 7, array(
				'htmlcolor' =&gt; true
			)
	);
</pre>
<p>
	<span style="color: rgb(22, 188, 42);"><strong>Válido: </strong></span>#000FFF, FF0000<br />
	<span style="color: rgb(255, 0, 0);"><strong>Inválido: </strong></span>#GGG111, #FFF (cores abreviadas são inválidas)</p>
</p>
<p>
	<strong>range</strong><br />
	Checa se o valor numérico está contido no intervalo especificado.</p>
<pre class="brush: php; title: ; notranslate">	$this-&gt;hasColumn('idade', 'integer', null, array(
				'range' =&gt; array(18, 70)
			)
	);
</pre>
<p>
	<span style="color: rgb(22, 188, 42);"><strong>Válido: </strong></span>19, 50, 69<br />
	<span style="color: rgb(255, 0, 0);"><strong>Inválido: </strong></span>10, 18, 70</p>
</p>
<p>
	<strong>unique</strong><br />
	Checa se o valor já existe no banco de dados.</p>
<pre class="brush: php; title: ; notranslate">	$this-&gt;hasColumn('rg', 'string', 15, array(
				'unique' =&gt; true
			)
	);
</pre>
</p>
<p>
	<strong>regexp</strong><br />
	Checa se o valor casa com a expressão regular passada.</p>
<pre class="brush: php; title: ; notranslate">	$this-&gt;hasColumn('somente_letras', 'string', 15, array(
				'regexp' =&gt; '/^[a-zA-Z]+$/'
			)
	);
</pre>
<p>
	<span style="color: rgb(22, 188, 42);"><strong>Válido: </strong></span>flex<br />
	<span style="color: rgb(255, 0, 0);"><strong>Inválido: </strong></span>flex4</p>
</p>
<p>
	<strong>creditcard</strong><br />
	Checa se o valor é um número de cartão de crédito válido.</p>
<pre class="brush: php; title: ; notranslate">	$this-&gt;hasColumn('cartao', 'integer', 16, array(
				'creditcard' =&gt; true
			)
	);
</pre>
<p>
	<span style="color: rgb(22, 188, 42);"><strong>Válido: </strong></span>Cartões Visa, Master Card, American Express, Discover e Diners<br />
	<span style="color: rgb(255, 0, 0);"><strong>Inválido: </strong></span>Outras bandeiras, exceto as citadas acima</p>
</p>
<p>
	<strong>readonly</strong><br />
	Evita que o valor de uma coluna da tabela seja alterado.</p>
<pre class="brush: php; title: ; notranslate">	$this-&gt;hasColumn('coluna_que_nao_pode_ser_alterada', 'string', 25, array(
				'readonly' =&gt; true
			)
	);
</pre>
</p>
<p>
	<strong>unsigned</strong><br />
	Checa se o valor númerico passado possui sinal, de menos, por exemplo.</p>
<pre class="brush: php; title: ; notranslate">	$this-&gt;hasColumn('idade', 'integer', 3, array(
				'unsigned' =&gt; true
			)
	);
</pre>
<p>
	<span style="color: rgb(22, 188, 42);"><strong>Válido: </strong></span>70, 100<br />
	<span style="color: rgb(255, 0, 0);"><strong>Inválido: </strong></span>-20</p>
</p>
<p>
	<strong>usstate</strong><br />
	Checa se a string passada é a sigla válida de um estado americano. Confira a lista completa <a href="http://en.wikipedia.org/wiki/Us_states" rel="externo nofollow">aqui</a>.</p>
<pre class="brush: php; title: ; notranslate">	$this-&gt;hasColumn('estado_americano', 'string', 2, array(
				'usstate' =&gt; true
			)
	);
</pre>
<p>
	<span style="color: rgb(22, 188, 42);"><strong>Válido: </strong></span>AL, CA<br />
	<span style="color: rgb(255, 0, 0);"><strong>Inválido: </strong></span>QW</p>
</p>
<p>
	<strong>country</strong><br />
	Checa se a string passada é a sigla válida de um país. Confira a lista completa <a href="http://en.wikipedia.org/wiki/ISO_3166-1" rel="externo nofollow">aqui</a>.</p>
<pre class="brush: php; title: ; notranslate">	$this-&gt;hasColumn('pais', 'string', 2, array(
				'country' =&gt; true
			)
	);
</pre>
<p>
	<span style="color: rgb(22, 188, 42);"><strong>Válido: </strong></span>br, BR, ar<br />
	<span style="color: rgb(255, 0, 0);"><strong>Inválido: </strong></span>xx</p>
<p>
	No próximo post mostrarei como fazer um validador de estados brasileiros e outro de CEP's.</p>
<p>	Grande abraço e até a próxima!</p>
]]></content:encoded>
			<wfw:commentRss>http://www.fonini.net/blog/validadores-do-doctrine-validators/feed</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Tutorial de Doctrine, um ORM para PHP</title>
		<link>http://www.fonini.net/blog/tutorial-de-doctrine-um-orm-para-php</link>
		<comments>http://www.fonini.net/blog/tutorial-de-doctrine-um-orm-para-php#comments</comments>
		<pubDate>Tue, 14 Sep 2010 08:04:30 +0000</pubDate>
		<dc:creator>fonini</dc:creator>
				<category><![CDATA[Web]]></category>
		<category><![CDATA[Doctrine]]></category>
		<category><![CDATA[PHP]]></category>

		<guid isPermaLink="false">http://www.fonini.net/blog/?p=118</guid>
		<description><![CDATA[O Doctrine é um mapeador objeto-relacional (ORM) para PHP, aos moldes do Hibernate para Java. Este ORM elimina a tarefa de escrever consultas SQL básicas, além de facilitar a conexão com o banco de dados, através da extensão PDO. O Doctrine permite que você crie seu model escrevendo suas classes em PHP (seguindo alguns padrões [...]]]></description>
			<content:encoded><![CDATA[<p>
	O <a href="http://www.doctrine-project.org" rel="externo nofollow">Doctrine</a> é um mapeador objeto-relacional (ORM) para PHP, aos moldes do Hibernate para Java. Este ORM elimina a tarefa de escrever consultas SQL básicas, além de facilitar a conexão com o banco de dados, através da extensão PDO. O Doctrine permite que você crie seu model escrevendo suas classes em PHP (seguindo alguns padrões pré-definidos), através de arquivos YAML ou ele se encarrega da geração do model através das tabelas já criadas no banco de dados. Uma vez que o model está criado, você pode definir validadores para campos específicos da tabela realizando essas alterações na classe gerada que estende cada model. Dessa forma, seu model fica preservado, você apenas altera a classe estendida, tornando fácil desfazer modificações.</p>
<p>
	<strong>Instalação</strong></p>
<p>	Baixe a última versão estável no <a href="http://www.doctrine-project.org/projects/orm/download" rel="externo nofollow">site do projeto</a>. No momento em que escrevo este post, a última versão estável é a 1.2.3. A versão 2 escontra-se em fase beta. Quem sabe quando ela for lançada sai mais um post. Crie uma pasta para seu projeto no seu webserver e dentro dela crie uma pasta lib. Após criar a pasta, extraia o Doctrine para ela. A estrutura deverá ficar semelhante a esta:<br />
	seu_projeto/lib/Doctrine<br />
	seu_projeto/lib/vendor<br />
	seu_projeto/lib/Doctrine.php</p>
<p>	Crie também uma pasta chamada "models" na raíz do projeto, dando permissão 777 a ela. Esta pasta irá conter o model da aplicação.<br />
	seu_projeto/models</p>
<p>
	<strong>Configuração</strong></p>
<p>	Crie um arquivo na pasta raíz do projeto chamado "bootstrap.php". Esse arquivo irá conter as configurações e parâmetros de funcionamento do Doctrine. Abaixo está o arquivo que eu uso. Você pode definir outros parâmetros consultando a <a href="http://www.doctrine-project.org/projects/orm/1.2/docs/en" rel="externo nofollow">documentação oficial</a>.</p>
<pre class="brush: php; title: ; notranslate">// seu_projeto/bootstrap.php

require_once(dirname(__FILE__) . '/lib/Doctrine.php');

spl_autoload_register(array('Doctrine', 'autoload'));
spl_autoload_register(array('Doctrine_Core', 'modelsAutoload'));

$manager = Doctrine_Manager::getInstance();

// Configurações do banco de dados. O banco deve ser criado previamente.
$user = 'postgres';
$password = 'teste';
$host = 'localhost';
$dbname = 'testdoctrine';
$driver = 'pgsql';

$conn = Doctrine_Manager::connection($driver.'://'.$user.':'.$password.'@'.$host.'/'.$dbname);
$conn-&gt;setOption('username', $user);
$conn-&gt;setOption('password', $password);
$manager-&gt;setAttribute(Doctrine_Core::ATTR_EXPORT, Doctrine_Core::EXPORT_ALL);
$manager-&gt;setAttribute(Doctrine_Core::ATTR_MODEL_LOADING, Doctrine_Core::MODEL_LOADING_CONSERVATIVE);
$manager-&gt;setAttribute(Doctrine_Core::ATTR_AUTOLOAD_TABLE_CLASSES, true);
$manager-&gt;setAttribute(Doctrine_Core::ATTR_VALIDATE, Doctrine_Core::VALIDATE_ALL);

// Permite o override dos metodos do model.
$manager-&gt;setAttribute(Doctrine_Core::ATTR_AUTO_ACCESSOR_OVERRIDE, true);

// Formato das sequências (uso para PostgreSQL)
$manager-&gt;setAttribute(Doctrine_Core::ATTR_SEQNAME_FORMAT, '%s_seq');

// Carrega os models da pasta especificada, no caso &quot;models&quot;
Doctrine_Core::loadModels('models');
</pre>
<p>
	
	 </p>
<p>
	<strong>Criação dos models</strong></p>
<p>	Com seu projeto configurado, o próximo passo é criar o model. Vou mostrar as 3 formas disponíveis.
	 </p>
<p>
	<em><strong>Gerando as classes através das tabelas já existentes</strong></em></p>
<p>	Crie um arquivo chamado "test.php" que será usado neste e nos próximos passos. Deverá ter o seguinte conteúdo:
	 </p>
<pre class="brush: php; title: ; notranslate">require_once('bootstrap.php');
</pre>
<p>
	Agora, basta adicionar as linhas abaixo ao seu arquivo "test.php". Comente-a após a geração, pois senão os models serão gerados novamente a cada execução.
	 </p>
<pre class="brush: php; title: ; notranslate">// seu_projeto/test.php
require_once('bootstrap.php');

Doctrine_Core::generateModelsFromDb('models', array('doctrine'), array(
	'generateTableClasses' =&gt; true
	)
);
</pre>
<p>
	Você pode usar como exemplo as tabelas abaixo:
	 </p>
<pre class="brush: sql; title: ; notranslate">CREATE TABLE cidade (
    id bigint NOT NULL,
    nome character(500) NOT NULL,
    uf character(2) NOT NULL
);

CREATE TABLE pessoa (
    id bigint NOT NULL,
    nome character(500) NOT NULL,
    data_nasc date,
    id_cidade bigint
);

ALTER TABLE ONLY cidade ADD CONSTRAINT cidade_pkey PRIMARY KEY (id);
ALTER TABLE ONLY pessoa ADD CONSTRAINT pessoa_pkey PRIMARY KEY (id);
ALTER TABLE ONLY pessoa ADD CONSTRAINT
pessoa_id_cidade_cidade_id FOREIGN KEY (id_cidade) REFERENCES cidade(id);
</pre>
<p>
	<em><strong>Gerando as classes através de um arquivo YAML</strong></em></p>
<p>	Um arquivo YAML (extensão .yml) é um arquivo semelhante a um arquivo XML e eu diria muito mais poderoso (minha opinião). Ao invés de tags, os dados são representados pela identação dos atributos e seus valores (o pessoal do Python ama isso). A identação deve ser feita com <strong>espaços</strong> e não com tabulações. Para mais informações, consulte a <a href="http://en.wikipedia.org/wiki/YAML" rel="externo nofollow">Wikipédia</a>.<br />
	Esta forma permite representar seus models no arquivo YAML.<br />
	Se você ainda não tem classes definidas, crie o arquivo "schemas.yml" na raíz do projeto com o conteúdo abaixo:
	 </p>
<pre>Cidade:
  connection: 0
  tableName: cidade
  columns:
    id:
      fixed: false
      notnull: true
      primary: true
      autoincrement: true
      type: integer(8)
    nome:
      fixed: true
      notnull: true
      type: string(500)
    uf:
      fixed: true
      notnull: true
      type: string(2)
  relations:
    Pessoa:
      local: id
      foreign: id_cidade
      type: many
Pessoa:
  connection: 0
  tableName: pessoa
  columns:
    id:
      fixed: false
      notnull: true
      primary: true
      autoincrement: true
      type: integer(8)
    nome:
      fixed: true
      notnull: true
      type: string(500)
    data_nasc: date(25)
    id_cidade: integer(8)
  relations:
    Cidade:
      local: id_cidade
      foreign: id
      type: one
</pre>
<p>
	Caso você já tenha as classes definidas, basta remover o código de geração das classes do arquivo "test.php" e adicionar as linhas abaixo:
	 </p>
<pre class="brush:php">// seu_projeto/test.php
require_once('bootstrap.php');
Doctrine_Core::generateYamlFromModels('schema.yml', 'models');
</pre>
<p>
	Após executar o test.php, você verá um arquivo chamado "schema.yml" na pasta raíz, com a definição do model. Crie agora um arquivo chamado "generate.php" com o código abaixo. Esse arquivo será responsável por remover as tabelas do banco de dados (se existirem) e recriá-las com base no arquivo "schema.yml", gerando também as classes PHP. Portanto, muito cuidado, só execute quando for estritamente necessário, sob a pena de perder os dados do banco.
	 </p>
<pre class="brush: php; title: ; notranslate">// seu_projeto/generate.php
require_once('bootstrap.php');

//Remova as próximas 2 linhas caso não queira remover e criar seu banco a cada execução.
Doctrine_Core::dropDatabases();
Doctrine_Core::createDatabases();
Doctrine_Core::generateModelsFromYaml('schema.yml', 'models');
Doctrine_Core::createTablesFromModels('models');
</pre>
<p>
	<em><strong>Definindo manualmente suas classes PHP</strong></em></p>
<p>	Usarei como exemplo duas classes, Pessoa e Cidade, sendo que uma pessoa pertence a uma cidade. Basta criar dois arquivos na pasta "models", Pessoa.php e Cidade.php, com o código abaixo:
	 </p>
<pre class="brush: php; title: ; notranslate">// seu_projeto/models/Cidade.php

class Cidade extends Doctrine_Record{
	public function setTableDefinition(){
		$this-&gt;hasColumn('id', 'integer', null, array(
			'fixed' =&gt; false,
			'notnull' =&gt; true,
			'primary' =&gt; true,
			'autoincrement' =&gt; true
			)
		);
		$this-&gt;hasColumn('nome', 'string', 500, array('fixed' =&gt; true, 'notnull' =&gt; true));
		$this-&gt;hasColumn('uf', 'string', 2, array('fixed' =&gt; true, 'notnull' =&gt;; true));
	}
}
</pre>
<pre class="brush: php; title: ; notranslate">// seu_projeto/models/Pessoa.php

class Pessoa extends Doctrine_Record{
	public function setTableDefinition(){
		$this-&gt;hasColumn('id', 'integer', null, array(
			'fixed' =&gt; false,
			'notnull' =&gt; true,
			'primary' =&gt; true,
			'autoincrement' =&gt; true
			)
		);
		$this-&gt;hasColumn('nome', 'string', 500, array('fixed' =&gt; true, 'notnull' =&gt; true));
		$this-&gt;hasColumn('data_nasc', 'date');
		$this-&gt;hasColumn('id_cidade', 'integer');
	}

	public function setUp(){
		$this-&gt;hasOne('Cidade', array(
				'local' =&gt; 'id_cidade',
				'foreign' =&gt; 'id'
			)
		);
	}
}
</pre>
<p>
	Após a definição das classes, rode o arquivo "test.php" com a linha "Doctrine_Core::generateYamlFromModels('schema.yml', 'models');". Após rodar esse arquivo, execute o "generate.php", que irá apagar o banco de dados, criá-lo novamente e criar as tabelas referentes as classes.</p>
<p>
	<strong>Realizando consultas</strong></p>
<p>	Com o model pronto, vamos realizar algumas consultas.
	 </p>
<p>
	<em>Inserindo pessoa com uma cidade associada a ela</em></p>
<pre class="brush: php; title: ; notranslate">$cidade = new Cidade();
$cidade-&gt;nome = 'Marau';
$cidade-&gt;uf = 'RS';
$cidade-&gt;save();

$pessoa = new Pessoa();
$pessoa-&gt;nome = &quot;Jonnas Fonini&quot;;
$pessoa-&gt;data_nasc = date('1990-04-12');
$pessoa-&gt;id_cidade = $cidade;
$pessoa-&gt;save();
</pre>
<p>
	<em>Consultando informações de uma pessoa</em></p>
<pre class="brush: php; title: ; notranslate">$pessoa = Doctrine_Core::getTable('Pessoa')-&gt;find(1);
echo 'Id: '.$pessoa-&gt;id.'&lt;br /&gt;';
echo 'Nome: '.$pessoa-&gt;nome.'&lt;br /&gt;';
echo 'Data Nasc.: '.$pessoa-&gt;data_nasc.'&lt;br /&gt;';
echo 'Cidade: '.$pessoa-&gt;Cidade-&gt;nome;
</pre>
<p>
	<em>Atualizando informações de uma pessoa</em></p>
<pre class="brush: php; title: ; notranslate">$pessoa = Doctrine_Core::getTable('Pessoa')-&gt;find(1);
$pessoa-&gt;data_nasc = date('Y-m-d');
$pessoa-&gt;save();
</pre>
<p>
	<em>Removendo uma pessoa</em></p>
<pre class="brush: php; title: ; notranslate">$pessoa = Doctrine_Core::getTable('Pessoa')-&gt;find(1);
$pessoa-&gt;delete();
</pre>
</p>
<p>
	<strong>Download</strong></p>
<p>	<a href="http://www.fonini.net/labs/projeto-doctrine.zip">Clique aqui</a> para baixar o projeto já pronto. Mude as configurações do banco de dados no arquivo "bootstrap.php".</p>
<p>
	<strong>Conclusão</strong></p>
<p>	O Doctrine facilita muito a manipulação do banco de dados em PHP, poupando a você o trabalho de escrever consultas SQL. Incremente ainda mais seus estudos estudando o framework <a href="http://www.symfony-project.org" rel="externo nofollow">Symfony</a>, um dos mais completos da atualizade e que faz uso do Doctrine. Pretendo criar mais posts sobre o Doctrine em breve.<br />
	Grande abraço a todos e até a próxima.</p>
<p>	<a href="http://www.soudev.com.br">#soudev</a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.fonini.net/blog/tutorial-de-doctrine-um-orm-para-php/feed</wfw:commentRss>
		<slash:comments>8</slash:comments>
		</item>
		<item>
		<title>sfNicEditPlugin: Adicione um editor de texto rico aos seus forms no Symfony</title>
		<link>http://www.fonini.net/blog/sfniceditplugin-adicione-um-editor-de-texto-rico-aos-seus-forms-no-symfony</link>
		<comments>http://www.fonini.net/blog/sfniceditplugin-adicione-um-editor-de-texto-rico-aos-seus-forms-no-symfony#comments</comments>
		<pubDate>Tue, 24 Aug 2010 10:11:30 +0000</pubDate>
		<dc:creator>fonini</dc:creator>
				<category><![CDATA[Web]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[Plugins]]></category>
		<category><![CDATA[Symfony]]></category>

		<guid isPermaLink="false">http://www.fonini.net/blog/?p=116</guid>
		<description><![CDATA[Em meados de 2009 usei o framework Symfony para desenvolver um sistema em PHP para um projeto do qual eu era bolsista. Terminado o projeto, abandonei o framework. Agora reiniciei meus estudos e estou gostando bastante. Tanto que já desenvolvi meu primeiro plugin para compartilhar com a comunidade e já tenho muitos outros em mente. [...]]]></description>
			<content:encoded><![CDATA[<p>Em meados de 2009 usei o framework Symfony para desenvolver um sistema em PHP para um projeto do qual eu era bolsista. Terminado o projeto, abandonei o framework. Agora reiniciei meus estudos e estou gostando bastante. Tanto que já desenvolvi meu primeiro plugin para compartilhar com a comunidade e já tenho muitos outros em mente.</p>
<p>O nome do plugin é sfNicEditPlugin. Ele adiciona uma instância do editor de texto rico <a href="http://www.nicedit.com" rel="externo nofollow">NicEdit</a> a um textarea. Esta é a primeira versão do plugin, ainda faltam alguns parâmetros que o NicEdit aceita, outros já estão disponíveis.</p>
<p>Você pode encontrar o plugin no meu <a href="http://github.com/fonini/sfNicEditPlugin" rel="externo nofollow">GitHub</a> ou na <a href="http://www.symfony-project.org/plugins/sfNicEditPlugin" rel="externo nofollow">página de plugins do Symfony</a>. Em ambos os locais você encontra instruções de instalação em inglês. Aqui no blog vou publicar a versão em português.</p>
<p><strong>Instalação</strong><br ></p>
<p>Instalação (via pacote PEAR)</p>

<div class="wp-terminal">fonini@valhalla:$ symfony plugin:install sfNicEditPlugin<br/></div>

<p>Instalação via Git</p>

<div class="wp-terminal">fonini@valhalla:$ git clone git://github.com/fonini/sfNicEditPlugin.git<br/></div>

<p>
Ou baixe o plugin <a href="http://plugins.symfony-project.org/get/sfNicEditPlugin/sfNicEditPlugin-1.0.1.tgz" rel="nofollow externo">aqui</a> e extraia para a pasta plugins.</p>
<p>Você deve ativar o plugin, editando o arquivo config/ProjectConfiguration.class.php.</p>
<pre class="brush: php; title: ; notranslate">
class ProjectConfiguration extends sfProjectConfiguration{
	public function setup(){
		$this-&gt;enablePlugins(array('sfDoctrinePlugin', 'sfNicEditPlugin', '...'));
	}
}
</pre>
<p>Após ativar o plugin, você deve publicar os arquivos CSS e JS utilizados por ele. Rode o seguinte comando:</p>

<div class="wp-terminal">fonini@valhalla:$ symfony plugin:publish-assets<br/></div>

<p>Por último, limpe o cache:</p>

<div class="wp-terminal">fonini@valhalla:$ symfony cc<br/></div>

<p></p>
<p><strong>Usando o widget</strong></p>
<p>Basta você editar a classe que gera o form em que você vai usar o NicEdit, por exemplo lib/form/doctrine/NewsForm.class.php.</p>
<pre class="brush: php; title: ; notranslate">
public function configure(){
	$this-&gt;setWidget('text', new sfWidgetFormTextareaNicEdit(array('fullPanel' =&gt; true), array('cols' =&gt; 100, 'rows' =&gt; 20)));
}
</pre>
<p>Pretendo disponibilizar uma nova versão em breve com todos os parâmetros de configuração disponíves no NicEdit. Entre em contato em caso de dúvida. Abraço!</p>
]]></content:encoded>
			<wfw:commentRss>http://www.fonini.net/blog/sfniceditplugin-adicione-um-editor-de-texto-rico-aos-seus-forms-no-symfony/feed</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Quarto e último dia de palestras no FISL11</title>
		<link>http://www.fonini.net/blog/quarto-e-ultimo-dia-de-palestras-no-fisl11</link>
		<comments>http://www.fonini.net/blog/quarto-e-ultimo-dia-de-palestras-no-fisl11#comments</comments>
		<pubDate>Mon, 26 Jul 2010 09:13:12 +0000</pubDate>
		<dc:creator>fonini</dc:creator>
				<category><![CDATA[Geral]]></category>
		<category><![CDATA[Evento]]></category>
		<category><![CDATA[FISL11]]></category>
		<category><![CDATA[Software Livre]]></category>

		<guid isPermaLink="false">http://www.fonini.net/blog/?p=114</guid>
		<description><![CDATA[Último dia do FISL11. No geral, o fórum valeu muito a pena, muitas palestras legais, algumas nem tanto, mas o que importa é a contribuição de cada um dos palestrantes com o software livre. O evento foi muito bem organizado, exceto a infra-estrutura wireless que decepcionou todo mundo novamente. Mas nem tudo é perfeito e [...]]]></description>
			<content:encoded><![CDATA[<p>
	Último dia do FISL11. No geral, o fórum valeu muito a pena, muitas palestras legais, algumas nem tanto, mas o que importa é a contribuição de cada um dos palestrantes com o software livre. O evento foi muito bem organizado, exceto a infra-estrutura wireless que decepcionou todo mundo novamente. Mas nem tudo é perfeito e ainda assim quero muito voltar no ano que vem. Ganhei uma camiseta do iG preenchendo um cadastro (sem validação nenhuma, por sinal). Destaque também para os adesivos muito legais do iG, alguns com os Ditados Populares (<a href="http://goncin.wordpress.com/2010/06/21/ditados-populares-em-php/" rel="externo nofollow">parte 1</a>, <a href="http://goncin.wordpress.com/2010/06/29/ditados-populares-em-php-parte-2/" rel="externo nofollow">parte 2</a>, <a href="http://goncin.wordpress.com/2010/07/22/ditados-populares-em-php-parte-3-a-batelada-final/" rel="externo nofollow">parte 3</a>), criação do Fausto Cintra (<a href="http://twitter.com/g0nc1n" rel="externo nofollow">@g0nc1n</a>), alguns reescritos em Ruby e Python, além de algumas frases legais em Shell Script.</p>
<p>
	<strong>09:00 - Testes automatizados para o desenvolvimento colaborativo (Rodrigo Damazio)</strong></p>
<p>
	Palestra muito boa, explicando alguns aspectos sobre testes automatizados, com alguns exemplos em Java e Python. Também foram mostradas algumas ferramentas open-source para auxilar no desenvolvimento, bem como uma leve explicação sobre frameworks de injeção de dependência.
	 </p>
<p>
	<strong>10:00 - O Hacker e O Administrador de Redes (Paulo Fernando Lanella)</strong></p>
<p>
	Confesso que dormi em alguns momentos da palestra, que tratou sobre a cultura hacker e a rotina do administrador de redes, mas não foi legal como parece pelo título. A palestra teve uma parte legal, que era uma imagem da rotina do SysAdmin escrita em inglês com algumas frases engraçadinhas.
	 </p>
<p>
	<strong>11:00 - Novidades do Django 1.2 e o que vem por aí (Marcos Daniel Petry)</strong></p>
<p>
	Palestra destinada a quem já conhece o Django, apresentando as novidades da nova versão. Quem não conhece, com certeza ficou com vontade de testar e usar.
	 </p>
<p>
	<strong>13:00 - Quer aprender a programar de verdade? Pergunte-me como! (Henrique Bastos)</strong></p>
<p>
	A palestra abordou como os dojos podem ajudar que quer aprender a programar ou deseja aumentar seus conhecimentos. Também mostrou como é possível montar um pequeno grupo de estudos para aprender uma determinada linguagem colaborativamente, distribuir tarefas entre os participantes, discutir as soluções apresentadas e participar de eventos.
	 </p>
<p>
	<strong>15:00 - Criando soluções inteligentes com Shell Script (Rafael de Carvalho Farias)</strong></p>
<p>
	Shell Script é muito massa. O palestrante mostrou como criar um script para configuração de servidores Linux, evitando tarefas repetitivas e automatizando algumas outras. Você pode ajudar e acompanhar o desenvolvimento do script no site do palestrante e desenvolvedor: <a href="http://www.rafaelfarias.com" rel="externo nofollow">http://www.rafaelfarias.com</a>
	 </p>
<p>
	<strong>16:00 - Depurando o kernel Linux de forma interativa com KGDB (Edjunior Barbosa Machado, Breno Leitão)</strong></p>
<p>
	Palestra bem técnica explicando como depurar o kernel do Linux para a resolução de problemas. Os palestrantes ressaltaram que o próprio Linux Torvalds não usa depuradores, mas os desenvolvedores estão autorizados a usá-los
	 </p>
<p>
	<strong>18:00 - <em>Cancelada</em> - Database Refactoring com PostgreSQL (Fabrízio de Royes Mello</strong></p>
<p>
	
	 </p>
<p>
	<strong>18:00 - oVirt - Ambiente minimalista de virtualização para servidores (Ricardo Marin Matinata)</strong></p>
<p>
	Usando o Fedora como base, o palestrante mostrou como criar um ambiente confiável e minimalista para virtualizar servidores. Dormi em alguns momentos e saí na metade.
	 </p>
<p>
	<strong>19:00 - FOSS Business Basics (Jon "maddog" Hall)</strong></p>
<p>
	Última palestra do FISL que assisti. O grande Maddog mostrou o que é necessário ter para ganhar dinheiro com software livre. Infelizmente tive que sair na metade pois o ônibus ia sair em breve :(
	 </p>
<p>
	É isso ai gurizadinha, terminou mais um FISL que valeu muito a pena, apesar de ser muito cansativo, mas tentaremos estar aqui novamente no ano que vem. </p>
<p>Veja <a href="http://www.flickr.com/photos/39474373@N05/sets/72157624461156003/" rel="externo nofollow">aqui</a> algumas fotos do evento. Obrigado por terem paciência de ler estes posts. Grande abraço!</p>
]]></content:encoded>
			<wfw:commentRss>http://www.fonini.net/blog/quarto-e-ultimo-dia-de-palestras-no-fisl11/feed</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
	</channel>
</rss>

