11 de novembro de 2010

Calendário JQuery nos filtros

Solução: sfFormExtraPlugin
Tutorial para o symfony 1.4: este senhor explica bem como fazer isto.

Para alterar o formato default da data (MM/DD/YYYY) para DD/MM/YYYY nos filter's (é similar para os forms) editem o ficheiro lib/filter/doctrine/moduloFilter.class.php:
public function setup()
  {
 parent::setup();

 $this->widgetSchema['created_at'] = new sfWidgetFormFilterDate(
  array(
   'from_date' => new sfWidgetFormJQueryDate(
     array(
      'image' => '/images/calendar.png',
      'culture' => 'pt',
      'date_widget' => new sfWidgetFormDate(
        array(
         'format' => '%day%/%month%/%year%'
        )
      )
     )
   ),
   'to_date' => new sfWidgetFormJQueryDate(
     array(
      'image' => '/images/calendar.png',
      'culture' => 'pt',
      'date_widget' => new sfWidgetFormDate(
        array(
         'format' => '%day%/%month%/%year%'
        )
      )
     )
   )
  )
 );

Output de ficheiro .CSV e forçar o seu download

Para forçar o download dum ficheiro .csv basta editar modulo/config/view.yml:
nomedaactionSuccess:
  has_layout: false
  http_metas:
    content-type: application/msexcel

Se quisermos inferir um determinado nome a esse ficheiro, na modulo/actions/action.class.php:
public function executeNomedaaction(sfWebRequest $request) {
...
    $this->getResponse()->addHttpMeta('Content-disposition', "attachment; filename=nopme_do_ficheiro.csv");
...

Aceder aos 'filters' definidos no backend

Como certamente ja repararam, sempre que aplicam um filtro num backend do symfony, ele fica em sessão e mesmo que naveguem entre módulos ele é preservado.

Para acederem aos filtros aplicados podem usar o seguinte numa action:

$this->getUser()->getAttributeHolder()->getAll('admin_module')

Ou na view:

sfContext::getInstance()->getUser()->getAttributeHolder()->getAll(’admin_module’);

13 de outubro de 2010

Problemas com encoding no MySQL

Hoje, mesmo com o collate da base de dados e das tabelas definido como utf8_general_ci, ficheiros php em UTF-8 e headers html definidos como UTF-8, os dados estavam a entrar com um encoding estranho em base de dados...

Solução:

Logo após a conecção à base de dados, executar a seguinte query:

mysql_query("SET NAMES 'utf8';");

That did the trick :)

8 de julho de 2010

Cookies em iframes - Problema no IE

Se tivermos uma iframe externa que está a definir cookies - por exemplo, para validar uma sessão - as definições de segurança pré-definidas no IE impedem-nos de aceder aos cookies.

Para que tal seja possível temos que adicionar informação P3P aos headers das nossas páginas da iframe.

Em php:
header('P3P: CP="CAO PSA OUR"');

A especificação completa P3P pode ser consultada aqui.

16 de junho de 2010

sfPager para arrays de elementos

Como já devem saber, podemos utilizar o sfDoctrinePager para paginar resultados de uma consulta à base de dados.

No entanto, por vezes necessitamos de paginar resultados contidos num array e não num objecto do Doctrine.

Hoje vou mostrar como isso é possível.

10 de maio de 2010

Desproteger acção de módulo do admin-generator

Nota: Dica para symfony 1.2.9

Os módulos criados a partir do admin-generator estão protegidos por default.

No entanto, pode por vezes haver necessidade em desproteger uma determinada acção. Para tal, o ideal seria editar o generator.yml e o security.yml como se faz num módulo não-admin-generated.. Mas o facto é que isso não funciona porque em todos os módulos do admin generator há uma pre-execução de uma função que força a que o utilizador tenha credenciais de administrador:

public function preExecute()
{
  $this->configuration = new moduleGeneratorConfiguration();
  if (!$this->getUser()->hasCredential($this->configuration->getCredentials($this->getActionName())))
  {
    $this->forward(sfConfig::get('sf_secure_module'), sfConfig::get('sf_secure_action'));
  }
  // ...
}

Hack possível para solucionar este problema

No actions.class.php do módulo, colar a função do preExecute das autoActions (semelhante à função acima) e desproteger as acções pretendidas. Exemplo:

public function preExecute()
{
  $this->configuration = new oemproGeneratorConfiguration();

  $action = $this->getActionName();
  if ($action == 'accaoNumeroUm' || $action == 'accaoNumeroDois')
  {
  } else {
    if (!$this->getUser()->hasCredential($this->configuration->getCredentials($this->getActionName())))
    {
      $this->forward(sfConfig::get('sf_secure_module'), sfConfig::get('sf_secure_action'));
    }
  }
  // ...
}

Confesso que não é a solução mais bonita, mas pelo menos funciona :)

27 de abril de 2010

Duas instalações de Symfony no mesmo domínio sem criar subdomínios

Para conseguir ter duas instalações de Symfony no mesmo domínio sem criar subdomínios (usando directorias/pastas diferentes)


Em primeiro ligar é necessário garantir que conseguimos aceder às aplicações de forma separada e, para isso, vamos criar, por exemplo, um alias no nosso servidor (apache).


Alias /applicacao1/sf "/var/www/aplicacao1/data/web/sf"
Alias /applicacao2/sf "/var/www/aplicacao2/data/web/sf" 
Alias /applicacao1 "/var/www/aplicacao1/web"
Alias /applicacao2 "/var/www/aplicacao1/web"
 


Depois é necessário alterar o .htaccess de cada aplicação:

/var/www/aplicacao1/web/.htaccess:
# uncomment the following line, if you are having trouble
# getting no_script_name to work
RewriteBase /applicacao1


/var/www/aplicacao2/web/.htaccess:
# uncomment the following line, if you are having trouble
# getting no_script_name to work
RewriteBase /applicacao2


Mais informação aqui:

http://stackoverflow.com/questions/2148182/how-to-configure-apache-to-have-two-symfony-projects-in-the-same-domain-without

20 de abril de 2010

I18N Extract para além das path's predefinidas

php symfony i18n:extract frontend en --auto-save

Como já devem saber, esta task pesquisa por strings "i18n ready" nos nossos ficheiros .php.

Por strings "i18n ready" entenda-se chamadas à função __() do I18N Helper.

Por default, esta task pesquisa apenas nos templates e nos lib's da aplicação escolhida. Deixando por extrair as strings que estão, por exemplo, nos nossos plugins.

Para forçar a pesquisa de "i18n ready strings" noutras localizações podemos fazer uma coisa feia e desaconselhável mas que resulta...

Basta editar um ficheiro do core do symfony:
symfony/lib/i18n/extract/sfI18nApplicationExtract.class.php

public function extract()
  {
    foreach ($this->extractObjects as $extractObject)
    {
      $extractObject->extract();
    }

    // Add global templates
    $this->extractFromPhpFiles(sfConfig::get('sf_app_template_dir'));

    // Add global librairies
    $this->extractFromPhpFiles(sfConfig::get('sf_app_lib_dir'));

    // Hack: Pesquisar tambem no directorio dos plugins
    $this->extractFromPhpFiles(sfConfig::get('sf_plugins_dir'));
  }

No exemplo acima forçei a pesquisa no sf_plugins_dir.

16 de abril de 2010

CMS/CMF em Symfony

Hoje queria apresentar 3 Content Management Systems (ou Frameworks), feitos em Symfony. Confesso que apenas dei uma vista d'olhos, mas, embora todos me pareçam bastante poderosos, a simplicidade de edição do Apostrophe foi a que me agradou mais.

Apostrophe

Website: http://www.apostrophenow.com/
Demonstração (Front/Back Office): http://demo.apostrophenow.com/


Sympal

Website: http://www.sympalphp.org/
Demonstração (Front/Back Office): http://www.sympalphp.org/sympal_demo/

Diem

Website: http://diem-project.org/

Demonstração (Front Office): http://demo.diem-project.org/
Demonstração (Back Office): http://demo.diem-project.org/admin

13 de abril de 2010

I18N a sério - O URL também é para ser traduzido

Sempre li que I18N é fácil de o implementar, mas muitas vezes esquecem-se de "pormenores". Como por exemplo, questões relacionadas com o SEO como a tradução dos URL's.

Após vasculhar a web à procura de uma solução para o symfony 1.2, experimentei mais que um plugin mas este foi o que melhor funcionou uma vez que permite a criação de ficheiros routing.yml para cada culture

Para instalar usem o SVN:
cd project/plugins
svn export http://svn.symfony-project.com/plugins/ysfDimensionsPlugin/branches/1.2/ ysfDimensionsPlugin

Dicas para a sua utilização podem ser encontradas aqui:
http://svn.symfony-project.com/plugins/ysfDimensionsPlugin/branches/1.2/README

e aqui:
http://www.sadai.net/full-i18n-with-ysfdimensionsplugin

5 de abril de 2010

Função de geração slug

Ainda que o Doctrine tenha um behaviour que automaticamente gera slugs, por vezes é necessário uma função para criar uma slug, fica aqui uma exemplo:
function slugString($string, $replacement = '_')
{
  $aux = preg_quote($replacement, '/');
 
  $map = array(
    '/à|á|ã|â/' => 'a',
    '/è|é|ê|ẽ|ë/' => 'e',
    '/ì|í|î/' => 'i',
    '/ò|ó|ô|õ|ø/' => 'o',
    '/ù|ú|ũ|û/' => 'u',
    '/ç/' => 'c',
    '/ñ/' => 'n',
    '/ä|æ/' => 'ae',
    '/ö/' => 'oe',
    '/ü/' => 'ue',
    '/Ä/' => 'Ae',
    '/Ü/' => 'Ue',
    '/Ö/' => 'Oe',
    '/ß/' => 'ss',
    '/[^\w\s]/' => ' ',
    '/\\s+/' => $replacement
  );
 
  return preg_replace(array_keys($map), array_values($map), $string);
}
Retirada daqui.

16 de março de 2010

Downloadify: Client-Side File Generation

Este post não está relacionado com symfony.

Downloadify: Client-Side File Generation

Downloadify is a tiny JavaScript + Flash library that enables the generation and saving of files on the fly, in the browser, without server interaction.

Muito simples e pode vir a dar jeito

Symfony L10n

Mesmo site, duas línguas, dois conteúdos separados. Easy: http://blog.o-x-t.com/2009/04/19/symfony-l10n-going-further

8 de março de 2010

Solução para deploy sem output

Parece que sou das poucas pessoas afectadas por isto, no windows e linux parece que funciona tudo direito. No entanto desde que actualizei para a versão 1.4 do symfony, sempre que faço symfony project:deploy não tenho qualquer output ainda que os ficheiros se sincronizem como esperado.

Como é sempre bom saber que ficheiros foram actualizados, descobri que existe um argumento para tornar o deploy verboso (-t):

php symfony project:deploy production --go -t

Aqui.

3 de março de 2010

Limpar Cache do frontend no backend

Em 3 passos:
  1. Mudar para o environment pretendido
  2. Limpar cache desse environment
  3. Voltar a mudar o environment para o actual
sfContext::switchTo('frontend'); //switch to the environment you wish to clear
sfContext::getInstance()->getViewCacheManager()->getCache()->clean(sfCache::ALL);
sfContext::switchTo('backend'); //switch back to the environment you started from
(Neste exemplo estamos no 'backend' e pretendemos limpar a cache do 'frontend').


EDIT

Pelo que li, o método anterior só funciona em Symfony 1.2, para a versão 1.4 usei o comando rm do terminal:
$frontend_cache_dir = sfConfig::get('sf_cache_dir').'/frontoffice/prod/config/*';
system('rm -rf '.$frontend_cache_dir);

12 de fevereiro de 2010

Numa listagem do admin generator criar um link para um módulo e acção diferentes

Criar o método para devolver o link, no modelo que estamos a trabalhar:
public function getArticleLink()
{
  return link_to($this->getArticle()->getTitle(), 'article/edit?id='.$this->getArticleId());
}

No generator.yml colocar a entrada respectiva:
generator:
  class:              sfPropelAdminGenerator
  param:
    model_class:      Comment
    theme:            default

    fields:
      id:             { name: Id }
      article_link:   { name: Article }
      author:         { name: Author }
      date:           { name: Published on }
      content:        { name: Body }

    list:
      display:        [id, article_link, date]
      ... 


Retirado daqui:
http://vit.free.fr/symfony/0.6.3/generator.html

Criar administração com acção SHOW

Em symfony 1.2 com propel pode usar-se este plugin:

http://www.symfony-project.org/plugins/sfPropelAdminGeneratorWithShowPlugin
ou aqui:
http://symplist.net/plugins/sfPropelAdminGeneratorWithShowPlugin

No caso do symfony 1.4 com doctrine, já temos uma opção mais completa, com este plugin:

http://www.symfony-project.org/plugins/sfAdminThemejRollerPlugin

11 de fevereiro de 2010

sfGuard credenciais para acesso a módulos

As fixtures abaixo vão gerar:
  • 2 grupos de utilizadores (admin e author)
  • 2 tipos de permissoes (admin e author)
  • 2 utilizadores (admin e author)
sfGuardUser:
  sgu_admin:
    username:       admin
    password:       admin
    is_super_admin: true
  sgu_author:
    username:       author
    password:       author
    is_super_admin: false

sfGuardPermission:
  sgp_admin:
    name:           admin
    description:    Administrator permission
  sgp_author:
    name:           author
    description:    Author permission

sfGuardGroup:
  sgg_admin:
    name:           admin
    description:    Administrator group
  sgg_author:
    name:           author
    description:    Author group

sfGuardGroupPermission:
  sggp_admin:
    sfGuardGroup:       sgg_admin
    sfGuardPermission:  sgp_admin
  sggp_author:
    sfGuardGroup:       sgg_author
    sfGuardPermission:  sgp_author

sfGuardUserGroup:
  sgug_admin:
    sfGuardGroup:       sgg_admin
    sfGuardUser:        sgu_admin
  sgug_author:
    sfGuardGroup:       sgg_author
    sfGuardUser:        sgu_author

Para no backend fazer com que um utilizador do grupo "author" apenas tenha acesso (de leitura e escrita) no módulo "article" deve-se editar o ficheiro
apps/backend/modules/article/config/security.yml:
default:
  is_secure: on
  credentials: [author]

Para todos os restantes módulos temos que restringir o acesso a utilizadores do grupo "admin":
Para garantirmos que os restantes módulos estejam apenas acessíveis para utilizadores do grupo "admin",  temos que editar o ficheiro
apps/backend/config/security.yml:
default:
  is_secure: on
  credentials: [admin]


Se numa vista com acesso geral quisermos filtrar o conteúdo dependendo da credencial, podemos verifica-la assim:
$sf_user->hasCredential('author')

Mais informações sobre sfGuard estão disponíveis aqui e aqui.
Mais informações sobre credentials aqui.

Re-escrever método get duma tabela

Como já não é a primeira vez que me esqueço fica aqui a nota. Neste exemplo vou re-escrever o método getSuperCategory que por default retorna o nome da "SuperCategory" caso exista, ou vazio, caso contrário:
class Category extends BaseCategory
{
  public function getSuperCategory()
  {
    return $this->_get('super_category_id')?Doctrine::getTable('SuperCategory')->find($this->_get('super_category_id')):'<Nenhuma>';
  }
}
Agora quando chamar o getSuperCategory e não existir SuperCategory associada é-me retornado <Nenhuma>

Motor de templating no symfony 2.0?

Pois é, um dos aspectos que, por um lado gostei, mas por outro lado estranhei quando comecei a trabalhar com Symfony, foi o facto de não usar nenhum mecanismo de templates adicional como acontece em muitas frameworks (motores como por exemplo Smarty).

Apesar dos mecanismos de templating tenderem a ser muito simples, o facto é que se trata de uma outra "linguagem" que é necessário aprender, daí ter achado boa ideia poder usar o PHP para fazer os templates.

Agora um dos fundadores/developers do Symfony aborda este tema de uma forma muito interessante explorando as vantagens e desvantagens desta escolha:

http://fabien.potencier.org/article/34/templating-engines-in-php

Provavelmente terei de concordar que o uso do PHP pode "complicar" alguns templates, sobretudo do ponto de vista de um Web Designer, e também pode "incentivar" o programador a fazer "asneiras" deixando-o implementar algumas tarefas que deveriam ter sido feitas no controlador ou no modelo.

Vamos ver como correm os desenvolvimentos do Twig até ao lançamento do symfony 2, mas a julgar pelo sucesso que foi a história do YAML, parece-me que a participação do Fabien neste projecto pode indiciar mais um caso de sucesso .

10 de fevereiro de 2010

Developing for Facebook

Link: http://www.symfony-project.org/more-with-symfony/1_4/en/12-Developing-for-Facebook

(...)
- Choosing between FBML and XFBML: Problem solved by symfony
-  How Facebook Connect works and different Integration Strategies
- Best Practices for Facebook Applications
- Using symfony's logging System for debugging FBML
-  Using a Proxy to avoid wrong Facebook Redirections
- Redirecting inside an FBML application
(...)

Gerar gráfico do modelo de dados



Plugin: http://www.symfony-project.org/plugins/sfDoctrineGraphvizPlugin

Programa para visualizar os gráficos: http://www.graphviz.org/

Nota: Para instalar é necessário usar a opção --stability=beta (uma vez que o plugin ainda está numa versão beta).




Obrigado ao Filipe pera dica!

8 de fevereiro de 2010

Inserir valores extra nos formulários antes da validação

Retirado daqui:

http://groups.google.com/group/symfony-users/browse_thread/thread/c4a90c5a140a90ed

O problema é:
- quero especificar o ACCOUNT_ID no objecto a ser editado/criado, mas sem que esse valor alguma vez passe para o utilizador sob a forma de hidden field.
- quero ainda manter o validador do formulário para garantir que esse account_id existe. Além disso quero manter o estado original no backend (admin generator)

1ª hipótese ("martelada"):
Fazer set ao validator - sfValidatorPass(), e inserir de account_id o valor no controller ou no $form->updateObject()

2ª hipótese:
Se o account_id é determinado na action, ou seja, não pode ser obtido a partir do objecto em si (nesse caso alteraria dentro do próprio ojecto),  então colocar o valor de account_id numa option do form e de seguida adicionar esse valor usando updateObject() . Como, desta forma, o account_id nunca entra no "mundo" do utilizador não há necessidade de o validar. As validações de base de dados garantem que não ocorre nenhum erro inesperado.

3ª hipótese:
Popular o objecto antes de o passar ao form, ou depois de fazer bind (antes de fazer save()). Neste caso para manter a lógica do account_id completamente fora da class form.

4ª hipótese:
Fazer merge do account_id no array que é passado ao bind. Desta forma tudo se processa como se o account_id tivesse sido submetido. Para manter a validação deve-se manter o validator e apenas fazer unset do widget.

2 de fevereiro de 2010

Interactive embedded forms

Download de uma aplicação com exemplo: aqui.


Confesso que ainda não experimentei, mas pareceu-me bem. Fica a dica.

How to Write Plugins for symfony

Apresentação oficial pelo Fabien Potencier, sobre como criar plugins no symfony.
Note-se a nuance:

Choose a prefix (sf is only for oficial plugins) your initials for example.

29 de janeiro de 2010

Acções adicionais em formulários do Admin Generator

Para adicionar uma função no formulário de edição do Admin Generator, para além das convencionais: "Back to List", "Save" e "Save and Add" temos que editar o generator desse módulo e criar a acção:

Editar o ficheiro app_name/modules/module_name/config/generator.yml:
generator:
  param:
    config:
      actions: ~
      fields:  ~
      list: ~
      filter:  ~
      form: ~
      edit:
        actions:
          _list: ~
          _save: ~
          _save_and_add: ~
          _delete: ~
          save_and_edit_template:
            name: "Save and Edit Template"
            params: confirm=De certeza?
            action: saveAndEditTemplate
      new:     ~

Agora criar a respectiva acção  em app_name/modules/module_name/actions/actions.class.php:
class productActions extends autoProductActions
{
  public function executeSaveAndEditTemplate(sfWebRequest $request)
  {
    // codigo
  }
}


Nota:
No exemplo acima a acção estará apenas disponível ao editar um objecto, mas o bloco "actions" pode ser movido para o "new" (acção apenas disponível ao criar novo objecto), ou para o "form" (acção disponível na edição e criação).

28 de janeiro de 2010

Variaveis globais do sfConfig


Symfony Framework

sf_symfony_lib_dir
The real path to the framework’s lib directory
(/usr/share/php/symfony/symfony12/lib)

Project Structure and Layout

sf_root_dir
The path to the project root
(/var/www/project_name)
sf_apps_dir
The path to the project’s apps folder
(/var/www/project_name/apps)
sf_lib_dir
The path to the project’s lib folder
(/var/www/project_name/lib)
sf_log_dir
The path to the project’s log folder
(/var/www/project_name/log)
sf_data_dir
The path to the project’s data folder
(/var/www/project_name/data)
sf_config_dir
The path to the project’s config folder
(/var/www/project_name/config)
sf_test_dir
The path to the project’s test folder
(/var/www/project_name/test)
sf_doc_dir
The path to the project’s doc folder
(/var/www/project_name/doc)
sf_plugins_dir
The path to the project’s plugins folder
(/var/www/project_name/plugins)
sf_cache_dir
The path to the project’s plugins folder
(/var/www/project_name/cache)
sf_web_dir
The path to the project’s plugins folder
(/var/www/project_name/web)
sf_upload_dir
The path to the project’s upload folder
(/var/www/project_name/web/uploads)

Application Information

sf_app
The current application
(backend)
sf_environment
The current environment
(dev)
sf_debug
Whether debugging is enabled
(1)

Application Structure and Layout

sf_app_dir
The path to the current application
(/var/www/project_name/apps/backend)
sf_app_config_dir
The path to the current application’s config directory
(/var/www/project_name/apps/backend/config)
sf_app_lib_dir
The path to the current application’s lib directory
(/var/www/project_name/apps/backend/lib)
sf_app_module_dir
The path to the current application’s module directory
(/var/www/project_name/apps/backend/modules)
sf_app_template_dir
The path to the current application’s template directory
(/var/www/project_name/apps/backend/templates)
sf_app_i18n_dir
The path to the current application’s i18n directory
(/var/www/project_name/apps/backend/i18n)

Cache Structure and Layout

sf_app_base_cache_dir
The path to the current application’s directory in the cache
(/var/www/project_name/cache/backend)
sf_app_cache_dir
The path to the current application’s directory in the cache by current environment
(/var/www/project_name/cache/backend/dev)
sf_template_cache_dir
The path to the current application’s templates directory in the cache by current environment
(/var/www/project_name/cache/backend/dev/template)
sf_i18n_cache_dir
The path to the current application’s i18n directory in the cache by current environment
(/var/www/project_name/cache/backend/dev/i18n)
sf_config_cache_dir
The path to the current application’s config directory in the cache by current environment
(/var/www/project_name/cache/backend/dev/config)
sf_test_cache_dir
The path to the current application’s test directory in the cache by current environment
(/var/www/project_name/cache/backend/dev/test)
sf_module_cache_dir
The path to the current application’s modules directory in the cache by current environment
(/var/www/project_name/cache/backend/dev/modules)

Application Settings

You can access any value in settings.yml by prepending “sf_” to the value.
sf_error_404_module
The module that contains the 404 action (default)
sf_error_404_action
The action that displays the 404 error (error404)
sf_logging_enabled
Boolean for whether logging is currently enabled (1)
sf_escaping_strategy
Whether the sfView class is using the Escaping Strategy (1)
sf_no_script_name
Whether the application is requiring the script name. (1)
sf_csrf_secret
The CSRF secret (UniqueSecret)

Onchange em DoctrineForms


$this->widgetSchema['category_id'] = new sfWidgetFormDoctrineChoice(array(
'model' => 'Category',
'default' => '',
'add_empty' => 'Seleccione categoria'
), array('onchange' => 'alert("hi")'));

27 de janeiro de 2010

Obter o last insert id.

Eis a forma de obter o last_insert_id quando estamos a usar as querys Propel em raw sql.

$this->conn = Propel::getConnection();
$query = "INSERT INTO something (something, something)";
$statement = $this->conn->prepare(query);
$result = $statement->execute();

$new_created_id = $this->conn->LastInsertId();

26 de janeiro de 2010

Problemas com schema.yml e doctrine:insert-sql

Já não é a primeira vez que tenho problemas em gerar o sql para o meu schema.yml...

Cenário
Altero o schema.yml, executo php symfony doctrine:build --sql mas quando vejo o ficheiro .sql gerado, ele não corresponde ao schema definido!

Motivo
O .sql é gerado a partir do modelo e não do schema.yml

Solução
  1. Alterar o schema.yml conforme pretendido
  2. Gerar o novo modelo com php symfony doctrine:build --model
  3. Agora sim, executar php symfony doctrine:build --sql

19 de janeiro de 2010

Embed Forms no Symfony

Para analisar e eventualmente traduzir :)

http://sandbox-ws.com/frameworks/symfony-frameworks/how-to-embed-forms-in-symfony-12-admin-generator

http://sandbox-ws.com/frameworks/symfony-frameworks/how-to-embed-forms-in-symfony-12-admin-generator-part-2

http://sandbox-ws.com/frameworks/symfony-frameworks/how-to-embed-forms-in-symfony-12-admin-generator-part-3

12 de janeiro de 2010

30 boas práticas em Symfony


Encontrado aqui.

Layout específico para um método

Por vezes precisamos de ter um método com um layout completamente diferente do geral (que está em: aplicacao/templates/layout.php).

Para atribuir um layout diferente a um módulo específico basta:
  1. Criar o novo layout em: aplicacao/novo_layout.php
  2. No modulo pretendido, criar o ficheiro: aplicacao/modulo/config/view.yml
  3. Nesse novo ficheiro dizer qual o layout que diz respeito ao método pretendido, assim:
termsSuccess:
layout: plain_layout
# neste caso o metodo termsSuccess terá o layout definido em aplicacao/templates/plain_layout.php
No ficheiro views.yml é também possível dizer que um determinado método não tem qualquer layout associado (ex: o método serve apenas fazer uma chamada à base de dados e é redireccionado após isso para a homepage):
leadCentreSubmitSuccess:
has_layout: false
# a vista leadCentreSubmitSuccess.php não existe
Quando se definem estas excepções de vistas, é sempre seguro assegurar que o layout pré-definido não é afectado, por isso convém acrescentar esta linha ao ficheiro views.yml:
all:
layout: layout
# assegura que o layout pre-definido continua a ser o aplicacao/tempaltes/layout.php

Redirect para Referer (página anterior)

Esta técnica permite redireccionar o utilizador para a página anterior, no caso de existir, ou para a página principal:
public function executeShow(sfWebRequest $request)
{
// ....
$referer = $this->getRequest()->getReferer();
$this->redirect($referer ? $referer : '@homepage');
}


Espero que vos dê tanto jeito como a mim :)