10 short answers to frequently asked questions about Symfony
Krzysztof Karolczak | Wednesday April 15th, 2009I wanted to put together few simple answers to problems which I came across when browsing through Symfony related forums and mailing lists. The list is of course open and please feel free to write a comment with your own question. I’ll be glad to help if I only can
.
Remark: The answers generally apply to all the versions of Symfony if not specified otherwise. And the exemplary code uses Propel.
1. How to gain access to the Request object outside the action?
In any place in your Symfony project you can initialize an instance of sfContext by simply calling sfContext::getInstance() and use it to retrieve other important object including the Request.
For example:
$context = sfContext::getInstance();
$context->getActionName();
$context->getActionStack();
$context->getController();
$context->getDatabaseConnection();
$context->getLogger();
$context->getModuleDirectory();
$context->getModuleName();
$context->getRequest();
$context->getResponse();
$context->getUser();
2. How to make an object_select_tag create a drop down containing a sorted list?
Let’s say that we have an object $record with person_id field, which is a foreign reference to a Person class. We want in our form to display object_select_tag that will contain all the possible choices of Person objects sorted for example by their name.
By calling:
object_select_tag ($record, ‘getPersonId’);
We only get a list sorted by id (probably) – because object_select_tag uses PersonPeer::doSelect() by default.
So the solution is:
object_select_tag ($record, ‘getPersonId’, array (
‘related_class’ => ‘Person’,
‘peer_method’ => ‘doOrderedSelect’,
‘include_blank’ => true)
) ;
And we just need to create a doOrderedSelect method in PersonPeer class, that might look like this:
public static function doOrderedSelect($c = ”)
{
If(!$c)
$c = new Criteria();
$c->addAscendingOrderByColumn(PersonPeer::NAME);
return parent::doSelect($c);
}
And remember that for all of that to work Person class has to have a __toString() method [see point 3].
3. The magic __toString() method.
The most commonly used PHP5 magic method in Symfony projects is the __toString() method, which specifies what value should be returned when the given object is cast to string (or simply used as a string).
It is a very natural programming approach to specify what ‘natural language phrase’ should be associated with an object instance. A short example to illustrate that:
class Person extends BasePerson
{
public function __toString()
{
return $this->getName() . ‘ ‘ . $this->getSurname();
}
}
And now we can print out the name and surname of our Person class instance – let’s say $example_person – simply by writing echo $example_person.
The __toString() method is used by some of the Symfony form helpers and it’s usually worth spending a bit extra time to create those methods in our model – just for the sake of code readabilty.
But be careful when using PHP version older then 5.2 -because __toString() method was only called when it was directly combined with echo() or print(), which might cause unexpected results sometimes.
4. How to create a paginated list in Symfony?
Symfony comes with a sfPropelPager which handles all the paging for us. I hope the preceding code is self-explanatory.
The action:
public function executeList()
{
…
$rows_per_page = sfConfig::get(’app_rows_per_page’); // Now you can set the number of rows per page in your_app/config/app.yml
$page = $this->getRequestParameter(’page’, 1);
$pager = new sfPropelPager(’YourClass’, $rows_per_page);
$pager->setCriteria($c);
$pager->setPage($page);
$pager->init();
$this->pager = $pager;
}
The template:
<?php if ($pager->haveToPaginate()): ?>
<div class=”pagination”>
<?php echo link_to(’<< ‘, ‘example/list?page=’.$pager->getFirstPage()) ?>
<?php echo link_to(’ <’, ‘example/list?page=’.$pager->getPreviousPage()) ?>
<?php $links = $pager->getLinks(); foreach ($links as $page): ?>
<?php echo ($page == $pager->getPage()) ? $page : link_to($page, ‘example/list?page=’.$page) ?>
<?php endforeach ?>
<?php echo link_to(’> ‘, ‘example/list?page=’.$pager->getNextPage()) ?>
<?php echo link_to(’ >>’, ‘example/list?page=’.$pager->getLastPage()) ?>
</div>
<?php endif; ?>
5. How to use pager with a custom peer method like doSelectJoinAll()?
Let’s assume that we have a pager used to display a list of objects with foreign references and we want to sort it by one of the fields from a foreign table. We’ll need to use o join for that and it would be nice if we could use one of the generated methods like doSelectJoin*(), e.g. doSelectJoinAll().
The solution is very simple. Before calling $pager->init() use the pager’s setPeerMethod(). In our case that would be:
$pager->setPeerMethod(’doSelectJoinAll’);
6. Problem with storing dates before year 1970 in some databases.
It was an issue for Symfony 1.0.X – don’t know if it applies to other versions as well.
For some db the data type date didn’t work as expected for dates prior to 01.01.1970. There exist a special, additional date type bu_date that you have to use in your schema.yml.
date_of_birth: { type: bu_date }
7. JavaScript in Ajax response call is not executed.
In Symfony if the response code of the Ajax call contains JavaScript it won’t be executed by default – for security reasons.
You need to explicitly declare for Ajax helpers the ability to execute scripts in remote responses – which can be done with the script option.
Using the example from Symfony’s documentation:
<?php
// If the response of the post/delete action contains JavaScript,
// allow it to be executed by the browser
echo link_to_remote(’Delete this post’, array(
‘update’ => ‘feedback’,
‘url’ => ‘post/delete?id=’.$post->getId(),
’script’ => true,
)) ?>
8. 9. 10. … are in progress, and I’m open to your questions
.






8 : How to configure a date field with a
Jf | Thursday April 23rd, 20098 : How to configure a date field with a date picker with generator.yml ?