Subversion Repositories Applications.papyrus

Rev

Rev 320 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
320 jpm 1
<?php
2
/* vim: set expandtab tabstop=4 shiftwidth=4: */
3
// +----------------------------------------------------------------------+
4
// | PHP version 4.0                                                      |
5
// +----------------------------------------------------------------------+
6
// | Copyright (c) 1997-2003 The PHP Group                                |
7
// +----------------------------------------------------------------------+
8
// | This source file is subject to version 2.0 of the PHP license,       |
9
// | that is bundled with this package in the file LICENSE, and is        |
10
// | available at through the world-wide-web at                           |
11
// | http://www.php.net/license/2_02.txt.                                 |
12
// | If you did not receive a copy of the PHP license and are unable to   |
13
// | obtain it through the world-wide-web, please send a note to          |
14
// | license@php.net so we can mail you a copy immediately.               |
15
// +----------------------------------------------------------------------+
16
// | Authors: Adam Daniel <adaniel1@eesus.jnj.com>                        |
17
// |          Alexey Borzov <borz_off@cs.msu.su>                          |
18
// |          Bertrand Mansion <bmansion@mamasam.com>                     |
19
// +----------------------------------------------------------------------+
20
//
443 ddelon 21
// $Id: RuleRegistry.php,v 1.2 2005-09-20 17:01:22 ddelon Exp $
320 jpm 22
 
23
/**
24
* Registers rule objects and uses them for validation
25
*
26
*/
27
class HTML_QuickForm_RuleRegistry
28
{
29
    /**
30
     * Array containing references to used rules
31
     * @var     array
32
     * @access  private
33
     */
34
    var $_rules = array();
35
 
36
 
37
    /**
38
     * Returns a singleton of HTML_QuickForm_RuleRegistry
39
     *
40
     * Usually, only one RuleRegistry object is needed, this is the reason
41
     * why it is recommended to use this method to get the validation object.
42
     *
43
     * @access    public
44
     * @static
45
     * @return    object    Reference to the HTML_QuickForm_RuleRegistry singleton
46
     */
47
    function &singleton()
48
    {
49
        static $obj;
50
        if (!isset($obj)) {
51
            $obj = new HTML_QuickForm_RuleRegistry();
52
        }
53
        return $obj;
54
    } // end func singleton
55
 
56
    /**
57
     * Registers a new validation rule
58
     *
59
     * In order to use a custom rule in your form, you need to register it
60
     * first. For regular expressions, one can directly use the 'regex' type
61
     * rule in addRule(), this is faster than registering the rule.
62
     *
63
     * Functions and methods can be registered. Use the 'function' type.
64
     * When registering a method, specify the class name as second parameter.
65
     *
66
     * You can also register an HTML_QuickForm_Rule subclass with its own
67
     * validate() method.
68
     *
69
     * @param     string    $ruleName   Name of validation rule
70
     * @param     string    $type       Either: 'regex', 'function' or null
71
     * @param     string    $data1      Name of function, regular expression or
72
     *                                  HTML_QuickForm_Rule object class name
73
     * @param     string    $data2      Object parent of above function or HTML_QuickForm_Rule file path
74
     * @access    public
75
     * @return    void
76
     */
77
    function registerRule($ruleName, $type, $data1, $data2 = null)
78
    {
79
        $type = strtolower($type);
80
        if ($type == 'regex') {
81
            // Regular expression
82
            $rule =& $this->getRule('regex');
83
            $rule->addData($ruleName, $data1);
84
            $GLOBALS['_HTML_QuickForm_registered_rules'][$ruleName] = $GLOBALS['_HTML_QuickForm_registered_rules']['regex'];
85
 
86
        } elseif ($type == 'function' || $type == 'callback') {
87
            // Callback function
88
            $rule =& $this->getRule('callback');
89
            $rule->addData($ruleName, $data1, $data2, 'function' == $type);
90
            $GLOBALS['_HTML_QuickForm_registered_rules'][$ruleName] = $GLOBALS['_HTML_QuickForm_registered_rules']['callback'];
91
 
92
        } elseif (is_object($data1)) {
93
            // An instance of HTML_QuickForm_Rule
94
            $this->_rules[strtolower(get_class($data1))] = $data1;
95
            $GLOBALS['_HTML_QuickForm_registered_rules'][$ruleName] = array(strtolower(get_class($data1)), null);
96
 
97
        } else {
98
            // Rule class name
99
            $GLOBALS['_HTML_QuickForm_registered_rules'][$ruleName] = array(strtolower($data1), $data2);
100
        }
101
    } // end func registerRule
102
 
103
    /**
104
     * Returns a reference to the requested rule object
105
     *
106
     * @param     string   $ruleName        Name of the requested rule
107
     * @access    public
108
     * @return    object
109
     */
110
    function &getRule($ruleName)
111
    {
112
        list($class, $path) = $GLOBALS['_HTML_QuickForm_registered_rules'][$ruleName];
113
 
114
        if (!isset($this->_rules[$class])) {
115
            if (!empty($path)) {
116
                include_once($path);
117
            }
118
            $this->_rules[$class] =& new $class();
119
        }
120
        $this->_rules[$class]->setName($ruleName);
121
        return $this->_rules[$class];
122
    } // end func getRule
123
 
124
    /**
125
     * Performs validation on the given values
126
     *
127
     * @param     string   $ruleName        Name of the rule to be used
128
     * @param     mixed    $values          Can be a scalar or an array of values
129
     *                                      to be validated
130
     * @param     mixed    $options         Options used by the rule
131
     * @param     mixed    $multiple        Whether to validate an array of values altogether
132
     * @access    public
133
     * @return    mixed    true if no error found, int of valid values (when an array of values is given) or false if error
134
     */
135
    function validate($ruleName, $values, $options = null, $multiple = false)
136
    {
137
        $rule =& $this->getRule($ruleName);
138
 
139
        if (is_array($values) && !$multiple) {
140
            $result = 0;
141
            foreach ($values as $value) {
142
                if ($rule->validate($value, $options) === true) {
143
                    $result++;
144
                }
145
            }
146
            return ($result == 0) ? false : $result;
147
        } else {
148
            return $rule->validate($values, $options);
149
        }
150
    } // end func validate
151
 
152
    /**
153
     * Returns the validation test in javascript code
154
     *
155
     * @param     mixed     Element(s) the rule applies to
156
     * @param     string    Element name, in case $element is not array
157
     * @param     array     Rule data
158
     * @access    public
159
     * @return    string    JavaScript for the rule
160
     */
161
    function getValidationScript(&$element, $elementName, $ruleData)
162
    {
163
        $reset =  (isset($ruleData['reset'])) ? $ruleData['reset'] : false;
164
        $rule  =& $this->getRule($ruleData['type']);
165
        if (!is_array($element)) {
166
            list($jsValue, $jsReset) = $this->_getJsValue($element, $elementName, $reset, null);
167
        } else {
168
            $jsValue = "  value = new Array();\n";
169
            $jsReset = '';
170
            for ($i = 0; $i < count($element); $i++) {
171
                list($tmp_value, $tmp_reset) = $this->_getJsValue($element[$i], $element[$i]->getName(), $reset, $i);
172
                $jsValue .= "\n" . $tmp_value;
173
                $jsReset .= $tmp_reset;
174
            }
175
        }
176
        $jsField = isset($ruleData['group'])? $ruleData['group']: $elementName;
177
        list ($jsPrefix, $jsCheck) = $rule->getValidationScript($ruleData['format']);
178
        if (!isset($ruleData['howmany'])) {
179
            $js = $jsValue . "\n" . $jsPrefix .
180
                  "  if (" . str_replace('{jsVar}', 'value', $jsCheck) . " && !errFlag['{$jsField}']) {\n" .
181
                  "    errFlag['{$jsField}'] = true;\n" .
182
                  "    _qfMsg = _qfMsg + '\\n - {$ruleData['message']}';\n" .
183
                  $jsReset .
184
                  "  }\n";
185
        } else {
186
            $js = $jsValue . "\n" . $jsPrefix .
187
                  "  var res = 0;\n" .
188
                  "  for (var i = 0; i < value.length; i++) {\n" .
189
                  "    if (!(" . str_replace('{jsVar}', 'value[i]', $jsCheck) . ")) {\n" .
190
                  "      res++;\n" .
191
                  "    }\n" .
192
                  "  }\n" .
193
                  "  if (res < {$ruleData['howmany']} && !errFlag['{$jsField}']) {\n" .
194
                  "    errFlag['{$jsField}'] = true;\n" .
195
                  "    _qfMsg = _qfMsg + '\\n - {$ruleData['message']}';\n" .
196
                  $jsReset .
197
                  "  }\n";
198
        }
199
        return $js;
200
    } // end func getValidationScript
201
 
202
 
203
   /**
204
    * Returns JavaScript to get and to reset the element's value
205
    *
206
    * @access private
207
    * @param  object HTML_QuickForm_element     element being processed
208
    * @param  string    element's name
209
    * @param  bool      whether to generate JavaScript to reset the value
210
    * @param  integer   value's index in the array (only used for multielement rules)
211
    * @return array     first item is value javascript, second is reset
212
    */
213
    function _getJsValue(&$element, $elementName, $reset = false, $index = null)
214
    {
215
        $jsIndex = isset($index)? '[' . $index . ']': '';
216
        $tmp_reset = $reset? "    var field = frm.elements['$elementName'];\n": '';
217
        if (is_a($element, 'html_quickform_group')) {
443 ddelon 218
            $value = "  _qfGroups['{$elementName}'] = {";
219
            $elements =& $element->getElements();
220
            for ($i = 0, $count = count($elements); $i < $count; $i++) {
221
                $append = ($elements[$i]->getType() == 'select' && $elements[$i]->getMultiple())? '[]': '';
222
                $value .= "'" . $element->getElementName($i) . $append . "': true" .
223
                          ($i < $count - 1? ', ': '');
320 jpm 224
            }
225
            $value .=
443 ddelon 226
                "};\n" .
320 jpm 227
                "  value{$jsIndex} = new Array();\n" .
228
                "  var valueIdx = 0;\n" .
229
                "  for (var i = 0; i < frm.elements.length; i++) {\n" .
230
                "    var _element = frm.elements[i];\n" .
443 ddelon 231
                "    if (_element.name in _qfGroups['{$elementName}']) {\n" .
320 jpm 232
                "      switch (_element.type) {\n" .
233
                "        case 'checkbox':\n" .
234
                "        case 'radio':\n" .
235
                "          if (_element.checked) {\n" .
236
                "            value{$jsIndex}[valueIdx++] = _element.value;\n" .
237
                "          }\n" .
238
                "          break;\n" .
443 ddelon 239
                "        case 'select-one':\n" .
320 jpm 240
                "          if (-1 != _element.selectedIndex) {\n" .
241
                "            value{$jsIndex}[valueIdx++] = _element.options[_element.selectedIndex].value;\n" .
242
                "          }\n" .
243
                "          break;\n" .
443 ddelon 244
                "        case 'select-multiple':\n" .
245
                "          var tmpVal = new Array();\n" .
246
                "          var tmpIdx = 0;\n" .
247
                "          for (var j = 0; j < _element.options.length; j++) {\n" .
248
                "            if (_element.options[j].selected) {\n" .
249
                "              tmpVal[tmpIdx++] = _element.options[j].value;\n" .
250
                "            }\n" .
251
                "          }\n" .
252
                "          if (tmpIdx > 0) {\n" .
253
                "            value{$jsIndex}[valueIdx++] = tmpVal;\n" .
254
                "          }\n" .
255
                "          break;\n" .
320 jpm 256
                "        default:\n" .
257
                "          value{$jsIndex}[valueIdx++] = _element.value;\n" .
258
                "      }\n" .
259
                "    }\n" .
260
                "  }\n";
261
            if ($reset) {
262
                $tmp_reset =
263
                    "    for (var i = 0; i < frm.elements.length; i++) {\n" .
264
                    "      var _element = frm.elements[i];\n" .
443 ddelon 265
                    "      if (_element.name in _qfGroups['{$elementName}']) {\n" .
320 jpm 266
                    "        switch (_element.type) {\n" .
267
                    "          case 'checkbox':\n" .
268
                    "          case 'radio':\n" .
269
                    "            _element.checked = _element.defaultChecked;\n" .
270
                    "            break;\n" .
443 ddelon 271
                    "          case 'select-one':\n" .
272
                    "          case 'select-multiple:\n" .
320 jpm 273
                    "            for (var j = 0; j < _element.options.length; j++) {\n" .
274
                    "              _element.options[j].selected = _element.options[j].defaultSelected;\n" .
275
                    "            }\n" .
276
                    "            break;\n" .
277
                    "          default:\n" .
278
                    "            _element.value = _element.defaultValue;\n" .
279
                    "        }\n" .
280
                    "      }\n" .
281
                    "    }\n";
282
            }
283
 
284
        } elseif ($element->getType() == 'select') {
285
            if ($element->getMultiple()) {
286
                $elementName .= '[]';
287
                $value =
288
                    "  value{$jsIndex} = new Array();\n" .
289
                    "  var valueIdx = 0;\n" .
290
                    "  for (var i = 0; i < frm.elements['{$elementName}'].options.length; i++) {\n" .
291
                    "    if (frm.elements['{$elementName}'].options[i].selected) {\n" .
292
                    "      value{$jsIndex}[valueIdx++] = frm.elements['{$elementName}'].options[i].value;\n" .
293
                    "    }\n" .
294
                    "  }\n";
295
            } else {
443 ddelon 296
                $value = "  value{$jsIndex} = frm.elements['{$elementName}'].selectedIndex == -1? '': frm.elements['{$elementName}'].options[frm.elements['{$elementName}'].selectedIndex].value;\n";
320 jpm 297
            }
298
            if ($reset) {
299
                $tmp_reset .=
300
                    "    for (var i = 0; i < field.options.length; i++) {\n" .
301
                    "      field.options[i].selected = field.options[i].defaultSelected;\n" .
302
                    "    }\n";
303
            }
304
 
443 ddelon 305
        } elseif ($element->getType() == 'checkbox' && !is_a($element, 'html_quickform_advcheckbox')) {
320 jpm 306
            $value = "  if (frm.elements['$elementName'].checked) {\n" .
307
                     "    value{$jsIndex} = '1';\n" .
308
                     "  } else {\n" .
309
                     "    value{$jsIndex} = '';\n" .
310
                     "  }";
311
            $tmp_reset .= ($reset) ? "    field.checked = field.defaultChecked;\n" : '';
312
 
313
        } elseif ($element->getType() == 'radio') {
314
            $value = "  value{$jsIndex} = '';\n" .
315
                     "  for (var i = 0; i < frm.elements['$elementName'].length; i++) {\n" .
316
                     "    if (frm.elements['$elementName'][i].checked) {\n" .
317
                     "      value{$jsIndex} = frm.elements['$elementName'][i].value;\n" .
318
                     "    }\n" .
319
                     "  }";
320
            if ($reset) {
321
                $tmp_reset .= "    for (var i = 0; i < field.length; i++) {\n" .
322
                              "      field[i].checked = field[i].defaultChecked;\n" .
323
                              "    }";
324
            }
325
 
326
        } else {
327
            $value = "  value{$jsIndex} = frm.elements['$elementName'].value;";
328
            $tmp_reset .= ($reset) ? "    field.value = field.defaultValue;\n" : '';
329
        }
330
        return array($value, $tmp_reset);
331
    }
332
} // end class HTML_QuickForm_RuleRegistry
333
?>