0cb581fdcb4ed2d298423f7ac7fc45b0f919bafe
[atutor.git] / mods / wiki / plugins / lib / libxprofile.php
1 <?php
2 /*
3    XUP/XProfile parser and verification class
4    ------------------------------------------
5    
6    $xuser = new xprofile("http://example.org/profile.xml");
7    ...
8    if ($xuser->login($password)) {
9       ...
10       echo $xuser->info["nickname"];
11    }
12
13    Should work with the older PEAR and the HTTP request class (PD) from
14    upgradephp.
15 */
16
17 #-- libs
18 if (!class_exists("http_request")) {
19   include_once("http.php");          # from upgradephp/contrib/
20   //include_once("http/request.php");  # from PEAR
21 }
22
23 #-- config
24 //define("XPROFILE_SITE", "example.com");   // preferred identifier of website
25 define("XPROFILE_SITE", preg_replace("/^www\./","",$_SERVER["SERVER_NAME"]));
26
27
28 #-- retrieves and verifies xml user profile
29 class xprofile {
30
31    #-- constructor takes URL of profile or "user@domain" shortcut
32    function xprofile($url, $xml=NULL, $uu0=0, $_redir=1) {
33    
34       #-- shortcut id
35       if (strpos($url, "@") && !strpos($url, "/")) {
36          $un = strtok($url, "@");
37          $url = "http://" . strtok("@") . "/xprofile/" . $un;
38       }
39    
40       #-- keep id
41       $this->url = $url;
42
43       #-- fetch data
44       if (empty($xml) && !strncmp($url, "http://", 7)) {
45          list($xml, $head) = $this->http("GET", $url);
46          if (!$xml) { return; }
47       }
48       
49       #-- parse it
50       $p = new xprofile_parser($xml);
51       $p->parse();
52       if (isset($p->control) || isset($p->info)) {
53          $this->control = (array)$p->control;
54          $this->info = (array)$p->info;
55          $this->text = (array)$p->text;   // already lcased
56       }
57       #-- "real" URL found?
58       if ($this->url != $this->control["self"]) {
59          $this->url = $this->control["self"];
60          if ($_redir) { 
61             $this->xprofile($this->url, NULL, 0, 0);
62          }
63       }
64    }
65
66    #-- verifies a user as owner of profile instance
67    function login($password) {
68       if ($login = $this->control["login"]) {
69          $params = array(
70             "url" => $this->url,
71             "password" => $password,
72             "site" => XPROFILE_SITE,
73          );
74          list($result, $headers) = $this->http("POST", $login, $params);
75            // should come without appended \r or \n (as per spec, but hey)
76          return(rtrim($result) === "1");
77       }
78    }
79
80    #-- HTTP requests
81    function http($method, $url, $formdata=array()) {
82       if (class_exists("http_request")) {
83          $req = new http_request();
84          $req->setMethod($method);
85          $req->setURL($url);
86          $req->addHeader("Accept", "xml/user-profile, text/boolean, */*; q=0.1");
87          if ($formdata) {
88             $req->params += $formdata;
89             $req->_postData = $formdata;  // PEAR tries to annoy us
90          }
91          $r = $req->sendRequest();
92          if ($r && ($r->getResponseStatus() == 200)) {
93             return array($r->getResponseBody(), $r->getResponseHeader());
94          }
95       }
96       elseif ($method=="GET") {
97          return array(file_get_contents($url), array());
98       }
99       elseif ($method=="POST") {
100          // give up
101       }
102       return array(NULL, NULL);
103    }
104 }
105
106
107 #-- xup parsing
108 class xprofile_parser extends easy_xml {
109
110    function xprofile_parser($xml) {
111       #-- prepare
112       $this->easy_xml();
113       $this->xmlns["urn:mime:xml/user-profile"] = "xup";
114       $this->xmlns2["xup"] = "";
115       #-- go
116       $this->parse($xml);
117       return($this);
118    }
119
120    #-- XML tags
121    function start($xp, &$tag, &$attr) {
122       parent::start($xp, $tag, $attr);
123       $p = $this->parent;
124       unset($this->text_meta);
125       if ($tag == "link") {
126          $this->{$p}[strtolower($attr["rel"])] = $attr["href"];
127       }
128       elseif ($tag == "meta") {
129          $name = strtolower($attr["name"]);
130          if (isset($attr["content"])) {
131             $this->{$p}[$name] = $attr["content"];
132          }
133          elseif ($this->parent == "text") {
134             $this->text_meta = $name;
135          }
136       }
137    }
138    #-- text:meta content
139    function cdata($xp, $text) {
140       if (isset($this->text_meta)) {
141          $this->text[$this->text_meta] = $text;
142          unset($this->text_meta);
143       }
144    }
145 }
146
147
148 ?>