Tuesday, November 30, 2010

Create RESTful Applications Using The Zend Framework

The Zend Framework 1.9 release added a new feature - Zend_Rest_Controller. Zend_Rest_Controller and Zend_Rest_Route classes go hand in hand. In the previous versions of the Zend Framework, we have had the Zend_Rest_Server component. We still have. Since Zend_Rest_Server provides an RPC like component violating the REST architectural constraint, it is likely to be deprecated in the future versions of the Zend Framework.
In this article let us explore how to make use of Zend_Rest_Route and Zend_Rest_Controller to build a RESTful server application. Zend_Rest_Route routes the request to the appropriate module, controller and action depending on the HTTP request method and URI.
Let's start coding. We build the RESTful application based on the QuickStart project.

Adding the Zend_Rest_Route in the bootstrap

You can choose to enable Zend_Rest_Route for the entire application or for specific set of modules. In this example we enable the rest route for the entire application.
Bootstrap the front controller resource and add the rest route.

<?phpprotected function _initRestRoute()
{
        
$this->bootstrap('frontController');
        
$frontController Zend_Controller_Front::getInstance();
        
$restRoute = new Zend_Rest_Route($frontController);
        
$frontController->getRouter()->addRoute('default'$restRoute);

}
?>

Creating the Zend_Rest_Controller

Create the file application/controllers/ArticleController.php. We extend Zend_Rest_Controller instead of Zend_Controller_Action. In our controller we are going to have five actions.
  1. indexAction - return all articles
  2. getAction - return a particular article
  3. postAction - create a new article
  4. putAction - update a particular article
  5. deleteAction - delete a particular article
These actions are defined as abstract methods in the Zend_Rest_Controller class.
The skeletal controller looks like:

<?phpclass ArticleController extends Zend_Rest_Controller{

    public function 
init()
    {
        
$this->_helper->viewRenderer->setNoRender(true);
    }

    public function 
indexAction()
    {
    }

    public function 
getAction()
    {
    }
   
    public function 
postAction()
    {
    }
   
    public function 
putAction()
    {
    }
   
    public function 
deleteAction()
    {
    }

}
?>

For the purpose of brevity, I have disabled the view for this controller in the init() hook. To test the routing of the requests, let's append sample messages to the response object in each action.

<?php
 
public function indexAction()
    {
         
$this->getResponse()
            ->
appendBody("From indexAction() returning all articles");
    }

    public function 
getAction()
    {
        
$this->getResponse()
            ->
appendBody("From getAction() returning the requested article");

    }
   
    public function 
postAction()
    {
        
$this->getResponse()
            ->
appendBody("From postAction() creating the requested article");

    }
   
    public function 
putAction()
    {
        
$this->getResponse()
            ->
appendBody("From putAction() updating the requested article");

    }
   
    public function 
deleteAction()
    {
        
$this->getResponse()
            ->
appendBody("From deleteAction() deleting the requested article");

    }
?>

Testing the RESTful server using curl

On my computer I have installed this application for the domain zfrest.example.com. We use the curl command to test our RESTful server.
Testing the indexAction() : The URI http://zfrest.example.com/article represents the article resource. All articles are returned for this request.
$ curl http://zfrest.example.com/article
I get the following output:

From indexAction() returning all articles
Testing the getAction() : The URI http://zfrest.example.com/article/1 represents the resource - article 1.

$ curl http://zfrest.example.com/article/1
I get the following output:

From getAction() returning the requested article
Testing the postAction() : we make an HTTP POST request to http://zfrest.example.com.
$ curl -d "article=myarticle" http://zfrest.example.com/article/
I get the following output:

From postAction() creating the requested article
Testing the putAction() : we request the article 1 to be updated by making HTTP PUT request to http://zfrest.example.com/article/1

$ curl -d "article=updatedarticle" -X PUT http://zfrest.example.com/article/1
I get the following output:

From putAction() updating the requested article
Testing the deleteAction() : we send an HTTP DELETE request to http://zfrest.example.com/article/1
curl -X DELETE http://zfrest.example.com/article/1
I get the following output:

From deleteAction() deleting the requested article

Summarizing the exercise

Zend Framework allows you to build RESTful server applications using the Zend_Rest_Controller component. The curl command is a very useful tool to test RESTful servers. If you don't have the curl command on your computer, you can write a PHP script and make use of the curl extension provided by PHP. In the upcoming posts of this series, I will discuss managing API keys from your RESTful application, returning appropriate HTTP response codes, reading the body from PUT and DELETE requests and more.
Are you going to a build RESTful server using the Zend_Rest_Controller component? Tell me about your experiences.
Create RESTful Applications Using The Zend Framework - Part II : Using HTTP Response Code

Create RESTful Applications Using The Zend Framework - Part III : Managing API Key

n the first two posts of this series, we discussed how to route REST requests to controllers and return HTTP response code. In this article I will talk about managing API keys.
Having the clients send API key within the HTTP header is convenient to handle. We can quickly check the HTTP request header and decide whether to allow or deny the request.
As a prerequisite you should be familiar writing front controller plugins. Let's write a front controller plugin that does the following:
  • Check whether the request has the correct API key in the HTTP header
  • If the correct API key in the HTTP header is missing, set the appropriate HTTP response code and route the request to error controller
We will not perform any changes to our previous article controller.
Let's start writing code.
Step 1: Write the front controller plugin.
Create the directory library/My/Controller/Plugin.
Inform the autoloader about the namespace 'My'. Also, register the plugin "My_Controller_Plugin_RestAuth". Let's add these lines to our configuration file application/configs/application.ini generated by Zend_Tool(or the quick start guide).
autoloadernamespaces.1 = "My_"
resources.frontController.plugins = "My_Controller_Plugin_RestAuth"
Let's write the front controller plugin. Create and edit the file library/My/Controller/Plugin/RestAuth.php


<?phpclass My_Controller_Plugin_RestAuth extends Zend_Controller_Plugin_Abstract{
    public function 
preDispatch(Zend_Controller_Request_Abstract $request)
    {
        
$apiKey $request->getHeader('apikey');

        if (
$apiKey != 'secret') {
            
$this->getResponse()
                    ->
setHttpResponseCode(403)
                    ->
appendBody("Invalid API Key\n")
                    ;
            
$request->setModuleName('default')
                        ->
setControllerName('error')
                        ->
setActionName('access')
                        ->
setDispatched(true);

        }

    }

}
?>
In our front controller plugin, we hook into the preDispatch() method. Before a controller action is executed, our Predispatch() method is called.
In our preDispatch() method, we check whether the HTTP request header contains the key 'apikey' with value 'secret'. If the request does not have the correct API key we set the 403 HTTP response code and set the controller and action to 'error' and 'access' respectively. We also set the dispatched status to true.
Step 2: Add the 'access' action to the error controller in application/controllers/ErrorController.php.

<?phppublic function accessAction()
{
        
$this->_helper->ViewRenderer->setNoRender(true);
}
?>
In the sample code, we simply disable the view. In your application, you could perform logging in the access action of the error controller.
Step 3: Let's test our application using cUrl.
Make a request without sending the 'apikey' HTTP header.
curl http://zfrest.example.com/article -v
The sample output of the above command looks like:

* About to connect() to zfrest.example.com port 80 (#0)
*   Trying 127.0.0.1... connected
* Connected to zfrest.example.com (127.0.0.1) port 80 (#0)
> GET /article HTTP/1.1
> User-Agent: curl/7.19.7 (i386-redhat-linux-gnu) libcurl/7.19.7 NSS/3.12.4.5 zlib/1.2.3 libidn/1.9 libssh2/1.2
> Host: zfrest.example.com
> Accept: */*
> 
< HTTP/1.1 403 Forbidden
< Date: Mon, 01 Mar 2010 08:46:03 GMT
< Server: Apache/2.2.14 (Fedora)
< X-Powered-By: PHP/5.3.1
< Content-Length: 16
< Connection: close
< Content-Type: text/html; charset=UTF-8
< 
Invalid API Key
* Closing connection #0
We recieved the HTTP response code 403 with the body content 'Invalid API Key'.
Let's make another test. This time, let's add the correct API key in the request HTTP header.
curl -H "apikey: secret" http://zfrest.example.com/article -v
Using the -H switch, we can send headers.
The output :

* About to connect() to zfrest.example.com port 80 (#0)
*   Trying 127.0.0.1... connected
* Connected to zfrest.example.com (127.0.0.1) port 80 (#0)
> GET /article HTTP/1.1
> User-Agent: curl/7.19.7 (i386-redhat-linux-gnu) libcurl/7.19.7 NSS/3.12.4.5 zlib/1.2.3 libidn/1.9 libssh2/1.2
> Host: zfrest.example.com
> Accept: */*
> apikey: secret
> 
< HTTP/1.1 200 OK
< Date: Mon, 01 Mar 2010 08:57:15 GMT
< Server: Apache/2.2.14 (Fedora)
< X-Powered-By: PHP/5.3.1
< Content-Length: 20
< Connection: close
< Content-Type: text/html; charset=UTF-8
< 
* Closing connection #0
all articles content
This time we received the HTTP response code 200 with body content 'all articles content'.

Monday, November 29, 2010

Create RESTful Applications Using The Zend Framework - Part II : Using HTTP Response Code

In our last example, we used Zend_Rest_Route and Zend_Rest_Controller to demonstrate how to map requests to controller actions. We also used the response object to send text content in the HTTP response. In this article let us send appropriate HTTP response codes using the response object.
RFC 2616 describes HTTP response codes to use in various contexts.
In this example, we will use a few response codes
  • 200 OK - successfully returning the requested articles
  • 201 Created - article has been created
  • 204 No Content - article has been deleted
  • 404 Not Found - no resource found at the requested URI
  • 503 Service Unavailable - the server is experiencing heavy load. Try later.
We will cover other HTTP response codes in upcoming articles on the subject.
Let's start coding. Grab the ArticleContoller.php from the article Create RESTful Applications Using The Zend Framework
.

Demonstrating the usage of HTTP response code 200

Modify the indexAction() of our ArticleController

<?phppublic function indexAction()
    {
         
$this->getResponse()
            ->
setHttpResponseCode(200)
            ->
appendBody("all articles content");
    }
?>
The Zend_Controller_Response_Abstract class has the method setResponseCode() using which we can set the HTTP response code. If we weren't using Zend Framework, we would simply use the PHP function header().
In this article, we again use cUrl from the command line to view the response. The -v switch to the curl command prints the output in verbose mode.
curl http://zfrest.example.com/article -v
* About to connect() to zfrest.example.com port 80 (#0)
*   Trying 127.0.0.1... connected
* Connected to zfrest.example.com (127.0.0.1) port 80 (#0)
> GET /article HTTP/1.1
> User-Agent: curl/7.19.7 (i386-redhat-linux-gnu) libcurl/7.19.7 NSS/3.12.4.5 zlib/1.2.3 libidn/1.9 libssh2/1.0
> Host: zfrest.example.com
> Accept: */*
> 
< HTTP/1.1 200 OK
< Date: Sat, 23 Jan 2010 18:11:08 GMT
< Server: Apache/2.2.13 (Fedora)
< X-Powered-By: PHP/5.2.11
< Content-Length: 20
< Connection: close
< Content-Type: text/html; charset=UTF-8
< 
* Closing connection #0
all articles content
If you observe carefully, the response contains the line

HTTP/1.1 200 OK

Demonstrating the usage of HTTP response code 201

Let's perform HTTP POST action on the article resource. We modify the postAction of ArticleController

<?phppublic function postAction()
    {
        
$this->getResponse()
             ->
setHttpResponseCode(201)
            ->
appendBody("created the article\n")
            ->
appendBody("http://zfrest.example.com/article/5");

    }
?>
In the response body we also mention the URI from which the newly created article can be accessed.
The output looks like

curl -d "article=myarticle" http://zfrest.example.com/article/ -v
* About to connect() to zfrest.example.com port 80 (#0)
*   Trying 127.0.0.1... connected
* Connected to zfrest.example.com (127.0.0.1) port 80 (#0)
> POST /article/ HTTP/1.1
> User-Agent: curl/7.19.7 (i386-redhat-linux-gnu) libcurl/7.19.7 NSS/3.12.4.5 zlib/1.2.3 libidn/1.9 libssh2/1.0
> Host: zfrest.example.com
> Accept: */*
> Content-Length: 17
> Content-Type: application/x-www-form-urlencoded
> 
< HTTP/1.1 201 Created
< Date: Sat, 23 Jan 2010 17:52:51 GMT
< Server: Apache/2.2.13 (Fedora)
< X-Powered-By: PHP/5.2.11
< Content-Length: 55
< Connection: close
< Content-Type: text/html; charset=UTF-8
< 
created the article
* Closing connection #0
http://zfrest.example.com/article/5

Demonstrating the usage of HTTP response code 204

Let's delete an article. The user agent does not require any content in the body when the article is deleted.
We modify the deleteAction() of ArticleController

<?php
 
public function deleteAction()
    {
        
$this->getResponse()
            ->
setHttpResponseCode(204);

    }
?>
The output on the command line looks like:
curl -X DELETE http://zfrest.example.com/article/12 -v
* About to connect() to zfrest.example.com port 80 (#0)
*   Trying 127.0.0.1... connected
* Connected to zfrest.example.com (127.0.0.1) port 80 (#0)
> DELETE /article/12 HTTP/1.1
> User-Agent: curl/7.19.7 (i386-redhat-linux-gnu) libcurl/7.19.7 NSS/3.12.4.5 zlib/1.2.3 libidn/1.9 libssh2/1.0
> Host: zfrest.example.com
> Accept: */*
> 
< HTTP/1.1 204 No Content
< Date: Sat, 23 Jan 2010 17:58:14 GMT
< Server: Apache/2.2.13 (Fedora)
< X-Powered-By: PHP/5.2.11
< Content-Length: 0
< Connection: close
< Content-Type: text/html; charset=UTF-8
< 
* Closing connection #0

Demonstrating the usage of HTTP response code 404

Let's try to access article 20 which does not exist.
Modify the getAction() of ArticleController. For the sake of example, let's pretend the getAction() is prepared to respond to only non-existent resources.
<?php public function getAction()
    {
        
$this->getResponse()
            ->
setHttpResponseCode(404)
            ->
appendBody("requested article 20 not found");

    }
?>
The output looks like:

curl http://zfrest.example.com/article/20 -v

* About to connect() to zfrest.example.com port 80 (#0)
*   Trying 127.0.0.1... connected
* Connected to zfrest.example.com (127.0.0.1) port 80 (#0)
> GET /article/20 HTTP/1.1
> User-Agent: curl/7.19.7 (i386-redhat-linux-gnu) libcurl/7.19.7 NSS/3.12.4.5 zlib/1.2.3 libidn/1.9 libssh2/1.0
> Host: zfrest.example.com
> Accept: */*
> 
< HTTP/1.1 404 Not Found
< Date: Sat, 23 Jan 2010 18:17:56 GMT
< Server: Apache/2.2.13 (Fedora)
< X-Powered-By: PHP/5.2.11
< Content-Length: 30
< Connection: close
< Content-Type: text/html; charset=UTF-8
< 
* Closing connection #0
requested article 20 not found

Demonstrating the usage of HTTP response code 503

Lastly, let's respond with the HTTP code 503.
Modify the putAction of ArticleController

public function putAction()
    {
        $this->getResponse()
            ->setHttpResponseCode(503)
            ->appendBody("unable to process put requests. Please try later");
 
    }
The output looks like:

curl -d "article=updatedarticle" -X PUT http://zfrest.example.com/article/1 -v
* About to connect() to zfrest.example.com port 80 (#0)
*   Trying 127.0.0.1... connected
* Connected to zfrest.example.com (127.0.0.1) port 80 (#0)
> PUT /article/1 HTTP/1.1
> User-Agent: curl/7.19.7 (i386-redhat-linux-gnu) libcurl/7.19.7 NSS/3.12.4.5 zlib/1.2.3 libidn/1.9 libssh2/1.0
> Host: zfrest.example.com
> Accept: */*
> Content-Length: 22
> Content-Type: application/x-www-form-urlencoded
> 
< HTTP/1.1 503 Service Temporarily Unavailable
< Date: Sat, 23 Jan 2010 18:21:48 GMT
< Server: Apache/2.2.13 (Fedora)
< X-Powered-By: PHP/5.2.11
< Content-Length: 48
< Connection: close
< Content-Type: text/html; charset=UTF-8
< 
* Closing connection #0
unable to process put requests. Please try later
When implementing a REST client you could simply examine the HTTP response code to check whether the request was successful. One common area where you can see response codes being examined is AJAX applications.
For your convenience, I am posting the entire code of the ArticleController.php below.


<?php
class ArticleController extends Zend_Rest_Controller{

    public function 
init()
    {
        
$this->_helper->viewRenderer->setNoRender(true);
    }

    public function 
indexAction()
    {
         
$this->getResponse()
            ->
setHttpResponseCode(200)
            ->
appendBody("all articles content");
    }

    public function 
getAction()
    {
        
$this->getResponse()
            ->
setHttpResponseCode(404)
            ->
appendBody("requested article 20 not found");

    }

    public function 
postAction()
    {
        
$this->getResponse()
             ->
setHttpResponseCode(201)
            ->
appendBody("created the article\n")
            ->
appendBody("http://zfrest.example.com/article/5");

    }

    public function 
putAction()
    {
        
$this->getResponse()
            ->
setHttpResponseCode(503)
            ->
appendBody("unable to process put requests. Please try later");

    }

    public function 
deleteAction()
    {
        
$this->getResponse()
            ->
setHttpResponseCode(204);

    }

}
?>

Friday, October 1, 2010

Image thumbnail viewer plugin-Jquery

is it?

FancyBox is a tool for displaying images, html content and multi-media in a Mac-style "lightbox" that floats overtop of web page.
It was built using the jQuery library. Licensed under both MIT and GPL licenses

Features

  • Can display images, HTML elements, SWF movies, Iframes and also Ajax requests
  • Customizable through settings and CSS
  • Groups related items and adds navigation.
  • If the mouse wheel plugin is included in the page then FancyBox will respond to mouse wheel events as well
  • Support fancy transitions by using easing plugin
  • Adds a nice drop shadow under the zoomed item

Examples

Different animations - 'fade', 'elastic' and 'none'
example1 example2 example3
Different title positions - 'outside', 'inside' and 'over'
example4 example5 example6
Image gallery (ps, try using mouse scroll wheel)

Various examples
Examples of manual call

Wednesday, September 29, 2010

Dates Between Two Dates

<?php
$fromDate = "2009-01-01";
$toDate = "2009-01-15";

$dateMonthYearArr = array();
$fromDateTS = strtotime($fromDate);
$toDateTS = strtotime($toDate);

for ($currentDateTS = $fromDateTS; $currentDateTS <= $toDateTS; $currentDateTS += (60 * 60 * 24)) {
// use date() and $currentDateTS to format the dates in between
$currentDateStr = date("Y-m-d",$currentDateTS);
$dateMonthYearArr[] = $currentDateStr;
//print $currentDateStr.”<br />”;
}

echo  "<pre>";
print_r($dateMonthYearArr);
echo "</pre>";
?>