Location: PHPKode > scripts > Graphite > cgutteridge-Graphite-7124869/Graphite/Description.php
<?php
# A Graphite Description is an object to describe the routes of attributes
# which we wish to use to describe a specific resource, and to allow that
# to be nicely expressed in JSON.

class Graphite_Description
{
	var $graph;
	var $resource;
	var $routes = array();
	var $tree = array(
		"+" => array(),
		"-" => array() );
	# header, footer

	function __construct( $resource )
	{
		$this->graph = $resource->g;
		$this->resource = $resource;
	}

	function addRoute( $route )
	{
		$this->routes[$route] = true;
		$preds = preg_split( '/\//', $route );
		$treeptr = &$this->tree;
		foreach( $preds as $pred )
		{
			$dir = "+";
			if( substr($pred,0,1) == "-" ) { $pred = substr($pred,1); $dir = "-"; }
			if( !isset( $treeptr[$dir][$pred] ) )
			{
				$treeptr[$dir][$pred] = array( "+" => array(), "-" => array() );
			}
			$treeptr = &$treeptr[$dir][$pred];
		}
	}

	function toDebug()
	{
		$json = array();
		$this->_jsonify( $this->tree, $this->resource, $json );

		return print_r( $json, 1 );
	}

	function toJSON()
	{
		$json = array();
		$this->_jsonify( $this->tree, $this->resource, $json );

		return json_encode( $json );
	}

	function _jsonify( $tree, $resource, &$json )
	{
		foreach( $resource->relations() as $relation )
		{
			$code = $this->graph->shrinkURI( $relation );
			$jsonkey = $code;
			$dir = "+";
			if( $relation->nodeType() == "#inverseRelation" )
			{
				$dir = "-";
				$jsonkey = "$jsonkey of";
			}
			if( !isset($tree[$dir]["*"]) && !isset($tree[$dir][$code]) ) { continue; }

			foreach( $resource->all( $relation ) as $value )
			{
				if( is_a( $value, "Graphite_Literal" ) )
				{
					$json[$jsonkey][] = Graphite::asString($value);
				}
				else
				{
					$subjson = array();
					$uri = Graphite::asString($value);
					if( substr( $uri,0,2 ) != "_:" ) { $subjson["_uri"] = $uri; }
					if( isset( $tree[$dir][$code]) )
					{
						$this->_jsonify( $tree[$dir][$code], $value, $subjson );
					}
					if( isset( $tree[$dir]["*"]) )
					{
						$this->_jsonify( $tree[$dir]["*"], $value, $subjson );
					}
					$json[$jsonkey][] = $subjson;
				}
			}
		}
	}

	function toGraph()
	{
		$new_graph = new Graphite();
		$this->_tograph( $this->tree, $this->resource, $new_graph );
		return $new_graph;
	}

	function _tograph( $tree, $resource, &$new_graph )
	{
		foreach( $resource->relations() as $relation )
		{
			$code = $this->graph->shrinkURI( $relation );
			$dir = "+";
			if( $relation->nodeType() == "#inverseRelation" )
			{
				$dir = "-";
			}

			if( !isset($tree[$dir]["*"]) && !isset($tree[$dir][$code]) ) { continue; }

			foreach( $resource->all( $relation ) as $value )
			{
				if( is_a( $value, "Graphite_Literal" ) )
				{
					$datatype = $value->datatype();
					if( !isset($datatype) ) { $datatype='literal'; }
					$new_graph->addTriple(
						Graphite::asString($resource),
						Graphite::asString($relation),
						Graphite::asString($value),
						$datatype,
						$value->language() );
				}
				else
				{
					if( isset( $tree[$dir][$code]) )
					{
						$this->_tograph( $tree[$dir][$code], $value, $new_graph );
					}
					if( isset( $tree[$dir]["*"]) )
					{
						$this->_tograph( $tree[$dir]["*"], $value, $new_graph );
					}
					if( $dir == "+" )
					{
						$new_graph->addTriple(
							Graphite::asString($resource),
							Graphite::asString($relation),
							Graphite::asString($value) );
					}
					else
					{
						$new_graph->addTriple(
							Graphite::asString($value),
							Graphite::asString($relation),
							Graphite::asString($resource) );
					}
				}
			}
		}
	}

	function loadSPARQL( $endpoint, $debug = false )
	{
		$bits = $this->_toSPARQL( $this->tree, "", null, "" );
		$n = 0;
		foreach( $bits as $bit )
		{
			$sparql = "CONSTRUCT { ".$bit['construct']." } WHERE { ".$bit['where']." }";
			if( $debug || @$_GET["_graphite_debug"] ) {
				 print "<div style='padding: 1em'><tt>\n\n".htmlspecialchars($sparql)."</tt></div>\n\n";
			}
			$n+=$this->graph->loadSPARQL( $endpoint, $sparql );
		}
		return $n;
	}

	function _toSPARQL($tree, $suffix, $in_dangler = null, $sparqlprefix = "" )
	{
		$bits = array();
		if( !isset( $in_dangler ) )
		{
			$in_dangler = "<".Graphite::asString($this->resource).">";
		}

		$i = 0;
		foreach( $tree as $dir=>$routes )
		{
			if( sizeof($routes) == 0 ) { continue; }

			$pres = array();
			if( isset($routes["*"]) )
			{
				$sub = "?s".$suffix."_".$i;
				$pre = "?p".$suffix."_".$i;
				$obj = "?o".$suffix."_".$i;

				if( $dir == "+" )
				{
					$out_dangler = $obj;
					$sub = $in_dangler;
				}
				else # inverse
				{
					$out_dangler = $sub;
					$obj = $in_dangler;
				}

				$construct = "$sub $pre $obj . ";
				$where = "$sparqlprefix $sub $pre $obj .";
				if( isset( $routes["*"] ) )
				{
					$bits_from_routes = $this->_toSPARQL( $routes["*"], $suffix."_".$i, $out_dangler, "" );
					$i++;
					foreach( $bits_from_routes as $bit )
					{
						$construct .= $bit["construct"];
						$where .= " OPTIONAL { ".$bit["where"]." }";
					}
				}
				$bits []= array( "where"=>$where, "construct"=>$construct );

				foreach( $routes as $pred=>$route )
				{
					if( $pred == "*" ) { continue; }

					$pre = "<".$this->graph->expandURI( $pred ).">";

					$bits_from_routes = $this->_toSPARQL( $route, $suffix."_".$i, $out_dangler, "$sparqlprefix $sub $pre $obj ." );
					$i++;
					foreach( $bits_from_routes as $bit )
					{
						$bits []= $bit;
					}
				}
			}
			else
			{
				foreach( array_keys( $routes ) as $pred )
				{
					$sub = "?s".$suffix."_".$i;
					$pre = "<".$this->graph->expandURI( $pred ).">";
					$obj = "?o".$suffix."_".$i;

					if( $dir == "+" )
					{
						$out_dangler = $obj;
						$sub = $in_dangler;
					}
					else # inverse
					{
						$out_dangler = $sub;
						$obj = $in_dangler;
					}

					$bits_from_routes = $this->_toSPARQL( $routes[$pred],$suffix."_".$i, $out_dangler, "" );
					$i++;

					$construct = "$sub $pre $obj . ";
					$where = "$sparqlprefix $sub $pre $obj .";
					foreach( $bits_from_routes as $bit )
					{
						$construct .= $bit["construct"];
						$where .= " OPTIONAL { ".$bit["where"]." }";
					}

					$bits []= array( "where"=>$where, "construct"=>$construct );
				}
			}
		}

		return $bits;
	} # end _toSPARQL

	function getFormats()
	{
		return array(
			"json"=>"JSON",
			"nt"=>"RDF (Triples)",
			"ttl"=>"RDF (Turtle)",
			"rdf"=>"RDF (XML)",
			"rdf.html" => "RDF (RDF HTML Debug)",
		);
	}

	function handleFormat( $format )
	{
		if( $format == 'json' )
		{
			if( isset( $_GET['callback'] ) )
			{
				header( "Content-type: application/javascript" );
				print $_GET['callback']."( ".$this->toJSON()." );\n";
			}
			else
			{
				header( "Content-type: application/json" );
				print $this->toJSON();
			}

			return true;
		}

		if( $format == 'ttl' )
		{
			header( "Content-type: text/turtle" );
			print $this->toGraph()->serialize( "Turtle" );
			return true;
		}

		if( $format == 'nt' )
		{
			header( "Content-type: text/plain" );
			print $this->toGraph()->serialize( "NTriples" );
			return true;
		}

		if( $format == 'rdf' )
		{
			header( "Content-type: application/rdf+xml" );
			print $this->toGraph()->serialize( "RDFXML" );
			return true;
		}

		if( $format == 'rdf.html' )
		{
			header( "Content-type: text/html" );
			print $this->toGraph()->dump();
			return true;
		}

		if( $format == 'debug' )
		{
			header( "Content-type: text/plain" );
			print $this->toDebug();
			return true;
		}

		return false;
	}
}
Return current item: Graphite