January 2008

Criando um Pake Task p/ symfony

Pake Task são atalhos (ou alias) para executar comandos na linha de comando.

Atualmente, a documentação do symfony não explica como criar pake tasks. Vou tentar explicar um pouco o que eu entendi.Primeiramente, o arquivo deverá ficar em myproject/data/tasks. Crie a pasta, caso não exista.

Vou criar um paketask para zipar a pasta do projeto e colocar no diretório anterior.

myproject/data/tasks/sfPakeZip.php:


pake_desc(‘Cria um zip do projeto’);
// aqui vem a descrição do pakepake_task(‘zip’, ‘project_exists’);
// o primeiro parametro (zip) vai ser o nome do comando a ser digitado

function run_zip($task, $args)
// a declaracao é feita run_NOME_DO_COMAND
{
      pake_echo_action(‘tar’, ‘Criando o ZIP’);
      // vamos escrever essa frase na tela enquanto o comando nao termina

     exec(‘PROJ=`pwd | awk \’BEGIN {FS="/"} {print $NF}\’`;cd ..; tar -czf $PROJ.tgz $PROJ; cd $PROJ’);
     // o exec recebe os comandos SHELL a serem executados.
     // podemos chamar outros pake tasks aqui dentro, por exemplo:
     // run_freeze($task, $args);
}

Salve o arquivo. Limpe o cache: symfony cc

Rode o pake: symfony zip

php
symfony

Comments (3)

Permalink

Helper do symfony para fazer máscaras de campos input

Para facilitar o preenchimento de formulários com CNPJ,CEP,CPF e manter um
banco limpo, fiz alguns helpers para facilitar a nossa vida.

Esses helpers fazem uma máscara no campo input. As máscaras existentes são
para CNPJ, CPF, TELEFONE e SOMENTEMEROS.

Instalação


Download dos arquivos: formmask.zip

Copie o arquivo mask_func.js para o diretorio /web/js
Copie o arquivo FormMaskHelper.php para o diretorio /lib/helper
Limpe o cache

Utilizando


No template, chame o helper:

<?php use_helper("FormMask") ?>

Os helpers disponíveis são: input_cpfmask_tag , input_cnpjmask_tag,
input_telefonemask_tag, input_cepmask_tag, input_numeromask_tag

Eles são utilizados da mesma forma que um input_tag padrão;

Exemplo



<?php use_helper("FormMask") ?>

cpf: <?php echo input_cpfmask_tag("cpf" , "" , array("class" => "teste")) ?> <br />
cep: <?php echo input_cepmask_tag("cep") ?> <br />
cnpj: <?php echo input_cnpjmask_tag("cnpj") ?> <br />
telefone: <?php echo input_telefonemask_tag("telefone") ?> <br />
numeros: <?php echo input_numeromask_tag("telefone") ?> <br />

.

Demonstração


http://demo.symfonybr.com/index.php/formmask

Créditos


Elcio Ferreira desenvolveu o javascript utilizado nesse helper. Muito bom. http://elcio.com.br/ajax/mascara/

php
symfony

Comments (1)

Permalink

Utilizando Partial e Components



Partial


Se você quiser utilizar alguns códigos ou textos em sua página de outros arquivos, você pensa em include. No symfony existe um comando semelhante, que é o partial. Os partials são pedaços de códigos reutilizáveis, são armazenados na pasta templates/, contém código HTML e php embutido. Um arquivo partial SEMPRE começa com sublinhado (_), isso ajuda a distiguir os arquivos, já que eles ficam no mesmo diretório. Um partial pode ser incluido se estiver no mesmo módulo, em outro módulo, ou no diretório global templates/.
O comando para usar é include_partial(), os parâmetros são o nome do módulo e o nome do arquivo sem o sublinhado (_) e o .php.

Exemplo:


//myapp/modules/seumodulo/templates/_testepartial.php do mesmo módulo
//Como o partial está no mesmo módulo, você pode omiti-lo

<?php include_partial(‘testepartial’); ?>

//myapp/modules/fotos/templates/_testepartial.php
//‘fotos’ é um exemplo do nome do módulo

<?php include_partial(‘fotos/testepartial’);

“Como utilizar variáveis do meu template (indexSuccess.php por exemplo) na minha partial (no caso _testepartial.php)?”
Muita calma nessa hora.
Para resolver isso é muito simples, basta você definir uma variável no seumodulo/actions/actions.class.php

class seumoduloActions extends sfActions {
  public function executeIndex()
  {
    $this->total = 2000;
  }
}

Agora o seu template seumodulo/templates/indexSuccess.php terá:

<p>www.symfonybr.com</p>
<?php include_partial(‘testepartial’,array(‘totalpartial’ => $total)) ?>

E no myapp/modules/seumodulo/templates/_testepartial.php:

<p>Visitas: <?php echo $totalpartial; ?> por dia :x!</p>

Se você quiser pegar o conteúdo de uma partial sem exibi-lo, utilize o get_partial().



Components


E se você quiser ao invés de usar apenas alguns códigos ou textos, utilizar um template de outro módulo com suas próprias actions?
Muito mais calma nessa hora porque é pra isso que serve o components.

Digamos que você tem um site e tenha 2 links: um pra videos e outro pra fotos. Você agora quer exibir apenas o conteúdo do módulo videos e do módulo fotos.
No módulo videos, adicione em modules/videos/template/_index.php


<?php echo "Lista de videos"; ?>

Para que as actions do módulo videos funcionem no components, faça o seguinte:
Na pasta modules/videos/actions/ copie e cole o arquivo actions.class.php e renomeie para components.class.php.
Agora, altere ele onde tem

class videosActions extends sfActions

para

class videosComponents extends sfComponents

PS: Lembrar de trocar o nome do módulo (videos)

Agora na sua página principal, use o helper include_components():


<?php include_component(‘videos’,‘index’); ?>

Como no partial, você pode passar variáveis para os components:

<?php include_component(‘videos’,‘index’, array(‘foo’ => ‘bar’); ?>

;//No próprio componente
<?php echo $this->foo; ?> //retorna bar

//No _index.php
<?php echo $foo; ?> //retorna bar

A grande diferença é que no Components, você pode usar as actions do módulo, ou seja, colocar a lógica de programação (consulta de banco, por exemplo) no arquivo actions.class.php e utilizá-los no template.

O Partial não dá suporte ao actions.class.php, então seguindo o padrão MVC, você só usaria o partial para mostrar algum conteúdo html que não precise de lógica de programação.

php
symfony

Comments (2)

Permalink

Arquivos YAML podem ter comandos PHP (YAML can contain php code)

Esses dias estava mexendo num projeto que envolvia paths, etc.
Foi quando resolvi criar no app.yml o tal path:

app.yml



all:
  path:
    cartoes:   /cartoes

Ok. Eu usava isso da seguinte maneira na action:


()
$path = sfConfig::get("sf_root_dir") . sfConfig::get("app_path_cartoes") . "/";

Como eu tive que usar isso mais de uma vez, aconteceu de paths serem escritos errados como por exemplo:

// duas barras no meio
sfConfig::get("sf_root_dir")."/".sfConfig::get("app_path_cartoes")."/";
// sem a barra no final
sfConfig::get("sf_root_dir").sfConfig::get("app_path_cartoes");
// sem nenhuma barra
sfConfig::get("sf_root_dir").sfConfig::get("app_path_cartoes");

além de eu estar escrevendo código a mais…
Então, descobri que o YML aceita comandos de PHP, porém com alguns pequenos detalhes.


all:
  path:
    cartoes: <? php echo (sfConfig::get(‘sf_root_dir’)."/cartoes/\n" ?>

O lance é ficar atento ao “\n” no final, porque sem isso vai o YML fica inválido gerando erro.
Isso pode ser melhorado utilizando o echoln.


all:
  path:
    cartoes: <? php echoln (sfConfig::get(‘sf_root_dir’) . "/cartoes/" ?>

Pronto. Ai temos o path correto que utilizará apenas um sfConfig::get.
Isso pode ser usado para outros diversos casos, é claro.

php
symfony

Comments (1)

Permalink

Manipulando campo do tipo blob com symfony (Parte 2-2)

Vamos lá! Teremos que criar um novo component.A classe do componente deve ficar em apps/frontend/modules/arquivo/actions/components.class.php:

Action



class arquivoComponents extends sfComponents
{
}

?>

OBS: class NOME-DO-MODULOComponents extends…

Vamos criar um método executeLer().
Retorne um arquivo qualquer, apenas para teste. Aqui vou retornar o arquivo mais recente.


class arquivoComponents extends sfComponents
{
    public function executeLer() {
      $c->addDescendingOrderByColumn(ArquivoPeer::CREATED_AT);
      $arquivo = ArquivoPeer::doSelectOne($c);

      $this->bin = $arquivo->getImg(); // conteudo binario

      // não podemos ter layout já que essa action
      //só pode retornar o binário e nada de HTML
      $this->setLayout(false);
      $this->getResponse()->clearHttpHeaders();
      // atribuindo o header
     $this->getResponse()->setHttpHeader("Content-Type", "image/jpeg", true);
     // passo o header do tamanho do arquivo
     $this->getResponse()->setHttpHeader("Content-Length", strlen($this->bin), true);
  }
}

?>

Template (_ler.php)


Agora vamos criar a view desse componente.
Ela deve ficar em apps/frontend/modules/arquivo/templates/_ler.php

O _ler.php terá apenas:


 <?php echo $bin ?>

Agora para introduzir a imagem que esse componente gera em algum template, basta chamar o componente:

 <?php include_component("arquivo", "ler") ?>

OBS: Limpe o cache

$ symfony cc

Lembrando: Podemos passar parametros ao incluir um componente.

Podemos passar o ID da imagem a ser recuperada. (nesse caso é preciso adaptar a action para receber esse id)


<?php include_component("arquivo", "ler", array("idimg" => 5)) ?>

Para receber o parametro na action: $this->idimg
Para receber o parametro na view: $idimg

php
symfony

Comments (1)

Permalink

Manipulando campo do tipo blob com symfony (Parte 1-2)

Esses dias fiz um sistema que utilizava o tipo de campo BLOB para armazenar umas imagens.
Até então eu não sabia como fazer para manipular tais arquivos como BLOB.

Então, fiz da seguinte maneira:

Aplicação/Módulos


No meu exemplo de teste usei a aplicação “frontend” (symfony init-app frontend) e o módulo “arquivo” (symfony init-module frontend arquivo)

O schema.yml (config/schema.yml)



propel:
  arquivo:
    _attributes:       { phpName: Arquivo }
    id:
    img:               blob
    mime:              varchar(120)
    created_at:

O form


(apps/frontend/modules/arquivo/templates/indexSuccess.php)
<?php use_helper("Validation") ?>
<?php echo form_tag(‘arquivo/salvararquivo’ , ‘multipart=true’) ?>
<?php echo input_file_tag(‘arquivo’) ?>
<?php echo form_error(‘arquivo’); // esse helper é responsável por mostrar o erro de validação, caso exista ?>
<?php echo submit_tag(‘enviar’) ?>
</form>

OBS: Lembrar do MULTIPART=TRUE (fiquei um bom tempo até me lembrar de passar esse parâmetro).

Action – Recebo o arquivo do form


(apps/frontend/modules/arquivo/actions/actions.class.php)

    public function executeSalvararquivo() {
      $phpFile = $this->getRequest()->getFile(‘arquivo’); // pego o arquivo do form
      $fileType  = $this->getRequest()->getFileType(‘arquivo’); // pego o mimetype do arquivo
      $fileBinario = file_get_contents($phpFile["tmp_name"]); // pego o conteudo binario do arquivo

     $arquivo = new Arquivo();
     $arquivo->setImg($fileBinario); // esse é o campo BLOB
     $arquivo->setMime($fileType);
     $arquivo->save();
   }
   public function handleErrorSalvararquivo() {
     // esse metodo serve para retornar ao formulário caso algum erro seja encontrado
     $this->forward("arquivo" , "index");
   }

Validando o arquivo enviado


(apps/frontend/modules/arquivo/validate/salvararquivo.yml)

fillin:
  enabled:  true
fields:
  arquivo:
    file:  true
    required:
      msg:   É obrigatório o envio de uma imagem
    sfFileValidator:
      mime_types:
        – ‘image/jpeg’
        – ‘image/pjpeg’
      mime_types_error:  Apenas imagens do tipo JPG são válidas
      max_size:   20000
      max_size_error:  O tamanho máximo da imagem é de 20KB

Sucesso


(apps/frontend/modules/arquivo/templates/salvararquivoSuccess.php)

  Arquivo salvo com sucesso.

Perfeito. Temos agora um arquivo armazenado no banco de dados.

E para mostrar esse arquivo/imagem numa view ? Usaremos Components. Será a parte II desse post.

>>

php
symfony

Comments (0)

Permalink