1: <?php
2: // $Id: form.php,v 1.1 2007/05/15 02:34:42 minahito Exp $
3: // ------------------------------------------------------------------------ //
4: // XOOPS - PHP Content Management System //
5: // Copyright (c) 2000 XOOPS.org //
6: // <http://www.xoops.org/> //
7: // ------------------------------------------------------------------------ //
8: // This program is free software; you can redistribute it and/or modify //
9: // it under the terms of the GNU General Public License as published by //
10: // the Free Software Foundation; either version 2 of the License, or //
11: // (at your option) any later version. //
12: // //
13: // You may not change or alter any portion of this comment or credits //
14: // of supporting developers from this source code or any supporting //
15: // source code which is considered copyrighted (c) material of the //
16: // original comment or credit authors. //
17: // //
18: // This program is distributed in the hope that it will be useful, //
19: // but WITHOUT ANY WARRANTY; without even the implied warranty of //
20: // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the //
21: // GNU General Public License for more details. //
22: // //
23: // You should have received a copy of the GNU General Public License //
24: // along with this program; if not, write to the Free Software //
25: // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA //
26: // ------------------------------------------------------------------------ //
27: // Author: Kazumi Ono (AKA onokazu) //
28: // URL: http://www.myweb.ne.jp/, http://www.xoops.org/, http://jp.xoops.org/ //
29: // Project: The XOOPS Project //
30: // ------------------------------------------------------------------------- //
31: // public abstruct
32: /**
33: *
34: *
35: * @package kernel
36: * @subpackage form
37: *
38: * @author Kazumi Ono <onokazu@xoops.org>
39: * @copyright copyright (c) 2000-2003 XOOPS.org
40: */
41:
42:
43: /**
44: * Abstract base class for forms
45: *
46: * @author Kazumi Ono <onokazu@xoops.org>
47: * @copyright copyright (c) 2000-2003 XOOPS.org
48: *
49: * @package kernel
50: * @subpackage form
51: */
52: class XoopsForm {
53: /**#@+
54: * @access private
55: */
56: /**
57: * "action" attribute for the html form
58: * @var string
59: */
60: var $_action;
61:
62: /**
63: * "method" attribute for the form.
64: * @var string
65: */
66: var $_method;
67:
68: /**
69: * "name" attribute of the form
70: * @var string
71: */
72: var $_name;
73:
74: /**
75: * title for the form
76: * @var string
77: */
78: var $_title;
79:
80: /**
81: * array of {@link XoopsFormElement} objects
82: * @var array
83: */
84: var $_elements = array();
85:
86: /**
87: * extra information for the <form> tag
88: * @var string
89: */
90: var $_extra;
91:
92: /**
93: * required elements
94: * @var array
95: */
96: var $_required = array();
97:
98: /**#@-*/
99:
100: /**
101: * constructor
102: *
103: * @param string $title title of the form
104: * @param string $name "name" attribute for the <form> tag
105: * @param string $action "action" attribute for the <form> tag
106: * @param string $method "method" attribute for the <form> tag
107: * @param bool $addtoken whether to add a security token to the form
108: */
109: function XoopsForm($title, $name, $action, $method="post", $addtoken = false){
110: $this->_title = $title;
111: $this->_name = $name;
112: $this->_action = $action;
113: $this->_method = $method;
114: if ($addtoken != false) {
115: $this->addElement(new XoopsFormHiddenToken());
116: }
117: }
118:
119: /**
120: * return the title of the form
121: *
122: * @return string
123: */
124: function getTitle(){
125: return $this->_title;
126: }
127:
128: /**
129: * get the "name" attribute for the <form> tag
130: *
131: * @return string
132: */
133: function getName(){
134: return $this->_name;
135: }
136:
137: /**
138: * get the "action" attribute for the <form> tag
139: *
140: * @return string
141: */
142: function getAction(){
143: return $this->_action;
144: }
145:
146: /**
147: * get the "method" attribute for the <form> tag
148: *
149: * @return string
150: */
151: function getMethod(){
152: return $this->_method;
153: }
154:
155: /**
156: * Add an element to the form
157: *
158: * @param object &$formElement reference to a {@link XoopsFormElement}
159: * @param bool $required is this a "required" element?
160: */
161: function addElement(&$formElement, $required=false){
162: if ( is_string( $formElement ) ) {
163: $this->_elements[] = $formElement;
164: } elseif ( is_subclass_of($formElement, 'xoopsformelement') ) {
165: $this->_elements[] =& $formElement;
166: if ($required) {
167: if (!$formElement->isContainer()) {
168: $this->_required[] =& $formElement;
169: } else {
170: $required_elements =& $formElement->getRequired();
171: $count = count($required_elements);
172: for ($i = 0 ; $i < $count; $i++) {
173: $this->_required[] =& $required_elements[$i];
174: }
175: }
176: }
177: }
178: }
179:
180: /**
181: * get an array of forms elements
182: *
183: * @param bool get elements recursively?
184: * @return array array of {@link XoopsFormElement}s
185: */
186: function &getElements($recurse = false){
187: if (!$recurse) {
188: return $this->_elements;
189: } else {
190: $ret = array();
191: $count = count($this->_elements);
192: for ($i = 0; $i < $count; $i++) {
193: if (!is_object($this->_elements[$i])) {
194: $ret[] = $this->_elements[$i];
195: }
196: if (!$this->_elements[$i]->isContainer()) {
197: $ret[] =& $this->_elements[$i];
198: } else {
199: $elements =& $this->_elements[$i]->getElements(true);
200: $count2 = count($elements);
201: for ($j = 0; $j < $count2; $j++) {
202: $ret[] =& $elements[$j];
203: }
204: unset($elements);
205: }
206: }
207: return $ret;
208: }
209: }
210:
211: /**
212: * get an array of "name" attributes of form elements
213: *
214: * @return array array of form element names
215: */
216: function getElementNames()
217: {
218: $ret = array();
219: $elements =& $this->getElements(true);
220: $count = count($elements);
221: for ($i = 0; $i < $count; $i++) {
222: $ret[] = $elements[$i]->getName();
223: }
224: return $ret;
225: }
226:
227: /**
228: * get a reference to a {@link XoopsFormElement} object by its "name"
229: *
230: * @param string $name "name" attribute assigned to a {@link XoopsFormElement}
231: * @return object reference to a {@link XoopsFormElement}, false if not found
232: */
233: function &getElementByName($name){
234: $elements =& $this->getElements(true);
235: $count = count($elements);
236: for ($i = 0; $i < $count; $i++) {
237: if ($name == $elements[$i]->getName()) {
238: return $elements[$i];
239: }
240: }
241: $ret = false;
242: return $ret;
243: }
244:
245: /**
246: * Sets the "value" attribute of a form element
247: *
248: * @param string $name the "name" attribute of a form element
249: * @param string $value the "value" attribute of a form element
250: */
251: function setElementValue($name, $value){
252: $ele =& $this->getElementByName($name);
253: if (is_object($ele) && method_exists($ele, 'setValue')) {
254: $ele->setValue($value);
255: }
256: }
257:
258: /**
259: * Sets the "value" attribute of form elements in a batch
260: *
261: * @param array $values array of name/value pairs to be assigned to form elements
262: */
263: function setElementValues($values){
264: if (is_array($values) && !empty($values)) {
265: // will not use getElementByName() for performance..
266: $elements =& $this->getElements(true);
267: $count = count($elements);
268: for ($i = 0; $i < $count; $i++) {
269: $name = $elements[$i]->getName();
270: if ($name && isset($values[$name]) && method_exists($elements[$i], 'setValue')) {
271: $elements[$i]->setValue($values[$name]);
272: }
273: }
274: }
275: }
276:
277: /**
278: * Gets the "value" attribute of a form element
279: *
280: * @param string $name the "name" attribute of a form element
281: * @return string the "value" attribute assigned to a form element, null if not set
282: */
283: function &getElementValue($name){
284: $ele =& $this->getElementByName($name);
285: if (is_object($ele) && method_exists($ele, 'getValue')) {
286: return $ele->getValue($value);
287: }
288:
289: $ret = null;
290: return $ret;
291: }
292:
293: /**
294: * gets the "value" attribute of all form elements
295: *
296: * @return array array of name/value pairs assigned to form elements
297: */
298: function &getElementValues(){
299: // will not use getElementByName() for performance..
300: $elements =& $this->getElements(true);
301: $count = count($elements);
302: $values = array();
303: for ($i = 0; $i < $count; $i++) {
304: $name = $elements[$i]->getName();
305: if ($name && method_exists($elements[$i], 'getValue')) {
306: $values[$name] =& $elements[$i]->getValue();
307: }
308: }
309: return $values;
310: }
311:
312: /**
313: * set the extra attributes for the <form> tag
314: *
315: * @param string $extra extra attributes for the <form> tag
316: */
317: function setExtra($extra){
318: $this->_extra = " ".$extra;
319: }
320:
321: /**
322: * get the extra attributes for the <form> tag
323: *
324: * @return string
325: */
326: function &getExtra(){
327: if (isset($this->_extra)) {
328: $ret =& $this->_extra;
329: } else {
330: $ret = '';
331: }
332: return $ret;
333: }
334:
335: /**
336: * make an element "required"
337: *
338: * @param object &$formElement reference to a {@link XoopsFormElement}
339: */
340: function setRequired(&$formElement){
341: $this->_required[] =& $formElement;
342: }
343:
344: /**
345: * get an array of "required" form elements
346: *
347: * @return array array of {@link XoopsFormElement}s
348: */
349: function &getRequired(){
350: return $this->_required;
351: }
352:
353: /**
354: * insert a break in the form
355: *
356: * This method is abstract. It must be overwritten in the child classes.
357: *
358: * @param string $extra extra information for the break
359: * @abstract
360: */
361: function insertBreak($extra = null){
362: }
363:
364: /**
365: * returns renderered form
366: *
367: * This method is abstract. It must be overwritten in the child classes.
368: *
369: * @abstract
370: */
371: function render(){
372: }
373:
374: /**
375: * displays rendered form
376: */
377: function display(){
378: echo $this->render();
379: }
380:
381: /**
382: * Renders the Javascript function needed for client-side for validation
383: *
384: * @param boolean $withtags Include the < javascript > tags in the returned string
385: */
386: function renderValidationJS( $withtags = true ) {
387: $root =& XCube_Root::getSingleton();
388: $renderSystem =& $root->getRenderSystem(XOOPSFORM_DEPENDENCE_RENDER_SYSTEM);
389:
390: $renderTarget =& $renderSystem->createRenderTarget();
391:
392: $renderTarget->setAttribute('legacy_module', 'legacy');
393: $renderTarget->setTemplateName("legacy_xoopsform_opt_validationjs.html");
394: $renderTarget->setAttribute('form', $this);
395: $renderTarget->setAttribute('withtags', $withtags);
396:
397: $required =& $this->getRequired();
398: $reqcount = count($required);
399:
400: $renderTarget->setAttribute('required', $required);
401: $renderTarget->setAttribute('required_count', $reqcount);
402:
403: $renderSystem->render($renderTarget);
404:
405: return $renderTarget->getResult();
406:
407:
408: $js = "";
409: if ( $withtags ) {
410: $js .= "\n<!-- Start Form Vaidation JavaScript //-->\n<script type='text/javascript'>\n<!--//\n";
411: }
412: $myts =& MyTextSanitizer::getInstance();
413: $formname = $this->getName();
414: $required =& $this->getRequired();
415: $reqcount = count($required);
416: $js .= "function xoopsFormValidate_{$formname}() {
417: myform = window.document.$formname;\n";
418: for ($i = 0; $i < $reqcount; $i++) {
419: $eltname = $required[$i]->getName();
420: $eltcaption = trim( $required[$i]->getCaption() );
421: $eltmsg = empty($eltcaption) ? sprintf( _FORM_ENTER, $eltname ) : sprintf( _FORM_ENTER, $eltcaption );
422: $eltmsg = str_replace('"', '\"', stripslashes($eltmsg));
423: $js .= "if ( myform.{$eltname}.value == \"\" ) "
424: . "{ window.alert(\"{$eltmsg}\"); myform.{$eltname}.focus(); return false; }\n";
425: }
426: $js .= "return true;\n}\n";
427: if ( $withtags ) {
428: $js .= "//--></script>\n<!-- End Form Vaidation JavaScript //-->\n";
429: }
430: return $js;
431: }
432: /**
433: * assign to smarty form template instead of displaying directly
434: *
435: * @param object &$tpl reference to a {@link Smarty} object
436: * @see Smarty
437: */
438: function assign(&$tpl){
439: $i = 0;
440: $elements = array();
441: foreach ( $this->getElements() as $ele ) {
442: $n = ($ele->getName() != "") ? $ele->getName() : $i;
443: $elements[$n]['name'] = $ele->getName();
444: $elements[$n]['caption'] = $ele->getCaption();
445: $elements[$n]['body'] = $ele->render();
446: $elements[$n]['hidden'] = $ele->isHidden();
447: if ($ele->getDescription() != '') {
448: $elements[$n]['description'] = $ele->getDescription();
449: }
450: $i++;
451: }
452: $js = $this->renderValidationJS();
453: $tpl->assign($this->getName(), array('title' => $this->getTitle(), 'name' => $this->getName(), 'action' => $this->getAction(), 'method' => $this->getMethod(), 'extra' => 'onsubmit="return xoopsFormValidate_'.$this->getName().'();"'.$this->getExtra(), 'javascript' => $js, 'elements' => $elements));
454: }
455: }
456: ?>