Christer’s blog o’ fun

June 28, 2008

Zend_Service_ReCaptcha in the standard incubator

Filed under: PHP, Technology — Tags: , , , , — christer @ 11:24 am

I imported the Zend_Service_ReCaptcha stuff to the Zend Framework standard incubator yesterday. You can access it from the subversion repository at http://framework.zend.com/svn/framework/standard/incubator/library/Zend/Service/.

The component also includes a class to use the mail hide feature over at recaptcha.net that allows you to render an email address as something like user…@foo.com and the reader has to solve a recaptcha to see the complete email address.

No documentation has been made yet but I will include some basic usage of the component in this post.

Display a ReCaptcha in a form

First you need to register at recaptcha.net to get a set of public/private keys for the domain you want to use the recaptcha on. If you develop something locally and you use localhost as hostname you will need to register localhost on the recaptcha site to get the keys. Once you have the keys you are good to go!

When displaying the captcha you will only need the public key. The private key will be used when you verify the user input to see if a user has solved the captcha or not.


<?php
/** @see Zend_Service_ReCaptcha */
require_once 'Zend/Service/ReCaptcha.php';

$publicKey = 'my public key from recaptcha.net';
$reCaptcha = new Zend_Service_ReCaptcha($publicKey);
?>

<html>
    <head>
        <title>ReCaptcha test</title>
    </head>
    <body>
        <form action="" method="post">
            <?= $reCaptcha ?>
            <input type="submit" name="submit" value="Submit" />
        </form>
    </body>
</html>

Replace the public key with your own public key and you will see something that hopefully resembles this screenshot:

Zend_Service_ReCaptcha

Verify the user input

Now that we have our recaptcha in place we need to verify the user input. To do that we have to expand the block of php code at the top of our example here a bit.

PS! The syntax highlight plugin manages to write !emptyempty in the code below, so you’ll need to fix that if you copy the code.


<?php
/** @see Zend_Service_ReCaptcha */
require_once 'Zend/Service/ReCaptcha.php';

$publicKey = 'my public key from recaptcha.net';
$reCaptcha = new Zend_Service_ReCaptcha($publicKey);

// See if the form has been posted and that the two fields from the
// recaptcha are not empty
if (isset($_POST['submit']) &&
    !empty($_POST['recaptcha_challenge_field']) &&
    !empty($_POST['recaptcha_response_field']) ) {
    // Set the private key. We need this to verify user input
    $privateKey = 'my private key';
    $reCaptcha->setPrivateKey($privateKey);

    // See if the input is valid
    $response = $reCaptcha->verify($_POST['recaptcha_challenge_field'],
                                   $_POST['recaptcha_response_field']);

    if (!$response->isValid()) {
        // Not valid. Add the error message from the recaptcha web service
        // to the recaptcha object so it will be shown in the recaptcha
        $reCaptcha->setParam('error', $response->getErrorCode());
    } else {
        // Success! The recaptcha has been solved
    }
}
?>

<html>
    <head>
        <title>ReCaptcha test</title>
    </head>
    <body>
        <form action="" method="post">
            <?= $reCaptcha ?>
            <input type="submit" name="submit" value="Submit" />
        </form>
    </body>
</html>

And thats it!

Hide email addresses with Zend_Service_ReCaptcha_MailHide

If you need to display an email address you can hide parts of it using the Zend_Service_ReCaptcha_MailHide component. You need a separate pair of public/private keys for this so head over to recaptcha.net and grab those keys.

Lets say we want to hide mynewemailaddress@domain.com. Do something like the following piece of code:


/** @see Zend_Service_ReCaptcha */
require_once 'Zend/Service/ReCaptcha/MailHide.php';

$publicKey = 'my public key';
$privateKey = 'my super duper private key';

$mailHide = new Zend_Service_ReCaptcha_MailHide($publicKey,
                                                $privateKey,
                                                'mynewemailaddress@domain.com');

print($mailHide);

The output of this will be myne…@domain.com except that the “…” part will have link to a JavaScript popup that displays a recaptcha, and once the user solves it, the complete email address will be displayed.

So … feel free to play around with the component and if you find some errors or feel that something is missing, let me know! I will add some more stuff about custom themes the next couple of days and maybe make a Zend Framework theme for the recaptcha.

June 25, 2008

Enforcing a PHP coding standard using PHP_CodeSniffer - Part 1

Filed under: PHP, Technology — Tags: , , , , , , — christer @ 9:45 pm

This is the first part of a rather exciting trilogy (a thriller if you may) on how to use the PHP_CodeSniffer component from the PEAR repository to force developers to follow a set of coding standards before allowing them to commit code to a Subversion repository. This can also be accomplished using other Version Control Systems (VCS’s) but I will focus on Subversion. In this part of the trilogy I will explain the importance of having a coding standard, and I will give you a short introduction on how the PHP_CodeSniffer component works and some basic usage of it.

Let’s get on with the show!

When working together with other developers it’s important to agree on some sort of coding standard (not only in PHP). Why is this important you say? You don’t always get to play with stuff you have written yourself. Whenever you are to debug code that someone else wrote, wouldn’t it be great to know that he/she writes code that at least looks like your own?

Using a coding standard doesn’t force developers to solve problems the exact same way, but it might make the solution easier to read for other developers. It might also help developers from doing some pretty nasty errors. Let’s say you have the following piece of code:


if (isset($_COOKIE['userId']) && isset($_COOKIE['userSecret'])) {
    $actualUserSecret = fetchUserSecretCode($_COOKIE['userId']);

    if ($actualUserSecret = $_COOKIE['userSecret']) {
        // ok … the secret code in the cookie is the same as the one
        // returned from the fetchUserSecretCode function. Let's login
        // the user

        // …
    }
}

Now … the code above is all valid, but it contains a pretty nasty bug. The line that says:


if ($actualUserSecret = $_COOKIE['userSecret']) {

is missing an equal sign, so it will always evaluate to true, which in this case will log in the user with the user id from the cookie. If you want to log in as other users you could just change the user id in the cookie, and make a new request, and voila!

This bug is pretty hard to identify since the developer who wrote it probably just didn’t press the equal sign hard enough the second time and the code produced it still valid. The developer “knows” that the error has to be somewhere else and doesn’t even look in the right place. Some of you reading this is probably saying something like: “Come on, nobody will ever manage to do something that stupid!?”. The reason I chose this as an example is because yours truly exploited this “bug” in someone’s code once, so yeah … it’s possible to write something like the example above.

Another issue is when users start to mix up tabs and spaces for indentation and have different editor settings. If you open up a script that has both tabs and spaces used for indentation and your editor has a different tab width than the one who used spaces as indentation all hell breaks loose. Suddenly you won’t even get to order breakfast from your favorite Whammy Burger because you had to spend five extra minutes removing someone’s tabs and, well, we all know what happens next…

What has this got to do with a coding standard? What if the coding standard you were said to follow specified that doing assignments inside an if-test was illegal or that the use of tabs as indentation (or tabs in your code at all) were strictly forbidden? Wouldn’t that fix this issue? That depends on how you deploy the code you are writing. To be able to enforce a standard you need to attach a check that finds out if the code you are sharing with other developers adheres to some standard. Subversion (and other VCS’s) will let you add “hooks” to different events that occur. The event we would like to attach the coding standard check to is the one that occurs before the changes in code actually gets pushed to the repository: the pre-commit event. This event, as it’s name clearly specifies, happens before the commit is done, and it has the power to stop the commit from happening.

The next question is how do we actually check the code against a standard? This is where the PHP_CodeSniffer component comes into play. As its name implies, it will actually sniff PHP code. You might have heard Ramones singing something about wanting to sniff some glue… I’ll let you in on a little secret: The original lyrics actually went a little something like this:

Now I wanna sniff some code
Now I wanna have strings to explode
All the kids wanna sniff some code
All the kids want strings to explode

Let’s get on with the show and start sniffing that code!

PHP_CodeSniffer uses something called sniffs and tokens to pull this off. A Sniff is actually a PHP class that checks one part of the coding standard only. A coding standard in PHP_CodeSniffer is a collection of these sniff classes. One example of a sniff is: “Disallow Tab Indentation”.

A token is an internal representation of a part of userland PHP code. Most of you have probably seen a token in an error message. If you do something like:


$foo = 'foo'
$foobar = $foo . 'bar';

you will get “syntax error, unexpected T_VARIABLE in … ” because you forgot to end the first line with a semi-colon. This actually shows us that some error messages in PHP aren’t all fun and games, but that’s a different story…

The T_VARIABLE part of the error message is as some of you might have guessed a token. PHP_CodeSniffer uses the Tokenizer extension in PHP to generate tokens of the PHP scripts it gets as input and the sniff classes you implement can use these tokens to analyze the input and see if it is correct according to the coding standard.

PHP_CodeSniffer comes with some complete coding standards and enough predefined sniff classes to let you define your own standard by using only predefined sniffs. If you simply want to follow the PEAR coding standard you can use the one that comes with the component. The component also includes a couple of command line scripts (Linux and Windows) that will let you examine your code with little effort.

Since the component belongs to PEAR, the default coding standard is PEAR (no shit Sherlock!). If you also want to use the PEAR standard on your code you can issue the following command (on Linux):

php /path/to/phpcs /path/to/script.php

PHP_CodeSniffer will then analyze script.php and see if it follows the PEAR standard. If not, you will get a bunch of errors informing you on the parts of your code that is different from the standard. If you have lots of code inside a directory you can simply use the name of the directory as argument to the phpcs script instead of the single script name. If you want to use some of the other coding standards that comes with the component you can do so by adding the –standard=<standard> argument. To use the “Zend” standard on a directory of code you can do something like this:

php /path/to/phpcs –standard=Zend /path/to/your/code/

And that’s it for this part actually. In the next part, which I hope to finish sometime this weekend or early next week,  I will create a coding standard in the PHP_CodeSniffer component and show you how to use some of the many sniff classes already defined to get you up and running with a shiny “new” coding standard. I will also show you how to extend some of them to do something a little different.

In the last part I will show you how to implement new sniff classes. The last part will also contain information on how to become the least popular guy on the development team: Add a check to the pre-commit hook so no one can commit code unless it follows the standard 100%!

June 19, 2008

WTF?! Que pasa?!

Filed under: Technology — Tags: , , , — christer @ 7:35 pm

A couple of Norwegian guys has just released a Norwegian translation of Twitter over at qpsa.no. Oh wait … it just looks like Twitter! Almost had me fooled there!

They seem to believe that this “new” service will revolutionize social networking in Norway… well … I truly believe that Angelina Jolie will dump Brad Pitt and come over to Oslogata to meet me instead… Let’s see what happens first!

Mats just published a post about the same thing over at his blog!

Zend_Service_Recaptcha is accepted

Filed under: PHP, Technology — Tags: , , — christer @ 5:33 pm

Just received a mail from Matthew Weier O’Phinney saying that the Zend_Service_Recaptcha proposal is accepted for inclusion in standard/incubator. So Paddy … you wanna update me on what changes you have done to the initial code soon? :p

Norwegian Developer Conference 2008

Filed under: Technology — Tags: , , , , , , , — christer @ 3:22 pm

Tuesday and Wednesday this week I attended NDC 2008 in Oslo together with Naveed and Erlend from work. On Tuesday I attended the following talks:

  • Thrashing by Mary Poppendieck
  • What is Pull Scheduling by Mary Poppendieck
  • Designing for testability by Roy Osherove
  • Data related testing by Roy Osherove

Read more about the talks at the schedule for day 1.

On Wednesday I attended the following talks:

  • Natural Laws of Agile Software Development (Part 1, 2 and 3) by Ron Jeffries and Chet Hendrickson
  • Introduction to Behaviour Driven Development by Aslak Hellesøy

Read more about the talks at the schedule for day 2.

Roy Osherove also squeezed in a song after every talk which was very neat. I liked the one about databases. Download it from one of his blog posts.

If you look at the schedule there was some stuff about ASP.NET, Silverlight, C# and more Microsoft related stuff but since I’m not too interested in any of those technologies I went for the more “generic” talks.

As a developer I already know that most of the stuff these guys talks about works (XP, Agile development, TDD, Coding standards ++), but it’s not that easy to make all parts of an organization understand that this is the way to go. I’m not saying that by following these methodologies and rules you will make killer stuff automagically but in the long run you will most likely end up with something allot more manageable and stable and it will most certainly be more easy for new employees to get up and running and a better understanding of your code base.

Again there are some talks that just don’t manage to get the point through (In MY opinion). Aslak Hellesøy talked about Behavior Driven Development and I honestly didn’t get the point of it. The talk only lasted for about an hour so it’s not much time, but I have read about BDD before and have seen some examples of it, so I didn’t show up completely empty handed, but still … I don’t get it.

To show an example Aslak used rspec which is a BDD framework for Ruby that enables you to write “stories” that you can use to test your code. These stories will act as a supplement for unit testing. While unit testing is for developers only, these stories can be read and understood by non-technical people as well. I guess writing these stories will make a pretty good specification for the software you are about to write but I found it hard to come up with “good” stories that makes sense. I think I just need some better examples! :)

Anyways, the conference was very good. Some of the speakers are probably the best you can get on the subjects they talked about. I met up with Olav Tollefsen (who I travelled to Zürich with for the Microsoft Live Services course in March) and had a chat with him. It sounded like next years NDC will be bigger and better, so if we are going there next year as well I will be looking forward to that!

June 6, 2008

Working from home + ssh tunnels = Instant win!

Filed under: Technology, Work related — Tags: , , , — christer @ 11:03 am

Since I have to get out to Hankø as soon as possible after work today to help the re-bolting guys I decided to work from home to save some time (the train ride to work lasts for one hour). When I sat down to give some of our consultants some more tickets on our Trac I remembered that I could no longer reach our internal development machine via the firewall at work because of some ongoing network changes. The firewall at work has a port that is forwarded to port 22 on our development machine so we can more easily access the machine but that is no longer an option since the access to the firewall is restricted.

I tried to access it via some firewalls at our server parks and found one that worked. Now … how can I be able to browse the internal dev machine at work (at port 80) from home, via a firewall at an external server park, via a port on a firewall at work that only forwards to 22 on the development machine?

Enter ssh tunneling!

I will use the following host names on the machines I need to talk to:

Development machine at work: dev
Firewall at work: fw-work (assume port 44444 forwards to dev:22)
Firewall at server park: fw-park

Now … what I want is to browse dev in my browser. First I edit my /etc/hosts file to have dev point to 127.0.0.1. The next thing I need to do is to shut down the local apache process since I want to forward all traffic on port 80 on my localhost through an ssh tunnel. Once that’s taken care of I need to
create a tunnel to fw-park using a random port:

ssh -L 2222:fw-work:44444 myusernameatwork@fw-park

Ok … so now I have a port on my machine at home (2222) that goes to port 44444 at the firewall at work (which is forwarded to dev:22) via fw-park. Once I’m connected to fw-park I can test the tunnel by doing:

ssh -p 2222 myusernameatwork@localhost

I enter my password and voila, I’m logged on to dev! So, the last step is to send all traffic on port 80 on localhost through that port so it ends up on port 80 on dev. To do that I issue the following command:

sudo ssh -p 2222 -L 80:dev:80 myusernameatwork@localhost

I need to be root to forward a port below 1024 so I prefix the command with sudo. When I’m logged in I point my browser to http://dev/ and suddenly I can browse the dev machine! Thanks to Mats for helping me out with this one!

May 28, 2008

More Example Zend Framework Blog madness

Filed under: PHP, Technology — Tags: , , — christer @ 9:45 am

May 26, 2008

WordPress usability issues

Filed under: Technology — Tags: , — christer @ 1:19 pm

Mats has written a couple of posts about some usability issues in the WordPress blogging software:

I agree with most of the points he mentions. Especially the ones about the placement of the save button in the admin dashboard. If anyone else reads this feel free to link it in your blog as well!

Zend_Service_Recaptcha proposal

Filed under: PHP, Technology — Tags: , — christer @ 11:19 am

A little while back I wrote a set of classes in PHP to fetch a reCAPTCHA instead of using the libraries they offer (which is just a set of functions). I checked to see if there was a proposal for a reCAPTCHA ZF component and Pádraic Brady had a proposal placeholder in the wiki. There was no relevant information in the proposal so I restructured my stuff a little to make it “ZF compliant” and sent Padraic an email about it.

The proposal has been updated and I’m co-proposing it with Pádraic and you’ll find it over at the ZF wiki.

May 20, 2008

Norwegian PHP Testfest

Filed under: PHP, Technology — Tags: , , , — christer @ 5:01 pm

The Norwegian PHP User Group is hosting a Testfest on the 29th of May. My friend Mats is probably going there but I can’t make it that day. I’ll check the code coverage list and see whats missing and maybe I’ll write some tests and submit them.

Older Posts »

Blog at WordPress.com.