ZF-7430: Loading ini-file form reads all data as strings causing error when JSON encoding for zend_dojo_forms
Description
When reading a ini-file the Zend_Config_Ini::_processKey has only a save:
$config[$key] = $value;
this should be changed to:
if (is_numeric($value)){
$config[$key] = floatval($value);
}else{
$config[$key] = $value;
}
Background When using forms loaded from ini-files the options are transformed into JSON:s if they're complex. When strings are converted they create:
array(4) {
["min"]=>
string(1) "0"
["max"]=>
string(1) "4"
["places"]=>
string(1) "1"
["pattern"]=>
string(9) "##0.## cm"
}
string(56) "{"min":"0","max":"4","places":"1","pattern":"##0.## cm"}"
After suggested fix:
array(4) {
["min"]=>
float(0)
["max"]=>
float(4)
["places"]=>
float(1)
["pattern"]=>
string(9) "##0.## cm"
}
string(50) "{"min":0,"max":4,"places":1,"pattern":"##0.## cm"}"
Previous bug report - the code that caused it The constraints should look like this for dojo to handle them correctly: constraints="{min:0,max:100,places:1}"
Zend_Dojo creates this: constraints="{'min':'0','max':'100','places':'1'}"
Places and min work but max is ignored. Here's my test-code:
[test_element_form]
; general form metainformation
demo.test_element_form.method = "post"
demo.test_element_form.class = "zend_form"
; number element
demo.test_element_form.elements.number.type = "NumberTextBox"
demo.test_element_form.elements.number.options.label = "number"
demo.test_element_form.elements.number.options.constraints.min = 0
demo.test_element_form.elements.number.options.constraints.max = 100
demo.test_element_form.elements.number.options.constraints.places = 1
demo.test_element_form.elements.number.options.smallDelta = "1"
demo.test_element_form.elements.number.options.largeDelta = "10"
; submit element
demo.test_element_form.elements.submit.type = "submit"
demo.test_element_form.elements.submit.name = "save"
public function testAction(){
$config = new Zend_Config_Ini('../config/demo_forms.ini', 'test_element_form');
Zend_Loader::loadClass('Zend_Dojo_Form');
$form = new Zend_Dojo_Form($config->demo->test_element_form);
$this->view->form = $form->render();
}
Quick fix In Zend_Dojo_View_Helper_Dijit::_prepareDijit(array $attribs, array $params, $type, $dijit = null) change:
...
// Normalize constraints, if present// Normalize constraints, if present
foreach ($this->_jsonParams as $param) {
if (array_key_exists($param, $params)) {
require_once 'Zend/Json.php';
if (is_array($params[$param])) {
$values = array();
foreach ($params[$param] as $key => $value) {
if (!is_scalar($value)) {
continue;
}
$values[$key] = $value;
}
} elseif (is_string($params[$param])) {
$values = (array) $params[$param];
} else {
$values = array();
}
$values = Zend_Json::encode($values);
if ($this->_useDeclarative()) {
$values = str_replace('"', "'", $values);
}
$params[$param] = $values;
}
}
to
// Normalize constraints, if present
foreach ($this->_jsonParams as $param) {
if (array_key_exists($param, $params)) {
require_once 'Zend/Json.php';
if (is_array($params[$param])) {
$values = array();
foreach ($params[$param] as $key => $value) {
if (!is_scalar($value)) {
continue;
}
$values[$key] = $value;
}
} elseif (is_string($params[$param])) {
$values = (array) $params[$param];
} else {
$values = array();
}
$values = Zend_Json::encode($values);
if ($this->_useDeclarative()) {
$values = str_replace('"', "'", $values);
}
if ($param == "constraints"){
$values = str_replace('\'', "", $values);
$values = str_replace('"', "", $values);
}
$params[$param] = $values;
}
}
I think the if($param == "constraints") probably is unnecessary but I'm a little unsure. I guess the real problem is Zend_Json::encode() but I have no experience of how it works and this fix works although it's not the prettiest
Comments
Posted by Max Gordon (mgordon) on 2009-08-01T06:24:28.000+0000
Found the bug, se above for suggested fix