<?
    
# A PHP/XSLT based transformer and browser for
    # Friend-of-a-Friend (FoaF) descriptions.
    #
    # (c) 2002-2006 Morten Frederiksen
    #
    # XSS bug fixes by Robby Griffin.
    #
    # License: http://www.gnu.org/licenses/gpl
    #
    
if ($_SERVER['REMOTE_ADDR']=='192.168.1.16')
        
error_reporting(2047);
    
header('Connection: close');
    if (
preg_match('|inktomisearch.com$|',@$_SERVER['REMOTE_HOST'])
            ||
preg_match('|betaspider.com$|',@$_SERVER['REMOTE_HOST'])) {
        
header('HTTP/1.1 403 Slow Down');
        exit;
    }

    include_once(
'../getFoaF.php');
    
$Redland=librdf_php_get_world();

    
$metadata='explorer.rdf';
    
$foaf='http://www.mfd-consult.dk/index.rdf';
    
$ifp='foaf-ifp.xsl';
    
$xsl='explorer.xsl';
#if (preg_match('|^192\.168\.|',$_SERVER['REMOTE_ADDR']))
#    $xsl='explorer-1.11.xsl';

    
if (@$_GET['foaf']!='')
        
$foaf=$_GET['foaf'];

    
$xslt=xslt_create();
    
xslt_set_error_handler($xslt,'xsltError');
    
$xslterror='';

    if (
preg_match('|^wn:([a-z])([a-z_]+)$|i',$foaf,$M))
        
$foaf='http://xmlns.com/wordnet/1.6/'.strtoupper($M[1]).strtolower($M[2]);
    list(
$foaf,$foafdata)=getFoaF($foaf);
#if (preg_match('|^192\.168\.|',$_SERVER['REMOTE_ADDR']))
#    print($foafdata);

    
$xhtml='';
    if (
$foafdata && @$_GET['source']=='foaf')
        
$xhtml='<pre>'.htmlspecialchars($foafdata).'</pre>';
    elseif (
$foafdata)
    {
        
$foafIFP=@xslt_process($xslt,'arg:/_xml','arg:/_xsl',NULL,
                array(
'/_xsl'=>join('',file($ifp)),'/_xml'=>$foafdata),
                array(
'foaf'=>$foaf));
        
$foafdata=redlandify($foaf,$foafdata);
        
$NS='<?xml version="1.0" encoding="UTF-8"?><ns>';
        if (
preg_match_all('|xmlns(:[^=\s]+)?\s*=\s*[\'"]([^\'"]+)[\'"]|',$foafdata,$M,PREG_SET_ORDER))
        {
            
$uris=array();
            foreach (
$M as $ns)
            {
                
$uri=$ns[2];
                
$uris[$uri]=1;
            };
            foreach (
array_keys($uris) as $uri)
            {
                if (!
preg_match('|^http:|',$uri))
                    break;
                
$file='ns/'.preg_replace('|[^a-z0-9\.-]|','',$uri);
                if (
file_exists($file) &&
                        (
filesize($file)<=1 && filemtime($file)>(time()-30*86400)
                        ||
filemtime($file)>(time()-30*86400)))
                    
$schema=join('',file($file));
                else
                {
                    
$rdf='<?xml version="1.0"?>
<xsl:stylesheet
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
    version="1.0">
<xsl:output
    method="xml"
    omit-xml-declaration="yes"
    encoding="utf-8"/>
<xsl:template match="/">
    <xsl:copy-of select="//rdf:RDF"/>
</xsl:template>
</xsl:stylesheet>'
;
                    
$rdfs=getFoaF_curl($uri);
                    if (!(
$schema=@xslt_process($xslt,'arg:/_xml','arg:/_xsl',NULL,
                            array(
'/_xsl'=>$rdf,'/_xml'=>$rdfs))))
                    {
                        
$rdfs=preg_replace('|^.+?(<\w+:RDF.+</\w+:RDF>).+$|s','$1',$rdfs);
                        
$schema=@xslt_process($xslt,'arg:/_xml','arg:/_xsl',NULL,
                                array(
'/_xsl'=>$rdf,'/_xml'=>$rdfs));
                    };
                    if (
strlen($schema)==1)
                        
$schema='';
                    if (
$fp=fopen($file,'w'))
                    {
                        @
fwrite($fp,$schema);
                        !@
fclose($fp);
                    };
                };
                
$NS.='<schema ns="'.$uri.'">';
                
$NS.=$schema.'</schema>';
            };
        };
        
$NS.='</ns>';
        if (
$foafdata=='!')
        {
            
$xhtml='<head><title>Error</title></head>
<body><h1>Error</h1><p>Unable to parse FoaF (<a href="'
.htmlspecialchars($foaf).'">'.htmlspecialchars($foaf).'</a>).</p><p>It doesn\'t seem to be valid RDF/XML, you may want to try out the <a href="http://www.w3.org/RDF/Validator/">RDF Validator</a>.</p></body>';
        }
        elseif ((
$xhtml=xslt_process($xslt,'arg:/_xml','arg:/_xsl',NULL,
                array(
'/_xsl'=>join('',@file($xsl)),'/_xml'=>$foafdata,
                
'/schema'=>$NS,'/ifp'=>$foafIFP),
                array(
'foaf'=>$foaf,'ifp'=>'1','schema'=>'1')))
                && (
$xhtml!='<?xml version="1.0" encoding="UTF-8"?>'."\n"))
        {
            
$metafoot=xslt_process($xslt,'arg:/_xml','arg:/_xsl',NULL,
                    array(
'/_xsl'=>join('',@file('metafoot.xsl',1)),'/_xml'=>join('',file($metadata))));
            print(
str_replace('<!--foaf-explorer-footer-->',$metafoot,$xhtml));
            exit;
        }
        else
            
$xhtml='<head><title>Error</title></head>
<body><h1>Error</h1><p>Unable to parse FoaF (<a href="'
.htmlspecialchars($foaf).'">'.htmlspecialchars($foaf).'</a>).</p><p>It doesn\'t seem to be valid RDF/XML, you may want to try out the <a href="http://www.w3.org/RDF/Validator/">RDF Validator</a>.</p><p>Raw XSLT error message: '.$xslterror.'</p></body>';
    }
    else
        
$xhtml='<head><title>Error</title></head>
<body><h1>Error</h1><p>Unable to find or read FoaF (<a href="'
.htmlspecialchars($foaf).'">'.htmlspecialchars($foaf).'</a>).</p><pre>'.($foafdata?htmlspecialchars($foafdata):'').'</pre></body>';

    if (
$xhtml!='')
    {
        
$xhtml='<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
'
.$xhtml.'</html>';
        print(
$xhtml);
    };

    function
xsltError($x,$e,$l,$f)
    {
        global
$xslterror;
        
$xslterror='Sablotron XSLT transformation error';
        
reset($f);
        while(list(
$key,$val)=each($f))
        {
            if (
$key=='line')
                
$xslterror.=' on line '.$val;
            if (
$key=='msg')
                
$xslterror.=': <strong>'.$val.'</strong>';
        };
        
$xslterror.='.';
    };

    function
redlandify($uri,$rdfxml)
    {
        global
$Redland;

        
/* Parse... */
        
$base=librdf_new_uri($Redland,$uri);
        
$parser=librdf_new_parser($Redland,'raptor','application/rdf+xml',librdf_new_uri($Redland,'-'));
        
$stream=librdf_parser_parse_string_as_stream($parser,$rdfxml,$base);
        if (!
$stream || librdf_stream_end($stream))
            return
'!';
        
$Nodes=array();
        
$Namespaces=array('http://www.w3.org/1999/02/22-rdf-syntax-ns#'=>'rdf');
        
$count=0;
        while (!
librdf_stream_end($stream))
        {
            
$statement=librdf_stream_get_object($stream);
            
$subject=librdf_new_node_from_node(librdf_statement_get_subject($statement));
            
$predicate=librdf_new_node_from_node(librdf_statement_get_predicate($statement));
            
$object=librdf_new_node_from_node(librdf_statement_get_object($statement));
            
$preduri=librdf_uri_to_string(librdf_node_get_uri($predicate));
            if (
preg_match('|^(\w+:.+#)(.+)$|',$preduri,$Predicate)
                    ||
preg_match('|^(\w+:.+\?)(.+)$|',$preduri,$Predicate)
                    ||
preg_match('|^(\w+:.+/)([^/]+)$|',$preduri,$Predicate))
            {
                if (!
key_exists($Predicate[1],$Namespaces))
                    
$Namespaces[$Predicate[1]]='ns'.count($Namespaces);
                
$predicate=$Namespaces[$Predicate[1]].':'.$Predicate[2];
                
$node=librdf_node_to_string($subject);
                if (!
key_exists($node,$Nodes))
                    
$Nodes[$node]=array();
                
$found=0;
                
$os=librdf_node_to_string($object);
                
reset($Nodes[$node]);
                while(!
$found && list(,$pso)=each($Nodes[$node])) {
                    
$p=key($pso);
                    list(
$s,$o)=current($pso);
                    
$found=($p==$predicate && librdf_node_to_string($o)==$os);
                }
                if(!
$found)
                    
array_push($Nodes[$node],array($predicate=>array($subject,$object)));
            }
            
librdf_stream_next($stream);
            
$count++;
        };
        
librdf_free_stream($stream);
        
librdf_free_parser($parser);
        
librdf_free_uri($base);
        
$stream=0;
        
$parser=0;
        
$base=0;
        if (
$count>2500 && !preg_match('|^192\.168\.|',$_SERVER['REMOTE_ADDR'])) {
            
header('HTTP/1.1 400 Bad Request');
            
header('Content-Type: text/plain');
            print(
"ETOOMANYTRIPLES: Sorry, that URI contains too many triples ($count), unable to transform.");
            exit;
        }

        
/* Reserialize... */
        
$xml='<?xml version="1.0" encoding="UTF-8"?><rdf:RDF';
        while (list(
$uri,$prefix)=each($Namespaces))
            
$xml.="\n  xmlns:$prefix=\"$uri\"";
        
$xml.=">\n";
        
reset($Nodes);
        while (list(,
$Node)=each($Nodes))
        {
            
reset($Node);
            
$pso=current($Node);
            
$p=key($pso);
            list(
$s,$o)=current($pso);
            
$xml.='<rdf:Description';
            if (
librdf_node_get_type($s)==1)
            {
                
$uriref=librdf_node_get_uri($s);
                
$xml.=' rdf:about="'.htmlspecialchars(librdf_uri_to_string($uriref)).'"';
            }
            else
            {
                
$name=librdf_node_get_blank_identifier($s);
#                $xml.=' rdf:nodeID="'.htmlspecialchars($name).'"';
                
$xml.=' rdf:ID="'.htmlspecialchars($name).'"';
            }
            
$xml.=">\n";
            
$lastn='';
            while (list(,
$pso)=each($Node))
            {
                
$predicate=key($pso);
                list(,
$object)=current($pso);
                
$n='  <'.$predicate;
                
$type=librdf_node_get_type($object);
                if (
$type==1)
                    
$n.=' rdf:resource="'.htmlspecialchars(librdf_uri_to_string(librdf_node_get_uri($object))).'"/';
                elseif (
$type==4)
#                    $xml.=' rdf:nodeID="'.htmlspecialchars(librdf_node_get_blank_identifier($object)).'"/';
                    
$n.=' rdf:resource="#'.htmlspecialchars(librdf_node_get_blank_identifier($object)).'"/';
                elseif (
$type==2)
                {
                    if (
librdf_node_get_literal_value_language($object)!='')
                        
$n.=' xml:lang="'.htmlspecialchars(librdf_node_get_literal_value_language($object)).'"';
#                    if (librdf_node_get_literal_value_datatype_uri($object))
#                        $xml.=' rdf:datatype="'.htmlspecialchars(librdf_uri_to_string(librdf_node_get_literal_value_datatype_uri($object))).'"';
                    
if (librdf_node_get_literal_value_is_wf_xml($object))
                        
$n.=' rdf:parseType="Literal">'.librdf_node_get_literal_value($object).'</'.$predicate;
                    else
                        
$n.='>'.htmlspecialchars(librdf_node_get_literal_value($object)).'</'.$predicate;
                }
                
$n.=">\n";
                if(
$n!=$lastn)
                    
$xml.=$n;
                
$lastn=$n;
            };
            
$xml.="</rdf:Description>\n";
        };
        
$xml.="</rdf:RDF>";
#if ($_SERVER['REMOTE_ADDR']=='192.168.1.16')
#    print($xml);
        
return $xml;
    };

#librdf_uri* error_count_uri=librdf_new_uri(world, LIBRDF_PARSER_FEATURE_ERROR_COUNT);
#const char* error_count_string=librdf_parser_get_feature(parser, error_count_uri);
#int error_count=atoi(error_count_string);
#fprintf(stderr, "Parsing returned %d errors\n", error_count);
#librdf_free_uri(error_count_uri)

?>