Perform validation only on create using php-activerecord - php

I am creating a User Model using Codeigniter and php-activerecord and the wiki says I can use 'on' => 'create' to have a validation only run when a new record is created, like this,
static $validates_presence_of = array(
array('title', 'message' => 'cannot be blank on a book!', 'on' => 'create')
);
It also states that we have access to "save", "update" and "delete"...
None of these are working for me though and I can figure out why, here is my code,
// Validations
static $validates_presence_of = array(
array('email', 'message' => 'Please enter a valid email address.'),
array('password', 'message' => 'Password must be provided.', 'on' => 'create')
);
I want to set it up like this so that when a user updates their profile, they can leave their password blank to keep their current one.
I would appreciate any help or guidance! Thanks!

The reason for this is most likely because it's not been implemented.
Relevant classes are lib/Model.php and lib/Validations.php
From a purely abstract standpoint, you would need to track the mode of operation between save and create. To do this, I created a public property (public $validation_mode) within lib/Model.php and set that property to 'create' or 'save' in private methods Model::insert() and Model::update() respectively. These values match the 'on' property you are trying to use.
Then within lib/Validations.php, I modified the following methods:
Validations::validates_presence_of()
public function validates_presence_of($attrs)
{
$configuration = array_merge(self::$DEFAULT_VALIDATION_OPTIONS, array('message' => Errors::$DEFAULT_ERROR_MESSAGES['blank'], 'on' => 'save'));
foreach ($attrs as $attr)
{
$options = array_merge($configuration, $attr);
$this->record->add_on_blank($options[0], $options['message'], $options);
}
}
Errors::add_on_blank()
public function add_on_blank($attribute, $msg, $options = array())
{
if (!$msg)
$msg = self::$DEFAULT_ERROR_MESSAGES['blank'];
if (($value = $this->model->$attribute) === '' || $value === null)
{
if(array_key_exists('on', $options))
{
if($options['on'] == $this->model->validation_mode)
{
$this->add($attribute, $msg);
}
} else {
$this->add($attribute, $msg);
}
}
}
What this does basically is passes ALL the $options specified in your model (including the 'on' property) down to the Errors::add_on_blank() method where it now has enough information to differentiate between 'on' => 'create' and the default ('on' => 'save'). Using the public $validation_mode property from the Model class ($this->model->validation_mode), we can determine what the current mode of operation is and whether or not we wish to continue adding the error message or skip it this time around.
Obviously you would want to document any changes you make and test thoroughly. According to the documentation, all validation methods supposedly support this "common option" along side allow_null, allow_blank but again, if it's not implemented, you will have to make it happen yourself by making these necessary changes.

should be call the validation method like this:
#example
$your_obj = new Instace();
if($your_obj->is_valid()) {
// if all is correct your logical code
}
else {
// your logical to show the error messages
}
//doesnt work if you write
if(!$your_obj->is_valid())
//the other way you must be use the next method
if($your_obj->is_invalid())

I'm find a answer for your question without edit library.
Add the before_validation callback and add in this callback a validation rule. It works for me.
static $before_validation_on_create = array('before_validation_on_create');
static $validates_presence_of = array(
array('login'),
);
public function before_validation_on_create() {
self::$validates_presence_of[] = array('password');
}

Related

CodeIgniter 4 - Validation Custom Rule Function Quandry

In my CI4 learning, I have started by trying to simulate user sign in functionality. I have a Controller, two Views (not shown here, but really simply pages- one a pretty much just single form, and the other one a “blank” success HTML page), a set of custom rules in the Validation.php file, and a CustomRule.php file with the first of the methods that will implement all my custom rules (which, ultimately, I’d like to have all set in the Validation.php file). For lack of a better idea, I’ve stuck the CustomRules.php file in the app\Config\ folder.
Here is my problem:
For the life of me, I can’t figure out how to get the Validation service to pass additional parameters (from the form) to my custom rules function called ‘user_validated’. The CI4 documentation describes what the custom function needs to cater for when accepting additional parameters, but not how to trigger the Validation service to pass these additional parameters to one’s custom function… so although ‘user_validated’ is called, only ‘user_email_offered’ is ever passed as in as a string- nothing else goes in, from what I can tell. How do I get around this?
I have tried inserting < $validation->setRuleGroup('user_signin'); > before the call to validate, but found that I could move the setting of the rule group into the call to validate, using: $validationResult = $this->validate('user_signin'), which seemed to do the same, and which doesn't seem to work without the rule-group as a parameter (?). This still doesn't seem to be what triggers the additional data to be passed to the custom rule's method.
Extracts from my hack are appended below.
I’d be very grateful one of you knowledgeable folk could please point me in the right direction.
In app\Controllers\SignupTest.php:
<?php
namespace App\Controllers;
use CodeIgniter\Controller;
class SignupTest extends BaseController
{
public function index() { // redirection from the default to signup(), signin(), ...
return $this->signup();
}
public function signup() {
helper(['form']);
$validation = \Config\Services::validation();
if ($this->request->getPost()) { // still TBD: any different to using $this->request->getGetPost() ?
$validationResult = $this->validate('user_signin'); // set the rules to use: 'user_signin', 'user_signup'
if (!$validationResult) {
$validationErrors = $validation->getErrors();
return view('SignupTestView', $validationErrors); // redisplay simple html form view with list of validation errors
} else {
return view('SignupTestViewSuccess'); // display view to show success
}
} else {
return view('SignupTestView'); // initial display, in the event of there being no POST data
}
}
}
In \app\Config\CustomRules.php:
<?php
namespace Config;
use App\Models\UserModel;
//--------------------------------------------------------------------
// Custom Rule Functions
//--------------------------------------------------------------------
class CustomRules
{
public function user_validated(string $str, string $fields = NULL, array $data = NULL, string &$error = NULL) : bool{
$user_email_offered = $str;
$user_password_offered = ''; // to be extracted using $fields = explode(',', $fields), but $fields is never provided in the call to this user_validated method
if (($user_email_offered !== NULL) && ($user_password_offered !== NULL)) {
$usermodel = new UserModel(); // intended to create a UserEntity to permit connectivity to the database
$user_found = $usermodel->find($user_email_offered); // we're going to assume that user_email is unique (which is a rule configured in the database table)
if ($user_found === NULL) { // check if user exists before doing the more involved checks in the else-if section below, which may throw exceptions if there's nothing to compare (?)
...
}
}
In \app\Config\Validation.php:
?php
namespace Config;
class Validation
{
//--------------------------------------------------------------------
// Setup
//--------------------------------------------------------------------
/**
* Stores the classes that contain the
* rules that are available.
*
* #var array
*/
public $ruleSets = [
\CodeIgniter\Validation\Rules::class,
\CodeIgniter\Validation\FormatRules::class,
\CodeIgniter\Validation\FileRules::class,
\CodeIgniter\Validation\CreditCardRules::class,
\Config\CustomRules::class,
];
/**
* Specifies the views that are used to display the
* errors.
*
* #var array
*/
public $templates = [
'list' => 'CodeIgniter\Validation\Views\list',
'single' => 'CodeIgniter\Validation\Views\single',
];
//--------------------------------------------------------------------
// Custom Rules
//--------------------------------------------------------------------
/* configurable limits for validation rules array below*/
const user_email_min_lenth = 9;
const user_email_max_lenth = 50;
const user_password_min_lenth = 6;
const user_password_max_lenth = 25;
public $user_signin = [
'user_email' => [
'label' => 'e-mail address',
'rules' => 'trim|required|valid_email|user_validated', // user_validated is custom rule, that will have a custom error message
'errors' => [
'required' => 'You must provide an {field}',
'valid_email' => 'Please enter a valid {field}',
]
],
'user_password' => [
'label' => 'password',
'rules' => 'trim|required',
'errors' => [
'required' => 'Enter a {field} to sign in',
'user_password_check' => 'No such user/{field} combination found',
]
Calling custom rule with parameters should be exactly the same as calling CI4's regular rules. Let's get for example "required_without". You use it like in this example:
$validation->setRule('username', 'Username', 'required_without[id,email]');
And the function is declared as so:
public function required_without($str = null, string $fields, array $data): bool
{
$fields = explode(',', $fields);
//...
}
where $str - this is your main field, $fields - string, packing a comma-separated array.
As for Grouping rules, you do not need to group rules to be able to use custom rules with parameters.
If you have only 2 fields to test against you can go a bit cheaper, which will not be perfect but still works:
Function:
public function myrule(string $mainfield, string $fieldtotestwith): bool
{
//doing stuff
}
Validating rule:
$validation->setRule('somemainfield', 'Something', 'myrule[somesecondfield]');

Lumen provide a code for validation errors

Currently in lumen when you use the $this->validate($request, $rules) function inside of a controller it will throw a ValidationException with error for your validation rules(if any fail of course).
However, I need to have a code for every validation rule. We can set custom messages for rules, but I need to add a unique code.
I know there's a "formatErrorsUsing" function, where you can pass a formatter. But the data returned by the passed argument to it, has already dropped the names of the rules that failed, and replaced them with their messages. I of course don't want to string check the message to determine the code that should go there.
I considered setting the message of all rules to be "CODE|This is the message" and parsing out the code, but this feels like a very hacked solution. There has to be a cleaner way right?
I've solved this for now with the following solution:
private function ruleToCode($rule) {
$map = [
'Required' => 1001,
];
if(isset($map[$rule])) {
return $map[$rule];
}
return $rule;
}
public function formatValidationErrors(Validator $validator) {
$errors = [];
foreach($validator->failed() as $field => $failed) {
foreach($failed as $rule => $params) {
$errors[] = [
'code' => $this->ruleToCode($rule),
'field' => $field,
];
}
}
return $errors;
}

Cakephp - check if owner of item on website is currently logged in User

I have a couple of different 'items' on my website that I am building with cakePHP, for instance a Recipe and a ShoppingList.
I want certain items in my view (e.g. update and delete functionality links) to only be visible to the person who uploaded that item.
I want to add a function that would compare any given id to the currently logged in user's id. It would look something like this:
public function compareUser($id){
if(!empty($this->userInfo) && $this->userInfo['User']['id'] == $id){
return true;
}
}
$this->userInfo is set in beforeFilter:
$this->userInfo = $this->User->find('first', array('conditions' => array('id' => $this->Auth->user('id'))));
I have tried putting it in my appController, but that doesn't seem to work.
How can I implement this properly? Thanks!
This is best done using the isAuthorized($user) method.
All the information about your current user is stored in $this->Session->read('Auth.User') (this retrieves the full array, if you just wanted to get their 'id' you use $this->Auth->user('id') as you already did).
From the above it should hopefully be clear that normally you don't need to retrieve the user's details through an extra query as they are already stored in the Auth component of the session :)
Make sure in the setup for your Auth component you have 'authorize' => 'controller' and add the following to your AppController:
public function isAuthorized($user) {
//I want the default to be allow the user access so I will return true
return TRUE;
}
Then add the following to your RecipesController (and ShoppingListsController if you want the same thing there):
public function isAuthorized($user) {
if ($this->action === 'update' || $this->action === 'delete') {
$recipe = $this->Recipe->find(
'first',
'conditions' => array(
'id' => $this->params['pass'][0]
)
'fields' => array(
'user_id'
)
);
if ($this->Auth->user('id') == $recipe['Recipe']['user_id']) {
return TRUE;
}
else {
return FALSE;
}
}
return parent::isAuthorized($user);
}
Now if someone tries to access www.yourDomain.com/recipes/update/2 or www.yourDomain.com/recipes/delete/2 it will check if the current user's id is 2, if it is you're good to go, if not then it blocks them from that page.
Edit:
Easiest way to have a method accessible from all places I would suggest putting it in the AppModel that way all your models will inherit it:
//inside AppModel
public function isOwnedBy($id) {
if (AuthComponent::user('id) == $id) {
return TRUE;
}
return FALSE;
}

is_unique for codeigniter form validation

I'm trying to figure out how I can use the is_unique rule from the Codeigniter form validation library in the following situation.
I'm trying to submit a edit user form and have the rule:
$this->form_validation->set_rules('user_name', 'User Name', 'required|trim|xss_clean|is_unique[users.user_name]');
What if other values in the form are being changed but this value stays the same. The form is going to see that this value already exists so how would I protect it from editing if this value isn't changed.
Using your code as an example, the is_unique validation rule works by looking for a field called user_name in your users database table. If the field with the same value exists it validates as false.
To make sure it runs only when the user submits a new value, you could check the posted value $this->input->post('user_name') against the value you pulled from the database to populate your form with. If they are the same, don't validate is_unique;
if($this->input->post('user_name') != $original_value) {
$is_unique = '|is_unique[users.user_name]'
} else {
$is_unique = ''
}
$this->form_validation->set_rules('user_name', 'User Name', 'required|trim|xss_clean'.$is_unique);
There's a better way to go around it, I think, still using CodeIgniters' validation library...
Use edit_unique where you pass an extra parameter which is the id of the row you're editing.. See below.. I use it and works pretty fine for me.. hope it helps
$this->form_validation->set_rules('user_name', 'User Name', 'required|trim|xss_clean|edit_unique[users.user_name.'.$id.']');
$something = $this->input->post('something');
$this->form->validation->set_rules('something','Something','xss_clean|is_unique['tbl'.users]');
if($this->form_validation->run()== FALSE){
}
Simple Way
Just Change isset to is_object in system/libraries/form_validation.php
public function is_unique($str, $field)
{
sscanf($field, '%[^.].%[^.]', $table, $field);
return is_object($this->CI->db) //default isset
? ($this->CI->db->limit(1)->get_where($table, array($field => $str))->num_rows() === 0)
: FALSE;
}
Here's an easy method that worked for me and uses well documented code (thanks to https://github.com/ivantcholakov for sharing it!). I found it referenced at https://github.com/bcit-ci/CodeIgniter/issues/3109#issuecomment-46346280
Download https://github.com/ivantcholakov/starter-public-edition-3/blob/master/platform/application/libraries/MY_Form_validation.php (MIT licensed) and save it to your application at application\libraries\MY_Form_validation.php
Delete these two lines from __construct():
$this->CI->load->helper('checkbox');
$this->CI->load->helper('email');
Delete all the functions except __construct() and unique().
At the end of the __construct() method of your controller add this line:
$this->load->library('form_validation');
As per the documentation of the unique() method update your validation rule to add a "unique" rule like this (e.g. if you already have required and trim rules):
…|required|unique[tablename.fieldname,tablename.(primaryKey-used-for-updates)]|trim...
Extend Form_validation.php library create class inside of application/libraries file name MY_Form_validation.php
<?php
class MY_Form_validation extends CI_Form_validation{
protected $ci;
public function __construct($config = array()){
parent::__construct($config);
$this->ci =& get_instance();
}
public function is_unique_update($str, $field){
$explode=explode('#', $field);
$field_name=$explode['0'];
$field_id_key=$explode['1'];
$field_id_value=$explode['2'];
sscanf($field_name, '%[^.].%[^.]', $table, $field_name);
if(isset($this->ci->db)){
if($this->ci->db->limit(1)->get_where($table, array($field_name => $str,$field_id_key=>$field_id_value))->num_rows() === 0){
$this->ci->form_validation->set_message('is_unique_update', 'The {field} field must contain a unique value.');
return false;
}
return true;
}
}
}
Now in your controller
$this->form_validation->set_rules('user_name', 'User Name', 'required|trim|xss_clean|is_unique_update[users.user_name#id#'.$id.']');
"#" I used for explode the string
where id is primary key of users table
and $id is the value of id.
Now you can use this is_unique_update validation in any controller.
This question is very old but maybe some new people experience this problem and this is the solution for it.
I bet your are using Modular Extensions (HMVC) and you have created a new library, MY_Form_validation. You did id for callbacks, so you have this line of code on your class in order to use callbacks:
$this->form_validation->CI =& $this;
Well, the solution to this is whenever you want to use "is_unique" you must delete this line of code "$this->form_validation->CI =& $this;" from the class. I have experienced this problem and i fix it this way, it works fine now.
If you realy want to use callbacks "$this->form_validation->CI =& $this;", then do it only on required "methods" / "functions" where you don't want to use is_unique.
This code helpful for unique validation to create and update function...
In controller
Add this form validation code in both create and update function
$this->form_validation->set_rules('order_no', 'Order no', 'required|callback_check_order_no');
Add this call back function in controller
function check_order_no($order_no) {
if($this->input->post('id'))
$id = $this->input->post('id');
else
$id = '';
$result = $this->Data_model->check_unique_order_no($id, $order_no);
if($result == 0)
$response = true;
else {
$this->form_validation->set_message('check_order_no', 'Order no already exist');
$response = false;
}
return $response;
}
In model
function check_unique_order_no($id = '', $order_no) {
$this->db->where('order_no', $order_no);
$this->db->where('status', "A");
if($id) {
$this->db->where_not_in('id', $id);
}
return $this->db->get('delivery_order')->num_rows();
}
I'm using codeigniter3 and it shows me error when I check username on updating the value, is_unique is not designed to work with update scenario
so using #Anthony Mutisya's answer, here is the complete solution
in your controller, add this line while validation username of the current user with the database
$this->form_validation->set_rules('user_name', 'User Name', 'required|trim|xss_clean|edit_unique[users.user_name.'.$id.']');
You can get that $id from your submited form.
Now, add the following function to /system/libraries/Form_Validation.php this file. System folder is present in your root of CodeIgniter3 folder.
/**
* edit_unique // for check on update value
*
* Check if the input value doesn't already exist
* in the specified database field.
*
* #param string $str
* #param string $field
* #return bool
*/
function edit_unique($value, $params) {
$CI =& get_instance();
$CI->load->database();
$CI->form_validation->set_message('edit_unique', "Sorry, that %s is already being used.");
list($table, $field, $current_id) = explode(".", $params);
$query = $CI->db->select()->from($table)->where($field, $value)->limit(1)->get();
if ($query->row() && $query->row()->id != $current_id)
{
return FALSE;
} else {
return TRUE;
}
}
It works perfectly fine in my case
CodeIgniter 4 has already solution for that,
$validation->setRules([
'email' => 'required|valid_email|is_unique[users.email,id,{id}]',
]);
$_POST = [
'id' => 4,
'email' => 'foo#example.com',
];
then the {id} placeholder would be replaced with the number 4, giving this revised rule:
$validation->setRules([
'email' => 'required|valid_email|is_unique[users.email,id,4]',
]);
Official Documentation
we must have to add table name for is_unique
for Exp.
is_unique[users.email]

Difference between Controller and Model in MVC

I'm little confused about controller and model in MVC framework (codeIgniter). Its clear to me that controller methods calls the views and Model methods interact with database.
However, I'm little confused about the following types of methods, which are called by methods in a controller.
hash_password //returns hash password.
valid_email //validates email format and return true or false
is_logged //check if session has a variable, returns true or false
generate_random_string //generates and hashes a random string
Should they be placed in controller or in a model?
Currently I place all of the above functions in a controller. Is it correct?
I think the is_logged should be placed in the Model for User. Note that the User might be a customer in your case or any class that you have made to model a user of your service.
The valid_email and generate_random_string are more or less utility functions, which you can place in a Utility or Utilities model, so that these are reusable in various controllers in your application.
The hash_password, can be placed in either the User model or Utility model. I am more tempted to place it in Utility model, since its a hashing function and there is nothing the user cares about. However, I can imagine there can be argument(s) otherwise.
The following SO question (though for a different framework) can also serve as a rule of thumb:
Where to put custom functions in Zend Framework 1.10
generally controllers are used to determine how to handle the http requests made..
There's nothing wrong in creating some functions which directly respond to the http requests.
but if it has anything to do with the DB, its better to place those function in the model, and call them from the controller.
Controller should combine view with model, so every validation shoulde be placed in model
this is my example from kohana
CONTROLLER
<?php
/**
* User Controller
*/
class Controller_Admin_User extends Controller_Admin_Template {
public function action_index()
{
$this->template->body = View::factory('admin/user/index')
->set('i', 0)
->bind('users', $users)
->bind('groups', $groups)
->bind('id_user_group', $id_user_group);
$model_user = new Model_Admin_User;
$users = $model_user->get_users(Arr::get($_GET, 'sort'), Arr::get($_GET, 'order'));
$model_usergroup = new Model_Admin_Usergroup;
$groups = $model_usergroup->get_user_group();
}
public function action_add()
{
$this->template->body = View::factory('admin/user/form_add')
->bind('error', $error)
->bind('groups', $groups)
->bind('post', $post);
$model_usergroup = new Model_Admin_Usergroup;
$groups = $model_usergroup->get_user_group();
if($_POST)
{
$model_user = new Model_Admin_User;
if($model_user->save($_POST) == false)
{
$error = $model_user->error;
$post = $_POST;
}
else
{
$this->request->redirect('admin/user');
}
}
}
MODEL
class Model_Back_User extends Model {
private $qb;
public $aliases = array(
'id'=> 'id_user'
);
public $error = array(
'name' => null,
'surname' => null,
'login' => null,
'password' => null,
'id_user_group' => null,
'old_password' => null,
'new_password' => null,
'confirm' => null,
'email' => null,
'phone' => null,
);
private $rules = array(
'name' => array('not_empty' => null, 'alpha' => null),
'surname' => array('not_empty' => null, 'alpha' => null),
'login' => array('not_empty' => null),
'password' => array('not_empty' => null),
'id_user_group' => array('not_empty' => null),
'email' => array('not_empty' => null, 'email' => null),
'phone' => array('not_empty' => null),
'old_password' => array('not_empty' => null),
'new_password' => array('not_empty' => null),
'confirm' => array('matches' => array('new_password'))
);
public function __construct()
{
$this->qb = new Querybuilder;
//parent::__construct();
}
public function change_password($data)
{
$validate = Validate::factory($data)
->filter(true, 'trim')
->rules('old_password', $this->rules['old_password'])
->rules('new_password', $this->rules['new_password'])
->rules('confirm', $this->rules['confirm'])
->callback('old_password', array($this, 'password_exists'), array('id_user'=> $data['id_user']));
if($validate->check() == false)
{
$this->error = array_merge($this->error, $validate->errors('user'));
return false;
}
$u = Session::instance()->get('user');
$this->edit(array('password'=> $this->password($data['new_password'])), array('id_user'=> $u['id_user']));
return true;
}
public function password_exists(Validate $valid, $field, $param)
{
if($this->user_exists(array('password'=> $this->password($valid[$field]), 'id_user'=> $param['id_user'])) == false)
{
$valid->error($field, 'old password is incorrect', array($valid[$field]));
}
}
public function save($data)
{
$validate = Validate::factory($data)
->filter(true, 'trim')
->rules('name', $this->rules['name'])
->rules('surname', $this->rules['surname'])
->rules('user_group_id', $this->rules['id_user_group'])
->rules('email', $this->rules['email'])
->rules('phone', $this->rules['phone']);
$edit = false;
if(isset($data['id_user']) AND Validate::not_empty($data['id_user']))
{
$edit = true;
}
else
{
$validate->rules('login', $this->rules['login'])
->rules('password', $this->rules['password']);
}
if($validate->check() == false)
{
$this->error = array_merge($this->error, $validate->errors('user'));
return false;
}
if($edit == true)
{
$this->edit(
array(
'name' => $data['name'],
'user_group_id' => $data['user_group_id']
),
array(
'id_user'=> $data['id_user']
)
);
return true;
}
return $this->add(
array(
'name' => $data['name'],
'login' => $data['login'],
'password' => $data['password'],
'user_group_id' => $data['user_group_id']
)
);
}
protected function add($data)
{
$data['password'] = $this->password($data['password']);
return $this->_db->query(Database::INSERT,
$this->qb->insert('user')->set($data)->build_query()
);
}
View is not so important thats why i dont put this here.
Generally speaking - a model should know stuff about it's own data. So anything related purely to a model's own data - should go in the model.
Eg the hash_password and email-validation methods - a model should know how to validate or update it's own data-fields, so those should go in the model.
However a controller should know about how to direct user actions appropriately and to load the correct models for views etc.
EG the session-related method should go in the controller, because the session is used for storing the user's state (based on past actions).
The "generate random string" method is very vague and may be used everywhere. I'd put that in a separate library possibly included in the model/controller as appropriate.
I've been using Codeigniter for a long time and I'd do the following with your functions as far as placement goes:
hash_password //returns hash password.
I'd put something like a password hasher in a library or helper file so I could call it from my controller like:
// pretend library I'd make for tasks like hashing etc
$this->load->library('passwords');
// transform posted password into it's hashed version
$password = $this->password_library->hash_password($this->input->post('password'));
I'm assuming you want to hash/salt the password and store it in your database in that example
valid_email //validates email format and return true or false
This is already in form_validation, so...
is_logged //check if session has a variable, returns true or false
This should also connect to a authentication library
generate_random_string //generates and hashes a random string
Again, this would come from a library or helper.
SO WHEN DO YOU USE A MODEL?
Me, I use models exclusively for in/out on the database. All my queries go in there. I usually have my model's functions return data objects so I can loop through them in my views.
Controllers call your data from your models, then dump everything into your views. Outside functionality always goes into libraries and helpers. I like to do the "MY_library" and extend Codeigniter's own stuff - especially with forms and the html helper etc.

Categories