Something went wrong on our end
Utils.php 19.05 KiB
<?php
class Utils{
public static function uri2curie($uri){
global $conf;
$ns = $conf['ns'];
$curie = $uri;
$aux = $uri;
foreach($ns as $k => $v){
$aux = preg_replace("|^$v|", "", $uri);
if($aux != $uri){
$uriSegments = explode("/", $aux);
$lastSegment = array_pop($uriSegments);
if(sizeof($uriSegments)>0){
$prefix = $k."_".(implode("_", $uriSegments));
//Adding "new" namespace
$conf['ns'][$prefix] = $v.implode("/", $uriSegments)."/";
}else{
$prefix = $k;
}
$curie = $prefix.":".$lastSegment;
break;
}
}
return $curie;
}
public static function curie2uri($curie){
global $conf;
$ns = $conf['ns'];
$parts = explode(':', $curie);
//Avoid if we have a namespace prefix called 'http'
if(preg_match('|^//|', $parts[1])){
return $curie;
}
if(sizeof($parts)>1 ){
if(!isset($ns[$parts[0]])){
$prefixSegments = explode("_", $parts[0]);
$realPrefix = array_shift($prefixSegments);
$conf['ns'][$parts[0]] = $ns[$realPrefix].join("/", $prefixSegments);
return $ns[$realPrefix].join("/", $prefixSegments)."/".$parts[1];
}else{
return $ns[$parts[0]].$parts[1];
}
}else{
return $curie;
}
}
public static function getPrefix($curie){
global $conf;
$ns = $conf['ns'];
$parts = explode(':', $curie);
//Avoid if we have a namespace prefix called 'http'
if(preg_match('|^//|', $parts[1])){
return $curie;
}
return array('ns' => $ns[$parts[0]], 'prefix' => $parts[0]);
}
public static function getTemplate($uri){
$filename = str_replace(":", "_", $uri);
if(file_exists ($filename)){
include_once($filename);
}
}
private static function sparqlResult2Obj($data){
global $conf;
$obj = array();
if(!isset($data['results'])){
foreach($data as $k => $v){
$obj[$k] = Utils::sparqlResult2Obj($v);
}
}else{
$aux = $data['results']['bindings'];
if(sizeof($aux)>0){
foreach($aux as $w){
$row = array();
foreach($w as $k => $v){
$row[$k]['value'] = $v['value'];
if($v['type'] == 'uri'){
$row[$k]['curie'] = Utils::uri2curie($v['value']);
$row[$k]['localname'] = array_pop(explode(":",$row[$k]['curie']));
$row[$k]['uri'] = 1;
}elseif($v['type'] == 'bnode'){
$row[$k]['curie'] = 'blankNode';
$row[$k]['blank'] = 1;
}else{
$row[$k]['literal'] = 1;
$row[$k]['curie'] = $v['value'];
if(isset($v['datatype'])){
$row[$k]['type'] = $v['datatype'];
}
if(isset($v['xml:lang'])){
$row[$k]['lang'] = $v['xml:lang'];
}
}
}
/*if(sizeof($aux) == 1){
$obj = $row;
}*/
if(sizeof($row) >0){
array_push($obj, $row);
}
}
}
}
return $obj;
}
public static function getExtension($accept_string){
global $conf;
$extension = "html";
foreach($conf['http_accept'] as $ext => $accept_arr){
if(in_array($accept_string, $accept_arr)){
$extension = $ext;
}
}
return $extension;
}
public static function getBestContentType($accept_string){
global $conf;
$a = explode(",", $accept_string);
$b = array();
foreach($a as $v){
foreach($conf['http_accept'] as $formatTypeArray){
if(strstr($v, ";")){
$aux = explode(";", $v);
$aux[0] = trim($aux[0]);
if(in_array($aux[0], $formatTypeArray)){
$b[$aux[0]] = floatval(trim(str_replace("q=","",$aux[1])));
}
}else{
$value = trim($v);
if(in_array($value, $formatTypeArray)){
$b[$value] = 1.0;
}
}
}
}
$a = $b;
arsort($a);
$ct = 'text/html';
foreach($a as $k => $v){
$ct = $k;
break;
}
if($ct == NULL || $ct == "" || $ct == "*/*"){
$ct = 'text/html';
}
return $ct;
}
private static function travelTree($tree){
$results = array();
if(is_string($tree)){
return $tree;
}
foreach($tree as $t){
$aux = Utils::travelTree($t);
if(is_array($aux)){
$results = array_merge($results, $aux);
}else{
array_push($results, $aux);
}
}
return $results;
}
public static function serializeRdf($data, $extension='rdf'){
global $conf;
global $lodspk;
$ser;
$dPointer;
$docs = Utils::travelTree($data);
require_once($conf['home'].'lib/arc2/ARC2.php');
$parser = ARC2::getRDFParser();
$triples = array();
foreach($docs as $d){
$parser->parse($conf['basedir'], $d);
$t = $parser->getTriples();
$triples = array_merge($triples, $t);
}
if($lodspk['mirror_external_uris']){
global $uri;
global $localUri;
$t = array();
$t['s'] = $localUri;
$t['s_type'] = 'uri';
$t['p'] = "http://www.w3.org/2002/07/owl#sameAs";
$t['o'] = $uri;
$t['o_type'] = 'uri';
array_push($triples, $t);
$t['p'] = "http://www.w3.org/2000/10/swap/pim/contact#preferredURI";
array_push($triples, $t);
}
switch ($extension){
case 'ttl':
$ser = ARC2::getTurtleSerializer();
break;
case 'nt':
$ser = ARC2::getNTriplesSerializer();
break;
case 'json':
$ser = ARC2::getRDFJSONSerializer();
break;
case 'rdf':
$ser = ARC2::getRDFXMLSerializer();
break;
default:
$ser = null;
}
if($ser != null){
$doc = $ser->getSerializedTriples($triples);
}else{
$doc = var_export($data, true);
}
return $doc;
}
public static function processDocument($viewFile, $lodspk, $data){
global $conf;
global $lodspk;
$contentType = $lodspk['contentType'];
$extension = Utils::getExtension($contentType);
header('Content-Type: '.$contentType);
if(isset($lodspk['resultRdf']) && $lodspk['resultRdf'] == true){
echo Utils::serializeRdf($data, $extension);
}else{
Utils::showView($lodspk, $data, $viewFile);
}
}
public static function getResultsType($query){
global $conf;
global $uri;
if(preg_match("/select/i", $query)){
return $conf['output']['select'];
}elseif(preg_match("/describe/i", $query)){
return $conf['output']['describe'];
}elseif(preg_match("/construct/i", $query)){
return $conf['output']['describe'];
}elseif(preg_match("/ask/i", $query)){
return $conf['output']['ask'];
}else{
HTTPStatus::send500($uri);
}
}
public static function queryDir($modelDir, &$r, &$f){
global $conf;
global $uri;
global $lodspk;
global $endpoints;
global $results;
$strippedModelDir = str_replace('endpoint.', '', $modelDir);
$lodspk['model'] = $modelDir;
$originalDir = getcwd();
$subDirs= array();
if($conf['debug']){
Logging::log("Entering $strippedModelDir from ".getcwd(), E_USER_NOTICE);
}
chdir($modelDir);
$handle = opendir('.');
while (false !== ($modelFile = readdir($handle))) {
if($modelFile != "." && $modelFile != ".." && strpos($modelFile, ".") !== 0){
if(is_dir($modelFile)){
if(strpos('endpoint.', $modelFile) == 0){
if($conf['debug']){
Logging::log("Save $modelFile for later, after all the queries in the current directory has been resolved", E_USER_NOTICE);
}
$subDirs[]=$modelFile;
}
}else{
if(preg_match('/\.query$/', $modelFile)){
$e = null;
if(!isset($endpoints[$strippedModelDir])){
if($conf['debug']){
Logging::log("Creating endpoint for $strippedModelDir", E_USER_NOTICE);
}
if(!isset($conf['endpoint'][$strippedModelDir])){
if($conf['debug']){
Logging::log("Couldn't find $strippedModelDir as a list of available endpoints. Will continue using 'local'", E_USER_WARNING);
}
$e = $endpoints['local'];
}else{
$endpoints[$strippedModelDir] = new Endpoint($conf['endpoint'][$strippedModelDir], $conf['endpoint']['config']);
$e = $endpoints[$strippedModelDir];
}
}else{
$e = $endpoints[$strippedModelDir];
}
if($modelDir != $lodspk['type']){
if(!isset($r[$strippedModelDir]) ){
$r[$strippedModelDir] = array();
$f[$strippedModelDir] = array();
}
Utils::queryFile($modelFile, $e, $r[$strippedModelDir], $f);
}else{
Utils::queryFile($modelFile, $e, $r, $f);
}
}
}
}
}
closedir($handle);
$originalDir = $lodspk['model'];
if(isset($subDirs)){
foreach($subDirs as $v){
if(!isset($r[$modelDir])){
$r[$modelDir] = array();
}
if($modelDir != $lodspk['type']){
Utils::queryDir($v, $r[$strippedModelDir], $f[$strippedModelDir]);
}else{
Utils::queryDir($v, $r, $f);
}
}
}
// chdir($conf['home']);
//return $data;
}
public static function queryFile($modelFile, $e, &$rPointer, &$fPointer){
global $conf;
global $lodspk;
global $results;
global $firstResults;
global $uri;
$data = array();
$strippedModelFile = str_replace('endpoint.', '', str_replace('.query', '',$modelFile));
if(!is_dir($modelFile)){
require_once($conf['home'].'lib/Haanga/lib/Haanga.php');
Haanga::configure(array(
'cache_dir' => $conf['home'].'cache/',
'autoescape' => FALSE,
));
//Haanga supports the dot (.) convention only for objects
if(is_array($lodspk)){
$lodspkObj = Convert::array_to_object($lodspk);
$lodspk = $lodspkObj;
}
$r2 = Convert::array_copy($results);
$models = Convert::array_to_object($r2);
$f2 = Convert::array_copy($firstResults);
$first = Convert::array_to_object($f2);
$vars = compact('uri', 'lodspk', 'conf', 'models', 'first');
$q = file_get_contents($modelFile);
if($q == false){
HTTPStatus::send500("I can't load ".$modelFile." in ".getcwd());
}
$fnc = Haanga::compile($q);
$query = $fnc($vars, TRUE);
if(is_object($lodspk)){
$lodspkObj = Convert::object_to_array($lodspk);
$lodspk = $lodspkObj;
}
$query = Utils::addPrefixes($query);
if($lodspk['transform_select_query']==true){
include_once($conf['home'].'lib/arc2/ARC2.php');
$parser = ARC2::getSPARQLParser();
$parser->parse($query);
$sparqlConstruct = array();
if (!$parser->getErrors()) {
$resultVars = array();
$q_infos = $parser->getQueryInfos();
foreach($q_infos['query']['result_vars'] as $v){
if($v['type'] == 'var'){
$resultVars[$v['value']] = 1;
}
};
$x = Utils::extractObj($q_infos['query']['pattern']);
foreach($x as $v){
if(($resultVars[$v['s']] && $v['s_type'] == 'var')
|| ($resultVars[$v['p']] && $v['p_type'] == 'var')
|| ($resultVars[$v['o']] && $v['o_type'] == 'var')){
array_push($sparqlConstruct, $v);
}
}
$construct = "";
foreach($sparqlConstruct as $v){
if($v['s_type'] == 'uri'){
$construct .= "<".$v['s']."> ";
}elseif($v['s_type'] == 'var'){
$construct .= '?'.$v['s'].' ';
}else{
$construct.= $v['s']." ";
}
if($v['p_type'] == 'uri'){
$construct .= "<".$v['p']."> ";
}elseif($v['p_type'] == 'var'){
$construct .= '?'.$v['p'].' ';
}else{
$construct.= $v['p']." ";
}
if($v['o_type'] == 'uri'){
$construct .= "<".$v['o']."> ";
}elseif($v['o_type'] == 'literal'){
$construct .= '"'.$v['o'].'" ';
}elseif($v['o_type'] == 'var'){
$construct .= '?'.$v['o'].' ';
}else{
$construct.= $v['o']." ";
}
$construct .= ".\n";
}
if($construct == ""){
if(sizeof($q_infos['query']['result_vars'])>0){
//For now, assuming variables are in the GRAPH ?g
$query = "CONSTRUCT {?g ?x ?y} WHERE{GRAPH ?g{?g ?x ?y}}";
}else{
HTTPStatus::send500();
}
}else{
$query = preg_replace('/select\s*[^{]*\s*(where)?\s*{/i', 'CONSTRUCT {'.$construct.'} WHERE{', $query);
}
}else {
return;
//HTTPStatus::send500("invalid query: " . var_export($parser->getErrors(), true)."\n\nQUERY:\n".$query);
}
}
if($conf['debug']){
Logging::log($modelFile." against ".$e->getSparqlUrl());
Logging::log($query);
Logging::log("Running query from ".$modelFile." on endpoint ".$e->getSparqlURL(), E_USER_NOTICE);
}
$initTime = microtime(true);
$aux = $e->query($query, Utils::getResultsType($query));
$endTime = microtime(true);
if($conf['debug']){
Logging::log("Execution time: ".($endTime - $initTime)." seconds");
}
$timeObj = new stdClass();
$timeObj->query = new stdClass();
$timeObj->query->value = $strippedModelFile;
$timeObj->time = new stdClass();
$timeObj->time->value = ($endTime - $initTime);
$lodspk['queryTimes'][$strippedModelFile] = $timeObj;
if($modelFile != $lodspk['type']){
if(!isset($rPointer[$strippedModelFile])){
$rPointer[$strippedModelFile] = array();
$firstResults[$strippedModelFile] = array();
}
if(Utils::getResultsType($query) == $conf['output']['select']){
$rPointer[$strippedModelFile] = Utils::sparqlResult2Obj($aux);
$fPointer[$strippedModelFile] = $rPointer[$strippedModelFile][0];
}else{
$lodspk['resultRdf'] = true;
$rPointer[$strippedModelFile] = $aux;
}
}else{
if(Utils::getResultsType($query) == $conf['output']['select']){
$rPointer = Utils::sparqlResult2Obj($aux);
$fPointer[$strippedModelFile] = $rPointer[0];
}else{
$lodspk['resultRdf'] = true;
$rPointer = $aux;
}
}
}else{
if(strpos('endpoint.', $modelFile) == 0){
if($conf['debug']){
Logging::log("$modelFile is a directory, will process it later", E_USER_NOTICE);
}
if($modelFile != $lodspk['type']){
if(!isset($rPointer[$strippedModelFile])){
$rPointer[$strippedModelFile] = array();
}
Utils::queryDir($modelFile, $rPointer[$strippedModelFile], $fPointer[$strippedModelFile]);
}else{
Utils::queryDir($modelFile, $rPointer, $fPointer);
}
}
}
}
public static function internalize($array){
global $conf;
$firstResultsKeyAppearance = true;
foreach($array as $key => $value){
if(!isset($value['value'])){
$array[$key] = Utils::internalize($value);
/*if($firstResultsKeyAppearance){
$firstResultsKeyAppearance = false;
$array['_firstResults']=$array[$key];
}*/
}else{
if(isset($value['uri']) && $value['uri'] == 1){
//If there is no mirroring, it wouldn't hurt to have available this value (e.g., using templates from a mirrored instance to a non-mirrored one)
$value['mirroredUri'] = $value['value'];
$value['mirroredCurie'] = Utils::uri2curie($value['value']);
if(isset($conf['mirror_external_uris']) && $conf['mirror_external_uris'] != false){
if(is_bool($conf['mirror_external_uris'])){
$value['value'] = preg_replace("|^".$conf['ns']['local']."|", $conf['basedir'], $value['value']);
}elseif(is_string($conf['mirror_external_uris'])){
$value['value'] = preg_replace("|^".$conf['mirror_external_uris']."|", $conf['basedir'], $value['value']);
}else{
HTTPStatus::send500("Error in mirroring configuration");
exit(1);
}
}
$value['curie'] = $value['mirroredCurie'];
$array[$key] = $value;
}
}
}
return $array;
}
public static function getfirstResults($array){
global $conf;
$firstResultsKeyAppearance = true;
foreach($array as $key => $value){
if(!isset($value['value'])){
$aux = Utils::getfirstResults($value);
if(isset($aux['0'])){
$array[$key] = $aux['0'];
}else{
$array[$key] = $aux;
}
}
}
return $array;
}
public static function showView($lodspkData, $data, $view){
global $conf;
global $uri;
global $lodspk;
global $extension;
//$lodspk = $conf['view']['standard'];
$lodspk = $lodspkData;
if(isset($lodspkData['params'])){
$lodspk['this']['params'] = $lodspkData['params'];
}
if(isset($lodspk['queryTimes'])){
$lodspk['queryTimes'] = Convert::array_to_object($lodspk['queryTimes']);
}
require_once($conf['home'].'lib/Haanga/lib/Haanga.php');
$viewAux = explode("/",$view);
$viewFile = array_pop($viewAux);
//$viewFile = $view;
$viewPath = join("/", $viewAux);
Haanga::configure(array(
'template_dir' => $viewPath,
'cache_dir' => $conf['home'].'cache/',
));
$models = $data;
Convert::getPaths($models, "");
$first = $lodspk['firstResults'];
unset($lodspk['firstResults']);
//unset($lodspk);
$vars = compact('uri','lodspk', 'conf', 'models', 'first');
if($conf['debug']){
//Logging::log(var_export($vars, true));
}
if(is_string($data)){
echo($data);
}elseif(is_file($view)){
try{
Haanga::Load($viewFile, $vars);
}catch(Exception $e){
echo '<pre>';
echo($e->getMessage()."' in ".$e->getFile().":".$e->getLine()."\nStack trace:\n".$e->getTraceAsString());
echo '</pre>';
}
}elseif($view == null){
$fnc = Haanga::compile('{{models|safe}}');
$fnc($vars, TRUE);
}else{
echo $conf['home'].$viewPath." ".$viewFile;
$fnc = Haanga::compile($view);
$fnc($vars, TRUE);
}
}
private static function extractObj($obj, $term = 'triple'){
$triples = array();
if(is_array($obj)){
foreach($obj as $k => $v){
if($v['type'] != 'triple'){
$aux = Utils::extractObj($v);
if($aux['type'] != 'triple'){
$triples = array_merge($triples,$aux);
}else{
$triples = array_merge($triples, $aux);
}
}else{
array_push($triples, $v);
}
}
}
return $triples;
}
public static function addPrefixes($q){
global $conf;
$matches = array();
$visited = array();
$newQuery = $q;
if(preg_match_all("|\s(\w+):\w+|", $q, $matches) > 0){
foreach($matches[1] as $v){
if(!isset($visited[$v]) && isset($conf['ns'][$v])){
$newQuery = "PREFIX ".$v.": <".$conf['ns'][$v].">\n".$newQuery;
$visited[$v] = true;
}
}
}
return $newQuery;
}
public static function filterTriples($triples, $pattern){
//Simples match/filter function possible
$result = array();
foreach($triples as $t){
if( (($pattern[0] != null && $pattern[0] == $t['s']) || $pattern[0] == null) &&
(($pattern[1] != null && $pattern[1] == $t['p']) || $pattern[1] == null) &&
(($pattern[2] != null && $pattern[2] == $t['o']) || $pattern[2] == null) ){
$result[] = array($t['s'], $t['p'], $t['o']);
}
}
return $result;
}
}
?>