php

Symfony2 Exception – DateTime::__construct(): It is not safe to rely on the system’s timezone settings.

Dando os primeiros passos com o Symfony2, acabei batendo de frente com um erro que provavelmente veio da configuração do MAMP.

DateTime::__construct(): It is not safe to rely on the system’s timezone settings. You are required to use the date.timezone setting or the date_default_timezone_set() function. In case you used any of those methods and you are still getting this warning, you most likely misspelled the timezone identifier. We selected ‘America/Sao_Paulo’ for ‘BRT/-3.0/no DST’ instead

O php que eu estou chamando fica no /usr/bin/php.

Para solucionar o problema eu passei o arquivo de configuração pela linha de comando.

$ php -c /Applications/MAMP/bin/php/php5.3.6/conf/ app/console
Symfony version 2.0.0 – app/dev/debug
Usage:
  [options] command [arguments]
(...)

Criei um alias para melhorar mais ainda:

$ alias sf2=“php -c /Applications/MAMP/bin/php/php5.3.6/conf/”
$ sf2 app/console
Symfony version 2.0.0 – app/dev/debug
Usage:
  [options] command [arguments]
(...)

php
symfony2

Comments (0)

Permalink

Compilando e instalando a extensão intl no OS X 10.6.8 – Symfony2

Um dos requisitos da instalação do Symfony2 é a extensão intl.so do PHP.
Vou mostrar aqui todos os passos que executei para compilar e instalar.

$ uname -a
Darwin pedrocasado.local 10.8.0 Darwin Kernel Version 10.8.0: Tue Jun 7 16:32:41 PDT 2011; root:xnu-1504.15.3~1/RELEASE_X86_64 ×86_64

1 – Fiz o download do MAMP 2.0 e instalei.

2 – É necessário termos instalado uma lib chamada ICU. Suponho que você já tenha o MacPorts instalado para efetuar esse próximo passo:

$ sudo port install icu
Password:
—-> Fetching archive for icu
—-> Attempting to fetch icu-4.6.1_0.darwin_10.x86_64.tbz2 from http://packages.macports.org/icu
—-> Attempting to fetch icu-4.6.1_0.darwin_10.x86_64.tbz2.rmd160 from http://packages.macports.org/icu
—-> Installing icu 4.6.1_0<br /> ---> Activating icu 4.6.1_0
—-> Cleaning icu
$ icu-config
usage: icu-config [ —noverify ] [ —bindir ] [ —cc ] [ —cflags ] [ —cflags-dynamic ] [ ] [ —cppflags ] [ —cppflags-dynamic ] [ ] [ —cppflags-searchpath ] [ —cxx ] [ —cxxflags ] [ —cxxflags-dynamic ] [ ] [ —detect-prefix ] [ —exec-prefix ] [ —exists ] [ —help, -?, —usage ] [ —icudata ] [ —icudata-install-dir ] [ —icudata-mode ] [ —icudatadir ] [ —invoke ] [ —invoke= ] [ —ldflags ] [ —ldflags-layout ] [ —ldflags-libsonly ] [ —ldflags-searchpath ] [ —ldflags-system ] [ —ldflags-icuio ] [ —ldflags-obsolete ] [ —mandir ] [ —prefix ] [ —prefix=XXX ] [ —sbindir ] [ —shared-datadir ] [ —shlib-c ] [ —shlib-cc ] [ —sysconfdir ] [ —unicode-version ] [ —version ] [ —incfile ] [ —incpkgdatafile ] [ —install ] [ —mkinstalldirs ]
$

Você terá problemas se efetuar os próximos passos sem ter o ICU instalado: configure: error: Unable to detect ICU prefix or /usr/bin/icu-config failed. Please verify ICU install prefix and make sure icu-config works.

3 – Vá até o diretório /Applications/XAMPP/xamppfiles/lib/php/php-5.3.4/ext/intl e execute os comandos abaixo:


$ cd /Applications/XAMPP//xamppfiles/lib/php/php-5.3.4/ext/intl
$ phpize
Configuring for:
PHP Api Version: 20090626
Zend Module Api No: 20090626
Zend Extension Api No: 220090626

$ ./configure —enable-intl
checking for grep that handles long lines and -e… /usr/bin/grep
checking for egrep… /usr/bin/grep -E
checking for a sed that does not truncate output… /usr/bin/sed
checking for cc… cc
checking for C compiler default output file name… a.out
(…)
checking for icu-config… /opt/local/bin/icu-config
checking for location of ICU headers and libraries… /opt/local
checking for ICU 3.4 or greater… found 4.6.1
checking for g++… g++
(…)
configure: creating ./config.status
config.status: creating config.h

$ make test
(…)

4 – Agora vamos compilar e copiar a extensão para o diretório do MAMP.

$ sudo make install
Installing shared extensions: /usr/lib/php/extensions/no-debug-non-zts-20090626/
$ ls -l /usr/lib/php/extensions/no-debug-non-zts-20090626/
total 480
-rwxr-xr-x 1 root wheel 223864 Aug 6 16:13 intl.so
$ cp /usr/lib/php/extensions/no-debug-non-zts-20090626/intl.so /Applications/MAMP/bin/php/php5.3.6/lib/php/extensions/no-debug-non-zts-20090626/
$

5 – Sua extensão já está compilada e pronta para ser utilizada. Vamos adicionar a linha extension=intl.so no php.ini:

$ echo ‘extension=intl.so’ >> /Applications/MAMP//bin/php/php5.3.6/conf/php.ini

Estou disponibilizando aqui o link do intl.so caso alguém queira tentar utilizar.

É isso ai.
Valeu!

php
symfony2

Comments (0)

Permalink

Instalando o Symfony2

Fala galera blz?

Como vocês sabem, dia 28/07 foi lançada a versão 2 do Symfony. E claro, não pudemos deixar de instalar e ver as suas mudanças!
Para começar, seguiremos o passo-a-passo do próprio site do symfony, que agora é symfony.com :D

Baixe o sandbox (http://symfony.com/download) e descompacte na pasta root de seu webserver. De cara notamos que a estrutura de diretórios mudou um pouco. Para ver as diferenças da versão 1, vá em http://symfony.com/doc/current/cookbook/symfony1.html.
Depois de descompactado, começa uma parte nova e interessante: a configuração via browser.

“Symfony2 comes with a visual server configuration tester to help avoid some headaches that come from Web server or PHP misconfiguration.”

Ou seja, agora ele detectará erros nas configurações do seu PHP e no seu webserver! Basta entrar na URL http://localhost/Symfony/web/config.php para identificá-los.

Nesta página você verá erros que deverá corrigir, e alguns warnings que corrige se quiser. Abaixo os erros que apareceu para mim:

  1. You are running PHP version “5.2.17“, but Symfony needs at least PHP5.3.2“ to run. Before using Symfony, install PHP5.3.2“ or newer.
  2. Change the permissions of the “app/cache/“ directory so that the web server can write into it.
  3. Change the permissions of the “app/logs/“ directory so that the web server can write into it.
  4. Upgrade your APC extension (3.0.17+)


Os passos 1, 2 e 3 foram tranquilos. Bastando dar permissões nas pastas e atualizar a versão do PHP (estou usando a versão antiga pois estou no trabalho rs).
No passo 4, tive que instalar uma versão nova do APC (Alternate PHP Cache), um framework para otimizar o cache do PHP.
Para quem usa o Linux é mais fácil, basta baixar o pacote em http://pecl.php.net/package/APC.
Para quem usa o Windows, achei um ótimo tutorial: http://candidosalesg.wordpress.com/2011/03/07/como-habilitar-cache-apc-php-no-windows/

Depois de corrigido os problemas que o SF2 encontrou, você pode já configurar via browser sua aplicação, como selecionar o tipo de banco de dados (MySQL, PostgreSQL, Oracle), login, senha etc… ou pode pular essa parte e ir direto pra Welcome Page.

Pronto! Sua instalação está concluida. Qualquer dúvida, deixe nos comentários. Em breve postaremos mais coisas sobre a versão 2 desse framework bizarro!

Abs

php

Comments (13)

Permalink

How to remove/unset the filters in an admin module. [symfony 1.4]

In your generator.yml use class: false for the filter:


config:
      actions: ~
      fields:  ~
      list:    ~
      filter:
        class: false
      form:    ~
      edit:    ~
      new:     ~
 

php

Comments (1)

Permalink

Projeto QuemLiga

Eu (Pedro Casado) e meu amigo Bernardo Alves criamos um projeto chamado Quem Liga feito com symfony 1.4 e propel 1.4.

O projeto ‘Quem liga’ é um banco de dados que armazena telefones de pessoas/empresas que incomodam nosso dia-a-dia oferecendo produtos, cobrando contas, se passando por outras pessoas, etc.

Se você recebeu uma ligação, uma mensagem ou é apenas um número desconhecido e quer saber mais sobre ele, você não é o único. Faça uma busca pelo telefone em nossa base e veja o comentário de outras pessoas.

Se ainda não houver comentários, seja o primeiro e deixe seu recado.

Estamos abertos para sugestões e comentários.

www.quemliga.com.br

php
propel
symfony

Comments (0)

Permalink

Selectbox para escolher cidade de acordo com o estado utilizando widgets e symfony 1.4 (Propel/Doctrine)

Nesse post vou explicar como fazer um selectbox que só mostra as cidades referentes ao respectivo estado selecionado anteriormente.

stado_cidade_sfDependentPlugin1.jpg

Vamos considerar a seguinte modelagem (config/schema.yml):


propel:
  estado:
    id:
    uf:   varchar(2)
    nome: varchar(60)

  cidade:
    id:
    nome:       varchar(40)
    estado_id:  { type: integer, foreignTable: estado, foreignReference: id, onDelete: cascade }
    capital:    varchar(1)
    created_at:
    updated_at:

  usuario:
    id:
    nome:        varchar(100)
    cidade_id:  { type: integer, foreignTable: cidade, foreignReference: id, onDelete: cascade }
 

Para preencher as tabelas estado e cidade, utilizei o seguinte SQL com dados do Brasil. CARGA_CIDADES_E_ESTADOS_BRASIL.zip

O próximo passo é instalar o plugin sfDependentSelectPlugin em nosso projeto. Baixe o arquivo sfDependentSelectPlugin-0.1.5.tgz e descompacte na pasta plugins/ de seu projeto. Eu renomeei a pasta de plugins/sfDependentSelectPlugin-0.1.5/ para plugins/sfDependentSelectPlugin/.

Habilite o plugin no seu projeto (config/ProjectConfiguration.class.php)

$this->enablePlugins(…, ‘sfDependentSelectPlugin’);

Limpe o cache do seu projeto:
$ php symfony cc

Publique o javascript do plugin com o comando:
$ php symfony plugin:publish-assets

Crie o CRUD para o usuário:
$ php symfony propel:generate-module frontend usuario Usuario

Agora vamos alterar o form do usuário: lib/form/UsuarioForm.class.php:
class UsuarioForm extends BaseUsuarioForm
{
  public function configure()
  {
    $this->widgetSchema[‘estado_id’] = new sfWidgetFormPropelChoice(array(
            ‘model’     => ‘Estado’,
            ‘add_empty’ => true
     ));

    $this->widgetSchema[‘cidade_id’] = new sfWidgetFormPropelDependentSelect (array(
            ‘model’     => ‘Cidade’,
            ‘depends’   => ‘Estado’,
            ‘add_empty’ => ‘Selecione a cidade’
    ));

    $this->validatorSchema[‘estado_id’] = new sfValidatorPropelChoice(array(
        ‘model’ => ‘Estado’,
    ));

    $this->validatorSchema[‘cidade_id’] = new sfValidatorPropelChoice(array(
        ‘model’ => ‘Cidade’,
    ));
  }
}

Vale lembrar que você pode utilizar o sfWidgetFormDoctrineDependentSelect ao invés do sfWidgetFormPropelDependentSelect.

Agora vamos alterar o template para receber o widget do estado também (\apps\APLICACAO\modules\usuario\templates\_form.php)


      <tr>
        <th><?php echo $form[‘estado_id’]->renderLabel() ?></th>
        <td>
          <?php echo $form[‘estado_id’]->renderError() ?>
          <?php echo $form[‘estado_id’] ?>
        </td>
      </tr>
      <tr>
        <th><?php echo $form[‘cidade_id’]->renderLabel() ?></th>
        <td>
          <?php echo $form[‘cidade_id’]->renderError() ?>
          <?php echo $form[‘cidade_id’] ?>
        </td>
      </tr>

Pronto! Acesse a página do módulo e veja o select da cidade dependente do select do estado.

Esse plugin faz um pouco mais do que isso como dependência infinita, utilização de ajax, etc.. Para ver a documentação completa acesse: http://www.symfony-project.org/plugins/sfDependentSelectPlugin

ajax
doctrine
form
php
plugins
propel

Comments (3)

Permalink

Utilizando Swift numa task (symfony 1.3/1.4)

Ao utilizar esse código na task:

$message = Swift_Message::newInstance();

Tive o seguinte erro:

PHP Fatal error: Class ‘Swift_Message’ not found in […]

Solução:

$message = $this->getMailer()->compose("from@mail","to@mail","subject","body");

cli
php
snippet
swift

Comments (0)

Permalink

symfony 1.0 e Swift 4

Ao utilizar o Swift 4 com o symfony 1.0, tive o seguinte erro:

Fatal error: Cannot instantiate abstract class Swift in /[…]/apps/frontend/modules/[…]/actions/actions.class.php on line 40

Não sei porque o autoload do symfony não funcionou. Só consigo utilizar a classe incluindo o swift_required.php

require_once(dirname(FILE).‘/../lib/swift/lib/swift_required.php’);

Se estiver tendo problemas de tela branca com o Swift, utilize:


error_reporting(E_ALL);
ini_set(‘display_errors’, ‘1’);
 

Aqui vai um exemplo completo:


// swift 4.0.6
require_once(dirname(FILE).‘/../lib/swift/lib/swift_required.php’);

$transport = Swift_SmtpTransport::newInstance(‘smtp.servidor.com.br’, 25)
  ->setUsername(‘usuario’)
  ->setPassword(‘senha’)
  ->setTimeout(60);

$mailer = Swift_Mailer::newInstance($transport);
$message = Swift_Message::newInstance("Titulo")
  ->setFrom("from@email.com")
  ->setTo("para@email.com")
  ->setBody("Mensagem", ‘text/html’);

$mailer->send($message);
 

Aqui fala um pouco sobre esse assunto: http://forum.symfony-project.org/index.php/m/77609/

php
swift

Comments (0)

Permalink

Aumentando o timeout da sessão do usuário (sf 1.2)

Editar arquivo apps/(aplicacao)/config/factories.yml e alterar os segundos do ‘timeout’:

all:
  user:
   class: myUser
   param:
     timeout:         2700
 

php
snippet
yml

Comments (0)

Permalink

Tratando múltiplos telefones com embedded forms no admin generator

No meu post anterior, comentei sobre uma tabela (imovel) que possui diversos telefones (1-N). Nesse post vou tentar explicar como fiz o formulário de edição para tratar os N telefones dos imoveis.

O jeito que fiz vai ficar como a imagem abaixo. Vou deixar sempre 3 campos em branco para adicionar novos telefones. Para remover um telefone, basta deixa-lo em branco (em breve eu crio um botão com ajax para remover).

Vamos começar editando o lib/form/ImovelForm.class.php

class ImovelForm extends BaseImovelForm
{
  public function configure()
  {
      $todoWrapperForm = new sfForm();
      if ($this->getObject()->countTelefoneImovels() > 0) {
          foreach ($this->getObject()->getTelefoneImovels() as $telefone){
             $todoWrapperForm->embedForm(‘tel_’.$telefone->getId(), new TelefoneImovelForm($telefone));
          }
      }
    // adiciona os 3 forms em branco
    $todoWrapperForm->embedForm(‘tel_A’, new TelefoneImovelForm());
    $todoWrapperForm->embedForm(‘tel_B’, new TelefoneImovelForm());
    $todoWrapperForm->embedForm(‘tel_C’, new TelefoneImovelForm());

    $this->embedForm(‘tels’, $todoWrapperForm);

    $this->validatorSchema->setOption(‘filter_extra_fields’, false);
    $this->validatorSchema->setOption(‘allow_extra_fields’, true);

  }

  public function bind(array $taintedValues = null, array $taintedFiles = null) {
    foreach($this->embeddedForms[‘tels’]->getEmbeddedForms() as $key=>$telForm)
    {
       if ($taintedValues[‘tels’][$key][‘telefone’] == "")
       {
          unset($this->embeddedForms[‘tels’]->embeddedForms[$key], $taintedValues[‘tels’][$key]);
          $telForm->getObject()->delete();
       }
    }
    parent::bind($taintedValues, $taintedFiles);
  }

  // http://trac.symfony-project.org/ticket/5842
  public function saveEmbeddedForms($con = null, $forms = null, $taintedValues = null, $taintedFiles = null)
  {
    //atualiza o imovel_id da telefone_imovel depois de ter o imovel salvo
    //http://www.thatsquality.com/articles/embedding-child-forms-with-sfformpropel-a-practical-example
    foreach($this->embeddedForms[‘tels’]->getEmbeddedForms() as $telForm)
    {
       if (!$telForm->getObject()->getImovelId())
       {
         $telForm->getObject()->setImovelId($this->getObject()->getId());
       }
    }

    if (is_null($con))
    {
      $con = $this->getConnection();
    }

    if (is_null($forms))
    {
      $forms = $this->embeddedForms;
    }

    if (is_null($taintedValues))
   {
      $taintedValues = $this->taintedValues;
   }

   if (is_null($taintedFiles))
   {
      $taintedFiles = $this->taintedFiles;
   }

   foreach ($forms as $key => $form)
   {
       // é esse trecho que corrige o problema
       if ($form instanceof sfFormPropel)
       {
          $form->bindAndSave($taintedValues[$key], $taintedFiles);
       } else {
          $this->saveEmbeddedForms($con, $form->getEmbeddedForms(), $taintedValues[$key], $taintedFiles);
       }
   }
 }
}
 

Agora vamos criar um partial para mostrar os telefones no formulário. Crie o arquivo apps/backend/imovel/templates/_tels.php


<div id="embed_tels">
<?php foreach ($form->getEmbeddedForms() as $key => $itemForm) {
             if (substr($key , 0 , 8) == ‘tels’): ?>
                 <div class="sf_admin_form_row sf_admin_text sf_admin_form_field_telefone<?php echo preg_replace("/[^0-9]/", ‘’, $key); //only number ?>">
                    <div>
                       <?php echo $form[$key]; ?>
                    </div>
                 </div>
             <?php endif ?>
<?php } ?>
</div>
 

Depois de ter criado o partial, basta adiciona-lo ao apps/backend/imovel/config/generator.yml


edit:
  display: [_tels, campo1, campo2]
 

É isso.. tive como referência diversos sites, mas principalmente o blog that’s quality.

http://www.thatsquality.com/search?query=embedded

embedded form
form
php
propel

Comments (0)

Permalink