Validating an images dimensions through Model validation

Since Cake's default model validation really doesn't support files that well, we have to build the methods our self. Right now I will be showing you how to validate an images dimensions. The method will either check the width, the height or both width and height. Simply place the following code in your AppModel.

/**
 * Checks an image dimensions
 *
 * @param array $data
 * @param int $width
 * @param int $height
 * @return boolean
 */
public function dimension($data, $width = 100, $height = null) {
	$data = array_values($data);
	$field = $data[0];
	if (empty($field['tmp_name'])) {
		return false;
	} else {
		$file = getimagesize($field['tmp_name']);
		if (!$file) {
			return false;
		}
		$w = $file[0];
		$h = $file[1];
		$width = intval($width);
		$height = intval($height);
		if ($width > 0 && $height > 0) {
			return ($w > $width || $h > $height) ? false : true;
		} else if ($width > 0 && !$height) {
			return ($w > $width) ? false : true;
		} else if ($height > 0 && !$width) {
			return ($h > $height) ? false : true;
		} else {
			return false;
		}
	}
	return true;
}

To use this validation, you would write it like any other custom validation rule. Lets set up our example view and model validation.

// View
echo $form->create('TestModel', array('type' => 'file'));
echo $form->input('image', array('type' => 'file'));
echo $form->end('Upload');
// Model
class TestModel extends AppModel {
    public $validate = array(
        'image' => array(
            'rule' => array('dimensions', 500, 500),
            'message' => 'Your image dimensions are incorrect: 500x500'
        )
    );
}

Now all you have to do is validate the data using your Models save() or validates() method. If the image fails the dimensions, the error should appear next to the field.

Problems with allowEmpty on files

Since the file support in Cake is lacking, you cannot use allowEmpty equals true. So this means that your image validation fields will always be required. There is currently a Trac bug for this with a quick fix.

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.

Checking if an element exists

So with my new design, I wanted a way to keep all columns around the same height, especially so the middle doesn't look awkward. To do this, I was going to use JavaScript and get the heights of each column and then calculate. A problem was that some pages do not have the right column, so I had to test to see if the column existed. To do that, all you use is the getElementById().

var el = document.getElementById('column');
if (el != null) {
	// Column exists
}

Easy enough now isn't it. I'm not exactly sure how this is done in jQuery, as I couldn't find an answer in the documentation. It is probably done with some selector and traversing magic. Now, to make things easier, we can package this into a function to be reused over and over.

function elementExists(id) {
	return document.getElementById(id);
}
if (elementExists('column')) {
	// Column exists
}

Facebook Usernames: Proof web users are morons

So if you recently logged into your Facebook, you would notice the new Facebook Usernames. These usernames work like any site, where you get to pick your unique url, I'm surprised it hasn't been implemented sooner! But the sad sad sad thing is, is the comments posted by the Facebook users. I have never seen such a cesspool of moronic and illiterate users in my life, no wonder all web developers "dumb down the UI". Currently the blog has 60,000+ comments and 45,000+ likes, but what I to talk about is all the complaints the users are supplying. Lets just list out a few right now.

  • Stop turning into another Myspace
  • Now how will I be able to search/find people I know
  • Usernames will make it harder to remember people

First off I would like to say, WHAT THE *%#?!? Honestly, I never knew how stupid users can be. It's obvious none of these users know a single thing about the web, SEO, networking or the benefits of this implementation.

Stop turning into another Myspace

This is the most ludicrous comment of them all, and it makes up for a good 85% of the comments. Since when did Myspace start the username in the url system? Thousands of websites implement this feature and it has been around nearly since the beginning of the internet. Personally, I think the unique urls are a crux in the web world and should be implemented on any site that has user generated content or social community aspects. This just proves how narrow minded and web illiterate common users are.

Now how will I be able to search/find people I know

Usernames ARE NOT THE SAME as your regular name, the usernames are ONLY FOR THE URLS. You can still search for anyone on Facebook with their regular first and last name OR their username. I fail to see how someone can be this stupid to not understand that.

Usernames will make it harder to remember people

Again, let me reiterate... Usernames ARE ONLY FOR URLS. So let me ask you this, do you remember everyone's current URL right now? This is my URL, and a guess at what my new one will be:

http://www.facebook.com/profile.php?id=672639577&ref;=profile
http://www.facebook.com/miles.johnson

Now how the *%@$ is that more difficult to remember? I know damn well you don't remember everyone's user id, now stop complaining.

I could keep going on about Facebooks users, but I don't want to write a book. I slowly lose faith in web development and the direction it will be heading if all users are like this. I'm done ranting, I feel sorry for you Facebook.

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!)