38
42
class ActiveRecord2 extends KumbiaModel implements Iterator
41
* Obtener datos cargados en objeto del Modelo
44
const FETCH_MODEL = 'model';
47
* Obtener datos cargados en objeto
50
const FETCH_OBJ = 'obj';
53
* Obtener datos cargados en array
56
const FETCH_ARRAY = 'array';
59
45
* Conexion a base datos que se utilizara
63
protected $_connection = NULL;
49
protected $_connection = null;
66
51
* Tabla origen de datos
70
protected $_table = NULL;
55
protected $_table = null;
77
protected $_schema = NULL;
61
protected $_schema = null;
80
63
* Objeto DbQuery para implementar chain
84
67
protected $_dbQuery = NULL;
87
* Posicion en el iterador
91
private $_pointer = 0;
68
private $_pointer = 0;
94
70
* ResulSet PDOStatement
98
protected $_resultSet = NULL;
101
* Modo de obtener datos
105
protected $_fetchMode = self::FETCH_MODEL;
74
private $_resultSet = NULL;
108
76
* Constructor de la class
111
public function __construct ($data = NULL)
78
public function __constructor ($data = null)
113
80
if (is_array($data)) {
119
* Carga el array como atributos del objeto
123
public function dump($data)
125
foreach ($data as $k => $v) {
131
* Callback antes de crear
135
protected function _beforeCreate()
139
* Callback despues de crear
143
protected function _afterCreate()
147
* Callback antes de actualizar
151
protected function _beforeUpdate()
155
* Callback despues de actualizar
159
protected function _afterUpdate()
163
* Modo de obtener datos
165
* @param integer $mode
166
* @return ActiveRecord
168
public function setFetchMode($mode)
170
$this->_fetchMode = $mode;
81
foreach ($data as $k => $v) {
87
* Efectua una busqueda
89
* @param string|array parametros de busqueda
92
public function find ()
95
// nuevo contenedor de consulta
96
$this->_dbQuery = new DbQuery();
97
$this->_dbQuery->select();
101
$this->_dbQuery->table($this->_table);
102
// asigna el esquema si existe
103
if ($this->_schema) {
104
$this->_dbQuery->schema($this->_schema);
106
return $this->findBySql($this->_dbQuery);
108
public function all ()
111
* Devuelve la instancia para realizar chain
115
public function get ()
117
$this->_dbQuery = new DbQuery();
118
return $this->_dbQuery->select();
121
* Efectua una busqueda de una consulta sql
123
* @param string | DbQuery $sql
126
public function findBySql ($sql)
128
$bind = $sql->getBind();
129
// carga el adaptador especifico para la conexion
130
$adapter = DbAdapter::factory($this->_connection);
131
// si no es un string, entonces es DbQuery
132
if (! is_string($sql)) {
133
$sql = $adapter->query($sql);
135
// ejecuta la consulta
136
$this->_resultSet = $adapter->pdo()->prepare($sql);
137
if ($this->_resultSet->execute($bind)) {
143
* Ejecuta una setencia SQL aplicando Prepared Statement
145
* @param string $sql Setencia SQL
146
* @param array $params parametros que seran enlazados al SQL
149
public function sql ($sql, $params = NULL)
151
// carga el adaptador especifico para la conexion
152
$adapter = DbAdapter::factory($this->_connection);
153
$this->_resultSet = $adapter->pdo()->prepare($sql);
154
if ($this->_resultSet->execute($params)) {
160
* Realiza un insert sobre la tabla
162
* @param array $data información a ser guardada
165
public function insert ($data = null)
167
// nuevo contenedor de consulta
168
$dbQuery = new DbQuery();
170
$dbQuery->table($this->_table);
171
// asigna el esquema si existe
172
if ($this->_schema) {
173
$dbQuery->schema($this->_schema);
175
$dbQuery->insert($data);
176
$adapter = DbAdapter::factory($this->_connection);
178
$prepare = $adapter->pdo()->prepare($adapter->query($dbQuery));
179
return $prepare->execute($data);
180
} catch (PDOException $e) { //echo $prepare->errorCode();die;
187
* @param string Class
190
public function fetchObject ()
192
$this->_resultSet->setFetchMode(PDO::FETCH_INTO, $this);
193
return $this->_resultSet->fetch();
175
196
* reset result set pointer
176
197
* (implementation required by 'rewind()' method in Iterator interface)
219
236
return $this->_pointer < $this->_resultSet->rowCount();
223
* Indica el modo de obtener datos al ResultSet actual
226
protected function _fetchMode($fetchMode = NULL)
228
// Si no se especifica toma el por defecto
230
$fetchMode = $this->_fetchMode;
233
switch ($fetchMode) {
234
// Obtener instancias del mismo modelo
235
case self::FETCH_MODEL:
236
// Instancias de un nuevo modelo, por lo tanto libre de los atributos de la instancia actual
237
$this->_resultSet->setFetchMode(PDO::FETCH_INTO, new self());
240
// Obtener instancias de objetos simples
241
case self::FETCH_OBJ:
242
$this->_resultSet->setFetchMode(PDO::FETCH_OBJ);
246
case self::FETCH_ARRAY:
247
$this->_resultSet->setFetchMode(PDO::FETCH_ASSOC);
253
* Asigna la tabla fuente de datos
255
* @param string $table
256
* @return ActiveRecord
258
public function setTable($table)
260
$this->_table = $table;
265
* Obtiene la tabla fuente de datos
269
public function getTable()
273
$this->_table = Util::smallcase(get_class($this));
277
return $this->_table;
283
* @param string $schema
284
* @return ActiveRecord
286
public function setSchema($schema)
288
$this->_schema = $schema;
297
public function getSchema()
299
return $this->_schema;
305
* @param string $conn
306
* @return ActiveRecord
308
public function setConnection($conn)
310
$this->_connection = $conn;
315
* Obtiene la conexion
319
public function getConnection()
321
return $this->_connection;
325
* Ejecuta una setencia SQL aplicando Prepared Statement
327
* @param string $sql Setencia SQL
328
* @param array $params parametros que seran enlazados al SQL
329
* @param string $fetchMode
330
* @return ActiveRecord
332
public function sql ($sql, $params = NULL, $fetchMode = NULL)
335
// Obtiene una instancia del adaptador y prepara la consulta
336
$this->_resultSet = DbAdapter::factory($this->_connection)->prepare($sql);
338
// Indica el modo de obtener los datos en el ResultSet
339
$this->_fetchMode($fetchMode);
341
// Ejecuta la consulta
342
$this->_resultSet->execute($params);
344
} catch (PDOException $e) {
345
// Aqui debemos ir a cada adapter y verificar el código de error SQLSTATE
346
echo $this->_resultSet->errorCode();
353
* Ejecuta una consulta de dbQuery
355
* @param DbQuery $dbQuery Objeto de consulta
356
* @param string $fetchMode
357
* @return ActiveRecord
359
public function query($dbQuery, $fetchMode = NULL)
361
$dbQuery->table($this->getTable());
363
// Asigna el esquema si existe
364
if ($this->_schema) {
365
$dbQuery->schema($this->_schema);
369
// Obtiene una instancia del adaptador y prepara la consulta
370
$this->_resultSet = DbAdapter::factory($this->_connection)->prepareDbQuery($dbQuery);
372
// Indica el modo de obtener los datos en el ResultSet
373
$this->_fetchMode($fetchMode);
375
// Ejecuta la consulta
376
$this->_resultSet->execute($dbQuery->getBind());
378
} catch (PDOException $e) {
379
// Aqui debemos ir a cada adapter y verificar el código de error SQLSTATE
380
echo $this->_resultSet->errorCode();
385
* Devuelve la instancia para realizar chain
389
public function get ()
391
// Crea la instancia de DbQuery
392
$this->_dbQuery = new DbQuery();
394
return $this->_dbQuery;
398
* Efectua una busqueda
400
* @param string $fetchMode
401
* @return ActiveRecord
403
public function find ($fetchMode = NULL)
405
if (! $this->_dbQuery) {
408
return $this->query($this->_dbQuery->select(), $fetchMode);
412
* Obtiene un array con los items resultantes de la busqueda
414
* @param string $fetchMode
417
public function all ($fetchMode = NULL)
419
return $this->find($fetchMode)->_resultSet->fetchAll();
423
* Obtiene el primer elemento de la busqueda
425
* @param string $fetchMode
426
* @return ActiveRecord
428
public function first ($fetchMode = NULL)
430
if (! $this->_dbQuery) {
434
// Realiza la busqueda y retorna el objeto ActiveRecord
435
return $this->query($this->_dbQuery->select()->limit(1)->offset(0), $fetchMode)->_resultSet->fetch();
439
* Busca por medio de una columna especifica
441
* @param string $column columna de busqueda
442
* @param string $value valor para la busqueda
443
* @param string $fetchMode
444
* @return ActiveRecord
446
public function findBy($column, $value, $fetchMode = NULL)
448
$this->get()->where("$column = :value")->bindValue('value', $value);
449
return $this->first($fetchMode);
453
* Busca por medio de una columna especifica y obtiene todas la coincidencias
455
* @param string $column columna de busqueda
456
* @param string $value valor para la busqueda
457
* @param string $fetchMode
458
* @return ActiveRecord
460
public function findAllBy($column, $value, $fetchMode = NULL)
462
$this->get()->where("$column = :value")->bindValue('value', $value);
463
return $this->find($fetchMode);
467
* Obtiene la clave primaria
471
public function getPK()
473
return DbAdapter::factory($this->_connection)->describe($this->getTable(), $this->_schema)->getPK();
477
* Buscar por medio de la clave primaria
479
* @param string $value
480
* @param string $fetchMode
481
* @return ActiveRecord
483
public function findByPK($value, $fetchMode = NULL)
485
return $this->findBy($this->getPK(), $value, $fetchMode);
489
* Obtiene un array de los atributos que corresponden a columnas
494
private function _getTableValues()
498
// Itera en cada atributo
499
foreach(DbAdapter::factory($this->_connection)
500
->describe($this->getTable(), $this->_schema)
501
->getAttributesList() as $attr) {
503
if(property_exists($this, $attr)) {
504
if($this->$attr === '') {
507
$data[$attr] = $this->$attr;
518
* Realiza un insert sobre la tabla
520
* @param array $data información a ser guardada
521
* @return ActiveRecord
523
public function create ($data = NULL)
525
// Si es un array, se cargan los atributos en el objeto
526
if (is_array($data)) {
530
// @see ActiveRecordValidator
531
require_once CORE_PATH . 'libs/ActiveRecord/active_record2/active_record_validator.php';
533
// Ejecuta la validacion
534
if(ActiveRecordValidator::validateOnCreate($this) === FALSE) {
538
// Callback antes de crear
539
if($this->_beforeCreate() === FALSE) {
543
// Nuevo contenedor de consulta
544
$dbQuery = new DbQuery();
546
// Ejecuta la consulta
547
if($this->query($dbQuery->insert($this->_getTableValues()))) {
548
// Callback despues de crear
549
$this->_afterCreate();
557
* Realiza un update sobre la tabla
559
* @param array $data información a ser guardada
562
public function updateAll ($data)
564
if (! $this->_dbQuery) {
568
// Ejecuta la consulta
569
return $this->query($this->_dbQuery->update($data));
573
* Realiza un delete sobre la tabla
577
public function deleteAll ()
579
if (! $this->_dbQuery) {
583
// Ejecuta la consulta
584
return $this->query($this->_dbQuery->delete());
592
public function validators()
596
* Cuenta las apariciones de filas
598
* @param string $column
601
public function count($column = '*')
603
if (! $this->_dbQuery) {
607
$this->_dbQuery->columns("COUNT($column) AS n");
608
return $this->first(self::FETCH_OBJ)->n;
612
* Verifica si existe al menos una fila con las condiciones indicadas
616
public function existsOne()
618
return $this->count() > 0;
622
* Establece condicion de busqueda con clave primaria
624
* @param DbQuery $dbQuery
626
protected function _wherePK($dbQuery)
628
// Obtiene la clave primaria
629
$pk = $this->getPK();
631
// Si es clave primaria compuesta
634
if(!isset($this->$k)) {
635
throw new KumbiaException("Debe definir valor para la columna $k de la clave primaria");
638
$dbQuery->where("$k = :pk_$k")->bindValue("pk_$k", $this->$k);
641
if(!isset($this->$pk)) {
642
throw new KumbiaException("Debe definir valor para la clave primaria");
645
$dbQuery->where("$pk = :pk_$pk")->bindValue("pk_$pk", $this->$pk);
650
* Verifica si esta persistente en la BD el objeto actual en la bd
654
public function exists()
656
// Objeto de consulta
657
$dbQuery = $this->get();
659
// Establece condicion de busqueda con clave primaria
660
$this->_wherePK($dbQuery);
662
return $this->existsOne();
666
* Realiza un update del registro sobre la tabla
668
* @param array $data información a ser guardada
671
public function update($data = NULL)
673
// Si es un array, se cargan los atributos en el objeto
674
if (is_array($data)) {
678
// @see ActiveRecordValidator
679
require_once CORE_PATH . 'libs/ActiveRecord/active_record2/active_record_validator.php';
681
// Ejecuta la validacion
682
if(ActiveRecordValidator::validateOnUpdate($this) === FALSE) {
686
// Callback antes de actualizar
687
if($this->_beforeUpdate() === FALSE) {
691
// Si no existe el registro
692
if(!$this->exists()) {
696
// Objeto de consulta
697
$dbQuery = new DbQuery();
698
// Establece condicion de busqueda con clave primaria
699
$this->_wherePK($dbQuery);
701
// Ejecuta la consulta con el query utilizado para el exists
702
if($this->query($dbQuery->update($this->_getTableValues()))) {
703
// Callback despues de actualizar
704
$this->_afterUpdate();