See Release Notes
Long Term Support Release
Differences Between: [Versions 401 and 402] [Versions 401 and 403]
1 <?php 2 // This file is part of Moodle - http://moodle.org/ 3 // 4 // Moodle is free software: you can redistribute it and/or modify 5 // it under the terms of the GNU General Public License as published by 6 // the Free Software Foundation, either version 3 of the License, or 7 // (at your option) any later version. 8 // 9 // Moodle is distributed in the hope that it will be useful, 10 // but WITHOUT ANY WARRANTY; without even the implied warranty of 11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 // GNU General Public License for more details. 13 // 14 // You should have received a copy of the GNU General Public License 15 // along with Moodle. If not, see <http://www.gnu.org/licenses/>. 16 17 namespace tool_brickfield; 18 19 defined('MOODLE_INTERNAL') || die; 20 21 // The curl class is in filelib. 22 global $CFG; 23 require_once("{$CFG->libdir}/filelib.php"); 24 25 use curl; 26 use moodle_url; 27 28 /** 29 * Class brickfieldconnect. Contains all function to connect to Brickfield external services. 30 * 31 * @package tool_brickfield 32 * @author 2020 Onwards Mike Churchward <mike@brickfieldlabs.ie> 33 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL 34 */ 35 class brickfieldconnect extends curl { 36 37 /** @var string The base api uri. */ 38 private static $baseapiuri = 'https://api.mybrickfield.ie/moodle/'; 39 40 /** @var array Endpoint details for setting and checking a site registration */ 41 const ACTION_CHECK_REGISTRATION = [ 42 'endpoint' => 'checkRegister', 43 'method' => 'get', 44 ]; 45 46 /** @var array Endpoint details for sending site summary data */ 47 const ACTION_SEND_SUMMARY = [ 48 'endpoint' => 'summary', 49 'method' => 'post', 50 ]; 51 52 /** 53 * Object method to test whether site is already registered. 54 * @return bool 55 */ 56 public function is_registered(): bool { 57 return !empty($this->get_registration_id_for_credentials()); 58 } 59 60 /** 61 * Update registration of this site. 62 * @param string $apikey The API key to use for the registration attempt 63 * @param string $secretkey The secret key to use 64 * @return bool 65 */ 66 public function update_registration(string $apikey, string $secretkey): bool { 67 $registrationid = $this->get_registration_id_for_credentials($apikey, $secretkey); 68 if (empty($registrationid)) { 69 return false; 70 } 71 72 (new registration())->set_siteid($registrationid); 73 return true; 74 } 75 76 /** 77 * Send the summary data to Brickfield. 78 * @return bool 79 * @throws \dml_exception 80 */ 81 public function send_summary(): bool { 82 // Run a registration check. 83 if (!(new registration())->validate()) { 84 return false; 85 } 86 87 $headers = $this->get_common_headers(); 88 89 // Sanity-check $headers 'id' value. 90 if (!isset($headers['id'])) { 91 return false; 92 } 93 94 $this->set_headers($headers); 95 $summary = accessibility::get_summary_data($headers['id']); 96 $body = json_encode($summary, JSON_UNESCAPED_SLASHES); 97 $result = json_decode($this->call(self::ACTION_SEND_SUMMARY, $body)); 98 if (is_object($result) && ((int)$result->statusCode === 200)) { 99 return true; 100 } else { 101 return false; 102 } 103 } 104 105 /** 106 * Get the URL required for the command. 107 * 108 * @param array $command The command to call, for example see self::ACTION_REGISTER 109 * @return string The complete URL 110 */ 111 protected function get_url_for_command(array $command): string { 112 return $this->get_baseapiuri() . $command['endpoint']; 113 } 114 115 /** 116 * Call the specified command. 117 * 118 * @param array $command The command to call, for example see self::ACTION_REGISTER 119 * @param array|string $params The params provided to the call 120 * @return string The response body 121 */ 122 protected function call(array $command, $params = ''): string { 123 $url = $this->get_url_for_command($command); 124 if ($command['method'] === 'get') { 125 return $this->get($url, $params); 126 } 127 128 if ($command['method'] === 'post') { 129 return $this->post($url, $params); 130 } 131 132 return ''; 133 } 134 135 /** 136 * Get the common headers used for all calls to the Brickfields endpoints. 137 * 138 * @return array 139 */ 140 protected function get_common_headers(): array { 141 $headers = [ 142 'Cache-Control' => 'no-cache', 143 'Content-Type' => 'application/json', 144 'siteurl' => static::get_siteurl(), 145 ]; 146 147 if (static::has_registration_key()) { 148 $registration = new registration(); 149 $headers['secret'] = $registration->get_api_key(); 150 $headers['userhash'] = $registration->get_secret_key(); 151 $headers['id'] = $registration->get_siteid(); 152 } 153 154 return $headers; 155 } 156 157 /** 158 * Set headers on the request from the specified list of headers. 159 * 160 * @param array $headers An array of header name => value 161 */ 162 protected function set_headers(array $headers) { 163 foreach ($headers as $key => $value) { 164 $this->setHeader("{$key}: {$value}"); 165 } 166 } 167 168 /** 169 * Whether the site currently has a registration key stored. 170 * 171 * @return bool 172 */ 173 protected function has_registration_key(): bool { 174 $registration = new registration(); 175 $localkey = $registration->get_api_key(); 176 $localhash = $registration->get_secret_key(); 177 $localid = $registration->get_siteid(); 178 179 if (!$localhash || !$localkey || !$localid) { 180 return false; 181 } 182 183 return true; 184 } 185 186 /** 187 * Get a normalised URL for the site. 188 * 189 * @return string 190 */ 191 protected function get_siteurl(): string { 192 return (new moodle_url('/'))->out(false); 193 } 194 195 /** 196 * Get the registration ID for the given set of credentials. 197 * @param null|string $apikey The API key to use for the registration attempt 198 * @param null|string $secretkey The secret key to use 199 * @return null|string The registration ID if registration was successful, or null if not 200 */ 201 protected function get_registration_id_for_credentials(string $apikey = null, string $secretkey = null): string { 202 $headers = $this->get_common_headers(); 203 if ($apikey || $secretkey) { 204 $headers['secret'] = $apikey; 205 $headers['userhash'] = $secretkey; 206 } else if (!$this->has_registration_key()) { 207 return ''; 208 } 209 210 $this->set_headers($headers); 211 $response = $this->call(self::ACTION_CHECK_REGISTRATION); 212 213 if ((int)$this->info['http_code'] !== 200) { 214 // The response was unsuccessful. 215 return ''; 216 } 217 218 $result = json_decode($response); 219 if (!$result) { 220 // The response could not be decoded. 221 return ''; 222 } 223 224 if ((int)$result->statusCode !== 200) { 225 // The data from the response suggests a failure. 226 return ''; 227 } 228 229 // Decode the actual result. 230 $registrationdata = json_decode($result->body); 231 if (empty($registrationdata) || !is_array($registrationdata)) { 232 // Unable to decode the body of the response. 233 return ''; 234 } 235 236 if (!property_exists($registrationdata[0], 'id') || !property_exists($registrationdata[0]->id, 'N')) { 237 // Unable to find a valid id in the response. 238 return ''; 239 } 240 241 return $registrationdata[0]->id->N; 242 } 243 244 /** 245 * Get the check registration API URI. 246 * @return string 247 * @throws dml_exception 248 */ 249 protected function get_baseapiuri(): string { 250 $baseapiuri = get_config(manager::PLUGINNAME, 'baseapiuri'); 251 if (!empty($baseapiuri)) { 252 return $baseapiuri; 253 } else { 254 set_config('baseapiuri', self::$baseapiuri, manager::PLUGINNAME); 255 return self::$baseapiuri; 256 } 257 } 258 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body