jQuery, cross-domain JSONP and PHP

I worked on this today and need to write it up so I have a point of reference for next time.

Objective

From SiteA.com, call on a PHP sctipt on SiteB.com via JavaScript (jQuery).

Solution

SiteA.com - HTML template

<div class="recent-blog-list"></div>

SiteA.com - jQuery script

jQuery(document).ready(function(){
// load recent blog posts:
var url = "//siteB.com/recent-blog.php?jsoncallback=?";
jQuery.ajax({
type: 'GET',
url: url,
dataType: 'jsonp',
crossDomain: true,
}).done(function(response){
// Insert new data:
jQuery(".recent-blog-list").html(blog_post_list);
}).fail(function(jqxhr, textStatus, error){
var err = textStatus + ', ' + error;
console.log( "Request Failed: " + err);
});
});

SiteB.com - PHP script

<?php

// (Load this for WordPress scope inclusion)

include ("wp-load.php");

$post_list = '<ul>';
query_posts('showposts=10');
while (have_posts()) {
the_post();
$date = get_the_date();
$permalink = get_permalink();
$title = $org_title = get_the_title();
$title = strlen($title)>50?substr($title, 0, 50) . "...":$title;
$post_list = $post_list.'<li><a href="'.$permalink.'" title="'.$org_title.'">'.$title.'</a>'.'</li>';
}
$post_list = $post_list.'</ul>';

if(array_key_exists('jsoncallback', $_GET)) {
// Output JSON result:
header('Content-type: application/json; charset=utf-8');
print $_GET['jsoncallback']."(".json_encode($post_list).")";
}
else {
// Output plain HTML result:
print $post_list;
}
Bookmark and ShareSubscribe

Firebug: "Image corrupt or truncated: <unknown>"

Working on an application that was already built before I came to it, I came across this error:

"Image corrupt or truncated: <unknown>"

It only appears in Firebug's console in Firefox (it did not show up in IE or Chrome).

After Googling a bit I found that a lot of people seemed to be blaming it on favicon.ico. As far as the error went though, no line number is indicated and the favicon actually does appear in the Window's title bar/tab.

Thinking that maybe there was something wrong with the format of my favicon.ico, I opened it in Adobe Fireworks to see if it was possibly misformatted in some way and if there was a chance that re-saving it might help. Fireworks told me that it was actually an 8 bit BMP file and I found out through more Googling that ICO files can be made by simply saving your images as a BMP and then changing the file extension to .ico. I repeated this action but still wound up with the same error.

Out of curiosity, I browsed directly to the favicon and noticed that in the window title/tab title the following appeared: "favicon.ico (BMP Image, 20x20 pixels)". So it was actually still being interpreted by Firefox as a BMP image, not an icon.

Confounded I decided that even though this BMP/ICO file extension conversion seemed simple enough, Firefox must be interpreting it differently still. So, resorting to an online ICO file generator (http://www.favicon.co.uk/) I managed to fix my problem. I uploaded the BMP version of my icon (20x20 pixels) and generated an ICO version at a more official icon size of 16x16 pixels.'

Voila! No more error and the title in the window/tab now appears as "favicon.ico (ICON Image, 16x16 pixels)" when you browse directly to the favicon.

PS. Even though browsers these days seem quite capable of picking up a favicon in the root folder of your application, it's always a good idea to explicitly point to it:

<link href="http://[YOURWEBSITE]/favicon.ico" rel="shortcut icon" type="image/x-icon" />

Bookmark and ShareSubscribe

Apply a date mask to an Epoch timestamp (UDF)

What is Epoch time?

Not the 1970 Epoch"The Unix epoch (or Unix time or POSIX time or Unix timestamp) is the number of seconds that have elapsed since January 1, 1970 (midnight UTC/GMT), not counting leap seconds (in ISO 8601: 1970-01-01T00:00:00Z). Literally speaking the epoch is Unix time 0 (midnight 1/1/1970), but 'epoch' is often used as a synonym for 'Unix time'. Many Unix systems store epoch dates as a signed 32-bit integer, which might cause problems on January 19, 2038 (known as the Year 2038 problem or Y2038)."
- epochconverter.com

What am I talking about?

In recent work I came across a database table that was storing Epoch timestamp values. I'm sure there are other UDFs out there to convert Epoch timestamps to a readable disply format, but I thought I'd give it ago anyway.

I came across a ColdFusion Cookbook sample that fit the scenario perfectly, written by Rob Brooks-Bilson. It explains the process of converting an Epoch seconds timestamp to a Date object. This was my base.

With a few additions, my UDF became (apologies for the formatting):

<cffunction name="applyMaskToEpoch"
returntype="string"
output="no">


<cfargument name="epochTimestamp"
type="numeric"
required="true"
hint="Epoch timestamp (10-13 digit numeric string)." >


<cfargument name="dateMask"
type="string"
required="false"
default="dd mmmm yyyy"
hint="Date mask pattern (Eg. dd mmmm yyyy)." >


<cfargument name="timeMask"
type="string"
required="false"
default="h:mm:ss tt"
hint="Time mask pattern (Eg. hh:mm:ss tt)." >


<cfargument name="delimeter"
type="string"
required="false"
default=", "
hint="Delimeter to be placed between date and time output." >


<cfset var sEpochTimestamp = left(arguments.epochTimestamp,10) >
<cfset var sDateMask = arguments.dateMask >
<cfset var sTimeMask = arguments.timeMask >
<cfset var objDateTime = "" >
<cfset var sFormattedDate = "" >
<cfset var sFormattedTime = "" >
<cfset var sDelimeter = arguments.delimeter >
<cfset var sResult = "" >

<cfset objDateTime = DateAdd("s",sEpochTimestamp,DateConvert("utc2Local", "January 1 1970 00:00")) >
<cfset sFormattedDate = DateFormat( objDateTime, sDateMask ) >
<cfset sFormattedTime = TimeFormat( objDateTime, sTimeMask ) >
<cfset sResult = sFormattedDate & sDelimeter & sFormattedTime >

<cfreturn sResult />
</cffunction>

Example usage:

<cfset iEpochTimestamp = getTickCount() >
<cfoutput>
#applyMaskToEpoch(iEpochTimestamp,'d-mmm-yy','h:mm:ss tt',', ')#
</cfoutput>

Example output:

7-Apr-11, 3:51:25 PM
(where the Epoch seconds value from getTickCount() was 1302155485932)

UPDATE:

Thanks Damon for your comments below regarding an alternative approach that will allow you to display a date/time including milliseconds, by utilitsing Java's Date class directly. Applying the changes Damon has suggested, we end up with the following version of the UDF:

<cffunction name="applyMaskToEpoch"
returntype="string"
output="no">


<cfargument name="epochTimestamp"
type="numeric"
required="true"
hint="Epoch timestamp (13 digit numeric string)." >


<cfargument name="dateMask"
type="string"
required="false"
default="dd mmmm yyyy"
hint="Date mask pattern (Eg. dd mmmm yyyy)." >


<cfargument name="timeMask"
type="string"
required="false"
default="h:mm:ss:L tt"
hint="Time mask pattern (Eg. hh:mm:ss:L tt)." >


<cfargument name="delimeter"
type="string"
required="false"
default=", "
hint="Delimeter to be placed between date and time output." >


<cfset var sEpochTimestamp = arguments.epochTimestamp >
<cfset var sDateMask = arguments.dateMask >
<cfset var sTimeMask = arguments.timeMask >
<cfset var objDateTime = "" >
<cfset var sFormattedDate = "" >
<cfset var sFormattedTime = "" >
<cfset var sDelimeter = arguments.delimeter >
<cfset var sResult = "" >

<cfset objDateTime = createObject('java', 'java.util.Date').init(javaCast('long', sEpochTimestamp)) >
<cfset sFormattedDate = DateFormat( objDateTime, sDateMask ) >
<cfset sFormattedTime = TimeFormat( objDateTime, sTimeMask ) >
<cfset sResult = sFormattedDate & sDelimeter & sFormattedTime >

<cfreturn sResult />
</cffunction>

Example usage (added millisecond mask 'L'):

<cfset iEpochTimestamp = getTickCount() >
<cfoutput>
#applyMaskToEpoch(iEpochTimestamp,'d-mmm-yy','h:mm:ss:L tt',', ')#
</cfoutput>

Example output:

11-Apr-11, 2:11:58:714 PM
(where the Epoch seconds value from getTickCount() was 1302495118714)

Download (.zip): demo & source (includes three variations of the UDF)

A few notes:

  • As far as I know, since ColdFusion MX getTickCount() has been returning an Epoch seconds timestamp value. The length of this value is 13 digits. In this UDF and the ColdFusion Cookbook example (in the comments regarding Java Epoch) you should note that Left(str,10) is used to trim the Epoch numeric string value to the required 10 digits in length.
  • I'm not sure if getTickCount() returned am Epoch seconds value before ColdFusion MX.
  • Thanks to Damon's comments (below) it has been pointed out that Java's Date class can be utilised instead, to get the same result. Taking this route also means trimming of the Epoch value down to 10 digits is not required - allowing you to use the full 13 digit Epoch millisecond value. This will of course also now allow you to display milliseconds if you wish.
  • If you are running your site on a shared host that disables the use of CreateObject('Java') (ie. GoDaddy, Net24, and many others unfortunately), the second UDF is not for you. The first one should work though.
  • The image in the post obviously has nothing to do with Epoch. Although, when I say "Epoch" in my head it always reminds me of Ewok.
Further reading:

Bookmark and ShareSubscribe