| Current Path : /home/quelfutuu/www/plugins/auto/mastodon/v2.0.1/lib/tootophp/ |
| Current File : /home/quelfutuu/www/plugins/auto/mastodon/v2.0.1/lib/tootophp/TootoPHP.php |
<?php
/**
* TootoPHP
*
* @author Maxence Cauderlier
* @link http://max-koder.fr
* @link https://framagit.org/MaxKoder/TootoPHP
* @link https://git.nursit.net/Cerdic/TootoPHP
* @package TootoPHP
* @version 1.3.0
* @license http://opensource.org/licenses/MIT The MIT License
*/
namespace TootoPHP;
/**
* TootoPHP is a class to dialog with Mastodon API
*/
class TootoPHP
{
/**
* Mastodon Instance Name, like 'mastodon.social'
* @var string
*/
protected $domain;
/**
* Path to the JSON file
* @var string
*/
protected $jsonFile;
/**
* HttpRequest Instance
* @var \TootoPHP\HttpRequest
*/
protected $http;
/**
* Defaults headers for HttpRequest
* @var array
*/
protected $headers = [
'Content-Type' => 'application/json; charset=utf-8',
'Accept' => '*/*'
];
/**
* Credentials to register App
* @var array
*/
protected $credentials = [
'client_name' => '',
'redirect_uris' => 'urn:ietf:wg:oauth:2.0:oob',
'scopes' => 'read write follow',
'website' => ''
];
/**
* Credentials to use Mastodon API
* @var array
*/
protected $appCredentials = [];
/**
* Authenticated User infos
* @var array
*/
private $userInfos = [];
/**
* Setting Domain, like 'mastodon.social'
* @param string $domain
* @param string $dir
* optionnal dir to store App tokens
*/
public function __construct($domain = 'mastodon.social', $dir = null)
{
$this->domain = $domain;
// Store credentials in JSON file, in 'tootophp' dir
if (is_null($dir)) {
$dir = __DIR__ . DIRECTORY_SEPARATOR;
}
$hash = substr(md5($domain),0,4);
$this->jsonFile = $dir . 'tootophp-'.$hash.'.json';
}
/**
* Register Application
*
* $applicationName is name of your app, like 'TootoPHP'
* $websiteURL is website URL, like 'http://max-koder.fr
*
* @param string $applicationName
* @param string $websiteURL
* @param string $redirectUris
* one URI per line
* @param bool $forceRegister
* force registering the app, even if jsonFile already exists
* @return boolean|$this
*/
public function registerApp($applicationName, $websiteURL = '', $redirectUris = null, $forceRegister = false)
{
$this->credentials['client_name'] = $applicationName;
$this->credentials['website'] = $websiteURL;
if (!is_null($redirectUris)) {
$this->credentials['redirect_uris'] = $redirectUris;
}
$this->http = new HttpRequest($this->domain);
if ($forceRegister or !is_file($this->jsonFile)) {
// Create new App
$writeApp = $this->createApp();
if ($writeApp === false) {
return false;
}
}
// Get AppCredentials by JSON
$this->appCredentials = $this->loadCredentialsByJSON();
if (isset($this->appCredentials['bearer'])) {
$this->headers['Authorization'] = 'Bearer ' . $this->appCredentials['bearer'];
}
return $this;
}
/**
* Get Authorization URL
*
* After Register App, Authorization URL provide a page to accept App use Mastodon
* And return an auth code for method getAccessToken
* @param string $redirectUri
* @return boolean|string
*/
public function getAuthUrl($redirectUri = null)
{
if (is_array($this->appCredentials) && isset($this->appCredentials['client_id'])) {
// Get Authorization URL
return $this->http->domainURL . 'oauth/authorize/?' . http_build_query([
'client_id' => $this->appCredentials['client_id'],
'redirect_uri' => $redirectUri ? $redirectUri : 'urn:ietf:wg:oauth:2.0:oob',
'response_type' => 'code',
'scope' => 'read write follow',
]);
}
return false;
}
/**
* Get Access Token
*
* Access Token is granted to authentify user, and gave by getAuthUrl method
* by accepting app is using Mastodon
*
* @throws \Exception
*
* @param string $authCode
* @param string $redirectUri
* @param bool $store
* @return boolean|string
*/
public function registerAccessToken($authCode, $redirectUri = null, $store = true)
{
if (is_array($this->appCredentials) && isset($this->appCredentials['client_id'])) {
// Exchange Access Token for our Auth Token
$token = $this->http->post(
'oauth/token', $this->headers,
[
'grant_type' => 'authorization_code',
'redirect_uri' => $redirectUri ? $redirectUri : 'urn:ietf:wg:oauth:2.0:oob',
'client_id' => $this->appCredentials['client_id'],
'client_secret' => $this->appCredentials['client_secret'],
'code' => $authCode
]
);
if (isset($token['error'])) {
throw new \Exception($token['error'] . ': '. $token['error_description']);
}
// Save our Token
return $this->catchBearerToken($token, $store);
}
return false;
}
/**
* Authentify user with stored access token
* @param string $accessToken
* @param bool $store
* @return bool|string
*/
public function authentifyWithToken($accessToken, $store = true) {
if ($accessToken) {
// Prepare header and save our Token if needed
return $this->catchBearerToken(array('access_token' => $accessToken), $store);
}
return false;
}
/**
* Authentify User
*
* You have to authentify to API before using Mastodon
*
* @param string $userName
* @param string $password
* @return bool|string
*/
public function authentify($userName, $password)
{
return $this->authUser($userName, $password);
}
/**
*
* @param $command
* @param string $method
* @param array $params
* @return array
*/
public function callApi($command, $method='get', $params=array())
{
$res = array();
switch ($method) {
case 'get':
$res['content'] = $this->http->get(
$this->http->apiURL . $command,
$this->headers,
$params
);
$res['http_code'] = $this->http->last_http_code;
$res['url'] = $this->http->last_url;
$res['time'] = $_SERVER['REQUEST_TIME'];
$headers = explode("\n", $this->http->last_headers);
$headers = array_map('trim', $headers);
$res['headers'] = array_filter($headers);
break;
case 'post':
$res['content'] = $this->http->post(
$this->http->apiURL . $command,
$this->headers,
$params
);
$res['http_code'] = $this->http->last_http_code;
$res['url'] = $this->http->last_url;
$res['time'] = $_SERVER['REQUEST_TIME'];
$headers = explode("\n", $this->http->last_headers);
$headers = array_map('trim', $headers);
$res['headers'] = array_filter($headers);
break;
default:
$res = false;
break;
}
return $res;
}
/**
* Get authenticated user
*
* @return bool|array
*/
public function getUser()
{
if (empty($this->userInfos)) {
$user = $this->http->get(
$this->http->apiURL . 'accounts/verify_credentials',
$this->headers,
null
);
if (is_array($user) && isset($user['username'])) {
$this->userInfos = $user;
}
else {
return false;
}
}
return $this->userInfos;
}
/**
* Get authenticated user ID
*
* @return string
*/
public function getUserID()
{
$user = $this->getUser();
if (!is_array($user)) {
return false;
}
return $user['id'];
}
/**
* Get authenticated user favourites
*
* Return as an array all user's favourites status
*
* @return array
*/
public function getFavourites()
{
return $this->http->get(
$this->http->apiURL . 'favourites',
$this->headers,
null
);
}
/**
* Get authenticated user's notifications
* Return as an array all user's notifications
*
* @return array
*/
public function getNotifications()
{
return $this->http->get(
$this->http->apiURL . 'notifications',
$this->headers,
null
);
}
/**
* Get an account by his ID
*
* Return account as an array
*
* @param string $id
* @return array
*/
public function getAccount($id)
{
return $this->http->get(
$this->http->apiURL . 'accounts/' . $id,
$this->headers,
null
);
}
/**
* Post a new status
*
* Post a new status in Mastodon instance
*
* Return entire status as an array
*
* @param string $content Toot content
* @param string $visibility Toot visibility (optionnal)
* Values are :
* - public
* - unlisted
* - private
* - direct
* @param array $medias Medias IDs
* @return array
*/
public function postStatus($content, $visibility = 'public', $medias = [])
{
return $this->http->post(
$this->http->apiURL . 'statuses',
$this->headers,
[
'status' => $content,
'visibility' => $visibility,
'media_ids' => $medias
]
);
}
/**
* Get user's followers by his ID
* If not ID is given, return the authenticated user's followers
*
* Return all followers as an array
*
* @param string $id
* @param array $params
* Params is optionnal associative array with these keys :
* limit : Maximum number of accounts to get (Default 40, Max 80)
* max_id : Get a list of followers with ID less than or equal this value
* since_id : Get a list of followers with ID greater than this value
* @return array
*/
public function getFollowers($id = false, $params = [])
{
if ($id === false) {
$id = $this->getUserID();
}
return $this->http->get(
$this->http->apiURL . 'accounts/' . $id . '/followers',
$this->headers,
$params
);
}
/**
* Get user's following by his ID
* If not ID is given, return the authenticated user's following
*
* Return all followings as an array
*
* @param string $id
* @return array
*/
public function getFollowing($id = false)
{
if ($id === false) {
$id = $this->getUserID();
}
return $this->http->get(
$this->http->apiURL . 'accounts/' . $id . '/following',
$this->headers,
null
);
}
/**
* Get user's statuses by his ID
* If not ID is given, return the authenticated user's statuses
*
* Return all statuses as an array
*
* @param string $id
* @param array $params
* Params is optionnal associative array with these keys :
* only_media : Only return statuses that have media attachments
* exclude_replies : Skip statuses that reply to other statuses
* @return array
*/
public function getStatuses($id = false, $params = [])
{
if ($id === false) {
$id = $this->getUserID();
}
return $this->http->get(
$this->http->apiURL . 'accounts/' . $id . '/statuses',
$this->headers,
$params
);
}
/**
* Upload a media from drive to use it in a toot
*
* @param string $filePath Path to the media
* @return array
*/
public function createAttachement($filePath)
{
$mimeType = mime_content_type($filePath);
$curlFile = curl_file_create( $filePath, $mimeType, 'file' );
$url = $this->http->domainURL . $this->http->apiURL . 'media';
$headers = [
'Content-Type' => 'multipart/form-data',
];
$postField =[
'access_token' => $this->appCredentials['bearer'],
'file' => $curlFile,
];
$opts = [
CURLOPT_SSL_VERIFYPEER => false,
CURLOPT_HTTPHEADER => $headers,
CURLOPT_URL => $url,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_POST => true,
CURLOPT_POSTFIELDS => $postField,
];
$curlHandle = curl_init();
curl_setopt_array( $curlHandle, $opts );
$response = curl_exec( $curlHandle );
curl_close( $curlHandle );
return json_decode( $response, true );
}
/**
* Authentify user
*
* Authentify user to get access token
* If successfull, save token and return it
*
* @param string $userName
* @param string $password
* @return boolean|string
*/
protected function authUser($userName = null, $password = null)
{
if (!empty($userName) && !empty($password)) {
if (is_array($this->appCredentials) && isset($this->appCredentials['client_id'])) {
// Get authentified token
$token = $this->http->post(
'oauth/token',
$this->headers,
[
'grant_type' => 'password',
'client_id' => $this->appCredentials['client_id'],
'client_secret' => $this->appCredentials['client_secret'],
'username' => $userName,
'password' => $password,
]
);
// Save our Token
return $this->catchBearerToken($token);
}
}
return false;
}
/**
* Catch the 'access_token' from a token
*
* Get access token to save it from a token
* Return Access Token
*
* @param array $token
* @param bool $store
* @return boolean|string
*/
protected function catchBearerToken($token = null, $store = true)
{
if (!empty($token) && isset($token['access_token'])) {
// Add Token to AppCredentials and save it
$this->appCredentials['bearer'] = $token['access_token'];
$this->headers['Authorization'] = 'Bearer ' . $token['access_token'];
if ($store){
$this->saveCredentialsToJSON($this->appCredentials);
}
return $token['access_token'];
}
return false;
}
/**
* Create new App
*
* Create new application with credentials given in 'registerApp' method
* and save IDs in the JSON file to use them later.
*
* Return true if success
*
* @return boolean
*/
protected function createApp()
{
$credentials = $this->http->post($this->http->apiURL . 'apps', $this->headers, $this->credentials);
if ($credentials === false) {
return false;
}
return $this->saveCredentialsToJSON($credentials);
}
/**
* Save credentials in the JSON file
*
* Return true if success
*
* @param array $credentials
* @return boolean
*/
protected function saveCredentialsToJSON($credentials)
{
return file_put_contents($this->jsonFile, json_encode($credentials, JSON_PRETTY_PRINT));
}
/**
* Load credentials by JSON
*
* Credentials are saved in JSON to save many requests
*
* @return array
*/
protected function loadCredentialsByJSON()
{
$content = file_get_contents($this->jsonFile);
return json_decode($content, true);
}
}