Yii Framework Forum: Wtf! - Yii Framework Forum

Jump to content

Page 1 of 1
  • You cannot start a new topic
  • You cannot reply to this topic

Wtf! Things that didn't quite work out Rate Topic: -----

#1 User is offline   Mike 

  • Elite Member
  • PipPipPipPipPip
  • Yii
  • Group: Members
  • Posts: 3,016
  • Joined: 06-October 08
  • Location:Upper Palatinate

Posted 03 May 2013 - 03:35 AM

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?

Here goes mine:

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 (bool) Yii::app()->params['somefeature'] - 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 :)
0

#2 User is offline   Fabrizio Caldarelli 

  • Advanced Member
  • PipPipPip
  • Yii
  • Group: Members
  • Posts: 302
  • Joined: 21-March 13
  • Location:Rome, Italy

Posted 03 May 2013 - 03:40 AM

I think that

        array(
            'label' => 'Some feature',
            'visible' => Yii::app()->params['somefeature'] ? true : false,
        ),


it's not completely correct.

Infact "somefeature" key could not be setted.

So i think that correct code should be:

        array(
            'label' => 'Some feature',
            'visible' => isset(Yii::app()->params['somefeature']) ? (Yii::app()->params['somefeature']===true) : false,
        ),


or you can use

array_key_exists('somefeature', Yii::app()->params) 


instead

isset(Yii::app()->params['somefeature'])

0

#3 User is offline   Mike 

  • Elite Member
  • PipPipPipPipPip
  • Yii
  • Group: Members
  • Posts: 3,016
  • Joined: 06-October 08
  • Location:Upper Palatinate

Posted 03 May 2013 - 03:45 AM

Well, it was not set in my case. Yii allows you to look for parameters that don't exist - no error in this case. It only gives you null. That's why i prefer the shorter code in my solution.
0

#4 User is offline   Fabrizio Caldarelli 

  • Advanced Member
  • PipPipPip
  • Yii
  • Group: Members
  • Posts: 302
  • Joined: 21-March 13
  • Location:Rome, Italy

Posted 03 May 2013 - 03:52 AM

View PostMike, on 03 May 2013 - 03:45 AM, said:

Well, it was not set in my case. Yii allows you to look for parameters that don't exist - no error in this case. It only gives you null. That's why i prefer the shorter code in my solution.



I think that it's not so, because you are calling direcly params array, without passing for an Yii method.

So you should check if key exists. I think that you are missing warning display errors.
0

#5 User is offline   Mike 

  • Elite Member
  • PipPipPipPipPip
  • Yii
  • Group: Members
  • Posts: 3,016
  • Joined: 06-October 08
  • Location:Upper Palatinate

Posted 03 May 2013 - 03:58 AM

Warnings are turnded on :). If you access Yii::app()->params you get back an CAttributeCollection which extends from CMap and implements ArrayAccess. Thus you can use it like an array, but it does not necessarily have the same error behavior. In the above case it calls offsetGet() which in turn calls itemAt() - and this simply returns null if a key does not exist. No error. So it's valid to access non existant keys in the params array. You'll just get null back.
0

#6 User is offline   Fabrizio Caldarelli 

  • Advanced Member
  • PipPipPip
  • Yii
  • Group: Members
  • Posts: 302
  • Joined: 21-March 13
  • Location:Rome, Italy

Posted 03 May 2013 - 04:05 AM

Ok, then you are right. i I thought that params was an array and not and object.
0

#7 User is offline   softark 

  • Keep It Simple
  • Yii
  • Group: Moderators
  • Posts: 2,082
  • Joined: 16-February 11
  • Location:Japan

Posted 03 May 2013 - 08:19 AM

I love this wiki article.

The Comedy of Errors

The latest "comedy" (or "wtf!") has been mine. :lol:
1

#8 User is offline   Fabrizio Caldarelli 

  • Advanced Member
  • PipPipPip
  • Yii
  • Group: Members
  • Posts: 302
  • Joined: 21-March 13
  • Location:Rome, Italy

Posted 03 May 2013 - 08:34 AM

I quote completely! :rolleyes:
0

#9 User is offline   Mike 

  • Elite Member
  • PipPipPipPipPip
  • Yii
  • Group: Members
  • Posts: 3,016
  • Joined: 06-October 08
  • Location:Upper Palatinate

Posted 03 May 2013 - 08:51 AM

Heh, didn't know that. Nice :)
0

Share this topic:


Page 1 of 1
  • You cannot start a new topic
  • You cannot reply to this topic

1 User(s) are reading this topic
0 members, 1 guests, 0 anonymous users