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 (https://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('&amp;', '&', htmlspecialchars((string)$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|false "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(!isset($this->_caption)) {
263: $this->_caption = '';
264: }
265: if (strlen($this->_description) > 0) {
266: return $encode ? htmlspecialchars(strip_tags($this->_caption . ' - ' . $this->_description), ENT_QUOTES) : strip_tags($this->_caption . ' - ' . $this->_description);
267: } else {
268: return $encode ? htmlspecialchars(strip_tags($this->_caption), ENT_QUOTES) : strip_tags($this->_caption);
269: }
270: }
271:
272: /**
273: * set the element's description
274: *
275: * @param string $description
276: */
277: public function setDescription($description)
278: {
279: $this->_description = (isset($description) && !empty($description)) ? trim($description) : $description;
280: }
281:
282: /**
283: * get the element's description
284: *
285: * @param bool $encode To sanitizer the text?
286: * @return string
287: */
288: public function getDescription($encode = false)
289: {
290: return $encode ? htmlspecialchars($this->_description, ENT_QUOTES) : $this->_description;
291: }
292:
293: /**
294: * flag the element as "hidden"
295: */
296: public function setHidden()
297: {
298: $this->_hidden = true;
299: }
300:
301: /**
302: * Find out if an element is "hidden".
303: *
304: * @return bool
305: */
306: public function isHidden()
307: {
308: return $this->_hidden;
309: }
310:
311: /**
312: * Find out if an element is required.
313: *
314: * @return bool
315: */
316: public function isRequired()
317: {
318: return $this->_required;
319: }
320:
321: /**
322: * Add extra attributes to the element.
323: *
324: * This string will be inserted verbatim and unvalidated in the
325: * element's tag. Know what you are doing!
326: *
327: * @param string $extra
328: * @param bool $replace If true, passed string will replace current content otherwise it will be appended to it
329: * @return array New content of the extra string
330: */
331: public function setExtra($extra, $replace = false)
332: {
333: if ($replace) {
334: $this->_extra = array(trim($extra));
335: } else {
336: $this->_extra[] = trim($extra);
337: }
338:
339: return $this->_extra;
340: }
341:
342: /**
343: * Get the extra attributes for the element
344: *
345: * @param bool $encode To sanitizer the text?
346: * @return string
347: */
348: public function getExtra($encode = false)
349: {
350: if (!$encode) {
351: return ' ' . implode(' ', $this->_extra);
352: }
353: $value = array();
354: foreach ($this->_extra as $val) {
355: $value[] = str_replace('>', '&gt;', str_replace('<', '&lt;', $val));
356: }
357:
358: return empty($value) ? '' : ' ' . implode(' ', $value);
359: }
360:
361: /**
362: * Set the element's nocolspan
363: * Modified by Catzwolf
364: *
365: * @param bool $nocolspan
366: *
367: * @deprecated PLEASE AVOID USING THIS METHOD
368: */
369: public function setNocolspan($nocolspan = true)
370: {
371: $this->_nocolspan = $nocolspan;
372: }
373:
374: /**
375: * Get the element's nocolspan
376: * Modified by Catzwolf
377: *
378: * @return string|bool
379: *
380: * @deprecated PLEASE AVOID USING THIS METHOD
381: */
382: public function getNocolspan()
383: {
384: return $this->_nocolspan;
385: }
386:
387: /**
388: * get the element's nocolspan
389: * Modified by Catzwolf
390: *
391: * @return string
392: *
393: * @deprecated PLEASE AVOID USING THIS METHOD
394: */
395: public function getFormType()
396: {
397: return $this->_formtype;
398: }
399:
400: /**
401: * set the element's nocolspan
402: * Modified by Catzwolf
403: *
404: * @param string $value
405: *
406: * @deprecated PLEASE AVOID USING THIS METHOD
407: */
408: public function setFormType($value = '')
409: {
410: $this->_formtype = $value;
411: }
412:
413: /**
414: * Render custom javascript validation code
415: *
416: * @seealso XoopsForm::renderValidationJS
417: */
418: public function renderValidationJS()
419: {
420: // render custom validation code if any
421: if (!empty($this->customValidationCode)) {
422: return implode(NWLINE, $this->customValidationCode);
423: // generate validation code if required
424: } elseif ($this->isRequired() && $eltname = $this->getName()) {
425: // $eltname = $this->getName();
426: $eltcaption = $this->getCaption();
427: $eltmsg = empty($eltcaption) ? sprintf(_FORM_ENTER, $eltname) : sprintf(_FORM_ENTER, $eltcaption);
428: $eltmsg = str_replace(array(':', '?', '%'), '', $eltmsg);
429: $eltmsg = str_replace('"', '\"', stripslashes($eltmsg));
430: $eltmsg = strip_tags($eltmsg);
431: echo $this->getFormType();
432: switch ($this->getFormType()) {
433: case 'checkbox':
434: return NWLINE . "if (!myform.{$eltname}.checked) { window.alert(\"{$eltmsg}\"); myform.{$eltname}.focus(); return false; }\n";
435: default:
436: return NWLINE . "if (myform.{$eltname}.value == \"\") { window.alert(\"{$eltmsg}\"); myform.{$eltname}.focus(); return false; }\n";
437: } // switch
438: }
439:
440: return false;
441: }
442:
443: /**
444: * Generates output for the element.
445: *
446: * This method is abstract and must be overwritten by the child classes.
447: *
448: * @abstract
449: */
450: public function render()
451: {
452: }
453: }
454: