XOOPS RMCommon Utilities  2.1.8.91RC
 All Classes Namespaces Files Functions Variables
object.php
Go to the documentation of this file.
1 <?php
2 // $Id: object.php 877 2011-12-25 02:42:16Z i.bitcero $
3 // --------------------------------------------------------------
4 // Red México Common Utilities
5 // A framework for Red México Modules
6 // Author: Eduardo Cortés <i.bitcero@gmail.com>
7 // Email: i.bitcero@gmail.com
8 // License: GPL 2.0
9 // --------------------------------------------------------------
10 
11 
21 class RMObject
22 {
23 
30  protected $vars = array();
31 
38  public $cleanVars = array();
39 
46  private $_isNew = false;
47 
54  private $_isDirty = false;
55 
62  private $_errors = array();
63 
69  private $_filters = array();
74  protected $primary = 'id';
75  protected $db = null;
76  protected $_log = array();
77  protected $_dbtable = '';
78  private $_tblcolumns = array();
79  private $_uniquefield = '';
80 
84  private $objectColumns = array();
85  private $primaryCols = array();
86 
87  public function id(){
88  return $this->getVar($this->primary);
89  }
95  function setNew()
96  {
97  $this->_isNew = true;
98  }
99  function unsetNew()
100  {
101  $this->_isNew = false;
102  }
103  function isNew()
104  {
105  return $this->_isNew;
106  }
115  function setDirty()
116  {
117  $this->_isDirty = true;
118  }
119  function unsetDirty()
120  {
121  $this->_isDirty = false;
122  }
123  function isDirty()
124  {
125  return $this->_isDirty;
126  }
140  function initVar($key, $data_type, $value = null, $required = false, $maxlength = null, $options = '')
141  {
142  if (isset($this->vars[$key])) return;
143  $this->vars[$key] = array('value' => $value, 'required' => $required, 'data_type' => $data_type, 'maxlength' => $maxlength, 'changed' => false, 'options' => $options);
144  }
150  function setVarType($var, $type){
151  if (!isset($this->vars[$var])) return false;
152  return $this->vars[$var]['data_type'] = $type;
153  }
159  function setVarLen($var, $len=null){
160  if (!isset($this->vars[$var])) return false;
161  return $this->vars[$var]['maxlength'] = $len;
162  }
168  function setVarRequired($var, $required){
169  if (!isset($this->vars[$var])) return false;
170  return $this->vars[$var]['required'] = $required;
171  }
179  function assignVar($key, $value)
180  {
181  if (isset($value) && isset($this->vars[$key])) {
182  $this->vars[$key]['value'] =& $value;
183  }
184  }
185 
192  function assignVars($var_arr)
193  {
194  if (empty($var_arr)) return;
195  foreach ($var_arr as $key => $value) {
196  $this->assignVar($key, stripslashes($value));
197  }
198  $this->unsetNew();
199  }
200 
209  function setVar($key, $value, $not_gpc = false)
210  {
211  if (!empty($key) && isset($value) && isset($this->vars[$key])) {
212  $this->vars[$key]['value'] =& $value;
213  $this->vars[$key]['not_gpc'] = $not_gpc;
214  $this->vars[$key]['changed'] = true;
215  $this->setDirty();
216  }
217  }
218 
226  function setVars($var_arr, $not_gpc = false)
227  {
228  foreach ($var_arr as $key => $value) {
229  $this->setVar($key, $value, $not_gpc);
230  }
231  }
232 
244  function setFormVars($var_arr=null, $pref='xo_', $not_gpc=false) {
245  $len = strlen($pref);
246  foreach ($var_arr as $key => $value) {
247  if ($pref == substr($key,0,$len)) {
248  $this->setVar(substr($key,$len), $value, $not_gpc);
249  }
250  }
251  }
252 
253 
261  public function getVars($formated = false, $format = 's')
262  {
263  if (!$formated){
264  return $this->vars;
265  }
266 
267  $ret = array();
268  foreach ($this->vars as $key => $var){
269  $ret[$key] = $this->getVar($key, $format);
270  }
271 
272  return $ret;
273 
274  }
283  function getValues( $keys = null, $format = 's', $maxDepth = 1 ) {
284  if ( !isset( $keys ) ) {
285  $keys = array_keys( $this->vars );
286  }
287  $vars = array();
288  foreach ( $keys as $key ) {
289  if ( isset( $this->vars[$key] ) ) {
290  if ( is_object( $this->vars[$key] ) && is_a( $this->vars[$key], 'EXMObject' ) ) {
291  if ( $maxDepth ) {
292  $vars[$key] = $this->vars[$key]->getValues( null, $format, $maxDepth - 1 );
293  }
294  } else {
295  $vars[$key] = $this->getVar( $key, $format );
296  }
297  }
298  }
299  return $vars;
300  }
309  function getVar($key, $format = 's')
310  {
311  $ret = $this->vars[$key]['value'];
312 
313  switch ($this->vars[$key]['data_type']) {
314 
315  case XOBJ_DTYPE_TXTBOX:
316  switch (strtolower($format)) {
317  case 's':
318  case 'show':
319  case 'e':
320  case 'edit':
321  $ts = TextCleaner::getInstance();
322  return $ts->specialchars($ret);
323  break;
324  case 'p':
325  case 'preview':
326  case 'f':
327  case 'formpreview':
328  $ts =& TextCleaner::getInstance();
329  return $ts->specialchars($ts->stripSlashesGPC($ret));
330  break 1;
331  case 'n':
332  case 'none':
333  default:
334  break 1;
335  }
336  break;
337  case XOBJ_DTYPE_TXTAREA:
338  switch (strtolower($format)) {
339  case 's':
340  case 'show':
341  return TextCleaner::getInstance()->to_display($ret);
342  break 1;
343  case 'e':
344  case 'edit':
345  $ts = TextCleaner::getInstance();
346  return $ts->specialchars($ts->stripslashes($ret));
347  break;
348  case 'p':
349  case 'preview':
350  $ts =& TextCleaner::getInstance();
351  $html = !empty($this->vars['dohtml']['value']) ? 1 : 0;
352  $xcode = (!isset($this->vars['doxcode']['value']) || $this->vars['doxcode']['value'] == 1) ? 1 : 0;
353  $smiley = (!isset($this->vars['dosmiley']['value']) || $this->vars['dosmiley']['value'] == 1) ? 1 : 0;
354  $image = (!isset($this->vars['doimage']['value']) || $this->vars['doimage']['value'] == 1) ? 1 : 0;
355  $br = (!isset($this->vars['dobr']['value']) || $this->vars['dobr']['value'] == 1) ? 1 : 0;
356  return $ts->previewTarea($ret, $html, $smiley, $xcode, $image, $br);
357  break 1;
358  case 'f':
359  case 'formpreview':
360  $ts =& TextCleaner::getInstance();
361  return htmlspecialchars($ts->stripSlashesGPC($ret), ENT_QUOTES);
362  break 1;
363  case 'n':
364  case 'none':
365  default:
366  return $ret;
367  break 1;
368  }
369  break;
370  case XOBJ_DTYPE_ARRAY:
371  if (!is_array($ret) && trim($ret)!=''){
372  $ret =& unserialize($ret);
373  } else {
374  $ret = $ret;
375  }
376  break;
377  case XOBJ_DTYPE_SOURCE:
378  switch (strtolower($format)) {
379  case 's':
380  case 'show':
381  break 1;
382  case 'e':
383  case 'edit':
384  return htmlspecialchars($ret, ENT_QUOTES);
385  break 1;
386  case 'p':
387  case 'preview':
388  $ts =& TextCleaner::getInstance();
389  return $ts->stripSlashesGPC($ret);
390  break 1;
391  case 'f':
392  case 'formpreview':
393  $ts =& TextCleaner::getInstance();
394  return htmlspecialchars($ts->stripSlashesGPC($ret), ENT_QUOTES);
395  break 1;
396  case 'n':
397  case 'none':
398  default:
399  break 1;
400  }
401  break;
402  default:
403  if ($this->vars[$key]['options'] != '' && $ret != '') {
404  switch (strtolower($format)) {
405  case 's':
406  case 'show':
407  $selected = explode('|', $ret);
408  $options = explode('|', $this->vars[$key]['options']);
409  $i = 1;
410  $ret = array();
411  foreach ($options as $op) {
412  if (in_array($i, $selected)) {
413  $ret[] = $op;
414  }
415  $i++;
416  }
417  return implode(', ', $ret);
418  case 'e':
419  case 'edit':
420  $ret = explode('|', $ret);
421  break 1;
422  default:
423  break 1;
424  }
425 
426  }
427  break;
428  }
429  return $ret;
430  }
431 
439  public function cleanVars()
440  {
441  $ts =& TextCleaner::getInstance();
442  $existing_errors = $this->getErrors();
443  $this->_errors = array();
444  foreach ($this->vars as $k => $v) {
445  $cleanv = $v['value'];
446  if (!$v['changed']) {
447  } else {
448  $cleanv = is_string($cleanv) ? trim($cleanv) : $cleanv;
449  switch ($v['data_type']) {
450  case XOBJ_DTYPE_TXTBOX:
451  if ($v['required'] && $cleanv != '0' && $cleanv == '') {
452  $this->setErrors( sprintf( _XOBJ_ERR_REQUIRED, $k ) );
453  continue;
454  }
455  if (isset($v['maxlength']) && strlen($cleanv) > intval($v['maxlength'])) {
456  $this->setErrors( sprintf( _XOBJ_ERR_SHORTERTHAN, $k, intval( $v['maxlength'] ) ) );
457  continue;
458  }
459  $cleanv = TextCleaner::stripslashes($cleanv);
460  break;
461  case XOBJ_DTYPE_TXTAREA:
462  if ($v['required'] && $cleanv != '0' && $cleanv == '') {
463  $this->setErrors( sprintf( _XOBJ_ERR_REQUIRED, $k ) );
464  continue;
465  }
466 
467  $cleanv = TextCleaner::stripslashes($cleanv);
468  break;
469  case XOBJ_DTYPE_SOURCE:
470  $cleanv = TextCleaner::stripslashes($cleanv);
471  break;
472  case XOBJ_DTYPE_INT:
473  $cleanv = intval($cleanv);
474  break;
475  case XOBJ_DTYPE_EMAIL:
476  if ($v['required'] && $cleanv == '') {
477  $this->setErrors( sprintf( _XOBJ_ERR_REQUIRED, $k ) );
478  continue;
479  }
480  if ($cleanv != '' && !preg_match("/^[_a-z0-9-]+(\.[_a-z0-9-]+)*@[a-z0-9-]+([\.][a-z0-9-]+)+$/i",$cleanv)) {
481  $this->setErrors("Invalid Email");
482  continue;
483  }
484  $cleanv = TextCleaner::stripslashes($cleanv);
485  break;
486  case XOBJ_DTYPE_URL:
487  if ($v['required'] && $cleanv == '') {
488  $this->setErrors( sprintf( _XOBJ_ERR_REQUIRED, $k ) );
489  continue;
490  }
491  if ($cleanv != '' && !preg_match("/^http[s]*:\/\//i", $cleanv)) {
492  $cleanv = 'http://' . $cleanv;
493  }
494  $cleanv = TextCleaner::stripslashes($cleanv);
495  break;
496  case XOBJ_DTYPE_ARRAY:
497  $cleanv = !empty($cleanv) && is_array($cleanv) ? serialize($cleanv) : $cleanv;
498  break;
499  case XOBJ_DTYPE_STIME:
500  case XOBJ_DTYPE_MTIME:
501  case XOBJ_DTYPE_LTIME:
502  $cleanv = !is_string($cleanv) ? intval($cleanv) : strtotime($cleanv);
503  break;
504  default:
505  break;
506  }
507  }
508  $this->cleanVars[$k] =& $cleanv;
509  unset($cleanv);
510  }
511 
512  if (count($this->_errors) > 0) {
513  $this->_errors = array_merge($existing_errors, $this->_errors);
514  return false;
515  }
516  $this->_errors = array_merge($existing_errors, $this->_errors);
517  $this->unsetDirty();
518  return true;
519  }
520 
524  protected function clear_vars(){
525  foreach ($this->vars as $var){
526  $var['value'] = '';
527  }
528  $this->_isNew = true;
529  $this->_errors = array();
530  $this->_filters = array();
531  }
532 
539  function registerFilter($filtername)
540  {
541  $this->_filters[] = $filtername;
542  }
543 
549  function _loadFilters()
550  {
551  //include_once ABSPATH.'/class/filters/filter.php';
552  //foreach ($this->_filters as $f) {
553  // include_once ABSPATH.'/class/filters/'.strtolower($f).'php';
554  //}
555  }
556 
563  function rmClone()
564  {
565  $class = get_class($this);
566  $clone = new $class();
567  foreach ($this->vars as $k => $v) {
568  $clone->assignVar($k, $v['value']);
569  }
570  // need this to notify the handler class that this is a newly created object
571  $clone->setNew();
572  return $clone;
573  }
574 
581  function setErrors($err_str)
582  {
583  $this->_errors[] = trim($err_str);
584  }
585 
592  function getErrors()
593  {
594  return $this->errors(false);
595  }
596 
603  function getHtmlErrors()
604  {
605  return $this->errores(true);
606  }
611  protected function addError($text){
612  $this->setErrors($text);
613  }
622  public function errors($html=true){
623  $ret = '';
624 
625  if (count($this->_errors)<=0){ return $html ? '' : array(); }
626 
627  if ($html){
628 
629  $ret .= "<div class='outer' style='padding: 1px;'>";
630  foreach ($this->_errors as $k){
631  $ret .= "<div class='odd'>$k</div>";
632  }
633  $ret .= "</div>";
634 
635  } else {
636 
637  return $this->_errors;
638 
639  }
640 
641  return $ret;
642  }
647  protected function varIsset($var){
648  if (isset($this->vars[$var])){
649  return true;
650  } else {
651  return false;
652  }
653  }
659  protected function logger($event,$style=''){
660  $rtn = array();
661  $rtn['event'] = $event;
662  $rtn['style'] = $style;
663  $this->_log[] = $rtn;
664  }
668  protected function clearLogger(){
669  $this->_log = array();
670  }
679  public function getLogger($ashtml = true){
680  if (!$ashtml){
681  return $this->_log;
682  }
683 
684  $rtn = '';
685  foreach ($this->_log as $k){
686  $rtn .= "<div style='padding: 2px;";
687  if ($k['style']!=''){
688  if (stripos($k['style'],'text-align:')==''){
689  $rtn .= ' text-align: left;';
690  }
691  $rtn .= ' ' . $k['style'];
692  }
693  $rtn .= "'>".(trim($k['event'])=='' ? '&nbsp;' : $k['event'])."</div>\n";
694  }
695 
696  return $rtn;
697  }
704  protected function getColumns(){
705 
706  static $objectColumns;
707  static $primaryCols;
708  if (!empty($objectColumns[get_class($this)])){
709  $this->primary = $primaryCols[get_class($this)];
710  $this->_tblcolumns = $objectColumns[get_class($this)];
711  return $objectColumns[get_class($this)];
712  } else {
713  if (empty($this->_tblcolumns)){
714  $result = $this->db->queryF("SHOW COLUMNS IN ".$this->_dbtable);
715  while ($row = $this->db->fetchArray($result)){
716  if ($row['Extra'] == 'auto_increment'){
717  $this->primary = $row['Field'];
718  $primaryCols[get_class($this)] = $row['Field'];
719  }
720  $this->_tblcolumns[] = $row;
721  }
722  }
723  $objectColumns[get_class($this)] = $this->_tblcolumns;
724  return $objectColumns[get_class($this)];
725  }
726  }
731  protected function initVarsFromTable(){
732 
733  foreach ($this->getColumns() as $k => $v){
734  $efes = array();
735  preg_match("/(.+)(\(([,0-9]+)\))/", $v['Type'], $efes);
736  if (!isset($efes[1])){
737  $efes[1] = $v['Type'];
738  }
739 
740  switch ($efes[1]){
741  case 'mediumint':
742  case 'int':
743  case 'tinyint':
744  case 'smallint':
745  case 'bigint':
746  case 'timestamp':
747  case 'year':
748  case 'bool':
749  $type = XOBJ_DTYPE_INT;
750  $lon = null;
751  break;
752  case 'float':
753  case 'double':
754  $type = XOBJ_DTYPE_FLOAT;
755  break;
756  case 'decimal':
757  $type = XOBJ_DTYPE_TXTBOX;
758  $lon = null;
759  break;
760  case 'time':
761  $type = XOBJ_DTYPE_TXTBOX;
762  $lon = 8;
763  break;
764  case 'datetime':
765  $type = XOBJ_DTYPE_TXTBOX;
766  $lon = 19;
767  break;
768  case 'date':
769  $type = XOBJ_DTYPE_TXTBOX;
770  $lon = 10;
771  break;
772  case 'char':
773  case 'tinyblob':
774  case 'tinytext':
775  case 'enum':
776  case 'set':
777  case 'varchar':
778  $type = XOBJ_DTYPE_TXTBOX;
779  $lon = isset($len[3]) ? $len[3] : null;
780  break;
781  case 'text':
782  case 'blob':
783  case 'mediumblob':
784  case 'mediumtext':
785  case 'longblob':
786  case 'longtext':
787  $type = XOBJ_DTYPE_TXTAREA;
788  $lon = null;
789  break;
790  default:
791  $type = XOBJ_DTYPE_OTHER;
792  $lon = null;
793  break;
794 
795 
796  }
797 
798  $this->initVar($v['Field'], $type, $v['Default'], false, $lon);
799  }
800  }
801 
808  protected function loadValues($id){
809 
810  if (get_magic_quotes_gpc())
811  $id = stripslashes($id);
812 
813  $id = mysql_real_escape_string($id);
814 
815  $sql = "SELECT * FROM $this->_dbtable WHERE `$this->primary`='$id'";
816  $result = $this->db->query($sql);
817  if ($this->db->getRowsNum($result)<=0) return false;
818 
819  $row = $this->db->fetchArray($result);
820  foreach ($row as $k => $v){
821  $this->setVar($k, $v);
822  }
823 
824  return true;
825  }
826 
830  protected function loadValuesFiltered($filter=''){
831 
832  if (get_magic_quotes_gpc())
833  $filter = stripslashes($filter);
834 
835  $sql = "SELECT * FROM $this->_dbtable WHERE $filter";
836  $result = $this->db->query($sql);
837  if ($this->db->getRowsNum($result)<=0) return false;
838 
839  $row = $this->db->fetchArray($result);
840  $this->assignVars($row);
841 
842  return true;
843 
844  }
845 
850  protected function loadValuesArray($values){
851  if (!is_array($values) || empty($values)){
852  return false;
853  }
857  $query = '';
858  foreach ($values as $k => $v){
859  if (get_magic_quotes_gpc())
860  $v = stripslashes($v);
861  $values[$k] = mysql_real_escape_string($v);
862  $query .= $query=='' ? "`$k`='$v'" : " AND `$k`='$v'";
863  }
864 
865  $sql = "SELECT * FROM $this->_dbtable WHERE $query";
866  $result = $this->db->queryF($sql);
867  if ($this->db->getRowsNum($result)<=0) return false;
868 
869  $row = $this->db->fetchArray($result);
870  $myts =& TextCleaner::getInstance();
871  foreach ($row as $k => $v){
872  $this->setVar($k, $myts->stripslashes($v));
873  }
874 
875  return true;
876 
877  }
882  protected function saveToTable(){
883  $myts =& TextCleaner::getInstance();
884  $this->cleanVars();
885  $sql = "INSERT INTO $this->_dbtable (";
886  $fields = '';
887  $values = '';
888  foreach ($this->_tblcolumns as $k){
889  if ($k['Extra'] == 'auto_increment') continue;
890  $fields .= ($fields == '') ? "`$k[Field]`" : ", `$k[Field]`";
891  $values .= ($values=='') ? "'".addslashes($this->cleanVars[$k['Field']])."'" : ", '".addslashes($this->cleanVars[$k['Field']])."'";
892  }
893 
894  $sql .= $fields .") VALUES (". $values .")";
895 
896  if (!$this->db->queryF($sql)){
897  $this->addError($this->db->error());
898  return false;
899  } else {
900  $this->setVar($this->primary, $this->db->getInsertId());
901  $this->unsetNew();
902  return true;
903  }
904 
905  }
909  protected function updateTable(){
910  if (empty($this->_tblcolumns)) $this->getColumns();
911 
912  $myts =& TextCleaner::getInstance();
913  $sql = "UPDATE $this->_dbtable SET ";
914  $fields = '';
915 
916  $this->cleanVars();
917 
918  foreach ($this->_tblcolumns as $k){
919  if ($k['Extra'] == 'auto_increment') continue;
920  $fields .= $fields == '' ? "`$k[Field]`='".addslashes($this->cleanVars[$k['Field']])."'" : ", `$k[Field]`='".addslashes($this->cleanVars[$k['Field']])."'";
921  }
922 
923  $sql .= $fields . " WHERE `$this->primary`='".$this->getVar($this->primary)."'";
924 
925  $this->db->queryF($sql);
926  if ($this->db->error()!=''){
927  $this->addError($this->db->error());
928  return false;
929  } else {
930  return true;
931  }
932  }
936  protected function deleteFromTable(){
937 
938  $sql = "DELETE FROM $this->_dbtable WHERE `$this->primary`='".$this->getVar($this->primary)."'";
939  $this->db->queryF($sql);
940  if ($this->db->error()!=''){
941  $this->addError($this->db->error());
942  return false;
943  } else {
944  return true;
945  }
946 
947  }
948 }