├── README.markdown └── lib └── MY_Model.php /README.markdown: -------------------------------------------------------------------------------- 1 | # CodeIgniter Base Model 2 | 3 | Here is the base model that I use on all of my CodeIgniter projects. This provides all of the basic CRUD functionality I need just by extending my models to the MY_Model class and defining a few variables: 4 | 5 | ```php 6 | class Company_model extends MY_Model { 7 | 8 | var $primary_table = 'companies'; 9 | 10 | var $validate_field_existence = TRUE; 11 | 12 | var $fields = array( 13 | 'id', 14 | 'name', 15 | 'address', 16 | 'city', 17 | 'state', 18 | 'zipcode', 19 | 'phone', 20 | 'is_active', 21 | 'date_created', 22 | 'date_modified' 23 | ); 24 | 25 | var $required_fields = array( 26 | 'name', 27 | 'address', 28 | 'city', 29 | 'state', 30 | 'zipcode', 31 | 'phone' 32 | ); 33 | 34 | } 35 | ``` 36 | 37 | * **primary_table** - The name of the table the model should execute queries on. 38 | * **validate_field_existence** - Set to true to turn on field existence validation. 39 | * **fields** - An array of the fields in the database that the model has access to. If you don't specify the fields here they will be pulled dynamically from the database and the query will be cached. 40 | * **required_fields** An array of fields that must be submitted any time a record is created or updated. 41 | 42 | Inserting records works like this: 43 | 44 | ```php 45 | // put all form data into an array 46 | $options = array( 47 | 'name' => $this->input->post('company_name'), 48 | 'address' => $this->input->post('company_address'), 49 | 'city' => $this->input->post('company_city'), 50 | 'state' => $this->input->post('company_state'), 51 | 'zipcode' => $this->input->post('company_zip'), 52 | 'phone' => $this->input->post('company_phone'), 53 | 'is_active' => $this->input->post('company_is_active') 54 | ); 55 | // send the array to the model 56 | $company = $this->company_model->add($options); 57 | ``` 58 | 59 | When selecting records, you can filter by any field specified in the fields array of the model: 60 | 61 | ```php 62 | $options = array( 63 | 'name' => $this->input->post('search_name'), 64 | 'zipcode' => $this->input->post('search_zipcode') 65 | ); 66 | $company = $this->company_model->get($options); 67 | ``` 68 | If you specify the primary key, the model knows you are looking for a single record and will return the object rather than the query result. 69 | 70 | This model is based on a model by Shawn McCool from his article [How To Write A Better Model In CodeIgniter](http://heybigname.com/2009/08/28/how-to-write-a-better-model-in-code-igniter/). It has worked out pretty well for me so far but I would love to get some feedback from the community and see if anyone has ideas for improvements or if they have a base model that they enjoy working with. 71 | -------------------------------------------------------------------------------- /lib/MY_Model.php: -------------------------------------------------------------------------------- 1 | models)) 59 | { 60 | foreach ($this->models as $model) 61 | { 62 | $this->load->model($model); 63 | } 64 | } 65 | } 66 | 67 | /** 68 | * add method creates a record in the table. 69 | * 70 | * Options: array of fields available 71 | * 72 | * @param array $options 73 | * @return int ID on success, bool false on fail 74 | */ 75 | function add($options = array()) 76 | { 77 | if ( ! $this->_required($this->required_fields, $options)) 78 | { 79 | return FALSE; 80 | } 81 | 82 | $this->_set_editable_fields($this->primary_table); 83 | 84 | $this->_validate_options_exist($options); 85 | 86 | $default = array( 87 | 'date_created' => date($this->config->item('log_date_format')), 88 | 'date_modified' => date($this->config->item('log_date_format')) 89 | ); 90 | $options = $this->_default($default, $options); 91 | 92 | // qualification (make sure that we're not allowing the site to insert data that it shouldn't) 93 | foreach ($this->fields as $field) 94 | { 95 | if (isset($options[$field])) 96 | { 97 | $this->db->set($field, $options[$field]); 98 | } 99 | } 100 | 101 | $query = $this->db->insert($this->primary_table); 102 | 103 | if ($query) 104 | { 105 | if ($this->no_primary_key == FALSE) 106 | { 107 | return $this->db->insert_id(); 108 | } 109 | else 110 | { 111 | return TRUE; 112 | } 113 | } 114 | } 115 | 116 | /** 117 | * get method returns an array of qualified record objects 118 | * 119 | * Option: Values 120 | * 121 | * Returns (array of objects) 122 | * 123 | * @param array $options 124 | * @return array result() 125 | */ 126 | function get($options = array()) 127 | { 128 | // set an array for field querys and values 129 | // This allows gets with operators 130 | // $options = array('status >' => 5) 131 | $option_fields = array(); 132 | foreach($options as $key => $value) 133 | { 134 | $parts = explode(' ', $key, 2); 135 | 136 | $field = isset($parts[0]) ? $parts[0] : ''; 137 | $operator = isset($parts[1]) ? $parts[1] : ''; 138 | 139 | $option_fields[$field]['query'] = $key; 140 | $option_fields[$field]['value'] = $value; 141 | } 142 | 143 | $defaults = array( 144 | 'sort_direction' => 'asc' 145 | ); 146 | $options = $this->_default($defaults, $options); 147 | 148 | $this->_set_editable_fields($this->primary_table); 149 | 150 | foreach ($this->fields as $field) 151 | { 152 | if (isset($option_fields[$field])) 153 | { 154 | $this->db->where($option_fields[$field]['query'], $option_fields[$field]['value']); 155 | } 156 | } 157 | 158 | if (isset($options['limit']) && isset($options['offset'])) 159 | { 160 | $this->db->limit($options['limit'], $options['offset']); 161 | } 162 | else 163 | { 164 | if (isset($options['limit'])) 165 | { 166 | $this->db->limit($options['limit']); 167 | } 168 | } 169 | 170 | if (isset($options['sort_by'])) 171 | { 172 | $this->db->order_by($options['sort_by'], $options['sort_direction']); 173 | } 174 | 175 | $query = $this->db->get($this->primary_table); 176 | 177 | // if an id was specified we know you only are retrieving a single record so we return the object 178 | if (isset($options[$this->primary_key])) 179 | { 180 | return $query->row(); 181 | } 182 | else 183 | { 184 | return $query; 185 | } 186 | } 187 | 188 | /** 189 | * update method alters a record in the table. 190 | * 191 | * Option: Values 192 | * 193 | * @param array $options 194 | * @return int affected_rows() 195 | */ 196 | function update($options = array()) 197 | { 198 | $required = array($this->primary_key); 199 | if ( ! $this->_required($required, $options)) 200 | { 201 | return FALSE; 202 | } 203 | 204 | $this->_set_editable_fields($this->primary_table); 205 | 206 | $this->_validate_options_exist($options); 207 | 208 | $default = array( 209 | 'date_modified' => date($this->config->item('log_date_format')) 210 | ); 211 | $options = $this->_default($default, $options); 212 | 213 | // qualification (make sure that we're not allowing the site to insert data that it shouldn't) 214 | foreach ($this->fields as $field) 215 | { 216 | if (isset($options[$field])) 217 | { 218 | $this->db->set($field, $options[$field]); 219 | } 220 | } 221 | 222 | $this->db->where($this->primary_key, $options[$this->primary_key]); 223 | 224 | $this->db->update($this->primary_table); 225 | 226 | return $this->db->affected_rows(); 227 | } 228 | 229 | /** 230 | * delete method removes a record from the table 231 | * 232 | * Option: Values 233 | * -------------- 234 | * id (required) 235 | * 236 | * @param array $options 237 | */ 238 | function delete($options = array()) 239 | { 240 | $required = array($this->primary_key); 241 | if ( ! $this->_required($required, $options)) 242 | { 243 | return FALSE; 244 | } 245 | 246 | $this->db->where($this->primary_key, $options[$this->primary_key]); 247 | return $this->db->delete($this->primary_table); 248 | } 249 | 250 | /** 251 | * Validates that the fields you are trying to modify actually exist in the database 252 | * 253 | * Only use this method for debugging, not fit for production code because of the number of queries it has to run 254 | * 255 | * @param string $options 256 | * @return void 257 | */ 258 | function _validate_options_exist($options) 259 | { 260 | if ($this->validate_field_existence == TRUE) 261 | { 262 | foreach ($options as $key => $value) 263 | { 264 | $parts = explode(' ', $key); 265 | $field = $parts[1]; 266 | 267 | if ( ! $this->db->field_exists($field, $this->primary_table)) 268 | { 269 | show_error('You are trying to insert data into a field that does not exist. The field "'. $field .'" does not exist in the "'. $this->primary_table .'" table.'); 270 | } 271 | } 272 | } 273 | } 274 | 275 | /** 276 | * set editable fields in the table, if no fields are specified in the model, fields will be pulled dynamically from the table 277 | * 278 | * @return void 279 | */ 280 | function _set_editable_fields() 281 | { 282 | if (empty($this->fields)) 283 | { 284 | // pull the fields dynamically from the database 285 | $this->db->cache_on(); 286 | $this->fields = $this->db->list_fields($this->primary_table); 287 | $this->db->cache_off(); 288 | } 289 | } 290 | 291 | /** 292 | * _required method returns false if the $data array does not contain all of the keys assigned by the $required array. 293 | * 294 | * @param array $required 295 | * @param array $data 296 | * @return bool 297 | */ 298 | function _required($required, $data) 299 | { 300 | foreach ($required as $field) 301 | { 302 | if ( ! isset($data[$field])) 303 | { 304 | return FALSE; 305 | } 306 | } 307 | return TRUE; 308 | } 309 | 310 | /** 311 | * _default method combines the options array with a set of defaults giving the values in the options array priority. 312 | * 313 | * @param array $defaults 314 | * @param array $options 315 | * @return array 316 | */ 317 | function _default($defaults, $options) 318 | { 319 | return array_merge($defaults, $options); 320 | } 321 | } --------------------------------------------------------------------------------