jqGrid

Filed in Development Leave a comment

jqGrid is an excellent data grid plugin for jQuery which I wanted to use in my TV Schedule application. It went very smoothly except for the order in which the columns are displayed. jqGrid will display the columns in the order that it receives them. Continue Reading

, ,

Basic user authentication

Filed in Recipe Manager Leave a comment

Today I got the basic user authentication going for the Recipe Manager using this tutorial.

Users Controller

class UsersController extends AppController
{
	var $name = "Users";
	//var $helpers = array('Html', 'Form');
 
	function index()
	{
 
	}
 
	function beforeFilter()
	{
		$this->__validateLoginStatus();
	}
 
	function login()
	{
		if(empty($this->data) == false)
		{
			if(($user = $this->User->validateLogin($this->data['User'])) == true)
			{
				$this->Session->write('User', $user);
				$this->Session->setFlash('You\'ve successfully logged in.');
				$this->redirect('/recipes/');
				exit();
			}
			else
			{
				$this->Session->setFlash('Sorry, the information you\'ve entered is incorrect.');
				exit();
			}
		}
	}
 
	function register()
	{
		if (!empty($this->data))
		{
			//Sanitize::clean($this->data);
			$this->data['User']['password'] = md5($this->data['User']['password']);
			$this->User->create(); // create the model
 
			if ($this->User->save($this->data))
			{
				$this->Session->write('User', $this->User->findByUsername($this->data['User']['username']));
				$this->Session->setFlash('Thank you for registering.');
				$this->redirect('login/');
			}
			else
			{
				$this->Session->setFlash('The User could not be saved. Please, try again.');
			}
		}
	}
 
	function logout()
	{
		$this->Session->destroy('user');
		$this->Session->setFlash('You\'ve successfully logged out.', 2);
		$this->redirect('login');
	}
 
	function __validateLoginStatus()
	{
		if($this->action != 'login' && $this->action != 'logout')
		{
			if($this->Session->check('User') == false)
			{
				$this->redirect('login');
				$this->Session->setFlash('The URL you\'ve followed requires you login.');
			}
		}
	}
 
}

Login View

<div class="login">
<h2>Login</h2>
create('User', array('action' =&gt; 'login'));?&gt;
        input('username');?&gt;
        input('password');?&gt;
        submit('Login');?&gt;
    end(); ?&gt;</div>

Register View

<div class="login">
<h2>Login</h2>
create('User', array('action' =&gt; 'register'));?&gt;
        input('email');?&gt;
        input('username');?&gt;
        input('password');?&gt;
        submit('Register');?&gt;
    end(); ?&gt;</div>

Adding this to the app_controller causes each view to authenticate the user.

class AppController extends Controller {
 
	var $helpers = array('Html', 'Javascript', 'Ajax');
 
	function beforeFilter()
	{
            if($this-&gt;Session-&gt;check('User') == false)
            {
                $this-&gt;redirect('/users/login');
                $this-&gt;Session-&gt;setFlash('The URL you\'ve followed requires you login.');
            }
    }
}

I still have to work on showing user messages and sanitizing the data but this is a good start.

CakePHP so far

Filed in Recipe Manager Leave a comment

I have finally started the recipe manager project. I decided upon the CakePHP framework thanks to a recommendation from Anthony. I have found a few places that have some documentation to help get started.

I have most of the framework for the application fleshed out. I can add, edit and delete ingredient_types, ingredients, measurement_types, measurements, recipe_types and recipes.

I am stuck at the moment on adding, deleting items from the ingredients_list for a recipe. Every recipe has one or more ingredients that are stored in the ingredients_list table. This table contains the amount, the measurement_type, ingredient and a description. So you can store:

1 cup chopped broccoli or 2 ounces of shaved garlic

When adding or editing a recipe I want to simply be able to add a new line item for the ingredient. I can picture how to do this without CakePHP but I cant seem to find the trick to do it with. Essentially each item in the recipe edit view should have a button that allows you to delete that particular item. In the add view their should be a button that simply adds a new empty ingredient.

There are some things lacking in the CakePHP documentation, although its better than most. I had one other problem that I had to sort of hack around until I get a better solution. The task was to edit a recipe. This involves getting all the ingredients from the ingredient_list for the recipe to be edited. This is done with the following line:

$list = $this->IngredientList->find('all', array ('recipe_id' => $id));

You would assume that as the recipe id is passed to the IngredientList controller you would only get records for that particular recipe. But not so. This means that I made a mistake somewhere in my table definitions but I have gone over it many times trying to find it but to no avail. My work around is this:

foreach($list as $item)
{
    //debug($item['IngredientList']['recipe_id'], true);
    if($item['IngredientList']['recipe_id'] == $id)
    {
        $ing_list[] = $item;
    }
}

Essentially I just loop through the array looking for the current recipe ID. If I find it I add it to an array that I pass to the view. Here is the whole action for edit:

function edit($id = null)
{
    $this->Recipe->id = $id;
    $this->set_recipe_types();
    $this->set_ingredients();
    $this->set_measurement_types();
 
    $list = $this->IngredientList->find('all', array ('recipe_id' => $id));
 
    //debug($list, true);
 
    foreach($list as $item)
    {
        //debug($item['IngredientList']['recipe_id'], true);
        if($item['IngredientList']['recipe_id'] == $id)
        {
        $ing_list[] = $item;
        }
    }
 
    $this->set('ingredient_list', $ing_list);
 
    if (empty($this->data))
    {
        $this->data = $this->Recipe->read();
    }
    else
    {
        if ($this->Recipe->saveAll($this->data))
        {
            $this->flash('Your recipe has been updated.','/recipes');
        }
    }
}

TOP