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

/s3db3.5.10/pearlib/arc/store/ARC2_StoreEndpoint.php

https://github.com/drobbins/s3db
PHP | 716 lines | 610 code | 60 blank | 46 comment | 65 complexity | 1677ecffa24ba139585afa24d2e1d4d5 MD5 | raw file
  1. <?php
  2. /*
  3. homepage: http://arc.semsol.org/
  4. license: http://arc.semsol.org/license
  5. class: ARC2 SPARQL Endpoint
  6. author: Benjamin Nowack
  7. version: 2008-07-02 (Addition: SPOG export via dump method or DUMP query)
  8. */
  9. ARC2::inc('Store');
  10. class ARC2_StoreEndpoint extends ARC2_Store {
  11. function __construct($a = '', &$caller) {
  12. parent::__construct($a, $caller);
  13. }
  14. function ARC2_StoreEndpoint($a = '', &$caller) {
  15. $this->__construct($a, $caller);
  16. }
  17. function __init() {
  18. parent::__init();
  19. $this->headers = array('http' => 'HTTP/1.1 200 OK');
  20. $this->read_key = $this->v('endpoint_read_key', '', $this->a);
  21. $this->write_key = $this->v('endpoint_write_key', '', $this->a);
  22. $this->a['store_allow_extension_functions'] = $this->v('store_allow_extension_functions', 0, $this->a);
  23. $this->result = '';
  24. }
  25. /* */
  26. function getQueryString($mthd = '') {
  27. $r = '';
  28. if (!$mthd || ($mthd == 'post')) {
  29. $r = @file_get_contents('php://input');
  30. }
  31. $r = !$r ?$this->v1('QUERY_STRING', '', $_SERVER) : $r;
  32. return $r;
  33. }
  34. function p($name='', $mthd = '', $multi = '', $default = '') {
  35. $mthd = strtolower($mthd);
  36. if($multi){
  37. $qs = $this->getQueryString($mthd);
  38. if (preg_match_all('/\&' . $name . '=([^\&]*)/', $qs, $m)){
  39. foreach ($m[1] as $i => $val) {
  40. $m[1][$i] = stripslashes($val);
  41. }
  42. return $m[1];
  43. }
  44. return $default ? $default : array();
  45. }
  46. $args = array_merge($_GET, $_POST);
  47. $r = isset($args[$name]) ? $args[$name] : $default;
  48. return is_array($r) ? $r : stripslashes($r);
  49. }
  50. /* */
  51. function getFeatures() {
  52. return $this->v1('endpoint_features', array(), $this->a);
  53. }
  54. function setHeader($k, $v) {
  55. $this->headers[$k] = $v;
  56. }
  57. function sendHeaders() {
  58. $this->setHeader('content-length', 'Content-Length: ' . strlen($this->getResult()));
  59. foreach ($this->headers as $k => $v) {
  60. header($v);
  61. }
  62. }
  63. function getResult() {
  64. return $this->result;
  65. }
  66. /* */
  67. function handleRequest($auto_setup = 0) {
  68. if (!$this->isSetUp()) {
  69. if ($auto_setup) {
  70. $this->setUp();
  71. return $this->handleRequest();
  72. }
  73. else {
  74. $this->setHeader('http', 'HTTP/1.1 400 Bad Request');
  75. $this->setHeader('content-type', 'Content-type: text/plain; charset=utf-8');
  76. $this->result = 'Missing configuration or the endpoint store was not set up yet.';
  77. }
  78. }
  79. elseif ($img = $this->p('img')) {
  80. $this->handleImgRequest($img);
  81. }
  82. elseif ($q = $this->p('query')) {
  83. $this->checkProcesses();
  84. $this->handleQueryRequest($q);
  85. }
  86. else {
  87. $this->handleEmptyRequest();
  88. }
  89. }
  90. function go($auto_setup = 0) {
  91. $this->handleRequest($auto_setup);
  92. $this->sendHeaders();
  93. echo $this->getResult();
  94. }
  95. /* */
  96. function handleImgRequest($img) {
  97. $this->setHeader('content-type', 'Content-type: image/gif');
  98. $imgs = array(
  99. 'bg_body' => base64_decode('R0lGODlhAQBkAMQAAPf39/Hx8erq6vPz8/Ly8u/v7+np6fT09Ovr6/b29u3t7ejo6Pz8/Pv7+/39/fr6+vj4+P7+/vn5+f///wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAAAAAAALAAAAAABAGQAAAUp4GIIiFIExHAkAAC9cAxJdG3TT67vTe//jKBQ6Cgaj5GkcpmcOJ/QZwgAOw=='),
  100. );
  101. $this->result = isset($imgs[$img]) ? $imgs[$img] : '';
  102. }
  103. /* */
  104. function handleEmptyRequest() {
  105. $this->setHeader('content-type', 'Content-type: text/html; charset=utf-8');
  106. $this->result = $this->getHTMLFormDoc();
  107. }
  108. /* */
  109. function checkProcesses() {
  110. }
  111. /* */
  112. function handleQueryRequest($q) {
  113. if (preg_match('/^dump/i', $q)) {
  114. $infos = array('query' => array('type' => 'dump'));
  115. }
  116. else {
  117. ARC2::inc('SPARQLPlusParser');
  118. $p = & new ARC2_SPARQLPlusParser($this->a, $this);
  119. $p->parse($q);
  120. $infos = $p->getQueryInfos();
  121. }
  122. /* errors? */
  123. if ($errors = $this->getErrors()) {
  124. $this->setHeader('http', 'HTTP/1.1 400 Bad Request');
  125. $this->setHeader('content-type', 'Content-type: text/plain; charset=utf-8');
  126. $this->result = join("\n", $errors);
  127. return true;
  128. }
  129. $qt = $infos['query']['type'];
  130. /* wrong read key? */
  131. if ($this->read_key && ($this->p('key') != $this->read_key) && preg_match('/^(select|ask|construct|describe|dump)$/', $qt)) {
  132. $this->setHeader('http', 'HTTP/1.1 401 Access denied');
  133. $this->setHeader('content-type', 'Content-type: text/plain; charset=utf-8');
  134. $this->result = 'Access denied. Missing or wrong "key" parameter.';
  135. return true;
  136. }
  137. /* wrong write key? */
  138. if ($this->write_key && ($this->p('key') != $this->write_key) && preg_match('/^(load|insert|delete|update)$/', $qt)) {
  139. $this->setHeader('http', 'HTTP/1.1 401 Access denied');
  140. $this->setHeader('content-type', 'Content-type: text/plain; charset=utf-8');
  141. $this->result = 'Access denied. Missing or wrong "key" parameter.';
  142. return true;
  143. }
  144. /* non-allowed query type? */
  145. if (!in_array($qt, $this->getFeatures())) {
  146. $this->setHeader('http', 'HTTP/1.1 401 Access denied');
  147. $this->setHeader('content-type', 'Content-type: text/plain; charset=utf-8');
  148. $this->result = 'Access denied for "' .$qt. '" query';
  149. return true;
  150. }
  151. /* load/insert/delete via GET */
  152. if (in_array($qt, array('load', 'insert', 'delete')) && isset($_GET['query'])) {
  153. $this->setHeader('http', 'HTTP/1.1 501 Not Implemented');
  154. $this->setHeader('content-type', 'Content-type: text/plain; charset=utf-8');
  155. $this->result = 'Query type "' .$qt. '" not supported via GET';
  156. return true;
  157. }
  158. /* unsupported query type */
  159. if (!in_array($qt, array('select', 'ask', 'describe', 'construct', 'load', 'insert', 'delete', 'dump'))) {
  160. $this->setHeader('http', 'HTTP/1.1 501 Not Implemented');
  161. $this->setHeader('content-type', 'Content-type: text/plain; charset=utf-8');
  162. $this->result = 'Unsupported query type "' .$qt. '"';
  163. return true;
  164. }
  165. /* adjust infos */
  166. $infos = $this->adjustQueryInfos($infos);
  167. $t1 = ARC2::mtime();
  168. $r = array('result' => $this->runQuery($infos, $qt));
  169. $t2 = ARC2::mtime();
  170. $r['query_time'] = $t2 - $t1;
  171. /* query errors? */
  172. if ($errors = $this->getErrors()) {
  173. $this->setHeader('http', 'HTTP/1.1 400 Bad Request');
  174. $this->setHeader('content-type', 'Content-type: text/plain; charset=utf-8');
  175. $this->result = 'Error: ' . join("\n", $errors);
  176. return true;
  177. }
  178. /* result */
  179. $m = 'get' . ucfirst($qt) . 'ResultDoc';
  180. if (method_exists($this, $m)) {
  181. $this->result = $this->$m($r);
  182. }
  183. else {
  184. $this->setHeader('content-type', 'Content-type: text/plain; charset=utf-8');
  185. $this->result = 'Result serializer not available, dumping raw data:' . "\n" . print_r($r, 1);
  186. }
  187. }
  188. /* */
  189. function adjustQueryInfos($infos) {
  190. /* limit */
  191. if ($max_l = $this->v('endpoint_max_limit', 0, $this->a)) {
  192. if ($this->v('limit', $max_l + 1, $infos['query']) > $max_l) {
  193. $infos['query']['limit'] = $max_l;
  194. }
  195. }
  196. /* default-graph-uri / named-graph-uri */
  197. $dgs = $this->p('default-graph-uri', '', 1);
  198. $ngs = $this->p('named-graph-uri', '', 1);
  199. if (count(array_merge($dgs, $ngs))) {
  200. $ds = array();
  201. foreach ($dgs as $g) {
  202. $ds[] = array('graph' => $this->calcURI($g), 'named' => 0);
  203. }
  204. foreach ($ngs as $g) {
  205. $ds[] = array('graph' => $this->calcURI($g), 'named' => 1);
  206. }
  207. $infos['query']['dataset'] = $ds;
  208. }
  209. /* sql result format */
  210. if (($this->p('format') == 'sql') || ($this->p('output') == 'sql')) {
  211. $infos['result_format'] = 'sql';
  212. }
  213. return $infos;
  214. }
  215. /* */
  216. function getResultFormat($formats, $default) {
  217. $prefs = array();
  218. /* arg */
  219. if (($v = $this->p('format')) || ($v = $this->p('output'))) {
  220. $prefs[] = $v;
  221. }
  222. /* accept header */
  223. if ($vals = explode(',', $_SERVER['HTTP_ACCEPT'])) {
  224. $o_vals = array();
  225. foreach ($vals as $val) {
  226. if (preg_match('/(rdf\+n3|x\-turtle|rdf\+xml|sparql\-results\+xml|sparql\-results\+json|json)/', $val, $m)) {
  227. $o_vals[$m[1]] = 1;
  228. if (preg_match('/\;q\=([0-9\.]+)/', $val, $sub_m)) {
  229. $o_vals[$m[1]] = 1 * $sub_m[1];
  230. }
  231. }
  232. }
  233. arsort($o_vals);
  234. foreach ($o_vals as $val => $prio) {
  235. $prefs[] = $val;
  236. }
  237. }
  238. /* default */
  239. $prefs[] = $default;
  240. foreach ($prefs as $pref) {
  241. if (isset($formats[$pref])) {
  242. return $formats[$pref];
  243. }
  244. }
  245. }
  246. /* */
  247. function getSelectResultDoc($r) {
  248. $formats = array(
  249. 'xml' => 'SPARQLXML', 'sparql-results+xml' => 'SPARQLXML',
  250. 'json' => 'SPARQLJSON', 'sparql-results+json' => 'SPARQLJSON',
  251. 'php_ser' => 'PHPSER', 'sql' => 'xxSQL', 'plain' => 'Plain', 'htmltab' => 'HTMLTable',
  252. );
  253. if ($f = $this->getResultFormat($formats, 'xml')) {
  254. $m = 'get' . $f . 'SelectResultDoc';
  255. return method_exists($this, $m) ? $this->$m($r) : 'not implemented';
  256. }
  257. return '';
  258. }
  259. function getSPARQLXMLSelectResultDoc($r) {
  260. $this->setHeader('content-type', 'Content-Type: application/sparql-results+xml');
  261. $vars = $r['result']['variables'];
  262. $rows = $r['result']['rows'];
  263. $dur = $r['query_time'];
  264. $nl = "\n";
  265. /* doc */
  266. $r = '' .
  267. '<?xml version="1.0"?>' .
  268. $nl . '<sparql xmlns="http://www.w3.org/2005/sparql-results#">' .
  269. '';
  270. /* head */
  271. $r .= $nl . ' <head>';
  272. $r .= $nl . ' <!-- query time: '. round($dur, 4) .' sec -->';
  273. if (is_array($vars)) {
  274. foreach ($vars as $var) {
  275. $r .= $nl . ' <variable name="' .$var. '"/>';
  276. }
  277. }
  278. $r .= $nl . ' </head>';
  279. /* results */
  280. $r .= $nl . ' <results>';
  281. if (is_array($rows)) {
  282. foreach ($rows as $row) {
  283. $r .= $nl . ' <result>';
  284. foreach ($vars as $var) {
  285. if (isset($row[$var])) {
  286. $r .= $nl . ' <binding name="' .$var. '">';
  287. if ($row[$var . ' type'] == 'uri') {
  288. $r .= $nl . ' <uri>' .htmlspecialchars($row[$var]). '</uri>';
  289. }
  290. elseif ($row[$var . ' type'] == 'bnode') {
  291. $r .= $nl . ' <bnode>' .substr($row[$var], 2). '</bnode>';
  292. }
  293. else {
  294. $dt = isset($row[$var . ' datatype']) ? ' datatype="' .htmlspecialchars($row[$var . ' datatype']). '"' : '';
  295. $lang = isset($row[$var . ' lang']) ? ' xml:lang="' .htmlspecialchars($row[$var . ' lang']). '"' : '';
  296. $r .= $nl . ' <literal' . $dt . $lang . '>' .htmlspecialchars($row[$var]). '</literal>';
  297. }
  298. $r .= $nl . ' </binding>';
  299. }
  300. }
  301. $r .= $nl . ' </result>';
  302. }
  303. }
  304. $r .= $nl . ' </results>';
  305. /* /doc */
  306. $r .= $nl . '</sparql>';
  307. return $r;
  308. }
  309. function getSPARQLJSONSelectResultDoc($r) {
  310. $this->setHeader('content-type', 'Content-Type: application/sparql-results+json');
  311. $vars = $r['result']['variables'];
  312. $rows = $r['result']['rows'];
  313. $dur = $r['query_time'];
  314. $nl = "\n";
  315. /* doc */
  316. $r = '{';
  317. /* head */
  318. $r .= $nl . ' "head": {';
  319. $r .= $nl . ' "vars": [';
  320. $first_var = 1;
  321. foreach ($vars as $var) {
  322. $r .= $first_var ? $nl : ',' . $nl;
  323. $r .= ' "' .$var. '"';
  324. $first_var = 0;
  325. }
  326. $r .= $nl . ' ]';
  327. $r .= $nl . ' },';
  328. /* results */
  329. $r .= $nl . ' "results": {';
  330. $r .= $nl . ' "bindings": [';
  331. $first_row = 1;
  332. foreach ($rows as $row) {
  333. $r .= $first_row ? $nl : ',' . $nl;
  334. $r .= ' {';
  335. $first_var = 1;
  336. foreach ($vars as $var) {
  337. if (isset($row[$var])) {
  338. $r .= $first_var ? $nl : ',' . $nl . $nl;
  339. $r .= ' "' .$var. '": {';
  340. if ($row[$var . ' type'] == 'uri') {
  341. $r .= $nl . ' "type": "uri",';
  342. $r .= $nl . ' "value": "' .mysql_real_escape_string($row[$var]). '"';
  343. }
  344. elseif ($row[$var . ' type'] == 'bnode') {
  345. $r .= $nl . ' "type": "bnode",';
  346. $r .= $nl . ' "value": "' . substr($row[$var], 2) . '"';
  347. }
  348. else {
  349. $dt = isset($row[$var . ' datatype']) ? ',' . $nl .' "datatype": "' .mysql_real_escape_string($row[$var . ' datatype']). '"' : '';
  350. $lang = isset($row[$var . ' lang']) ? ',' . $nl .' "xml:lang": "' .mysql_real_escape_string($row[$var . ' lang']). '"' : '';
  351. $type = $dt ? 'typed-literal' : 'literal';
  352. $r .= $nl . ' "type": "' . $type . '",';
  353. $r .= $nl . ' "value": "' . $this->jsonEscape($row[$var]) . '"';
  354. $r .= $dt . $lang;
  355. }
  356. $r .= $nl . ' }';
  357. $first_var = 0;
  358. }
  359. }
  360. $r .= $nl . ' }';
  361. $first_row = 0;
  362. }
  363. $r .= $nl . ' ]';
  364. $r .= $nl . ' }';
  365. /* /doc */
  366. $r .= $nl . '}';
  367. if (($v = $this->p('jsonp')) || ($v = $this->p('callback'))) {
  368. $r = $v . '(' . $r . ')';
  369. }
  370. return $r;
  371. }
  372. function getPHPSERSelectResultDoc($r) {
  373. $this->setHeader('content-type', 'Content-Type: text/plain');
  374. return serialize($r);
  375. }
  376. function getSQLSelectResultDoc($r) {
  377. $this->setHeader('content-type', 'Content-Type: text/plain');
  378. return $r['result'];
  379. }
  380. function getPlainSelectResultDoc($r) {
  381. $this->setHeader('content-type', 'Content-Type: text/plain');
  382. return print_r($r['result'], 1);
  383. }
  384. function getHTMLTableSelectResultDoc($r) {
  385. $this->setHeader('content-type', 'Content-Type: text/html');
  386. $vars = $r['result']['variables'];
  387. $rows = $r['result']['rows'];
  388. $dur = $r['query_time'];
  389. $r = $this->getHTMLDocHead();
  390. $r .= '
  391. <body>
  392. <table>
  393. ' . $this->getHTMLTableRows($rows, $vars) . '
  394. </table>
  395. </body>
  396. </html>
  397. ';
  398. return $r;
  399. }
  400. function getHTMLTableRows($rows, $vars) {
  401. $r = '';
  402. foreach ($rows as $row) {
  403. $hr = '';
  404. $rr = '';
  405. foreach ($vars as $var) {
  406. $hr .= $r ? '' : '<th>' . htmlspecialchars($var) . '</th>';
  407. $rr .= '<td>' . @htmlspecialchars($row[$var]) . '</td>';
  408. }
  409. $r .= $hr ? '<tr>' . $hr . '</tr>' : '';
  410. $r .= '<tr>' . $rr . '</tr>';
  411. }
  412. return $r ? $r : '<em>No results found</em>';
  413. }
  414. /* */
  415. function getAskResultDoc($r) {
  416. $formats = array(
  417. 'xml' => 'SPARQLXML', 'sparql-results+xml' => 'SPARQLXML',
  418. 'json' => 'SPARQLJSON', 'sparql-results+json' => 'SPARQLJSON',
  419. 'plain' => 'Plain',
  420. 'php_ser' => 'PHPSER'
  421. );
  422. if ($f = $this->getResultFormat($formats, 'xml')) {
  423. $m = 'get' . $f . 'AskResultDoc';
  424. return method_exists($this, $m) ? $this->$m($r) : 'not implemented';
  425. }
  426. return '';
  427. }
  428. function getSPARQLXMLAskResultDoc($r) {
  429. $this->setHeader('content-type', 'Content-Type: application/sparql-results+xml');
  430. $r_val = $r['result'] ? 'true' : 'false';
  431. $dur = $r['query_time'];
  432. $nl = "\n";
  433. return '' .
  434. '<?xml version="1.0"?>' .
  435. $nl . '<sparql xmlns="http://www.w3.org/2005/sparql-results#">' .
  436. $nl . ' <head>' .
  437. $nl . ' <!-- query time: '. round($dur, 4) .' sec -->' .
  438. $nl . ' </head>' .
  439. $nl . ' <boolean>' .$r_val. '</boolean>' .
  440. $nl . '</sparql>' .
  441. '';
  442. }
  443. function getSPARQLJSONAskResultDoc($r) {
  444. $this->setHeader('content-type', 'Content-Type: application/sparql-results+json');
  445. $r_val = $r['result'] ? 'true' : 'false';
  446. $dur = $r['query_time'];
  447. $nl = "\n";
  448. $r = '' .
  449. $nl . '{' .
  450. $nl . ' "head": {' .
  451. $nl . ' },' .
  452. $nl . ' "boolean" : ' . $r_val .
  453. $nl . '}' .
  454. '';
  455. if (($v = $this->p('jsonp')) || ($v = $this->p('callback'))) {
  456. $r = $v . '(' . $r . ')';
  457. }
  458. return $r;
  459. }
  460. function getPHPSERAskResultDoc($r) {
  461. $this->setHeader('content-type', 'Content-Type: text/plain');
  462. return serialize($r);
  463. }
  464. function getPlainAskResultDoc($r) {
  465. $this->setHeader('content-type', 'Content-Type: text/plain');
  466. return $r['result'] ? 'true' : 'false';
  467. }
  468. /* */
  469. function getConstructResultDoc($r) {
  470. $formats = array(
  471. 'rdfxml' => 'RDFXML', 'rdf+xml' => 'RDFXML',
  472. 'json' => 'RDFJSON', 'rdf+json' => 'RDFJSON',
  473. 'turtle' => 'Turtle', 'x-turtle' => 'Turtle', 'rdf+n3' => 'Turtle',
  474. 'php_ser' => 'PHPSER'
  475. );
  476. if ($f = $this->getResultFormat($formats, 'rdfxml')) {
  477. $m = 'get' . $f . 'ConstructResultDoc';
  478. return method_exists($this, $m) ? $this->$m($r) : 'not implemented';
  479. }
  480. return '';
  481. }
  482. function getRDFXMLConstructResultDoc($r) {
  483. $this->setHeader('content-type', 'Content-Type: application/rdf+xml');
  484. $index = $r['result'];
  485. $ser = ARC2::getRDFXMLSerializer($this->a);
  486. $dur = $r['query_time'];
  487. return $ser->getSerializedIndex($index) . "\n" . '<!-- query time: ' . $dur . ' -->';
  488. }
  489. function getTurtleConstructResultDoc($r) {
  490. $this->setHeader('content-type', 'Content-Type: application/x-turtle');
  491. $index = $r['result'];
  492. $ser = ARC2::getTurtleSerializer($this->a);
  493. $dur = $r['query_time'];
  494. return '# query time: ' . $dur . "\n" . $ser->getSerializedIndex($index);
  495. }
  496. function getRDFJSONConstructResultDoc($r) {
  497. $this->setHeader('content-type', 'Content-Type: application/json');
  498. $index = $r['result'];
  499. $ser = ARC2::getRDFJSONSerializer($this->a);
  500. $dur = $r['query_time'];
  501. $r = $ser->getSerializedIndex($index);
  502. if (($v = $this->p('jsonp')) || ($v = $this->p('callback'))) {
  503. $r = $v . '(' . $r . ')';
  504. }
  505. return $r;
  506. }
  507. function getPHPSERConstructResultDoc($r) {
  508. $this->setHeader('content-type', 'Content-Type: text/plain');
  509. return serialize($r);
  510. }
  511. /* */
  512. function getDescribeResultDoc($r) {
  513. $formats = array(
  514. 'rdfxml' => 'RDFXML', 'rdf+xml' => 'RDFXML',
  515. 'json' => 'RDFJSON', 'rdf+json' => 'RDFJSON',
  516. 'turtle' => 'Turtle', 'x-turtle' => 'Turtle', 'rdf+n3' => 'Turtle',
  517. 'php_ser' => 'PHPSER'
  518. );
  519. if ($f = $this->getResultFormat($formats, 'rdfxml')) {
  520. $m = 'get' . $f . 'DescribeResultDoc';
  521. return method_exists($this, $m) ? $this->$m($r) : 'not implemented';
  522. }
  523. return '';
  524. }
  525. function getRDFXMLDescribeResultDoc($r) {
  526. $this->setHeader('content-type', 'Content-Type: application/rdf+xml');
  527. $index = $r['result'];
  528. $ser = ARC2::getRDFXMLSerializer($this->a);
  529. $dur = $r['query_time'];
  530. return $ser->getSerializedIndex($index) . "\n" . '<!-- query time: ' . $dur . ' -->';
  531. }
  532. function getTurtleDescribeResultDoc($r) {
  533. $this->setHeader('content-type', 'Content-Type: application/x-turtle');
  534. $index = $r['result'];
  535. $ser = ARC2::getTurtleSerializer($this->a);
  536. $dur = $r['query_time'];
  537. return '# query time: ' . $dur . "\n" . $ser->getSerializedIndex($index);
  538. }
  539. function getRDFJSONDescribeResultDoc($r) {
  540. $this->setHeader('content-type', 'Content-Type: application/json');
  541. $index = $r['result'];
  542. $ser = ARC2::getRDFJSONSerializer($this->a);
  543. $dur = $r['query_time'];
  544. $r = $ser->getSerializedIndex($index);
  545. if (($v = $this->p('jsonp')) || ($v = $this->p('callback'))) {
  546. $r = $v . '(' . $r . ')';
  547. }
  548. return $r;
  549. }
  550. function getPHPSERDescribeResultDoc($r) {
  551. $this->setHeader('content-type', 'Content-Type: text/plain');
  552. return serialize($r);
  553. }
  554. /* */
  555. function getDumpResultDoc() {
  556. $this->headers = array();
  557. return '';
  558. }
  559. /* */
  560. function jsonEscape($v) {
  561. if (function_exists('json_encode')) return trim(json_encode($v), '"');
  562. $from = array("\\", "\r", "\t", "\n", '"', "\b", "\f", "/");
  563. $to = array('\\\\', '\r', '\t', '\n', '\"', '\b', '\f', '\/');
  564. return str_replace($from, $to, $v);
  565. }
  566. /* */
  567. function getHTMLFormDoc() {
  568. $r = '' .
  569. $this->getHTMLDocHead() . '
  570. <body>
  571. <h1>ARC SPARQL+ Endpoint (v' . ARC2::getVersion() . ')</h1>
  572. <div class="intro">
  573. <p>
  574. This interface implements
  575. <a href="http://www.w3.org/TR/rdf-sparql-query/">SPARQL</a> and
  576. <a href="http://arc.semsol.org/docs/v2/sparql+">SPARQL+</a> via <a href="http://www.w3.org/TR/rdf-sparql-protocol/#query-bindings-http">HTTP Bindings</a>.
  577. </p>
  578. <p>
  579. Enabled operations: ' . join(', ', $this->getFeatures()) . '
  580. </p>
  581. <p>
  582. Max. number of results : ' . $this->v('endpoint_max_limit', '<em>unrestricted</em>', $this->a) . '
  583. </p>
  584. </div>
  585. <form id="sparql-form" action="" enctype="application/x-www-form-urlencoded" method="post">
  586. <textarea id="query" name="query" rows="20" cols="80">
  587. SELECT ?s ?p ?o WHERE {
  588. ?s ?p ?o .
  589. }
  590. LIMIT 10
  591. </textarea>
  592. Output format (if supported by query type):
  593. <select id="output" name="output">
  594. <option value="">default</option>
  595. <option value="xml">XML</option>
  596. <option value="json">JSON</option>
  597. <option value="plain">Plain</option>
  598. <option value="php_ser">Serialized PHP</option>
  599. <option value="turtle">Turtle</option>
  600. <option value="rdfxml">RDF/XML</option>
  601. <!-- <option value="sql">SQL</option> -->
  602. <option value="htmltab">HTML Table</option>
  603. </select><br /><br />
  604. jsonp/callback (for JSON results):
  605. <input type="text" id="jsonp" name="jsonp" /><br /><br />
  606. API key (if required):
  607. <input type="text" id="key" name="key" /><br /><br />
  608. Set form method:
  609. <a href="javascript:;" onclick="javascript:document.getElementById(\'sparql-form\').method=\'get\'">GET</a>
  610. <a href="javascript:;" onclick="javascript:document.getElementById(\'sparql-form\').method=\'post\'">POST</a>
  611. <br /><br />
  612. <input type="submit" value="Send Query" />
  613. </form>
  614. </body>
  615. </html>
  616. ';
  617. return $r;
  618. }
  619. function getHTMLDocHead() {
  620. return '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
  621. <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
  622. <head>
  623. <title>ARC SPARQL+ Endpoint</title>
  624. <style type="text/css">
  625. body {
  626. font-size: 14px;
  627. font-family: Trebuchet MS, Verdana, Geneva, sans-serif;
  628. background: #fff url(?img=bg_body) top center repeat-x;
  629. padding: 5px 20px 20px 20px;
  630. color: #666;
  631. }
  632. h1 { font-size: 1.6em; font-weight: normal; }
  633. a { color: #c00000; }
  634. th, td {
  635. border: 1px dotted #eee;
  636. padding: 2px 4px;
  637. }
  638. #query { display: block; width: 80%; height: 300px; margin-bottom: 10px;}
  639. </style>
  640. </head>
  641. ';
  642. }
  643. /* */
  644. }