##The home page for harikt's fork of lithium_blog
Get you copy, of lithium_blog , and [setup your labs.](http://dev.lithify.me/lithium/wiki/guides/installation)
I hope you have setup your li3 command. Run the below command from the lithium_blog directory.
{{{
$li3 create user
}}}
Will create users controller, user model, and test for users.
If you point your browser to /users/add or /users , you will get an error reporting the template is not there. So you want create the corresponding templates in the users folder of views. Create add.html.php
A simple form which is self explanatory.
{{{
//views/users/add.html.php
<?= $this->form->create($user); ?>
<?= $this->form->field(array('fullname' => 'Full Name : ')); ?>
<?= $this->form->field(array('username' => 'User Name : ')); ?>
<?= $this->form->field(array('email' => 'Email Address : ')); ?>
<?php /* echo $this->form->field('gender', array(
'type' => 'select',
'list' => array('male' => 'Male', 'female' => 'Female'),
'empty' => true // if provided empty it will show a blank field.
));*/ ?>
<div>Your favourite Color : <?php /* echo $this->form->select('colors', array(1 => 'red', 2 => 'green', 3 => 'blue'), array(
'id' => 'Colors', 'value' => 2, 'empty' => true
));*/
?></div>
<?php //echo $this->form->field(array('gender' => 'Male'),array('type' => 'radio')); ?>
<?php //echo $this->form->field(array('gender' => 'Female'),array('type' => 'radio')); ?>
<?= $this->form->field('password', array('type'=>'password')); ?>
<?php //echo $this->form->hidden('hiddenvariable', array('value' => 'notshown')); ?>
<?php //echo $this->form->field('image',array('type'=>'file')); ?>
<?= $this->form->submit('Save'); ?>
<?= $this->form->end(); ?>
}}}
Now you have the form . I have commented some fields, you can uncomment and see how it looks.
Now you need to add validations right ?
Its easy as adding rules in the validates array of model. In this case user located at models/User.php. For [more rules](http://lithify.me/docs/lithium/util/Validator)
{{{
<?php
//models/User.php
namespace app\models;
class User extends \lithium\data\Model {
public $validates = array(
'fullname' => 'Please enter a full name',
'username' => 'Please enter a user name',
'email' => array(
array('notEmpty', 'message' => 'email is empty'),
array('email', 'message' => 'email is not valid'),
)
);
}
?>
}}}
Lithium command already would have created something like the code below
{{{
<?php
namespace app\controllers;
use \app\models\User;
class UsersController extends \lithium\action\Controller {
public function index() {
$users = User::all();
return compact('users');
}
public function view() {
$user = User::first($this->request->id);
return compact('user');
}
public function add() {
$user = User::create();
if (($this->request->data) && $user->save($this->request->data)) {
$this->redirect(array('Users::view', 'args' => array($user->id)));
}
return compact('user');
}
public function edit() {
$user = User::find($this->request->id);
if (!$user) {
$this->redirect('Users::index');
}
if (($this->request->data) && $user->save($this->request->data)) {
$this->redirect(array('Users::view', 'args' => array($user->id)));
}
return compact('user');
}
}
?>
}}}
Here we have an index , add, edit , delete actions . You can create the corresponding templates edit.html.php , delete.html.php , index.html.php like the one we created .
For edit and add we can use a single template ;) . Lithium can render the view of another action.
When we submit the form , the form will be validated with the rules written. So it will only save data once there is no errors.
We need a database connection and table . What and where ?
So lets create the table . I have a database with name lithium_blog.
{{{
CREATE TABLE `users` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`username` varchar(50) NOT NULL,
`password` varchar(50) NOT NULL,
`fullname` varchar(100) NOT NULL,
`url` varchar(50) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=13 DEFAULT CHARSET=latin1 COMMENT='List of users of website'
}}}
Now you need to tell lithium about your database setup.
Uncomment the line from config/bootstrap.php
{{{
require __DIR__ . '/bootstrap/connections.php';
}}}
Now go and edit the file connections.php . We are going to use MySQL , so we need to uncomment the below line .
{{{
//config/bootstrap/connections.php
Connections::add('default', array(
'type' => 'database',
'adapter' => 'MySql',
'host' => 'localhost',
'login' => 'lithium_blog',
'password' => 'lithium_blog',
'database' => 'lithium_blog'
));
}}}
For convinience to remember the projects in my local system its having same name , username and password ;). Change it with yours :) .
Now we have setup the connection . We can now add users, just try and query look the datas. The password will be saved as it is. We need to change that behaviour so that it will be encrypted and saved.
In that way we can use lithiums [form based authentication] ( http://lithify.me/docs/lithium/security/auth/adapter/Form ) for login. With lithium its easy to create filters. So this filter will be triggered and thus we can do what ever logic we need to do inside that filter. So in this case a hash for password. So lets add the filter for the User model, the final code will look like the one below.
{{{
<?php
//models/User.php
namespace app\models;
class User extends \lithium\data\Model {
public $validates = array(
'fullname' => 'Please enter a full name',
'username' => 'Please enter a user name',
'email' => array(
array('notEmpty', 'message' => 'email is empty'),
array('email', 'message' => 'email is not valid'),
)
);
}
User::applyFilter('save', function($self, $params, $chain){
$record = $params['entity'];
if (!$record->id) {
$record->password = \lithium\util\String::hash($record->password);
}
if (!empty($params['data'])) {
$params['data']['password'] = \lithium\util\String::hash($params['data']['password']);
$record->set($params['data']);
}
$params['entity'] = $record;
return $chain->next($self, $params, $chain);
});
?>
}}}
Now point to users/add and save with some data and do a select query on the table, you can see the password is not saved as text.
Lets now do a simple authentication. So go and uncomment the line so we can store the session after we do the authentication.
{{{
//File config/bootstrap.php
require __DIR__ . '/bootstrap/session.php';
}}}
Edit file config/bootstrap/session.php and uncomment the below lines in it. I am not going what we are doing, read from the file itself what we are doing , now you got right ? ;)
{{{
<?php
use lithium\storage\Session;
Session::config(array(
'cookie' => array('adapter' => 'Cookie'),
'default' => array('adapter' => 'Php')
));
use lithium\security\Auth;
Auth::config(array(
'default' => array(
'adapter' => 'Form',
'model' => 'User',
'fields' => array('username', 'password')
)
));
?>
}}}
Now we need to create an action login inside the user controller.
{{{
//File controllers/UserController.php
public function login() {
if (Auth::check('default', $this->request)) {
//echo "What happened ? ";
$this->redirect(array('Posts::index','args' => array()));
}
}
}}}
So we need a login form with username and password as fields.
{{{
// File /views/users/login.html.php
<?= $this->form->create(); ?>
<?= $this->form->field('username'); ?>
<?= $this->form->field('password', array('type'=>'password')); ?>
<?= $this->form->submit('Login'); ?>
<?= $this->form->end();
}}}
Note that we have provided
{{{ 'fields' => array('username', 'password') }}}
in the session.php. ie why, if you have given email, use email instead for username.
Try to login. Hope its working for you :) . What about logout ?
Create a logout action in users controller and after logging out redirect to index page or some where else. You need an empty logout.html.php file though.
{{{
//in controllers/UserController.php
public function logout() {
Auth::clear('default');
// as its in development Auth::clear() has a bug , so don't tell its not working.
}
}}}
## Search our posts with Zend_Search_Lucene
I am using Zend_Search_Lucene . You can see the [a documentation](http://framework.zend.com/manual/en/zend.search.lucene.overview.html) and a nice tutorial by John Herren over [a here](http://devzone.zend.com/article/91).
Tell lithium to load the Zend framework library.
{{{
// file at config/bootstrap/libraries.php
Libraries::add("Zend", array(
"prefix" => "Zend_",
'path' => '/usr/share/php/ZendFramework-1.11.2/library/Zend',
"includePath" => '/usr/share/php/ZendFramework-1.11.2/library',
"bootstrap" => "Loader/Autoloader.php",
"loader" => array("Zend_Loader_Autoloader", "autoload"),
"transform" => function($class) { return str_replace("_", "/", $class) . ".php"; }
));
}}}
My Zend framework path is /usr/share/php/ZendFramework-1.11.2/library . Change it according to yours.
We are creating Lucene search index with the help of makeindex method of searches controller . Just make sure you create an empty makeindex.html.php else lithium complaints no template found.
Have created a form with method get, and passing the action of form to searches controllers index. Below is the SearchesController.php file.
{{{
<?php
namespace app\controllers;
use \app\models\Post,
\Zend_Search_Lucene,
\Zend_Search_Lucene_Field,
\Zend_Search_Lucene_Document;
class SearchesController extends \lithium\action\Controller {
/*
* Called when a search happens. Here we assume the method type of form is get,
* else use ->data instead of ->query.
*/
public function index() {
/*
*Same path where we have created the index.
*/
$index = new Zend_Search_Lucene( __DIR__ . '/../data/blog-indexs');
$query = $this->request->query['query'];
$searches = $index->find($query);
return compact('index', 'query', 'searches');
}
/*
* More details about Zend_Search_Lucene visit
* http://framework.zend.com/manual/en/zend.search.lucene.html
* This function just makes index and store files in a directory.
*/
public function makeindex() {
/*
* We are storing the index in data folder.
* You can see a new folder named data where the controllers reside.
*/
$index = new Zend_Search_Lucene( __DIR__ . '/../data/blog-indexs', true);
$posts = Post::all();
foreach( $posts as $post ) {
$doc = new Zend_Search_Lucene_Document();
$doc->addField(Zend_Search_Lucene_Field::Keyword('url', '/posts/view/' . $this->sanitize($post->id)));
$doc->addField(Zend_Search_Lucene_Field::Text('title', $this->sanitize($post->title)));
$doc->addField(Zend_Search_Lucene_Field::Unstored('body', $this->sanitize($post->body)));
$index->addDocument($doc);
}
$index->commit();
}
public function sanitize($input) {
return htmlentities(strip_tags( $input ));
}
}
?>
}}}
The view of searchescontroller index.html.php
{{{
Search for <?= $query; ?> returned <?= count($searches)?> hits <br />
<?php foreach ($searches as $hit) { ?>
<?= $this->html->link( $hit->title , $hit->url );?>
<?php } ?>
}}}
Now you have search and also you are loading another library. How easy is it right ?
We have access rules with the help of a plugin at present. Check out [li3_access]( https://github.com/tmaiaroto/li3_access )
ie it ,hope you enjoyed.