Nerds who love the symfony-project
29 Aug
Lately I’ve been working on some Symfony batch components to load/export data into and out of a database. If you are looking for a way to send emails from your Symfony batch scripts there are two ways.
1) Use An Action
It is possible to use a pre-defined action within a module for sending emails. You can, for example do this:
sfContext::getInstance()->getController()->sendEmail('module', 'mySendEmailAction');
Where you have a module called ‘module’ and an action within that called ‘mySendEmailAction’. You do however, run into issues when you want to pass paramaters across from your batch script to your action. I havent figured that one out yet - so if you know, let us know!
The important thing to note with this option is that you will need to enable the is_internal setting in module.yml of your module. The is_internal paramater allows you to restrict access to your action so that it only takes internal calls. To change this so that outside components (eg batch) can call your action, set is_internal to false. If you dont do this, you might get an error like this:
Uncaught exception ’sfConfigurationException’ with message ‘Action”mySendEmailAction” from module “module” cannot be called directly’ in /usr/share/php/symfony/controller/sfController.class.php:237
2) Directly use sfMail
The other, simpler option is to use sfMail directly. Within your Symfony batch script, just write your own custom method to send mail.
function sendEmail(){ // class initialization $mail = new sfMail(); $mail->initialize(); $mail->setMailer('sendmail'); $mail->setCharset('utf-8'); // definition of the required parameters $mail->setSender('webmaster@my-company.com', 'Me'); $mail->setFrom('info@my-company.com', 'My Company'); $mail->addReplyTo('webmaster_copy@my-company.com'); $mail->addAddress('test@test.com'); $mail->setSubject('Those Symfony nerds are hot'); $mail->setBody('Well.. they think they are'); $mail->send(); }
Do you know of any other or better ways? Let us know! I’m not too sure how Symfony 1.1 tasks handels this, that will be another blog post in a few months time…
11 Aug
I was working on a project that I decided could do with some client side AJAX validation…. So a bit of digging around led me to sfYzAjaxValidationPlugin… I quickly found out that the old plugin faq’s now redirect to the new plugin site… The only problem was, the plugin I was after, and it seems a lot of other plugins, haven’t been migrated over yet.
My forum post about it went unanswered, but last night I came across a post from Fabien in the symfony google group noting that for a limited time only, the old plugins site is available here : http://raw.trac.symfony-project.org/wiki/SymfonyPlugins
Hopefully that will help others out looking for plugins that for whatever reason aren’t on the new site yet.
6 Aug
I’m working on a project that requires some batch data loads and export to excel functions. This was really the first time I’ve used Symfony batch.
Here are some random tips that helped me write my batch script. I think the Symfony book could use a bit more documentation detail when it comes to symfony batch as there are some things that aren’t even mentioned. Note: This is for Symfony 1.0.
Random Tip #1: Creating a symfony batch
I’m amazed how the documentation was lacking the details of what to put in the symfony batch, they just need a better explanation. So here is an example:
./symfony init-batch default symfony-nerds-look-good backend
In the example above, I’ve created a batch script called symfony-nerds-look-good, now, you might think that’s a problem in itself, but that’s another blog post! So the format of creating a batch job is of this is:
./symfony init-batch default scriptName appName
Note that ‘default’ is the name of the batch template. You can define multiple batch templates, but most of the time, the ‘default’ should be all that you need.
Random Tip #2: Symfony batch logs
If you are used to logging some custom logs with the Symfony logging classes in your view, its different for a batch component. In the actions class, this is all you have to do to write a log:
$this->logMessage("Creating spreadsheet...", "debug");
However, in batch you must do the following:
$logger = sfLogger::getInstance(); //firstly declare the instance of the sfLogger (otherwise you wont be able to log) $logger->log("Creating spreadsheet", SF_LOG_DEBUG); //Then use the standard symfony log constance (eg SF_LOG_DEBUG or SF_LOG_WARN) etc...
So it is slightly different to how you might normally do it.
Random Tip #3: Using model objects and the database with batch
If you would like to use the generated ORM objects that Propel has generated for you, you wont be able to straight away. You will notice if you try to, you will get the error “No connection params set for propel”. You must first instantiate a sfDatabaseManager, then initialise it:
$databaseManager = new sfDatabaseManager(); $databaseManager->initialize(); //Then you can access your model objects and write your criteria as per the usual way
Hope this helps you get started. Do you have any tips with Symfony batch? Let us know!
6 Aug
I am working on an interesting project where I have been given the task of creating a web interface that allows an authenticated and authorised user to conduct specific types of search on a huge data set.
The data set begins as flat text logs which are transformed and loaded into a normalised schema - which was designed well before I got involved. So, I have been very impressed by the way that propel and creole have consistently reverse engineered the schema and built a reliable model.
This is not a post about Propel or Creole but I thought to put this into context since I have been given a development specification that requires me to present data on a browser in a manner different to the way in which it is ordered and layed out in the database schema.
So - consider a table that has the following structure:
id (auto increment unique id) my_date (of type date) my_date_as_int (a conversion of date to int eg 2008-08-06 would be 20080806)
The insertion of dates into the above fields is not ordered - so id 1 may have an older date than id 2 and so on…for example:
| id | my_date_as_int | my_date |
| 1 | 20080602 | 2008-06-02 |
| 2 | 20080724 | 2008-07-24 |
| 3 | 20080723 | 2008-07-23 |
| 4 | 20080411 | 2008-04-11 |
| 5 | 20080412 | 2008-04-12 |
My task was to create a “drop down” select tag that showed the above sorted in an ascending order by the date field.
Step 1. Create a __toString method to return the date field as opposed to the Id.
public function __toString() { return $this->getMyDate(); }
Step 2. Create a custom method in the relevant Peer class to get a sorted list:
public static function getSortedDate() { $c = new Criteria(); $c->addAscendingOrderByColumn(DatePeer::MY_DATE_AS_INT); $rs = DatePeer::doSelect($c); return $rs; }
As you can see, I choose to sort by the integer representation of the date field, but you can use the MY_DATE field in the same manner.
Step 3. Create a drop down select_tag in your view.
There are two options here.
Option 1. Standard form name, value pairs being the date and id fields respectivey.
<?php echo object_select_tag('', 'getMyDate', array ( 'related_class' => 'Date', 'peer_method' => 'getSortedDate', 'include_blank' => true, )) ?>
Option 2. Form name, value pairs being the my_date and the my_date_as_int fields respectivey.
<?php echo select_tag('', objects_for_select(DatePeer::getSortedDate(), 'getMyDateAsInt','getMyDate'), array('id'=>"this_date",'name'=>"this_date")) ?>
That is it! The view then renders a drop down select that is constructed firstly by a call to the getSortedDate method, which in turn returns an array of sorted items - each of which is shown in the drop down using the __toString method to convert from an id to the date.
1 Aug
Today the guys at the Symfony Project announced plugins have a new home. Symfony Plugins.

It’s great. Some great new features:
This will help the developer community to get together and start contributing as one. It’s similar to Ubuntu Launchpad - not quite as advanced, but with the new introduction of developers being able to own plugins and contribute in such a clear way - its going to be a great addition to the community.