Someone came into the #symfony channel on freenode asking how to add conditional validators that would require a text box to be filled out when a checkbox was ticked. As I realize this is a common question (though the circumstances may change), I wanted to put this example up here as well, for others.
Here’s the example:
public function configure()
// ... snip ...
new sfValidatorCallback(array('callback' => array($this, 'contextualChecks')))
public function contextualChecks($validator, $values)
if ($values['checkbox_1'] == 1)
if ($values['textbox_for_checkbox_1'] == '')
$error = new sfValidatorError($validator, 'Field is required when Checkbox 1 is checked.');
$ves = new sfValidatorErrorSchema($validator, array('textbox_for_checkbox_1' => $error));
Note: I completely left out returning $values in the initial draft. I apologize!
I have just made my first release to GitHub, majaxPheanstalkPlugin for symfony 1.4.x (possibly will work on older ones). It’s a set of tools that help to access Beanstalkd and make building workers much simpler.
It builds off of the work of Paul Annesley (pda)‘s pheanstalk which provides a simple php library for accessing a Beanstalkd server.
The goal is to provide you with simple tools for managing your Beanstalkd integration. Right now it’s just worker thread tools and a simple factory, but I hope to grow it into a more complete library as time goes on.
When building my URL shortener, ZapX, I ran into a bit of a problem. I wanted to be able to make the shortest possible urls using the characters 0-9, a-z, and A-Z, otherwise known as base 62.
PHP’s native base_convert only goes up to base 36, so I was forced to resort to my own devices to get the job done. Long story short, here’s one that goes up to base 62:
function extended_base_convert($dec, $base)
$numchart = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';
$min_base = 2;
$max_base = strlen($numchart);
if ($base < $min_base || $base > $max_base)
$value = $dec;
$ptr = ceil($value / $base);
$buf = array();
$buf[$ptr] = substr($numchart, ($value % $base), 1);
$value = intval($value / $base);
} while ($value > 0);
$buf = array_reverse($buf);
return implode('', $buf);
Here’s just a quick note for those of you working with caching solutions for dynamic data in Symfony.
Update: If testability is a concern, please read the follow up to this article.
One of the challenges with caching is deciding where the limit is. What’s worth caching, and what isn’t. Because cleaning up that old data is hard… isn’t it?
Not so much!
You just need to make a helper and a checks, and you’ll be expertly picking out the templates to invalidate!
The first hurdle with clearing out invalid data, is that usually your backend is separate from the frontend, so it’s a non-trivial reach to try and invalidate cache files of other applications. Or is it?
public static function clearCachePattern($pattern)
$envs = array('prod', 'dev');
$apps = array('backend', 'frontend');
foreach($envs as $env)
foreach($apps as $app)
$app_cache_dir = sfConfig::get('sf_cache_dir').DIRECTORY_SEPARATOR.$app. DIRECTORY_SEPARATOR.$env.DIRECTORY_SEPARATOR.'template';
$cache_vars = array(
'cache_dir' => $app_cache_dir,
'cache_key_use_vary_headers' => true,
'cache_key_use_host_name' => true,
$cache = new sfFileCache($cache_vars);
Your $cache_vars will differ depending on your cache settings, but essentially, that’s your main helper setup.
Now here’s what I use in my objects for cache clear detection:
class MyObject extends Doctrine_Record
private $pendingClearCacheEntries = false;
public function preSave($event)
$this->pendingClearCacheEntries = true;
public function postSave($event)
$this->pendingClearCacheEntries = false;
public function clearCacheEntries()
Of course, your patterns will change depending on your cache options (I.e. I use the **/** because I have enabled cache_key_use_host_name, other settings may not accept this pattern.)
Happy caching, and if you have any questions, feel free to let me know!