XRDS.php

Go to the documentation of this file.
00001 <?php
00002 
00019 require_once 'Auth/Yadis/XML.php';
00020 
00025 define('SERVICES_YADIS_MATCH_ALL', 101);
00026 
00031 define('SERVICES_YADIS_MATCH_ANY', 102);
00032 
00037 define('SERVICES_YADIS_MAX_PRIORITY', pow(2, 30));
00038 
00042 define('Auth_Yadis_XMLNS_XRD_2_0', 'xri://$xrd*($v*2.0)');
00043 
00047 define('Auth_Yadis_XMLNS_XRDS', 'xri://$xrds');
00048 
00049 function Auth_Yadis_getNSMap()
00050 {
00051     return array('xrds' => Auth_Yadis_XMLNS_XRDS,
00052                  'xrd' => Auth_Yadis_XMLNS_XRD_2_0);
00053 }
00054 
00058 function Auth_Yadis_array_scramble($arr)
00059 {
00060     $result = array();
00061 
00062     while (count($arr)) {
00063         $index = array_rand($arr, 1);
00064         $result[] = $arr[$index];
00065         unset($arr[$index]);
00066     }
00067 
00068     return $result;
00069 }
00070 
00083 class Auth_Yadis_Service {
00084 
00088     function Auth_Yadis_Service()
00089     {
00090         $this->element = null;
00091         $this->parser = null;
00092     }
00093 
00100     function getTypes()
00101     {
00102         $t = array();
00103         foreach ($this->getElements('xrd:Type') as $elem) {
00104             $c = $this->parser->content($elem);
00105             if ($c) {
00106                 $t[] = $c;
00107             }
00108         }
00109         return $t;
00110     }
00111 
00112     function matchTypes($type_uris)
00113     {
00114         $result = array();
00115 
00116         foreach ($this->getTypes() as $typ) {
00117             if (in_array($typ, $type_uris)) {
00118                 $result[] = $typ;
00119             }
00120         }
00121 
00122         return $result;
00123     }
00124 
00131     function getURIs()
00132     {
00133         $uris = array();
00134         $last = array();
00135 
00136         foreach ($this->getElements('xrd:URI') as $elem) {
00137             $uri_string = $this->parser->content($elem);
00138             $attrs = $this->parser->attributes($elem);
00139             if ($attrs &&
00140                 array_key_exists('priority', $attrs)) {
00141                 $priority = intval($attrs['priority']);
00142                 if (!array_key_exists($priority, $uris)) {
00143                     $uris[$priority] = array();
00144                 }
00145 
00146                 $uris[$priority][] = $uri_string;
00147             } else {
00148                 $last[] = $uri_string;
00149             }
00150         }
00151 
00152         $keys = array_keys($uris);
00153         sort($keys);
00154 
00155         // Rebuild array of URIs.
00156         $result = array();
00157         foreach ($keys as $k) {
00158             $new_uris = Auth_Yadis_array_scramble($uris[$k]);
00159             $result = array_merge($result, $new_uris);
00160         }
00161 
00162         $result = array_merge($result,
00163                               Auth_Yadis_array_scramble($last));
00164 
00165         return $result;
00166     }
00167 
00175     function getPriority()
00176     {
00177         $attributes = $this->parser->attributes($this->element);
00178 
00179         if (array_key_exists('priority', $attributes)) {
00180             return intval($attributes['priority']);
00181         }
00182 
00183         return null;
00184     }
00185 
00201     function getElements($name)
00202     {
00203         return $this->parser->evalXPath($name, $this->element);
00204     }
00205 }
00206 
00207 /*
00208  * Return the expiration date of this XRD element, or None if no
00209  * expiration was specified.
00210  *
00211  * @param $default The value to use as the expiration if no expiration
00212  * was specified in the XRD.
00213  */
00214 function Auth_Yadis_getXRDExpiration($xrd_element, $default=null)
00215 {
00216     $expires_element = $xrd_element->$parser->evalXPath('/xrd:Expires');
00217     if ($expires_element === null) {
00218         return $default;
00219     } else {
00220         $expires_string = $expires_element->text;
00221 
00222         // Will raise ValueError if the string is not the expected
00223         // format
00224         $t = strptime($expires_string, "%Y-%m-%dT%H:%M:%SZ");
00225 
00226         if ($t === false) {
00227             return false;
00228         }
00229 
00230         // [int $hour [, int $minute [, int $second [,
00231         //  int $month [, int $day [, int $year ]]]]]]
00232         return mktime($t['tm_hour'], $t['tm_min'], $t['tm_sec'],
00233                       $t['tm_mon'], $t['tm_day'], $t['tm_year']);
00234     }
00235 }
00236 
00252 class Auth_Yadis_XRDS {
00253 
00258     function Auth_Yadis_XRDS(&$xmlParser, &$xrdNodes)
00259     {
00260         $this->parser =& $xmlParser;
00261         $this->xrdNode = $xrdNodes[count($xrdNodes) - 1];
00262         $this->allXrdNodes =& $xrdNodes;
00263         $this->serviceList = array();
00264         $this->_parse();
00265     }
00266 
00276     function &parseXRDS($xml_string, $extra_ns_map = null)
00277     {
00278         $_null = null;
00279 
00280         if (!$xml_string) {
00281             return $_null;
00282         }
00283 
00284         $parser = Auth_Yadis_getXMLParser();
00285 
00286         $ns_map = Auth_Yadis_getNSMap();
00287 
00288         if ($extra_ns_map && is_array($extra_ns_map)) {
00289             $ns_map = array_merge($ns_map, $extra_ns_map);
00290         }
00291 
00292         if (!($parser && $parser->init($xml_string, $ns_map))) {
00293             return $_null;
00294         }
00295 
00296         // Try to get root element.
00297         $root = $parser->evalXPath('/xrds:XRDS[1]');
00298         if (!$root) {
00299             return $_null;
00300         }
00301 
00302         if (is_array($root)) {
00303             $root = $root[0];
00304         }
00305 
00306         $attrs = $parser->attributes($root);
00307 
00308         if (array_key_exists('xmlns:xrd', $attrs) &&
00309             $attrs['xmlns:xrd'] != Auth_Yadis_XMLNS_XRDS) {
00310             return $_null;
00311         } else if (array_key_exists('xmlns', $attrs) &&
00312                    preg_match('/xri/', $attrs['xmlns']) &&
00313                    $attrs['xmlns'] != Auth_Yadis_XMLNS_XRD_2_0) {
00314             return $_null;
00315         }
00316 
00317         // Get the last XRD node.
00318         $xrd_nodes = $parser->evalXPath('/xrds:XRDS[1]/xrd:XRD');
00319 
00320         if (!$xrd_nodes) {
00321             return $_null;
00322         }
00323 
00324         $xrds = new Auth_Yadis_XRDS($parser, $xrd_nodes);
00325         return $xrds;
00326     }
00327 
00331     function _addService($priority, $service)
00332     {
00333         $priority = intval($priority);
00334 
00335         if (!array_key_exists($priority, $this->serviceList)) {
00336             $this->serviceList[$priority] = array();
00337         }
00338 
00339         $this->serviceList[$priority][] = $service;
00340     }
00341 
00348     function _parse()
00349     {
00350         $this->serviceList = array();
00351 
00352         $services = $this->parser->evalXPath('xrd:Service', $this->xrdNode);
00353 
00354         foreach ($services as $node) {
00355             $s =& new Auth_Yadis_Service();
00356             $s->element = $node;
00357             $s->parser =& $this->parser;
00358 
00359             $priority = $s->getPriority();
00360 
00361             if ($priority === null) {
00362                 $priority = SERVICES_YADIS_MAX_PRIORITY;
00363             }
00364 
00365             $this->_addService($priority, $s);
00366         }
00367     }
00368 
00393     function services($filters = null,
00394                       $filter_mode = SERVICES_YADIS_MATCH_ANY)
00395     {
00396 
00397         $pri_keys = array_keys($this->serviceList);
00398         sort($pri_keys, SORT_NUMERIC);
00399 
00400         // If no filters are specified, return the entire service
00401         // list, ordered by priority.
00402         if (!$filters ||
00403             (!is_array($filters))) {
00404 
00405             $result = array();
00406             foreach ($pri_keys as $pri) {
00407                 $result = array_merge($result, $this->serviceList[$pri]);
00408             }
00409 
00410             return $result;
00411         }
00412 
00413         // If a bad filter mode is specified, return null.
00414         if (!in_array($filter_mode, array(SERVICES_YADIS_MATCH_ANY,
00415                                           SERVICES_YADIS_MATCH_ALL))) {
00416             return null;
00417         }
00418 
00419         // Otherwise, use the callbacks in the filter list to
00420         // determine which services are returned.
00421         $filtered = array();
00422 
00423         foreach ($pri_keys as $priority_value) {
00424             $service_obj_list = $this->serviceList[$priority_value];
00425 
00426             foreach ($service_obj_list as $service) {
00427 
00428                 $matches = 0;
00429 
00430                 foreach ($filters as $filter) {
00431                     if (call_user_func_array($filter, array($service))) {
00432                         $matches++;
00433 
00434                         if ($filter_mode == SERVICES_YADIS_MATCH_ANY) {
00435                             $pri = $service->getPriority();
00436                             if ($pri === null) {
00437                                 $pri = SERVICES_YADIS_MAX_PRIORITY;
00438                             }
00439 
00440                             if (!array_key_exists($pri, $filtered)) {
00441                                 $filtered[$pri] = array();
00442                             }
00443 
00444                             $filtered[$pri][] = $service;
00445                             break;
00446                         }
00447                     }
00448                 }
00449 
00450                 if (($filter_mode == SERVICES_YADIS_MATCH_ALL) &&
00451                     ($matches == count($filters))) {
00452 
00453                     $pri = $service->getPriority();
00454                     if ($pri === null) {
00455                         $pri = SERVICES_YADIS_MAX_PRIORITY;
00456                     }
00457 
00458                     if (!array_key_exists($pri, $filtered)) {
00459                         $filtered[$pri] = array();
00460                     }
00461                     $filtered[$pri][] = $service;
00462                 }
00463             }
00464         }
00465 
00466         $pri_keys = array_keys($filtered);
00467         sort($pri_keys, SORT_NUMERIC);
00468 
00469         $result = array();
00470         foreach ($pri_keys as $pri) {
00471             $result = array_merge($result, $filtered[$pri]);
00472         }
00473 
00474         return $result;
00475     }
00476 }
00477 
00478 ?>

Generated on Thu Feb 19 15:02:21 2009 for OXID eShop CE by  doxygen 1.5.5