Tag Archives: Symfony

Configure the symfony-mailer (swiftmailer) during runtime

One of my current projects is a multi-client environment. Each client has its own smtp-settings for the mailings that are done within that application.

From static …

Symfony allows the configuration of the mailer in its factories.yml. There smtp-settings can be definied. But in this case this is impossible as every client has different smtp-settings (every client can use its own smtp-settings to handle mailings).

As I did not want to create an instance of the Swift_Mailer (and Swift_SmtpTransport) myself I decided to create my own mailer-class which is derived from the symfony one. So I get the full benefits of logging.

… to dynamic

class myDynamicMailer extends sfMailer
{
  public function __construct(sfEventDispatcher $dispatcher, $options)
  {
    // Load client based configuration
    $cfg = EmailConfiguration::getCurrent();
 
    if(!$cfg->isSmtpConfigured())
    {
      $options["class"] = "Swift_MailTransport";
    }
    else
    {
      // Update settings for the current client
      $options["transport"]["param"]["host"]      = $cfg->getHostname();
      $options["transport"]["param"]["port"]      = $cfg->getPort();
      $options["transport"]["param"]["username"]  = $cfg->getUsername();
      $options["transport"]["param"]["password"]  = $cfg->getDecryptedPassword();
    }
 
    parent::__construct($dispatcher, $options);
  }
}

Simply update factories.yml with the new class and the dynamic configuration is applied.

all:
  mailer:
    class: myDynamicMailer
    # Rest follows here

Its time to change the orm

I attended the great symfony day 09 in cologne yesterday. It was an awesome conference with nice people, interesting talks and discussions.

Propel is dead

One thing got crystal clear during the talks. Propel is dead! In the next version 1.3 of symfony Doctrine will be the default orm. If thats not a hint … In symfony 2.0 Propel will be deprecated. Additionally the “leader of Propel” stated out that he is no longer leading Propel.

So its time to move to Doctrine. The new features in Doctrine 1.2 described by Jonathan Wage are quite nice. And Doctrine 2.0 will be even more impressive.

Sadly it will require a lot of work rewriting Propel “criteria queries” with Doctrine’s DQL-queries. But I’m certain that this step makes my applications future prove.

Problems with default values in Propel

Default values rule!

I’m using Propel 1.2 (an upgrade will be done soon) but for other people out there …

Consider the following declaration-fragment for the “Foo-entity”. Nothing special here.

<column name="name" type="VARCHAR" size="32" required="true" />
<column name="culture" type="CHAR" size="5" required="true" default="de_DE" />

Now if we create the new object and show the state (var_dump) of the object the culture-field is set to ‘de_DE’ which is correct.

$inst = new Foo();
$inst->setName('Foobar');
$inst->save();

But if you look in your (debug-)logfiles you will see that the insert-query will be generated as:

INSERT INTO foo (NAME) VALUES ('Foobar')

Where is the value for the culture column?

Propel keeps track of the modified columns to reduce the size of the update/insert-queries. The default values for the object will not be set through the generated class-methods. Instead the default values are directly assgined in the member-variable of the generated class. So Propel is unaware that the values has changed.

protected $culture = 'de_DE';

Conclusion

I don’t know if this bug is fixed in Propel 1.3. Soon I will know …

As I will continue working with Propel 1.2 in the current project the “workaround” is to manually set the culture. This is best done in the constructor of your derived class. So Propel knows that the column is modified.

class Foo extends BaseFoo
{
  public function __construct()
  {
     // Note: The generated base-class does not have a constructor
     // so parent::__construct will fail!
     $this->setCulture($this->getCulture());
  }
}

Translating the sfAssetLibraryPlugin using gettext instead of XLIFF

I’m using the sfAssetLibraryPlugin in one of my active projects. This project uses gettext for interface translation.

The plugin ships with XLIFF-files for interface translation. In order to get gettext working simply create the required directories inside the plugin-directory (plugins/sfAssetLibraryPlugin/modules/sfAsset/i18n) and create a new catalog for each language (de, en, fr, ...).

The important thing here is to take care of the “translation-namespace” the plugin uses (sfAsset in this case).

echo __('Description', null, 'sfAsset');

Directory layout

Directory layout of the sfAssetLibraryPlugin


So your gettext-catalog-file has to be named sfAsset.po and not message.po as one could think when reading in the symfony-wiki.

SQL-Join with multiple conditions when using Propel

Propels (Creole) “criteria infrastructure” is a great speed-up for the development process and makes it easy to “write” queries. However if you are forced to create a SQL-Join which requires multiple join-conditions the criteria-api is not a helper anymore.

In order to make use of the criteria-api even in this case a “hack” can be used. Someone else described it in a blog-post.

$c = new Criteria();
$c->addJoin(Object1Peer::ID, Object2Peer::ID .
  ' AND ' . Object1Peer::LOCALE . ' = ' . Object2Peer::LOCALE .
  ' AND ' . Object1Peer::WHATEVER . ' = ' . Object2Peer::WHATEVER,
  Criteria::JOIN);

Its a “hack” but you are not required to write the whole sql-query on your own and can rely on the criteria-api.

As I found out the Propel-developers are aware of this problem and a solution is planned for the (hopefully soon) next Propel release 1.4.