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