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
/**
18
 * Statement base object for xAPI structure checking and validation.
19
 *
20
 * @package    core_xapi
21
 * @copyright  2020 Ferran Recio
22
 * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
23
 */
24
 
25
namespace core_xapi\local;
26
 
27
use core_xapi\local\statement\item;
28
use core_xapi\local\statement\item_actor;
29
use core_xapi\local\statement\item_object;
30
use core_xapi\local\statement\item_verb;
31
use core_xapi\local\statement\item_result;
32
use core_xapi\local\statement\item_attachment;
33
use core_xapi\local\statement\item_context;
34
use core_xapi\xapi_exception;
35
use JsonSerializable;
36
use stdClass;
37
 
38
defined('MOODLE_INTERNAL') || die();
39
 
40
/**
41
 * Privacy Subsystem for core_xapi implementing null_provider.
42
 *
43
 * @copyright  2020 Ferran Recio
44
 * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
45
 */
46
class statement implements JsonSerializable {
47
 
48
    /** @var item_actor The statement actor. */
49
    protected $actor = null;
50
 
51
    /** @var item_verb The statement verb. */
52
    protected $verb = null;
53
 
54
    /** @var item_object The statement object. */
55
    protected $object = null;
56
 
57
    /** @var item_result The statement result. */
58
    protected $result = null;
59
 
60
    /** @var item_context The statement context. */
61
    protected $context = null;
62
 
63
    /** @var string The statement timestamp. */
64
    protected $timestamp = null;
65
 
66
    /** @var string The statement stored. */
67
    protected $stored = null;
68
 
69
    /** @var item_actor The statement authority. */
70
    protected $authority = null;
71
 
72
    /** @var string The statement version. */
73
    protected $version = null;
74
 
75
    /** @var item_attachment[] The statement attachments. */
76
    protected $attachments = null;
77
 
78
    /** @var additionalfields list of additional fields. */
79
    private static $additionalsfields = [
80
        'timestamp', 'stored', 'version'
81
    ];
82
 
83
    /**
84
     * Function to create a full statement from xAPI statement data.
85
     *
86
     * @param stdClass $data the original xAPI statement
87
     * @return statement statement object
88
     */
89
    public static function create_from_data(stdClass $data): self {
90
 
91
        $result  = new self();
92
 
93
        $requiredfields = ['actor', 'verb', 'object'];
94
        foreach ($requiredfields as $required) {
95
            if (!isset($data->$required)) {
96
                throw new xapi_exception("Missing '{$required}'");
97
            }
98
        }
99
        $result->set_actor(item_actor::create_from_data($data->actor));
100
        $result->set_verb(item_verb::create_from_data($data->verb));
101
        $result->set_object(item_object::create_from_data($data->object));
102
 
103
        if (isset($data->result)) {
104
            $result->set_result(item_result::create_from_data($data->result));
105
        }
106
 
107
        if (!empty($data->attachments)) {
108
            if (!is_array($data->attachments)) {
109
                throw new xapi_exception("Attachments must be an array");
110
            }
111
            foreach ($data->attachments as $attachment) {
112
                $result->add_attachment(item_attachment::create_from_data($attachment));
113
            }
114
        }
115
 
116
        if (isset($data->context)) {
117
            $result->set_context(item_context::create_from_data($data->context));
118
        }
119
 
120
        if (isset($data->authority)) {
121
            $result->set_authority(item_actor::create_from_data($data->authority));
122
        }
123
 
124
        // Store other generic xAPI statement fields.
125
        foreach (self::$additionalsfields as $additional) {
126
            if (isset($data->$additional)) {
127
                $method = 'set_'.$additional;
128
                $result->$method($data->$additional);
129
            }
130
        }
131
        return $result;
132
    }
133
 
134
    /**
135
     * Return the data to serialize in case JSON statement is needed.
136
     *
137
     * @return stdClass the statement data structure
138
     */
139
    public function jsonSerialize(): stdClass {
140
        $result = (object) [
141
            'actor' => $this->actor,
142
            'verb' => $this->verb,
143
            'object' => $this->object,
144
        ];
145
        if (!empty($this->result)) {
146
            $result->result = $this->result;
147
        }
148
        if (!empty($this->context)) {
149
            $result->context = $this->context;
150
        }
151
        if (!empty($this->authority)) {
152
            $result->authority = $this->authority;
153
        }
154
        if (!empty($this->attachments)) {
155
            $result->attachments = $this->attachments;
156
        }
157
        foreach (self::$additionalsfields as $additional) {
158
            if (!empty($this->$additional)) {
159
                $result->$additional = $this->$additional;
160
            }
161
        }
162
        return $result;
163
    }
164
 
165
    /**
166
     * Returns a minified version of a given statement.
167
     *
168
     * The returned structure is suitable to store in the "other" field
169
     * of logstore. xAPI standard specifies a list of attributes that can be calculated
170
     * instead of stored literally. This function get rid of these attributes.
171
     *
172
     * Note: it also converts stdClass to assoc array to make it compatible
173
     * with "other" field in the logstore
174
     *
175
     * @return array the minimal statement needed to be stored a part from logstore data
176
     */
177
    public function minify(): ?array {
178
        $result = [];
179
        $fields = ['verb', 'object',  'context', 'result', 'authority', 'attachments'];
180
        foreach ($fields as $field) {
181
            if (!empty($this->$field)) {
182
                $result[$field] = $this->$field;
183
            }
184
        }
185
        return json_decode(json_encode($result), true);
186
    }
187
 
188
    /**
189
     * Set the statement actor.
190
     *
191
     * @param item_actor $actor actor item
192
     */
193
    public function set_actor(item_actor $actor): void {
194
        $this->actor = $actor;
195
    }
196
 
197
    /**
198
     * Set the statement verb.
199
     *
200
     * @param item_verb $verb verb element
201
     */
202
    public function set_verb(item_verb $verb): void {
203
        $this->verb = $verb;
204
    }
205
 
206
    /**
207
     * Set the statement object.
208
     *
209
     * @param item_object $object compatible object item
210
     */
211
    public function set_object(item_object $object): void {
212
        $this->object = $object;
213
    }
214
 
215
    /**
216
     * Set the statement context.
217
     *
218
     * @param item_context $context context item element
219
     */
220
    public function set_context(item_context $context): void {
221
        $this->context = $context;
222
    }
223
 
224
    /**
225
     * Set the statement result.
226
     *
227
     * @param item_result $result result item element
228
     */
229
    public function set_result(item_result $result): void {
230
        $this->result = $result;
231
    }
232
 
233
    /**
234
     * Set the statement timestamp.
235
     *
236
     * @param string $timestamp timestamp element
237
     */
238
    public function set_timestamp(string $timestamp): void {
239
        $this->timestamp = $timestamp;
240
    }
241
 
242
    /**
243
     * Set the statement stored.
244
     *
245
     * @param string $stored stored element
246
     */
247
    public function set_stored(string $stored): void {
248
        $this->stored = $stored;
249
    }
250
 
251
    /**
252
     * Set the statement authority.
253
     *
254
     * @param item $authority authority item element
255
     */
256
    public function set_authority(item_actor $authority): void {
257
        $this->authority = $authority;
258
    }
259
 
260
    /**
261
     * Set the statement version.
262
     *
263
     * @param string $version version element
264
     */
265
    public function set_version(string $version): void {
266
        $this->version = $version;
267
    }
268
 
269
    /**
270
     * Adds and attachment to the statement.
271
     *
272
     * @param item $attachments attachments item element
273
     */
274
    public function add_attachment(item_attachment $attachment): void {
275
        if ($this->attachments === null) {
276
            $this->attachments = [];
277
        }
278
        $this->attachments[] = $attachment;
279
    }
280
 
281
    /**
282
     * Returns the moodle user represented by this statement actor.
283
     *
284
     * @throws xapi_exception if it's a group statement
285
     * @return stdClass user record
286
     */
287
    public function get_user(): stdClass {
288
        if (!$this->actor) {
289
            throw new xapi_exception("No actor defined");
290
        }
291
        return $this->actor->get_user();
292
    }
293
 
294
    /**
295
     * Return all moodle users represented by this statement actor.
296
     *
297
     * @return array user records
298
     */
299
    public function get_all_users(): array {
300
        if (!$this->actor) {
301
            throw new xapi_exception("No actor defined");
302
        }
303
        return $this->actor->get_all_users();
304
    }
305
 
306
    /**
307
     * Return the moodle group represented by this statement actor.
308
     *
309
     * @throws xapi_exception if it is not a group statement
310
     * @return stdClass a group record
311
     */
312
    public function get_group(): stdClass {
313
        if (!$this->actor) {
314
            throw new xapi_exception("No actor defined");
315
        }
316
        if (method_exists($this->actor, 'get_group')) {
317
            return $this->actor->get_group();
318
        }
319
        throw new xapi_exception("Method not valid on this actor");
320
    }
321
 
322
    /**
323
     * Returns the statement verb ID.
324
     *
325
     * @throws xapi_exception in case the item is no yet defined
326
     * @return string verb ID
327
     */
328
    public function get_verb_id(): string {
329
        if (!$this->verb) {
330
            throw new xapi_exception("No verb defined");
331
        }
332
        return $this->verb->get_id();
333
    }
334
 
335
    /**
336
     * Returns the statement activity ID.
337
     *
338
     * @throws xapi_exception in case the item is no yet defined
339
     * @return string activity ID
340
     */
341
    public function get_activity_id(): string {
342
        if (!$this->object) {
343
            throw new xapi_exception("No object defined");
344
        }
345
        if (method_exists($this->object, 'get_id')) {
346
            return $this->object->get_id();
347
        }
348
        throw new xapi_exception("Method not valid on this object");
349
    }
350
 
351
    /**
352
     * Return the statement actor if it is defined.
353
     *
354
     * @return item_actor|null
355
     */
356
    public function get_actor(): ?item_actor {
357
        return $this->actor;
358
    }
359
 
360
    /**
361
     * Return the statement verb if it is defined.
362
     *
363
     * @return item_verb|null
364
     */
365
    public function get_verb(): ?item_verb {
366
        return $this->verb;
367
    }
368
 
369
    /**
370
     * Return the statement object if it is defined.
371
     *
372
     * @return item_object|null
373
     */
374
    public function get_object(): ?item_object {
375
        return $this->object;
376
    }
377
 
378
    /**
379
     * Return the statement context if it is defined.
380
     *
381
     * @return item|null
382
     */
383
    public function get_context(): ?item_context {
384
        return $this->context;
385
    }
386
 
387
    /**
388
     * Return the statement result if it is defined.
389
     *
390
     * @return item|null
391
     */
392
    public function get_result(): ?item_result {
393
        return $this->result;
394
    }
395
 
396
    /**
397
     * Return the statement timestamp if it is defined.
398
     *
399
     * @return string|null
400
     */
401
    public function get_timestamp(): ?string {
402
        return $this->timestamp;
403
    }
404
 
405
    /**
406
     * Return the statement stored if it is defined.
407
     *
408
     * @return string|null
409
     */
410
    public function get_stored(): ?string {
411
        return $this->stored;
412
    }
413
 
414
    /**
415
     * Return the statement authority if it is defined.
416
     *
417
     * @return item_actor|null
418
     */
419
    public function get_authority(): ?item_actor {
420
        return $this->authority;
421
    }
422
 
423
    /**
424
     * Return the statement version if it is defined.
425
     *
426
     * @return string|null
427
     */
428
    public function get_version(): ?string {
429
        return $this->version;
430
    }
431
 
432
    /**
433
     * Return the statement attachments if it is defined.
434
     *
435
     * @return item_attachment[]|null
436
     */
437
    public function get_attachments(): ?array {
438
        return $this->attachments;
439
    }
440
}