Monday, August 22, 2011

AJAX Call Problem in Facebook application http / https issue

Today I got report from one of my client (for whom I have developed a facebook app recently) that in some browsers the app is not working. Nothing happens when a button is clicked (a facebook share dialog should appear)! So, I investigated the problem. I found that when the button is clicked, the URL used for AJAX call starts with https and in some browsers (example: Chrome) it was giving a javascript error. This is because the application started with http there where in some other facebook account, it start with https. So I handled the issue with the following code in my jQuery function that is called when the button is clicked:
 var protocol = $(location).attr("protocol");  
 var loadUrl = 'http://secure.example.com/server/serve.php';  
 if (protocol == 'https:') {  
     loadUrl = 'https://secure.example.com/server/serve.php';  
 }  
And it solved the problem!

Thursday, July 28, 2011

I am back

It's been a while I am not writing in this blog. But I frequently get into problems and find solutions searching Google, so I think I should write down my problems and solutions, at least the link. Sometimes I also read interesting blog posts about programming or software development or something else that is not worth sharing in facebook, so I shall share those links also with my comments.

Stay tuned. :)

Saturday, September 18, 2010

PHP Script to get Alexa rank using Alexa API

Here is an example PHP code that uses Alexa API to get Alexa rank. Note that for Alexa API, you need to purchase keys, as it's not free. Though it's not free cost is very low.

define("ACCESS_KEY_ID", "put key here");
define("SECRET_ACCESS_KEY", "put key here");
define("SERVICE_ENDPOINT", "http://awis.amazonaws.com?");

define("ACTION", "UrlInfo");
define("RESPONSE_GROUP", "Rank, LinksInCount");

$results = array();

function get_alexa_rank($site_url)
{
global $results;
$results = array();

$awis_url = generate_url($site_url);

$result = make_http_request($awis_url);

// Parse XML and display results

$current_tag = "";

$xml_parser = xml_parser_create("");
xml_parser_set_option($xml_parser, XML_OPTION_CASE_FOLDING, false);
xml_set_element_handler($xml_parser, "start_tag", "end_tag");
xml_set_character_data_handler($xml_parser, "contents");
xml_parse($xml_parser, $result, true);
xml_parser_free($xml_parser);

return $results['rank']."|".$results['linksincount'];
}

function contents($parser, $data) {
global $current_tag, $results;
switch ($current_tag) {
case "aws:LinksInCount":
$results['linksincount'] .= $data;
break;
case "aws:Rank":
$results['rank'] .= $data;
break;
}
}

function start_tag($parser, $name) {
global $current_tag, $results;
$current_tag = $name;
}

function end_tag() {
global $current_tag;
$current_tag = '';

}

// Returns the AWS url to get AWIS information for the given site

function generate_url($site_url) {
$timestamp = generate_timestamp();
$site_enc = urlencode($site_url);
$timestamp_enc = urlencode($timestamp);
$signature_enc = urlencode(calculate_RFC2104HMAC(ACTION . $timestamp, SECRET_ACCESS_KEY));

return SERVICE_ENDPOINT
. "AWSAccessKeyId=".ACCESS_KEY_ID
. "&Action=".ACTION
. "&ResponseGroup=".RESPONSE_GROUP
. "&Timestamp=$timestamp_enc"
. "&Signature=$signature_enc"
. "&Url=$site_enc";

}


// Calculate signature using HMAC: http://www.faqs.org/rfcs/rfc2104.html

function calculate_RFC2104HMAC ($data, $key) {
return base64_encode (
pack("H*", sha1((str_pad($key, 64, chr(0x00))
^(str_repeat(chr(0x5c), 64))) .
pack("H*", sha1((str_pad($key, 64, chr(0x00))
^(str_repeat(chr(0x36), 64))) . $data))))
);
}

// Timestamp format: yyyy-MM-dd'T'HH:mm:ss.SSS'Z'

function generate_timestamp () {
return gmdate("Y-m-d\TH:i:s.\\0\\0\\0\\Z", time());
}

// Make an http request to the specified URL and return the result

function make_http_request($url){
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_TIMEOUT, 4);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
$result = curl_exec($ch);
curl_close($ch);
return $result;
}

Wednesday, August 5, 2009

strtok in PHP - a common mistake

strtok, that splits a string into tokens is a very useful function for the programmers. Here is an example code that shows the use of strtok function to extract integers from a comma separated string.

$list = "1,2,4,10,8,0,20,30,9";

$token = strtok($list, ",");
while($token)
{
print $token."\n";
$token = strtok(",");
}
?>

Using the code we get this output:

1
2
4
10
8

Where are the other four integers? Actually when the value of $token is zero (0) - the sixth integer in the list, while ($token) evaluates to False and the loop is broken there. Lets use while($token != FALSE) instead.

$token = strtok($list, ",");
while($token != FALSE)
{
print $token."\n";
$token = strtok(",");
}

Still the same output. Oh, the mistake is we used the '!=' operator which tests the equality between $token and FALSE. Here zero (0) is equal to FALSE. A stupid way to avoid the problem is to calculate the length - while(strlen($token)) and it will work definitely! as the length of the string '0' is 1. But best solution (to me) is to use the '!==' operator which means not identical. So the following code works fine:

$list = "1,2,4,10,8,0,20,30,9";

$token = strtok($list, ",");
while($token !== FALSE)
{
print $token."\n";
$token = strtok(",");
}
?>

Output:

1
2
4
10
8
0
20
30
9

It's always useful to know details about operators in PHP.

Wednesday, May 13, 2009

Trouble with Facebook Client API

I have working on facebook application development (it's a game named Fighter Jets), and facing some weired problem. I have decided to share my experience here.

Today I tried the post link feature of the facebook API. First I tried the following code:
$facebook->api_client->links_post($user_id, 'http://khaaan.com/','Best. Website. Ever.');
I got it from their API documentation.

I got error using it. It says that 'The url you supplied is invalid'. May be it's invalid. Then I changed the URL to http://www.google.com, which is valid definitely! Still getting the same problem!! WTF!

Then I searched their forum and found that I am not the only victim, some people already faced this problem and one of them solved the problem in the following way:
$facebook->api_client->links_post('http://khaaan.com/','Best. Website. Ever.', $user_id);

Which works! Needed to use the user id as the third parameter, but from the example in the API documentation we see that it's the first parameter.

I really don't understand why the documentation is wrong.