symfony

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

Adicionando um filtro customizado no admin generator (symfony 1.2)

Tenho uma tabela (1-N) que possui diversos telefones relacionados.

config/schema.yml:


imovel:
  id:
  ()
  created_at:

imovel_telefone:
  id:
  imovel_id:
  telefone:   varchar(20)
  created_at:
 

No admin generator, será necessário criar um filtro customizado, porque o telefone não faz parte da tabela imovel. Para isso, vamos alterar o arquivo lib/filter/ImovelFormFilter.class.php


class ImovelFormFilter extends BaseImovelFormFilter
{
  public function configure() {
     $this->widgetSchema[‘telefone’] = new sfWidgetFormInput();
     $this->validatorSchema[‘telefone’] = new sfValidatorPass(array(‘required’ => false));
  }

  public function getFields() {
    return array_merge(array(‘telefone’ => ‘Telefone’), parent::getFields());
  }

  protected function addTelefoneColumnCriteria(Criteria $criteria, $field, $values) {
    $criteria->addJoin(ImovelPeer::ID, TelefoneImovelPeer::IMOVEL_ID, Criteria::LEFT_JOIN);
    $criteria->add(TelefoneImovelPeer::TELEFONE, $values);
  }
}
 

Para finalizar, altere o generator.yml do seu backend e adicione o field telefone.


filter:
  fields:
    display:  [ telefone, campo1, campo2 ]
 

filter
php
symfony

Comments (0)

Permalink

Symfony Experts

Dia 21 de fevereiro o pessoal do symfonynerds.com lançou um novo portal: www.symfonyexperts.com

O site é basicamente igual ao WP Questions, porém totalmente voltado para o symfony.

Vale a pena dar uma olhada.

Mais informações aqui: http://symfonynerds.com/blog/?p=359

php
symfony

Comments (0)

Permalink

Removendo recursivamente diretórios .svn

Comecei a migrar essa semana todos meus projetos para o SVN. Acontece que, se quisermos baixar o arquivo de um SVN e migrar para outro, temos problemas porque é criado um diretório .svn/ dentro de todos subdiretórios. Para resolver este problema, criei um alias que remove recursivamente os diretórios .svn/ da pasta corrente.

Com o comando find conseguimos achar os diretórios .svn:

$ find . -type d -name .svn

./.svn
./sourceA/.svn
./sourceB/.svn
./sourceB/module/.svn
./sourceC/.svn

Podemos, junto ao find, passar o comando rm -rf:

$ rm -rf `find . -type d -name .svn`

Podemos agora criar um alias e adicionar ao profile do usuário:

$ echo “alias csvn=‘echo ‘removendo pastas .svn/’; rm -rf `find . -type d -name .svn`’” >> ~/.bash_profile
$ . ~/.bash_profile
$ svn checkout svn://server.com/svn/project
A project/index.php
A project/sourceA/a.php
A project/sourceA/a1.php
A project/sourceA/a2.php
A project/sourceB/b.php
A project/sourceB/module/lib.php
A project/sourceC/c.php
Checked out revision 15.
$ cd project
$ csvn
removendo pastas .svn/

Agora podemos fazer checkout de um SVN, jogar para outro e versionar normalmente.

Observações:

-> Tomar muito cuidado para não utilizar este comando na raiz ou em algum diretório perigoso.
-> Não é recomendável utilizar este alias como root.

É isso! Valeu!

php
symfony
unix

Comments (2)

Permalink

Manipulando campos BLOB com symfony 1.2 e Propel 1.3

Estou começando a dar meus primeiros passos com o symfony 1.2. Acabei de perder 1 hora pesquisando sobre como manipular campos BLOB no MySQL.

Tenho uma tabela que possui uma coluna imagem do tipo BLOB. Quando tento obter o valor desta coluna com o $objeto->getImagem(), o retorno é um resource (vardump: Resource id #403). Antigamente, no symfony 1.0, o próprio método era responsável por ‘converter’ o resource para string.

Agora, pesquisando na internet, descobri um modo de fazer esta ‘conversão’. Podemos fazer override da função getImagem() ou criar uma nova. No meu caso, resolvi criar uma função nova. Considerando minha tabela noticia:

lib/model/Noticia.class.php


class Noticia extends BaseNoticia
{
    public function getPathImg() {
        $content="";
        if (is_resource($this->getImagem())) {
          while(!feof($this->getImagem())){
                    $content.= fread($this->getImagem(), 1024);
                  }
                  rewind($this->getImagem());
                  return ‘/uploads/banners/’.$content;
                } else return ‘/uploads/banners/’.$this->getImagem();   
    }
}
 

Achei esta dica no site do propel, em: http://propel.phpdb.org/trac/ticket/672

Pelo status do ticket, este retorno passou a ser um resource por questão de flexibilidade e performance.

Gostaria de obter comentários sobre performance e/ou sugestão sobre esta solução que achei.

Valeu!

php
symfony

Comments (0)

Permalink

symfony é um dos finalistas para o 2009 Sourceforge Community Choice Awards

Graças à dedicada comunidade, o symfony foi escolhido como um dos finalistas para o 2009 Sourceforge Community Choice Awards em três categorias!

  • Best Project (Melhor projeto)
  • Best Tool or Utility for Developers (Melhor ferramenta para desenvolvedores)
  • Best Project for the Enterprise (Melhor projeto para empresa)


Alguns outros projetos também são finalistas como: phpMyAdmin, FLOW3, Joomla, TYPO3, and vtiger CRM.

Se você gosta do symfony, ou se gosta de PHP, ou se quer estar junto com a gente, vote: http://sourceforge.net/community/cca09/vote/

php
symfony

Comments (0)

Permalink

sfPropelSyncContentPlugin: Plugin para importar/exportar o banco de dados entre ambientes (dev/prod)

Saiu no dia 16/10/2008 um novo plugin chamando sfPropelSyncContentPlugin

Esse plugin tem a função de tornar mais prático a manipulação do banco de dados. Com ele podemos facilmente importar todo o banco de dados de produção para desenvolvimento e vice-versa. Ele utiliza o mysqldump e alguns outros comandos do mysql.

Podemos atualizar nossa base de desenvolvimento com os dados de produção com o seguinte comando:

$ symfony propel-sync-content frontend dev from prod@production

Por outro lado, podemos fazer o inverso, ou seja, atualizar a base de produção com os dados de desenvolvimento:

$ symfony propel-sync-content frontend dev to prod@production

O plugin também permite atualização de diretórios. Basta configurar o app.yml em: apps/frontend/config/app.yml


all:
  sfPropelSyncContentPlugin:
    content:
      * "web/uploads"
 

Com a configuração acima, além de atualizarmos a base de dados, vamos atualizar a pasta web/upload também.

Valeu!

plugins
producao
symfony

Comments (0)

Permalink

Dinamizando conteúdo no symfony com slots

Em diversos casos precisamos completar nosso layout com mais de uma área dinâmica. Por exemplo, suponha uma situação em que nós precisamos ter as meta-tags diferentes para cada action executada. No nosso caso, nós teremos as meta-tags padrões e estaremos fazendo um override delas no template. A intenção é termos as meta-tags de description e keywords (nesse exemplo) dinâmicas. Sendo assim, cada página terá as keywords e descriptions respectivas. Isso é fundamental para motores de busca, SEO, etc..

Para essa solução, utilizaremos o slot. Basicamente, slot é um lugar que você estará reservando para um conteúdo específico. Esse lugar pode ser definido no layout, template ou até em um partial. Está muito abstrato ainda, não é? Vou mostrar um exemplo.

Podemos ter por exemplo no apps/APLICACAO/templates/layout.php algo assim:


<html>
<head>
 <?php if (has_slot(‘http_metas’)): ?>
   <?php include_slot(‘http_metas’) ?>
 <?php endif: ?>
</head>
 

Dentro de um template, apps/APLICACAO/modules/faleconosco/indexSuccess.php poderíamos ter um código como esse:


<?php slot(‘http_metas’) ?>
 <meta name="title" content="Fale conosco" />
 <meta name="description" content="Entre em contato conosco pelo formulário abaixo ou fale direto conosco pelo telefone xxxxx" />
 <meta name="keywords" content="contato, telefone, etc, etc" />
<?php end_slot() ?>
 

Ou seja, quando o usuário acessar a action index do módulo faleconosco, as meta-tags dele serão essas citadas acima. É claro que esse é um exemplo muito simples.

Isso pode ficar mais interessante pegando palavras-chave de um banco de dados, ou a descrição de um produto, artigo, etc.. É bom lembrar que a meta-tag de description tem um ideal de caracteres. Se não me engano é algo em torno de 200~300. Corrijam se estiver errado.

Vale a pena lembrar que para setar os meta-tags não é obrigatório utilizar os slots. Eles podem ser setados direto na action apps/APLICACAO/modules/faleconosco/actions/actions.class.php:


$this->getResponse()->setTitle(‘My Title’);
$this->getResponse()->addMeta(‘description’,‘My Description’);
$this->getResponse()->addMeta(‘keywords’,‘My Keywords’);
 

Esse foi só um exemplo da utilização dos slots. Eles possuem diversas outras utilidades para dinamizar conteúdos.

php
symfony

Comments (1)

Permalink

Descompactando arquivos ZIP vindo de um form com symfony

Nesse post vou mostrar como faço para tratar arquivos ZIP vindo de um formulário.

Primeiramente, precisamos ter instalado a biblioteca zip. Para isso, podemos utilizar o comando abaixo:

$ pecl install zip

Suponhamos um formulário simples:


    <?php echo form_tag("upload/do" , "method=post multipart=true") ?>
      <?php echo input_file_tag("anexos") ?>
    </form>
 

Na action que irá tratar o formulário:


    $phpFile = sfContext::getInstance()->getRequest()->getFile(‘anexos’);

    $zip = new ZipArchive();
    $res = $zip->open($phpFile["tmp_name"]);
    if ($res === TRUE) {
        $zip->extractTo(sfConfig::get(‘sf_upload_dir’).‘/imagens/’); // web/uploads/imagens
        $zip->close();
    } else {
         // logar o erro onde preferir..
        // echo ‘failed, code:’ . $res;
    }
 

Neste exemplo não estou considerando validação do tipo de arquivo, etc..

É obrigatório ter no formulário multipart=true senão não irá funcionar.

Valeeeeu! =)

php
symfony

Comments (0)

Permalink