@madpilot makes

Image verification for comments in WordPress 2.0

I’m sick of blog spam. It is such a pain to have to mark it all as spam (And what exactly does that function do? I’ve seen the same spam come through many times, so it doesn’t seem to learn…)

Anyways, here is my quick and dirty hack to add a image verification box on the comments page (Warning WordPress hack ahead – I’ll bother to learn the plugin system one day…)

This hack requires the following PHP libraries installed on your server: Freetype, GD and mcrypt.

Create a new file in $PATH_TO_YOU_BLOG/wp-image-verify.php

Insert the following code:

<?php
  require( dirname(__FILE__) . /wp-config.php’ );
  $verifier = $_REQUEST[‘verifier’];
  $display_string = decrypt($verifier);
  $image_details = imagettfbbox (10, 0, /usr/share/fonts/TTF/tahoma.ttf’, $display_string);
  $image = imagecreatetruecolor($image_details[4]  $image_details[5], (0  $image_details[5])  (0  $image_details[3]) + 1);
  imageantialias($image, true);
  $background = imagecolorallocate($image, 255, 255, 255);
  imagefill($image, 0, 0, $background);
  imagettftext($image, 10, 0, $image_details[0] + 1, 0  $image_details[5], imagecolorallocate($image, 119, 119, 119), /usr/share/fonts/TTF/tahoma.ttf’, $display_string);
  header(“Content-type: image/png”);
  imagepng($image);
?>

Note – you will probably (ok will) have to change the path of the font as /usr/share/fonts/TTF/tahoma.ttf is a font I copied from my windows directory.

Open $PATH_TO_YOU_BLOG/wp-comments-post.php and add the following lines at around line 25:

$verifier = trim($_POST[‘verifier’]);
$verifier_compare = decrypt($_POST[‘verifier_hash’]);

Open $PATH_TO_YOU_BLOG/includes/comments-functions.php and add the following lines at the top of the file:

// image verifier functions – by Myles Eftos
$key = “afedss”; // Enter a 5 character string
$iv = “sdfesdf”; // Enter a 7 character IV
function random_string($length = 6) {
  $str = ;
  for($i = 0; $i < $length; $i++) {
    $str .= chr(rand(ord(‘A’), ord(‘Z’)));
  }
  return $str;
}

function encrypt($string) {
  global $key;
  global $iv;
  return base64_encode(mcrypt_encrypt(MCRYPT_DES, $key, $string, MCRYPT_MODE_ECB, $iv));
}

function decrypt($string) {
  global $key;
  global $iv;
  return chop(mcrypt_decrypt(MCRYPT_DES, $key, base64_decode($string), MCRYPT_MODE_ECB, $iv));
}

All done :)

Things to think about when sending email

I, like most other people in the world receive a lot of spam. I do have a spam filter, but it isn’t perfect, and errs on the side of caution – and for good reason. It is my business account and I don’t want to miss any potential leads. This does mean that I still receive a number of spam emails a day. Now most of these are obvoious spam mails, but a couple have come through that were legitimate. The only reason I opened them is because something about the name or subject triggered a response. Unfortunately, this isn’t always the case.

So here are a couple of things to think about when sending emails out to other people:

  1. Use your FULL name. That includes both a first name and surname. Getting an email from “Joe” makes me think it is spam. “Joe Bloggs” is better. This is especially important if you have a common name and if you are emailling someone for the first time.
  2. Take some time thinking about a decent subject line. Avoid common spam terms like “Hey” or “Hi
  3. To take the subject line thing further – don’t just reply to an un-related email. It makes searching a pain in the arse. I had one client who would do this and when I was searching for a particular email I had to sift through 400 emails all entitled “Re: “.

Anyone think of any more?

Indenting highlighted source code with WordPress 2.0

Ok, after going away and thinking about the problem, I came up with a quick and dirty (But seemingly effective and compliant) way of doing the indenting. It does require a small modification to the GeSHi code. I’m going to use an empty inline tag (ins tag – which stands for insert – how appropriate…)

Open the geshi.php file (See my previous post about code highlighting in WordPress 2.0 if you have no idea what I’m talking about) and find the indent function. Search for all the nbsp elements and replace with:

<ins class="in"></ins>

Now open the insertcode.css file and the style.css (in your theme) and add:

ins.in {
  margin-left: 15px;
}

Voila! indenting. The output looks like this:

<?php
echo "hello" . world();
function world() {
  return "world";
}
?>

A few more notes: html and xml highlighting is pretty well broken unless you add a erroneous space between the angle bracket and the tag (See this example) and don’t try to use special characters. I’m currently tweaking the colour coding classes to make them look nicer too. I’ll post these when they are done.

WordPress 2.0 mod: Insert highlighted code.

I have complained before about not being able to insert source code into WordPress when using the TinyMCE Rich Text Editor. Sure, I could switch to plain text mode, but frankly I would prefer an RTE as it makes entering posts much quicker. There is a TinyMCE plugin called insertcode written by by Maxime Lardenois which does exactly what I wanted. In fact, it even uses the GeSHI cde highlighter class (written in PHP) to do code highlighting. There is something like 50 different languages which are supported – Very cool.

Unfortunately, installation was not quite as simple as I hoped. Here is what I had to do (Substitute [blog_root] with the absolute path to your wordpress install):

  1. Untar the GeSHI tarball and copy the geshi.php files and geshi directory to [blog_root]/wp-includes
  2. Unrar (yes rar) the insertcode RAR file to [blog_root]/wp-includes/js/tinymce/plugins/insertcode (Create the insertcode directory first)
  3. THe RAR file I go didn’t have a directory structure – I don’t know whether I just messed up or what, but I had to create the following directories: config, css, images, jscripts, langs, webservice
  4. Copy config.php into the config directory, insertcode.css into the css directory, insertcode.gif into the images directory, insertcode.js into the jscripts directory all the php files into the webservice directory and all of the language files (e.g. en.js) into the langs directory. You should only have editor_plugin.js editor_plugin_src.js and insertcode.htm files in the insertcode dir.
  5. Open get_highlighted_code.php and change the $geshi->set_header_type(GESHI_HEADER_PRE) to $geshi->set_header_type(GESHI_HEADER_DIV)
  6. Open [blog_root]/wp-includes/js/tinymce/tiny_mce.gzip.php and find the line $plugins = apply_filters – add ‘insertcode’ to the array
  7. Still in tiny_mce.gzip.php add ‘insertcode’ to the line that starts with $mce_buttons = apply_filters
  8. Finally add the following to lines to the initArray javascript array:

content_css : “/[blog_url_path]/wp-includes/js/tinymce/plugins/insertcode/css/insertcode.css”,

encoding : “xhtml”,

This should add a new button to your toolbar with the letter “C” into. Pressing the button should pop a dialog box in which you can cut and paste code.

To make it look nice on the front end cut and paste the contents of insertcode.css into you themes’ style.css file:

That SHOULD be it.

<li class="li1">
  <div class="de1">
    [echo</span>](http://www.php.net/echo) print_message<span class="br0">(</span><span class="br0">)</span>;
  </div>
</li>

<li class="li1">
  <div class="de1">
    <span class="kw2">function</span> print_message<span class="br0">(</span><span class="br0">)</span> <span class="br0">{</span>
  </div>
</li>

<li class="li1">
  <div class="de1">
    <span class="kw1">return</span> <span class="st0">&#8220;Hello World!&#8221;</span>;
  </div>
</li>

<li class="li1">
  <div class="de1">
    <span class="br0">}</span>
  </div>
</li>

<li class="li1">
  <div class="de1">
    <span class="kw2">?></span>
  </div>
</li>

You will notice that the indentation gets stripped – this is (I think) a WordPress thing. I’ll post a solution once I figure one out :) Also, it can be a little tempermental – you have been warned. And as always: YMMV.

Edit: I’ve fixed the indent bug: check out this post.

3rd Degree e-news site publishes it’s first edition

The Edith Cowan University journalism students have launched the first edition of 3rd Degree – an online e-news site. The site was designed by Paul Bui and was developed by me in CakePHP.

The site allows the 3rd year students to understand the pressure of publishing a weekly news publication, with different teams controlling different parts of the process. If you would like to receive the weekly newsletter, you can register here.

3rd Degree is the brainchild of Kayt Davies, who is the lecturer in the unit.

New port80 event announced.

Port80 – the Australian Web Industry, of which I’m the membership officer has announced the next event – Ideas3.

The event features John Allsop from Sydney, who is a directory of Westciv, creators of Stylemaster; and Mark Boulton from the UK who is a noted typographer and designer who is currently working at the BBC.

For those of you who aren’t in Perth for the event on April 11, we will be posting the podcasts and photos after the event.

As an aside, the new Port80 site, which drives the event and memeber management systems was written by me in CakePHP.

Interested in starting a Port80 group in your local area? We are currently preparing an information pack. Port80 started as a way for web designers and developers in Perth could catch up in a casual, informal environment – usually at a pub. It is amazing how well it works – it’s a great way to meet other like minded people. You can read a better history on the Port80 website. Don’t forget to check out the port80 forums too!

Adding automatic JavaScipt validators to CakePHP

I’m reposting the validators.php file that I uploaded in my previous post, but this time adding a function that will automatically generate a javascript function called validate() that returns an array of error strings. This is made possible because CakePHP’s validation model uses regular expressions.

NOTE: This function has been written using my modified validator class. Please read my previous post to see what it is all about.

The strings and expressions are identical to the ones you get by callling $this->modelName->validates() in a controller, so you can avoid a round trip to the server in many cases.

To use, drop the validators.php into your app helpers directory (as before), and call the function $validators->javascriptErrors(‘modelName’); where modelName is the name of the model you want to pull the validation data from. For those of you playing at home, you may notice that the $modelNames variable gets converted to an array – this is because you can actually supply an array of modelNames if you need to validate the inputs from multiple models. Why? I had a need for it in a project, which I might go through later :)

Now, this isn’t quite complete, because it only returns an array of strings, you still need to output the string somehow. I usually output the strings to div, as I hate JavaScript alerts. The code for which is here. In that file I have defined a function called validateForm(form); which updates the div and returns false on an error, so you can use it in the onSubmit handler for the form.

Improved validation using CakePHP

I quite like CakePHP – in fact, I find it rather difficult to do site without it now. It makes everything so much easier, especially the ActiveModel classes. However, I have found the validation model a little lacking. The way it is currently implemented only allows one validation expression for each database column, and you need to re-write the validation message on each page the model is used on. This is quite restrictive and error prone – if you need to add a field to the database, you have to update more than one page.

I have managed to modify the way the validators work, so that you can define a message and have multiple validation expressions for each field.

I used the modifications on the AccountancyAge Careers Fair by modifying the model.php file that lives in the Cake library directory and it worked really well, but I wanted to set it up so that I didn’t have to modify these files everytime – It is really inconvienient to have to re-make the changes when updating the library. This is expecially a problem at the moment, because there seems to be a new release candidate every other day (Which is great – can’t wait for version 1!)

Anyway, after a little digging, I found that it is possible to override the app_model.php file in the same way as you can override the default app_controller.php file. By placing a copy of the file in the app/ directory, Cake will use this file instead.

The modification

The modification as it stands overrides the invalidFields function of model.php (this is based on RC3 – RC4 should work ok as well). You can download the new app_model.php here.

To define validation rules, you add an associative array with the paramaters expression and message. This is probably best explained using an example. Say you have a required field called “post_code” that must not be empty and must be 4 digits, you could do the following:

var $validate = array(

‘post_code’ => array(

array(‘expression’ => VALID_NOT_EMPTY, ‘message’ => ‘You have not entered a post code’),

array(‘expression’ => ‘/d{4}/’, ‘message’ => ‘A postcode must be four digits’)

)

);

Easy as! There is one last thing though. To make it easier to display the messages, I have created the following user helper called validators.php (Drop it in to app/views/helpers) (Download validators.php here)

To use, you put the function < ?php echo $validators->tagErrorMessages() ?> (Don’t forget to include Validators in your helper array) which will generate a block message wrapped in div tags with the class “message”. You can customise this file if you don’t like the way it is displayed.

Happy baking :)

Review: Siemans SpeedStream 6520 ADSL2+ Modem Router

With my move to my new house/office, and with Amnet offering static IPs on their ADSL 2 plans it has become time to retire my trusty Alcatel ADSL modem and WRT54G modem/router combination. I went through this process about a year ago when I blew the power supply on my WRT54G and was not impressed with the quality of many of the routers out there. Instead, I modified another power supply and got a UPS (I learnt my lesson)

Anyway, my luck hasn’t changed. Amnet offer a Siemans SpeedStream 6520 with their accounts, so I thought I would give it a go. As far as I can tell, this modem/router is only being offered by Telstra and Amnet as a package and as a result, you can’t purchase it from a retail store.

Problems:

  • The router doesn’t seem to handle persistent connections well. If I open an SSH session, it will often drop out after a period of inactivity – using the PuTTY “keep-alive” feature fixes the problem, so it isn’t the quality of my connection. The same occurs with my Outlook IMAP connection. Very annoying.
  • It doesn’t support port forwarding beyond DMZ – not a huge problem, but I liked this feature of the WRT54G
  • For some weird reason, my VoIP software – eyeBeam, can’t connect through the firewall. It’s little brother, X-Lite works fine, but eye-Beam is so much better I’m quited annoyed at this. Note this may not be a problem with the router, but it worked fine with the WRT54G.

I’ve asked for a refund for it and have ordered a Linksys WAG54Gv2 which is the combination big brother of the WRT54G. Hopefully Linksys is on other winner with this product. I’ll let you know.

Australia Day

Australia Day is my favourite holiday of the year. What has happened in previous years is we would all assemble at Trashy Central for the world famous potato salad contest. It is amazing how, when you say you are having a potato salad contest, ever persons response follows the lines of “I make the best potato salad EVER!” Judged by the party host, the winner gets taken to the restaurant of their choice.

Then down to the foreshore to watch the fireworks, whilst the host stays back to prepare for party: Stage 2.

The party continues once everyone meanders back up.

What happened this year? I worked. It was for a UK client, so cries of “But it’s Australia day!” went unheeded. So I spent the day in front of my laptop, with the TripleJ hottest 100 blaring.

I did mange to finish by 6 and walk down to Maylands (Just down the road now that we are in Mt Lawley) with Giovanna and her family to watch the skyworks – so not all was lost. Still would have been nice to hang with the Knutsfords though :(

Next year – I’m partying!

Previous Next