This is documentation for Kohana v2.3.x.

Table of Contents
TodoProof read this page, add many more examples .. validation

<< Back to ORM Main Page

Examples of Using ORM

Combining ORM and Pagination

ORM and Pagination can be combined quickly by using the count_last_query method that just executes the original query again without limit and offset. The following example would be used in a controller.

$per_page = $this->input->get('limit', 1);
$page_num = $this->input->get('page', 1);
$offset   = ($page_num - 1) * $per_page;
 
$user = ORM::factory('user', 'john.smith');
$posts = $user->limit($per_page, $offset)->blog_posts;
$pages = Pagination::factory(array
(
    'style' => 'digg',
    'items_per_page' => $per_page,
    'query_string' => 'page',
    'total_items' => $user->count_last_query()
));
 
foreach ($posts as $post)
{
    echo $post->title, ' by ', $post->author->username, '<br/>';
}
echo $pages;

Here is another example of pagination that comes from Oscar Bajner's Kohana 101 guide after being adapted to ORM. This example uses the count_all() method to find the total number of items.

	public function page($pagenum)
	{
		$this->template->title = 'L33t Str33t::Products';
		$this->template->content = new View('pages/products');
 
		// Instantiate Pagination, passing it the total number of product rows.
		$paging = new Pagination(array
			(
			'total_items' => ORM::factory('product')->with('category')->count_all(),
			));
 
		// render the page links
		$this->template->content->pagination = $paging->render();
 
		// Display X items per page, from offset = page number
		$this->template->content->products = ORM::factory('product')
			->with('category')
			->orderby(array('category:description' => 'ASC', 'code' => 'ASC'))
			->limit($paging->items_per_page, $paging->sql_offset)
			->find_all();
	}

Combining ORM and Validation

ORM has the ability to validate and save data automatically. Any errors encountered during validation can be used to feedback to the view using the standard Validation Library error reporting method.

To use Validation in an ORM model a set of validation rules and filters must be defined within a public method called validate, which overloads the ORM::validate() method.

Setting up the ORM model

class Person_Model extends ORM
{
	/**
	 * Validates and optionally saves a new user record from an array.
	 *
	 * @param  array    values to check
	 * @param  boolean  save[Optional] the record when validation succeeds
	 * @return boolean
	 */
	public function validate(array & $array, $save = FALSE)
	{
		// Initialise the validation library and setup some rules
		$array = Validation::factory($array)
				->pre_filter('trim')
				->add_rules('tel', 'required', 'phone[7,10,11,14]')
				->add_rules('name', 'required', array($this, '_name_exists'));
 
		return parent::validate($array, $save);
	}
 
	/**
	 * Tests if a username exists in the database. This can be used as a
	 * Validation rule.
	 *
	 * @param   mixed    name to check
	 * @return  boolean
	 */
	public function _name_exists($name)
	{
		// Uses a ternary operator to ensure that no records returns as TRUE, some records as FALSE
		return (bool) ! $this->db
			->where(array('name' => $name, 'id !=' => $this->id))
			->count_records($this->table_name);
 
	}
}

The Validation library is used to validate the data using the rules supplied. For this reason, if using custom rules, callbacks or filters they must be publicly accessible. If a callback method is not required elsewhere, it is sensible to prefix the method name with an underscore as shown above.

Using Validation in your controller

Using ORM validation within controllers is simple. The ORM::validate() method will only ever return a boolean TRUE or FALSE. The array supplied to the ORM::validate() method is symbolically linked and will be transformed into a Validation object. You can also pass TRUE or a string as second parameter to save automatically the data (this means that if validation was successful, the save method will be called right after). If a string is passed, the validate() method will then perform a redirection (url::redirect($string_passed)). Note that the validate() method only populates your model with fields that actually have validation rules, so if you have fields that aren't being validated, you need to explicitly set the model values to the form fields before saving (or before calling validate with the auto-save option) – see http://forum.kohanaphp.com/comments.php?DiscussionID=2101 and http://forum.kohanaphp.com/comments.php?DiscussionID=1426 for more details.

class Person_Controller extends Controller
{
	public function index()
	{
		// Create a new person
		$person = ORM::factory('person');
 
		// If there is a post and $_POST is not empty
		if ($this->input->post())
		{
			//Pull out fields we want from POST. We do this for 2 reasons:
			// 1) Manually set non-validated fields (address1 and address2) because validate() won't do it for us.
			// 2) Safety precaution -- only set fields we're expecting (otherwise someone could inject a different "id" into the POST data, for example).
			$data = arr::extract($this->input->post(), 'name', 'tel', 'address1', 'address2');
 
			// If the post data validates using the rules setup in the person model
			if ($person->validate($data))
			{
				//Successfully validated!
				$person->save();
				url::redirect('some/other/page');
 
				//Note that we could have passed TRUE to validate() to auto-save, or we could pass the redirect path to auto-save-and-redirect.
			}
			else
			{
			// Otherwise use the $data->errors() array to output the errors
				echo '<h1>Submitted data had errors</h1><ul>';
				foreach ($data->errors() as $key => $value)
					echo '<li><strong>'.$key.' :</strong> '.$value.'</li>';
 
				echo '</ul>';
			}
		}
		// Create an input form (and populate the fields with last submitted values if there were errors)
		echo form::open();
		echo form::input('name', $person->name);
		echo form::input('tel', $person->tel);
		echo form::input('address1', $person->address1);
		echo form::input('address2', $person->address2);
		echo form::submit('submit', 'Save');
		echo form::close();
	}
}

Continue to the next section: Advanced Topics >>