ILIAS  release_4-3 Revision
 All Data Structures Namespaces Files Functions Variables Groups Pages
XRDS.php
Go to the documentation of this file.
1 <?php
2 
19 require_once 'Auth/Yadis/XML.php';
20 
25 define('SERVICES_YADIS_MATCH_ALL', 101);
26 
31 define('SERVICES_YADIS_MATCH_ANY', 102);
32 
37 define('SERVICES_YADIS_MAX_PRIORITY', pow(2, 30));
38 
42 define('Auth_Yadis_XMLNS_XRD_2_0', 'xri://$xrd*($v*2.0)');
43 
47 define('Auth_Yadis_XMLNS_XRDS', 'xri://$xrds');
48 
50 {
51  return array('xrds' => Auth_Yadis_XMLNS_XRDS,
52  'xrd' => Auth_Yadis_XMLNS_XRD_2_0);
53 }
54 
59 {
60  $result = array();
61 
62  while (count($arr)) {
63  $index = array_rand($arr, 1);
64  $result[] = $arr[$index];
65  unset($arr[$index]);
66  }
67 
68  return $result;
69 }
70 
84 
88  function Auth_Yadis_Service()
89  {
90  $this->element = null;
91  $this->parser = null;
92  }
93 
100  function getTypes()
101  {
102  $t = array();
103  foreach ($this->getElements('xrd:Type') as $elem) {
104  $c = $this->parser->content($elem);
105  if ($c) {
106  $t[] = $c;
107  }
108  }
109  return $t;
110  }
111 
112  function matchTypes($type_uris)
113  {
114  $result = array();
115 
116  foreach ($this->getTypes() as $typ) {
117  if (in_array($typ, $type_uris)) {
118  $result[] = $typ;
119  }
120  }
121 
122  return $result;
123  }
124 
131  function getURIs()
132  {
133  $uris = array();
134  $last = array();
135 
136  foreach ($this->getElements('xrd:URI') as $elem) {
137  $uri_string = $this->parser->content($elem);
138  $attrs = $this->parser->attributes($elem);
139  if ($attrs &&
140  array_key_exists('priority', $attrs)) {
141  $priority = intval($attrs['priority']);
142  if (!array_key_exists($priority, $uris)) {
143  $uris[$priority] = array();
144  }
145 
146  $uris[$priority][] = $uri_string;
147  } else {
148  $last[] = $uri_string;
149  }
150  }
151 
152  $keys = array_keys($uris);
153  sort($keys);
154 
155  // Rebuild array of URIs.
156  $result = array();
157  foreach ($keys as $k) {
158  $new_uris = Auth_Yadis_array_scramble($uris[$k]);
159  $result = array_merge($result, $new_uris);
160  }
161 
162  $result = array_merge($result,
164 
165  return $result;
166  }
167 
175  function getPriority()
176  {
177  $attributes = $this->parser->attributes($this->element);
178 
179  if (array_key_exists('priority', $attributes)) {
180  return intval($attributes['priority']);
181  }
182 
183  return null;
184  }
185 
201  function getElements($name)
202  {
203  return $this->parser->evalXPath($name, $this->element);
204  }
205 }
206 
207 /*
208  * Return the expiration date of this XRD element, or None if no
209  * expiration was specified.
210  *
211  * @param $default The value to use as the expiration if no expiration
212  * was specified in the XRD.
213  */
214 function Auth_Yadis_getXRDExpiration($xrd_element, $default=null)
215 {
216  $expires_element = $xrd_element->$parser->evalXPath('/xrd:Expires');
217  if ($expires_element === null) {
218  return $default;
219  } else {
220  $expires_string = $expires_element->text;
221 
222  // Will raise ValueError if the string is not the expected
223  // format
224  $t = strptime($expires_string, "%Y-%m-%dT%H:%M:%SZ");
225 
226  if ($t === false) {
227  return false;
228  }
229 
230  // [int $hour [, int $minute [, int $second [,
231  // int $month [, int $day [, int $year ]]]]]]
232  return mktime($t['tm_hour'], $t['tm_min'], $t['tm_sec'],
233  $t['tm_mon'], $t['tm_day'], $t['tm_year']);
234  }
235 }
236 
253 
258  function Auth_Yadis_XRDS($xmlParser, $xrdNodes)
259  {
260  $this->parser = $xmlParser;
261  $this->xrdNode = $xrdNodes[count($xrdNodes) - 1];
262  $this->allXrdNodes = $xrdNodes;
263  $this->serviceList = array();
264  $this->_parse();
265  }
266 
276  static function parseXRDS($xml_string, $extra_ns_map = null)
277  {
278  $_null = null;
279 
280  if (!$xml_string) {
281  return $_null;
282  }
283 
284  $parser = Auth_Yadis_getXMLParser();
285 
286  $ns_map = Auth_Yadis_getNSMap();
287 
288  if ($extra_ns_map && is_array($extra_ns_map)) {
289  $ns_map = array_merge($ns_map, $extra_ns_map);
290  }
291 
292  if (!($parser && $parser->init($xml_string, $ns_map))) {
293  return $_null;
294  }
295 
296  // Try to get root element.
297  $root = $parser->evalXPath('/xrds:XRDS[1]');
298  if (!$root) {
299  return $_null;
300  }
301 
302  if (is_array($root)) {
303  $root = $root[0];
304  }
305 
306  $attrs = $parser->attributes($root);
307 
308  if (array_key_exists('xmlns:xrd', $attrs) &&
309  $attrs['xmlns:xrd'] != Auth_Yadis_XMLNS_XRDS) {
310  return $_null;
311  } else if (array_key_exists('xmlns', $attrs) &&
312  preg_match('/xri/', $attrs['xmlns']) &&
313  $attrs['xmlns'] != Auth_Yadis_XMLNS_XRD_2_0) {
314  return $_null;
315  }
316 
317  // Get the last XRD node.
318  $xrd_nodes = $parser->evalXPath('/xrds:XRDS[1]/xrd:XRD');
319 
320  if (!$xrd_nodes) {
321  return $_null;
322  }
323 
324  $xrds = new Auth_Yadis_XRDS($parser, $xrd_nodes);
325  return $xrds;
326  }
327 
331  function _addService($priority, $service)
332  {
333  $priority = intval($priority);
334 
335  if (!array_key_exists($priority, $this->serviceList)) {
336  $this->serviceList[$priority] = array();
337  }
338 
339  $this->serviceList[$priority][] = $service;
340  }
341 
348  function _parse()
349  {
350  $this->serviceList = array();
351 
352  $services = $this->parser->evalXPath('xrd:Service', $this->xrdNode);
353 
354  foreach ($services as $node) {
355  $s = new Auth_Yadis_Service();
356  $s->element = $node;
357  $s->parser = $this->parser;
358 
359  $priority = $s->getPriority();
360 
361  if ($priority === null) {
362  $priority = SERVICES_YADIS_MAX_PRIORITY;
363  }
364 
365  $this->_addService($priority, $s);
366  }
367  }
368 
393  function services($filters = null,
394  $filter_mode = SERVICES_YADIS_MATCH_ANY)
395  {
396 
397  $pri_keys = array_keys($this->serviceList);
398  sort($pri_keys, SORT_NUMERIC);
399 
400  // If no filters are specified, return the entire service
401  // list, ordered by priority.
402  if (!$filters ||
403  (!is_array($filters))) {
404 
405  $result = array();
406  foreach ($pri_keys as $pri) {
407  $result = array_merge($result, $this->serviceList[$pri]);
408  }
409 
410  return $result;
411  }
412 
413  // If a bad filter mode is specified, return null.
414  if (!in_array($filter_mode, array(SERVICES_YADIS_MATCH_ANY,
416  return null;
417  }
418 
419  // Otherwise, use the callbacks in the filter list to
420  // determine which services are returned.
421  $filtered = array();
422 
423  foreach ($pri_keys as $priority_value) {
424  $service_obj_list = $this->serviceList[$priority_value];
425 
426  foreach ($service_obj_list as $service) {
427 
428  $matches = 0;
429 
430  foreach ($filters as $filter) {
431 
432  if (call_user_func_array($filter, array(&$service))) {
433  $matches++;
434 
435  if ($filter_mode == SERVICES_YADIS_MATCH_ANY) {
436  $pri = $service->getPriority();
437  if ($pri === null) {
439  }
440 
441  if (!array_key_exists($pri, $filtered)) {
442  $filtered[$pri] = array();
443  }
444 
445  $filtered[$pri][] = $service;
446  break;
447  }
448  }
449  }
450 
451  if (($filter_mode == SERVICES_YADIS_MATCH_ALL) &&
452  ($matches == count($filters))) {
453 
454  $pri = $service->getPriority();
455  if ($pri === null) {
457  }
458 
459  if (!array_key_exists($pri, $filtered)) {
460  $filtered[$pri] = array();
461  }
462  $filtered[$pri][] = $service;
463  }
464  }
465  }
466 
467  $pri_keys = array_keys($filtered);
468  sort($pri_keys, SORT_NUMERIC);
469 
470  $result = array();
471  foreach ($pri_keys as $pri) {
472  $result = array_merge($result, $filtered[$pri]);
473  }
474 
475  return $result;
476  }
477 }
478