Code snippets now available

So over the years I have written many small code snippets, functions and what have you, and thought it would be a good idea to release them to you guys. I use most of these snippets on my own projects and applications and are great to be re-usable everywhere. Most, if not all the snippets, will deal with PHP and Javascript, however I have thrown in some CakePHP and jQuery ones.

View all 21 code snippets

Ajax Handler

On top of releasing my code snippets, I have recently made my AjaxHandler component available. The component can be placed in any CakePHP application and then applied to specific controller actions to handle them as Ajax requests. The handler does nearly everything automatic and even responds with the correct data structure and content type.

Check it out and let me know what you think!

Download the Ajax Handler

Feed Aggregator Component officially released!

I recently needed the ability to display a list of feed items, but the catch was I needed them to be combined from multiple feeds, a feed aggregator. At first I was expecting to find this in the bakery, but was saddened when there was none. So I sat down and began coding. I've never created a feed aggregator before, but it was relatively easy.

Its really simple, the script is a CakePHP Component that will take a list of feeds and aggregate them into a single array based on their timestamp. It works with RSS 1.0 (RDF), RSS 2.0 and Atom 1.0 and has the ability to cache its results.

View full documentation and download version 1.1

Enjoy! Let me know if there are any bugs.

Protecting your forms with the Security Component

Many users are unaware of this feature as it is not stated within the Cookbook, but the SecurityComponent by default will secure and protect your forms (if you have added Security to the $components array). What does that mean you ask, well it's simple. The Security will add hidden token fields within all your forms that will protect you against many types of robots. An example of a token field can be seen below.

Array
(
    [_Token] => Array
        (
            [key] => 40bbf3ac6cb4cd9bfaa617c088aa938bb398e80f
            [fields] => b5a93a2492bd2e6016856828d8046ba1f6f6200b%3An%3A0%3A%7B%7D
        )
)

These token fields are a dynamically generated hash, based on all the fields currently available in a specific form. On top of this, the Token will only last for a limited duration, so if your session takes forever on a certain form, you will be blackholed. Now on to the term blackhole, this basically means your form will post to a blank/white page and will fail.

Using Javascript to change input values

If you use Javascript to change a hidden inputs value, the Security will blackhole the form because it checks to see if any hidden fields have changed values (if it has, its usually a bot). To bypass this check, you would add this code to your controllers beforeFilter(). The array should consist of the field names you DO NOT want the Security to validate, so in this case it would be the name of our hidden field.

$this->Security->disabledFields = array('hiddenfield1', 'hiddenfield2', 'randomfield');
Not validating a form at all

If you have Security enabled, but do not want it to validate a certain form, you would set validatePost to false in your beforeFilter(). This is MANDATORY if you are doing any type of Ajax requests.

if ($this->params['action'] == 'actionName') {
	$this->Security->validatePost = false;
}
// Ajax requests
$this->Security->validatePost = false; 
if (!$this->RequestHandler->isAjax()) {
	$this->Security->blackHole($this, 'You are not authorized to process this request!');
}

And that is all, simple isn't it? All it requires is you adding the SecurityComponent to your controllers $components and a bit of magic on your end.

Official release of the AutoLogin Component

Many of you have heard me mention a component that keeps your Auth session active, even after the browser is closed. Well I think its time to officially announce it, my AutoLogin component. This component ties into the Auth component and allows a user to "remember me" to keep them constantly logged in. All data is saved to cookies and encrypted and hashed to no hijacking can occur. The best part though, is that the component automatically and magically saves and deletes cookies without you having to configure it (although you can configure it, check out the docs).

Download the latest version of AutoLogin

In other script related news...
Commentia has been updated to v1.3
Resession has been updated to v1.8 (now with more Security!)

Using CakePHP's Auth Component

This article pertains to CakePHP 1.2 only!

Since recently diving into CakePHP, I thought the best area to learn would be the user authentication and login. Luckily CakePHP comes bundled with an Authorization Component, and is literally the easiest thing to install. Below I will show you the basics of getting Auth working; do note that I was working in CakePHP 1.2 and PHP 5. To begin the following items must be implemented:

  • Database - A users table with the fields id, username and password (can be customized but recommended)
  • Controller - A users controller with a login and logout action
  • Model - A user model that correlates with the users table
Setting up AppController

The first thing we need to do is setup the AppController. We are placing the code in the AppController so that all child controllers inherit the AuthComponent. Begin by including the AuthComponent by binding it to the $components parameter. We will now create the beforeFilter() action that will hold all the Auth settings that will be passed to the child controllers.

<?php
class AppController extends Controller {
	public $components = array('Auth');
	public function beforeFilter() { 
		Security::setHash('md5');
		// Authenticate
		$this->Auth->loginAction = array('controller' => 'users', 'action' => 'login');
		$this->Auth->loginRedirect = array('controller' => 'dashboard', 'action' => 'index');
		$this->Auth->loginError = 'No username and password was found with that combination.';
		$this->Auth->logoutRedirect = '/';
	}
} 
?>

In the beforeFilter() action above, you will notice 4 different variables being set. loginRedirect determines what controller/action pair to redirect to upon a successful login, where as logoutRedirect is the route to redirect to when logging out. loginAction is the controller/action in which your login form and processing will be taking place (its best to use CakePHPs defaults of /user/login/). For more information on these variables and additional variables, visit the corresponding cookbook page.

Setting up the UsersController

The next step is to create the UsersController and create the required actions. Within the login() action, there is no need to do any manual form processing or login, the auth system does that magically behind the scenes. You can literally leave this action empty, unless you wish to add a page title $this->pageTitle or validate it against the User model. Within the logout() action we run a redirect to the auth system, which logs us out and redirects to the logoutRedirect we specified in the AppController.

<?php
class UsersController extends AppController {
	public function login() {
		// No form processing needed, Auth does it automatically
	}
	public function logout() {
		$this->redirect($this->Auth->logout());
	}
	public function beforeFilter() {
		parent::beforeFilter();
		// Does not require being logged in
		$this->Auth->allow('signup', 'forgot');
		// If logged in, these pages require logout
		if ($this->Auth->user() && in_array($this->params['action'], array('signup', 'login'))) {
			$this->redirect('/');
		}
	}
}
?>

Now you may see some additional code; another beforeFilter()! This beforeFilter() is specific only to the current controller. It is extremely important to place parent::beforeFilter() in the action so that the parent beforeFilter() can initialize the AuthComponent. The allow() method takes arguments of actions (within the current controller) that do not require you to be logged in to view. Beneath that you will see some custom code that I have written. This code defines actions that require you to be logged out to view (it seems auth does not have anything for that). There are additional methods you can read about in the cookbook.

Creating the form

This is probably the easiest step of the process. Simply use Cake's built in HtmlHelper to build the form. Be sure to name the form after the model you are using for auth (e.g., User).

<?php 
echo $form->create('User', array('url' => array('controller' => 'users', 'action' => 'login')));
echo $form->input('username');
echo $form->input('password');
echo $form->submit('Login');
echo $form->end(); 
?>
Adding additional functionality

There are a couple ways to increase the functionality of the AuthComponent. Typically when you login, the user information in the database that matches the username/password combo is then stored in the AuthComponent. To retrieve the users information you would use the method $this->Auth->user(). A nice way of doing things is binding a $user variable to all views so you can access the users data.

// app_controller.php
public function beforeRender() {
    $this->set('user', $this->Auth->user());
    // In the views $user['User']['username'] would display the logged in users username
}
// controllers/users_controller.php
public function beforeRender() {
	parent::beforeRender();
}

If you would like to use a different model with the AuthComponent, you would add a $this->Auth->userModel variable in AppController::beforeFilter(). You can also add some additional conditions to the login query, for example, making sure a user is active.

$this->Auth->userModel = 'Member';
$this->Auth->userScope = array('User.status' => 'active');
Debugging problems

While working with the AuthComponent, I ran into one major problem. If you are using an old database that is ported over to use CakePHP and you did not use a password salt on the old passwords, be sure to disable Cake's salt (or leave it empty). I didn't realize this for nearly 2 days on why the passwords did not match and then it hit me, Cake's salted passwords will not match existing passwords. If this is a new database, no need to worry about the previous statements.

If for some reason you cannot have a field labeled username or password within your database, there are ways to set it to something else. You would do that by setting the $this->Auth->fields variables in AppController::beforeFilter(). For more information on this subject, visit the trouble shooting in the cookbook.

$this->Auth->fields = array('username' => 'email', 'password' => 'secretpass');
Conclusion

I hope this has been helpful to someone! I spent days debugging and installing this system and by doing so I learned the system in and out. If you have any questions be sure to leave a comment or drop a line by using the contact form. Thanks again for reading, come back for more tutorials!

Debugging the CakePHP Auth Component

Finally, I figured it out. For the past 2 days I have been messing with the CakePHP AuthComponent (A prebuilt user login and authentication system). The problem was that it would not log in, even though I was entering correct data from the database. I spent many hours and even posted on the Google CakePHP Discussion group. Even with their help it still would not work, but I found the problem!

CakePHP comes with a password salt feature that automatically salts and encrypts any index called "password" within an array. The problem was that the previous passwords in the database were not encrypted with a salt, so hence the passwords never matched! Once I made the Cake salt empty, it worked in all its glory. I will be posting up a tutorial this week on how to use the AuthComponent, for anyone who was as lost as me trying to get it working.