Blogs, Forums and CakePHP

In one of my contracts, I am writing a full application with membership, conference signups, information pages, and a small little forum. This is all per the customer’s request. The solution I decided on, was CakePHP for the framework. It is not going to be a big, full site like a MySpace, or Facebook. It is a small local non-profit group who will be able to have its membership keep in touch via the site. So the main pages are not hard. Most of the pages will follow a simplistic CRUD (create, read, update and delete) format, with the site admins being able to create, update and delete most pages. But instead of having a static site, they wanted the membership to be able to interact with the authors of the pages, and themselves.

The pages are not hard to enable this. I could have just as easily installed a WordPress instance for the solution, themed it up, and be done. Which I was seriously considering, as this already has the permissions, updates, management, etc. However, they were not too happy with something like this. So I looked elsewhere. Drupal would provide a good out of the box solution, but there were problems with the modules, and it seemed to take too much overhead to get the groups, permissions and other CMS features set up for this small site. The next idea I looked at was going the CakePHP route. Continue reading Blogs, Forums and CakePHP

Don’t forget the basics

There was something I was asked to troubleshoot between two different environments. Most reputable places will give at least 2 different environments for application development, the best is to have at least three, development, stage, and production areas. I was asked resolve and fix an issue in the stage area, but it was not happening in the development area. Normally, I follow a few simple rules to get through this type of troubleshooting. Today, for some reason, I blew those off. Now this is not an end all be all type of list, and I use what is good for me and what I have learned. Other people may find different ways to do this, and find ways that work for them more. Here are some of the major items I check for with web applications in PHP.

  • Check the Apache services, connection, or anything that would lead to just no resulting page whatsoever.
  • Check the DB server, make sure the server is working, the connection is good, the data flow is there
  • Check the permission of the database, the tables, the sequences, etc. Whatever is needed from the database, make sure the caller has permissions to do that task
  • Check the code objects/PEAR packages/framework extensions are installed. If you have a recent version of PHP, then you should be good for PEAR, and if you have the most recent framework version (like Symfony, CakePHP or Zend) that should house them all, but never hurts to check
  • Check instantiated objects, function calls, object variables, etc. Most of the time it could be a spelling error, or the call is made before the object is created
  • I check the data being returned and the statements making the calls. What I am calling for may not be listed, or I may need to grab data from another table. This sometimes creates errors for other functions expecting an array and getting a character value.
  • Dump the session, maybe the session variable was never set, or never started.
  • Form data and POST variables are always good to give a good ol’ var_dump() or print_r().

Obviously this is not all of them, nor is this just a quick checklist. Some of these may take a while to go through, and may have a lot of details to peruse through to find the answer. This will not always give the answer the quickest ways, nor will it ever just shine the answer down to you. But it helps to isolate issues starting form the global level, work down to the application level, and then down to the code level. Plus, it helps eliminate the obvious problems first, so that when someone asks “is the printer is turned on?”, I don’t sit there looking stupid because “it is turned off” and I just never looked. But that is what happens at times.

Today, I completely forgot about permissions on a database. Sure, the code works in development, I have my hands all over that environment. But when it does not work in the staging area, I should have checked permissions instead of just lopping off my hand with endless queries to try and see where the code went wrong. Just one simple act of a GRANT permission to the application user calling the query would have fixed it. But I was forgetful and should have checked that first. Sometimes developers go down the wrong path. To stay down the wrong path, well, you can finish that one on your own.

CakePHP Authentication

After last weeks Auth component, it is now time to go into the full Authentication of a user. In order to use the full power of the Auth component, the table should be named “users”. In the table I created, there were a few different things put in, but for the sake of this, I will limit those.

CREATE TABLE IF NOT EXISTS `users` (
	`user_id` int(11) NOT NULL auto_increment,
	`username` varchar(25) NOT NULL,
	`password` varchar(250) NOT NULL,
	`full_name` varchar(250) NOT NULL,
	`email` varchar(250) NOT NULL,
	`remote_address` varchar(16) NOT NULL,
	`last_login` datetime default NULL,
	`last_login_ip` varchar(16) default NULL,
	`created` datetime NOT NULL,
	`modified` datetime default NULL,
	PRIMARY KEY  (`user_id`),
	UNIQUE KEY `username` (`username`)
) ENGINE=MyISAM  DEFAULT CHARSET=utf8 AUTO_INCREMENT=1 ;

In this table, there is a lot you really do not need, but here is the breakdown: ‘user_id’ is needed for my purposes, ‘username’ and ‘password’ are named as such to be able to use the Auth component methods. The other fields are for personalization (full_name and email). The next three are just for simplistic CYA that should always be good practice, grap the registered IP address, date the user last logged in and the IP they logged in from. Is this a foolproof way of CYA? No. But it starts you out on the right track. The last two I always put in all of my tables, as CakePHP updates those automatically, so this also helps to track when created and when changed.

Now that the table is done, we need to provide some quick validation for registration and such. In the model, the code should look similar to this:

var $name = 'User';
var $primaryKey = 'user_id';
var $validate = array(
	'username' => array(
		'alphaNumeric' => array(
			'rule'		=> 'alphaNumeric',
			'required'	=> true,
			'on'		=> 'create',
			'message'	=> 'Username must be only letters and numbers, no special characters'
		),
		'between' => array(
			'rule' 		=> array('between', 5, 20),
			'on'		=> 'create',
			'message'	=> 'Username must be between 5 and 20 characters',
		),
		'isUnique' => array(
			'rule'		=> 'isUnique',
			'on'		=> 'create',
			'message'	=> 'This username is already taken. Please choose a different one.'
		)
	),
	'email' => array(
		'rule'		=> array('email', true),
		'required'	=> true,
		'message'	=> 'Please provide a valid email address'
	),
);

Continue reading CakePHP Authentication

CakePHP 1.2

I am not sure if this is the new Web 2.0 thing or not, but this version of Cake really ought to be a whole version step instead of an increment. I have been using CakePHP 1.1.x for a few different projects, and now have been messing around with 1.2.0.x for a little while now. A lot has changed in it. The Command Line Interface (CLI) is different than before, so when I first loaded it in then went to the shell to start baking, I was met by errors and messages. I expected to see similar things since this was an “incremental step from 1.1.x to 1.2.x, but there was a huge change from 1.1.x to 1.2.0.7296 RC2.

However, I got past the whole CLI and Baking, and started to continue through the other steps. Some of the ideas I like, and have started to explore are the Auth functionality. Not that this changes around the ACLs or replaces them, but a way to enhance the use of ACLs. In this application, I did not need any ACLs, but this Auth component helps out a lot. In the previous version of Cake, I wrote my own quick Auth component and tied it in with the AppController.php. Now, I just add in the Auth component in the AppController and then in the different controllers I create, I extend it and allow certain actions to be accessed based on login/no login. It does help, but there is still alot to do.

AppController.php:

class AppController extends Controller {	
	var $components = array('Auth');	
    . . . 

users_controller.php:

class UsersController extends AppController {
function beforeFilter() {
		parent::beforeFilter();
		
		// Set User allowed actions.
		$this->Auth->allow('register');
		$this->Auth->autoRedirect = false;
		$this->Auth->authorize = 'controller';
		$this->set('my_id', $this->Auth->user('user_id'));	
	}
	
	function isAuthorized() {		
		return true; 
	}

In the AppController.php I set up the Auth to be used. In the individual controllers, I need to check the allowed actions in the Before Filter function. (I also have some actions in the Before Filter of the parent AppController for sub links, which is why it is inheriting the parent in the users controller. Maybe another post for those?)

In the users controller, I can allow certain actions by using the $this->Auth->allow() function. In this example, I only want people who have not logged in to access the register page. Auth also automatically allows everyone to access login, so there is no need to declare it. I could allow all actions by

$this->Auth->allow('*'); 

But I want to prevent people who have not logged in from seeing the user profile pages.

The next line is to stop the Auth redirect. Once authentication happens, it automatically redirects. I did not want this, so I stopped it by setting it to false. Next, I needed to allow for further checks when authentication happens against the ‘user’ model. Because I set this to ‘controller’, I needed to add the function ‘isAuthorized()’. Right now I have this returning true, which really is pointless as it does no additional checks, as of yet. But I needed to build this on for development when I get the profile model up. When it is up, there will be additional validation taking place.

Last, I am setting a variable based on the current user who has logged in. If there is a log in, then Auth will capture that in

$this->Auth->user('user_id');

NOTE: the ‘user_id’ is the name of the field for the user identifier. In my model/user table, I called it user_id.
This will now set the variable for use in other functions, and when I need to pull data based on this id. It may be a shortcut, it may not be, either way, it is real helpful to be able to call that in the before filter.

This is just one thing I liked about the new version. It may have been in the older version, but I never saw it or used it. But there are other things I really like as well.

Finally back up

After a few years of deliberating and going thru different iterations of site code, I have returned to the WordPress world and will write at the very least, the weekly entry in the blog. This will definitely have some issues as I see, as I am still deciding on the correct theme. But that will all be settled some time soon.

I have set up a few categories as of right now, and may add some more, but may not have to add any at all.

Current projects I am working on includes my full time job working with Fox Entertainment building online applications in PHP. Working with other side projects that include CakePHP for a local non profit organization, developing applications for the iPhone/iPod and another project to develop the plugin applications for those mobile apps on the Mac.

If there are any questions, then let me know.