PageRenderTime 53ms CodeModel.GetById 25ms RepoModel.GetById 0ms app.codeStats 0ms

/institutions/european-election-results/lib/moriarty/graph.class.php

https://github.com/LATC/EU-data-cloud
PHP | 381 lines | 184 code | 41 blank | 156 comment | 36 complexity | 31f42a7cf7c7e91b89c22759a59c21e6 MD5 | raw file
  1. <?php
  2. require_once dirname(__FILE__) . DIRECTORY_SEPARATOR . 'moriarty.inc.php';
  3. require_once MORIARTY_ARC_DIR . "ARC2.php";
  4. require_once MORIARTY_DIR . 'httprequest.class.php';
  5. require_once MORIARTY_DIR . 'httprequestfactory.class.php';
  6. require_once MORIARTY_DIR . 'simplegraph.class.php';
  7. require_once MORIARTY_DIR . 'changeset.class.php';
  8. /**
  9. * The base class for graphs in a store.
  10. */
  11. class Graph {
  12. /**
  13. * @access private
  14. */
  15. var $uri;
  16. /**
  17. * @access private
  18. */
  19. var $credentials;
  20. /**
  21. * @access private
  22. */
  23. var $request_factory;
  24. /**
  25. * Create a new instance of this class
  26. * @param string uri URI of the graph
  27. * @param Credentials credentials the credentials to use for authenticated requests (optional)
  28. */
  29. function __construct($uri, $credentials = null, $request_factory = null) {
  30. $this->uri = $uri;
  31. $this->credentials = $credentials;
  32. $this->request_factory = $request_factory;
  33. }
  34. /**
  35. * Apply a changeset to the graph
  36. * @param ChangeSet cs the changeset to apply
  37. * @return HttpResponse
  38. */
  39. function apply_changeset($cs) {
  40. return $this->apply_changeset_turtle( $cs->to_turtle());
  41. }
  42. /**
  43. * Apply a changeset in a versioned manner to the graph
  44. * @param ChangeSet cs the changeset to apply
  45. * @return HttpResponse
  46. */
  47. function apply_versioned_changeset($cs) {
  48. return $this->apply_versioned_changeset_rdfxml( $cs->to_rdfxml());
  49. }
  50. /**
  51. * Apply a changeset to the graph
  52. * @param string rdfxml the changeset to apply, serialised as RDF/XML
  53. * @return HttpResponse
  54. */
  55. function apply_changeset_turtle($turtle) {
  56. if (empty( $this->request_factory) ) {
  57. $this->request_factory = new HttpRequestFactory();
  58. }
  59. $uri = $this->uri;
  60. $request = $this->request_factory->make( 'POST', $uri, $this->credentials);
  61. $request->set_accept("*/*");
  62. $request->set_content_type("application/vnd.talis.changeset+turtle");
  63. $request->set_body( $turtle );
  64. return $request->execute();
  65. }
  66. /**
  67. * Apply a changeset to the graph
  68. * @param string rdfxml the changeset to apply, serialised as RDF/XML
  69. * @return HttpResponse
  70. */
  71. function apply_changeset_rdfxml($rdfxml) {
  72. if (empty( $this->request_factory) ) {
  73. $this->request_factory = new HttpRequestFactory();
  74. }
  75. $uri = $this->uri;
  76. $request = $this->request_factory->make( 'POST', $uri, $this->credentials);
  77. $request->set_accept("*/*");
  78. $request->set_content_type("application/vnd.talis.changeset+xml");
  79. $request->set_body( $rdfxml );
  80. return $request->execute();
  81. }
  82. /**
  83. * Apply a changeset in a versioned manner to the graph
  84. * @param string rdfxml the changeset to apply, serialised as RDF/XML
  85. * @return HttpResponse
  86. */
  87. function apply_versioned_changeset_rdfxml($rdfxml) {
  88. if (empty( $this->request_factory) ) {
  89. $this->request_factory = new HttpRequestFactory();
  90. }
  91. $uri = $this->uri . '/changesets';
  92. $request = $this->request_factory->make( 'POST', $uri, $this->credentials);
  93. $request->set_accept("*/*");
  94. $request->set_content_type("application/vnd.talis.changeset+xml");
  95. $request->set_body( $rdfxml );
  96. return $request->execute();
  97. }
  98. /**
  99. * Submit some RDF/XML to be added to the graph
  100. * @param string rdfxml the RDF to be submitted, serialised as RDF/XML
  101. * @return HttpResponse
  102. */
  103. function submit_rdfxml($rdfxml) {
  104. if (empty( $this->request_factory) ) {
  105. $this->request_factory = new HttpRequestFactory();
  106. }
  107. $uri = $this->uri;
  108. $request = $this->request_factory->make( 'POST', $uri, $this->credentials);
  109. $request->set_content_type("application/rdf+xml");
  110. $request->set_accept("*/*");
  111. $request->set_body( $rdfxml );
  112. return $request->execute();
  113. }
  114. /**
  115. * Submit some Turtle to be added to the graph
  116. * @param string turtle the RDF to be submitted, serialised as Turtle
  117. * @return HttpResponse
  118. */
  119. function submit_turtle($turtle, $gzip_encode=false) {
  120. if (empty( $this->request_factory) ) {
  121. $this->request_factory = new HttpRequestFactory();
  122. }
  123. $uri = $this->uri;
  124. $request = $this->request_factory->make( 'POST', $uri, $this->credentials);
  125. $request->set_content_type("text/turtle");
  126. $request->set_accept("*/*");
  127. $request->set_body( $turtle, $gzip_encode);
  128. return $request->execute();
  129. }
  130. function submit_ntriples_in_batches_from_file($filename,$no_of_lines=500, $callback=false) {
  131. $responses = array();
  132. $pointer = fopen($filename, 'r');
  133. $batch = '';
  134. $lineCount=0;
  135. while($line = fgets($pointer)){
  136. $batch.=$line;
  137. $lineCount++;
  138. if($lineCount==$no_of_lines){
  139. $response = $this->submit_turtle($batch);
  140. $responses[] = $response;
  141. if(is_callable($callback)){
  142. call_user_func($callback, $response);
  143. } else if($response->is_success()===false){
  144. return $responses;
  145. }
  146. $lineCount=0;
  147. $batch='';
  148. }
  149. }
  150. if(!empty($batch)){
  151. $response=$this->submit_turtle($batch);
  152. if(is_callable($callback)){
  153. call_user_func($callback, $response);
  154. }
  155. $responses[]=$response;
  156. }
  157. return $responses;
  158. }
  159. /**
  160. * Obtain the graph's bounded description of a given resource
  161. * @see http://n2.talis.com/wiki/Metabox#Describing_a_Resource
  162. * @param string uri the URI of the resource to be described
  163. * @param string output the desired output format of the response (e.g. rdf, xml, json, ntriples, turtle)
  164. * @return HttpResponse
  165. */
  166. function describe( $uri, $output = null ) {
  167. $request = $this->get_describe_request($uri, $output);
  168. return $request->execute();
  169. }
  170. function get_describe_uri( $uri, $output = null ) {
  171. $request_uri = $this->uri . '?about=' . urlencode($uri);
  172. if ($output) {
  173. $request_uri .= '&output=' . urlencode($output);
  174. }
  175. return $request_uri;
  176. }
  177. function get_describe_request( $uri, $output = null ) {
  178. if (empty( $this->request_factory) ) {
  179. $this->request_factory = new HttpRequestFactory();
  180. }
  181. $request_uri = $this->get_describe_uri($uri, $output);
  182. $request = $this->request_factory->make( 'GET', $request_uri, $this->credentials);
  183. if ($output) {
  184. $request->set_accept("*/*");
  185. }
  186. else {
  187. $request->set_accept("application/rdf+xml");
  188. }
  189. $request->set_content_type("application/x-www-form-urlencoded");
  190. return $request;
  191. }
  192. /**
  193. * Obtain the graph's bounded description of a given resource
  194. * @deprecated triple lists are deprecated
  195. */
  196. function describe_to_triple_list( $uri ) {
  197. $triples = array();
  198. $response = $this->describe( $uri );
  199. $parser_args=array(
  200. "bnode_prefix"=>"genid",
  201. "base"=> $this->uri
  202. );
  203. $parser = ARC2::getRDFXMLParser($parser_args);
  204. if ( $response->body ) {
  205. $parser->parse($this->uri, $response->body );
  206. $triples = $parser->getTriples();
  207. }
  208. return $triples;
  209. }
  210. /**
  211. * Obtain the graph's bounded description of a given resource. This is designed to be fast since it uses RDF/JSON which requires no parsing by the SimpleGraph class. This method always returns a SimpleGraph, which will be empty if any HTTP errors occured.
  212. * @see http://n2.talis.com/wiki/Metabox#Describing_a_Resource
  213. * @param string uri the URI of the resource to be described
  214. * @return SimpleGraph
  215. */
  216. function describe_to_simple_graph( $uri ) {
  217. $graph = new SimpleGraph();
  218. $response = $this->describe( $uri, OUTPUT_TYPE_JSON );
  219. if ( $response->is_success() ) {
  220. $graph->from_json( $response->body );
  221. }
  222. return $graph;
  223. }
  224. /**
  225. * Tests whether the graph contains a bounded description of a given resource. This uses a conditional GET.
  226. * @see http://n2.talis.com/wiki/Metabox#Describing_a_Resource
  227. * @param string uri the URI of the resource to be described
  228. * @return boolean true if the graph contains triples with the resource as a subject, false otherwise
  229. */
  230. function has_description( $uri ) {
  231. if (empty( $this->request_factory) ) {
  232. $this->request_factory = new HttpRequestFactory();
  233. }
  234. $request_uri = $this->uri . '?about=' . urlencode($uri);
  235. $request = $this->request_factory->make( 'GET', $request_uri, $this->credentials);
  236. $request->set_accept("application/rdf+xml");
  237. $request->set_if_match("*");
  238. $response = $request->execute();
  239. if ($response->status_code == 200) {
  240. return true;
  241. }
  242. else if ($response->status_code == 412) {
  243. return false;
  244. }
  245. }
  246. /**
  247. * mirror_from_uri:
  248. *
  249. * @return array of responses from http requests, and overall success status
  250. * @author Keith Alexander
  251. *
  252. *
  253. **/
  254. function mirror_from_uri($url, $rdf_content=false)
  255. {
  256. $return = array(
  257. 'get_page' => false,
  258. 'get_copy' => false,
  259. 'update_data' => false,
  260. 'success' => false,
  261. );
  262. if (empty( $this->request_factory) ) {
  263. $this->request_factory = new HttpRequestFactory();
  264. }
  265. if(!$rdf_content){
  266. $web_page_request = $this->request_factory->make('GET', $url);
  267. $web_page_request->set_accept('application/rdf+xml;q=0.8,text/turtle;q=0.9,*/*;q=0.1');
  268. $web_page_response = $web_page_request->execute();
  269. $return['get_page'] = $web_page_response;
  270. $web_page_content = $web_page_response->body;
  271. } else {
  272. $web_page_content = $rdf_content;
  273. $return['rdf_content'] = $rdf_content;
  274. }
  275. if($rdf_content OR $web_page_response->is_success() ){
  276. $newGraph = new SimpleGraph();
  277. $newGraph->add_rdf($web_page_content, $url);
  278. $jsonGraphContent = $newGraph->to_json();
  279. $newGraph->add_resource_triple($url, OPEN_JSON, $jsonGraphContent);
  280. $newGraph->skolemise_bnodes(trim($url,'#').'#');
  281. $after = $newGraph->get_index();
  282. # get previous copy if it exists
  283. $cached_page_response = $this->describe($url, 'json');
  284. $return['get_copy'] = $cached_page_response;
  285. if($cached_page_response->status_code == '200'){
  286. $description_index = json_decode($cached_page_response->body, true);
  287. if(isset($description_index[$url]) AND isset($description_index[$url][OPEN_JSON])){
  288. $before = json_decode($description_index[$url][OPEN_JSON][0]['value'], 1);
  289. } else {
  290. $before = false;
  291. }
  292. } else if( $cached_page_response->status_code == '404' ) {
  293. $before = false;
  294. } else {
  295. return $return;
  296. }
  297. # build new changeset
  298. $Changeset = new ChangeSet(array('before' => $before, 'after' => $after, 'creatorName' => 'Graph::mirror_from_uri', 'changeReason' => 'mirroring from '.$url));
  299. if($Changeset->has_changes()){
  300. $return['update_data'] = $this->apply_changeset($Changeset);
  301. if($return['update_data']->is_success()){
  302. $return['success'] = true;
  303. } else if($return['update_data']->status_code=='409'){ # Conflict. some statements already removed.
  304. $before_graph = new SimpleGraph($before);
  305. $return['reapply_before_triples'] = $this->get_metabox()->submit_turtle($before_graph->to_turtle());
  306. if($return['reapply_before_triples']->status_code=='204'){ #Succeeded. No content
  307. $return['update_data'] = $this->get_metabox()->apply_changeset($Changeset);
  308. $return['success'] = $return['update_data']->is_success();
  309. }
  310. } else {
  311. return $return;
  312. }
  313. return $return;
  314. } else {
  315. $return['success'] = true;
  316. return $return;
  317. }
  318. } else {
  319. return $return;
  320. }
  321. }
  322. }
  323. ?>