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-2016 XOOPS Project (www.xoops.org) 13 * @license GNU GPL 2 (http://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 20defined('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 */ 29define('XOBJ_DTYPE_TXTBOX', 1); 30define('XOBJ_DTYPE_TXTAREA', 2); 31define('XOBJ_DTYPE_INT', 3); 32define('XOBJ_DTYPE_URL', 4); 33define('XOBJ_DTYPE_EMAIL', 5); 34define('XOBJ_DTYPE_ARRAY', 6); 35define('XOBJ_DTYPE_OTHER', 7); 36define('XOBJ_DTYPE_SOURCE', 8); 37define('XOBJ_DTYPE_STIME', 9); 38define('XOBJ_DTYPE_MTIME', 10); 39define('XOBJ_DTYPE_LTIME', 11); 40define('XOBJ_DTYPE_FLOAT', 13); 41define('XOBJ_DTYPE_DECIMAL', 14); 42define('XOBJ_DTYPE_ENUM', 15); 43// YOU SHOULD NEVER USE THE FOLLOWING TYPES, THEY WILL BE REMOVED 44define('XOBJ_DTYPE_UNICODE_TXTBOX', 16); 45define('XOBJ_DTYPE_UNICODE_TXTAREA', 17); 46define('XOBJ_DTYPE_UNICODE_URL', 18); 47define('XOBJ_DTYPE_UNICODE_EMAIL', 19); 48define('XOBJ_DTYPE_UNICODE_ARRAY', 20); 49define('XOBJ_DTYPE_UNICODE_OTHER', 21); 50// Addition for 2.5.5 51define('XOBJ_DTYPE_DATE', 22); 52define('XOBJ_DTYPE_TIME', 23); 53define('XOBJ_DTYPE_TIMESTAMP', 24); 54 55/** 56 * Base class for all objects in the Xoops kernel (and beyond) 57 */ 58class 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']},"); 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 null $value 189 * @param bool $required require html form input? 190 * @param int $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 $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 // YOU SHOULD NOT USE THE ABOVE TYPES, THEY WILL BE REMOVED 255 default: 256 $this->vars[$key]['value'] =& $value; 257 } 258 } 259 } 260 261 /** 262 * assign values to multiple variables in a batch 263 * 264 * @access private 265 * @param $var_arr 266 * @internal param array $var_array associative array of values to assign 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 * assign a value to a variable 277 * 278 * @access public 279 * @param string $key name of the variable to assign 280 * @param mixed $value value to assign 281 * @param bool $not_gpc 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 * assign values to multiple variables in a batch 295 * 296 * @access private 297 * @param array $var_arr associative array of values to assign 298 * @param bool $not_gpc 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 * unset variable(s) for the object 309 * 310 * @access public 311 * 312 * @param mixed $var 313 * 314 * @return bool 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 * @param $var 334 * @return bool 335 * @deprecated use destroyVars() instead, destoryVars() will be removed in the next major release 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 * Assign values to multiple variables in a batch 346 * 347 * Meant for a CGI context: 348 * - prefixed CGI args are considered save 349 * - avoids polluting of namespace with CGI args 350 * 351 * @access private 352 * @param array $var_arr associative array of values to assign 353 * @param string $pref prefix (only keys starting with the prefix will be set) 354 * @param bool $not_gpc 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 * returns all variables for the object 368 * 369 * @access public 370 * @return array associative array of key->value pairs 371 */ 372 public function &getVars() 373 { 374 return $this->vars; 375 } 376 377 /** 378 * Returns the values of the specified variables 379 * 380 * @param mixed $keys An array containing the names of the keys to retrieve, or null to get all of them 381 * @param string $format Format to use (see getVar) 382 * @param int $maxDepth Maximum level of recursion to use if some vars are objects themselves 383 * @return array associative array of key->value pairs 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 * returns a specific variable for the object in a proper format 408 * 409 * YOU SHOULD NOT USE ANY OF THE UNICODE TYPES, THEY WILL BE REMOVED 410 * 411 * @access public 412 * @param string $key key of the object's variable to be returned 413 * @param string $format format to use for the output 414 * @return mixed formatted value of the variable 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 * clean values of all variables of the object for storage. 699 * also add slashes wherever needed 700 * 701 * YOU SHOULD NOT USE ANY OF THE UNICODE TYPES, THEY WILL BE REMOVED 702 * 703 * @return bool true if successful 704 * @access public 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'); //_XOBJ_ERR_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 = XOOPS_PROT . $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');//_XOBJ_ERR_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 = XOOPS_PROT . $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 * dynamically register additional filter for the object 886 * 887 * @param string $filtername name of the filter 888 * 889 * @deprecated \XoopsObject::registerFilter is deprecated since XOOPS 2.5.8 and will be removed in the next major release 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 * load all additional filters that have been registered to the object 900 * 901 * @access private 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 * load all local filters for the object 924 * 925 * Filter distribution: 926 * In each module folder there is a folder "filter" containing filter files with, 927 * filename: [name_of_target_class][.][function/action_name][.php]; 928 * function name: [dirname][_][name_of_target_class][_][function/action_name]; 929 * parameter: the target object 930 * 931 * @param string $method function or action name 932 * 933 * @deprecated \XoopsObject::loadFilters is deprecated since XOOPS 2.5.8 and will be removed in the next major release 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 /* @var XoopsModuleHandler $module_handler */ 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 * create a clone(copy) of the current object 967 * 968 * @access public 969 * @return object clone 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 // need this to notify the handler class that this is a newly created object 980 $clone->setNew(); 981 982 return $clone; 983 } 984 985 /** 986 * Adjust a newly cloned object 987 */ 988 public function __clone() 989 { 990 // need this to notify the handler class that this is a newly created object 991 $this->setNew(); 992 } 993 994 /** 995 * add an error 996 * 997 * @param $err_str 998 * @internal param string $value error to add 999 * @access public 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 * return the errors for this object as an array 1012 * 1013 * @return array an array of errors 1014 * @access public 1015 */ 1016 public function getErrors() 1017 { 1018 return $this->_errors; 1019 } 1020 1021 /** 1022 * return the errors for this object as html 1023 * 1024 * @return string html listing the errors 1025 * @access public 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 * Returns an array representation of the object 1043 * 1044 * Deprecated, use getValues() directly 1045 * 1046 * @return array 1047 */ 1048 public function toArray() 1049 { 1050 return $this->getValues(); 1051 } 1052} 1053 1054/** 1055 * XOOPS object handler class. 1056 * This class is an abstract class of handler classes that are responsible for providing 1057 * data access mechanisms to the data source of its corresponding data objects 1058 * 1059 * @package kernel 1060 * @abstract 1061 * @author Kazumi Ono <onokazu@xoops.org> 1062 * @copyright (c) 2000-2016 XOOPS Project (www.xoops.org) 1063 */ 1064class XoopsObjectHandler 1065{ 1066 /** 1067 * XoopsDatabase holds referenced to {@link XoopsDatabase} class object 1068 * 1069 * @var XoopsDatabase 1070 */ 1071 public $db; 1072 1073 /** 1074 * called from child classes only 1075 * 1076 * @param XoopsDatabase $db reference to the {@link XoopsDatabase} object 1077 * @access protected 1078 */ 1079 public function __construct(XoopsDatabase $db) 1080 { 1081 /* @var XoopsMySQLDatabase $db */ 1082 $this->db = $db; 1083 } 1084 1085 /** 1086 * PHP 4 style constructor compatibility shim 1087 * 1088 * @param XoopsDatabase $db database object 1089 * @deprecated all callers should be using parent::__construct() 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 * creates a new object 1100 * 1101 * @abstract 1102 * @return XoopsObject 1103 */ 1104 public function create() 1105 { 1106 } 1107 1108 /** 1109 * gets a value object 1110 * 1111 * @param int $int_id 1112 * @abstract 1113 * @return XoopsObject 1114 */ 1115 public function get($int_id) 1116 { 1117 } 1118 1119 /** 1120 * insert/update object 1121 * 1122 * @param XoopsObject $object 1123 * @abstract 1124 */ 1125 public function insert(XoopsObject $object) 1126 { 1127 } 1128 1129 /** 1130 * delete object from database 1131 * 1132 * @param XoopsObject $object 1133 * @abstract 1134 */ 1135 public function delete(XoopsObject $object) 1136 { 1137 } 1138} 1139 1140/** 1141 * Persistable Object Handler class. 1142 * 1143 * @author Taiwen Jiang <phppp@users.sourceforge.net> 1144 * @author Jan Keller Pedersen <mithrandir@xoops.org> 1145 * @copyright (c) 2000-2016 XOOPS Project (www.xoops.org) 1146 * @package Kernel 1147 */ 1148class XoopsPersistableObjectHandler extends XoopsObjectHandler 1149{ 1150 /** 1151 * holds reference to custom extended object handler 1152 * 1153 * var object 1154 * 1155 * @access private 1156 */ 1157 /** 1158 * static protected 1159 */ 1160 public $handler; 1161 1162 /** 1163 * holds reference to predefined extended object handlers: read, stats, joint, write, sync 1164 * 1165 * The handlers hold methods for different purposes, which could be all put together inside of current class. 1166 * However, load codes only if they are necessary, thus they are now split out. 1167 * 1168 * var array of objects 1169 * 1170 * @access private 1171 */ 1172 /** 1173 * static protected 1174 */ 1175 public $handlers = array('read' => null, 'stats' => null, 'joint' => null, 'write' => null, 'sync' => null); 1176 1177 /** 1178 * Information about the class, the handler is managing 1179 * 1180 * @var string 1181 */ 1182 public $table; 1183 1184 /** 1185 * @var string 1186 */ 1187 public $keyName; 1188 1189 /** 1190 * @var string 1191 */ 1192 public $className; 1193 1194 /** 1195 * @var string 1196 */ 1197 public $identifierName; 1198 1199 /** 1200 * @var string 1201 */ 1202 public $field_link; 1203 1204 /** 1205 * @var string 1206 */ 1207 public $field_object; 1208 1209 /** 1210 * Constructor 1211 * 1212 * @param null|XoopsDatabase $db database connection 1213 * @param string $table Name of database table 1214 * @param string $className Name of the XoopsObject class this handler manages 1215 * @param string $keyName Name of the property holding the key 1216 * @param string $identifierName Name of the property holding an identifier 1217 * name (title, name ...), used on getList() 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 * PHP 4 style constructor compatibility shim 1234 * 1235 * @param null|XoopsDatabase $db database connection 1236 * @param string $table Name of database table 1237 * @param string $className Name of the XoopsObject class this handler manages 1238 * @param string $keyName Name of the property holding the key 1239 * @param string $identifierName Name of the property holding an identifier 1240 * name (title, name ...), used on getList() 1241 * 1242 * @deprecated all callers should be using parent::__construct() 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 * Set custom handler 1253 * 1254 * @access protected 1255 * @param null|string $handler 1256 * @param null $args 1257 * @param string $path path to class 1258 * @internal param object $handler 1259 * @internal param mixed $args 1260 * @return object of handler 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 * Load predefined handler 1277 * 1278 * @access protected 1279 * @param string $name handler name 1280 * @param mixed $args args 1281 * @return XoopsModelAbstract of handler {@link XoopsModelAbstract} 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 * // Following code just kept as placeholder for PHP5 1298 * if (!isset(self::$handlers[$name])) { 1299 * self::$handlers[$name] = XoopsModelFactory::loadHandler($this, $name, $args); 1300 * } else { 1301 * self::$handlers[$name]->setHandler($this); 1302 * self::$handlers[$name]->setVars($args); 1303 * } 1304 * 1305 * return self::$handlers[$name]; 1306 */ 1307 } 1308 1309 /** 1310 * Magic method for overloading of delegation 1311 * 1312 * To be enabled in XOOPS 3.0 with PHP 5 1313 * 1314 * @access protected 1315 * @param string $name method name 1316 * @param array $args arguments 1317 * @return mixed 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 * Methods of native handler {@link XoopsPersistableObjectHandler} 1337 */ 1338 /** 1339 * create a new object 1340 * 1341 * @param bool $isNew Flag the new objects as new 1342 * @return XoopsObject {@link XoopsObject} 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 * Load a {@link XoopsObject} object from the database 1356 * 1357 * @access protected 1358 * @param mixed $id ID 1359 * @param array $fields fields to fetch 1360 * @return XoopsObject {@link XoopsObject} 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 //$sql = "SELECT {$select} FROM {$this->table} WHERE {$this->keyName} = " . $this->db->quote($id); 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 * Methods of write handler {@link XoopsObjectWrite} 1398 */ 1399 /** 1400 * insert an object into the database 1401 * 1402 * @param XoopsObject $object {@link XoopsObject} reference to object 1403 * @param bool $force flag to force the query execution despite security settings 1404 * @return mixed object ID 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 * delete an object from the database 1415 * 1416 * @param XoopsObject $object {@link XoopsObject} reference to the object to delete 1417 * @param bool $force 1418 * @return bool FALSE if failed. 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 * delete all objects matching the conditions 1429 * 1430 * @param CriteriaElement $criteria {@link CriteriaElement} with conditions to meet 1431 * @param bool $force force to delete 1432 * @param bool $asObject delete in object way: instantiate all objects and delete one by one 1433 * @return bool 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 * Change a field for objects with a certain criteria 1444 * 1445 * @param string $fieldname Name of the field 1446 * @param mixed $fieldvalue Value to write 1447 * @param CriteriaElement $criteria {@link CriteriaElement} 1448 * @param bool $force force to query 1449 * @return bool 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 * Methods of read handler {@link XoopsObjectRead} 1464 */ 1465 /** 1466 * Retrieve objects from the database 1467 * 1468 * @param CriteriaElement $criteria {@link CriteriaElement} conditions to be met 1469 * @param bool $id_as_key use the ID as key for the array 1470 * @param bool $as_object return an array of objects 1471 * @return array 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 * get all objects matching a condition 1483 * 1484 * @param CriteriaElement $criteria {@link CriteriaElement} to match 1485 * @param array $fields variables to fetch 1486 * @param bool $asObject flag indicating as object, otherwise as array 1487 * @param bool $id_as_key use the ID as key for the array 1488 * @return array of objects/array {@link XoopsObject} 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 * Retrieve a list of objects data 1500 * 1501 * @param CriteriaElement $criteria {@link CriteriaElement} conditions to be met 1502 * @param int $limit Max number of objects to fetch 1503 * @param int $start Which record to start at 1504 * @return array 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 * get IDs of objects matching a condition 1516 * 1517 * @param CriteriaElement $criteria {@link CriteriaElement} to match 1518 * @return array of object IDs 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 * get a limited list of objects matching a condition 1530 * 1531 * {@link CriteriaCompo} 1532 * 1533 * @param int $limit Max number of objects to fetch 1534 * @param int $start Which record to start at 1535 * @param CriteriaElement $criteria {@link CriteriaElement} to match 1536 * @param array $fields variables to fetch 1537 * @param bool $asObject flag indicating as object, otherwise as array 1538 * @return array of objects {@link XoopsObject} 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 * Methods of stats handler {@link XoopsObjectStats} 1554 */ 1555 /** 1556 * count objects matching a condition 1557 * 1558 * @param CriteriaElement $criteria {@link CriteriaElement} to match 1559 * @return int count of objects 1560 */ 1561 public function getCount(CriteriaElement $criteria = null) 1562 { 1563 $handler = $this->loadHandler('stats'); 1564 1565 return $handler->getCount($criteria); 1566 } 1567 1568 /** 1569 * Get counts of objects matching a condition 1570 * 1571 * @param CriteriaElement $criteria {@link CriteriaElement} to match 1572 * @return array of counts 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 * Methods of joint handler {@link XoopsObjectJoint} 1587 */ 1588 /** 1589 * get a list of objects matching a condition joint with another related object 1590 * 1591 * @param CriteriaElement $criteria {@link CriteriaElement} to match 1592 * @param array $fields variables to fetch 1593 * @param bool $asObject flag indicating as object, otherwise as array 1594 * @param string $field_link field of linked object for JOIN 1595 * @param string $field_object field of current object for JOIN 1596 * @return array of objects {@link XoopsObject} 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 * Count of objects matching a condition 1608 * 1609 * @param CriteriaElement $criteria {@link CriteriaElement} to match 1610 * @return int count of objects 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 * array of count of objects matching a condition of, groupby linked object keyname 1622 * 1623 * @param CriteriaElement $criteria {@link CriteriaElement} to match 1624 * @return int count of objects 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 * update objects matching a condition against linked objects 1636 * 1637 * @param array $data array of key => value 1638 * @param CriteriaElement $criteria {@link CriteriaElement} to match 1639 * @return int count of objects 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 * Delete objects matching a condition against linked objects 1651 * 1652 * @param CriteriaElement $criteria {@link CriteriaElement} to match 1653 * @return int count of objects 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 * Methods of sync handler {@link XoopsObjectSync} 1669 */ 1670 /** 1671 * Clean orphan objects against linked objects 1672 * 1673 * @param string $table_link table of linked object for JOIN 1674 * @param string $field_link field of linked object for JOIN 1675 * @param string $field_object field of current object for JOIN 1676 * @return bool true on success 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 * Synchronizing objects 1688 * 1689 * @return bool true on success 1690 */ 1691 public function synchronization() 1692 { 1693 $retval = $this->cleanOrphan(); 1694 1695 return $retval; 1696 } 1697 /** 1698 * *#@- 1699 */ 1700 1701 /**#@+ 1702 * @deprecated 1703 * @param $result 1704 * @param bool $id_as_key 1705 * @param bool $as_object 1706 * @return bool 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