PageRenderTime 26ms CodeModel.GetById 27ms RepoModel.GetById 1ms app.codeStats 0ms

/application/libraries/Services/Yadis/Yadis.php

https://github.com/supplychainstudies/OSI
PHP | 311 lines | 125 code | 26 blank | 160 comment | 20 complexity | c9f66c177190e483c3fb3e6ec180e292 MD5 | raw file
  1. <?php
  2. /**
  3. * The core PHP Yadis implementation.
  4. *
  5. * PHP versions 4 and 5
  6. *
  7. * LICENSE: See the COPYING file included in this distribution.
  8. *
  9. * @package Yadis
  10. * @author JanRain, Inc. <openid@janrain.com>
  11. * @copyright 2005 Janrain, Inc.
  12. * @license http://www.gnu.org/copyleft/lesser.html LGPL
  13. */
  14. /**
  15. * Need both fetcher types so we can use the right one based on the
  16. * presence or absence of CURL.
  17. */
  18. //require_once "Services/Yadis/PlainHTTPFetcher.php";
  19. //require_once "Services/Yadis/ParanoidHTTPFetcher.php";
  20. require_once "PlainHTTPFetcher.php";
  21. require_once "ParanoidHTTPFetcher.php";
  22. /**
  23. * Need this for parsing HTML (looking for META tags).
  24. */
  25. //require_once "Services/Yadis/ParseHTML.php";
  26. require_once "ParseHTML.php";
  27. /**
  28. * Need this to parse the XRDS document during Yadis discovery.
  29. */
  30. //require_once "Services/Yadis/XRDS.php";
  31. require_once "XRDS.php";
  32. /**
  33. * This is the core of the PHP Yadis library. This is the only class
  34. * a user needs to use to perform Yadis discovery. This class
  35. * performs the discovery AND stores the result of the discovery.
  36. *
  37. * First, require this library into your program source:
  38. *
  39. * <pre> require_once "Services/Yadis/Yadis.php";</pre>
  40. *
  41. * To perform Yadis discovery, first call the "discover" method
  42. * statically with a URI parameter:
  43. *
  44. * <pre> $http_response = array();
  45. * $fetcher = Services_Yadis_Yadis::getHTTPFetcher();
  46. * $yadis_object = Services_Yadis_Yadis::discover($uri,
  47. * $http_response, $fetcher);</pre>
  48. *
  49. * If the discovery succeeds, $yadis_object will be an instance of
  50. * {@link Services_Yadis_Yadis}. If not, it will be null. The XRDS
  51. * document found during discovery should have service descriptions,
  52. * which can be accessed by calling
  53. *
  54. * <pre> $service_list = $yadis_object->services();</pre>
  55. *
  56. * which returns an array of objects which describe each service.
  57. * These objects are instances of Services_Yadis_Service. Each object
  58. * describes exactly one whole Service element, complete with all of
  59. * its Types and URIs (no expansion is performed). The common use
  60. * case for using the service objects returned by services() is to
  61. * write one or more filter functions and pass those to services():
  62. *
  63. * <pre> $service_list = $yadis_object->services(
  64. * array("filterByURI",
  65. * "filterByExtension"));</pre>
  66. *
  67. * The filter functions (whose names appear in the array passed to
  68. * services()) take the following form:
  69. *
  70. * <pre> function myFilter(&$service) {
  71. * // Query $service object here. Return true if the service
  72. * // matches your query; false if not.
  73. * }</pre>
  74. *
  75. * This is an example of a filter which uses a regular expression to
  76. * match the content of URI tags (note that the Services_Yadis_Service
  77. * class provides a getURIs() method which you should use instead of
  78. * this contrived example):
  79. *
  80. * <pre>
  81. * function URIMatcher(&$service) {
  82. * foreach ($service->getElements('xrd:URI') as $uri) {
  83. * if (preg_match("/some_pattern/",
  84. * $service->parser->content($uri))) {
  85. * return true;
  86. * }
  87. * }
  88. * return false;
  89. * }</pre>
  90. *
  91. * The filter functions you pass will be called for each service
  92. * object to determine which ones match the criteria your filters
  93. * specify. The default behavior is that if a given service object
  94. * matches ANY of the filters specified in the services() call, it
  95. * will be returned. You can specify that a given service object will
  96. * be returned ONLY if it matches ALL specified filters by changing
  97. * the match mode of services():
  98. *
  99. * <pre> $yadis_object->services(array("filter1", "filter2"),
  100. * SERVICES_YADIS_MATCH_ALL);</pre>
  101. *
  102. * See {@link SERVICES_YADIS_MATCH_ALL} and {@link
  103. * SERVICES_YADIS_MATCH_ANY}.
  104. *
  105. * Services described in an XRDS should have a library which you'll
  106. * probably be using. Those libraries are responsible for defining
  107. * filters that can be used with the "services()" call. If you need
  108. * to write your own filter, see the documentation for {@link
  109. * Services_Yadis_Service}.
  110. *
  111. * @package Yadis
  112. */
  113. class Services_Yadis_Yadis {
  114. /**
  115. * Returns an HTTP fetcher object. If the CURL extension is
  116. * present, an instance of {@link Services_Yadis_ParanoidHTTPFetcher}
  117. * is returned. If not, an instance of
  118. * {@link Services_Yadis_PlainHTTPFetcher} is returned.
  119. */
  120. function getHTTPFetcher($timeout = 20)
  121. {
  122. if (defined('Services_Yadis_CURL_PRESENT') &&
  123. Services_Yadis_CURL_PRESENT) {
  124. $fetcher = new Services_Yadis_ParanoidHTTPFetcher($timeout);
  125. } else {
  126. $fetcher = new Services_Yadis_PlainHTTPFetcher($timeout);
  127. }
  128. return $fetcher;
  129. }
  130. /**
  131. * @access private
  132. */
  133. function _getHeader($header_list, $names)
  134. {
  135. foreach ($header_list as $name => $value) {
  136. foreach ($names as $n) {
  137. if (strtolower($name) == strtolower($n)) {
  138. return $value;
  139. }
  140. }
  141. }
  142. return null;
  143. }
  144. /**
  145. * @access private
  146. */
  147. function _getContentType($content_type_header)
  148. {
  149. if ($content_type_header) {
  150. $parts = explode(";", $content_type_header);
  151. return strtolower($parts[0]);
  152. }
  153. }
  154. /**
  155. * This should be called statically and will build a Yadis
  156. * instance if the discovery process succeeds. This implements
  157. * Yadis discovery as specified in the Yadis specification.
  158. *
  159. * @param string $uri The URI on which to perform Yadis discovery.
  160. *
  161. * @param array $http_response An array reference where the HTTP
  162. * response object will be stored (see {@link
  163. * Services_Yadis_HTTPResponse}.
  164. *
  165. * @param Services_Yadis_HTTPFetcher $fetcher An instance of a
  166. * Services_Yadis_HTTPFetcher subclass.
  167. *
  168. * @param array $extra_ns_map An array which maps namespace names
  169. * to namespace URIs to be used when parsing the Yadis XRDS
  170. * document.
  171. *
  172. * @param integer $timeout An optional fetcher timeout, in seconds.
  173. *
  174. * @return mixed $obj Either null or an instance of
  175. * Services_Yadis_Yadis, depending on whether the discovery
  176. * succeeded.
  177. */
  178. function discover($uri, &$http_response, &$fetcher,
  179. $extra_ns_map = null, $timeout = 20)
  180. {
  181. if (!$uri) {
  182. return null;
  183. }
  184. $request_uri = $uri;
  185. $headers = array("Accept: application/xrds+xml");
  186. if (!$fetcher) {
  187. $fetcher = Services_Yadis_Yadis::getHTTPFetcher($timeout);
  188. }
  189. $response = $fetcher->get($uri, $headers);
  190. $http_response = $response;
  191. if (!$response) {
  192. return null;
  193. }
  194. if ($response->status != 200) {
  195. return null;
  196. }
  197. $xrds_uri = $response->final_url;
  198. $uri = $response->final_url;
  199. $body = $response->body;
  200. $xrds_header_uri = Services_Yadis_Yadis::_getHeader(
  201. $response->headers,
  202. array('x-xrds-location',
  203. 'x-yadis-location'));
  204. $content_type = Services_Yadis_Yadis::_getHeader($response->headers,
  205. array('content-type'));
  206. if ($xrds_header_uri) {
  207. $xrds_uri = $xrds_header_uri;
  208. $response = $fetcher->get($xrds_uri);
  209. $http_response = $response;
  210. if (!$response) {
  211. return null;
  212. } else {
  213. $body = $response->body;
  214. $headers = $response->headers;
  215. $content_type = Services_Yadis_Yadis::_getHeader($headers,
  216. array('content-type'));
  217. }
  218. }
  219. if (Services_Yadis_Yadis::_getContentType($content_type) !=
  220. 'application/xrds+xml') {
  221. // Treat the body as HTML and look for a META tag.
  222. $parser = new Services_Yadis_ParseHTML();
  223. $new_uri = $parser->getHTTPEquiv($body);
  224. $xrds_uri = null;
  225. if ($new_uri) {
  226. $response = $fetcher->get($new_uri);
  227. if ($response->status != 200) {
  228. return null;
  229. }
  230. $http_response = $response;
  231. $body = $response->body;
  232. $xrds_uri = $new_uri;
  233. $content_type = Services_Yadis_Yadis::_getHeader(
  234. $response->headers,
  235. array('content-type'));
  236. }
  237. }
  238. $xrds = Services_Yadis_XRDS::parseXRDS($body, $extra_ns_map);
  239. if ($xrds !== null) {
  240. $y = new Services_Yadis_Yadis();
  241. $y->request_uri = $request_uri;
  242. $y->xrds = $xrds;
  243. $y->uri = $uri;
  244. $y->xrds_uri = $xrds_uri;
  245. $y->body = $body;
  246. $y->content_type = $content_type;
  247. return $y;
  248. } else {
  249. return null;
  250. }
  251. }
  252. /**
  253. * Instantiates an empty Services_Yadis_Yadis object. This
  254. * constructor should not be used by any user of the library.
  255. * This constructor results in a completely useless object which
  256. * must be populated with valid discovery information. Instead of
  257. * using this constructor, call
  258. * Services_Yadis_Yadis::discover($uri).
  259. */
  260. function Services_Yadis_Yadis()
  261. {
  262. $this->request_uri = null;
  263. $this->uri = null;
  264. $this->xrds = null;
  265. $this->xrds_uri = null;
  266. $this->body = null;
  267. $this->content_type = null;
  268. }
  269. /**
  270. * Returns the list of service objects as described by the XRDS
  271. * document, if this yadis object represents a successful Yadis
  272. * discovery.
  273. *
  274. * @return array $services An array of {@link Services_Yadis_Service}
  275. * objects
  276. */
  277. function services()
  278. {
  279. if ($this->xrds) {
  280. return $this->xrds->services();
  281. }
  282. return null;
  283. }
  284. }
  285. ?>