1: <?php
2: /**
3: * XOOPS form element
4: *
5: * You may not change or alter any portion of this comment or credits
6: * of supporting developers from this source code or any supporting source code
7: * which is considered copyrighted (c) material of the original comment or credit authors.
8: * This program is distributed in the hope that it will be useful,
9: * but WITHOUT ANY WARRANTY; without even the implied warranty of
10: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
11: *
12: * @copyright (c) 2000-2016 XOOPS Project (www.xoops.org)
13: * @license GNU GPL 2 (http://www.gnu.org/licenses/gpl-2.0.html)
14: * @package kernel
15: * @subpackage form
16: * @since 2.0.0
17: */
18:
19: defined('XOOPS_ROOT_PATH') || exit('Restricted access');
20:
21: /**
22: * Abstract base class for form elements
23: */
24: class XoopsFormElement
25: {
26: /**
27: * Javascript performing additional validation of this element data
28: *
29: * This property contains a list of Javascript snippets that will be sent to
30: * XoopsForm::renderValidationJS().
31: * NB: All elements are added to the output one after the other, so don't forget
32: * to add a ";" after each to ensure no Javascript syntax error is generated.
33: *
34: * @var array ()
35: */
36: public $customValidationCode = array();
37:
38: /**
39: * *#@+
40: *
41: * @access private
42: */
43: /**
44: * "name" attribute of the element
45: *
46: * @var string
47: */
48: public $_name;
49:
50: /**
51: * caption of the element
52: *
53: * @var string
54: */
55: public $_caption;
56:
57: /**
58: * Accesskey for this element
59: *
60: * @var string
61: */
62: public $_accesskey = '';
63:
64: /**
65: * HTML classes for this element
66: *
67: * @var array
68: */
69: public $_class = array();
70:
71: /**
72: * hidden?
73: *
74: * @var bool
75: */
76: public $_hidden = false;
77:
78: /**
79: * extra attributes to go in the tag
80: *
81: * @var array
82: */
83: public $_extra = array();
84:
85: /**
86: * required field?
87: *
88: * @var bool
89: */
90: public $_required = false;
91:
92: /**
93: * description of the field
94: *
95: * @var string
96: */
97: public $_description = '';
98:
99: /**
100: * *#@-
101: */
102:
103: /**
104: * CAtzwolf: Modified for No Colspan
105: *
106: * Lets a developer have only one column in a form element rather than two.
107: * Example of usgage: Allows text editors to span 2 columns rathe than pushed into one column
108: *
109: * @deprecated PLEASE AVOID USING THIS METHOD
110: *
111: * @var bool
112: */
113: public $_nocolspan = false;
114:
115: /**
116: * Get form type
117: *
118: * @deprecated PLEASE AVOID USING THIS METHOD
119: */
120: public $_formtype = '';
121:
122: /**
123: * constructor
124: */
125: public function __construct()
126: {
127: exit('This class cannot be instantiated!');
128: }
129:
130: /**
131: * Is this element a container of other elements?
132: *
133: * @return bool false
134: */
135: public function isContainer()
136: {
137: return false;
138: }
139:
140: /**
141: * set the "name" attribute for the element
142: *
143: * @param string $name "name" attribute for the element
144: */
145: public function setName($name)
146: {
147: $this->_name = trim($name);
148: }
149:
150: /**
151: * get the "name" attribute for the element
152: *
153: * @param bool $encode
154: *
155: * @return string "name" attribute
156: */
157: public function getName($encode = true)
158: {
159: if (false !== (bool)$encode) {
160: return str_replace('&', '&', htmlspecialchars($this->_name, ENT_QUOTES));
161: }
162:
163: return $this->_name;
164: }
165:
166: /**
167: * set the "accesskey" attribute for the element
168: *
169: * @param string $key "accesskey" attribute for the element
170: */
171: public function setAccessKey($key)
172: {
173: $this->_accesskey = trim($key);
174: }
175:
176: /**
177: * get the "accesskey" attribute for the element
178: *
179: * @return string "accesskey" attribute value
180: */
181: public function getAccessKey()
182: {
183: return $this->_accesskey;
184: }
185:
186: /**
187: * If the accesskey is found in the specified string, underlines it
188: *
189: * @param string $str String where to search the accesskey occurence
190: * @return string Enhanced string with the 1st occurence of accesskey underlined
191: */
192: public function getAccessString($str)
193: {
194: $access = $this->getAccessKey();
195: if (!empty($access) && (false !== ($pos = strpos($str, $access)))) {
196: return htmlspecialchars(substr($str, 0, $pos), ENT_QUOTES) . '<span style="text-decoration: underline;">' . htmlspecialchars(substr($str, $pos, 1), ENT_QUOTES) . '</span>' . htmlspecialchars(substr($str, $pos + 1), ENT_QUOTES);
197: }
198:
199: return htmlspecialchars($str, ENT_QUOTES);
200: }
201:
202: /**
203: * set the "class" attribute for the element
204: *
205: * @param string $class
206: */
207: public function setClass($class)
208: {
209: $class = trim($class);
210: if (!empty($class)) {
211: $this->_class[] = $class;
212: }
213: }
214:
215: /**
216: * get the "class" attribute for the element
217: *
218: * @return string "class" attribute value
219: */
220: public function getClass()
221: {
222: if (empty($this->_class)) {
223: return false;
224: }
225: $classes = array();
226: foreach ($this->_class as $class) {
227: $classes[] = htmlspecialchars($class, ENT_QUOTES);
228: }
229:
230: return implode(' ', $classes);
231: }
232:
233: /**
234: * set the caption for the element
235: *
236: * @param string $caption
237: */
238: public function setCaption($caption)
239: {
240: $this->_caption = trim($caption);
241: }
242:
243: /**
244: * get the caption for the element
245: *
246: * @param bool $encode To sanitizer the text?
247: * @return string
248: */
249: public function getCaption($encode = false)
250: {
251: return $encode ? htmlspecialchars($this->_caption, ENT_QUOTES) : $this->_caption;
252: }
253:
254: /**
255: * get the caption for the element
256: *
257: * @param bool $encode To sanitizer the text?
258: * @return string
259: */
260: public function getTitle($encode = true)
261: {
262: if (strlen($this->_description) > 0) {
263: return $encode ? htmlspecialchars(strip_tags($this->_caption . ' - ' . $this->_description), ENT_QUOTES) : strip_tags($this->_caption . ' - ' . $this->_description);
264: } else {
265: return $encode ? htmlspecialchars(strip_tags($this->_caption), ENT_QUOTES) : strip_tags($this->_caption);
266: }
267: }
268:
269: /**
270: * set the element's description
271: *
272: * @param string $description
273: */
274: public function setDescription($description)
275: {
276: $this->_description = trim($description);
277: }
278:
279: /**
280: * get the element's description
281: *
282: * @param bool $encode To sanitizer the text?
283: * @return string
284: */
285: public function getDescription($encode = false)
286: {
287: return $encode ? htmlspecialchars($this->_description, ENT_QUOTES) : $this->_description;
288: }
289:
290: /**
291: * flag the element as "hidden"
292: */
293: public function setHidden()
294: {
295: $this->_hidden = true;
296: }
297:
298: /**
299: * Find out if an element is "hidden".
300: *
301: * @return bool
302: */
303: public function isHidden()
304: {
305: return $this->_hidden;
306: }
307:
308: /**
309: * Find out if an element is required.
310: *
311: * @return bool
312: */
313: public function isRequired()
314: {
315: return $this->_required;
316: }
317:
318: /**
319: * Add extra attributes to the element.
320: *
321: * This string will be inserted verbatim and unvalidated in the
322: * element's tag. Know what you are doing!
323: *
324: * @param string $extra
325: * @param bool $replace If true, passed string will replace current content otherwise it will be appended to it
326: * @return array New content of the extra string
327: */
328: public function setExtra($extra, $replace = false)
329: {
330: if ($replace) {
331: $this->_extra = array(trim($extra));
332: } else {
333: $this->_extra[] = trim($extra);
334: }
335:
336: return $this->_extra;
337: }
338:
339: /**
340: * Get the extra attributes for the element
341: *
342: * @param bool $encode To sanitizer the text?
343: * @return string
344: */
345: public function getExtra($encode = false)
346: {
347: if (!$encode) {
348: return ' ' . implode(' ', $this->_extra);
349: }
350: $value = array();
351: foreach ($this->_extra as $val) {
352: $value[] = str_replace('>', '>', str_replace('<', '<', $val));
353: }
354:
355: return empty($value) ? '' : ' ' . implode(' ', $value);
356: }
357:
358: /**
359: * Set the element's nocolspan
360: * Modified by Catzwolf
361: *
362: * @param bool $nocolspan
363: *
364: * @deprecated PLEASE AVOID USING THIS METHOD
365: */
366: public function setNocolspan($nocolspan = true)
367: {
368: $this->_nocolspan = $nocolspan;
369: }
370:
371: /**
372: * Get the element's nocolspan
373: * Modified by Catzwolf
374: *
375: * @return string
376: *
377: * @deprecated PLEASE AVOID USING THIS METHOD
378: */
379: public function getNocolspan()
380: {
381: return $this->_nocolspan;
382: }
383:
384: /**
385: * get the element's nocolspan
386: * Modified by Catzwolf
387: *
388: * @return string
389: *
390: * @deprecated PLEASE AVOID USING THIS METHOD
391: */
392: public function getFormType()
393: {
394: return $this->_formtype;
395: }
396:
397: /**
398: * set the element's nocolspan
399: * Modified by Catzwolf
400: *
401: * @param string $value
402: *
403: * @deprecated PLEASE AVOID USING THIS METHOD
404: */
405: public function setFormType($value = '')
406: {
407: $this->_formtype = $value;
408: }
409:
410: /**
411: * Render custom javascript validation code
412: *
413: * @seealso XoopsForm::renderValidationJS
414: */
415: public function renderValidationJS()
416: {
417: // render custom validation code if any
418: if (!empty($this->customValidationCode)) {
419: return implode(NWLINE, $this->customValidationCode);
420: // generate validation code if required
421: } elseif ($this->isRequired() && $eltname = $this->getName()) {
422: // $eltname = $this->getName();
423: $eltcaption = $this->getCaption();
424: $eltmsg = empty($eltcaption) ? sprintf(_FORM_ENTER, $eltname) : sprintf(_FORM_ENTER, $eltcaption);
425: $eltmsg = str_replace(array(':', '?', '%'), '', $eltmsg);
426: $eltmsg = str_replace('"', '\"', stripslashes($eltmsg));
427: $eltmsg = strip_tags($eltmsg);
428: echo $this->getFormType();
429: switch ($this->getFormType()) {
430: case 'checkbox':
431: return NWLINE . "if (!myform.{$eltname}.checked) { window.alert(\"{$eltmsg}\"); myform.{$eltname}.focus(); return false; }\n";
432: break;
433: default:
434: return NWLINE . "if (myform.{$eltname}.value == \"\") { window.alert(\"{$eltmsg}\"); myform.{$eltname}.focus(); return false; }\n";
435: break;
436: } // switch
437: }
438:
439: return false;
440: }
441:
442: /**
443: * Generates output for the element.
444: *
445: * This method is abstract and must be overwritten by the child classes.
446: *
447: * @abstract
448: */
449: public function render()
450: {
451: }
452: }
453: