Static File Version Control in CakePHP

Friday, December 7th, 2007

One of the problems I’ve had is how to push updates to static files like javascript and content style sheets. If you want to program for performance you have to use a far future expires header to cut down on HTTP requests. The downside to this is that when you update your script and it has the same file name, the users browser wont know that its updated. Entity tags still involve a HTTP request even though the cut down drastically on the data usage.

The tedious way to fix this is to put the version number in the filename and change every layout to link to the new file.

One of the ideas I brainstormed was to add a GET to the URL in each layout that prints out the build/version number. This is an OK fix in that I only have to update my app/config with the new version number but the downside is that the user has to redownload every static file again even if it hasn’t been updated. I could make version numbers for every static file. This is kind of tedious because I have to program a different version number into every layout.

Then it dawned on me that I could override the built in helpers like $javascript->link() and $html->metalink() combined with a simple array with the name of script and the build number to do version control for me.

so a config file like:

$versions = array(’myscript.js’=>’BUILDNUMBER’,'another.js’=>’BUILD2′);

In a layout:

$javascript->link(’my_script.js’)

becomes

<script type=”text/javascript” src=”/js/my_script.js?ver=BUILDNUMBER”></script>

By using a GET the browser is fooled into downloading the file without having to deal with a mess of older files which should be inside some sort of version control system anyway.

I’ll post the code I used later this week when I complete it. If something like this has already been created for CakePHP, I’d like to hear about it.

First Project Takes off

Monday, November 12th, 2007

Its been about 10 days since I started my cool pictures project. I’ve added a lot of new features like an RSS Feed, sitemap, stats and easy navigation. I still want to give people the ability to upload and create their own niche communities. I have a few other ideas that I’ll keep under wraps for now.

In the last 3 days over 9,000 unique IPs have been to the site and viewed 66,000 images and consumed 10 gigabytes of bandwidth. The majority have come from Stumble Upon which is a really great tool bar. I’ve been using it for about a month already and I usually read things before they ever appear on the other big social bookmarking sites. Personally, I think SU is what Digg should have become.

Cron Job in CakePHP 1.2

Monday, November 12th, 2007

After looking around the net for a way to execute cakephp scripts via a crontab I became fed up and made my own solution. I simply added a function to my existing controller and then executed it via a wget.

class PostsController extends AppController
function crontab {
// 404 if the request isnt from the localhost
if($_SERVER(’REMOTE_ADDR’) != ‘127.0.0.1′))
{
$this->cakeError(’error404′);
exit; // dont know if this is needed
}
// execute the cronjob
doSomething();
exit; // dont want to use a view
} // end controller

Now we just make a cron job to run every five minutes

wget –spider http://mydomain.com/posts/crontab

Proof of Concept Project Released

Saturday, November 3rd, 2007

Rabbit AttackMy first proof of concept project, cool pictures has been added to the sub domain of this website. The site is fairly simple and most of the magic comes from behind the scenes to easily post images in a single click. I used the CakePHP framework to complete it in about two days.

There is still a few changes I want to make and features I want to implement. I’m planning on releasing 3-4 more small projects of similar scope before I move on to the three main ideas I plan on implementing.

I’m hoping to have one of my other projects out next week.

Cakephp unique validation in 1.2

Friday, September 21st, 2007

A little disclaimer: I could be totally wrong because I’m still learning the ins and outs of CakePHP.

I don’t like the current solution for validation of unique fields in the 1.2 CakePHP AppModel mainly because I couldn’t get it to work so I created my own. Sorry about the formatting, I’ve never posted code in my blog before and not being able to properly indent the code isn’t a big concern for me. The code was inspired by the comments between speedmax and cakebaker on his blog.

// YourModel.php
var $validate = array( // validate our username and email
'username' => array('rule' => array('alphaNumeric')),
'email' => array('rule' => array('email'))
);
function beforeSave() {
$check = array('username','email'); // username and email are unique
return $this->checkUnique($check);
}

The code above specifies username and email as unique values and will check for them in the database before we save. Below is my modified app model.

// AppModel.php
class AppModel extends Model {
function checkUnique($myUnique) {
$sql = "";
foreach($myUnique as $name ) {
if($sql!="") $sql.=' OR ';
$sql .= $this->name.".$name=\"".$this->data[$this->name][$name].’”‘;
}
$found = $this->find($sql);
$same = isset($this->id) && $found[$this->name]['id'] == $this->id;
return !$found || $found && $same;
}
}

Now in the controller all you have to do is save your data.

if($this->YourModel->save($this->data)) {
// success
} else {
// failure
}

The code runs save() -> validate() -> beforeSave() -> checkUnique() and wont save to mysql if validate or beforeSave is false. I think the code is a little more strait-forward compared to making countless arrays within arrays.