247 lines
		
	
	
		
			7.7 KiB
		
	
	
	
		
			PHP
		
	
	
	
	
	
			
		
		
	
	
			247 lines
		
	
	
		
			7.7 KiB
		
	
	
	
		
			PHP
		
	
	
	
	
	
<?php
 | 
						|
/*
 | 
						|
 * StatusNet - the distributed open-source microblogging tool
 | 
						|
 * Copyright (C) 2010, StatusNet, Inc.
 | 
						|
 *
 | 
						|
 * This program is free software: you can redistribute it and/or modify
 | 
						|
 * it under the terms of the GNU Affero General Public License as published by
 | 
						|
 * the Free Software Foundation, either version 3 of the License, or
 | 
						|
 * (at your option) any later version.
 | 
						|
 *
 | 
						|
 * This program is distributed in the hope that it will be useful,
 | 
						|
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
						|
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
						|
 * GNU Affero General Public License for more details.
 | 
						|
 *
 | 
						|
 * You should have received a copy of the GNU Affero General Public License
 | 
						|
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 | 
						|
 */
 | 
						|
 | 
						|
/**
 | 
						|
 * Basic client class for Yammer's OAuth/JSON API.
 | 
						|
 * 
 | 
						|
 * @package YammerImportPlugin
 | 
						|
 * @author Brion Vibber <brion@status.net>
 | 
						|
 */
 | 
						|
class SN_YammerClient
 | 
						|
{
 | 
						|
    protected $apiBase = "https://www.yammer.com";
 | 
						|
    protected $consumerKey, $consumerSecret;
 | 
						|
    protected $token, $tokenSecret, $verifier;
 | 
						|
 | 
						|
    public function __construct($consumerKey, $consumerSecret, $token=null, $tokenSecret=null)
 | 
						|
    {
 | 
						|
        $this->consumerKey = $consumerKey;
 | 
						|
        $this->consumerSecret = $consumerSecret;
 | 
						|
        $this->token = $token;
 | 
						|
        $this->tokenSecret = $tokenSecret;
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * Make an HTTP GET request with OAuth headers and return an HTTPResponse
 | 
						|
     * with the returned body and codes.
 | 
						|
     *
 | 
						|
     * @param string $url
 | 
						|
     * @return HTTPResponse
 | 
						|
     *
 | 
						|
     * @throws Exception on low-level network error
 | 
						|
     */
 | 
						|
    protected function httpGet($url)
 | 
						|
    {
 | 
						|
        $headers = array('Authorization: ' . $this->authHeader());
 | 
						|
 | 
						|
        $client = HTTPClient::start();
 | 
						|
        return $client->get($url, $headers);
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * Make an HTTP GET request with OAuth headers and return the response body
 | 
						|
     * on success.
 | 
						|
     *
 | 
						|
     * @param string $url
 | 
						|
     * @return string
 | 
						|
     *
 | 
						|
     * @throws Exception on low-level network or HTTP error
 | 
						|
     */
 | 
						|
    public function fetchUrl($url)
 | 
						|
    {
 | 
						|
        $response = $this->httpGet($url);
 | 
						|
        if ($response->isOk()) {
 | 
						|
            return $response->getBody();
 | 
						|
        } else {
 | 
						|
            throw new Exception("Yammer API returned HTTP code " . $response->getStatus() . ': ' . $response->getBody());
 | 
						|
        }
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * Make an HTTP hit with OAuth headers and return the response body on success.
 | 
						|
     *
 | 
						|
     * @param string $path URL chunk for the API method
 | 
						|
     * @param array $params
 | 
						|
     * @return string
 | 
						|
     *
 | 
						|
     * @throws Exception on low-level network or HTTP error
 | 
						|
     */
 | 
						|
    protected function fetchApi($path, $params=array())
 | 
						|
    {
 | 
						|
        $url = $this->apiBase . '/' . $path;
 | 
						|
        if ($params) {
 | 
						|
            $url .= '?' . http_build_query($params, null, '&');
 | 
						|
        }
 | 
						|
        return $this->fetchUrl($url);
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * Hit the main Yammer API point and decode returned JSON data.
 | 
						|
     *
 | 
						|
     * @param string $method
 | 
						|
     * @param array $params
 | 
						|
     * @return array from JSON data
 | 
						|
     *
 | 
						|
     * @throws Exception for HTTP error or bad JSON return
 | 
						|
     */
 | 
						|
    public function api($method, $params=array())
 | 
						|
    {
 | 
						|
        $body = $this->fetchApi("api/v1/$method.json", $params);
 | 
						|
        $data = json_decode($body, true);
 | 
						|
        if ($data === null) {
 | 
						|
            common_log(LOG_ERR, "Invalid JSON response from Yammer API: " . $body);
 | 
						|
            throw new Exception("Invalid JSON response from Yammer API");
 | 
						|
        }
 | 
						|
        return $data;
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * Build an Authorization header value from the keys we have available.
 | 
						|
     */
 | 
						|
    protected function authHeader()
 | 
						|
    {
 | 
						|
        // token
 | 
						|
        // token_secret
 | 
						|
        $params = array('realm' => '',
 | 
						|
                        'oauth_consumer_key' => $this->consumerKey,
 | 
						|
                        'oauth_signature_method' => 'PLAINTEXT',
 | 
						|
                        'oauth_timestamp' => time(),
 | 
						|
                        'oauth_nonce' => time(),
 | 
						|
                        'oauth_version' => '1.0');
 | 
						|
        if ($this->token) {
 | 
						|
            $params['oauth_token'] = $this->token;
 | 
						|
        }
 | 
						|
        if ($this->tokenSecret) {
 | 
						|
            $params['oauth_signature'] = $this->consumerSecret . '&' . $this->tokenSecret;
 | 
						|
        } else {
 | 
						|
            $params['oauth_signature'] = $this->consumerSecret . '&';
 | 
						|
        }
 | 
						|
        if ($this->verifier) {
 | 
						|
            $params['oauth_verifier'] = $this->verifier;
 | 
						|
        }
 | 
						|
        $parts = array_map(array($this, 'authHeaderChunk'), array_keys($params), array_values($params));
 | 
						|
        return 'OAuth ' . implode(', ', $parts);
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * Encode a key-value pair for use in an authentication header.
 | 
						|
     *
 | 
						|
     * @param string $key
 | 
						|
     * @param string $val
 | 
						|
     * @return string
 | 
						|
     */
 | 
						|
    protected function authHeaderChunk($key, $val)
 | 
						|
    {
 | 
						|
        return urlencode($key) . '="' . urlencode($val) . '"';
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * Ask the Yammer server for a request token, which can be passed on
 | 
						|
     * to authorizeUrl() for the user to start the authentication process.
 | 
						|
     *
 | 
						|
     * @return array of oauth return data; should contain nice things
 | 
						|
     */
 | 
						|
    public function requestToken()
 | 
						|
    {
 | 
						|
        if ($this->token || $this->tokenSecret) {
 | 
						|
            throw new Exception("Requesting a token, but already set up with a token");
 | 
						|
        }
 | 
						|
        $data = $this->fetchApi('oauth/request_token');
 | 
						|
        $arr = array();
 | 
						|
        parse_str($data, $arr);
 | 
						|
        return $arr;
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * Get a final access token from the verifier/PIN code provided to
 | 
						|
     * the user from Yammer's auth pages.
 | 
						|
     *
 | 
						|
     * @return array of oauth return data; should contain nice things
 | 
						|
     */
 | 
						|
    public function accessToken($verifier)
 | 
						|
    {
 | 
						|
        $this->verifier = $verifier;
 | 
						|
        $data = $this->fetchApi('oauth/access_token');
 | 
						|
        $this->verifier = null;
 | 
						|
        $arr = array();
 | 
						|
        parse_str($data, $arr);
 | 
						|
        return $arr;
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * Give the URL to send users to to authorize a new app setup.
 | 
						|
     *
 | 
						|
     * @param string $token as returned from accessToken()
 | 
						|
     * @return string URL
 | 
						|
     */
 | 
						|
    public function authorizeUrl($token)
 | 
						|
    {
 | 
						|
        return $this->apiBase . '/oauth/authorize?oauth_token=' . urlencode($token);
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * High-level API hit: fetch all messages in the network (up to 20 at a time).
 | 
						|
     * Return data is the full JSON array returned, including meta and references
 | 
						|
     * sections.
 | 
						|
     *
 | 
						|
     * The matching messages themselves will be in the 'messages' item within.
 | 
						|
     *
 | 
						|
     * @param array $options optional set of additional params for the request.
 | 
						|
     * @return array
 | 
						|
     *
 | 
						|
     * @throws Exception on low-level or HTTP error
 | 
						|
     */
 | 
						|
    public function messages($params=array())
 | 
						|
    {
 | 
						|
        return $this->api('messages', $params);
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * High-level API hit: fetch all users in the network (up to 50 at a time).
 | 
						|
     * Return data is the full JSON array returned, listing user items.
 | 
						|
     *
 | 
						|
     * The matching messages themselves will be in the 'users' item within.
 | 
						|
     *
 | 
						|
     * @param array $options optional set of additional params for the request.
 | 
						|
     * @return array of JSON-sourced user data arrays
 | 
						|
     *
 | 
						|
     * @throws Exception on low-level or HTTP error
 | 
						|
     */
 | 
						|
    public function users($params=array())
 | 
						|
    {
 | 
						|
        return $this->api('users', $params);
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * High-level API hit: fetch all groups in the network (up to 20 at a time).
 | 
						|
     * Return data is the full JSON array returned, listing user items.
 | 
						|
     *
 | 
						|
     * The matching messages themselves will be in the 'users' item within.
 | 
						|
     *
 | 
						|
     * @param array $options optional set of additional params for the request.
 | 
						|
     * @return array of JSON-sourced user data arrays
 | 
						|
     *
 | 
						|
     * @throws Exception on low-level or HTTP error
 | 
						|
     */
 | 
						|
    public function groups($params=array())
 | 
						|
    {
 | 
						|
        return $this->api('groups', $params);
 | 
						|
    }
 | 
						|
}
 |