• Main Page
  • Related Pages
  • Namespaces
  • Data Structures
  • Files
  • Examples
  • File List
  • Globals

cms/openid/Services/Yadis/XRDS.php

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         // Rebuild array of URIs.
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         // Try to get root element.
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         // Get the last XRD node.
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         // If no filters are specified, return the entire service
00341         // list, ordered by priority.
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         // If a bad filter mode is specified, return null.
00354         if (!in_array($filter_mode, array(SERVICES_YADIS_MATCH_ANY,
00355                                           SERVICES_YADIS_MATCH_ALL))) {
00356             return null;
00357         }
00358 
00359         // Otherwise, use the callbacks in the filter list to
00360         // determine which services are returned.
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 ?>

Generated on Sun Jan 2 2011 04:55:32 for Pragyan CMS by  doxygen 1.7.1