Code Listing
<?php
include("erdft_parser.php");
$erdf = file_get_contents('test.erdft');
//instantiate template parser: params are ($template_string, $sparql_var_regex, $sparql_optional_regex, $arc_config_path)
//
$eRdfT = new eRDFT($erdf, '/{(\$[a-zA-Z_]+)[^\}]*?}/', '/(\$[a-zA-Z_]+?)_optional/', './arc_config.php');
$data = $eRdfT->get_results();
$vars = array_keys($data[0]);
//set Smarty variables
include('/usr/lib/php/Smarty/libs/Smarty.class.php');
$smarty = new Smarty;
foreach($vars as $var)
{
//determine whether to give variable a value or an array
if(strpos($var, '__') )//this is a variable naming convention - array keys being named $singular__key and arrays being named $plural
{
//get array name
$parts = explode('__', $var);
$array_name = $parts[0].'s';
$smarty->assign($array_name, $data);
$new_form = '$'.$parts[0].'.'.$var;
$erdf = str_replace( '$'.$var , $new_form , $erdf); //convert to $row.key
}
else
{
$v = $data[0][$var];
$smarty->assign($var, $v);
}
}
$erdf = preg_replace($eRdfT->REG_EXES['SPARQL_OPTIONAL'],'$1',$erdf);
$smarty->template_dir = './templates';
//now process
$handle = fopen("templates/temp_test.tpl", "w");
if (fwrite($handle, $erdf) === FALSE) {
echo "Cannot write to file ($filename)";
exit;
}
fclose($handle);
$smarty->display("temp_test.tpl");
?>
<?php
/**
* A script to process an Exhibit JSON template
* file into one or more SPARQL queries, and return the results as
* an Exhibit JSON file.
* The template file should be a normal Exhibit database, except objects under the "types" and "properties" objects
* should have a property called "uri", containing the URI of the Class or Property,
* items should have some properties with empty values,
* and an item's "label" should be the name of another property.
* Author: Keith Alexander
*/
/*Instantiate ARC API */
require_once("arc/ARC_api.php");
$api_args = array(
"inc_path"=>"./arc/",
"config_path"=>"./arc_config.php"
);
$api = new ARC_api($api_args);
$api->db_connect();
//read the JSON template file
require('json.php');
$json = new Services_JSON();
$data = $json->decode(file_get_contents('template.json'));
//get all the items - we will create a query for each item we find
$template_items = $data->items;
//empty the items array from our original JSON file - we will fill it with results
$data->items = array();
//iterate over the template items, creating a query
foreach($template_items as $item)
{
//the subject of the graph - can be preset by the user, or left blank
//so we either turn it into <http://example.com/users-id#> or ?id
$subject = (isset($item->id) && !empty($item->id))? '<'.$item->id.'>' : '?id';
// get the human readable type label
$type_name = $item->type;
// get the type's IRI
$type = '<'.$data->types->$type_name->uri.'>';
//get the label's property name
$label_prop_name = $item->label;
//get the label's property's IRI
$label_prop = '<'.$data->properties->$label_prop_name->uri.'>';
//for storing WHERE conditions
$triples = array();
//vars in the select statement
$vars = array();
//jsonc is a parameter that the ARC store accepts to strip out
// unwanted meta properties from the JSON results object
$jsonc = array('id');
//iterate over the template item's properties
foreach($item as $k => $v)
{
//determine node type of object
if(empty($v))
{
$object = '?'.$k;
}
elseif( (substr($v,0,1)=='<') && (substr($v,-1,1)=='>') )
{
$object = $k;
}
else
{
$object ='"'.$v. '"';
}
$vars[]='?'.$k;
$jsonc[]= $k;
if(!in_array($k, array('type','id','label')) )
{
$property = $data->properties->$k->uri;
$triples[] = <<<_SPQL_
$subject <{$property}> $object .
_SPQL_;
}
}
$sparql = "SELECT ?id ".implode(" ", $vars)." \r\n WHERE { \r\n\t GRAPH ?id {
$subject <http://www.w3.org/1999/02/22-rdf-syntax-ns#type> $type . \r\n
$subject <http://www.w3.org/1999/02/22-rdf-syntax-ns#type> ?type . \r\n
$subject $label_prop ?label . \r\n
?id $label_prop ?label . \r\n
".implode("\r\n", $triples)." \r\n\t } \r\n } LIMIT 100";
$args=array(
"result_type"=>'json', // (rows|json|xml|single|rows_n_count|row_count|sql)
"query"=>$sparql,
"result_type_args"=>array("jsonc"=> implode(",",$jsonc),)
);
$qr=$api->query($args);
$result = $json->decode($qr['result']);
foreach($result->results->bindings as $row)
{
//make the rdf:type human readable
$row->type = $type_name;
$data->items[] = $row;
}
}
//output
header("Content-type: text");
echo stripslashes($json->encode($data));
?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html lang="en">
<head profile="http://purl.org/NET/erdf/profile">
<link rel="schema.dc" href="http://purl.org/dc/elements/1.1/" />
<link rel="schema.foaf" href="http://xmlns.com/foaf/0.1/" />
<link rel="schema.rdf" href="http://www.w3.org/1999/02/22-rdf-syntax-ns#" />
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
<title>eRDFT test </title>
</head>
<body>
<h1>eRDFT test</h1>
<h2>Things with dc:titles from the datastore</h2>
<ul>
{foreach from="$rows" item="row"}
<li id="{$row__foo}"><span class="dc-title">{$row__title}</span></li>
{/foreach}
</ul>
<div class="-Person" id="{$someone}">
<p>My name is <strong class="foaf-name">{$myname}</strong>.</p>
</div>
</body>
</html>
<?php
/**
*
*
* @author Keith Alexander
* @version 0.3
* @copyright GPL
* @package eRDFT
* class eRDFT : a class that uses ARC_erdf_parser to retrieve triples
* from an eRDF template and convert them into SPARQL queries, retrieve data from
* the ARC mysql-backed RDF triple store, and store it as an associative array which can then be used
* by the eRDF template to display the data.
*
* //Changes: changed the conditions in makeWhereClause to do better optional clause selection
**/
require_once("arc/ARC_api.php");
require_once("arc/ARC_erdf_parser.php");
class eRDFT
{
var $erdf,
$base_href=false,
$arc_config_path,
$api,
$triple_info = array(),
$processed_triples = array(),
$sparql_vars = array(),
$sparqls = array(),
$resource_indices = array(),
$levels = array(),
$resultsets = array(),
$top_level_resultset = array(),
$results = array(),
$errors = array(),
$REG_EXES = array(
'SPARQL_VAR' => '/(\$[a-zA-Z_\.]+)/',
'IRI' => '/^([a-zA-Z]+:\/\/[^\W"\']+)/',
'SPARQL_OPTIONAL' => '/(\$[a-zA-Z_\.]+?)_optional/',
);
function eRDFT($erdf, $base=false, $regexes=array(), $arc_config_path=null, $auto=true)
{
$this->erdf = $erdf;
$this->arc_config_path = ($arc_config_path)? $arc_config_path : dirname(__FILE__).'/arc/arc_config.php';
/*Instantiate API */
$api_args = array(
"inc_path"=> dirname(__FILE__)."/arc/",
"config_path"=> $this->arc_config_path,
);
$this->api = new ARC_api($api_args);
$this->api->db_connect() or die("Couldn't connect to database");
if(!$this->api->store_exists()) $this->api->create_store() or die("Couldn't create rdfstore - check user permissions");
if($base) $this->base_href = $base;
foreach($regexes as $k => $v)
{
$this->REG_EXES[$k] = $v;
}
if($auto)
{
$this->parse_erdf($erdf);
$this->makeResultsets();
$this->doQueries();
$this->format_erdf();
} //else the user can make changes to the triples before processing
}
function makeResultsets()
{
$sparql_vars = $this->sparql_vars;
foreach($sparql_vars as $v)
{
$resultsets =& $this->resultsets;
if(strpos($v, '__')) // __ is the path separator
{
$path_keys = array_slice(explode('__', substr($v,1)), 0, -1);
$path = "['".implode("']['sub_results']['", $path_keys)."']";
eval('$resultsets["sub_results"]'.$path."['sparql_vars'][] = '".$v."';");
array_push($path_keys, '');
$prefix = implode('__', $path_keys);
eval('$resultsets["sub_results"]'.$path."['row_prefix'] = '{$prefix}';");
}
else
{
$this->top_level_resultset['sparql_vars'][] = $v;
}
}
}
// parses eRDF html and extracts triples
function parse_erdf()
{
$erdf = $this->erdf;
$parser_args=array("encoding"=>"auto");
if($this->base_href) $parser_args['base'] = $this->base_href;
$parser=new ARC_erdf_parser($parser_args);
$p_result=$parser->parse_data($this->erdf);
//check if the eRDF parses
if($p_result["result"] && !$p_result["error"])
{
//get triples
$this->triple_info = $parser->get_triple_infos();
//process triples for sparql syntax
for($x=0; $x < count($this->triple_info['triples'] ); $x++)
{
$t = $this->triple_info['triples'][$x];
//clean s and o into sparql vars. stuff{$name} => $name
foreach(array('s','o') as $k )
{
$this->_format_node($k, $t);
}
$this->processed_triples[] = $t;
}
}
else
{
if($p_result["error"]) $this->errors[]=$p_result['error'];
return false;
}
}
function get_triples_by_subject($s, &$qt)
{
$nqt = array();
for ($i=0; $i < count($qt); $i++)
{
$t = $qt[$i];
if($t['s'] == $s)
{
$nqt[]=$t;
unset($qt[$i]);
}
}
return $nqt;
}
function doQueries()
{
//make prefix head
$prefixes = '';
foreach($this->triple_info['prefixes'] as $k => $v) $prefixes.='PREFIX '.$k.': '.'<'.$v.'>'." \r\n";
$whereclause = $this->makeWhereClause($sparql_vars);
$sparql = $prefixes;
//top level sparql
if(!empty($this->top_level_resultset['sparql_vars']))
{
$sparql.="\r\n SELECT ".implode(" ", array_unique($this->top_level_resultset['sparql_vars']))."\r\n WHERE { $whereclause } LIMIT 1";
$this->top_level_resultset['sparql'] = $sparql;
$data = $this->get_data($sparql);
if($data[0]) foreach($data[0] as $k => $v) $this->results[$k] = $v;
}
//get nested loops recursively
$this->nested_data($this->resultsets['sub_results'], $this->results, $prefixes, $data[0]);
}
function nested_data(&$resultset, &$dataset, $prefixes, $parent_row=array(), $parent_row_prefix)
{
foreach($resultset as $k => $v)
{
//build the sparql query string
$sparql = $prefixes;
$sparql_vars = array_unique($v['sparql_vars']);
$whereclause = $this->makeWhereClause($sparql_vars,$parent_row,$parent_row_prefix);
$sparql.="\r\n SELECT ".implode(" ",$sparql_vars)."\r\n WHERE { GRAPH ?erdftgraph { $whereclause } } LIMIT 50";
$sparql = str_replace($v['row_prefix'],'', $sparql ); //get rid of this particular row prefix
//eg: cd__artist becomes artist, but artist__name stays artist__name in this query
$resultset[$k]['sparql'] = $sparql;
//get and save results
//the $k of resultset is pluralised in dataset by appending an 's'. Better to write 'mouses' than have to think about whether 'mice' will work.
$dataset[$k.'s'] = ($this->get_data($sparql, 'rows'));
if(isset($resultset[$k]['sub_results']) && !empty($dataset[$k.'s']))
{
//now go through each row of the current result set, making a query for any sub result sets
$row_number = 0;
foreach($dataset[$k.'s'] as $row)
{
$whereclause = $this->makeWhereClause($v2['sparql_vars'],$row, $v2['row_prefix']);
$this->nested_data($resultset[$k]['sub_results'], $dataset[$k.'s'][$row_number], $prefixes, $row, $v['row_prefix']);
$row_number++;
}
}
}
}
// queries the rdf-store with the sparql query and gets back the data
function get_data($sparql, $resultype='rows')
{
$this->sparqls[] = $sparql;
$query_args=array(
"result_type"=>$resultype, // (rows|json|xml|single|rows_n_count|row_count|sql)
"query"=>$sparql
);
$qr=$this->api->query($query_args) or die("Couldn't query datastore");
if (!empty($qr['error'])) $this->errors[] = $qr['error'];
if (empty($qr['result'])) $this->errors[] = 'Query returned no data.';
//return $qr['result'];
return $qr['result'];
}
function get_eRDF()
{
return $this->erdf;
}
function get_results()
{
return $this->results;
}
function get_sparqls()
{
return $this->sparqls;
}
function index_resources()
{
$tri = $this->processed_triples;
if(empty($tri)) $this->errors[] = 'No Triples were processed!';
$r = array();
foreach($tri as $t)
{
$r[$t['s']]['props'][] = $t;
$r[$t['o']]['inverse_props'][] = $t;
$r[$t['s']]['all_props'][] = $t;
$r[$t['o']]['all_props'][] = $t;
//array_unique($r['subjects'][$t['s']]['props']);
}
$this->resource_indices = $r;
}
function _format_node($k, &$t)
{
$node &= $t[$k];
if(preg_match($this->REG_EXES['SPARQL_VAR'], $t[$k], $m))
{
if( preg_match($this->REG_EXES['SPARQL_OPTIONAL'],$m[1],$sub_m))// it's an optional variable
{
//triple is only optional if the optional node is the object
if($t[$k] == $t['o']) $t['SPARQL_TRIPLE_TYPE'] = 'OPTIONAL';
$t[$k.'_erdft_type'] = 'SPARQL_OPTIONAL_VAR';
$t[$k] = str_replace('.','__',$sub_m[1]);
$this->sparql_vars[]=$t[$k];
}
else //it's a regular variable
{
$t[$k.'_erdft_type'] = 'SPARQL_VAR';
$t[$k] = str_replace('.','__',$m[1]);
$this->sparql_vars[]=$t[$k];
}
}
// elseif($t[$k] == '') //if a node is empty, give it a var
// {
// $t[$k] = '?ERDFT';
// $t[$k.'_erdft_type'] = 'SPARQL_VAR';
// $this->errors[]='The query is not accurate - you need to add an id to your top level element' ;
// }
elseif( preg_match($this->REG_EXES['IRI'], $t[$k]) ) //IRI syntax
{
$t[$k] = '<' . $t[$k].'>';
$t[$k.'_erdft_type'] = 'IRI';
}
else // quote literals
{
$t[$k] = '"'.$t[$k].'"';
$t[$k.'_erdft_type'] = 'LITERAL';
}
return $t[$k];
}
function makeWhereClause($sparql_vars, $datarow=array(), $row_prefix='')
{
$conditions = array();
$optionals = array();
foreach($this->processed_triples as $rt)
{
foreach(array('s','o') as $k)
{
//if var is like $foo__bar, we need to get 'bar', which may be a heading in the row
$rowheader = substr($rt[$k], strlen($row_prefix)+1);
if((!strpos($rowheader,'__') ) && $datarow[$rowheader] )
{
$rt[$k] = $datarow[$rowheader];
$rt[$k] = $this->_format_node($k, &$rt);
}
}
if((strpos($rt['s_erdft_type'], '_VAR') !== false) || (strpos($rt['o_erdft_type'], '_VAR') !== false) )
{
$condition = "{$rt['s']} {$rt['p_qname']} {$rt['o']} .";
if ( ($rt['o_erdft_type'] == 'SPARQL_OPTIONAL_VAR') && (in_array($rt['s'], $sparql_vars) ) )
{
$optionals[] = "\r\n OPTIONAL( {$condition} )";
}
elseif ( ( ($rt['s_erdft_type'] == 'SPARQL_OPTIONAL_VAR')
&& (!in_array($rt['o'], $sparql_vars) ) )
|| ($rt['o_erdft_type'] == 'SPARQL_OPTIONAL_VAR')
&& (!in_array($rt['o'], $sparql_vars)
&& $rt['s_erdft_type'] == 'IRI' ) )
{
//blank
}
else $conditions[] = $condition;
}
}
if(empty($conditions)) $this->errors[]='The query needs some non-optional clauses';
$conditions = implode("\t\r\n",$conditions);
$optionals = implode("\t\r\n",$optionals);
$whereclause = $conditions.$optionals;
return $whereclause;
}
function format_erdf()
{
$erdf &= $this->erdf;
$erdf = preg_replace($this->REG_EXES['SPARQL_OPTIONAL'], '$1', $erdf);
return $erdf;
}
}
?>
<?php
/**
*
*
* @author Keith Alexander
* @version 0.2
* @copyright GPL
* @package eRDFT
* class eRDFT : a class that uses ARC_erdf_parser to retrieve triples
* from an eRDF template and convert them into SPARQL queries, retrieve data from
* the ARC mysql-backed RDF triple store, and store it as an associative array which can then be used
* by the eRDF template to display the data.
**/
require_once("arc/ARC_api.php");
require_once("arc/ARC_erdf_parser.php");
class eRDFT
{
var $erdf,
$arc_config_path,
$api,
$triple_info = array(),
$processed_triples = array(),
$sparql_vars = array(),
$sparqls = array(),
$resource_indices = array(),
$levels = array(),
$resultsets = array(),
$top_level_resultset = array(),
$results = array(),
$errors = array(),
$REG_EXES = array(
'SPARQL_VAR' => '/(\$[a-zA-Z_]+)/',
'IRI' => '/^([a-zA-Z]+:\/\/[^\W"\']+)/',
'SPARQL_OPTIONAL' => '/(\$[a-zA-Z_]+?)_optional/',
);
function eRDFT($erdf, $regexes=array(), $arc_config_path=null, $auto=true)
{
$this->erdf = $erdf;
$this->arc_config_path = ($arc_config_path)? $arc_config_path : dirname(__FILE__).'/arc/arc_config.php';
/*Instantiate API */
$api_args = array(
"inc_path"=> dirname(__FILE__)."/arc/",
"config_path"=> $this->arc_config_path,
);
$this->api = new ARC_api($api_args);
$this->api->db_connect() or die("Couldn't connect to database");
if(!$this->api->store_exists()) $this->api->create_store() or die("Couldn't create rdfstore - check user permissions");
foreach($regexes as $k => $v)
{
$this->REG_EXES[$k] = $v;
}
if($auto)
{
$this->parse_erdf($erdf);
$this->makeResultsets();
$this->doQueries();
$this->format_erdf();
} //else the user can make changes to the triples before processing
}
function makeResultsets()
{
$sparql_vars = $this->sparql_vars;
foreach($sparql_vars as $v)
{
$resultsets =& $this->resultsets;
if(strpos($v, '__')) // __ is the path separator
{
$path_keys = array_slice(explode('__', substr($v,1)), 0, -1);
$path = "['".implode("']['sub_results']['", $path_keys)."']";
eval('$resultsets["sub_results"]'.$path."['sparql_vars'][] = '".$v."';");
array_push($path_keys, '');
$prefix = implode('__', $path_keys);
eval('$resultsets["sub_results"]'.$path."['row_prefix'] = '{$prefix}';");
}
else
{
$this->top_level_resultset['sparql_vars'][] = $v;
}
}
}
// parses eRDF html and extracts triples
function parse_erdf()
{
$erdf = $this->erdf;
$parser_args=array("encoding"=>"auto");
$parser=new ARC_erdf_parser($parser_args);
$p_result=$parser->parse_data($this->erdf);
//check if the eRDF parses
if($p_result["result"] && !$p_result["error"])
{
//get triples
$this->triple_info = $parser->get_triple_infos();
//process triples for sparql syntax
for($x=0; $x < count($this->triple_info['triples'] ); $x++)
{
$t = $this->triple_info['triples'][$x];
//clean s and o into sparql vars. stuff{$name} => $name
foreach(array('s','o') as $k )
{
$this->_format_node($t[$k], $t);
}
$this->processed_triples[] = $t;
}
}
else
{
if($p_result["error"]) $this->errors[]=$p_result['error'];
return false;
}
}
function get_triples_by_subject($s, &$qt)
{
$nqt = array();
for ($i=0; $i < count($qt); $i++)
{
$t = $qt[$i];
if($t['s'] == $s)
{
$nqt[]=$t;
unset($qt[$i]);
}
}
return $nqt;
}
function doQueries()
{
//make prefix head
$prefixes = '';
foreach($this->triple_info['prefixes'] as $k => $v) $prefixes.='PREFIX '.$k.': '.'<'.$v.'>'." \r\n";
$conditions = array();
$optionals = array();
foreach($this->processed_triples as $rt)
{
$condition = "{$rt['s']} {$rt['p_qname']} {$rt['o']} .";
if ( isset($rt['SPARQL_TRIPLE_TYPE']) && $rt['SPARQL_TRIPLE_TYPE'] == 'OPTIONAL') $optionals[] = "OPTIONAL( {$condition} )";
else $conditions[] = $condition;
}
$sparql = $prefixes;
if(empty($conditions)) $this->errors[]='The query needs some non-optional clauses';
$conditions = implode("\t\r\n",$conditions);
$optionals = implode("\t\r\n",$optionals);
$whereclause = $conditions.$optionals;
//top level sparql
$sparql.="\r\n SELECT DISTINCT ".implode(" ", array_unique($this->top_level_resultset['sparql_vars']))."\r\n WHERE { $whereclause } LIMIT 1";
$this->top_level_resultset['sparql'] = $sparql;
$data = $this->get_data($sparql);
if($data[0]) foreach($data[0] as $k => $v) $this->results[$k] = $v;
//get nested loops recursively
$this->nested_data($this->resultsets['sub_results'], $this->results, $prefixes, $whereclause);
}
function nested_data(&$resultset, &$dataset, $prefixes, $whereclause)
{
//the $k of resultset is pluralised in dataset by appending an 's'. Better to write 'mouses' than have to think about whether 'mice' will work.
foreach($resultset as $k => $v)
{
//build the sparql query string
$sparql = $prefixes;
$sparql_vars = array_unique($v['sparql_vars']);
$sparql.="\r\n SELECT ".implode(" ",$sparql_vars)."\r\n WHERE { $whereclause } LIMIT 3";
$sparql = str_replace($v['row_prefix'],'', $sparql ); //get rid of this particular row prefix
//eg: cd__artist becomes artist, but artist__name stays artist__name in this query
$resultset[$k]['sparql'] = $sparql;
//get and save results
$dataset[$k.'s'] = $this->get_data($sparql, 'rows');
if(isset($resultset[$k]['sub_results']) && !empty($dataset[$k.'s']))
{
//now go through each row of the current result set, making a query for any sub result sets
$row_number = 0;
foreach($dataset[$k.'s'] as $row)
{
foreach($row as $result_head => $result_value)
{
//now we replace the variable with the values we already retrieved for the sub query
$non_var = $this->_format_node($result_value, $nothing_happens_with_this_variable);
foreach($resultset[$k]['sub_results'] as $k2 => $v2)
{
$whereclause = str_replace('$'.$v2['row_prefix'].$result_head, $non_var, $whereclause);
}
$this->nested_data($resultset[$k]['sub_results'], $dataset[$k.'s'][$row_number], $prefixes, $whereclause);
}
$row_number++;
}
}
}
}
// queries the rdf-store with the sparql query and gets back the data
function get_data($sparql, $resultype='rows')
{
$this->sparqls[] = $sparql;
$query_args=array(
"result_type"=>$resultype, // (rows|json|xml|single|rows_n_count|row_count|sql)
"query"=>$sparql
);
$qr=$this->api->query($query_args) or die("Couldn't query datastore");
if (!empty($qr['error'])) $this->errors[] = $qr['error'];
if (empty($qr['result'])) $this->errors[] = 'Query returned no data.';
//return $qr['result'];
return $qr['result'];
}
function get_eRDF()
{
return $this->erdf;
}
function get_results()
{
return $this->results;
}
function get_sparqls()
{
return $this->sparqls;
}
function index_resources()
{
$tri = $this->processed_triples;
if(empty($tri)) $this->errors[] = 'No Triples were processed!';
$r = array();
foreach($tri as $t)
{
$r[$t['s']]['props'][] = $t;
$r[$t['o']]['inverse_props'][] = $t;
$r[$t['s']]['all_props'][] = $t;
$r[$t['o']]['all_props'][] = $t;
//array_unique($r['subjects'][$t['s']]['props']);
}
$this->resource_indices = $r;
}
function _format_node(&$node, &$t)
{
if(preg_match($this->REG_EXES['SPARQL_VAR'], $node, $m))
{
if( preg_match($this->REG_EXES['SPARQL_OPTIONAL'],$m[1],$sub_m))
{
$node = str_replace('.','__',$sub_m[1]);
$this->sparql_vars[]=$node;
$t['SPARQL_TRIPLE_TYPE'] = 'OPTIONAL';
}
else
{
$node = str_replace('.','__',$m[1]);
$this->sparql_vars[]=$m[1];
}
$t[$k.'_erdft_type'] = 'SPARQL_VAR';
}
elseif($node == '') //if a node is empty, give it a var
{
$node = '?ERDFT';
$t[$k.'_erdft_type'] = 'SPARQL_VAR';
$this->errors[]='The query is not accurate - you need to add an id to your top level element' ;
}
elseif( preg_match($this->REG_EXES['IRI'], $node) ) //IRI syntax
{
$node = '<' . $node.'>';
$t[$k.'_erdft_type'] = 'IRI';
}
else // quote literals
{
$node = '"'.$node.'"';
$t[$k.'_erdft_type'] = 'LITERAL';
}
return $node;
}
function format_erdf()
{
$erdf &= $this->erdf;
$erdf = preg_replace($this->REG_EXES['SPARQL_OPTIONAL'], '$1', $erdf);
}
}
?>
<?php
function arc_get_api_config(){
$config = array(
/* db */
"db_host"=>"localhost",
"db_name"=>"YourDBname",
"db_user"=>"Username",
"db_pwd"=>"password",
/* store prefix */
"prefix"=>"arc",
/* store */
"store_type"=>"basic+", // (basic|basic+|split)
"id_type"=>"hash_int", // (hash_int|hash_md5|hash_sha1|incr_int)
"reversible_consolidation"=>false, // adds additional columns
"index_type"=>"advanced", // (basic|advanced)
"index_graph_iris"=>true, // add graph columns to indexes
"index_words"=>true, // creates FULLTEXT index on values
"charset"=>"utf8" // for MySQL, if supported
);
return $config;
}
?>
<?php
require_once 'smartyresource.php';
class eRdfResource extends SmartyResource
{
function eRdfResource(&$tonic, $url, $metadata = array(), $body = NULL, $exists = FALSE)
{
parent::smartyResource(&$tonic, $url, $metadata, $body, $exists);
}
function getOwlSameAs()
{
//needs some kind of permission checker
if(array_key_exists('owl-sameAs', $_GET))
return 'http://'.$_SERVER['SERVER_NAME'].$this->_tonic->baseUrl.$_GET['owl-sameAs'];
else return false;
}
function get($requestData = NULL, $requestDataType = NULL)
{
require("erdft_parser.php");
$stringTemplates = new stringTemplates();
$this->_smarty->register_resource('string', array(&$stringTemplates,
'getTemplate',
'getTimestamp',
'getSecure',
'getTrusted'));
$resource =& Resource::find($this->_tonic, $this->getUrl());
$this->_smarty->assign_by_ref('this', $this);
$this->_smarty->assign_by_ref('resource', $this); // deprecated
$erdf = $resource->getBody();
$template = $this->getMetadata('template');
if ($template) {
$erdf = $this->_smarty->fetch($template, $this->_url, $this->_url);
} else {
$erdf = $this->_smarty->fetch('tonic:_body', $this->_url, $this->_url);
}
$eRdfT = new eRDFT($erdf); //this is the regex for sparql_vars
$data = $eRdfT->get_results();
//set Smarty variables
$this->_smarty->assign('errors', $eRdfT->errors);
$this->_smarty->assign('data', $data);
foreach($data as $k => $v) $this->_smarty->assign($k,$v);
$stringTemplates->template('erdft', $erdf);
$this->_smarty->display("string:erdft");
}
function post($requestData = NULL, $requestDataType = NULL)
{
parse_str(urldecode($requestData), $post); //makes $post the same as $_POST before tonic flattened it
if($post['rdf:RDF'])
{
$iri = 'http://'.$_SERVER['SERVER_NAME'].$this->getFullUrl();
$redir = $this->getMetadata('redirect_url');
$redirect_url = ($redir)? $redir : $this->getUrl();
$form_url = ($this->getMetadata('form_url'))? $this->getMetadata('form_url'): $this->_tonic->basePath.$this->getUrl();
//process POST by fetching the html form, getting the allowed input names, and passing them through functions named in the class parameters
require 'FormProcessor.class.php';
$formProcessor = new FormProcessor($post, $iri, $redirect_url);
$processed_POST = $this->_process_POST($form_url, &$post, &$formProcessor);
//convert data to rdf
$rdf = $this->_array2rdf(array('rdf:RDF' => $post['rdf:RDF']));
//save the data
if(empty($formProcessor->errors))
{
require 'ArcAdapter.php';
$store = new ArcAdapter('api/api_config.php');
if ($store->insert($formProcessor->iri, $rdf) )
{
$this->get();
}
else
{
die("couldn't save ".htmlentities( $rdf));
}
}
else
{
var_dump($formProcessor->errors);
$this->_smarty->assign('errors', $formProcessor->errors);
}
}
return get();
}
function _array2rdf($in)
{
$rdf='';
if(is_array($in))
{
foreach($in as $k => $v)
{
if(is_string($v))
{
if(substr($v,0,7)=='http://')
{
$rdf.= '<'.$k.' rdf:resource="'. $v.'"/>';
}
else
{
$rdf.= '<'.$k.'>'. $v .'</'.$k.'>';
}
}
else //$v is an array
{
$atts = array();
foreach(array_keys($v) as $ak)
{
if((strpos($ak,'xmlns') === 0 || strtolower($ak)== 'rdf:about') )
{
$atts[] = $ak.'="'.$v[$ak].'"';
unset($v[$ak]);
}
}
$space = (empty($atts))? '':' ';
if(strtolower($k) == 'rdf:li')
{
foreach($v as $li)
{
$vx = $this->_array2rdf($li);
$rdf.= '<'.$k.$space.implode(" \r\n",$atts).'>'. $vx .'</'.$k.'>';
}
}
else
{
$vx = $this->_array2rdf($v);
$rdf.= '<'.$k.$space.implode(" \r\n",$atts).'>'. $vx .'</'.$k.'>';
}
}
}
return $rdf;
}
else
{
return($in);
}
}
function _escape_array($arr = array())
{
$rs = array();
while(list($key,$val) = each($arr)) {
if(is_array($val))
{ $rs[$key] = $this->_escape_array($val); }
else
{ $rs[$key] = htmlspecialchars(utf8_encode($val)); }
}
return $rs;
}
function _process_POST($url, $post, &$formProcessor)
{
$simple = file_get_contents($url);
if(!$simple) $formProcessor->errors[]='Couldn\'t retrieve form page to parse.';
$p = xml_parser_create();
xml_parse_into_struct($p, $simple, $vals, $index);
xml_parser_free($p);
$previous_row_num = -2; //to get the previous row num
foreach($vals as $r)
{
$previous_row_num++;
if(isset($r['attributes']['NAME'])) //it's (probably) a form element
{
parse_str($r['attributes']['NAME'], $out);
$template_post_array = array_merge_recursive($template_post_array, $out);
preg_match_all('/([^\[\]]+)/', $r['attributes']['NAME'], $matches);
//this builds up a path to the assoc array element as a string - eg: 'rdf:Rdf[foaf:name]'
$path = '';
for($x = 0; $x < count($matches[1]); $x++)
{
$curr_key = $matches[1][$x];
$path.='["'.$curr_key.'"]';
}
if(isset($r['attributes']['CLASS'])) //now set the classnames string as the value of the name associative array
{
preg_match_all('/f_([a-zA-Z_0-9&]+)/', $r['attributes']['CLASS'], $m);
$functions = $m[1];
//get user value to be passed through functions
eval('$user_value = $post'.$path.';');
if(!empty($functions))
{
foreach($functions as $f)
{
//presumably calls the functions in the order they appear in the class string
$identifier = $vals[$previous_row_num]['value'];
$user_value = call_user_func(array(&$formProcessor, $f), $user_value, $identifier);
}
eval('$post'.$path.' = "'.$user_value.'";');
}
}
}
}
return $post;
}
}
class stringTemplates {
var $templates = array();
function getTemplate ($tplName, &$tplSource, &$smarty)
{
if(array_key_exists($tplName, $this->templates)) {
$tplSource = $this->templates[$tplName];
return TRUE;
}
return FALSE;
}
function getTimestamp($tplName, &$tplTimestamp, &$smarty)
{
if(array_key_exists($tplName, $this->templates)) {
$tplTimestamp = time();
return TRUE;
}
return FALSE;
}
function getSecure($tpl_name, &$smarty)
{
return TRUE;
}
function getTrusted($tpl_name, &$smarty)
{
}
function template($tplName, $tpl)
{
if(empty($tplName)) {
return FALSE;
}
$this->templates[$tplName] = $tpl;
}
}
?>
<?php
class FormProcessor
{
var $errors = array();
var $messages = array();
var $iri = '';
var $redirect_location = '';
var $post = array();
function FormProcessor(&$post, $iri = '', $redirect_location = '')
{
$this->post = $post;
$this->iri = $iri; //now the developer can change the iri of the rdf with the class methods
$this->redirect_location = $redirect_location; //and the redirect location once the form has been processed
}
function not_empty($val='', $parent_text)
{
if(strlen($val) < 1 )
{
$this->errors[] = $parent_text.' is empty.';
return false;
}
else
{
return $val;
}
}
function set_iri($val='', $parent_text)
{
$this->iri = $val;
}
}
?>