Proyectos de Subversion Moodle

Rev

| Ultima modificación | Ver Log |

Rev Autor Línea Nro. Línea
1 efrain 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
     */
248
    protected function get_baseapiuri(): string {
249
        $baseapiuri = get_config(manager::PLUGINNAME, 'baseapiuri');
250
        if (!empty($baseapiuri)) {
251
            return $baseapiuri;
252
        } else {
253
            set_config('baseapiuri', self::$baseapiuri, manager::PLUGINNAME);
254
            return self::$baseapiuri;
255
        }
256
    }
257
}