Scenario: I have a view to which i pass a kohana record-set object, and view will go through each record and display its values in appropriate format. In the view i have to alert user with a message. This alert will only get activated if certain criterion is met, for example, view have to do PHP datediff using the date
property of each record and see whether it is the best time to display the alert to user.
What i am thinking is instead of the view do the calculation, i would do it inside the controller. However, I believe it is a bad idea inside the controller to have a loop which iterates through each record and do the calculation and wraps the record inside a wrapper object along with additional properties specific for view. What i am looking for something like a callback in the model which gets called every time, a record is fetched. I can do the my calculations there and return the object. Is such an approach possible with Kohana? If not, please tell me what is the best solution to fit in this requirement?
Thanks for your time and attention.
Yes indeed, your suggestion is a good one and I use it all the time.
I assume you have a model which extends ORM. As an example, you could do something like this.
class Model_Example extends ORM {
protected $_primary_key = 'id';
protected $_table_name = 'example_table';
// possibly relations, filters etc.
function should_message_be_shown() {
if( !$this->_loaded ) {
throw new Kohana_Exception('Should only be called on loaded objects');
}
if( $this->date_created > ( time() - 3600 ) ) {
return true;
}
return false;
}
function get_user_message() {
if( !$this->_loaded ) {
throw new Kohana_Exception('Should only be called on loaded objects');
}
return 'Hi ' . $this->user_name . '! This is your personal message';
}
}
The method should_message_be_shown()
makes use of the class variable Model_Example::date_created
. This assumes you have a table column called date_created
which holds an UNIX timestamp. So in this particular example it returns true if the record was created within the last hour.
I have added a check to see if the record is actually loaded and throw an exception otherwise.
To complete the example, you can fetch and use the model in your controller and view like this:
class Controller_Example extends Controller {
function action_index() {
$records = ORM::factory('Example')->where('something', '=', true)->find_all();
$this->response->body(View::factory('example')
->set('examples', $records));
}
}
And the view file:
<div class="example-list">
<?php foreach($examples as $example): ?>
<div class="example-item">
<h2><?php echo $example->title; ?></h2>
<?php if($example->should_message_be_shown()): ?>
<div class="message">
<?php echo $example->get_user_message(); ?>
</div>
<?php endif; ?>
</div>
<?php endforeach; ?>
</div>