Url encoding, mod_rewrite, and pretty url’s

While using CakePHP sometimes you face a situation where you need to pass an url (or any other piece of text) as argument to another action, and your first impulse to do that is to look at the PHP function list and pick the urlencode() one, so you go ahead and urlencode() your data happily. But sadly, when you click on that link, you get an HTTP 404 not found error, why that? That happens due to a bug at Apache’s mod_rewrite module, it decodes permaturely the encoded ‘/’ present in url’s, it seems to be fixed after 2.2.12 but i leave here a workaround anyway.

Sometimes people ask for a solution in community and i see answers like “you can always pass a base64 representation for your data”, but there’s a little problem with that, the Base64 encoding uses the following 64 characters [A-Za-z0-9], “/” and  “+”, as you can see the last two chars are not friendly for this use, what solution do we have?

We can base64 encode it, and replace all nocive characters by a conventional ones, when decoding we do exactly the opposite and everything will work like a charm.

One cake way for doing that:

Well.. we could need it everywhere, so the best way to implement it is as a Library, with CakePHP 1.3 we have a “libs” directory under our app, so we can create there a file called “url_encoder.php” with the following code:

<?php

class UrlEncoder {

    public static function encode($url) {
        return preg_replace(array('/\+/', '/\//'), array('-', '_'), base64_encode($url));
    }

    public static function decode($url_encoded) {
        return base64_decode(preg_replace(array('/-/', '/_/'), array('+', '/'), $url_encoded));
    }

}

And now you could import it and use it anywhere!:

App::import('Lib', 'UrlEncoder');
...
echo $this->Html->link('My link', array('action' => 'do_something', 'some_data' => UrlEncoder::encode('My beautifull/nocive data!')));
...

Model validation messages and i18n

Hi there!

I believe that everyone who already used i18n within CakePHP noticed that when you define model validation messages it simply doesn’t get translated, so.. what to do to bring i18n to work with these messages?

It’s simple and easy, there’s a method invalidate() in the Model class, it is used for marking fields as invalid, it receives a field to invalidate and a message, everything we need to do is overriding this method in our AppModel and calling the Model invalidate() method with our message wrapped by the translation function as shown below:

class AppModel extends Model {

	function invalidate($field, $value = true) {
		return parent::invalidate($field, __($value, true));
	}

}

.. and voilá! You won’t need to bother with it anymore :-)

My first post

Hi everyone! Be wellcome to my blog, this is my first post!

First of all, my english is not the best one and i apologize for that, hope you can read my posts, go ahead and find out my typos ;)

I’m creating this blog for sharing the world some daily development  notes, tricks, tips, anything that could help someone out there on his creativity and frustrations, and also as  a way to keep a record of stuff that could be important later  :-)

So.. I  hope you appreciate it, share your ideas, improvements, constructive critcism.

Feel free to comment everything and everywhere!