Decorator pattern and baking a pizza

I am a self proclaimed master chef. And I love baking pizza. I was going through a video and the presenter mentioned the process of baking pizza as an example of decorator pattern. I had some example PHP “pizza” code lying around and decided to use namespaces and composer to build upon it. Here is the Just an example of decorator pattern. I might push more code to GitHub.

Update: I have been trying to get hang of Java and I did this same example using Java. Actually it was pretty easy to translate this code to Java. I did find and replace all for most of the stuff. Here is the repo.

How not to do a CI controller? – Tips to develop CodeIgniter Controllers

I cam across a post that was actually a small tutorial on CodeIgniter. The tutorial had what ever it requires to write a basic controller. I am picking up the same post and adding my comments to the post.

The original post – http://phpmaster.com/untangling-mvc-with-codeigniter/

The controller

<?php
public function index() {
    $this->load->helper("form");
    $this->load->library("form_validation");

    $this->form_validation->set_rules("first", "First Name",
        "required");
    $this->form_validation->set_rules("last", "Last Name",
        "required");
    $this->form_validation->set_rules("email", "Email Address",
        "required|valid_email");

    if ($this->form_validation->run() == false) {
        $this->load->view("phpmasterform_view");
    }
    else {
        $first = $_POST["first"];
        $last = $_POST["last"];
        $email = $_POST["email"];
        $data = array("first_name" => $first,
                      "last_name" => $last,
                      "email" => $email);

        $this->load->model("phpmasterform_model");
        $this->phpmasterform_model->insert_address($data);
        $this->load->view("formsuccess");
    }
}

What is wrong with this Controller?
The controller doesn’t utilises the full powers of a framework. Any decent framework or a develop methodology will suggest you to move configurations to a separate place. CI has configuration settings for almost everything. The configuration folder is easily identifiable and path is /application/config. In this folder is file autoload.php. This file is commented and is self explanatory. I will move the form helper and form_validation library loading tasks to autoload.php. Read more about it here, Auto-loading Resources. Then in same config folder I will create another file named form_validation.php which will hold all my validation rules. This will be a centralised place to hold all the validation rules. I can easily modify just one file and change validation rules on my whim and fancy. Read more about this here, “Saving Sets of Validation Rules to a Config File“. All these were just small tips and one can read the manual and find more about them. But the biggest mistake I found in this controller was blindly consuming the user input. The commandment of web development says

Thy shalt never trust user input.

CI provides a Input Class library. This library is so important that CI loads it by default. So if you are using CI, use this library.
This was not the only possible security hole. If run through other files in CI, they all start with following line

if ( ! defined('BASEPATH')) exit('No direct script access allowed');

.
This restricts some one from directly accessing the file if path to that file is known.
After all this the controller is changed to following

<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');
public function index() {
    if (false === $this->form_validation->run(feedback)) {
        $this->load->view("phpmasterform_view");
    }
    else {
/*
    if you have set following "$config['global_xss_filtering'] = TRUE;"in your 
    application/config/config.php then you don't need to pass 2nd param as 
    true in following three lines.
*/
        $first = $this->input->post("first", true);
        $last = $this->input->post("last", true);
        $email = $this->input->post("email", true);

        $data = array("first_name" => $first,
                      "last_name" => $last,
                      "email" => $email);

        $this->load->model("phpmasterform_model");
        $this->phpmasterform_model->insert_address($data);
        $this->load->view("formsuccess");
    }
}

Following is form_validation.php, this will go in application/config/ folder.

<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');

$config = array(
    'feedback' => array(
        array(
            'field' => 'first',
            'label' => 'First name',
            'rules' => 'required'
        ),
        array(
            'field' => 'last',
            'label' => 'Last name',
            'rules' => 'required'
        ),
        array(
            'field' => 'email',
            'label' => 'Email',
            'rules' => 'required'
        )
    ),
);

Last thing to do is to modify autload.php and load form helper and form validation library. This should give an idea how to develop a maintainable code in CI.
Happy coding!

M4 – My top secret learning project :-)

Yahoo! is now going through a very tough time and is being ignored for mostly. There is hardly any attention being paid to Yahoo! products. I recently tried to play with Yahoo! Application Platform and YQL. One can develop web based and standalone applications using YAP SDK and YQL. These apps are more or less similar to Facebook Apps in architecture. I used YQL and quickly created a small site that fetches Sensex data and displays it. Please visit http://www.indianbizdirectory.com/.

The domain IndianBizDirectory.com was lying idle for more than 4-5 years. I ran a small example fetch weather data for Beverly using YQL console. The example is so simple and self explaining. I was encouraged and decided to use YQL in some real life stuff. I used CodeIgniter to set up a project. Codeigniter is my framework of choice for rapidly developing prototypes. I searched for some feeds and web pages for data and as usual Yahoo! and Google were there to help me. Apart from this I hooked up BSEIndia.com, NDTV.com, Bing.com and MoneyControl.com for data. Initially I decided to run real time calls to these data sources. I setup a very basic logger with CI that mailed me every time a call to any data source or feed failed. I asked my friends to start hitting my site. They hammered it for two weeks. It was slow. And occasionally the feed from BSEIndia.com was failing. I studied logs an realised that the speed was slow due to multiple calls, there were at least 4 to 5 calls to different data sources, were making the page slow. I decided to cache the data. This increased the speed. So

  • on every page load, CI checks if cache is available and loads it, if not then it updates cache for that particular data source/feed.
  • there is a background process that caches data for Sensex during trading hours. The cache is refreshed every 15 minutes.
  • there are chances that a feed may fail during the background process, in that case the process leaves the cache in its original state. The cache is updated by CI.

I found there that BSE feed failure log entries were reduced though the data was not real time. After fetching data I used Xpath to transform data into HTML. Result, I could develop a standalone self sustaining website that displays useful Sensex, Forex and Commodity data. One can see Sensex top looser and gainers, clicking on a scrip name shows further detail about that scrip. On top of it, I added Bing search to fetch and display news related to that particular scrip. All in all, it was a great experiment and learning.

To monetize this effort, I added Google Ads on all pages. I wanted to add more ads but don’t have experience with other platforms.

After this, I am planning to dirty my hands with Python, PyGTK specifically to solve a problem I usually face. 🙂

Method chaining

I love the way CodeIgniter explains method chaining by saying.

Method chaining allows you to simplify your syntax by connecting multiple functions.

As explained above it simply lets you do things like

FileObject->OpenFile('FileName')->AppendLine('Hello World!')->CloseFile()

Its neat. But in PHP, you have to have PHP5.x. This wonderful thing is also available in JavaScript. From jQuery home page

$("p.neat").addClass("ohmy").show("slow");

How to do method chaining?
To have an object chain methods every method in that object must return a reference to itself. Easy. Example?

<?php
class MethodChainingExample{
	public function methodOne(){
		echo __METHOD__." \n";
		return $this;
	}
	public function anotherMethod(){
		echo __METHOD__." \n";
		return $this;
	}
	public function oneMoreMethod(){
		echo __METHOD__." \n";
		return $this;
	}
}
$example =  new MethodChainingExample;
$example->methodOne()->anotherMethod()->oneMoreMethod();

Hello World in CakePHP – 3 steps

  1. Download and set up CakePHP in your webroot. Stop reading further if you cant do it or you are not sure how to do it.
  2. Create a file named “helloworld_controller.php” in folder “cakephp/app/controllers/helloworld_controller.php” and paste following code in the file
    <?php
    class HelloWorldController extends Controller {
    public $name = 'HelloWorld'; //Controller name, we need it.
    public $uses=null; //The example doesn't "use" any model.
    public $autoRender=false; //Do not render "automagically"
    public function index() {//The default action for a CakePHP controller
    echo __METHOD__;//This will print HelloWorld suffixed with some more info ;-)
    }
    }
  3. Point your browser to CakePHP installation on your server for example “http://localhost/cakephp/helloworld/”

Piece of cake… 🙂