2 # (c)2010 Christopher Gutteridge / University of Southampton
3 # some extra features and bugfixes by Bart Nagel
7 # Requires ARC2 to be included.
8 # suggested call method:
9 # include_once("arc/ARC2.php");
10 # include_once("Graphite.php");
13 # EasyRDF - http://code.google.com/p/easyrdf/
14 # SimpleGraph - http://code.google.com/p/moriarty/wiki/SimpleGraph
16 # I've used function calls in common with EasyRDF, where it makes sense
17 # to do so. Easy RDF now uses our dump() style. We're one big happy linked
21 # hasRelationValue, hasRelation, filter, loadString,
25 # added sioc: (needs to be documented in the parent of graphite-docs.html),
26 # addTriples, addTriple, loadSPARQL
31 public function __construct( $namespaces = array(), $uri = null )
33 $this->t = array( "sp" => array(), "op"=>array() );
34 foreach( $namespaces as $short=>$long )
36 $this->ns( $short, $long );
38 $this->ns( "foaf", "http://xmlns.com/foaf/0.1/" );
39 $this->ns( "dc", "http://purl.org/dc/elements/1.1/" );
40 $this->ns( "dct", "http://purl.org/dc/terms/" );
41 $this->ns( "rdf", "http://www.w3.org/1999/02/22-rdf-syntax-ns#" );
42 $this->ns( "rdfs", "http://www.w3.org/2000/01/rdf-schema#" );
43 $this->ns( "owl", "http://www.w3.org/2002/07/owl#" );
44 $this->ns( "xsd", "http://www.w3.org/2001/XMLSchema#" );
45 $this->ns( "cc", "http://creativecommons.org/ns#" );
46 $this->ns( "bibo", "http://purl.org/ontology/bibo/" );
47 $this->ns( "skos", "http://www.w3.org/2004/02/skos/core#" );
48 $this->ns( "geo", "http://www.w3.org/2003/01/geo/wgs84_pos#" );
49 $this->ns( "sioc", "http://rdfs.org/sioc/ns#" );
50 $this->ns( "oo", "http://purl.org/openorg/" );
52 $this->loaded = array();
55 $this->firstGraphURI = null;
58 $this->forceString( $uri );
62 $this->bnodeprefix = 0;
65 public function cacheDir( $dir, $age = 86400 ) # default age is 24 hours
68 if( !file_exists( $dir ) ) { $error = "No such directory: $dir"; }
69 elseif( !is_dir( $dir ) ) { $error = "Not a directory: $dir"; }
70 elseif( !is_writable( $dir ) ) { $error = "Not writable: $dir"; }
72 print "<ul><li>Graphite cacheDir error: $error</li></ul>";
76 $this->cacheDir = $dir;
77 $this->cacheAge = $age;
81 public function setDebug( $boolean ) { $this->debug = $boolean; }
83 function removeFragment( $uri )
85 return preg_replace( "/#.*/", "", $uri );
88 function loaded( $uri )
90 if( !array_key_exists( $this->removeFragment( $uri ), $this->loaded ) )
94 return $this->loaded[$this->removeFragment( $uri )];
97 public function load( $uri, $aliases = array(), $map = array() )
99 $this->forceString( $uri );
100 $uri = $this->expandURI( $uri );
102 if( substr( $uri,0,5 ) == "data:" )
104 $data = urldecode( preg_replace( "/^data:[^,]*,/","", $uri ) );
105 $parser = ARC2::getTurtleParser();
106 $parser->parse( $uri, $data );
110 if( $this->loaded( $uri ) !== false ) { return $this->loaded( $uri ); }
111 if( isset($this->cacheDir) )
113 $filename = $this->cacheDir."/".md5( $this->removeFragment( $uri ) );
115 if( !file_exists( $filename ) || filemtime($filename)+$this->cacheAge < time() )
117 # decache if out of date, even if we fail to re cache.
118 if( file_exists( $filename ) ) { unlink( $filename ); }
122 $old_user_agent = ini_get('user_agent');
123 ini_set('user_agent', "PHP\r\nAccept: application/rdf+xml");
127 # dirty hack to set the accept header without using curl
128 if( !$rdf_fp = fopen($url, 'r') ) { break; }
129 $meta_data = stream_get_meta_data($rdf_fp);
131 if( @!$meta_data['wrapper_data'] )
136 foreach($meta_data['wrapper_data'] as $response)
138 if (substr(strtolower($response), 0, 10) == 'location: ')
140 $newurl = substr($response, 10);
141 if( substr( $newurl, 0, 1 ) == "/" )
143 $parts = preg_split( "/\//",$url );
144 $newurl = $parts[0]."//".$parts[2].$newurl;
149 if (substr(strtolower($response), 0, 14) == 'content-type: ')
151 $mime = preg_replace( "/\s*;.*$/","", substr($response, 14));
154 if( !$redir ) { break; }
156 ini_set('user_agent', $old_user_agent);
157 if( $ttl > 0 && $mime == "application/rdf+xml" && $rdf_fp )
159 # candidate for caching!
160 if (!$cache_fp = fopen($filename, 'w'))
162 echo "Cannot write file ($filename)";
166 while (!feof($rdf_fp)) {
167 fwrite( $cache_fp, fread($rdf_fp, 8192) );
175 if( isset( $filename ) && file_exists( $filename ) )
177 $parser = ARC2::getRDFXMLParser();
178 $parser->parse( $uri, file_get_contents($filename) );
182 $parser = ARC2::getRDFParser();
183 # Don't try to load the same URI twice!
185 if( !isset( $this->firstGraphURI ) )
187 $this->firstGraphURI = $uri;
189 $parser->parse( $uri );
193 $errors = $parser->getErrors();
194 $parser->resetErrors();
195 if( sizeof($errors) )
199 print "<h3>Error loading: $uri</h3>";
200 print "<ul><li>".join( "</li><li>",$errors)."</li></ul>";
204 $this->loaded[$this->removeFragment( $uri )] = $this->addTriples( $parser->getTriples(), $aliases, $map );
205 return $this->loaded( $uri );
208 function loadSPARQL( $endpoint, $query )
210 return $this->load( $endpoint."?query=".urlencode($query) );
213 function addTurtle( $base, $data )
215 $parser = ARC2::getTurtleParser();
216 $parser->parse( $base, $data );
217 $errors = $parser->getErrors();
218 $parser->resetErrors();
219 if( sizeof($errors) )
223 print "<h3>Error loading turtle string</h3>";
224 print "<ul><li>".join( "</li><li>",$errors)."</li></ul>";
228 return $this->addTriples( $parser->getTriples() );
230 function addRDFXML( $base, $data )
232 $parser = ARC2::getRDFXMLParser();
233 $parser->parse( $base, $data );
234 $errors = $parser->getErrors();
235 $parser->resetErrors();
236 if( sizeof($errors) )
240 print "<h3>Error loading RDFXML string</h3>";
241 print "<ul><li>".join( "</li><li>",$errors)."</li></ul>";
245 return $this->addTriples( $parser->getTriples() );
248 function addBnodePrefix( $uri ) {
249 return preg_replace( "/^_:/", "_:g" . $this->bnodeprefix . "-", $uri );
252 function addTriples( $triples, $aliases = array(), $map = array() )
254 $this->bnodeprefix++;
256 foreach( $triples as $t )
258 $t["s"] = $this->addBnodePrefix( $this->cleanURI($t["s"]) );
259 if( !isset($map[$t["s"]]) ) { continue; }
260 $t["p"] = $this->cleanURI($t["p"]);
261 if( $t["p"] != "http://www.w3.org/2002/07/owl#sameAs" ) { continue; }
262 $aliases[$this->addBnodePrefix( $t["o"] )] = $t["s"];
264 foreach( $triples as $t )
266 $datatype = $t["o_datatype"];
267 if( $t["o_type"] == "literal" && !$datatype ) { $datatype = "literal"; }
268 $this->addTriple( $t["s"], $t["p"], $t["o"], $datatype, $t["o_lang"], $aliases );
270 return sizeof( $triples );
273 function addTriple( $s,$p,$o,$o_datatype=null,$o_lang=null,$aliases=array() )
275 $s = $this->addBnodePrefix( $this->cleanURI( $s ) );
276 if( $o_datatype != "literal" )
278 $o = $this->addBnodePrefix( $this->cleanURI( $o ) );
281 if( isset($aliases[$s]) ) { $s=$aliases[$s]; }
282 if( isset($aliases[$p]) ) { $p=$aliases[$p]; }
283 if( isset($aliases[$o]) ) { $o=$aliases[$o]; }
285 if( isset( $o_datatype ) && $o_datatype )
287 if( $o_datatype == 'literal' ) { $o_datatype = null; }
288 $this->t["sp"][$s][$p][] = array(
295 $this->t["sp"][$s][$p][] = $o;
297 $this->t["op"][$o][$p][] = $s;
300 public function toArcTriples()
302 $arcTriples = array();
303 foreach( $this->allSubjects() as $s )
305 $arcTriples = array_merge( $arcTriples, $s->toArcTriples( false ) );
310 public function serialize( $type = "RDFXML" )
312 $serializer = ARC2::getSer( $type, array( "ns" => $this->ns ) );
313 return $serializer->getSerializedTriples( $this->toArcTriples() );
316 public function cleanURI( $uri )
318 if( !$uri ) { return; }
319 return preg_replace( '/^(https?:\/\/[^:\/]+):80\//','$1/', $uri );
322 public function primaryTopic( $uri = null )
324 if( !$uri ) { $uri = $this->firstGraphURI; }
325 if( !$uri ) { return new Graphite_Null($this->g); }
326 $this->forceString( $uri );
328 return $this->resource( $uri )->get( "foaf:primaryTopic", "-foaf:isPrimaryTopicOf" );
331 public function ns( $short, $long )
333 if( preg_match( '/^(urn|doi|http|https|ftp|mailto|xmlns|file|data)$/', $short ) )
335 print "<ul><li>Setting a namespace called '$short' is just asking for trouble. Abort.</li></ul>";
338 $this->ns[$short] = $long;
341 public function resource( $uri )
343 $this->forceString( $uri );
344 $uri = $this->expandURI( $uri );
345 return new Graphite_Resource( $this, $uri );
348 public function allOfType( $uri )
350 return $this->resource( $uri )->all("-rdf:type");
353 public function shrinkURI( $uri )
355 $this->forceString( $uri );
356 if( $uri == "" ) { return "* This Document *"; }
357 foreach( $this->ns as $short=>$long )
359 if( substr( $uri, 0, strlen($long) ) == $long )
361 return $short.":".substr( $uri, strlen($long ));
367 public function expandURI( $uri )
369 $this->forceString( $uri );
370 if( preg_match( '/:/', $uri ) )
372 list( $ns, $tag ) = preg_split( "/:/", $uri, 2 );
373 if( isset($this->ns[$ns]) )
375 return $this->ns[$ns].$tag;
382 public function allSubjects()
384 $r = new Graphite_ResourceList( $this );
385 foreach( $this->t["sp"] as $subject_uri=>$foo )
387 $r[] = new Graphite_Resource( $this, $subject_uri );
392 public function allObjects()
394 $r = new Graphite_ResourceList( $this );
395 foreach( $this->t["op"] as $object_uri=>$foo )
397 $r[] = new Graphite_Resource( $this, $object_uri );
402 public function dump($options=array())
405 foreach( $this->t["sp"] as $subject_uri=>$foo )
407 $subject = new Graphite_Resource( $this, $subject_uri );
408 $r []= $subject->dump($options);
413 public function forceString( &$uri )
415 if( is_object( $uri ) ) { $uri = $uri->toString(); }
422 function __construct( $g )
426 function isNull() { return false; }
427 function has() { return false; }
428 function get() { return new Graphite_Null($this->g); }
429 function type() { return new Graphite_Null($this->g); }
430 function label() { return "[UNKNOWN]"; }
431 function hasLabel() { return false; }
432 function all() { return new Graphite_ResourceList($this->g, array()); }
433 function types() { return $this->all(); }
434 function relations() { return $this->all(); }
435 function load() { return 0; }
436 function loadSameAs() { return 0; }
437 function loadSameAsOrg($prefix) { return 0; }
438 function loadDataGovUKBackLinks() { return 0; }
440 function dumpText() { return "Non existant Node"; }
441 function dump() { return "<div style='padding:0.5em; background-color:lightgrey;border:dashed 1px grey;'>Non-existant Node</div>"; }
442 function nodeType() { return "#node"; }
443 function __toString() { return "[NULL]"; }
444 function toString() { return $this->__toString(); }
446 protected function parsePropertyArg( $arg )
448 if( is_a( $arg, "Graphite_Resource" ) )
450 if( is_a( $arg, "Graphite_InverseRelation" ) )
452 $this->g->forceString( $arg );
453 return array( "op", "$arg" );
455 $this->g->forceString( $arg );
456 return array( "sp", "$arg" );
460 if( substr( $arg,0,1) == "-" )
463 $arg = substr($arg,1);
465 return array( $set, $this->g->expandURI( "$arg" ) );
468 class Graphite_Null extends Graphite_Node
470 function nodeType() { return "#null"; }
471 function isNull() { return true; }
473 class Graphite_Literal extends Graphite_Node
475 function __construct( $g, $triple )
478 $this->triple = $triple;
479 $this->v = $triple["v"];
482 function __toString() { return $this->triple["v"]; }
484 function dumpValueText()
487 if( isset($this->triple["l"]) && $this->triple["l"])
489 $r.="@".$this->triple["l"];
491 if( isset($this->triple["d"]) )
493 $r.="^^".$this->g->shrinkURI($this->triple["d"]);
498 function dumpValueHTML()
500 $v = htmlspecialchars( $this->triple["v"],ENT_COMPAT,"UTF-8" );
502 $v = preg_replace( "/\t/", "<span class='special_char' style='font-size:70%'>[tab]</span>", $v );
503 $v = preg_replace( "/\n/", "<span class='special_char' style='font-size:70%'>[nl]</span><br />", $v );
504 $v = preg_replace( "/\r/", "<span class='special_char' style='font-size:70%'>[cr]</span>", $v );
505 $v = preg_replace( "/ +/e", "\"<span class='special_char' style='font-size:70%'>\".str_repeat(\"␣\",strlen(\"$0\")).\"</span>\"", $v );
508 if( isset($this->triple["l"]) && $this->triple["l"])
510 $r.="@".$this->triple["l"];
512 if( isset($this->triple["d"]) )
514 $r.="^^".$this->g->shrinkURI($this->triple["d"]);
521 if( isset($this->triple["d"]) )
523 return $this->triple["d"];
530 return "<span style='color:blue'>".$this->dumpValueHTML()."</span>";
534 class Graphite_Resource extends Graphite_Node
536 function __construct( $g, $uri )
539 $this->g->forceString( $uri );
543 public function get( /* List */ )
545 $args = func_get_args();
546 if( $args[0] instanceof Graphite_ResourceList ) { $args = $args[0]; }
547 if( is_array( $args[0] ) ) { $args = func_get_arg( 0 ); }
549 $l = $this->all( $args );
550 if( sizeof( $l ) == 0 ) { return new Graphite_Null($this->g); }
554 public function getString( /* List */ )
556 $args = func_get_args();
557 if( $args[0] instanceof Graphite_ResourceList ) { $args = $args[0]; }
558 if( is_array( $args[0] ) ) { $args = func_get_arg( 0 ); }
560 $l = $this->all( $args );
561 if( sizeof( $l ) == 0 ) { return; }
562 return $l[0]->toString();
565 public function allString( /* List */ )
567 $args = func_get_args();
568 if( $args[0] instanceof Graphite_ResourceList ) { $args = $args[0]; }
569 if( is_array( $args[0] ) ) { $args = func_get_arg( 0 ); }
572 foreach( $this->all( $args ) as $item )
574 $l []= $item->toString();
576 return new Graphite_ResourceList($this->g,$l);
579 public function has( /* List */ )
581 $args = func_get_args();
582 if( $args[0] instanceof Graphite_ResourceList ) { $args = $args[0]; }
583 if( is_array( $args[0] ) ) { $args = func_get_arg( 0 ); }
585 foreach( $args as $arg )
587 list( $set, $relation_uri ) = $this->parsePropertyArg( $arg );
588 if( isset($this->g->t[$set][$this->uri])
589 && isset($this->g->t[$set][$this->uri][$relation_uri]) )
597 public function all( /* List */ )
599 $args = func_get_args();
600 if( $args[0] instanceof Graphite_ResourceList ) { $args = $args[0]; }
601 if( is_array( $args[0] ) ) { $args = func_get_arg( 0 ); }
604 foreach( $args as $arg )
606 list( $set, $relation_uri ) = $this->parsePropertyArg( $arg );
607 if( !isset($this->g->t[$set][$this->uri])
608 || !isset($this->g->t[$set][$this->uri][$relation_uri]) )
613 foreach( $this->g->t[$set][$this->uri][$relation_uri] as $v )
617 $l []= new Graphite_Literal( $this->g, $v );
619 else if( !isset($done[$v]) )
621 $l []= new Graphite_Resource( $this->g, $v );
626 return new Graphite_ResourceList($this->g,$l);
629 public function relations()
632 if( isset( $this->g->t["sp"][$this->uri] ) )
634 foreach( array_keys( $this->g->t["sp"][$this->uri] ) as $pred )
636 $r []= new Graphite_Relation( $this->g, $pred );
639 if( isset( $this->g->t["op"][$this->uri] ) )
641 foreach( array_keys( $this->g->t["op"][$this->uri] ) as $pred )
643 $r []= new Graphite_InverseRelation( $this->g, $pred );
647 return new Graphite_ResourceList($this->g,$r);
650 public function toArcTriples( $bnodes = true )
652 $arcTriples = array();
653 $bnodes_to_add = array();
657 if( preg_match( '/^_:/', $s ) )
662 foreach( $this->g->t["sp"][$s] as $p => $os )
664 $p = $this->g->expandURI( $p );
666 if( preg_match( '/^_:/', $p ) )
678 if( isset( $o["l"] ) && $o["l"] )
682 if( isset( $o["d"] ) )
684 $o_datatype = $this->g->expandURI( $o["d"] );
690 $o = $this->g->expandURI( $o );
692 if( preg_match( '/^_:/', $o ) )
695 $bnodes_to_add[] = $o;
706 $triple["o_datatype"] = $o_datatype;
707 $triple["o_lang"] = $o_lang;
709 $arcTriples[] = $triple;
715 foreach( array_unique( $bnodes_to_add ) as $bnode )
717 $arcTriples = array_merge( $arcTriples, $this->g->resource( $bnode )->toArcTriples() );
723 public function serialize( $type = "RDFXML" )
725 $serializer = ARC2::getSer( $type, array( "ns" => $this->g->ns ) );
726 return $serializer->getSerializedTriples( $this->toArcTriples() );
729 public function load()
731 return $this->g->load( $this->uri );
734 public function loadSameAsOrg( $prefix )
736 $sameasorg_uri = "http://sameas.org/rdf?uri=".urlencode( $this->uri );
737 $n = $this->g->load( $sameasorg_uri );
738 $n+= $this->loadSameAs( $prefix );
742 function loadDataGovUKBackLinks()
744 $backurl = "http://backlinks.psi.enakting.org/resource/rdf/".$this->uri;
745 return $this->g->load( $backurl, array(), array( $this->uri=>1 ) );
748 public function loadSameAs( $prefix=null )
751 foreach( $this->all( "owl:sameAs" ) as $sameas )
753 $this->g->forceString( $sameas );
754 if( $prefix && substr( $sameas, 0, strlen($prefix )) != $prefix )
759 $cnt += $this->g->load( $sameas, array( $sameas=>$this->uri ) );
764 public function type()
766 return $this->get( "rdf:type" );
769 public function types()
771 return $this->all( "rdf:type" );
774 public function isType( /* List */ )
776 $args = func_get_args();
777 if( $args[0] instanceof Graphite_ResourceList ) { $args = $args[0]; }
778 if( is_array( $args[0] ) ) { $args = func_get_arg( 0 ); }
780 foreach( $this->allString( 'rdf:type' ) as $type )
782 foreach( $args as $arg )
784 $uri = $this->g->expandURI( $arg );
785 if( $uri == $type ) { return true; }
792 public function hasLabel()
794 return $this->has( "skos:prefLabel", "rdfs:label", "foaf:name", "dct:title", "dc:title", "sioc:name" );
796 public function label()
798 return $this->get( "skos:prefLabel", "rdfs:label", "foaf:name", "dct:title", "dc:title", "sioc:name" )->toString();
801 public function link()
803 return "<a title='".$this->uri."' href='".$this->uri."'>".$this->uri."</a>";
806 public function dumpText()
810 foreach( $this->relations() as $prop )
813 foreach( $this->all( $prop ) as $obj )
815 $olist []= $obj->dumpValueText();
817 $plist []= $this->g->shrinkURI($prop)." ".join( ", ",$olist );
819 return $this->g->shrinkURI($this->uri)."\n ".join( ";\n ", $plist )." .\n";
822 public function dump( $options = array() )
826 foreach( $this->relations() as $prop )
829 $all = $this->all( $prop );
830 foreach( $all as $obj )
832 $olist []= $obj->dumpValue($options);
834 if( is_a( $prop, "Graphite_InverseRelation" ) )
836 $pattern = "<span style='font-size:130%%'>←</span> is <a title='%s' href='%s' style='text-decoration:none;color: green'>%s</a> of <span style='font-size:130%%'>←</span> %s";
840 $pattern = "<span style='font-size:130%%'>→</span> <a title='%s' href='%s' style='text-decoration:none;color: green'>%s</a> <span style='font-size:130%%'>→</span> %s";
842 $this->g->forceString( $prop );
843 $plist []= sprintf( $pattern, $prop, $prop, $this->g->shrinkURI($prop), join( ", ",$olist ));
845 $r.= "\n<a name='".htmlentities($this->uri)."'></a><div style='text-align:left;font-family: arial;padding:0.5em; background-color:lightgrey;border:dashed 1px grey;margin-bottom:2px;'>\n";
846 if( isset($options["label"] ) )
848 $label = $this->label();
849 if( $label == "[NULL]" ) { $label = ""; } else { $label = "<strong>$label</strong>"; }
850 if( $this->has( "rdf:type" ) )
852 if( $this->get( "rdf:type" )->hasLabel() )
854 $typename = $this->get( "rdf:type" )->label();
858 $bits = preg_split( "/[\/#]/", @$this->get( "rdf:type" )->uri );
859 $typename = array_pop( $bits );
860 $typename = preg_replace( "/([a-z])([A-Z])/","$1 $2",$typename );
862 $r .= preg_replace( "/>a ([AEIOU])/i", ">an $1", "<div style='float:right'>a $typename</div>" );
864 if( $label != "" ) { $r.="<div>$label</div>"; }
866 $r.= " <!-- DUMP:".$this->uri." -->\n <div><a title='".$this->uri."' href='".$this->uri."' style='text-decoration:none'>".$this->g->shrinkURI($this->uri)."</a></div>\n";
867 $r.=" <div style='padding-left: 3em'>\n <div>".join( "</div>\n <div>", $plist )."</div></div><div style='clear:both;height:1px; overflow:hidden'> </div></div>";
871 function __toString() { return $this->uri; }
872 function dumpValue($options=array())
874 $label = $this->dumpValueText();
875 if( $this->hasLabel() && @$options["labeluris"] )
877 $label = $this->label();
880 if( @$options["internallinks"] )
882 $href = "#".htmlentities($this->uri);
884 return "<a href='".$href."' title='".$this->uri."' style='text-decoration:none;color:red'>".$label."</a>";
886 function dumpValueText() { return $this->g->shrinkURI( $this->uri ); }
887 function nodeType() { return "#resource"; }
890 class Graphite_Relation extends Graphite_Resource
892 function nodeType() { return "#relation"; }
895 class Graphite_InverseRelation extends Graphite_Relation
897 function nodeType() { return "#inverseRelation"; }
899 class Graphite_ResourceList extends ArrayIterator
901 function __construct( $g, $a=array() )
905 if( $a instanceof Graphite_ResourceList )
907 print "<li>Graphite warning: passing a Graphite_ResourceList as the array passed to new Graphite_ResourceList will make weird stuff happen.</li>";
909 parent::__construct( $this->arr );
913 function join( $str )
917 foreach( $this as $resource )
919 if( !$first ) { $l []= $str; }
920 $this->g->forceString( $resource );
924 return join( "", $l );
930 foreach( $this as $resource )
932 $l [] = $resource->dump();
934 return join( "", $l );
937 public function duplicate()
940 foreach( $this as $resource ) { $l []= $resource; }
941 return new Graphite_ResourceList($this->g,$l);
944 public function sort( /* List */ )
946 $args = func_get_args();
947 if( $args[0] instanceof Graphite_ResourceList ) { $args = $args[0]; }
948 if( is_array( $args[0] ) ) { $args = func_get_arg( 0 ); }
950 global $graphite_sort_args;
951 $graphite_sort_args = array();
952 foreach( $args as $arg )
954 if( $arg instanceof Graphite_Resource ) { $arg = $arg->toString(); }
955 $graphite_sort_args [] = $arg;
958 $new_list = $this->duplicate();
959 usort($new_list->arr, "graphite_sort_list_cmp" );
964 public function uasort( $cmp )
966 usort($this->arr, $cmp );
969 public function get( /* List */ )
971 $args = func_get_args();
972 if( $args[0] instanceof Graphite_ResourceList ) { $args = $args[0]; }
973 if( is_array( $args[0] ) ) { $args = func_get_arg( 0 ); }
975 foreach( $this as $resource )
977 $l [] = $resource->get( $args );
979 return new Graphite_ResourceList($this->g,$l);
982 public function getString( /* List */ )
984 $args = func_get_args();
985 if( $args[0] instanceof Graphite_ResourceList ) { $args = $args[0]; }
986 if( is_array( $args[0] ) ) { $args = func_get_arg( 0 ); }
988 foreach( $this as $resource )
990 $l [] = $resource->getString( $args );
992 return new Graphite_ResourceList($this->g,$l);
995 public function label()
998 foreach( $this as $resource )
1000 $l [] = $resource->label();
1002 return new Graphite_ResourceList($this->g,$l);
1005 public function load()
1008 foreach( $this as $resource )
1010 $n += $resource->load();
1015 public function allString( /* List */ )
1017 $args = func_get_args();
1018 if( $args[0] instanceof Graphite_ResourceList ) { $args = $args[0]; }
1019 if( is_array( $args[0] ) ) { $args = func_get_arg( 0 ); }
1022 foreach( $this as $resource )
1024 $all = $resource->all( $args );
1025 foreach( $all as $to_add )
1027 if( isset($done[$to_add->toString()]) ) { continue; }
1028 $l []= $to_add->toString();
1029 $done[$to_add->toString()] = 1;
1032 return new Graphite_ResourceList($this->g,$l);
1035 public function all( /* List */ )
1037 $args = func_get_args();
1038 if( $args[0] instanceof Graphite_ResourceList ) { $args = $args[0]; }
1039 if( is_array( $args[0] ) ) { $args = func_get_arg( 0 ); }
1042 foreach( $this as $resource )
1044 $all = $resource->all( $args );
1045 foreach( $all as $to_add )
1047 if( isset($done[$to_add->toString()]) ) { continue; }
1049 $done[$to_add->toString()] = 1;
1052 return new Graphite_ResourceList($this->g,$l);
1055 function append( $x /* List */ )
1057 $args = func_get_args();
1058 if( $args[0] instanceof Graphite_ResourceList ) { $args = $args[0]; }
1059 if( is_array( $args[0] ) ) { $args = func_get_arg( 0 ); }
1061 $list = $this->duplicate();
1062 foreach( $args as $arg )
1064 if( ! $arg instanceof Graphite_Resource ) { $arg = $this->g->resource( $arg ); }
1074 foreach( $this as $resource )
1076 if( isset( $done[$resource->toString()] ) ) { continue; }
1078 $done[$resource->toString()]=1;
1080 return new Graphite_ResourceList($this->g,$l);
1083 function union( /* List */ )
1085 $args = func_get_args();
1086 if( $args[0] instanceof Graphite_ResourceList ) { $args = $args[0]; }
1087 if( is_array( $args[0] ) ) { $args = func_get_arg( 0 ); }
1089 $list = new Graphite_ResourceList($this->g);
1091 foreach( $this as $resource )
1093 if( isset( $done[$resource->toString()] ) ) { continue; }
1094 $list [] = $resource;
1095 $done[$resource->toString()]=1;
1097 foreach( $args as $arg )
1099 if( ! $arg instanceof Graphite_Resource ) { $arg = $this->g->resource( $arg ); }
1100 if( isset( $done[$arg->toString()] ) ) { continue; }
1102 $done[$arg->toString()]=1;
1107 function intersection( /* List */ )
1109 $args = func_get_args();
1110 if( $args[0] instanceof Graphite_ResourceList ) { $args = $args[0]; }
1111 if( is_array( $args[0] ) ) { $args = func_get_arg( 0 ); }
1113 $list = new Graphite_ResourceList($this->g,array());
1115 foreach( $this as $arg )
1117 if( ! $arg instanceof Graphite_Resource ) { $arg = $this->g->resource( $arg ); }
1118 $seen[$arg->toString()]=1;
1120 foreach( $args as $arg )
1122 if( ! $arg instanceof Graphite_Resource ) { $arg = $this->g->resource( $arg ); }
1123 if( ! isset($seen[$arg->toString()]) ) { continue; }
1129 function except( /* List */ )
1131 $args = func_get_args();
1132 if( $args[0] instanceof Graphite_ResourceList ) { $args = $args[0]; }
1133 if( is_array( $args[0] ) ) { $args = func_get_arg( 0 ); }
1135 $list = new Graphite_ResourceList($this->g,array());
1137 foreach( $args as $arg )
1139 if( ! $arg instanceof Graphite_Resource ) { $arg = $this->g->resource( $arg ); }
1140 $exclude[$arg->toString()]=1;
1142 foreach( $this as $arg )
1144 if( ! $arg instanceof Graphite_Resource ) { $arg = $this->g->resource( $arg ); }
1145 if( isset($exclude[$arg->toString()]) ) { continue; }
1151 function allOfType( $uri )
1153 $list = new Graphite_ResourceList( $this->g, array() );
1154 foreach( $this as $item )
1156 if( $item->isType( $uri ) )
1165 function graphite_sort_list_cmp( $a, $b )
1167 global $graphite_sort_args;
1169 foreach( $graphite_sort_args as $arg )
1171 $va = $a->get( $arg );
1172 $vb = $b->get( $arg );
1173 if($va < $vb) return -1;
1174 if($va > $vb) return 1;