CakePHP URL Shortener Service Tutorial

CakePHP URL Shortener Service Tutorial

Make a new view file called short.ctp which should be placed in the shorten directory within views. Next add the following code to get our view looking awesome:

<div id="bigurl"><?php echo $html->link('http://home.ly/'.$shorturl, array('controller'=>'shorten', 'action'=>'redirectUrl', 'shortcode'=>$shorturl)); ?></div>

This just shows our URL as a link, which we used CakePHP’s html helper to produce! The first part of the link is what is displayed, we faked it to be home.ly, we don’t own the domain, but for presentation sake, we included it, when it really should be: http://jotlab.com/tutorial/url/……hardly short! The second part links through a route to a action we will make a bit later on. So I will explain this url a bit more then. Easy!

So now we have a semi functional website, we can add urls, we can see the url that has been shortened. What you might of noticed however, is that the urls you enter don’t have to be urls to be shortened! This isn’t going to work! So we’ll need to put in some validation to make sure that the url submitted, is in fact, a url. Like I said before, our models need to be big fatty boom batty models, it just works better this way. Well guess what? Validation goes in models too! So let’s add it in already! Open up your model again, and add:

var $validate = array(
			'url' => array('rule' => array('url', true))
		);

What? That’s it? Yep! This sets up the validation. On the left is the field that is being tested, the url input field from the form. Then we apply a rule on it, which just happens to be a url rule, which CakePHP has pre-prepared for you! What is this true thing? That is a little feature that the developers have built in, that for the url validation, makes sure there is a protocol added with the url. So if you enter in me.com it won’t validate, but if you enter in http://me.com it will! You lucky thing you. So go ahead, try enter a url, try test it out. It works!

So we have an application that adds, displays, validates and washes the dishes. “But there’s no HBO!!!” you cry, the urls don’t redirect when you go to them! We’ll let’s go set this up. In order to do this, we need to set up another action, and also a route to catch all and route to the action which redirects! First let’s make the action (add this to your shorten_controller.php):

function redirectUrl($shortcode){
	$fullurl = $this->Shorten->getFullUrl($shortcode);
	if(!empty($fullurl)){
		$this->redirect($fullurl);
	} else {
		$this->redirect(array('controller'=>'shorten', 'action'=>'index'));
	}
}

What this does is sets up another action, but it receives something, something that our route will pass to it. The action also talks to our model again, to get the full url of the particular shortened url. The action then checks if the model spat back a url, basically whether it existed or not. If the url is present, then we redirect the user to it, if it is not, then with our route, we redirect our user back to the index page to insert a url. The model function is quite straight forward:

function getFullUrl($shortcode){
	$fullurl = $this->field('url', array('shortcode'=>$shortcode));
	return $fullurl;
}

This just grabs the record’s url field which is associated to the unique shortcode, which was randomly generated before. Both the controller and model functions however depend on one thing as you have seen, the $shortcode variable. Where does this come from? Well it comes from the URL itself! Our route picks this up and passes it to our controller, which then uses it to pass to our model. Where is this so called route you ask? Well open up your routes.php file and under the previous route add:

Router::connect('/:shortcode', array('controller' => 'shorten', 'action' => 'redirectUrl'), array('pass'=>array('shortcode')));

You should only have two routes, these two, and in this order:

Router::connect('/', array('controller' => 'shorten', 'action' => 'index'));
Router::connect('/:shortcode', array('controller' => 'shorten', 'action' => 'redirectUrl'), array('pass'=>array('shortcode')));

As you can see, we really only have two pages. Routes operate in order of precedence, if the page is simply / then it will go to the index, but anything else, anything after the / if present will route to the redirectUrl action! The :shortcode captures the string within the url, and then we tell it to pass it to the controller via array(‘pass’=>array(‘shortcode’)). So with these three things added: your route, your action and your model function, your site is now 100% operational! Go try adding a url, then navigating to the link or clicking on the url generated after you submit a url! Yayyyy, you got redirected!

Posted by VoiDeT

Categorised under CakePHP
Bookmark the permalink or leave a trackback.

10 Comments

  1. i have never seen such a comprehensive tutortial on this , good on yah, i’ll buy you a paypal beer any day :)

    August 26, 2009 @ 3:07 pm
  2. hendrik

    great work, thank you!

    August 31, 2009 @ 5:39 am
  3. Awesome tutorial man! Thanks allot

    December 16, 2009 @ 4:25 am
  4. nice post..what about stat a.k.a link tracking? it will be great if u include it.
    i bake mine at letsclick.co.cc for learning purpose.

    April 30, 2010 @ 7:43 am
  5. VoiDeT

    That would be quite easy, just depends how much information you would like to store.
    For example you could simply increment a count field in the row for that entry.
    Or you could make a completely new table in the database that would log each view/click and the according information, like IP, datetime etc.

    April 30, 2010 @ 9:00 am
  6. The demo file not work http://jotlab.com/tutorials/url/, url not found

    May 23, 2010 @ 3:30 am
  7. Hi, i don like very much the function getFilename. Why dont you try using a function the transform the id of the link into a string with numbers and letters?

    pseudocode for add a link;
    // find link, if not in database insert new link
    // link_shorted= base_convert($link_id, 10, 36);
    // return link_shorted

    pseudocode for get a encoded link;
    // link_id= base_convert($link_code, 36,10);
    // search link by id
    // redirect

    if you want even shorter link you could use this functions;

    function any2dec( $num) {
    $base=62;
    $index = substr( “0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ”, 0, $base );

    $out = 0;
    $len = strlen( $num ) – 1;
    for ( $t = 0; $t = 0; $t– ) {
    $a = floor( $num / pow( $base, $t ) );
    $out = $out . substr( $index, $a, 1 );
    $num = $num – ( $a * pow( $base, $t ) );
    }
    return $out;
    }

    July 3, 2010 @ 4:11 pm
  8. VoiDeT

    Exactly right. This is why at the beginning I said it wasn’t the best way to do it. But for the sake of this intermediate tutorial i thought using those baseencodes would be far beyond the scope of the tutorial. I did find similar functions on php.net that would be used to encode/decode ids or unique identifiers. But thanks for your observant comments!

    July 3, 2010 @ 4:14 pm
  9. >>Exactly right. This is why at the beginning I said it wasn’t the best way to do it.

    upss, i didnt read anything i just read the code, my bad!

    July 3, 2010 @ 4:19 pm
  10. VoiDeT

    No problem at all! Thanks for your input :)

    July 3, 2010 @ 4:21 pm

5 Trackbacks

  1. [...] CakePHP URL Shortener Service Tutorial • Jotlab [...]

  2. [...] Jotlab has a post on going from clean install to working URL shortener in 8 simple pages. [...]

  3. [...] CakePHP URL Short­ener Ser­vice Tutorial [...]

  4. By 9 Awesome CakePHP Tutorials | DevMoose on June 27, 2010 at 12:02 am

    [...] CakePHP URL Shortener Service Tutorial [...]

  5. [...] 2010 por eugenio85 Etiquetado: acortador, cakephp, PHP, tutorial, url shortener Despues de leer este articulo decidi escribir mi propio tutorial, mientras pensaba en como escribir note que en meneame utilizan [...]

Post a Comment

Your email is never published nor shared. Required fields are marked *

*
*

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>

or