PageRenderTime 26ms CodeModel.GetById 21ms RepoModel.GetById 0ms app.codeStats 0ms

/ontowiki/src/extensions/plugins/linkeddata/linkeddata.php

https://bitbucket.org/nihilus/ontowiki
PHP | 266 lines | 180 code | 34 blank | 52 comment | 23 complexity | 40e9789825c2eff47f97c2fe735ea1fd MD5 | raw file
Possible License(s): BSD-3-Clause, GPL-2.0
  1. <?php
  2. /**
  3. * OntoWiki linked data plug-in
  4. *
  5. * Takes a request URL as a resource URI and forwards to a appropriate
  6. * action if a resource exists, thus providing dereferencable resource URIs.
  7. *
  8. * @category OntoWiki
  9. * @package OntoWiki_extensions_plugins
  10. * @author Norman Heino <norman.heino@gmail.com>
  11. * @copyright Copyright (c) 2008, {@link http://aksw.org AKSW}
  12. * @license http://opensource.org/licenses/gpl-license.php GNU General Public License (GPL)
  13. * @version $Id: linkeddata.php 4093 2009-08-19 22:29:29Z christian.wuerker $
  14. */
  15. class LinkeddataPlugin extends OntoWiki_Plugin
  16. {
  17. /**
  18. * Recognized mime type requests and format (f) parameter values
  19. * @var array
  20. */
  21. private $_typeMapping = array(
  22. '' => 'xhtml', // default is xhtml
  23. 'text/html' => 'xhtml', // we only deliver XML-compatible html
  24. 'application/xhtml+xml' => 'xhtml',
  25. 'application/rdf+xml' => 'rdf',
  26. 'text/n3' => 'n3',
  27. 'application/json' => 'json',
  28. 'application/xml' => 'xhtml' // TODO: should this be xhtml or rdf?
  29. );
  30. /**
  31. * Handles an arbitrary URI by checking if a resource exists in the store
  32. * and forwarding to a redirecting to a URL that provides information
  33. * about that resource in the requested mime type.
  34. *
  35. * @param string $uri the requested URI
  36. * @param Zend_Controller_Request_Http
  37. *
  38. * @return boolean False if the request was not handled, i.e. no resource was found.
  39. */
  40. public function onIsDispatchable($event)
  41. {
  42. $store = OntoWiki::getInstance()->erfurt->getStore();
  43. $request = Zend_Controller_Front::getInstance()->getRequest();
  44. $response = Zend_Controller_Front::getInstance()->getResponse();
  45. $uri = $event->uri;
  46. try {
  47. $graph = $this->_getFirstReadableGraphForUri($uri);
  48. if (!$graph) {
  49. return false;
  50. }
  51. // content negotiation
  52. $type = (string)$this->_matchDocumentTypeRequest($event->request, array(
  53. 'text/html',
  54. 'application/xhtml+xml',
  55. 'application/rdf+xml',
  56. 'text/n3',
  57. 'application/json',
  58. 'application/xml'
  59. ));
  60. $format = 'rdf';
  61. if (isset($this->_privateConfig->format)) {
  62. $format = $this->_privateConfig->format;
  63. }
  64. if (true === (boolean)$this->_privateConfig->provenance->enabled) {
  65. $prov = 1;
  66. } else {
  67. $prov = 0;
  68. }
  69. // graph URIs export the whole graph
  70. if ($graph === $uri) {
  71. $controllerName = 'model';
  72. $actionName = 'export';
  73. } else {
  74. $controllerName = 'resource';
  75. $actionName = 'export';
  76. }
  77. // redirect accordingly
  78. switch ($this->_typeMapping[$type]) {
  79. case 'rdf':
  80. // set export action
  81. $url = new OntoWiki_Url(array('controller' => $controllerName, 'action' => $actionName), array());
  82. $url->setParam('r', $uri, true)
  83. ->setParam('f', $format)
  84. ->setParam('m', $graph)
  85. ->setParam('provenance', $prov);
  86. break;
  87. case 'xhtml':
  88. default:
  89. // make active graph (session required)
  90. OntoWiki::getInstance()->selectedModel = $store->getModel($graph);
  91. // default property view
  92. $url = new OntoWiki_Url(array('route' => 'properties'), array());
  93. $url->setParam('r', $uri, true)
  94. ->setParam('m', $graph);
  95. break;
  96. }
  97. $request->setDispatched(true);
  98. // give plugins a chance to do something
  99. $event = new Erfurt_Event('beforeLinkedDataRedirect');
  100. $event->response = $response;
  101. $event->trigger();
  102. // set redirect and send immediately
  103. $response->setRedirect((string)$url, 303)
  104. ->sendResponse();
  105. // TODO: do it the official Zend way
  106. exit;
  107. return false;
  108. } catch (Erfurt_Exception $e) {
  109. // don't handle errors since other plug-ins
  110. // could chain this event
  111. return false;
  112. }
  113. }
  114. public function onRouteShutdown($event)
  115. {
  116. $owApp = OntoWiki::getInstance();
  117. $requestUri = $owApp->config->urlBase . ltrim($event->request->getPathInfo(), '/');
  118. $viewPos = strrpos($requestUri, '/view/');
  119. if ($viewPos !== false) {
  120. $uri = substr($requestUri, 0, $viewPos) . '/id/' . substr($requestUri, $viewPos+6);
  121. $store = Erfurt_App::getInstance()->getStore();
  122. $result = $store->getGraphsUsingResource($uri, false);
  123. if ($result) {
  124. // get source graph
  125. $allowedGraph = null;
  126. $ac = Erfurt_App::getInstance()->getAc();
  127. foreach ($result as $g) {
  128. if ($ac->isModelAllowed('view', $g)) {
  129. $allowedGraph = $g;
  130. break;
  131. }
  132. }
  133. $graph = null;
  134. if ($allowedGraph !== null) {
  135. $graph = $store->getModel($allowedGraph);
  136. $owApp->selectedModel = $graph;
  137. }
  138. $resource = new OntoWiki_Resource($uri, $graph);
  139. $owApp->selectedResource = $resource;
  140. }
  141. }
  142. $dataPos = strrpos($requestUri, '/data/');
  143. if ($dataPos !== false) {
  144. $uri = substr($requestUri, 0, $dataPos) . '/id/' . substr($requestUri, $dataPos+6);
  145. $store = Erfurt_App::getInstance()->getStore();
  146. $result = $store->getGraphsUsingResource($uri, false);
  147. if ($result) {
  148. // get source graph
  149. $allowedGraph = null;
  150. $ac = Erfurt_App::getInstance()->getAc();
  151. foreach ($result as $g) {
  152. if ($ac->isModelAllowed('view', $g)) {
  153. $allowedGraph = $g;
  154. break;
  155. }
  156. }
  157. $graph = null;
  158. if ($allowedGraph !== null) {
  159. $graph = $store->getModel($allowedGraph);
  160. $owApp->selectedModel = $graph;
  161. }
  162. $resource = new OntoWiki_Resource($uri, $graph);
  163. $owApp->selectedResource = $resource;
  164. }
  165. }
  166. }
  167. public function onNeedsGraphForLinkedDataUri($event)
  168. {
  169. return $this->_getFirstReadableGraphForUri($event->uri);
  170. }
  171. public function onNeedsLinkedDataUri($event)
  172. {
  173. if ($this->_isLinkedDataUri($event->uri)) {
  174. $g = $this->_getFirstReadableGraphForUri($event->uri);
  175. if ($g !== false) {
  176. return true;
  177. }
  178. }
  179. return false;
  180. }
  181. /**
  182. * Matches the request's accept header againest supported mime types
  183. * and returns the supported type with highest priority found.
  184. *
  185. * @param Zend_Request_Abstract the request object
  186. *
  187. * @return string
  188. */
  189. private function _matchDocumentTypeRequest($request, array $supportedTypes = array())
  190. {
  191. return OntoWiki_Utils::matchMimetypeFromRequest($request, $supportedTypes);
  192. }
  193. private function _getFirstReadableGraphForUri($uri)
  194. {
  195. $store = OntoWiki::getInstance()->erfurt->getStore();
  196. try {
  197. $result = $store->getGraphsUsingResource($uri, false);
  198. if ($result) {
  199. // get source graph
  200. $allowedGraph = null;
  201. $ac = Erfurt_App::getInstance()->getAc();
  202. foreach ($result as $g) {
  203. if ($ac->isModelAllowed('view', $g)) {
  204. $allowedGraph = $g;
  205. break;
  206. }
  207. }
  208. if (null === $allowedGraph) {
  209. // We use the first matching graph. The user is redirected and the next request
  210. // has to decide, whether user is allowed to view or not. (Workaround since there are problems
  211. // with linkeddata and https).
  212. return $result[0];
  213. } else {
  214. return $allowedGraph;
  215. }
  216. } else {
  217. return null;
  218. }
  219. } catch (Excpetion $e) {
  220. return null;
  221. }
  222. }
  223. private function _isLinkedDataUri($uri)
  224. {
  225. $owApp = OntoWiki::getInstance();
  226. $owBase = $owApp->config->urlBase;
  227. if (substr($uri, 0, strlen($owBase)) === $owBase) {
  228. return true;
  229. }
  230. return false;
  231. }
  232. }