KumbiaPHP  beta2
Framework PHP
 Todo Estructuras de Datos Namespaces Archivos Funciones Variables Páginas
kumbia_active_record.php
Ir a la documentación de este archivo.
1 <?php
24 require CORE_PATH . 'libs/db/db.php';
25 
70 {
71  //Soportados
72 
78  protected $db;
84  protected $database;
90  protected $schema;
96  protected $source;
102  protected $count;
108  protected $fields = array();
114  protected $primary_key = array();
120  protected $non_primary = array();
126  protected $not_null = array();
132  protected $_with_default = array();
138  protected $alias = array();
145  protected $is_view = false;
151  protected $debug = false;
157  protected $logger = false;
163  protected $persistent = false;
177  protected $_validates = array('inclusion_in' => array(), 'exclusion_of' => array(), 'numericality_of' => array(),
178  'format_of' => array(), 'date_in' => array(), 'email_in' => array(), 'uniqueness_of' => array());
184  protected $_in = array();
190  protected $_at = array();
197  protected $_where_pk;
203  protected $_dumped = false;
210  protected $_dump_lock = false;
216  protected $_data_type = array();
222  protected $_has_one = array();
228  protected $_has_many = array();
234  protected $_belongs_to = array();
240  protected $_has_and_belongs_to_many = array();
246  protected $parent_of = array();
250  protected static $_models = array();
254  protected static $models = array();
255 
261  function __construct($data=null)
262  {
263  if (!$this->source) {
264  $this->_model_name();
265  }
266 
270  if (method_exists($this, 'initialize')) {
271  $this->initialize();
272  }
273 
277  $this->_connect();
278 
279  if ($data) {
280  if (!is_array($data)) $data = Util::getParams(func_get_args());
281  foreach($this->fields as $field) {
282  if (isset($data[$field])) {
283  $this->$field = $data[$field];
284  }
285  }
286  }
287  }
288 
293  protected function _model_name()
294  {
295  if (!$this->source) {
296  $this->source = Util::smallcase(get_class($this));
297  }
298  }
299 
305  public function set_source($source)
306  {
307  $this->source = $source;
308  }
309 
315  public function get_source()
316  {
317  return $this->source;
318  }
319 
325  public function set_database($database)
326  {
327  $this->database = $database;
328  }
329 
335  public function get_database()
336  {
337  if ($this->database) {
338  return $this->database;
339  } else {
340  $core = Config::read('config');
341  return $core['application']['database'];
342  }
343  }
344 
351  public function is_dumped()
352  {
353  return $this->_dumped;
354  }
355 
363  protected function _get_relation_data($mmodel)
364  {
365  if (array_key_exists($mmodel, $this->_belongs_to)) {
366  $relation = $this->_belongs_to[$mmodel];
367  return self::get($relation->model)->find_first($this->{$relation->fk});
368  } elseif (array_key_exists($mmodel, $this->_has_one)) {
369  $relation = $this->_has_one[$mmodel];
370  if ($this->{$this->primary_key[0]}) {
371  return self::get($relation->model)->find_first("{$relation->fk}={$this->db->add_quotes($this->{$this->primary_key[0]}) }");
372  } else {
373  return NULL;
374  }
375  } elseif (array_key_exists($mmodel, $this->_has_many)) {
376  $relation = $this->_has_many[$mmodel];
377  if ($this->{$this->primary_key[0]}) {
378  return self::get($relation->model)->find("{$relation->fk}={$this->db->add_quotes($this->{$this->primary_key[0]}) }");
379  } else {
380  return array();
381  }
382  } elseif (array_key_exists($mmodel, $this->_has_and_belongs_to_many)) {
383  $relation = $this->_has_and_belongs_to_many[$mmodel];
384  $relation_model = self::get($relation->model);
385  $source = ($this->schema ? "{$this->schema}." : NULL ) . $this->source;
386  $relation_source = ($relation_model->schema ? "{$relation_model->schema}." : NULL ) . $relation_model->source;
391  if (!isset($relation->through)) {
392  if ($source > $relation_source) {
393  $relation->through = "{$this->source}_{$relation_source}";
394  } else {
395  $relation->through = "{$relation_source}_{$this->source}";
396  }
397  }else{
398  $through = explode('/', $relation->through);
399  $relation->through = end($through);
400  }
401  if ($this->{$this->primary_key[0]}) {
402  return $relation_model->find_all_by_sql("SELECT $relation_source.* FROM $relation_source, {$relation->through}, $source
403  WHERE {$relation->through}.{$relation->key} = {$this->db->add_quotes($this->{$this->primary_key[0]}) }
404  AND {$relation->through}.{$relation->fk} = $relation_source.{$relation_model->primary_key[0]}
405  AND {$relation->through}.{$relation->key} = $source.{$this->primary_key[0]}
406  ORDER BY $relation_source.{$relation_model->primary_key[0]}");
407  } else {
408  return array();
409  }
410  } else {
411  return FALSE; //si no existe ninguna asociación devuelve false.
412  }
413  }
414 
421  function __get($property)
422  {
423  if (!$this->_dump_lock) {
424  if (!isset($this->$property)) {
425  return $this->_get_relation_data($property);
426  }
427  }
428  return $this->$property;
429  }
430 
438  function __set($property, $value)
439  {
440  if (!$this->_dump_lock) {
441  if (is_object($value) && is_subclass_of($value, 'KumbiaActiveRecord')) {
442  if (array_key_exists($property, $this->_belongs_to)) {
443  $relation = $this->_belongs_to[$property];
444  $value->dump_model();
445  $this->{$relation->fk} = $value->{$value->primary_key[0]};
446  return;
447  } elseif (array_key_exists($property, $this->_has_one)) {
448  $relation = $this->_has_one[$property];
449  $value->{$relation->fk} = $this->{$this->primary_key[0]};
450  return;
451  }
452  } elseif ($property == "source") {
453  $value = KumbiaActiveRecord::sql_item_sanitize($value);
454  }
455  }
456  $this->$property = $value;
457  }
458 
463  public function __call($method, $args = array())
464  {
465  if (substr($method, 0, 8) == "find_by_") {
466  $field = substr($method, 8);
468  if (isset($args[0])) {
469  $arg = array("conditions: $field = {$this->db->add_quotes($args[0])}");
470  unset($args[0]);
471  } else {
472  $arg = array();
473  }
474  return call_user_func_array(array($this, "find_first"), array_merge($arg, $args));
475  }
476  if (substr($method, 0, 9) == "count_by_") {
477  $field = substr($method, 9);
479  if (isset($args[0])) {
480  $arg = array("conditions: $field = {$this->db->add_quotes($args[0])}");
481  unset($args[0]);
482  } else {
483  $arg = array();
484  }
485  return call_user_func_array(array($this, "count"), array_merge($arg, $args));
486  }
487  if (substr($method, 0, 12) == "find_all_by_") {
488  $field = substr($method, 12);
490  if (isset($args[0])) {
491  $arg = array("conditions: $field = {$this->db->add_quotes($args[0])}");
492  unset($args[0]);
493  } else {
494  $arg = array();
495  }
496  return call_user_func_array(array($this, "find"), array_merge($arg, $args));
497  }
498  $model = preg_replace('/^get/', '', $method);
499  $mmodel = Util::smallcase($model);
500  if (($data = $this->_get_relation_data($mmodel)) !== FALSE) {
501  return $data;
502  }
503 
504  if (method_exists($this, $method)) {
505  call_user_func_array(array($this, $method), $args);
506  } else {
507  throw new KumbiaException("No existe el método '$method' en ActiveRecord::" . get_class($this));
508  }
509 
510  return $this->$method($args);
511  }
512 
516  protected function _connect()
517  {
518  if (!is_object($this->db)) {
519  $this->db = Db::factory($this->database);
520  }
521  $this->db->debug = $this->debug;
522  $this->db->logger = $this->logger;
523  $this->dump();
524  }
525 
530  public function dump_model()
531  {
532  $this->_connect();
533  }
534 
541  protected function dump()
542  {
543  if ($this->_dumped) {
544  return false;
545  }
546  //$a = array();
547  if ($this->source) {
548  $this->source = str_replace(";", '', strtolower($this->source));
549  } else {
550  $this->_model_name();
551  if (!$this->source) {
552  return false;
553  }
554  }
555  $table = $this->source;
556  $schema = $this->schema;
557  if (!count(self::get_meta_data($this->source))) {
558  $this->_dumped = true;
559  $this->_dump_info($table, $schema);
560  if (!count($this->primary_key)) {
561  if (!$this->is_view) {
562  throw new KumbiaException("No se ha definido una llave primaria para la tabla '$table' esto imposibilita crear el ActiveRecord para esta entidad");
563  }
564  }
565  } else {
566  if (!$this->is_dumped()) {
567  $this->_dumped = true;
568  $this->_dump_info($table, $schema);
569  }
570  }
571  return true;
572  }
573 
581  protected function _dump_info($table, $schema = '')
582  {
583  $this->_dump_lock = true;
584  if (!count(self::get_meta_data($table))) {
585  $meta_data = $this->db->describe_table($table, $schema);
586  if ($meta_data) {
587  self::set_meta_data($table, $meta_data);
588  }
589  }
590  foreach (self::get_meta_data($table) as $field) {
591  $this->fields[] = $field['Field'];
592  $aliasAux = $field['Field'];
593  if ($field['Key'] == 'PRI') {
594  $this->primary_key[] = $field['Field'];
595  $this->alias[$field['Field']] = 'Código';
596  } else
597  $this->non_primary[] = $field['Field'];
604  if ($field['Null'] == 'NO' && !(isset($field['Default']) && $field['Default'])) {
605  $this->not_null[] = $field['Field'];
606  }
607  if (isset($field['Default']) && $field['Default']) {
608  $this->_with_default[] = $field['Field'];
609  }
610  if ($field['Type']) {
611  $this->_data_type[$field['Field']] = strtolower($field['Type']);
612  }
613  if (substr($field['Field'], strlen($field['Field']) - 3, 3) == '_at') {
614  $this->_at[] = $field['Field'];
615  $aliasAux = substr($field['Field'], 0, -3);
616  }
617  if (substr($field['Field'], strlen($field['Field']) - 3, 3) == '_in') {
618  $this->_in[] = $field['Field'];
619  $aliasAux = substr($field['Field'], 0, -3);
620  }
621  if (substr($field['Field'], strlen($field['Field']) - 3, 3) == '_id') {
622  $aliasAux = substr($field['Field'], 0, -3);
623  }
624  //humanizando el alias
625  $this->alias[$field['Field']] = ucwords(strtr($aliasAux, '_-', ' '));
626  }
627  $this->_dump_lock = false;
628  return true;
629  }
630 
637  public function get_alias($key=null)
638  {
639  if ($key && array_key_exists($key, $this->alias)) {
640  return $this->alias[$key];
641  } else {
642  throw new KumbiaException("No se pudo obtener el Alias, porque el key: \"$key\" no existe.");
643  }
644  }
645 
652  public function set_alias($key=null, $value=null)
653  {
654  if ($key && array_key_exists($key, $this->alias)) {
655  $this->alias[$key] = $value;
656  } else {
657  throw new KumbiaException("No se pudo asignar el nuevo valor al Alias, porque el key: \"$key\" no existe.");
658  }
659  }
660 
666  public function commit()
667  {
668  return $this->db->commit();
669  }
670 
676  public function rollback()
677  {
678  return $this->db->rollback();
679  }
680 
686  public function begin()
687  {
688  $this->_connect();//(true);
689  return $this->db->begin();
690  }
691 
698  public function find_all_by_sql($sqlQuery)
699  {
700  $results = array();
701  foreach ($this->db->fetch_all($sqlQuery) as $result) {
702  $results[] = $this->dump_result($result);
703  }
704  return $results;
705  }
706 
713  public function find_by_sql($sqlQuery)
714  {
715  $row = $this->db->fetch_one($sqlQuery);
716  if ($row !== false) {
717  $this->dump_result_self($row);
718  return $this->dump_result($row);
719  } else {
720  return false;
721  }
722  }
723 
730  public function sql($sqlQuery)
731  {
732  return $this->db->query($sqlQuery);
733  }
734 
743  public function find_first($what = '')
744  {
745  $what = Util::getParams(func_get_args());
746  $select = "SELECT ";
747  if (isset($what['columns'])) {
748  $select.= KumbiaActiveRecord::sql_sanitize($what['columns']);
749  } elseif (isset($what['distinct'])) {
750  $select.= 'DISTINCT ';
751  $select.= $what['distinct'] ? KumbiaActiveRecord::sql_sanitize($what['distinct']) : join(",", $this->fields);
752  } else {
753  $select.= join(",", $this->fields);
754  }
755  if ($this->schema) {
756  $select.= " FROM {$this->schema}.{$this->source}";
757  } else {
758  $select.= " FROM {$this->source}";
759  }
760  $what['limit'] = 1;
761  $select.= $this->convert_params_to_sql($what);
762  $resp = false;
763 
764  $result = $this->db->fetch_one($select);
765  if ($result) {
766  $this->dump_result_self($result);
767  $resp = $this->dump_result($result);
768  }
769 
770  return $resp;
771  }
772 
787  public function find($what = '')
788  {
789  $what = Util::getParams(func_get_args());
790  $select = "SELECT ";
791  if (isset($what['columns'])) {
792  $select.= $what['columns'] ? KumbiaActiveRecord::sql_sanitize($what['columns']) : join(",", $this->fields);
793  } elseif (isset($what['distinct'])) {
794  $select.= 'DISTINCT ';
795  $select.= $what['distinct'] ? KumbiaActiveRecord::sql_sanitize($what['distinct']) : join(",", $this->fields);
796  } else {
797  $select.= join(",", $this->fields);
798  }
799  if ($this->schema) {
800  $select.= " FROM {$this->schema}.{$this->source}";
801  } else {
802  $select.= " FROM {$this->source}";
803  }
804  $select.= $this->convert_params_to_sql($what);
805  $results = array();
806  $all_results = $this->db->in_query($select);
807  foreach ($all_results AS $result) {
808  $results[] = $this->dump_result($result);
809  }
810 
811  $this->count = count($results, COUNT_NORMAL);
812  if (isset($what[0]) && is_numeric($what[0])) {
813  if (!isset($results[0])) {
814  $this->count = 0;
815  return false;
816  } else {
817  $this->dump_result_self($all_results[0]);
818  $this->count = 1;
819  return $results[0];
820  }
821  } else {
822  $this->count = count($results, COUNT_NORMAL);
823  return $results;
824  }
825  }
826 
827  /*
828  * Arma una consulta SQL con el parametro $what, así:
829  * $what = Util::getParams(func_get_args());
830  * $select = "SELECT * FROM Clientes";
831  * $select.= $this->convert_params_to_sql($what);
832  *
833  * @param string|array $what
834  * @return string
835  */
836 
837  public function convert_params_to_sql($what = '')
838  {
839  $select = '';
840  if (is_array($what)) {
841  if (!isset($what['conditions'])) {
842  if (!isset($this->primary_key[0]) && (isset($this->id) || $this->is_view)) {
843  $this->primary_key[0] = "id";
844  }
845  KumbiaActiveRecord::sql_item_sanitize($this->primary_key[0]);
846  if (isset($what[0])) {
847  if (is_numeric($what[0])) {
848  $what['conditions'] = "{$this->primary_key[0]} = ".(int)$what[0] ;
849  } else {
850  if ($what[0] == '') {
851  $what['conditions'] = "{$this->primary_key[0]} = ''";
852  } else {
853  $what['conditions'] = $what[0];
854  }
855  }
856  }
857  }
858  if (isset($what['join'])) {
859  $select.= " {$what['join']}";
860  }
861  if (isset($what['conditions'])) {
862  $select.= " WHERE {$what['conditions']}";
863  }
864  if (isset($what['group'])) {
865  $select.= " GROUP BY {$what['group']}";
866  }
867  if (isset($what['having'])) {
868  $select.= " HAVING {$what['having']}";
869  }
870  if (isset($what['order'])) {
871  KumbiaActiveRecord::sql_sanitize($what['order']);
872  $select.= " ORDER BY {$what['order']}";
873  }
874  $limit_args = array($select);
875  if (isset($what['limit'])) {
876  array_push($limit_args, "limit: ".(int)$what['limit']);
877  }
878  if (isset($what['offset'])) {
879  array_push($limit_args, "offset: ".(int)$what['offset']);
880  }
881  if (count($limit_args) > 1) {
882  $select = call_user_func_array(array($this, 'limit'), $limit_args);
883  }
884  } else {
885  if (strlen($what)) {
886  if (is_numeric($what)) {
887  $select.= "WHERE {$this->primary_key[0]} = ".(int)$what[0] ;
888  } else {
889  $select.= "WHERE $what";
890  }
891  }
892  }
893  return $select;
894  }
895 
896  /*
897  * Devuelve una clausula LIMIT adecuada al RDBMS empleado
898  *
899  * limit: maxima cantidad de elementos a mostrar
900  * offset: desde que elemento se comienza a mostrar
901  *
902  * @param string $sql consulta select
903  * @return String clausula LIMIT adecuada al RDBMS empleado
904  */
905 
906  public function limit($sql)
907  {
908  $args = func_get_args();
909  return call_user_func_array(array($this->db, 'limit'), $args);
910  }
911 
920  public function distinct($what = '')
921  {
922  $what = Util::getParams(func_get_args());
923  if ($this->schema) {
924  $table = $this->schema . "." . $this->source;
925  } else {
926  $table = $this->source;
927  }
928  if (!isset($what['columns'])) {
929  $what['columns'] = $what['0'];
930  } else {
931  if (!$what['columns']) {
932  $what['columns'] = $what['0'];
933  }
934  }
935  $what['columns'] = KumbiaActiveRecord::sql_sanitize($what['columns']);
936  $select = "SELECT DISTINCT {$what['columns']} FROM $table ";
940  unset($what[0]);
941  $select.= $this->convert_params_to_sql($what);
942  $results = array();
943  foreach ($this->db->fetch_all($select) as $result) {
944  $results[] = $result[0];
945  }
946  return $results;
947  }
948 
955  static public function static_select_one($sql)
956  {
957  $db = Db::factory();
958  if (substr(ltrim($sql), 0, 7) != "SELECT") {
959  $sql = "SELECT " . $sql;
960  }
961  $num = $db->fetch_one($sql);
962  return $num[0];
963  }
964 
971  public function count($what = '')
972  {
973  $what = Util::getParams(func_get_args());
974  if ($this->schema) {
975  $table = "{$this->schema}.{$this->source}";
976  } else {
977  $table = $this->source;
978  }
979  unset($what['order']);
980  if (isset($what['distinct']) && $what['distinct']) {
981  if (isset($what['group'])) {
982  $select = "SELECT COUNT(*) FROM (SELECT DISTINCT {$what['distinct']} FROM $table ";
983  $select.= $this->convert_params_to_sql($what);
984  $select.= ') AS t ';
985  } else {
986  $select = "SELECT COUNT(DISTINCT {$what['distinct']}) FROM $table ";
987  $select.= $this->convert_params_to_sql($what);
988  }
989  } else {
990  $select = "SELECT COUNT(*) FROM $table ";
991  $select.= $this->convert_params_to_sql($what);
992  }
993  $num = $this->db->fetch_one($select);
994  return $num[0];
995  }
996 
1003  public function average($what = '')
1004  {
1005  $what = Util::getParams(func_get_args());
1006  if (isset($what['column'])) {
1007  if (!$what['column']) {
1008  $what['column'] = $what[0];
1009  }
1010  } else {
1011  $what['column'] = $what[0];
1012  }
1013  unset($what[0]);
1014  KumbiaActiveRecord::sql_item_sanitize($what['column']);
1015  if ($this->schema) {
1016  $table = "{$this->schema}.{$this->source}";
1017  } else {
1018  $table = $this->source;
1019  }
1020  $select = "SELECT AVG({$what['column']}) FROM $table ";
1021  $select.= $this->convert_params_to_sql($what);
1022  $num = $this->db->fetch_one($select);
1023  return $num[0];
1024  }
1025 
1026  public function sum($what = '')
1027  {
1028  $what = Util::getParams(func_get_args());
1029  if (isset($what['column'])) {
1030  if (!$what['column']) {
1031  $what['column'] = $what[0];
1032  }
1033  } else {
1034  $what['column'] = $what[0];
1035  }
1036  unset($what[0]);
1037  KumbiaActiveRecord::sql_item_sanitize($what['column']);
1038  if ($this->schema) {
1039  $table = "{$this->schema}.{$this->source}";
1040  } else {
1041  $table = $this->source;
1042  }
1043  $select = "SELECT SUM({$what['column']}) FROM $table ";
1044  $select.= $this->convert_params_to_sql($what);
1045  $num = $this->db->fetch_one($select);
1046  return $num[0];
1047  }
1048 
1055  public function maximum($what = '')
1056  {
1057  $what = Util::getParams(func_get_args());
1058  if (isset($what['column'])) {
1059  if (!$what['column']) {
1060  $what['column'] = $what[0];
1061  }
1062  } else {
1063  $what['column'] = $what[0];
1064  }
1065  unset($what[0]);
1066  KumbiaActiveRecord::sql_item_sanitize($what['column']);
1067  if ($this->schema) {
1068  $table = "{$this->schema}.{$this->source}";
1069  } else {
1070  $table = $this->source;
1071  }
1072  $select = "SELECT MAX({$what['column']}) FROM $table ";
1073  $select.= $this->convert_params_to_sql($what);
1074  $num = $this->db->fetch_one($select);
1075  return $num[0];
1076  }
1077 
1084  public function minimum($what = '')
1085  {
1086  $what = Util::getParams(func_get_args());
1087  if (isset($what['column'])) {
1088  if (!$what['column']) {
1089  $what['column'] = $what[0];
1090  }
1091  } else {
1092  $what['column'] = $what[0];
1093  }
1094  unset($what[0]);
1095  KumbiaActiveRecord::sql_item_sanitize($what['column']);
1096  if ($this->schema) {
1097  $table = "{$this->schema}.{$this->source}";
1098  } else {
1099  $table = $this->source;
1100  }
1101  $select = "SELECT MIN({$what['column']}) FROM $table ";
1102  $select.= $this->convert_params_to_sql($what);
1103  $num = $this->db->fetch_one($select);
1104  return $num[0];
1105  }
1106 
1113  public function count_by_sql($sqlQuery)
1114  {
1115  $num = $this->db->fetch_one($sqlQuery);
1116  return $num[0];
1117  }
1118 
1127  public function dump_result($result)
1128  {
1129  $obj = clone $this;
1133  if (isset($result['type'])) {
1134  if (in_array($result['type'], $this->parent_of)) {
1135  if (class_exists($result['type'])) {
1136  $obj = new $result['type'];
1137  unset($result['type']);
1138  }
1139  }
1140  }
1141  $this->_dump_lock = true;
1142  if (is_array($result)) {
1143  foreach ($result as $k => $r) {
1144  if (!is_numeric($k)) {
1145  $obj->$k = stripslashes($r);
1146  }
1147  }
1148  }
1149  $this->_dump_lock = false;
1150  return $obj;
1151  }
1152 
1160  public function dump_result_self($result)
1161  {
1162  $this->_dump_lock = true;
1163  if (is_array($result)) {
1164  foreach ($result as $k => $r) {
1165  if (!is_numeric($k)) {
1166  $this->$k = stripslashes($r);
1167  }
1168  }
1169  }
1170  $this->_dump_lock = false;
1171  }
1172 
1180  public function create_from_request($form = null)
1181  {
1182  if (!$form) {
1183  $form = $this->source;
1184  }
1185  return $this->create($_REQUEST[$form]);
1186  }
1187 
1195  public function save_from_request($form = null)
1196  {
1197  if (!$form) {
1198  $form = $this->source;
1199  }
1200  return $this->save($_REQUEST[$form]);
1201  }
1202 
1209  public function update_from_request($form = null)
1210  {
1211  if (!$form) {
1212  $form = $this->source;
1213  }
1214  return $this->update($_REQUEST[$form]);
1215  }
1216 
1223  public function create()
1224  {
1225  if (func_num_args() > 0) {
1226  $params = Util::getParams(func_get_args());
1227  $values = (isset($params[0]) && is_array($params[0])) ? $params[0] : $params;
1228  foreach ($this->fields as $field) {
1229  if (isset($values[$field])) {
1230  $this->$field = $values[$field];
1231  }
1232  }
1233  }
1234  if ($this->primary_key[0] == 'id') {
1235  $this->id = null;
1236  }
1237  return $this->save();
1238  }
1239 
1246  function exists($where_pk = '')
1247  {
1248  if ($this->schema) {
1249  $table = "{$this->schema}.{$this->source}";
1250  } else {
1251  $table = $this->source;
1252  }
1253  if (!$where_pk) {
1254  $where_pk = array();
1255  foreach ($this->primary_key as $key) {
1256  if ($this->$key) {
1257  $where_pk[] = " $key = '{$this->$key}'";
1258  }
1259  }
1260  if (count($where_pk)) {
1261  $this->_where_pk = join(" AND ", $where_pk);
1262  } else {
1263  return 0;
1264  }
1265  $query = "SELECT COUNT(*) FROM $table WHERE {$this->_where_pk}";
1266  } else {
1267  if (is_numeric($where_pk)) {
1268  $query = "SELECT COUNT(*) FROM $table WHERE {$this->primary_key[0]} = '$where_pk'";
1269  } else {
1270  $query = "SELECT COUNT(*) FROM $table WHERE $where_pk";
1271  }
1272  }
1273  $num = $this->db->fetch_one($query);
1274  return $num[0];
1275  }
1276 
1282  public function save($values=null)
1283  {
1284  if ($values) {
1285  if (!is_array($values))
1286  $values = Util::getParams(func_get_args());
1287  foreach ($this->fields as $field) {
1288  if (isset($values[$field])) {
1289  $this->$field = $values[$field];
1290  }
1291  }
1292  }
1293  $ex = $this->exists();
1294  if ($this->schema) {
1295  $table = $this->schema . "." . $this->source;
1296  } else {
1297  $table = $this->source;
1298  }
1299  #Run Validation Callbacks Before
1300  if (method_exists($this, 'before_validation')) {
1301  if ($this->before_validation() == 'cancel') {
1302  return false;
1303  }
1304  } else {
1305  if (isset($this->before_validation)) {
1306  $method = $this->before_validation;
1307  if ($this->$method() == 'cancel') {
1308  return false;
1309  }
1310  }
1311  }
1312  if (!$ex) {
1313  if (method_exists($this, "before_validation_on_create")) {
1314  if ($this->before_validation_on_create() == 'cancel') {
1315  return false;
1316  }
1317  } else {
1318  if (isset($this->before_validation_on_create)) {
1319  $method = $this->before_validation_on_create;
1320  if ($this->$method() == 'cancel') {
1321  return false;
1322  }
1323  }
1324  }
1325  }
1326  if ($ex) {
1327  if (method_exists($this, "before_validation_on_update")) {
1328  if ($this->before_validation_on_update() == 'cancel') {
1329  return false;
1330  }
1331  } else {
1332  if (isset($this->before_validation_on_update)) {
1333  $method = $this->before_validation_on_update;
1334  if ($this->$method() == 'cancel') {
1335  return false;
1336  }
1337  }
1338  }
1339  }
1340 
1345  if (isset($this->_validates['presence_of'])) {
1346  foreach ($this->_validates['presence_of'] as $f => $opt) {
1347  if (isset($this->$f) && (is_null($this->$f) || $this->$f == '')) {
1348  if (!$ex && $f == $this->primary_key[0])
1349  continue;
1350  if (isset($opt['message'])) {
1351  Flash::error($opt['message']);
1352  return false;
1353  } else {
1354  $field = isset($opt['field']) ? $opt['field'] : $f;
1355  Flash::error("Error: El campo $field no puede ser nulo");
1356  return false;
1357  }
1358  }
1359  }
1360  }
1361 
1369  foreach ($this->not_null as $f) {
1370  if (in_array($f, $this->_with_default)) {
1371  continue;
1372  }
1373 
1374  if (!isset($this->$f) || is_null($this->$f) || $this->$f == '') {
1375  if (!$ex && $f == $this->primary_key[0]) {
1376  continue;
1377  }
1378  if (!$ex && in_array($f, $this->_at)) {
1379  continue;
1380  }
1381  if ($ex && in_array($f, $this->_in)) {
1382  continue;
1383  }
1384  Flash::error("Error: El campo $f no puede ser nulo");
1385  return false;
1386  }
1387  }
1388 
1393  if (isset($this->_validates['length_of'])) {
1394  foreach ($this->_validates['length_of'] as $f => $opt) {
1395  if (isset($this->$f) && !is_null($this->$f) && $this->$f != '') {
1396  $field = isset($opt['field']) ? $opt['field'] : $f;
1397 
1398  if (strlen($this->$f) < $opt['min']) {
1399  if (isset($opt['too_short']))
1400  Flash::error($opt['too_short']);
1401  else
1402  Flash::error("Error: El campo $field debe tener como mínimo $opt[min] caracteres");
1403  return false;
1404  }
1405 
1406  if (strlen($this->$f) > $opt['max']) {
1407  if (isset($opt['too_long']))
1408  Flash::error($opt['too_long']);
1409  else
1410  Flash::error("Error: El campo $field debe tener como máximo $opt[max] caracteres");
1411  return false;
1412  }
1413  }
1414  }
1415  }
1416 
1421  foreach ($this->_validates['inclusion_in'] as $f => $opt) {
1422  if (isset($this->$f) && !is_null($this->$f) && $this->$f != '') {
1423  if (!in_array($this->$f, $opt['list'])) {
1424  if (isset($opt['message'])) {
1425  Flash::error($opt['message']);
1426  } else {
1427  $field = isset($opt['field']) ? $opt['field'] : $f;
1428  Flash::error("$field debe tener un valor entre (" . join(",", $opt['list']) . ")");
1429  }
1430  return false;
1431  }
1432  }
1433  }
1434 
1439  foreach ($this->_validates['exclusion_of'] as $f => $opt) {
1440  if (isset($this->$f) && !is_null($this->$f) && $this->$f != '') {
1441  if (in_array($this->$f, $opt['list'])) {
1442  if (isset($opt['message'])) {
1443  Flash::error($opt['message']);
1444  } else {
1445  $field = isset($opt['field']) ? $opt['field'] : $f;
1446  Flash::error("$field no debe tener un valor entre (" . join(",", $opt['list']) . ")");
1447  }
1448  return false;
1449  }
1450  }
1451  }
1452 
1457  foreach ($this->_validates['numericality_of'] as $f => $opt) {
1458  if (isset($this->$f) && !is_null($this->$f) && $this->$f != '') {
1459  if (!is_numeric($this->$f)) {
1460  if (isset($opt['message'])) {
1461  Flash::error($opt['message']);
1462  } else {
1463  $field = isset($opt['field']) ? $opt['field'] : $f;
1464  Flash::error("$field debe tener un valor numérico");
1465  }
1466  return false;
1467  }
1468  }
1469  }
1470 
1475  foreach ($this->_validates['format_of'] as $f => $opt) {
1476  if (isset($this->$f) && !is_null($this->$f) && $this->$f != '') {
1477  if (!filter_var($this->$f, FILTER_VALIDATE_REGEXP, array("options" => array("regexp" => $opt['pattern'])))) {
1478  if (isset($opt['message'])) {
1479  Flash::error($opt['message']);
1480  } else {
1481  $field = isset($opt['field']) ? $opt['field'] : $f;
1482  Flash::error("Formato erroneo para $field");
1483  }
1484  return false;
1485  }
1486  }
1487  }
1488 
1493  foreach ($this->_validates['date_in'] as $f => $opt) {
1494  if (isset($this->$f) && !is_null($this->$f) && $this->$f != '') {
1495  if (!filter_var($this->$f, FILTER_VALIDATE_REGEXP, array("options" => array("regexp" => "/^\d{4}[-\/](0[1-9]|1[012])[-\/](0[1-9]|[12][0-9]|3[01])$/")))) {
1496  if (isset($opt['message'])) {
1497  Flash::error($opt['message']);
1498  } else {
1499  $field = isset($opt['field']) ? $opt['field'] : $f;
1500  Flash::error("Formato de fecha erroneo para $field");
1501  }
1502  return false;
1503  }
1504  }
1505  }
1506 
1511  foreach ($this->_validates['email_in'] as $f => $opt) {
1512  if (isset($this->$f) && !is_null($this->$f) && $this->$f != '') {
1513  if (!filter_var($this->$f, FILTER_VALIDATE_EMAIL)) {
1514  if (isset($opt['message'])) {
1515  Flash::error($opt['message']);
1516  } else {
1517  $field = isset($opt['field']) ? $opt['field'] : $f;
1518  Flash::error("Formato de e-mail erroneo en el campo $field");
1519  }
1520  return false;
1521  }
1522  }
1523  }
1524 
1529  // parche para que no tome encuenta el propio registro
1530  // al validar campos unicos, ya que si lo toma en cuenta
1531  // lanzará error de validacion porque ya existe un registro
1532  // con igual valor en el campo unico.
1533  $and_condition = $ex ? " AND {$this->primary_key[0]} != '{$this->{$this->primary_key[0]}}'" : '';
1534  foreach ($this->_validates['uniqueness_of'] as $f => $opt) {
1535  if (isset($this->$f) && !is_null($this->$f) && $this->$f != '') {
1536  $result = $this->db->fetch_one("SELECT COUNT(*) FROM $table WHERE $f = {$this->db->add_quotes($this->$f)} $and_condition");
1537  if ($result[0]) {
1538  if (isset($opt['message'])) {
1539  Flash::error($opt['message']);
1540  } else {
1541  $field = isset($opt['field']) ? $opt['field'] : $f;
1542  Flash::error("El valor '{$this->$f}' ya existe para el campo $field");
1543  }
1544  return false;
1545  }
1546  }
1547  }
1548 
1549  #Run Validation Callbacks After
1550  if (!$ex) {
1551  if (method_exists($this, "after_validation_on_create")) {
1552  if ($this->after_validation_on_create() == 'cancel') {
1553  return false;
1554  }
1555  } else {
1556  if (isset($this->after_validation_on_create)) {
1557  $method = $this->after_validation_on_create;
1558  if ($this->$method() == 'cancel') {
1559  return false;
1560  }
1561  }
1562  }
1563  }
1564  if ($ex) {
1565  if (method_exists($this, "after_validation_on_update")) {
1566  if ($this->after_validation_on_update() == 'cancel') {
1567  return false;
1568  }
1569  } else {
1570  if (isset($this->after_validation_on_update)) {
1571  $method = $this->after_validation_on_update;
1572  if ($this->$method() == 'cancel')
1573  return false;
1574  }
1575  }
1576  }
1577 
1578  if (method_exists($this, 'after_validation')) {
1579  if ($this->after_validation() == 'cancel') {
1580  return false;
1581  }
1582  } else {
1583  if (isset($this->after_validation)) {
1584  $method = $this->after_validation;
1585  if ($this->$method() == 'cancel') {
1586  return false;
1587  }
1588  }
1589  }
1590  # Run Before Callbacks
1591  if (method_exists($this, "before_save")) {
1592  if ($this->before_save() == 'cancel') {
1593  return false;
1594  }
1595  } else {
1596  if (isset($this->before_save)) {
1597  $method = $this->before_save;
1598  if ($this->$method() == 'cancel') {
1599  return false;
1600  }
1601  }
1602  }
1603  if ($ex) {
1604  if (method_exists($this, "before_update")) {
1605  if ($this->before_update() == 'cancel') {
1606  return false;
1607  }
1608  } else {
1609  if (isset($this->before_update)) {
1610  $method = $this->before_update;
1611  if ($this->$method() == 'cancel') {
1612  return false;
1613  }
1614  }
1615  }
1616  }
1617  if (!$ex) {
1618  if (method_exists($this, "before_create")) {
1619  if ($this->before_create() == 'cancel') {
1620  return false;
1621  }
1622  } else {
1623  if (isset($this->before_create)) {
1624  $method = $this->before_create;
1625  if ($this->$method() == 'cancel') {
1626  return false;
1627  }
1628  }
1629  }
1630  }
1631  $environment = Config::read('databases');
1632  $config = $environment[$this->get_database()];
1633  if ($ex) {
1634  $fields = array();
1635  $values = array();
1636  foreach ($this->non_primary as $np) {
1638  if (in_array($np, $this->_in)) {
1639  if ($config['type'] == 'oracle') {
1640  $this->$np = date("Y-m-d");
1641  } else {
1642  $this->$np = date("Y-m-d G:i:s");
1643  }
1644  }
1645  if (isset($this->$np)) {
1646  $fields[] = $np;
1647  if (is_null($this->$np) || $this->$np == '') {
1648  $values[] = 'NULL';
1649  } else {
1653  if ($this->_data_type[$np] == 'date' && $config['type'] == 'oracle') {
1654  $values[] = "TO_DATE(" . $this->db->add_quotes($this->$np) . ", 'YYYY-MM-DD')";
1655  } else {
1656  $values[] = $this->db->add_quotes($this->$np);
1657  }
1658  }
1659  }
1660  }
1661  $val = $this->db->update($table, $fields, $values, $this->_where_pk);
1662  } else {
1663  $fields = array();
1664  $values = array();
1665  foreach ($this->fields as $field) {
1666  if ($field != $this->primary_key[0] && !$this->id) {
1667  if (in_array($field, $this->_at)) {
1668  if ($config['type'] == 'oracle') {
1669  $this->$field = date("Y-m-d");
1670  } else {
1671  $this->$field = date("Y-m-d G:i:s");
1672  }
1673  }
1674  if (in_array($field, $this->_in)) {
1675  unset($this->$field);
1676  }
1677 
1678  if (isset($this->$field) && $this->$field !== '' && $this->$field !== NULL) {
1679  $fields[] = KumbiaActiveRecord::sql_sanitize($field);
1680 
1681  if (($this->_data_type[$field] == 'datetime' OR $this->_data_type[$field] == 'date') && ($config['type'] == 'mysql' OR $config['type'] == 'mysqli')) {
1682  $values[] = $this->db->add_quotes(date("Y-m-d G:i:s", strtotime($this->$field)));
1683  } elseif ($this->_data_type[$field] == 'date' && $config['type'] == 'oracle') {
1684  //Se debe especificar el formato de fecha en Oracle
1685  $values[] = "TO_DATE(" . $this->db->add_quotes($this->$field) . ", 'YYYY-MM-DD')";
1686  } else {
1687  $values[] = $this->db->add_quotes($this->$field);
1688  }
1689  } elseif (in_array($field, $this->_with_default)) {
1690  $fields[] = KumbiaActiveRecord::sql_sanitize($field);
1691  $values[] = 'DEFAULT';
1692  } else {
1693  $fields[] = KumbiaActiveRecord::sql_sanitize($field);
1694  $values[] = 'NULL';
1695  }
1696  } else {
1700  if ($config['type'] == 'oracle') {
1701  if (!$this->id) {
1702  $fields[] = "id";
1703  $values[] = $this->source . "_id_seq.NEXTVAL";
1704  }
1705  }
1706  if ($config['type'] == 'informix') {
1707  if (!$this->id) {
1708  $fields[] = "id";
1709  $values[] = 0;
1710  }
1711  }
1712  }
1713  }
1714 
1715  $val = $this->db->insert($table, $values, $fields);
1716  }
1717  if (!isset($config['pdo']) && $config['type'] == 'oracle') {
1718  $this->commit();
1719  }
1720  if (!$ex) {
1721  //$this->db->logger = true;
1722  $m = $this->db->last_insert_id($table, $this->primary_key[0]);
1723  $this->find_first($m);
1724  }
1725  if ($val) {
1726  if ($ex) {
1727  if (method_exists($this, "after_update")) {
1728  if ($this->after_update() == 'cancel') {
1729  return false;
1730  }
1731  } else {
1732  if (isset($this->after_update)) {
1733  $method = $this->after_update;
1734  if ($this->$method() == 'cancel') {
1735  return false;
1736  }
1737  }
1738  }
1739  }
1740  if (!$ex) {
1741  if (method_exists($this, "after_create")) {
1742  if ($this->after_create() == 'cancel') {
1743  return false;
1744  }
1745  } else {
1746  if (isset($this->after_create)) {
1747  $method = $this->after_create;
1748  if ($this->$method() == 'cancel') {
1749  return false;
1750  }
1751  }
1752  }
1753  }
1754  if (method_exists($this, "after_save")) {
1755  if ($this->after_save() == 'cancel') {
1756  return false;
1757  }
1758  } else {
1759  if (isset($this->after_save)) {
1760  $method = $this->after_save;
1761  if ($this->$method() == 'cancel') {
1762  return false;
1763  }
1764  }
1765  }
1766  return $val;
1767  } else {
1768  return false;
1769  }
1770  }
1771 
1779  function find_all_by($field, $value)
1780  {
1782  return $this->find("conditions: $field = {$this->db->add_quotes($value) }");
1783  }
1784 
1791  function update()
1792  {
1793  if (func_num_args() > 0) {
1794  $params = Util::getParams(func_get_args());
1795  $values = (isset($params[0]) && is_array($params[0])) ? $params[0] : $params;
1796  foreach ($this->fields as $field) {
1797  if (isset($values[$field])) {
1798  $this->$field = $values[$field];
1799  }
1800  }
1801  }
1802  if ($this->exists()) {
1803  if (method_exists($this, 'before_change')) {
1804  $obj = clone $this;
1805  if ($this->before_change($obj->find($this->{$this->primary_key[0]})) == 'cancel') {
1806  return false;
1807  }
1808  unset($obj);
1809  }
1810  if ($this->save()) {
1811  if (method_exists($this, 'after_change')) {
1812  if ($this->after_change($this) == 'cancel') {
1813  return false;
1814  }
1815  }
1816  return true;
1817  }
1818  } else {
1819  Flash::error('No se puede actualizar porque el registro no existe');
1820  return false;
1821  }
1822  }
1823 
1829  public function delete($what = '')
1830  {
1831  if (func_num_args() > 1) {
1832  $what = Util::getParams(func_get_args());
1833  }
1834  if ($this->schema) {
1835  $table = $this->schema . "." . $this->source;
1836  } else {
1837  $table = $this->source;
1838  }
1839  $conditions = '';
1840  if (is_array($what)) {
1841  if ($what["conditions"]) {
1842  $conditions = $what["conditions"];
1843  }
1844  } else {
1845  if (is_numeric($what)) {
1846  KumbiaActiveRecord::sql_sanitize($this->primary_key[0]);
1847  $conditions = "{$this->primary_key[0]} = '$what'";
1848  } else {
1849  if ($what) {
1850  $conditions = $what;
1851  } else {
1852  KumbiaActiveRecord::sql_sanitize($this->primary_key[0]);
1853  $conditions = "{$this->primary_key[0]} = '{$this->{$this->primary_key[0]}}'";
1854  }
1855  }
1856  }
1857  if (method_exists($this, "before_delete")) {
1858  if ($this->{$this->primary_key[0]}) {
1859  $this->find($this->{$this->primary_key[0]});
1860  }
1861  if ($this->before_delete() == 'cancel') {
1862  return false;
1863  }
1864  } else {
1865  if (isset($this->before_delete)) {
1866  if ($this->{$this->primary_key[0]}) {
1867  $this->find($this->{$this->primary_key[0]});
1868  }
1869  $method = $this->before_delete;
1870  if ($this->$method() == 'cancel') {
1871  return false;
1872  }
1873  }
1874  }
1875  $val = $this->db->delete($table, $conditions);
1876  if ($val) {
1877  if (method_exists($this, "after_delete")) {
1878  if ($this->after_delete() == 'cancel') {
1879  return false;
1880  }
1881  } else {
1882  if (isset($this->after_delete)) {
1883  $method = $this->after_delete;
1884  if ($this->$method() == 'cancel') {
1885  return false;
1886  }
1887  }
1888  }
1889  }
1890  return $val;
1891  }
1892 
1900  public function update_all($values)
1901  {
1902  $params = array();
1903  if ($this->schema) {
1904  $table = $this->schema . "." . $this->source;
1905  } else {
1906  $table = $this->source;
1907  }
1908  if (func_num_args() > 1) {
1909  $params = Util::getParams(func_get_args());
1910  }
1911  if (!isset($params['conditions']) || !$params['conditions']) {
1912  if (isset($params[1])) {
1913  $params['conditions'] = $params[1];
1914  } else {
1915  $params['conditions'] = '';
1916  }
1917  }
1918  if ($params['conditions']) {
1919  $params['conditions'] = " WHERE " . $params['conditions'];
1920  }
1921  $sql = "UPDATE $table SET $values {$params['conditions']}";
1922  $limit_args = array($sql);
1923  if (isset($params['limit'])) {
1924  array_push($limit_args, "limit: $params[limit]");
1925  }
1926  if (isset($params['offset'])) {
1927  array_push($limit_args, "offset: $params[offset]");
1928  }
1929  if (count($limit_args) > 1) {
1930  $sql = call_user_func_array(array($this, 'limit'), $limit_args);
1931  }
1932  $environment = Config::read('databases');
1933  $config = $environment[$this->get_database()];
1934  if (!isset($config->pdo) || !$config->pdo) {
1935  if ($config['type'] == "informix") {
1936  $this->db->set_return_rows(false);
1937  }
1938  }
1939  return $this->db->query($sql);
1940  }
1941 
1948  public function delete_all($conditions = '')
1949  {
1950  //$limit = '';
1951  if ($this->schema) {
1952  $table = $this->schema . "." . $this->source;
1953  } else {
1954  $table = $this->source;
1955  }
1956  if (func_num_args() > 1) {
1957  $params = Util::getParams(func_get_args());
1958  $limit_args = array($select);
1959  if (isset($params['limit'])) {
1960  array_push($limit_args, "limit: $params[limit]");
1961  }
1962  if (isset($params['offset'])) {
1963  array_push($limit_args, "offset: $params[offset]");
1964  }
1965  if (count($limit_args) > 1) {
1966  $select = call_user_func_array(array($this, 'limit'), $limit_args);
1967  }
1968  }
1969  return $this->db->delete($table, $conditions);
1970  }
1971 
1983  public function inspect()
1984  {
1985  $inspect = array();
1986  foreach ($this->fields as $field) {
1987  if (!is_array($field)) {
1988  $inspect[] = "$field: {$this->$field}";
1989  }
1990  }
1991  return join(", ", $inspect);
1992  }
1993 
2009  protected function validates_presence_of($field, $params=array())
2010  {
2011  if (is_string($params))
2012  $params = Util::getParams(func_get_args());
2013 
2014  $this->_validates['presence_of'][$field] = $params;
2015  }
2016 
2030  protected function validates_length_of($field, $max, $min=0, $params=array())
2031  {
2032  if (is_string($params))
2033  $params = Util::getParams(func_get_args());
2034 
2035  $this->_validates['length_of'][$field] = $params;
2036  $this->_validates['length_of'][$field]['min'] = $min;
2037  $this->_validates['length_of'][$field]['max'] = $max;
2038  }
2039 
2050  protected function validates_inclusion_in($field, $list, $params=array())
2051  {
2052  if (is_string($params))
2053  $params = Util::getParams(func_get_args());
2054 
2055  $this->_validates['inclusion_in'][$field] = $params;
2056  $this->_validates['inclusion_in'][$field]['list'] = $list;
2057  }
2058 
2069  protected function validates_exclusion_of($field, $list, $params=array())
2070  {
2071  if (is_string($params))
2072  $params = Util::getParams(func_get_args());
2073 
2074  $this->_validates['exclusion_of'][$field] = $params;
2075  $this->_validates['exclusion_of'][$field]['list'] = $list;
2076  }
2077 
2088  protected function validates_format_of($field, $pattern, $params=array())
2089  {
2090  if (is_string($params))
2091  $params = Util::getParams(func_get_args());
2092 
2093  $this->_validates['format_of'][$field] = $params;
2094  $this->_validates['format_of'][$field]['pattern'] = $pattern;
2095  }
2096 
2106  protected function validates_numericality_of($field, $params=array())
2107  {
2108  if (is_string($params))
2109  $params = Util::getParams(func_get_args());
2110 
2111  $this->_validates['numericality_of'][$field] = $params;
2112  }
2113 
2123  protected function validates_email_in($field, $params=array())
2124  {
2125  if (is_string($params))
2126  $params = Util::getParams(func_get_args());
2127 
2128  $this->_validates['email_in'][$field] = $params;
2129  }
2130 
2140  protected function validates_uniqueness_of($field, $params=array())
2141  {
2142  if (is_string($params))
2143  $params = Util::getParams(func_get_args());
2144 
2145  $this->_validates['uniqueness_of'][$field] = $params;
2146  }
2147 
2157  protected function validates_date_in($field, $params=array())
2158  {
2159  if (is_string($params))
2160  $params = Util::getParams(func_get_args());
2161 
2162  $this->_validates['date_in'][$field] = $params;
2163  }
2164 
2171  public function is_a_numeric_type($field)
2172  {
2173  if (strpos(" " . $this->_data_type[$field], "int") || strpos(" " . $this->_data_type[$field], "decimal") || strpos(" " . $this->_data_type[$field], "number")) {
2174  return true;
2175  } else {
2176  return false;
2177  }
2178  }
2179 
2186  static function get_meta_data($table)
2187  {
2188  if (isset(self::$models[$table])) {
2189  return self::$models[$table];
2190  } elseif (PRODUCTION) {
2191 
2192  $metadata = Cache::driver()->get($table, 'kumbia.models');
2193  if ($metadata) {
2194  return self::$models[$table] = unserialize($metadata);
2195  }
2196  }
2197  return array();
2198  }
2199 
2206  static function set_meta_data($table, $meta_data)
2207  {
2208  if (PRODUCTION) {
2209  Cache::driver()->save(serialize($meta_data), Config::get('config.application.metadata_lifetime'), $table, 'kumbia.models');
2210  }
2211  self::$models[$table] = $meta_data;
2212  return true;
2213  }
2214 
2215  /* * *****************************************************************************************
2216  * Metodos para generacion de relaciones
2217  * ***************************************************************************************** */
2218 
2227  protected function has_one($relation)
2228  {
2229  $params = Util::getParams(func_get_args());
2230  for ($i = 0; isset($params[$i]); $i++) {
2231  $relation = Util::smallcase($params[$i]);
2232  $index = explode('/', $relation);
2233  $index = end($index);
2234  if (!array_key_exists($index, $this->_has_one)) {
2235  $this->_has_one[$index] = new stdClass();
2236  $this->_has_one[$index]->model = isset($params['model']) ? $params['model'] : $relation;
2237  $this->_has_one[$index]->fk = isset($params['fk']) ? $params['fk'] : Util::smallcase(get_class($this)) . '_id';
2238  }
2239  }
2240  }
2241 
2250  protected function belongs_to($relation)
2251  {
2252  $params = Util::getParams(func_get_args());
2253  for ($i = 0; isset($params[$i]); $i++) {
2254  $relation = Util::smallcase($params[$i]);
2255  $index = explode('/', $relation);
2256  $index = end($index);
2257  if (!array_key_exists($index, $this->_belongs_to)) {
2258  $this->_belongs_to[$index] = new stdClass();
2259  $this->_belongs_to[$index]->model = isset($params['model']) ? $params['model'] : $relation;
2260  $this->_belongs_to[$index]->fk = isset($params['fk']) ? $params['fk'] : "{$relation}_id";
2261  }
2262  }
2263  }
2264 
2273  protected function has_many($relation)
2274  {
2275  $params = Util::getParams(func_get_args());
2276  for ($i = 0; isset($params[$i]); $i++) {
2277  $relation = Util::smallcase($params[$i]);
2278  $index = explode('/', $relation);
2279  $index = end($index);
2280  if (!array_key_exists($index, $this->_has_many)) {
2281  $this->_has_many[$index] = new stdClass();
2282  $this->_has_many[$index]->model = isset($params['model']) ? $params['model'] : $relation;
2283  $this->_has_many[$index]->fk = isset($params['fk']) ? $params['fk'] : Util::smallcase(get_class($this)) . '_id';
2284  }
2285  }
2286  }
2287 
2298  protected function has_and_belongs_to_many($relation)
2299  {
2300  $params = Util::getParams(func_get_args());
2301  for ($i = 0; isset($params[$i]); $i++) {
2302  $relation = Util::smallcase($params[$i]);
2303  if (!array_key_exists($relation, $this->_has_and_belongs_to_many)) {
2304  $this->_has_and_belongs_to_many[$relation] = new stdClass();
2305  $this->_has_and_belongs_to_many[$relation]->model = isset($params['model']) ? $params['model'] : $relation;
2306  $this->_has_and_belongs_to_many[$relation]->fk = isset($params['fk']) ? $params['fk'] : "{$relation}_id";
2307  $this->_has_and_belongs_to_many[$relation]->key = isset($params['key']) ? $params['key'] : Util::smallcase(get_class($this)) . '_id';
2308  if (isset($params['through'])) {
2309  $this->_has_and_belongs_to_many[$relation]->through = $params['through'];
2310  }
2311  }
2312  }
2313  }
2314 
2324  public function parent_of($parent)
2325  {
2326  $parents = func_get_args();
2327  foreach ($parents as $parent) {
2328  if (!in_array($parent, $this->parent_of)) {
2329  $this->parent_of[] = $parent;
2330  }
2331  }
2332  }
2333 
2340  public static function sql_item_sanitize($sql_item)
2341  {
2342  $sql_item = trim($sql_item);
2343  if ($sql_item !== '' && $sql_item !== null) {
2344  $sql_temp = preg_replace('/\s+/', '', $sql_item);
2345  if (!preg_match('/^[a-zA-Z0-9_\.]+$/', $sql_temp)) {
2346  throw new KumbiaException("Se esta tratando de ejecutar una operacion maliciosa!");
2347  }
2348  }
2349  return $sql_item;
2350  }
2351 
2358  public static function sql_sanitize($sql_item)
2359  {
2360  $sql_item = trim($sql_item);
2361  if ($sql_item !== '' && $sql_item !== null) {
2362  $sql_temp = preg_replace('/\s+/', '', $sql_item);
2363  if (!preg_match('/^[a-zA-Z_0-9\,\(\)\.\*]+$/', $sql_temp)) {
2364  throw new KumbiaException("Se esta tratando de ejecutar una operacion maliciosa!");
2365  }
2366  }
2367  return $sql_item;
2368  }
2369 
2375  protected function exceptions($e)
2376  {
2377  throw $e;
2378  }
2379 
2384  public function __toString()
2385  {
2386  return "<" . get_class() . " Object>";
2387  }
2388 
2399  public function paginate()
2400  {
2401  $args = func_get_args();
2402  array_unshift($args, $this);
2403  //if(!class_exists('Paginator')){
2404  require_once CORE_PATH . 'libs/kumbia_active_record/behaviors/paginate.php';
2405  //}
2406  return call_user_func_array(array('Paginator', 'paginate'), $args);
2407  }
2408 
2420  public function paginate_by_sql($sql)
2421  {
2422  $args = func_get_args();
2423  array_unshift($args, $this);
2424  //if(!class_exists('Paginator')){
2425  require_once CORE_PATH . 'libs/kumbia_active_record/behaviors/paginate.php';
2426  //}
2427  return call_user_func_array(array('Paginator', 'paginate_by_sql'), $args);
2428  }
2429 
2434  public function __sleep()
2435  {
2439  $this->db = null;
2440 
2441  return array_keys(get_object_vars($this));
2442  }
2443 
2448  public function __wakeup()
2449  {
2453  $this->_connect();
2454  }
2455 
2463  public static function get($model)
2464  {
2465  if (isset(self::$_models[$model])) {
2466  return self::$_models[$model];
2467  }
2468 
2472  $Model = Util::camelcase(basename($model));
2473 
2477  if (!class_exists($Model, false)) {
2481  $file = APP_PATH . "models/$model.php";
2482  if (is_file($file)) {
2483  include $file;
2484  } else {
2485  throw new KumbiaException(null, 'no_model');
2486  }
2487  }
2488 
2489  self::$_models[$model] = $obj = new $Model();
2490  return $obj;
2491  }
2492 
2498  public function to_json()
2499  {
2500  return json_encode($this);
2501  }
2502 
2508  public function to_array()
2509  {
2510  return ((array) $this);
2511  }
2512 
2519  public function serialize()
2520  {
2521  return serialize($this);
2522  }
2523 
2524 }