1: <?php
2: /**
3: * XOOPS Kernel Object
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-2019 XOOPS Project (https://xoops.org)
13: * @license GNU GPL 2 (https://www.gnu.org/licenses/gpl-2.0.html)
14: * @package kernel
15: * @since 2.0.0
16: * @author Kazumi Ono (AKA onokazu) http://www.myweb.ne.jp/, http://jp.xoops.org/
17: * @author Taiwen Jiang <phppp@users.sourceforge.net>
18: */
19:
20: defined('XOOPS_ROOT_PATH') || exit('Restricted access');
21: /**
22: * YOU SHOULD NOT USE ANY OF THE UNICODE TYPES, THEY WILL BE REMOVED
23: */
24:
25: /**
26: * *#@+
27: * Xoops object datatype
28: */
29: define('XOBJ_DTYPE_TXTBOX', 1);
30: define('XOBJ_DTYPE_TXTAREA', 2);
31: define('XOBJ_DTYPE_INT', 3);
32: define('XOBJ_DTYPE_URL', 4);
33: define('XOBJ_DTYPE_EMAIL', 5);
34: define('XOBJ_DTYPE_ARRAY', 6);
35: define('XOBJ_DTYPE_OTHER', 7);
36: define('XOBJ_DTYPE_SOURCE', 8);
37: define('XOBJ_DTYPE_STIME', 9);
38: define('XOBJ_DTYPE_MTIME', 10);
39: define('XOBJ_DTYPE_LTIME', 11);
40: define('XOBJ_DTYPE_FLOAT', 13);
41: define('XOBJ_DTYPE_DECIMAL', 14);
42: define('XOBJ_DTYPE_ENUM', 15);
43: // YOU SHOULD NEVER USE THE FOLLOWING TYPES, THEY WILL BE REMOVED
44: define('XOBJ_DTYPE_UNICODE_TXTBOX', 16);
45: define('XOBJ_DTYPE_UNICODE_TXTAREA', 17);
46: define('XOBJ_DTYPE_UNICODE_URL', 18);
47: define('XOBJ_DTYPE_UNICODE_EMAIL', 19);
48: define('XOBJ_DTYPE_UNICODE_ARRAY', 20);
49: define('XOBJ_DTYPE_UNICODE_OTHER', 21);
50: // Addition for 2.5.5
51: define('XOBJ_DTYPE_DATE', 22);
52: define('XOBJ_DTYPE_TIME', 23);
53: define('XOBJ_DTYPE_TIMESTAMP', 24);
54:
55: /**
56: * Base class for all objects in the Xoops kernel (and beyond)
57: */
58: class XoopsObject
59: {
60: /**
61: * holds all variables(properties) of an object
62: *
63: * @var array
64: * @access protected
65: */
66: public $vars = array();
67:
68: /**
69: * variables cleaned for store in DB
70: *
71: * @var array
72: * @access protected
73: */
74: public $cleanVars = array();
75:
76: /**
77: * is it a newly created object?
78: *
79: * @var bool
80: * @access private
81: */
82: public $_isNew = false;
83:
84: /**
85: * has any of the values been modified?
86: *
87: * @var bool
88: * @access private
89: */
90: public $_isDirty = false;
91:
92: /**
93: * errors
94: *
95: * @var array
96: * @access private
97: */
98: public $_errors = array();
99:
100: /**
101: * additional filters registered dynamically by a child class object
102: *
103: * @access private
104: */
105: public $_filters = array();
106:
107: /**
108: * constructor
109: *
110: * normally, this is called from child classes only
111: *
112: * @access public
113: */
114: public function __construct()
115: {
116: }
117:
118: /**
119: * PHP 4 style constructor compatibility shim
120: * @deprecated all callers should be using parent::__construct()
121: */
122: public function XoopsObject()
123: {
124: $trace = debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS, 1);
125: trigger_error("Should call parent::__construct in {$trace[0]['file']} line {$trace[0]['line']},", E_USER_DEPRECATED);
126: self::__construct();
127: }
128:
129: /**
130: * *#@+
131: * used for new/clone objects
132: *
133: * @access public
134: */
135: public function setNew()
136: {
137: $this->_isNew = true;
138: }
139:
140: public function unsetNew()
141: {
142: $this->_isNew = false;
143: }
144:
145: /**
146: * @return bool
147: */
148: public function isNew()
149: {
150: return $this->_isNew;
151: }
152:
153: /**
154: * *#@+
155: * mark modified objects as dirty
156: *
157: * used for modified objects only
158: *
159: * @access public
160: */
161: public function setDirty()
162: {
163: $this->_isDirty = true;
164: }
165:
166: public function unsetDirty()
167: {
168: $this->_isDirty = false;
169: }
170:
171: /**
172: * @return bool
173: */
174: public function isDirty()
175: {
176: return $this->_isDirty;
177: }
178:
179: /**
180: * initialize variables for the object
181: *
182: * YOU SHOULD NOT USE THE $enumeration PARAMETER
183: *
184: * @access public
185: *
186: * @param string $key
187: * @param int $data_type set to one of XOBJ_DTYPE_XXX constants (set to XOBJ_DTYPE_OTHER if no data type checking nor text sanitizing is required)
188: * @param mixed $value
189: * @param bool $required require html form input?
190: * @param int|null $maxlength for XOBJ_DTYPE_TXTBOX type only
191: * @param string $options
192: * @param string $enumerations
193: *
194: * @return void
195: */
196: public function initVar($key, $data_type, $value = null, $required = false, $maxlength = null, $options = '', $enumerations = '')
197: {
198: $this->vars[$key] = array(
199: 'value' => $value,
200: 'required' => $required,
201: 'data_type' => $data_type,
202: 'maxlength' => $maxlength,
203: 'changed' => false,
204: 'options' => $options,
205: 'enumeration' => $enumerations);
206: }
207:
208: /**
209: * assign a value to a variable
210: *
211: * @access public
212: * @param string $key name of the variable to assign
213: * @param mixed $value value to assign
214: */
215: public function assignVar($key, $value)
216: {
217: if (isset($key) && isset($this->vars[$key])) {
218: switch ($this->vars[$key]['data_type']) {
219: case XOBJ_DTYPE_UNICODE_ARRAY:
220: if (is_array($value)) {
221: $temp = $value;
222: array_walk($temp, 'xoops_aw_decode');
223: $value = $temp;
224: $this->vars[$key]['value'] = $value;
225: } else {
226: $this->vars[$key]['value'] = xoops_convert_decode($value);
227: }
228: break;
229: case XOBJ_DTYPE_UNICODE_URL:
230: case XOBJ_DTYPE_UNICODE_EMAIL:
231: case XOBJ_DTYPE_UNICODE_OTHER:
232: case XOBJ_DTYPE_UNICODE_TXTBOX:
233: case XOBJ_DTYPE_UNICODE_TXTAREA:
234: $this->vars[$key]['value'] = xoops_convert_decode($value);
235: break;
236: case XOBJ_DTYPE_DATE:
237: if (!is_string($value) && is_numeric($value)) {
238: $this->vars[$key]['value'] = date(_DBDATESTRING, $value);
239: } else {
240: $this->vars[$key]['value'] = date(_DBDATESTRING, strtotime($value));
241: }
242: break;
243: case XOBJ_DTYPE_TIME:
244: if (!is_string($value) && is_numeric($value)) {
245: $this->vars[$key]['value'] = date(_DBTIMESTRING, $value);
246: } else {
247: $this->vars[$key]['value'] = date(_DBTIMESTRING, strtotime($value));
248: }
249: break;
250: case XOBJ_DTYPE_TIMESTAMP:
251: if (!is_string($value) && is_numeric($value)) {
252: $this->vars[$key]['value'] = date(_DBTIMESTAMPSTRING, $value);
253: } else {
254: $this->vars[$key]['value'] = date(_DBTIMESTAMPSTRING, strtotime($value));
255: }
256: break;
257: // YOU SHOULD NOT USE THE ABOVE TYPES, THEY WILL BE REMOVED
258: default:
259: $this->vars[$key]['value'] =& $value;
260: }
261: }
262: }
263:
264: /**
265: * assign values to multiple variables in a batch
266: *
267: * @access private
268: * @param array $var_arr associative array of values to assign
269: */
270: public function assignVars($var_arr)
271: {
272: if (is_array($var_arr)) {
273: foreach ($var_arr as $key => $value) {
274: $this->assignVar($key, $value);
275: }
276: }
277: }
278:
279: /**
280: * assign a value to a variable
281: *
282: * @access public
283: * @param string $key name of the variable to assign
284: * @param mixed $value value to assign
285: * @param bool $not_gpc
286: */
287: public function setVar($key, $value, $not_gpc = false)
288: {
289: if (!empty($key) && isset($value) && isset($this->vars[$key])) {
290: $this->vars[$key]['value'] =& $value;
291: $this->vars[$key]['not_gpc'] = $not_gpc;
292: $this->vars[$key]['changed'] = true;
293: $this->setDirty();
294: }
295: }
296:
297: /**
298: * assign values to multiple variables in a batch
299: *
300: * @access private
301: * @param array $var_arr associative array of values to assign
302: * @param bool $not_gpc
303: */
304: public function setVars($var_arr, $not_gpc = false)
305: {
306: if (is_array($var_arr)) {
307: foreach ($var_arr as $key => $value) {
308: $this->setVar($key, $value, $not_gpc);
309: }
310: }
311: }
312:
313: /**
314: * unset variable(s) for the object
315: *
316: * @access public
317: *
318: * @param mixed $var
319: *
320: * @return bool
321: */
322: public function destroyVars($var)
323: {
324: if (empty($var)) {
325: return true;
326: }
327: $var = !is_array($var) ? array($var) : $var;
328: foreach ($var as $key) {
329: if (!isset($this->vars[$key])) {
330: continue;
331: }
332: $this->vars[$key]['changed'] = null;
333: }
334:
335: return true;
336: }
337:
338: /**
339: * @param mixed $var
340: * @return bool
341: * @deprecated use destroyVars() instead, destoryVars() will be removed in the next major release
342: */
343: public function destoryVars($var)
344: {
345: $trace = debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS, 1);
346: $GLOBALS['xoopsLogger']->addDeprecated(__METHOD__ . "() is deprecated, called from {$trace[0]['file']}line {$trace[0]['line']}");
347: return $this->destroyVars($var);
348: }
349:
350: /**
351: * Assign values to multiple variables in a batch
352: *
353: * Meant for a CGI context:
354: * - prefixed CGI args are considered save
355: * - avoids polluting of namespace with CGI args
356: *
357: * @param array $var_arr associative array of values to assign
358: * @param string $pref prefix (only keys starting with the prefix will be set)
359: * @param bool $not_gpc
360: *
361: * @return void
362: *
363: * @deprecated This method will be removed in the next major XOOPS version
364: */
365: public function setFormVars($var_arr = null, $pref = 'xo_', $not_gpc = false)
366: {
367: $trace = debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS, 1);
368: $GLOBALS['xoopsLogger']->addDeprecated(__METHOD__ . "() is deprecated, called from {$trace[0]['file']}line {$trace[0]['line']}");
369:
370: $len = strlen($pref);
371: if (is_array($var_arr)) {
372: foreach ($var_arr as $key => $value) {
373: if ($pref == substr($key, 0, $len)) {
374: $this->setVar(substr($key, $len), $value, $not_gpc);
375: }
376: }
377: }
378: }
379:
380: /**
381: * returns all variables for the object
382: *
383: * @access public
384: * @return array associative array of key->value pairs
385: */
386: public function &getVars()
387: {
388: return $this->vars;
389: }
390:
391: /**
392: * Returns the values of the specified variables
393: *
394: * @param mixed $keys An array containing the names of the keys to retrieve, or null to get all of them
395: * @param string $format Format to use (see getVar)
396: * @param int $maxDepth Maximum level of recursion to use if some vars are objects themselves
397: * @return array associative array of key->value pairs
398: */
399: public function getValues($keys = null, $format = 's', $maxDepth = 1)
400: {
401: if (!isset($keys)) {
402: $keys = array_keys($this->vars);
403: }
404: $vars = array();
405: foreach ($keys as $key) {
406: if (isset($this->vars[$key])) {
407: if (is_object($this->vars[$key]) && is_a($this->vars[$key], 'XoopsObject')) {
408: if ($maxDepth) {
409: $vars[$key] = $this->vars[$key]->getValues(null, $format, $maxDepth - 1);
410: }
411: } else {
412: $vars[$key] = $this->getVar($key, $format);
413: }
414: }
415: }
416:
417: return $vars;
418: }
419:
420: /**
421: * returns a specific variable for the object in a proper format
422: *
423: * YOU SHOULD NOT USE ANY OF THE UNICODE TYPES, THEY WILL BE REMOVED
424: *
425: * @access public
426: * @param string $key key of the object's variable to be returned
427: * @param string|null $format format to use for the output
428: * @return mixed formatted value of the variable
429: */
430: public function getVar($key, $format = null)
431: {
432: $format = (null === $format) ? 's' : (string) $format;
433: $ret = null;
434: if (!isset($this->vars[$key])) {
435: return $ret;
436: }
437: $ret = $this->vars[$key]['value'];
438: $myts = \MyTextSanitizer::getInstance();
439: switch ($this->vars[$key]['data_type']) {
440: case XOBJ_DTYPE_INT:
441: $ret = (null === $ret) ? null : (int) $ret;
442: break;
443: case XOBJ_DTYPE_UNICODE_TXTBOX:
444: case XOBJ_DTYPE_TXTBOX:
445: switch (strtolower($format)) {
446: case 's':
447: case 'show':
448: case 'e':
449: case 'edit':
450: return $myts->htmlSpecialChars($ret);
451: break 1;
452: case 'p':
453: case 'preview':
454: case 'f':
455: case 'formpreview':
456: return $myts->htmlSpecialChars($myts->stripSlashesGPC($ret));
457: break 1;
458: case 'n':
459: case 'none':
460: default:
461: break 1;
462: }
463: break;
464: case XOBJ_DTYPE_UNICODE_TXTAREA:
465: case XOBJ_DTYPE_TXTAREA:
466: switch (strtolower($format)) {
467: case 's':
468: case 'show':
469: $html = !empty($this->vars['dohtml']['value']) ? 1 : 0;
470: $xcode = (!isset($this->vars['doxcode']['value']) || $this->vars['doxcode']['value'] == 1) ? 1 : 0;
471: $smiley = (!isset($this->vars['dosmiley']['value']) || $this->vars['dosmiley']['value'] == 1) ? 1 : 0;
472: $image = (!isset($this->vars['doimage']['value']) || $this->vars['doimage']['value'] == 1) ? 1 : 0;
473: $br = (!isset($this->vars['dobr']['value']) || $this->vars['dobr']['value'] == 1) ? 1 : 0;
474:
475: return $myts->displayTarea($ret, $html, $smiley, $xcode, $image, $br);
476: break 1;
477: case 'e':
478: case 'edit':
479: return htmlspecialchars((string)$ret, ENT_QUOTES);
480: break 1;
481: case 'p':
482: case 'preview':
483: $html = !empty($this->vars['dohtml']['value']) ? 1 : 0;
484: $xcode = (!isset($this->vars['doxcode']['value']) || $this->vars['doxcode']['value'] == 1) ? 1 : 0;
485: $smiley = (!isset($this->vars['dosmiley']['value']) || $this->vars['dosmiley']['value'] == 1) ? 1 : 0;
486: $image = (!isset($this->vars['doimage']['value']) || $this->vars['doimage']['value'] == 1) ? 1 : 0;
487: $br = (!isset($this->vars['dobr']['value']) || $this->vars['dobr']['value'] == 1) ? 1 : 0;
488:
489: return $myts->previewTarea($ret, $html, $smiley, $xcode, $image, $br);
490: break 1;
491: case 'f':
492: case 'formpreview':
493: return htmlspecialchars($myts->stripSlashesGPC($ret), ENT_QUOTES);
494: break 1;
495: case 'n':
496: case 'none':
497: default:
498: break 1;
499: }
500: break;
501: case XOBJ_DTYPE_UNICODE_ARRAY:
502: switch (strtolower($format)) {
503: case 'n':
504: case 'none':
505: break 1;
506: default:
507: if (!is_array($ret)) {
508: if ($ret != '') {
509: $ret = unserialize($ret);
510: }
511: $ret = is_array($ret) ? $ret : array();
512: if (is_array($ret)) {
513: $ret = array_walk($ret, 'xoops_aw_decode');
514: }
515: }
516:
517: return $ret;
518: break 1;
519: }
520: break;
521: case XOBJ_DTYPE_ARRAY:
522: switch (strtolower($format)) {
523: case 'n':
524: case 'none':
525: break 1;
526: default:
527: if (!is_array($ret)) {
528: if ($ret != '') {
529: $ret = unserialize($ret);
530: }
531: $ret = is_array($ret) ? $ret : array();
532: }
533:
534: return $ret;
535: break 1;
536: }
537: break;
538: case XOBJ_DTYPE_SOURCE:
539: switch (strtolower($format)) {
540: case 's':
541: case 'show':
542: break 1;
543: case 'e':
544: case 'edit':
545: return htmlspecialchars($ret, ENT_QUOTES);
546: break 1;
547: case 'p':
548: case 'preview':
549: return $myts->stripSlashesGPC($ret);
550: break 1;
551: case 'f':
552: case 'formpreview':
553: return htmlspecialchars($myts->stripSlashesGPC($ret), ENT_QUOTES);
554: break 1;
555: case 'n':
556: case 'none':
557: default:
558: break 1;
559: }
560: break;
561: case XOBJ_DTYPE_DATE:
562: switch (strtolower($format)) {
563: case 's':
564: case 'show':
565: if (is_string($ret) && !is_numeric($ret)) {
566: return date(_DBDATESTRING, strtotime($ret));
567: } else {
568: return date(_DBDATESTRING, $ret);
569: }
570: break 1;
571: case 'e':
572: case 'edit':
573: if (is_string($ret) && !is_numeric($ret)) {
574: return htmlspecialchars(date(_DBDATESTRING, strtotime($ret)), ENT_QUOTES);
575: } else {
576: return htmlspecialchars(date(_DBDATESTRING, $ret), ENT_QUOTES);
577: }
578: break 1;
579: case 'p':
580: case 'preview':
581: if (is_string($ret) && !is_numeric($ret)) {
582: return $myts->stripSlashesGPC(date(_DBDATESTRING, strtotime($ret)));
583: } else {
584: return $myts->stripSlashesGPC(date(_DBDATESTRING, $ret));
585: }
586: break 1;
587: case 'f':
588: case 'formpreview':
589: if (is_string($ret) && !is_numeric($ret)) {
590: return htmlspecialchars($myts->stripSlashesGPC(date(_DBDATESTRING, strtotime($ret))), ENT_QUOTES);
591: } else {
592: return htmlspecialchars($myts->stripSlashesGPC(date(_DBDATESTRING, $ret)), ENT_QUOTES);
593: }
594: break 1;
595: case 'n':
596: case 'none':
597: default:
598: break 1;
599: }
600: break;
601: case XOBJ_DTYPE_TIME:
602: switch (strtolower($format)) {
603: case 's':
604: case 'show':
605: if (is_string($ret) && !is_numeric($ret)) {
606: return date(_DBTIMESTRING, strtotime($ret));
607: } else {
608: return date(_DBTIMESTRING, $ret);
609: }
610: break 1;
611: case 'e':
612: case 'edit':
613: if (is_string($ret) && !is_numeric($ret)) {
614: return htmlspecialchars(date(_DBTIMESTRING, strtotime($ret)), ENT_QUOTES);
615: } else {
616: return htmlspecialchars(date(_DBTIMESTRING, $ret), ENT_QUOTES);
617: }
618: break 1;
619: case 'p':
620: case 'preview':
621: if (is_string($ret) && !is_numeric($ret)) {
622: return $myts->stripSlashesGPC(date(_DBTIMESTRING, strtotime($ret)));
623: } else {
624: return $myts->stripSlashesGPC(date(_DBTIMESTRING, $ret));
625: }
626: break 1;
627: case 'f':
628: case 'formpreview':
629: if (is_string($ret) && !is_numeric($ret)) {
630: return htmlspecialchars($myts->stripSlashesGPC(date(_DBTIMESTRING, strtotime($ret))), ENT_QUOTES);
631: } else {
632: return htmlspecialchars($myts->stripSlashesGPC(date(_DBTIMESTRING, $ret)), ENT_QUOTES);
633: }
634: break 1;
635: case 'n':
636: case 'none':
637: default:
638: break 1;
639: }
640: break;
641: case XOBJ_DTYPE_TIMESTAMP:
642: switch (strtolower($format)) {
643: case 's':
644: case 'show':
645: if (is_string($ret) && !is_numeric($ret)) {
646: return date(_DBTIMESTAMPSTRING, strtotime($ret));
647: } else {
648: return date(_DBTIMESTAMPSTRING, $ret);
649: }
650: break 1;
651: case 'e':
652: case 'edit':
653: if (is_string($ret) && !is_numeric($ret)) {
654: return htmlspecialchars(date(_DBTIMESTAMPSTRING, strtotime($ret)), ENT_QUOTES);
655: } else {
656: return htmlspecialchars(date(_DBTIMESTAMPSTRING, $ret), ENT_QUOTES);
657: }
658: break 1;
659: case 'p':
660: case 'preview':
661: if (is_string($ret) && !is_numeric($ret)) {
662: return $myts->stripSlashesGPC(date(_DBTIMESTAMPSTRING, strtotime($ret)));
663: } else {
664: return $myts->stripSlashesGPC(date(_DBTIMESTAMPSTRING, $ret));
665: }
666: break 1;
667: case 'f':
668: case 'formpreview':
669: if (is_string($ret) && !is_numeric($ret)) {
670: return htmlspecialchars($myts->stripSlashesGPC(date(_DBTIMESTAMPSTRING, strtotime($ret))), ENT_QUOTES);
671: } else {
672: return htmlspecialchars($myts->stripSlashesGPC(date(_DBTIMESTAMPSTRING, $ret)), ENT_QUOTES);
673: }
674: break 1;
675: case 'n':
676: case 'none':
677: default:
678: break 1;
679: }
680: break;
681: default:
682: if ($this->vars[$key]['options'] != '' && $ret != '') {
683: switch (strtolower($format)) {
684: case 's':
685: case 'show':
686: $selected = explode('|', $ret);
687: $options = explode('|', $this->vars[$key]['options']);
688: $i = 1;
689: $ret = array();
690: foreach ($options as $op) {
691: if (in_array($i, $selected)) {
692: $ret[] = $op;
693: }
694: ++$i;
695: }
696:
697: return implode(', ', $ret);
698: case 'e':
699: case 'edit':
700: $ret = explode('|', $ret);
701: break 1;
702: default:
703: break 1;
704: }
705: }
706: break;
707: }
708:
709: return $ret;
710: }
711:
712: /**
713: * clean values of all variables of the object for storage.
714: * also add slashes wherever needed
715: *
716: * YOU SHOULD NOT USE ANY OF THE UNICODE TYPES, THEY WILL BE REMOVED
717: *
718: * @return bool true if successful
719: * @access public
720: */
721: public function cleanVars()
722: {
723: $myts = \MyTextSanitizer::getInstance();
724: $existing_errors = $this->getErrors();
725: $this->_errors = array();
726: foreach ($this->vars as $k => $v) {
727: $cleanv = $v['value'];
728: if (!$v['changed']) {
729: } else {
730: $cleanv = is_string($cleanv) ? trim($cleanv) : $cleanv;
731: switch ($v['data_type']) {
732: case XOBJ_DTYPE_TIMESTAMP:
733: $cleanv = !is_string($cleanv) && is_numeric($cleanv) ? date(_DBTIMESTAMPSTRING, $cleanv) : date(_DBTIMESTAMPSTRING, strtotime($cleanv));
734: break;
735: case XOBJ_DTYPE_TIME:
736: $cleanv = !is_string($cleanv) && is_numeric($cleanv) ? date(_DBTIMESTRING, $cleanv) : date(_DBTIMESTRING, strtotime($cleanv));
737: break;
738: case XOBJ_DTYPE_DATE:
739: $cleanv = !is_string($cleanv) && is_numeric($cleanv) ? date(_DBDATESTRING, $cleanv) : date(_DBDATESTRING, strtotime($cleanv));
740: break;
741: case XOBJ_DTYPE_TXTBOX:
742: if ($v['required'] && $cleanv != '0' && $cleanv == '') {
743: $this->setErrors(sprintf(_XOBJ_ERR_REQUIRED, $k));
744: continue 2;
745: }
746: if (isset($v['maxlength']) && strlen($cleanv) > (int)$v['maxlength']) {
747: $this->setErrors(sprintf(_XOBJ_ERR_SHORTERTHAN, $k, (int)$v['maxlength']));
748: continue 2;
749: }
750: if (!$v['not_gpc']) {
751: $cleanv = $myts->stripSlashesGPC($myts->censorString($cleanv));
752: } else {
753: $cleanv = $myts->censorString($cleanv);
754: }
755: break;
756: case XOBJ_DTYPE_TXTAREA:
757: if ($v['required'] && $cleanv != '0' && $cleanv == '') {
758: $this->setErrors(sprintf(_XOBJ_ERR_REQUIRED, $k));
759: continue 2;
760: }
761: if (!$v['not_gpc']) {
762: $cleanv = $myts->stripSlashesGPC($myts->censorString($cleanv));
763: } else {
764: $cleanv = $myts->censorString($cleanv);
765: }
766: break;
767: case XOBJ_DTYPE_SOURCE:
768: if (!$v['not_gpc']) {
769: $cleanv = $myts->stripSlashesGPC($cleanv);
770: }
771: break;
772: case XOBJ_DTYPE_INT:
773: $cleanv = (int)$cleanv;
774: break;
775:
776: case XOBJ_DTYPE_EMAIL:
777: if ($v['required'] && $cleanv == '') {
778: $this->setErrors(sprintf(_XOBJ_ERR_REQUIRED, $k));
779: continue 2;
780: }
781: if ($cleanv != '' && !preg_match("/^[_a-z0-9-]+(\.[_a-z0-9-]+)*@[a-z0-9-]+([\.][a-z0-9-]+)+$/i", $cleanv)) {
782: $this->setErrors('Invalid Email'); //_XOBJ_ERR_INVALID_EMAIL
783: continue 2;
784: }
785: if (!$v['not_gpc']) {
786: $cleanv = $myts->stripSlashesGPC($cleanv);
787: }
788: break;
789: case XOBJ_DTYPE_URL:
790: if ($v['required'] && $cleanv == '') {
791: $this->setErrors(sprintf(_XOBJ_ERR_REQUIRED, $k));
792: continue 2;
793: }
794: if ($cleanv != '' && !preg_match("/^http[s]*:\/\//i", $cleanv)) {
795: $cleanv = XOOPS_PROT . $cleanv;
796: }
797: if (!$v['not_gpc']) {
798: $cleanv = $myts->stripSlashesGPC($cleanv);
799: }
800: break;
801: case XOBJ_DTYPE_ARRAY:
802: $cleanv = (array)$cleanv;
803: $cleanv = serialize($cleanv);
804: break;
805: case XOBJ_DTYPE_STIME:
806: case XOBJ_DTYPE_MTIME:
807: case XOBJ_DTYPE_LTIME:
808: $cleanv = !is_string($cleanv) ? (int)$cleanv : strtotime($cleanv);
809: break;
810: case XOBJ_DTYPE_FLOAT:
811: $cleanv = (float)$cleanv;
812: break;
813: case XOBJ_DTYPE_DECIMAL:
814: $cleanv = (float)$cleanv;
815: break;
816: case XOBJ_DTYPE_ENUM:
817: if (!in_array($cleanv, $v['enumeration'])) {
818: $this->setErrors('Invalid Enumeration');//_XOBJ_ERR_INVALID_ENUMERATION
819: continue 2;
820: }
821: break;
822: case XOBJ_DTYPE_UNICODE_TXTBOX:
823: if ($v['required'] && $cleanv != '0' && $cleanv == '') {
824: $this->setErrors(sprintf(_XOBJ_ERR_REQUIRED, $k));
825: continue 2;
826: }
827: $cleanv = xoops_convert_encode($cleanv);
828: if (isset($v['maxlength']) && strlen($cleanv) > (int)$v['maxlength']) {
829: $this->setErrors(sprintf(_XOBJ_ERR_SHORTERTHAN, $k, (int)$v['maxlength']));
830: continue 2;
831: }
832: if (!$v['not_gpc']) {
833: $cleanv = $myts->stripSlashesGPC($myts->censorString($cleanv));
834: } else {
835: $cleanv = $myts->censorString($cleanv);
836: }
837: break;
838: case XOBJ_DTYPE_UNICODE_TXTAREA:
839: if ($v['required'] && $cleanv != '0' && $cleanv == '') {
840: $this->setErrors(sprintf(_XOBJ_ERR_REQUIRED, $k));
841: continue 2;
842: }
843: $cleanv = xoops_convert_encode($cleanv);
844: if (!$v['not_gpc']) {
845: $cleanv = $myts->stripSlashesGPC($myts->censorString($cleanv));
846: } else {
847: $cleanv = $myts->censorString($cleanv);
848: }
849: break;
850: case XOBJ_DTYPE_UNICODE_EMAIL:
851: if ($v['required'] && $cleanv == '') {
852: $this->setErrors(sprintf(_XOBJ_ERR_REQUIRED, $k));
853: continue 2;
854: }
855: if ($cleanv != '' && !preg_match("/^[_a-z0-9-]+(\.[_a-z0-9-]+)*@[a-z0-9-]+([\.][a-z0-9-]+)+$/i", $cleanv)) {
856: $this->setErrors('Invalid Email');
857: continue 2;
858: }
859: $cleanv = xoops_convert_encode($cleanv);
860: if (!$v['not_gpc']) {
861: $cleanv = $myts->stripSlashesGPC($cleanv);
862: }
863: break;
864: case XOBJ_DTYPE_UNICODE_URL:
865: if ($v['required'] && $cleanv == '') {
866: $this->setErrors(sprintf(_XOBJ_ERR_REQUIRED, $k));
867: continue 2;
868: }
869: if ($cleanv != '' && !preg_match("/^http[s]*:\/\//i", $cleanv)) {
870: $cleanv = XOOPS_PROT . $cleanv;
871: }
872: $cleanv = xoops_convert_encode($cleanv);
873: if (!$v['not_gpc']) {
874: $cleanv = $myts->stripSlashesGPC($cleanv);
875: }
876: break;
877: case XOBJ_DTYPE_UNICODE_ARRAY:
878: $cleanv = serialize(array_walk($cleanv, 'xoops_aw_encode'));
879: break;
880: default:
881: break;
882:
883: }
884: }
885: $this->cleanVars[$k] = str_replace('\\"', '"', (string) $cleanv);
886: unset($cleanv);
887: }
888: if (count($this->_errors) > 0) {
889: $this->_errors = array_merge($existing_errors, $this->_errors);
890:
891: return false;
892: }
893: $this->_errors = array_merge($existing_errors, $this->_errors);
894: $this->unsetDirty();
895:
896: return true;
897: }
898:
899: /**
900: * dynamically register additional filter for the object
901: *
902: * @param string $filtername name of the filter
903: *
904: * @deprecated \XoopsObject::registerFilter is deprecated since XOOPS 2.5.8 and will be removed in the next major release
905: */
906: public function registerFilter($filtername)
907: {
908: $trace = debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS, 1);
909: $GLOBALS['xoopsLogger']->addDeprecated(__METHOD__ . "() is deprecated, called from {$trace[0]['file']}line {$trace[0]['line']}");
910: $this->_filters[] = $filtername;
911: }
912:
913: /**
914: * load all additional filters that have been registered to the object
915: *
916: * @access private
917: */
918: public function _loadFilters()
919: {
920: static $loaded;
921: if (isset($loaded)) {
922: return null;
923: }
924: $loaded = 1;
925:
926: $path = empty($this->plugin_path) ? __DIR__ . '/filters' : $this->plugin_path;
927: if (file_exists($file = $path . '/filter.php')) {
928: include_once $file;
929: foreach ($this->_filters as $f) {
930: if (file_exists($file = $path . '/' . strtolower($f) . 'php')) {
931: include_once $file;
932: }
933: }
934: }
935: }
936:
937: /**
938: * load all local filters for the object
939: *
940: * Filter distribution:
941: * In each module folder there is a folder "filter" containing filter files with,
942: * filename: [name_of_target_class][.][function/action_name][.php];
943: * function name: [dirname][_][name_of_target_class][_][function/action_name];
944: * parameter: the target object
945: *
946: * @param string $method function or action name
947: *
948: * @deprecated \XoopsObject::loadFilters is deprecated since XOOPS 2.5.8 and will be removed in the next major release
949: */
950: public function loadFilters($method)
951: {
952: $trace = debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS, 1);
953: $GLOBALS['xoopsLogger']->addDeprecated(__METHOD__ . "() is deprecated, called from {$trace[0]['file']}line {$trace[0]['line']}");
954:
955: $this->_loadFilters();
956:
957: xoops_load('XoopsCache');
958: $class = get_class($this);
959: if (!$modules_active = XoopsCache::read('system_modules_active')) {
960: /** @var XoopsModuleHandler $module_handler */
961: $module_handler = xoops_getHandler('module');
962: $modules_obj = $module_handler->getObjects(new Criteria('isactive', 1));
963: $modules_active = array();
964: foreach (array_keys($modules_obj) as $key) {
965: $modules_active[] = $modules_obj[$key]->getVar('dirname');
966: }
967: unset($modules_obj);
968: XoopsCache::write('system_modules_active', $modules_active);
969: }
970: foreach ($modules_active as $dirname) {
971: if (file_exists($file = XOOPS_ROOT_PATH . '/modules/' . $dirname . '/filter/' . $class . '.' . $method . '.php')) {
972: include_once $file;
973: if (function_exists($class . '_' . $method)) {
974: call_user_func_array($dirname . '_' . $class . '_' . $method, array(&$this));
975: }
976: }
977: }
978: }
979:
980: /**
981: * create a clone(copy) of the current object
982: *
983: * @access public
984: * @return object clone
985: */
986: public function xoopsClone()
987: {
988: $class = get_class($this);
989: $clone = null;
990: $clone = new $class();
991: foreach ($this->vars as $k => $v) {
992: $clone->assignVar($k, $v['value']);
993: }
994: // need this to notify the handler class that this is a newly created object
995: $clone->setNew();
996:
997: return $clone;
998: }
999:
1000: /**
1001: * Adjust a newly cloned object
1002: */
1003: public function __clone()
1004: {
1005: // need this to notify the handler class that this is a newly created object
1006: $this->setNew();
1007: }
1008:
1009: /**
1010: * add an error
1011: *
1012: * @param array|string $err_str
1013: * @internal param string $value error to add
1014: * @access public
1015: */
1016: public function setErrors($err_str)
1017: {
1018: if (is_array($err_str)) {
1019: $this->_errors = array_merge($this->_errors, $err_str);
1020: } else {
1021: $this->_errors[] = trim($err_str);
1022: }
1023: }
1024:
1025: /**
1026: * return the errors for this object as an array
1027: *
1028: * @return array an array of errors
1029: * @access public
1030: */
1031: public function getErrors()
1032: {
1033: return $this->_errors;
1034: }
1035:
1036: /**
1037: * return the errors for this object as html
1038: *
1039: * @return string html listing the errors
1040: * @access public
1041: */
1042: public function getHtmlErrors()
1043: {
1044: $ret = '<h4>Errors</h4>';
1045: if (!empty($this->_errors)) {
1046: foreach ($this->_errors as $error) {
1047: $ret .= $error . '<br>';
1048: }
1049: } else {
1050: $ret .= 'None<br>';
1051: }
1052:
1053: return $ret;
1054: }
1055:
1056: /**
1057: * Returns an array representation of the object
1058: *
1059: * Deprecated, use getValues() directly
1060: *
1061: * @return array
1062: */
1063: public function toArray()
1064: {
1065: return $this->getValues();
1066: }
1067: }
1068:
1069: /**
1070: * XOOPS object handler class.
1071: * This class is an abstract class of handler classes that are responsible for providing
1072: * data access mechanisms to the data source of its corresponding data objects
1073: *
1074: * @package kernel
1075: * @abstract
1076: * @author Kazumi Ono <onokazu@xoops.org>
1077: * @copyright (c) 2000-2016 XOOPS Project (www.xoops.org)
1078: */
1079: class XoopsObjectHandler
1080: {
1081: /**
1082: * XoopsDatabase holds referenced to {@link XoopsDatabase} class object
1083: *
1084: * @var XoopsDatabase
1085: */
1086: public $db;
1087:
1088: /**
1089: * called from child classes only
1090: *
1091: * @param XoopsDatabase $db reference to the {@link XoopsDatabase} object
1092: * @access protected
1093: */
1094: public function __construct(XoopsDatabase $db)
1095: {
1096: /** @var XoopsMySQLDatabase $db */
1097: $this->db = $db;
1098: }
1099:
1100: /**
1101: * PHP 4 style constructor compatibility shim
1102: *
1103: * @param XoopsDatabase $db database object
1104: * @deprecated all callers should be using parent::__construct()
1105: */
1106: public function XoopsObjectHandler($db)
1107: {
1108: $trace = debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS, 1);
1109: trigger_error("Should call parent::__construct in {$trace[0]['file']} line {$trace[0]['line']},", E_USER_DEPRECATED);
1110: self::__construct($db);
1111: }
1112:
1113: /**
1114: * creates a new object
1115: *
1116: * @abstract
1117: * @return XoopsObject
1118: */
1119: public function create()
1120: {
1121: }
1122:
1123: /**
1124: * gets a value object
1125: *
1126: * @param int $id
1127: * @abstract
1128: * @return XoopsObject
1129: */
1130: public function get($id)
1131: {
1132: }
1133:
1134: /**
1135: * insert/update object
1136: *
1137: * @param XoopsObject $object
1138: * @abstract
1139: */
1140: public function insert(XoopsObject $object)
1141: {
1142: }
1143:
1144: /**
1145: * delete object from database
1146: *
1147: * @param XoopsObject $object
1148: * @abstract
1149: */
1150: public function delete(XoopsObject $object)
1151: {
1152: }
1153: }
1154:
1155: /**
1156: * Persistable Object Handler class.
1157: *
1158: * @author Taiwen Jiang <phppp@users.sourceforge.net>
1159: * @author Jan Keller Pedersen <mithrandir@xoops.org>
1160: * @copyright (c) 2000-2016 XOOPS Project (www.xoops.org)
1161: * @package Kernel
1162: */
1163: class XoopsPersistableObjectHandler extends XoopsObjectHandler
1164: {
1165:
1166: //PHP 8.2 Dynamic properties deprecated
1167: public $table_link;
1168:
1169: /**
1170: * holds reference to custom extended object handler
1171: *
1172: * var object
1173: *
1174: * @access private
1175: */
1176: /**
1177: * static protected
1178: */
1179: public $handler;
1180:
1181: /**
1182: * holds reference to predefined extended object handlers: read, stats, joint, write, sync
1183: *
1184: * The handlers hold methods for different purposes, which could be all put together inside the current class.
1185: * However, load codes only if they are necessary, thus they are now split out.
1186: *
1187: * var array of objects
1188: *
1189: * @access private
1190: */
1191: /**
1192: * static protected
1193: */
1194: public $handlers = array('read' => null, 'stats' => null, 'joint' => null, 'write' => null, 'sync' => null);
1195:
1196: /**
1197: * Information about the class, the handler is managing
1198: *
1199: * @var string
1200: */
1201: public $table;
1202:
1203: /**
1204: * @var string
1205: */
1206: public $keyName;
1207:
1208: /**
1209: * @var string
1210: */
1211: public $className;
1212:
1213: /**
1214: * @var string
1215: */
1216: public $identifierName;
1217:
1218: /**
1219: * @var string
1220: */
1221: public $field_link;
1222:
1223: /**
1224: * @var string
1225: */
1226: public $field_object;
1227:
1228: /**
1229: * Constructor
1230: *
1231: * @param null|XoopsDatabase $db database connection
1232: * @param string $table Name of database table
1233: * @param string $className Name of the XoopsObject class this handler manages
1234: * @param string $keyName Name of the property holding the key
1235: * @param string $identifierName Name of the property holding an identifier
1236: * name (title, name ...), used on getList()
1237: */
1238: public function __construct(XoopsDatabase $db = null, $table = '', $className = '', $keyName = '', $identifierName = '')
1239: {
1240: $db = XoopsDatabaseFactory::getDatabaseConnection();
1241: $table = $db->prefix($table);
1242: parent::__construct($db);
1243: $this->table = $table;
1244: $this->keyName = $keyName;
1245: $this->className = $className;
1246: if ($identifierName) {
1247: $this->identifierName = $identifierName;
1248: }
1249: }
1250:
1251: /**
1252: * PHP 4 style constructor compatibility shim
1253: *
1254: * @param null|XoopsDatabase $db database connection
1255: * @param string $table Name of database table
1256: * @param string $className Name of the XoopsObject class this handler manages
1257: * @param string $keyName Name of the property holding the key
1258: * @param string $identifierName Name of the property holding an identifier
1259: * name (title, name ...), used on getList()
1260: *
1261: * @deprecated all callers should be using parent::__construct()
1262: */
1263: public function XoopsPersistableObjectHandler(XoopsDatabase $db = null, $table = '', $className = '', $keyName = '', $identifierName = '')
1264: {
1265: $trace = debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS, 1);
1266: trigger_error("Should call parent::__construct in {$trace[0]['file']} line {$trace[0]['line']},", E_USER_DEPRECATED);
1267: self::__construct($db, $table, $className, $keyName, $identifierName);
1268: }
1269:
1270: /**
1271: * Set custom handler
1272: *
1273: * @access protected
1274: * @param null|string $handler
1275: * @param null $args
1276: * @param string $path path to class
1277: * @internal param object $handler
1278: * @internal param mixed $args
1279: * @return object of handler
1280: */
1281: public function setHandler($handler = null, $args = null, $path = null)
1282: {
1283: $this->handler = null;
1284: if (is_object($handler)) {
1285: $this->handler = $handler;
1286: } elseif (is_string($handler)) {
1287: xoops_load('XoopsModelFactory');
1288: $this->handler = XoopsModelFactory::loadHandler($this, $handler, $args);
1289: }
1290:
1291: return $this->handler;
1292: }
1293:
1294: /**
1295: * Load predefined handler
1296: *
1297: * @access protected
1298: * @param string $name handler name
1299: * @param mixed $args args
1300: * @return XoopsModelAbstract of handler {@link XoopsModelAbstract}
1301: */
1302: public function loadHandler($name, $args = null)
1303: {
1304: static $handlers;
1305: if (!isset($handlers[$name])) {
1306: xoops_load('XoopsModelFactory');
1307: $handlers[$name] = XoopsModelFactory::loadHandler($this, $name, $args);
1308: } else {
1309: $handlers[$name]->setHandler($this);
1310: $handlers[$name]->setVars($args);
1311: }
1312:
1313: return $handlers[$name];
1314:
1315: /**
1316: * // Following code just kept as placeholder for PHP5
1317: * if (!isset(self::$handlers[$name])) {
1318: * self::$handlers[$name] = XoopsModelFactory::loadHandler($this, $name, $args);
1319: * } else {
1320: * self::$handlers[$name]->setHandler($this);
1321: * self::$handlers[$name]->setVars($args);
1322: * }
1323: *
1324: * return self::$handlers[$name];
1325: */
1326: }
1327:
1328: /**
1329: * Magic method for overloading of delegation
1330: *
1331: * To be enabled in XOOPS 3.0 with PHP 5
1332: *
1333: * @access protected
1334: * @param string $name method name
1335: * @param array $args arguments
1336: * @return mixed
1337: */
1338: public function __call($name, $args)
1339: {
1340: if (is_object($this->handler) && is_callable(array($this->handler, $name))) {
1341: return call_user_func_array(array($this->handler, $name), $args);
1342: }
1343: foreach (array_keys($this->handlers) as $_handler) {
1344: $handler = $this->loadHandler($_handler);
1345: if (is_callable(array($handler, $name))) {
1346: return call_user_func_array(array($handler, $name), $args);
1347: }
1348: }
1349:
1350: return null;
1351: }
1352:
1353: /**
1354: * *#@+
1355: * Methods of native handler {@link XoopsPersistableObjectHandler}
1356: */
1357: /**
1358: * create a new object
1359: *
1360: * @param bool $isNew Flag the new objects as new
1361: * @return XoopsObject {@link XoopsObject}
1362: */
1363: public function create($isNew = true)
1364: {
1365: $obj = new $this->className();
1366: if ($isNew === true) {
1367: $obj->setNew();
1368: }
1369:
1370: return $obj;
1371: }
1372:
1373: /**
1374: * Load a {@link XoopsObject} object from the database
1375: *
1376: * @access protected
1377: * @param mixed $id ID
1378: * @param array|null $fields fields to fetch
1379: * @return XoopsObject|null {@link XoopsObject}
1380: */
1381: public function get($id = null, $fields = null)
1382: {
1383: $object = null;
1384: if (empty($id)) {
1385: $object = $this->create();
1386:
1387: return $object;
1388: }
1389: if (!empty($fields) && \is_array($fields)) {
1390: $select = implode(',', $fields);
1391: if (!in_array($this->keyName, $fields)) {
1392: $select .= ', ' . $this->keyName;
1393: }
1394: } else {
1395: $select = '*';
1396: }
1397: $sql = sprintf('SELECT %s FROM %s WHERE %s = %s', $select, $this->table, $this->keyName, $this->db->quote($id));
1398: //$sql = "SELECT {$select} FROM {$this->table} WHERE {$this->keyName} = " . $this->db->quote($id);
1399: $result = $this->db->query($sql);
1400: if (!$this->db->isResultSet($result)) {
1401: return $object;
1402: }
1403: if (!$this->db->getRowsNum($result)) {
1404: return $object;
1405: }
1406: $object = $this->create(false);
1407: $object->assignVars($this->db->fetchArray($result));
1408:
1409: return $object;
1410: }
1411: /**
1412: * *#@-
1413: */
1414:
1415: /**
1416: * *#@+
1417: * Methods of write handler {@link XoopsObjectWrite}
1418: */
1419: /**
1420: * insert an object into the database
1421: *
1422: * @param XoopsObject $object {@link XoopsObject} reference to object
1423: * @param bool $force flag to force the query execution despite security settings
1424: * @return mixed object ID
1425: */
1426: public function insert(XoopsObject $object, $force = true)
1427: {
1428: $handler = $this->loadHandler('write');
1429:
1430: return $handler->insert($object, $force);
1431: }
1432:
1433: /**
1434: * delete an object from the database
1435: *
1436: * @param XoopsObject $object {@link XoopsObject} reference to the object to delete
1437: * @param bool $force
1438: * @return bool FALSE if failed.
1439: */
1440: public function delete(XoopsObject $object, $force = false)
1441: {
1442: $handler = $this->loadHandler('write');
1443:
1444: return $handler->delete($object, $force);
1445: }
1446:
1447: /**
1448: * delete all objects matching the conditions
1449: *
1450: * @param \CriteriaElement|null $criteria {@link CriteriaElement} with conditions to meet
1451: * @param bool $force force to delete
1452: * @param bool $asObject delete in object way: instantiate all objects and delete one by one
1453: * @return bool|int
1454: */
1455: public function deleteAll(CriteriaElement $criteria = null, $force = true, $asObject = false)
1456: {
1457: $handler = $this->loadHandler('write');
1458:
1459: return $handler->deleteAll($criteria, $force, $asObject);
1460: }
1461:
1462: /**
1463: * Change a field for objects with a certain criteria
1464: *
1465: * @param string $fieldname Name of the field
1466: * @param mixed $fieldvalue Value to write
1467: * @param \CriteriaElement|null $criteria {@link CriteriaElement}
1468: * @param bool $force force to query
1469: * @return bool
1470: */
1471: public function updateAll($fieldname, $fieldvalue, CriteriaElement $criteria = null, $force = false)
1472: {
1473: $handler = $this->loadHandler('write');
1474:
1475: return $handler->updateAll($fieldname, $fieldvalue, $criteria, $force);
1476: }
1477: /**
1478: * *#@-
1479: */
1480:
1481: /**
1482: * *#@+
1483: * Methods of read handler {@link XoopsObjectRead}
1484: */
1485: /**
1486: * Retrieve objects from the database
1487: *
1488: * @param \CriteriaElement|null $criteria {@link CriteriaElement} conditions to be met
1489: * @param bool $id_as_key use the ID as key for the array
1490: * @param bool $as_object return an array of objects
1491: * @return array
1492: */
1493: public function &getObjects(CriteriaElement $criteria = null, $id_as_key = false, $as_object = true)
1494: {
1495: $handler = $this->loadHandler('read');
1496: $ret = $handler->getObjects($criteria, $id_as_key, $as_object);
1497:
1498: return $ret;
1499: }
1500:
1501: /**
1502: * get all objects matching a condition
1503: *
1504: * @param \CriteriaElement|null $criteria {@link CriteriaElement} to match
1505: * @param array|null $fields variables to fetch
1506: * @param bool $asObject flag indicating as object, otherwise as array
1507: * @param bool $id_as_key use the ID as key for the array
1508: * @return array of objects/array {@link XoopsObject}
1509: */
1510: public function &getAll(CriteriaElement $criteria = null, $fields = null, $asObject = true, $id_as_key = true)
1511: {
1512: $handler = $this->loadHandler('read');
1513: $ret = $handler->getAll($criteria, $fields, $asObject, $id_as_key);
1514:
1515: return $ret;
1516: }
1517:
1518: /**
1519: * Retrieve a list of objects data
1520: *
1521: * @param \CriteriaElement|null $criteria {@link CriteriaElement} conditions to be met
1522: * @param int $limit Max number of objects to fetch
1523: * @param int $start Which record to start at
1524: * @return array
1525: */
1526: public function getList(CriteriaElement $criteria = null, $limit = 0, $start = 0)
1527: {
1528: $handler = $this->loadHandler('read');
1529: $ret = $handler->getList($criteria, $limit, $start);
1530:
1531: return $ret;
1532: }
1533:
1534: /**
1535: * get IDs of objects matching a condition
1536: *
1537: * @param \CriteriaElement|null $criteria {@link CriteriaElement} to match
1538: * @return array of object IDs
1539: */
1540: public function &getIds(CriteriaElement $criteria = null)
1541: {
1542: $handler = $this->loadHandler('read');
1543: $ret = $handler->getIds($criteria);
1544:
1545: return $ret;
1546: }
1547:
1548: /**
1549: * get a limited list of objects matching a condition
1550: *
1551: * {@link CriteriaCompo}
1552: *
1553: * @param int $limit Max number of objects to fetch
1554: * @param int $start Which record to start at
1555: * @param \CriteriaElement|null $criteria {@link CriteriaElement} to match
1556: * @param array|null $fields variables to fetch
1557: * @param bool $asObject flag indicating as object, otherwise as array
1558: * @return array of objects {@link XoopsObject}
1559: */
1560: public function &getByLimit($limit = 0, $start = 0, CriteriaElement $criteria = null, $fields = null, $asObject = true)
1561: {
1562: $handler = $this->loadHandler('read');
1563: $ret = $handler->getByLimit($limit, $start, $criteria, $fields, $asObject);
1564:
1565: return $ret;
1566: }
1567: /**
1568: * *#@-
1569: */
1570:
1571: /**
1572: * *#@+
1573: * Methods of stats handler {@link XoopsObjectStats}
1574: */
1575: /**
1576: * count objects matching a condition
1577: *
1578: * @param \CriteriaElement|null $criteria {@link CriteriaElement} to match
1579: * @return int count of objects
1580: */
1581: public function getCount(CriteriaElement $criteria = null)
1582: {
1583: $handler = $this->loadHandler('stats');
1584:
1585: return $handler->getCount($criteria);
1586: }
1587:
1588: /**
1589: * Get counts of objects matching a condition
1590: *
1591: * @param \CriteriaElement|null $criteria {@link CriteriaElement} to match
1592: * @return array of counts
1593: */
1594: public function getCounts(CriteriaElement $criteria = null)
1595: {
1596: $handler = $this->loadHandler('stats');
1597:
1598: return $handler->getCounts($criteria);
1599: }
1600: /**
1601: * *#@-
1602: */
1603:
1604: /**
1605: * *#@+
1606: * Methods of joint handler {@link XoopsObjectJoint}
1607: */
1608: /**
1609: * get a list of objects matching a condition joint with another related object
1610: *
1611: * @param \CriteriaElement|null $criteria {@link CriteriaElement} to match
1612: * @param array|null $fields variables to fetch
1613: * @param bool $asObject flag indicating as object, otherwise as array
1614: * @param string|null $field_link field of linked object for JOIN
1615: * @param string|null $field_object field of current object for JOIN
1616: * @return array of objects {@link XoopsObject}
1617: */
1618: public function &getByLink(CriteriaElement $criteria = null, $fields = null, $asObject = true, $field_link = null, $field_object = null)
1619: {
1620: $handler = $this->loadHandler('joint');
1621: $ret = $handler->getByLink($criteria, $fields, $asObject, $field_link, $field_object);
1622:
1623: return $ret;
1624: }
1625:
1626: /**
1627: * Count of objects matching a condition
1628: *
1629: * @param \CriteriaElement|null $criteria {@link CriteriaElement} to match
1630: * @return int count of objects
1631: */
1632: public function getCountByLink(CriteriaElement $criteria = null)
1633: {
1634: $handler = $this->loadHandler('joint');
1635: $ret = $handler->getCountByLink($criteria);
1636:
1637: return $ret;
1638: }
1639:
1640: /**
1641: * array of count of objects matching a condition of, groupby linked object keyname
1642: *
1643: * @param \CriteriaElement|null $criteria {@link CriteriaElement} to match
1644: * @return int count of objects
1645: */
1646: public function getCountsByLink(CriteriaElement $criteria = null)
1647: {
1648: $handler = $this->loadHandler('joint');
1649: $ret = $handler->getCountsByLink($criteria);
1650:
1651: return $ret;
1652: }
1653:
1654: /**
1655: * update objects matching a condition against linked objects
1656: *
1657: * @param array $data array of key => value
1658: * @param \CriteriaElement|null $criteria {@link CriteriaElement} to match
1659: * @return int count of objects
1660: */
1661: public function updateByLink($data, CriteriaElement $criteria = null)
1662: {
1663: $handler = $this->loadHandler('joint');
1664: $ret = $handler->updateByLink($data, $criteria);
1665:
1666: return $ret;
1667: }
1668:
1669: /**
1670: * Delete objects matching a condition against linked objects
1671: *
1672: * @param \CriteriaElement|null $criteria {@link CriteriaElement} to match
1673: * @return int|null count of objects
1674: */
1675: public function deleteByLink(CriteriaElement $criteria = null)
1676: {
1677: $handler = $this->loadHandler('joint');
1678: $ret = $handler->deleteByLink($criteria);
1679:
1680: return $ret;
1681: }
1682: /**
1683: * *#@-
1684: */
1685:
1686: /**
1687: * *#@+
1688: * Methods of sync handler {@link XoopsObjectSync}
1689: */
1690: /**
1691: * Clean orphan objects against linked objects
1692: *
1693: * @param string $table_link table of linked object for JOIN
1694: * @param string $field_link field of linked object for JOIN
1695: * @param string $field_object field of current object for JOIN
1696: * @return bool true on success
1697: */
1698: public function cleanOrphan($table_link = '', $field_link = '', $field_object = '')
1699: {
1700: $handler = $this->loadHandler('sync');
1701: $ret = $handler->cleanOrphan($table_link, $field_link, $field_object);
1702:
1703: return $ret;
1704: }
1705:
1706: /**
1707: * Synchronizing objects
1708: *
1709: * @return bool true on success
1710: */
1711: public function synchronization()
1712: {
1713: $retval = $this->cleanOrphan();
1714:
1715: return $retval;
1716: }
1717: /**
1718: * *#@-
1719: */
1720:
1721: /**#@+
1722: * @deprecated
1723: * @param $result
1724: * @param bool $id_as_key
1725: * @param bool $as_object
1726: * @return bool
1727: */
1728: public function convertResultSet($result, $id_as_key = false, $as_object = true)
1729: {
1730: $GLOBALS['xoopsLogger']->addDeprecated(__METHOD__ . ' is deprecated');
1731:
1732: return false;
1733: }
1734: /**#@-*/
1735: }
1736: