Skip to content

Instantly share code, notes, and snippets.

@unarist
Created December 27, 2017 01:49
Show Gist options
  • Save unarist/5aa0d534fbd2b64b071f76083cd0c9b2 to your computer and use it in GitHub Desktop.
Save unarist/5aa0d534fbd2b64b071f76083cd0c9b2 to your computer and use it in GitHub Desktop.
<?php
abstract class Body {
protected $contentType;
protected $encodedBody;
public function getContentType() {
return $this->contentType;
}
public function getEncodedBody() {
return $this->encodedBody;
}
}
class UrlEncodedBody extends Body {
public function __construct($params) {
$this->contentType = 'application/x-www-form-urlencoded';
$this->encodedBody = http_build_query($params);
}
}
class JsonBody extends Body {
public function __construct($params) {
$this->contentType = 'application/json';
$this->encodedBody = json_encode($params);
}
}
/*
register -> (save id/secret) -> getAuthorizationUrl
setClientId -> (obtain auth code) -> setTokenFromCode
setClientId -> getAnonymousToken
setClientId -> setToken
*/
class Mastodon
{
const OOB_URI = 'urn:ietf:wg:oauth:2.0:oob';
private $base_url;
private $config = [
'client_name' => '',
'redirect_uri' => self::OOB_URI,
'scope' => 'read',
'website' => ''
];
private $client_id;
private $client_secret;
private $token;
public function __construct($base_url, $config) {
$this->base_url = $base_url;
$this->config = array_merge($this->config, $config);
}
/* === OAuth === */
public function register() {
$resp = $this->curl('POST', '/api/v1/apps', [], new JsonBody([
'client_name' => $this->config['client_name'],
'redirect_uris' => $this->config['redirect_uri'],
'scopes' => $this->config['scope'],
'website' => $this->config['website']
]));
if ($resp) {
$this->client_id = $resp['client_id'];
$this->client_secret = $resp['client_secret'];
}
return $resp;
}
public function setClientId($client_id, $client_secret) {
$this->client_id = $client_id;
$this->client_secret = $client_secret;
}
public function getAuthorizationUrl() {
$params = [
'client_id' => $this->client_id,
'redirect_uri' => $this->config['redirect_uri'],
'response_type' => 'code'
];
return $this->base_url . '/oauth/authorize?' . http_build_query($params);
}
public function getAnonymousToken() {
$resp = $this->curl('POST', '/oauth/token', [], new UrlEncodedBody([
'client_id' => $this->client_id,
'client_secret' => $this->client_secret,
'grant_type' => 'client_credentials'
]));
if ($resp) {
$this->token = $resp['access_token'];
}
return $resp;
}
public function getTokenFromCode($code) {
$resp = $this->curl('POST', '/oauth/token', [], new UrlEncodedBody([
'client_id' => $this->client_id,
'client_secret' => $this->client_secret,
'grant_type' => 'authorization_code',
'code' => $code,
'redirect_uri' => $this->config['redirect_uri']
]));
if ($resp) {
$this->token = $resp['access_token'];
}
return $resp;
}
public function setToken($access_token) {
$this->token = $access_token;
}
/* === API === */
public function get($url, array $query = []) {
return $this->curl('GET', $url, $query);
}
public function post($url, array $body = []) {
return $this->curl('POST', $url, [], new JsonBody($body));
}
/* === Private methods === */
private function curl($method, $url, $query = [], Body $body = null) {
$absurl = $this->base_url . $url;
$headers = [];
if ($this->token) {
$headers[] = 'Authorization: Bearer ' . $this->token;
}
$opts = [
CURLOPT_URL => $absurl,
CURLOPT_RETURNTRANSFER => true,
// ほんとはよくない
CURLOPT_SSL_VERIFYPEER => false,
];
if ($method === 'GET' && $query) {
$opts[CURLOPT_URL] .= '?' . http_build_query($query);
}
if ($method === 'POST' && $body) {
$headers[] = 'Content-Type:' . $body->getContentType();
$opts[CURLOPT_POST] = true;
$opts[CURLOPT_POSTFIELDS] = $body->getEncodedBody();
}
$opts[CURLOPT_HTTPHEADER] = $headers;
$curl = curl_init();
curl_setopt_array($curl, $opts);
$result = curl_exec($curl);
if($result === false) {
throw new Exception(curl_error($curl));
}
curl_close($curl);
return json_decode($result, true);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment