From bafe05a0bb581750562f11646260c374d1a68e99 Mon Sep 17 00:00:00 2001 From: jazinheira Date: Fri, 17 May 2019 11:45:33 -0400 Subject: [PATCH 01/11] Add createGroup() function --- lib/DiscourseAPI.php | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/lib/DiscourseAPI.php b/lib/DiscourseAPI.php index 9bfaf8a..973d4c0 100644 --- a/lib/DiscourseAPI.php +++ b/lib/DiscourseAPI.php @@ -145,6 +145,30 @@ function group($groupname, $usernames = array()) } } + /** + * createGroup + * + * @param string $name name of new group + * + * @return mixed HTTP return code and API return object + */ + + function createGroup($name) + { + $obj = $this->_getRequest('/admin/groups/' . $name . '.json'); + if ($obj->http_code != 200) { + return false; + } + + $params = array( + 'group' => array( + 'name' => $name, + ) + ); + + return $this->_postRequest('/admin/groups', $params); + } + /** * getGroups * From c2abfbf0a0b901c4c0aea2da1c7541582b6e7391 Mon Sep 17 00:00:00 2001 From: jazinheira Date: Fri, 17 May 2019 15:45:59 -0400 Subject: [PATCH 02/11] Add DELETE requests --- lib/DiscourseAPI.php | 38 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 38 insertions(+) diff --git a/lib/DiscourseAPI.php b/lib/DiscourseAPI.php index 973d4c0..cbeeb45 100644 --- a/lib/DiscourseAPI.php +++ b/lib/DiscourseAPI.php @@ -31,6 +31,44 @@ function __construct($dcHostname, $apiKey = null, $protocol='http', $httpAuthNam $this->_httpAuthPass = $httpAuthPass; } + private function _deleteRequest($reqString, $paramArray = null, $apiUser = 'system') + { + return $this->_deletepostRequest($reqString, $paramArray, $apiUser, true); + } + + private function _deletepostRequest($reqString, $paramArray = null, $apiUser = 'system', $putMethod = false) + { + $ch = curl_init(); + $url = sprintf( + '%s://%s%s?api_key=%s&api_username=%s', + $this->_protocol, + $this->_dcHostname, + $reqString, + $this->_apiKey, + $apiUser + ); + curl_setopt($ch, CURLOPT_URL, $url); + curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($paramArray)); + curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); + if ($putMethod) { + curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "DELETE"); + } + + if (!empty($this->_httpAuthName) && !empty($this->_httpAuthPass)) { + curl_setopt($ch, CURLOPT_USERPWD, $this->_httpAuthName . ":" . $this->_httpAuthPass); + curl_setopt($ch, CURLOPT_HTTPAUTH, CURLAUTH_BASIC); + } + + $body = curl_exec($ch); + $rc = curl_getinfo($ch, CURLINFO_HTTP_CODE); + curl_close($ch); + + $resObj = new \stdClass(); + $resObj->http_code = $rc; + $resObj->apiresult = json_decode($body); + return $resObj; + } + private function _getRequest($reqString, $paramArray = null, $apiUser = 'system') { if ($paramArray == null) { From 6da0a157340b60471f6d33a212d7a4e255c74896 Mon Sep 17 00:00:00 2001 From: jazinheira Date: Fri, 17 May 2019 15:46:32 -0400 Subject: [PATCH 03/11] Fix createGroup check if group already exists --- lib/DiscourseAPI.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/DiscourseAPI.php b/lib/DiscourseAPI.php index cbeeb45..f49c9bc 100644 --- a/lib/DiscourseAPI.php +++ b/lib/DiscourseAPI.php @@ -193,8 +193,8 @@ function group($groupname, $usernames = array()) function createGroup($name) { - $obj = $this->_getRequest('/admin/groups/' . $name . '.json'); - if ($obj->http_code != 200) { + $obj = $this->_getRequest('/groups/' . $name . '.json'); + if ($obj->http_code == 200) { return false; } From 55d263407fc244c94a132eed7411e8c504336b4a Mon Sep 17 00:00:00 2001 From: jazinheira Date: Fri, 17 May 2019 15:46:55 -0400 Subject: [PATCH 04/11] Add deleteGroup() function --- lib/DiscourseAPI.php | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/lib/DiscourseAPI.php b/lib/DiscourseAPI.php index f49c9bc..deef4d3 100644 --- a/lib/DiscourseAPI.php +++ b/lib/DiscourseAPI.php @@ -207,6 +207,24 @@ function createGroup($name) return $this->_postRequest('/admin/groups', $params); } + /** + * deleteGroup + * + * @param string $name name of group to delete + * + * @return mixed HTTP return code and API return object + */ + + function deleteGroup($name) + { + $obj = $this->_getRequest('/groups/' . $name . '.json'); + if ($obj->http_code != 200) { + return false; + } + + return $this->_deleteRequest('/admin/groups/' . $obj->apiresult->group->id . '.json'); + } + /** * getGroups * From 6458c3549d5ce244be1d10cfb95f1e4a0a7539f9 Mon Sep 17 00:00:00 2001 From: mentalstring Date: Thu, 23 Jan 2020 18:55:29 +0000 Subject: [PATCH 05/11] Update API authentication method Authentication using api-key/api-username in the query parameters is going to stop working [1]. This replaces it with HTTP headers. [1] https://meta.discourse.org/t/discourse-api-documentation/22706 --- lib/DiscourseAPI.php | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/lib/DiscourseAPI.php b/lib/DiscourseAPI.php index 9bfaf8a..7e62e70 100644 --- a/lib/DiscourseAPI.php +++ b/lib/DiscourseAPI.php @@ -36,8 +36,6 @@ private function _getRequest($reqString, $paramArray = null, $apiUser = 'system' if ($paramArray == null) { $paramArray = array(); } - $paramArray['api_key'] = $this->_apiKey; - $paramArray['api_username'] = $apiUser; $ch = curl_init(); $url = sprintf( '%s://%s%s?%s', @@ -46,7 +44,12 @@ private function _getRequest($reqString, $paramArray = null, $apiUser = 'system' $reqString, http_build_query($paramArray) ); - + + curl_setopt($ch, CURLOPT_HTTPHEADER, [ + "Api-Key: " . $this->_apiKey, + "Api-Username: $apiUser" + ]); + if (!empty($this->_httpAuthName) && !empty($this->_httpAuthPass)) { curl_setopt($ch, CURLOPT_USERPWD, $this->_httpAuthName . ":" . $this->_httpAuthPass); curl_setopt($ch, CURLOPT_HTTPAUTH, CURLAUTH_BASIC); From 8afe946e4d6229d58c07ea8e86d2030afae94acc Mon Sep 17 00:00:00 2001 From: Ben Bowler Date: Tue, 31 Mar 2020 10:14:20 +0100 Subject: [PATCH 06/11] Work through the createPost request to get it working --- example.php | 7 +-- lib/DiscourseAPI.php | 144 ++++++++++++++++++++++--------------------- 2 files changed, 77 insertions(+), 74 deletions(-) diff --git a/example.php b/example.php index 3804525..d1cb27d 100644 --- a/example.php +++ b/example.php @@ -24,7 +24,7 @@ // create a topic $r = $api->createTopic( - 'This is the title of a brand new topic', + 'This is the title of a brand new topic', "This is the body text of a brand new topic. I really don't know what to say", $catId, "johndoe" @@ -36,14 +36,11 @@ $r = $api->createPost( 'This is the body of a new post in an existing topic', $topicId, - $catId, 'johndoe' ); - + // change sitesetting // use 'true' and 'false' between quotes $r = $api->changeSiteSetting('invite_expiry_days', 29); print_r($r); - - diff --git a/lib/DiscourseAPI.php b/lib/DiscourseAPI.php index 7e62e70..2503102 100644 --- a/lib/DiscourseAPI.php +++ b/lib/DiscourseAPI.php @@ -1,18 +1,18 @@ - * @copyright 2013, DiscourseHosting.com - * @license http://www.gnu.org/licenses/gpl-2.0.html GPLv2 - * @link https://github.com/discoursehosting/discourse-api-php - */ + * Discourse API client for PHP + * + * This is the Discourse API client for PHP + * This is a very experimental API implementation. + * + * @category DiscourseAPI + * @package DiscourseAPI + * @author Original author DiscourseHosting + * @copyright 2013, DiscourseHosting.com + * @license http://www.gnu.org/licenses/gpl-2.0.html GPLv2 + * @link https://github.com/discoursehosting/discourse-api-php + */ class DiscourseAPI { @@ -22,11 +22,11 @@ class DiscourseAPI private $_httpAuthName = ''; private $_httpAuthPass = ''; - function __construct($dcHostname, $apiKey = null, $protocol='http', $httpAuthName='', $httpAuthPass='') + function __construct($dcHostname, $apiKey = null, $protocol = 'http', $httpAuthName = '', $httpAuthPass = '') { $this->_dcHostname = $dcHostname; $this->_apiKey = $apiKey; - $this->_protocol=$protocol; + $this->_protocol = $protocol; $this->_httpAuthName = $httpAuthName; $this->_httpAuthPass = $httpAuthPass; } @@ -39,18 +39,18 @@ private function _getRequest($reqString, $paramArray = null, $apiUser = 'system' $ch = curl_init(); $url = sprintf( '%s://%s%s?%s', - $this->_protocol, - $this->_dcHostname, - $reqString, + $this->_protocol, + $this->_dcHostname, + $reqString, http_build_query($paramArray) ); - curl_setopt($ch, CURLOPT_HTTPHEADER, [ + curl_setopt($ch, CURLOPT_HTTPHEADER, [ "Api-Key: " . $this->_apiKey, "Api-Username: $apiUser" ]); - - if (!empty($this->_httpAuthName) && !empty($this->_httpAuthPass)) { + + if (!empty($this->_httpAuthName) && !empty($this->_httpAuthPass)) { curl_setopt($ch, CURLOPT_USERPWD, $this->_httpAuthName . ":" . $this->_httpAuthPass); curl_setopt($ch, CURLOPT_HTTPAUTH, CURLAUTH_BASIC); } @@ -74,28 +74,32 @@ private function _putRequest($reqString, $paramArray, $apiUser = 'system') private function _postRequest($reqString, $paramArray, $apiUser = 'system') { + return $this->_putpostRequest($reqString, $paramArray, $apiUser, false); } private function _putpostRequest($reqString, $paramArray, $apiUser = 'system', $putMethod = false) { + $ch = curl_init(); $url = sprintf( '%s://%s%s?api_key=%s&api_username=%s', - $this->_protocol, - $this->_dcHostname, - $reqString, - $this->_apiKey, + $this->_protocol, + $this->_dcHostname, + $reqString, + $this->_apiKey, $apiUser ); + + curl_setopt($ch, CURLOPT_URL, $url); curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($paramArray)); curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); if ($putMethod) { curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "PUT"); } - - if (!empty($this->_httpAuthName) && !empty($this->_httpAuthPass)) { + + if (!empty($this->_httpAuthName) && !empty($this->_httpAuthPass)) { curl_setopt($ch, CURLOPT_USERPWD, $this->_httpAuthName . ":" . $this->_httpAuthPass); curl_setopt($ch, CURLOPT_HTTPAUTH, CURLAUTH_BASIC); } @@ -126,8 +130,8 @@ function group($groupname, $usernames = array()) return false; } - foreach($obj->apiresult as $group) { - if($group->name === $groupname) { + foreach ($obj->apiresult as $group) { + if ($group->name === $groupname) { $groupId = $group->id; break; } @@ -141,7 +145,7 @@ function group($groupname, $usernames = array()) ) ); - if($groupId) { + if ($groupId) { return $this->_putRequest('/admin/groups/' . $groupId, $params); } else { return $this->_postRequest('/admin/groups', $params); @@ -214,19 +218,19 @@ function activateUser($userId) return $this->_putRequest("/admin/users/{$userId}/activate", array()); } - /** - * suspendUser - * - * @param integer $userId id of user to suspend - * - * @return mixed HTTP return code - */ + /** + * suspendUser + * + * @param integer $userId id of user to suspend + * + * @return mixed HTTP return code + */ function suspendUser($userId) { return $this->_putRequest("/admin/users/{$userId}/suspend", array()); } - + /** * getUsernameByEmail * @@ -237,19 +241,20 @@ function suspendUser($userId) function getUsernameByEmail($email) { - $users = $this->_getRequest('/admin/users/list/active.json', - [ 'filter' => $email, 'show_emails' => 'true' ] + $users = $this->_getRequest( + '/admin/users/list/active.json', + ['filter' => $email, 'show_emails' => 'true'] ); - foreach($users->apiresult as $user) { - if($user->email === $email) { + foreach ($users->apiresult as $user) { + if ($user->email === $email) { return $user->username; } } - + return false; } - /** + /** * getUserByUsername * * @param string $userName username of user @@ -261,18 +266,18 @@ function getUserByUsername($userName) { return $this->_getRequest("/users/{$userName}.json"); } - + /** - * getUserByExternalID - * - * @param string $externalID external id of sso user - * - * @return mixed HTTP return code and API return object - */ - function getUserByExternalID($externalID) - { - return $this->_getRequest("/users/by-external/{$externalID}.json"); - } + * getUserByExternalID + * + * @param string $externalID external id of sso user + * + * @return mixed HTTP return code and API return object + */ + function getUserByExternalID($externalID) + { + return $this->_getRequest("/users/by-external/{$externalID}.json"); + } /** * createCategory @@ -307,7 +312,7 @@ function createCategory($categoryName, $color, $textColor = '000000', $userName * @return mixed HTTP return code and API return object */ - function createTopic($topicTitle, $bodyText, $categoryId, $userName, $replyToId = 0) + function createTopic($topicTitle, $bodyText, $categoryId, $userName, $replyToId = 0) { $params = array( 'title' => $topicTitle, @@ -318,7 +323,7 @@ function createTopic($topicTitle, $bodyText, $categoryId, $userName, $replyToId ); return $this->_postRequest('/posts', $params, $userName); } - + /** * watchTopic * @@ -327,26 +332,28 @@ function createTopic($topicTitle, $bodyText, $categoryId, $userName, $replyToId * If no username is given, topic will be watched with * the system API username */ - function watchTopic($topicId, $userName = 'system') - { + function watchTopic($topicId, $userName = 'system') + { $params = array( - 'notification_level' => '3' + 'notification_level' => '3' ); return $this->_postRequest("/t/{$topicId}/notifications.json", $params, $userName); - } + } /** * createPost * - * NOT WORKING YET + * @param string $bodyText body text of topic post + * @param string $topicId topic id - must me a string not array + * @param string $userName user to create topic as + * + * @return mixed HTTP return code and API return object */ - function createPost($bodyText, $topicId, $categoryId, $userName) + function createPost($bodyText, $topicId, $userName) { $params = array( 'raw' => $bodyText, - 'archetype' => 'regular', - 'category' => $categoryId, 'topic_id' => $topicId ); return $this->_postRequest('/posts', $params, $userName); @@ -358,7 +365,7 @@ function inviteUser($email, $topicId, $userName = 'system') 'email' => $email, 'topic_id' => $topicId ); - return $this->_postRequest('/t/'.intval($topicId).'/invite.json', $params, $userName); + return $this->_postRequest('/t/' . intval($topicId) . '/invite.json', $params, $userName); } function changeSiteSetting($siteSetting, $value) @@ -366,7 +373,7 @@ function changeSiteSetting($siteSetting, $value) $params = array($siteSetting => $value); return $this->_putRequest('/admin/site_settings/' . $siteSetting, $params); } - + function getIDByEmail($email) { $username = $this->getUsernameByEmail($email); @@ -383,10 +390,9 @@ function logoutByEmail($email) $params = array('username_or_email' => $email); return $this->_postRequest('/admin/users/' . $user_id . '/log_out', $params); } - - function getUserinfoByName($username) + + function getUserinfoByName($username) { return $this->_getRequest("/users/{$username}.json"); } } - From 49a5f2e4f864619ead743a8ed7575a66c7d56223 Mon Sep 17 00:00:00 2001 From: Ben Bowler Date: Tue, 31 Mar 2020 11:18:54 +0100 Subject: [PATCH 07/11] Add support for getTopic --- lib/DiscourseAPI.php | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/lib/DiscourseAPI.php b/lib/DiscourseAPI.php index 2503102..08fec16 100644 --- a/lib/DiscourseAPI.php +++ b/lib/DiscourseAPI.php @@ -45,6 +45,7 @@ private function _getRequest($reqString, $paramArray = null, $apiUser = 'system' http_build_query($paramArray) ); + // TODO: move post requests to this auth also curl_setopt($ch, CURLOPT_HTTPHEADER, [ "Api-Key: " . $this->_apiKey, "Api-Username: $apiUser" @@ -91,7 +92,6 @@ private function _putpostRequest($reqString, $paramArray, $apiUser = 'system', $ $apiUser ); - curl_setopt($ch, CURLOPT_URL, $url); curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($paramArray)); curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); @@ -300,6 +300,18 @@ function createCategory($categoryName, $color, $textColor = '000000', $userName return $this->_postRequest('/categories', $params, $userName); } + /** + * getTopic + * + * @param string $topicId id of topic + * + * @return mixed HTTP return code and API return object + */ + function getTopic($topicID) + { + return $this->_getRequest('/t/' . $topicID . '.json'); + } + /** * createTopic * @@ -311,7 +323,6 @@ function createCategory($categoryName, $color, $textColor = '000000', $userName * * @return mixed HTTP return code and API return object */ - function createTopic($topicTitle, $bodyText, $categoryId, $userName, $replyToId = 0) { $params = array( @@ -349,7 +360,6 @@ function watchTopic($topicId, $userName = 'system') * * @return mixed HTTP return code and API return object */ - function createPost($bodyText, $topicId, $userName) { $params = array( From c9fc6677966abf9c8b5902bc125e8f6f47076710 Mon Sep 17 00:00:00 2001 From: jazinheira Date: Fri, 17 May 2019 11:45:33 -0400 Subject: [PATCH 08/11] Add createGroup() function --- lib/DiscourseAPI.php | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/lib/DiscourseAPI.php b/lib/DiscourseAPI.php index 08fec16..c4ef4f3 100644 --- a/lib/DiscourseAPI.php +++ b/lib/DiscourseAPI.php @@ -152,6 +152,30 @@ function group($groupname, $usernames = array()) } } + /** + * createGroup + * + * @param string $name name of new group + * + * @return mixed HTTP return code and API return object + */ + + function createGroup($name) + { + $obj = $this->_getRequest('/admin/groups/' . $name . '.json'); + if ($obj->http_code != 200) { + return false; + } + + $params = array( + 'group' => array( + 'name' => $name, + ) + ); + + return $this->_postRequest('/admin/groups', $params); + } + /** * getGroups * From 456dd34baabf2d4c9eb8a4dc458e8b14b6c3ba8f Mon Sep 17 00:00:00 2001 From: jazinheira Date: Fri, 17 May 2019 15:45:59 -0400 Subject: [PATCH 09/11] Add DELETE requests --- lib/DiscourseAPI.php | 38 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 38 insertions(+) diff --git a/lib/DiscourseAPI.php b/lib/DiscourseAPI.php index c4ef4f3..2b77278 100644 --- a/lib/DiscourseAPI.php +++ b/lib/DiscourseAPI.php @@ -31,6 +31,44 @@ function __construct($dcHostname, $apiKey = null, $protocol = 'http', $httpAuthN $this->_httpAuthPass = $httpAuthPass; } + private function _deleteRequest($reqString, $paramArray = null, $apiUser = 'system') + { + return $this->_deletepostRequest($reqString, $paramArray, $apiUser, true); + } + + private function _deletepostRequest($reqString, $paramArray = null, $apiUser = 'system', $putMethod = false) + { + $ch = curl_init(); + $url = sprintf( + '%s://%s%s?api_key=%s&api_username=%s', + $this->_protocol, + $this->_dcHostname, + $reqString, + $this->_apiKey, + $apiUser + ); + curl_setopt($ch, CURLOPT_URL, $url); + curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($paramArray)); + curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); + if ($putMethod) { + curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "DELETE"); + } + + if (!empty($this->_httpAuthName) && !empty($this->_httpAuthPass)) { + curl_setopt($ch, CURLOPT_USERPWD, $this->_httpAuthName . ":" . $this->_httpAuthPass); + curl_setopt($ch, CURLOPT_HTTPAUTH, CURLAUTH_BASIC); + } + + $body = curl_exec($ch); + $rc = curl_getinfo($ch, CURLINFO_HTTP_CODE); + curl_close($ch); + + $resObj = new \stdClass(); + $resObj->http_code = $rc; + $resObj->apiresult = json_decode($body); + return $resObj; + } + private function _getRequest($reqString, $paramArray = null, $apiUser = 'system') { if ($paramArray == null) { From 3d15c9e523d79fa0a835b0dd81a872f1b715ee6a Mon Sep 17 00:00:00 2001 From: jazinheira Date: Fri, 17 May 2019 15:46:32 -0400 Subject: [PATCH 10/11] Fix createGroup check if group already exists --- lib/DiscourseAPI.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/DiscourseAPI.php b/lib/DiscourseAPI.php index 2b77278..5062cfc 100644 --- a/lib/DiscourseAPI.php +++ b/lib/DiscourseAPI.php @@ -200,8 +200,8 @@ function group($groupname, $usernames = array()) function createGroup($name) { - $obj = $this->_getRequest('/admin/groups/' . $name . '.json'); - if ($obj->http_code != 200) { + $obj = $this->_getRequest('/groups/' . $name . '.json'); + if ($obj->http_code == 200) { return false; } From 418346a53a1cd178de1bc1a09d9e748f28a2cc81 Mon Sep 17 00:00:00 2001 From: jazinheira Date: Fri, 17 May 2019 15:46:55 -0400 Subject: [PATCH 11/11] Add deleteGroup() function --- lib/DiscourseAPI.php | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/lib/DiscourseAPI.php b/lib/DiscourseAPI.php index 5062cfc..06980d3 100644 --- a/lib/DiscourseAPI.php +++ b/lib/DiscourseAPI.php @@ -214,6 +214,24 @@ function createGroup($name) return $this->_postRequest('/admin/groups', $params); } + /** + * deleteGroup + * + * @param string $name name of group to delete + * + * @return mixed HTTP return code and API return object + */ + + function deleteGroup($name) + { + $obj = $this->_getRequest('/groups/' . $name . '.json'); + if ($obj->http_code != 200) { + return false; + } + + return $this->_deleteRequest('/admin/groups/' . $obj->apiresult->group->id . '.json'); + } + /** * getGroups *