Tuesday, May 24, 2011

Getting started with drupal module development

Drupal is a very handy CMS, there are tons of modules written to extend the functionalities of drupal. This post will guide you to write a simple drupal module.

There must be at least two files to create a drupal module,

  • module_name.info
  • module_name.module

In this example I will use module_name as "cities". Then my two files would be cities.info and cities.module

Create a folder inside sites/all/modules which has the same name as your module, in this case it's "cities". Inside cities create two files cities.info and cities.module

It is possible to save your module in module folder but it is not recommended as that folder is kinda reserved for drupal core module. Instead of messing with core guys it is advisable to maintain a separate place for custom modules.

cities.info

cities.info file contains all the necessary information for drupal to know about your module. name, description, core are the musts in this file. There are also set of optional info which you can include but here in this example I only use required information only.

; $Id$
name = cities
description = This is a module that display list of cities 
core = 6.x


cities.module

what exactly is a hook?

Here is a good question if you are a newbie to drupal module development. Concept of hook is very important when it comes to drupal module development. Module system in drupal is based on hook, simply it's a php fuction which defines set of parameters and a result type. Hooks allow modules to interact with the drupal core.

In this example module I've used three hooks, hook_help, hook_perm and hook_block.

hook_help : provides help and additional information.
hook_perm : defines permissions for the module.
hook_block: creates a block or set of blocks.

We have to replace hook with our module name when using them.

This example block module cities will display a list of cities pulled out of a database.

<?php
// $Id: cities.module$

/**
 * @file
 * This is a module that display list of cities
 */

/**
 * Implementation of hook_help().
 */
function cities_help($path, $arg) {
  switch ($path) {
    case 'cities':
      return '<p>'. t('<b>help hook. This is a module that display list of cities.</b>') .'</p>';
  }
}

/**
 * Implementation of hook_perm().
 */
function cities_perm() {
  return array('access cites');
}

/**
 * grabbing data from the database
 */

global $arr; 
$arr=array();
global $datas;
$datas="";

$link = mysql_connect ('localhost', 'root', '');
$db = mysql_select_db ('cities', $link);

$sql = "SELECT name FROM city";
$sel = mysql_query($sql);
   
   if (mysql_num_rows($sel) > 0) { 
    $i=0;
    while($row = mysql_fetch_array($sel)) {
          
     $arr[$i]=$row['name'];
     $i=$i+1;
    }
    }
    
 foreach( $arr as $key => $value){
   $datas=$datas." ".$value."<br/>";
  }
  mysql_close();

/**
 * Implementation of hook_block().
 */
function cities_block($op = 'list', $delta = 0, $edit = array()) {
global $datas;
  if ($op == "list") {
    $block = array();
    $block[0]["info"] = t('cities');
    return $block;
  }
  elseif ($op == 'view') {
    $block_content = '<p>This is a block that display list of cities.</p>';
    $block['subject'] = 'City List';
    $block['content'] = $datas;
    return $block;
  }
}


Omitting the closing php tag is a drupal coding standard which prevents runtime issues.


Don't forget to enable your module (administrator-->modules) and pick a suitable place (administrator-->block) for it. Available permissions for this module can be viewed and customized from administrator-->permissions

That's it, now with this basic knowledge in hand it's not far away when you write more complex modules.

Tuesday, April 12, 2011

Star rating with MooStarRating

I'm not lying if I say javascript gives life to lifeless webpages. Javascript libraris make it easier for the developers to develop JavaScript-based applications especially with AJAX. Mootools is such a javascript framework. moostarrating is a mootools plugin which creates a javascript/ajax based attractive star rating system.

Following example shows you how to use moostarrating system and how to save the rating in a database using an Ajax call.

First download mootools core using this link.

Download the moostarrating plugin using this link. This page describes how to use the plugin but I thought it might be useful for all of you if I put here everything from the scratch.

I have deployed this example in a local environment, I recommend you to use xampp.

After installing xampp in windows, inside Apache Documents directory (C:\xampp\htdocs), create a new folder with a name you want, here I will use the name as "starRate". Extract the moostarrating plugin archive inside "starRate", also mootools core javascript should be placed inside "starRate".

Create a html file called star.html and save it inside "starRate". You can customize the default options and even functions in moostarrating.js the way you want.

star.html

<html>

<script src="mootools-core-1.3.1-full-compat.js"></script> 
 <script src="lorenzos-MooStarRating-422072a/Source/moostarrating.js"></script> 
 <script>   
  
  // When the DOM is ready....
  window.addEvent("domready",function() {
  
  MooStarRatingImages.defaultImageFolder = 'http://localhost/req/lorenzos-MooStarRating-422072a/Graphics/'; //Default images folder definition. You will use your own
   
   // Create our instance
   // Advanced options
   var advancedRating = new MooStarRating({
    form: 'ratingsForm', //Form name 
    radios: 'rating', //Radios name
    half: false, //if you need half star rating just make this true
    imageEmpty: 'star_boxed_empty.png', //Default images are in definition. You will use your own
    imageFull:  'star_boxed_full.png',
    imageHover: 'star_boxed_hover.png', 
    width: 17, 
    tip: 'Rate <i>[VALUE] / 7.0</i>', //Mouse rollover tip
    tipTarget: $('htmlTip'), //Tip element
    tipTargetType: 'html', //Tip type is HTML 
    
    // Send ajax request to server to save rating using "rating.php"
    onClick: function(value) {
          
     var requestHTMLData = new Request({
     url: 'rating.php',
     data: {rating: value}
     });
     requestHTMLData.send();
     }
     });  
   
   
  });
  
 </script> 
 <!-- radios have a default value, 2 -->
 <form name="ratingsForm">
    <label>Select The Number of Stars</label>
    <input type="radio" name="rating" value="1.0" checked="checked"> 
    
    <input type="radio" name="rating" value="2.0">
   
    <input type="radio" name="rating" value="3.0">
   
    <input type="radio" name="rating" value="4.0">
    
    <input type="radio" name="rating" value="5.0">
   
    <input type="radio" name="rating" value="6.0">
    
    <input type="radio" name="rating" value="7.0">
         
 <span id="htmlTip"></span>
</form>

</html>


In this example I use a php file to save the rating in a database. Create a database "rate_db", with a table "rate" with one column, you can use xampp phpmyadmin panel to create databases.

Create a php file called rate.php and save it inside "starRate" folder.

rate.php

<?php
$con = mysql_connect("localhost","root","");
if (!$con){
  die('Could not connect: ' . mysql_error());
}
mysql_select_db("rate_db", $con);

$dataSent = $_POST['rating'];

mysql_query("INSERT INTO rate VALUES('$dataSent')");

mysql_close($con);
?>



Start xampp control panel. Open up your favorite browser and place the following in address bar.

http://localhost/starRate/star.html



Now you'll be able to experience the usage of a fully functional star rating system.

Sunday, March 20, 2011

Getting started with GWT

GWT short for Google Web Development Kit lets programmers to develop Ajax web applications with java. Java codes are converted in to JavaScript and html codes by the GWT compiler. GWT applications are called modules and modules are described using a xml file, assuming the module name as "mymodule" name of the xml file would be "mymodule.gwt.xml". There is atleast one entry point for a module and it is same as the main method in a java program. GWT program code executes with in a HTML file and CSS file is used for alternating the look and feel.

Now that we are familiarized bit with terms and stuff we can move on to writing our own GWT application.

Step 1: Installing GWT plugin for eclipse

If you have already installed eclipse all you have to do is go to "Help" menu, under that "Install New Software" and give the URL as http://dl.google.com/eclipse/plugin/3.6 and click next and complete installation.


step 2: Creating a new project

Select File > New > Web Application Project. Enter the name "com.eviac.blog.helloworld" for the project name and package. By default it will select both "Use Google Web Toolkit" and "Use Google App Engine" as we only using Google Web Toolkit here you will have to deselect Google App Engine.


Now eclipse will create you a project with a package structure as shown below.


step 3: Creating the entry point

Inside the package com.eviac.blog.helloworld.client package create a java class named "HelloWorldGwt"

HelloWorldGwt.java
package com.eviac.blog.helloworld.client;

import com.google.gwt.core.client.EntryPoint;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.user.client.Window;
import com.google.gwt.user.client.ui.Button;
import com.google.gwt.user.client.ui.Label;
import com.google.gwt.user.client.ui.RootPanel;

public class HelloWorldGwt implements EntryPoint {

 @Override
 public void onModuleLoad() {
  final Label label = new Label("Hello World GWT !!!");
  final Button button = new Button("Click Here");
  button.addClickHandler(new ClickHandler() {
   @Override
   public void onClick(ClickEvent event) {
    label.setVisible(false);
    button.setText("welcome back again!");
    Window.alert("Welcome to GWT");
   }
  });

  RootPanel.get().add(label);
  RootPanel.get().add(button);
 }
}



Inside the package com.eviac.blog.helloworld create Com_eviac_blog_helloworld.gwt.xml file.

Com_eviac_blog_helloworld.gwt.xml

<?xml version="1.0" encoding="UTF-8"?>
<module rename-to='com_eviac_blog_helloworld'>
  <!-- Inherits Web Toolkit utilities.                        -->
  <inherits name='com.google.gwt.user.User'/>

  <inherits name='com.google.gwt.user.theme.standard.Standard'/>

  <!-- Specify the app entry point class.                         -->
  <entry-point class='com.eviac.blog.helloworld.client.HelloWorldGwt'/>
</module>


Step 3: Creating html page

Inside the folder war create Com_eviac_blog_helloworld.html file

Com_eviac_blog_helloworld.html

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">

<html>
  <head>
    <meta http-equiv="content-type" content="text/html; charset=UTF-8">
    <link type="text/css" rel="stylesheet" href="Com_eviac_blog_helloworld.css">
    <title>Hello World GWT</title>
    <script type="text/javascript" language="javascript" src="com_eviac_blog_helloworld/com_eviac_blog_helloworld.nocache.js"></script>
  </head>

  <body>

    <!-- optional tag: add this if needs history support -->
    <iframe src="javascript:''" id="__gwt_historyFrame" tabIndex='-1' style="position:absolute;width:0;height:0;border:0"></iframe>
    <h1><center>Hello World GWT</center></h1>
   
  </body>
</html>


Step 4: creating web.xml file

Inside the folder war/WEB-INF create a xml file called web.xml

web.xml

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE web-app
    PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
    "http://java.sun.com/dtd/web-app_2_3.dtd">
<web-app>

 <!-- Default page to serve -->
 <welcome-file-list>
  <welcome-file>Com_eviac_blog_helloworld.html</welcome-file>
 </welcome-file-list>
</web-app>



Step 5: Creating css file

Inside war falder create a css file named Com_eviac_blog_helloworld.css

Com_eviac_blog_helloworld.css

h1 {
  font-size: 2em;
  font-weight: bold;
  color: #6495ED;
}

.gwt-Label {
 color: #0000FF;
 font: normal 12px tahoma, arial, helvetica, sans-serif;
 height:3.5em;
 width: 10.7em;  
}

.gwt-Button {
 color: #0000FF;
 height:3.5em;
 width: 10.7em;
 font-size: 12px;
 font-family: arial, sans-serif; 
}



Alright now we are done with coding steps but wait for it, one more step to go

Step 6: Running GWT Application

To run right click on the project select Run As->Web Application then it will bring up a new view "Development Mode" copy the url generated.


Install GWT plugin for your web browser using this link.


Now paste the url in the browser and you'll see something like following and that's it.


Now that you know how to build a basic GWT application you can improve it by adding more functionalities and changing the look and feel using css file.

Thursday, February 24, 2011

Internet Control Message Protocol (ICMP)

Why ICMP is important

IP protocol lacks error reporting mechanism and hosting/managing queries. To compensate ICMP protocol comes to the role as a companion to IP protocol giving following two services.

  • Provides error reporting mechanism
  • Hosts and manages queries

Did you have any doubt

ICMP is a network layer protocol as IP is, so one would suspect whether ICMP messages are passed directly to the data link layer. The answer is no. ICMP messages are first encapsulated inside ip datagram and then passed to the below data link layer. Following image clearly shows you how it happens.


Talking about ICMP messages

  • Error reporting messages
  • ICMP acts as error reporting protocol it does not correct errors, error corrections are done by the higher level protocols. ICMP always sends the error messages to original source. There are five types of error messages as listed below.
    • Destination unreachable
    • Source quench
    • Time exeeded
    • Parameter problem
    • Redirection
  • Query messages
  • ICMP can also diagnose network problems through query messages. There are two pairs of query messages used for this purpose today.
    • Echo request or reply
    • Timestamp request or reply

Debugging tools that uses ICMP

ping

ping program can be used to find out whether a host is alive and responding. The source host sends an ICMP echo request message, if the destination host is alive it responds with ICMP echo reply messages.



traceroute

traceroute progam in unix or tracert in windows can be used to trace the route of a packet from source to destination.


Sunday, February 13, 2011

Crypto Samples in java part four -Stream Cipher

SendStream.java

import java.io.FileOutputStream;
import java.io.ObjectOutputStream;

import javax.crypto.Cipher;
import javax.crypto.CipherOutputStream;
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;

public class SendStream {
 
 public static void main(String[] args) {
  
  String data = "This have I thought good to deliver thee rrrr";
  
  //---------------Encryption ---------------------------------

  SecretKey key = null;

  try {
   KeyGenerator keygen = KeyGenerator.getInstance("DES");
   key = keygen.generateKey();

   Cipher cipher = Cipher.getInstance("DES/CBC/PKCS5Padding");
   cipher.init(Cipher.ENCRYPT_MODE, key);
   
   FileOutputStream fos = new FileOutputStream("cipher.file"); 
   CipherOutputStream cos = new CipherOutputStream(fos, cipher);
   ObjectOutputStream oos = new ObjectOutputStream(cos);   
   
   
   oos.writeObject(data);
   oos.flush();
   oos.close();
   
   
   FileOutputStream fosKey = new FileOutputStream("key.file"); 
   ObjectOutputStream oosKey = new ObjectOutputStream(fosKey); 
   oosKey.writeObject(key);
   oosKey.writeObject(cipher.getIV());

  } catch (Exception e) {
   e.printStackTrace();
  } 

 }

}



ReceiveStream.java

package ucsc.cipher;

import java.io.FileInputStream;
import java.io.ObjectInputStream;

import javax.crypto.Cipher;
import javax.crypto.CipherInputStream;
import javax.crypto.SecretKey;
import javax.crypto.spec.IvParameterSpec;

public class RecieveStream {
 
 public static void main(String[] args) {
  SecretKey key = null;

  try {
   FileInputStream fisKey = new FileInputStream("key.file"); 
   ObjectInputStream oosKey = new ObjectInputStream(fisKey); 
   
   key =  (SecretKey)oosKey.readObject();
   
   byte[] iv = (byte[])oosKey.readObject();


   Cipher cipher = Cipher.getInstance("DES/CBC/PKCS5Padding");
   cipher.init(Cipher.DECRYPT_MODE, key, new IvParameterSpec(iv));
   
   FileInputStream fis = new FileInputStream("cipher.file"); 
   CipherInputStream cis = new CipherInputStream(fis, cipher);
   ObjectInputStream ois = new ObjectInputStream(cis);   
   
   
            System.out.println((String)ois.readObject());   
   
  } catch (Exception e) {
   e.printStackTrace();
  } 

  
 }

}


Friday, February 11, 2011

Crypto Samples in java part three - Symmetric key encryption


A secret key is generated and only known by the sender and the receiver. Sender encrypts the plain text in to cypher text using the shared key and sends it to the receiver. After Receiver receives the encrypted message he/she decrypts the message using the shared key and grabs the original plain text (have a look at the image for a better understanding).

import java.security.spec.AlgorithmParameterSpec;

import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
import javax.crypto.spec.IvParameterSpec;

public class SimpleCipher {

 public static void main(String[] args) {

  String data = "This have I thought good to deliver thee";

  // ---------------Encryption ---------------------------------

  byte[] encrypted = null;
  byte[] iv = null;
  SecretKey key = null;

  try {
   KeyGenerator keygen = KeyGenerator.getInstance("DES");/*
                 * get the key
                 * generator
                 * instance
                 */
   key = keygen.generateKey();// generate the secret key

   Cipher cipher = Cipher.getInstance("DES/CBC/PKCS5Padding");
   /*
    * get cipher engine instance.DES algorithm is used and it requires
    * the input data to be 8-byte sized blocks. To encrypt a plain text
    * message that is not multiples of 8-byte blocks, the text message
    * must be padded with additional bytes to make the text message to
    * be multiples of 8-byte blocks.PKCS5Padding has used for that
    * purpose. note that CBC is a block cipher mode therefore we need
    * an initialization vector to chain blocks.
    */

   cipher.init(Cipher.ENCRYPT_MODE, key);/*
             * initializing cipher engine
             * for encryption
             */

   encrypted = cipher.doFinal(data.getBytes());/* do the encryption */

   iv = cipher.getIV();/*
         * save the initialization vector, remember that
         * we need this only when we are using cipher
         * block chaining mode for encryption
         */

  } catch (Exception e) {
   e.printStackTrace();
  }

  // ---------------Decryption ---------------------------------

  try {

   Cipher cipher = Cipher.getInstance("DES/CBC/PKCS5Padding");/*
                   * get
                   * cipher
                   * engine
                   * instance
                   */

   AlgorithmParameterSpec param = new IvParameterSpec(iv);/*
                  * set the
                  * vector
                  * value
                  */

   cipher.init(Cipher.DECRYPT_MODE, key, param);/*
               * initializing cipher
               * engine for decryption
               */

   byte[] decrypted = cipher.doFinal(encrypted);/*
               * obtain original plain
               * text
               */

   System.out.println(new String(decrypted));

  } catch (Exception e) {
   e.printStackTrace();
  }

 }

}


Monday, January 31, 2011

Crypto Samples in java part two - Message Digest Streams

SendStream.java writes data along with message digest to a file "test".

SendStream.java

import java.io.*;
import java.security.*;

public class SendStream {
 public static void main(String args[]) {
  try {

   // We need to write data + message digest to this file.
   // Basically this is the file we need to send to the receiver
   FileOutputStream fos = new FileOutputStream("test");

   // We are going to calculate the message digest with SHA
   MessageDigest md = MessageDigest.getInstance("SHA");

   // Updates the associated message digest
   // using the bits going through the stream.
   DigestOutputStream dos = new DigestOutputStream(fos, md);

   ObjectOutputStream oos = new ObjectOutputStream(dos);

   String data = "This have I thought good to deliver thee, "
     + "that thou mightst not lose the dues of rejoicing "
     + "by being ignorant of what greatness is promised thee.";

   // Write the specified object to the ObjectOutputStream
   // Now the message being written to the FileOutputStream
   // Also - this will update the message digest of the written data as well..
   oos.writeObject(data);

   // urns the digest function on or off. The default is on. When it is on, a call to one
   // of the write methods results in an update on the message digest. But when it is off,
   // the message digest is not updated.
   dos.on(false);

   // Now let's also write the message digest to the file,
   oos.writeObject(md.digest());

  } catch (Exception e) {
   System.out.println(e);
  }
 }
}



RecieveStream.java takes file "test" as an input reads the data and calculate digest of that data and compare it with the original message digest read from the file "test".

RecieveStream.java

import java.io.FileInputStream;
import java.io.ObjectInputStream;
import java.security.DigestInputStream;
import java.security.MessageDigest;

public class RecieveStream {
 public static void main(String args[]) {
  try {

   // Here we get a file from the sender - and we need to verify it's message digest
   // The file contains both the message and the digest.
   FileInputStream fis = new FileInputStream("test");

   // We are going to calculate the message digest with SHA
   MessageDigest md = MessageDigest.getInstance("SHA");

   // Updates the associated message digest
   // using the bits going through the stream.
   DigestInputStream dis = new DigestInputStream(fis, md);

   ObjectInputStream oos = new ObjectInputStream(dis);

   // Read the message from the file
   String data = (String) oos.readObject();
   
   dis.on(false);

   // Original message digest from the input file.
   byte[] originalDigest = (byte[]) oos.readObject();

   if (MessageDigest.isEqual(originalDigest, dis.getMessageDigest().digest())) {
    System.out.println("VALID");
   } else {
    System.out.println("INVALID");
   }

  } catch (Exception e) {
   System.out.println(e);
  }
 }
}