A Web App Based on a Model for the CodeIgniter PHP Framework - Review: the generic model class’s complete source code (Page 2 of 4 )
Before I proceed to demonstrate how to use the generic model class as part of a real estate web application, I will list the class's full source code. Here’s the entire signature of the model, including the corresponding comments for each of its methods:
<?php if (!defined('BASEPATH')) exit('No direct script access allowed');
/**
* CodeIgniter
*
* An open source application development framework for PHP 4.3.2 or newer
*
* @package CodeIgniter
* @author ExpressionEngine Dev Team
* @copyright Copyright (c) 2006, EllisLab, Inc.
* @license http://codeigniter.com/user_guide/license.html
* @link http://codeigniter.com
* @since Version 1.0
* @filesource
*/
// ------------------------------------------------------------------------
/**
* CodeIgniter Abstract Model Class
*
* @package CodeIgniter
* @subpackage Libraries
* @category Libraries
* @author ExpressionEngine Dev Team
* @link http://codeigniter.com/user_guide/libraries/config.html
*/
abstract class MY_Model extends Model
{
protected $table = ''; // table associated to the model
protected $fields = array(); // fields of table associated to the model
protected $id = NULL; // value of the primary key of the table associated to the model
protected $data = array(); // model input data
protected $insertID = NULL; // insertion ID
protected $numRows = NULL; // number of rows returned by SELECTS
protected $validation = array(); // model validation rules
protected $errors = array(); // model errors
/**
* Constructor
*
* @access protected
*/
protected function __construct()
{
parent::Model();
// get CI superobject as a model property
$this->ci =& get_instance();
}
/**
* Sets associated table data for the model
*
* @author Alejandro Gervasio
* @return void
* @access public
*/
public function setTableData($table = 'default')
{
if ($this->db->table_exists($table))
{
$this->table = $table;
$this->fields = $this->db->field_names($this->table);
}
}
/**
* Sets value of primary key of the associated table for the model
*
* @author Alejandro Gervasio
* @param integer
* @return void
* @access public
*/
public function setID($id)
{
$this->id = is_integer($id) AND $id > 0 ? $id : 1;
}
/**
* Gets value of primary key of the associated table for the model
*
* @author Alejandro Gervasio
* @return integer
* @access public
*/
public function getID()
{
return $this->id;
}
/** sets input data for the model
*
* @author Alejandro Gervasio
* @param array
* @return void
* @access public
*/
public function setData($data)
{
if ( is_array($data) AND count($data) > 0)
{
foreach ($data as $key => $value)
{
if (array_search($key, $this->fields) === FALSE)
{
unset($data[$key]);
}
}
$this->data = $data;
}
}
/**
* Sets validation rules for model data
*
* @author Alejandro Gervasio
* @param array
* @return void
* @access public
*/
public function setValidation($validation)
{
if ( is_array($validation) AND count($validation) > 0)
{
foreach ($validation as $field => $rule)
{
if (array_search($field, $this->fields) === FALSE)
{
unset($validation[$key]);
}
}
$this->validation = $validation;
}
}
/**
* Returns a result set with specified fields according to given conditions.
*
* @author Alejandro Gervasio
* @return query result on success - Boolean FALSE on failure
* @access public
*/
public function fetch($fields = '*', $where = NULL, $order = 'id ASC', $limit = NULL, $offset = 0, $join = NULL)
{
if ($fields != '*')
{
$this->db->select($fields);
}
if ($this->id != NULL)
{
$this->db->where('id', $this->id);
}
elseif($where != NULL)
{
$this->db->where($where);
}
if ($order != 'id ASC')
{
$this->db->orderby($order);
}
if ($limit != NULL)
{
$this->db->limit($limit, $offset);
}
if( $join != NULL)
{
$this->db->join($join);
}
$query = $this->db->get($this->table);
$this->numRows = $query->num_rows();
if ($this->numRows > 0)
{
return ($this->numRows > 1 ) ? $query->result() : $query->row();
}
$this->errors[] ='No rows were returned by the query.';
return FALSE;
}
/** Saves model data into associated table (validation rules are applied to input data)
*
*
* @author Alejandro Gervasio
* @return integer on success - Boolean FALSE on failure
* @access public
*/
public function save()
{
if ($this->data == NULL)
{
$this->errors[] = 'Error saving row.';
return FALSE;
}
// validate input data
if( !$this->validate())
{
return FALSE;
}
// Insert new row if ID was not set in the model
if ($this->id == NULL)
{
$this->db->insert($this->table, $this->data);
$this->insertID = $this->db->insert_id();
return $this->insertID;
}
// Otherwise update existing row
else
{
$this->db->where('id', $this->id)->update($this->table, $this->data);
return $this->db->affected_rows();
}
}
/** Deletes model data from associated table (validation rules are applied to input data)
*
*
* @author Alejandro Gervasio
* @return Boolean TRUE on success - Boolean FALSE on failure
* @access public
*/
public function delete()
{
if ($this->id == NULL)
{
$this->errors[] = 'Error deleting row.';
return FALSE;
}
$this->db->where('id', $this->id)->delete($this->table);
return TRUE;
}
/**
* Counts all rows in associated table
*
* @author Alejandro Gervasio
* @return integer (if the associated table is not empty)
* @access public
*/
public function countAll()
{
return $this->db->count_all($this->table);
}
/**
* Gets insertion ID
*
* @author alejandro gervasio
* @return integer
* @access public
*/
public function getInsertID()
{
return $this->insertID;
}
/**
* Executes a given query
*
* @author Alejandro Gervasio
* @param string
* @return result set/Boolean TRUE on success - Boolean FALSE on failure
* @access public
*/
public function query($query)
{
if (is_string($query))
{
if (FALSE === ($query = $this->db->query($query)))
{
$this->errors[] = 'Error performing query.';
}
return $query;
}
}
/**
* Gets number of rows returned by fetch() method
*
* @author Alejandro Gervasio
* @return integer
* @access public
*/
public function getNumRows()
{
return $this->numRows;
}
/** Gets insertion ID
*
* @author Alejandro Gervasio
* @return integer
* @access public
*/
public function getInsertID()
{
return $this->insertID;
}
/**
* Gets model errors
*
* @author Alejandro Gervasio
* @param string
* @return string
* @access public
*/
public function getErrors($errPrefix = '<p>')
{
// if no errors where found return an empty string
if( count($this->errors) === 0)
{
return '';
}
// otherwise build and return error string
$errorString = '';
$errorSufix = str_replace( '<', '</' , $errPrefix);
foreach ($this->errors as $error)
{
$errorString .= $errPrefix . $error . $errorSufix;
}
return $errorString;
}
/**
* Clears model properties
*
* @author Alejandro Gervasio
* @return void
* @access public
*/
public function clear()
{
$this->id = NULL;
$this->data = array();
$this->errors = array();
$this->validation = array();
}
/**
* Validates model input data
*
* @author Alejandro Gervasio
* @return Boolean TRUE on success - FALSE on failure
* @access protected
*/
protected function validate()
{
// If no validation rules or no model were provided data set appropiate error
if (count($this->validation) === 0)
{
$this->errors[] = 'No validation rules were set for the model.';
return FALSE;
}
// Loads CI validation library
$this->ci->load->library('validation');
// Load CI language file for validation
$this->ci->lang->load('validation');
// resets error messages
$this->errors = array();
foreach ($this->validation as $field => $rules)
{
$expRules = explode('|', $rules);
// if the field is not required check next one
if (! in_array('required', $expRules, TRUE))
{
continue;
}
// Iterates through the validation rules
foreach ($expRules as $rule)
{
// Removes the parameter from the rule (when specified)
$param = FALSE;
if (preg_match("/(.*?)\[(.*?)\]/", $rule, $match))
{
$rule = $match[1];
$param = $match[2];
}
// Calls the validation method that corresponds to the rule
if (method_exists($this->ci->validation, $rule))
{
$result = $this->ci->validation->$rule($this->data[$field], $param);
}
else
{
// Tries to run a native PHP function if method of CI validation class doesn't exist
if (function_exists($rule))
{
$result = $rule($this->data[$field]);
}
}
// if an offending field was found store error message in error array
if ($result === FALSE)
{
$this->errors[] = sprintf($this->ci->lang->line($rule),$field);
}
}
}
return (count($this->errors)) === 0 ? TRUE : FALSE;
}
}
// END MY_Model Class
/* End of file MY_Model.php */
/* Location: ./system/application/libraries/MY_Model.php */
Now that you hopefully recalled how the above “AbstractModel” class looks, as well as how it works in general, it’s time to see how it can be used in the context of a simple, yet illustrative, example. As I anticipated in the introduction, the next step that I’m going to take will be creating a sub class from the model, called “Property_model,” which naturally will inherit all of the functionality of its parent and also will be suited to performing CRUD operations against a sample MySQL database table containing some fictional properties. In this way we'll build a simple real estate web application.
In order to learn how this child model class will be defined, you’ll have to click on the link below and read the following section.
Next: Inheriting the functionality of the abstract model class >>
More Miscellaneous Code Articles More By Alejandros Gervasio
Please enable JavaScript to view the comments powered by Disqus. blog comments powered by