Go to the documentation of this file.00001 <?php
00002
00019 require_once 'Services/Yadis/XML.php';
00020
00025 define('SERVICES_YADIS_MATCH_ALL', 101);
00026
00031 define('SERVICES_YADIS_MATCH_ANY', 102);
00032
00033 global $_Services_Yadis_ns_map;
00034 $_Services_Yadis_ns_map = array('xrds' => 'xri://$xrds',
00035 'xrd' => 'xri://$xrd*($v*2.0)');
00036
00037 define('SERVICES_YADIS_MAX_PRIORITY', pow(2, 30));
00038
00042 function Services_Yadis_array_scramble($arr)
00043 {
00044 $result = array();
00045
00046 while (count($arr)) {
00047 $index = array_rand($arr, 1);
00048 $result[] = $arr[$index];
00049 unset($arr[$index]);
00050 }
00051
00052 return $result;
00053 }
00054
00067 class Services_Yadis_Service {
00068
00072 function Services_Yadis_Service()
00073 {
00074 $this->element = null;
00075 $this->parser = null;
00076 }
00077
00084 function getTypes()
00085 {
00086 $t = array();
00087 foreach ($this->getElements('xrd:Type') as $elem) {
00088 $c = $this->parser->content($elem);
00089 if ($c) {
00090 $t[] = $c;
00091 }
00092 }
00093 return $t;
00094 }
00095
00102 function getURIs()
00103 {
00104 $uris = array();
00105 $last = array();
00106
00107 foreach ($this->getElements('xrd:URI') as $elem) {
00108 $uri_string = $this->parser->content($elem);
00109 $attrs = $this->parser->attributes($elem);
00110 if ($attrs &&
00111 array_key_exists('priority', $attrs)) {
00112 $priority = intval($attrs['priority']);
00113 if (!array_key_exists($priority, $uris)) {
00114 $uris[$priority] = array();
00115 }
00116
00117 $uris[$priority][] = $uri_string;
00118 } else {
00119 $last[] = $uri_string;
00120 }
00121 }
00122
00123 $keys = array_keys($uris);
00124 sort($keys);
00125
00126
00127 $result = array();
00128 foreach ($keys as $k) {
00129 $new_uris = Services_Yadis_array_scramble($uris[$k]);
00130 $result = array_merge($result, $new_uris);
00131 }
00132
00133 $result = array_merge($result,
00134 Services_Yadis_array_scramble($last));
00135
00136 return $result;
00137 }
00138
00146 function getPriority()
00147 {
00148 $attributes = $this->parser->attributes($this->element);
00149
00150 if (array_key_exists('priority', $attributes)) {
00151 return intval($attributes['priority']);
00152 }
00153
00154 return null;
00155 }
00156
00172 function getElements($name)
00173 {
00174 return $this->parser->evalXPath($name, $this->element);
00175 }
00176 }
00177
00193 class Services_Yadis_XRDS {
00194
00199 function Services_Yadis_XRDS(&$xmlParser, &$xrdNode)
00200 {
00201 $this->parser =& $xmlParser;
00202 $this->xrdNode = $xrdNode;
00203 $this->serviceList = array();
00204 $this->_parse();
00205 }
00206
00216 function parseXRDS($xml_string, $extra_ns_map = null)
00217 {
00218 global $_Services_Yadis_ns_map;
00219
00220 if (!$xml_string) {
00221 return null;
00222 }
00223
00224 $parser = Services_Yadis_getXMLParser();
00225
00226 $ns_map = $_Services_Yadis_ns_map;
00227
00228 if ($extra_ns_map && is_array($extra_ns_map)) {
00229 $ns_map = array_merge($ns_map, $extra_ns_map);
00230 }
00231
00232 if (!($parser && $parser->init($xml_string, $ns_map))) {
00233 return null;
00234 }
00235
00236
00237 $root = $parser->evalXPath('/xrds:XRDS[1]');
00238 if (!$root) {
00239 return null;
00240 }
00241
00242 if (is_array($root)) {
00243 $root = $root[0];
00244 }
00245
00246 $attrs = $parser->attributes($root);
00247
00248 if (array_key_exists('xmlns:xrd', $attrs) &&
00249 $attrs['xmlns:xrd'] != 'xri://$xrd*($v*2.0)') {
00250 return null;
00251 } else if (array_key_exists('xmlns', $attrs) &&
00252 preg_match('/xri/', $attrs['xmlns']) &&
00253 $attrs['xmlns'] != 'xri://$xrd*($v*2.0)') {
00254 return null;
00255 }
00256
00257
00258 $xrd_nodes = $parser->evalXPath('/xrds:XRDS[1]/xrd:XRD[last()]');
00259
00260 if (!$xrd_nodes) {
00261 return null;
00262 }
00263
00264 $xrds = new Services_Yadis_XRDS($parser, $xrd_nodes[0]);
00265 return $xrds;
00266 }
00267
00271 function _addService($priority, $service)
00272 {
00273 $priority = intval($priority);
00274
00275 if (!array_key_exists($priority, $this->serviceList)) {
00276 $this->serviceList[$priority] = array();
00277 }
00278
00279 $this->serviceList[$priority][] = $service;
00280 }
00281
00288 function _parse()
00289 {
00290 $this->serviceList = array();
00291
00292 $services = $this->parser->evalXPath('xrd:Service', $this->xrdNode);
00293
00294 foreach ($services as $node) {
00295 $s =& new Services_Yadis_Service();
00296 $s->element = $node;
00297 $s->parser =& $this->parser;
00298
00299 $priority = $s->getPriority();
00300
00301 if ($priority === null) {
00302 $priority = SERVICES_YADIS_MAX_PRIORITY;
00303 }
00304
00305 $this->_addService($priority, $s);
00306 }
00307 }
00308
00333 function services($filters = null,
00334 $filter_mode = SERVICES_YADIS_MATCH_ANY)
00335 {
00336
00337 $pri_keys = array_keys($this->serviceList);
00338 sort($pri_keys, SORT_NUMERIC);
00339
00340
00341
00342 if (!$filters ||
00343 (!is_array($filters))) {
00344
00345 $result = array();
00346 foreach ($pri_keys as $pri) {
00347 $result = array_merge($result, $this->serviceList[$pri]);
00348 }
00349
00350 return $result;
00351 }
00352
00353
00354 if (!in_array($filter_mode, array(SERVICES_YADIS_MATCH_ANY,
00355 SERVICES_YADIS_MATCH_ALL))) {
00356 return null;
00357 }
00358
00359
00360
00361 $filtered = array();
00362
00363 foreach ($pri_keys as $priority_value) {
00364 $service_obj_list = $this->serviceList[$priority_value];
00365
00366 foreach ($service_obj_list as $service) {
00367
00368 $matches = 0;
00369
00370 foreach ($filters as $filter) {
00371 if (call_user_func_array($filter, array($service))) {
00372 $matches++;
00373
00374 if ($filter_mode == SERVICES_YADIS_MATCH_ANY) {
00375 $pri = $service->getPriority();
00376 if ($pri === null) {
00377 $pri = SERVICES_YADIS_MAX_PRIORITY;
00378 }
00379
00380 if (!array_key_exists($pri, $filtered)) {
00381 $filtered[$pri] = array();
00382 }
00383
00384 $filtered[$pri][] = $service;
00385 break;
00386 }
00387 }
00388 }
00389
00390 if (($filter_mode == SERVICES_YADIS_MATCH_ALL) &&
00391 ($matches == count($filters))) {
00392
00393 $pri = $service->getPriority();
00394 if ($pri === null) {
00395 $pri = SERVICES_YADIS_MAX_PRIORITY;
00396 }
00397
00398 if (!array_key_exists($pri, $filtered)) {
00399 $filtered[$pri] = array();
00400 }
00401 $filtered[$pri][] = $service;
00402 }
00403 }
00404 }
00405
00406 $pri_keys = array_keys($filtered);
00407 sort($pri_keys, SORT_NUMERIC);
00408
00409 $result = array();
00410 foreach ($pri_keys as $pri) {
00411 $result = array_merge($result, $filtered[$pri]);
00412 }
00413
00414 return $result;
00415 }
00416 }
00417
00418 ?>