<?
# 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');
include_once('getfoaf.php');
$Redland=librdf_php_get_world();
$metadata='explorer.rdf';
$foaf='http://myownspace.fr/myownFOAF/1.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)
?>