issue 74: Implement conditional statement in rulesets

git-svn-id: http://xe-core.googlecode.com/svn/branches/1.5.0@8582 201d5d3c-b55e-5fd7-737f-ddc643e51545
This commit is contained in:
taggon 2011-07-08 08:06:26 +00:00
parent e0c298d958
commit 1e70e0240b
4 changed files with 107 additions and 10 deletions

View file

@ -83,6 +83,16 @@ class Validator
$name = $filter['name'];
unset($filter['name']);
// conditional statement
if(isset($field->if)) {
$if = $field->if;
if(!is_array($if)) $if = array($if);
foreach($if as $idx=>$cond) {
$if[$idx] = (array)$cond->attrs;
}
$filter['if'] = $if;
}
$filters[$name] = $filter;
}
@ -117,17 +127,31 @@ class Validator
if(!is_array($fields)) return true;
$filter_default = array(
'required' => 'false',
'default' => '',
'modifiers' => array(),
'length' => 0,
'equalto' => 0,
'rule' => 0
'rule' => 0,
'if' => array()
);
$fields = array_map('trim', $fields);
foreach($this->_filters as $key=>$filter) {
$exists = array_key_exists($key, $fields);
$value = $exists?trim($fields[$key]):null;
$filter = array_merge($filter_default, $filter);
$value = $exists ? $fields[$key] : null;
// conditional statement
foreach($filter['if'] as $cond) {
if(!isset($cond['test']) || !isset($cond['attr'])) continue;
$func_body = preg_replace('/\\$(\w+)/', '$c[\'$1\']', $cond['test']);
$func = create_function('$c', "return !!({$func_body});");
if($func($fields)) $filter[$cond['attr']] = $cond['value'];
}
// attr : default
if(!$value && strlen($default=trim($filter['default']))) {
@ -240,7 +264,18 @@ class Validator
else $args = array($name=>$filter);
foreach($args as $name=>$filter) {
if($filter) $this->_filters[$name] = $filter;
if(!$filter) continue;
if(isset($filter['if'])) {
if(is_array($filter['if']) && count($filter['if'])) {
$key = key($filter['if']);
if(!is_int($key)) $filter['if'] = array($filter['if']);
} else {
unset($filter['if']);
}
}
$this->_filters[$name] = $filter;
}
}
@ -348,6 +383,13 @@ class Validator
if($min) $field[] = "minlength:'{$min}'";
if($max) $field[] = "maxlength:'{$max}'";
}
if($filter['if']) {
$ifs = array();
foreach($ifs as $if) {
$ifs[] = "{test:'{$if['test']}', attr:'{$if['attr']}', value:'{$if['value']}'}";
}
$field[] = "'if':[".implode(',', $ifs)."]";
}
if(count($field)) {
$field = '{'.implode(',', $field).'}';
$content[] = "v.addFilter('{$name}', {$field});";

View file

@ -86,7 +86,7 @@ var Validator = xe.createApp('Validator', {
},
API_VALIDATE : function(sender, params) {
var result = true, form = params[0], filter=null, callback=null;
var name, el, val, mod, len, lenb, max, min, maxb, minb, rules, e_el, e_val, i, c, r, result;
var name, el, val, mod, len, lenb, max, min, maxb, minb, rules, e_el, e_val, i, c, r, result, if_, fn;
if (form.elements['_filter']) filter = form.elements['_filter'].value;
if (!filter) return true;
@ -103,6 +103,14 @@ var Validator = xe.createApp('Validator', {
if(!el) continue;
if(filter['if']) {
for(i in filter['if']) {
if_ = filter['if'][i];
fn = new Function('el', 'return !!(' + (if_.test.replace(/$(\w+)/g, 'el["$1"]')) +')');
if(fn(form.elements)) filter[if_.attr] = if_.value;
}
}
if(!val) {
if(f['default']) val = f['default'];
if(f.required) return this.cast('ALERT', [form, name, 'isnull']) && false;
@ -164,6 +172,8 @@ var Validator = xe.createApp('Validator', {
var name = params[0].toLowerCase();
var filter = params[1];
if(filter['if'] && !$.isArray(filter['if'])) filter['if'] = [filter['if']];
filters[name] = filter;
},
API_DEL_FILTER : function(sender, params) {
@ -273,17 +283,17 @@ var EditorStub = xe.createPlugin('editor_stub', {
oValidator.registerPlugin(new EditorStub);
// functions
function get_value(elem) {
function get_value($elem) {
var vals = [];
if (elem.is(':radio')){
return elem.filter(':checked').val();
} else if (elem.is(':checkbox')) {
elem.filter(':checked').each(function(){
if ($elem.is(':radio')){
return $elem.filter(':checked').val();
} else if ($elem.is(':checkbox')) {
$elem.filter(':checked').each(function(){
vals.push(this.value);
});
return vals.join('|@|');
} else {
return elem.val();
return $elem.val();
}
}

View file

@ -75,6 +75,42 @@ class ValidatorTest extends PHPUnit_Framework_TestCase
public function testJSCompile() {
}
public function testCondition() {
$vd = new Validator();
$data = array('greeting1'=>'hello');
// No condition
$vd->addFilter('greeting1', array('required'=>'true'));
$this->assertTrue($vd->validate($data));
// Now greeting2 being mandatory if greeting1 is 'Hello'
$vd->addFilter('greeting2', array('if'=>array('test'=>'$greeting1 == "Hello"', 'attr'=>'required', 'value'=>'true')));
// Because greeting1 is 'hello', including lowercase 'h', greeting2 isn't required yet.
$this->assertTrue($vd->validate($data));
// Change the value of greeting1. Greeting2 is required now
$data['greeting1'] = 'Hello';
$this->assertFalse($vd->validate($data));
$data['greeting2'] = 'World';
$this->assertTrue($vd->validate($data));
}
public function testConditionXml() {
$vd = new Validator(dirname(__FILE__).'/condition.xml');
$data = array('greeting1'=>'hello');
$this->assertTrue($vd->validate($data));
// Change the value of greeting1. Greeting2 is required now
$data['greeting1'] = 'Hello';
$this->assertFalse($vd->validate($data));
$data['greeting2'] = 'World';
$this->assertTrue($vd->validate($data));
}
}
$mock_vars = array();

View file

@ -0,0 +1,9 @@
<?xml version="1.0" encoding="utf-8"?>
<ruleset version="1.5.0">
<fields>
<field name="greeting1" required="true" />
<field name="greeting2">
<if test="$greeting1 == 'Hello'" attr="required" value="true" />
</field>
</fields>
</ruleset>