Archive for the ‘PHP’ Category

Joomla! Localized Date Format

Tuesday, October 23rd, 2012

When working on a Joomla website, which is using the Urdu language package, I was trying to show the current date in Urdu on the top of the website header too. However, looks like finding the correct format string to convert the date to Urdu (or current language) was bit more tricky than I thought.I tried to find this in the Joomla support forums and documentation, but may be I was not using the correct search term, so didn’t found the relevant example.

After the search failure, I decided to explore the theme files to get idea on how this is done on the Article page, and I found the answer by looking at the article theme file at:
Joomla\templates\[Theme-Name]\html\com_content\article\default.php

And for those of you, who don’t like to browse that file, and just want the solution, the following code worked for me:

1
2
3
<?php 
	echo JHtml::_('date', JFactory::getDate(), JText::_('DATE_FORMAT_LC1'))
?>

The code itself is very simple. Basically, we are just getting the current date (second parameter), converting it to the correct date format, and then displaying it as HTML.

I hope this helps.

CodeIgniter File Upload and Mime Types

Tuesday, September 4th, 2012

As I mentioned in my other post CodeIgniter and File Upload Library, uploading a file using CodeIgniter requires you to also know the mime type of file being uploaded and add it to proper location.

I’m using CodeIngiter framework for Dynamic Subtitle Translator application, and it had worked great for me. However, few of my user complained that they can’t upload the sub-title files on the server, and get the following error when uploading subtitle files for translation:

The filetype you are attempting to upload is not allowed

I know that it has to do with not allowed mime-type, but I had no clue what mime-type was being passed by the uploader machine. To be on safe side, I searched for all the mime types which are used for the “.srt” file and added them to allowed list i.e.

1
array('text/plain', 'application/octet-stream', 'video/subtitle', '')

But one of the user was still getting the problem. Frustrated by not finding the clue, I started looking at the source code for the CodeIgniter upload helper library and found that the uploaded file type is stored in the “file_type” property of the class. That’s all what I needed. So, I changed the error message to also show the file-type of the uploaded application. Something like:

1
2
3
4
if ( ! $this->upload->do_upload("subtitleFile"))
	$this->data["error"] = $this->upload->display_errors() . 'File Type: ' . $this->upload->file_type;\
else
	// File is correct, so do the normal processing

Once the file-type is displayed in error message, user can easily report the new mime-types not being supported, and I can add them back in supported list. A bit long and tiring process, but it works without changing or breaking anything at CodeIgniter inner level.

IP Address to Country Lookup using iPInfoDB

Saturday, July 7th, 2012

Recently, I have been working on a simple idea, and that’s to show the Google GeoMaps (similar to the maps in Google Analytic) to show the different user activity directly on the site e.g. total number of downloads of a product by country, total subtitles translation, etc. My first research was to find some API which can draw decent looking graphs, as in Google Analytic, without considerable effort. Fortunately, I found that there is API from the Google which does exactly this:

Google GeoMaps

The next research task was to find a free and easy to use API which can provide the user location (City, Country, etc) given an API Address. While there are dozens such available, after trying few, I decided to go with the iPInfoDB API:
http://ipinfodb.com/ip_location_api.php

They have simple to use API, and also have sample PHP code on how to best use their service on the above API page. However, I ,after doing some research, ended up using the following code to fetch the user info from the IP Address:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
// Find the Country Name, Code and City information from the IPInfoDB:
// http://www.ipinfodb.com/ip_location_api_json.php
private function getGeoLocation()
{
	// Make a special cookie name by adding the IP address (to make different cookie per IP address)
	$cookieName = 'geolocation_'. str_replace('.', '_', $_SERVER['REMOTE_ADDR']);
 
	//Check if geolocation cookie exists (to avoid repeated calls to their server)
	if(!isset($_COOKIE[$cookieName]))
	{
		// If no, create a new request;
		$APIKey='{YOU-API-KEY}';
		$JSONUrl='http://api.ipinfodb.com/v3/ip-city/?key='.$APIKey.'&ip='.$_SERVER['REMOTE_ADDR'].'&format=json';
 
		// Get the JSON content from the remote URL
		$response = file_get_contents($JSONUrl);
 
		// Parse JSON
		$visitorGeolocation  = json_decode($response, true);
 
		// Geo Location query was successfull
		if ($visitorGeolocation && $visitorGeolocation['statusCode'] == 'OK') {
			$data = base64_encode(serialize($visitorGeolocation));
			setcookie($cookieName, $data, time()+3600*24*7); //set cookie for 1 week
		}
	}
	else
	{
		// Load previously stored info from the cooki
		$visitorGeolocation = unserialize(base64_decode($_COOKIE[$cookieName]));
	}
 
	return $visitorGeolocation;
}

This simple script also makes use of cookies to avoid sending repeated hits to their server if you have already found out the location of the user once. The two little tweaks I done to the code available at their API page are:

1) Make sure to add the user API Address in the cookie name. This helps detect the correct location for the user, even when he switches to different network within seven days.

2) I decided to use JSON fetch to get the results instead of using their wrapper class. This makes the overall code simple and clean.

With all this, I also ended up creating a simple product in the PHP which can be used to log and show the nice statistics graph on any website. I may make it available for public download soon. So, stay tuned.

PHP CURL and Peer Certificate Issue

Thursday, June 21st, 2012

I have been using the Microsoft Translator API for some time, and it worked great. This API requires the “Access Token” to validate all the AJAX calls, and it has been working fine for months.

Now a few days back, it broke, and when debugging the issue, I found that it was failing with the following exception:
“Exception’ with message ‘Peer certificate cannot be authenticated with known CA certificates”

Now a good secure way to detect and resolve this issue is to investigate why this certificate is not being verified. But since in this case was the site was of Microsoft, I simply decided to skip the authentication. All you need to do is add an option in curl for this:

curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);

This solved the issue very well.

BTW, on a side tip, following code to check and detect for the CURL execution failure works well for me:

//Get the Error Code returned by Curl.
$curlErrno = curl_errno($ch);
if($curlErrno){
	$curlError = curl_error($ch);
	throw new Exception($curlError);
}

Hope this helps.

Update: July 25, 2012 – While the above method works well for the local self signed certificates. It’s possible that you get the similar error for production/live website too using the valid certificates. For example, for one of my client site, who got the new certificate from the “Thawte SSL CA”, the PHP client was throwing following error:
SSL certificate problem, verify that the CA cert is OK. Details: error:14090086:SSL routines:SSL3_GET_SERVER_CERTIFICATE:certificate verify failed

For such errors, you should never ignore them by setting CURLOPT_SSL_VERIFYPEER to false, instead a proper method is to import the correct server certificate and then pass it to the CURL via the CURLOPT_CAINFO option. The following tutorial cover this in detail (see The proper fix section):
Using cURL in PHP to access HTTPS (SSL/TLS) protected sites

CodeIgniter and File Upload Library

Sunday, August 15th, 2010

CodeIgniter is a compact and amazing framework for developing neat and clear PHP projects. The more I work in this, the more I’m falling in love with it. Though it’s very well documented, but you can’t expect to find all what you need in the help file.

I was working on a project where I do need to support the subtitle file upload (of type SRT and SUB). According to the documentation all I need to do to support this is add the following line:

$config['allowed_types'] = 'sub|srt';

But when I add this line, the CodeIgniter was reject the SRT and SUB files with error that file type upload is not supported. As the framework is open source, thank God, so I looked at the corresponding code, and found that during upload, the code also checks for the file mime types and reject the file if the corresponding mime type is not defined in the “/application/config/mimes.php”. Once I know this, fixing this was just a matter of minutes. All I did was added the following two lines to the $mimes array in the file and it worked flawless:

'srt' => array('text/plain', 'application/octet-stream'),
'sub' => array('text/plain', 'application/octet-stream'),

The reason I added both the “text/plain” and “application/octet-stream” is because, when uploading the file, I sends the mime type as “text/plain”, while chrome and other browsers send “application/octet-stream”. Browsers! Browsers! Browsers!