In a comment to
this post, I said I would ping him back with my new trackback mechanism. It is now done, so I am doing the promised ping. This works by adding a javascript source insert at the end of my blog. The script checks to see if an update is needed and then outputs when the last ping is done. This does both trackback and weblogs pings. Now for the
script:
<?php>
// Use xmlrpc value
include('xmlrpc.inc');
function getval ($key) {
global $HTTP_GET_VARS;
if (get_magic_quotes_gpc()) {
return stripslashes($HTTP_GET_VARS[$key]);
}
return $HTTP_GET_VARS[$key];
}
//Make strtotime accept ISO formatted time often found in RSS
function toUnixTime($string)
{
$unixTime = strtotime($string);
if ($unixTime == -1) {
list($year,$month,$day,$hour,$minute,$second)
= split("[-:T\.]",$string);
$unixTime = strtotime("$year-$month-$day $hour:$minute:$second");
}
return $unixTime;
}
//Call the trackback script. If the trackback link ends with a slash
//then do an http POST otherwise do a get. A trackback ping includes
//title, excerpt, url, and blog name extracted from the rss.
function pingURL($trackback, $title, $url, $excerpt, $blog_name) {
$poststring = "title=" . urlencode(trim($title)) . "&excerpt=" .
urlencode(trim($excerpt)) . "&url=" . urlencode(trim($url)) .
"&blog_name=" . urlencode(trim($blog_name));
$tab = parse_url($trackback);
$host = $tab['host'];
$path = $tab['path'];
$query = $tab['query'];
if (strcmp($query, '') != 0) {
$file_name = $trackback . "&" . $poststring;
$file = fopen($file_name, "r");
if (!file) {
while (!feof($file)) {
$line = fgets($file, 4096);
}
}
} else {
$fp = fsockopen($host, 80, $errno, $errstr, $timeout = 30);
if ($fp) {
fputs($fp, "POST $path HTTP/1.1\r\n");
fputs($fp, "Host: $host\r\n");
fputs($fp, "Content-type: application/x-www-form-urlencoded\r\n");
fputs($fp, "Content-length: ".strlen($poststring)."\r\n");
fputs($fp, "Connection: close\r\n\r\n");
fputs($fp, $poststring . "\r\n\r\n");
while(!feof($fp)) {
$line = fgets($fp, 4096);
}
//close fp - we are done with it
fclose($fp);
}
}
}
// This function looks at a referenced site and looks for an RDF entry
// inside of an HTML comment. (Moveable type standard practice and
// added to the blinne.org blogger blog).
function pingSite($link) {
global $title, $blog_name, $description;
list ($url1, $aref1) = split("#", $link);
$file1 = fopen($url1, "r");
$aref1 = trim($aref1);
if ($file1) {
while (!feof($file1)) {
$line1 = fgets($file1, 4096);
$pattern = "a name=\\\"$aref1\\\"";
if (ereg($pattern, $line1, $reg)) {
break;
}
}
while (!feof($file1)) {
$line1 = fgets($file1, 4096);
if (ereg("\\]*href=\\\"([^\\\"]*)\\\"", $line1, $reg)) {
$link1 = $reg[1];
list ($url2, $aref2) = split("#", $reg[1]);
$file2 = fopen($url2, "r");
$aref2 = trim($aref2);
if ($file2) {
if (strcmp($aref2, "") != 0) {
while (!feof($file2)) {
$line2 = fgets($file2, 4096);
$pattern = "a name=\\\"$aref2\\\"";
if (ereg($pattern, $line2, $reg)) {
break;
}
}
}
$foundRDF = 0;
while (!feof($file2)) {
$line2 = fgets($file2, 4096);
if (ereg("\\ $foundRDF = 1;
break;
}
}
if ($foundRDF) {
$linkFound = 0;
$trackbackFound = 0;
while (!feof($file2)) {
$line2 = fgets($file2, 4096);
if (ereg("dc\\:identifier=\\\"([^\\\"]*)", $line2, $reg)) {
if (strcmp($reg[1], $link1) == 0) {
$linkFound = 1;
}
}
if (ereg("trackback\\:ping=\\\"([^\\\"]*)", $line2, $reg)) {
$trackback = $reg[1];
$trackbackFound = 1;
}
if ($linkFound && $trackbackFound) {
$trackbackFound =0;
$linkFound = 0;
pingURL($trackback, $title, $link, $description, $blog_name);
}
}
}
}
}
if (ereg("QSM.item.end", $line1, $reg)) {
break;
}
}
}
}
// Do an XML RPC to weblogs and blogrolling. Weblogs is commented out
// because Blogger pro automatically is pinged by blogger and it is slow
// to ping to boot.
function ping_weblogs($name, $address) {
$f = new xmlrpcmsg('weblogUpdates.ping', array(new xmlrpcval($name),
new xmlrpcval($address)));
//This is done by blogger.
$c = new xmlrpc_client("/RPC2", "rpc.weblogs.com", 80);
$r=$c->send($f);
$c = new xmlrpc_client("/pinger/", "rpc.blogrolling.com", 80);
$r=$c->send($f);
}
// XML parser support routine
function startElement($parser, $name, $attrs) {
global $insideitem, $tag, $title, $description, $link,$date;
$tag = $name;
if ($name == "ITEM") {
$insideitem = true;
}
}
// XML parser support routine
function endElement($parser, $name) {
global $insideitem, $tag, $title, $description, $link, $date, $last_update, $needed_update, $latest_time;
if ($name == "ITEM") {
$time = toUnixTime($date);
if ($time > $last_update) {
if ($time > $latest_time) {
$latest_time = $time;
}
$needed_update = 1;
pingSite($link);
}
$title = "";
$description = "";
$link = "";
$date = "";
$insideitem = false;
}
}
// XML parser support routine
function characterData($parser, $data) {
global $insideitem, $tag, $title, $description, $link, $date, $blog_name;
if ($insideitem) {
switch ($tag) {
case "TITLE":
$title .= $data;
break;
case "DESCRIPTION":
$description .= $data;
break;
case "LINK":
$link .= $data;
break;
case "DC:DATE":
$date .= $data;
break;
case "PUBDATE":
$date .= $data;
break;
}
} else {
switch ($tag) {
case "TITLE":
$blog_name .= $data;
break;
}
}
}
//main starts here
error_reporting(E_ERROR | E_PARSE);
$insideitem = false;
$tag = "";
$title = "";
$description = "";
$link = "";
$date = "";
$needed_update = 0;
$latest_time =0;
$blog_name="";
$rss = getval("rss");
$name = getval("name");
$address = getval("address");
$rss_update = $rss;
for ($i=0; $i < strlen($rss_update); $i++) {
if ($rss_update[$i] == ':' || $rss_update[$i] == '/') {
$rss_update[$i] = '_';
}
}
$file = fopen($rss_update, "r");
if (!$file) {
$last_update = 0;
} else {
$last_update = fgets($file, 4096);
}
$xml_parser = xml_parser_create();
xml_set_element_handler($xml_parser, "startElement", "endElement");
xml_set_character_data_handler($xml_parser, "characterData");
$fp = fopen($rss,"r")
or die("Error reading RSS data.");
while ($data = fread($fp, 4096))
xml_parse($xml_parser, $data, feof($fp))
or die(sprintf("XML error: %s at line %d",
xml_error_string(xml_get_error_code($xml_parser)),
xml_get_current_line_number($xml_parser)));
fclose($fp);
xml_parser_free($xml_parser);
if ($needed_update) {
$file = fopen($rss_update, "w");
$last_update = time();
if ($latest_time > $last_update) {
$last_update = $latest_time;
}
fwrite($file, time());
ping_weblogs($name, $address);
}
$time_string = strftime("%c", $last_update);
echo "document.write(\"Weblogs Last Updated: $time_string\");";
?>