Today i observed some obscure behavior in an application. I’m sure many of you have similar stories to tell. Why not collec them here in this thread?
[size="2"]Here goes mine:[/size]
In one of my apps we planned a new feature. The feature should not be launched before a specific date. But still we had to test it on our stage machine and also didn’t want to block other waiting deployments on production. So I thought, let’s use an application parameter as feature flag, to turn on/off the feature on every installation through the config file. I added a menu entry in the main menu like this:
<?php $this->widget('zii.widgets.CMenu', array(
'items' => array(
array(
'label' => 'Some feature',
'visible' => Yii::app()->params['somefeature'],
),
So the menu item would not be enabled unless i add ‘somefeature’ => true to the params section of my configuration file. I tested locally, set the ‘somefeature’ flag to true and false and everything worked. Then i deployed to the live site and soon after got a phone call, why I already activated the new feature there. I thought that’s impossible: I did not add anything at all to the config file there. So i double checked: Indeed, no ‘somefeature’ in the params section in the live config.
So why the heck was the menu item visible?
I debugged locally and removed the ‘somefeature’ param. Yii::app()->params[‘somefeature’] gave null and null should be equivalent to false, right?
Wrong! Not in this case. I had to dig into the source of CMenu.php to find out what’s going on:
<?php
protected function normalizeItems($items,$route,&$active)
{
foreach($items as $i=>$item)
{
if(isset($item['visible']) && !$item['visible'])
{
unset($items[$i]);
continue;
}
...
So the condition in the if seem to evaluate to false, even though there’s a $item[‘visible’]? Well, the problem is that the value is null and isset() returns false for null values. So i first tried to typecast to bool with b Yii::app()->params[‘somefeature’][/b] - but that still didn’t help (no clue, why). Only this (kind of ugly) solution worked in the end:
array(
'label' => 'Some feature',
'visible' => Yii::app()->params['somefeature'] ? true : false,
),
Case closed