Now it's time to talk database.
Our application will store the news, comments and user data in the database server, and in my case MySQL server. I created an database for the project called 'khn' and an user with access to the database.
Our first table will contain the news:
CREATE TABLE IF NOT EXISTS `news` ( `id` int(11) NOT NULL AUTO_INCREMENT, `user_id` int(11) NOT NULL, `user_name` varchar(100) NOT NULL, `title` varchar(255) NOT NULL, `body` text NOT NULL, `comments` int(11) NOT NULL DEFAULT '0', `points` int(11) NOT NULL DEFAULT '1', `created` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, PRIMARY KEY (`id`) ) ENGINE=MyISAM DEFAULT CHARSET=utf8 AUTO_INCREMENT=3 ; INSERT INTO `news` (`id`, `user_id`, `user_name`, `title`, `body`, `comments`, `points`, `created`) VALUES (1, 1, 'test 1', 'Test News 1', 'Test Body 1', 0, 1, '2010-10-16 13:45:49'), (2, 2, 'test 2', 'Test News 2', 'Test Body 2', 0, 2, '2010-10-16 13:45:49');
One table is enough for this lesson. To let Kohana know that we want to connect to a database, we must enable the database module. Open the bootstrap.php file (located in the application directory) and uncomment the following line:
'database' => MODPATH.'database', // Database access
Next copy the khn/modules/database/config/database.php file to the application/config/ directory and edit its content according to your configuration. Mine looks like that:
<?php defined('SYSPATH') or die('No direct access allowed.'); return array ( 'default' => array ( 'type' => 'mysql', 'connection' => array( /** * The following options are available for MySQL: * * string hostname server hostname, or socket * string database database name * string username database username * string password database password * boolean persistent use persistent connections? * * Ports and sockets may be appended to the hostname. */ 'hostname' => 'localhost', 'database' => 'khn', 'username' => 'adsms', 'password' => 'adsms', 'persistent' => FALSE, ), 'table_prefix' => '', 'charset' => 'utf8', 'caching' => FALSE, 'profiling' => TRUE, ) );
We'll create a model called Model_News, which will handle the news:
application/classes/model/news.php
<?php /** * Description of news * * @author aquilax */ class Model_News extends Model{ } ?>
Let's also add a method to get all the news for the home page:
/* * Load the news for the first page */ public function loadFirstPageNews($n){ return DB::select('id', 'title', 'user_id', 'user_name', 'comments', 'points', new Database_Expression('UNIX_TIMESTAMP(created) AS created')) ->from('news') ->order_by(new DatabaseExpression('(points - 1) / ((UNIX_TIMESTAMP(CURRENT_TIMESTAMP)-UNIX_TIMESTAMP(created))/3600 +2)^1.5'), 'DESC') ->order_by('created') ->limit($n) ->execute() ->as_array(); }The order_by section is taken from this Hacker News comment.
The DatabaseExpression class is used in the order_by function to prevent Kohana from escaping the expression, which breaks the resulting SQL.
I'm using the Query_Builder functions because I feel more comfortable with them. You can try to use the ORM class or raw SQL, which in this case shoult look like that:
SELECT id, title, user_id, user_name, comments, points, UNIX_TIMESTAMP(created) FROM news ORDER BY (points - 1) / ((UNIX_TIMESTAMP(CURRENT_TIMESTAMP)-UNIX_TIMESTAMP(created))*3600 +2)^1.5 DESC LIMIT 30
Now we have a function, which returns news for the home page. Let's call it in the home controller's action_index:
application/classes/controller/news
public function action_index(){ $this->data['news'] = $this->news->loadFirstPageNews(30); $this->render(); }
and change the view to print the news:
application/views/pages/news/index_tpl.php
<?php if ($news) { echo '
- '; foreach ($news as $row) { echo '
- '.html::entities($row['title']).' '; } echo '
Hello!
ReplyDeleteI have problem. I don't know where put this code from this:
"Let's also add a method to get all the news for the home page:
/*
* Load the news for the first page
*/
public function loadFirstPageNews($n){
return DB::select('id', 'title', 'user_id', 'user_name', 'comments', 'points', new Database_Expression('UNIX_TIMESTAMP(created) AS created'))
->from('news')
->order_by(new DatabaseExpression('(points - 1) / ((UNIX_TIMESTAMP(CURRENT_TIMESTAMP)-UNIX_TIMESTAMP(created))/3600 +2)^1.5'), 'DESC')
->order_by('created')
->limit($n)
->execute()
->as_array();
}
"
I want to say I'm working in 3.08. Kohana like you were working.
ReplyDeleteI think it's should be in:
application/classes/model/news.php
Then I made 2 last steps and I have error:
http://imageshack.us/photo/my-images/191/41213026.jpg/
undefinied property.. I think it's this 30
@Lucas the code goe to the news.php model:
ReplyDeleteapplication/classes/model/news.php
Check the whole model here:
https://gist.github.com/1376219
Also check the Controller code here: http://code.google.com/p/kohana-tutorial/source/browse/trunk/kohana/knh/application/classes/controller/news.php
ReplyDeleteNext Error: APPPATH\classes\model\news.php
ReplyDeleteErrorException [ Fatal Error ]: Class 'DatabaseExpression' not found
http://imageshack.us/f/522/53899541.jpg/
Problem solved .. AquilaX it should be Database_Expression
ReplyDeleteAnother problem..
ReplyDeletehttp://imageshack.us/photo/my-images/42/23557806.jpg/
problem solved ... I just added new user with all permission and access .. I don't know why It didn't work on basic root without password :) thanks..
ReplyDeletePerhaps I missed something somewhere along the way to get the model loaded (I'm using v3.2) but I had to change the action_index() model in the news controller to be:
ReplyDeletepublic function action_index() {
$model = Model::factory('News');
$this->data['news'] = $model->loadFirstPageNews(30);
$this->render();
}
Thanks for sharing this informative blog.
ReplyDeleteLooking for Low budget cottages in Ooty? Experience a pocket-friendly getaway amidst nature's beauty with our affordable and charming retreat in Ooty.