30 December, 2010

Basic url rewrite example

URL that is readable looks nice. But despite efforts by developers, sometimes for instance, using a Content Management System (CMS) serve url's in the format like,

http://www.testthis.com/list_products?cat_name=Shirts&cat_id=8


Now, this is really a bad url, and is prevelant with dynamic pages. Some of the problems of such url's are:
1) It exposes the type of data, query string to malicious users.
2) The characters such as question mark and ampersand can be troublesome.
3) Such url's wont be indedxed by search engines.

Solution to this is, above url can be mapped to something like this;

http://www.testthis.com/products/Shirts/8


Looks much better. And in order to do such mapping, we need url rewriting.
Apache's mod_rewrite gives us the ability to rewrite urls. Url rewrite can be
done to redirect from old to new address, clean up dirty url's, as mentioned above.
This makes our url's search engine friendly which means search engines can index such urls.

For url rewrite, we create a file .htaccess at the root of our project, and add following line.

RewriteEngine On


Basic Redirects

Lets say we moved all of our files from an older location to a new one, now we want to redirect all the links to current location. For that we can do the following.

RewriteEngine On
RewriteRule ^old\.html$ new.html


What the above rule does, is, it simple redirect from old.html to new.html page.
The ^ sign indicates Start of the url to be matched. If this character is removed, then our rule would also match hold.html
The $ sign indicates end of the string to be matched. In this case users would not know a redirect has occured from old.html to new.html

But lets say you want users to know that redirect has occured, that means you want to force a redirect. In such case you can do as,

RewriteEngine On
RewriteRule ^old\.html$ new.html [R]


Using Regular Expressions in Url Rewrite
The full strength of mod_rewrite can be felt at expense of complexity. Using regular expressions for url rewrite, you can have rules for set or urls, and have redirection for all to actual pages.
For example,

http://www.testthis.com/list_book?bookId=20


Now, we can rewrite this kind or url to make it friendly, as,

RewriteEngine On
RewriteRule ^book/([0-9][0-9])/$ list_book.php?bookId=$1


So above rule will create urls such as, http://www.testthis.com/book/8

But if a user types in like, http://www.testthis.com/book/8, our url rewrite rule wont work, as the slash at the end is missing, so to prevent such problems, we can do as,

RewriteEngine On
RewriteRule ^book/([0-9][0-9])/$ book/$1/ [R]
RewriteRule ^book/([0-9][0-9])/$ list_book.php?bookId=$1


Now, if a user enters something like book/12, our first rules comes in to add a slash at the end,then second
rule comes into play.

Regular expressions in url rewrite can be expanded by using modifiers, that allow you to match url with indefinite number of characters. Lets say, our url is like,
http://www.testthis.com/list_book?bookId=220

Our rule wont match this, as we have checked against two digits only, so we should use modifiers in this case.

RewriteEngine On
RewriteRule ^book/([0-9]+)$ book/$1/ [R]

+ indicates one or more of the preceeding characters or range.
* means 0 or more preceeding characters or range

So, above rule will match both book/1 and book/3000

In this way we can use mod_rewrite to rewrite url. These are just an introductory examples. There's a lot more way to move ahead in url rewriting and regular expressions. I hope this basic url rewrite post can be of some help to others.

27 December, 2010

Excel to Array in PHP

Customer's data can come from various sources, and making it easier for them to get the data into our system means we are increasing our customer's count. So, our code should support importing of data from different sources.
And one of the common sources can be Excel. So, we need to create an interface for customers so that they can load data from excel to our database.
Instead of spending hours entering data into forms, users can simply use tools such as excel to load data from excel using php.
In the following code, we load data from excel in php, read it and display the data back to the users. The displaying of data part can be replaced by inserting the loaded excel data to database to suit individual needs. And we are
using XML to do this.


Let's say we have a form "form.php" as:


File:





Now after user adds an excel file and uploads it, following code "do_act.php" is executed,

$dataArr = array();
if($_FILES["excelFle"]["tmp_name"]) {
$xmlDom = DOMDocument::load($_FILES["excelFle"]["tmp_name"]);
$allRows = $xmlDom->getElementsByTagName('Row');
//loop through each of the row element
foreach($allRows as $row) {
$cells = $row->getElementsByTagName('Cell');
$rowData = array();
foreach($cells as $cell) {
$rowData []= $cell->nodeValue;
}
$dataArr []= $rowData;
}
}

//so now you can check for the array of data as:
echo "
";
print_r($dataArr);
echo "
";

Excel to Array in PHP

Customer's data can come from various sources, and making it easier for them to get the data into our system means we are increasing our customer's count. So, our code should support importing of data from different sources.
And one of the common sources can be Excel. So, we need to create an interface for customers so that they can load data from excel to our database.
Instead of spending hours entering data into forms, users can simply use tools such as excel to load data from excel using php.
In the following code, we load data from excel in php, read it and display the data back to the users. The displaying of data part can be replaced by inserting the loaded excel data to database to suit individual needs. And we are
using XML to do this.


Let's say we have a form "form.php" as:


File:





Now after user adds an excel file and uploads it, following code "do_act.php" is executed,

$dataArr = array();
if($_FILES["excelFle"]["tmp_name"]) {
$xmlDom = DOMDocument::load($_FILES["excelFle"]["tmp_name"]);
$allRows = $xmlDom->getElementsByTagName('Row');
//loop through each of the row element
foreach($allRows as $row) {
$cells = $row->getElementsByTagName('Cell');
$rowData = array();
foreach($cells as $cell) {
$rowData []= $cell->nodeValue;
}
$dataArr []= $rowData;
}
}

//so now you can check for the array of data as:
echo "
";
print_r($dataArr);
echo "
";

22 December, 2010

Dynamic functions in CodeIgniter Model

Using dynamic function can be of great ease at times. Since i was developing some project on codeIgniter, i thought of giving it a try to create dynamic functions in codeigniter model. The following code is just a startup, if this works out good then will add more of the functions in it.
Functions can be created on the fly using PHP's magic method __call(). As per php.net this method is triggered when invoking methods that are not accessible in object context.
So, in codeIgniter as there are controllers, views and models. I thought of adding a model that would create dynamic functions, which can then be accessed by controllers.
The code snippet is just a test.
I created a Test_model.php file as:

class Test_model extends Model {
private $id = 0;
private $table;
private $fields = array();
function Test_model() {
parent::Model();
}
//setup the tablename and field names
function set_up_table($table, $fields) {
$this->table = $table;
foreach($fields as $key) {
$this->fields[$key] = null;
}
}
//magic method to set and get
function __call($method, $args) {
if(preg_match("/set_(.*)/", $method, $exists)) {
if(array_key_exists($exists[1], $this->fields)) {
$this->fields[$exists[1]] = $args[0];
return true;
}
}
else if(preg_match("/get_(.*)/", $method, $exists)) {
if(array_key_exists($exists[1], $this->fields)) {
return $this->fields[$exists[1]];
}
}
return false;
}
//function to insert to database
function insert() {
$this->db->insert($this->table, $this->fields);
return $this->db->insert_id();
}

}

Now the controller part:

class Welcome extends Controller {

function Welcome() {
parent::Controller();
}

function index() {
//name of fields in book table
$fieldsArr = array( 'id', 'author','title', 'publisher' );
$tableName = "book";

$this->load->model("Test_model", "test");
$this->test->set_up_table($tableName, $fieldsArr);
$this->test->set_author("John Doe");
$this->test->set_title("Advanced PHP Web Development");
$this->test->set_publisher("Wrox");
$bookId = $this->test->insert();

$this->load->view('welcome_message');
}
}

And thats it. The code in controller sets values for all the fields and then we call insert function created in our model. The main objective behind the code is to show how dynamic functions tend to ease out the process of coding.

Cross domain communication using jQuery

Due to some restrictions added by browsers, communication across cross domains is not possible by simple use of Ajax technology. It can be done though by adding a server-side script like PHP, and CURLing the other domain to get data and then passing it on to our javascript. But this method requires more code and is
not scalable.

A better way is to dynamically add script to the page, whose source points to the service url and get the response (data) in the script. This is what JSONP
(Javascript Object Notation with Padding) does.

JSON is a lightweight data exchange format for exchanging data between browser and server, and jQuery has a native support for JSONP calls beginning with version 1.2. We can load JSON data located at another domain specifying a JSONP callback.

This can be done as:


$.getJSON(domainurl+"&callback=?", function(response) {
alert("Username: " + response.username);
});


In above code jQuery replaces '?' after 'callback=' with a generated function name to call. And on complete the function name is removed.

Despite its ease of use for cross-domain comunication, JSONP has some drawbacks as well. Lets say, if the dynamic script addition does not work then nothing happens, we do not get any errors, it means there is no any error handling support in JSONP.

20 December, 2010

Parse XML using Javascript

It is quite easier to parse XML using Javascript. Most of the browsers have XML parsers for manipulating XML. But, prior to parsing the XML it must first be loaded to XML DOM object, which can then be accessed with Javascript. Since for some security reasons, browsers do not allow access across domains, both the page and the xml it is trying to load should be in same server.

Lets's say, we have an users.xml file like:



Sudhir
Bastakoti
27


John
Doe
72



Step 1: Load the XML

function loadXML(xmlFile) {
if(window.XMLHttpRequest) {
xvar = new XMLHttpRequest();
}
else {
xvar = new ActiveXObject("Microsoft.XMLHTTP");
}
xvar.open("GET", xmlFile, false);
xvar.send();
return xvar.responseXML;
}

OR, the XML can be loaded as string as well, like

function loadXMLString(xmlString) {
//here xmlString is the content of XML as string
if(window.DOMParser) {
parseIt = new DOMParser();
xDoc = parseIt.parseFromString(xmlString,"text/xml");
}
else {
xDoc = new ActiveXObject("Microsoft.XMLDOM");
xDoc.async = "false";
xDoc.loadXML(xmlString);
}
return xDoc;
}


There are some properties of DOM u.parentNode gives parent node of u, u.childNodes gives child nodes of u, u.attributes gives attributes nodes of u, u.nodeName gives name of u , u.nodeValue gives value of u
And we have a nodeType Property
Element has NodeType 1, Attribute 2, Text 3, Comment 8 and Document 9

Step 2:
To get the length of nodes we can do as:

xDoc = loadXML("books.xml");
u = xDoc.getElementsByTagName("user").length;
//it will output 2

To loop through all the nodes we can do as:

xDoc = loadXML("books.xml");
u = xDoc.documentElement.childNodes;
var details = "";
for(var i = 0; i < u.length; i++) {
details +=u[i].nodeName+": "+x[i].childNodes[0].nodeValue+"
";
}
alert(details);

16 December, 2010

Detect Ajax request using PHP

Sometimes, we need to detect ajax request using php. In such case, we can write following code that checks whether the request is ajax or not. It is helpful in conditions such as when i have to load a page depending on condition using a same function in php.

if(isset($_SERVER['HTTP_X_REQUESTED_WITH']) && $_SERVER['HTTP_X_REQUESTED_WITH'] == 'XMLHttpRequest')) {
echo "Ajax request";
}
else {
echo "Normal Page Load";
}

And thats it.

Check uncheck jquery plugin

I needed check all - uncheck all checkboxes feature to be added to lots of pages in one of my site, so thought of creating a jquery plugin for it, so that i would not have to write same piece of code here and there. So here's the plugin, if Check All checkbox is checked all the sub checkboxes are checked and vice-versa, and if Check All is checked and then any of the sub checkboxes is unchecked, then Check All will also be unchecked.

(function($) {
$.fn.extend({
checkun: function(options) {
var defaults = {
chkAllName : "",
chkBoxName : ""
}
var options = $.extend(defaults, options);
var chkAll = options.chkAllName;
var chkBoxs = options.chkBoxName;
var chkBoxesLength = $("input[name='"+chkBoxs+"']").length;

$("input[name='"+chkAll+"']").click(function() {
//get checked state of chkAll checkbox
var chkState = $(this).attr("checked");
if(chkState) {
$("input[name='"+chkBoxs+"']").attr("checked", true);
}
else {
$("input[name='"+chkBoxs+"']").attr("checked", false);
}
});
$("input[name='"+chkBoxs+"']").click(function() {
var subChkState = $(this).attr("checked");
if(subChkState) {
//get the total checkboxes and total checked checkboxes
var chkedLen = $("input[name='"+chkBoxs+"']:checked").length;
if(chkedLen == chkBoxesLength) {
$("input[name='"+chkAll+"']").attr("checked", true);
}
}
else {
//uncheck the chkAll checkbox
$("input[name='"+chkAll+"']").attr("checked", false);
}
});
}
});
})(jQuery);

And to test it, we use the following

//load jquery.js

//  Check All
//
//

Thats it. Hope this helps someone.

11 December, 2010

How to extract segment of video using FFMPEG

Once i had a situation where i had to extract a part (segment) of a video lets say from 3rd second to 8thd second. So after searching through FFMPEG documentation
i came to know how this could be done.
Following code snippet can be used to extract a segment of video.

$inputFile = "melt.mpg";
$outputFile = "melted.flv";
//-ss is the start time in HH:mm:ss
//-t is the end time in HH:mm:ss
system("path-to-ffmpeg/ffmpeg -i $inputFile -ss 00:00:03 -t 00:00:08 $outputFile");

And that's it.

How to get Lattitude and Longitude from Address using Google Maps

We can easily locate store using Goolge Maps Geocoder.
Google Maps uses REST method for accessing the services.

Our code uses cURL to locate stores using Google Maps API geocoder,
to query HTTP based geocoding API and SimpleXML to parse the
returned response. So, following code can be used to get the lattitude
and longitude of an address using google Maps Geocoder.

Lets start with the code using cURL for request. The cURL request
returns an XML in fact KML response on valid request.

$apiKey = "your_api_key_for_google_maps";
$address = "your_address";
$city = "your_city";
$state = "your_state_prefix";
$zip = "your_zip_code";

$url = "http://maps.google.com/maps/geo?output=xml&key=$apiKey&q=";
$query = $address.",".$city.",".$zip;
$url .= urlencode($query);

//initialize rhte curl object
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_HEADER, 0);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
$response = curl_exec($ch);
curl_close($ch);


Now its time to parse the XML response using PHP's SimpleXML.

$xmlResponse = simplexml_load_string($response);

//check if the status code in response is 200, i.e. OK
if($xmlResponse->Response->Status->code == 200) {
foreach($xmlResponse->Response as $response) {
foreach($response->Placemark as $place) {
$latLngArr = explode(",", $place->Point->coordinates);
$lattitude = $latLngArr[0];
$longitude = $latLngArr[1];
}
}
}

In this way we can find lattitude and longitude of an address
using Google Maps geocoder feature.

How to display tabs in Google Maps Info Window

Google MAPS API have added lots of tab related features to its info windows.
We can use multiple tabs in one info windows, and this can be changed
using different GInfoWindow methods provided be the API.
So displaying tabs in Google Maps Info Window is really a simple task.

Following code snippet creates an info window with two tabs in it.

Lets first create a container for our map.

var oMap = new GMap2(document.getElementById("divMap"));


Now, check if our browser supports Google Maps

if(GBrowserIsCompatible()) {
var oMap = new GMap2(document.getElementById("divMap"));
}


Now lets initialize the map to a specific area, this can be done as:

//the setCenter function accepts two arguments, one is the point
//calculated from lattitude & longitude, and second is the
//zoom level
if(GBrowserIsCompatible()) {
var oMap = new GMap2(document.getElementById("divMap"));
oMap.setCenter(new GLatLng(82, -110), 3);
}


Now lets add controls to our map. Google Maps API provides different
control functions, but we will be adding just two of those.

if(GBrowserIsCompatible()) {
var oMap = new GMap2(document.getElementById("divMap"));
oMap.addControl(new GSmallMapControl());
oMap.addControl(new GMapTypeControl());
oMap.setCenter(new GLatLng(82, -110), 3);
}


Now lets add a marker in our map. Markers in Google Maps are
the simplest among provided overlays.

if(GBrowserIsCompatible()) {
var oMap = new GMap2(document.getElementById("divMap"));
oMap.addControl(new GSmallMapControl());
oMap.addControl(new GMapTypeControl());
oMap.setCenter(new GLatLng(82, -110), 3);

marker = new GMarker(new GLatLng(82, -110));
oMap.addOverlay(marker);
}


Lastly lets add a tabbed info window now.

if(GBrowserIsCompatible()) {
var oMap = new GMap2(document.getElementById("divMap"));
oMap.addControl(new GSmallMapControl());
oMap.addControl(new GMapTypeControl());
oMap.setCenter(new GLatLng(82, -110), 3);

marker = new GMarker(new GLatLng(82, -110));
oMap.addOverlay(marker);

var tabInfos = [
new GInfoWindowTab("First Tab", "Contents for first tab."),
new GInfoWindowTab("Second Tab", "Contents for second tab."),
new GInfoWindowTab("Third Tab", "Contents for third tab.")
];

marker.openInfoWindowTabsHtml(tabInfos, {
selectedTab: 1, //first tab will be selected
maxWidth: 320 //max width of info window
});
GEvent.addListener(marker, 'click', function () {
marker.openInfoWindowTabsHtml(tabInfos);
});
}

And that's it.

08 December, 2010

Get all files inside a directory using php

Listing of files inside a directory can be done simply using php.
Following function can be used to list all the files inside a directory.

function list_directory($dirpath) {
$files = array(); //files array
$dirs = array(); //directories array
$file_num = 0; //set number of files to 0
$dir_num = 0; //set number of directories to 0
//check if the path is a directory
if (is_dir($dirpath)) {
//create a handle for opening directory
$hndl = opendir($dirpath);
//start the loop
do {
//read the directory
$fle = readdir($hndl);
if ($fle !== FALSE && $fle != "." && $fle != "..") {
//check if its a directory or a file
if (is_dir("$dirpath/$fle")) $dirs[$dir_num++] = $fle;
else $files[$file_num++] = $fle;
}
} while($fle !== FALSE);
closedir($hndl);
}
return array($dir_num, $file_num, $dirs, $files);
}