├── .gitignore ├── README.md └── Habitica.php /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Habitica PHP 2 | A PHP class for the Habitica API. 3 | 4 | ## API 5 | 6 | ### GET 7 | * User status 8 | * User tasks 9 | * Task id by task name/text 10 | * Task information by task id 11 | 12 | ### POST 13 | * Create New Tasks 14 | * `type: habit | daily | todo | reward` 15 | * `text: This is an example title` 16 | * `value: 0` 17 | * `note: This is just a simple note` 18 | * Score Tasks 19 | * `taskId: some-task-id` 20 | * `direction: up | down` 21 | * Update Tasks 22 | * `taskId: some-task-id` 23 | * `text: Updated title` 24 | 25 | ### PUT 26 | * Update Tasks 27 | * 'text: Updated title' (required) 28 | -------------------------------------------------------------------------------- /Habitica.php: -------------------------------------------------------------------------------- 1 | 4 | * @version 1.6 5 | * @link http://github.com/ruddfawcett/Habitica.php 6 | * @package Habitica.php 7 | */ 8 | 9 | class Habitica { 10 | public $userId; 11 | public $apiToken; 12 | public $apiURL; 13 | 14 | /** 15 | * Creates a new Habitica instance 16 | */ 17 | 18 | public function __construct ($userId, $apiToken) { 19 | $this->userId = $userId; 20 | $this->apiToken = $apiToken; 21 | $this->apiURL = 'https://habitica.com/api/v3'; 22 | 23 | if (!extension_loaded('cURL')) { 24 | throw new Exception('This Habitica PHP API class requires cURL in order to work.'); 25 | } 26 | } 27 | 28 | /** 29 | * Creates a new task for the userId and apiToken HabitRPG is initiated with 30 | * @param array $newTaskParams required keys: type and text (title) 31 | * @param array $newTaskParams optional keys: value, note 32 | */ 33 | 34 | public function newTask($newTaskParams) { 35 | if (is_array($newTaskParams)) { 36 | if (!empty($newTaskParams['type']) && !empty($newTaskParams['text'])) { 37 | $newTaskParamsEndpoint=$this->apiURL.'/tasks/user'; 38 | $newTaskPostBody=array(); 39 | $newTaskPostBody['type'] = $newTaskParams['type']; 40 | $newTaskPostBody['text'] = $newTaskParams['text']; 41 | if (!empty($newTaskParams['value'])) { 42 | $newTaskPostBody['value']=$newTaskParams['value']; 43 | } 44 | if (!empty($newTaskParams['note'])) { 45 | $newTaskPostBody['note']=$newTaskParams['note']; 46 | } 47 | 48 | $newTaskPostBody = json_encode($newTaskPostBody); 49 | 50 | return $this->curl($newTaskParamsEndpoint,'POST',$newTaskPostBody); 51 | } 52 | else { 53 | throw new Exception('Required keys of $newTaskParams are null.'); 54 | } 55 | } 56 | else { 57 | throw new Exception('newTask takes an array as it\'s parameter.'); 58 | } 59 | } 60 | 61 | /** 62 | * Returns a task's id using it's title/text 63 | * @param string $taskName 64 | */ 65 | 66 | public function getTaskId($taskName) { 67 | $all_tasks = $this->userTasks()['habitRPGData']['data']; 68 | foreach($all_tasks as $task) { 69 | if ($task['text'] == $taskName){ 70 | return $task['id']; 71 | } 72 | } 73 | return 'No task found with that name'; 74 | } 75 | 76 | /** 77 | * Up votes or down votes a task by taskId using apiToken and userId 78 | * @param array $scoringParams required keys: taskId and direction ('up' or 'down') 79 | * @param array $scoringParams optional keys: title, service and icon 80 | */ 81 | 82 | public function taskScoring($scoringParams) { 83 | if(is_array($scoringParams)) { 84 | if(!empty($scoringParams['taskId']) && !empty($scoringParams['direction'])) { 85 | $scoringEndpoint = $this->apiURL.'/tasks/'.$scoringParams['taskId'].'/score/'.$scoringParams['direction']; 86 | $scoringPostBody = array(); 87 | $scoringPostBody['apiToken'] = $this->apiToken; 88 | if(!empty($scoringParams['title'])) { 89 | $scoringPostBody['title'] = $scoringParams['title']; 90 | } 91 | if(!empty($scoringParams['service'])) { 92 | $scoringPostBody['service'] = $scoringParams['service']; 93 | } 94 | if(!empty($scoringParams['icon'])) { 95 | $scoringPostBody['icon'] = $scoringParams['icon']; 96 | } 97 | 98 | $scoringPostBody = json_encode($scoringPostBody); 99 | 100 | return $this->curl($scoringEndpoint, 'POST', $scoringPostBody); 101 | } 102 | else { 103 | throw new Exception('Required keys of $scoringParams are null.'); 104 | } 105 | } 106 | else { 107 | throw new Exception('taskScoring takes an array as it\'s parameter.'); 108 | } 109 | } 110 | 111 | /** 112 | * Grabs all a user's info using the apiToken and userId 113 | * @function userStats() no parameter's required, uses userId and apiToken 114 | */ 115 | 116 | public function userStats() { 117 | return $this->curl($this->apiURL.'/user', 'GET', NULL); 118 | } 119 | 120 | /** 121 | * Gets a JSON feed of all of a users task using apiToken and userId 122 | * @param string $userTasksType ex. habit,todo,daily (optional null value) 123 | * @param string $userTasksType allows to output only certain type of task 124 | */ 125 | 126 | public function userTasks($userTasksType=NULL) { 127 | $userTasksEndpoint = $this->apiURL.'/tasks/user'; 128 | if($userTasksType != NULL) { 129 | $userTasksEndpoint=$this->apiURL.'/tasks?type='.$userTasksType; 130 | } 131 | return $this->curl($userTasksEndpoint, 'GET', NULL); 132 | } 133 | 134 | /** 135 | * Get's info for a certain task only for the apiToken and userId passed 136 | * @param string $taskId taskId for user task, which can be grabbed from userTasks() 137 | */ 138 | 139 | public function userGetTask($taskId) { 140 | if (!empty($taskId)) { 141 | $userGetTaskEndpoint = $this->apiURL.'/tasks/'.$taskId; 142 | 143 | return $this->curl($userGetTaskEndpoint, 'GET', NULL); 144 | } 145 | else { 146 | throw new Exception('userGetTask needs a value as it\'s parameter.'); 147 | } 148 | } 149 | 150 | /** 151 | * Updates a task's for a userId and apiToken combo and a taskId 152 | * @param array $updateParams required keys: taskId and text 153 | */ 154 | 155 | public function updateTask($updateParams) { 156 | if (is_array($updateParams)) { 157 | if (!empty($updateParams['taskId']) && !empty($updateParams['text'])) { 158 | $updateParamsEndpoint=$this->apiURL.'/tasks/'.$updateParams['taskId']; 159 | $updateTaskPostBody = array(); 160 | $updateTaskPostBody['text'] = $updateParams['text']; 161 | 162 | $updateTaskPostBody = json_encode($updateTaskPostBody); 163 | 164 | return $this->curl($updateParamsEndpoint, 'PUT', $updateTaskPostBody); 165 | } 166 | else { 167 | throw new Exception('Required keys of $updateParams are null.'); 168 | } 169 | } 170 | else { 171 | throw new Exception('updateTask takes an array as it\'s parameter.'); 172 | } 173 | } 174 | 175 | /** 176 | * Performs all cURLs that are initated in each function, private function 177 | * @param string $endpoint is the URL of the cURL 178 | * @param string $curlType is the type of the cURL for the switch, e.g. PUT, POST, GET, etc. 179 | * @param array $postBody is the data that is posted to $endpoint in JSON 180 | */ 181 | 182 | private function curl($endpoint, $curlType, $postBody) { 183 | $curl = curl_init(); 184 | $curlArray = array( 185 | CURLOPT_RETURNTRANSFER => true, 186 | CURLOPT_HEADER => false, 187 | CURLOPT_HTTPHEADER => array( 188 | 'Content-type: application/json', 189 | 'x-api-user:'.$this->userId, 190 | 'x-api-key:'.$this->apiToken), 191 | CURLOPT_URL => $endpoint); 192 | switch($curlType) { 193 | case 'POST': 194 | $curlArray[CURLOPT_POSTFIELDS] = $postBody; 195 | $curlArray[CURLOPT_POST] = true; 196 | curl_setopt_array($curl, $curlArray); 197 | break; 198 | case 'GET': 199 | curl_setopt_array($curl, $curlArray); 200 | break; 201 | case 'PUT': 202 | $curlArray[CURLOPT_CUSTOMREQUEST] = 'PUT'; 203 | $curlArray[CURLOPT_POSTFIELDS] = $postBody; 204 | curl_setopt_array($curl, $curlArray); 205 | break; 206 | case 'DELETE': 207 | break; 208 | default: 209 | throw new Exception('Please use a valid method as the cURL type.'); 210 | } 211 | 212 | $habitRPGResponse = curl_exec($curl); 213 | $habitRPGHTTPCode = curl_getinfo($curl, CURLINFO_HTTP_CODE); 214 | 215 | curl_close($curl); 216 | 217 | if ($habitRPGHTTPCode >= 200 && $habitRPGHTTPCode < 300) { 218 | return array('result' => true, 'habitRPGData' => json_decode($habitRPGResponse,true)); 219 | } 220 | else { 221 | $habitRPGResponse = json_decode($habitRPGResponse,true); 222 | return array('error' => $habitRPGResponse['err'], 'details' => array('httpCode' => $habitRPGHTTPCode, 'endpoint' => $endpoint, 'dataSent' => json_decode($postBody, true))); 223 | } 224 | } 225 | } 226 | ?> 227 | --------------------------------------------------------------------------------