Pingback Server PHP Implementation


<?php
require('../xmlrpc/xmlrpc.inc');
require('../xmlrpc/xmlrpcs.inc');
require('../include/db.php');
dbConnect();

set_error_handler("errorHandler");

function &xSqlQuery($query) {
    global $userid;
    if ($resource = mysql_query($query)) {
        return $resource;
    } else {
        $error = mysql_error();
        errorlog('Query failed: '.$query.' - '.$error);
        ?>
        <methodResponse>
            <fault>
                <value>
                    <struct>
                        <member>
                            <name>faultCode</name>
                            <value><int>0</int></value>
                        </member>
                        <member>
                            <name>faultString</name>
                            <value>
                                <string>
                                    Error description: <?=$error?>.
                                </string>
                            </value>
                        </member>
                    </struct>
                </value>
            </fault>
        </methodResponse>
        <?php
        die();
    }
}

function errorHandler($error_code, $error_description, $filename, $line_number, $context) {
    switch ($error_code) {
        case E_NOTICE:
        case E_WARNING:
            break;
        default:
            $body = "Error code: $error_code  \n";
            $body .= "Error description: $error_description  \n";
            $body .= "Error occured in: $filename, line $line_number  \n";
            errorlog($body);
            ?>
            <methodResponse>
                <fault>
                    <value>
                        <struct>
                            <member>
                                <name>faultCode</name>
                                <value><int>0</int></value>
                            </member>
                            <member>
                                <name>faultString</name>
                                <value>
                                    <string>
                                        Error code: <?=$error_code?>.
                                        Error description: <?=$error_description?>.
                                        Error occured in: <?=$filename?>, line <?=$line_number?>.
                                    </string>
                                </value>
                            </member>
                        </struct>
                    </value>
                </fault>
            </methodResponse>
            <?php
            die();
    }
}

function errorlog($msg) {
    $query = "INSERT INTO bloglogs (date, message) VALUES (NOW(), '".addslashes($msg)."')";
    @mysql_query($query);
}

function pingback($params) {
    $param1 = $params->getParam(0);
    $param2 = $params->getParam(1);
    $sourceURI = $param1->scalarval();
    $targetURI = $param2->scalarval();
    $file = @fopen($sourceURI, "r");
    if(!$file) {
        // This page they claim they're linking to me from, it doesn't exist!  That can't be right.
        $error = "Source URI (".$sourceURI.") does not exist (target URI was ".$targetURI.")";
        errorLog($error);
        return new xmlrpcresp(0, 0x0010, $error);
    }
    $headerOk = 0;
    for($count = 0; $count < count($http_response_header); $count++) {
        if(strstr($http_response_header[$count],"Content-Type: text/")) {
            $headerOk = 1;
        }
    }
    if($headerOk == 0) {
        // Check for MIME-type disabled in case it excludes valid stuff by accident (eg. application/xhtml+xml).
        // return new xmlrpcresp(new xmlrpcval(0, 0x0011));
    }
    $fileContents = fread($file,100000);//$filestats['size']);
    if(!strstr($fileContents, preg_replace("/&(amp;)?/i","&amp;",$targetURI))) {
        // Doesn't contain a valid link
        if(!strstr($fileContents, str_replace("&amp;","&",$targetURI))) {
            // Doesn't contain an invalid link either!
            $error = "Source URI (".$sourceURI.") does not contain a link to the target URI (".$targetURI.")";
            errorLog($error);
            return new xmlrpcresp(0, 0x0011, $error);
        }
    }
    if(preg_match("/<title>([^<]*)<\/title>/i",$fileContents,$matches)) {
        $title = $matches[1];
    } else {
        $title = '';
    }
    fclose($file);
    preg_match("/xiven.com\/blog.php[^\"]*[[\?|&]start=([0-9]+)/i",$targetURI,$target);
    if($target[1] == '') {
        // The URI given was not recognised as being that of a blog post on this site.
        $error = "Specified target URI (".$targetURI.") cannot be used as a target (source URI was ".$sourceURI.")";
        errorLog($error);
        return new xmlrpcresp(0, 0x0021, $error);
    }
    $query = "SELECT COUNT(*) AS number FROM blogentries ";
    $query .= "WHERE id = ".$target[1];
    $rdsBlog =& xSqlQuery($query);
    $rdBlog = mysql_fetch_array($rdsBlog);
    if($rdBlog['number'] <> 1) {
        // A blog entry was specified that doesn't exist!
        $error = "Specified target URI (".$targetURI.") does not exist (source URI was ".$sourceURI.")";
        errorLog($error);
        return new xmlrpcresp(0, 0x0020, $error);
    }
    $query = "SELECT COUNT(*) AS number FROM blogxrefs ";
    $query .= "WHERE sourceURI = '".preg_replace("/&(amp;)?/i","&amp;",$sourceURI)."' AND target = ".$target[1];
    $rdsPb =& xSqlQuery($query);
    $rdPb = mysql_fetch_array($rdsPb);
    if($rdPb['number'] > 0) {
        // They've already pingbacked/trackbacked this post once from this source URI.  No more!!!
        $error = "The pingback from ".$sourceURI." to ".$targetURI." has already been registered";
        errorLog($error);
        return new xmlrpcresp(0, 0x0030, $error);
    }
    $query = "INSERT INTO blogxrefs (type, date, sourceURI, target, title) ";
    $query .= "VALUES ('Pingback', NOW(), '".preg_replace("/&(amp;)?/i","&amp;",$sourceURI)."', ".$target[1].", ";
    $query .= "'".addslashes($title)."')";
    xSqlQuery($query);
    
    // Yay! We done it! We is l33t!
    $error = "Thanks! Pingback from ".$sourceURI." to ".$targetURI." registered";
    errorLog($error);
    return new xmlrpcresp(new xmlrpcval($error, "string"));
}

$s=new xmlrpc_server(array("pingback.ping" => array("function" => "pingback")));
?>