Permalink
Browse files

Fixes CHtml::value() bug.

  • Loading branch information...
1 parent 9fc3eeb commit fd5672978eea235d5522bce5e711cf14ac4d505c @resurtm committed Dec 21, 2012
Showing with 26 additions and 10 deletions.
  1. +20 −10 framework/web/helpers/CHtml.php
  2. +6 −0 tests/framework/web/helpers/CHtmlTest.php
@@ -1891,18 +1891,28 @@ public static function listData($models,$valueField,$textField,$groupField='')
*/
public static function value($model,$attribute,$defaultValue=null)
{
- if(is_callable($attribute))
+ // Why we're strictly comparing $attribute[0] with NULL character in the condition below?
+ // This is needed to distinguish string returned by "create_function" and plain string which
+ // was generated in the PHP code. "create_function" has very useful property/feature:
+ // it returns string with prepended NULL character. Note that this is NOT a clumsy trick,
+ // it's documented and known feature.
+ // String created by "create_function": "{NULL}lambda_{XX}"
+ // String generated in the PHP code: "some_string_without_NULLs"
+ // (Using strings containing NULL bytes as attribute names does not make sense.)
+
+ if(is_scalar($attribute) && $attribute[0]!==chr(0))
+ foreach(explode('.',$attribute) as $name)
+ {
+ if(is_object($model) && isset($model->$name))
+ $model=$model->$name;
+ elseif(is_array($model) && isset($model[$name]))
+ $model=$model[$name];
+ else
+ return $defaultValue;
+ }
+ else
return call_user_func($attribute,$model);
- foreach(explode('.',$attribute) as $name)
- {
- if(is_object($model) && isset($model->$name))
- $model=$model->$name;
- elseif(is_array($model) && isset($model[$name]))
- $model=$model[$name];
- else
- return $defaultValue;
- }
return $model;
}
@@ -478,6 +478,12 @@ public function providerValue()
array(array('k1'=>'v1','k2'=>'v2','v3','v4'),create_function('$model','return $model["k2"];'),null,'v2'),
array((object)array('k1'=>'v1','k2'=>'v2','v3','v4'),create_function('$model','return $model->k2;'),null,'v2'),
+ // standard PHP functions should not be treated as callables
+ array(array('array_filter'=>'array_filter','sort'=>'sort'),'sort',null,'sort'),
+ array(array('array_filter'=>'array_filter','sort'=>'sort'),'array_map','defaultValue','defaultValue'),
+ array((object)array('array_filter'=>'array_filter','sort'=>'sort'),'sort',null,'sort'),
+ array((object)array('array_filter'=>'array_filter','sort'=>'sort'),'array_map','defaultValue','defaultValue'),
+
// dot access, array
array(array('k1'=>array('k2'=>array('k3'=>'v3')),array('v1','k4'=>'v4')),'k1.k2.k3',null,'v3'),
array(array('k1'=>array('k2'=>array('k3'=>'v3')),array('v1','k4'=>'v4')),'0.0',null,'v1'),

0 comments on commit fd56729

Please sign in to comment.