/** * Saves Information on the ActiveRecord Properties * @param array $values array de valores a cargar * @return boolean success */ public function save($values = null) { if ($values) { if (!is_array($values)) { $values = Util::getParams(func_get_args()); } foreach ($this->fields as $field) { if (isset($values[$field])) { $this->{$field} = $values[$field]; } } } $ex = $this->exists(); if ($this->schema) { $table = $this->schema . "." . $this->source; } else { $table = $this->source; } #Run Validation Callbacks Before if (method_exists($this, 'before_validation')) { if ($this->before_validation() == 'cancel') { return false; } } else { if (isset($this->before_validation)) { $method = $this->before_validation; if ($this->{$method}() == 'cancel') { return false; } } } if (!$ex) { if (method_exists($this, "before_validation_on_create")) { if ($this->before_validation_on_create() == 'cancel') { return false; } } else { if (isset($this->before_validation_on_create)) { $method = $this->before_validation_on_create; if ($this->{$method}() == 'cancel') { return false; } } } } if ($ex) { if (method_exists($this, "before_validation_on_update")) { if ($this->before_validation_on_update() == 'cancel') { return false; } } else { if (isset($this->before_validation_on_update)) { $method = $this->before_validation_on_update; if ($this->{$method}() == 'cancel') { return false; } } } } /** * Validacion validates_presence * */ if (isset($this->_validates['presence_of'])) { foreach ($this->_validates['presence_of'] as $f => $opt) { if (isset($this->{$f}) && (is_null($this->{$f}) || $this->{$f} == '')) { if (!$ex && $f == $this->primary_key[0]) { continue; } if (isset($opt['message'])) { Flash::error($opt['message']); return false; } else { $field = isset($opt['field']) ? $opt['field'] : $f; Flash::error("Error: El campo {$field} no puede ser nulo"); return false; } } } } /** * Recordamos que aqui no aparecen los que tienen valores por defecto, * pero sin embargo se debe estar pendiente de validar en las otras verificaciones * los campos nulos, ya que en estas si el campo es nulo, realmente se refiere a un campo que * debe tomar el valor por defecto * */ foreach ($this->not_null as $f) { if (in_array($f, $this->_with_default)) { continue; } if (!isset($this->{$f}) || is_null($this->{$f}) || $this->{$f} == '') { if (!$ex && $f == $this->primary_key[0]) { continue; } if (!$ex && in_array($f, $this->_at)) { continue; } if ($ex && in_array($f, $this->_in)) { continue; } Flash::error("Error: El campo {$f} no puede ser nulo"); return false; } } /** * Validacion validates_length * */ if (isset($this->_validates['length_of'])) { foreach ($this->_validates['length_of'] as $f => $opt) { if (isset($this->{$f}) && !is_null($this->{$f}) && $this->{$f} != '') { $field = isset($opt['field']) ? $opt['field'] : $f; if (strlen($this->{$f}) < $opt['min']) { if (isset($opt['too_short'])) { Flash::error($opt['too_short']); } else { Flash::error("Error: El campo {$field} debe tener como mínimo {$opt['min']} caracteres"); } return false; } if (strlen($this->{$f}) > $opt['max']) { if (isset($opt['too_long'])) { Flash::error($opt['too_long']); } else { Flash::error("Error: El campo {$field} debe tener como máximo {$opt['max']} caracteres"); } return false; } } } } /** * Validacion validates_inclusion * */ foreach ($this->_validates['inclusion_in'] as $f => $opt) { if (isset($this->{$f}) && !is_null($this->{$f}) && $this->{$f} != '') { if (!in_array($this->{$f}, $opt['list'])) { if (isset($opt['message'])) { Flash::error($opt['message']); } else { $field = isset($opt['field']) ? $opt['field'] : $f; Flash::error("{$field} debe tener un valor entre (" . join(",", $opt['list']) . ")"); } return false; } } } /** * Validacion validates_exclusion * */ foreach ($this->_validates['exclusion_of'] as $f => $opt) { if (isset($this->{$f}) && !is_null($this->{$f}) && $this->{$f} != '') { if (in_array($this->{$f}, $opt['list'])) { if (isset($opt['message'])) { Flash::error($opt['message']); } else { $field = isset($opt['field']) ? $opt['field'] : $f; Flash::error("{$field} no debe tener un valor entre (" . join(",", $opt['list']) . ")"); } return false; } } } /** * Validacion validates_numericality * */ foreach ($this->_validates['numericality_of'] as $f => $opt) { if (isset($this->{$f}) && !is_null($this->{$f}) && $this->{$f} != '') { if (!is_numeric($this->{$f})) { if (isset($opt['message'])) { Flash::error($opt['message']); } else { $field = isset($opt['field']) ? $opt['field'] : $f; Flash::error("{$field} debe tener un valor numérico"); } return false; } } } /** * Validacion validates_format * */ foreach ($this->_validates['format_of'] as $f => $opt) { if (isset($this->{$f}) && !is_null($this->{$f}) && $this->{$f} != '') { if (!filter_var($this->{$f}, FILTER_VALIDATE_REGEXP, array("options" => array("regexp" => $opt['pattern'])))) { if (isset($opt['message'])) { Flash::error($opt['message']); } else { $field = isset($opt['field']) ? $opt['field'] : $f; Flash::error("Formato erroneo para {$field}"); } return false; } } } /** * Validacion validates_date * */ foreach ($this->_validates['date_in'] as $f => $opt) { if (isset($this->{$f}) && !is_null($this->{$f}) && $this->{$f} != '') { 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])\$/")))) { if (isset($opt['message'])) { Flash::error($opt['message']); } else { $field = isset($opt['field']) ? $opt['field'] : $f; Flash::error("Formato de fecha erroneo para {$field}"); } return false; } } } /** * Validacion validates_email * */ foreach ($this->_validates['email_in'] as $f => $opt) { if (isset($this->{$f}) && !is_null($this->{$f}) && $this->{$f} != '') { if (!filter_var($this->{$f}, FILTER_VALIDATE_EMAIL)) { if (isset($opt['message'])) { Flash::error($opt['message']); } else { $field = isset($opt['field']) ? $opt['field'] : $f; Flash::error("Formato de e-mail erroneo en el campo {$field}"); } return false; } } } /** * Validacion validates_uniqueness * */ // parche para que no tome encuenta el propio registro // al validar campos unicos, ya que si lo toma en cuenta // lanzará error de validacion porque ya existe un registro // con igual valor en el campo unico. $and_condition = $ex ? " AND {$this->primary_key[0]} != '{$this->{$this->primary_key[0]}}'" : ''; foreach ($this->_validates['uniqueness_of'] as $f => $opt) { if (isset($this->{$f}) && !is_null($this->{$f}) && $this->{$f} != '') { $result = $this->db->fetch_one("SELECT COUNT(*) FROM {$table} WHERE {$f} = {$this->db->add_quotes($this->{$f})} {$and_condition}"); if ($result[0]) { if (isset($opt['message'])) { Flash::error($opt['message']); } else { $field = isset($opt['field']) ? $opt['field'] : $f; Flash::error("El valor '{$this->{$f}}' ya existe para el campo {$field}"); } return false; } } } #Run Validation Callbacks After if (!$ex) { if (method_exists($this, "after_validation_on_create")) { if ($this->after_validation_on_create() == 'cancel') { return false; } } else { if (isset($this->after_validation_on_create)) { $method = $this->after_validation_on_create; if ($this->{$method}() == 'cancel') { return false; } } } } if ($ex) { if (method_exists($this, "after_validation_on_update")) { if ($this->after_validation_on_update() == 'cancel') { return false; } } else { if (isset($this->after_validation_on_update)) { $method = $this->after_validation_on_update; if ($this->{$method}() == 'cancel') { return false; } } } } if (method_exists($this, 'after_validation')) { if ($this->after_validation() == 'cancel') { return false; } } else { if (isset($this->after_validation)) { $method = $this->after_validation; if ($this->{$method}() == 'cancel') { return false; } } } # Run Before Callbacks if (method_exists($this, "before_save")) { if ($this->before_save() == 'cancel') { return false; } } else { if (isset($this->before_save)) { $method = $this->before_save; if ($this->{$method}() == 'cancel') { return false; } } } if ($ex) { if (method_exists($this, "before_update")) { if ($this->before_update() == 'cancel') { return false; } } else { if (isset($this->before_update)) { $method = $this->before_update; if ($this->{$method}() == 'cancel') { return false; } } } } if (!$ex) { if (method_exists($this, "before_create")) { if ($this->before_create() == 'cancel') { return false; } } else { if (isset($this->before_create)) { $method = $this->before_create; if ($this->{$method}() == 'cancel') { return false; } } } } $environment = Config::read('databases'); $config = $environment[$this->get_database()]; if ($ex) { $fields = array(); $values = array(); foreach ($this->non_primary as $np) { $np = ActiveRecord::sql_item_sanizite($np); if (in_array($np, $this->_in)) { if ($config['type'] == 'oracle') { $this->{$np} = date("Y-m-d"); } else { $this->{$np} = date("Y-m-d G:i:s"); } } if (isset($this->{$np})) { $fields[] = $np; if (is_null($this->{$np}) || $this->{$np} == '') { $values[] = 'NULL'; } else { /** * Se debe especificar el formato de fecha en Oracle */ if ($this->_data_type[$np] == 'date' && $config['type'] == 'oracle') { $values[] = "TO_DATE(" . $this->db->add_quotes($this->{$np}) . ", 'YYYY-MM-DD')"; } else { $values[] = $this->db->add_quotes($this->{$np}); } } } } $val = $this->db->update($table, $fields, $values, $this->_where_pk); } else { $fields = array(); $values = array(); foreach ($this->fields as $field) { if ($field != $this->primary_key[0] && !$this->id) { if (in_array($field, $this->_at)) { if ($config['type'] == 'oracle') { $this->{$field} = date("Y-m-d"); } else { $this->{$field} = date("Y-m-d G:i:s"); } } if (in_array($field, $this->_in)) { unset($this->{$field}); } if (isset($this->{$field}) && $this->{$field} !== '' && $this->{$field} !== NULL) { $fields[] = ActiveRecord::sql_sanizite($field); if (($this->_data_type[$field] == 'datetime' || $this->_data_type[$field] == 'date') && $config['type'] == 'mysql') { $values[] = $this->db->add_quotes(date("Y-m-d G:i:s", strtotime($this->{$field}))); } elseif ($this->_data_type[$field] == 'date' && $config['type'] == 'oracle') { //Se debe especificar el formato de fecha en Oracle $values[] = "TO_DATE(" . $this->db->add_quotes($this->{$field}) . ", 'YYYY-MM-DD')"; } else { $values[] = $this->db->add_quotes($this->{$field}); } } elseif (in_array($field, $this->_with_default)) { $fields[] = ActiveRecord::sql_sanizite($field); $values[] = 'DEFAULT'; } else { $fields[] = ActiveRecord::sql_sanizite($field); $values[] = 'NULL'; } } else { /** * Campos autonumericos en Oracle deben utilizar una sequencia auxiliar */ if ($config['type'] == 'oracle') { if (!$this->id) { $fields[] = "id"; $values[] = $this->source . "_id_seq.NEXTVAL"; } } if ($config['type'] == 'informix') { if (!$this->id) { $fields[] = "id"; $values[] = 0; } } } } $val = $this->db->insert($table, $values, $fields); } if (!isset($config['pdo']) && $config['type'] == 'oracle') { $this->commit(); } if (!$ex) { //$this->db->logger = true; $m = $this->db->last_insert_id($table, $this->primary_key[0]); $this->find_first($m); } if ($val) { if ($ex) { if (method_exists($this, "after_update")) { if ($this->after_update() == 'cancel') { return false; } } else { if (isset($this->after_update)) { $method = $this->after_update; if ($this->{$method}() == 'cancel') { return false; } } } } if (!$ex) { if (method_exists($this, "after_create")) { if ($this->after_create() == 'cancel') { return false; } } else { if (isset($this->after_create)) { $method = $this->after_create; if ($this->{$method}() == 'cancel') { return false; } } } } if (method_exists($this, "after_save")) { if ($this->after_save() == 'cancel') { return false; } } else { if (isset($this->after_save)) { $method = $this->after_save; if ($this->{$method}() == 'cancel') { return false; } } } return $val; } else { return false; } }