]> git.mxchange.org Git - quix0rs-gnu-social.git/blob - plugins/YammerImport/sn_yammerclient.php
Fetch more user data in Yammer imports, including the primary email address (preconfi...
[quix0rs-gnu-social.git] / plugins / YammerImport / sn_yammerclient.php
1 <?php
2 /*
3  * StatusNet - the distributed open-source microblogging tool
4  * Copyright (C) 2010, StatusNet, Inc.
5  *
6  * This program is free software: you can redistribute it and/or modify
7  * it under the terms of the GNU Affero General Public License as published by
8  * the Free Software Foundation, either version 3 of the License, or
9  * (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU Affero General Public License for more details.
15  *
16  * You should have received a copy of the GNU Affero General Public License
17  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
18  */
19
20 /**
21  * Basic client class for Yammer's OAuth/JSON API.
22  * 
23  * @package YammerImportPlugin
24  * @author Brion Vibber <brion@status.net>
25  */
26 class SN_YammerClient
27 {
28     protected $apiBase = "https://www.yammer.com";
29     protected $consumerKey, $consumerSecret;
30     protected $token, $tokenSecret, $verifier;
31
32     public function __construct($consumerKey, $consumerSecret, $token=null, $tokenSecret=null)
33     {
34         $this->consumerKey = $consumerKey;
35         $this->consumerSecret = $consumerSecret;
36         $this->token = $token;
37         $this->tokenSecret = $tokenSecret;
38     }
39
40     /**
41      * Make an HTTP GET request with OAuth headers and return an HTTPResponse
42      * with the returned body and codes.
43      *
44      * @param string $url
45      * @return HTTPResponse
46      *
47      * @throws Exception on low-level network error
48      */
49     protected function httpGet($url)
50     {
51         $headers = array('Authorization: ' . $this->authHeader());
52
53         $client = HTTPClient::start();
54         return $client->get($url, $headers);
55     }
56
57     /**
58      * Make an HTTP GET request with OAuth headers and return the response body
59      * on success.
60      *
61      * @param string $url
62      * @return string
63      *
64      * @throws Exception on low-level network or HTTP error
65      */
66     public function fetchUrl($url)
67     {
68         $response = $this->httpGet($url);
69         if ($response->isOk()) {
70             return $response->getBody();
71         } else {
72             throw new Exception("Yammer API returned HTTP code " . $response->getStatus() . ': ' . $response->getBody());
73         }
74     }
75
76     /**
77      * Make an HTTP hit with OAuth headers and return the response body on success.
78      *
79      * @param string $path URL chunk for the API method
80      * @param array $params
81      * @return string
82      *
83      * @throws Exception on low-level network or HTTP error
84      */
85     protected function fetchApi($path, $params=array())
86     {
87         $url = $this->apiBase . '/' . $path;
88         if ($params) {
89             $url .= '?' . http_build_query($params, null, '&');
90         }
91         return $this->fetchUrl($url);
92     }
93
94     /**
95      * Hit the main Yammer API point and decode returned JSON data.
96      *
97      * @param string $method
98      * @param array $params
99      * @return array from JSON data
100      *
101      * @throws Exception for HTTP error or bad JSON return
102      */
103     protected function api($method, $params=array())
104     {
105         $body = $this->fetchApi("api/v1/$method.json", $params);
106         $data = json_decode($body, true);
107         if (!$data) {
108             throw new Exception("Invalid JSON response from Yammer API");
109         }
110         return $data;
111     }
112
113     /**
114      * Build an Authorization header value from the keys we have available.
115      */
116     protected function authHeader()
117     {
118         // token
119         // token_secret
120         $params = array('realm' => '',
121                         'oauth_consumer_key' => $this->consumerKey,
122                         'oauth_signature_method' => 'PLAINTEXT',
123                         'oauth_timestamp' => time(),
124                         'oauth_nonce' => time(),
125                         'oauth_version' => '1.0');
126         if ($this->token) {
127             $params['oauth_token'] = $this->token;
128         }
129         if ($this->tokenSecret) {
130             $params['oauth_signature'] = $this->consumerSecret . '&' . $this->tokenSecret;
131         } else {
132             $params['oauth_signature'] = $this->consumerSecret . '&';
133         }
134         if ($this->verifier) {
135             $params['oauth_verifier'] = $this->verifier;
136         }
137         $parts = array_map(array($this, 'authHeaderChunk'), array_keys($params), array_values($params));
138         return 'OAuth ' . implode(', ', $parts);
139     }
140
141     /**
142      * @param string $key
143      * @param string $val
144      */
145     protected function authHeaderChunk($key, $val)
146     {
147         return urlencode($key) . '="' . urlencode($val) . '"';
148     }
149
150     /**
151      * @return array of oauth return data; should contain nice things
152      */
153     public function requestToken()
154     {
155         if ($this->token || $this->tokenSecret) {
156             throw new Exception("Requesting a token, but already set up with a token");
157         }
158         $data = $this->fetch('oauth/request_token');
159         $arr = array();
160         parse_str($data, $arr);
161         return $arr;
162     }
163
164     /**
165      * @return array of oauth return data; should contain nice things
166      */
167     public function accessToken($verifier)
168     {
169         $this->verifier = $verifier;
170         $data = $this->fetch('oauth/access_token');
171         $this->verifier = null;
172         $arr = array();
173         parse_str($data, $arr);
174         return $arr;
175     }
176
177     /**
178      * Give the URL to send users to to authorize a new app setup
179      *
180      * @param string $token as returned from accessToken()
181      * @return string URL
182      */
183     public function authorizeUrl($token)
184     {
185         return $this->apiBase . '/oauth/authorize?oauth_token=' . urlencode($token);
186     }
187
188     /**
189      * High-level API hit: fetch all messages in the network (up to 20 at a time).
190      * Return data is the full JSON array returned, including meta and references
191      * sections.
192      *
193      * The matching messages themselves will be in the 'messages' item within.
194      *
195      * @param array $options optional set of additional params for the request.
196      * @return array
197      *
198      * @throws Exception on low-level or HTTP error
199      */
200     public function messages($params=array())
201     {
202         return $this->api('messages', $params);
203     }
204
205     /**
206      * High-level API hit: fetch all users in the network (up to 50 at a time).
207      * Return data is the full JSON array returned, listing user items.
208      *
209      * The matching messages themselves will be in the 'users' item within.
210      *
211      * @param array $options optional set of additional params for the request.
212      * @return array of JSON-sourced user data arrays
213      *
214      * @throws Exception on low-level or HTTP error
215      */
216     public function users($params=array())
217     {
218         return $this->api('users', $params);
219     }
220 }