Issues

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

Found the bug, se above for suggested fix