headers [] = 'Accept: image/gif, image/x-bitmap, image/jpeg, image/pjpeg';
$this->headers [] = 'Connection: Keep-Alive';
$this->headers [] = 'Content-type: application/x-www-form-urlencoded;charset=UTF-8';
$this->user_agent = 'Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1; .NET CLR 1.0.3705; .NET CLR 1.1.4322; Media Center PC 4.0)';
$this->compression = $compression;
$this->proxy = $proxy;
$this->cookies = $cookies;
if ($this->cookies == TRUE)
$this->cookie ( $cookie );
}
/**
* Set the cookie file name. If file exists then file name is made absolute
* else an empty file is created.
*
* @param string $cookie_file
*/
function cookie($cookie_file) {
if (file_exists ( $cookie_file )) {
$this->cookie_file = realpath($cookie_file);
} else {
$fch = fopen ( $cookie_file, 'w' ) or $this->error ( 'The cookie file could not be opened. Make sure this directory has the correct permissions' );
$this->cookie_file = realpath($cookie_file);
fclose ( $fch );
}
}
/**
* Send a GET request via curl, using the current settings, cookies, etc
*
* @param string $url
* @return string - contents of the url
*/
function get($url) {
$process = curl_init ( $url );
curl_setopt ( $process, CURLOPT_HTTPHEADER, $this->headers );
curl_setopt ( $process, CURLOPT_HEADER, $this->header );
curl_setopt ( $process, CURLOPT_USERAGENT, $this->user_agent );
if ($this->cookies == TRUE)
curl_setopt ( $process, CURLOPT_COOKIEFILE, $this->cookie_file );
if ($this->cookies == TRUE)
curl_setopt ( $process, CURLOPT_COOKIEJAR, $this->cookie_file );
curl_setopt ( $process, CURLOPT_ENCODING, $this->compression );
curl_setopt ( $process, CURLOPT_TIMEOUT, 30 );
if ($this->proxy)
curl_setopt ( $process, CURLOPT_PROXY, $this->proxy );
if ($this->referer)
curl_setopt( $process, CURLOPT_REFERER, $this->referer );
curl_setopt ( $process, CURLOPT_AUTOREFERER, 1 );
curl_setopt ( $process, CURLOPT_RETURNTRANSFER, 1 );
curl_setopt ( $process, CURLOPT_FOLLOWLOCATION, 1 );
$return = curl_exec ( $process );
curl_close ( $process );
return $return;
}
/**
* Send a POST request along with the post data
*
* @param string $url - a valid url resource
* @param string $data - url encoded query string
* @return string - contents of the url fetc
*/
function post($url, $data) {
$process = curl_init ( $url );
curl_setopt ( $process, CURLOPT_HTTPHEADER, $this->headers );
curl_setopt ( $process, CURLOPT_HEADER, $this->header );
curl_setopt ( $process, CURLOPT_USERAGENT, $this->user_agent );
if ($this->cookies == TRUE)
curl_setopt ( $process, CURLOPT_COOKIEFILE, $this->cookie_file );
if ($this->cookies == TRUE)
curl_setopt ( $process, CURLOPT_COOKIEJAR, $this->cookie_file );
curl_setopt ( $process, CURLOPT_ENCODING, $this->compression );
curl_setopt ( $process, CURLOPT_TIMEOUT, 30 );
if ($this->proxy)
curl_setopt ( $process, CURLOPT_PROXY, $this->proxy );
if ($this->referer)
curl_setopt( $process, CURLOPT_REFERER, $this->referer );
curl_setopt ( $process, CURLOPT_POSTFIELDS, $data );
curl_setopt ( $process, CURLOPT_AUTOREFERER, 1 );
curl_setopt ( $process, CURLOPT_RETURNTRANSFER, 1 );
curl_setopt ( $process, CURLOPT_FOLLOWLOCATION, 1 );
curl_setopt ( $process, CURLOPT_POST, 1 );
$return = curl_exec ( $process );
curl_close ( $process );
return $return;
}
/**
* Just dump the error in a formatted way
*
* @param string $error
*/
function error($error) {
echo "
cURL Error
$error
";
die ();
}
}
/**
* Various utility functions for the Flipkurl class
* Contains functions for cleaning, parsing data mainly
* the fetching part etc are implemented in Flipkurl class
*
*/
class FlipMisc {
/**
* Returns all instances between two string delimiters
*
* @param string $s - the string to find stuff inside
* @param string $st - starting string
* @param string $en - ending string
* @return array - all matching instances
*/
static function get_between($s,$st='<',$en='>') {
$re = array();
$el = explode($st,$s);
$l = count($el);
$cpos=0;
$m = array();
for( $i=1; $i<$l; $i++ ) {
$m[]= substr($el[$i],0,strpos($el[$i],$en) );
}
return $m;
}
/**
* Returns the first instance between two string delimiters
*
* @param string $s - the string to find stuff inside
* @param string $st - starting string
* @param string $en - ending string
* @return array - all matching instances
*/
static function get_single_between( $s, $st, $en ) {
$re = array();
$el = explode($st,$s);
$l = count($el);
$cpos=0;
$m = '';
for( $i=1; $i<$l; $i++ ) {
return substr($el[$i],0,strpos($el[$i],$en) );
}
return $m;
}
/**
* Returns the integer version of the rupees string
* Input is given with "Rs. 123". Simple cleanup thou.
* Can use regex, but duh forgot.
*
* @param string $str
* @return integer - int value in the money
*/
static function get_price_int( $str ) {
$str = trim(str_ireplace( 'Rs', '', trim($str) ));
$str = trim( $str, '.' );
$str = trim( $str );
$str = (int)$str;
return $str;
}
/**
* This function is used to extract information such as price, discount being given & savings
* in proper integer / float formats from the given html block containing priced related stuff
*
* @param string $str
* @return array - containing price, discount% & saving
*/
static function clean_prices( $str ) {
$price=0;
$discount=0;
$saving=0;
$parts = explode( "
", $str );
$parts = array_map( 'trim', $parts );
$price = $parts[0];
if( count($parts)>2 ) {
$saving = substr( $parts[1], strpos( $parts[1], "Rs" ) );
$discount = (float)FlipMisc::get_single_between( $parts[2], "(", "%)" );
}
if( stripos( $price, "Rs" ) !== false )
$price = str_ireplace( "Rs", "", $price );
$price = trim( $price, ". " );
$price = (int)$price;
if( stripos( $saving, "Rs" ) !== false )
$saving = str_ireplace( "Rs", "", $saving );
$saving = trim( $saving, ". " );
$saving = (int)$saving;
return array( 'price'=>$price, 'discount'=>$discount, 'saving'=>$saving );
}
/**
* Similarly clean up the chunk of html containing book related info
* like link to book's page, id, title, author, etc
*
* @param string $str
* @return array
*/
static function clean_titles( $str ) {
$link = FlipMisc::get_single_between( $str, 'href="', '"' );
$edition_id = substr( $link, strrpos( $link, "-" )+1 );
$title = FlipMisc::get_single_between( $str, '">', "" );
$author = FlipMisc::get_single_between( $str, "", "" );
$author = trim( strip_tags( $author ) );
if( ($pos=strpos($author,"by")) !== false and $pos == 0 )
$author = trim( substr( $author, 2 ) );
if( empty($edition_id) ) {
$title = $author = $link = '';
$id = null;
}
return array( 'id'=>$edition_id, 'author'=>$author, 'title'=>$title, 'link'=>$link );
}
/**
* This function uses the above few functions to fetch and clean up the data from cart contets page
* and puts them in a nicely formatted array
*
* @param string $con - raw HTML of the viewcart.php page
* @return array
*/
static function getCartContents( $con ) {
$prices = FlipMisc::get_between( $con, '', '
' );
$titles = FlipMisc::get_between( $con, '', '
' );
foreach( $prices as $pi=>$value )
$prices[ $pi ] = FlipMisc::clean_prices( $prices[$pi] );
foreach( $titles as $ti=>$value )
$titles[ $ti ] = FlipMisc::clean_prices( $titles[$ti] );
$quantity = FlipMisc::get_between( $con, 'cart_edition_qty_textbox" size="3" value="','"' );
$summary = FlipMisc::get_between( $con, '', '' );
$summary = array_map( 'strip_tags', $summary );
$summary_arr["total"] = (int)trim(str_ireplace( 'Rs', '', trim($summary[0]) ),' .,');
$summary_arr["discount"] = (float)FlipMisc::get_single_between( $summary[1], "(", '%)' );
$summary_arr["saving"] = (int)trim(FlipMisc::get_single_between( $summary[1], ".", '(' ));
$cart = array();
foreach( $titles as $title_i=>$info ) {
$eid = strtoupper($info["id"]);
if( empty( $eid ) ) continue;
$cart[ $eid ] = array_merge( $prices[ $title_i ], $info );
$cart[ $eid ][ "quantity" ] = (int)$quantity[ $title_i ];
}
$cartinfo = array(
'items' => $cart,
'summary' => $summary_arr
);
return $cartinfo;
}
/**
* This parses the search listing page's raw HTML to fetch the listing in a formatted array
* for easier use.
*
* It makes use of DomDocument & DomXPath. Remembered that i could use it after
* i wrote the dirty way for getCartContents(). Not feeling like rewriting the above chunk, so letteing it be.
* Perhaps will include in next-version, if there is one !
*
* @param string $con - raw html dump
* @return array
*/
static function parseSearchListing( $con ) {
$docObj = new DOMDocument();
@$docObj->loadHTML( $con );
$xpath = new DOMXPath( $docObj );
$items = $xpath->query("//div[@class='search_result_item']");
$sinfo = $xpath->query("//span[@class='search_intro']")->item(0)->nodeValue;
//Showing 1-10 of 2461 search result
$matches = array();
preg_match( "/([\d]+)-([\d]+) of ([\d]+)/", $sinfo, $matches );
$listing["from"] = (int)$matches[1];
$listing["to"] = (int)$matches[2];
$listing["total"] = (int)$matches[3];
$listing["pages"] = ceil( (float)$listing["total"] / ($listing["to"]-$listing["from"]) );
$listing["page"] = ceil($listing["from"] / ($listing["to"]-$listing["from"]));
foreach( $items as $i=>$item ) {
$j = $i+1;
$tinfo = $xpath->query("//div[@class='search_result_item'][$j]//div[@class='search_result_title']//a");
$opinfo = $xpath->query("//div[@class='search_result_item'][$j]//span[@class='search_results_price']//span")->item(0);
$dpinfo = $xpath->query("//div[@class='search_result_item'][$j]//span[@class='search_results_price']//font")->item(0);
$diinfo = $xpath->query("//div[@class='search_result_item'][$j]//span[@class='search_results_discount']//b")->item(0);
$status = $xpath->query("//div[@class='search_result_item'][$j]//td//i")->item(0);
$summary= $xpath->query("//div[@class='search_result_item'][$j]//div[@class='search_results_about']")->item(0);
$id = $xpath->query("//div[@class='search_result_item'][$j]//input[@name='eid']")->item(0);
if( !$id )
$id = $xpath->query("//div[@class='search_result_item'][$j]//input[@name='edition_id']")->item(0);
$dpinfo = $dpinfo ? FlipMisc::get_price_int($dpinfo->nodeValue) : 0;
$opinfo = $opinfo ? FlipMisc::get_price_int($opinfo->nodeValue) : $dpinfo;
$spinfo = $opinfo != $dpinfo ? $opinfo-$dpinfo : 0;
$diinfo = $diinfo ? (float)trim($diinfo->nodeValue,'%') : 0;
$summary= $summary? $summary->nodeValue : "";
$stinfo = trim($status->nodeValue,'. ');
$stinfo = empty($stinfo) ? "Out of stock" : $stinfo;
$title = array();
$title[ "mrp" ] = $opinfo;
$title[ "price" ] = $dpinfo;
$title[ "saving" ] = $spinfo;
$title[ "discount" ] = $diinfo;
$title[ "status" ] = $stinfo;
$title[ "summary" ] = $summary;
$title[ "eid" ] = $id->getAttribute('value');
foreach( $tinfo as $z=>$bar ) {
if( $z==0 ) {
$title["title"] = trim($bar->nodeValue);
$title["link"] = $bar->getAttribute('href');
} else {
$title["author"][] = $bar->nodeValue;
}
}
$listing["results"][] = $title;
}
return $listing;
}
}
/**
* class Flipkurl
* The main class to handle the flipkart functions
*
*/
class Flipkurl {
var $cookiefile;
var $h_curl = null;
var $isLogged = false;
var $email;
var $pass;
var $cookies_dir = "./";
function __construct() {
$this->init();
}
/**
* Retreives a formatted array of the search listing for given parameters
*
* Login required - no
*
* @param string $search - keyword term
* @param string $who - get by author or title
* @param int $page - the page number of listing
* @return array
*/
function getSearchListing( $search, $who='', $page='' ) {
$query = urlencode($search);
if( $page )
$page = "&start=".($page*10);
if( $who ) {
if( $who == 'author' or $who == 'title' )
$who = '&field='.$who;
}
$url = "http://www.flipkart.com/search.php?query=$query".$page.$who;
$con = $this->h_curl->get( $url );
$listing = FlipMisc::parseSearchListing( $con );
return $listing;
}
/**
* Returns the current contents of shopping cart
*
* @return array
*/
function getCartContents() {
$con = $this->h_curl->get( "http://www.flipkart.com/viewcart.php");
//var_dump( $con );
$contents = FlipMisc::getCartContents( $con );
return $contents;
}
/**
* Init
*
*/
function init() {
$this->h_curl = new cURL(1);
$this->cookies_dir = "./";
$this->h_curl->referer = "http://www.flipkart.com";
}
/**
* Login into flipkart.
*
* If the cookie file is already present, a new curl request won't be sent.
* Instead the existing file will be considered authenticated and used for all subsequent requests
*
* @param string $email - plaintext username/email id
* @param string $pass - plaintext password
* @param boolean $fresh - do a fresh login and rewrite cookie file
* @return true - if login successful, else false
*/
function login( $email, $pass, $fresh=false ) {
$this->email = $email;
$this->pass = $pass;
$cookiefile = rtrim($this->cookies_dir,'/'). "/".md5($email).".txt";
$this->cookiefile = $cookiefile;
if( !$fresh && file_exists( $cookiefile ) && strlen($x=file_get_contents($cookiefile))>10 ) {
$this->h_curl->cookie( $cookiefile );
//var_dump( $this->h_curl->cookie_file );
$this->isLogged = true;
return true;
} else {
$this->h_curl->cookie( $cookiefile );
$res = $this->doAction( "LOGINUSERACCOUNT", array("email"=>$email,"password"=>md5($pass)) );
if ( trim($res) == "0" ) {
$this->isLogged = false;
unlink( $cookiefile );
return false;
} else {
$this->isLogged = true;
return true;
}
}
return false;
}
/**
* Logout. Cleanup cookie files and any other traces;
*
*/
function logout() {
$this->isLogged = false;
@unlink( $this->cookiefile );
$this->init();
}
/**
* Flipkart's all main functions go via a gateway file called kenny.php and it takes action parameter
*
* @param string $action - what action to be performed
* @param array $params - any additional parameters
* @return string - raw HTML after doing a POST to gateway file
*/
function doAction( $action, $params=array() ) {
$params[ "action" ] = $action;
return $this->h_curl->post( "http://www.flipkart.com/kenny.php", http_build_query($params));
}
/**
* Add a book to the shopping cart.
* The bookid is a unique code at flipkart for every book.
* It can be obtained via search listing function
*
* Bookid is also known as edition id
*
* @param string $bid - unique bookid
*/
function addBook( $bid ) {
$res = $this->h_curl->post("http://www.flipkart.com/viewcart.php", "eid=$bid");
}
/**
* Remove a particular book from shopping cart
*
* @param string $bid
*/
function removeBook( $bid ) {
$res = $this->h_curl->post("http://www.flipkart.com/kenny.php", "action=DELETEFROMCART&edition_id=$bid" );
}
/**
* Update the quantity of a particular book in the cart
*
* @param string $bid
* @param int $qty
*/
function updateQuantity( $bid, $qty ) {
$res = $this->h_curl->post("http://www.flipkart.com/kenny.php", "action=CHANGE_CART_QTY&edition_id=$bid&quantity=$qty" );
}
/**
* Add a particular book to wishlist
*
* @param string $bid
*/
function addToWishList( $bid ) {
$res = $this->h_curl->post("http://www.flipkart.com/kenny.php", "action=ADDTOWISHLIST&edition_id=$bid" );
}
/**
* You can move a book from your current shopping cart to wishlist.
* Makes sense cos you don't wana buy it now, but you don't wana lose selection either.
*
* @param string $bid
*/
function moveToWishList( $bid ) {
$res = $this->h_curl->post("http://www.flipkart.com/kenny.php", "action=MOVE_TOWISHLIST_FROMCART&edition_id=$bid" );
}
/**
* Remove the book from wishlist
*
* @param int $bid
*/
function removeFromWishList( $bid ) {
$res = $this->h_curl->post("http://www.flipkart.com/kenny.php", "action=DELETEFROMWISHLIST&edition_id=$bid" );
}
}
?>